trodo-node 1.1.0 → 2.1.0

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 (68) hide show
  1. package/README.md +340 -103
  2. package/dist/cjs/TrodoClient.js +77 -19
  3. package/dist/cjs/TrodoClient.js.map +1 -1
  4. package/dist/cjs/api/ApiClient.js +21 -3
  5. package/dist/cjs/api/ApiClient.js.map +1 -1
  6. package/dist/cjs/api/endpoints.js +7 -1
  7. package/dist/cjs/api/endpoints.js.map +1 -1
  8. package/dist/cjs/index.js +104 -8
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/otel/autoInstrument.js +253 -0
  11. package/dist/cjs/otel/autoInstrument.js.map +1 -0
  12. package/dist/cjs/otel/context.js +49 -0
  13. package/dist/cjs/otel/context.js.map +1 -0
  14. package/dist/cjs/otel/helpers.js +254 -0
  15. package/dist/cjs/otel/helpers.js.map +1 -0
  16. package/dist/cjs/otel/processor.js +129 -0
  17. package/dist/cjs/otel/processor.js.map +1 -0
  18. package/dist/cjs/otel/uuid.js +24 -0
  19. package/dist/cjs/otel/uuid.js.map +1 -0
  20. package/dist/cjs/otel/wrapAgent.js +399 -0
  21. package/dist/cjs/otel/wrapAgent.js.map +1 -0
  22. package/dist/cjs/queue/BatchFlusher.js +1 -1
  23. package/dist/cjs/queue/BatchFlusher.js.map +1 -1
  24. package/dist/esm/TrodoClient.d.ts +34 -1
  25. package/dist/esm/TrodoClient.d.ts.map +1 -1
  26. package/dist/esm/TrodoClient.js +77 -19
  27. package/dist/esm/TrodoClient.js.map +1 -1
  28. package/dist/esm/api/ApiClient.d.ts +9 -1
  29. package/dist/esm/api/ApiClient.d.ts.map +1 -1
  30. package/dist/esm/api/ApiClient.js +21 -3
  31. package/dist/esm/api/ApiClient.js.map +1 -1
  32. package/dist/esm/api/endpoints.d.ts +6 -1
  33. package/dist/esm/api/endpoints.d.ts.map +1 -1
  34. package/dist/esm/api/endpoints.js +7 -1
  35. package/dist/esm/api/endpoints.js.map +1 -1
  36. package/dist/esm/index.d.ts +84 -8
  37. package/dist/esm/index.d.ts.map +1 -1
  38. package/dist/esm/index.js +89 -7
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/otel/autoInstrument.d.ts +61 -0
  41. package/dist/esm/otel/autoInstrument.d.ts.map +1 -0
  42. package/dist/esm/otel/autoInstrument.js +248 -0
  43. package/dist/esm/otel/autoInstrument.js.map +1 -0
  44. package/dist/esm/otel/context.d.ts +26 -0
  45. package/dist/esm/otel/context.d.ts.map +1 -0
  46. package/dist/esm/otel/context.js +44 -0
  47. package/dist/esm/otel/context.js.map +1 -0
  48. package/dist/esm/otel/helpers.d.ts +119 -0
  49. package/dist/esm/otel/helpers.d.ts.map +1 -0
  50. package/dist/esm/otel/helpers.js +244 -0
  51. package/dist/esm/otel/helpers.js.map +1 -0
  52. package/dist/esm/otel/processor.d.ts +94 -0
  53. package/dist/esm/otel/processor.d.ts.map +1 -0
  54. package/dist/esm/otel/processor.js +125 -0
  55. package/dist/esm/otel/processor.js.map +1 -0
  56. package/dist/esm/otel/uuid.d.ts +7 -0
  57. package/dist/esm/otel/uuid.d.ts.map +1 -0
  58. package/dist/esm/otel/uuid.js +21 -0
  59. package/dist/esm/otel/uuid.js.map +1 -0
  60. package/dist/esm/otel/wrapAgent.d.ts +100 -0
  61. package/dist/esm/otel/wrapAgent.d.ts.map +1 -0
  62. package/dist/esm/otel/wrapAgent.js +389 -0
  63. package/dist/esm/otel/wrapAgent.js.map +1 -0
  64. package/dist/esm/queue/BatchFlusher.js +1 -1
  65. package/dist/esm/queue/BatchFlusher.js.map +1 -1
  66. package/dist/esm/types/index.d.ts +26 -0
  67. package/dist/esm/types/index.d.ts.map +1 -1
  68. package/package.json +1 -1
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Span helpers: `trace`, `tool`, `llm`, `retrieval` — typed function
3
+ * wrappers that auto-capture input/output/error. Plus `trackLlmCall` and
4
+ * Express middleware for cross-service run joining.
5
+ *
6
+ * These are the customer-facing surface for custom code: wrap once, get a
7
+ * span with args as input, return value as output, exception as error.
8
+ */
9
+ import { getActiveContext } from './context.js';
10
+ import { joinRun, withSpan, } from './wrapAgent.js';
11
+ function _input(args) {
12
+ if (args.length === 0)
13
+ return undefined;
14
+ if (args.length === 1)
15
+ return args[0];
16
+ return args;
17
+ }
18
+ function _wrap(name, fn, kind, options = {}, hooks) {
19
+ return async (...args) => {
20
+ return withSpan(undefined, name, async (span) => {
21
+ if (kind === 'tool')
22
+ span.setTool(name);
23
+ hooks?.onEnter?.(span);
24
+ const result = await fn(...args);
25
+ try {
26
+ hooks?.onResult?.(span, result);
27
+ }
28
+ catch {
29
+ /* never break user code */
30
+ }
31
+ span.setOutput(result);
32
+ return result;
33
+ }, { kind, input: _input(args), ...options });
34
+ };
35
+ }
36
+ export function tool(a, b) {
37
+ // name-first form: tool(name, fn)
38
+ if (typeof a === 'string' && typeof b === 'function') {
39
+ return _wrap(a, b, 'tool');
40
+ }
41
+ // fn-first form: tool(fn, options?)
42
+ const fn = a;
43
+ const options = (b || {});
44
+ const toolName = options.name || fn.name || 'anonymous-tool';
45
+ const kind = (options.kind || 'tool');
46
+ return _wrap(toolName, fn, kind);
47
+ }
48
+ /**
49
+ * Wrap a function as a generic span. Mirrors the uselemma `trace()` helper.
50
+ *
51
+ * const prepare = trodo.trace('prepare', async (input) => { ... });
52
+ */
53
+ export function trace(name, fn, options = {}) {
54
+ return _wrap(name, fn, 'generic', options);
55
+ }
56
+ /** Wrap a retriever / vector search as a kind='retrieval' span. */
57
+ export function retrieval(name, fn, options = {}) {
58
+ return _wrap(name, fn, 'retrieval', options);
59
+ }
60
+ function _defaultExtractUsage(result) {
61
+ if (!result || typeof result !== 'object')
62
+ return {};
63
+ const r = result;
64
+ // OpenAI / OpenAI-compat: { usage: { prompt_tokens, completion_tokens } }
65
+ const usage = r.usage;
66
+ if (usage) {
67
+ if ('prompt_tokens' in usage || 'completion_tokens' in usage) {
68
+ return {
69
+ inputTokens: usage.prompt_tokens,
70
+ outputTokens: usage.completion_tokens,
71
+ };
72
+ }
73
+ // Anthropic: { usage: { input_tokens, output_tokens } }
74
+ if ('input_tokens' in usage || 'output_tokens' in usage) {
75
+ return {
76
+ inputTokens: usage.input_tokens,
77
+ outputTokens: usage.output_tokens,
78
+ };
79
+ }
80
+ }
81
+ // Gemini: { usageMetadata: { promptTokenCount, candidatesTokenCount } }
82
+ const meta = r.usageMetadata;
83
+ if (meta) {
84
+ return {
85
+ inputTokens: meta.promptTokenCount,
86
+ outputTokens: meta.candidatesTokenCount,
87
+ };
88
+ }
89
+ return {};
90
+ }
91
+ /**
92
+ * Wrap an LLM call — auto-extracts tokens from OpenAI/Anthropic/Gemini
93
+ * response shapes.
94
+ *
95
+ * const answer = trodo.llm('answer', callOpenAI, {
96
+ * model: 'gpt-4o-mini', provider: 'openai',
97
+ * });
98
+ */
99
+ export function llm(name, fn, options = {}) {
100
+ const { model, provider, temperature, extractUsage, ...rest } = options;
101
+ const extractor = extractUsage || _defaultExtractUsage;
102
+ return _wrap(name, fn, 'llm', rest, {
103
+ onEnter: (s) => {
104
+ if (model || provider || temperature !== undefined) {
105
+ s.setLlm({ model, provider, temperature });
106
+ }
107
+ },
108
+ onResult: (s, result) => {
109
+ const { inputTokens, outputTokens } = extractor(result);
110
+ if (inputTokens !== undefined || outputTokens !== undefined) {
111
+ s.setLlm({
112
+ model,
113
+ provider,
114
+ inputTokens,
115
+ outputTokens,
116
+ temperature,
117
+ });
118
+ }
119
+ },
120
+ });
121
+ }
122
+ /**
123
+ * Return a raw OTel tracer — the Trodo processor is already subscribed.
124
+ * Use for advanced cases where you want to emit spans with the raw OTel
125
+ * API; they flow through to Trodo like any other span.
126
+ */
127
+ export function getTracer(name = 'trodo') {
128
+ // Lazy import keeps @opentelemetry/api optional at runtime until used.
129
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
130
+ const api = require('@opentelemetry/api');
131
+ return api.trace.getTracer(name);
132
+ }
133
+ /**
134
+ * Record a one-shot LLM span for a raw-HTTP caller. Opens and immediately
135
+ * closes a span(kind='llm') populated with the model + token counts +
136
+ * prompt/completion. No-op outside an active run context.
137
+ *
138
+ * Usage:
139
+ * const resp = await fetch(url, { body: JSON.stringify(body) }).then(r => r.json());
140
+ * await trodo.trackLlmCall({
141
+ * model: 'gemini-2.5-flash',
142
+ * provider: 'google',
143
+ * inputTokens: resp.usageMetadata.promptTokenCount,
144
+ * outputTokens: resp.usageMetadata.candidatesTokenCount,
145
+ * prompt: body,
146
+ * completion: resp,
147
+ * });
148
+ */
149
+ export async function trackLlmCall(params) {
150
+ if (!getActiveContext())
151
+ return;
152
+ const spanName = params.name || (params.model ? `llm.${params.provider}.${params.model}` : 'llm');
153
+ await withSpan(undefined, spanName, async (span) => {
154
+ span.setLlm({
155
+ model: params.model,
156
+ provider: params.provider,
157
+ inputTokens: params.inputTokens,
158
+ outputTokens: params.outputTokens,
159
+ cost: params.cost,
160
+ temperature: params.temperature,
161
+ });
162
+ if (params.completion !== undefined) {
163
+ span.setOutput(params.completion);
164
+ }
165
+ }, {
166
+ kind: 'llm',
167
+ input: params.prompt,
168
+ attributes: params.metadata,
169
+ });
170
+ }
171
+ // ---------------------------------------------------------------------------
172
+ // Express / Connect middleware for automatic cross-service run joining
173
+ // ---------------------------------------------------------------------------
174
+ const TRODO_RUN_HEADER = 'x-trodo-run-id';
175
+ const TRODO_PARENT_SPAN_HEADER = 'x-trodo-parent-span-id';
176
+ const TRODO_AGENT_HEADER = 'x-trodo-agent-name';
177
+ /**
178
+ * Return an Express/Connect middleware that auto-joins inbound runs.
179
+ *
180
+ * If the inbound request has X-Trodo-Run-Id, every span created while
181
+ * handling the request nests under the caller's run. Otherwise the
182
+ * handler runs with no active context (no-op tracking).
183
+ *
184
+ * Usage:
185
+ * import express from 'express';
186
+ * import trodo from 'trodo-node';
187
+ * trodo.init({ siteId: '...' });
188
+ * const app = express();
189
+ * app.use(trodo.expressMiddleware());
190
+ */
191
+ export function expressMiddleware(deps) {
192
+ const { processor, teamSiteId } = deps;
193
+ return (req, res, next) => {
194
+ const headers = req.headers || {};
195
+ const getHeader = (name) => {
196
+ const raw = headers[name] ?? headers[name.toLowerCase()];
197
+ if (!raw)
198
+ return undefined;
199
+ return Array.isArray(raw) ? raw[0] : raw;
200
+ };
201
+ const runId = getHeader(TRODO_RUN_HEADER);
202
+ if (!runId) {
203
+ next();
204
+ return;
205
+ }
206
+ const parentSpanId = getHeader(TRODO_PARENT_SPAN_HEADER) || null;
207
+ const agentHeader = getHeader(TRODO_AGENT_HEADER);
208
+ const name = agentHeader ||
209
+ `http.${(req.method || 'GET').toUpperCase()}.${req.path || req.url || ''}`;
210
+ const input = {
211
+ method: req.method,
212
+ path: req.path || req.url || req.originalUrl,
213
+ };
214
+ joinRun(processor, teamSiteId, runId, parentSpanId, async (span) => {
215
+ await new Promise((resolve) => {
216
+ if (res.on) {
217
+ res.on('finish', () => {
218
+ span.setOutput({ status_code: res.statusCode });
219
+ resolve();
220
+ });
221
+ res.on('close', () => resolve());
222
+ }
223
+ next();
224
+ });
225
+ }, { name, kind: 'agent', input }).catch(() => {
226
+ /* swallow — SDK never throws into user code */
227
+ });
228
+ };
229
+ }
230
+ /**
231
+ * Return HTTP headers carrying the current run/span context. Use when
232
+ * making outbound HTTP calls to downstream services so they can joinRun
233
+ * instead of creating their own runs.
234
+ */
235
+ export function propagationHeaders() {
236
+ const ctx = getActiveContext();
237
+ if (!ctx)
238
+ return {};
239
+ const headers = { 'X-Trodo-Run-Id': ctx.runId };
240
+ if (ctx.spanId)
241
+ headers['X-Trodo-Parent-Span-Id'] = ctx.spanId;
242
+ return headers;
243
+ }
244
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/otel/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,OAAO,EACP,QAAQ,GAGT,MAAM,gBAAgB,CAAC;AAUxB,SAAS,MAAM,CAAC,IAAe;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,KAAK,CACZ,IAAY,EACZ,EAAkB,EAClB,IAA8C,EAC9C,UAA2B,EAAE,EAC7B,KAGC;IAED,OAAO,KAAK,EAAE,GAAG,IAAU,EAAc,EAAE;QACzC,OAAO,QAAQ,CACb,SAA0C,EAC1C,IAAI,EACJ,KAAK,EAAE,IAAgB,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACxC,KAAK,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;YACvB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YACjC,IAAI,CAAC;gBACH,KAAK,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,2BAA2B;YAC7B,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC,EACD,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,CAC1C,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAmBD,MAAM,UAAU,IAAI,CAClB,CAA0B,EAC1B,CAAgC;IAEhC,kCAAkC;IAClC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,UAAU,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,oCAAoC;IACpC,MAAM,EAAE,GAAG,CAAmB,CAAC;IAC/B,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAgB,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,gBAAgB,CAAC;IAC7D,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAqC,CAAC;IAC1E,OAAO,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CACnB,IAAY,EACZ,EAAkB,EAClB,UAA2B,EAAE;IAE7B,OAAO,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,EAAkB,EAClB,UAA2B,EAAE;IAE7B,OAAO,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AASD,SAAS,oBAAoB,CAC3B,MAAe;IAEf,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,CAAC,GAAG,MAAiC,CAAC;IAC5C,0EAA0E;IAC1E,MAAM,KAAK,GAAG,CAAC,CAAC,KAA4C,CAAC;IAC7D,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,eAAe,IAAI,KAAK,IAAI,mBAAmB,IAAI,KAAK,EAAE,CAAC;YAC7D,OAAO;gBACL,WAAW,EAAE,KAAK,CAAC,aAAmC;gBACtD,YAAY,EAAE,KAAK,CAAC,iBAAuC;aAC5D,CAAC;QACJ,CAAC;QACD,wDAAwD;QACxD,IAAI,cAAc,IAAI,KAAK,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;YACxD,OAAO;gBACL,WAAW,EAAE,KAAK,CAAC,YAAkC;gBACrD,YAAY,EAAE,KAAK,CAAC,aAAmC;aACxD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,wEAAwE;IACxE,MAAM,IAAI,GAAG,CAAC,CAAC,aAAoD,CAAC;IACpE,IAAI,IAAI,EAAE,CAAC;QACT,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,gBAAsC;YACxD,YAAY,EAAE,IAAI,CAAC,oBAA0C;SAC9D,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CACjB,IAAY,EACZ,EAAkB,EAClB,UAAsB,EAAE;IAExB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACxE,MAAM,SAAS,GAAG,YAAY,IAAI,oBAAoB,CAAC;IACvD,OAAO,KAAK,CAAU,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QAC3C,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACb,IAAI,KAAK,IAAI,QAAQ,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBACnD,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YACtB,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YACxD,IAAI,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC5D,CAAC,CAAC,MAAM,CAAC;oBACP,KAAK;oBACL,QAAQ;oBACR,WAAW;oBACX,YAAY;oBACZ,WAAW;iBACZ,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAI,GAAG,OAAO;IACtC,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1C,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAeD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA0B;IAC3D,IAAI,CAAC,gBAAgB,EAAE;QAAE,OAAO;IAChC,MAAM,QAAQ,GACZ,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,MAAM,QAAQ,CACZ,SAA0C,EAC1C,QAAQ,EACR,KAAK,EAAE,IAAgB,EAAE,EAAE;QACzB,IAAI,CAAC,MAAM,CAAC;YACV,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,UAAU,EAAE,MAAM,CAAC,QAAQ;KAC5B,CACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAC1C,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAqBhD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA2B;IAE3B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,GAAe,EAAE,GAAe,EAAE,IAAY,EAAQ,EAAE;QAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAsB,EAAE;YACrD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG;gBAAE,OAAO,SAAS,CAAC;YAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC3C,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,MAAM,YAAY,GAAG,SAAS,CAAC,wBAAwB,CAAC,IAAI,IAAI,CAAC;QACjE,MAAM,WAAW,GAAG,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAClD,MAAM,IAAI,GACR,WAAW;YACX,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC;QAE7E,MAAM,KAAK,GAAG;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW;SAC7C,CAAC;QAEF,OAAO,CACL,SAAS,EACT,UAAU,EACV,KAAK,EACL,YAAY,EACZ,KAAK,EAAE,IAAI,EAAE,EAAE;YACb,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;oBACX,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;wBACpB,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;wBAChD,OAAO,EAAE,CAAC;oBACZ,CAAC,CAAC,CAAC;oBACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBACnC,CAAC;gBACD,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACL,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAC/B,CAAC,KAAK,CAAC,GAAG,EAAE;YACX,+CAA+C;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,OAAO,GAA2B,EAAE,gBAAgB,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;IACxE,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAC/D,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * TrodoSpanProcessor — buffers completed spans and ships them to the Trodo
3
+ * backend in batches.
4
+ *
5
+ * Shape is compatible with OpenTelemetry's SpanProcessor (onStart / onEnd /
6
+ * shutdown / forceFlush) so users can register it with the OTel NodeSDK and
7
+ * have auto-instrumented spans (Anthropic/OpenAI/Vercel AI SDK/LangChain)
8
+ * flow through it into Trodo.
9
+ *
10
+ * Without a real OTel SDK, our wrapAgent/withSpan helpers call onStart/onEnd
11
+ * directly — so the processor handles both paths uniformly.
12
+ */
13
+ import type { ApiClient } from '../api/ApiClient.js';
14
+ export interface TrodoSpan {
15
+ span_id: string;
16
+ run_id: string;
17
+ parent_span_id: string | null;
18
+ kind: 'llm' | 'tool' | 'agent' | 'retrieval' | 'generic';
19
+ name: string;
20
+ status: 'ok' | 'error';
21
+ started_at: string;
22
+ ended_at?: string;
23
+ duration_ms?: number;
24
+ input?: string;
25
+ output?: string;
26
+ error_type?: string;
27
+ error_message?: string;
28
+ model?: string;
29
+ provider?: string;
30
+ input_tokens?: number;
31
+ output_tokens?: number;
32
+ cost?: number;
33
+ temperature?: number;
34
+ tool_name?: string;
35
+ attributes?: Record<string, unknown>;
36
+ }
37
+ export interface TrodoRun {
38
+ run_id: string;
39
+ agent_name: string;
40
+ distinct_id?: string | null;
41
+ conversation_id?: string | null;
42
+ parent_run_id?: string | null;
43
+ status: 'running' | 'ok' | 'error';
44
+ input?: string;
45
+ output?: string;
46
+ error_summary?: string;
47
+ started_at: string;
48
+ ended_at?: string;
49
+ duration_ms?: number;
50
+ metadata?: Record<string, unknown>;
51
+ attributes?: Record<string, unknown>;
52
+ total_tokens_in?: number;
53
+ total_tokens_out?: number;
54
+ total_cost?: number;
55
+ span_count?: number;
56
+ tool_count?: number;
57
+ error_count?: number;
58
+ }
59
+ export interface ProcessorOptions {
60
+ apiClient: ApiClient;
61
+ maxBatchSize?: number;
62
+ flushIntervalMs?: number;
63
+ maxSpansPerRun?: number;
64
+ }
65
+ export declare class TrodoSpanProcessor {
66
+ private readonly apiClient;
67
+ private readonly maxBatchSize;
68
+ private readonly flushIntervalMs;
69
+ private readonly maxSpansPerRun;
70
+ private queue;
71
+ private pendingByRun;
72
+ private joinedRuns;
73
+ private timer;
74
+ private stopped;
75
+ constructor(opts: ProcessorOptions);
76
+ private startTimer;
77
+ /** Mark a run as joined — its spans flush immediately via append_spans. */
78
+ markJoined(runId: string): void;
79
+ unmarkJoined(runId: string): void;
80
+ /** Read (without removing) the buffered spans for a run — used for run aggregation. */
81
+ getPending(runId: string): TrodoSpan[];
82
+ /** Buffer a span for async flush. Called by wrapAgent/withSpan + OTel onEnd. */
83
+ enqueueSpan(span: TrodoSpan): void;
84
+ /** Stream spans for a long-running or joined run without finalising. */
85
+ appendSpans(runId: string, spans: TrodoSpan[]): Promise<void>;
86
+ /** Fire-and-forget run+spans ingest, used when wrapAgent finalises. */
87
+ ingestRun(run: TrodoRun): Promise<void>;
88
+ private flushSpans;
89
+ forceFlush(): Promise<void>;
90
+ shutdown(): Promise<void>;
91
+ onStart(): void;
92
+ onEnd(span: TrodoSpan): void;
93
+ }
94
+ //# sourceMappingURL=processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../../src/otel/processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ export class TrodoSpanProcessor {
2
+ constructor(opts) {
3
+ this.queue = [];
4
+ this.pendingByRun = new Map();
5
+ this.joinedRuns = new Set();
6
+ this.timer = null;
7
+ this.stopped = false;
8
+ this.apiClient = opts.apiClient;
9
+ this.maxBatchSize = opts.maxBatchSize ?? 64;
10
+ this.flushIntervalMs = opts.flushIntervalMs ?? 2000;
11
+ this.maxSpansPerRun = opts.maxSpansPerRun ?? 1000;
12
+ this.startTimer();
13
+ }
14
+ startTimer() {
15
+ if (this.timer || this.stopped)
16
+ return;
17
+ this.timer = setInterval(() => {
18
+ this.flushSpans().catch(() => { });
19
+ }, this.flushIntervalMs);
20
+ // Don't block Node from exiting because of our timer.
21
+ if (this.timer && typeof this.timer.unref === 'function') {
22
+ this.timer.unref();
23
+ }
24
+ }
25
+ /** Mark a run as joined — its spans flush immediately via append_spans. */
26
+ markJoined(runId) {
27
+ this.joinedRuns.add(runId);
28
+ }
29
+ unmarkJoined(runId) {
30
+ this.joinedRuns.delete(runId);
31
+ this.pendingByRun.delete(runId);
32
+ }
33
+ /** Read (without removing) the buffered spans for a run — used for run aggregation. */
34
+ getPending(runId) {
35
+ return (this.pendingByRun.get(runId) || []).slice();
36
+ }
37
+ /** Buffer a span for async flush. Called by wrapAgent/withSpan + OTel onEnd. */
38
+ enqueueSpan(span) {
39
+ if (this.joinedRuns.has(span.run_id)) {
40
+ // Owning service is remote — forward each span immediately.
41
+ this.apiClient
42
+ .postSpansAppend(span.run_id, [span])
43
+ .catch(() => { });
44
+ return;
45
+ }
46
+ this.queue.push(span);
47
+ const runBuf = this.pendingByRun.get(span.run_id) || [];
48
+ if (runBuf.length < this.maxSpansPerRun) {
49
+ runBuf.push(span);
50
+ this.pendingByRun.set(span.run_id, runBuf);
51
+ }
52
+ if (this.queue.length >= this.maxBatchSize) {
53
+ this.flushSpans().catch(() => { });
54
+ }
55
+ }
56
+ /** Stream spans for a long-running or joined run without finalising. */
57
+ async appendSpans(runId, spans) {
58
+ if (!spans.length)
59
+ return;
60
+ try {
61
+ await this.apiClient.postSpansAppend(runId, spans);
62
+ }
63
+ catch {
64
+ /* silent */
65
+ }
66
+ }
67
+ /** Fire-and-forget run+spans ingest, used when wrapAgent finalises. */
68
+ async ingestRun(run) {
69
+ const spans = this.pendingByRun.get(run.run_id) || [];
70
+ this.pendingByRun.delete(run.run_id);
71
+ this.queue = this.queue.filter((s) => s.run_id !== run.run_id);
72
+ try {
73
+ await this.apiClient.postRunIngest({
74
+ run: run,
75
+ spans: spans,
76
+ });
77
+ }
78
+ catch {
79
+ /* silent — SDK must never throw into user code */
80
+ }
81
+ }
82
+ async flushSpans() {
83
+ if (this.queue.length === 0)
84
+ return;
85
+ const batch = this.queue.splice(0, this.maxBatchSize);
86
+ // Group pending-only spans by run_id and POST to /runs/:run_id/spans.
87
+ const byRun = new Map();
88
+ for (const span of batch) {
89
+ const arr = byRun.get(span.run_id) || [];
90
+ arr.push(span);
91
+ byRun.set(span.run_id, arr);
92
+ }
93
+ const tasks = [];
94
+ for (const [runId, spans] of byRun.entries()) {
95
+ tasks.push(this.apiClient
96
+ .postSpansAppend(runId, spans)
97
+ .catch(() => {
98
+ // Re-queue for next tick on failure.
99
+ this.queue.push(...spans);
100
+ }));
101
+ }
102
+ await Promise.all(tasks);
103
+ }
104
+ async forceFlush() {
105
+ await this.flushSpans();
106
+ }
107
+ async shutdown() {
108
+ this.stopped = true;
109
+ if (this.timer) {
110
+ clearInterval(this.timer);
111
+ this.timer = null;
112
+ }
113
+ await this.forceFlush();
114
+ }
115
+ // ---------- OpenTelemetry SpanProcessor interface (subset) ----------
116
+ // Implemented so this can be registered with OTel SDK's addSpanProcessor().
117
+ // A thin adapter is in autoInstrument.ts.
118
+ onStart() {
119
+ /* noop — Trodo flushes on span end */
120
+ }
121
+ onEnd(span) {
122
+ this.enqueueSpan(span);
123
+ }
124
+ }
125
+ //# sourceMappingURL=processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.js","sourceRoot":"","sources":["../../../src/otel/processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * RFC4122 v4 UUIDs — used for run_id, span_id, parent_span_id.
3
+ * Uses the runtime's crypto.randomUUID when available, falls back to a
4
+ * Math.random-based generator so we don't pull in a dependency for tests.
5
+ */
6
+ export declare function uuidv4(): string;
7
+ //# sourceMappingURL=uuid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../../../src/otel/uuid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAY/B"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * RFC4122 v4 UUIDs — used for run_id, span_id, parent_span_id.
3
+ * Uses the runtime's crypto.randomUUID when available, falls back to a
4
+ * Math.random-based generator so we don't pull in a dependency for tests.
5
+ */
6
+ export function uuidv4() {
7
+ try {
8
+ const c = globalThis.crypto;
9
+ if (c?.randomUUID)
10
+ return c.randomUUID();
11
+ }
12
+ catch {
13
+ /* fall through */
14
+ }
15
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {
16
+ const r = (Math.random() * 16) | 0;
17
+ const v = ch === 'x' ? r : (r & 0x3) | 0x8;
18
+ return v.toString(16);
19
+ });
20
+ }
21
+ //# sourceMappingURL=uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../../src/otel/uuid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC;QACH,MAAM,CAAC,GAAI,UAAyD,CAAC,MAAM,CAAC;QAC5E,IAAI,CAAC,EAAE,UAAU;YAAE,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IACD,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;QACpE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC3C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,100 @@
1
+ import type { TrodoSpanProcessor, TrodoSpan } from './processor.js';
2
+ export interface WrapAgentOptions {
3
+ distinctId?: string | null;
4
+ conversationId?: string | null;
5
+ parentRunId?: string | null;
6
+ metadata?: Record<string, unknown>;
7
+ }
8
+ export interface WrapAgentResult<R> {
9
+ result: R;
10
+ runId: string;
11
+ }
12
+ export interface WithSpanOptions {
13
+ kind?: TrodoSpan['kind'];
14
+ input?: unknown;
15
+ attributes?: Record<string, unknown>;
16
+ }
17
+ export interface JoinRunOptions {
18
+ name?: string;
19
+ kind?: TrodoSpan['kind'];
20
+ input?: unknown;
21
+ attributes?: Record<string, unknown>;
22
+ }
23
+ /** Return the currently active run_id, if any. */
24
+ export declare function currentRunId(): string | null;
25
+ /** Return the currently active span_id, if any. */
26
+ export declare function currentSpanId(): string | null;
27
+ /**
28
+ * RunHandle — returned by wrapAgent so callers can set input/output after
29
+ * inspecting the arguments / result. Mirrors the Python RunHandle API.
30
+ */
31
+ export declare class RunHandle {
32
+ readonly runId: string;
33
+ readonly agentName: string;
34
+ input?: string;
35
+ output?: string;
36
+ metadata: Record<string, unknown>;
37
+ constructor(runId: string, agentName: string);
38
+ setInput(value: unknown): void;
39
+ setOutput(value: unknown): void;
40
+ setMetadata(extra: Record<string, unknown>): void;
41
+ }
42
+ /**
43
+ * SpanHandle — returned by withSpan / joinRun. Collect LLM model/token/cost
44
+ * info and tool name here; the processor picks them up at span close.
45
+ */
46
+ export declare class SpanHandle {
47
+ readonly spanId: string;
48
+ readonly name: string;
49
+ input?: string;
50
+ output?: string;
51
+ attributes: Record<string, unknown>;
52
+ model?: string;
53
+ provider?: string;
54
+ inputTokens?: number;
55
+ outputTokens?: number;
56
+ cost?: number;
57
+ temperature?: number;
58
+ toolName?: string;
59
+ constructor(spanId: string, name: string);
60
+ setInput(value: unknown): void;
61
+ setOutput(value: unknown): void;
62
+ setAttribute(key: string, value: unknown): void;
63
+ setLlm(opts: {
64
+ model?: string;
65
+ provider?: string;
66
+ inputTokens?: number;
67
+ outputTokens?: number;
68
+ cost?: number;
69
+ temperature?: number;
70
+ }): void;
71
+ setTool(name: string): void;
72
+ }
73
+ /**
74
+ * Wrap an async function as an agent run. Every OTel span (or withSpan call)
75
+ * created inside `fn` is auto-nested under the run via AsyncLocalStorage.
76
+ *
77
+ * The callback receives a RunHandle so it can call `handle.setInput(...)` /
78
+ * `handle.setOutput(...)`. Old-style callbacks (no arg) still work.
79
+ */
80
+ export declare function wrapAgent<R>(processor: TrodoSpanProcessor, teamSiteId: string, agentName: string, fn: (handle: RunHandle) => Promise<R> | R, options?: WrapAgentOptions): Promise<WrapAgentResult<R>>;
81
+ /**
82
+ * Create a nested span for non-auto-instrumented work (KB lookups, custom
83
+ * tools, computation). Requires an enclosing wrapAgent/joinRun.
84
+ *
85
+ * The callback receives a SpanHandle so the caller can record LLM tokens /
86
+ * tool name / output inside the function body.
87
+ */
88
+ export declare function withSpan<R>(_processor: TrodoSpanProcessor, name: string, fn: (handle: SpanHandle) => Promise<R> | R, options?: WithSpanOptions): Promise<R>;
89
+ /**
90
+ * Join an existing agent run owned by a remote service. Opens a SPAN (not a
91
+ * run) under ``parentSpanId``; every span produced inside ``fn`` — including
92
+ * OTel auto-instrumented LLM spans — flushes to the backend as a child of
93
+ * the caller's run via append_spans. We never ingest a run here.
94
+ *
95
+ * Typical use: Express/FastAPI middleware detects ``X-Trodo-Run-Id`` +
96
+ * ``X-Trodo-Parent-Span-Id`` on an inbound request and wraps the handler
97
+ * with joinRun so the handler's work nests under the caller's run.
98
+ */
99
+ export declare function joinRun<R>(processor: TrodoSpanProcessor, teamSiteId: string, runId: string, parentSpanId: string | null, fn: (handle: SpanHandle) => Promise<R> | R, options?: JoinRunOptions): Promise<R>;
100
+ //# sourceMappingURL=wrapAgent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapAgent.d.ts","sourceRoot":"","sources":["../../../src/otel/wrapAgent.ts"],"names":[],"mappings":"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"}