@rkat/sdk 0.8.23 → 0.8.26

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.
@@ -0,0 +1,904 @@
1
+ import type { AssistantImageId, BackgroundJobTerminalStatus, BlobRef, CommsNoticeKind, ContentBlock, ContentInput, Provider, ProviderImageMetadata, RevisedPromptDisposition, SenderContentTaint, SkillKey, SystemNoticePeer, ToolConfigChangedPayload, TranscriptRewriteReason, TranscriptRewriteSelection } from './types.js';
2
+ export type AgentErrorClass = "llm" | "store" | "tool" | "policy_indeterminate" | "mcp" | "session_not_found" | "budget" | "max_tokens" | "content_filtered" | "max_turns" | "cancelled" | "invalid_state" | "operation_not_found" | "depth_limit" | "concurrency_limit" | "config" | "internal" | "build" | "auth" | "callback_pending" | "skill" | "structured_output" | "invalid_output_schema" | "hook" | "terminal" | "no_pending_boundary";
3
+ /**
4
+ * Stable identifier for a configured hook.
5
+ */
6
+ export type HookId = string;
7
+ /**
8
+ * Hook points available in V1.
9
+ */
10
+ export type HookPoint = "run_started" | "run_completed" | "run_failed" | "pre_llm_request" | "post_llm_response" | "pre_tool_execution" | "post_tool_execution" | "turn_boundary";
11
+ /**
12
+ * Typed reason codes for guardrail denials.
13
+ */
14
+ export type HookReasonCode = "policy_violation" | "safety_violation" | "schema_violation" | "timeout" | "runtime_error";
15
+ export type LlmProviderErrorKind = "invalid_request" | "content_filtered" | "server_error" | "server_overloaded" | "connection_reset" | "unknown" | "stream_parse_error" | "incomplete_response" | "request_too_large";
16
+ export type LlmProviderErrorRetryability = "retryable" | "non_retryable";
17
+ /**
18
+ * Closed machine-owned classifier for why a turn reached a terminal failure.
19
+ */
20
+ export type TurnTerminalCauseKind = "unknown" | "hook_denied" | "hook_failure" | "llm_failure" | "tool_failure" | "structured_output_validation_failed" | "budget_exhausted" | "time_budget_exceeded" | "retry_exhausted" | "turn_limit_reached" | "runtime_apply_failure" | "fatal_failure";
21
+ /**
22
+ * Terminal outcome of a turn.
23
+ */
24
+ export type TurnTerminalOutcome = "none" | "completed" | "failed" | "cancelled" | "budget_exhausted" | "time_budget_exceeded" | "structured_output_validation_failed";
25
+ export type AgentErrorReason = {
26
+ reason_type: "llm_rate_limited";
27
+ retry_after_ms?: number | null;
28
+ } | {
29
+ max: number;
30
+ reason_type: "llm_context_exceeded";
31
+ requested: number;
32
+ } | {
33
+ reason_type: "llm_auth_error";
34
+ } | {
35
+ model: string;
36
+ reason_type: "llm_invalid_model";
37
+ } | {
38
+ provider_error: unknown;
39
+ provider_error_kind: LlmProviderErrorKind;
40
+ provider_error_retryability: LlmProviderErrorRetryability;
41
+ reason_type: "llm_provider_error";
42
+ } | {
43
+ duration_ms: number;
44
+ reason_type: "llm_network_timeout";
45
+ } | {
46
+ duration_ms: number;
47
+ reason_type: "llm_call_timeout";
48
+ } | {
49
+ hook_id?: HookId | null;
50
+ point: HookPoint;
51
+ reason_code: HookReasonCode;
52
+ reason_type: "hook_denied";
53
+ } | {
54
+ hook_id: HookId;
55
+ reason_type: "hook_timeout";
56
+ timeout_ms: number;
57
+ } | {
58
+ hook_id: HookId;
59
+ reason: string;
60
+ reason_type: "hook_execution_failed";
61
+ } | {
62
+ reason: string;
63
+ reason_type: "hook_config_invalid";
64
+ } | {
65
+ attempts: number;
66
+ reason: string;
67
+ reason_type: "structured_output_validation_failed";
68
+ } | {
69
+ reason: string;
70
+ reason_type: "invalid_output_schema";
71
+ } | {
72
+ binding_key: string;
73
+ message: string;
74
+ reason_type: "auth_reauth_required";
75
+ } | {
76
+ args: unknown;
77
+ reason_type: "callback_pending";
78
+ tool_name: string;
79
+ tool_use_id?: string;
80
+ } | {
81
+ cause_kind: TurnTerminalCauseKind;
82
+ outcome: TurnTerminalOutcome;
83
+ reason_type: "turn_terminal_cause";
84
+ };
85
+ export type AgentErrorReport = {
86
+ class: AgentErrorClass;
87
+ message: string;
88
+ reason?: AgentErrorReason | null;
89
+ };
90
+ /**
91
+ * Typed public event payload for a canonical assistant image block appended to history.
92
+ */
93
+ export interface AssistantImageEvent {
94
+ blob_ref: BlobRef;
95
+ height: number;
96
+ image_id: AssistantImageId;
97
+ media_type: string;
98
+ meta: ProviderImageMetadata;
99
+ revised_prompt: RevisedPromptDisposition;
100
+ width: number;
101
+ }
102
+ /**
103
+ * Type of budget being tracked
104
+ */
105
+ export type BudgetType = "tokens" | "time" | "tool_calls";
106
+ /**
107
+ * Typed cause of a compaction projection-handoff refusal.
108
+ *
109
+ * The runtime coordinator refuses for structurally different reasons, and a
110
+ * host routing severity (page vs log) needs the cause, not a message
111
+ * substring. This is the wire-stable vocabulary carried by
112
+ * [`crate::event::CompactionFailureReason::ProjectionHandoffRefused`];
113
+ * [`CompactionCommitCoordinationError::refusal`] is its only producer.
114
+ */
115
+ export type CompactionHandoffRefusal = "session_mismatch" | "runtime_epoch_rotated" | "runtime_epoch_retired" | "runtime_binding_rotated" | "runtime_binding_absent" | "durable_projection_unsupported" | "unclassified";
116
+ /**
117
+ * Whether the history a failed compaction preserved can still be sent.
118
+ *
119
+ * This is the severity discriminator for compaction-persistence failures: the
120
+ * same refusal is a log line on a session that still fits its window and a
121
+ * hard wedge on one that does not (every subsequent turn is refused, and the
122
+ * only path out is a compaction that persists). Classification reuses the
123
+ * pre-dispatch authorities rather than a second limit table:
124
+ * [`ContextBudgetState`](crate::ContextBudgetState) over the active model
125
+ * profile's window, and the compactor's effective request-byte cap over the
126
+ * exact provider-lowered body size.
127
+ *
128
+ * Both authorities are read at composed-request scope, which is the scope the
129
+ * question is asked at: the transcript is not what crosses the provider
130
+ * boundary, the request built from it is. A transcript-only token measure
131
+ * under-reports every request by the tool schemas that ride it, which is the
132
+ * exact shape that used to be reported as [`Self::StillFits`] while every
133
+ * turn died on the provider's context limit.
134
+ */
135
+ export type CompactionPreservedHistoryFit = "unclassified" | "still_fits" | "over_window";
136
+ /**
137
+ * Typed, serializable cause of a non-fatal compaction failure.
138
+ *
139
+ * Compaction is best-effort: when it fails the agent continues with the
140
+ * uncompacted history. This enum is the wire-stable projection of the
141
+ * in-flight [`crate::agent::compact::CompactionError`] plus the post-summary
142
+ * commit failures (memory indexing, transcript rewrite) surfaced from the
143
+ * agent loop. Each variant carries the typed cause; the [`Display`] impl
144
+ * renders the human-facing message consumers used to read off the old
145
+ * `error: String` field.
146
+ *
147
+ * [`Display`]: std::fmt::Display
148
+ */
149
+ export type CompactionFailureReason = {
150
+ error_class: AgentErrorClass;
151
+ kind: "llm_failed";
152
+ message: string;
153
+ } | {
154
+ kind: "empty_summary";
155
+ } | {
156
+ kind: "curator_failed";
157
+ message: string;
158
+ } | {
159
+ kind: "estimation_failed";
160
+ message: string;
161
+ } | {
162
+ attempted_entries: number;
163
+ kind: "memory_indexing_failed";
164
+ message: string;
165
+ } | {
166
+ kind: "transcript_rewrite_failed";
167
+ message: string;
168
+ } | {
169
+ attempted_entries: number;
170
+ kind: "projection_handoff_refused";
171
+ message: string;
172
+ preserved_history: CompactionPreservedHistoryFit;
173
+ refusal: CompactionHandoffRefusal;
174
+ };
175
+ /**
176
+ * Provider-native convention used to normalize tokens presented to a model.
177
+ */
178
+ export type PresentedTokenConvention = "anthropic_disjoint_input_components" | "open_ai_input_includes_cached_subset" | "gemini_prompt_includes_cached_subset" | "open_ai_compatible_prompt_includes_cache_details" | "host_declared_inclusive_input_total";
179
+ /**
180
+ * How the provider adapter obtained the normalized presented-token total.
181
+ */
182
+ export type TokenAggregationProvenance = "sum_disjoint_provider_components" | "provider_inclusive_input_total";
183
+ /**
184
+ * One provider adapter's normalized accounting for a single model turn.
185
+ */
186
+ export interface ProviderTokenAccounting {
187
+ aggregation: TokenAggregationProvenance;
188
+ convention: PresentedTokenConvention;
189
+ model: string;
190
+ presented_tokens: number;
191
+ provider: Provider;
192
+ }
193
+ /**
194
+ * Token usage statistics.
195
+ *
196
+ * # The same field names carry two different denominators
197
+ *
198
+ * This shape is reused for two semantically different accounts, and
199
+ * `input_tokens` does not mean the same thing in both:
200
+ *
201
+ * - **Per-call** ([`TurnUsage`], carried by `turn_completed.usage`): raw
202
+ * provider counters for exactly one provider request. For Anthropic
203
+ * `input_tokens` is the *uncached* input only, with cache-write and
204
+ * cache-read input reported separately in `cache_creation_tokens` and
205
+ * `cache_read_tokens`. The normalized presented-input total for that one
206
+ * call is [`TurnUsage::presented_tokens`].
207
+ * - **Cumulative** ([`CumulativeUsage`], carried by `run_completed.usage`): a
208
+ * running total over every provider call recorded on the *session*, not on
209
+ * one run. Its `input_tokens` is the saturating sum of each call's
210
+ * *presented* tokens (see [`CumulativeUsage::add_turn`]), and its cache
211
+ * detail fields are always `None` because their relationship to the input
212
+ * total is provider-specific.
213
+ *
214
+ * # What consumers must not sum
215
+ *
216
+ * - Never sum `run_completed.usage` with per-call usage, and never sum
217
+ * `run_completed.usage` across runs: each value is already the whole
218
+ * session's total to date, so adding two of them double-counts everything
219
+ * before the later one. Take the latest value.
220
+ * - Never sum per-call `input_tokens` and expect it to match
221
+ * `run_completed.usage.input_tokens`. On a cache-heavy Anthropic session the
222
+ * two use different denominators and will not agree. Sum
223
+ * `turn_completed.usage.accounting.presented_tokens` (that is,
224
+ * [`TurnUsage::presented_tokens`]) instead, which is exactly what
225
+ * [`CumulativeUsage::add_turn`] does.
226
+ * - Do not expect the per-call rows to reconcile with the cumulative account
227
+ * either. Intermediate tool-loop calls, the structured-output extraction
228
+ * call, and the compaction summary call are all charged to the cumulative
229
+ * account and publish no `turn_completed` row, so the rows cover a strict
230
+ * subset of the tokens.
231
+ *
232
+ * The worked example lives in `docs/reference/usage-accounting.mdx`. Its
233
+ * numbers are pinned against the agent loop by
234
+ * `turn_rows_cover_one_call_while_the_run_total_is_session_cumulative`
235
+ * (`meerkat-core/src/agent/usage_accounting_tests.rs`) and against this type's
236
+ * arithmetic by `cumulative_usage_matches_documented_aggregation_example`.
237
+ */
238
+ export type Usage = {
239
+ cache_creation_tokens?: number | null;
240
+ cache_read_tokens?: number | null;
241
+ input_tokens: number;
242
+ output_tokens: number;
243
+ provider_accounting?: ProviderTokenAccounting | null;
244
+ };
245
+ /**
246
+ * Cumulative usage across committed turns. Cache detail counters are not
247
+ * aggregated because their relationship to input totals is provider-specific.
248
+ *
249
+ * This value is **already a total**, and the total is session-scoped: on the
250
+ * event stream it is `Session::total_usage()`, which is persisted with the
251
+ * session and restored on resume, so `run_completed.usage` on the second run of
252
+ * a session already contains the first run's calls. Adding it to per-call
253
+ * usage, or summing the values observed on two runs, double-counts. It also
254
+ * intentionally carries no [`crate::ProviderTokenAccounting`], because one
255
+ * session may span providers and models and so cannot truthfully claim a
256
+ * single per-call convention; per-model attribution is read from the per-call
257
+ * `turn_completed` rows, which cover only the calls that closed a run.
258
+ */
259
+ export type CumulativeUsage = Usage;
260
+ /**
261
+ * Which side of a turn commit produced the discarded proof.
262
+ *
263
+ * Load-bearing for hosts: `PersistedEvidence` is inherited poison from an
264
+ * earlier turn, `AuthoredThisTurn` is this turn's own lowering disagreeing
265
+ * with the committed transcript. The two have different root causes and are
266
+ * otherwise indistinguishable from the outside.
267
+ */
268
+ export type CacheBreakpointDiscardOrigin = "authored_this_turn" | "persisted_evidence";
269
+ /**
270
+ * Why one provider-authored cache breakpoint was discarded instead of
271
+ * retained as durable session evidence.
272
+ *
273
+ * A cache breakpoint is an optimization artifact anchored to the exact
274
+ * transcript head a provider lowered. Ordinary transcript motion - a
275
+ * synthetic-notice refresh, a compaction, a re-materialized prefix - moves
276
+ * that anchor without saying anything about the transcript's own integrity.
277
+ * Every variant here therefore describes the ARTIFACT. Faults that describe
278
+ * the committed TRANSCRIPT stay [`CacheBreakpointEvidenceError`].
279
+ */
280
+ export type CacheBreakpointDiscardReason = {
281
+ kind: "boundary_outside_committed_transcript";
282
+ message_count: number;
283
+ message_len: number;
284
+ } | {
285
+ kind: "canonical_prefix_moved";
286
+ } | {
287
+ detail: string;
288
+ kind: "evidence_unusable";
289
+ } | {
290
+ kind: "projected_boundary_unmappable";
291
+ };
292
+ /**
293
+ * Stable provider-independent identity of an authored cache breakpoint.
294
+ */
295
+ export type CacheBreakpointBoundary = {
296
+ kind: "system_profile_prefix";
297
+ message_count: number;
298
+ } | {
299
+ kind: "transcript_after";
300
+ message_count: number;
301
+ };
302
+ /**
303
+ * Identity of a discarded proof, when the proof itself could be decoded.
304
+ */
305
+ export interface DiscardedCacheBreakpointIdentity {
306
+ boundary: CacheBreakpointBoundary;
307
+ model: string;
308
+ provider: Provider;
309
+ }
310
+ /**
311
+ * One provider-authored cache proof that could not be retained.
312
+ */
313
+ export type DiscardedCacheBreakpoint = {
314
+ identity?: DiscardedCacheBreakpointIdentity | null;
315
+ origin: CacheBreakpointDiscardOrigin;
316
+ reason: CacheBreakpointDiscardReason;
317
+ };
318
+ /**
319
+ * One turn's provider-authored accounting named a different provider/model
320
+ * than the request it answered.
321
+ *
322
+ * # Why this is not the same fault as absent accounting
323
+ *
324
+ * A mismatched identity still arrives with a complete, internally consistent
325
+ * measurement: the [`PresentedTokenConvention`] travels with the number, so
326
+ * the counters mean what they say regardless of which name is attached. The
327
+ * disputed fact is attribution alone, so the token axis still advances on the
328
+ * number the provider actually sent. Absent accounting has no number at all
329
+ * and therefore cannot advance anything. Collapsing the two would either kill
330
+ * correct work over a name or fabricate counters over silence.
331
+ *
332
+ * # Why the reported identity is preserved verbatim
333
+ *
334
+ * Rewriting `reported_*` to the active identity would publish an agreement
335
+ * that was never observed - a guess laundered as evidence. Both sides are
336
+ * carried so a host can see exactly who disagreed with whom.
337
+ */
338
+ export interface DisputedTurnUsageAccountingIdentity {
339
+ active_model: string;
340
+ active_provider: Provider;
341
+ reported_model: string;
342
+ reported_provider: Provider;
343
+ }
344
+ /**
345
+ * Typed reason a hook execution failed (engine-level fault, not a guardrail
346
+ * denial).
347
+ *
348
+ * Mirrors the [`HookReasonCode`] precedent: the variant is the typed owner of
349
+ * the failure cause; the human-readable string is a [`Display`] derivation,
350
+ * never a separately-stored field.
351
+ *
352
+ * [`Display`]: std::fmt::Display
353
+ */
354
+ export type HookFailureReason = {
355
+ reason_code: "timeout";
356
+ timeout_ms: number;
357
+ } | {
358
+ message: string;
359
+ reason_code: "execution_failed";
360
+ } | {
361
+ message: string;
362
+ reason_code: "config_invalid";
363
+ } | {
364
+ reason_code: "observe_only_violation";
365
+ };
366
+ /**
367
+ * Typed reason an interaction stream was abandoned before normal terminal
368
+ * delivery. This is intentionally distinct from [`InteractionStreamState::Expired`]:
369
+ * expiry proves that the attach TTL elapsed while the stream was still
370
+ * reserved, whereas abandonment records an observed failure.
371
+ */
372
+ export type InteractionStreamAbandonReason = "send_failed" | "admission_rejected" | "response_rejected" | "terminal_delivery_failed";
373
+ /**
374
+ * Typed reason an interaction-scoped run failed (terminal event for tap
375
+ * subscribers).
376
+ *
377
+ * Mirrors [`CompactionFailureReason`]: the variant is the typed owner of the
378
+ * failure cause; the human-readable string is a [`Display`] derivation,
379
+ * never a separately-carried field.
380
+ *
381
+ * [`Display`]: std::fmt::Display
382
+ */
383
+ export type InteractionFailureReason = {
384
+ kind: "cancelled";
385
+ } | {
386
+ detail: string;
387
+ kind: "abandoned";
388
+ } | {
389
+ kind: "interaction_stream_abandoned";
390
+ reason: InteractionStreamAbandonReason;
391
+ } | {
392
+ detail: string;
393
+ kind: "finalization_failed";
394
+ } | {
395
+ attempts: number;
396
+ kind: "extraction_failed";
397
+ last_output: string;
398
+ reason: string;
399
+ };
400
+ /**
401
+ * Unique identifier for an interaction.
402
+ */
403
+ export type InteractionId = string;
404
+ /**
405
+ * Closed classifier for recoverable LLM failures.
406
+ */
407
+ export type LlmRetryFailureKind = "rate_limited" | "network_timeout" | "call_timeout" | "retryable_provider_error";
408
+ /**
409
+ * Typed recoverable LLM failure carried through retry authority.
410
+ */
411
+ export type LlmRetryFailure = {
412
+ duration_ms?: number | null;
413
+ kind: LlmRetryFailureKind;
414
+ message: string;
415
+ provider: string;
416
+ retry_after_ms?: number | null;
417
+ };
418
+ /**
419
+ * Typed retry delay plan selected for a recoverable LLM failure.
420
+ */
421
+ export type LlmRetryPlan = {
422
+ attempt: number;
423
+ budget_capped: boolean;
424
+ computed_delay_ms: number;
425
+ max_retries: number;
426
+ rate_limit_floor_applied: boolean;
427
+ retry_after_hint_ms?: number | null;
428
+ selected_delay_ms: number;
429
+ };
430
+ /**
431
+ * Recoverable LLM retry lifecycle payload accepted by turn authority.
432
+ */
433
+ export interface LlmRetrySchedule {
434
+ failure: LlmRetryFailure;
435
+ plan: LlmRetryPlan;
436
+ }
437
+ /**
438
+ * One externally routed callback tool call inside a suspended assistant
439
+ * tool-use batch.
440
+ */
441
+ export interface PendingCallbackToolCall {
442
+ args: unknown;
443
+ tool_name: string;
444
+ tool_use_id: string;
445
+ }
446
+ /**
447
+ * Typed input fact for a run boundary.
448
+ *
449
+ * A run either starts from caller-provided content or resumes from tool
450
+ * results already staged at the session's pending-continuation boundary.
451
+ * The pending-tail case is its own typed variant — run-boundary events and
452
+ * hooks never fabricate an empty-string prompt to stand in for it.
453
+ */
454
+ export type RunInput = {
455
+ content: ContentInput;
456
+ kind: "content";
457
+ } | {
458
+ kind: "pending_tool_results";
459
+ };
460
+ /**
461
+ * Warnings emitted during schema lowering.
462
+ */
463
+ export interface SchemaWarning {
464
+ message: string;
465
+ path: string;
466
+ provider: Provider;
467
+ }
468
+ /**
469
+ * Typed semantic kind of a provider-executed (server-side) tool.
470
+ *
471
+ * This is the single typed owner of the server-tool identity. Each provider
472
+ * adapter parses its native discriminator into this enum once at the streaming
473
+ * boundary, so downstream consumers never re-classify by matching a
474
+ * `name: String`. Provider-native sub-event detail (e.g. OpenAI's
475
+ * `web_search_call` vs `web_search_result`) is preserved in the accompanying
476
+ * `content` JSON, not in this kind.
477
+ *
478
+ * `ProviderNative` is the verbatim escape hatch for dynamic provider tool
479
+ * names (Anthropic `server_tool_use` carries an arbitrary tool name that must
480
+ * round-trip exactly on replay). It is the only variant carrying a string,
481
+ * and that string IS the typed fact — not a re-derivable label.
482
+ */
483
+ export type ServerToolKind = {
484
+ kind: "web_search";
485
+ } | {
486
+ kind: "google_search";
487
+ } | {
488
+ kind: "provider_native";
489
+ name: string;
490
+ };
491
+ /**
492
+ * Unique identifier for a session (UUID v7 for time-ordering)
493
+ */
494
+ export type SessionId = string;
495
+ /**
496
+ * Slug-validated capability identifier for skill requirements.
497
+ *
498
+ * Replaces the legacy `Vec<String>` capability lists with a typed
499
+ * namespace. Parsed at construction, so callers cannot smuggle invalid
500
+ * identifiers into descriptors or requirements.
501
+ */
502
+ export type CapabilityId = string;
503
+ export type SkillResolutionFailureReason = {
504
+ key: SkillKey;
505
+ reason_type: "not_found";
506
+ } | {
507
+ capability: CapabilityId;
508
+ key: SkillKey;
509
+ reason_type: "capability_unavailable";
510
+ } | {
511
+ message: string;
512
+ reason_type: "load";
513
+ } | {
514
+ message: string;
515
+ reason_type: "parse";
516
+ } | {
517
+ existing_fingerprint: string;
518
+ new_fingerprint: string;
519
+ reason_type: "source_uuid_collision";
520
+ source_uuid: string;
521
+ } | {
522
+ existing_source_uuid: string;
523
+ fingerprint: string;
524
+ mutated_source_uuid: string;
525
+ reason_type: "source_uuid_mutation_without_lineage";
526
+ } | {
527
+ event_id: string;
528
+ event_kind: string;
529
+ reason_type: "missing_skill_remaps";
530
+ } | {
531
+ from_skill_name: string;
532
+ from_source_uuid: string;
533
+ reason_type: "remap_without_lineage";
534
+ to_skill_name: string;
535
+ to_source_uuid: string;
536
+ } | {
537
+ alias: string;
538
+ reason_type: "unknown_skill_alias";
539
+ } | {
540
+ reason_type: "remap_cycle";
541
+ skill_name: string;
542
+ source_uuid: string;
543
+ } | {
544
+ message: string;
545
+ reason_type: "unknown";
546
+ };
547
+ /**
548
+ * Why the model stopped generating
549
+ */
550
+ export type StopReason = "end_turn" | "tool_use" | "max_tokens" | "stop_sequence" | "content_filter" | "cancelled";
551
+ /**
552
+ * Typed reason a best-effort event stream dropped frames.
553
+ *
554
+ * The variant is the typed owner of the truncation cause; the human-readable
555
+ * string is a [`Display`](std::fmt::Display) derivation, never a
556
+ * separately-carried field. `StreamTruncated` is a UI hint — the terminal
557
+ * event remains authoritative.
558
+ */
559
+ export type StreamTruncationReason = {
560
+ kind: "channel_full";
561
+ } | {
562
+ dropped: number;
563
+ kind: "stream_lagged";
564
+ } | {
565
+ dropped: number;
566
+ kind: "output_audio_degraded";
567
+ } | {
568
+ kind: "remote_cursor_overrun";
569
+ watermark: number;
570
+ } | {
571
+ durable_seq: number;
572
+ encoded_bytes: number;
573
+ kind: "oversized_remote_event";
574
+ max_bytes: number;
575
+ };
576
+ export type ToolCallArguments = Record<string, unknown>;
577
+ export interface SystemTime {
578
+ nanos_since_epoch: number;
579
+ secs_since_epoch: number;
580
+ }
581
+ /**
582
+ * Immutable rewrite commit that advances a session transcript head.
583
+ */
584
+ export type TranscriptRewriteCommit = {
585
+ actor?: string | null;
586
+ committed_at: SystemTime;
587
+ messages_after: number;
588
+ messages_before: number;
589
+ original_span_digest: string;
590
+ parent_revision: string;
591
+ reason: TranscriptRewriteReason;
592
+ replacement_digest: string;
593
+ revision: string;
594
+ rewrite_generation?: number;
595
+ selection: TranscriptRewriteSelection;
596
+ };
597
+ /**
598
+ * Rolling, canonical identity of an ordered exact rewrite-commit prefix.
599
+ *
600
+ * This is a semantic graph fact, not a replay-cursor assertion. It is carried
601
+ * by the graph, folded into checkpoint authority, and independently matched
602
+ * against the EventStore's receipt. One ordinary lineage-tail commit extends
603
+ * the accumulator with one commit serialization; it never re-hashes the
604
+ * accumulated prefix.
605
+ */
606
+ export interface TranscriptRewritePrefixAccumulator {
607
+ digest: string;
608
+ occurrence_count: number;
609
+ }
610
+ /**
611
+ * Receipt for one non-empty ordered transcript-rewrite suffix.
612
+ *
613
+ * The transition is self-verifying:
614
+ * `start_prefix.extend(commits) == end_prefix`. Occurrence generations are
615
+ * checked by [`TranscriptRewritePrefixAccumulator::extend`], so neither a gap
616
+ * nor a duplicate can be hidden inside one receipt.
617
+ */
618
+ export interface TranscriptRewriteAuditReceiptBatch {
619
+ commits: TranscriptRewriteCommit[];
620
+ end_prefix: TranscriptRewritePrefixAccumulator;
621
+ start_prefix: TranscriptRewritePrefixAccumulator;
622
+ }
623
+ /**
624
+ * Immutable transcript revision body retained by the session-local graph.
625
+ */
626
+ export type TranscriptRevisionBody = {
627
+ created_at: SystemTime;
628
+ messages: unknown[];
629
+ parent_revision?: string | null;
630
+ revision: string;
631
+ };
632
+ /**
633
+ * Self-contained append-only transcript rewrite record.
634
+ */
635
+ export interface TranscriptRewriteRecord {
636
+ commit: TranscriptRewriteCommit;
637
+ digest_format?: number;
638
+ parent_body: TranscriptRevisionBody;
639
+ revision_body: TranscriptRevisionBody;
640
+ }
641
+ /**
642
+ * Usage for one provider turn.
643
+ *
644
+ * This is deliberately distinct from cumulative [`Usage`] on event
645
+ * boundaries, while retaining the existing flat wire shape.
646
+ *
647
+ * # Model and provider attribution
648
+ *
649
+ * `accounting` is the single owner of per-call attribution: it carries the
650
+ * [`crate::Provider`] and the model string of the request that produced these
651
+ * counters, minted by the provider adapter from the lowered request rather than
652
+ * from configuration intent. A consumer reading only the event stream can
653
+ * therefore attribute one `turn_completed` row to a model without joining
654
+ * against session metadata:
655
+ * `turn_completed.usage.accounting.provider` /
656
+ * `turn_completed.usage.accounting.model`.
657
+ *
658
+ * There is deliberately no second copy of the model or provider beside
659
+ * `accounting` on the event: attribution has one owner.
660
+ */
661
+ export type TurnUsage = {
662
+ accounting: ProviderTokenAccounting;
663
+ cache_creation_tokens?: number | null;
664
+ cache_read_tokens?: number | null;
665
+ input_tokens: number;
666
+ output_tokens: number;
667
+ provider_accounting?: ProviderTokenAccounting | null;
668
+ };
669
+ /**
670
+ * Provider token accounting for one model turn was absent.
671
+ *
672
+ * # What this makes untrue, and what it does not
673
+ *
674
+ * A provider that streams a complete answer and no usage event has stated
675
+ * nothing about tokens. The turn's SEMANTIC facts - what the model said,
676
+ * which tools it asked for, what may be committed to the transcript - are
677
+ * untouched by that silence, so this absence terminalizes none of them. Only
678
+ * the accounting axis is affected, and it is affected by being left exactly
679
+ * where it was: no counter advances, no per-call row is published, and no
680
+ * value is substituted for the one the provider did not send.
681
+ *
682
+ * This value states the absence and nothing more. It does not assert that the
683
+ * turn completed: the turn's own terminal fact has its own owner, and a turn
684
+ * whose accounting went missing can still fail afterwards on unrelated
685
+ * grounds.
686
+ *
687
+ * # Why the identity here is not accounting
688
+ *
689
+ * `provider` and `model` name the REQUEST this turn was lowered for. They are
690
+ * the address of the missing measurement, not a reconstruction of it, and
691
+ * carry no counters. This is exactly the line
692
+ * [`ProviderTokenAccounting::host_declared`] would cross: it would mint
693
+ * provider attribution for numbers no provider issued.
694
+ */
695
+ export interface UnmeasuredTurnUsageAccounting {
696
+ model: string;
697
+ provider: Provider;
698
+ }
699
+ /**
700
+ * Events emitted during agent execution
701
+ *
702
+ * These events form the streaming API for consumers.
703
+ */
704
+ export type AgentEvent = {
705
+ input: RunInput;
706
+ session_id: SessionId;
707
+ type: "run_started";
708
+ } | {
709
+ extraction_required?: boolean;
710
+ result: string;
711
+ session_id: SessionId;
712
+ structured_output?: unknown;
713
+ terminal_cause_kind?: TurnTerminalCauseKind | null;
714
+ type: "run_completed";
715
+ usage: CumulativeUsage;
716
+ } | {
717
+ schema_warnings?: SchemaWarning[] | null;
718
+ session_id: SessionId;
719
+ structured_output: unknown;
720
+ type: "extraction_succeeded";
721
+ } | {
722
+ attempts: number;
723
+ last_output: string;
724
+ reason: string;
725
+ session_id: SessionId;
726
+ type: "extraction_failed";
727
+ } | {
728
+ error_report: AgentErrorReport;
729
+ session_id: SessionId;
730
+ terminal_cause_kind?: TurnTerminalCauseKind | null;
731
+ type: "run_failed";
732
+ } | {
733
+ hook_id: HookId;
734
+ point: HookPoint;
735
+ type: "hook_started";
736
+ } | {
737
+ duration_ms: number;
738
+ hook_id: HookId;
739
+ point: HookPoint;
740
+ type: "hook_completed";
741
+ } | {
742
+ hook_id: HookId;
743
+ point: HookPoint;
744
+ reason: HookFailureReason;
745
+ type: "hook_failed";
746
+ } | {
747
+ hook_id: HookId;
748
+ message: string;
749
+ payload?: unknown;
750
+ point: HookPoint;
751
+ reason_code: HookReasonCode;
752
+ type: "hook_denied";
753
+ } | {
754
+ turn_number: number;
755
+ type: "turn_started";
756
+ } | {
757
+ delta: string;
758
+ type: "reasoning_delta";
759
+ } | {
760
+ content: string;
761
+ type: "reasoning_complete";
762
+ } | {
763
+ delta: string;
764
+ type: "text_delta";
765
+ } | {
766
+ content: string;
767
+ type: "text_complete";
768
+ } | {
769
+ content: unknown;
770
+ id?: string | null;
771
+ kind: ServerToolKind;
772
+ type: "server_tool_content";
773
+ } | {
774
+ image: AssistantImageEvent;
775
+ type: "assistant_image_appended";
776
+ } | {
777
+ args: ToolCallArguments;
778
+ id: string;
779
+ name: string;
780
+ type: "tool_call_requested";
781
+ } | {
782
+ content: ContentBlock[];
783
+ id: string;
784
+ is_error: boolean;
785
+ name: string;
786
+ type: "tool_result_received";
787
+ } | {
788
+ stop_reason: StopReason;
789
+ type: "turn_completed";
790
+ usage?: TurnUsage | null;
791
+ } | {
792
+ id: string;
793
+ name: string;
794
+ type: "tool_execution_started";
795
+ } | {
796
+ content: ContentBlock[];
797
+ duration_ms: number;
798
+ id: string;
799
+ is_error: boolean;
800
+ name: string;
801
+ type: "tool_execution_completed";
802
+ } | {
803
+ id: string;
804
+ name: string;
805
+ timeout_ms: number;
806
+ type: "tool_execution_timed_out";
807
+ } | {
808
+ estimated_history_tokens: number;
809
+ input_tokens: number;
810
+ message_count: number;
811
+ type: "compaction_started";
812
+ } | {
813
+ messages_after: number;
814
+ messages_before: number;
815
+ summary_tokens: number;
816
+ type: "compaction_completed";
817
+ } | {
818
+ reason: CompactionFailureReason;
819
+ type: "compaction_failed";
820
+ } | {
821
+ budget_type: BudgetType;
822
+ limit: number;
823
+ percent: number;
824
+ type: "budget_warning";
825
+ used: number;
826
+ } | {
827
+ retry: LlmRetrySchedule;
828
+ type: "retrying";
829
+ } | {
830
+ injection_bytes: number;
831
+ skills: SkillKey[];
832
+ type: "skills_resolved";
833
+ } | {
834
+ reason: SkillResolutionFailureReason;
835
+ skill_key?: SkillKey | null;
836
+ type: "skill_resolution_failed";
837
+ } | {
838
+ interaction_id: InteractionId;
839
+ result: string;
840
+ structured_output?: unknown;
841
+ type: "interaction_complete";
842
+ } | {
843
+ args: unknown;
844
+ interaction_id: InteractionId;
845
+ pending_tool_calls?: PendingCallbackToolCall[];
846
+ tool_name: string;
847
+ type: "interaction_callback_pending";
848
+ } | {
849
+ interaction_id: InteractionId;
850
+ reason: InteractionFailureReason;
851
+ type: "interaction_failed";
852
+ } | {
853
+ reason: StreamTruncationReason;
854
+ type: "stream_truncated";
855
+ } | {
856
+ payload: ToolConfigChangedPayload;
857
+ type: "tool_config_changed";
858
+ } | {
859
+ detail: string;
860
+ display_name: string;
861
+ job_id: string;
862
+ terminal_status: BackgroundJobTerminalStatus;
863
+ type: "background_job_completed";
864
+ } | {
865
+ record: TranscriptRewriteRecord;
866
+ session_id: SessionId;
867
+ type: "transcript_rewrite_committed";
868
+ } | {
869
+ final_assistant_text?: string | null;
870
+ receipt: TranscriptRewriteAuditReceiptBatch;
871
+ session_id: SessionId;
872
+ type: "transcript_rewrite_audit_receipt_committed";
873
+ } | {
874
+ discarded: DiscardedCacheBreakpoint[];
875
+ retained: number;
876
+ session_id: SessionId;
877
+ type: "provider_cache_breakpoints_discarded";
878
+ } | {
879
+ kind: CommsNoticeKind;
880
+ peer?: SystemNoticePeer | null;
881
+ request_id?: string | null;
882
+ sender_taint?: SenderContentTaint | null;
883
+ type: "peer_content_ingested";
884
+ } | {
885
+ session_id: SessionId;
886
+ type: "turn_usage_accounting_unmeasured";
887
+ unmeasured: UnmeasuredTurnUsageAccounting;
888
+ } | {
889
+ dispute: DisputedTurnUsageAccountingIdentity;
890
+ session_id: SessionId;
891
+ type: "turn_usage_accounting_identity_disputed";
892
+ };
893
+ /**
894
+ * Scope attribution frame for multi-agent streaming.
895
+ */
896
+ export type StreamScopeFrame = {
897
+ scope: "primary";
898
+ session_id: string;
899
+ } | {
900
+ agent_identity: string;
901
+ flow_run_id: string;
902
+ scope: "mob_member";
903
+ };
904
+ //# sourceMappingURL=event_types.d.ts.map