societyai 0.0.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/CHANGELOG.md +111 -0
- package/LICENSE +21 -0
- package/README.md +879 -0
- package/dist/builder.d.ts +181 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +667 -0
- package/dist/builder.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +107 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +319 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +219 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +395 -0
- package/dist/events.js.map +1 -0
- package/dist/graph.d.ts +104 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +366 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +78 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory.d.ts +146 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +353 -0
- package/dist/memory.js.map +1 -0
- package/dist/metrics.d.ts +143 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +271 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware.d.ts +147 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +484 -0
- package/dist/middleware.js.map +1 -0
- package/dist/models.d.ts +32 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +211 -0
- package/dist/models.js.map +1 -0
- package/dist/patterns.d.ts +6 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +68 -0
- package/dist/patterns.js.map +1 -0
- package/dist/pipeline.d.ts +84 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +569 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/retry.d.ts +5 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +70 -0
- package/dist/retry.js.map +1 -0
- package/dist/society.d.ts +94 -0
- package/dist/society.d.ts.map +1 -0
- package/dist/society.js +721 -0
- package/dist/society.js.map +1 -0
- package/dist/strategies.d.ts +55 -0
- package/dist/strategies.d.ts.map +1 -0
- package/dist/strategies.js +678 -0
- package/dist/strategies.js.map +1 -0
- package/dist/tools.d.ts +88 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +366 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +64 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +334 -0
- package/dist/validation.js.map +1 -0
- package/dist/worker-pool.d.ts +17 -0
- package/dist/worker-pool.d.ts.map +1 -0
- package/dist/worker-pool.js +80 -0
- package/dist/worker-pool.js.map +1 -0
- package/docs/README.md +468 -0
- package/docs/advanced.md +616 -0
- package/docs/aggregation-strategies.md +926 -0
- package/docs/api-reference.md +771 -0
- package/docs/architecture.md +648 -0
- package/docs/context-system.md +642 -0
- package/docs/event-system.md +1047 -0
- package/docs/examples.md +576 -0
- package/docs/getting-started.md +564 -0
- package/docs/graph-execution.md +389 -0
- package/docs/memory-system.md +497 -0
- package/docs/metrics-observability.md +560 -0
- package/docs/middleware-system.md +1038 -0
- package/docs/migration.md +296 -0
- package/docs/pipeline-patterns.md +761 -0
- package/docs/structured-output.md +612 -0
- package/docs/tool-calling.md +491 -0
- package/docs/workflows.md +740 -0
- package/examples/README.md +234 -0
- package/examples/advanced-patterns.ts +115 -0
- package/examples/complete-integration.ts +327 -0
- package/examples/graph-workflow.ts +161 -0
- package/examples/memory-system.ts +155 -0
- package/examples/metrics-tracking.ts +243 -0
- package/examples/structured-output.ts +231 -0
- package/examples/tool-calling.ts +163 -0
- package/package.json +94 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using SocietyGraph for Complex Workflows
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to use the graph-based execution engine
|
|
5
|
+
* to create a sophisticated code review workflow with conditional branching,
|
|
6
|
+
* loops, and parallel execution.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
GraphBuilder,
|
|
11
|
+
NodeType,
|
|
12
|
+
AgentBuilder,
|
|
13
|
+
RoleBuilder,
|
|
14
|
+
StandardModelBase,
|
|
15
|
+
} from '../src';
|
|
16
|
+
|
|
17
|
+
// Mock AI Model for demonstration
|
|
18
|
+
class MockModel extends StandardModelBase {
|
|
19
|
+
constructor(name: string) {
|
|
20
|
+
super({ name }, async (prompt: unknown) => {
|
|
21
|
+
// Simulate AI response
|
|
22
|
+
const promptStr = typeof prompt === 'string' ? prompt : JSON.stringify(prompt);
|
|
23
|
+
|
|
24
|
+
if (promptStr.includes('analyze')) {
|
|
25
|
+
return 'The code looks good but needs better error handling.';
|
|
26
|
+
} else if (promptStr.includes('valid')) {
|
|
27
|
+
return 'valid: true\nThe improvements have been applied successfully.';
|
|
28
|
+
} else if (promptStr.includes('fix')) {
|
|
29
|
+
return 'Added try-catch blocks and improved error messages.';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return 'Task completed successfully.';
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function runGraphExample(): Promise<void> {
|
|
38
|
+
console.log('=== Graph-Based Workflow Example ===\n');
|
|
39
|
+
|
|
40
|
+
// Create AI models
|
|
41
|
+
const model = new MockModel('code-analyzer');
|
|
42
|
+
|
|
43
|
+
// Create agent roles
|
|
44
|
+
const analyzerRole = RoleBuilder.create()
|
|
45
|
+
.withId('analyzer')
|
|
46
|
+
.withName('Code Analyzer')
|
|
47
|
+
.withSystemPrompt('You analyze code and identify issues.')
|
|
48
|
+
.build();
|
|
49
|
+
|
|
50
|
+
const fixerRole = RoleBuilder.create()
|
|
51
|
+
.withId('fixer')
|
|
52
|
+
.withName('Code Fixer')
|
|
53
|
+
.withSystemPrompt('You fix code issues.')
|
|
54
|
+
.build();
|
|
55
|
+
|
|
56
|
+
const validatorRole = RoleBuilder.create()
|
|
57
|
+
.withId('validator')
|
|
58
|
+
.withName('Code Validator')
|
|
59
|
+
.withSystemPrompt('You validate code fixes.')
|
|
60
|
+
.build();
|
|
61
|
+
|
|
62
|
+
// Create agents
|
|
63
|
+
const agents = [
|
|
64
|
+
AgentBuilder.create()
|
|
65
|
+
.withId('analyzer-1')
|
|
66
|
+
.withRole(analyzerRole)
|
|
67
|
+
.withModel(model)
|
|
68
|
+
.build(),
|
|
69
|
+
AgentBuilder.create()
|
|
70
|
+
.withId('fixer-1')
|
|
71
|
+
.withRole(fixerRole)
|
|
72
|
+
.withModel(model)
|
|
73
|
+
.build(),
|
|
74
|
+
AgentBuilder.create()
|
|
75
|
+
.withId('validator-1')
|
|
76
|
+
.withRole(validatorRole)
|
|
77
|
+
.withModel(model)
|
|
78
|
+
.build(),
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
// Build the graph
|
|
82
|
+
const graph = GraphBuilder.create()
|
|
83
|
+
// Start node
|
|
84
|
+
.addNode('start', NodeType.START)
|
|
85
|
+
|
|
86
|
+
// Analyze the code
|
|
87
|
+
.addNode('analyze', NodeType.AGENT, { agentId: 'analyzer-1' })
|
|
88
|
+
|
|
89
|
+
// Conditional: Does it need fixing?
|
|
90
|
+
.addNode('needs-fix', NodeType.CONDITION, {
|
|
91
|
+
condition: (result) => !result.includes('looks good'),
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// Fix the code
|
|
95
|
+
.addNode('fix', NodeType.AGENT, { agentId: 'fixer-1' })
|
|
96
|
+
|
|
97
|
+
// Validate the fix
|
|
98
|
+
.addNode('validate', NodeType.AGENT, { agentId: 'validator-1' })
|
|
99
|
+
|
|
100
|
+
// Conditional: Is it valid?
|
|
101
|
+
.addNode('is-valid', NodeType.CONDITION, {
|
|
102
|
+
condition: (result) => result.includes('valid: true'),
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// Transform for final output
|
|
106
|
+
.addNode('format', NodeType.TRANSFORM, {
|
|
107
|
+
transformer: (result) => `✓ Code Review Complete:\n${result}`,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// End node
|
|
111
|
+
.addNode('end', NodeType.END)
|
|
112
|
+
|
|
113
|
+
// Connect the nodes
|
|
114
|
+
.addEdge('start', 'analyze')
|
|
115
|
+
.addEdge('analyze', 'needs-fix')
|
|
116
|
+
|
|
117
|
+
// Conditional edges
|
|
118
|
+
.addConditionalEdge({
|
|
119
|
+
from: 'needs-fix',
|
|
120
|
+
condition: (result) => !result.includes('looks good'),
|
|
121
|
+
truePath: 'fix',
|
|
122
|
+
falsePath: 'format',
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
.addEdge('fix', 'validate')
|
|
126
|
+
.addEdge('validate', 'is-valid')
|
|
127
|
+
|
|
128
|
+
// Loop back if validation fails (max 3 iterations)
|
|
129
|
+
.addConditionalEdge({
|
|
130
|
+
from: 'is-valid',
|
|
131
|
+
condition: (result) => result.includes('valid: true'),
|
|
132
|
+
truePath: 'format',
|
|
133
|
+
falsePath: 'fix',
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
.addEdge('format', 'end')
|
|
137
|
+
|
|
138
|
+
.build();
|
|
139
|
+
|
|
140
|
+
// Execute the graph
|
|
141
|
+
console.log('Visualizing graph structure:');
|
|
142
|
+
console.log(graph.visualize());
|
|
143
|
+
console.log('\nExecuting workflow...\n');
|
|
144
|
+
|
|
145
|
+
const result = await graph.execute(
|
|
146
|
+
'Analyze this TypeScript function for potential issues',
|
|
147
|
+
agents
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
console.log('Result:', result.output);
|
|
151
|
+
console.log('\nExecution path:', result.executionPath.join(' → '));
|
|
152
|
+
console.log('Duration:', result.duration, 'ms');
|
|
153
|
+
console.log('Success:', result.success);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Run the example
|
|
157
|
+
if (require.main === module) {
|
|
158
|
+
runGraphExample().catch(console.error);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { runGraphExample };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Memory System
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates the multi-level memory system including
|
|
5
|
+
* short-term, long-term, and entity memory.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
MemoryBuilder,
|
|
10
|
+
} from '../src';
|
|
11
|
+
|
|
12
|
+
async function runMemoryExample(): Promise<void> {
|
|
13
|
+
console.log('=== Memory System Example ===\n');
|
|
14
|
+
|
|
15
|
+
// Create memory system
|
|
16
|
+
const memory = MemoryBuilder.create()
|
|
17
|
+
.withShortTermMemory({
|
|
18
|
+
maxMessages: 10,
|
|
19
|
+
summarizeAfter: 20,
|
|
20
|
+
decayRate: 0.1,
|
|
21
|
+
})
|
|
22
|
+
.withLongTermMemory({
|
|
23
|
+
maxEntries: 100,
|
|
24
|
+
})
|
|
25
|
+
.build();
|
|
26
|
+
|
|
27
|
+
console.log('--- Short-Term Memory ---');
|
|
28
|
+
|
|
29
|
+
// Add conversation history
|
|
30
|
+
await memory.add('User asked about TypeScript features', {
|
|
31
|
+
type: 'conversation',
|
|
32
|
+
importance: 0.7,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await memory.add('Explained TypeScript generics', {
|
|
36
|
+
type: 'conversation',
|
|
37
|
+
importance: 0.8,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
await memory.add('User wants to learn about decorators', {
|
|
41
|
+
type: 'conversation',
|
|
42
|
+
importance: 0.9,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const shortTerm = memory.getShortTerm();
|
|
46
|
+
const recentMemories = shortTerm.getRecent(5);
|
|
47
|
+
|
|
48
|
+
console.log(`Recent memories: ${recentMemories.length}`);
|
|
49
|
+
recentMemories.forEach(m => {
|
|
50
|
+
console.log(`- ${m.content} (importance: ${m.importance?.toFixed(2)})`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log('\n--- Long-Term Memory ---');
|
|
54
|
+
|
|
55
|
+
// Add facts to long-term memory
|
|
56
|
+
await memory.add('TypeScript is a typed superset of JavaScript', {
|
|
57
|
+
type: 'fact',
|
|
58
|
+
importance: 1.0,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await memory.add('TypeScript compiles to plain JavaScript', {
|
|
62
|
+
type: 'fact',
|
|
63
|
+
importance: 0.9,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await memory.add('Generics provide type-safe reusable components', {
|
|
67
|
+
type: 'fact',
|
|
68
|
+
importance: 0.8,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Retrieve relevant facts
|
|
72
|
+
const context = await memory.retrieve('TypeScript generics', {
|
|
73
|
+
includeShortTerm: true,
|
|
74
|
+
includeLongTerm: true,
|
|
75
|
+
limit: 3,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
console.log('Retrieved context for "TypeScript generics":');
|
|
79
|
+
console.log(context);
|
|
80
|
+
|
|
81
|
+
console.log('\n--- Entity Memory ---');
|
|
82
|
+
|
|
83
|
+
const entities = memory.getEntities();
|
|
84
|
+
|
|
85
|
+
// Add entities
|
|
86
|
+
entities.upsert('John Doe', 'person', [
|
|
87
|
+
'Prefers TypeScript over JavaScript',
|
|
88
|
+
'Learning about decorators',
|
|
89
|
+
'Works as a software engineer',
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
entities.upsert('React', 'framework', [
|
|
93
|
+
'Popular UI library',
|
|
94
|
+
'Works well with TypeScript',
|
|
95
|
+
'Uses JSX syntax',
|
|
96
|
+
]);
|
|
97
|
+
|
|
98
|
+
entities.upsert('TypeScript', 'language', [
|
|
99
|
+
'Statically typed',
|
|
100
|
+
'Compiles to JavaScript',
|
|
101
|
+
'Developed by Microsoft',
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
// Search entities
|
|
105
|
+
const foundEntities = entities.search('TypeScript');
|
|
106
|
+
console.log(`Found ${foundEntities.length} entities related to "TypeScript":`);
|
|
107
|
+
|
|
108
|
+
foundEntities.forEach(entity => {
|
|
109
|
+
console.log(`\n${entity.name} (${entity.type}):`);
|
|
110
|
+
entity.facts.forEach(fact => console.log(` - ${fact}`));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Get entity by type
|
|
114
|
+
const people = entities.getByType('person');
|
|
115
|
+
console.log(`\n${people.length} person entities:`);
|
|
116
|
+
people.forEach(p => console.log(`- ${p.name}`));
|
|
117
|
+
|
|
118
|
+
console.log('\n--- Memory Statistics ---');
|
|
119
|
+
|
|
120
|
+
const stats = memory.getStats();
|
|
121
|
+
console.log('Short-term messages:', stats.shortTerm.messages);
|
|
122
|
+
console.log('Long-term total:', stats.longTerm.total);
|
|
123
|
+
console.log('Long-term by type:', stats.longTerm.byType);
|
|
124
|
+
console.log('Entities total:', stats.entities.total);
|
|
125
|
+
console.log('Entities by type:', stats.entities.byType);
|
|
126
|
+
|
|
127
|
+
console.log('\n--- Advanced: Importance Decay ---');
|
|
128
|
+
|
|
129
|
+
// Simulate time passing
|
|
130
|
+
shortTerm.applyDecay();
|
|
131
|
+
|
|
132
|
+
const decayedMemories = shortTerm.getRecent(5);
|
|
133
|
+
console.log('After decay:');
|
|
134
|
+
decayedMemories.forEach(m => {
|
|
135
|
+
console.log(`- ${m.content} (importance: ${m.importance?.toFixed(2)})`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
console.log('\n--- Advanced: Entity Updates ---');
|
|
139
|
+
|
|
140
|
+
// Update existing entity with new facts
|
|
141
|
+
entities.upsert('John Doe', 'person', [
|
|
142
|
+
'Completed TypeScript decorators tutorial',
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
const john = entities.get('John Doe', 'person');
|
|
146
|
+
console.log(`\nJohn Doe's facts (${john?.facts.length} total):`);
|
|
147
|
+
john?.facts.forEach(fact => console.log(` - ${fact}`));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Run the example
|
|
151
|
+
if (require.main === module) {
|
|
152
|
+
runMemoryExample().catch(console.error);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { runMemoryExample };
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Metrics and Observability
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates comprehensive tracking of token usage,
|
|
5
|
+
* execution time, costs, and OpenTelemetry-compatible trace export.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
MetricsBuilder,
|
|
10
|
+
MetricsTracker,
|
|
11
|
+
TokenCounter,
|
|
12
|
+
PerformanceProfiler,
|
|
13
|
+
CommonCostConfigs,
|
|
14
|
+
StandardModelBase,
|
|
15
|
+
} from '../src';
|
|
16
|
+
|
|
17
|
+
// Example model with token tracking (for reference)
|
|
18
|
+
// This class demonstrates how to integrate metrics tracking into a custom model
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
|
+
class TrackedModel extends StandardModelBase {
|
|
21
|
+
constructor(name: string, private tracker: MetricsTracker) {
|
|
22
|
+
super({ name }, async (prompt: unknown) => {
|
|
23
|
+
const promptStr = typeof prompt === 'string' ? prompt : JSON.stringify(prompt);
|
|
24
|
+
|
|
25
|
+
// Simulate processing
|
|
26
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
27
|
+
|
|
28
|
+
const response = `Processed: ${promptStr.substring(0, 50)}...`;
|
|
29
|
+
|
|
30
|
+
// Track tokens
|
|
31
|
+
// Count tokens for tracking
|
|
32
|
+
// const tokens = TokenCounter.count(promptStr, response);
|
|
33
|
+
|
|
34
|
+
return response;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function runMetricsExample(): Promise<void> {
|
|
40
|
+
console.log('=== Metrics and Observability Example ===\n');
|
|
41
|
+
|
|
42
|
+
// Create metrics tracker
|
|
43
|
+
const tracker = MetricsBuilder.create()
|
|
44
|
+
.withTokenTracking()
|
|
45
|
+
.withCostTracking(CommonCostConfigs['gpt-4'])
|
|
46
|
+
.withCostTracking(CommonCostConfigs['claude-3-sonnet'])
|
|
47
|
+
.build();
|
|
48
|
+
|
|
49
|
+
console.log('--- Basic Tracking ---');
|
|
50
|
+
|
|
51
|
+
// Start tracking a workflow
|
|
52
|
+
tracker.start('workflow-1', { userId: 'user123', task: 'analysis' });
|
|
53
|
+
|
|
54
|
+
// Simulate some work
|
|
55
|
+
await new Promise(resolve => setTimeout(resolve, 150));
|
|
56
|
+
|
|
57
|
+
// End tracking with token metrics
|
|
58
|
+
const snapshot1 = tracker.end('workflow-1', {
|
|
59
|
+
tokens: {
|
|
60
|
+
inputTokens: 500,
|
|
61
|
+
outputTokens: 300,
|
|
62
|
+
totalTokens: 800,
|
|
63
|
+
model: 'gpt-4',
|
|
64
|
+
},
|
|
65
|
+
custom: {
|
|
66
|
+
apiCalls: 3,
|
|
67
|
+
cacheHits: 1,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
console.log('Workflow completed:');
|
|
72
|
+
console.log('- Duration:', snapshot1.execution.duration, 'ms');
|
|
73
|
+
console.log('- Tokens:', snapshot1.tokens?.totalTokens);
|
|
74
|
+
console.log('- Estimated cost:', `$${snapshot1.cost?.totalCost.toFixed(4)}`);
|
|
75
|
+
console.log('- Custom metrics:', snapshot1.custom);
|
|
76
|
+
|
|
77
|
+
// Track multiple workflows
|
|
78
|
+
console.log('\n--- Multiple Workflows ---');
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < 3; i++) {
|
|
81
|
+
tracker.start(`agent-${i}`);
|
|
82
|
+
await new Promise(resolve => setTimeout(resolve, Math.random() * 100));
|
|
83
|
+
|
|
84
|
+
tracker.end(`agent-${i}`, {
|
|
85
|
+
tokens: {
|
|
86
|
+
inputTokens: Math.floor(Math.random() * 500) + 100,
|
|
87
|
+
outputTokens: Math.floor(Math.random() * 300) + 50,
|
|
88
|
+
totalTokens: 0,
|
|
89
|
+
model: 'claude-3-sonnet',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Get aggregated metrics
|
|
95
|
+
const aggregated = tracker.getAggregated();
|
|
96
|
+
|
|
97
|
+
console.log('Aggregated metrics:');
|
|
98
|
+
console.log('- Total executions:', aggregated.totalExecutions);
|
|
99
|
+
console.log('- Successful:', aggregated.successfulExecutions);
|
|
100
|
+
console.log('- Average duration:', aggregated.averageDuration.toFixed(2), 'ms');
|
|
101
|
+
console.log('- Total tokens:', aggregated.totalTokens);
|
|
102
|
+
console.log('- Total cost:', `$${aggregated.totalCost?.toFixed(4)}`);
|
|
103
|
+
|
|
104
|
+
// Track failure
|
|
105
|
+
console.log('\n--- Failure Tracking ---');
|
|
106
|
+
|
|
107
|
+
tracker.start('failing-workflow');
|
|
108
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
throw new Error('Simulated failure');
|
|
112
|
+
} catch (error) {
|
|
113
|
+
tracker.fail('failing-workflow', error as Error);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const failedMetrics = tracker.getAggregated();
|
|
117
|
+
console.log('Failed executions:', failedMetrics.failedExecutions);
|
|
118
|
+
|
|
119
|
+
// Performance profiling
|
|
120
|
+
console.log('\n--- Performance Profiling ---');
|
|
121
|
+
|
|
122
|
+
const profiler = new PerformanceProfiler();
|
|
123
|
+
|
|
124
|
+
profiler.mark('start');
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
126
|
+
|
|
127
|
+
profiler.mark('phase-1-complete');
|
|
128
|
+
await new Promise(resolve => setTimeout(resolve, 75));
|
|
129
|
+
|
|
130
|
+
profiler.mark('phase-2-complete');
|
|
131
|
+
await new Promise(resolve => setTimeout(resolve, 25));
|
|
132
|
+
|
|
133
|
+
profiler.mark('end');
|
|
134
|
+
|
|
135
|
+
const phase1Duration = profiler.measure('phase-1', 'start', 'phase-1-complete');
|
|
136
|
+
const phase2Duration = profiler.measure('phase-2', 'phase-1-complete', 'phase-2-complete');
|
|
137
|
+
const totalDuration = profiler.measure('total', 'start', 'end');
|
|
138
|
+
|
|
139
|
+
console.log('Phase 1 duration:', phase1Duration, 'ms');
|
|
140
|
+
console.log('Phase 2 duration:', phase2Duration, 'ms');
|
|
141
|
+
console.log('Total duration:', totalDuration, 'ms');
|
|
142
|
+
|
|
143
|
+
console.log('\nAll measures:', profiler.getMeasures());
|
|
144
|
+
|
|
145
|
+
// Token estimation
|
|
146
|
+
console.log('\n--- Token Estimation ---');
|
|
147
|
+
|
|
148
|
+
const text1 = 'This is a short text message.';
|
|
149
|
+
const text2 = 'This is a much longer text message with more content and details that will result in more tokens being counted.';
|
|
150
|
+
|
|
151
|
+
console.log('Text 1 estimated tokens:', TokenCounter.estimate(text1));
|
|
152
|
+
console.log('Text 2 estimated tokens:', TokenCounter.estimate(text2));
|
|
153
|
+
|
|
154
|
+
const promptTokens = TokenCounter.count(text2, text1);
|
|
155
|
+
console.log('Prompt + response tokens:', promptTokens);
|
|
156
|
+
|
|
157
|
+
// Export metrics
|
|
158
|
+
console.log('\n--- Metrics Export ---');
|
|
159
|
+
|
|
160
|
+
const jsonExport = tracker.export();
|
|
161
|
+
console.log('JSON export length:', jsonExport.length, 'characters');
|
|
162
|
+
console.log('(Truncated preview):', jsonExport.substring(0, 200), '...');
|
|
163
|
+
|
|
164
|
+
// OpenTelemetry export
|
|
165
|
+
const otelTraces = tracker.exportOTel();
|
|
166
|
+
console.log('\nOpenTelemetry traces:', otelTraces.length);
|
|
167
|
+
console.log('Sample trace:');
|
|
168
|
+
console.log({
|
|
169
|
+
name: otelTraces[0]?.name,
|
|
170
|
+
duration: otelTraces[0]?.endTimeUnixNano - otelTraces[0]?.startTimeUnixNano,
|
|
171
|
+
status: otelTraces[0]?.status.code,
|
|
172
|
+
attributes: Object.keys(otelTraces[0]?.attributes || {}),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Filter history
|
|
176
|
+
console.log('\n--- Filtered History ---');
|
|
177
|
+
|
|
178
|
+
const workflow1History = tracker.getHistory({ id: 'workflow-1' });
|
|
179
|
+
console.log('Workflow-1 executions:', workflow1History.length);
|
|
180
|
+
|
|
181
|
+
const successfulHistory = tracker.getHistory({ success: true });
|
|
182
|
+
console.log('Successful executions:', successfulHistory.length);
|
|
183
|
+
|
|
184
|
+
const failedHistory = tracker.getHistory({ success: false });
|
|
185
|
+
console.log('Failed executions:', failedHistory.length);
|
|
186
|
+
|
|
187
|
+
// Per-agent breakdown
|
|
188
|
+
console.log('\n--- Per-Agent Breakdown ---');
|
|
189
|
+
|
|
190
|
+
const byAgent = aggregated.byAgent;
|
|
191
|
+
if (byAgent) {
|
|
192
|
+
for (const [agentId, snapshots] of Object.entries(byAgent)) {
|
|
193
|
+
console.log(`\n${agentId}:`);
|
|
194
|
+
console.log(` - Executions: ${snapshots.length}`);
|
|
195
|
+
|
|
196
|
+
const totalDuration = snapshots.reduce((sum, s) => sum + (s.execution.duration || 0), 0);
|
|
197
|
+
console.log(` - Total duration: ${totalDuration}ms`);
|
|
198
|
+
|
|
199
|
+
const totalTokens = snapshots.reduce((sum, s) => sum + (s.tokens?.totalTokens || 0), 0);
|
|
200
|
+
if (totalTokens > 0) {
|
|
201
|
+
console.log(` - Total tokens: ${totalTokens}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const totalCost = snapshots.reduce((sum, s) => sum + (s.cost?.totalCost || 0), 0);
|
|
205
|
+
if (totalCost > 0) {
|
|
206
|
+
console.log(` - Total cost: $${totalCost.toFixed(4)}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Cost comparison across models
|
|
212
|
+
console.log('\n--- Cost Comparison ---');
|
|
213
|
+
|
|
214
|
+
const models = [
|
|
215
|
+
{ name: 'gpt-4', tokens: 1000 },
|
|
216
|
+
{ name: 'gpt-4-turbo', tokens: 1000 },
|
|
217
|
+
{ name: 'gpt-3.5-turbo', tokens: 1000 },
|
|
218
|
+
{ name: 'claude-3-opus', tokens: 1000 },
|
|
219
|
+
{ name: 'claude-3-sonnet', tokens: 1000 },
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
console.log('Cost for 1000 tokens (500 input + 500 output):');
|
|
223
|
+
|
|
224
|
+
for (const model of models) {
|
|
225
|
+
const config = CommonCostConfigs[model.name as keyof typeof CommonCostConfigs];
|
|
226
|
+
if (config) {
|
|
227
|
+
const inputCost = (500 / 1000) * config.inputCostPer1K;
|
|
228
|
+
const outputCost = (500 / 1000) * config.outputCostPer1K;
|
|
229
|
+
const totalCost = inputCost + outputCost;
|
|
230
|
+
|
|
231
|
+
console.log(`- ${model.name}: $${totalCost.toFixed(4)}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Run the example
|
|
237
|
+
if (require.main === module) {
|
|
238
|
+
(async (): Promise<void> => {
|
|
239
|
+
await runMetricsExample().catch(console.error);
|
|
240
|
+
})();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export { runMetricsExample };
|