autotel-devtools 20.1.0 → 21.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/dist/cli.cjs +2 -2
- package/dist/cli.js +2 -2
- package/dist/{error-aggregator-CGgWr2OH.d.cts → error-aggregator-D8VKciLY.d.ts} +12 -10
- package/dist/{error-aggregator-DufjI2IG.d.ts → error-aggregator-DCEKMOm3.d.cts} +12 -10
- package/dist/{exporter-CEKKJTci.d.cts → exporter-Dt4kx128.d.cts} +15 -7
- package/dist/{exporter-BJwufQwg.d.ts → exporter-Due9Rd4s.d.ts} +15 -7
- package/dist/genai/index.cjs +93 -107
- package/dist/genai/index.d.cts +1 -32
- package/dist/genai/index.d.ts +1 -32
- package/dist/genai/index.js +94 -107
- package/dist/{http-Ddn7gT0R.js → http-CNZMrnzv.js} +93 -57
- package/dist/{http-D44dITGS.cjs → http-CXSzX4ee.cjs} +93 -57
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/dist/json-fields-CPjKZ2WH.js +47 -0
- package/dist/json-fields-DZFlNqT2.cjs +83 -0
- package/dist/{listen-DGzVi7DE.cjs → listen-CEJ3nYJf.cjs} +1 -1
- package/dist/{listen-NVMbBWHw.js → listen-DBfsfcdd.js} +1 -1
- package/dist/server/exporter.d.cts +1 -1
- package/dist/server/exporter.d.ts +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +1 -1
- package/dist/types-DHDvZnnn.d.cts +47 -0
- package/dist/types-DHDvZnnn.d.ts +47 -0
- package/dist/widget.global.js +15 -15
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_http = require('./http-
|
|
3
|
-
const require_listen = require('./listen-
|
|
2
|
+
const require_http = require('./http-CXSzX4ee.cjs');
|
|
3
|
+
const require_listen = require('./listen-CEJ3nYJf.cjs');
|
|
4
4
|
let node_http = require("node:http");
|
|
5
5
|
let node_fs = require("node:fs");
|
|
6
6
|
let node_path = require("node:path");
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as probePortHolder, f as DevtoolsServer, m as hostHeaderIsLoopback, r as resolveSourceRoot, t as attachDevtoolsRoutes } from "./http-
|
|
3
|
-
import { t as listenLoopbackDualStack } from "./listen-
|
|
2
|
+
import { a as probePortHolder, f as DevtoolsServer, m as hostHeaderIsLoopback, r as resolveSourceRoot, t as attachDevtoolsRoutes } from "./http-CNZMrnzv.js";
|
|
3
|
+
import { t as listenLoopbackDualStack } from "./listen-DBfsfcdd.js";
|
|
4
4
|
import { createServer } from "node:http";
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-Due9Rd4s.js";
|
|
2
2
|
//#region src/server/error-aggregator.d.ts
|
|
3
|
+
/** How many errors the aggregator is holding, and what they are. */
|
|
4
|
+
interface ErrorStats {
|
|
5
|
+
totalGroups: number;
|
|
6
|
+
totalErrors: number;
|
|
7
|
+
recentErrors: number;
|
|
8
|
+
topErrorTypes: Array<{
|
|
9
|
+
type: string;
|
|
10
|
+
count: number;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
3
13
|
interface ErrorAggregatorOptions {
|
|
4
14
|
/**
|
|
5
15
|
* Maximum number of error groups to track (default: 100)
|
|
@@ -96,15 +106,7 @@ declare class ErrorAggregator {
|
|
|
96
106
|
/**
|
|
97
107
|
* Get error statistics
|
|
98
108
|
*/
|
|
99
|
-
getStats():
|
|
100
|
-
totalGroups: number;
|
|
101
|
-
totalErrors: number;
|
|
102
|
-
recentErrors: number;
|
|
103
|
-
topErrorTypes: Array<{
|
|
104
|
-
type: string;
|
|
105
|
-
count: number;
|
|
106
|
-
}>;
|
|
107
|
-
};
|
|
109
|
+
getStats(): ErrorStats;
|
|
108
110
|
/**
|
|
109
111
|
* Clear all error groups
|
|
110
112
|
*/
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-Dt4kx128.cjs";
|
|
2
2
|
//#region src/server/error-aggregator.d.ts
|
|
3
|
+
/** How many errors the aggregator is holding, and what they are. */
|
|
4
|
+
interface ErrorStats {
|
|
5
|
+
totalGroups: number;
|
|
6
|
+
totalErrors: number;
|
|
7
|
+
recentErrors: number;
|
|
8
|
+
topErrorTypes: Array<{
|
|
9
|
+
type: string;
|
|
10
|
+
count: number;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
3
13
|
interface ErrorAggregatorOptions {
|
|
4
14
|
/**
|
|
5
15
|
* Maximum number of error groups to track (default: 100)
|
|
@@ -96,15 +106,7 @@ declare class ErrorAggregator {
|
|
|
96
106
|
/**
|
|
97
107
|
* Get error statistics
|
|
98
108
|
*/
|
|
99
|
-
getStats():
|
|
100
|
-
totalGroups: number;
|
|
101
|
-
totalErrors: number;
|
|
102
|
-
recentErrors: number;
|
|
103
|
-
topErrorTypes: Array<{
|
|
104
|
-
type: string;
|
|
105
|
-
count: number;
|
|
106
|
-
}>;
|
|
107
|
-
};
|
|
109
|
+
getStats(): ErrorStats;
|
|
108
110
|
/**
|
|
109
111
|
* Clear all error groups
|
|
110
112
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as SpanAttributes } from "./types-DHDvZnnn.cjs";
|
|
1
2
|
import { Server } from "node:http";
|
|
2
3
|
import { AgentRawEvent, AgentSession, OtelMetricRecord } from "autotel-agents";
|
|
3
4
|
import { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
|
|
@@ -12,7 +13,7 @@ interface SpanData {
|
|
|
12
13
|
startTime: number;
|
|
13
14
|
endTime: number;
|
|
14
15
|
duration: number;
|
|
15
|
-
attributes:
|
|
16
|
+
attributes: SpanAttributes;
|
|
16
17
|
status: {
|
|
17
18
|
code: 'OK' | 'ERROR' | 'UNSET';
|
|
18
19
|
message?: string;
|
|
@@ -20,12 +21,12 @@ interface SpanData {
|
|
|
20
21
|
events?: Array<{
|
|
21
22
|
name: string;
|
|
22
23
|
timestamp: number;
|
|
23
|
-
attributes?:
|
|
24
|
+
attributes?: SpanAttributes;
|
|
24
25
|
}>;
|
|
25
26
|
links?: Array<{
|
|
26
27
|
traceId: string;
|
|
27
28
|
spanId: string;
|
|
28
|
-
attributes?:
|
|
29
|
+
attributes?: SpanAttributes;
|
|
29
30
|
}>;
|
|
30
31
|
scope?: {
|
|
31
32
|
name?: string;
|
|
@@ -61,14 +62,14 @@ interface LogData {
|
|
|
61
62
|
severityNumber?: number;
|
|
62
63
|
body: string | Record<string, unknown>;
|
|
63
64
|
timestamp: number;
|
|
64
|
-
attributes?:
|
|
65
|
+
attributes?: SpanAttributes;
|
|
65
66
|
resource?: Record<string, unknown>;
|
|
66
67
|
}
|
|
67
68
|
interface MetricData {
|
|
68
69
|
type: 'event' | 'funnel' | 'outcome' | 'value';
|
|
69
70
|
name: string;
|
|
70
71
|
value?: number;
|
|
71
|
-
attributes:
|
|
72
|
+
attributes: SpanAttributes;
|
|
72
73
|
timestamp: number;
|
|
73
74
|
traceId?: string;
|
|
74
75
|
}
|
|
@@ -83,7 +84,7 @@ interface ErrorGroup {
|
|
|
83
84
|
affectedTraces: string[];
|
|
84
85
|
affectedSpans: string[];
|
|
85
86
|
service?: string;
|
|
86
|
-
attributes?:
|
|
87
|
+
attributes?: SpanAttributes;
|
|
87
88
|
}
|
|
88
89
|
interface ErrorOccurrence {
|
|
89
90
|
traceId: string;
|
|
@@ -95,8 +96,15 @@ interface ErrorOccurrence {
|
|
|
95
96
|
type: string;
|
|
96
97
|
message: string;
|
|
97
98
|
stackTrace?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Grouping key the emitting SDK already decided on (`exception.fingerprint`,
|
|
101
|
+
* written by autotel's `exceptionFingerprint()` enricher). When present the
|
|
102
|
+
* aggregator groups by it instead of re-deriving one from the stack string,
|
|
103
|
+
* so this tab agrees with every other backend receiving the same spans.
|
|
104
|
+
*/
|
|
105
|
+
fingerprint?: string;
|
|
98
106
|
};
|
|
99
|
-
attributes?:
|
|
107
|
+
attributes?: SpanAttributes;
|
|
100
108
|
}
|
|
101
109
|
interface DevtoolsData {
|
|
102
110
|
traces: TraceData[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { n as SpanAttributes } from "./types-DHDvZnnn.js";
|
|
1
2
|
import { Server } from "node:http";
|
|
2
3
|
import { AgentRawEvent, AgentSession, OtelMetricRecord } from "autotel-agents";
|
|
3
4
|
import { ExportResult } from "@opentelemetry/core";
|
|
@@ -12,7 +13,7 @@ interface SpanData {
|
|
|
12
13
|
startTime: number;
|
|
13
14
|
endTime: number;
|
|
14
15
|
duration: number;
|
|
15
|
-
attributes:
|
|
16
|
+
attributes: SpanAttributes;
|
|
16
17
|
status: {
|
|
17
18
|
code: 'OK' | 'ERROR' | 'UNSET';
|
|
18
19
|
message?: string;
|
|
@@ -20,12 +21,12 @@ interface SpanData {
|
|
|
20
21
|
events?: Array<{
|
|
21
22
|
name: string;
|
|
22
23
|
timestamp: number;
|
|
23
|
-
attributes?:
|
|
24
|
+
attributes?: SpanAttributes;
|
|
24
25
|
}>;
|
|
25
26
|
links?: Array<{
|
|
26
27
|
traceId: string;
|
|
27
28
|
spanId: string;
|
|
28
|
-
attributes?:
|
|
29
|
+
attributes?: SpanAttributes;
|
|
29
30
|
}>;
|
|
30
31
|
scope?: {
|
|
31
32
|
name?: string;
|
|
@@ -61,14 +62,14 @@ interface LogData {
|
|
|
61
62
|
severityNumber?: number;
|
|
62
63
|
body: string | Record<string, unknown>;
|
|
63
64
|
timestamp: number;
|
|
64
|
-
attributes?:
|
|
65
|
+
attributes?: SpanAttributes;
|
|
65
66
|
resource?: Record<string, unknown>;
|
|
66
67
|
}
|
|
67
68
|
interface MetricData {
|
|
68
69
|
type: 'event' | 'funnel' | 'outcome' | 'value';
|
|
69
70
|
name: string;
|
|
70
71
|
value?: number;
|
|
71
|
-
attributes:
|
|
72
|
+
attributes: SpanAttributes;
|
|
72
73
|
timestamp: number;
|
|
73
74
|
traceId?: string;
|
|
74
75
|
}
|
|
@@ -83,7 +84,7 @@ interface ErrorGroup {
|
|
|
83
84
|
affectedTraces: string[];
|
|
84
85
|
affectedSpans: string[];
|
|
85
86
|
service?: string;
|
|
86
|
-
attributes?:
|
|
87
|
+
attributes?: SpanAttributes;
|
|
87
88
|
}
|
|
88
89
|
interface ErrorOccurrence {
|
|
89
90
|
traceId: string;
|
|
@@ -95,8 +96,15 @@ interface ErrorOccurrence {
|
|
|
95
96
|
type: string;
|
|
96
97
|
message: string;
|
|
97
98
|
stackTrace?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Grouping key the emitting SDK already decided on (`exception.fingerprint`,
|
|
101
|
+
* written by autotel's `exceptionFingerprint()` enricher). When present the
|
|
102
|
+
* aggregator groups by it instead of re-deriving one from the stack string,
|
|
103
|
+
* so this tab agrees with every other backend receiving the same spans.
|
|
104
|
+
*/
|
|
105
|
+
fingerprint?: string;
|
|
98
106
|
};
|
|
99
|
-
attributes?:
|
|
107
|
+
attributes?: SpanAttributes;
|
|
100
108
|
}
|
|
101
109
|
interface DevtoolsData {
|
|
102
110
|
traces: TraceData[];
|
package/dist/genai/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_json_fields = require('../json-fields-DZFlNqT2.cjs');
|
|
2
3
|
|
|
3
4
|
//#region src/widget/genai/detect.ts
|
|
4
5
|
const GENAI_MARKERS = [
|
|
@@ -150,25 +151,6 @@ function priceCall(inputs) {
|
|
|
150
151
|
|
|
151
152
|
//#endregion
|
|
152
153
|
//#region src/widget/genai/normalize.ts
|
|
153
|
-
function str(v) {
|
|
154
|
-
return typeof v === "string" ? v : void 0;
|
|
155
|
-
}
|
|
156
|
-
function num(v) {
|
|
157
|
-
if (typeof v === "number") return v;
|
|
158
|
-
if (typeof v === "string" && v !== "") {
|
|
159
|
-
const n = Number(v);
|
|
160
|
-
return Number.isFinite(n) ? n : void 0;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
function strArray(v) {
|
|
164
|
-
if (Array.isArray(v) && v.every((x) => typeof x === "string")) return v;
|
|
165
|
-
if (typeof v === "string") return [v];
|
|
166
|
-
}
|
|
167
|
-
function bool(v) {
|
|
168
|
-
if (typeof v === "boolean") return v;
|
|
169
|
-
if (v === "true") return true;
|
|
170
|
-
if (v === "false") return false;
|
|
171
|
-
}
|
|
172
154
|
function parseJson(v) {
|
|
173
155
|
if (v == null) return void 0;
|
|
174
156
|
if (typeof v === "object") return v;
|
|
@@ -221,9 +203,10 @@ function normalizeMessageParts(raw) {
|
|
|
221
203
|
value: p
|
|
222
204
|
};
|
|
223
205
|
});
|
|
224
|
-
|
|
206
|
+
const legacyText = require_json_fields.asString(raw.content);
|
|
207
|
+
if (legacyText !== void 0) return [{
|
|
225
208
|
kind: "text",
|
|
226
|
-
text:
|
|
209
|
+
text: legacyText
|
|
227
210
|
}];
|
|
228
211
|
if (raw.content != null) return [{
|
|
229
212
|
kind: "json",
|
|
@@ -232,7 +215,8 @@ function normalizeMessageParts(raw) {
|
|
|
232
215
|
return [];
|
|
233
216
|
}
|
|
234
217
|
function unwrapToolResult(payload) {
|
|
235
|
-
|
|
218
|
+
const wrapper = require_json_fields.asObject(payload);
|
|
219
|
+
return wrapper && "value" in wrapper ? wrapper.value : payload;
|
|
236
220
|
}
|
|
237
221
|
function classifyAiSdkPart(part) {
|
|
238
222
|
if (part.type === "tool-call") return {
|
|
@@ -346,8 +330,9 @@ function messagesFromEvents(events) {
|
|
|
346
330
|
for (const ev of events) {
|
|
347
331
|
const attrs = ev.attributes ?? {};
|
|
348
332
|
if (ev.name === "gen_ai.choice") {
|
|
349
|
-
const
|
|
350
|
-
const
|
|
333
|
+
const unparsedMessage = attrs.message;
|
|
334
|
+
const message = parseJson(attrs.message) ?? unparsedMessage;
|
|
335
|
+
const finishReason = require_json_fields.asString(attrs.finish_reason);
|
|
351
336
|
if (message) {
|
|
352
337
|
const normalized = normalizeMessage(message);
|
|
353
338
|
if (finishReason) normalized.finishReason = finishReason;
|
|
@@ -359,12 +344,13 @@ function messagesFromEvents(events) {
|
|
|
359
344
|
if (!m) continue;
|
|
360
345
|
const role = m[1];
|
|
361
346
|
const content = attrs.content;
|
|
362
|
-
const
|
|
347
|
+
const contentText = require_json_fields.asString(content);
|
|
348
|
+
const parsed = contentText === void 0 ? content : parseJson(contentText) ?? contentText;
|
|
363
349
|
out.push(normalizeMessage({
|
|
364
350
|
role,
|
|
365
351
|
content: parsed,
|
|
366
352
|
tool_calls: parseJson(attrs.tool_calls),
|
|
367
|
-
tool_call_id:
|
|
353
|
+
tool_call_id: require_json_fields.asString(attrs.id) ?? require_json_fields.asString(attrs.tool_call_id)
|
|
368
354
|
}));
|
|
369
355
|
}
|
|
370
356
|
return out;
|
|
@@ -372,7 +358,7 @@ function messagesFromEvents(events) {
|
|
|
372
358
|
function readToolDefinitions(attrs) {
|
|
373
359
|
const raw = parseJson(attrs["gen_ai.tool.definitions"] ?? attrs["gen_ai.orchestrator.agent.definitions"]);
|
|
374
360
|
if (!Array.isArray(raw)) return void 0;
|
|
375
|
-
return raw.filter((d) =>
|
|
361
|
+
return raw.filter((d) => require_json_fields.asString(d.name) !== void 0).map((d) => ({
|
|
376
362
|
name: d.name,
|
|
377
363
|
description: d.description,
|
|
378
364
|
type: d.type,
|
|
@@ -381,18 +367,18 @@ function readToolDefinitions(attrs) {
|
|
|
381
367
|
}
|
|
382
368
|
function readUsage(attrs) {
|
|
383
369
|
return {
|
|
384
|
-
inputTokens:
|
|
385
|
-
outputTokens:
|
|
386
|
-
reasoningOutputTokens:
|
|
387
|
-
cacheReadInputTokens:
|
|
388
|
-
cacheCreationInputTokens:
|
|
370
|
+
inputTokens: require_json_fields.asNumber(attrs["gen_ai.usage.input_tokens"]) ?? require_json_fields.asNumber(attrs["gen_ai.usage.prompt_tokens"]) ?? require_json_fields.asNumber(attrs["llm.usage.prompt_tokens"]) ?? require_json_fields.asNumber(attrs["ai.usage.inputTokens"]),
|
|
371
|
+
outputTokens: require_json_fields.asNumber(attrs["gen_ai.usage.output_tokens"]) ?? require_json_fields.asNumber(attrs["gen_ai.usage.completion_tokens"]) ?? require_json_fields.asNumber(attrs["llm.usage.completion_tokens"]) ?? require_json_fields.asNumber(attrs["ai.usage.outputTokens"]),
|
|
372
|
+
reasoningOutputTokens: require_json_fields.asNumber(attrs["gen_ai.usage.reasoning.output_tokens"]),
|
|
373
|
+
cacheReadInputTokens: require_json_fields.asNumber(attrs["gen_ai.usage.cache_read.input_tokens"]),
|
|
374
|
+
cacheCreationInputTokens: require_json_fields.asNumber(attrs["gen_ai.usage.cache_creation.input_tokens"])
|
|
389
375
|
};
|
|
390
376
|
}
|
|
391
377
|
function readStreaming(attrs) {
|
|
392
|
-
const timeToFirstChunkS =
|
|
393
|
-
const timeToFinishS =
|
|
394
|
-
const outputTokensPerSecond =
|
|
395
|
-
const timePerOutputChunkS =
|
|
378
|
+
const timeToFirstChunkS = require_json_fields.asNumber(attrs["gen_ai.response.time_to_first_chunk"]);
|
|
379
|
+
const timeToFinishS = require_json_fields.asNumber(attrs["gen_ai.response.time_to_finish"]);
|
|
380
|
+
const outputTokensPerSecond = require_json_fields.asNumber(attrs["gen_ai.response.output_tokens_per_second"]);
|
|
381
|
+
const timePerOutputChunkS = require_json_fields.asNumber(attrs["gen_ai.response.time_per_output_chunk"]);
|
|
396
382
|
if (timeToFirstChunkS === void 0 && timeToFinishS === void 0 && outputTokensPerSecond === void 0 && timePerOutputChunkS === void 0) return;
|
|
397
383
|
return {
|
|
398
384
|
timeToFirstChunkS,
|
|
@@ -402,12 +388,12 @@ function readStreaming(attrs) {
|
|
|
402
388
|
};
|
|
403
389
|
}
|
|
404
390
|
function readSession(attrs) {
|
|
405
|
-
const costUsd =
|
|
406
|
-
const inputTokens =
|
|
407
|
-
const outputTokens =
|
|
408
|
-
const stepCount =
|
|
409
|
-
const toolCallCount =
|
|
410
|
-
const errorCount =
|
|
391
|
+
const costUsd = require_json_fields.asNumber(attrs["gen_ai.session.cost.usd"]);
|
|
392
|
+
const inputTokens = require_json_fields.asNumber(attrs["gen_ai.session.input_tokens"]);
|
|
393
|
+
const outputTokens = require_json_fields.asNumber(attrs["gen_ai.session.output_tokens"]);
|
|
394
|
+
const stepCount = require_json_fields.asNumber(attrs["gen_ai.session.step.count"]);
|
|
395
|
+
const toolCallCount = require_json_fields.asNumber(attrs["gen_ai.session.tool_call.count"]);
|
|
396
|
+
const errorCount = require_json_fields.asNumber(attrs["gen_ai.session.error.count"]);
|
|
411
397
|
if (costUsd === void 0 && inputTokens === void 0 && outputTokens === void 0 && stepCount === void 0 && toolCallCount === void 0 && errorCount === void 0) return;
|
|
412
398
|
return {
|
|
413
399
|
costUsd,
|
|
@@ -419,18 +405,18 @@ function readSession(attrs) {
|
|
|
419
405
|
};
|
|
420
406
|
}
|
|
421
407
|
function readGuardDetails(a, defaultAction) {
|
|
422
|
-
const rule =
|
|
408
|
+
const rule = require_json_fields.asString(a["gen_ai.guard.rule"]);
|
|
423
409
|
if (!rule) return void 0;
|
|
424
410
|
return {
|
|
425
411
|
rule,
|
|
426
|
-
action:
|
|
427
|
-
message:
|
|
428
|
-
observed:
|
|
429
|
-
limit:
|
|
412
|
+
action: require_json_fields.asString(a["gen_ai.guard.action"]) ?? defaultAction,
|
|
413
|
+
message: require_json_fields.asString(a["gen_ai.guard.message"]),
|
|
414
|
+
observed: require_json_fields.asNumber(a["gen_ai.guard.observed"]),
|
|
415
|
+
limit: require_json_fields.asNumber(a["gen_ai.guard.limit"])
|
|
430
416
|
};
|
|
431
417
|
}
|
|
432
418
|
function readGuardAndWarnings(attrs, events) {
|
|
433
|
-
const stopped =
|
|
419
|
+
const stopped = require_json_fields.asBoolean(attrs["gen_ai.guard.stopped"]);
|
|
434
420
|
const warnings = [];
|
|
435
421
|
let guard = readGuardDetails(attrs);
|
|
436
422
|
const apply = (next) => {
|
|
@@ -539,17 +525,17 @@ const KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
539
525
|
]);
|
|
540
526
|
function toGenAiSpan(span) {
|
|
541
527
|
const attrs = span.attributes ?? {};
|
|
542
|
-
const provider = normalizeProviderName(
|
|
543
|
-
const operation =
|
|
544
|
-
const requestModel =
|
|
545
|
-
const responseModel =
|
|
528
|
+
const provider = normalizeProviderName(require_json_fields.asString(attrs["gen_ai.provider.name"]) ?? require_json_fields.asString(attrs["gen_ai.system"]) ?? require_json_fields.asString(attrs["ai.model.provider"]) ?? "unknown");
|
|
529
|
+
const operation = require_json_fields.asString(attrs["gen_ai.operation.name"]) ?? "chat";
|
|
530
|
+
const requestModel = require_json_fields.asString(attrs["gen_ai.request.model"]) ?? require_json_fields.asString(attrs["llm.request.model"]) ?? require_json_fields.asString(attrs["model_name"]) ?? require_json_fields.asString(attrs["ai.model.id"]) ?? "unknown";
|
|
531
|
+
const responseModel = require_json_fields.asString(attrs["gen_ai.response.model"]) ?? require_json_fields.asString(attrs["llm.response.model"]) ?? require_json_fields.asString(attrs["ai.response.model"]);
|
|
546
532
|
const inputMessages = readMessagesAttribute(attrs, "gen_ai.input.messages") ?? [];
|
|
547
533
|
const outputMessages = readMessagesAttribute(attrs, "gen_ai.output.messages") ?? [];
|
|
548
534
|
let systemInstructions = [];
|
|
549
535
|
const rawSystem = parseJson(attrs["gen_ai.system_instructions"]);
|
|
550
536
|
if (Array.isArray(rawSystem) && rawSystem.length > 0) {
|
|
551
|
-
const first = rawSystem[0];
|
|
552
|
-
if (first &&
|
|
537
|
+
const first = require_json_fields.asObject(rawSystem[0]);
|
|
538
|
+
if (first && "role" in first) systemInstructions = rawSystem.map((m) => normalizeMessage(m));
|
|
553
539
|
else systemInstructions = [{
|
|
554
540
|
role: "system",
|
|
555
541
|
parts: rawSystem.map((p) => p.type === "text" || p.content !== void 0 ? {
|
|
@@ -566,8 +552,8 @@ function toGenAiSpan(span) {
|
|
|
566
552
|
...inputMessages,
|
|
567
553
|
...outputMessages
|
|
568
554
|
] : messagesFromEvents(span.events);
|
|
569
|
-
const inputRef =
|
|
570
|
-
const outputRef =
|
|
555
|
+
const inputRef = require_json_fields.asString(attrs["gen_ai.input.messages.ref"]);
|
|
556
|
+
const outputRef = require_json_fields.asString(attrs["gen_ai.output.messages.ref"]);
|
|
571
557
|
const hasInputContent = messages.some((m) => m.role === "system" || m.role === "user");
|
|
572
558
|
const hasOutputContent = messages.some((m) => m.role === "assistant");
|
|
573
559
|
if (inputRef && !hasInputContent) messages.push({
|
|
@@ -610,14 +596,14 @@ function toGenAiSpan(span) {
|
|
|
610
596
|
}
|
|
611
597
|
}
|
|
612
598
|
const aiResponseToolCalls = parseJson(attrs["ai.response.toolCalls"]);
|
|
613
|
-
const assistantToolCalls = Array.isArray(aiResponseToolCalls) ? aiResponseToolCalls.filter((c) =>
|
|
599
|
+
const assistantToolCalls = Array.isArray(aiResponseToolCalls) ? aiResponseToolCalls.filter((c) => require_json_fields.asString(c.toolName) !== void 0).map((c) => ({
|
|
614
600
|
id: c.toolCallId,
|
|
615
601
|
name: c.toolName,
|
|
616
602
|
arguments: parseJson(c.input ?? c.args) ?? c.input ?? c.args ?? {}
|
|
617
603
|
})) : void 0;
|
|
618
|
-
const aiResponseText =
|
|
604
|
+
const aiResponseText = require_json_fields.asString(attrs["ai.response.text"]);
|
|
619
605
|
if (aiResponseText || assistantToolCalls && assistantToolCalls.length > 0) {
|
|
620
|
-
const finishReason =
|
|
606
|
+
const finishReason = require_json_fields.asStringArray(attrs["gen_ai.response.finish_reasons"])?.[0] ?? require_json_fields.asString(attrs["ai.response.finishReason"]);
|
|
621
607
|
const msg = normalizeMessage({
|
|
622
608
|
role: "assistant",
|
|
623
609
|
content: aiResponseText ?? ""
|
|
@@ -634,7 +620,7 @@ function toGenAiSpan(span) {
|
|
|
634
620
|
if (messages.length === 0) {
|
|
635
621
|
const legacy = [];
|
|
636
622
|
for (let i = 0; i < 32; i++) {
|
|
637
|
-
const role =
|
|
623
|
+
const role = require_json_fields.asString(attrs[`gen_ai.prompt.${i}.role`]) ?? require_json_fields.asString(attrs[`llm.prompts.${i}.role`]);
|
|
638
624
|
const content = attrs[`gen_ai.prompt.${i}.content`] ?? attrs[`llm.prompts.${i}.content`];
|
|
639
625
|
if (!role) break;
|
|
640
626
|
legacy.push(normalizeMessage({
|
|
@@ -643,9 +629,9 @@ function toGenAiSpan(span) {
|
|
|
643
629
|
}));
|
|
644
630
|
}
|
|
645
631
|
for (let i = 0; i < 32; i++) {
|
|
646
|
-
const role =
|
|
632
|
+
const role = require_json_fields.asString(attrs[`gen_ai.completion.${i}.role`]) ?? require_json_fields.asString(attrs[`llm.completions.${i}.role`]);
|
|
647
633
|
const content = attrs[`gen_ai.completion.${i}.content`] ?? attrs[`llm.completions.${i}.content`];
|
|
648
|
-
const finishReason =
|
|
634
|
+
const finishReason = require_json_fields.asString(attrs[`gen_ai.completion.${i}.finish_reason`]);
|
|
649
635
|
if (!role) break;
|
|
650
636
|
const msg = normalizeMessage({
|
|
651
637
|
role,
|
|
@@ -692,7 +678,7 @@ function toGenAiSpan(span) {
|
|
|
692
678
|
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
693
679
|
cacheCreationInputTokens: usage.cacheCreationInputTokens
|
|
694
680
|
});
|
|
695
|
-
const reportedCost =
|
|
681
|
+
const reportedCost = require_json_fields.asNumber(attrs["gen_ai.usage.cost.usd"]);
|
|
696
682
|
const cost = reportedCost !== void 0 ? {
|
|
697
683
|
currency: "USD",
|
|
698
684
|
input: tableCost?.input ?? 0,
|
|
@@ -705,34 +691,34 @@ function toGenAiSpan(span) {
|
|
|
705
691
|
const streaming = readStreaming(attrs);
|
|
706
692
|
const session = readSession(attrs);
|
|
707
693
|
const { guard, warnings } = readGuardAndWarnings(attrs, span.events);
|
|
708
|
-
const finishReasons =
|
|
709
|
-
const agentName =
|
|
710
|
-
const agentId =
|
|
711
|
-
const agentDescription =
|
|
712
|
-
const toolName =
|
|
713
|
-
const toolCallId =
|
|
714
|
-
const handoffFrom =
|
|
715
|
-
const handoffTo =
|
|
716
|
-
const guardrailName =
|
|
717
|
-
const guardrailTriggered =
|
|
718
|
-
const evalName =
|
|
719
|
-
const evalScoreValue =
|
|
720
|
-
const evalScoreLabel =
|
|
721
|
-
const evalExplanation =
|
|
722
|
-
const audioIn =
|
|
723
|
-
const audioOut =
|
|
724
|
-
const speechVoice =
|
|
725
|
-
const speechInputText =
|
|
726
|
-
const transcriptionText =
|
|
727
|
-
const embeddingDims =
|
|
728
|
-
const consentOutcome =
|
|
729
|
-
const policyDecision =
|
|
730
|
-
const injectionVerdict =
|
|
731
|
-
const actionRiskClass =
|
|
732
|
-
const inputProvenance =
|
|
733
|
-
const planStepIndex =
|
|
734
|
-
const securityEvent =
|
|
735
|
-
const guardStoppedAttr =
|
|
694
|
+
const finishReasons = require_json_fields.asStringArray(attrs["gen_ai.response.finish_reasons"]);
|
|
695
|
+
const agentName = require_json_fields.asString(attrs["gen_ai.agent.name"]);
|
|
696
|
+
const agentId = require_json_fields.asString(attrs["gen_ai.agent.id"]);
|
|
697
|
+
const agentDescription = require_json_fields.asString(attrs["gen_ai.agent.description"]);
|
|
698
|
+
const toolName = require_json_fields.asString(attrs["gen_ai.tool.name"]);
|
|
699
|
+
const toolCallId = require_json_fields.asString(attrs["gen_ai.tool.call.id"]);
|
|
700
|
+
const handoffFrom = require_json_fields.asString(attrs["gen_ai.handoff.from_agent"]);
|
|
701
|
+
const handoffTo = require_json_fields.asString(attrs["gen_ai.handoff.to_agent"]);
|
|
702
|
+
const guardrailName = require_json_fields.asString(attrs["gen_ai.guardrail.name"]);
|
|
703
|
+
const guardrailTriggered = require_json_fields.asBoolean(attrs["gen_ai.guardrail.triggered"]);
|
|
704
|
+
const evalName = require_json_fields.asString(attrs["gen_ai.evaluation.name"]);
|
|
705
|
+
const evalScoreValue = require_json_fields.asNumber(attrs["gen_ai.evaluation.score.value"]);
|
|
706
|
+
const evalScoreLabel = require_json_fields.asString(attrs["gen_ai.evaluation.score.label"]);
|
|
707
|
+
const evalExplanation = require_json_fields.asString(attrs["gen_ai.evaluation.explanation"]);
|
|
708
|
+
const audioIn = require_json_fields.asString(attrs["gen_ai.audio.input.format"]);
|
|
709
|
+
const audioOut = require_json_fields.asString(attrs["gen_ai.audio.output.format"]);
|
|
710
|
+
const speechVoice = require_json_fields.asString(attrs["gen_ai.speech.voice"]);
|
|
711
|
+
const speechInputText = require_json_fields.asString(attrs["gen_ai.speech.input_text"]);
|
|
712
|
+
const transcriptionText = require_json_fields.asString(attrs["gen_ai.transcription.text"]);
|
|
713
|
+
const embeddingDims = require_json_fields.asNumber(attrs["gen_ai.embeddings.dimension.count"]);
|
|
714
|
+
const consentOutcome = require_json_fields.asString(attrs["agent.consent.outcome"]);
|
|
715
|
+
const policyDecision = require_json_fields.asString(attrs["policy.decision"]);
|
|
716
|
+
const injectionVerdict = require_json_fields.asString(attrs["mcp.security.injection.verdict"]);
|
|
717
|
+
const actionRiskClass = require_json_fields.asString(attrs["agent.action.risk_class"]);
|
|
718
|
+
const inputProvenance = require_json_fields.asString(attrs["agent.input.provenance"]);
|
|
719
|
+
const planStepIndex = require_json_fields.asNumber(attrs["agent.plan.step_index"]);
|
|
720
|
+
const securityEvent = require_json_fields.asString(attrs["security.event"]);
|
|
721
|
+
const guardStoppedAttr = require_json_fields.asBoolean(attrs["gen_ai.guard.stopped"]);
|
|
736
722
|
const agentSecurity = consentOutcome || policyDecision || injectionVerdict || actionRiskClass || inputProvenance || planStepIndex !== void 0 || securityEvent || guardStoppedAttr !== void 0 || guard?.stopped ? {
|
|
737
723
|
...consentOutcome && { consentOutcome },
|
|
738
724
|
...policyDecision && { policyDecision },
|
|
@@ -764,15 +750,15 @@ function toGenAiSpan(span) {
|
|
|
764
750
|
requestModel,
|
|
765
751
|
responseModel,
|
|
766
752
|
params: {
|
|
767
|
-
temperature:
|
|
768
|
-
topP:
|
|
769
|
-
topK:
|
|
770
|
-
maxTokens:
|
|
771
|
-
stopSequences:
|
|
772
|
-
seed:
|
|
773
|
-
frequencyPenalty:
|
|
774
|
-
presencePenalty:
|
|
775
|
-
choiceCount:
|
|
753
|
+
temperature: require_json_fields.asNumber(attrs["gen_ai.request.temperature"]),
|
|
754
|
+
topP: require_json_fields.asNumber(attrs["gen_ai.request.top_p"]),
|
|
755
|
+
topK: require_json_fields.asNumber(attrs["gen_ai.request.top_k"]),
|
|
756
|
+
maxTokens: require_json_fields.asNumber(attrs["gen_ai.request.max_tokens"]),
|
|
757
|
+
stopSequences: require_json_fields.asStringArray(attrs["gen_ai.request.stop_sequences"]),
|
|
758
|
+
seed: require_json_fields.asNumber(attrs["gen_ai.request.seed"]),
|
|
759
|
+
frequencyPenalty: require_json_fields.asNumber(attrs["gen_ai.request.frequency_penalty"]),
|
|
760
|
+
presencePenalty: require_json_fields.asNumber(attrs["gen_ai.request.presence_penalty"]),
|
|
761
|
+
choiceCount: require_json_fields.asNumber(attrs["gen_ai.request.choice.count"])
|
|
776
762
|
},
|
|
777
763
|
messages,
|
|
778
764
|
toolDefinitions: readToolDefinitions(attrs),
|
|
@@ -784,7 +770,7 @@ function toGenAiSpan(span) {
|
|
|
784
770
|
session,
|
|
785
771
|
warnings,
|
|
786
772
|
finishReasons,
|
|
787
|
-
responseId:
|
|
773
|
+
responseId: require_json_fields.asString(attrs["gen_ai.response.id"]),
|
|
788
774
|
agent: agentId || agentName || agentDescription ? {
|
|
789
775
|
id: agentId,
|
|
790
776
|
name: agentName,
|
|
@@ -802,7 +788,7 @@ function toGenAiSpan(span) {
|
|
|
802
788
|
name: guardrailName,
|
|
803
789
|
triggered: guardrailTriggered
|
|
804
790
|
} : void 0,
|
|
805
|
-
conversationId:
|
|
791
|
+
conversationId: require_json_fields.asString(attrs["gen_ai.conversation.id"]),
|
|
806
792
|
agentSecurity,
|
|
807
793
|
evaluation: evalName || evalScoreValue !== void 0 || evalScoreLabel || evalExplanation ? {
|
|
808
794
|
name: evalName,
|
|
@@ -819,12 +805,12 @@ function toGenAiSpan(span) {
|
|
|
819
805
|
embeddingDimensions: embeddingDims
|
|
820
806
|
} : void 0,
|
|
821
807
|
extras: {
|
|
822
|
-
openaiServiceTier:
|
|
823
|
-
request:
|
|
824
|
-
response:
|
|
808
|
+
openaiServiceTier: require_json_fields.asString(attrs["gen_ai.openai.request.service_tier"]) || require_json_fields.asString(attrs["gen_ai.openai.response.service_tier"]) || require_json_fields.asString(attrs["openai.request.service_tier"]) || require_json_fields.asString(attrs["openai.response.service_tier"]) ? {
|
|
809
|
+
request: require_json_fields.asString(attrs["gen_ai.openai.request.service_tier"]) ?? require_json_fields.asString(attrs["openai.request.service_tier"]),
|
|
810
|
+
response: require_json_fields.asString(attrs["gen_ai.openai.response.service_tier"]) ?? require_json_fields.asString(attrs["openai.response.service_tier"])
|
|
825
811
|
} : void 0,
|
|
826
|
-
openaiSystemFingerprint:
|
|
827
|
-
openaiResponseFormat:
|
|
812
|
+
openaiSystemFingerprint: require_json_fields.asString(attrs["gen_ai.openai.response.system_fingerprint"]) ?? require_json_fields.asString(attrs["openai.response.system_fingerprint"]),
|
|
813
|
+
openaiResponseFormat: require_json_fields.asString(attrs["gen_ai.openai.request.response_format"]) ?? require_json_fields.asString(attrs["openai.request.response_format"]),
|
|
828
814
|
raw
|
|
829
815
|
}
|
|
830
816
|
};
|
package/dist/genai/index.d.cts
CHANGED
|
@@ -1,35 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/widget/types.d.ts
|
|
3
|
-
interface SpanData {
|
|
4
|
-
traceId: string;
|
|
5
|
-
spanId: string;
|
|
6
|
-
parentSpanId?: string;
|
|
7
|
-
name: string;
|
|
8
|
-
kind: 'INTERNAL' | 'SERVER' | 'CLIENT' | 'PRODUCER' | 'CONSUMER';
|
|
9
|
-
startTime: number;
|
|
10
|
-
endTime: number;
|
|
11
|
-
duration: number;
|
|
12
|
-
attributes: Record<string, any>;
|
|
13
|
-
status: {
|
|
14
|
-
code: 'OK' | 'ERROR' | 'UNSET';
|
|
15
|
-
message?: string;
|
|
16
|
-
};
|
|
17
|
-
events?: Array<{
|
|
18
|
-
name: string;
|
|
19
|
-
timestamp: number;
|
|
20
|
-
attributes?: Record<string, any>;
|
|
21
|
-
}>;
|
|
22
|
-
links?: Array<{
|
|
23
|
-
traceId: string;
|
|
24
|
-
spanId: string;
|
|
25
|
-
attributes?: Record<string, any>;
|
|
26
|
-
}>;
|
|
27
|
-
scope?: {
|
|
28
|
-
name?: string;
|
|
29
|
-
version?: string;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
1
|
+
import { r as SpanData } from "../types-DHDvZnnn.cjs";
|
|
33
2
|
//#region src/widget/genai/detect.d.ts
|
|
34
3
|
declare function isGenAiSpan(span: SpanData): boolean;
|
|
35
4
|
//#endregion
|