@tangle-network/traces 0.22.0 → 0.23.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/README.md +21 -5
- package/dist/{chunk-DON6NQ7H.js → chunk-7DVZCCZI.js} +271 -122
- package/dist/cli.js +69 -11
- package/dist/index.d.ts +94 -6
- package/dist/index.js +9 -1
- package/docs/trace-analysts.md +3 -2
- package/package.json +2 -2
|
@@ -151,6 +151,7 @@ var ATTR = {
|
|
|
151
151
|
* in-container path even when no such path exists on this host. */
|
|
152
152
|
ENVIRONMENT_CWD: "tangle.environment.cwd"
|
|
153
153
|
};
|
|
154
|
+
var SESSION_CWD_ATTR = "traces.session.cwd";
|
|
154
155
|
var INGEST_SOURCE_CLI = "cli";
|
|
155
156
|
function environmentAttributes(environment) {
|
|
156
157
|
if (!environment) return {};
|
|
@@ -254,6 +255,9 @@ function parseIsoToEpochMs(ts) {
|
|
|
254
255
|
return n;
|
|
255
256
|
}
|
|
256
257
|
function parseSince(value) {
|
|
258
|
+
return parseTimeBound(value, "--since");
|
|
259
|
+
}
|
|
260
|
+
function parseTimeBound(value, flag) {
|
|
257
261
|
const m = value.match(/^(\d+)\s*([mhd])$/i);
|
|
258
262
|
if (m) {
|
|
259
263
|
const unit = m[2].toLowerCase();
|
|
@@ -261,7 +265,7 @@ function parseSince(value) {
|
|
|
261
265
|
return Date.now() - Number(m[1]) * ms2;
|
|
262
266
|
}
|
|
263
267
|
const t = Date.parse(value);
|
|
264
|
-
if (Number.isNaN(t)) throw new Error(
|
|
268
|
+
if (Number.isNaN(t)) throw new Error(`${flag}: expected 30m / 2h / 7d or an ISO date, got "${value}"`);
|
|
265
269
|
return t;
|
|
266
270
|
}
|
|
267
271
|
|
|
@@ -2585,6 +2589,7 @@ var GeminiAdapter = class extends GeminiFamilyAdapter {
|
|
|
2585
2589
|
};
|
|
2586
2590
|
|
|
2587
2591
|
// src/adapters/actor.ts
|
|
2592
|
+
import { claudeRecordIsMachine } from "@tangle-network/harness-sessions";
|
|
2588
2593
|
var CMD_MARKERS = [
|
|
2589
2594
|
"<command-name>",
|
|
2590
2595
|
"<local-command-caveat>",
|
|
@@ -2633,22 +2638,6 @@ var SYNTHETIC_MARKERS = [
|
|
|
2633
2638
|
"Staff-engineer code review"
|
|
2634
2639
|
];
|
|
2635
2640
|
var AGENT_PROMPT = /^(you are\b|you're\b|read[- ]only\b|stop now\b|your task\b|your job\b|review the\b|audit\b|analyze the\b|return (only|a |the )|here is the\b|context:|task:|do not (revert|edit|touch)|work only in\b|you have been\b|act as\b|operate the\b|goal:|objective:)/i;
|
|
2636
|
-
var CLAUDE_MACHINE_PREFIXES = [
|
|
2637
|
-
"<local-command-caveat>",
|
|
2638
|
-
"<local-command-stdout>",
|
|
2639
|
-
"<local-command-stderr>",
|
|
2640
|
-
"Caveat: The messages below",
|
|
2641
|
-
"<task-notification>",
|
|
2642
|
-
"<bash-stdout>",
|
|
2643
|
-
"<bash-stderr>",
|
|
2644
|
-
"<user-prompt-submit-hook>",
|
|
2645
|
-
"[Request interrupted by user"
|
|
2646
|
-
];
|
|
2647
|
-
function claudeRecordIsMachine(args) {
|
|
2648
|
-
if (args.isMeta === true || args.isCompactSummary === true || args.entrypoint === "sdk-cli") return true;
|
|
2649
|
-
const text2 = args.text.trimStart();
|
|
2650
|
-
return CLAUDE_MACHINE_PREFIXES.some((prefix) => text2.startsWith(prefix));
|
|
2651
|
-
}
|
|
2652
2641
|
function textIsCmdOrInject(s) {
|
|
2653
2642
|
return CMD_MARKERS.some((m) => s.includes(m)) || INJECT_MARKERS.some((m) => s.includes(m));
|
|
2654
2643
|
}
|
|
@@ -2686,7 +2675,7 @@ function claudePromptStartsTask(args) {
|
|
|
2686
2675
|
}
|
|
2687
2676
|
function claudeActor(args) {
|
|
2688
2677
|
if (args.isSidechain === true) return "subagent-spawn";
|
|
2689
|
-
if (claudeRecordIsMachine(args)) return "injected";
|
|
2678
|
+
if (claudeRecordIsMachine({ ...args, entrypoint: args.entrypoint ?? void 0 })) return "injected";
|
|
2690
2679
|
if (args.userType != null && args.userType !== "external") return "injected";
|
|
2691
2680
|
if (textIsCmdOrInject(args.text)) return "injected";
|
|
2692
2681
|
if (textIsSynthetic(args.text)) return "injected";
|
|
@@ -2770,6 +2759,7 @@ import {
|
|
|
2770
2759
|
LLM_OUTPUT_TOKENS as LLM_OUTPUT_TOKENS2
|
|
2771
2760
|
} from "@tangle-network/agent-eval/trace-attributes";
|
|
2772
2761
|
import { ATTR as ATTR3, deriveHexId as deriveHexId2 } from "@tangle-network/agent-trace-contract";
|
|
2762
|
+
import { claudeRecordIsMachine as claudeRecordIsMachine2, claudeTypedPromptText } from "@tangle-network/harness-sessions";
|
|
2773
2763
|
|
|
2774
2764
|
// src/adapters/claude-subagent-sources.ts
|
|
2775
2765
|
import { readdir as readdir6, realpath } from "fs/promises";
|
|
@@ -3125,8 +3115,6 @@ var ORIGIN_EVIDENCE_ATTR = "traces.claude.actor_evidence";
|
|
|
3125
3115
|
var MACHINE_RECORD_ATTR = "traces.claude.machine_record";
|
|
3126
3116
|
var ORIGIN_RECORDED_ATTR = "traces.claude.origin_recorded";
|
|
3127
3117
|
var ORIGIN_KIND_ATTR = "traces.claude.origin_kind";
|
|
3128
|
-
var COMMAND_NAME = /<command-name>([\s\S]*?)<\/command-name>/;
|
|
3129
|
-
var COMMAND_ARGS = /<command-args>([\s\S]*?)<\/command-args>/;
|
|
3130
3118
|
var SPAWN_TYPE_KEY = "subagent_type";
|
|
3131
3119
|
var SPAWN_DESCRIPTION_KEY = "description";
|
|
3132
3120
|
var SPAWN_TYPE_ATTR = "traces.claude.subagent_type";
|
|
@@ -3322,12 +3310,6 @@ function claudeActorFromOrigin(recorded, fallback) {
|
|
|
3322
3310
|
}
|
|
3323
3311
|
return fallback();
|
|
3324
3312
|
}
|
|
3325
|
-
function typedPromptText(text2) {
|
|
3326
|
-
const name = COMMAND_NAME.exec(text2)?.[1]?.trim();
|
|
3327
|
-
if (!name) return text2;
|
|
3328
|
-
const args = COMMAND_ARGS.exec(text2)?.[1]?.trim();
|
|
3329
|
-
return args ? `${name} ${args}` : name;
|
|
3330
|
-
}
|
|
3331
3313
|
function recordedOrigin(origin) {
|
|
3332
3314
|
const kind = origin?.kind;
|
|
3333
3315
|
return typeof kind === "string" && kind.length > 0 ? kind : null;
|
|
@@ -3533,11 +3515,11 @@ function consumeClaudeEvent(event, uid, ctx, state) {
|
|
|
3533
3515
|
}
|
|
3534
3516
|
} else if (event.kind === "user") {
|
|
3535
3517
|
if (event.prompt) {
|
|
3536
|
-
const machine =
|
|
3518
|
+
const machine = claudeRecordIsMachine2({
|
|
3537
3519
|
text: event.prompt,
|
|
3538
3520
|
isMeta: event.isMeta,
|
|
3539
3521
|
isCompactSummary: event.isCompactSummary,
|
|
3540
|
-
entrypoint: event.entrypoint
|
|
3522
|
+
entrypoint: event.entrypoint ?? void 0
|
|
3541
3523
|
});
|
|
3542
3524
|
const actor = machine ? "injected" : claudeActorFromOrigin(event.originKind, () => claudeActor({
|
|
3543
3525
|
text: event.prompt ?? "",
|
|
@@ -3556,7 +3538,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
|
|
|
3556
3538
|
service: SERVICE4,
|
|
3557
3539
|
agent: ctx.agent,
|
|
3558
3540
|
step: state.step,
|
|
3559
|
-
content: actor === "human" ?
|
|
3541
|
+
content: actor === "human" ? claudeTypedPromptText(event.prompt) : event.prompt,
|
|
3560
3542
|
contentSource: event.contentSource,
|
|
3561
3543
|
actor
|
|
3562
3544
|
});
|
|
@@ -3577,7 +3559,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
|
|
|
3577
3559
|
} else if (event.kind === "attachment") {
|
|
3578
3560
|
backfillResult(state.toolSpanByUseId.get(event.result.toolUseId), event.timestamp, event.result);
|
|
3579
3561
|
} else if (event.kind === "queued-prompt") {
|
|
3580
|
-
const machine =
|
|
3562
|
+
const machine = claudeRecordIsMachine2({ text: event.prompt });
|
|
3581
3563
|
const actor = machine ? "injected" : claudeActorFromOrigin(event.originKind, () => "injected");
|
|
3582
3564
|
if (event.originKind) state.sawRecordedOrigin = true;
|
|
3583
3565
|
const prompt = userPromptSpan({
|
|
@@ -3588,7 +3570,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
|
|
|
3588
3570
|
service: SERVICE4,
|
|
3589
3571
|
agent: ctx.agent,
|
|
3590
3572
|
step: state.step,
|
|
3591
|
-
content: actor === "human" ?
|
|
3573
|
+
content: actor === "human" ? claudeTypedPromptText(event.prompt) : event.prompt,
|
|
3592
3574
|
contentSource: event.contentSource,
|
|
3593
3575
|
actor
|
|
3594
3576
|
});
|
|
@@ -3900,10 +3882,12 @@ var ClaudeAdapter = class {
|
|
|
3900
3882
|
let active = taskScope === "all";
|
|
3901
3883
|
let offeredTools;
|
|
3902
3884
|
let runResult;
|
|
3885
|
+
let recordedCwd;
|
|
3903
3886
|
for await (const event of readJsonl(ref.path, sessionJsonlOptions(ref, options))) {
|
|
3904
3887
|
options.signal?.throwIfAborted();
|
|
3905
3888
|
const eventSessionId = event.sessionId ?? event.session_id;
|
|
3906
3889
|
if (!discoveredTraceId && eventSessionId) discoveredTraceId = eventSessionId;
|
|
3890
|
+
if (!recordedCwd && typeof event.cwd === "string" && event.cwd.length > 0) recordedCwd = event.cwd;
|
|
3907
3891
|
if (event.type === "system" && event.subtype === "init" && Array.isArray(event.tools)) {
|
|
3908
3892
|
offeredTools = modelFacingToolNames(
|
|
3909
3893
|
event.tools.filter((t) => typeof t === "string"),
|
|
@@ -3973,6 +3957,7 @@ var ClaudeAdapter = class {
|
|
|
3973
3957
|
if (offeredTools) {
|
|
3974
3958
|
root.attributes[TOOL_DEFINITIONS_ATTR] = JSON.stringify(offeredTools.map((name) => ({ type: "function", name })));
|
|
3975
3959
|
}
|
|
3960
|
+
if (recordedCwd) root.attributes[SESSION_CWD_ATTR] = recordedCwd;
|
|
3976
3961
|
if (runResult) {
|
|
3977
3962
|
root.attributes[RUN_STATUS_ATTR] = runResult.failed ? "failed" : "completed";
|
|
3978
3963
|
root.status = runResult.failed ? { code: "ERROR", message: `the run ended with ${runResult.subtype}` } : { code: "OK" };
|
|
@@ -4626,6 +4611,9 @@ var CODEX_TOTAL_TOKENS_SOURCE = "codex.token_count.info.total_token_usage";
|
|
|
4626
4611
|
function reportedCount(value) {
|
|
4627
4612
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
4628
4613
|
}
|
|
4614
|
+
function nonEmpty(value) {
|
|
4615
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
4616
|
+
}
|
|
4629
4617
|
function normalizeCodexIds(spans) {
|
|
4630
4618
|
for (const item of spans) {
|
|
4631
4619
|
const sourceTraceId = item.trace_id;
|
|
@@ -5203,6 +5191,7 @@ var CodexAdapter = class {
|
|
|
5203
5191
|
}
|
|
5204
5192
|
}
|
|
5205
5193
|
const traceId = meta?.payload?.id ?? ref.sessionId;
|
|
5194
|
+
const recordedCwd = nonEmpty(meta?.payload?.cwd);
|
|
5206
5195
|
const scriptLaunched = meta?.payload?.originator === "codex_exec" || meta?.payload?.source === "exec";
|
|
5207
5196
|
const sessionRole = parentSessionId || meta?.payload?.thread_source === "subagent" ? "child" : "operator";
|
|
5208
5197
|
const rootId = `root:${traceId}`;
|
|
@@ -5221,6 +5210,7 @@ var CodexAdapter = class {
|
|
|
5221
5210
|
// Keep the source session identity searchable after the wire id is normalized.
|
|
5222
5211
|
"tangle.sessionId": traceId,
|
|
5223
5212
|
"traces.session.role": sessionRole,
|
|
5213
|
+
...recordedCwd ? { [SESSION_CWD_ATTR]: recordedCwd } : {},
|
|
5224
5214
|
"traces.codex.task_scope": options.taskScope === "latest" ? "latest" : options.taskScope === "turn" ? "turn" : forkBoundary ? "fork-current" : "all",
|
|
5225
5215
|
...selectedBoundary?.turnId ? { "traces.codex.turn_id": selectedBoundary.turnId } : {},
|
|
5226
5216
|
...parentSessionId ? { "traces.parent_session_id": parentSessionId } : {},
|
|
@@ -5865,6 +5855,7 @@ var OpencodeAdapter = class {
|
|
|
5865
5855
|
messages.push(await readJsonFile(join9(ref.path, f), options));
|
|
5866
5856
|
}
|
|
5867
5857
|
messages.sort((a, b) => (a.time?.created ?? 0) - (b.time?.created ?? 0));
|
|
5858
|
+
const recordedCwd = messages.map((message) => message.path?.cwd).find((cwd) => typeof cwd === "string" && cwd.length > 0);
|
|
5868
5859
|
const spans = [
|
|
5869
5860
|
span({
|
|
5870
5861
|
traceId,
|
|
@@ -5875,7 +5866,8 @@ var OpencodeAdapter = class {
|
|
|
5875
5866
|
startTime: isoOf(messages[0]?.time?.created),
|
|
5876
5867
|
endTime: isoOf(messages.at(-1)?.time?.completed ?? messages.at(-1)?.time?.created),
|
|
5877
5868
|
service: SERVICE6,
|
|
5878
|
-
agent: SERVICE6
|
|
5869
|
+
agent: SERVICE6,
|
|
5870
|
+
...recordedCwd ? { extra: { [SESSION_CWD_ATTR]: recordedCwd } } : {}
|
|
5879
5871
|
})
|
|
5880
5872
|
];
|
|
5881
5873
|
let step = 0;
|
|
@@ -5979,7 +5971,7 @@ var OpencodeAdapter = class {
|
|
|
5979
5971
|
// src/adapters/harness-sessions.ts
|
|
5980
5972
|
import { homedir as homedir8 } from "os";
|
|
5981
5973
|
import { open, stat as stat8 } from "fs/promises";
|
|
5982
|
-
import { join as join10 } from "path";
|
|
5974
|
+
import { basename as basename6, dirname as dirname4, join as join10 } from "path";
|
|
5983
5975
|
import {
|
|
5984
5976
|
claudeCodeRefForFile,
|
|
5985
5977
|
codexRefForFile,
|
|
@@ -6317,6 +6309,7 @@ var HarnessSessionsAdapter = class {
|
|
|
6317
6309
|
const root = spans[0];
|
|
6318
6310
|
root.attributes["service.name"] = this.harness;
|
|
6319
6311
|
root.attributes["traces.session.role"] = session.parentNativeSessionId ? "child" : "operator";
|
|
6312
|
+
if (session.cwd) root.attributes[SESSION_CWD_ATTR] = session.cwd;
|
|
6320
6313
|
if (session.parentNativeSessionId) root.attributes["traces.parent_session_id"] = session.parentNativeSessionId;
|
|
6321
6314
|
if (session.children.length > 0) {
|
|
6322
6315
|
root.attributes["traces.child_session_ids"] = JSON.stringify(session.children.map((child) => child.nativeSessionId));
|
|
@@ -6344,12 +6337,16 @@ var HarnessSessionsAdapter = class {
|
|
|
6344
6337
|
const toolByCallId = new Map(spans.filter((item) => item.attributes["openinference.span.kind"] === "TOOL").map((item) => [item.attributes["gen_ai.tool.call.id"], item]));
|
|
6345
6338
|
let childSpanCount = 0;
|
|
6346
6339
|
const childIds = new Set(session.children.map((child) => child.nativeSessionId));
|
|
6340
|
+
const readIds = /* @__PURE__ */ new Set();
|
|
6347
6341
|
for (const path of childPaths) {
|
|
6348
6342
|
const childRef = claudeCodeRefForFile(path, session.nativeSessionId);
|
|
6349
|
-
const
|
|
6350
|
-
|
|
6343
|
+
const read = await this.reader.read(childRef, { signal: options.signal, corruption: options.corruptionMode });
|
|
6344
|
+
const repeated = readIds.has(read.nativeSessionId);
|
|
6345
|
+
readIds.add(read.nativeSessionId);
|
|
6346
|
+
const child = repeated ? { ...read, nativeSessionId: `${read.nativeSessionId}@${basename6(dirname4(path))}` } : read;
|
|
6347
|
+
childIds.add(read.nativeSessionId);
|
|
6351
6348
|
if (!child.startedAt) continue;
|
|
6352
|
-
const binding = session.children.find((item) => item.nativeSessionId === child.nativeSessionId);
|
|
6349
|
+
const binding = repeated ? void 0 : session.children.find((item) => item.nativeSessionId === child.nativeSessionId);
|
|
6353
6350
|
const parent = binding?.toolCallId ? toolByCallId.get(binding.toolCallId) : void 0;
|
|
6354
6351
|
const projected = toOtlpSpans(child).map(asTracesSpan);
|
|
6355
6352
|
stampNativeProvenance(child, projected);
|
|
@@ -6397,7 +6394,7 @@ var SHARED_SESSION_ADAPTERS = [
|
|
|
6397
6394
|
// src/adapters/qwen.ts
|
|
6398
6395
|
import { readdir as readdir10, stat as stat9 } from "fs/promises";
|
|
6399
6396
|
import { homedir as homedir9 } from "os";
|
|
6400
|
-
import { basename as
|
|
6397
|
+
import { basename as basename7, join as join11 } from "path";
|
|
6401
6398
|
var SERVICE7 = "qwen";
|
|
6402
6399
|
function textOf6(parts) {
|
|
6403
6400
|
if (!parts) return "";
|
|
@@ -6440,7 +6437,7 @@ var QwenAdapter = class {
|
|
|
6440
6437
|
throw error;
|
|
6441
6438
|
}
|
|
6442
6439
|
if (opts.sinceMs && st.mtimeMs < opts.sinceMs) continue;
|
|
6443
|
-
refs.push({ harness: this.harness, sessionId:
|
|
6440
|
+
refs.push({ harness: this.harness, sessionId: basename7(f, ".jsonl"), path, cwd: null, mtimeMs: st.mtimeMs });
|
|
6444
6441
|
}
|
|
6445
6442
|
}
|
|
6446
6443
|
return refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
@@ -6595,7 +6592,7 @@ function selectAdapters(opts) {
|
|
|
6595
6592
|
|
|
6596
6593
|
// src/repo.ts
|
|
6597
6594
|
import { realpath as realpath2, stat as stat10 } from "fs/promises";
|
|
6598
|
-
import { dirname as
|
|
6595
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join12, normalize, parse as parsePath } from "path";
|
|
6599
6596
|
function normalizeRemote(url) {
|
|
6600
6597
|
const raw = url.trim();
|
|
6601
6598
|
if (!raw) return null;
|
|
@@ -6727,8 +6724,8 @@ async function nearestExistingDir(path) {
|
|
|
6727
6724
|
for (; ; ) {
|
|
6728
6725
|
const s = await pathStat(cur);
|
|
6729
6726
|
if (s?.isDirectory()) return cur;
|
|
6730
|
-
if (s?.isFile()) return
|
|
6731
|
-
const parent =
|
|
6727
|
+
if (s?.isFile()) return dirname5(cur);
|
|
6728
|
+
const parent = dirname5(cur);
|
|
6732
6729
|
if (parent === cur) return null;
|
|
6733
6730
|
cur = parent;
|
|
6734
6731
|
}
|
|
@@ -6737,7 +6734,7 @@ async function findGitRoot(path) {
|
|
|
6737
6734
|
let cur = await nearestExistingDir(path);
|
|
6738
6735
|
while (cur) {
|
|
6739
6736
|
if (await pathStat(join12(cur, ".git"))) return cur;
|
|
6740
|
-
const parent =
|
|
6737
|
+
const parent = dirname5(cur);
|
|
6741
6738
|
if (parent === cur) return null;
|
|
6742
6739
|
cur = parent;
|
|
6743
6740
|
}
|
|
@@ -6848,7 +6845,7 @@ function extractAbsolutePaths(spans) {
|
|
|
6848
6845
|
async function resolveRepoAttrs(cwd) {
|
|
6849
6846
|
if (!cwd) return {};
|
|
6850
6847
|
const attrs = { [ATTR.CWD]: cwd };
|
|
6851
|
-
const
|
|
6848
|
+
const basename16 = (() => {
|
|
6852
6849
|
const trimmed = cwd.replace(/\/+$/g, "");
|
|
6853
6850
|
const idx = trimmed.lastIndexOf("/");
|
|
6854
6851
|
const name = idx === -1 ? trimmed : trimmed.slice(idx + 1);
|
|
@@ -6870,7 +6867,7 @@ async function resolveRepoAttrs(cwd) {
|
|
|
6870
6867
|
if (commit) attrs[ATTR.GIT_COMMIT] = commit;
|
|
6871
6868
|
} catch {
|
|
6872
6869
|
}
|
|
6873
|
-
attrs[ATTR.SUBJECT_KEY] =
|
|
6870
|
+
attrs[ATTR.SUBJECT_KEY] = basename16;
|
|
6874
6871
|
return attrs;
|
|
6875
6872
|
}
|
|
6876
6873
|
async function repoCandidateForPath(path) {
|
|
@@ -8074,7 +8071,7 @@ var COMMAND_PREFIXES = /* @__PURE__ */ new Set([
|
|
|
8074
8071
|
var ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
8075
8072
|
var MAX_SHELL_DEPTH = 4;
|
|
8076
8073
|
var MAX_WORDS = 2e4;
|
|
8077
|
-
function
|
|
8074
|
+
function basename8(word) {
|
|
8078
8075
|
const cut = word.lastIndexOf("/");
|
|
8079
8076
|
return cut === -1 ? word : word.slice(cut + 1);
|
|
8080
8077
|
}
|
|
@@ -8173,7 +8170,7 @@ var ShellScanner = class {
|
|
|
8173
8170
|
let start = 0;
|
|
8174
8171
|
while (start < words.length) {
|
|
8175
8172
|
const word = words[start];
|
|
8176
|
-
if (ASSIGNMENT.test(word) || COMMAND_PREFIXES.has(
|
|
8173
|
+
if (ASSIGNMENT.test(word) || COMMAND_PREFIXES.has(basename8(word))) start += 1;
|
|
8177
8174
|
else break;
|
|
8178
8175
|
}
|
|
8179
8176
|
return start === 0 || start >= words.length ? words : words.slice(start);
|
|
@@ -8314,7 +8311,7 @@ function shellCommands(script, depth = 0) {
|
|
|
8314
8311
|
const out = [];
|
|
8315
8312
|
for (const words of commands) {
|
|
8316
8313
|
out.push(words);
|
|
8317
|
-
const name =
|
|
8314
|
+
const name = basename8(words[0] ?? "");
|
|
8318
8315
|
if (!SHELLS.has(name) || depth >= MAX_SHELL_DEPTH) continue;
|
|
8319
8316
|
for (let index = 1; index < words.length; index += 1) {
|
|
8320
8317
|
const word = words[index];
|
|
@@ -8342,7 +8339,7 @@ function commandTextFromInput(input) {
|
|
|
8342
8339
|
if (!Array.isArray(value) || value.length === 0) return void 0;
|
|
8343
8340
|
const words = value.filter((entry) => typeof entry === "string");
|
|
8344
8341
|
if (words.length !== value.length) return void 0;
|
|
8345
|
-
const head =
|
|
8342
|
+
const head = basename8(words[0] ?? "");
|
|
8346
8343
|
if (SHELLS.has(head)) {
|
|
8347
8344
|
const flag = words.findIndex((word, position) => position > 0 && /^-[a-z]*c$/.test(word));
|
|
8348
8345
|
if (flag !== -1 && words[flag + 1] !== void 0) return words[flag + 1];
|
|
@@ -8404,7 +8401,7 @@ function stringAttribute2(span2, key) {
|
|
|
8404
8401
|
const value = span2.attributes[key];
|
|
8405
8402
|
return typeof value === "string" ? value : null;
|
|
8406
8403
|
}
|
|
8407
|
-
function
|
|
8404
|
+
function basename9(word) {
|
|
8408
8405
|
const cut = word.lastIndexOf("/");
|
|
8409
8406
|
return cut === -1 ? word : word.slice(cut + 1);
|
|
8410
8407
|
}
|
|
@@ -8487,7 +8484,7 @@ function numbersInLine(line) {
|
|
|
8487
8484
|
function inferHeadBranch(commands, upTo, output) {
|
|
8488
8485
|
for (let index = upTo - 1; index >= 0; index -= 1) {
|
|
8489
8486
|
const words = commands[index];
|
|
8490
|
-
if (
|
|
8487
|
+
if (basename9(words[0] ?? "") !== "git" || words.length < 2) continue;
|
|
8491
8488
|
const sub = words[1];
|
|
8492
8489
|
const rest = words.slice(2);
|
|
8493
8490
|
if (sub === "push") {
|
|
@@ -8562,7 +8559,7 @@ function eventsFromRecord(record2, recordIndex) {
|
|
|
8562
8559
|
let createIndex = 0;
|
|
8563
8560
|
for (let index = 0; index < commands.length; index += 1) {
|
|
8564
8561
|
const words = commands[index];
|
|
8565
|
-
if (words.length < 3 || !GH_NAMES.has(
|
|
8562
|
+
if (words.length < 3 || !GH_NAMES.has(basename9(words[0])) || words[1] !== "pr") continue;
|
|
8566
8563
|
const action = words[2];
|
|
8567
8564
|
if (action === "create") {
|
|
8568
8565
|
const printedNumber = printed[createIndex] ?? null;
|
|
@@ -8811,12 +8808,13 @@ function computeSessionMeasurements(spans, tools, sessionId, harness) {
|
|
|
8811
8808
|
// src/session-facts.ts
|
|
8812
8809
|
import { OPENINFERENCE_SPAN_KIND as OPENINFERENCE_SPAN_KIND4, TOOL_NAME as TOOL_NAME5 } from "@tangle-network/agent-eval/trace-attributes";
|
|
8813
8810
|
import { ingestSpans, rankFirstFailure } from "@tangle-network/agent-eval/diagnosis";
|
|
8814
|
-
var SESSION_FACTS_MEASUREMENT_VERSION = "
|
|
8811
|
+
var SESSION_FACTS_MEASUREMENT_VERSION = "4";
|
|
8815
8812
|
var SESSION_TOKEN_TOTAL_ATTR = "traces.session.total_tokens";
|
|
8816
8813
|
var SPAN_SYNTHESIZED_ATTR = "traces.codex.span_synthesized";
|
|
8817
8814
|
var CORRUPTION_COUNT_ATTR = "traces.session.corruption_count";
|
|
8818
8815
|
var CORRUPTION_RECEIPT_VERSION_ATTR = "traces.session.corruption.receipt_version";
|
|
8819
8816
|
var FACT_TEXT_CAP = 2e3;
|
|
8817
|
+
var ANSWERED_TEXT_CAP = 1500;
|
|
8820
8818
|
var FACT_LIST_CAP = 200;
|
|
8821
8819
|
var CHANGED_FILE_LIST_CAP = 5e3;
|
|
8822
8820
|
function attr(span2, key) {
|
|
@@ -9046,47 +9044,105 @@ function turnText(span2) {
|
|
|
9046
9044
|
function normalizedTurnText(span2) {
|
|
9047
9045
|
return turnText(span2).replace(/\s+/g, " ").trim();
|
|
9048
9046
|
}
|
|
9047
|
+
var CAPTURE_CUT_MARKER = /… \[\+(\d+) chars\]$/;
|
|
9048
|
+
function clipAnswered(raw) {
|
|
9049
|
+
const text2 = raw.trim();
|
|
9050
|
+
const marker = CAPTURE_CUT_MARKER.exec(text2);
|
|
9051
|
+
const body = marker ? text2.slice(0, marker.index) : text2;
|
|
9052
|
+
if (body.length <= ANSWERED_TEXT_CAP) return text2;
|
|
9053
|
+
const lastKept = body.charCodeAt(ANSWERED_TEXT_CAP - 1);
|
|
9054
|
+
const keep = lastKept >= 55296 && lastKept <= 56319 ? ANSWERED_TEXT_CAP - 1 : ANSWERED_TEXT_CAP;
|
|
9055
|
+
const hidden = body.length - keep + (marker ? Number(marker[1]) : 0);
|
|
9056
|
+
return `${body.slice(0, keep)}\u2026 [+${hidden} chars]`;
|
|
9057
|
+
}
|
|
9058
|
+
function isOwnAgentMessage(span2) {
|
|
9059
|
+
return span2.name === "message.assistant" && span2.attributes[INHERITED_SPAN_ATTR] !== true && typeof span2.attributes.content === "string" && span2.attributes.content.trim().length > 0;
|
|
9060
|
+
}
|
|
9049
9061
|
function humanTurnsOf(spans) {
|
|
9050
9062
|
const excluded = /* @__PURE__ */ new Map();
|
|
9051
|
-
const drop = (reason,
|
|
9052
|
-
excluded.set(reason, [...excluded.get(reason) ?? [], spanId]);
|
|
9063
|
+
const drop = (reason, span2) => {
|
|
9064
|
+
excluded.set(reason, [...excluded.get(reason) ?? [], { spanId: span2.span_id, at: span2.start_time }]);
|
|
9053
9065
|
};
|
|
9054
9066
|
const kept = [];
|
|
9067
|
+
const turns = [];
|
|
9055
9068
|
let sinceKept = [];
|
|
9069
|
+
let lastAgentMessage = null;
|
|
9056
9070
|
for (const span2 of spans) {
|
|
9057
9071
|
if (isSubagentSpan(span2.attributes)) {
|
|
9058
|
-
if (span2.name === "user.prompt") drop(SUBAGENT_TURN_REASON, span2
|
|
9072
|
+
if (span2.name === "user.prompt") drop(SUBAGENT_TURN_REASON, span2);
|
|
9059
9073
|
continue;
|
|
9060
9074
|
}
|
|
9061
9075
|
if (span2.name !== "user.prompt") {
|
|
9076
|
+
if (isOwnAgentMessage(span2)) lastAgentMessage = span2;
|
|
9062
9077
|
sinceKept.push(span2);
|
|
9063
9078
|
continue;
|
|
9064
9079
|
}
|
|
9065
9080
|
if (span2.attributes[INHERITED_SPAN_ATTR] === true) {
|
|
9066
9081
|
const source = stringAttr2(span2, INHERITED_SOURCE_ATTR);
|
|
9067
|
-
drop(source === null ? INHERITED_TURN_REASON : `${INHERITED_TURN_REASON} (${source})`, span2
|
|
9082
|
+
drop(source === null ? INHERITED_TURN_REASON : `${INHERITED_TURN_REASON} (${source})`, span2);
|
|
9068
9083
|
continue;
|
|
9069
9084
|
}
|
|
9070
9085
|
const actor = stringAttr2(span2, ACTOR_ATTR) ?? "unclassified";
|
|
9071
9086
|
if (actor !== "human") {
|
|
9072
|
-
drop(TURN_EXCLUSION_REASONS[actor] ?? `the adapter classified this turn as "${actor}", not as a person typing`, span2
|
|
9087
|
+
drop(TURN_EXCLUSION_REASONS[actor] ?? `the adapter classified this turn as "${actor}", not as a person typing`, span2);
|
|
9073
9088
|
continue;
|
|
9074
9089
|
}
|
|
9075
9090
|
const previous = kept[kept.length - 1];
|
|
9076
9091
|
const duplicate = previous !== void 0 && previous.start_time === span2.start_time && normalizedTurnText(previous) === normalizedTurnText(span2) && normalizedTurnText(span2).length > 0 && !sinceKept.some(isAgentActivity);
|
|
9077
9092
|
if (duplicate) {
|
|
9078
|
-
drop(DUPLICATE_TURN_REASON, span2
|
|
9093
|
+
drop(DUPLICATE_TURN_REASON, span2);
|
|
9079
9094
|
continue;
|
|
9080
9095
|
}
|
|
9081
9096
|
kept.push(span2);
|
|
9097
|
+
turns.push({
|
|
9098
|
+
actor: "human",
|
|
9099
|
+
at: span2.start_time,
|
|
9100
|
+
text: turnText(span2),
|
|
9101
|
+
spanId: span2.span_id,
|
|
9102
|
+
answered: lastAgentMessage ? clipAnswered(lastAgentMessage.attributes.content) : null,
|
|
9103
|
+
answeredSpanId: lastAgentMessage?.span_id ?? null
|
|
9104
|
+
});
|
|
9082
9105
|
sinceKept = [];
|
|
9083
9106
|
}
|
|
9107
|
+
return { turns, excluded };
|
|
9108
|
+
}
|
|
9109
|
+
function excludedTurnFacts(excluded, keep) {
|
|
9110
|
+
return [...excluded].map(([reason, entries]) => [reason, entries.filter((entry) => keep(entry.at)).map((entry) => entry.spanId)]).filter(([, spanIds]) => spanIds.length > 0).sort(([left], [right]) => left.localeCompare(right)).map(([reason, spanIds]) => ({ reason, turns: spanIds.length, spanIds }));
|
|
9111
|
+
}
|
|
9112
|
+
function windowBounds(window) {
|
|
9113
|
+
if (!window || window.since === void 0 && window.until === void 0) return null;
|
|
9114
|
+
const bound = (value, name, open4) => {
|
|
9115
|
+
if (value === void 0) return open4;
|
|
9116
|
+
const ms2 = Date.parse(value);
|
|
9117
|
+
if (!Number.isFinite(ms2)) throw new RangeError(`window ${name} is not a readable time: ${value}`);
|
|
9118
|
+
return ms2;
|
|
9119
|
+
};
|
|
9120
|
+
const sinceMs = bound(window.since, "since", Number.NEGATIVE_INFINITY);
|
|
9121
|
+
const untilMs = bound(window.until, "until", Number.POSITIVE_INFINITY);
|
|
9122
|
+
if (!(sinceMs < untilMs)) throw new RangeError(`window since (${window.since}) must be before until (${window.until})`);
|
|
9084
9123
|
return {
|
|
9085
|
-
|
|
9086
|
-
|
|
9124
|
+
since: window.since === void 0 ? null : new Date(sinceMs).toISOString(),
|
|
9125
|
+
until: window.until === void 0 ? null : new Date(untilMs).toISOString(),
|
|
9126
|
+
sinceMs,
|
|
9127
|
+
untilMs
|
|
9087
9128
|
};
|
|
9088
9129
|
}
|
|
9130
|
+
function insideWindow(bounds, time) {
|
|
9131
|
+
if (bounds === null) return true;
|
|
9132
|
+
const ms2 = Date.parse(time);
|
|
9133
|
+
return Number.isFinite(ms2) && ms2 >= bounds.sinceMs && ms2 < bounds.untilMs;
|
|
9134
|
+
}
|
|
9135
|
+
function isRecordSpan(span2) {
|
|
9136
|
+
return span2.parent_span_id !== null && span2.attributes[CORRUPTION_RECEIPT_VERSION_ATTR] === void 0;
|
|
9137
|
+
}
|
|
9089
9138
|
function computeSessionFacts(spans, options = {}) {
|
|
9139
|
+
const bounds = windowBounds(options.window);
|
|
9140
|
+
return groupByTrace(spans).sort((left, right) => compareIds(left.traceId, right.traceId)).map((group) => sessionFactsForTrace(group.traceId, group.sessionId, group.spans, options, bounds));
|
|
9141
|
+
}
|
|
9142
|
+
function compareIds(left, right) {
|
|
9143
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
9144
|
+
}
|
|
9145
|
+
function groupByTrace(spans) {
|
|
9090
9146
|
const { sessionByTrace } = indexSessionIdsByTrace(spans);
|
|
9091
9147
|
const byTrace = /* @__PURE__ */ new Map();
|
|
9092
9148
|
for (const span2 of spans) {
|
|
@@ -9094,9 +9150,13 @@ function computeSessionFacts(spans, options = {}) {
|
|
|
9094
9150
|
if (group) group.push(span2);
|
|
9095
9151
|
else byTrace.set(span2.trace_id, [span2]);
|
|
9096
9152
|
}
|
|
9097
|
-
return [...byTrace].
|
|
9153
|
+
return [...byTrace].map(([traceId, traceSpans]) => ({
|
|
9154
|
+
traceId,
|
|
9155
|
+
sessionId: sessionByTrace.get(traceId) ?? null,
|
|
9156
|
+
spans: traceSpans
|
|
9157
|
+
}));
|
|
9098
9158
|
}
|
|
9099
|
-
function sessionFactsForTrace(traceId, sessionId, unordered, options) {
|
|
9159
|
+
function sessionFactsForTrace(traceId, sessionId, unordered, options, bounds) {
|
|
9100
9160
|
const spans = [...unordered].sort(byTraceOrder);
|
|
9101
9161
|
const harness = spans.map((span2) => stringAttr2(span2, "service.name")).find((name) => name !== null) ?? null;
|
|
9102
9162
|
const ownSpans = spans.filter((span2) => !isSubagentSpan(span2.attributes));
|
|
@@ -9110,8 +9170,11 @@ function sessionFactsForTrace(traceId, sessionId, unordered, options) {
|
|
|
9110
9170
|
for (const span2 of invoked) byName[toolName3(span2)] = (byName[toolName3(span2)] ?? 0) + 1;
|
|
9111
9171
|
const subagents = subagentsOf(ownSpans, spans);
|
|
9112
9172
|
const pullRequests = readPullRequests(ownSpans);
|
|
9113
|
-
const
|
|
9114
|
-
const
|
|
9173
|
+
const inWindow = (at) => insideWindow(bounds, at);
|
|
9174
|
+
const promptSpans = spans.filter((span2) => span2.name === "user.prompt" && inWindow(span2.start_time));
|
|
9175
|
+
const turnFacts = humanTurnsOf(spans);
|
|
9176
|
+
const humanTurns = turnFacts.turns.filter((turn) => inWindow(turn.at));
|
|
9177
|
+
const excludedTurns = excludedTurnFacts(turnFacts.excluded, inWindow);
|
|
9115
9178
|
const actorCounts = /* @__PURE__ */ new Map();
|
|
9116
9179
|
for (const span2 of promptSpans) {
|
|
9117
9180
|
const actor = stringAttr2(span2, ACTOR_ATTR) ?? "unclassified";
|
|
@@ -9131,16 +9194,20 @@ function sessionFactsForTrace(traceId, sessionId, unordered, options) {
|
|
|
9131
9194
|
);
|
|
9132
9195
|
const tokenSpan = spans.find((span2) => typeof span2.attributes[SESSION_TOKEN_TOTAL_ATTR] === "number");
|
|
9133
9196
|
const receipts = spans.filter((span2) => span2.attributes[CORRUPTION_RECEIPT_VERSION_ATTR] !== void 0);
|
|
9134
|
-
const recordSpans = spans.filter(
|
|
9135
|
-
(span2) => span2.parent_span_id !== null && span2.attributes[CORRUPTION_RECEIPT_VERSION_ATTR] === void 0
|
|
9136
|
-
).length;
|
|
9197
|
+
const recordSpans = spans.filter(isRecordSpan).length;
|
|
9137
9198
|
const corruptionSpan = spans.find((span2) => typeof span2.attributes[CORRUPTION_COUNT_ATTR] === "number");
|
|
9199
|
+
const cwdSpan = spans.find((span2) => stringAttr2(span2, SESSION_CWD_ATTR) !== null);
|
|
9138
9200
|
const facts = {
|
|
9139
9201
|
schemaVersion: 1,
|
|
9140
9202
|
kind: "traces.session_facts",
|
|
9141
9203
|
traceId,
|
|
9142
9204
|
sessionId,
|
|
9143
9205
|
harness,
|
|
9206
|
+
cwd: cwdSpan ? { value: stringAttr2(cwdSpan, SESSION_CWD_ATTR), spanIds: [cwdSpan.span_id], unavailable: null } : {
|
|
9207
|
+
value: null,
|
|
9208
|
+
spanIds: [],
|
|
9209
|
+
unavailable: `no span carries ${SESSION_CWD_ATTR}: the session source records no working directory, or the adapter that read it does not read one`
|
|
9210
|
+
},
|
|
9144
9211
|
spanCount: spans.length,
|
|
9145
9212
|
recordSpans,
|
|
9146
9213
|
unreadRecords: corruptionSpan ? {
|
|
@@ -9213,6 +9280,7 @@ function sessionFactsForTrace(traceId, sessionId, unordered, options) {
|
|
|
9213
9280
|
});
|
|
9214
9281
|
return {
|
|
9215
9282
|
...facts,
|
|
9283
|
+
cwd: withheld(),
|
|
9216
9284
|
humanTurns: withheld(),
|
|
9217
9285
|
finalMessages: withheld(),
|
|
9218
9286
|
changedFiles: withheld(),
|
|
@@ -9229,26 +9297,88 @@ function sessionFactsForTrace(traceId, sessionId, unordered, options) {
|
|
|
9229
9297
|
};
|
|
9230
9298
|
}
|
|
9231
9299
|
function buildSessionFactsReport(spans, options = {}) {
|
|
9232
|
-
const
|
|
9233
|
-
|
|
9300
|
+
const builder = createSessionFactsReportBuilder(options);
|
|
9301
|
+
builder.add(spans);
|
|
9302
|
+
return builder.build();
|
|
9303
|
+
}
|
|
9304
|
+
var WINDOW_SESSION_RULE = "a session is selected when at least one of its records starts or ends inside [since, until)";
|
|
9305
|
+
var WINDOW_TURN_RULE = "humanTurns, excludedTurns and turnsByActor keep only user.prompt turns that started inside [since, until); every other fact, and each turn's answered text, covers the whole session";
|
|
9306
|
+
function createSessionFactsReportBuilder(options = {}) {
|
|
9307
|
+
const bounds = windowBounds(options.window);
|
|
9308
|
+
const sessions = [];
|
|
9309
|
+
const digests = [];
|
|
9310
|
+
const outsideWindow = [];
|
|
9311
|
+
const unreadSessions = [];
|
|
9312
|
+
let spanCount = 0;
|
|
9234
9313
|
let evidenceThrough = null;
|
|
9235
|
-
|
|
9236
|
-
digest
|
|
9237
|
-
for (const
|
|
9238
|
-
|
|
9314
|
+
const select = (group) => {
|
|
9315
|
+
const digest = createHash7("sha256");
|
|
9316
|
+
for (const span2 of [...group.spans].sort((a, b) => a.span_id.localeCompare(b.span_id))) {
|
|
9317
|
+
digest.update(canonicalJson(span2)).update("\n");
|
|
9318
|
+
for (const time of [span2.start_time, span2.end_time]) {
|
|
9319
|
+
if (Number.isFinite(Date.parse(time)) && (evidenceThrough === null || Date.parse(time) > Date.parse(evidenceThrough))) evidenceThrough = time;
|
|
9320
|
+
}
|
|
9239
9321
|
}
|
|
9240
|
-
|
|
9322
|
+
digests.push({ traceId: group.traceId, digest: digest.digest("hex") });
|
|
9323
|
+
spanCount += group.spans.length;
|
|
9324
|
+
sessions.push(sessionFactsForTrace(group.traceId, group.sessionId, group.spans, options, bounds));
|
|
9325
|
+
};
|
|
9241
9326
|
return {
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9327
|
+
add(spans) {
|
|
9328
|
+
for (const group of groupByTrace(spans)) {
|
|
9329
|
+
if (bounds === null) {
|
|
9330
|
+
select(group);
|
|
9331
|
+
continue;
|
|
9332
|
+
}
|
|
9333
|
+
const records = group.spans.filter(isRecordSpan);
|
|
9334
|
+
if (records.length === 0) {
|
|
9335
|
+
const unread = group.spans.find((span2) => typeof span2.attributes[CORRUPTION_COUNT_ATTR] === "number");
|
|
9336
|
+
unreadSessions.push({
|
|
9337
|
+
sessionId: group.sessionId,
|
|
9338
|
+
traceId: group.traceId,
|
|
9339
|
+
source: null,
|
|
9340
|
+
reason: `no record could be read (${unread ? `${unread.attributes[CORRUPTION_COUNT_ATTR]} unread record(s)` : "no record spans"}), so whether the session holds a record inside the window is unknown`
|
|
9341
|
+
});
|
|
9342
|
+
continue;
|
|
9343
|
+
}
|
|
9344
|
+
if (records.some((span2) => insideWindow(bounds, span2.start_time) || insideWindow(bounds, span2.end_time))) select(group);
|
|
9345
|
+
else outsideWindow.push(group.sessionId ?? group.traceId);
|
|
9346
|
+
}
|
|
9347
|
+
},
|
|
9348
|
+
addUnread(session) {
|
|
9349
|
+
if (bounds === null) {
|
|
9350
|
+
throw new Error("an unread session is reported only by a windowed report; without a window, refuse the selection");
|
|
9351
|
+
}
|
|
9352
|
+
unreadSessions.push(session);
|
|
9353
|
+
},
|
|
9354
|
+
build() {
|
|
9355
|
+
const digest = createHash7("sha256");
|
|
9356
|
+
for (const entry of [...digests].sort((a, b) => a.traceId.localeCompare(b.traceId) || a.digest.localeCompare(b.digest))) {
|
|
9357
|
+
digest.update(`${entry.traceId}
|
|
9358
|
+
${entry.digest}
|
|
9359
|
+
`);
|
|
9360
|
+
}
|
|
9361
|
+
return {
|
|
9362
|
+
schemaVersion: 1,
|
|
9363
|
+
kind: "traces.session_facts_report",
|
|
9364
|
+
measurementVersion: SESSION_FACTS_MEASUREMENT_VERSION,
|
|
9365
|
+
sourceDigest: "sha256:" + digest.digest("hex"),
|
|
9366
|
+
evidenceThrough,
|
|
9367
|
+
contentIncluded: options.includeContent !== false,
|
|
9368
|
+
generatedAt: options.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
9369
|
+
harness: options.harness ?? null,
|
|
9370
|
+
spanCount,
|
|
9371
|
+
selection: bounds === null ? null : {
|
|
9372
|
+
since: bounds.since,
|
|
9373
|
+
until: bounds.until,
|
|
9374
|
+
sessionRule: WINDOW_SESSION_RULE,
|
|
9375
|
+
turnRule: WINDOW_TURN_RULE,
|
|
9376
|
+
outsideWindow: [...outsideWindow].sort(compareIds),
|
|
9377
|
+
unreadSessions: [...unreadSessions]
|
|
9378
|
+
},
|
|
9379
|
+
sessions: [...sessions].sort((left, right) => compareIds(left.traceId, right.traceId))
|
|
9380
|
+
};
|
|
9381
|
+
}
|
|
9252
9382
|
};
|
|
9253
9383
|
}
|
|
9254
9384
|
function factLine(label2, fact, rendered) {
|
|
@@ -9260,8 +9390,18 @@ function renderSessionFacts(report) {
|
|
|
9260
9390
|
const lines = [
|
|
9261
9391
|
`session facts \u2014 ${report.sessions.length} session(s), ${report.spanCount} span(s), deterministic, $0`
|
|
9262
9392
|
];
|
|
9393
|
+
const selection = report.selection;
|
|
9394
|
+
if (selection) {
|
|
9395
|
+
lines.push(
|
|
9396
|
+
`window [${selection.since ?? "open"}, ${selection.until ?? "open"}): turn facts count only turns inside it; ${selection.outsideWindow.length} session(s) read with no record inside it`
|
|
9397
|
+
);
|
|
9398
|
+
for (const unread of selection.unreadSessions) {
|
|
9399
|
+
lines.push(` unread session ${unread.sessionId ?? unread.traceId ?? unread.source ?? "unknown"}: ${unread.reason}`);
|
|
9400
|
+
}
|
|
9401
|
+
}
|
|
9263
9402
|
for (const facts of report.sessions) {
|
|
9264
9403
|
lines.push("", `${facts.sessionId ?? facts.traceId} [${facts.harness ?? "unknown harness"}] ${facts.spanCount} spans`);
|
|
9404
|
+
lines.push(factLine("cwd", facts.cwd, String(facts.cwd.value)));
|
|
9265
9405
|
lines.push(
|
|
9266
9406
|
factLine(
|
|
9267
9407
|
"tool calls",
|
|
@@ -9329,6 +9469,9 @@ function renderSessionFactsContext(report, options = {}) {
|
|
|
9329
9469
|
${JSON.stringify({ sessions, ...dropped2.length ? { omitted_fields: dropped2 } : {} })}`;
|
|
9330
9470
|
const dropped = [];
|
|
9331
9471
|
const sheds = [
|
|
9472
|
+
["human_turn_answered", (facts) => {
|
|
9473
|
+
for (const turn of facts.human_turns) delete turn.answered;
|
|
9474
|
+
}],
|
|
9332
9475
|
["human_turn_text", (facts) => {
|
|
9333
9476
|
for (const turn of facts.human_turns) delete turn.text;
|
|
9334
9477
|
}],
|
|
@@ -9419,6 +9562,7 @@ function compactFacts(facts) {
|
|
|
9419
9562
|
return {
|
|
9420
9563
|
session_id: facts.sessionId,
|
|
9421
9564
|
trace_id: facts.traceId,
|
|
9565
|
+
cwd: factJson(facts.cwd),
|
|
9422
9566
|
spans: facts.spanCount,
|
|
9423
9567
|
tool_calls: {
|
|
9424
9568
|
count: facts.toolCalls.value,
|
|
@@ -9441,7 +9585,8 @@ function compactFacts(facts) {
|
|
|
9441
9585
|
human_turns: (facts.humanTurns.value ?? []).map((turn) => ({
|
|
9442
9586
|
at: turn.at,
|
|
9443
9587
|
span_id: turn.spanId,
|
|
9444
|
-
text: turn.text
|
|
9588
|
+
text: turn.text,
|
|
9589
|
+
answered: turn.answered
|
|
9445
9590
|
})),
|
|
9446
9591
|
excluded_turns: facts.excludedTurns.value?.map((entry) => ({
|
|
9447
9592
|
reason: entry.reason,
|
|
@@ -9531,17 +9676,17 @@ import { isUtf8 as isUtf82 } from "buffer";
|
|
|
9531
9676
|
import { createHash as createHash10 } from "crypto";
|
|
9532
9677
|
import { constants } from "fs";
|
|
9533
9678
|
import { lstat as lstat2, open as open2, realpath as realpath3 } from "fs/promises";
|
|
9534
|
-
import { dirname as
|
|
9679
|
+
import { dirname as dirname9, isAbsolute as isAbsolute4, join as join18, relative as relative5, resolve as resolve6, sep as sep2 } from "path";
|
|
9535
9680
|
|
|
9536
9681
|
// src/bundle.ts
|
|
9537
9682
|
import { createHash as createHash9 } from "crypto";
|
|
9538
9683
|
import { copyFile, cp, lstat, mkdir as mkdir2, readdir as readdir13, readFile as readFile7, stat as stat12, writeFile as writeFile5 } from "fs/promises";
|
|
9539
|
-
import { dirname as
|
|
9684
|
+
import { dirname as dirname8, join as join17, relative as relative4, resolve as resolve5, sep } from "path";
|
|
9540
9685
|
|
|
9541
9686
|
// src/improvement.ts
|
|
9542
9687
|
import { access, mkdir, mkdtemp as mkdtemp2, writeFile as writeFile3 } from "fs/promises";
|
|
9543
9688
|
import { tmpdir as tmpdir3 } from "os";
|
|
9544
|
-
import { dirname as
|
|
9689
|
+
import { dirname as dirname6, join as join15, resolve as resolve4 } from "path";
|
|
9545
9690
|
import { pathToFileURL } from "url";
|
|
9546
9691
|
import {
|
|
9547
9692
|
AnalystRegistry,
|
|
@@ -11870,14 +12015,14 @@ async function runTraceImprovement(opts) {
|
|
|
11870
12015
|
};
|
|
11871
12016
|
}
|
|
11872
12017
|
async function saveReport(path, report) {
|
|
11873
|
-
await mkdir(
|
|
12018
|
+
await mkdir(dirname6(resolve4(path)), { recursive: true });
|
|
11874
12019
|
await writeFile3(path, report, "utf8");
|
|
11875
12020
|
}
|
|
11876
12021
|
|
|
11877
12022
|
// src/session-index.ts
|
|
11878
12023
|
import { mkdtemp as mkdtemp3, readdir as readdir12, readFile as readFile6, stat as stat11, writeFile as writeFile4 } from "fs/promises";
|
|
11879
12024
|
import { tmpdir as tmpdir4 } from "os";
|
|
11880
|
-
import { dirname as
|
|
12025
|
+
import { dirname as dirname7, join as join16 } from "path";
|
|
11881
12026
|
function indexRow(record2) {
|
|
11882
12027
|
return {
|
|
11883
12028
|
session: record2.session,
|
|
@@ -11948,13 +12093,13 @@ async function findContextRoot(cwd) {
|
|
|
11948
12093
|
let current = cwd;
|
|
11949
12094
|
const s = await pathStat2(current);
|
|
11950
12095
|
if (!s) return null;
|
|
11951
|
-
if (!s.isDirectory()) current =
|
|
12096
|
+
if (!s.isDirectory()) current = dirname7(current);
|
|
11952
12097
|
for (; ; ) {
|
|
11953
12098
|
if (await pathStat2(join16(current, ".git")) || await dirExists(join16(current, ".evolve")) || await fileExists(join16(current, "AGENTS.md")) || await fileExists(join16(current, "CLAUDE.md"))) {
|
|
11954
12099
|
return current;
|
|
11955
12100
|
}
|
|
11956
|
-
const parent =
|
|
11957
|
-
if (parent === current) return s.isDirectory() ? cwd :
|
|
12101
|
+
const parent = dirname7(current);
|
|
12102
|
+
if (parent === current) return s.isDirectory() ? cwd : dirname7(cwd);
|
|
11958
12103
|
current = parent;
|
|
11959
12104
|
}
|
|
11960
12105
|
}
|
|
@@ -12788,7 +12933,7 @@ async function assembleSessionBundle(opts) {
|
|
|
12788
12933
|
const subagentRelative = relative4(subagentsSource, file.path);
|
|
12789
12934
|
const path = resolve5(file.path) === resolve5(ref.path) ? bundlePath("session", "transcript.jsonl") : !subagentRelative.startsWith("..") && !subagentRelative.startsWith(sep) ? bundlePath("session", "subagents", subagentRelative) : bundlePath("session", "sources", `${sourceId}.jsonl`);
|
|
12790
12935
|
const target = join17(outDir, path);
|
|
12791
|
-
await mkdir2(
|
|
12936
|
+
await mkdir2(dirname8(target), { recursive: true });
|
|
12792
12937
|
await copyFile(file.path, target);
|
|
12793
12938
|
if (await fileSha256(target, opts.signal) !== file.sha256) {
|
|
12794
12939
|
throw new Error(`session source changed while retaining bundle evidence: ${file.path}`);
|
|
@@ -13232,7 +13377,7 @@ async function assertOutsideSourceBundle(directory, outputPath) {
|
|
|
13232
13377
|
break;
|
|
13233
13378
|
} catch (error) {
|
|
13234
13379
|
if (error.code !== "ENOENT") throw error;
|
|
13235
|
-
const parent =
|
|
13380
|
+
const parent = dirname9(ancestor);
|
|
13236
13381
|
if (parent === ancestor) throw error;
|
|
13237
13382
|
ancestor = parent;
|
|
13238
13383
|
}
|
|
@@ -13498,7 +13643,7 @@ import {
|
|
|
13498
13643
|
readFile as readFile10,
|
|
13499
13644
|
rm as rm2
|
|
13500
13645
|
} from "fs/promises";
|
|
13501
|
-
import { basename as
|
|
13646
|
+
import { basename as basename11, dirname as dirname11, join as join21, resolve as resolve8 } from "path";
|
|
13502
13647
|
|
|
13503
13648
|
// src/codetracebench-files.ts
|
|
13504
13649
|
import { createHash as createHash12, randomUUID } from "crypto";
|
|
@@ -13516,13 +13661,13 @@ import {
|
|
|
13516
13661
|
writeFile as writeFile6
|
|
13517
13662
|
} from "fs/promises";
|
|
13518
13663
|
import { hostname } from "os";
|
|
13519
|
-
import { basename as
|
|
13664
|
+
import { basename as basename10, dirname as dirname10, isAbsolute as isAbsolute5, join as join19, relative as relative6, resolve as resolve7, sep as sep3 } from "path";
|
|
13520
13665
|
async function claimImportLock(input) {
|
|
13521
13666
|
const claimId = randomUUID();
|
|
13522
13667
|
const path = `${input.outputDirectory}.lock`;
|
|
13523
13668
|
const temporary = join19(
|
|
13524
|
-
|
|
13525
|
-
`.${
|
|
13669
|
+
dirname10(path),
|
|
13670
|
+
`.${basename10(path)}.${claimId}.tmp`
|
|
13526
13671
|
);
|
|
13527
13672
|
const metadata = {
|
|
13528
13673
|
kind: "traces.codetracebench-import-lock",
|
|
@@ -13683,8 +13828,8 @@ async function assertPathMissing(path) {
|
|
|
13683
13828
|
async function atomicWriteFile(path, content, signal) {
|
|
13684
13829
|
signal.throwIfAborted();
|
|
13685
13830
|
const temporary = join19(
|
|
13686
|
-
|
|
13687
|
-
`.${
|
|
13831
|
+
dirname10(path),
|
|
13832
|
+
`.${basename10(path)}.${randomUUID()}.tmp`
|
|
13688
13833
|
);
|
|
13689
13834
|
try {
|
|
13690
13835
|
await writeFile6(temporary, content, {
|
|
@@ -14017,12 +14162,12 @@ async function importCodeTraceBench(options) {
|
|
|
14017
14162
|
const rowsPath = resolve8(options.rowsPath);
|
|
14018
14163
|
const trajectoryPath = resolve8(options.trajectoryDir);
|
|
14019
14164
|
const outputDirectory = resolve8(options.outDir);
|
|
14020
|
-
const outputBase =
|
|
14021
|
-
if (!outputBase || outputDirectory ===
|
|
14165
|
+
const outputBase = basename11(outputDirectory);
|
|
14166
|
+
if (!outputBase || outputDirectory === dirname11(outputDirectory)) {
|
|
14022
14167
|
throw new Error("CodeTraceBench output directory must not be a filesystem root");
|
|
14023
14168
|
}
|
|
14024
14169
|
options.signal?.throwIfAborted();
|
|
14025
|
-
await mkdir4(
|
|
14170
|
+
await mkdir4(dirname11(outputDirectory), { recursive: true });
|
|
14026
14171
|
const lock = await claimImportLock({
|
|
14027
14172
|
rowsPath,
|
|
14028
14173
|
trajectoryDirectory: trajectoryPath,
|
|
@@ -14061,7 +14206,7 @@ async function runCodeTraceBenchImport(input) {
|
|
|
14061
14206
|
const rows = parseRows(rowsBytes.toString("utf8"), rowsPath);
|
|
14062
14207
|
const sourceRows = validateRows(rows, rowsPath);
|
|
14063
14208
|
const stagingDirectory = await mkdtemp4(
|
|
14064
|
-
join21(
|
|
14209
|
+
join21(dirname11(outputDirectory), `.${outputBase}.tmp-`)
|
|
14065
14210
|
);
|
|
14066
14211
|
const stop = new AbortController();
|
|
14067
14212
|
const signal = outerSignal ? AbortSignal.any([outerSignal, stop.signal]) : stop.signal;
|
|
@@ -14121,10 +14266,10 @@ async function runCodeTraceBenchImport(input) {
|
|
|
14121
14266
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14122
14267
|
input: {
|
|
14123
14268
|
revision,
|
|
14124
|
-
rowsFile:
|
|
14269
|
+
rowsFile: basename11(rowsPath),
|
|
14125
14270
|
rowsSha256,
|
|
14126
14271
|
rowsBytes: rowsBytes.byteLength,
|
|
14127
|
-
trajectoryDirectory:
|
|
14272
|
+
trajectoryDirectory: basename11(trajectoryDirectory),
|
|
14128
14273
|
sha256: inputSha256
|
|
14129
14274
|
},
|
|
14130
14275
|
settings: {
|
|
@@ -16630,7 +16775,7 @@ async function writeTraceEvidenceExportFile(inputPath, outPath, opts = {}) {
|
|
|
16630
16775
|
// src/inspect.ts
|
|
16631
16776
|
import { mkdtemp as mkdtemp7, readFile as readFile13, writeFile as writeFile9 } from "fs/promises";
|
|
16632
16777
|
import { tmpdir as tmpdir7 } from "os";
|
|
16633
|
-
import { basename as
|
|
16778
|
+
import { basename as basename12, join as join25 } from "path";
|
|
16634
16779
|
var severityRank2 = {
|
|
16635
16780
|
high: 0,
|
|
16636
16781
|
medium: 1,
|
|
@@ -16813,7 +16958,7 @@ function addContextFindings(index, findings) {
|
|
|
16813
16958
|
refs: invalidJsonlFiles.slice(0, 5).map((file) => file.path)
|
|
16814
16959
|
});
|
|
16815
16960
|
}
|
|
16816
|
-
const skillRunFiles = files.filter((file) =>
|
|
16961
|
+
const skillRunFiles = files.filter((file) => basename12(file.path) === "skill-runs.jsonl" && (file.jsonl?.rows ?? 0) > 0).map((file) => {
|
|
16817
16962
|
const rows = file.jsonl?.rows ?? 0;
|
|
16818
16963
|
const keys = file.jsonl?.keys ?? {};
|
|
16819
16964
|
const linkKeyCounts = {
|
|
@@ -17353,7 +17498,7 @@ async function streamSessions(opts) {
|
|
|
17353
17498
|
|
|
17354
17499
|
// src/supervisor-run-context.ts
|
|
17355
17500
|
import { readFile as readFile14, stat as stat14 } from "fs/promises";
|
|
17356
|
-
import { basename as
|
|
17501
|
+
import { basename as basename13, join as join26 } from "path";
|
|
17357
17502
|
import { materializeTreeView } from "@tangle-network/agent-runtime/kernel";
|
|
17358
17503
|
import {
|
|
17359
17504
|
readRuntimeSupervisorRun
|
|
@@ -17526,7 +17671,7 @@ async function readFileRunContext(runDir, opts = {}) {
|
|
|
17526
17671
|
return {
|
|
17527
17672
|
...sources,
|
|
17528
17673
|
instanceId: opts.instanceId !== void 0 ? opts.instanceId : sources.instanceId,
|
|
17529
|
-
arm: opts.arm !== void 0 ? opts.arm :
|
|
17674
|
+
arm: opts.arm !== void 0 ? opts.arm : basename13(runDir),
|
|
17530
17675
|
workers: sources.workers !== null && coordination.present ? workerSources(sources.workers, coordination) : sources.workers,
|
|
17531
17676
|
...sources.journal !== null ? {
|
|
17532
17677
|
rootTranscriptRef: join26(runDir, SPAWN_JOURNAL_FILE),
|
|
@@ -19188,7 +19333,7 @@ async function watchSessions(opts) {
|
|
|
19188
19333
|
// src/bundle-view.ts
|
|
19189
19334
|
import { createHash as createHash17 } from "crypto";
|
|
19190
19335
|
import { mkdir as mkdir7, readdir as readdir17, readFile as readFile16, writeFile as writeFile11 } from "fs/promises";
|
|
19191
|
-
import { dirname as
|
|
19336
|
+
import { dirname as dirname12, join as join30, resolve as resolve11 } from "path";
|
|
19192
19337
|
var EVIDENCE_ONLY_ALLOW_LIST = [
|
|
19193
19338
|
{
|
|
19194
19339
|
path: "derived/session-index.json",
|
|
@@ -19426,7 +19571,7 @@ async function projectSessionBundle(opts) {
|
|
|
19426
19571
|
continue;
|
|
19427
19572
|
}
|
|
19428
19573
|
const target = join30(outDir, candidate.path);
|
|
19429
|
-
await mkdir7(
|
|
19574
|
+
await mkdir7(dirname12(target), { recursive: true });
|
|
19430
19575
|
await writeFile11(target, candidate.bytes);
|
|
19431
19576
|
carriedPaths.push(candidate.path);
|
|
19432
19577
|
carries.set(candidate.path, candidate.carries);
|
|
@@ -19630,7 +19775,7 @@ function renderRunDiff(report) {
|
|
|
19630
19775
|
// src/upload-state.ts
|
|
19631
19776
|
import { mkdir as mkdir8, readFile as readFile17, writeFile as writeFile12 } from "fs/promises";
|
|
19632
19777
|
import { homedir as homedir10 } from "os";
|
|
19633
|
-
import { dirname as
|
|
19778
|
+
import { dirname as dirname13, join as join31 } from "path";
|
|
19634
19779
|
import { contentHash } from "@tangle-network/agent-eval";
|
|
19635
19780
|
function stateFile() {
|
|
19636
19781
|
const base = process.env.XDG_STATE_HOME ?? join31(homedir10(), ".local", "state");
|
|
@@ -19654,7 +19799,7 @@ async function loadState() {
|
|
|
19654
19799
|
}
|
|
19655
19800
|
async function saveState(state) {
|
|
19656
19801
|
const f = stateFile();
|
|
19657
|
-
await mkdir8(
|
|
19802
|
+
await mkdir8(dirname13(f), { recursive: true });
|
|
19658
19803
|
await writeFile12(f, `${JSON.stringify(state, null, 2)}
|
|
19659
19804
|
`, "utf8");
|
|
19660
19805
|
}
|
|
@@ -19666,7 +19811,7 @@ function alreadyUploaded(state, harness, sessionId, hash2) {
|
|
|
19666
19811
|
import { readFile as readFile18 } from "fs/promises";
|
|
19667
19812
|
import { createRequire as createRequire2 } from "module";
|
|
19668
19813
|
import { hostname as hostname2 } from "os";
|
|
19669
|
-
import { basename as
|
|
19814
|
+
import { basename as basename14, join as join32 } from "path";
|
|
19670
19815
|
import { hostedClientFromEnv } from "@tangle-network/agent-eval/hosted";
|
|
19671
19816
|
import { assessShareSafety as assessShareSafety2, REDACTION_VERSION, redact as redact2, shareAllowed } from "@tangle-network/agent-eval/traces";
|
|
19672
19817
|
var require2 = createRequire2(import.meta.url);
|
|
@@ -19700,7 +19845,7 @@ async function gitBranch(cwd) {
|
|
|
19700
19845
|
async function sessionMeta(item) {
|
|
19701
19846
|
const meta = {
|
|
19702
19847
|
[ATTR.HARNESS]: item.ref.harness,
|
|
19703
|
-
[ATTR.SESSION_FILE]:
|
|
19848
|
+
[ATTR.SESSION_FILE]: basename14(item.ref.path),
|
|
19704
19849
|
[ATTR.HOST]: hostname2(),
|
|
19705
19850
|
[ATTR.UPLOADER]: `tangle-traces@${TRACES_VERSION}`,
|
|
19706
19851
|
[ATTR.REDACTION_VERSION]: REDACTION_VERSION,
|
|
@@ -19866,7 +20011,7 @@ async function executeUpload(plan, opts = {}) {
|
|
|
19866
20011
|
|
|
19867
20012
|
// src/verify-safe.ts
|
|
19868
20013
|
import { lstat as lstat4, readdir as readdir18, readFile as readFile19 } from "fs/promises";
|
|
19869
|
-
import { basename as
|
|
20014
|
+
import { basename as basename15, extname, join as join33, relative as relative7 } from "path";
|
|
19870
20015
|
import {
|
|
19871
20016
|
assessShareSafety as assessShareSafety3,
|
|
19872
20017
|
combineVerdicts as combineVerdicts2
|
|
@@ -19879,7 +20024,7 @@ async function verifySafe(target, options = {}) {
|
|
|
19879
20024
|
const unreadable = [];
|
|
19880
20025
|
const files = await listFiles(target, unreadable);
|
|
19881
20026
|
for (const file of files) {
|
|
19882
|
-
const label2 = relative7(target, file) ||
|
|
20027
|
+
const label2 = relative7(target, file) || basename15(file);
|
|
19883
20028
|
let bytes2;
|
|
19884
20029
|
try {
|
|
19885
20030
|
bytes2 = await readFile19(file);
|
|
@@ -19981,7 +20126,7 @@ function formatVerdict(result) {
|
|
|
19981
20126
|
// src/skill-usage.ts
|
|
19982
20127
|
import { mkdir as mkdir9, open as open3, readdir as readdir19, readFile as readFile20, rename as rename3, stat as stat17, writeFile as writeFile13 } from "fs/promises";
|
|
19983
20128
|
import { homedir as homedir11 } from "os";
|
|
19984
|
-
import { dirname as
|
|
20129
|
+
import { dirname as dirname14, join as join34 } from "path";
|
|
19985
20130
|
import { STORES } from "@tangle-network/harness-sessions/catalog";
|
|
19986
20131
|
var CHUNK_BYTES = 8 * 1024 * 1024;
|
|
19987
20132
|
var NEWLINE = 10;
|
|
@@ -20066,7 +20211,7 @@ var SkillUsageStore = class _SkillUsageStore {
|
|
|
20066
20211
|
files: this.files,
|
|
20067
20212
|
events: this.list().map((e) => [e.harness, e.kind, e.skill, e.root, e.ts, e.session, e.id])
|
|
20068
20213
|
};
|
|
20069
|
-
await mkdir9(
|
|
20214
|
+
await mkdir9(dirname14(this.path), { recursive: true });
|
|
20070
20215
|
const temporary = `${this.path}.${process.pid}.tmp`;
|
|
20071
20216
|
await writeFile13(temporary, JSON.stringify(body));
|
|
20072
20217
|
await rename3(temporary, this.path);
|
|
@@ -20345,7 +20490,7 @@ function skillName(value) {
|
|
|
20345
20490
|
}
|
|
20346
20491
|
function rootOf(baseDirectoryText) {
|
|
20347
20492
|
const directory = baseDirectoryText.slice(BASE_DIRECTORY.length).split("\n", 1)[0].trim();
|
|
20348
|
-
return
|
|
20493
|
+
return dirname14(directory);
|
|
20349
20494
|
}
|
|
20350
20495
|
function sessionFromPath(path) {
|
|
20351
20496
|
return SESSION_UUID.exec(path)?.[1] ?? path;
|
|
@@ -20550,6 +20695,7 @@ export {
|
|
|
20550
20695
|
isSynthesizedSpan,
|
|
20551
20696
|
isInheritedSpan,
|
|
20552
20697
|
ATTR,
|
|
20698
|
+
SESSION_CWD_ATTR,
|
|
20553
20699
|
INGEST_SOURCE_CLI,
|
|
20554
20700
|
environmentAttributes,
|
|
20555
20701
|
stampEnvironmentAttrs,
|
|
@@ -20561,6 +20707,7 @@ export {
|
|
|
20561
20707
|
appendAll,
|
|
20562
20708
|
parseIsoToEpochMs,
|
|
20563
20709
|
parseSince,
|
|
20710
|
+
parseTimeBound,
|
|
20564
20711
|
resolveOtlpInputFiles,
|
|
20565
20712
|
inferSpanKind,
|
|
20566
20713
|
otlpRowToSpan,
|
|
@@ -20649,10 +20796,12 @@ export {
|
|
|
20649
20796
|
SESSION_TOKEN_TOTAL_ATTR,
|
|
20650
20797
|
SPAN_SYNTHESIZED_ATTR,
|
|
20651
20798
|
FACT_TEXT_CAP,
|
|
20799
|
+
ANSWERED_TEXT_CAP,
|
|
20652
20800
|
FACT_LIST_CAP,
|
|
20653
20801
|
CHANGED_FILE_LIST_CAP,
|
|
20654
20802
|
computeSessionFacts,
|
|
20655
20803
|
buildSessionFactsReport,
|
|
20804
|
+
createSessionFactsReportBuilder,
|
|
20656
20805
|
renderSessionFacts,
|
|
20657
20806
|
PREPARED_CONTEXT_BYTE_CEILING,
|
|
20658
20807
|
renderSessionFactsContext,
|