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.
Files changed (114) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +879 -0
  4. package/dist/builder.d.ts +181 -0
  5. package/dist/builder.d.ts.map +1 -0
  6. package/dist/builder.js +667 -0
  7. package/dist/builder.js.map +1 -0
  8. package/dist/config.d.ts +43 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +11 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/context.d.ts +107 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +319 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/errors.d.ts +31 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +85 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/events.d.ts +219 -0
  21. package/dist/events.d.ts.map +1 -0
  22. package/dist/events.js +395 -0
  23. package/dist/events.js.map +1 -0
  24. package/dist/graph.d.ts +104 -0
  25. package/dist/graph.d.ts.map +1 -0
  26. package/dist/graph.js +366 -0
  27. package/dist/graph.js.map +1 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +113 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/logger.d.ts +13 -0
  33. package/dist/logger.d.ts.map +1 -0
  34. package/dist/logger.js +78 -0
  35. package/dist/logger.js.map +1 -0
  36. package/dist/memory.d.ts +146 -0
  37. package/dist/memory.d.ts.map +1 -0
  38. package/dist/memory.js +353 -0
  39. package/dist/memory.js.map +1 -0
  40. package/dist/metrics.d.ts +143 -0
  41. package/dist/metrics.d.ts.map +1 -0
  42. package/dist/metrics.js +271 -0
  43. package/dist/metrics.js.map +1 -0
  44. package/dist/middleware.d.ts +147 -0
  45. package/dist/middleware.d.ts.map +1 -0
  46. package/dist/middleware.js +484 -0
  47. package/dist/middleware.js.map +1 -0
  48. package/dist/models.d.ts +32 -0
  49. package/dist/models.d.ts.map +1 -0
  50. package/dist/models.js +211 -0
  51. package/dist/models.js.map +1 -0
  52. package/dist/patterns.d.ts +6 -0
  53. package/dist/patterns.d.ts.map +1 -0
  54. package/dist/patterns.js +68 -0
  55. package/dist/patterns.js.map +1 -0
  56. package/dist/pipeline.d.ts +84 -0
  57. package/dist/pipeline.d.ts.map +1 -0
  58. package/dist/pipeline.js +569 -0
  59. package/dist/pipeline.js.map +1 -0
  60. package/dist/retry.d.ts +5 -0
  61. package/dist/retry.d.ts.map +1 -0
  62. package/dist/retry.js +70 -0
  63. package/dist/retry.js.map +1 -0
  64. package/dist/society.d.ts +94 -0
  65. package/dist/society.d.ts.map +1 -0
  66. package/dist/society.js +721 -0
  67. package/dist/society.js.map +1 -0
  68. package/dist/strategies.d.ts +55 -0
  69. package/dist/strategies.d.ts.map +1 -0
  70. package/dist/strategies.js +678 -0
  71. package/dist/strategies.js.map +1 -0
  72. package/dist/tools.d.ts +88 -0
  73. package/dist/tools.d.ts.map +1 -0
  74. package/dist/tools.js +366 -0
  75. package/dist/tools.js.map +1 -0
  76. package/dist/types.d.ts +213 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +19 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/validation.d.ts +64 -0
  81. package/dist/validation.d.ts.map +1 -0
  82. package/dist/validation.js +334 -0
  83. package/dist/validation.js.map +1 -0
  84. package/dist/worker-pool.d.ts +17 -0
  85. package/dist/worker-pool.d.ts.map +1 -0
  86. package/dist/worker-pool.js +80 -0
  87. package/dist/worker-pool.js.map +1 -0
  88. package/docs/README.md +468 -0
  89. package/docs/advanced.md +616 -0
  90. package/docs/aggregation-strategies.md +926 -0
  91. package/docs/api-reference.md +771 -0
  92. package/docs/architecture.md +648 -0
  93. package/docs/context-system.md +642 -0
  94. package/docs/event-system.md +1047 -0
  95. package/docs/examples.md +576 -0
  96. package/docs/getting-started.md +564 -0
  97. package/docs/graph-execution.md +389 -0
  98. package/docs/memory-system.md +497 -0
  99. package/docs/metrics-observability.md +560 -0
  100. package/docs/middleware-system.md +1038 -0
  101. package/docs/migration.md +296 -0
  102. package/docs/pipeline-patterns.md +761 -0
  103. package/docs/structured-output.md +612 -0
  104. package/docs/tool-calling.md +491 -0
  105. package/docs/workflows.md +740 -0
  106. package/examples/README.md +234 -0
  107. package/examples/advanced-patterns.ts +115 -0
  108. package/examples/complete-integration.ts +327 -0
  109. package/examples/graph-workflow.ts +161 -0
  110. package/examples/memory-system.ts +155 -0
  111. package/examples/metrics-tracking.ts +243 -0
  112. package/examples/structured-output.ts +231 -0
  113. package/examples/tool-calling.ts +163 -0
  114. package/package.json +94 -0
