Add support for nested manifolds

Introduced the `NestedManifoldRegion` class to enable embedding of `WorkflowFunctionManifold` inside regions, allowing hierarchical workflows. Updated `bin.js` to demonstrate the new functionality and adjusted `lib.js` for nested region navigation and execution logic. Updated `package.json` to specify "type": "module" for ES module support.
This commit is contained in:
2024-11-09 14:01:59 -05:00
parent 7abd62046a
commit 41f4151d41
4 changed files with 173 additions and 120 deletions

137
lib.js
View File

@@ -1,105 +1,75 @@
// Simulated LLM Service
/**
* Simulates a Large Language Model (LLM) service for intent detection.
*/
export class DummyLlmService {
/**
* Queries the simulated LLM with a prompt.
* @param {string} prompt - The input prompt to query the LLM.
* @returns {Promise<{confidence: number, action: string}>} - The detected intent with confidence and action.
*/
async query(prompt) {
const intents = {
analyze: { confidence: 0.9, action: 'analysis' },
process: { confidence: 0.8, action: 'processing' },
transform: { confidence: 0.7, action: 'transformation' },
validate: { confidence: 0.85, action: 'validation' },
clean: { confidence: 0.85, action: 'cleaning' },
};
const matchedIntent = Object.entries(intents).find(([key]) =>
prompt.toLowerCase().includes(key),
prompt.toLowerCase().includes(key)
);
return matchedIntent ? matchedIntent[1] : { confidence: 0.1, action: 'unknown' };
}
}
// Interface for workflow operators
/**
* Represents a workflow operator responsible for performing a specific operation.
*/
export class WorkflowOperator {
/**
* Creates an instance of WorkflowOperator.
* @param {string} name - The name of the operator.
* @param {function(object): Promise<object>} operation - The operation function executed by the operator.
*/
constructor(name, operation) {
this.name = name;
this.operation = operation;
}
/**
* Executes the operator's operation with the given state.
* @param {object} state - The current state to be processed.
* @returns {Promise<object>} - The updated state after the operation.
*/
async execute(state) {
return await this.operation(state);
}
}
// Interface for manifold regions
/**
* Represents a region within the manifold, containing workflow operators.
*/
export class ManifoldRegion {
/**
* Creates an instance of ManifoldRegion.
* @param {string} name - The name of the region.
* @param {WorkflowOperator[]} [operators=[]] - The operators available in this region.
*/
constructor(name, operators = []) {
this.name = name;
this.operators = operators;
this.adjacentRegions = new Set();
}
/**
* Adds an operator to the region.
* @param {WorkflowOperator} operator - The operator to be added.
*/
addOperator(operator) {
this.operators.push(operator);
}
/**
* Establishes a connection to another region.
* @param {ManifoldRegion} region - The region to connect to.
*/
connectTo(region) {
this.adjacentRegions.add(region);
region.adjacentRegions.add(this);
}
/**
* Retrieves valid operators for the given state.
* @param {object} _state - The current state.
* @returns {Promise<WorkflowOperator[]>} - The list of valid operators.
*/
async getValidOperators(_state) {
return this.operators;
}
}
// Main manifold implementation
/**
* Represents the workflow function manifold managing regions and state transitions.
*/
export class NestedManifoldRegion extends ManifoldRegion {
constructor(name, nestedManifold) {
super(name);
this.nestedManifold = nestedManifold;
}
async getValidOperators(state) {
if (!this.nestedManifold.currentRegion) {
return [];
}
return await this.nestedManifold.currentRegion.getValidOperators(state);
}
async navigate(prompt) {
return await this.nestedManifold.navigate(prompt);
}
async executeWorkflow(prompt) {
const result = await this.nestedManifold.executeWorkflow(prompt);
return result;
}
}
export class WorkflowFunctionManifold {
/**
* Creates an instance of WorkflowFunctionManifold.
* @param {DummyLlmService} llmService - The LLM service used for intent detection.
*/
constructor(llmService) {
this.llmService = llmService;
this.regions = new Map();
@@ -107,10 +77,6 @@ export class WorkflowFunctionManifold {
this.state = {};
}
/**
* Adds a region to the manifold.
* @param {ManifoldRegion} region - The region to be added.
*/
addRegion(region) {
this.regions.set(region.name, region);
if (!this.currentRegion) {
@@ -118,52 +84,61 @@ export class WorkflowFunctionManifold {
}
}
/**
* Navigates to the next region based on the provided prompt.
* @param {string} prompt - The input prompt for intent matching.
* @returns {Promise<boolean>} - Whether navigation was successful.
*/
async navigate(prompt) {
try {
const intent = await this.llmService.query(prompt);
// If current region is nested, try to navigate within it first
if (this.currentRegion instanceof NestedManifoldRegion) {
const nestedNavigated = await this.currentRegion.navigate(prompt);
if (nestedNavigated) {
return true;
}
}
const intent = await this.llmService.query(prompt);
if (intent.confidence <= 0.5) {
return false;
}
// Try to find matching region
const nextRegion = Array.from(this.currentRegion.adjacentRegions).find(region =>
region.name.toLowerCase().includes(intent.action),
region.name.toLowerCase().includes(intent.action)
);
if (nextRegion && intent.confidence > 0.5) {
if (nextRegion) {
this.currentRegion = nextRegion;
return true;
}
console.warn(`No valid region found for prompt: "${prompt}"`);
return false;
} catch (error) {
console.error(`Error during navigation for prompt "${prompt}":`, error);
console.error('Navigation error:', error);
return false;
}
}
/**
* Executes the workflow based on the current region and provided prompt.
* @param {string} prompt - The input prompt for intent matching.
* @returns {Promise<boolean>} - Whether the workflow execution was successful.
*/
async executeWorkflow(prompt) {
try {
const operators = await this.currentRegion.getValidOperators(this.state);
if (this.currentRegion instanceof NestedManifoldRegion) {
const nestedResult = await this.currentRegion.executeWorkflow(prompt);
return nestedResult;
}
const intent = await this.llmService.query(prompt);
const operators = await this.currentRegion.getValidOperators(this.state);
const matchedOperator = operators.find(op => op.name.toLowerCase().includes(intent.action));
const matchedOperator = operators.find(op =>
op.name.toLowerCase().includes(intent.action)
);
if (matchedOperator) {
if (matchedOperator && intent.confidence > 0.5) {
this.state = await matchedOperator.execute(this.state);
return true;
}
console.warn(`No matching operator found for intent: ${intent.action}`);
return false;
} catch (error) {
console.error(`Error during workflow execution for prompt "${prompt}":`, error);
console.error('Execution error:', error);
return false;
}
}
}
}