@tangle-network/agent-app 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/agent-activity-C8ZG0F0M.d.ts +43 -0
- package/dist/chunk-5RT6KY4G.js +190 -0
- package/dist/chunk-5RT6KY4G.js.map +1 -0
- package/dist/chunk-AFDROJ64.js +218 -0
- package/dist/chunk-AFDROJ64.js.map +1 -0
- package/dist/{chunk-UIWB2F6N.js → chunk-UDXMR3AD.js} +80 -24
- package/dist/chunk-UDXMR3AD.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +31 -1
- package/dist/missions/index.d.ts +38 -5
- package/dist/missions/index.js +3 -1
- package/dist/trace/index.d.ts +137 -1
- package/dist/trace/index.js +24 -138
- package/dist/trace/index.js.map +1 -1
- package/dist/web-react/index.d.ts +79 -1
- package/dist/web-react/index.js +386 -133
- package/dist/web-react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-UIWB2F6N.js.map +0 -1
package/dist/missions/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
2
|
+
export { W as WithAgentActivity, s as stepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Durable mission state — the guarded status machine for a multi-step agent run.
|
|
3
6
|
*
|
|
@@ -130,7 +133,11 @@ interface MissionAuditEvent {
|
|
|
130
133
|
*/
|
|
131
134
|
interface MissionStorePort {
|
|
132
135
|
load(id: string): Promise<MissionRecord | null>;
|
|
133
|
-
|
|
136
|
+
/** `extras` are the opaque product-column values from
|
|
137
|
+
* `CreateMissionInput.extras` — write them in the SAME statement as the
|
|
138
|
+
* record (single-write creation) or ignore them if the table has no extra
|
|
139
|
+
* columns. */
|
|
140
|
+
insert(record: MissionRecord, extras?: Record<string, unknown>): Promise<MissionRecord>;
|
|
134
141
|
update(id: string, guard: MissionUpdateGuard, patch: MissionUpdatePatch): Promise<MissionRecord | null>;
|
|
135
142
|
appendEvent(event: MissionAuditEvent): Promise<void>;
|
|
136
143
|
}
|
|
@@ -160,6 +167,13 @@ interface CreateMissionInput {
|
|
|
160
167
|
* model). Read back via `mission.metadata`; the engine only reads
|
|
161
168
|
* `stopRequested` from it. */
|
|
162
169
|
metadata?: Record<string, unknown> | null;
|
|
170
|
+
/**
|
|
171
|
+
* Opaque product-column values handed VERBATIM to `MissionStorePort.insert`
|
|
172
|
+
* (e.g. a `workflowId` FK on the product's mission table), so creation is a
|
|
173
|
+
* single write — no post-insert stamp. The service never reads, validates,
|
|
174
|
+
* or persists them itself; they exist only on the insert call.
|
|
175
|
+
*/
|
|
176
|
+
extras?: Record<string, unknown>;
|
|
163
177
|
}
|
|
164
178
|
interface SetStepStatusPatch {
|
|
165
179
|
sublabel?: string;
|
|
@@ -204,8 +218,14 @@ interface MissionServiceOptions {
|
|
|
204
218
|
store: MissionStorePort;
|
|
205
219
|
/** Injectable clock (epoch ms). Default `Date.now`. */
|
|
206
220
|
now?: () => number;
|
|
207
|
-
/**
|
|
208
|
-
*
|
|
221
|
+
/**
|
|
222
|
+
* Row-id generator when `CreateMissionInput.id` is omitted. Default
|
|
223
|
+
* `crypto.randomUUID()` — a 36-char dashed UUID. Inject your own when your
|
|
224
|
+
* mission table already has an id shape (e.g. 32-hex matching D1 row
|
|
225
|
+
* defaults): the service stamps the generated id verbatim onto the inserted
|
|
226
|
+
* record, so a mismatch with the rest of your schema surfaces only at the
|
|
227
|
+
* product layer. Keep id shape parity here, not in the store.
|
|
228
|
+
*/
|
|
209
229
|
generateId?: () => string;
|
|
210
230
|
}
|
|
211
231
|
declare function createMissionService(options: MissionServiceOptions): MissionService;
|
|
@@ -243,6 +263,7 @@ declare function createInMemoryMissionStore(): InMemoryMissionStore;
|
|
|
243
263
|
* idempotent + order-tolerant, so a re-sent or duplicated event converges.
|
|
244
264
|
* The sink itself does no dedupe.
|
|
245
265
|
*/
|
|
266
|
+
|
|
246
267
|
interface MissionEventSink {
|
|
247
268
|
emit(event: MissionStreamEvent): void;
|
|
248
269
|
}
|
|
@@ -291,7 +312,14 @@ type MissionStreamEvent = {
|
|
|
291
312
|
missionId: string;
|
|
292
313
|
at: number;
|
|
293
314
|
stepId: string;
|
|
294
|
-
sublabel
|
|
315
|
+
sublabel?: string;
|
|
316
|
+
/**
|
|
317
|
+
* Full CURRENT snapshot of the step's delegated runs — never a delta.
|
|
318
|
+
* The reducer replaces the whole lane (latest snapshot wins by `at`), so
|
|
319
|
+
* emitters re-send everything they know each time and at-least-once /
|
|
320
|
+
* out-of-order delivery converges.
|
|
321
|
+
*/
|
|
322
|
+
agentActivity?: StepAgentActivity[];
|
|
295
323
|
} | {
|
|
296
324
|
type: 'step.completed';
|
|
297
325
|
missionId: string;
|
|
@@ -360,6 +388,11 @@ interface MissionStepState {
|
|
|
360
388
|
sublabel?: string;
|
|
361
389
|
reason?: string;
|
|
362
390
|
durationMs?: number;
|
|
391
|
+
/** Latest delegated-run snapshot for the step (see `step.updated`). */
|
|
392
|
+
agentActivity?: StepAgentActivity[];
|
|
393
|
+
/** The `at` of the snapshot currently held — an older snapshot arriving
|
|
394
|
+
* late never replaces a newer one. */
|
|
395
|
+
agentActivityAt?: number;
|
|
363
396
|
}
|
|
364
397
|
/** Live per-mission view the reducer folds events into. */
|
|
365
398
|
interface MissionState {
|
|
@@ -695,4 +728,4 @@ declare function parseMissionBlocks(fullContent: string, options?: ParseMissionB
|
|
|
695
728
|
*/
|
|
696
729
|
declare function buildAgentMissionPlan(steps: ParsedMissionStep[]): MissionStep[];
|
|
697
730
|
|
|
698
|
-
export { type CompleteMissionInput, type CreateMissionInput, DEFAULT_MISSION_STEP_KINDS, type InMemoryMissionStore, MISSION_CONTROL_CHANNEL_ID, type MissionApprovalsPort, type MissionAuditEvent, MissionConcurrencyError, type MissionCostLedger, type MissionEngine, type MissionEngineOptions, type MissionEventSink, type MissionGateKind, type MissionGateOptions, type MissionGateProposal, type MissionOutcome, type MissionPlanRunOptions, type MissionProposalResolution, type MissionRecord, type MissionService, type MissionServiceOptions, type MissionState, type MissionStatus, type MissionStep, type MissionStepState, type MissionStepStatus, type MissionStorePort, type MissionStreamEvent, type MissionStreamStatus, type MissionStreamStep, type MissionStreamStepStatus, type MissionUpdateGuard, type MissionUpdatePatch, type ParseMissionBlocksOptions, type ParsedMission, type ParsedMissionStep, type PlanOutcome, RetryableStepError, type SandboxDispatch, type SandboxDispatchDoneResult, type SandboxDispatchInProgressResult, type SandboxDispatchInput, type SandboxDispatchResult, type SetStepStatusPatch, type StepGateClassification, type StepOutcome, applyMissionEvent, asMissionStreamEvent, budgetGateProposalId, buildAgentMissionPlan, createInMemoryMissionStore, createMissionEngine, createMissionService, isMissionStopRequested, isMissionTerminal, mergeMissionState, noopEventSink, parseMissionBlocks, parseSessionStreamEnvelope, reduceMissionEvents, stepGateProposalId, volumeGateProposalId };
|
|
731
|
+
export { type CompleteMissionInput, type CreateMissionInput, DEFAULT_MISSION_STEP_KINDS, type InMemoryMissionStore, MISSION_CONTROL_CHANNEL_ID, type MissionApprovalsPort, type MissionAuditEvent, MissionConcurrencyError, type MissionCostLedger, type MissionEngine, type MissionEngineOptions, type MissionEventSink, type MissionGateKind, type MissionGateOptions, type MissionGateProposal, type MissionOutcome, type MissionPlanRunOptions, type MissionProposalResolution, type MissionRecord, type MissionService, type MissionServiceOptions, type MissionState, type MissionStatus, type MissionStep, type MissionStepState, type MissionStepStatus, type MissionStorePort, type MissionStreamEvent, type MissionStreamStatus, type MissionStreamStep, type MissionStreamStepStatus, type MissionUpdateGuard, type MissionUpdatePatch, type ParseMissionBlocksOptions, type ParsedMission, type ParsedMissionStep, type PlanOutcome, RetryableStepError, type SandboxDispatch, type SandboxDispatchDoneResult, type SandboxDispatchInProgressResult, type SandboxDispatchInput, type SandboxDispatchResult, type SetStepStatusPatch, StepAgentActivity, type StepGateClassification, type StepOutcome, applyMissionEvent, asMissionStreamEvent, budgetGateProposalId, buildAgentMissionPlan, createInMemoryMissionStore, createMissionEngine, createMissionService, isMissionStopRequested, isMissionTerminal, mergeMissionState, noopEventSink, parseMissionBlocks, parseSessionStreamEnvelope, reduceMissionEvents, stepGateProposalId, volumeGateProposalId };
|
package/dist/missions/index.js
CHANGED
|
@@ -17,9 +17,10 @@ import {
|
|
|
17
17
|
parseMissionBlocks,
|
|
18
18
|
parseSessionStreamEnvelope,
|
|
19
19
|
reduceMissionEvents,
|
|
20
|
+
stepAgentActivity,
|
|
20
21
|
stepGateProposalId,
|
|
21
22
|
volumeGateProposalId
|
|
22
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-UDXMR3AD.js";
|
|
23
24
|
export {
|
|
24
25
|
DEFAULT_MISSION_STEP_KINDS,
|
|
25
26
|
MISSION_CONTROL_CHANNEL_ID,
|
|
@@ -39,6 +40,7 @@ export {
|
|
|
39
40
|
parseMissionBlocks,
|
|
40
41
|
parseSessionStreamEnvelope,
|
|
41
42
|
reduceMissionEvents,
|
|
43
|
+
stepAgentActivity,
|
|
42
44
|
stepGateProposalId,
|
|
43
45
|
volumeGateProposalId
|
|
44
46
|
};
|
package/dist/trace/index.d.ts
CHANGED
|
@@ -1,3 +1,138 @@
|
|
|
1
|
+
import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mission trace context — mint + thread the trace ids that join a mission's
|
|
5
|
+
* step attempts and its delegated agent runs into ONE trace tree.
|
|
6
|
+
*
|
|
7
|
+
* ID formats are byte-compatible with agent-runtime's trace propagation
|
|
8
|
+
* (`readTraceContextFromEnv` / OTLP export): 32 lowercase hex chars for a
|
|
9
|
+
* trace id (16 bytes), 16 for a span id (8 bytes). The env pair from
|
|
10
|
+
* {@link traceEnv} is exactly what agent-runtime's MCP subprocess reads at
|
|
11
|
+
* startup (`TRACE_ID` + `PARENT_SPAN_ID`), so a delegation dispatched with it
|
|
12
|
+
* parents its loop→round→iteration spans under the mission's step span.
|
|
13
|
+
*
|
|
14
|
+
* Pure functions, no deps. Ids are DETERMINISTIC when a key is supplied
|
|
15
|
+
* (missionId / step-attempt seed) so a crashed driver re-mints the identical
|
|
16
|
+
* context on re-dispatch and the re-run joins the same trace instead of
|
|
17
|
+
* forking a new one; without a key they are random.
|
|
18
|
+
*/
|
|
19
|
+
interface MissionTraceContext {
|
|
20
|
+
/** 32-hex trace id shared by every span in the mission's tree. */
|
|
21
|
+
traceId: string;
|
|
22
|
+
/** 16-hex span id of the mission root — the parent of every step span. */
|
|
23
|
+
rootSpanId: string;
|
|
24
|
+
}
|
|
25
|
+
interface StepSpanContext {
|
|
26
|
+
traceId: string;
|
|
27
|
+
/** 16-hex span id of this step attempt (or any nested unit of work). */
|
|
28
|
+
spanId: string;
|
|
29
|
+
/** The span this one nests under. */
|
|
30
|
+
parentSpanId: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Mint a mission's trace context. With `missionId` the ids are a pure
|
|
34
|
+
* function of it; omitted, both ids are random.
|
|
35
|
+
*/
|
|
36
|
+
declare function createMissionTraceContext(missionId?: string): MissionTraceContext;
|
|
37
|
+
/**
|
|
38
|
+
* Derive a child span context under `parent` — one per step attempt (seed
|
|
39
|
+
* e.g. `"${stepId}#${attempt}"`), or nested under another step span. With a
|
|
40
|
+
* seed the span id is deterministic for the same parent + seed; omitted, it
|
|
41
|
+
* is random.
|
|
42
|
+
*/
|
|
43
|
+
declare function childSpanContext(parent: MissionTraceContext | StepSpanContext, seed?: string): StepSpanContext;
|
|
44
|
+
/**
|
|
45
|
+
* The env pair a delegation subprocess inherits — agent-runtime's
|
|
46
|
+
* `readTraceContextFromEnv` reads exactly these names. `PARENT_SPAN_ID` is
|
|
47
|
+
* the span the dispatched work nests under: the root for a mission context,
|
|
48
|
+
* the step-attempt span for a step context.
|
|
49
|
+
*/
|
|
50
|
+
declare function traceEnv(ctx: MissionTraceContext | StepSpanContext): {
|
|
51
|
+
TRACE_ID: string;
|
|
52
|
+
PARENT_SPAN_ID: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Delegation → FlowSpan converters — render what a mission's delegated agent
|
|
57
|
+
* runs actually did as ONE FlowTrace, drawable by the existing
|
|
58
|
+
* `renderWaterfall` (or any viewer that consumes FlowSpans).
|
|
59
|
+
*
|
|
60
|
+
* Two fidelities, one tree:
|
|
61
|
+
* - COARSE: `delegationActivityToFlowSpans` draws one 'tool' span per
|
|
62
|
+
* delegation from the StepAgentActivity snapshot (startedAt/durationMs) —
|
|
63
|
+
* available live, from the step's journaled lane.
|
|
64
|
+
* - FINE: `loopTraceEventsToFlowSpans` reconstructs agent-runtime's
|
|
65
|
+
* loop → round → iteration hierarchy from the LoopTraceEvent journal a
|
|
66
|
+
* delegation persists. FlowSpans carry no parent ids, so nesting rides the
|
|
67
|
+
* span NAME (`loop ▸ round 0 ▸ iter 1 (coder)`), matching how the ASCII
|
|
68
|
+
* waterfall reads.
|
|
69
|
+
*
|
|
70
|
+
* `composeMissionFlowTrace` lays a whole mission out: one 'pipeline' span per
|
|
71
|
+
* step, each step's delegations beneath it. Pure data transforms — the
|
|
72
|
+
* structural `LoopTraceEventLike` keeps this module free of the optional
|
|
73
|
+
* agent-runtime peer.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/** Structural mirror of agent-runtime's `LoopTraceEvent` — same fields, no
|
|
77
|
+
* import, so journals parsed from JSON feed straight in. */
|
|
78
|
+
interface LoopTraceEventLike {
|
|
79
|
+
kind: string;
|
|
80
|
+
runId: string;
|
|
81
|
+
/** Epoch ms. */
|
|
82
|
+
timestamp: number;
|
|
83
|
+
payload: object;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* One 'tool' FlowSpan per delegation, positioned relative to `turnStartMs`
|
|
87
|
+
* (the epoch-ms origin of the trace — usually the step or mission start).
|
|
88
|
+
* A row whose `startedAt` does not parse cannot be placed on a timeline and
|
|
89
|
+
* is omitted from the WATERFALL (it stays in the lane itself). A run without
|
|
90
|
+
* `durationMs` is still in flight: its span extends to `opts.nowMs` when
|
|
91
|
+
* given, else renders as a point — `approx` flags both.
|
|
92
|
+
*/
|
|
93
|
+
declare function delegationActivityToFlowSpans(activity: StepAgentActivity[], turnStartMs: number, opts?: {
|
|
94
|
+
nowMs?: number;
|
|
95
|
+
}): FlowSpan[];
|
|
96
|
+
/**
|
|
97
|
+
* Reconstruct one delegation's loop → round → iteration tree from its
|
|
98
|
+
* journaled LoopTraceEvents, as FlowSpans relative to `loop.started` (or the
|
|
99
|
+
* first event). Mirrors agent-runtime's `buildLoopOtelSpans` topology:
|
|
100
|
+
* rounds open on `loop.plan` and flush on the next plan / `loop.decision` /
|
|
101
|
+
* `loop.ended`; iterations span `loop.iteration.started` → `.ended`.
|
|
102
|
+
*/
|
|
103
|
+
declare function loopTraceEventsToFlowSpans(events: LoopTraceEventLike[]): FlowSpan[];
|
|
104
|
+
/**
|
|
105
|
+
* A single step's activity lane as its own FlowTrace — what a per-step
|
|
106
|
+
* drill-in renders. Origin defaults to the earliest delegation start so the
|
|
107
|
+
* waterfall begins at the lane's first run.
|
|
108
|
+
*/
|
|
109
|
+
declare function stepActivityFlowTrace(activity: StepAgentActivity[], opts?: {
|
|
110
|
+
startedAt?: number;
|
|
111
|
+
nowMs?: number;
|
|
112
|
+
}): FlowTrace;
|
|
113
|
+
interface MissionFlowStep {
|
|
114
|
+
id: string;
|
|
115
|
+
intent: string;
|
|
116
|
+
status?: string;
|
|
117
|
+
/** Epoch ms the step attempt started. Absent → laid out sequentially after
|
|
118
|
+
* the previous step (missions run steps in order), `approx` flagged. */
|
|
119
|
+
startedAt?: number;
|
|
120
|
+
durationMs?: number;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Compose a mission-wide FlowTrace: one 'pipeline' span per step, the step's
|
|
124
|
+
* delegated runs ('tool' spans, from `activity[stepId]`) beneath it. A step
|
|
125
|
+
* span always covers its delegations' extent. Cost is the sum of delegation
|
|
126
|
+
* `costUsd`; token counts are not knowable from the activity lane and stay 0.
|
|
127
|
+
*/
|
|
128
|
+
declare function composeMissionFlowTrace(input: {
|
|
129
|
+
steps: MissionFlowStep[];
|
|
130
|
+
/** Delegated-run snapshots keyed by step id (the step's `agentActivity`). */
|
|
131
|
+
activity?: Record<string, StepAgentActivity[]>;
|
|
132
|
+
/** Epoch-ms origin. Default: the earliest known step/delegation start. */
|
|
133
|
+
startedAt?: number;
|
|
134
|
+
}): FlowTrace;
|
|
135
|
+
|
|
1
136
|
/**
|
|
2
137
|
* `@tangle-network/agent-app/trace` — flow observability for agent turns.
|
|
3
138
|
*
|
|
@@ -13,6 +148,7 @@
|
|
|
13
148
|
* pump's flush window and the reader's poll cadence (~100–400ms); spans
|
|
14
149
|
* carry `approx: true` to keep reports honest about that.
|
|
15
150
|
*/
|
|
151
|
+
|
|
16
152
|
interface TimedEvent {
|
|
17
153
|
/** ms since turn start (`_t` stamped by pumpBufferedTurn). */
|
|
18
154
|
t: number;
|
|
@@ -68,4 +204,4 @@ declare function renderHistogram(values: number[], opts?: {
|
|
|
68
204
|
format?: (v: number) => string;
|
|
69
205
|
}): string;
|
|
70
206
|
|
|
71
|
-
export { type DistributionSummary, type FlowSpan, type FlowTrace, type TimedEvent, buildFlowTrace, renderHistogram, renderWaterfall, summarize, timedEventsFromLines };
|
|
207
|
+
export { type DistributionSummary, type FlowSpan, type FlowTrace, type LoopTraceEventLike, type MissionFlowStep, type MissionTraceContext, type StepSpanContext, type TimedEvent, buildFlowTrace, childSpanContext, composeMissionFlowTrace, createMissionTraceContext, delegationActivityToFlowSpans, loopTraceEventsToFlowSpans, renderHistogram, renderWaterfall, stepActivityFlowTrace, summarize, timedEventsFromLines, traceEnv };
|
package/dist/trace/index.js
CHANGED
|
@@ -1,145 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const spans = [];
|
|
18
|
-
let promptTokens = 0;
|
|
19
|
-
let completionTokens = 0;
|
|
20
|
-
let toolCalls = 0;
|
|
21
|
-
const first = events[0]?.t ?? 0;
|
|
22
|
-
if (first > 0) {
|
|
23
|
-
spans.push({ kind: "pipeline", name: "dispatch \u2192 first event", startMs: 0, endMs: first });
|
|
24
|
-
}
|
|
25
|
-
let segStart = null;
|
|
26
|
-
let segEnd = 0;
|
|
27
|
-
let segKinds = /* @__PURE__ */ new Set();
|
|
28
|
-
let lastDeltaT = first;
|
|
29
|
-
const openCalls = /* @__PURE__ */ new Map();
|
|
30
|
-
const closeSegment = () => {
|
|
31
|
-
if (segStart !== null) {
|
|
32
|
-
spans.push({
|
|
33
|
-
kind: "model",
|
|
34
|
-
name: segKinds.has("reasoning") ? "model turn (reasoning + text)" : "model turn",
|
|
35
|
-
startMs: segStart,
|
|
36
|
-
endMs: segEnd,
|
|
37
|
-
approx: true
|
|
38
|
-
});
|
|
39
|
-
segStart = null;
|
|
40
|
-
segKinds = /* @__PURE__ */ new Set();
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
for (const { t, event } of events) {
|
|
44
|
-
const inner = innerOf(event);
|
|
45
|
-
const type = String(event.kind === "tool_result" ? "tool_result" : inner.type ?? "");
|
|
46
|
-
if (type === "text" || type === "reasoning") {
|
|
47
|
-
if (segStart === null) segStart = t;
|
|
48
|
-
segEnd = t;
|
|
49
|
-
segKinds.add(type);
|
|
50
|
-
lastDeltaT = t;
|
|
51
|
-
} else if (type === "tool_call") {
|
|
52
|
-
closeSegment();
|
|
53
|
-
toolCalls++;
|
|
54
|
-
const call = inner.call ?? inner;
|
|
55
|
-
const id = String(call.toolCallId ?? `call_${toolCalls}`);
|
|
56
|
-
openCalls.set(id, { name: String(call.toolName ?? "tool"), emitT: t, lastDeltaT });
|
|
57
|
-
} else if (type === "tool_result") {
|
|
58
|
-
const id = String(event.toolCallId ?? inner.toolCallId ?? "");
|
|
59
|
-
const open = openCalls.get(id);
|
|
60
|
-
if (open) {
|
|
61
|
-
spans.push({
|
|
62
|
-
kind: "tool",
|
|
63
|
-
name: open.name,
|
|
64
|
-
// Execution happens between the end of the model turn that emitted
|
|
65
|
-
// the call and the result landing in the buffer.
|
|
66
|
-
startMs: open.lastDeltaT,
|
|
67
|
-
endMs: t,
|
|
68
|
-
approx: true,
|
|
69
|
-
meta: { ok: (event.outcome ?? inner.outcome)?.ok }
|
|
70
|
-
});
|
|
71
|
-
openCalls.delete(id);
|
|
72
|
-
}
|
|
73
|
-
} else if (type === "usage") {
|
|
74
|
-
const u = inner.usage ?? {};
|
|
75
|
-
promptTokens += u.promptTokens ?? 0;
|
|
76
|
-
completionTokens += u.completionTokens ?? 0;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
closeSegment();
|
|
80
|
-
const totalMs = events.length ? events[events.length - 1].t : 0;
|
|
81
|
-
const trace = { spans, totalMs, promptTokens, completionTokens, toolCalls };
|
|
82
|
-
const p = opts?.pricing;
|
|
83
|
-
if (p && (p.prompt != null || p.completion != null)) {
|
|
84
|
-
trace.costUsd = promptTokens * Number(p.prompt ?? 0) + completionTokens * Number(p.completion ?? 0);
|
|
85
|
-
}
|
|
86
|
-
return trace;
|
|
87
|
-
}
|
|
88
|
-
var fmtS = (ms) => `${(ms / 1e3).toFixed(1)}s`;
|
|
89
|
-
function renderWaterfall(trace, opts) {
|
|
90
|
-
const width = opts?.width ?? 40;
|
|
91
|
-
const scale = trace.totalMs > 0 ? width / trace.totalMs : 0;
|
|
92
|
-
const lines = [];
|
|
93
|
-
const spans = [...trace.spans].sort((a, b) => a.startMs - b.startMs);
|
|
94
|
-
for (let i = 0; i < spans.length; i++) {
|
|
95
|
-
const s = spans[i];
|
|
96
|
-
const offset = Math.round(s.startMs * scale);
|
|
97
|
-
const len = Math.max(1, Math.round((s.endMs - s.startMs) * scale));
|
|
98
|
-
const bar = " ".repeat(offset) + (s.kind === "tool" ? "\u2593" : s.kind === "pipeline" ? "\u2591" : "\u2588").repeat(len);
|
|
99
|
-
const branch = i === spans.length - 1 ? "\u2514\u2500" : "\u251C\u2500";
|
|
100
|
-
const dur = `${fmtS(s.endMs - s.startMs)}${s.approx ? "~" : ""}`;
|
|
101
|
-
lines.push(`${fmtS(s.startMs).padStart(7)} ${branch} ${bar.padEnd(width + 2)} ${s.name} (${dur})`);
|
|
102
|
-
}
|
|
103
|
-
const cost = trace.costUsd != null ? ` $${trace.costUsd.toFixed(trace.costUsd < 0.01 ? 6 : 4)}` : "";
|
|
104
|
-
lines.push(
|
|
105
|
-
`${fmtS(trace.totalMs).padStart(7)} \u2500\u2500 total \xB7 ${trace.promptTokens}p + ${trace.completionTokens}c tok \xB7 ${trace.toolCalls} tool calls${cost}`
|
|
106
|
-
);
|
|
107
|
-
return lines.join("\n");
|
|
108
|
-
}
|
|
109
|
-
function summarize(values) {
|
|
110
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
111
|
-
const q = (p) => sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))] ?? 0;
|
|
112
|
-
return { n: sorted.length, min: sorted[0] ?? 0, p50: q(0.5), p90: q(0.9), max: sorted[sorted.length - 1] ?? 0 };
|
|
113
|
-
}
|
|
114
|
-
function renderHistogram(values, opts) {
|
|
115
|
-
if (!values.length) return "(no samples)";
|
|
116
|
-
const buckets = opts?.buckets ?? 6;
|
|
117
|
-
const width = opts?.width ?? 24;
|
|
118
|
-
const fmt = opts?.format ?? ((v) => `${Math.round(v)}${opts?.unit ?? ""}`);
|
|
119
|
-
const s = summarize(values);
|
|
120
|
-
const lo = s.min;
|
|
121
|
-
const hi = s.max === s.min ? s.min + 1 : s.max;
|
|
122
|
-
const counts = new Array(buckets).fill(0);
|
|
123
|
-
for (const v of values) {
|
|
124
|
-
counts[Math.min(buckets - 1, Math.floor((v - lo) / (hi - lo) * buckets))]++;
|
|
125
|
-
}
|
|
126
|
-
const maxCount = Math.max(...counts);
|
|
127
|
-
const lines = [
|
|
128
|
-
`n=${s.n} min=${fmt(s.min)} p50=${fmt(s.p50)} p90=${fmt(s.p90)} max=${fmt(s.max)}`
|
|
129
|
-
];
|
|
130
|
-
for (let i = 0; i < buckets; i++) {
|
|
131
|
-
const a = lo + (hi - lo) * i / buckets;
|
|
132
|
-
const b = lo + (hi - lo) * (i + 1) / buckets;
|
|
133
|
-
const bar = "\u2588".repeat(Math.max(counts[i] > 0 ? 1 : 0, Math.round(counts[i] / maxCount * width)));
|
|
134
|
-
lines.push(`${fmt(a).padStart(8)}-${fmt(b).padEnd(8)} ${bar} ${counts[i]}`);
|
|
135
|
-
}
|
|
136
|
-
return lines.join("\n");
|
|
137
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
buildFlowTrace,
|
|
3
|
+
childSpanContext,
|
|
4
|
+
createMissionTraceContext,
|
|
5
|
+
renderHistogram,
|
|
6
|
+
renderWaterfall,
|
|
7
|
+
summarize,
|
|
8
|
+
timedEventsFromLines,
|
|
9
|
+
traceEnv
|
|
10
|
+
} from "../chunk-5RT6KY4G.js";
|
|
11
|
+
import {
|
|
12
|
+
composeMissionFlowTrace,
|
|
13
|
+
delegationActivityToFlowSpans,
|
|
14
|
+
loopTraceEventsToFlowSpans,
|
|
15
|
+
stepActivityFlowTrace
|
|
16
|
+
} from "../chunk-AFDROJ64.js";
|
|
138
17
|
export {
|
|
139
18
|
buildFlowTrace,
|
|
19
|
+
childSpanContext,
|
|
20
|
+
composeMissionFlowTrace,
|
|
21
|
+
createMissionTraceContext,
|
|
22
|
+
delegationActivityToFlowSpans,
|
|
23
|
+
loopTraceEventsToFlowSpans,
|
|
140
24
|
renderHistogram,
|
|
141
25
|
renderWaterfall,
|
|
26
|
+
stepActivityFlowTrace,
|
|
142
27
|
summarize,
|
|
143
|
-
timedEventsFromLines
|
|
28
|
+
timedEventsFromLines,
|
|
29
|
+
traceEnv
|
|
144
30
|
};
|
|
145
31
|
//# sourceMappingURL=index.js.map
|
package/dist/trace/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/trace/index.ts"],"sourcesContent":["/**\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 interface TimedEvent {\n /** ms since turn start (`_t` stamped by pumpBufferedTurn). */\n t: number\n event: Record<string, unknown>\n}\n\nexport interface FlowSpan {\n kind: 'pipeline' | 'model' | 'tool'\n name: string\n startMs: number\n endMs: number\n approx?: boolean\n meta?: Record<string, unknown>\n}\n\nexport interface FlowTrace {\n spans: FlowSpan[]\n totalMs: number\n promptTokens: number\n completionTokens: number\n /** Computed when per-token pricing is supplied. */\n costUsd?: number\n toolCalls: number\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\nexport interface DistributionSummary {\n n: number\n min: number\n p50: number\n p90: number\n max: number\n}\n\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":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
+
import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
4
|
+
import { FlowTrace } from '../trace/index.js';
|
|
3
5
|
import { C as CatalogModel } from '../model-catalog-BEAEVDaa.js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -119,6 +121,82 @@ declare function nextRevealCount(shown: number, targetLength: number, dtMs: numb
|
|
|
119
121
|
*/
|
|
120
122
|
declare function useSmoothText(target: string, enabled: boolean, opts?: SmoothRevealOptions): string;
|
|
121
123
|
|
|
124
|
+
type ActivityTone = 'live' | 'ok' | 'error' | 'neutral';
|
|
125
|
+
/** Map a delegation status (free-form string on the wire) to a render tone. */
|
|
126
|
+
declare function activityTone(status: string): ActivityTone;
|
|
127
|
+
/** "$0.4000" under a cent shows 4 decimals; null when unknown/zero. */
|
|
128
|
+
declare function formatActivityCost(costUsd?: number): string | null;
|
|
129
|
+
/** "8s" / "2m 05s" / "1h 12m"; null when unknown. */
|
|
130
|
+
declare function formatActivityDuration(durationMs?: number): string | null;
|
|
131
|
+
/** A delegation record on the cross-context surface; `missionRef` links a
|
|
132
|
+
* promoted delegation back to the mission/step that spawned it. */
|
|
133
|
+
interface AgentActivityRecord extends StepAgentActivity {
|
|
134
|
+
missionRef?: {
|
|
135
|
+
missionId: string;
|
|
136
|
+
stepId?: string;
|
|
137
|
+
label?: string;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
interface AgentActivityPage {
|
|
141
|
+
items: AgentActivityRecord[];
|
|
142
|
+
/** Opaque continuation token; absent ⇒ no further pages. */
|
|
143
|
+
nextCursor?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Fold a fetched page into the held rows: dedupe by `taskId` with the
|
|
147
|
+
* incoming row winning (a refresh re-fetches the head page, so newer
|
|
148
|
+
* snapshots of in-flight runs replace stale ones), newest `startedAt` first.
|
|
149
|
+
*/
|
|
150
|
+
declare function mergeActivityPages(existing: AgentActivityRecord[], incoming: AgentActivityRecord[]): AgentActivityRecord[];
|
|
151
|
+
interface WaterfallRow {
|
|
152
|
+
name: string;
|
|
153
|
+
kind: 'pipeline' | 'model' | 'tool';
|
|
154
|
+
/** Bar geometry as percentages of the trace's total span. */
|
|
155
|
+
offsetPct: number;
|
|
156
|
+
widthPct: number;
|
|
157
|
+
durationLabel: string;
|
|
158
|
+
approx: boolean;
|
|
159
|
+
/** False only when the span's meta carries an explicit failure. */
|
|
160
|
+
ok: boolean;
|
|
161
|
+
}
|
|
162
|
+
/** Project a FlowTrace into proportional bar geometry for {@link FlowWaterfall}. */
|
|
163
|
+
declare function waterfallLayout(trace: FlowTrace): WaterfallRow[];
|
|
164
|
+
interface FlowWaterfallProps {
|
|
165
|
+
trace: FlowTrace;
|
|
166
|
+
}
|
|
167
|
+
/** Compact proportional waterfall over a FlowTrace — span name, bar, duration
|
|
168
|
+
* per row; total + cost in the footer. */
|
|
169
|
+
declare function FlowWaterfall({ trace }: FlowWaterfallProps): react.JSX.Element | null;
|
|
170
|
+
interface MissionActivityLaneProps {
|
|
171
|
+
/** The step's delegated-run snapshot (`MissionStepState.agentActivity`). */
|
|
172
|
+
activity: StepAgentActivity[];
|
|
173
|
+
/** Epoch ms origin for the expanded waterfall — usually the step start. */
|
|
174
|
+
startedAt?: number;
|
|
175
|
+
/** Wall clock for extending in-flight runs on the waterfall. */
|
|
176
|
+
nowMs?: number;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Collapsed sub-rows under a mission step — one row per delegated run —
|
|
180
|
+
* expanding to the step's waterfall. Renders nothing for an empty lane.
|
|
181
|
+
*/
|
|
182
|
+
declare function MissionActivityLane({ activity, startedAt, nowMs }: MissionActivityLaneProps): react.JSX.Element | null;
|
|
183
|
+
interface AgentActivityPanelProps {
|
|
184
|
+
/** Data port — page through the product's delegation records. Called with
|
|
185
|
+
* no cursor on mount/refresh, with `nextCursor` for older pages. */
|
|
186
|
+
fetchActivity: (cursor?: string) => Promise<AgentActivityPage>;
|
|
187
|
+
/** Render the mission link for a promoted delegation (chip, anchor, router
|
|
188
|
+
* Link — the product's routing, not ours). */
|
|
189
|
+
renderMissionRef?: (ref: NonNullable<AgentActivityRecord['missionRef']>, record: AgentActivityRecord) => ReactNode;
|
|
190
|
+
title?: string;
|
|
191
|
+
emptyLabel?: string;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The standalone cross-context delegation surface: every agent run the
|
|
195
|
+
* product journaled, mission-spawned or not, with status, cost, drill-in, and
|
|
196
|
+
* a mission link slot for promoted delegations.
|
|
197
|
+
*/
|
|
198
|
+
declare function AgentActivityPanel({ fetchActivity, renderMissionRef, title, emptyLabel }: AgentActivityPanelProps): react.JSX.Element;
|
|
199
|
+
|
|
122
200
|
interface ChatMessageMetrics {
|
|
123
201
|
modelUsed?: string;
|
|
124
202
|
promptTokens?: number;
|
|
@@ -239,4 +317,4 @@ type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: Chat
|
|
|
239
317
|
*/
|
|
240
318
|
declare function ChatMessages({ messages, models, renderMarkdown, renderExtras, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, }: ChatMessagesProps): react.JSX.Element;
|
|
241
319
|
|
|
242
|
-
export { type ChatMessageMetrics, ChatMessages, type ChatMessagesProps, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ConsumeChatStreamResult, EffortPicker, type EffortPickerProps, ModelPicker, type ModelPickerProps, type ProposalApprovalHandlers, ProviderLogo, type ProviderLogoProps, RunDrillIn, type RunDrillInProps, type SmoothRevealOptions, type StreamChatOptions, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, consumeChatStream, dispatchChatStreamLine, formatModelCost, formatTokensPerSecond, nextRevealCount, pendingApprovalOf, streamChatTurn, useSmoothText };
|
|
320
|
+
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, type ChatMessageMetrics, ChatMessages, type ChatMessagesProps, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ConsumeChatStreamResult, EffortPicker, type EffortPickerProps, FlowWaterfall, type FlowWaterfallProps, MissionActivityLane, type MissionActivityLaneProps, ModelPicker, type ModelPickerProps, type ProposalApprovalHandlers, ProviderLogo, type ProviderLogoProps, RunDrillIn, type RunDrillInProps, type SmoothRevealOptions, type StreamChatOptions, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, type WaterfallRow, activityTone, consumeChatStream, dispatchChatStreamLine, formatActivityCost, formatActivityDuration, formatModelCost, formatTokensPerSecond, mergeActivityPages, nextRevealCount, pendingApprovalOf, streamChatTurn, useSmoothText, waterfallLayout };
|