@loongsuite/otel-util-genai 0.1.0-beta.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.
- package/LICENSE +201 -0
- package/README.md +262 -0
- package/dist/environment-variables.d.ts +8 -0
- package/dist/environment-variables.d.ts.map +1 -0
- package/dist/environment-variables.js +21 -0
- package/dist/environment-variables.js.map +1 -0
- package/dist/event-log/converter.d.ts +19 -0
- package/dist/event-log/converter.d.ts.map +1 -0
- package/dist/event-log/converter.js +216 -0
- package/dist/event-log/converter.js.map +1 -0
- package/dist/event-log/field-mapping.d.ts +53 -0
- package/dist/event-log/field-mapping.d.ts.map +1 -0
- package/dist/event-log/field-mapping.js +400 -0
- package/dist/event-log/field-mapping.js.map +1 -0
- package/dist/event-log/grouping.d.ts +67 -0
- package/dist/event-log/grouping.d.ts.map +1 -0
- package/dist/event-log/grouping.js +241 -0
- package/dist/event-log/grouping.js.map +1 -0
- package/dist/event-log/index.d.ts +5 -0
- package/dist/event-log/index.d.ts.map +1 -0
- package/dist/event-log/index.js +18 -0
- package/dist/event-log/index.js.map +1 -0
- package/dist/event-log/parent-context.d.ts +14 -0
- package/dist/event-log/parent-context.d.ts.map +1 -0
- package/dist/event-log/parent-context.js +45 -0
- package/dist/event-log/parent-context.js.map +1 -0
- package/dist/event-log/readable-spans.d.ts +36 -0
- package/dist/event-log/readable-spans.d.ts.map +1 -0
- package/dist/event-log/readable-spans.js +73 -0
- package/dist/event-log/readable-spans.js.map +1 -0
- package/dist/event-log/types.d.ts +78 -0
- package/dist/event-log/types.d.ts.map +1 -0
- package/dist/event-log/types.js +35 -0
- package/dist/event-log/types.js.map +1 -0
- package/dist/extended-environment-variables.d.ts +12 -0
- package/dist/extended-environment-variables.d.ts.map +1 -0
- package/dist/extended-environment-variables.js +25 -0
- package/dist/extended-environment-variables.js.map +1 -0
- package/dist/extended-handler.d.ts +50 -0
- package/dist/extended-handler.d.ts.map +1 -0
- package/dist/extended-handler.js +334 -0
- package/dist/extended-handler.js.map +1 -0
- package/dist/extended-metrics.d.ts +13 -0
- package/dist/extended-metrics.d.ts.map +1 -0
- package/dist/extended-metrics.js +27 -0
- package/dist/extended-metrics.js.map +1 -0
- package/dist/extended-span-utils.d.ts +14 -0
- package/dist/extended-span-utils.d.ts.map +1 -0
- package/dist/extended-span-utils.js +427 -0
- package/dist/extended-span-utils.js.map +1 -0
- package/dist/extended-types.d.ts +150 -0
- package/dist/extended-types.d.ts.map +1 -0
- package/dist/extended-types.js +46 -0
- package/dist/extended-types.js.map +1 -0
- package/dist/handler.d.ts +23 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +127 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/instruments.d.ts +4 -0
- package/dist/instruments.d.ts.map +1 -0
- package/dist/instruments.js +37 -0
- package/dist/instruments.js.map +1 -0
- package/dist/memory/memory-types.d.ts +26 -0
- package/dist/memory/memory-types.d.ts.map +1 -0
- package/dist/memory/memory-types.js +17 -0
- package/dist/memory/memory-types.js.map +1 -0
- package/dist/memory/memory-utils.d.ts +7 -0
- package/dist/memory/memory-utils.d.ts.map +1 -0
- package/dist/memory/memory-utils.js +121 -0
- package/dist/memory/memory-utils.js.map +1 -0
- package/dist/metrics.d.ts +11 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +77 -0
- package/dist/metrics.js.map +1 -0
- package/dist/semconv/gen-ai-extended-attributes.d.ts +101 -0
- package/dist/semconv/gen-ai-extended-attributes.d.ts.map +1 -0
- package/dist/semconv/gen-ai-extended-attributes.js +120 -0
- package/dist/semconv/gen-ai-extended-attributes.js.map +1 -0
- package/dist/semconv/gen-ai-memory-attributes.d.ts +28 -0
- package/dist/semconv/gen-ai-memory-attributes.d.ts.map +1 -0
- package/dist/semconv/gen-ai-memory-attributes.js +42 -0
- package/dist/semconv/gen-ai-memory-attributes.js.map +1 -0
- package/dist/span-utils.d.ts +18 -0
- package/dist/span-utils.d.ts.map +1 -0
- package/dist/span-utils.js +236 -0
- package/dist/span-utils.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +33 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +88 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
// Copyright The OpenTelemetry Authors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { createEntryInvocation, createExecuteToolInvocation, createInvokeAgentInvocation, createReactStepInvocation, } from "../extended-types.js";
|
|
15
|
+
import { createLLMInvocation, } from "../types.js";
|
|
16
|
+
import { EventName } from "./types.js";
|
|
17
|
+
/* -------------------------- primitive accessors -------------------------- */
|
|
18
|
+
function asString(value) {
|
|
19
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
20
|
+
}
|
|
21
|
+
function asNumber(value) {
|
|
22
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
23
|
+
return value;
|
|
24
|
+
if (typeof value === "string" && value.length > 0) {
|
|
25
|
+
const n = Number(value);
|
|
26
|
+
if (Number.isFinite(n))
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
function asStringArray(value) {
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
const arr = value.filter((v) => typeof v === "string" && v.length > 0);
|
|
34
|
+
return arr.length > 0 ? arr : undefined;
|
|
35
|
+
}
|
|
36
|
+
if (typeof value === "string" && value.length > 0) {
|
|
37
|
+
return [value];
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Read a uint64-nanosecond timestamp and return its millisecond value as
|
|
43
|
+
* understood by OTel JS SDK (which interprets startTime: number as ms).
|
|
44
|
+
*
|
|
45
|
+
* Accepts number, string (decimal), or bigint. Out-of-range values yield 0
|
|
46
|
+
* which lets the caller decide whether to warn or fall back.
|
|
47
|
+
*/
|
|
48
|
+
export function readNanoMs(value) {
|
|
49
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
50
|
+
return Math.floor(value / 1_000_000);
|
|
51
|
+
}
|
|
52
|
+
if (typeof value === "bigint" && value >= 0n) {
|
|
53
|
+
return Number(value / 1000000n);
|
|
54
|
+
}
|
|
55
|
+
if (typeof value === "string" && value.length > 0) {
|
|
56
|
+
try {
|
|
57
|
+
const b = BigInt(value);
|
|
58
|
+
if (b >= 0n)
|
|
59
|
+
return Number(b / 1000000n);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
const n = Number(value);
|
|
63
|
+
if (Number.isFinite(n) && n >= 0)
|
|
64
|
+
return Math.floor(n / 1_000_000);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
/* ----------------------------- JSON parsing ------------------------------ */
|
|
70
|
+
function parseJsonField(value) {
|
|
71
|
+
if (value == null)
|
|
72
|
+
return undefined;
|
|
73
|
+
if (typeof value !== "string")
|
|
74
|
+
return value;
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(value);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Parse messages as InputMessage[]. Accepts string (JSON) or parsed array. */
|
|
83
|
+
function parseInputMessages(raw) {
|
|
84
|
+
const parsed = parseJsonField(raw);
|
|
85
|
+
if (!Array.isArray(parsed))
|
|
86
|
+
return undefined;
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const m of parsed) {
|
|
89
|
+
if (m && typeof m === "object" && typeof m.role === "string") {
|
|
90
|
+
const rec = m;
|
|
91
|
+
const parts = Array.isArray(rec.parts) ? rec.parts : [];
|
|
92
|
+
out.push({ role: rec.role, parts });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return out.length > 0 ? out : undefined;
|
|
96
|
+
}
|
|
97
|
+
function parseOutputMessages(raw) {
|
|
98
|
+
const parsed = parseJsonField(raw);
|
|
99
|
+
if (!Array.isArray(parsed))
|
|
100
|
+
return undefined;
|
|
101
|
+
const out = [];
|
|
102
|
+
for (const m of parsed) {
|
|
103
|
+
if (m && typeof m === "object" && typeof m.role === "string") {
|
|
104
|
+
const rec = m;
|
|
105
|
+
const parts = Array.isArray(rec.parts) ? rec.parts : [];
|
|
106
|
+
const fr = rec.finish_reason ?? rec.finishReason;
|
|
107
|
+
out.push({
|
|
108
|
+
role: rec.role,
|
|
109
|
+
parts,
|
|
110
|
+
finishReason: typeof fr === "string" ? fr : "stop",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out.length > 0 ? out : undefined;
|
|
115
|
+
}
|
|
116
|
+
function parseSystemInstructions(raw) {
|
|
117
|
+
const parsed = parseJsonField(raw);
|
|
118
|
+
if (Array.isArray(parsed)) {
|
|
119
|
+
return parsed;
|
|
120
|
+
}
|
|
121
|
+
if (typeof parsed === "string") {
|
|
122
|
+
return [{ type: "text", content: parsed }];
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
function parseToolDefinitions(raw) {
|
|
127
|
+
const parsed = parseJsonField(raw);
|
|
128
|
+
if (!Array.isArray(parsed))
|
|
129
|
+
return undefined;
|
|
130
|
+
const out = [];
|
|
131
|
+
for (const td of parsed) {
|
|
132
|
+
if (td && typeof td === "object" && typeof td.name === "string") {
|
|
133
|
+
out.push({ ...td });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out.length > 0 ? out : undefined;
|
|
137
|
+
}
|
|
138
|
+
/* ----------------------- message-delta accumulator ----------------------- */
|
|
139
|
+
/**
|
|
140
|
+
* Build complete input messages for an LLM invocation by walking the turn's
|
|
141
|
+
* LLM pairs in order.
|
|
142
|
+
*
|
|
143
|
+
* Priority:
|
|
144
|
+
* 1. If the matching llm.request has gen_ai.input.messages (full), use it.
|
|
145
|
+
* 2. Else accumulate gen_ai.input.messages_delta from all prior llm.request
|
|
146
|
+
* records in the same turn (plus the current one).
|
|
147
|
+
*/
|
|
148
|
+
export function buildAccumulatedInputMessages(pairs, targetPairIndex) {
|
|
149
|
+
const target = pairs[targetPairIndex]?.request;
|
|
150
|
+
if (!target)
|
|
151
|
+
return [];
|
|
152
|
+
// Full messages on the target wins.
|
|
153
|
+
const full = parseInputMessages(target["gen_ai.input.messages"]);
|
|
154
|
+
if (full)
|
|
155
|
+
return full;
|
|
156
|
+
// Otherwise concat deltas of all prior + current requests.
|
|
157
|
+
const out = [];
|
|
158
|
+
for (let i = 0; i <= targetPairIndex; i++) {
|
|
159
|
+
const req = pairs[i]?.request;
|
|
160
|
+
if (!req)
|
|
161
|
+
continue;
|
|
162
|
+
const delta = parseInputMessages(req["gen_ai.input.messages_delta"]);
|
|
163
|
+
if (delta)
|
|
164
|
+
out.push(...delta);
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
/* --------------------------- invocation builders ------------------------- */
|
|
169
|
+
/** Default provider when missing from the event log. */
|
|
170
|
+
const DEFAULT_PROVIDER = "unknown";
|
|
171
|
+
/**
|
|
172
|
+
* Collect input messages from user-hook events (events that look like
|
|
173
|
+
* llm.request but actually mark "user prompt submitted"). Returns them in
|
|
174
|
+
* time order. Used by ENTRY/AGENT builders when user-hook events exist.
|
|
175
|
+
*/
|
|
176
|
+
function collectUserHookInputMessages(userHookRecords) {
|
|
177
|
+
if (userHookRecords.length === 0)
|
|
178
|
+
return [];
|
|
179
|
+
const sorted = [...userHookRecords].sort((a, b) => readNanoMs(a["time_unix_nano"]) - readNanoMs(b["time_unix_nano"]));
|
|
180
|
+
const out = [];
|
|
181
|
+
for (const hook of sorted) {
|
|
182
|
+
const msgs = parseInputMessages(hook["gen_ai.input.messages_delta"]) ??
|
|
183
|
+
parseInputMessages(hook["gen_ai.input.messages"]);
|
|
184
|
+
if (msgs)
|
|
185
|
+
out.push(...msgs);
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Build an EntryInvocation from a turn's records.
|
|
191
|
+
*
|
|
192
|
+
* @param turnRecords records remaining after user-hook events are removed
|
|
193
|
+
* @param userHookRecords events identified as user-input hook prompts;
|
|
194
|
+
* their messages_delta becomes the ENTRY input.
|
|
195
|
+
* If empty, falls back to the first real llm.request.
|
|
196
|
+
*/
|
|
197
|
+
export function buildEntryInvocation(turnRecords, userHookRecords = []) {
|
|
198
|
+
const first = turnRecords[0] ?? userHookRecords[0];
|
|
199
|
+
const sessionId = first ? asString(first["gen_ai.session.id"]) : undefined;
|
|
200
|
+
const userId = first ? asString(first["user.id"]) : undefined;
|
|
201
|
+
// Prefer user-hook events as the authoritative source of user input;
|
|
202
|
+
// fall back to the first llm.request's messages_delta only if no
|
|
203
|
+
// user-hook event exists.
|
|
204
|
+
let inputMessages = collectUserHookInputMessages(userHookRecords);
|
|
205
|
+
if (inputMessages.length === 0) {
|
|
206
|
+
const llmReq = turnRecords.find((r) => r["event.name"] === EventName.LLM_REQUEST);
|
|
207
|
+
if (llmReq) {
|
|
208
|
+
inputMessages = parseInputMessages(llmReq["gen_ai.input.messages_delta"]) ?? [];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const llmResp = [...turnRecords]
|
|
212
|
+
.reverse()
|
|
213
|
+
.find((r) => r["event.name"] === EventName.LLM_RESPONSE);
|
|
214
|
+
const outputMessages = (llmResp && parseOutputMessages(llmResp["gen_ai.output.messages"])) ?? [];
|
|
215
|
+
return createEntryInvocation({
|
|
216
|
+
sessionId: sessionId ?? null,
|
|
217
|
+
userId: userId ?? null,
|
|
218
|
+
inputMessages,
|
|
219
|
+
outputMessages,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/** Build an InvokeAgentInvocation by aggregating turn-level metadata. */
|
|
223
|
+
export function buildInvokeAgentInvocation(turnRecords, userHookRecords = []) {
|
|
224
|
+
const first = turnRecords[0] ?? userHookRecords[0] ?? {};
|
|
225
|
+
const provider = asString(first["gen_ai.provider.name"]) ?? DEFAULT_PROVIDER;
|
|
226
|
+
const requestModel = asString(first["gen_ai.request.model"]) ??
|
|
227
|
+
turnRecords
|
|
228
|
+
.map((r) => asString(r["gen_ai.request.model"]))
|
|
229
|
+
.find((v) => !!v) ??
|
|
230
|
+
null;
|
|
231
|
+
// Aggregate token usage from llm.response events.
|
|
232
|
+
let totalInput = 0;
|
|
233
|
+
let totalOutput = 0;
|
|
234
|
+
let totalCacheCreate = 0;
|
|
235
|
+
let totalCacheRead = 0;
|
|
236
|
+
let sawAny = false;
|
|
237
|
+
let responseModel = null;
|
|
238
|
+
let lastResponseId = null;
|
|
239
|
+
for (const r of turnRecords) {
|
|
240
|
+
if (r["event.name"] !== EventName.LLM_RESPONSE)
|
|
241
|
+
continue;
|
|
242
|
+
const inT = asNumber(r["gen_ai.usage.input_tokens"]);
|
|
243
|
+
const outT = asNumber(r["gen_ai.usage.output_tokens"]);
|
|
244
|
+
const ccT = asNumber(r["gen_ai.usage.cache_creation.input_tokens"]);
|
|
245
|
+
const crT = asNumber(r["gen_ai.usage.cache_read.input_tokens"]);
|
|
246
|
+
if (inT != null) {
|
|
247
|
+
totalInput += inT;
|
|
248
|
+
sawAny = true;
|
|
249
|
+
}
|
|
250
|
+
if (outT != null) {
|
|
251
|
+
totalOutput += outT;
|
|
252
|
+
sawAny = true;
|
|
253
|
+
}
|
|
254
|
+
if (ccT != null)
|
|
255
|
+
totalCacheCreate += ccT;
|
|
256
|
+
if (crT != null)
|
|
257
|
+
totalCacheRead += crT;
|
|
258
|
+
responseModel = asString(r["gen_ai.response.model"]) ?? responseModel;
|
|
259
|
+
lastResponseId = asString(r["gen_ai.response.id"]) ?? lastResponseId;
|
|
260
|
+
}
|
|
261
|
+
const llmReq = turnRecords.find((r) => r["event.name"] === EventName.LLM_REQUEST);
|
|
262
|
+
const llmResp = [...turnRecords]
|
|
263
|
+
.reverse()
|
|
264
|
+
.find((r) => r["event.name"] === EventName.LLM_RESPONSE);
|
|
265
|
+
// Prefer user-hook events for input.messages (same rule as ENTRY).
|
|
266
|
+
let inputMessages = collectUserHookInputMessages(userHookRecords);
|
|
267
|
+
if (inputMessages.length === 0) {
|
|
268
|
+
inputMessages =
|
|
269
|
+
(llmReq && parseInputMessages(llmReq["gen_ai.input.messages_delta"])) ?? [];
|
|
270
|
+
}
|
|
271
|
+
const outputMessages = (llmResp && parseOutputMessages(llmResp["gen_ai.output.messages"])) ?? [];
|
|
272
|
+
// system_instructions / tool_definitions: optimistically read from first
|
|
273
|
+
// record that carries them (schema upgrade in progress).
|
|
274
|
+
const sysRec = turnRecords.find((r) => r["gen_ai.system_instructions"] != null);
|
|
275
|
+
const toolDefsRec = turnRecords.find((r) => r["gen_ai.tool.definitions"] != null);
|
|
276
|
+
return createInvokeAgentInvocation(provider, {
|
|
277
|
+
agentName: asString(first["gen_ai.agent.name"]) ?? asString(first["gen_ai.agent.type"]) ?? null,
|
|
278
|
+
agentId: asString(first["gen_ai.agent.id"]) ?? null,
|
|
279
|
+
conversationId: asString(first["gen_ai.session.id"]) ?? null,
|
|
280
|
+
requestModel,
|
|
281
|
+
responseModelName: responseModel,
|
|
282
|
+
responseId: lastResponseId,
|
|
283
|
+
inputTokens: sawAny ? totalInput : null,
|
|
284
|
+
outputTokens: sawAny ? totalOutput : null,
|
|
285
|
+
usageCacheCreationInputTokens: totalCacheCreate > 0 ? totalCacheCreate : null,
|
|
286
|
+
usageCacheReadInputTokens: totalCacheRead > 0 ? totalCacheRead : null,
|
|
287
|
+
inputMessages,
|
|
288
|
+
outputMessages,
|
|
289
|
+
systemInstruction: sysRec ? parseSystemInstructions(sysRec["gen_ai.system_instructions"]) ?? [] : [],
|
|
290
|
+
toolDefinitions: toolDefsRec ? parseToolDefinitions(toolDefsRec["gen_ai.tool.definitions"]) ?? [] : [],
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/** Build a ReactStepInvocation from a step's records. */
|
|
294
|
+
export function buildReactStepInvocation(stepRecords) {
|
|
295
|
+
const first = stepRecords[0] ?? {};
|
|
296
|
+
// Round may be carried explicitly (gen_ai.react.round) or derivable from
|
|
297
|
+
// step.id suffix like "step_3" or "...:s3".
|
|
298
|
+
let round = null;
|
|
299
|
+
const explicitRound = asNumber(first["gen_ai.react.round"]);
|
|
300
|
+
if (explicitRound != null) {
|
|
301
|
+
round = explicitRound;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const stepId = asString(first["gen_ai.step.id"]);
|
|
305
|
+
if (stepId) {
|
|
306
|
+
const m = stepId.match(/(?:^|[_:s])(\d+)$/);
|
|
307
|
+
if (m)
|
|
308
|
+
round = Number(m[1]);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// finishReason may be carried explicitly (gen_ai.react.finish_reason) or
|
|
312
|
+
// derived from the last llm.response in the step.
|
|
313
|
+
let finishReason = asString(first["gen_ai.react.finish_reason"]) ?? null;
|
|
314
|
+
if (!finishReason) {
|
|
315
|
+
const lastResp = [...stepRecords]
|
|
316
|
+
.reverse()
|
|
317
|
+
.find((r) => r["event.name"] === EventName.LLM_RESPONSE);
|
|
318
|
+
if (lastResp) {
|
|
319
|
+
const reasons = asStringArray(lastResp["gen_ai.response.finish_reasons"]);
|
|
320
|
+
if (reasons?.length)
|
|
321
|
+
finishReason = reasons[0];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return createReactStepInvocation({
|
|
325
|
+
round,
|
|
326
|
+
finishReason,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Build an LLMInvocation from a paired llm.request + llm.response.
|
|
331
|
+
*
|
|
332
|
+
* Either side may be undefined (orphan event). The accumulator parameters let
|
|
333
|
+
* the caller supply complete input messages reconstructed across the turn's
|
|
334
|
+
* deltas; passing undefined falls back to reading messages off the request
|
|
335
|
+
* record alone.
|
|
336
|
+
*/
|
|
337
|
+
export function buildLlmInvocation(pair, accumulatedInputMessages, turnSystemInstruction, turnToolDefinitions) {
|
|
338
|
+
const req = pair.request;
|
|
339
|
+
const resp = pair.response;
|
|
340
|
+
const source = req ?? resp ?? {};
|
|
341
|
+
const provider = asString(source["gen_ai.provider.name"]) ?? DEFAULT_PROVIDER;
|
|
342
|
+
const requestModel = asString(source["gen_ai.request.model"]) ??
|
|
343
|
+
asString(req?.["gen_ai.request.model"]) ??
|
|
344
|
+
asString(resp?.["gen_ai.request.model"]) ??
|
|
345
|
+
null;
|
|
346
|
+
const inputMessages = accumulatedInputMessages ??
|
|
347
|
+
(req ? parseInputMessages(req["gen_ai.input.messages"]) : undefined) ??
|
|
348
|
+
[];
|
|
349
|
+
const outputMessages = (resp ? parseOutputMessages(resp["gen_ai.output.messages"]) : undefined) ?? [];
|
|
350
|
+
const finishReasons = (resp ? asStringArray(resp["gen_ai.response.finish_reasons"]) : undefined) ?? null;
|
|
351
|
+
const inputTokens = resp ? asNumber(resp["gen_ai.usage.input_tokens"]) ?? null : null;
|
|
352
|
+
const outputTokens = resp ? asNumber(resp["gen_ai.usage.output_tokens"]) ?? null : null;
|
|
353
|
+
const cacheCreate = resp ? asNumber(resp["gen_ai.usage.cache_creation.input_tokens"]) ?? null : null;
|
|
354
|
+
const cacheRead = resp ? asNumber(resp["gen_ai.usage.cache_read.input_tokens"]) ?? null : null;
|
|
355
|
+
return createLLMInvocation({
|
|
356
|
+
operationName: "chat",
|
|
357
|
+
provider,
|
|
358
|
+
requestModel,
|
|
359
|
+
responseModelName: (resp ? asString(resp["gen_ai.response.model"]) : undefined) ?? requestModel,
|
|
360
|
+
responseId: (resp ? asString(resp["gen_ai.response.id"]) : undefined) ?? null,
|
|
361
|
+
conversationId: asString(source["gen_ai.session.id"]) ?? null,
|
|
362
|
+
finishReasons,
|
|
363
|
+
inputTokens,
|
|
364
|
+
outputTokens,
|
|
365
|
+
usageCacheCreationInputTokens: cacheCreate,
|
|
366
|
+
usageCacheReadInputTokens: cacheRead,
|
|
367
|
+
inputMessages,
|
|
368
|
+
outputMessages,
|
|
369
|
+
systemInstruction: turnSystemInstruction ?? [],
|
|
370
|
+
toolDefinitions: turnToolDefinitions ?? [],
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
/** Build an ExecuteToolInvocation from a tool.call + tool.result pair. */
|
|
374
|
+
export function buildExecuteToolInvocation(pair) {
|
|
375
|
+
const source = pair.call ?? pair.result ?? {};
|
|
376
|
+
const toolName = asString(source["gen_ai.tool.name"]) ?? "unknown";
|
|
377
|
+
return createExecuteToolInvocation(toolName, {
|
|
378
|
+
toolCallId: asString(source["gen_ai.tool.call.id"]) ?? null,
|
|
379
|
+
toolType: asString(source["gen_ai.tool.type"]) ?? "function",
|
|
380
|
+
toolDescription: asString(source["gen_ai.tool.description"]) ?? null,
|
|
381
|
+
toolCallArguments: pair.call?.["gen_ai.tool.call.arguments"] ?? null,
|
|
382
|
+
toolCallResult: pair.result?.["gen_ai.tool.call.result"] ?? null,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/* -------- helpers exposed for converter to read turn-level fields -------- */
|
|
386
|
+
/** Pull system_instructions for a turn (first record carrying them). */
|
|
387
|
+
export function readTurnSystemInstruction(turnRecords) {
|
|
388
|
+
const rec = turnRecords.find((r) => r["gen_ai.system_instructions"] != null);
|
|
389
|
+
if (!rec)
|
|
390
|
+
return undefined;
|
|
391
|
+
return parseSystemInstructions(rec["gen_ai.system_instructions"]);
|
|
392
|
+
}
|
|
393
|
+
/** Pull tool_definitions for a turn (first record carrying them). */
|
|
394
|
+
export function readTurnToolDefinitions(turnRecords) {
|
|
395
|
+
const rec = turnRecords.find((r) => r["gen_ai.tool.definitions"] != null);
|
|
396
|
+
if (!rec)
|
|
397
|
+
return undefined;
|
|
398
|
+
return parseToolDefinitions(rec["gen_ai.tool.definitions"]);
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=field-mapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-mapping.js","sourceRoot":"","sources":["../../src/event-log/field-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type EventLogRecord, type LlmPair, type StepGroup, type ToolPair, type TurnGroup } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Candidate predicate for "user-input hook" llm.request events.
|
|
4
|
+
*
|
|
5
|
+
* Rule: an llm.request that has neither gen_ai.step.id nor
|
|
6
|
+
* gen_ai.request.model is a structural sign that the plugin is using
|
|
7
|
+
* llm.request to mark user-prompt submission (not a real LLM API call).
|
|
8
|
+
*
|
|
9
|
+
* This is only the structural check; the converter must also verify the
|
|
10
|
+
* event has no matching llm.response in the turn before routing it to ENTRY.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isUserHookCandidate(record: EventLogRecord): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Within a turn's records, identify which llm.request events should be
|
|
15
|
+
* treated as user-hook prompts (merged into ENTRY) versus kept for normal
|
|
16
|
+
* LLM-span generation.
|
|
17
|
+
*
|
|
18
|
+
* Rule: structural candidate (no step.id, no model) AND no peer llm.response
|
|
19
|
+
* that could conceivably pair with it. A real LLM call always has step.id,
|
|
20
|
+
* so its response also has step.id. A user-hook candidate (no step.id) can
|
|
21
|
+
* only legitimately pair with a no-step llm.response — which never exists
|
|
22
|
+
* in well-formed data. So we declare the candidate user-hook iff there is
|
|
23
|
+
* no llm.response in the same turn that also lacks step.id.
|
|
24
|
+
*
|
|
25
|
+
* This avoids cross-step mispairing (where the time-ordered pairLlm could
|
|
26
|
+
* otherwise greedy-match a candidate with a later step's response).
|
|
27
|
+
*/
|
|
28
|
+
export declare function partitionUserHookRequests(turnRecords: EventLogRecord[]): {
|
|
29
|
+
userHooks: EventLogRecord[];
|
|
30
|
+
remaining: EventLogRecord[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Group records by turn. Insertion order of turns is preserved (matches order
|
|
34
|
+
* the first record of each turn appears in the input).
|
|
35
|
+
*
|
|
36
|
+
* If multiple records within a turn carry different trace_id values the
|
|
37
|
+
* first valid one wins and a warning is pushed.
|
|
38
|
+
*/
|
|
39
|
+
export declare function groupByTurn(records: EventLogRecord[], warnings: string[]): TurnGroup[];
|
|
40
|
+
/**
|
|
41
|
+
* Group records within a turn by gen_ai.step.id. Records missing step.id are
|
|
42
|
+
* placed into a synthetic "__no_step__" group, which still produces one STEP
|
|
43
|
+
* span downstream.
|
|
44
|
+
*
|
|
45
|
+
* Insertion order is preserved.
|
|
46
|
+
*/
|
|
47
|
+
export declare function groupByStep(records: EventLogRecord[]): StepGroup[];
|
|
48
|
+
/**
|
|
49
|
+
* Pair llm.request with the following llm.response within the same step.
|
|
50
|
+
*
|
|
51
|
+
* Matching rules (in order):
|
|
52
|
+
* 1. If both records share a non-empty gen_ai.response.id, prefer ID match.
|
|
53
|
+
* (response.id appears on the response and sometimes is mirrored back to
|
|
54
|
+
* the request by the producer.)
|
|
55
|
+
* 2. Otherwise pair each request with the next unpaired response in
|
|
56
|
+
* time_unix_nano order.
|
|
57
|
+
*
|
|
58
|
+
* Orphan request/response records are returned as pairs with the other side
|
|
59
|
+
* undefined.
|
|
60
|
+
*/
|
|
61
|
+
export declare function pairLlm(records: EventLogRecord[], warnings: string[]): LlmPair[];
|
|
62
|
+
/**
|
|
63
|
+
* Pair tool.call with tool.result by gen_ai.tool.call.id. Orphans are
|
|
64
|
+
* returned with the missing side undefined.
|
|
65
|
+
*/
|
|
66
|
+
export declare function pairTool(records: EventLogRecord[], warnings: string[]): ToolPair[];
|
|
67
|
+
//# sourceMappingURL=grouping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grouping.d.ts","sourceRoot":"","sources":["../../src/event-log/grouping.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAMnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,cAAc,EAAE,GAC5B;IAAE,SAAS,EAAE,cAAc,EAAE,CAAC;IAAC,SAAS,EAAE,cAAc,EAAE,CAAA;CAAE,CA2B9D;AAeD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,MAAM,EAAE,GACjB,SAAS,EAAE,CA4Cb;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,CAelE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,EAAE,CA8CX;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,EAAE,CAuCZ"}
|