UNPKG

holosphere

Version:

Holonic Geospatial Communication Infrastructure

298 lines (261 loc) 11.1 kB
// holo_compute.js import * as h3 from 'h3-js'; /** * Computes operations across multiple layers up the hierarchy * @param {HoloSphere} holoInstance - The HoloSphere instance. * @param {string} holon - Starting holon identifier * @param {string} lens - The lens to compute * @param {object} options - Computation options * @param {number} [maxLevels=15] - Maximum levels to compute up * @param {string} [password] - Optional password for private holons */ export async function computeHierarchy(holoInstance, holon, lens, options, maxLevels = 15, password = null) { let currentHolon = holon; let currentRes = h3.getResolution(currentHolon); const results = []; while (currentRes > 0 && maxLevels > 0) { try { // Use the instance's compute method const result = await holoInstance.compute(currentHolon, lens, options, password); if (result) { results.push(result); } currentHolon = h3.cellToParent(currentHolon, currentRes - 1); currentRes--; maxLevels--; } catch (error) { console.error('Error in compute hierarchy:', error); break; } } return results; } /** * Computes operations on content within a holon and lens for one layer up. * @param {HoloSphere} holoInstance - The HoloSphere instance. * @param {string} holon - The holon identifier. * @param {string} lens - The lens to compute. * @param {object} options - Computation options * @param {string} options.operation - The operation to perform ('summarize', 'aggregate', 'concatenate') * @param {string[]} [options.fields] - Fields to perform operation on * @param {string} [options.targetField] - Field to store the result in * @param {string} [password] - Optional password for private holons * @throws {Error} If parameters are invalid or missing */ export async function compute(holoInstance, holon, lens, options, password = null) { // Validate required parameters if (!holon || !lens) { throw new Error('compute: Missing required parameters'); } // Convert string operation to options object if (typeof options === 'string') { options = { operation: options }; } if (!options?.operation) { throw new Error('compute: Missing required parameters'); } // Validate holon format and resolution first let res; try { res = h3.getResolution(holon); } catch (error) { throw new Error('compute: Invalid holon format'); } if (res < 1 || res > 15) { throw new Error('compute: Invalid holon resolution (must be between 1 and 15)'); } const { operation, fields = [], targetField, depth, maxDepth } = options; // Validate depth parameters if provided if (depth !== undefined && depth < 0) { throw new Error('compute: Invalid depth parameter'); } if (maxDepth !== undefined && (maxDepth < 1 || maxDepth > 15)) { throw new Error('compute: Invalid maxDepth parameter (must be between 1 and 15)'); } // Validate operation const validOperations = ['summarize', 'aggregate', 'concatenate']; if (!validOperations.includes(operation)) { throw new Error(`compute: Invalid operation (must be one of ${validOperations.join(', ')})`); } const parent = h3.cellToParent(holon, res - 1); const siblings = h3.cellToChildren(parent, res); // Collect all content from siblings using instance's getAll const contents = await Promise.all( siblings.map(sibling => holoInstance.getAll(sibling, lens, password)) ); const flatContents = contents.flat().filter(Boolean); if (flatContents.length > 0) { try { let computed; switch (operation) { case 'summarize': // For summarize, concatenate specified fields or use entire content const textToSummarize = fields.length > 0 ? flatContents.map(item => fields.map(field => item[field]).filter(Boolean).join('\n')).join('\n') : JSON.stringify(flatContents); computed = await holoInstance.summarize(textToSummarize); // Use instance's summarize break; case 'aggregate': // For aggregate, sum numeric fields computed = fields.reduce((acc, field) => { acc[field] = flatContents.reduce((sum, item) => { return sum + (Number(item[field]) || 0); }, 0); return acc; }, {}); break; case 'concatenate': // For concatenate, combine arrays or strings computed = fields.reduce((acc, field) => { acc[field] = flatContents.reduce((combined, item) => { const value = item[field]; if (Array.isArray(value)) { return [...combined, ...value]; } else if (value) { return [...combined, value]; } return combined; }, []); // Remove duplicates if array acc[field] = Array.from(new Set(acc[field])); return acc; }, {}); break; } if (computed) { const resultId = `${parent}_${operation}`; const result = { id: resultId, timestamp: Date.now() }; // Store result in targetField if specified, otherwise at root level if (targetField) { result[targetField] = computed; } else if (typeof computed === 'object') { Object.assign(result, computed); } else { result.value = computed; } await holoInstance.put(parent, lens, result, password); // Use instance's put return result; } } catch (error) { console.warn('Error in compute operation:', error); throw error; } } return null; } /** * Summarizes provided history text using OpenAI. * @param {HoloSphere} holoInstance - The HoloSphere instance. * @param {string} history - The history text to summarize. * @returns {Promise<string>} - The summarized text. */ export async function summarize(holoInstance, history) { if (!holoInstance.openai) { return 'OpenAI not initialized, please specify the API key in the constructor.' } try { const response = await holoInstance.openai.chat.completions.create({ model: "gpt-4", messages: [ { role: "system", content: "You are a helpful assistant that summarizes text concisely while preserving key information. Keep summaries clear and focused." }, { role: "user", content: history } ], temperature: 0.7, max_tokens: 500 }); return response.choices[0].message.content.trim(); } catch (error) { console.error('Error in summarize:', error); throw new Error('Failed to generate summary'); } } /** * Upcasts content to parent holonagons recursively using holograms. * @param {HoloSphere} holoInstance - The HoloSphere instance. * @param {string} holon - The current holon identifier. * @param {string} lens - The lens under which to upcast. * @param {object} content - The content to upcast. * @param {number} [maxLevels=15] - Maximum levels to upcast. * @returns {Promise<object>} - The original content. */ export async function upcast(holoInstance, holon, lens, content, maxLevels = 15) { // Store the actual content at the original resolution using instance's put await holoInstance.put(holon, lens, content); let res = h3.getResolution(holon); // If already at the highest level (res 0) or reached max levels, we're done if (res === 0 || maxLevels <= 0) { return content; } // Get the parent cell let parent = h3.cellToParent(holon, res - 1); // Create a hologram to store in the parent using instance's createHologram const hologram = holoInstance.createHologram(holon, lens, content); // Store the hologram in the parent cell using instance's put await holoInstance.put(parent, lens, hologram, null, { autoPropagate: false }); // Continue upcasting with the parent using instance's upcast if (res > 1 && maxLevels > 1) { // Recursively call the instance's upcast method // Pass the *hologram* to the next level, not the original content return holoInstance.upcast(parent, lens, hologram, maxLevels - 1); } return content; } /** * Updates the parent holon with a new report. * Note: This function assumes the existence of `getCellInfo` and `db.put` on the holoInstance, * which were not defined in the original class. Adjust as needed. * @param {HoloSphere} holoInstance - The HoloSphere instance. * @param {string} id - The child holon identifier. * @param {string} report - The report to update. * @returns {Promise<object>} - The updated parent information. */ export async function updateParent(holoInstance, id, report) { // Check if required methods exist on the instance if (typeof holoInstance.getCellInfo !== 'function' || !holoInstance.db || typeof holoInstance.db.put !== 'function') { console.warn('updateParent requires getCellInfo and db.put methods on the HoloSphere instance.'); // Decide how to handle this: throw error, return null, etc. // For now, let's proceed assuming they might exist but log a warning. } try { let cellinfo = await holoInstance.getCellInfo(id) let res = h3.getResolution(id) let parent = h3.cellToParent(id, res - 1) let parentInfo = await holoInstance.getCellInfo(parent) parentInfo.wisdom[id] = report //update summary using instance's summarize let summary = await holoInstance.summarize(Object.values(parentInfo.wisdom).join('\n')) parentInfo.summary = summary // Assuming db is accessible like this await holoInstance.db.put('cell', parentInfo) return parentInfo } catch (error) { console.error("Error during updateParent:", error); // Re-throw or handle error appropriately throw error; } } // Export all compute operations as default export default { computeHierarchy, compute, summarize, upcast, updateParent };