@@ -0,0 +1,560 @@
1
+ # Metrics & Observability
2
+
3
+ The Metrics & Observability system provides comprehensive tracking of AI agent performance, costs, and execution metrics with support for OpenTelemetry export.
4
+
5
+ ## Overview
6
+
7
+ The Metrics & Observability system provides:
8
+
9
+ - **MetricsTracker**: Track workflow execution, tokens, costs, and custom metrics
10
+ - **TokenCounter**: Estimate and count tokens for cost calculation
11
+ - **PerformanceProfiler**: Detailed performance profiling with marks and measures
12
+ - **Cost Estimation**: Automatic cost calculation for major AI models
13
+ - **OpenTelemetry Export**: Industry-standard trace format for observability platforms
14
+ - **Aggregation**: Combine metrics across multiple executions
15
+ - **History Tracking**: Maintain execution history with filtering
16
+
17
+ ## Core Components
18
+
19
+ ### MetricsTracker
20
+
21
+ Main metrics tracking class:
22
+
23
+ ```typescript
24
+ import { MetricsBuilder, CommonCostConfigs } from 'societyai';
25
+
26
+ const tracker = MetricsBuilder.create()
27
+ .withTokenTracking()
28
+ .withCostTracking(CommonCostConfigs['gpt-4'])
29
+ .withCustomMetrics(['api_calls', 'cache_hits'])
30
+ .build();
31
+
32
+ // Start tracking a workflow
33
+ tracker.start('workflow-1');
34
+
35
+ // Update during execution
36
+ tracker.updateTokens('workflow-1', {
37
+ inputTokens: 100,
38
+ outputTokens: 50,
39
+ totalTokens: 150,
40
+ model: 'gpt-4',
41
+ });
42
+
43
+ // Add custom metrics
44
+ tracker.addCustomMetric('workflow-1', 'api_calls', 5);
45
+
46
+ // End tracking
47
+ const snapshot = tracker.end('workflow-1');
48
+
49
+ console.log(snapshot);
50
+ // {
51
+ // id: 'workflow-1',
52
+ // execution: { success: true, duration: 1234, startTime: ..., endTime: ... },
53
+ // tokens: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },
54
+ // costs: { inputCost: 0.003, outputCost: 0.003, totalCost: 0.006 },
55
+ // customMetrics: { api_calls: 5 }
56
+ // }
57
+ ```
58
+
59
+ ### TokenCounter
60
+
61
+ Estimate and count tokens:
62
+
63
+ ```typescript
64
+ import { TokenCounter } from 'societyai';
65
+
66
+ const counter = new TokenCounter();
67
+
68
+ // Estimate tokens (approximately 4 characters per token)
69
+ const estimated = counter.estimate('Hello, how are you today?');
70
+ console.log(estimated); // ~7 tokens
71
+
72
+ // Count tokens in a string
73
+ const count = counter.count('This is a longer piece of text...');
74
+ console.log(count); // Token count
75
+
76
+ // Count tokens in messages
77
+ const messageCount = counter.countMessages([
78
+ { role: 'user', content: 'Hello' },
79
+ { role: 'assistant', content: 'Hi there!' },
80
+ ]);
81
+ ```
82
+
83
+ ### PerformanceProfiler
84
+
85
+ Detailed performance profiling:
86
+
87
+ ```typescript
88
+ import { PerformanceProfiler } from 'societyai';
89
+
90
+ const profiler = new PerformanceProfiler();
91
+
92
+ // Mark important points
93
+ profiler.mark('start-processing');
94
+ await processData();
95
+ profiler.mark('end-processing');
96
+
97
+ // Measure between marks
98
+ const duration = profiler.measure('processing-time', 'start-processing', 'end-processing');
99
+ console.log(`Processing took ${duration}ms`);
100
+
101
+ // Get all measurements
102
+ const measurements = profiler.getMeasurements();
103
+
104
+ // Clear profiler
105
+ profiler.clear();
106
+ ```
107
+
108
+ ## Cost Configurations
109
+
110
+ Pre-configured cost models for major AI providers:
111
+
112
+ ```typescript
113
+ import { CommonCostConfigs } from 'societyai';
114
+
115
+ // Available configurations
116
+ const configs = {
117
+ 'gpt-4': CommonCostConfigs['gpt-4'],
118
+ 'gpt-4-turbo': CommonCostConfigs['gpt-4-turbo'],
119
+ 'gpt-3.5-turbo': CommonCostConfigs['gpt-3.5-turbo'],
120
+ 'claude-3-opus': CommonCostConfigs['claude-3-opus'],
121
+ 'claude-3-sonnet': CommonCostConfigs['claude-3-sonnet'],
122
+ 'claude-3-haiku': CommonCostConfigs['claude-3-haiku'],
123
+ };
124
+
125
+ // Each config has
126
+ interface CostConfig {
127
+ model: string;
128
+ inputCostPer1K: number; // Cost per 1000 input tokens
129
+ outputCostPer1K: number; // Cost per 1000 output tokens
130
+ }
131
+
132
+ // GPT-4 example
133
+ // {
134
+ // model: 'gpt-4',
135
+ // inputCostPer1K: 0.03,
136
+ // outputCostPer1K: 0.06
137
+ // }
138
+ ```
139
+
140
+ ## Complete Example
141
+
142
+ ```typescript
143
+ import {
144
+ MetricsBuilder,
145
+ TokenCounter,
146
+ PerformanceProfiler,
147
+ CommonCostConfigs,
148
+ StandardModelBase,
149
+ } from 'societyai';
150
+
151
+ // Create tracked model
152
+ class TrackedModel extends StandardModelBase {
153
+ constructor(
154
+ name: string,
155
+ private tracker: MetricsTracker,
156
+ private workflowId: string
157
+ ) {
158
+ super({ name }, async (prompt: unknown) => {
159
+ const promptStr = typeof prompt === 'string' ? prompt : JSON.stringify(prompt);
160
+
161
+ // Estimate tokens
162
+ const counter = new TokenCounter();
163
+ const inputTokens = counter.estimate(promptStr);
164
+
165
+ // Simulate processing
166
+ await new Promise((resolve) => setTimeout(resolve, 100));
167
+ const response = `Response to: ${promptStr}`;
168
+ const outputTokens = counter.estimate(response);
169
+
170
+ // Track tokens
171
+ this.tracker.updateTokens(this.workflowId, {
172
+ inputTokens,
173
+ outputTokens,
174
+ totalTokens: inputTokens + outputTokens,
175
+ model: name,
176
+ });
177
+
178
+ return response;
179
+ });
180
+ }
181
+ }
182
+
183
+ // Setup tracking
184
+ const tracker = MetricsBuilder.create()
185
+ .withTokenTracking()
186
+ .withCostTracking(CommonCostConfigs['gpt-4'])
187
+ .withCustomMetrics(['agent_count'])
188
+ .build();
189
+
190
+ // Start workflow tracking
191
+ tracker.start('my-workflow');
192
+
193
+ // Execute agents
194
+ const model = new TrackedModel('gpt-4', tracker, 'my-workflow');
195
+ await model.process('Analyze this data');
196
+ await model.process('Generate report');
197
+
198
+ // Add custom metrics
199
+ tracker.addCustomMetric('my-workflow', 'agent_count', 2);
200
+
201
+ // End tracking
202
+ const snapshot = tracker.end('my-workflow');
203
+
204
+ // View results
205
+ console.log(`Duration: ${snapshot.execution.duration}ms`);
206
+ console.log(`Total tokens: ${snapshot.tokens?.totalTokens}`);
207
+ console.log(`Total cost: $${snapshot.costs?.totalCost?.toFixed(4)}`);
208
+ console.log(`Agents used: ${snapshot.customMetrics?.agent_count}`);
209
+ ```
210
+
211
+ ## Tracking Multiple Workflows
212
+
213
+ Track multiple workflows simultaneously:
214
+
215
+ ```typescript
216
+ const tracker = MetricsBuilder.create()
217
+ .withTokenTracking()
218
+ .withCostTracking(CommonCostConfigs['gpt-4'])
219
+ .build();
220
+
221
+ // Track multiple workflows
222
+ tracker.start('workflow-1');
223
+ tracker.start('workflow-2');
224
+ tracker.start('workflow-3');
225
+
226
+ // Update each independently
227
+ tracker.updateTokens('workflow-1', { inputTokens: 100, outputTokens: 50 });
228
+ tracker.updateTokens('workflow-2', { inputTokens: 200, outputTokens: 100 });
229
+
230
+ // End workflows
231
+ const result1 = tracker.end('workflow-1');
232
+ const result2 = tracker.end('workflow-2');
233
+ const result3 = tracker.fail('workflow-3', new Error('Failed'));
234
+
235
+ // View all
236
+ const all = tracker.getAll();
237
+ console.log(`Tracked ${all.length} workflows`);
238
+ ```
239
+
240
+ ## Aggregated Metrics
241
+
242
+ Combine metrics across multiple executions:
243
+
244
+ ```typescript
245
+ // Run multiple workflows
246
+ for (let i = 0; i < 10; i++) {
247
+ tracker.start(`workflow-${i}`);
248
+ // ... execute workflow ...
249
+ tracker.end(`workflow-${i}`, {
250
+ tokens: { totalTokens: 100 + i * 10 },
251
+ });
252
+ }
253
+
254
+ // Get aggregated metrics
255
+ const aggregated = tracker.aggregate();
256
+
257
+ console.log(aggregated);
258
+ // {
259
+ // totalExecutions: 10,
260
+ // successfulExecutions: 10,
261
+ // failedExecutions: 0,
262
+ // totalDuration: 12340,
263
+ // averageDuration: 1234,
264
+ // totalTokens: 1450,
265
+ // averageTokens: 145,
266
+ // totalCost: 0.087,
267
+ // averageCost: 0.0087
268
+ // }
269
+ ```
270
+
271
+ ## History and Filtering
272
+
273
+ Track execution history:
274
+
275
+ ```typescript
276
+ // Get all metrics
277
+ const allMetrics = tracker.getAll();
278
+
279
+ // Get metrics within date range
280
+ const recent = tracker.getHistory({
281
+ startTime: Date.now() - 3600000, // Last hour
282
+ endTime: Date.now(),
283
+ });
284
+
285
+ // Filter by success
286
+ const successful = tracker.getHistory({
287
+ success: true,
288
+ });
289
+
290
+ // Filter by token range
291
+ const highUsage = tracker.getHistory({
292
+ minTokens: 1000,
293
+ });
294
+
295
+ // Combine filters
296
+ const filtered = tracker.getHistory({
297
+ startTime: Date.now() - 86400000, // Last 24 hours
298
+ success: true,
299
+ minTokens: 500,
300
+ maxTokens: 2000,
301
+ });
302
+ ```
303
+
304
+ ## Export Formats
305
+
306
+ ### JSON Export
307
+
308
+ ```typescript
309
+ const jsonExport = tracker.exportJSON();
310
+
311
+ console.log(jsonExport);
312
+ // {
313
+ // timestamp: '2024-01-15T10:30:00Z',
314
+ // metrics: [
315
+ // {
316
+ // id: 'workflow-1',
317
+ // execution: { ... },
318
+ // tokens: { ... },
319
+ // costs: { ... }
320
+ // },
321
+ // ...
322
+ // ],
323
+ // aggregated: { ... }
324
+ // }
325
+
326
+ // Save to file
327
+ import fs from 'fs';
328
+ fs.writeFileSync('metrics.json', JSON.stringify(jsonExport, null, 2));
329
+ ```
330
+
331
+ ### OpenTelemetry Export
332
+
333
+ Export traces in OpenTelemetry format:
334
+
335
+ ```typescript
336
+ const otelTraces = tracker.exportOTel();
337
+
338
+ console.log(otelTraces);
339
+ // {
340
+ // resourceSpans: [
341
+ // {
342
+ // resource: {
343
+ // attributes: [
344
+ // { key: 'service.name', value: { stringValue: 'societyai' } }
345
+ // ]
346
+ // },
347
+ // scopeSpans: [
348
+ // {
349
+ // scope: { name: 'societyai-metrics' },
350
+ // spans: [
351
+ // {
352
+ // traceId: '...',
353
+ // spanId: '...',
354
+ // name: 'workflow-1',
355
+ // startTimeUnixNano: '...',
356
+ // endTimeUnixNano: '...',
357
+ // attributes: [...]
358
+ // }
359
+ // ]
360
+ // }
361
+ // ]
362
+ // }
363
+ // ]
364
+ // }
365
+
366
+ // Send to observability platform
367
+ await sendToJaeger(otelTraces);
368
+ await sendToDatadog(otelTraces);
369
+ ```
370
+
371
+ ## Cost Comparison
372
+
373
+ Compare costs across different models:
374
+
375
+ ```typescript
376
+ const models = [
377
+ 'gpt-4',
378
+ 'gpt-4-turbo',
379
+ 'gpt-3.5-turbo',
380
+ 'claude-3-opus',
381
+ 'claude-3-sonnet',
382
+ 'claude-3-haiku',
383
+ ];
384
+
385
+ const tokenUsage = {
386
+ inputTokens: 10000,
387
+ outputTokens: 5000,
388
+ };
389
+
390
+ console.log('Cost comparison for 10K input + 5K output tokens:\n');
391
+
392
+ models.forEach((modelName) => {
393
+ const config = CommonCostConfigs[modelName];
394
+ const inputCost = (tokenUsage.inputTokens / 1000) * config.inputCostPer1K;
395
+ const outputCost = (tokenUsage.outputTokens / 1000) * config.outputCostPer1K;
396
+ const totalCost = inputCost + outputCost;
397
+
398
+ console.log(`${modelName.padEnd(20)} $${totalCost.toFixed(4)}`);
399
+ });
400
+
401
+ // Output:
402
+ // gpt-4 $0.6000
403
+ // gpt-4-turbo $0.2000
404
+ // gpt-3.5-turbo $0.0100
405
+ // claude-3-opus $0.2250
406
+ // claude-3-sonnet $0.0450
407
+ // claude-3-haiku $0.0038
408
+ ```
409
+
410
+ ## Custom Metrics
411
+
412
+ Track domain-specific metrics:
413
+
414
+ ```typescript
415
+ const tracker = MetricsBuilder.create()
416
+ .withTokenTracking()
417
+ .withCustomMetrics(['api_calls', 'cache_hits', 'errors', 'retries', 'tool_calls'])
418
+ .build();
419
+
420
+ tracker.start('workflow-1');
421
+
422
+ // Track custom metrics
423
+ tracker.addCustomMetric('workflow-1', 'api_calls', 5);
424
+ tracker.addCustomMetric('workflow-1', 'cache_hits', 3);
425
+ tracker.addCustomMetric('workflow-1', 'tool_calls', 2);
426
+
427
+ // Increment metrics
428
+ tracker.incrementCustomMetric('workflow-1', 'errors');
429
+ tracker.incrementCustomMetric('workflow-1', 'retries');
430
+
431
+ const snapshot = tracker.end('workflow-1');
432
+ console.log(snapshot.customMetrics);
433
+ // {
434
+ // api_calls: 5,
435
+ // cache_hits: 3,
436
+ // errors: 1,
437
+ // retries: 1,
438
+ // tool_calls: 2
439
+ // }
440
+ ```
441
+
442
+ ## Real-Time Monitoring
443
+
444
+ Get snapshots during execution:
445
+
446
+ ```typescript
447
+ tracker.start('long-workflow');
448
+
449
+ // During execution
450
+ const currentSnapshot = tracker.getSnapshot('long-workflow');
451
+
452
+ console.log(`Current duration: ${currentSnapshot.execution.duration}ms`);
453
+ console.log(`Tokens so far: ${currentSnapshot.tokens?.totalTokens}`);
454
+ console.log(`Cost so far: $${currentSnapshot.costs?.totalCost}`);
455
+
456
+ // Continue execution...
457
+ ```
458
+
459
+ ## Integration with Graph
460
+
461
+ Track graph execution:
462
+
463
+ ```typescript
464
+ const tracker = MetricsBuilder.create()
465
+ .withTokenTracking()
466
+ .withCostTracking(CommonCostConfigs['gpt-4'])
467
+ .build();
468
+
469
+ // Wrap graph execution
470
+ async function executeWithMetrics(
471
+ graph: SocietyGraph,
472
+ input: string,
473
+ agents: AgentConfig[]
474
+ ): Promise<GraphResult> {
475
+ const workflowId = `graph-${Date.now()}`;
476
+
477
+ tracker.start(workflowId);
478
+
479
+ try {
480
+ const result = await graph.execute(input, agents);
481
+
482
+ // Track results
483
+ tracker.end(workflowId, {
484
+ tokens: {
485
+ // Extract from result
486
+ totalTokens: estimateTokens(result),
487
+ },
488
+ customMetrics: {
489
+ node_count: result.executionPath.length,
490
+ },
491
+ });
492
+
493
+ return result;
494
+ } catch (error) {
495
+ tracker.fail(workflowId, error as Error);
496
+ throw error;
497
+ }
498
+ }
499
+ ```
500
+
501
+ ## Best Practices
502
+
503
+ 1. **Track All Workflows**: Start tracking at the beginning of every workflow
504
+ 2. **Estimate Tokens**: Use TokenCounter for accurate cost estimation
505
+ 3. **Custom Metrics**: Track domain-specific metrics relevant to your use case
506
+ 4. **Export Regularly**: Export metrics to files or observability platforms
507
+ 5. **Monitor Costs**: Set up alerts for unusual cost spikes
508
+ 6. **Performance Profiling**: Use PerformanceProfiler for bottleneck identification
509
+ 7. **History Retention**: Clear old metrics periodically to save memory
510
+ 8. **Aggregate Data**: Use aggregation for trend analysis
511
+
512
+ ## Performance Profiling Example
513
+
514
+ ```typescript
515
+ const profiler = new PerformanceProfiler();
516
+ const tracker = MetricsBuilder.create().withTokenTracking().build();
517
+
518
+ tracker.start('workflow-1');
519
+ profiler.mark('start');
520
+
521
+ // Phase 1: Data loading
522
+ profiler.mark('loading-start');
523
+ await loadData();
524
+ profiler.mark('loading-end');
525
+ const loadTime = profiler.measure('loading', 'loading-start', 'loading-end');
526
+
527
+ // Phase 2: Processing
528
+ profiler.mark('processing-start');
529
+ await processData();
530
+ profiler.mark('processing-end');
531
+ const processTime = profiler.measure('processing', 'processing-start', 'processing-end');
532
+
533
+ // Phase 3: Generation
534
+ profiler.mark('generation-start');
535
+ await generateOutput();
536
+ profiler.mark('generation-end');
537
+ const genTime = profiler.measure('generation', 'generation-start', 'generation-end');
538
+
539
+ profiler.mark('end');
540
+ const totalTime = profiler.measure('total', 'start', 'end');
541
+
542
+ tracker.addCustomMetric('workflow-1', 'load_time', loadTime);
543
+ tracker.addCustomMetric('workflow-1', 'process_time', processTime);
544
+ tracker.addCustomMetric('workflow-1', 'gen_time', genTime);
545
+
546
+ const snapshot = tracker.end('workflow-1');
547
+
548
+ console.log('Performance breakdown:');
549
+ console.log(`Loading: ${loadTime}ms (${((loadTime / totalTime) * 100).toFixed(1)}%)`);
550
+ console.log(`Processing: ${processTime}ms (${((processTime / totalTime) * 100).toFixed(1)}%)`);
551
+ console.log(`Generation: ${genTime}ms (${((genTime / totalTime) * 100).toFixed(1)}%)`);
552
+ console.log(`Total: ${totalTime}ms`);
553
+ ```
554
+
555
+ ## Next Steps
556
+
557
+ - See [Graph Execution](./graph-execution.md) for workflow tracking
558
+ - See [Tool Calling](./tool-calling.md) for tool usage metrics
559
+ - See [Memory System](./memory-system.md) for context tracking
560
+ - See [Examples](./examples.md) for complete implementations