@tangle-network/agent-app 0.60.197 → 0.60.199

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.
Files changed (45) hide show
  1. package/dist/chat-routes/index.js +6 -4
  2. package/dist/chat-routes/index.js.map +1 -1
  3. package/dist/chat-routes/turn-routes.d.ts +28 -0
  4. package/dist/{chunk-XJEIGVMQ.js → chunk-2OWT3TNV.js} +2 -2
  5. package/dist/{chunk-XP77DJEF.js → chunk-6XXKFYIM.js} +72 -30
  6. package/dist/chunk-6XXKFYIM.js.map +1 -0
  7. package/dist/chunk-7XQIY2LU.js +151 -0
  8. package/dist/chunk-7XQIY2LU.js.map +1 -0
  9. package/dist/chunk-BKPJFES3.js +229 -0
  10. package/dist/chunk-BKPJFES3.js.map +1 -0
  11. package/dist/{chunk-7WEPGGOW.js → chunk-EGBNNTAL.js} +2 -2
  12. package/dist/{chunk-7WEPGGOW.js.map → chunk-EGBNNTAL.js.map} +1 -1
  13. package/dist/{chunk-SUIH5B55.js → chunk-RJJRRR5Z.js} +184 -16
  14. package/dist/chunk-RJJRRR5Z.js.map +1 -0
  15. package/dist/{chunk-FPOOBGRG.js → chunk-T4BLISYH.js} +40 -5
  16. package/dist/chunk-T4BLISYH.js.map +1 -0
  17. package/dist/public-consultation/index.d.ts +1 -1
  18. package/dist/public-consultation/index.js +2 -1
  19. package/dist/public-consultation/index.js.map +1 -1
  20. package/dist/runtime/index.js +4 -2
  21. package/dist/runtime/index.js.map +1 -1
  22. package/dist/runtime/router-turn.d.ts +14 -1
  23. package/dist/runtime/router-turn.js +3 -1
  24. package/dist/sandbox/index.d.ts +19 -0
  25. package/dist/sandbox/index.js +2 -1
  26. package/dist/sandbox/prompt-trace.d.ts +20 -0
  27. package/dist/sandbox/sandbox-run-tool.d.ts +8 -0
  28. package/dist/trace/index.d.ts +0 -1
  29. package/dist/trace/index.js +0 -240
  30. package/dist/trace/index.js.map +1 -1
  31. package/dist/turn-trace/index.d.ts +11 -0
  32. package/dist/turn-trace/index.js +121 -0
  33. package/dist/turn-trace/index.js.map +1 -0
  34. package/dist/turn-trace/otel.d.ts +36 -0
  35. package/dist/turn-trace/recorder.d.ts +122 -0
  36. package/dist/turn-trace/server-timing.d.ts +15 -0
  37. package/dist/turn-trace/traced-fetch.d.ts +31 -0
  38. package/dist/workspace-apps/index.js +1 -1
  39. package/dist/workspace-apps/react.js +1 -1
  40. package/package.json +6 -1
  41. package/dist/chunk-FPOOBGRG.js.map +0 -1
  42. package/dist/chunk-SUIH5B55.js.map +0 -1
  43. package/dist/chunk-XP77DJEF.js.map +0 -1
  44. package/dist/trace/stage-timing.d.ts +0 -61
  45. /package/dist/{chunk-XJEIGVMQ.js.map → chunk-2OWT3TNV.js.map} +0 -0
@@ -21,6 +21,7 @@
21
21
  import { type LoopMessage } from './loop';
22
22
  import { type TurnKnowledgeFile } from './turn-knowledge';
23
23
  import { type PlacementRecord, type VacuousAxis } from '@tangle-network/agent-runtime/placement';
24
+ import { type TurnSpan, type TurnTrace } from '../turn-trace/recorder';
24
25
  export { DURABLE_HOP_BUDGET_MS, turnCheckpointPath, workspaceTurnCheckpoints, type CheckpointWorkspaceStore, type TurnCheckpointStore } from './turn-continuation';
25
26
  export { budgetTurnKnowledge, turnKnowledgeInstructions, workspaceKnowledgeForTurn, type TurnKnowledgeBudget, type TurnKnowledgeFile } from './turn-knowledge';
26
27
  export { asksForLanguage, replyLanguageInstruction } from './reply-language';
@@ -42,6 +43,10 @@ export interface RouterTurnToolContext {
42
43
  emit(kind: string, data?: unknown): void;
43
44
  /** The sender's message this turn answers, so a tool can act only on what was asked (see {@link asksForLanguage}). */
44
45
  userMessage: string;
46
+ /** The turn's trace, when the turn records one. A tool that waits on a box or a service adds its own child spans under {@link span}. */
47
+ trace?: TurnTrace;
48
+ /** This tool call's `tool.call` span; the parent of any span the tool records. */
49
+ span?: TurnSpan;
45
50
  }
46
51
  /** One side event a tool reported while it ran. */
