@grafana/sigil-sdk-js 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 (110) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +367 -0
  3. package/dist/client.d.ts +102 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +1502 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/config.d.ts +9 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +190 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/content_capture.d.ts +35 -0
  12. package/dist/content_capture.d.ts.map +1 -0
  13. package/dist/content_capture.js +123 -0
  14. package/dist/content_capture.js.map +1 -0
  15. package/dist/context.d.ts +11 -0
  16. package/dist/context.d.ts.map +1 -0
  17. package/dist/context.js +53 -0
  18. package/dist/context.js.map +1 -0
  19. package/dist/exporters/default.d.ts +3 -0
  20. package/dist/exporters/default.d.ts.map +1 -0
  21. package/dist/exporters/default.js +34 -0
  22. package/dist/exporters/default.js.map +1 -0
  23. package/dist/exporters/grpc.d.ts +14 -0
  24. package/dist/exporters/grpc.d.ts.map +1 -0
  25. package/dist/exporters/grpc.js +369 -0
  26. package/dist/exporters/grpc.js.map +1 -0
  27. package/dist/exporters/http.d.ts +8 -0
  28. package/dist/exporters/http.d.ts.map +1 -0
  29. package/dist/exporters/http.js +258 -0
  30. package/dist/exporters/http.js.map +1 -0
  31. package/dist/frameworks/google-adk/index.d.ts +136 -0
  32. package/dist/frameworks/google-adk/index.d.ts.map +1 -0
  33. package/dist/frameworks/google-adk/index.js +509 -0
  34. package/dist/frameworks/google-adk/index.js.map +1 -0
  35. package/dist/frameworks/langchain/index.d.ts +29 -0
  36. package/dist/frameworks/langchain/index.d.ts.map +1 -0
  37. package/dist/frameworks/langchain/index.js +70 -0
  38. package/dist/frameworks/langchain/index.js.map +1 -0
  39. package/dist/frameworks/langgraph/index.d.ts +29 -0
  40. package/dist/frameworks/langgraph/index.d.ts.map +1 -0
  41. package/dist/frameworks/langgraph/index.js +70 -0
  42. package/dist/frameworks/langgraph/index.js.map +1 -0
  43. package/dist/frameworks/llamaindex/index.d.ts +43 -0
  44. package/dist/frameworks/llamaindex/index.d.ts.map +1 -0
  45. package/dist/frameworks/llamaindex/index.js +493 -0
  46. package/dist/frameworks/llamaindex/index.js.map +1 -0
  47. package/dist/frameworks/openai-agents/index.d.ts +33 -0
  48. package/dist/frameworks/openai-agents/index.d.ts.map +1 -0
  49. package/dist/frameworks/openai-agents/index.js +531 -0
  50. package/dist/frameworks/openai-agents/index.js.map +1 -0
  51. package/dist/frameworks/shared.d.ts +57 -0
  52. package/dist/frameworks/shared.d.ts.map +1 -0
  53. package/dist/frameworks/shared.js +1032 -0
  54. package/dist/frameworks/shared.js.map +1 -0
  55. package/dist/frameworks/vercel-ai-sdk/hooks.d.ts +18 -0
  56. package/dist/frameworks/vercel-ai-sdk/hooks.d.ts.map +1 -0
  57. package/dist/frameworks/vercel-ai-sdk/hooks.js +672 -0
  58. package/dist/frameworks/vercel-ai-sdk/hooks.js.map +1 -0
  59. package/dist/frameworks/vercel-ai-sdk/index.d.ts +8 -0
  60. package/dist/frameworks/vercel-ai-sdk/index.d.ts.map +1 -0
  61. package/dist/frameworks/vercel-ai-sdk/index.js +7 -0
  62. package/dist/frameworks/vercel-ai-sdk/index.js.map +1 -0
  63. package/dist/frameworks/vercel-ai-sdk/mapping.d.ts +49 -0
  64. package/dist/frameworks/vercel-ai-sdk/mapping.d.ts.map +1 -0
  65. package/dist/frameworks/vercel-ai-sdk/mapping.js +660 -0
  66. package/dist/frameworks/vercel-ai-sdk/mapping.js.map +1 -0
  67. package/dist/frameworks/vercel-ai-sdk/types.d.ts +126 -0
  68. package/dist/frameworks/vercel-ai-sdk/types.d.ts.map +1 -0
  69. package/dist/frameworks/vercel-ai-sdk/types.js +2 -0
  70. package/dist/frameworks/vercel-ai-sdk/types.js.map +1 -0
  71. package/dist/index.d.ts +12 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +12 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/providers/anthropic.d.ts +35 -0
  76. package/dist/providers/anthropic.d.ts.map +1 -0
  77. package/dist/providers/anthropic.js +581 -0
  78. package/dist/providers/anthropic.js.map +1 -0
  79. package/dist/providers/gemini.d.ts +42 -0
  80. package/dist/providers/gemini.d.ts.map +1 -0
  81. package/dist/providers/gemini.js +650 -0
  82. package/dist/providers/gemini.js.map +1 -0
  83. package/dist/providers/openai.d.ts +67 -0
  84. package/dist/providers/openai.d.ts.map +1 -0
  85. package/dist/providers/openai.js +1007 -0
  86. package/dist/providers/openai.js.map +1 -0
  87. package/dist/types.d.ts +461 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +2 -0
  90. package/dist/types.js.map +1 -0
  91. package/dist/utils.d.ts +25 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +331 -0
  94. package/dist/utils.js.map +1 -0
  95. package/docs/frameworks/google-adk.md +84 -0
  96. package/docs/frameworks/langchain.md +102 -0
  97. package/docs/frameworks/langgraph.md +137 -0
  98. package/docs/frameworks/llamaindex.md +82 -0
  99. package/docs/frameworks/openai-agents.md +88 -0
  100. package/docs/frameworks/vercel-ai-sdk.md +124 -0
  101. package/docs/index.md +22 -0
  102. package/docs/providers/anthropic.md +69 -0
  103. package/docs/providers/gemini.md +86 -0
  104. package/docs/providers/openai.md +151 -0
  105. package/package.json +80 -0
  106. package/proto/opentelemetry/proto/collector/trace/v1/trace_service.proto +77 -0
  107. package/proto/opentelemetry/proto/common/v1/common.proto +115 -0
  108. package/proto/opentelemetry/proto/resource/v1/resource.proto +44 -0
  109. package/proto/opentelemetry/proto/trace/v1/trace.proto +357 -0
  110. package/proto/sigil/v1/generation_ingest.proto +145 -0
