@tangle-network/traces 0.3.0 → 0.4.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/dist/{chunk-6NILXLUI.js → chunk-33NBMIH4.js} +292 -84
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -144,6 +144,11 @@ import { readdir, readFile, stat } from "fs/promises";
|
|
|
144
144
|
import { homedir } from "os";
|
|
145
145
|
import { basename, join } from "path";
|
|
146
146
|
var SERVICE = "amp";
|
|
147
|
+
var CONTENT_CAP = 8e3;
|
|
148
|
+
function textOf(content) {
|
|
149
|
+
if (typeof content === "string") return content.slice(0, CONTENT_CAP);
|
|
150
|
+
return (Array.isArray(content) ? content : []).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n").trim().slice(0, CONTENT_CAP);
|
|
151
|
+
}
|
|
147
152
|
var AmpAdapter = class {
|
|
148
153
|
harness = "amp";
|
|
149
154
|
threadsRoot() {
|
|
@@ -192,25 +197,47 @@ var AmpAdapter = class {
|
|
|
192
197
|
for (const m of messages) {
|
|
193
198
|
const mid = m.messageId ?? step;
|
|
194
199
|
const llmId = `llm:${mid}`;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
200
|
+
if (m.role === "user") {
|
|
201
|
+
const prompt = textOf(m.content);
|
|
202
|
+
if (prompt) {
|
|
203
|
+
spans.push(
|
|
204
|
+
span({
|
|
205
|
+
traceId,
|
|
206
|
+
spanId: `${llmId}:user`,
|
|
207
|
+
parentSpanId: rootId,
|
|
208
|
+
name: "user.prompt",
|
|
209
|
+
kind: "CHAIN",
|
|
210
|
+
startTime: start,
|
|
211
|
+
service: SERVICE,
|
|
212
|
+
agent: SERVICE,
|
|
213
|
+
step,
|
|
214
|
+
content: prompt
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
step += 1;
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
const u = m.usage;
|
|
221
|
+
const inputTokens2 = u ? (u.inputTokens ?? 0) + (u.cacheReadInputTokens ?? 0) + (u.cacheCreationInputTokens ?? 0) || null : null;
|
|
222
|
+
spans.push(
|
|
223
|
+
span({
|
|
224
|
+
traceId,
|
|
225
|
+
spanId: llmId,
|
|
226
|
+
parentSpanId: rootId,
|
|
227
|
+
name: `message.${m.role ?? "unknown"}`,
|
|
228
|
+
kind: "LLM",
|
|
229
|
+
startTime: start,
|
|
230
|
+
service: SERVICE,
|
|
231
|
+
agent: SERVICE,
|
|
232
|
+
model: u?.model ?? null,
|
|
233
|
+
inputTokens: inputTokens2,
|
|
234
|
+
outputTokens: u?.outputTokens ?? null,
|
|
235
|
+
step,
|
|
236
|
+
content: textOf(m.content) || null
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
step += 1;
|
|
240
|
+
}
|
|
214
241
|
for (const b of m.content ?? []) {
|
|
215
242
|
if (b.type === "tool_use" && b.name) {
|
|
216
243
|
const t = span({
|
|
@@ -263,6 +290,11 @@ function inputTokens(u) {
|
|
|
263
290
|
function asBlocks(content) {
|
|
264
291
|
return Array.isArray(content) ? content : [];
|
|
265
292
|
}
|
|
293
|
+
var CONTENT_CAP2 = 8e3;
|
|
294
|
+
function textOf2(content) {
|
|
295
|
+
if (typeof content === "string") return content.slice(0, CONTENT_CAP2);
|
|
296
|
+
return asBlocks(content).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n").trim().slice(0, CONTENT_CAP2);
|
|
297
|
+
}
|
|
266
298
|
function stringifyToolResult(content) {
|
|
267
299
|
if (typeof content === "string") return content;
|
|
268
300
|
if (Array.isArray(content)) {
|
|
@@ -292,7 +324,8 @@ function parseClaudeStream(events, ctx) {
|
|
|
292
324
|
model: ev.message.model ?? null,
|
|
293
325
|
inputTokens: inputTokens(ev.message.usage),
|
|
294
326
|
outputTokens: ev.message.usage?.output_tokens ?? null,
|
|
295
|
-
step
|
|
327
|
+
step,
|
|
328
|
+
content: textOf2(ev.message.content) || null
|
|
296
329
|
})
|
|
297
330
|
);
|
|
298
331
|
step += 1;
|
|
@@ -318,6 +351,24 @@ function parseClaudeStream(events, ctx) {
|
|
|
318
351
|
step += 1;
|
|
319
352
|
}
|
|
320
353
|
} else if (ev.type === "user" && ev.message) {
|
|
354
|
+
const prompt = textOf2(ev.message.content);
|
|
355
|
+
if (prompt) {
|
|
356
|
+
spans.push(
|
|
357
|
+
span({
|
|
358
|
+
traceId: ctx.traceId,
|
|
359
|
+
spanId: `${ctx.idPrefix}${uid}:user`,
|
|
360
|
+
parentSpanId: ctx.rootParent,
|
|
361
|
+
name: "user.prompt",
|
|
362
|
+
kind: "CHAIN",
|
|
363
|
+
startTime: ts,
|
|
364
|
+
service: SERVICE2,
|
|
365
|
+
agent: ctx.agent,
|
|
366
|
+
step,
|
|
367
|
+
content: prompt
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
step += 1;
|
|
371
|
+
}
|
|
321
372
|
for (const block of asBlocks(ev.message.content)) {
|
|
322
373
|
if (block.type !== "tool_result" || !block.tool_use_id) continue;
|
|
323
374
|
backfillResult(toolSpanByUseId.get(block.tool_use_id), ts, block.is_error === true, stringifyToolResult(block.content));
|
|
@@ -467,6 +518,10 @@ function contentToString(content) {
|
|
|
467
518
|
}
|
|
468
519
|
return "";
|
|
469
520
|
}
|
|
521
|
+
var CONTENT_CAP3 = 8e3;
|
|
522
|
+
function textOf3(content) {
|
|
523
|
+
return contentToString(content).trim().slice(0, CONTENT_CAP3);
|
|
524
|
+
}
|
|
470
525
|
function outputIsError(output) {
|
|
471
526
|
const s = typeof output === "string" ? output : JSON.stringify(output ?? "");
|
|
472
527
|
const error = /"success"\s*:\s*false|exit(?:_| )code["\s:]+[1-9]|\bcommand failed\b|\bENOENT\b|\berror:/i.test(s);
|
|
@@ -614,8 +669,27 @@ var CodexAdapter = class {
|
|
|
614
669
|
t.end_time = ts;
|
|
615
670
|
t.status = error ? { code: "ERROR", message } : { code: "OK" };
|
|
616
671
|
}
|
|
672
|
+
} else if (l.type === "response_item" && l.payload?.type === "message" && l.payload.role === "user") {
|
|
673
|
+
const prompt = textOf3(l.payload.content);
|
|
674
|
+
if (prompt) {
|
|
675
|
+
spans.push(
|
|
676
|
+
span({
|
|
677
|
+
traceId,
|
|
678
|
+
spanId: `msg:${step}:user`,
|
|
679
|
+
parentSpanId: rootId,
|
|
680
|
+
name: "user.prompt",
|
|
681
|
+
kind: "CHAIN",
|
|
682
|
+
startTime: ts,
|
|
683
|
+
service: SERVICE3,
|
|
684
|
+
agent: SERVICE3,
|
|
685
|
+
step,
|
|
686
|
+
content: prompt
|
|
687
|
+
})
|
|
688
|
+
);
|
|
689
|
+
step += 1;
|
|
690
|
+
}
|
|
617
691
|
} else if (l.type === "response_item" && l.payload?.type === "message") {
|
|
618
|
-
const text =
|
|
692
|
+
const text = textOf3(l.payload.content);
|
|
619
693
|
if (text) {
|
|
620
694
|
spans.push(
|
|
621
695
|
span({
|
|
@@ -628,7 +702,7 @@ var CodexAdapter = class {
|
|
|
628
702
|
service: SERVICE3,
|
|
629
703
|
agent: SERVICE3,
|
|
630
704
|
step,
|
|
631
|
-
content: text
|
|
705
|
+
content: text
|
|
632
706
|
})
|
|
633
707
|
);
|
|
634
708
|
step += 1;
|
|
@@ -770,6 +844,10 @@ import { readdir as readdir5, readFile as readFile5, stat as stat5 } from "fs/pr
|
|
|
770
844
|
import { homedir as homedir5 } from "os";
|
|
771
845
|
import { basename as basename4, join as join5 } from "path";
|
|
772
846
|
var SERVICE5 = "factory";
|
|
847
|
+
var CONTENT_CAP4 = 8e3;
|
|
848
|
+
function textOf4(content) {
|
|
849
|
+
return (content ?? []).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("").trim().slice(0, CONTENT_CAP4);
|
|
850
|
+
}
|
|
773
851
|
function parseLines4(raw) {
|
|
774
852
|
const out = [];
|
|
775
853
|
for (const line of raw.split("\n")) {
|
|
@@ -856,25 +934,45 @@ var FactoryAdapter = class {
|
|
|
856
934
|
if (l.type !== "message" || !l.message) continue;
|
|
857
935
|
const ts = l.timestamp ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
858
936
|
const role = l.message.role;
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
937
|
+
const text = textOf4(l.message.content);
|
|
938
|
+
if (role === "user") {
|
|
939
|
+
if (text) {
|
|
940
|
+
spans.push(
|
|
941
|
+
span({
|
|
942
|
+
traceId,
|
|
943
|
+
spanId: `user:${l.id ?? step}`,
|
|
944
|
+
parentSpanId: rootId,
|
|
945
|
+
name: "user.prompt",
|
|
946
|
+
kind: "CHAIN",
|
|
947
|
+
startTime: ts,
|
|
948
|
+
service: SERVICE5,
|
|
949
|
+
agent: SERVICE5,
|
|
950
|
+
step,
|
|
951
|
+
content: text
|
|
952
|
+
})
|
|
953
|
+
);
|
|
954
|
+
step += 1;
|
|
955
|
+
}
|
|
956
|
+
} else {
|
|
957
|
+
const llmId = `llm:${l.id ?? step}`;
|
|
958
|
+
spans.push(
|
|
959
|
+
span({
|
|
960
|
+
traceId,
|
|
961
|
+
spanId: llmId,
|
|
962
|
+
parentSpanId: rootId,
|
|
963
|
+
name: `message.${role ?? "unknown"}`,
|
|
964
|
+
kind: "LLM",
|
|
965
|
+
startTime: ts,
|
|
966
|
+
service: SERVICE5,
|
|
967
|
+
agent: SERVICE5,
|
|
968
|
+
model: settings.model ?? null,
|
|
969
|
+
step,
|
|
970
|
+
content: text || null
|
|
971
|
+
})
|
|
972
|
+
);
|
|
973
|
+
lastLlm = llmId;
|
|
974
|
+
step += 1;
|
|
975
|
+
}
|
|
878
976
|
for (const b of l.message.content ?? []) {
|
|
879
977
|
if (b.type === "tool_use" && b.name) {
|
|
880
978
|
const t = span({
|
|
@@ -912,6 +1010,10 @@ function tokens(t) {
|
|
|
912
1010
|
if (!t) return null;
|
|
913
1011
|
return t.actual ?? t.approx ?? null;
|
|
914
1012
|
}
|
|
1013
|
+
var CONTENT_CAP5 = 8e3;
|
|
1014
|
+
function textOf5(content) {
|
|
1015
|
+
return (content ?? "").trim().slice(0, CONTENT_CAP5);
|
|
1016
|
+
}
|
|
915
1017
|
var ForgeAdapter = class {
|
|
916
1018
|
harness = "forge";
|
|
917
1019
|
aliases = ["forgecode"];
|
|
@@ -964,7 +1066,26 @@ var ForgeAdapter = class {
|
|
|
964
1066
|
for (const raw of messages) {
|
|
965
1067
|
const entry = raw.message ?? raw;
|
|
966
1068
|
const ts = (/* @__PURE__ */ new Date(0)).toISOString();
|
|
967
|
-
if (entry.text) {
|
|
1069
|
+
if (entry.text && entry.text.role === "user") {
|
|
1070
|
+
const prompt = textOf5(entry.text.content);
|
|
1071
|
+
if (prompt) {
|
|
1072
|
+
spans.push(
|
|
1073
|
+
span({
|
|
1074
|
+
traceId,
|
|
1075
|
+
spanId: `user:${step}`,
|
|
1076
|
+
parentSpanId: rootId,
|
|
1077
|
+
name: "user.prompt",
|
|
1078
|
+
kind: "CHAIN",
|
|
1079
|
+
startTime: ts,
|
|
1080
|
+
service: SERVICE6,
|
|
1081
|
+
agent: SERVICE6,
|
|
1082
|
+
step,
|
|
1083
|
+
content: prompt
|
|
1084
|
+
})
|
|
1085
|
+
);
|
|
1086
|
+
step += 1;
|
|
1087
|
+
}
|
|
1088
|
+
} else if (entry.text) {
|
|
968
1089
|
const llmId = `llm:${step}`;
|
|
969
1090
|
spans.push(
|
|
970
1091
|
span({
|
|
@@ -980,7 +1101,7 @@ var ForgeAdapter = class {
|
|
|
980
1101
|
inputTokens: tokens(raw.usage?.prompt_tokens),
|
|
981
1102
|
outputTokens: tokens(raw.usage?.completion_tokens),
|
|
982
1103
|
step,
|
|
983
|
-
content: entry.text.content
|
|
1104
|
+
content: textOf5(entry.text.content) || null
|
|
984
1105
|
})
|
|
985
1106
|
);
|
|
986
1107
|
lastLlm = llmId;
|
|
@@ -1025,6 +1146,11 @@ function iso(ts, fallback) {
|
|
|
1025
1146
|
function toolStatusError(status) {
|
|
1026
1147
|
return status != null && /error|fail|cancel/i.test(status);
|
|
1027
1148
|
}
|
|
1149
|
+
var CONTENT_CAP6 = 8e3;
|
|
1150
|
+
function textOf6(content) {
|
|
1151
|
+
const s = typeof content === "string" ? content : JSON.stringify(content ?? "");
|
|
1152
|
+
return s.trim().slice(0, CONTENT_CAP6);
|
|
1153
|
+
}
|
|
1028
1154
|
var GeminiFamilyAdapter = class {
|
|
1029
1155
|
harness;
|
|
1030
1156
|
aliases;
|
|
@@ -1101,7 +1227,26 @@ var GeminiFamilyAdapter = class {
|
|
|
1101
1227
|
const mid = m.id ?? `m${step}`;
|
|
1102
1228
|
const ts = iso(m.timestamp, start);
|
|
1103
1229
|
const llmId = `llm:${mid}`;
|
|
1104
|
-
|
|
1230
|
+
if (m.type === "user") {
|
|
1231
|
+
const prompt = textOf6(m.content);
|
|
1232
|
+
if (prompt) {
|
|
1233
|
+
spans.push(
|
|
1234
|
+
span({
|
|
1235
|
+
traceId,
|
|
1236
|
+
spanId: `${llmId}:user`,
|
|
1237
|
+
parentSpanId: rootId,
|
|
1238
|
+
name: "user.prompt",
|
|
1239
|
+
kind: "CHAIN",
|
|
1240
|
+
startTime: ts,
|
|
1241
|
+
service: this.service,
|
|
1242
|
+
agent: this.service,
|
|
1243
|
+
step,
|
|
1244
|
+
content: prompt
|
|
1245
|
+
})
|
|
1246
|
+
);
|
|
1247
|
+
step += 1;
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1105
1250
|
spans.push(
|
|
1106
1251
|
span({
|
|
1107
1252
|
traceId,
|
|
@@ -1116,7 +1261,7 @@ var GeminiFamilyAdapter = class {
|
|
|
1116
1261
|
inputTokens: m.tokens?.input ?? null,
|
|
1117
1262
|
outputTokens: m.tokens?.output ?? null,
|
|
1118
1263
|
step,
|
|
1119
|
-
content: content
|
|
1264
|
+
content: textOf6(m.content) || null
|
|
1120
1265
|
})
|
|
1121
1266
|
);
|
|
1122
1267
|
step += 1;
|
|
@@ -1159,6 +1304,10 @@ var SERVICE7 = "opencode";
|
|
|
1159
1304
|
function isoOf(ms) {
|
|
1160
1305
|
return new Date(ms ?? 0).toISOString();
|
|
1161
1306
|
}
|
|
1307
|
+
var CONTENT_CAP7 = 8e3;
|
|
1308
|
+
function textOf7(parts) {
|
|
1309
|
+
return parts.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("\n").trim().slice(0, CONTENT_CAP7);
|
|
1310
|
+
}
|
|
1162
1311
|
var OpencodeAdapter = class {
|
|
1163
1312
|
harness = "opencode";
|
|
1164
1313
|
storage() {
|
|
@@ -1224,6 +1373,19 @@ var OpencodeAdapter = class {
|
|
|
1224
1373
|
for (const { msg } of messages) {
|
|
1225
1374
|
const mid = msg.id ?? `m${step}`;
|
|
1226
1375
|
const llmId = `llm:${mid}`;
|
|
1376
|
+
const pdir = join8(partRoot, mid);
|
|
1377
|
+
const parts = [];
|
|
1378
|
+
try {
|
|
1379
|
+
const partFiles = (await readdir8(pdir)).filter((f) => f.endsWith(".json"));
|
|
1380
|
+
for (const pf of partFiles) {
|
|
1381
|
+
try {
|
|
1382
|
+
parts.push(JSON.parse(await readFile8(join8(pdir, pf), "utf8")));
|
|
1383
|
+
} catch {
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
} catch {
|
|
1387
|
+
}
|
|
1388
|
+
const turnText = textOf7(parts);
|
|
1227
1389
|
spans.push(
|
|
1228
1390
|
span({
|
|
1229
1391
|
traceId,
|
|
@@ -1238,24 +1400,29 @@ var OpencodeAdapter = class {
|
|
|
1238
1400
|
model: msg.modelID ?? null,
|
|
1239
1401
|
inputTokens: msg.tokens?.input ?? null,
|
|
1240
1402
|
outputTokens: msg.tokens?.output ?? null,
|
|
1241
|
-
step
|
|
1403
|
+
step,
|
|
1404
|
+
content: turnText || null
|
|
1242
1405
|
})
|
|
1243
1406
|
);
|
|
1244
1407
|
step += 1;
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1408
|
+
if (msg.role === "user" && turnText) {
|
|
1409
|
+
spans.push(
|
|
1410
|
+
span({
|
|
1411
|
+
traceId,
|
|
1412
|
+
spanId: `${llmId}:user`,
|
|
1413
|
+
parentSpanId: rootId,
|
|
1414
|
+
name: "user.prompt",
|
|
1415
|
+
kind: "CHAIN",
|
|
1416
|
+
startTime: isoOf(msg.time?.created),
|
|
1417
|
+
service: SERVICE7,
|
|
1418
|
+
agent: SERVICE7,
|
|
1419
|
+
step,
|
|
1420
|
+
content: turnText
|
|
1421
|
+
})
|
|
1422
|
+
);
|
|
1423
|
+
step += 1;
|
|
1251
1424
|
}
|
|
1252
|
-
for (const
|
|
1253
|
-
let part;
|
|
1254
|
-
try {
|
|
1255
|
-
part = JSON.parse(await readFile8(join8(pdir, pf), "utf8"));
|
|
1256
|
-
} catch {
|
|
1257
|
-
continue;
|
|
1258
|
-
}
|
|
1425
|
+
for (const part of parts) {
|
|
1259
1426
|
if (part.type !== "tool" || !part.tool) continue;
|
|
1260
1427
|
const err = part.state?.status === "error";
|
|
1261
1428
|
spans.push(
|
|
@@ -1305,9 +1472,10 @@ function isToolBlock(b) {
|
|
|
1305
1472
|
function isToolResultBlock(b) {
|
|
1306
1473
|
return typeof b.type === "string" && /tool[_-]?result|tool[_-]?output/i.test(b.type);
|
|
1307
1474
|
}
|
|
1308
|
-
|
|
1475
|
+
var CONTENT_CAP8 = 8e3;
|
|
1476
|
+
function textOf8(content) {
|
|
1309
1477
|
if (!content) return "";
|
|
1310
|
-
return content.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
|
|
1478
|
+
return content.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("").trim().slice(0, CONTENT_CAP8);
|
|
1311
1479
|
}
|
|
1312
1480
|
var PiAdapter = class {
|
|
1313
1481
|
harness = "pi";
|
|
@@ -1375,27 +1543,48 @@ var PiAdapter = class {
|
|
|
1375
1543
|
const mid = l.id ?? `m${step}`;
|
|
1376
1544
|
const msg = l.message;
|
|
1377
1545
|
const llmId = `llm:${mid}`;
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1546
|
+
if (msg.role === "user") {
|
|
1547
|
+
const prompt = textOf8(msg.content);
|
|
1548
|
+
if (prompt) {
|
|
1549
|
+
spans.push(
|
|
1550
|
+
span({
|
|
1551
|
+
traceId,
|
|
1552
|
+
spanId: `${mid}:user`,
|
|
1553
|
+
parentSpanId: rootId,
|
|
1554
|
+
name: "user.prompt",
|
|
1555
|
+
kind: "CHAIN",
|
|
1556
|
+
startTime: ts,
|
|
1557
|
+
service: SERVICE8,
|
|
1558
|
+
agent: SERVICE8,
|
|
1559
|
+
step,
|
|
1560
|
+
content: prompt
|
|
1561
|
+
})
|
|
1562
|
+
);
|
|
1563
|
+
step += 1;
|
|
1564
|
+
}
|
|
1565
|
+
} else {
|
|
1566
|
+
const errored = !!msg.errorMessage;
|
|
1567
|
+
spans.push(
|
|
1568
|
+
span({
|
|
1569
|
+
traceId,
|
|
1570
|
+
spanId: llmId,
|
|
1571
|
+
parentSpanId: rootId,
|
|
1572
|
+
name: `message.${msg.role ?? "unknown"}`,
|
|
1573
|
+
kind: "LLM",
|
|
1574
|
+
startTime: ts,
|
|
1575
|
+
status: errored ? "ERROR" : "OK",
|
|
1576
|
+
statusMessage: errored ? msg.errorMessage.slice(0, 500) : void 0,
|
|
1577
|
+
service: SERVICE8,
|
|
1578
|
+
agent: SERVICE8,
|
|
1579
|
+
model: msg.model ?? null,
|
|
1580
|
+
inputTokens: msg.usage?.input ?? null,
|
|
1581
|
+
outputTokens: msg.usage?.output ?? null,
|
|
1582
|
+
step,
|
|
1583
|
+
content: textOf8(msg.content) || null
|
|
1584
|
+
})
|
|
1585
|
+
);
|
|
1586
|
+
step += 1;
|
|
1587
|
+
}
|
|
1399
1588
|
for (const b of msg.content ?? []) {
|
|
1400
1589
|
if (isToolBlock(b)) {
|
|
1401
1590
|
const name = b.toolName ?? b.name ?? "tool";
|
|
@@ -1447,7 +1636,7 @@ function parseLines6(raw) {
|
|
|
1447
1636
|
}
|
|
1448
1637
|
return out;
|
|
1449
1638
|
}
|
|
1450
|
-
function
|
|
1639
|
+
function textOf9(parts) {
|
|
1451
1640
|
if (!parts) return "";
|
|
1452
1641
|
return parts.filter((p) => typeof p.text === "string").map((p) => p.text).join("");
|
|
1453
1642
|
}
|
|
@@ -1529,7 +1718,7 @@ var QwenAdapter = class {
|
|
|
1529
1718
|
inputTokens: r.usageMetadata?.promptTokenCount ?? null,
|
|
1530
1719
|
outputTokens: r.usageMetadata?.candidatesTokenCount ?? null,
|
|
1531
1720
|
step,
|
|
1532
|
-
content:
|
|
1721
|
+
content: textOf9(r.message?.parts).slice(0, 8e3) || null
|
|
1533
1722
|
})
|
|
1534
1723
|
);
|
|
1535
1724
|
lastLlm = llmId;
|
|
@@ -1556,6 +1745,25 @@ var QwenAdapter = class {
|
|
|
1556
1745
|
openToolsByName.set(name, q);
|
|
1557
1746
|
step += 1;
|
|
1558
1747
|
}
|
|
1748
|
+
} else if (r.type === "user") {
|
|
1749
|
+
const prompt = textOf9(r.message?.parts).slice(0, 8e3);
|
|
1750
|
+
if (prompt) {
|
|
1751
|
+
spans.push(
|
|
1752
|
+
span({
|
|
1753
|
+
traceId,
|
|
1754
|
+
spanId: `user:${r.uuid ?? step}`,
|
|
1755
|
+
parentSpanId: rootId,
|
|
1756
|
+
name: "user.prompt",
|
|
1757
|
+
kind: "CHAIN",
|
|
1758
|
+
startTime: ts,
|
|
1759
|
+
service: SERVICE9,
|
|
1760
|
+
agent: SERVICE9,
|
|
1761
|
+
step,
|
|
1762
|
+
content: prompt
|
|
1763
|
+
})
|
|
1764
|
+
);
|
|
1765
|
+
step += 1;
|
|
1766
|
+
}
|
|
1559
1767
|
} else if (r.type === "tool_result") {
|
|
1560
1768
|
const err = r.toolCallResult?.status === "error" || r.toolCallResult?.error != null;
|
|
1561
1769
|
for (const p of r.message?.parts ?? []) {
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/traces",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|