llmjs2 1.3.8 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -476
- package/chain/AGENT_STEP_README.md +102 -0
- package/chain/README.md +257 -0
- package/chain/WORKFLOW_README.md +85 -0
- package/chain/agent-step-example.js +232 -0
- package/chain/docs/AGENT.md +126 -0
- package/chain/docs/GRAPH.md +490 -0
- package/chain/examples.js +314 -0
- package/chain/index.js +31 -0
- package/chain/lib/agent.js +338 -0
- package/chain/lib/flow/agent-step.js +119 -0
- package/chain/lib/flow/edge.js +24 -0
- package/chain/lib/flow/flow.js +76 -0
- package/chain/lib/flow/graph.js +331 -0
- package/chain/lib/flow/index.js +7 -0
- package/chain/lib/flow/step.js +63 -0
- package/chain/lib/memory/in-memory.js +117 -0
- package/chain/lib/memory/index.js +36 -0
- package/chain/lib/memory/lance-memory.js +225 -0
- package/chain/lib/memory/sqlite-memory.js +309 -0
- package/chain/simple-agent-step-example.js +168 -0
- package/chain/workflow-example-usage.js +70 -0
- package/chain/workflow-example.json +59 -0
- package/core/README.md +485 -0
- package/core/cli.js +275 -0
- package/core/docs/BASIC_USAGE.md +62 -0
- package/core/docs/CLI.md +104 -0
- package/{docs → core/docs}/GET_STARTED.md +129 -129
- package/{docs → core/docs}/GUARDRAILS_GUIDE.md +734 -734
- package/{docs → core/docs}/README.md +47 -47
- package/core/docs/ROUTER_GUIDE.md +199 -0
- package/{docs → core/docs}/SERVER_MODE.md +358 -350
- package/core/index.js +115 -0
- package/{providers → core/providers}/ollama.js +14 -6
- package/{providers → core/providers}/openai.js +14 -6
- package/{providers → core/providers}/openrouter.js +14 -6
- package/core/router.js +252 -0
- package/{server.js → core/server.js} +15 -5
- package/package.json +43 -27
- package/cli.js +0 -195
- package/docs/BASIC_USAGE.md +0 -296
- package/docs/CLI.md +0 -455
- package/docs/ROUTER_GUIDE.md +0 -402
- package/index.js +0 -265
- package/router.js +0 -273
- package/test-completion.js +0 -99
- package/test.js +0 -246
- /package/{config.yaml → core/config.yaml} +0 -0
- /package/{logger.js → core/logger.js} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple AgentStep Example (Mock Agents)
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates AgentStep usage with mock agents that don't make real AI calls.
|
|
5
|
+
* Perfect for understanding the API without waiting for AI responses.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { AgentStep, Graph } = require('./index');
|
|
9
|
+
|
|
10
|
+
// Mock Agent class for demonstration (simulates AI responses)
|
|
11
|
+
class MockAgent {
|
|
12
|
+
constructor(responses) {
|
|
13
|
+
this.responses = responses;
|
|
14
|
+
this.callCount = 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async generate(input) {
|
|
18
|
+
// Simulate processing time
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
20
|
+
|
|
21
|
+
const response = this.responses[this.callCount % this.responses.length];
|
|
22
|
+
this.callCount++;
|
|
23
|
+
|
|
24
|
+
console.log(`🤖 MockAgent responding to: "${input.substring(0, 50)}..."`);
|
|
25
|
+
return `${response} (Response #${this.callCount})`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function runSimpleAgentStepExample() {
|
|
30
|
+
console.log('🚀 Simple AgentStep Example with Mock Agents\n');
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Create Mock Agents with Predefined Responses
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
const dataProcessorAgent = new MockAgent([
|
|
37
|
+
'Data processed successfully. Found 150 records with 95% quality score.',
|
|
38
|
+
'Analysis complete. Key insights: trend increasing by 23% monthly.',
|
|
39
|
+
'Validation passed. No anomalies detected in the dataset.'
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
const reportGeneratorAgent = new MockAgent([
|
|
43
|
+
'Generated comprehensive report with charts and recommendations.',
|
|
44
|
+
'Created executive summary highlighting key performance indicators.',
|
|
45
|
+
'Compiled detailed analysis report with actionable insights.'
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
const qualityCheckerAgent = new MockAgent([
|
|
49
|
+
'Quality check passed. Content meets all standards.',
|
|
50
|
+
'Minor issues found and corrected. Quality improved by 15%.',
|
|
51
|
+
'High-quality content validated. Ready for publication.'
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Create AgentSteps with Different Mapping Strategies
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
// Example 1: Function-based input mapping
|
|
59
|
+
const processDataStep = new AgentStep({
|
|
60
|
+
name: 'process-data',
|
|
61
|
+
agent: dataProcessorAgent,
|
|
62
|
+
inputMapper: (context) => {
|
|
63
|
+
const data = context.rawData || [];
|
|
64
|
+
return `Process this dataset with ${data.length} items: ${data.slice(0, 3).join(', ')}...`;
|
|
65
|
+
},
|
|
66
|
+
outputMapper: (response, context) => ({
|
|
67
|
+
processedData: response,
|
|
68
|
+
recordCount: context.rawData?.length || 0,
|
|
69
|
+
processingTimestamp: new Date().toISOString()
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Example 2: Template-based input mapping
|
|
74
|
+
const generateReportStep = new AgentStep({
|
|
75
|
+
name: 'generate-report',
|
|
76
|
+
agent: reportGeneratorAgent,
|
|
77
|
+
inputMapper: 'Create a report based on: {{processedData}} from {{recordCount}} records',
|
|
78
|
+
outputMapper: (response, context) => ({
|
|
79
|
+
report: response,
|
|
80
|
+
basedOn: context['process-data'].processedData,
|
|
81
|
+
generatedAt: new Date().toISOString()
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Example 3: Default mapping (no custom mappers)
|
|
86
|
+
const qualityCheckStep = new AgentStep({
|
|
87
|
+
name: 'quality-check',
|
|
88
|
+
agent: qualityCheckerAgent
|
|
89
|
+
// Uses default input/output mapping
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Build and Execute Workflow
|
|
94
|
+
// ============================================================================
|
|
95
|
+
|
|
96
|
+
console.log('🏗️ Building workflow with AgentSteps...');
|
|
97
|
+
|
|
98
|
+
const workflow = new Graph({ name: 'agent-step-demo' })
|
|
99
|
+
.step(processDataStep, generateReportStep, qualityCheckStep)
|
|
100
|
+
.edge(processDataStep, generateReportStep)
|
|
101
|
+
.edge(generateReportStep, qualityCheckStep)
|
|
102
|
+
.compile();
|
|
103
|
+
|
|
104
|
+
console.log('▶️ Executing workflow...\n');
|
|
105
|
+
|
|
106
|
+
// Test with different datasets
|
|
107
|
+
const testDatasets = [
|
|
108
|
+
{ rawData: [10, 20, 30, 40, 50] },
|
|
109
|
+
{ rawData: ['apple', 'banana', 'cherry', 'date'] },
|
|
110
|
+
{ rawData: [1.5, 2.7, 3.9, 4.2, 5.8, 6.1] }
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < testDatasets.length; i++) {
|
|
114
|
+
console.log(`📊 Test Dataset ${i + 1}:`);
|
|
115
|
+
console.log(` Input: ${JSON.stringify(testDatasets[i])}`);
|
|
116
|
+
|
|
117
|
+
const result = await workflow.run(testDatasets[i]);
|
|
118
|
+
|
|
119
|
+
console.log(` ✓ Data Processing: ${result['process-data'].processedData.substring(0, 60)}...`);
|
|
120
|
+
console.log(` ✓ Report Generation: ${result['generate-report'].report.substring(0, 60)}...`);
|
|
121
|
+
console.log(` ✓ Quality Check: ${result['quality-check'].response.substring(0, 60)}...`);
|
|
122
|
+
console.log(' ✅ Workflow completed\n');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Demonstrate Parallel Agent Execution
|
|
127
|
+
// ============================================================================
|
|
128
|
+
|
|
129
|
+
console.log('🔀 Demonstrating Parallel Agent Execution...\n');
|
|
130
|
+
|
|
131
|
+
// Create parallel workflow
|
|
132
|
+
const parallelWorkflow = new Graph({ name: 'parallel-agents' })
|
|
133
|
+
.step(
|
|
134
|
+
new AgentStep({ name: 'agent-a', agent: new MockAgent(['Task A completed']) }),
|
|
135
|
+
new AgentStep({ name: 'agent-b', agent: new MockAgent(['Task B completed']) }),
|
|
136
|
+
new AgentStep({ name: 'agent-c', agent: new MockAgent(['Task C completed']) }),
|
|
137
|
+
new AgentStep({
|
|
138
|
+
name: 'combiner',
|
|
139
|
+
agent: new MockAgent(['Combined all parallel results successfully'])
|
|
140
|
+
})
|
|
141
|
+
)
|
|
142
|
+
.edge('agent-a', 'combiner')
|
|
143
|
+
.edge('agent-b', 'combiner')
|
|
144
|
+
.edge('agent-c', 'combiner')
|
|
145
|
+
.compile();
|
|
146
|
+
|
|
147
|
+
console.log('▶️ Running parallel agent workflow...');
|
|
148
|
+
const parallelResult = await parallelWorkflow.run({});
|
|
149
|
+
|
|
150
|
+
console.log(' Parallel Results:');
|
|
151
|
+
Object.keys(parallelResult).forEach(key => {
|
|
152
|
+
if (parallelResult[key].response) {
|
|
153
|
+
console.log(` ✓ ${key}: ${parallelResult[key].response}`);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
console.log('\n🎉 AgentStep examples completed successfully!');
|
|
158
|
+
console.log('\n💡 Demonstrated Features:');
|
|
159
|
+
console.log(' • Function-based input/output mapping');
|
|
160
|
+
console.log(' • Template-based input mapping');
|
|
161
|
+
console.log(' • Default mapping behavior');
|
|
162
|
+
console.log(' • Sequential workflow execution');
|
|
163
|
+
console.log(' • Parallel agent execution');
|
|
164
|
+
console.log(' • Context passing between steps');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Run the example
|
|
168
|
+
runSimpleAgentStepExample().catch(console.error);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Loading and running a workflow from JSON configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { Graph } = require('./index');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
|
|
8
|
+
// Load workflow from JSON file
|
|
9
|
+
function loadWorkflowFromFile(filename) {
|
|
10
|
+
try {
|
|
11
|
+
const config = JSON.parse(fs.readFileSync(filename, 'utf8'));
|
|
12
|
+
return Graph.load(config);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
throw new Error(`Failed to load workflow from ${filename}: ${error.message}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Example usage
|
|
19
|
+
async function runExampleWorkflow() {
|
|
20
|
+
console.log('Loading simple workflow from JSON configuration...\n');
|
|
21
|
+
|
|
22
|
+
// Load the workflow
|
|
23
|
+
const workflow = loadWorkflowFromFile('./workflow-example.json').compile();
|
|
24
|
+
|
|
25
|
+
// Test with small data (should succeed)
|
|
26
|
+
console.log('=== Testing with small data (success path) ===');
|
|
27
|
+
const smallData = [1, 2, 3, 4]; // Sum = 20, should be < 100
|
|
28
|
+
|
|
29
|
+
const result1 = await workflow.run({ input: smallData });
|
|
30
|
+
console.log('\n=== Small Data Results ===');
|
|
31
|
+
console.log('Validation passed:', result1.validate?.valid);
|
|
32
|
+
console.log('Processing completed:', !!result1['check-result']);
|
|
33
|
+
console.log('Success handler triggered:', !!result1['success-handler']);
|
|
34
|
+
console.log('Warning handler triggered:', !!result1['warning-handler']);
|
|
35
|
+
console.log('Final result:', result1['success-handler']?.result);
|
|
36
|
+
|
|
37
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
38
|
+
|
|
39
|
+
// Test with large data (should trigger warning)
|
|
40
|
+
console.log('=== Testing with large data (warning path) ===');
|
|
41
|
+
const largeData = [20, 30, 40, 50]; // Sum = 140, should be > 100
|
|
42
|
+
|
|
43
|
+
const result2 = await workflow.run({ input: largeData });
|
|
44
|
+
console.log('\n=== Large Data Results ===');
|
|
45
|
+
console.log('Validation passed:', result2.validate?.valid);
|
|
46
|
+
console.log('Processing completed:', !!result2['check-result']);
|
|
47
|
+
console.log('Success handler triggered:', !!result2['success-handler']);
|
|
48
|
+
console.log('Warning handler triggered:', !!result2['warning-handler']);
|
|
49
|
+
if (result2['warning-handler']) {
|
|
50
|
+
console.log('Warning message:', result2['warning-handler'].message);
|
|
51
|
+
console.log('Final result:', result2['warning-handler'].result);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
55
|
+
|
|
56
|
+
// Test validation failure
|
|
57
|
+
console.log('=== Testing validation failure ===');
|
|
58
|
+
try {
|
|
59
|
+
await workflow.run({ input: [] }); // Empty array should fail
|
|
60
|
+
console.log('Unexpected success');
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.log('\n=== Validation Error (Expected) ===');
|
|
63
|
+
console.log('Error:', error.message);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log('\nWorkflow example completed successfully!');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Run the example
|
|
70
|
+
runExampleWorkflow().catch(console.error);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "simple-workflow",
|
|
3
|
+
"description": "A simple workflow demonstrating JSON loading, parallel execution, conditional logic, and agent integration",
|
|
4
|
+
"steps": [
|
|
5
|
+
{
|
|
6
|
+
"name": "validate",
|
|
7
|
+
"description": "Validate input data",
|
|
8
|
+
"execute": "async (context) => { console.log('Validating input...'); const data = context.input; if (!data || data.length === 0) { throw new Error('No input data'); } return { valid: true, data: data }; }"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"name": "analyze-data",
|
|
12
|
+
"type": "agent",
|
|
13
|
+
"description": "Analyze the processed data using AI",
|
|
14
|
+
"instruction": "You are a data analysis expert. Analyze the provided data and provide insights.",
|
|
15
|
+
"tools": [],
|
|
16
|
+
"model": "gpt-4",
|
|
17
|
+
"userPrompt": "Analyze this data: {{validate.data}}. Provide insights about patterns, trends, and recommendations."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "process-a",
|
|
21
|
+
"description": "Process data - path A",
|
|
22
|
+
"execute": "async (context) => { console.log('Processing path A...'); const result = context.validate.data.map(x => x * 2); return { processed: result, path: 'A' }; }"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "process-b",
|
|
26
|
+
"description": "Process data - path B",
|
|
27
|
+
"execute": "async (context) => { console.log('Processing path B...'); const result = context.validate.data.map(x => x + 10); return { processed: result, path: 'B' }; }"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "check-result",
|
|
31
|
+
"description": "Check processing result and analysis",
|
|
32
|
+
"execute": "async (context) => { console.log('Checking result...'); const resultA = context['process-a'].processed; const resultB = context['process-b'].processed; const sumA = resultA.reduce((a, b) => a + b, 0); const sumB = resultB.reduce((a, b) => a + b, 0); const totalSum = sumA + sumB; const analysis = context['analyze-data'] || 'No analysis available'; return { sum: totalSum, isLarge: totalSum > 100, analysis: analysis }; }"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "success-handler",
|
|
36
|
+
"description": "Handle successful processing",
|
|
37
|
+
"execute": "async (context) => { console.log('SUCCESS: Processing completed!'); const result = context['check-result']; return { status: 'success', result: result.sum, analysis: result.analysis }; }"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "warning-handler",
|
|
41
|
+
"description": "Handle large result warning",
|
|
42
|
+
"execute": "async (context) => { console.log('WARNING: Large result detected!'); const result = context['check-result']; return { status: 'warning', message: 'Result exceeds threshold', result: result.sum, analysis: result.analysis }; }"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"edges": [
|
|
46
|
+
{ "from": "validate", "to": "process-a" },
|
|
47
|
+
{ "from": "validate", "to": "process-b" },
|
|
48
|
+
{ "from": "validate", "to": "analyze-data" },
|
|
49
|
+
{ "from": "process-a", "to": "check-result" },
|
|
50
|
+
{ "from": "process-b", "to": "check-result" },
|
|
51
|
+
{ "from": "analyze-data", "to": "check-result" },
|
|
52
|
+
{ "from": "check-result", "to": "success-handler", "condition": "(result) => !result.isLarge" },
|
|
53
|
+
{ "from": "check-result", "to": "warning-handler", "condition": "(result) => result.isLarge" }
|
|
54
|
+
],
|
|
55
|
+
"metadata": {
|
|
56
|
+
"version": "1.0.0",
|
|
57
|
+
"description": "Demonstrates JSON workflow loading, parallel processing, and conditional branching"
|
|
58
|
+
}
|
|
59
|
+
}
|