@@ -0,0 +1,1032 @@
1
+ import { SpanKind, SpanStatusCode, trace } from '@opentelemetry/api';
2
+ const frameworkInstrumentationName = 'github.com/grafana/sigil/sdks/js/frameworks';
3
+ const spanAttrOperationName = 'gen_ai.operation.name';
4
+ const spanAttrConversationID = 'gen_ai.conversation.id';
5
+ const spanAttrFrameworkName = 'sigil.framework.name';
6
+ const spanAttrFrameworkSource = 'sigil.framework.source';
7
+ const spanAttrFrameworkLanguage = 'sigil.framework.language';
8
+ const spanAttrFrameworkRunID = 'sigil.framework.run_id';
9
+ const spanAttrFrameworkThreadID = 'sigil.framework.thread_id';
10
+ const spanAttrFrameworkParentRunID = 'sigil.framework.parent_run_id';
11
+ const spanAttrFrameworkComponentName = 'sigil.framework.component_name';
12
+ const spanAttrFrameworkRunType = 'sigil.framework.run_type';
13
+ const spanAttrFrameworkTags = 'sigil.framework.tags';
14
+ const spanAttrFrameworkRetryAttempt = 'sigil.framework.retry_attempt';
15
+ const spanAttrFrameworkLangGraphNode = 'sigil.framework.langgraph.node';
16
+ const spanAttrFrameworkEventID = 'sigil.framework.event_id';
17
+ const spanAttrErrorType = 'error.type';
18
+ const spanAttrErrorCategory = 'error.category';
19
+ const frameworkSource = 'handler';
20
+ const maxFrameworkMetadataDepth = 5;
21
+ export class SigilFrameworkHandler {
22
+ client;
23
+ frameworkName;
24
+ frameworkLanguage;
25
+ runs = new Map();
26
+ toolRuns = new Map();
27
+ chainSpans = new Map();
28
+ retrieverSpans = new Map();
29
+ agentName;
30
+ agentVersion;
31
+ providerResolver;
32
+ provider;
33
+ captureInputs;
34
+ captureOutputs;
35
+ extraTags;
36
+ extraMetadata;
37
+ constructor(client, frameworkName, frameworkLanguage, options = {}) {
38
+ this.client = client;
39
+ this.frameworkName = frameworkName;
40
+ this.frameworkLanguage = frameworkLanguage;
41
+ this.agentName = options.agentName;
42
+ this.agentVersion = options.agentVersion;
43
+ this.providerResolver = options.providerResolver ?? 'auto';
44
+ this.provider = options.provider;
45
+ this.captureInputs = options.captureInputs ?? true;
46
+ this.captureOutputs = options.captureOutputs ?? true;
47
+ this.extraTags = { ...(options.extraTags ?? {}) };
48
+ this.extraMetadata = { ...(options.extraMetadata ?? {}) };
49
+ }
50
+ onLLMStart(serialized, prompts, runId, parentRunId, extraParams, callbackTags, callbackMetadata, runName) {
51
+ const runKey = String(runId);
52
+ if (runKey.length === 0 || this.runs.has(runKey)) {
53
+ return;
54
+ }
55
+ const invocationParams = asRecord(extraParams?.invocation_params);
56
+ const modelName = resolveModelName(serialized, invocationParams);
57
+ const provider = resolveProvider(this.provider, this.providerResolver, modelName, serialized, invocationParams);
58
+ const stream = isStreaming(invocationParams);
59
+ const input = this.captureInputs ? mapPromptInputs(prompts) : [];
60
+ const context = this.buildFrameworkContext({
61
+ runId: runKey,
62
+ parentRunId,
63
+ runType: 'llm',
64
+ runName,
65
+ serialized,
66
+ invocationParams,
67
+ extraParams,
68
+ callbackTags,
69
+ callbackMetadata,
70
+ });
71
+ const payload = this.startPayload(runKey, provider, modelName, context);
72
+ const recorder = stream ? this.client.startStreamingGeneration(payload) : this.client.startGeneration(payload);
73
+ this.runs.set(runKey, {
74
+ recorder,
75
+ input,
76
+ captureOutputs: this.captureOutputs,
77
+ outputChunks: [],
78
+ firstTokenRecorded: false,
79
+ });
80
+ }
81
+ onChatModelStart(serialized, messages, runId, parentRunId, extraParams, callbackTags, callbackMetadata, runName) {
82
+ const runKey = String(runId);
83
+ if (runKey.length === 0 || this.runs.has(runKey)) {
84
+ return;
85
+ }
86
+ const invocationParams = asRecord(extraParams?.invocation_params);
87
+ const modelName = resolveModelName(serialized, invocationParams);
88
+ const provider = resolveProvider(this.provider, this.providerResolver, modelName, serialized, invocationParams);
89
+ const stream = isStreaming(invocationParams);
90
+ const input = this.captureInputs ? mapChatInputs(messages) : [];
91
+ const context = this.buildFrameworkContext({
92
+ runId: runKey,
93
+ parentRunId,
94
+ runType: 'chat',
95
+ runName,
96
+ serialized,
97
+ invocationParams,
98
+ extraParams,
99
+ callbackTags,
100
+ callbackMetadata,
101
+ });
102
+ const payload = this.startPayload(runKey, provider, modelName, context);
103
+ const recorder = stream ? this.client.startStreamingGeneration(payload) : this.client.startGeneration(payload);
104
+ this.runs.set(runKey, {
105
+ recorder,
106
+ input,
107
+ captureOutputs: this.captureOutputs,
108
+ outputChunks: [],
109
+ firstTokenRecorded: false,
110
+ });
111
+ }
112
+ onLLMNewToken(token, runId) {
113
+ const runState = this.runs.get(String(runId));
114
+ if (runState === undefined) {
115
+ return;
116
+ }
117
+ if (typeof token !== 'string' || token.trim().length === 0) {
118
+ return;
119
+ }
120
+ if (runState.captureOutputs) {
121
+ runState.outputChunks.push(token);
122
+ }
123
+ if (!runState.firstTokenRecorded) {
124
+ runState.firstTokenRecorded = true;
125
+ runState.recorder.setFirstTokenAt(new Date());
126
+ }
127
+ }
128
+ onLLMEnd(output, runId) {
129
+ const runState = this.runs.get(String(runId));
130
+ if (runState === undefined) {
131
+ return;
132
+ }
133
+ this.runs.delete(String(runId));
134
+ try {
135
+ const llmOutput = asRecord(read(output, 'llm_output'));
136
+ const responseModel = asString(read(llmOutput, 'model_name'));
137
+ const stopReason = asString(read(llmOutput, 'finish_reason'));
138
+ const usage = mapUsage(read(llmOutput, 'token_usage'));
139
+ let mappedOutput;
140
+ if (runState.captureOutputs) {
141
+ mappedOutput = mapOutputMessages(output);
142
+ if ((mappedOutput?.length ?? 0) === 0 && runState.outputChunks.length > 0) {
143
+ mappedOutput = [{ role: 'assistant', content: runState.outputChunks.join('') }];
144
+ }
145
+ }
146
+ const result = {
147
+ input: runState.input,
148
+ output: mappedOutput,
149
+ usage,
150
+ responseModel: responseModel.length > 0 ? responseModel : undefined,
151
+ stopReason: stopReason.length > 0 ? stopReason : undefined,
152
+ };
153
+ runState.recorder.setResult(result);
154
+ }
155
+ finally {
156
+ runState.recorder.end();
157
+ }
158
+ const recorderError = runState.recorder.getError();
159
+ if (recorderError !== undefined) {
160
+ throw recorderError;
161
+ }
162
+ }
163
+ onLLMError(error, runId) {
164
+ const runState = this.runs.get(String(runId));
165
+ if (runState === undefined) {
166
+ return;
167
+ }
168
+ this.runs.delete(String(runId));
169
+ try {
170
+ runState.recorder.setCallError(error);
171
+ if (runState.captureOutputs && runState.outputChunks.length > 0) {
172
+ runState.recorder.setResult({
173
+ input: runState.input,
174
+ output: [{ role: 'assistant', content: runState.outputChunks.join('') }],
175
+ });
176
+ }
177
+ }
178
+ finally {
179
+ runState.recorder.end();
180
+ }
181
+ const recorderError = runState.recorder.getError();
182
+ if (recorderError !== undefined) {
183
+ throw recorderError;
184
+ }
185
+ }
186
+ onToolStart(serialized, input, runId, parentRunId, callbackTags, callbackMetadata, runName, extraParams) {
187
+ const runKey = String(runId);
188
+ if (runKey.length === 0 || this.toolRuns.has(runKey)) {
189
+ return;
190
+ }
191
+ const invocationParams = asRecord(extraParams?.invocation_params);
192
+ const context = this.buildFrameworkContext({
193
+ runId: runKey,
194
+ parentRunId,
195
+ runType: 'tool',
196
+ runName,
197
+ serialized,
198
+ invocationParams,
199
+ extraParams,
200
+ callbackTags,
201
+ callbackMetadata,
202
+ });
203
+ const toolName = resolveToolName(serialized, context.componentName);
204
+ const recorder = this.client.startToolExecution({
205
+ toolName,
206
+ toolDescription: resolveToolDescription(serialized),
207
+ conversationId: context.conversationId,
208
+ agentName: this.agentName,
209
+ agentVersion: this.agentVersion,
210
+ includeContent: this.captureInputs || this.captureOutputs,
211
+ });
212
+ this.toolRuns.set(runKey, {
213
+ recorder,
214
+ arguments: this.captureInputs ? resolveToolArguments(input, extraParams) : undefined,
215
+ captureOutputs: this.captureOutputs,
216
+ });
217
+ }
218
+ onToolEnd(output, runId) {
219
+ const runState = this.toolRuns.get(String(runId));
220
+ if (runState === undefined) {
221
+ return;
222
+ }
223
+ this.toolRuns.delete(String(runId));
224
+ try {
225
+ const result = {};
226
+ if (runState.arguments !== undefined) {
227
+ result.arguments = runState.arguments;
228
+ }
229
+ if (runState.captureOutputs) {
230
+ result.result = output;
231
+ }
232
+ runState.recorder.setResult(result);
233
+ }
234
+ finally {
235
+ runState.recorder.end();
236
+ }
237
+ const recorderError = runState.recorder.getError();
238
+ if (recorderError !== undefined) {
239
+ throw recorderError;
240
+ }
241
+ }
242
+ onToolError(error, runId) {
243
+ const runState = this.toolRuns.get(String(runId));
244
+ if (runState === undefined) {
245
+ return;
246
+ }
247
+ this.toolRuns.delete(String(runId));
248
+ try {
249
+ runState.recorder.setCallError(error);
250
+ }
251
+ finally {
252
+ runState.recorder.end();
253
+ }
254
+ const recorderError = runState.recorder.getError();
255
+ if (recorderError !== undefined) {
256
+ throw recorderError;
257
+ }
258
+ }
259
+ onChainStart(serialized, runId, parentRunId, callbackTags, callbackMetadata, callbackRunType, runName, extraParams) {
260
+ const runKey = String(runId);
261
+ if (runKey.length === 0 || this.chainSpans.has(runKey)) {
262
+ return;
263
+ }
264
+ const invocationParams = asRecord(extraParams?.invocation_params);
265
+ const context = this.buildFrameworkContext({
266
+ runId: runKey,
267
+ parentRunId,
268
+ runType: notEmpty(callbackRunType) ? String(callbackRunType).trim() : 'chain',
269
+ runName,
270
+ serialized,
271
+ invocationParams,
272
+ extraParams,
273
+ callbackTags,
274
+ callbackMetadata,
275
+ });
276
+ const spanName = notEmpty(context.componentName)
277
+ ? `${this.frameworkName}.chain ${context.componentName}`
278
+ : `${this.frameworkName}.chain`;
279
+ const span = this.getFrameworkTracer().startSpan(spanName, { kind: SpanKind.INTERNAL });
280
+ this.setFrameworkSpanAttributes(span, context, 'framework_chain');
281
+ this.chainSpans.set(runKey, span);
282
+ }
283
+ onChainEnd(runId) {
284
+ this.endFrameworkSpan(this.chainSpans, runId, undefined);
285
+ }
286
+ onChainError(error, runId) {
287
+ this.endFrameworkSpan(this.chainSpans, runId, error);
288
+ }
289
+ onRetrieverStart(serialized, runId, parentRunId, callbackTags, callbackMetadata, runName, extraParams) {
290
+ const runKey = String(runId);
291
+ if (runKey.length === 0 || this.retrieverSpans.has(runKey)) {
292
+ return;
293
+ }
294
+ const invocationParams = asRecord(extraParams?.invocation_params);
295
+ const context = this.buildFrameworkContext({
296
+ runId: runKey,
297
+ parentRunId,
298
+ runType: 'retriever',
299
+ runName,
300
+ serialized,
301
+ invocationParams,
302
+ extraParams,
303
+ callbackTags,
304
+ callbackMetadata,
305
+ });
306
+ const spanName = notEmpty(context.componentName)
307
+ ? `${this.frameworkName}.retriever ${context.componentName}`
308
+ : `${this.frameworkName}.retriever`;
309
+ const span = this.getFrameworkTracer().startSpan(spanName, { kind: SpanKind.INTERNAL });
310
+ this.setFrameworkSpanAttributes(span, context, 'framework_retriever');
311
+ this.retrieverSpans.set(runKey, span);
312
+ }
313
+ onRetrieverEnd(runId) {
314
+ this.endFrameworkSpan(this.retrieverSpans, runId, undefined);
315
+ }
316
+ onRetrieverError(error, runId) {
317
+ this.endFrameworkSpan(this.retrieverSpans, runId, error);
318
+ }
319
+ startPayload(_runId, provider, modelName, context) {
320
+ return {
321
+ conversationId: context.conversationId,
322
+ agentName: this.agentName,
323
+ agentVersion: this.agentVersion,
324
+ model: {
325
+ provider,
326
+ name: modelName,
327
+ },
328
+ tags: context.tags,
329
+ metadata: context.metadata,
330
+ };
331
+ }
332
+ getFrameworkTracer() {
333
+ const internalClient = this.client;
334
+ return internalClient.tracer ?? trace.getTracer(frameworkInstrumentationName);
335
+ }
336
+ setFrameworkSpanAttributes(span, context, operationName) {
337
+ span.setAttribute(spanAttrOperationName, operationName);
338
+ span.setAttribute(spanAttrFrameworkName, this.frameworkName);
339
+ span.setAttribute(spanAttrFrameworkSource, frameworkSource);
340
+ span.setAttribute(spanAttrFrameworkLanguage, this.frameworkLanguage);
341
+ span.setAttribute(spanAttrFrameworkRunID, asString(context.metadata[spanAttrFrameworkRunID]));
342
+ if (notEmpty(context.conversationId)) {
343
+ span.setAttribute(spanAttrConversationID, context.conversationId);
344
+ }
345
+ if (notEmpty(context.threadId)) {
346
+ span.setAttribute(spanAttrFrameworkThreadID, context.threadId);
347
+ }
348
+ if (notEmpty(context.parentRunId)) {
349
+ span.setAttribute(spanAttrFrameworkParentRunID, context.parentRunId);
350
+ }
351
+ if (notEmpty(context.componentName)) {
352
+ span.setAttribute(spanAttrFrameworkComponentName, context.componentName);
353
+ }
354
+ if (notEmpty(context.runType)) {
355
+ span.setAttribute(spanAttrFrameworkRunType, context.runType);
356
+ }
357
+ if (context.retryAttempt !== undefined) {
358
+ span.setAttribute(spanAttrFrameworkRetryAttempt, context.retryAttempt);
359
+ }
360
+ if (notEmpty(context.langgraphNode)) {
361
+ span.setAttribute(spanAttrFrameworkLangGraphNode, context.langgraphNode);
362
+ }
363
+ if (notEmpty(context.eventId)) {
364
+ span.setAttribute(spanAttrFrameworkEventID, context.eventId);
365
+ }
366
+ }
367
+ endFrameworkSpan(spans, runId, error) {
368
+ const runKey = String(runId);
369
+ const span = spans.get(runKey);
370
+ if (span === undefined) {
371
+ return;
372
+ }
373
+ spans.delete(runKey);
374
+ if (error === undefined) {
375
+ span.setStatus({ code: SpanStatusCode.OK });
376
+ span.end();
377
+ return;
378
+ }
379
+ span.setAttribute(spanAttrErrorType, 'framework_error');
380
+ span.setAttribute(spanAttrErrorCategory, 'sdk_error');
381
+ span.recordException(asError(error));
382
+ span.setStatus({ code: SpanStatusCode.ERROR, message: asError(error).message });
383
+ span.end();
384
+ }
385
+ buildFrameworkContext(params) {
386
+ const conversation = resolveFrameworkConversationContext(this.frameworkName, params.runId, params.serialized, params.invocationParams, params.extraParams, params.callbackMetadata);
387
+ const componentName = resolveComponentName(params.serialized, params.callbackMetadata, params.extraParams, params.runName);
388
+ const retryAttempt = resolveFrameworkRetryAttempt(params.callbackMetadata, params.extraParams, params.invocationParams, params.serialized);
389
+ const parentRunId = normalizeRunID(params.parentRunId);
390
+ const runType = params.runType.trim();
391
+ const frameworkTags = normalizeFrameworkTags(params.callbackTags ?? read(params.extraParams, 'tags') ?? read(params.callbackMetadata, 'tags'));
392
+ const langgraphNode = this.frameworkName === 'langgraph'
393
+ ? resolveLangGraphNode(params.callbackMetadata, params.extraParams, params.invocationParams, params.serialized)
394
+ : '';
395
+ const eventId = resolveFrameworkEventID(params.callbackMetadata, params.extraParams, params.invocationParams, params.serialized);
396
+ const rawMetadata = {
397
+ ...this.extraMetadata,
398
+ [spanAttrFrameworkRunID]: params.runId,
399
+ [spanAttrFrameworkRunType]: runType,
400
+ };
401
+ if (conversation.threadId.length > 0) {
402
+ rawMetadata[spanAttrFrameworkThreadID] = conversation.threadId;
403
+ }
404
+ if (parentRunId.length > 0) {
405
+ rawMetadata[spanAttrFrameworkParentRunID] = parentRunId;
406
+ }
407
+ if (componentName.length > 0) {
408
+ rawMetadata[spanAttrFrameworkComponentName] = componentName;
409
+ }
410
+ if (frameworkTags.length > 0) {
411
+ rawMetadata[spanAttrFrameworkTags] = frameworkTags;
412
+ }
413
+ if (retryAttempt !== undefined) {
414
+ rawMetadata[spanAttrFrameworkRetryAttempt] = retryAttempt;
415
+ }
416
+ if (langgraphNode.length > 0) {
417
+ rawMetadata[spanAttrFrameworkLangGraphNode] = langgraphNode;
418
+ }
419
+ if (eventId.length > 0) {
420
+ rawMetadata[spanAttrFrameworkEventID] = eventId;
421
+ }
422
+ const metadata = normalizeFrameworkMetadata(rawMetadata);
423
+ const tags = {
424
+ ...this.extraTags,
425
+ 'sigil.framework.name': this.frameworkName,
426
+ 'sigil.framework.source': frameworkSource,
427
+ 'sigil.framework.language': this.frameworkLanguage,
428
+ };
429
+ return {
430
+ conversationId: conversation.conversationId,
431
+ threadId: conversation.threadId,
432
+ metadata,
433
+ tags,
434
+ componentName,
435
+ parentRunId,
436
+ runType,
437
+ retryAttempt,
438
+ langgraphNode,
439
+ eventId,
440
+ };
441
+ }
442
+ }
443
+ function resolveProvider(explicitProvider, resolver, modelName, serialized, invocationParams) {
444
+ const explicit = normalizeProvider(explicitProvider);
445
+ if (explicit.length > 0) {
446
+ return explicit;
447
+ }
448
+ if (typeof resolver === 'function') {
449
+ const resolved = normalizeProvider(resolver({
450
+ modelName,
451
+ serialized,
452
+ invocationParams,
453
+ }));
454
+ return resolved.length > 0 ? resolved : 'custom';
455
+ }
456
+ for (const payload of [asRecord(invocationParams), asRecord(serialized)]) {
457
+ const fromProvider = normalizeProvider(asString(read(payload, 'provider')));
458
+ if (fromProvider.length > 0) {
459
+ return fromProvider;
460
+ }
461
+ const fromLsProvider = normalizeProvider(asString(read(payload, 'ls_provider')));
462
+ if (fromLsProvider.length > 0) {
463
+ return fromLsProvider;
464
+ }
465
+ }
466
+ return inferProviderFromModelName(modelName);
467
+ }
468
+ function resolveModelName(serialized, invocationParams) {
469
+ for (const payload of [asRecord(invocationParams), asRecord(serialized)]) {
470
+ for (const key of ['model', 'model_name', 'ls_model_name']) {
471
+ const value = asString(read(payload, key));
472
+ if (value.length > 0) {
473
+ return value;
474
+ }
475
+ }
476
+ const kwargs = asRecord(read(payload, 'kwargs'));
477
+ for (const key of ['model', 'model_name']) {
478
+ const value = asString(read(kwargs, key));
479
+ if (value.length > 0) {
480
+ return value;
481
+ }
482
+ }
483
+ }
484
+ return 'unknown';
485
+ }
486
+ function isStreaming(invocationParams) {
487
+ if (invocationParams === undefined) {
488
+ return false;
489
+ }
490
+ return asBoolean(read(invocationParams, 'stream')) || asBoolean(read(invocationParams, 'streaming'));
491
+ }
492
+ function resolveFrameworkThreadId(serialized, invocationParams, extraParams, callbackMetadata) {
493
+ for (const payload of [callbackMetadata, extraParams, invocationParams, serialized]) {
494
+ const threadId = threadIdFromPayload(payload);
495
+ if (threadId.length > 0) {
496
+ return threadId;
497
+ }
498
+ }
499
+ return '';
500
+ }
501
+ function resolveFrameworkConversationContext(frameworkName, runId, serialized, invocationParams, extraParams, callbackMetadata) {
502
+ for (const payload of [callbackMetadata, extraParams, invocationParams, serialized]) {
503
+ const conversationId = conversationIdFromPayload(payload);
504
+ if (conversationId.length > 0) {
505
+ const threadId = threadIdFromPayload(payload);
506
+ if (threadId.length > 0) {
507
+ return { conversationId, threadId };
508
+ }
509
+ return {
510
+ conversationId,
511
+ threadId: resolveFrameworkThreadId(serialized, invocationParams, extraParams, callbackMetadata),
512
+ };
513
+ }
514
+ }
515
+ const threadId = resolveFrameworkThreadId(serialized, invocationParams, extraParams, callbackMetadata);
516
+ if (threadId.length > 0) {
517
+ return { conversationId: threadId, threadId };
518
+ }
519
+ // Deterministic fallback when frameworks do not expose session/conversation identity.
520
+ return { conversationId: `sigil:framework:${frameworkName}:${runId}`, threadId: '' };
521
+ }
522
+ function threadIdFromPayload(payload) {
523
+ const candidates = [
524
+ asString(read(payload, 'thread_id')),
525
+ asString(read(payload, 'threadId')),
526
+ asString(read(read(payload, 'metadata'), 'thread_id')),
527
+ asString(read(read(payload, 'metadata'), 'threadId')),
528
+ asString(read(read(payload, 'configurable'), 'thread_id')),
529
+ asString(read(read(payload, 'configurable'), 'threadId')),
530
+ asString(read(read(payload, 'config'), 'thread_id')),
531
+ asString(read(read(payload, 'config'), 'threadId')),
532
+ asString(read(read(read(payload, 'config'), 'metadata'), 'thread_id')),
533
+ asString(read(read(read(payload, 'config'), 'metadata'), 'threadId')),
534
+ asString(read(read(read(payload, 'config'), 'configurable'), 'thread_id')),
535
+ asString(read(read(read(payload, 'config'), 'configurable'), 'threadId')),
536
+ ];
537
+ for (const candidate of candidates) {
538
+ if (candidate.length > 0) {
539
+ return candidate;
540
+ }
541
+ }
542
+ return '';
543
+ }
544
+ function conversationIdFromPayload(payload) {
545
+ const candidates = [
546
+ asString(read(payload, 'conversation_id')),
547
+ asString(read(payload, 'conversationId')),
548
+ asString(read(payload, 'session_id')),
549
+ asString(read(payload, 'sessionId')),
550
+ asString(read(payload, 'group_id')),
551
+ asString(read(payload, 'groupId')),
552
+ asString(read(read(payload, 'metadata'), 'conversation_id')),
553
+ asString(read(read(payload, 'metadata'), 'conversationId')),
554
+ asString(read(read(payload, 'metadata'), 'session_id')),
555
+ asString(read(read(payload, 'metadata'), 'sessionId')),
556
+ asString(read(read(payload, 'metadata'), 'group_id')),
557
+ asString(read(read(payload, 'metadata'), 'groupId')),
558
+ asString(read(read(payload, 'configurable'), 'conversation_id')),
559
+ asString(read(read(payload, 'configurable'), 'conversationId')),
560
+ asString(read(read(payload, 'configurable'), 'session_id')),
561
+ asString(read(read(payload, 'configurable'), 'sessionId')),
562
+ asString(read(read(payload, 'configurable'), 'group_id')),
563
+ asString(read(read(payload, 'configurable'), 'groupId')),
564
+ asString(read(read(payload, 'config'), 'conversation_id')),
565
+ asString(read(read(payload, 'config'), 'conversationId')),
566
+ asString(read(read(payload, 'config'), 'session_id')),
567
+ asString(read(read(payload, 'config'), 'sessionId')),
568
+ asString(read(read(payload, 'config'), 'group_id')),
569
+ asString(read(read(payload, 'config'), 'groupId')),
570
+ ];
571
+ for (const candidate of candidates) {
572
+ if (candidate.length > 0) {
573
+ return candidate;
574
+ }
575
+ }
576
+ return '';
577
+ }
578
+ function resolveComponentName(serialized, callbackMetadata, extraParams, runName) {
579
+ const candidates = [
580
+ asString(read(serialized, 'name')),
581
+ idPath(read(serialized, 'id')),
582
+ idPath(read(serialized, 'lc_id')),
583
+ asString(read(read(serialized, 'kwargs'), 'name')),
584
+ asString(read(callbackMetadata, 'component_name')),
585
+ asString(read(extraParams, 'component_name')),
586
+ asString(runName),
587
+ ];
588
+ for (const candidate of candidates) {
589
+ if (candidate.length > 0) {
590
+ return candidate;
591
+ }
592
+ }
593
+ return '';
594
+ }
595
+ function resolveLangGraphNode(callbackMetadata, extraParams, invocationParams, serialized) {
596
+ for (const payload of [callbackMetadata, extraParams, invocationParams, asRecord(serialized)]) {
597
+ const candidate = langGraphNodeFromPayload(payload);
598
+ if (candidate.length > 0) {
599
+ return candidate;
600
+ }
601
+ }
602
+ return '';
603
+ }
604
+ function langGraphNodeFromPayload(payload) {
605
+ const candidates = [
606
+ asString(read(payload, 'langgraph_node')),
607
+ asString(read(payload, 'langgraph_node_name')),
608
+ asString(read(payload, 'node_name')),
609
+ asString(read(payload, 'node')),
610
+ asString(read(read(payload, 'metadata'), 'langgraph_node')),
611
+ asString(read(read(payload, 'metadata'), 'langgraph_node_name')),
612
+ asString(read(read(payload, 'configurable'), 'langgraph_node')),
613
+ asString(read(read(payload, 'configurable'), 'langgraph_node_name')),
614
+ asString(read(read(read(payload, 'config'), 'metadata'), 'langgraph_node')),
615
+ asString(read(read(read(payload, 'config'), 'configurable'), 'langgraph_node')),
616
+ asString(read(read(read(payload, 'config'), 'configurable'), '__pregel_node')),
617
+ ];
618
+ for (const candidate of candidates) {
619
+ if (candidate.length > 0) {
620
+ return candidate;
621
+ }
622
+ }
623
+ return '';
624
+ }
625
+ function resolveFrameworkRetryAttempt(...payloads) {
626
+ for (const payload of payloads) {
627
+ const value = retryAttemptFromPayload(payload);
628
+ if (value !== undefined) {
629
+ return value;
630
+ }
631
+ }
632
+ return undefined;
633
+ }
634
+ function resolveFrameworkEventID(...payloads) {
635
+ for (const payload of payloads) {
636
+ const candidates = [
637
+ asString(read(payload, 'event_id')),
638
+ asString(read(payload, 'eventId')),
639
+ asString(read(payload, 'invocation_id')),
640
+ asString(read(payload, 'invocationId')),
641
+ asString(read(read(payload, 'metadata'), 'event_id')),
642
+ asString(read(read(payload, 'metadata'), 'eventId')),
643
+ asString(read(read(payload, 'metadata'), 'invocation_id')),
644
+ asString(read(read(payload, 'metadata'), 'invocationId')),
645
+ ];
646
+ for (const candidate of candidates) {
647
+ if (candidate.length > 0) {
648
+ return candidate;
649
+ }
650
+ }
651
+ }
652
+ return '';
653
+ }
654
+ function retryAttemptFromPayload(payload) {
655
+ const candidates = [
656
+ read(payload, 'retry_attempt'),
657
+ read(payload, 'retryAttempt'),
658
+ read(payload, 'attempt'),
659
+ read(payload, 'retry'),
660
+ read(read(payload, 'metadata'), 'retry_attempt'),
661
+ read(read(payload, 'metadata'), 'retryAttempt'),
662
+ read(read(payload, 'configurable'), 'retry_attempt'),
663
+ read(read(payload, 'configurable'), 'retryAttempt'),
664
+ ];
665
+ for (const candidate of candidates) {
666
+ const parsed = asMaybeInt(candidate);
667
+ if (parsed !== undefined) {
668
+ return parsed;
669
+ }
670
+ }
671
+ return undefined;
672
+ }
673
+ function normalizeFrameworkTags(raw) {
674
+ const values = Array.isArray(raw) ? raw : [raw];
675
+ const seen = new Set();
676
+ const output = [];
677
+ for (const value of values) {
678
+ if (typeof value !== 'string') {
679
+ continue;
680
+ }
681
+ const trimmed = value.trim();
682
+ if (trimmed.length === 0 || seen.has(trimmed)) {
683
+ continue;
684
+ }
685
+ seen.add(trimmed);
686
+ output.push(trimmed);
687
+ }
688
+ return output;
689
+ }
690
+ function normalizeFrameworkMetadata(raw) {
691
+ const out = {};
692
+ const seen = new WeakSet();
693
+ for (const [key, value] of Object.entries(raw)) {
694
+ const normalizedKey = key.trim();
695
+ if (normalizedKey.length === 0) {
696
+ continue;
697
+ }
698
+ const normalizedValue = normalizeFrameworkMetadataValue(value, 0, seen);
699
+ if (normalizedValue !== undefined) {
700
+ out[normalizedKey] = normalizedValue;
701
+ }
702
+ }
703
+ return out;
704
+ }
705
+ function normalizeFrameworkMetadataValue(value, depth, seen) {
706
+ if (depth > maxFrameworkMetadataDepth || value === undefined) {
707
+ return undefined;
708
+ }
709
+ if (value === null || typeof value === 'boolean' || typeof value === 'string') {
710
+ return value;
711
+ }
712
+ if (typeof value === 'number') {
713
+ return Number.isFinite(value) ? value : undefined;
714
+ }
715
+ if (value instanceof Date) {
716
+ return Number.isFinite(value.getTime()) ? value.toISOString() : undefined;
717
+ }
718
+ if (typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
719
+ return undefined;
720
+ }
721
+ if (Array.isArray(value)) {
722
+ const normalized = value
723
+ .map((item) => normalizeFrameworkMetadataValue(item, depth + 1, seen))
724
+ .filter((item) => item !== undefined);
725
+ return normalized;
726
+ }
727
+ if (!isRecord(value)) {
728
+ return undefined;
729
+ }
730
+ if (seen.has(value)) {
731
+ return '[circular]';
732
+ }
733
+ seen.add(value);
734
+ try {
735
+ const normalizedObject = {};
736
+ for (const [key, nestedValue] of Object.entries(value)) {
737
+ const nestedKey = key.trim();
738
+ if (nestedKey.length === 0) {
739
+ continue;
740
+ }
741
+ const normalizedNestedValue = normalizeFrameworkMetadataValue(nestedValue, depth + 1, seen);
742
+ if (normalizedNestedValue !== undefined) {
743
+ normalizedObject[nestedKey] = normalizedNestedValue;
744
+ }
745
+ }
746
+ return normalizedObject;
747
+ }
748
+ finally {
749
+ seen.delete(value);
750
+ }
751
+ }
752
+ function normalizeRunID(runId) {
753
+ if (typeof runId !== 'string') {
754
+ return '';
755
+ }
756
+ return runId.trim();
757
+ }
758
+ function resolveToolName(serialized, componentName) {
759
+ const candidates = [
760
+ asString(read(serialized, 'name')),
761
+ asString(read(serialized, 'tool_name')),
762
+ componentName,
763
+ 'framework_tool',
764
+ ];
765
+ for (const candidate of candidates) {
766
+ if (candidate.length > 0) {
767
+ return candidate;
768
+ }
769
+ }
770
+ return 'framework_tool';
771
+ }
772
+ function resolveToolDescription(serialized) {
773
+ const description = asString(read(serialized, 'description'));
774
+ if (description.length > 0) {
775
+ return description;
776
+ }
777
+ return undefined;
778
+ }
779
+ function resolveToolArguments(input, extraParams) {
780
+ const explicitInputs = read(extraParams, 'inputs');
781
+ if (explicitInputs !== undefined) {
782
+ return explicitInputs;
783
+ }
784
+ if (typeof input === 'string') {
785
+ return input.trim();
786
+ }
787
+ return input;
788
+ }
789
+ function idPath(value) {
790
+ if (!Array.isArray(value)) {
791
+ return '';
792
+ }
793
+ const parts = value
794
+ .filter((item) => typeof item === 'string')
795
+ .map((item) => item.trim())
796
+ .filter((item) => item.length > 0);
797
+ return parts.join('.');
798
+ }
799
+ function mapPromptInputs(prompts) {
800
+ if (!Array.isArray(prompts)) {
801
+ return [];
802
+ }
803
+ const input = [];
804
+ for (const prompt of prompts) {
805
+ if (typeof prompt !== 'string') {
806
+ continue;
807
+ }
808
+ const trimmed = prompt.trim();
809
+ if (trimmed.length === 0) {
810
+ continue;
811
+ }
812
+ input.push({ role: 'user', content: trimmed });
813
+ }
814
+ return input;
815
+ }
816
+ function mapChatInputs(messages) {
817
+ if (!Array.isArray(messages)) {
818
+ return [];
819
+ }
820
+ const output = [];
821
+ for (const batch of messages) {
822
+ if (!Array.isArray(batch)) {
823
+ continue;
824
+ }
825
+ for (const message of batch) {
826
+ const text = extractMessageText(message);
827
+ if (text.length === 0) {
828
+ continue;
829
+ }
830
+ output.push({
831
+ role: normalizeRole(extractMessageRole(message)),
832
+ content: text,
833
+ });
834
+ }
835
+ }
836
+ return output;
837
+ }
838
+ function mapOutputMessages(output) {
839
+ const generations = read(output, 'generations');
840
+ if (!Array.isArray(generations)) {
841
+ return [];
842
+ }
843
+ const texts = [];
844
+ for (const candidates of generations) {
845
+ if (!Array.isArray(candidates)) {
846
+ continue;
847
+ }
848
+ for (const candidate of candidates) {
849
+ const text = extractGenerationText(candidate);
850
+ if (text.length > 0) {
851
+ texts.push(text);
852
+ }
853
+ }
854
+ }
855
+ if (texts.length === 0) {
856
+ return [];
857
+ }
858
+ return [{ role: 'assistant', content: texts.join('\n') }];
859
+ }
860
+ function extractGenerationText(candidate) {
861
+ const text = asString(read(candidate, 'text'));
862
+ if (text.length > 0) {
863
+ return text;
864
+ }
865
+ return extractMessageText(read(candidate, 'message'));
866
+ }
867
+ function extractMessageText(message) {
868
+ const content = read(message, 'content');
869
+ if (typeof content === 'string') {
870
+ return content.trim();
871
+ }
872
+ if (Array.isArray(content)) {
873
+ const parts = [];
874
+ for (const item of content) {
875
+ if (typeof item === 'string') {
876
+ const trimmed = item.trim();
877
+ if (trimmed.length > 0) {
878
+ parts.push(trimmed);
879
+ }
880
+ continue;
881
+ }
882
+ const text = asString(read(item, 'text'));
883
+ if (text.length > 0) {
884
+ parts.push(text);
885
+ }
886
+ }
887
+ return parts.join(' ').trim();
888
+ }
889
+ if (isRecord(content)) {
890
+ return asString(read(content, 'text'));
891
+ }
892
+ return '';
893
+ }
894
+ function extractMessageRole(message) {
895
+ const role = asString(read(message, 'role'));
896
+ if (role.length > 0) {
897
+ return role;
898
+ }
899
+ return asString(read(message, 'type'));
900
+ }
901
+ function normalizeRole(role) {
902
+ const normalized = role.trim().toLowerCase();
903
+ if (normalized === 'assistant' || normalized === 'ai') {
904
+ return 'assistant';
905
+ }
906
+ if (normalized === 'tool') {
907
+ return 'tool';
908
+ }
909
+ return 'user';
910
+ }
911
+ function mapUsage(rawUsage) {
912
+ const usage = asRecord(rawUsage);
913
+ if (usage === undefined) {
914
+ return undefined;
915
+ }
916
+ const inputTokens = asInt(read(usage, 'prompt_tokens')) || asInt(read(usage, 'input_tokens'));
917
+ const outputTokens = asInt(read(usage, 'completion_tokens')) || asInt(read(usage, 'output_tokens'));
918
+ const totalTokens = asInt(read(usage, 'total_tokens')) || inputTokens + outputTokens;
919
+ if (inputTokens === 0 && outputTokens === 0 && totalTokens === 0) {
920
+ return undefined;
921
+ }
922
+ return {
923
+ inputTokens,
924
+ outputTokens,
925
+ totalTokens,
926
+ };
927
+ }
928
+ function inferProviderFromModelName(modelName) {
929
+ const normalized = modelName.trim().toLowerCase();
930
+ if (normalized.startsWith('gpt-') ||
931
+ normalized.startsWith('o1') ||
932
+ normalized.startsWith('o3') ||
933
+ normalized.startsWith('o4')) {
934
+ return 'openai';
935
+ }
936
+ if (normalized.startsWith('claude-')) {
937
+ return 'anthropic';
938
+ }
939
+ if (normalized.startsWith('gemini-')) {
940
+ return 'gemini';
941
+ }
942
+ return 'custom';
943
+ }
944
+ function normalizeProvider(value) {
945
+ const normalized = (value ?? '').trim().toLowerCase();
946
+ if (normalized === 'openai' || normalized === 'anthropic' || normalized === 'gemini') {
947
+ return normalized;
948
+ }
949
+ if (normalized.length === 0) {
950
+ return '';
951
+ }
952
+ return 'custom';
953
+ }
954
+ function read(value, key) {
955
+ if (isRecord(value)) {
956
+ return value[key];
957
+ }
958
+ return undefined;
959
+ }
960
+ function asRecord(value) {
961
+ return isRecord(value) ? value : undefined;
962
+ }
963
+ function asString(value) {
964
+ if (typeof value !== 'string') {
965
+ return '';
966
+ }
967
+ return value.trim();
968
+ }
969
+ function asInt(value) {
970
+ if (typeof value === 'number' && Number.isFinite(value)) {
971
+ return Math.trunc(value);
972
+ }
973
+ if (typeof value === 'string' && value.trim().length > 0) {
974
+ const parsed = Number.parseInt(value, 10);
975
+ if (Number.isFinite(parsed)) {
976
+ return parsed;
977
+ }
978
+ }
979
+ return 0;
980
+ }
981
+ function asMaybeInt(value) {
982
+ if (value === undefined || value === null || typeof value === 'boolean') {
983
+ return undefined;
984
+ }
985
+ if (typeof value === 'number') {
986
+ if (!Number.isFinite(value) || !Number.isInteger(value)) {
987
+ return undefined;
988
+ }
989
+ return value;
990
+ }
991
+ if (typeof value === 'string') {
992
+ const trimmed = value.trim();
993
+ if (trimmed.length === 0) {
994
+ return undefined;
995
+ }
996
+ const parsed = Number.parseInt(trimmed, 10);
997
+ if (Number.isNaN(parsed)) {
998
+ return undefined;
999
+ }
1000
+ return parsed;
1001
+ }
1002
+ return undefined;
1003
+ }
1004
+ function asBoolean(value) {
1005
+ if (typeof value === 'boolean') {
1006
+ return value;
1007
+ }
1008
+ if (typeof value === 'number') {
1009
+ return value !== 0;
1010
+ }
1011
+ if (typeof value === 'string') {
1012
+ const normalized = value.trim().toLowerCase();
1013
+ return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
1014
+ }
1015
+ return false;
1016
+ }
1017
+ function asError(value) {
1018
+ if (value instanceof Error) {
1019
+ return value;
1020
+ }
1021
+ if (typeof value === 'string') {
1022
+ return new Error(value);
1023
+ }
1024
+ return new Error('framework callback error');
1025
+ }
1026
+ function isRecord(value) {
1027
+ return typeof value === 'object' && value !== null;
1028
+ }
1029
+ function notEmpty(value) {
1030
+ return typeof value === 'string' && value.trim().length > 0;
1031
+ }
1032
+ //# sourceMappingURL=shared.js.map