@tangle-network/traces 0.9.14 → 0.9.16

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.
@@ -4180,6 +4180,24 @@ import { readdir as readdir11, stat as stat9 } from "fs/promises";
4180
4180
  import { homedir as homedir10 } from "os";
4181
4181
  import { basename as basename8, join as join10 } from "path";
4182
4182
  var SERVICE9 = "pi";
4183
+ function terminalStatus(message) {
4184
+ const stopReason = message?.stopReason ?? "missing";
4185
+ if (message?.role === "assistant" && stopReason === "stop") {
4186
+ return { status: "OK", stopReason };
4187
+ }
4188
+ if (message?.role === "assistant" && (stopReason === "error" || message.errorMessage)) {
4189
+ return {
4190
+ status: "ERROR",
4191
+ statusMessage: message.errorMessage?.slice(0, 500) ?? "Pi assistant stopped with an error",
4192
+ stopReason
4193
+ };
4194
+ }
4195
+ return {
4196
+ status: "UNSET",
4197
+ statusMessage: message === void 0 ? "Pi session contained no messages" : `Pi session ended after ${message.role} with stopReason "${stopReason}"`,
4198
+ stopReason
4199
+ };
4200
+ }
4183
4201
  function isToolBlock(b) {
4184
4202
  return typeof b.type === "string" && /tool[_-]?call|tool[_-]?use|^tool$/i.test(b.type);
4185
4203
  }
@@ -4192,6 +4210,17 @@ function textOf8(content) {
4192
4210
  content.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("")
4193
4211
  );
4194
4212
  }
