@traccia2/sdk 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/LICENSE +23 -0
- package/README.md +503 -0
- package/dist/auto.d.ts +27 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +171 -0
- package/dist/auto.js.map +1 -0
- package/dist/config/env-config.d.ts +21 -0
- package/dist/config/env-config.d.ts.map +1 -0
- package/dist/config/env-config.js +111 -0
- package/dist/config/env-config.js.map +1 -0
- package/dist/config/pricing-config.d.ts +27 -0
- package/dist/config/pricing-config.d.ts.map +1 -0
- package/dist/config/pricing-config.js +74 -0
- package/dist/config/pricing-config.js.map +1 -0
- package/dist/config/runtime-config.d.ts +65 -0
- package/dist/config/runtime-config.d.ts.map +1 -0
- package/dist/config/runtime-config.js +97 -0
- package/dist/config/runtime-config.js.map +1 -0
- package/dist/context/context.d.ts +29 -0
- package/dist/context/context.d.ts.map +1 -0
- package/dist/context/context.js +48 -0
- package/dist/context/context.js.map +1 -0
- package/dist/exporter/console-exporter.d.ts +18 -0
- package/dist/exporter/console-exporter.d.ts.map +1 -0
- package/dist/exporter/console-exporter.js +39 -0
- package/dist/exporter/console-exporter.js.map +1 -0
- package/dist/exporter/http-exporter.d.ts +57 -0
- package/dist/exporter/http-exporter.d.ts.map +1 -0
- package/dist/exporter/http-exporter.js +181 -0
- package/dist/exporter/http-exporter.js.map +1 -0
- package/dist/exporter/index.d.ts +7 -0
- package/dist/exporter/index.d.ts.map +1 -0
- package/dist/exporter/index.js +12 -0
- package/dist/exporter/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +16 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/langchain-callback.d.ts +72 -0
- package/dist/integrations/langchain-callback.d.ts.map +1 -0
- package/dist/integrations/langchain-callback.js +201 -0
- package/dist/integrations/langchain-callback.js.map +1 -0
- package/dist/integrations/langgraph-instrumentation.d.ts +57 -0
- package/dist/integrations/langgraph-instrumentation.d.ts.map +1 -0
- package/dist/integrations/langgraph-instrumentation.js +162 -0
- package/dist/integrations/langgraph-instrumentation.js.map +1 -0
- package/dist/processor/batch-processor.d.ts +68 -0
- package/dist/processor/batch-processor.d.ts.map +1 -0
- package/dist/processor/batch-processor.js +150 -0
- package/dist/processor/batch-processor.js.map +1 -0
- package/dist/processor/cost-processor.d.ts +16 -0
- package/dist/processor/cost-processor.d.ts.map +1 -0
- package/dist/processor/cost-processor.js +50 -0
- package/dist/processor/cost-processor.js.map +1 -0
- package/dist/processor/index.d.ts +9 -0
- package/dist/processor/index.d.ts.map +1 -0
- package/dist/processor/index.js +18 -0
- package/dist/processor/index.js.map +1 -0
- package/dist/processor/logging-processor.d.ts +13 -0
- package/dist/processor/logging-processor.d.ts.map +1 -0
- package/dist/processor/logging-processor.js +26 -0
- package/dist/processor/logging-processor.js.map +1 -0
- package/dist/processor/sampler.d.ts +20 -0
- package/dist/processor/sampler.d.ts.map +1 -0
- package/dist/processor/sampler.js +33 -0
- package/dist/processor/sampler.js.map +1 -0
- package/dist/processor/token-counter.d.ts +13 -0
- package/dist/processor/token-counter.d.ts.map +1 -0
- package/dist/processor/token-counter.js +40 -0
- package/dist/processor/token-counter.js.map +1 -0
- package/dist/tracer/index.d.ts +8 -0
- package/dist/tracer/index.d.ts.map +1 -0
- package/dist/tracer/index.js +15 -0
- package/dist/tracer/index.js.map +1 -0
- package/dist/tracer/provider.d.ts +59 -0
- package/dist/tracer/provider.d.ts.map +1 -0
- package/dist/tracer/provider.js +114 -0
- package/dist/tracer/provider.js.map +1 -0
- package/dist/tracer/span-context.d.ts +23 -0
- package/dist/tracer/span-context.d.ts.map +1 -0
- package/dist/tracer/span-context.js +34 -0
- package/dist/tracer/span-context.js.map +1 -0
- package/dist/tracer/span.d.ts +49 -0
- package/dist/tracer/span.d.ts.map +1 -0
- package/dist/tracer/span.js +118 -0
- package/dist/tracer/span.js.map +1 -0
- package/dist/tracer/tracer.d.ts +28 -0
- package/dist/tracer/tracer.d.ts.map +1 -0
- package/dist/tracer/tracer.js +75 -0
- package/dist/tracer/tracer.js.map +1 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/package.json +79 -0
- package/src/__tests__/exporter.test.ts +62 -0
- package/src/__tests__/integrations-langchain.test.ts +384 -0
- package/src/__tests__/integrations-langgraph.test.ts +479 -0
- package/src/__tests__/processor.test.ts +89 -0
- package/src/__tests__/span.test.ts +103 -0
- package/src/__tests__/tracer.test.ts +89 -0
- package/src/auto.ts +198 -0
- package/src/config/env-config.ts +93 -0
- package/src/config/pricing-config.ts +84 -0
- package/src/config/runtime-config.ts +108 -0
- package/src/context/context.ts +52 -0
- package/src/exporter/console-exporter.ts +38 -0
- package/src/exporter/http-exporter.ts +188 -0
- package/src/exporter/index.ts +7 -0
- package/src/index.ts +51 -0
- package/src/integrations/README.md +287 -0
- package/src/integrations/index.ts +13 -0
- package/src/integrations/langchain-callback.ts +229 -0
- package/src/integrations/langgraph-instrumentation.ts +174 -0
- package/src/processor/batch-processor.ts +180 -0
- package/src/processor/cost-processor.ts +57 -0
- package/src/processor/index.ts +9 -0
- package/src/processor/logging-processor.ts +26 -0
- package/src/processor/sampler.ts +35 -0
- package/src/processor/token-counter.ts +42 -0
- package/src/tracer/index.ts +8 -0
- package/src/tracer/provider.ts +130 -0
- package/src/tracer/span-context.ts +46 -0
- package/src/tracer/span.ts +145 -0
- package/src/tracer/tracer.ts +100 -0
- package/src/types.ts +155 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Exporter for sending spans to a backend service.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as https from 'https';
|
|
6
|
+
import * as http from 'http';
|
|
7
|
+
import { ISpan, ISpanExporter } from '../types';
|
|
8
|
+
|
|
9
|
+
export const DEFAULT_ENDPOINT = 'https://api.dashboard.com/api/v1/traces';
|
|
10
|
+
|
|
11
|
+
const TRANSIENT_STATUS_CODES = new Set([429, 503, 504]);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* HTTP Exporter configuration.
|
|
15
|
+
*/
|
|
16
|
+
export interface HttpExporterOptions {
|
|
17
|
+
endpoint?: string;
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
timeout?: number;
|
|
20
|
+
maxRetries?: number;
|
|
21
|
+
backoffBase?: number;
|
|
22
|
+
backoffJitter?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* HTTP Exporter for sending spans to a backend.
|
|
27
|
+
*/
|
|
28
|
+
export class HttpExporter implements ISpanExporter {
|
|
29
|
+
private endpoint: string;
|
|
30
|
+
private apiKey?: string;
|
|
31
|
+
private timeout: number;
|
|
32
|
+
private maxRetries: number;
|
|
33
|
+
private backoffBase: number;
|
|
34
|
+
private backoffJitter: number;
|
|
35
|
+
|
|
36
|
+
constructor(options: HttpExporterOptions = {}) {
|
|
37
|
+
this.endpoint = options.endpoint || DEFAULT_ENDPOINT;
|
|
38
|
+
this.apiKey = options.apiKey;
|
|
39
|
+
this.timeout = options.timeout || 10000;
|
|
40
|
+
this.maxRetries = options.maxRetries || 5;
|
|
41
|
+
this.backoffBase = options.backoffBase || 1;
|
|
42
|
+
this.backoffJitter = options.backoffJitter || 0.5;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Export spans to the backend.
|
|
47
|
+
*/
|
|
48
|
+
async export(spans: ISpan[]): Promise<boolean> {
|
|
49
|
+
if (spans.length === 0) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const payload = this.serializeSpans(spans);
|
|
54
|
+
const headers = this.getHeaders();
|
|
55
|
+
|
|
56
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
57
|
+
try {
|
|
58
|
+
const status = await this.sendRequest(payload, headers);
|
|
59
|
+
|
|
60
|
+
if (status >= 200 && status < 300) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!TRANSIENT_STATUS_CODES.has(status)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const backoff = this.computeBackoff(attempt);
|
|
69
|
+
await this.sleep(backoff);
|
|
70
|
+
} catch {
|
|
71
|
+
// Treat transport errors as transient
|
|
72
|
+
if (attempt < this.maxRetries - 1) {
|
|
73
|
+
const backoff = this.computeBackoff(attempt);
|
|
74
|
+
await this.sleep(backoff);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Shutdown the exporter.
|
|
84
|
+
*/
|
|
85
|
+
async shutdown(): Promise<void> {
|
|
86
|
+
// No-op for HTTP exporter
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Serialize spans to JSON bytes.
|
|
91
|
+
*/
|
|
92
|
+
private serializeSpans(spans: ISpan[]): string {
|
|
93
|
+
const serialized = spans.map((span) => ({
|
|
94
|
+
traceId: span.context.traceId,
|
|
95
|
+
spanId: span.context.spanId,
|
|
96
|
+
parentSpanId: span.parentSpanId,
|
|
97
|
+
name: span.name,
|
|
98
|
+
startTimeNs: span.startTimeNs,
|
|
99
|
+
endTimeNs: span.endTimeNs,
|
|
100
|
+
durationNs: span.durationNs,
|
|
101
|
+
attributes: span.attributes,
|
|
102
|
+
events: span.events,
|
|
103
|
+
status: span.status,
|
|
104
|
+
statusDescription: span.statusDescription,
|
|
105
|
+
traceFlags: span.context.traceFlags,
|
|
106
|
+
traceState: span.context.traceState,
|
|
107
|
+
}));
|
|
108
|
+
|
|
109
|
+
return JSON.stringify(serialized);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get request headers.
|
|
114
|
+
*/
|
|
115
|
+
private getHeaders(): Record<string, string> {
|
|
116
|
+
const headers: Record<string, string> = {
|
|
117
|
+
'Content-Type': 'application/json',
|
|
118
|
+
'User-Agent': 'traccia-sdk-ts/1.0.0',
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (this.apiKey) {
|
|
122
|
+
headers['Authorization'] = `Bearer ${this.apiKey}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return headers;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Send HTTP request.
|
|
130
|
+
*/
|
|
131
|
+
private sendRequest(payload: string, headers: Record<string, string>): Promise<number> {
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
const url = new URL(this.endpoint);
|
|
134
|
+
const isHttps = url.protocol === 'https:';
|
|
135
|
+
const client = isHttps ? https : http;
|
|
136
|
+
|
|
137
|
+
const options = {
|
|
138
|
+
hostname: url.hostname,
|
|
139
|
+
port: url.port,
|
|
140
|
+
path: url.pathname + url.search,
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: {
|
|
143
|
+
...headers,
|
|
144
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
145
|
+
},
|
|
146
|
+
timeout: this.timeout,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const request = client.request(options, (response) => {
|
|
150
|
+
response.on('data', () => {
|
|
151
|
+
// Consume data but don't store
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
response.on('end', () => {
|
|
155
|
+
resolve(response.statusCode || 500);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
request.on('error', (error) => {
|
|
160
|
+
reject(error);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
request.on('timeout', () => {
|
|
164
|
+
request.destroy();
|
|
165
|
+
reject(new Error('Request timeout'));
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
request.write(payload);
|
|
169
|
+
request.end();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Compute exponential backoff with jitter.
|
|
175
|
+
*/
|
|
176
|
+
private computeBackoff(attempt: number): number {
|
|
177
|
+
const exponential = this.backoffBase * Math.pow(2, attempt);
|
|
178
|
+
const jitter = Math.random() * this.backoffJitter;
|
|
179
|
+
return (exponential + jitter) * 1000;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Sleep for a given number of milliseconds.
|
|
184
|
+
*/
|
|
185
|
+
private sleep(ms: number): Promise<void> {
|
|
186
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
187
|
+
}
|
|
188
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main SDK entry point.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
getTracer,
|
|
7
|
+
getTracerProvider,
|
|
8
|
+
setTracerProvider,
|
|
9
|
+
startTracing,
|
|
10
|
+
stopTracing,
|
|
11
|
+
} from './auto';
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
TracerProvider,
|
|
15
|
+
Tracer,
|
|
16
|
+
Span,
|
|
17
|
+
SpanContext,
|
|
18
|
+
} from './tracer';
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
HttpExporter,
|
|
22
|
+
ConsoleExporter,
|
|
23
|
+
} from './exporter';
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
Sampler,
|
|
27
|
+
BatchSpanProcessor,
|
|
28
|
+
TokenCountingProcessor,
|
|
29
|
+
CostAnnotatingProcessor,
|
|
30
|
+
LoggingSpanProcessor,
|
|
31
|
+
} from './processor';
|
|
32
|
+
|
|
33
|
+
export type {
|
|
34
|
+
ISpan,
|
|
35
|
+
ITracer,
|
|
36
|
+
ITracerProvider,
|
|
37
|
+
ISpanContext,
|
|
38
|
+
ISpanProcessor,
|
|
39
|
+
ISpanExporter,
|
|
40
|
+
ISampler,
|
|
41
|
+
SDKConfig,
|
|
42
|
+
Resource,
|
|
43
|
+
SpanEvent,
|
|
44
|
+
SamplingResult,
|
|
45
|
+
} from './types';
|
|
46
|
+
|
|
47
|
+
export { SpanStatus } from './types';
|
|
48
|
+
|
|
49
|
+
// Integrations (optional)
|
|
50
|
+
// Import from '@traccia/sdk/integrations' for framework-specific integrations
|
|
51
|
+
// See src/integrations/README.md for documentation
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Traccia SDK Integrations
|
|
2
|
+
|
|
3
|
+
Automatic instrumentation for popular frameworks and libraries. These integrations seamlessly add tracing to your applications without changing your code.
|
|
4
|
+
|
|
5
|
+
## Available Integrations
|
|
6
|
+
|
|
7
|
+
### LangChain Integration
|
|
8
|
+
|
|
9
|
+
Automatically trace LangChain agents, chains, and tools without any code changes.
|
|
10
|
+
|
|
11
|
+
#### Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install langchain @traccia/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
#### Usage
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { ChatOpenAI } from 'langchain/chat_models/openai';
|
|
21
|
+
import { AgentExecutor, createOpenAIToolsAgent } from 'langchain/agents';
|
|
22
|
+
import { Tool } from '@langchain/core/tools';
|
|
23
|
+
import { TraciaCallbackHandler } from '@traccia/sdk/integrations/langchain-callback';
|
|
24
|
+
|
|
25
|
+
// Create your agent as usual
|
|
26
|
+
const tools = [/* your tools */];
|
|
27
|
+
const llm = new ChatOpenAI({ modelName: 'gpt-4' });
|
|
28
|
+
|
|
29
|
+
// Create Traccia callback handler
|
|
30
|
+
const traciaHandler = new TraciaCallbackHandler();
|
|
31
|
+
|
|
32
|
+
// Add callback to your chain/agent
|
|
33
|
+
const agent = await createOpenAIToolsAgent({ llm, tools, callbacks: [traciaHandler] });
|
|
34
|
+
const executor = new AgentExecutor({ agent, tools, callbacks: [traciaHandler] });
|
|
35
|
+
|
|
36
|
+
// Use as normal - fully traced!
|
|
37
|
+
const result = await executor.invoke({ input: 'What is 2+2?' });
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Automatic Tracing Features
|
|
41
|
+
|
|
42
|
+
- **LLM Calls**: Captures model name, prompt length, completion tokens, total tokens
|
|
43
|
+
- **Chain Execution**: Traces chain start/end with chain name and execution time
|
|
44
|
+
- **Tool Usage**: Records tool invocations, inputs, and outputs
|
|
45
|
+
- **Agent Actions**: Captures agent decisions and reasoning steps
|
|
46
|
+
- **Error Handling**: Records exceptions and failures with full context
|
|
47
|
+
- **Nested Execution**: Automatically handles nested chains and tool calls through runId hierarchy
|
|
48
|
+
|
|
49
|
+
#### Span Hierarchy
|
|
50
|
+
|
|
51
|
+
Spans are automatically organized in a hierarchy:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
agent-executor (root)
|
|
55
|
+
├── chain-1 (input processing)
|
|
56
|
+
│ └── llm-call (model inference)
|
|
57
|
+
├── tool-1 (tool execution)
|
|
58
|
+
│ └── api-call
|
|
59
|
+
└── chain-2 (final processing)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### LangGraph Integration
|
|
63
|
+
|
|
64
|
+
Automatic instrumentation for LangGraph state graphs and node execution.
|
|
65
|
+
|
|
66
|
+
#### Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install langraph @traccia/sdk
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Usage - Option 1: Instrument Graph
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { StateGraph } from '@langchain/langgraph';
|
|
76
|
+
import { instrumentLangGraph } from '@traccia/sdk/integrations/langgraph';
|
|
77
|
+
|
|
78
|
+
const graph = new StateGraph(AgentState)
|
|
79
|
+
.addNode('agent', agentNode)
|
|
80
|
+
.addNode('tools', toolsNode)
|
|
81
|
+
.addEdge('agent', 'tools');
|
|
82
|
+
|
|
83
|
+
// Instrument for automatic tracing
|
|
84
|
+
const instrumentedGraph = instrumentLangGraph(graph, {
|
|
85
|
+
graphName: 'my-agent-graph',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const compiled = instrumentedGraph.compile();
|
|
89
|
+
|
|
90
|
+
// Automatically traced!
|
|
91
|
+
await compiled.invoke({ messages: [] });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Usage - Option 2: Trace Individual Nodes
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { createTracedNode } from '@traccia/sdk/integrations/langgraph';
|
|
98
|
+
|
|
99
|
+
const agentNode = createTracedNode('agent', async (state) => {
|
|
100
|
+
// Your agent logic
|
|
101
|
+
return { messages: [...state.messages, response] };
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const toolsNode = createTracedNode('tools', async (state) => {
|
|
105
|
+
// Your tool logic
|
|
106
|
+
return { messages: [...state.messages, results] };
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const graph = new StateGraph(AgentState)
|
|
110
|
+
.addNode('agent', agentNode)
|
|
111
|
+
.addNode('tools', toolsNode);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Usage - Option 3: Trace Conditionals
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { createTracedConditional } from '@traccia/sdk/integrations/langgraph';
|
|
118
|
+
|
|
119
|
+
const shouldContinue = createTracedConditional('should_continue', (state) => {
|
|
120
|
+
const messages = state.messages;
|
|
121
|
+
if (messages[messages.length - 1].tool_calls) {
|
|
122
|
+
return 'tools';
|
|
123
|
+
}
|
|
124
|
+
return 'end';
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
graph.addConditionalEdges('agent', shouldContinue);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Automatic Tracing Features
|
|
131
|
+
|
|
132
|
+
- **Graph Execution**: Root span for entire graph invocation
|
|
133
|
+
- **Streaming**: Traces streaming calls with event counts
|
|
134
|
+
- **Node Execution**: Individual spans for each node with execution context
|
|
135
|
+
- **Conditionals**: Records conditional routing decisions
|
|
136
|
+
- **Thread Context**: Captures thread_id for multi-turn conversations
|
|
137
|
+
- **Error Handling**: Records failures at any level with full stack traces
|
|
138
|
+
|
|
139
|
+
#### Span Hierarchy
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
langgraph-invoke (root)
|
|
143
|
+
├── node:agent
|
|
144
|
+
├── condition:should_continue
|
|
145
|
+
└── node:tools
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
Both integrations respect the standard Traccia SDK configuration through environment variables:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Enable tracing
|
|
154
|
+
AGENT_DASHBOARD_ENABLED=true
|
|
155
|
+
|
|
156
|
+
# Set API endpoint and key (if using HTTP exporter)
|
|
157
|
+
AGENT_DASHBOARD_API_ENDPOINT=http://localhost:3000
|
|
158
|
+
AGENT_DASHBOARD_API_KEY=your-key
|
|
159
|
+
|
|
160
|
+
# Sampling and processing
|
|
161
|
+
AGENT_DASHBOARD_SAMPLE_RATE=1.0
|
|
162
|
+
AGENT_DASHBOARD_BATCH_SIZE=10
|
|
163
|
+
AGENT_DASHBOARD_BATCH_INTERVAL_MS=5000
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
See [Configuration Guide](../README.md#configuration) for all options.
|
|
167
|
+
|
|
168
|
+
## Error Handling
|
|
169
|
+
|
|
170
|
+
All integrations implement graceful error handling:
|
|
171
|
+
|
|
172
|
+
- Integration errors don't crash your application
|
|
173
|
+
- Failed spans are silently dropped if span system has issues
|
|
174
|
+
- Exceptions are recorded to spans with full context
|
|
175
|
+
- Stream/async processing continues on errors
|
|
176
|
+
|
|
177
|
+
## Performance Considerations
|
|
178
|
+
|
|
179
|
+
### Overhead
|
|
180
|
+
|
|
181
|
+
- **LangChain**: ~1-2ms per span creation (async, non-blocking)
|
|
182
|
+
- **LangGraph**: ~2-3ms per node execution overhead
|
|
183
|
+
- **Network**: Async batch export (configurable delays)
|
|
184
|
+
|
|
185
|
+
### Optimization Tips
|
|
186
|
+
|
|
187
|
+
1. **Increase Batch Size** for high-throughput apps:
|
|
188
|
+
```bash
|
|
189
|
+
AGENT_DASHBOARD_BATCH_SIZE=100
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
2. **Use Sampling** to reduce data volume:
|
|
193
|
+
```bash
|
|
194
|
+
AGENT_DASHBOARD_SAMPLE_RATE=0.1 # 10% sampling
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
3. **Disable Cost Tracking** if not needed:
|
|
198
|
+
```bash
|
|
199
|
+
AGENT_DASHBOARD_ENABLE_COST_TRACKING=false
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
4. **Use Console Exporter** for development:
|
|
203
|
+
```typescript
|
|
204
|
+
import { ConsoleExporter } from '@traccia/sdk';
|
|
205
|
+
// No network overhead
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Testing
|
|
209
|
+
|
|
210
|
+
When testing applications with integrations, consider:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { ConsoleExporter } from '@traccia/sdk';
|
|
214
|
+
import { startTracing } from '@traccia/sdk';
|
|
215
|
+
|
|
216
|
+
// In test setup
|
|
217
|
+
startTracing({
|
|
218
|
+
exporters: [new ConsoleExporter()], // Avoid network calls
|
|
219
|
+
enableTokenCounting: false, // Skip token count overhead
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Your tests run with tracing enabled but no external calls
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Best Practices
|
|
226
|
+
|
|
227
|
+
1. **Initialize Before Creating Tools/Agents**:
|
|
228
|
+
```typescript
|
|
229
|
+
// ✅ Good
|
|
230
|
+
startTracing({ /* config */ });
|
|
231
|
+
const llm = new ChatOpenAI();
|
|
232
|
+
const handler = new TraciaCallbackHandler();
|
|
233
|
+
|
|
234
|
+
// ❌ Avoid
|
|
235
|
+
const llm = new ChatOpenAI();
|
|
236
|
+
startTracing();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
2. **Reuse Handler Instances**:
|
|
240
|
+
```typescript
|
|
241
|
+
// ✅ Good - one handler for all chains
|
|
242
|
+
const handler = new TraciaCallbackHandler();
|
|
243
|
+
const executor1 = new AgentExecutor({ callbacks: [handler] });
|
|
244
|
+
const executor2 = new AgentExecutor({ callbacks: [handler] });
|
|
245
|
+
|
|
246
|
+
// ❌ Avoid - new handler for each (more overhead)
|
|
247
|
+
const executor1 = new AgentExecutor({ callbacks: [new TraciaCallbackHandler()] });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
3. **Use Graph Instrumentation Over Node Wrapping** (when possible):
|
|
251
|
+
```typescript
|
|
252
|
+
// ✅ Good - cleaner API
|
|
253
|
+
const graph = instrumentLangGraph(graph);
|
|
254
|
+
|
|
255
|
+
// ✅ Also good - when you need fine-grained control
|
|
256
|
+
const agentNode = createTracedNode('agent', func);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
4. **Capture Domain-Specific Attributes**:
|
|
260
|
+
```typescript
|
|
261
|
+
// Extend with custom metadata
|
|
262
|
+
const handler = new TraciaCallbackHandler();
|
|
263
|
+
// (Future: custom span enrichment support)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Limitations & Known Issues
|
|
267
|
+
|
|
268
|
+
- **LangChain**: Requires langchain ≥ 0.1.0 (callback system)
|
|
269
|
+
- **LangGraph**: Works with compiled graphs; streaming has event-level tracking
|
|
270
|
+
- **Context Propagation**: Traces are linked through runId hierarchy; distributed tracing requires parent trace context
|
|
271
|
+
|
|
272
|
+
## Contributing
|
|
273
|
+
|
|
274
|
+
To add new integrations:
|
|
275
|
+
|
|
276
|
+
1. Create `src/integrations/{framework}-instrumentation.ts`
|
|
277
|
+
2. Export in `src/integrations/index.ts`
|
|
278
|
+
3. Add usage documentation here
|
|
279
|
+
4. Submit PR with tests and examples
|
|
280
|
+
|
|
281
|
+
## Support
|
|
282
|
+
|
|
283
|
+
For issues or questions:
|
|
284
|
+
|
|
285
|
+
- 📖 [Main README](../README.md)
|
|
286
|
+
- 🐛 [GitHub Issues](https://github.com/stratumtech/traccia-sdk)
|
|
287
|
+
- 💬 [Discussions](https://github.com/stratumtech/traccia-sdk/discussions)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traccia SDK Integrations
|
|
3
|
+
* Provides automatic instrumentation for popular frameworks and libraries.
|
|
4
|
+
*
|
|
5
|
+
* @module integrations
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { TraciaCallbackHandler } from './langchain-callback';
|
|
9
|
+
export {
|
|
10
|
+
instrumentLangGraph,
|
|
11
|
+
createTracedNode,
|
|
12
|
+
createTracedConditional,
|
|
13
|
+
} from './langgraph-instrumentation';
|