- Add intelligent-router.sh hook for automatic agent routing - Add AUTO-TRIGGER-SUMMARY.md documentation - Add FINAL-INTEGRATION-SUMMARY.md documentation - Complete Prometheus integration (6 commands + 4 tools) - Complete Dexto integration (12 commands + 5 tools) - Enhanced Ralph with access to all agents - Fix /clawd command (removed disable-model-invocation) - Update hooks.json to v5 with intelligent routing - 291 total skills now available - All 21 commands with automatic routing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
b52318eeae
·
2026-01-28 00:27:56 +04:00
History
Telemetry Module
OpenTelemetry distributed tracing for Dexto agent operations.
What It Does
- Traces execution flow across DextoAgent, LLM services, and tool operations
- Captures token usage for all LLM calls (input/output/total tokens)
- Exports to OTLP-compatible backends (Jaeger, Grafana, etc.)
- Zero overhead when disabled - all instrumentation is opt-in
Architecture
Decorator-Based Instrumentation
Uses @InstrumentClass decorator on critical execution paths:
DextoAgent- Top-level orchestratorVercelLLMService- LLM operations (all providers via Vercel AI SDK)ToolManager- Tool execution
Not decorated (following selective instrumentation strategy):
- Low-level services (MCPManager, SessionManager, PluginManager)
- Storage/memory operations (ResourceManager, MemoryManager)
Initialization
Telemetry is initialized in createAgentServices() before any decorated classes are instantiated:
// packages/core/src/utils/service-initializer.ts
if (config.telemetry?.enabled) {
await Telemetry.init(config.telemetry);
}
Agent Switching
For sequential agent switching, telemetry is shut down before creating the new agent:
// packages/cli/src/api/server.ts
await Telemetry.shutdownGlobal(); // Old telemetry
newAgent = await getDexto().createAgent(agentId); // Fresh telemetry
Configuration
Enable in your agent config:
# agents/my-agent.yml
telemetry:
enabled: true
serviceName: my-dexto-agent
tracerName: dexto-tracer
export:
type: otlp
protocol: http
endpoint: http://localhost:4318/v1/traces
Testing with Jaeger
1. Start Jaeger
docker run -d \
--name jaeger \
-p 16686:16686 \
-p 4318:4318 \
jaegertracing/all-in-one:latest
Ports:
16686- Jaeger UI (web interface)4318- OTLP HTTP receiver (where Dexto sends traces)
2. Enable Telemetry
Telemetry is already enabled in agents/default-agent.yml. To disable, set enabled: false.
3. Run Dexto webUI
# Run in CLI mode
pnpm run dev
4. Generate Traces
Send messages through CLI or WebUI to generate traces.
5. View Traces
- Open Jaeger UI: http://localhost:16686
- Select service:
dexto-default-agent - Click "Find Traces"
- Select an operation:
agent.run
6. Verify Trace Structure
Click on a trace to see the span hierarchy:
agent.run (20.95s total)
├─ agent.maybeGenerateTitle (14.99ms)
└─ llm.vercel.completeTask (20.93s)
└─ llm.vercel.streamText (20.92s)
├─ POST https://api.openai.com/... (10.01s) ← HTTP auto-instrumentation
└─ POST https://api.openai.com/... (10.79s) ← HTTP auto-instrumentation
What to verify:
- ✅ Span names use correct prefixes (
agent.,llm.vercel.) - ✅ Span hierarchy shows parent-child relationships
- ✅ HTTP auto-instrumentation captures API calls
- ✅ Token usage attributes:
gen_ai.usage.input_tokens,gen_ai.usage.output_tokens - ✅ No errors in console logs
7. Cleanup
docker stop jaeger
docker rm jaeger
Module Structure
telemetry/
├── README.md # This file
├── telemetry.ts # Core Telemetry class, SDK initialization
├── decorators.ts # @InstrumentClass decorator implementation
├── schemas.ts # Zod schemas for telemetry config
├── types.ts # TypeScript types for spans and traces
├── exporters.ts # CompositeExporter for multi-destination support
└── utils.ts # Helper functions
Key Files
telemetry.ts
Telemetry.init(config)- Initialize OpenTelemetry SDKTelemetry.shutdownGlobal()- Shutdown for agent switchingTelemetry.get()- Get initialized instance
decorators.ts
@InstrumentClass(options)- Decorator for automatic tracingwithSpan(spanName, fn, options)- Manual span creation
exporters.ts
CompositeExporter- Multi-destination exporting with recursive telemetry filtering
Adding Telemetry to New Modules
Use the @InstrumentClass decorator on classes in critical execution paths:
import { InstrumentClass } from '../telemetry/decorators.js';
@InstrumentClass({
prefix: 'mymodule', // Span prefix: mymodule.methodName
excludeMethods: ['helper'] // Methods to skip
})
export class MyModule {
async process(data: string): Promise<void> {
// Span automatically created: "mymodule.process"
// Add custom attributes to active span:
const span = trace.getActiveSpan();
if (span) {
span.setAttribute('data.length', data.length);
}
}
}
Troubleshooting
No traces appearing in Jaeger?
- Verify Jaeger is running:
docker ps | grep jaeger - Check endpoint in agent config:
http://localhost:4318/v1/traces - Check console for "Telemetry initialized" log
- Verify
enabled: truein telemetry config
Only seeing HTTP GET/POST spans?
- These are from OpenTelemetry's automatic HTTP instrumentation (expected!)
- Filter by Operation:
agent.runto see decorated spans - Click into a trace to see the full hierarchy
Build errors?
- Run
pnpm installif dependencies are missing - Ensure you're on the
telemetrybranch
Further Documentation
- Full feature plan:
/feature-plans/telemetry.md - Configuration options: See
schemas.ts - OpenTelemetry docs: https://opentelemetry.io/docs/