4213
+ function toolResultOutput(content) {
4214
+ if (content?.length === 1 && content[0]?.type === "text" && typeof content[0].text === "string") {
4215
+ return content[0].text;
4216
+ }
4217
+ return content;
4218
+ }
4219
+ function completeToolSpan(toolSpan, result) {
4220
+ toolSpan.end_time = result.timestamp;
4221
+ toolSpan.status = result.isError ? { code: "ERROR", message: result.errorMessage } : { code: "OK" };
4222
+ recordToolOutput(toolSpan, result.output);
4223
+ }
4195
4224
  var PiAdapter = class {
4196
4225
  harness = "pi";
4197
4226
  root() {
@@ -4240,9 +4269,11 @@ var PiAdapter = class {
4240
4269
  const sourceRootId = `root:${sourceTraceId}`;
4241
4270
  const spans = [];
4242
4271
  const toolByCallId = /* @__PURE__ */ new Map();
4272
+ const pendingResults = /* @__PURE__ */ new Map();
4243
4273
  let firstTimestamp;
4244
4274
  let lastTimestamp;
4245
4275
  let sessionLine;
4276
+ let terminalMessage;
4246
4277
  let sawLine = false;
4247
4278
  let step = 0;
4248
4279
  for await (const l of readJsonl(ref.path, sessionJsonlOptions(ref, options))) {
@@ -4258,8 +4289,32 @@ var PiAdapter = class {
4258
4289
  const ts = l.timestamp ?? (/* @__PURE__ */ new Date(0)).toISOString();
4259
4290
  const mid = l.id ?? `m${step}`;
4260
4291
  const msg = l.message;
4292
+ terminalMessage = {
4293
+ role: msg.role ?? "unknown",
4294
+ stopReason: msg.stopReason,
4295
+ errorMessage: msg.errorMessage
4296
+ };
4261
4297
  const llmId = `llm:${mid}`;
4262
- if (msg.role === "user") {
4298
+ if (msg.role === "toolResult") {
4299
+ const callId = msg.toolCallId ?? `${mid}:result`;
4300
+ const errorMessage = textOf8(msg.content).slice(0, 500) || "tool result reported error";
4301
+ const result = {
4302
+ callId,
4303
+ toolName: msg.toolName ?? "tool",
4304
+ timestamp: ts,
4305
+ isError: msg.isError === true,
4306
+ output: toolResultOutput(msg.content),
4307
+ errorMessage,
4308
+ step
4309
+ };
4310
+ const toolSpan = toolByCallId.get(callId);
4311
+ if (toolSpan) completeToolSpan(toolSpan, result);
4312
+ else {
4313
+ pendingResults.set(callId, result);
4314
+ step += 1;
4315
+ }
4316
+ continue;
4317
+ } else if (msg.role === "user") {
4263
4318
  const prompt = textOf8(msg.content);
4264
4319
  if (prompt) {
4265
4320
  spans.push(
@@ -4293,6 +4348,9 @@ var PiAdapter = class {
4293
4348
  model: msg.model ?? null,
4294
4349
  inputTokens: msg.usage?.input ?? null,
4295
4350
  outputTokens: msg.usage?.output ?? null,
4351
+ reasoningTokens: msg.usage?.reasoning ?? null,
4352
+ cachedInputTokens: msg.usage?.cacheRead ?? null,
4353
+ cacheWriteInputTokens: msg.usage?.cacheWrite ?? null,
4296
4354
  step,
4297
4355
  content: textOf8(msg.content) || null
4298
4356
  })
@@ -4313,11 +4371,17 @@ var PiAdapter = class {
4313
4371
  service: SERVICE9,
4314
4372
  agent: SERVICE9,
4315
4373
  tool: name,
4374
+ status: "UNSET",
4316
4375
  step,
4317
4376
  extra: toolIoAttributes({ input: b.input ?? b.args ?? b.arguments })
4318
4377
  });
4319
4378
  spans.push(toolSpan);
4320
4379
  toolByCallId.set(callId, toolSpan);
4380
+ const pending = pendingResults.get(callId);
4381
+ if (pending) {
4382
+ completeToolSpan(toolSpan, pending);
4383
+ pendingResults.delete(callId);
4384
+ }
4321
4385
  step += 1;
4322
4386
  } else if (isToolResultBlock(b)) {
4323
4387
  const callId = b.toolCallId ?? b.callId ?? b.id ?? "";
@@ -4331,8 +4395,32 @@ var PiAdapter = class {
4331
4395
  }
4332
4396
  }
4333
4397
  }
4398
+ for (const result of pendingResults.values()) {
4399
+ spans.push(
4400
+ span({
4401
+ traceId: sourceTraceId,
4402
+ spanId: `tool:${result.callId}`,
4403
+ parentSpanId: sourceRootId,
4404
+ name: `tool.${result.toolName}`,
4405
+ kind: "TOOL",
4406
+ startTime: result.timestamp,
4407
+ endTime: result.timestamp,
4408
+ status: result.isError ? "ERROR" : "OK",
4409
+ statusMessage: result.isError ? result.errorMessage : void 0,
4410
+ service: SERVICE9,
4411
+ agent: SERVICE9,
4412
+ tool: result.toolName,
4413
+ step: result.step,
4414
+ extra: {
4415
+ ...toolIoAttributes({ output: result.output }),
4416
+ "traces.pi.tool_result_without_call": true
4417
+ }
4418
+ })
4419
+ );
4420
+ }
4334
4421
  const traceId = sessionLine?.id ?? sourceTraceId;
4335
4422
  const rootId = `root:${traceId}`;
4423
+ const terminal = terminalStatus(terminalMessage);
4336
4424
  for (const item of spans) {
4337
4425
  item.trace_id = traceId;
4338
4426
  if (item.parent_span_id === sourceRootId) item.parent_span_id = rootId;
@@ -4345,8 +4433,11 @@ var PiAdapter = class {
4345
4433
  kind: "AGENT",
4346
4434
  startTime: sessionLine?.timestamp ?? firstTimestamp ?? (/* @__PURE__ */ new Date(0)).toISOString(),
4347
4435
  endTime: lastTimestamp,
4436
+ status: terminal.status,
4437
+ statusMessage: terminal.statusMessage,
4348
4438
  service: SERVICE9,
4349
- agent: SERVICE9
4439
+ agent: SERVICE9,
4440
+ extra: { "traces.pi.stop_reason": terminal.stopReason }
4350
4441
  });
4351
4442
  return [root, ...spans];
4352
4443
  }
package/dist/cli.js CHANGED
@@ -43,7 +43,7 @@ import {
43
43
  writePolicyEvidenceFile,
44
44
  writeSessionIndexFile,
45
45
  writeTraceEvidenceExportFile
46
- } from "./chunk-SKUFTUDV.js";
46
+ } from "./chunk-I4W6DECY.js";
47
47
 
48
48
  // src/cli.ts
49
49
  import { readFileSync } from "fs";
package/dist/index.d.ts CHANGED
@@ -712,8 +712,10 @@ declare class FactoryAdapter implements HarnessTraceAdapter {
712
712
  *
713
713
  * Line types: `session` (id + cwd), `model_change`, `thinking_level_change`,
714
714
  * and `message`. A `message` line wraps `message.{role, model, provider,
715
- * content[], usage.{input,output}, stopReason, errorMessage}`. Tool calls
716
- * ride inside `message.content[]` as tool blocks.
715
+ * content[], usage.{input,output,reasoning,cacheRead,cacheWrite}, stopReason,
716
+ * errorMessage}`. Tool calls
717
+ * ride inside assistant `message.content[]` blocks; their completions are
718
+ * separate `role: "toolResult"` messages keyed by `message.toolCallId`.
717
719
  */
718
720
 
719
721
  declare class PiAdapter implements HarnessTraceAdapter {
package/dist/index.js CHANGED
@@ -130,7 +130,7 @@ import {
130
130
  writeSessionIndexFile,
131
131
  writeTraceEvidenceExportFile,
132
132
  writeTraceImprovementArtifacts
133
- } from "./chunk-SKUFTUDV.js";
133
+ } from "./chunk-I4W6DECY.js";
134
134
 
135
135
  // src/collect.ts
136
136
  async function collectSessions(opts = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/traces",
3
- "version": "0.9.14",
3
+ "version": "0.9.16",
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",