47
52
  export interface RouterTurnToolEvent {
@@ -199,8 +204,16 @@ export interface RouterTurnOptions {
199
204
  /** Runaway backstop on model turns. Default 12. */
200
205
  maxToolTurns?: number;
201
206
  maxTokens?: number;
202
- /** Sent as `x-tangle-trace-id` so the router's generation joins the app's trace. */
207
+ /** Sent as `x-tangle-trace-id` so the router's generation joins the app's trace. Characters the Router
208
+ * refuses in that header (the `:` of an execution id) become `_`; see {@link turnTraceId}. Default: the
209
+ * `trace`'s id. */
203
210
  traceId?: string;
211
+ /**
212
+ * The turn's trace (`@tangle-network/agent-app/turn-trace`). Every model request is recorded as a
213
+ * `model.call` span with the Router's `Server-Timing` split into network and server time, and every tool
214
+ * call as a `tool.call` span that tool-side spans hang from. Without it nothing is recorded.
215
+ */
216
+ trace?: TurnTrace;
204
217
  fetchImpl?: typeof fetch;
205
218
  onEvent?: (event: RouterTurnEvent) => void;
206
219
  /** Map a thrown tool error to what the model reads. Default: an error carrying string `code`
@@ -11,9 +11,11 @@ import {
11
11
  turnKnowledgeInstructions,
12
12
  workspaceKnowledgeForTurn,
13
13
  workspaceTurnCheckpoints
14
- } from "../chunk-FPOOBGRG.js";
14
+ } from "../chunk-T4BLISYH.js";
15
+ import "../chunk-7XQIY2LU.js";
15
16
  import "../chunk-D6UJEOZQ.js";
16
17
  import "../chunk-AMUXRAUO.js";
18
+ import "../chunk-BKPJFES3.js";
17
19
  export {
18
20
  DURABLE_HOP_BUDGET_MS,
19
21
  asksForLanguage,
@@ -5,6 +5,7 @@ import { type AppToolName, type AppToolContext, type ToolHeaderNames } from '../
5
5
  import { type Harness } from '../harness/index';
6
6
  import { type TangleExecutionEnvironment } from '../runtime/model';
7
7
  import { type Outcome } from './outcome';
8
+ import type { TurnSpan, TurnTrace } from '../turn-trace/recorder';
8
9
  import { type ProfileFingerprint } from '../profile/fingerprint';
9
10
  import { type ComposeProfileBudget } from '../profile/budget';
10
11
  import { resolveModel, resolveModelSelection, backendModelFields, requireTransportableModel, SandboxModelResolutionError, type ProviderResolutionConfig, type ResolvedModel, type ModelSelection, type ModelSelectionFailure, type ModelSelectionError, type ModelSelectionSource } from './model';
@@ -282,6 +283,15 @@ export interface EnsureWorkspaceSandboxOptions {
282
283
  * product can see which round trip a slow acquisition spent its time in.
283
284
  * Omitted, nothing is measured. */
284
285
  measure?: <T>(stage: string, operation: () => Promise<T>) => Promise<T>;
286
+ /**
287
+ * The turn's trace. The ensure is recorded as one `sandbox.claim` span whose children are the
288
+ * `sandbox.ensure.*` steps (`credentials`, `list_running`, `finalize` for a reused box; `list_stopped`,
289
+ * `resume` for a stopped one; `create`, `wait_running`, `bootstrap` for a new one), so a slow claim names
290
+ * the step it waited on. Omitted, nothing is recorded; `measure` is unchanged and still called.
291
+ */
292
+ trace?: TurnTrace;
293
+ /** The span the claim hangs from. Default: the trace's root. */
294
+ traceParent?: TurnSpan;
285
295
  }
286
296
  /** What `/sandbox` reports once a box is provisioned, reused, or resumed. */
287
297
  export interface SandboxProvisionedObservation {
@@ -695,6 +705,15 @@ export interface StreamSandboxPromptOptions {
695
705
  detach?: boolean;
696
706
  onProfileResolved?: (fingerprint: ProfileFingerprint) => void;
697
707
  spend?: SandboxSpendHooks;
708
+ /**
709
+ * The turn's trace (`@tangle-network/agent-app/turn-trace`). Its id is sent as `traceId`, the
710
+ * `x-tangle-trace-id` the Sandbox API, orchestrator, sidecar and the Router's dispatch rows all record, and
711
+ * the stream is recorded as a `sandbox.prompt` span: the sidecar's first-text phases, the generation and
712
+ * each tool the box agent ran. Omitted, the SDK mints a trace id the app does not keep.
713
+ */
714
+ trace?: TurnTrace;
715
+ /** The span the prompt hangs from. Default: the trace's root. */
716
+ traceParent?: TurnSpan;
698
717
  }
699
718
  /**
700
719
  * The small event shape consumed by agent-gateway's streaming adapters.
@@ -97,7 +97,7 @@ import {
97
97
  warmBinOf,
98
98
  warmWeekdayOf,
99
99
  writeProfileFilesToBox
100
- } from "../chunk-SUIH5B55.js";
100
+ } from "../chunk-RJJRRR5Z.js";
101
101
  import {
102
102
  EGRESS_PROXY_RECOVERY_PHASE,
103
103
  EGRESS_PROXY_RECOVERY_REQUIRED,
@@ -146,6 +146,7 @@ import "../chunk-S5SRJJQG.js";
146
146
  import "../chunk-IJAXOQJU.js";
147
147
  import "../chunk-UGWQLQDS.js";
148
148
  import "../chunk-E65YV7VV.js";
149
+ import "../chunk-7XQIY2LU.js";
149
150
  import "../chunk-D6UJEOZQ.js";
150
151
  export {
151
152
  DEFAULT_ESCALATION_TOOLS,
@@ -0,0 +1,20 @@
1
+ /**
2
+ * What a sandbox prompt stream tells the turn's trace: one `sandbox.prompt`
3
+ * span for the whole stream, the sidecar's own first-text phases as child
4
+ * spans, one `sandbox.generation` span from the first visible text, and one
5
+ * `tool.call` span for each tool the box agent ran.
6
+ *
7
+ * Every time here is read on this side of the wire, from when each event
8
+ * arrived. Event arrival is quantized by the stream's chunking, so the tool
9
+ * spans carry `approx: true`. The sidecar's phases are offsets on its own
10
+ * clock; only their durations are used, and the wait that no phase holds (the
11
+ * SDK, the API, the orchestrator and the host, both ways) is `sandbox.transit`.
12
+ */
13
+ import type { TurnSpan, TurnSpanAttrs, TurnTrace } from '../turn-trace/recorder';
14
+ export interface PromptTrace {
15
+ /** Read one raw sandbox event. Never throws. */
16
+ observe(event: unknown): void;
17
+ /** End the stream's spans. `error` marks the prompt failed. */
18
+ end(error?: unknown): void;
19
+ }
20
+ export declare function createPromptTrace(trace: TurnTrace, parent: TurnSpan | undefined, meta: TurnSpanAttrs): PromptTrace;
@@ -18,6 +18,7 @@
18
18
  * one the speculator listens for (`DEFAULT_ESCALATION_TOOLS`).
19
19
  */
20
20
  import type { SandboxInstance } from '@tangle-network/sandbox';
21
+ import type { TurnSpan, TurnTrace } from '../turn-trace/recorder';
21
22
  import { type SandboxRuntimeConfig, type StreamSandboxPromptOptions } from './index';
22
23
  export type SandboxRunFailureCode = 'sandbox_unavailable' | 'sandbox_failed' | 'sandbox_empty' | 'invalid_arguments';
23
24
  /** A typed `sandbox_run` failure. `code` and `message` are what the model reads. */
@@ -30,12 +31,19 @@ export declare class SandboxRunError extends Error {
30
31
  /** The engine's per-call tool context (`RouterTurnToolContext`), kept structural so this module does not import the engine. */
31
32
  export interface SandboxToolContext {
32
33
  emit(kind: string, data?: unknown): void;
34
+ /** The turn's trace and this call's `tool.call` span (`runRouterTurn` supplies both). The box claim, the box run and the
35
+ * trace id sent to the Sandbox API follow from them; without them nothing is recorded. */
36
+ trace?: TurnTrace;
37
+ span?: TurnSpan;
33
38
  }
34
39
  export interface SandboxTaskOptions {
35
40
  signal: AbortSignal;
36
41
  timeoutMs: number;
37
42
  /** Streams a typed side event from the box run (a progress step, a file written) as the turn's `tool_event`. */
38
43
  emit(kind: string, data?: unknown): void;
44
+ /** The turn's trace and this call's span, for a runner that streams a prompt (`sandboxPromptRunner` does). */
45
+ trace?: TurnTrace;
46
+ span?: TurnSpan;
39
47
  }
40
48
  export interface SandboxRunToolOptions {
41
49
  /** The box this call runs in. The product provisions, binds and bills it; this module never
@@ -16,7 +16,6 @@
16
16
  export * from './mission-trace';
17
17
  export * from './flow-types';
18
18
  export * from './mission-flow';
19
- export * from './stage-timing';
20
19
  import type { FlowTrace } from './flow-types';
21
20
  /** Represent a timed event with a timestamp and associated event data */
22
21
  export interface TimedEvent {
@@ -46,242 +46,6 @@ function randomHex(byteLength) {
46
46
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
47
47
  }
48
48
 
49
- // src/trace/stage-timing.ts
50
- var STAGE_TIMING_EVENT = "stage_timing";
51
- var STAGE_TIMING_VERSION = 1;
52
- var MAX_STAGE_LENGTH = 80;
53
- var MAX_IDENTIFIER_LENGTH = 128;
54
- var MAX_DETAIL_KEYS = 8;
55
- var MAX_DETAIL_KEY_LENGTH = 64;
56
- var MAX_DETAIL_STRING_LENGTH = 64;
57
- var SENSITIVE_KEY = /(?:api|auth|access|refresh|session|private|secret|password|credential|cookie|bearer|token|ssn|ein|email|phone)[_-]?(?:key|token|secret)?/iu;
58
- var CREDENTIAL_VALUE = /\b(?:bearer|basic|digest|token)\s+\S+|\bapi[-_ ]?key\s*[:=]\s*\S+/iu;
59
- function boundedIdentifier(value) {
60
- if (typeof value !== "string") return void 0;
61
- const trimmed = value.trim();
62
- return trimmed ? trimmed.slice(0, MAX_IDENTIFIER_LENGTH) : void 0;
63
- }
64
- function safeProperty(value, key) {
65
- try {
66
- return Reflect.get(value, key);
67
- } catch {
68
- return void 0;
69
- }
70
- }
71
- function isObject(value) {
72
- return value !== null && typeof value === "object";
73
- }
74
- function sanitizeDetail(detail) {
75
- try {
76
- if (!isObject(detail) || Array.isArray(detail)) return void 0;
77
- const entries = [];
78
- for (const [rawKey, value] of Object.entries(detail)) {
79
- if (entries.length >= MAX_DETAIL_KEYS) break;
80
- const normalizedKey = rawKey.trim();
81
- if (!normalizedKey || SENSITIVE_KEY.test(normalizedKey) || value === void 0) {
82
- continue;
83
- }
84
- const key = normalizedKey.slice(0, MAX_DETAIL_KEY_LENGTH);
85
- if (typeof value === "string") {
86
- if (CREDENTIAL_VALUE.test(value)) continue;
87
- entries.push([key, value.slice(0, MAX_DETAIL_STRING_LENGTH)]);
88
- } else if (typeof value === "number") {
89
- entries.push([key, Number.isFinite(value) ? value : null]);
90
- } else if (typeof value === "boolean" || value === null) {
91
- entries.push([key, value]);
92
- }
93
- }
94
- return entries.length > 0 ? Object.fromEntries(entries) : void 0;
95
- } catch {
96
- return void 0;
97
- }
98
- }
99
- function isStageTimingKind(value) {
100
- return value === "leaf" || value === "span";
101
- }
102
- function isStageTimingOutcome(value) {
103
- return value === "ok" || value === "error" || value === "timeout" || value === "skipped";
104
- }
105
- function buildStageTimingRecord(context, stage, startedAt, durationMs, input = {}) {
106
- try {
107
- const name = typeof stage === "string" ? stage.trim() : "";
108
- if (!name || !Number.isFinite(startedAt) || startedAt < 0 || !Number.isFinite(durationMs) || durationMs < 0 || !isObject(context) || !isObject(input)) {
109
- return null;
110
- }
111
- const rawKind = safeProperty(input, "kind");
112
- const rawOutcome = safeProperty(input, "outcome");
113
- const kind = rawKind === void 0 ? "leaf" : rawKind;
114
- const outcome = rawOutcome === void 0 ? "ok" : rawOutcome;
115
- if (!isStageTimingKind(kind) || !isStageTimingOutcome(outcome)) return null;
116
- const runId = boundedIdentifier(safeProperty(context, "runId"));
117
- if (!runId) return null;
118
- const record = {
119
- evt: STAGE_TIMING_EVENT,
120
- v: STAGE_TIMING_VERSION,
121
- stage: name.slice(0, MAX_STAGE_LENGTH),
122
- kind,
123
- startedAt: Math.round(startedAt),
124
- durationMs: Math.round(durationMs),
125
- outcome,
126
- runId
127
- };
128
- for (const key of [
129
- "workspaceId",
130
- "threadId",
131
- "sandboxId",
132
- "model",
133
- "harness",
134
- "path"
135
- ]) {
136
- const value = boundedIdentifier(safeProperty(context, key));
137
- if (value) record[key] = value;
138
- }
139
- const attempt = safeProperty(input, "attempt");
140
- if (typeof attempt === "number" && Number.isSafeInteger(attempt) && attempt >= 0) {
141
- record.attempt = attempt;
142
- }
143
- const detail = sanitizeDetail(safeProperty(input, "detail"));
144
- if (detail) record.detail = detail;
145
- return record;
146
- } catch {
147
- return null;
148
- }
149
- }
150
- function safePrimitiveText(value) {
151
- if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean" && typeof value !== "bigint" && typeof value !== "symbol") {
152
- return "";
153
- }
154
- try {
155
- return String(value);
156
- } catch {
157
- return "";
158
- }
159
- }
160
- function outcomeForError(error) {
161
- try {
162
- const objectLike = isObject(error) || typeof error === "function";
163
- const code = objectLike ? safePrimitiveText(safeProperty(error, "code")) : "";
164
- const message = objectLike ? safePrimitiveText(safeProperty(error, "message")) : safePrimitiveText(error);
165
- return /timeout|timed ?out|deadline/iu.test(`${code} ${message}`) ? "timeout" : "error";
166
- } catch {
167
- return "error";
168
- }
169
- }
170
- function safeClock(now) {
171
- try {
172
- const value = now();
173
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
174
- } catch {
175
- return void 0;
176
- }
177
- }
178
- function safeObject(value) {
179
- try {
180
- if (!isObject(value) || Array.isArray(value)) return {};
181
- return { ...value };
182
- } catch {
183
- return {};
184
- }
185
- }
186
- function mergeInputs(base, extra) {
187
- const baseObject = safeObject(base);
188
- const extraObject = safeObject(extra);
189
- const detail = {
190
- ...safeObject(baseObject.detail),
191
- ...safeObject(extraObject.detail)
192
- };
193
- return {
194
- ...baseObject,
195
- ...extraObject,
196
- detail
197
- };
198
- }
199
- function withOutcome(extra, outcome) {
200
- return { ...safeObject(extra), outcome };
201
- }
202
- function createStageTiming(options) {
203
- const now = options.now ?? (() => Date.now());
204
- const generatedRunId = () => {
205
- try {
206
- const value = (options.createRunId ?? (() => crypto.randomUUID()))();
207
- return boundedIdentifier(value) ?? crypto.randomUUID();
208
- } catch {
209
- try {
210
- return crypto.randomUUID();
211
- } catch {
212
- return "run-unknown";
213
- }
214
- }
215
- };
216
- const context = {
217
- ...options.context,
218
- runId: boundedIdentifier(options.context?.runId) ?? generatedRunId()
219
- };
220
- const emit = (stage, startedAt, durationMs, input = {}) => {
221
- try {
222
- const record = buildStageTimingRecord(context, stage, startedAt, durationMs, input);
223
- if (!record) return;
224
- const result = options.emit(record);
225
- if (result && typeof result.then === "function") {
226
- void Promise.resolve(result).catch(() => void 0);
227
- }
228
- } catch {
229
- }
230
- };
231
- const start = (stage, input = {}) => {
232
- const observedStart = safeClock(now);
233
- const startedAt = observedStart ?? 0;
234
- let emitted = false;
235
- const finish = (extra = {}) => {
236
- if (emitted) return;
237
- emitted = true;
238
- if (observedStart === void 0) return;
239
- const observedEnd = safeClock(now);
240
- if (observedEnd === void 0) return;
241
- try {
242
- emit(stage, observedStart, observedEnd - observedStart, mergeInputs(input, extra));
243
- } catch {
244
- }
245
- };
246
- return {
247
- startedAt,
248
- done: finish,
249
- fail(error, extra = {}) {
250
- let outcome = "error";
251
- try {
252
- outcome = outcomeForError(error);
253
- } catch {
254
- }
255
- finish(withOutcome(extra, outcome));
256
- }
257
- };
258
- };
259
- return {
260
- context,
261
- setContext(input) {
262
- try {
263
- Object.assign(context, input);
264
- } catch {
265
- }
266
- },
267
- recordDuration(stage, startedAt, durationMs, input = {}) {
268
- emit(stage, startedAt, durationMs, input);
269
- },
270
- start,
271
- async measure(stage, input, operation) {
272
- const handle = start(stage, input);
273
- try {
274
- const value = await operation();
275
- handle.done();
276
- return value;
277
- } catch (error) {
278
- handle.fail(error);
279
- throw error;
280
- }
281
- }
282
- };
283
- }
284
-
285
49
  // src/trace/index.ts
286
50
  function timedEventsFromLines(lines) {
287
51
  const out = [];
@@ -420,14 +184,10 @@ function renderHistogram(values, opts) {
420
184
  return lines.join("\n");
421
185
  }
422
186
  export {
423
- STAGE_TIMING_EVENT,
424
- STAGE_TIMING_VERSION,
425
187
  buildFlowTrace,
426
- buildStageTimingRecord,
427
188
  childSpanContext,
428
189
  composeMissionFlowTrace,
429
190
  createMissionTraceContext,
430
- createStageTiming,
431
191
  delegationActivityToFlowSpans,
432
192
  loopTraceEventsToFlowSpans,
433
193
  renderHistogram,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/trace/mission-trace.ts","../../src/trace/stage-timing.ts","../../src/trace/index.ts"],"sourcesContent":["/**\n * Mission trace context — mint + thread the trace ids that join a mission's\n * step attempts and its delegated agent runs into ONE trace tree.\n *\n * ID formats are byte-compatible with agent-runtime's trace propagation\n * (`readTraceContextFromEnv` / OTLP export): 32 lowercase hex chars for a\n * trace id (16 bytes), 16 for a span id (8 bytes). The env pair from\n * {@link traceEnv} is exactly what agent-runtime's MCP subprocess reads at\n * startup (`TRACE_ID` + `PARENT_SPAN_ID`), so a delegation dispatched with it\n * parents its loop→round→iteration spans under the mission's step span.\n *\n * Pure functions, no deps. Ids are DETERMINISTIC when a key is supplied\n * (missionId / step-attempt seed) so a crashed driver re-mints the identical\n * context on re-dispatch and the re-run joins the same trace instead of\n * forking a new one; without a key they are random.\n */\n\nexport interface MissionTraceContext {\n /** 32-hex trace id shared by every span in the mission's tree. */\n traceId: string\n /** 16-hex span id of the mission root — the parent of every step span. */\n rootSpanId: string\n}\n\n/** Define context information for a step span including trace, span, and parent span identifiers */\nexport interface StepSpanContext {\n traceId: string\n /** 16-hex span id of this step attempt (or any nested unit of work). */\n spanId: string\n /** The span this one nests under. */\n parentSpanId: string\n}\n\n/**\n * Mint a mission's trace context. With `missionId` the ids are a pure\n * function of it; omitted, both ids are random.\n */\nexport function createMissionTraceContext(missionId?: string): MissionTraceContext {\n if (missionId !== undefined && missionId !== '') {\n return {\n traceId: hex64(fnv1a64(`mission-trace:${missionId}`)) + hex64(fnv1a64(`mission-trace:2:${missionId}`)),\n rootSpanId: hex64(fnv1a64(`mission-root-span:${missionId}`)),\n }\n }\n return { traceId: randomHex(16), rootSpanId: randomHex(8) }\n}\n\n/**\n * Derive a child span context under `parent` — one per step attempt (seed\n * e.g. `\"${stepId}#${attempt}\"`), or nested under another step span. With a\n * seed the span id is deterministic for the same parent + seed; omitted, it\n * is random.\n */\nexport function childSpanContext(\n parent: MissionTraceContext | StepSpanContext,\n seed?: string,\n): StepSpanContext {\n const parentSpanId = 'rootSpanId' in parent ? parent.rootSpanId : parent.spanId\n const spanId =\n seed !== undefined && seed !== ''\n ? hex64(fnv1a64(`span:${parent.traceId}:${parentSpanId}:${seed}`))\n : randomHex(8)\n return { traceId: parent.traceId, spanId, parentSpanId }\n}\n\n/**\n * The env pair a delegation subprocess inherits — agent-runtime's\n * `readTraceContextFromEnv` reads exactly these names. `PARENT_SPAN_ID` is\n * the span the dispatched work nests under: the root for a mission context,\n * the step-attempt span for a step context.\n */\nexport function traceEnv(ctx: MissionTraceContext | StepSpanContext): {\n TRACE_ID: string\n PARENT_SPAN_ID: string\n} {\n return {\n TRACE_ID: ctx.traceId,\n PARENT_SPAN_ID: 'rootSpanId' in ctx ? ctx.rootSpanId : ctx.spanId,\n }\n}\n\n// FNV-1a 64-bit over UTF-16 code units — a stable, dependency-free digest for\n// deterministic ids. Not cryptographic; trace ids only need uniqueness within\n// a tenant's missions, not unforgeability.\nconst FNV_OFFSET = 0xcbf29ce484222325n\nconst FNV_PRIME = 0x100000001b3n\nconst MASK_64 = 0xffffffffffffffffn\n\nfunction fnv1a64(input: string): bigint {\n let hash = FNV_OFFSET\n for (let i = 0; i < input.length; i++) {\n hash ^= BigInt(input.charCodeAt(i))\n hash = (hash * FNV_PRIME) & MASK_64\n }\n return hash\n}\n\nfunction hex64(value: bigint): string {\n return value.toString(16).padStart(16, '0')\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength)\n globalThis.crypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/** Structured, bounded latency records for one request or agent turn. */\n\nexport const STAGE_TIMING_EVENT = 'stage_timing'\nexport const STAGE_TIMING_VERSION = 1\n\nexport type StageTimingOutcome = 'ok' | 'error' | 'timeout' | 'skipped'\nexport type StageTimingKind = 'leaf' | 'span'\nexport type StageTimingDetailValue = string | number | boolean | null\n\nexport interface StageTimingContext {\n runId: string\n workspaceId?: string\n threadId?: string\n sandboxId?: string\n model?: string\n harness?: string\n path?: string\n}\n\nexport interface StageTimingRecordInput {\n kind?: StageTimingKind\n outcome?: StageTimingOutcome\n attempt?: number\n /** Bounded primitive operational metadata only. Do not pass user input or credentials. */\n detail?: Record<string, StageTimingDetailValue | undefined>\n}\n\nexport interface StageTimingRecord extends StageTimingContext {\n evt: typeof STAGE_TIMING_EVENT\n v: typeof STAGE_TIMING_VERSION\n stage: string\n kind: StageTimingKind\n startedAt: number\n durationMs: number\n outcome: StageTimingOutcome\n attempt?: number\n detail?: Record<string, StageTimingDetailValue>\n}\n\nexport interface StageTimingHandle {\n readonly startedAt: number\n done(input?: StageTimingRecordInput): void\n fail(error: unknown, input?: StageTimingRecordInput): void\n}\n\nexport interface StageTiming {\n readonly context: Readonly<StageTimingContext>\n setContext(input: Partial<Omit<StageTimingContext, 'runId'>>): void\n recordDuration(\n stage: string,\n startedAt: number,\n durationMs: number,\n input?: StageTimingRecordInput,\n ): void\n start(stage: string, input?: StageTimingRecordInput): StageTimingHandle\n measure<T>(\n stage: string,\n input: StageTimingRecordInput,\n operation: () => Promise<T>,\n ): Promise<T>\n}\n\nexport interface CreateStageTimingOptions {\n context?: Partial<StageTimingContext>\n /** Carrier for a validated record. Throws and rejected promises are contained. */\n emit(record: StageTimingRecord): void | Promise<void>\n /** Epoch-millisecond clock. Defaults to `Date.now`; clock failures drop the record. */\n now?(): number\n /** ID seam used only when `context.runId` is absent. */\n createRunId?(): string\n}\n\nconst MAX_STAGE_LENGTH = 80\nconst MAX_IDENTIFIER_LENGTH = 128\nconst MAX_DETAIL_KEYS = 8\nconst MAX_DETAIL_KEY_LENGTH = 64\nconst MAX_DETAIL_STRING_LENGTH = 64\nconst SENSITIVE_KEY =\n /(?:api|auth|access|refresh|session|private|secret|password|credential|cookie|bearer|token|ssn|ein|email|phone)[_-]?(?:key|token|secret)?/iu\nconst CREDENTIAL_VALUE =\n /\\b(?:bearer|basic|digest|token)\\s+\\S+|\\bapi[-_ ]?key\\s*[:=]\\s*\\S+/iu\n\nfunction boundedIdentifier(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed ? trimmed.slice(0, MAX_IDENTIFIER_LENGTH) : undefined\n}\n\nfunction safeProperty(value: object, key: string): unknown {\n try {\n return Reflect.get(value, key)\n } catch {\n return undefined\n }\n}\n\nfunction isObject(value: unknown): value is object {\n return value !== null && typeof value === 'object'\n}\n\nfunction sanitizeDetail(\n detail: unknown,\n): Record<string, StageTimingDetailValue> | undefined {\n try {\n if (!isObject(detail) || Array.isArray(detail)) return undefined\n const entries: [string, StageTimingDetailValue][] = []\n for (const [rawKey, value] of Object.entries(detail)) {\n if (entries.length >= MAX_DETAIL_KEYS) break\n const normalizedKey = rawKey.trim()\n if (\n !normalizedKey ||\n SENSITIVE_KEY.test(normalizedKey) ||\n value === undefined\n ) {\n continue\n }\n const key = normalizedKey.slice(0, MAX_DETAIL_KEY_LENGTH)\n if (typeof value === 'string') {\n if (CREDENTIAL_VALUE.test(value)) continue\n entries.push([key, value.slice(0, MAX_DETAIL_STRING_LENGTH)])\n } else if (typeof value === 'number') {\n entries.push([key, Number.isFinite(value) ? value : null])\n } else if (typeof value === 'boolean' || value === null) {\n entries.push([key, value])\n }\n }\n return entries.length > 0 ? Object.fromEntries(entries) : undefined\n } catch {\n return undefined\n }\n}\n\nfunction isStageTimingKind(value: unknown): value is StageTimingKind {\n return value === 'leaf' || value === 'span'\n}\n\nfunction isStageTimingOutcome(value: unknown): value is StageTimingOutcome {\n return value === 'ok' || value === 'error' || value === 'timeout' || value === 'skipped'\n}\n\n/** Build one safe record, or return null when its required fields are invalid. */\nexport function buildStageTimingRecord(\n context: StageTimingContext,\n stage: string,\n startedAt: number,\n durationMs: number,\n input: StageTimingRecordInput = {},\n): StageTimingRecord | null {\n try {\n const name = typeof stage === 'string' ? stage.trim() : ''\n if (\n !name ||\n !Number.isFinite(startedAt) ||\n startedAt < 0 ||\n !Number.isFinite(durationMs) ||\n durationMs < 0 ||\n !isObject(context) ||\n !isObject(input)\n ) {\n return null\n }\n\n const rawKind = safeProperty(input, 'kind')\n const rawOutcome = safeProperty(input, 'outcome')\n const kind = rawKind === undefined ? 'leaf' : rawKind\n const outcome = rawOutcome === undefined ? 'ok' : rawOutcome\n if (!isStageTimingKind(kind) || !isStageTimingOutcome(outcome)) return null\n\n const runId = boundedIdentifier(safeProperty(context, 'runId'))\n if (!runId) return null\n const record: StageTimingRecord = {\n evt: STAGE_TIMING_EVENT,\n v: STAGE_TIMING_VERSION,\n stage: name.slice(0, MAX_STAGE_LENGTH),\n kind,\n startedAt: Math.round(startedAt),\n durationMs: Math.round(durationMs),\n outcome,\n runId,\n }\n\n for (const key of [\n 'workspaceId',\n 'threadId',\n 'sandboxId',\n 'model',\n 'harness',\n 'path',\n ] as const) {\n const value = boundedIdentifier(safeProperty(context, key))\n if (value) record[key] = value\n }\n const attempt = safeProperty(input, 'attempt')\n if (\n typeof attempt === 'number' &&\n Number.isSafeInteger(attempt) &&\n attempt >= 0\n ) {\n record.attempt = attempt\n }\n const detail = sanitizeDetail(safeProperty(input, 'detail'))\n if (detail) record.detail = detail\n return record\n } catch {\n return null\n }\n}\n\nfunction safePrimitiveText(value: unknown): string {\n if (\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean' &&\n typeof value !== 'bigint' &&\n typeof value !== 'symbol'\n ) {\n return ''\n }\n try {\n return String(value)\n } catch {\n return ''\n }\n}\n\nfunction outcomeForError(error: unknown): StageTimingOutcome {\n try {\n const objectLike = isObject(error) || typeof error === 'function'\n const code = objectLike ? safePrimitiveText(safeProperty(error as object, 'code')) : ''\n const message = objectLike\n ? safePrimitiveText(safeProperty(error as object, 'message'))\n : safePrimitiveText(error)\n return /timeout|timed ?out|deadline/iu.test(`${code} ${message}`)\n ? 'timeout'\n : 'error'\n } catch {\n return 'error'\n }\n}\n\nfunction safeClock(now: () => number): number | undefined {\n try {\n const value = now()\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n ? value\n : undefined\n } catch {\n return undefined\n }\n}\n\nfunction safeObject(value: unknown): Record<string, unknown> {\n try {\n if (!isObject(value) || Array.isArray(value)) return {}\n return { ...value }\n } catch {\n return {}\n }\n}\n\nfunction mergeInputs(\n base: unknown,\n extra: unknown,\n): StageTimingRecordInput {\n const baseObject = safeObject(base)\n const extraObject = safeObject(extra)\n const detail = {\n ...safeObject(baseObject.detail),\n ...safeObject(extraObject.detail),\n }\n return {\n ...baseObject,\n ...extraObject,\n detail: detail as Record<string, StageTimingDetailValue | undefined>,\n }\n}\n\nfunction withOutcome(extra: unknown, outcome: StageTimingOutcome): StageTimingRecordInput {\n return { ...safeObject(extra), outcome }\n}\n\n/**\n * Create a stage timer with an injected carrier. Invalid records and carrier\n * failures are dropped because telemetry cannot decide request success.\n */\nexport function createStageTiming(options: CreateStageTimingOptions): StageTiming {\n const now = options.now ?? (() => Date.now())\n const generatedRunId = () => {\n try {\n const value = (options.createRunId ?? (() => crypto.randomUUID()))()\n return boundedIdentifier(value) ?? crypto.randomUUID()\n } catch {\n try {\n return crypto.randomUUID()\n } catch {\n return 'run-unknown'\n }\n }\n }\n const context: StageTimingContext = {\n ...options.context,\n runId: boundedIdentifier(options.context?.runId) ?? generatedRunId(),\n }\n\n const emit = (\n stage: string,\n startedAt: number,\n durationMs: number,\n input: StageTimingRecordInput = {},\n ): void => {\n try {\n const record = buildStageTimingRecord(context, stage, startedAt, durationMs, input)\n if (!record) return\n const result = options.emit(record)\n if (result && typeof result.then === 'function') {\n void Promise.resolve(result).catch(() => undefined)\n }\n } catch {\n // Telemetry cannot decide whether the measured operation succeeds.\n }\n }\n\n const start = (\n stage: string,\n input: StageTimingRecordInput = {},\n ): StageTimingHandle => {\n const observedStart = safeClock(now)\n const startedAt = observedStart ?? 0\n let emitted = false\n const finish = (extra: StageTimingRecordInput = {}) => {\n if (emitted) return\n emitted = true\n if (observedStart === undefined) return\n const observedEnd = safeClock(now)\n if (observedEnd === undefined) return\n try {\n emit(stage, observedStart, observedEnd - observedStart, mergeInputs(input, extra))\n } catch {\n // A timer must never change the measured operation.\n }\n }\n return {\n startedAt,\n done: finish,\n fail(error, extra = {}) {\n let outcome: StageTimingOutcome = 'error'\n try {\n outcome = outcomeForError(error)\n } catch {\n // Keep the fallback error outcome when classification is hostile.\n }\n finish(withOutcome(extra, outcome))\n },\n }\n }\n\n return {\n context,\n setContext(input) {\n try {\n Object.assign(context, input)\n } catch {\n // Telemetry context updates cannot affect the measured operation.\n }\n },\n recordDuration(stage, startedAt, durationMs, input = {}) {\n emit(stage, startedAt, durationMs, input)\n },\n start,\n async measure(stage, input, operation) {\n const handle = start(stage, input)\n try {\n const value = await operation()\n handle.done()\n return value\n } catch (error) {\n handle.fail(error)\n throw error\n }\n },\n }\n}\n","/**\n * `@tangle-network/agent-app/trace` — flow observability for agent turns.\n *\n * The turn buffer stamps `_t` (ms since turn start) on every event, so any\n * live stream OR any historical turn replayed from a TurnEventStore can be\n * reconstructed into a span trace: pipeline overhead, model segments (with\n * thinking TTFT), tool executions, token usage, and cost. Renderers turn\n * traces and multi-run samples into ASCII waterfalls and histograms — the\n * default artifact for \"how did this run actually behave\" questions across\n * evals, hill-climbs, and production debugging.\n *\n * Span boundaries derived from a buffered stream are quantized by the\n * pump's flush window and the reader's poll cadence (~100–400ms); spans\n * carry `approx: true` to keep reports honest about that.\n */\n\nexport * from './mission-trace'\nexport * from './flow-types'\nexport * from './mission-flow'\nexport * from './stage-timing'\n\nimport type { FlowSpan, FlowTrace } from './flow-types'\n\n/** Represent a timed event with a timestamp and associated event data */\nexport interface TimedEvent {\n /** ms since turn start (`_t` stamped by pumpBufferedTurn). */\n t: number\n event: Record<string, unknown>\n}\n\n/** Parse stored turn-event lines (JSON strings with `_t`) into TimedEvents. */\nexport function timedEventsFromLines(lines: string[]): TimedEvent[] {\n const out: TimedEvent[] = []\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>\n if (typeof parsed._t === 'number') out.push({ t: parsed._t, event: parsed })\n } catch {\n /* skip torn lines */\n }\n }\n return out.sort((a, b) => a.t - b.t)\n}\n\nfunction innerOf(e: Record<string, unknown>): Record<string, unknown> {\n return (e.kind === 'event' ? (e.event as Record<string, unknown>) : e) ?? {}\n}\n\n/**\n * Derive a span trace from timestamped turn events. Model segments are runs\n * of text/reasoning deltas; a tool span opens at the last delta before its\n * tool_call emission and closes at the matching tool_result.\n */\nexport function buildFlowTrace(\n events: TimedEvent[],\n opts?: { pricing?: { prompt?: string | number; completion?: string | number } },\n): FlowTrace {\n const spans: FlowSpan[] = []\n let promptTokens = 0\n let completionTokens = 0\n let toolCalls = 0\n\n const first = events[0]?.t ?? 0\n if (first > 0) {\n spans.push({ kind: 'pipeline', name: 'dispatch → first event', startMs: 0, endMs: first })\n }\n\n let segStart: number | null = null\n let segEnd = 0\n let segKinds = new Set<string>()\n let lastDeltaT = first\n const openCalls = new Map<string, { name: string; emitT: number; lastDeltaT: number }>()\n\n const closeSegment = () => {\n if (segStart !== null) {\n spans.push({\n kind: 'model',\n name: segKinds.has('reasoning') ? 'model turn (reasoning + text)' : 'model turn',\n startMs: segStart,\n endMs: segEnd,\n approx: true,\n })\n segStart = null\n segKinds = new Set()\n }\n }\n\n for (const { t, event } of events) {\n const inner = innerOf(event)\n const type = String(event.kind === 'tool_result' ? 'tool_result' : (inner.type ?? ''))\n\n if (type === 'text' || type === 'reasoning') {\n if (segStart === null) segStart = t\n segEnd = t\n segKinds.add(type)\n lastDeltaT = t\n } else if (type === 'tool_call') {\n closeSegment()\n toolCalls++\n const call = (inner.call ?? inner) as Record<string, unknown>\n const id = String(call.toolCallId ?? `call_${toolCalls}`)\n openCalls.set(id, { name: String(call.toolName ?? 'tool'), emitT: t, lastDeltaT })\n } else if (type === 'tool_result') {\n const id = String(event.toolCallId ?? inner.toolCallId ?? '')\n const open = openCalls.get(id)\n if (open) {\n spans.push({\n kind: 'tool',\n name: open.name,\n // Execution happens between the end of the model turn that emitted\n // the call and the result landing in the buffer.\n startMs: open.lastDeltaT,\n endMs: t,\n approx: true,\n meta: { ok: ((event.outcome ?? inner.outcome) as { ok?: boolean } | undefined)?.ok },\n })\n openCalls.delete(id)\n }\n } else if (type === 'usage') {\n const u = (inner.usage ?? {}) as { promptTokens?: number; completionTokens?: number }\n promptTokens += u.promptTokens ?? 0\n completionTokens += u.completionTokens ?? 0\n }\n }\n closeSegment()\n\n const totalMs = events.length ? events[events.length - 1]!.t : 0\n const trace: FlowTrace = { spans, totalMs, promptTokens, completionTokens, toolCalls }\n const p = opts?.pricing\n if (p && (p.prompt != null || p.completion != null)) {\n trace.costUsd = promptTokens * Number(p.prompt ?? 0) + completionTokens * Number(p.completion ?? 0)\n }\n return trace\n}\n\nconst fmtS = (ms: number) => `${(ms / 1000).toFixed(1)}s`\n\n/** ASCII waterfall cascade — the default artifact for explaining a flow. */\nexport function renderWaterfall(trace: FlowTrace, opts?: { width?: number }): string {\n const width = opts?.width ?? 40\n const scale = trace.totalMs > 0 ? width / trace.totalMs : 0\n const lines: string[] = []\n const spans = [...trace.spans].sort((a, b) => a.startMs - b.startMs)\n for (let i = 0; i < spans.length; i++) {\n const s = spans[i]!\n const offset = Math.round(s.startMs * scale)\n const len = Math.max(1, Math.round((s.endMs - s.startMs) * scale))\n const bar = ' '.repeat(offset) + (s.kind === 'tool' ? '▓' : s.kind === 'pipeline' ? '░' : '█').repeat(len)\n const branch = i === spans.length - 1 ? '└─' : '├─'\n const dur = `${fmtS(s.endMs - s.startMs)}${s.approx ? '~' : ''}`\n lines.push(`${fmtS(s.startMs).padStart(7)} ${branch} ${bar.padEnd(width + 2)} ${s.name} (${dur})`)\n }\n const cost = trace.costUsd != null ? ` $${trace.costUsd.toFixed(trace.costUsd < 0.01 ? 6 : 4)}` : ''\n lines.push(\n `${fmtS(trace.totalMs).padStart(7)} ── total · ${trace.promptTokens}p + ${trace.completionTokens}c tok · ${trace.toolCalls} tool calls${cost}`,\n )\n return lines.join('\\n')\n}\n\n/** Summarize key statistics of a numerical distribution including count, min, percentiles, and max */\nexport interface DistributionSummary {\n n: number\n min: number\n p50: number\n p90: number\n max: number\n}\n\n/** Summarize numeric values into a distribution summary including count, min, median, 90th percentile, and max */\nexport function summarize(values: number[]): DistributionSummary {\n const sorted = [...values].sort((a, b) => a - b)\n const q = (p: number) => sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))] ?? 0\n return { n: sorted.length, min: sorted[0] ?? 0, p50: q(0.5), p90: q(0.9), max: sorted[sorted.length - 1] ?? 0 }\n}\n\n/** ASCII histogram for multi-run samples (eval latencies, costs, scores). */\nexport function renderHistogram(\n values: number[],\n opts?: { buckets?: number; width?: number; unit?: string; format?: (v: number) => string },\n): string {\n if (!values.length) return '(no samples)'\n const buckets = opts?.buckets ?? 6\n const width = opts?.width ?? 24\n const fmt = opts?.format ?? ((v: number) => `${Math.round(v)}${opts?.unit ?? ''}`)\n const s = summarize(values)\n const lo = s.min\n const hi = s.max === s.min ? s.min + 1 : s.max\n const counts = new Array<number>(buckets).fill(0)\n for (const v of values) {\n counts[Math.min(buckets - 1, Math.floor(((v - lo) / (hi - lo)) * buckets))]!++\n }\n const maxCount = Math.max(...counts)\n const lines = [\n `n=${s.n} min=${fmt(s.min)} p50=${fmt(s.p50)} p90=${fmt(s.p90)} max=${fmt(s.max)}`,\n ]\n for (let i = 0; i < buckets; i++) {\n const a = lo + ((hi - lo) * i) / buckets\n const b = lo + ((hi - lo) * (i + 1)) / buckets\n const bar = '█'.repeat(Math.max(counts[i]! > 0 ? 1 : 0, Math.round((counts[i]! / maxCount) * width)))\n lines.push(`${fmt(a).padStart(8)}-${fmt(b).padEnd(8)} ${bar} ${counts[i]}`)\n }\n return lines.join('\\n')\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/trace/mission-trace.ts","../../src/trace/index.ts"],"sourcesContent":["/**\n * Mission trace context — mint + thread the trace ids that join a mission's\n * step attempts and its delegated agent runs into ONE trace tree.\n *\n * ID formats are byte-compatible with agent-runtime's trace propagation\n * (`readTraceContextFromEnv` / OTLP export): 32 lowercase hex chars for a\n * trace id (16 bytes), 16 for a span id (8 bytes). The env pair from\n * {@link traceEnv} is exactly what agent-runtime's MCP subprocess reads at\n * startup (`TRACE_ID` + `PARENT_SPAN_ID`), so a delegation dispatched with it\n * parents its loop→round→iteration spans under the mission's step span.\n *\n * Pure functions, no deps. Ids are DETERMINISTIC when a key is supplied\n * (missionId / step-attempt seed) so a crashed driver re-mints the identical\n * context on re-dispatch and the re-run joins the same trace instead of\n * forking a new one; without a key they are random.\n */\n\nexport interface MissionTraceContext {\n /** 32-hex trace id shared by every span in the mission's tree. */\n traceId: string\n /** 16-hex span id of the mission root — the parent of every step span. */\n rootSpanId: string\n}\n\n/** Define context information for a step span including trace, span, and parent span identifiers */\nexport interface StepSpanContext {\n traceId: string\n /** 16-hex span id of this step attempt (or any nested unit of work). */\n spanId: string\n /** The span this one nests under. */\n parentSpanId: string\n}\n\n/**\n * Mint a mission's trace context. With `missionId` the ids are a pure\n * function of it; omitted, both ids are random.\n */\nexport function createMissionTraceContext(missionId?: string): MissionTraceContext {\n if (missionId !== undefined && missionId !== '') {\n return {\n traceId: hex64(fnv1a64(`mission-trace:${missionId}`)) + hex64(fnv1a64(`mission-trace:2:${missionId}`)),\n rootSpanId: hex64(fnv1a64(`mission-root-span:${missionId}`)),\n }\n }\n return { traceId: randomHex(16), rootSpanId: randomHex(8) }\n}\n\n/**\n * Derive a child span context under `parent` — one per step attempt (seed\n * e.g. `\"${stepId}#${attempt}\"`), or nested under another step span. With a\n * seed the span id is deterministic for the same parent + seed; omitted, it\n * is random.\n */\nexport function childSpanContext(\n parent: MissionTraceContext | StepSpanContext,\n seed?: string,\n): StepSpanContext {\n const parentSpanId = 'rootSpanId' in parent ? parent.rootSpanId : parent.spanId\n const spanId =\n seed !== undefined && seed !== ''\n ? hex64(fnv1a64(`span:${parent.traceId}:${parentSpanId}:${seed}`))\n : randomHex(8)\n return { traceId: parent.traceId, spanId, parentSpanId }\n}\n\n/**\n * The env pair a delegation subprocess inherits — agent-runtime's\n * `readTraceContextFromEnv` reads exactly these names. `PARENT_SPAN_ID` is\n * the span the dispatched work nests under: the root for a mission context,\n * the step-attempt span for a step context.\n */\nexport function traceEnv(ctx: MissionTraceContext | StepSpanContext): {\n TRACE_ID: string\n PARENT_SPAN_ID: string\n} {\n return {\n TRACE_ID: ctx.traceId,\n PARENT_SPAN_ID: 'rootSpanId' in ctx ? ctx.rootSpanId : ctx.spanId,\n }\n}\n\n// FNV-1a 64-bit over UTF-16 code units — a stable, dependency-free digest for\n// deterministic ids. Not cryptographic; trace ids only need uniqueness within\n// a tenant's missions, not unforgeability.\nconst FNV_OFFSET = 0xcbf29ce484222325n\nconst FNV_PRIME = 0x100000001b3n\nconst MASK_64 = 0xffffffffffffffffn\n\nfunction fnv1a64(input: string): bigint {\n let hash = FNV_OFFSET\n for (let i = 0; i < input.length; i++) {\n hash ^= BigInt(input.charCodeAt(i))\n hash = (hash * FNV_PRIME) & MASK_64\n }\n return hash\n}\n\nfunction hex64(value: bigint): string {\n return value.toString(16).padStart(16, '0')\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength)\n globalThis.crypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * `@tangle-network/agent-app/trace` — flow observability for agent turns.\n *\n * The turn buffer stamps `_t` (ms since turn start) on every event, so any\n * live stream OR any historical turn replayed from a TurnEventStore can be\n * reconstructed into a span trace: pipeline overhead, model segments (with\n * thinking TTFT), tool executions, token usage, and cost. Renderers turn\n * traces and multi-run samples into ASCII waterfalls and histograms — the\n * default artifact for \"how did this run actually behave\" questions across\n * evals, hill-climbs, and production debugging.\n *\n * Span boundaries derived from a buffered stream are quantized by the\n * pump's flush window and the reader's poll cadence (~100–400ms); spans\n * carry `approx: true` to keep reports honest about that.\n */\n\nexport * from './mission-trace'\nexport * from './flow-types'\nexport * from './mission-flow'\n\nimport type { FlowSpan, FlowTrace } from './flow-types'\n\n/** Represent a timed event with a timestamp and associated event data */\nexport interface TimedEvent {\n /** ms since turn start (`_t` stamped by pumpBufferedTurn). */\n t: number\n event: Record<string, unknown>\n}\n\n/** Parse stored turn-event lines (JSON strings with `_t`) into TimedEvents. */\nexport function timedEventsFromLines(lines: string[]): TimedEvent[] {\n const out: TimedEvent[] = []\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>\n if (typeof parsed._t === 'number') out.push({ t: parsed._t, event: parsed })\n } catch {\n /* skip torn lines */\n }\n }\n return out.sort((a, b) => a.t - b.t)\n}\n\nfunction innerOf(e: Record<string, unknown>): Record<string, unknown> {\n return (e.kind === 'event' ? (e.event as Record<string, unknown>) : e) ?? {}\n}\n\n/**\n * Derive a span trace from timestamped turn events. Model segments are runs\n * of text/reasoning deltas; a tool span opens at the last delta before its\n * tool_call emission and closes at the matching tool_result.\n */\nexport function buildFlowTrace(\n events: TimedEvent[],\n opts?: { pricing?: { prompt?: string | number; completion?: string | number } },\n): FlowTrace {\n const spans: FlowSpan[] = []\n let promptTokens = 0\n let completionTokens = 0\n let toolCalls = 0\n\n const first = events[0]?.t ?? 0\n if (first > 0) {\n spans.push({ kind: 'pipeline', name: 'dispatch → first event', startMs: 0, endMs: first })\n }\n\n let segStart: number | null = null\n let segEnd = 0\n let segKinds = new Set<string>()\n let lastDeltaT = first\n const openCalls = new Map<string, { name: string; emitT: number; lastDeltaT: number }>()\n\n const closeSegment = () => {\n if (segStart !== null) {\n spans.push({\n kind: 'model',\n name: segKinds.has('reasoning') ? 'model turn (reasoning + text)' : 'model turn',\n startMs: segStart,\n endMs: segEnd,\n approx: true,\n })\n segStart = null\n segKinds = new Set()\n }\n }\n\n for (const { t, event } of events) {\n const inner = innerOf(event)\n const type = String(event.kind === 'tool_result' ? 'tool_result' : (inner.type ?? ''))\n\n if (type === 'text' || type === 'reasoning') {\n if (segStart === null) segStart = t\n segEnd = t\n segKinds.add(type)\n lastDeltaT = t\n } else if (type === 'tool_call') {\n closeSegment()\n toolCalls++\n const call = (inner.call ?? inner) as Record<string, unknown>\n const id = String(call.toolCallId ?? `call_${toolCalls}`)\n openCalls.set(id, { name: String(call.toolName ?? 'tool'), emitT: t, lastDeltaT })\n } else if (type === 'tool_result') {\n const id = String(event.toolCallId ?? inner.toolCallId ?? '')\n const open = openCalls.get(id)\n if (open) {\n spans.push({\n kind: 'tool',\n name: open.name,\n // Execution happens between the end of the model turn that emitted\n // the call and the result landing in the buffer.\n startMs: open.lastDeltaT,\n endMs: t,\n approx: true,\n meta: { ok: ((event.outcome ?? inner.outcome) as { ok?: boolean } | undefined)?.ok },\n })\n openCalls.delete(id)\n }\n } else if (type === 'usage') {\n const u = (inner.usage ?? {}) as { promptTokens?: number; completionTokens?: number }\n promptTokens += u.promptTokens ?? 0\n completionTokens += u.completionTokens ?? 0\n }\n }\n closeSegment()\n\n const totalMs = events.length ? events[events.length - 1]!.t : 0\n const trace: FlowTrace = { spans, totalMs, promptTokens, completionTokens, toolCalls }\n const p = opts?.pricing\n if (p && (p.prompt != null || p.completion != null)) {\n trace.costUsd = promptTokens * Number(p.prompt ?? 0) + completionTokens * Number(p.completion ?? 0)\n }\n return trace\n}\n\nconst fmtS = (ms: number) => `${(ms / 1000).toFixed(1)}s`\n\n/** ASCII waterfall cascade — the default artifact for explaining a flow. */\nexport function renderWaterfall(trace: FlowTrace, opts?: { width?: number }): string {\n const width = opts?.width ?? 40\n const scale = trace.totalMs > 0 ? width / trace.totalMs : 0\n const lines: string[] = []\n const spans = [...trace.spans].sort((a, b) => a.startMs - b.startMs)\n for (let i = 0; i < spans.length; i++) {\n const s = spans[i]!\n const offset = Math.round(s.startMs * scale)\n const len = Math.max(1, Math.round((s.endMs - s.startMs) * scale))\n const bar = ' '.repeat(offset) + (s.kind === 'tool' ? '▓' : s.kind === 'pipeline' ? '░' : '█').repeat(len)\n const branch = i === spans.length - 1 ? '└─' : '├─'\n const dur = `${fmtS(s.endMs - s.startMs)}${s.approx ? '~' : ''}`\n lines.push(`${fmtS(s.startMs).padStart(7)} ${branch} ${bar.padEnd(width + 2)} ${s.name} (${dur})`)\n }\n const cost = trace.costUsd != null ? ` $${trace.costUsd.toFixed(trace.costUsd < 0.01 ? 6 : 4)}` : ''\n lines.push(\n `${fmtS(trace.totalMs).padStart(7)} ── total · ${trace.promptTokens}p + ${trace.completionTokens}c tok · ${trace.toolCalls} tool calls${cost}`,\n )\n return lines.join('\\n')\n}\n\n/** Summarize key statistics of a numerical distribution including count, min, percentiles, and max */\nexport interface DistributionSummary {\n n: number\n min: number\n p50: number\n p90: number\n max: number\n}\n\n/** Summarize numeric values into a distribution summary including count, min, median, 90th percentile, and max */\nexport function summarize(values: number[]): DistributionSummary {\n const sorted = [...values].sort((a, b) => a - b)\n const q = (p: number) => sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))] ?? 0\n return { n: sorted.length, min: sorted[0] ?? 0, p50: q(0.5), p90: q(0.9), max: sorted[sorted.length - 1] ?? 0 }\n}\n\n/** ASCII histogram for multi-run samples (eval latencies, costs, scores). */\nexport function renderHistogram(\n values: number[],\n opts?: { buckets?: number; width?: number; unit?: string; format?: (v: number) => string },\n): string {\n if (!values.length) return '(no samples)'\n const buckets = opts?.buckets ?? 6\n const width = opts?.width ?? 24\n const fmt = opts?.format ?? ((v: number) => `${Math.round(v)}${opts?.unit ?? ''}`)\n const s = summarize(values)\n const lo = s.min\n const hi = s.max === s.min ? s.min + 1 : s.max\n const counts = new Array<number>(buckets).fill(0)\n for (const v of values) {\n counts[Math.min(buckets - 1, Math.floor(((v - lo) / (hi - lo)) * buckets))]!++\n }\n const maxCount = Math.max(...counts)\n const lines = [\n `n=${s.n} min=${fmt(s.min)} p50=${fmt(s.p50)} p90=${fmt(s.p90)} max=${fmt(s.max)}`,\n ]\n for (let i = 0; i < buckets; i++) {\n const a = lo + ((hi - lo) * i) / buckets\n const b = lo + ((hi - lo) * (i + 1)) / buckets\n const bar = '█'.repeat(Math.max(counts[i]! > 0 ? 1 : 0, Math.round((counts[i]! / maxCount) * width)))\n lines.push(`${fmt(a).padStart(8)}-${fmt(b).padEnd(8)} ${bar} ${counts[i]}`)\n }\n return lines.join('\\n')\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `@tangle-network/agent-app/turn-trace` — one trace per agent turn.
3
+ *
4
+ * The recorder and the Router/Sandbox helpers are runtime-neutral. The OTLP
5
+ * sink imports the agent-runtime root, so a browser bundle must not import this
6
+ * entry; server code imports it for `createIntelligenceTurnTraceSink`.
7
+ */
8
+ export * from './recorder';
9
+ export * from './server-timing';
10
+ export * from './traced-fetch';
11
+ export * from './otel';