import type { CacheUsageReport } from "./cache-helpers.js"; import type { CheckpointRestoreAudit } from "./checkpoint-restore.js"; import type { AgentLoopOptions, AgentLoopStrategy, ArtifactValidation, BudgetAxisUsage, BudgetConsumedCounters, CompactionOptions, ContentBlock, ErrorInfo, GuardrailRecord, Guardrails, InstructionInjector, JsonObject, Message, ModelConfig, OwnershipScope, ProviderRequestOptions, ProviderRequestPolicy, ProviderResolver, ProviderStopReason, RetryOptions, RunLimitBreach, RunLimitName, RunLimits, Skill, StopHook, SubscriberOverflowPolicy, SystemPromptConfig, ToolCallAuthority, ToolCallContent, ToolCallSummary, TurnBudgets, TurnPolicyOptions, Usage } from "./contracts-core.js"; import type { AgentRunInterruption, AgentRunStateOptions } from "./contracts-run-state.js"; import type { SecretRedactor } from "./redaction.js"; import type { ToolValidator } from "./tools.js"; export type ProviderEvent = { readonly type: "message_start"; readonly messageId?: string; } | { readonly type: "content_delta"; readonly content: ContentBlock; } | { readonly type: "tool_call_delta"; readonly index: number; readonly id?: string; readonly name?: string; readonly argumentsText?: string; readonly authority?: ToolCallAuthority; } | { readonly type: "tool_call"; readonly call: ToolCallContent; } | { readonly type: "usage"; readonly usage: Usage; } | { readonly type: "continuation_required"; readonly cursor: string; readonly reason?: string; } | { readonly type: "done"; readonly usage?: Usage; readonly stopReason?: ProviderStopReason; } | { readonly type: "error"; readonly error: ErrorInfo; }; export type RealtimeEvent = { readonly type: "session_started"; readonly sessionId?: string; } | { readonly type: "audio_delta"; readonly audio: Uint8Array; } | { readonly type: "transcript_delta"; readonly text: string; readonly role: "user" | "assistant"; } | { readonly type: "tool_call"; readonly call: ToolCallContent; } | { readonly type: "usage"; readonly usage: Usage; } | { readonly type: "interrupted"; } | { readonly type: "session_closed"; readonly reason?: string; } | { readonly type: "error"; readonly error: ErrorInfo; }; /** Neutral bidirectional realtime session seam. The provider owns the transport * (e.g. WebSocket); the host owns audio capture/playback and session lifecycle. */ export type InputAssemblyLayout = "legacy" | "cache_aware"; /** Opaque provenance ref for the resolved prompt version that produced a run * (plan 042). Identity only — never prompt content; the body is recoverable * from the prompt store via `hash`. */ export interface PromptVersionRef { /** Prompt name within the host's prompt store. */ readonly name: string; /** Immutable version number assigned by the prompt store. */ readonly version: number; /** Content hash of the exact UTF-8 body bytes: `sha256:<64 lowercase hex>`. */ readonly hash: string; } export interface RunOptions { readonly signal?: AbortSignal; readonly model?: ModelConfig; readonly providerSource?: ProviderResolver; /** Run-scoped ceilings. When an agent config also sets limits, these can only narrow it. */ readonly limits?: RunLimits; readonly providerOptions?: ProviderRequestOptions; /** Portable thinking intent for this run. Overrides `AgentConfig.thinkingLevel`. */ readonly thinkingLevel?: string; readonly providerRequestPolicies?: ProviderRequestPolicy | readonly ProviderRequestPolicy[]; readonly systemPrompt?: SystemPromptConfig; readonly compaction?: false | CompactionOptions; readonly retry?: false | RetryOptions; readonly metadata?: Readonly>; readonly redactor?: SecretRedactor; readonly runLedger?: RunLedger; /** Optional durable recovery store. Per-run value overrides this agent default. */ readonly effectStore?: ToolEffectStore; readonly ownership?: OwnershipScope; /** Host-verified identity; when set, must project onto `ownership` without widening. */ readonly identity?: import("./identity.js").AgentIdentity; readonly idempotencyKey?: string; readonly validate?: ToolValidator; readonly activeSkills?: readonly string[]; readonly skills?: readonly Skill[]; /** Migration opt-in: activate every skill in a configured `SkillRegistry` when `activeSkills` / `skills` are unset. */ readonly activateAllSkills?: true; /** Progressive: catalog (name+description) unless loaded; eager: full instructions every turn. Default progressive. */ readonly skillsDisclosure?: import("./skill-disclosure.js").SkillsDisclosure; /** * Optional per-run allow-list of registered tool names. Omitted → every registered tool (legacy). * Empty → no tools this run. Unknown names fail closed. Cannot widen the agent registry or a * checkpointed grant; resume intersects this list with current authority. */ readonly toolNames?: readonly string[]; /** Tools disclosure: "all" (default) sends every active tool schema; "search" sends top-k + the generated `search_tools` tool. */ readonly toolsDisclosure?: import("./tool-search.js").ToolsDisclosure; /** Per-turn restrictive allow-list over the run grant. Overrides `AgentConfig.toolNarrowing`. */ readonly toolNarrowing?: import("./contracts-core/agent.js").ToolNarrowing; /** Opt-in: tools hidden this turn stay callable by name (default off). Overrides agent config. */ readonly allowHiddenToolCalls?: true; readonly toolsSearch?: import("./tool-search.js").ToolsSearchOptions; /** Opt-in projection-only fold for aged large tool results in provider view; store untouched. */ readonly toolResultFold?: import("./tool-result-fold.js").ToolResultFoldOptions; /** Per-run overlay for `AgentConfig.attentionCompiler` (plan 074 C12): `false` disables the * compiler for this run, `true` is a no-op, an object may only relax the agent setting * (gate ratios up, `keepLast`/`thinkingKeepTurns` down, `excludeTools` extended). Enabling * the compiler where the agent config left it off throws before the first provider turn. */ readonly attentionCompiler?: import("./contracts-core/attention.js").AttentionCompilerSetting; readonly instructionInjectors?: readonly InstructionInjector[]; readonly inputLayout?: InputAssemblyLayout; readonly loop?: AgentLoopStrategy | AgentLoopOptions; /** Appended to agent-level guardrails for this run. */ readonly guardrails?: Guardrails; /** Opt-in durable interruption/checkpointing. */ readonly runState?: AgentRunStateOptions; /** Prompt provenance: copied verbatim onto this run's start and finish ledger records. */ readonly promptVersion?: PromptVersionRef; /** * Host turn policy (plan 084 Task 2): a clean turn cap and/or a synchronous stop callback * evaluated before every provider request. Omitted → no callback runs. */ readonly turnPolicy?: TurnPolicyOptions; /** Appended to agent-level stop hooks for this run (plan 106 R1). */ readonly stopHooks?: readonly StopHook[]; } export interface ProviderTurnMetadata { readonly providerId: string; readonly model: ModelConfig; readonly requestId?: string; readonly latencyMs?: number; readonly attempt?: number; readonly httpStatus?: number; readonly rateLimitRemaining?: number; readonly rateLimitResetMs?: number; /** Why the provider turn stopped (plan 087 T1); present on `provider_turn_finished` only. */ readonly stopReason?: ProviderStopReason; /** Effective budget state at turn end (plan 087 T1); present on `provider_turn_finished` only. */ readonly budgets?: TurnBudgets; /** Provider-reported cache usage and derived hit rate; absent when cache usage is unknown. */ readonly cache?: CacheUsageReport; /** Effective tool menu this turn. Names hashed in request order; never includes args. */ readonly tools?: { readonly count: number; readonly idsHash: string; }; } export interface ToolExecutionMetadata { readonly durationMs: number; readonly status: ToolCallStatus; } export type DelegatedAgentStepState = "active" | "done" | "error"; export type DelegatedAgentStepKind = "assistant" | "tool" | "subagent" | "checkpoint" | "unknown"; /** Token counters only; delegated adapters must never put thought text in this shape. */ export interface DelegatedAgentStepUsage { readonly inputTokens?: number; readonly outputTokens?: number; readonly thinkingTokens?: number; readonly cacheReadTokens?: number; readonly cacheWriteTokens?: number; readonly totalTokens?: number; } /** Safe delegated timeline metadata. Raw arguments, results, paths, URIs, and event bodies are not fields. */ export interface DelegatedAgentStep { readonly type: "delegated_agent_step"; readonly sessionId: string; readonly runId: string; readonly adapterId: string; readonly externalConversationId: string; readonly stepIndex: number; readonly state: DelegatedAgentStepState; readonly kind: DelegatedAgentStepKind; readonly durationMs?: number; readonly usage?: DelegatedAgentStepUsage; readonly toolName?: string; readonly subagentType?: string; readonly detail?: { readonly referenceId?: string; readonly label?: string; }; } /** Why a run stopped cleanly. `host_policy` is a `RunOptions.turnPolicy` stop, `hook_limit` a stop-hook continuation cap; the rest are loop ceilings (F4). */ export type AgentFinishReason = "turn_limit" | "token_limit" | "refusal" | "host_policy" | "hook_limit"; /** * Origin of an agent event forwarded from a delegated child (supervisor child-event passthrough). * Present only on child events routed onto a parent stream; absent on a session's own events. */ export interface ChildEventOrigin { readonly childId: string; readonly delegationId: string; /** Delegation depth: 1 is a direct child of the hosting supervisor. */ readonly depth: number; } /** Payload union of every agent event; the exported `AgentEvent` adds the optional child origin tag. */ type AgentEventPayload = { readonly type: "agent_started"; readonly sessionId: string; readonly runId: string; } | { readonly type: "agent_finished"; readonly sessionId: string; readonly runId: string; readonly usage?: Usage; /** Why the loop stopped, when a limit/ceiling, a host turn policy, or a stop-hook continuation cap ended the run cleanly (F4). Absent = natural end. */ readonly finishReason?: AgentFinishReason; /** Host stop detail from `TurnPolicyOptions.stop` (≤256 bytes, redacted). Present only with `finishReason: "host_policy"`. */ readonly stopDetail?: string; } | { readonly type: "agent_suspended"; readonly sessionId: string; readonly runId: string; readonly interruption: AgentRunInterruption; readonly version: number; } | { readonly type: "agent_resumed"; readonly sessionId: string; readonly runId: string; readonly version: number; /** Plan 094 Task 3: audit of the external-state restore hooks that ran before this claim. */ readonly restore?: CheckpointRestoreAudit; } | { readonly type: "agent_denied"; readonly sessionId: string; readonly runId: string; readonly interruption: AgentRunInterruption; readonly version: number; } | { readonly type: "turn_started"; readonly sessionId: string; readonly runId: string; readonly turn: number; } | { readonly type: "turn_finished"; readonly sessionId: string; readonly runId: string; readonly turn: number; } | { /** * Host middleware completed this turn without a provider request (plan 096). No `usage` field: * a deterministic turn has no provider cost, so accounting must never zero-fill one. */ readonly type: "deterministic_turn"; readonly sessionId: string; readonly runId: string; readonly turn: number; /** Answering middleware id (provenance); ids only, never free host code. */ readonly middleware: string; } | { readonly type: "provider_turn_started"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly metadata: ProviderTurnMetadata; } | { readonly type: "provider_turn_finished"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly metadata: ProviderTurnMetadata; readonly usage?: Usage; readonly error?: ErrorInfo; } | { readonly type: "message_started"; readonly sessionId: string; readonly runId: string; readonly message: Message; } | { readonly type: "message_delta"; readonly sessionId: string; readonly runId: string; readonly content: ContentBlock; } | { readonly type: "message_finished"; readonly sessionId: string; readonly runId: string; readonly message: Message; } | DelegatedAgentStep | { readonly type: "tool_execution_started"; readonly sessionId: string; readonly runId: string; readonly call: ToolCallContent; } | { readonly type: "tool_execution_progress"; readonly sessionId: string; readonly runId: string; readonly toolCallId: string; readonly name: string; readonly progress?: unknown; readonly metadata?: Readonly>; } | { readonly type: "tool_execution_finished"; readonly sessionId: string; readonly runId: string; readonly result: ToolResult; readonly metadata: ToolExecutionMetadata; } | { readonly type: "tool_execution_error"; readonly sessionId: string; readonly runId: string; readonly call: ToolCallContent; readonly error: ErrorInfo; readonly metadata: ToolExecutionMetadata; } | { readonly type: "tool_execution_blocked"; readonly sessionId: string; readonly runId: string; readonly toolCallId: string; readonly name: string; readonly reason: string; readonly error: ErrorInfo; readonly metadata: ToolExecutionMetadata; } | { /** Host `toolNarrowing` asked for names outside the run grant; those names were dropped. */ readonly type: "tool_narrowing_clamped"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly dropped: readonly string[]; } | { readonly type: "guardrail_decision"; readonly sessionId: string; readonly runId: string; readonly toolCallId?: string; readonly toolName?: string; readonly record: GuardrailRecord; } | { readonly type: "run_limit_exceeded"; readonly sessionId: string; readonly runId: string; readonly breach: RunLimitBreach; } | { /** Terminal attribution for a run that died on a run limit (plan 087 T2): which axis fired, * counters at exhaustion, how close the other axes were, and hashes of recent tool calls. */ readonly type: "budget_exhausted"; readonly sessionId: string; readonly runId: string; readonly limit: RunLimitName; readonly consumed: BudgetConsumedCounters; readonly closestOtherAxes: readonly BudgetAxisUsage[]; readonly recentToolCalls: readonly ToolCallSummary[]; } | { readonly type: "queue_updated"; readonly sessionId: string; readonly runId: string; readonly size: number; } | { /** A steered message was dropped by a terminal input guardrail; the run continues without it. */ readonly type: "steer_rejected"; readonly sessionId: string; readonly runId: string; readonly message: Message; readonly record: GuardrailRecord; } | { readonly type: "event_subscriber_overflow"; readonly sessionId: string; readonly runId?: string; readonly droppedEvents: number; readonly maxQueuedEvents: number; readonly overflow: SubscriberOverflowPolicy; } | { readonly type: "compaction_started"; readonly sessionId: string; readonly runId?: string; } | { readonly type: "compaction_finished"; readonly sessionId: string; readonly runId?: string; readonly summary: string; } | { /** One attention-compiler mutation (plan 074 R15/T6): measured counts only, never message text. */ readonly type: "attention_compiled"; readonly sessionId: string; readonly runId?: string; readonly used: number; /** Estimated tokens of the same request after this turn's mutation. */ readonly usedAfter: number; readonly inputCap: number; readonly triggerRatio: number; readonly droppedThinkingTurns: number; readonly stubbedToolResults: number; /** Payload bytes the tool stubs took out of this request. */ readonly stubbedBytes: number; readonly truncated: boolean; } | { readonly type: "retry_scheduled"; readonly sessionId: string; readonly runId: string; readonly attempt: number; readonly delayMs: number; readonly error: ErrorInfo; } | { readonly type: "error"; readonly sessionId?: string; readonly runId?: string; readonly error: ErrorInfo; } | { readonly type: "artifact_validation_started"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly attempt: number; } | { readonly type: "artifact_validation_finished"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly attempt: number; readonly result: ArtifactValidation; } | { readonly type: "artifact_revision_started"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly attempt: number; readonly failure: ArtifactValidation; } | { readonly type: "artifact_finished"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly attempt: number; readonly result: ArtifactValidation; } | { readonly type: "artifact_failed"; readonly sessionId: string; readonly runId: string; readonly turn: number; readonly attempt: number; readonly result: ArtifactValidation; }; /** * One agent event. `child` is set only when the event was forwarded from a delegated child * (e.g. supervisor `report: "stream"` passthrough), so hosts can route it onto a parent stream * without per-event-type special cases. It never replaces the event's own `sessionId`/`runId`. */ export type AgentEvent = AgentEventPayload & { readonly child?: ChildEventOrigin; }; export type ToolEffectKind = "none" | "local_mutation" | "external_mutation"; export type ToolEffectIdempotency = "none" | "optional" | "required" | "tool_managed" | "unsupported"; /** Static or validated-argument classification of one tool call's side-effect behavior. */ export interface ToolEffectDeclaration { readonly kind: ToolEffectKind; readonly idempotency: ToolEffectIdempotency; } /** Runs after argument validation. It must be synchronous, deterministic, bounded, and side-effect-free. */ export type ToolEffectClassifier = (args: JsonObject, context: ToolExecutionContext) => ToolEffectDeclaration; /** * Elicitation contract declared by a tool. When a durable gated run suspends on this tool, * the pending decision has kind `elicitation` and carries this schema as its payload contract; * the resume decision's `elicitation` payload resolves the call without executing it. */ export interface ToolElicitationRequest { /** Typed payload contract; bounded to HARD_MAX_ELICITATION_BYTES when serialized. */ readonly schema: JsonObject; /** Human-facing reason (e.g. the question); bounded to MAX_DECISION_REASON_BYTES. */ readonly reason?: string; /** Answer-shape validation beyond structural schema checks; throw to reject the payload. */ readonly validate?: (payload: JsonObject) => void; } /** Neutral tool-kind union mirroring the ACP `ToolKind` set (B4); never an ACP import in `src/`. */ export type ToolKind = "read" | "edit" | "delete" | "move" | "search" | "execute" | "think" | "fetch" | "switch_mode" | "other"; export interface ToolDefinition { readonly name: string; /** Optional explicit kind; consumers (e.g. the ACP mapper) use it instead of name heuristics. */ readonly kind?: ToolKind; readonly description?: string; readonly parameters?: JsonObject; /** Force any provider turn containing this tool to dispatch sequentially. */ readonly exclusive?: boolean; /** Optional side-effect declaration. Omitted tools retain legacy unmanaged dispatch. */ readonly effect?: ToolEffectDeclaration | ToolEffectClassifier; /** Optional elicitation contract for durable gating; return undefined to fall back to plain tool approval. */ readonly elicitation?: (args: JsonObject, context: ToolExecutionContext) => ToolElicitationRequest | undefined; execute(args: JsonObject, context: ToolExecutionContext): Promise | ToolResult; } export interface ToolRegistry { register(tool: ToolDefinition): void; get(name: string): ToolDefinition | undefined; resolve(name: string): ToolDefinition; list(): readonly ToolDefinition[]; } export interface ToolExecutionContext { readonly sessionId: string; readonly runId: string; readonly toolCallId: string; readonly signal?: AbortSignal; readonly metadata?: Readonly>; /** Host-verified identity for this tool invocation, when enterprise identity is active. */ readonly identity?: import("./identity.js").AgentIdentity; /** Core-derived stable effect key. Never accept a model-supplied key as authority. */ readonly idempotencyKey?: string; progress?(progress?: unknown, metadata?: Readonly>): void | Promise; } export interface ToolResult { readonly toolCallId: string; readonly name: string; readonly content?: readonly ContentBlock[]; readonly value?: unknown; readonly error?: ErrorInfo; readonly metadata?: Readonly>; } export type ToolEffectStatus = "pending" | "dispatched" | "completed" | "failed_retryable" | "failed_terminal" | "unknown"; export interface ToolEffectRecord extends OwnershipScope { readonly key: string; readonly sessionId: string; readonly runId: string; readonly toolCallId: string; readonly toolName: string; readonly argumentsHash: string; readonly status: ToolEffectStatus; readonly attempt: number; readonly version: number; readonly claimToken?: string; readonly result?: ToolResult; readonly resultRef?: string; readonly failure?: { readonly code: string; readonly reference?: string; }; readonly createdAt: string; readonly updatedAt: string; readonly expiresAt?: string; } export interface ToolEffectKey { readonly identity: import("./identity.js").AgentIdentity; readonly ownership: OwnershipScope; readonly key: string; readonly sessionId: string; readonly runId: string; readonly toolCallId: string; readonly toolName: string; readonly argumentsHash: string; readonly signal?: AbortSignal; } export interface ToolEffectTransition extends ToolEffectKey { readonly claimToken: string; readonly expectedVersion: number; } /** Durable claim/CAS store for recoverable tool effects. */ export interface ToolEffectStore { get(input: ToolEffectKey): Promise; begin(input: ToolEffectKey & { readonly claimTtlMs?: number; readonly maxAttempts?: number; }): Promise<{ readonly outcome: "acquired" | "existing"; readonly record: ToolEffectRecord; }>; markDispatched(input: ToolEffectTransition): Promise; complete(input: ToolEffectTransition & { readonly result?: ToolResult; readonly resultRef?: string; }): Promise; fail(input: ToolEffectTransition & { readonly status: "failed_retryable" | "failed_terminal"; readonly failure: { readonly code: string; readonly reference?: string; }; }): Promise; markUnknown(input: ToolEffectTransition & { readonly failure?: { readonly code: string; readonly reference?: string; }; }): Promise; resolveUnknown(input: ToolEffectKey & { readonly expectedVersion: number; readonly status: "completed" | "failed_retryable" | "failed_terminal"; readonly result?: ToolResult; readonly resultRef?: string; readonly failure?: { readonly code: string; readonly reference?: string; }; }): Promise; cleanup(input: { readonly ownership: OwnershipScope; readonly before: string; readonly limit?: number; readonly signal?: AbortSignal; }): Promise<{ readonly deleted: number; }>; } export type RunStatus = "queued" | "running" | "suspended" | "denied" | "succeeded" | "failed" | "aborted"; /** Stored run record. */ export interface RunRecord extends OwnershipScope { readonly id: string; readonly sessionId: string; readonly branchId?: string; readonly agentDefinitionId?: string; readonly agentDefinitionVersion?: string; readonly model?: ModelConfig; readonly provider?: string; readonly idempotencyKey?: string; readonly status?: RunStatus; readonly startedAt: string; readonly finishedAt?: string; readonly abortReason?: string; /** Present when the loop stopped on a ceiling or host policy instead of a natural end. */ readonly stopReason?: AgentFinishReason; /** Host stop detail from `TurnPolicyOptions.stop` (≤256 bytes, redacted). */ readonly stopDetail?: string; readonly error?: ErrorInfo; readonly metadata?: Readonly>; /** Provenance ref copied from `RunOptions.promptVersion` when the host supplied one. */ readonly promptVersion?: PromptVersionRef; } export type AgentEventType = AgentEvent["type"]; /** Stored agent event ledger row. The `event` payload should be redacted before storage when secrets are present. */ export interface AgentEventRecord extends OwnershipScope { readonly id: string; readonly sessionId: string; readonly runId?: string; /** Durable sources allocate positive, strictly increasing per-run positions. */ readonly sequence?: number; readonly entryId?: string; readonly type: AgentEventType; readonly timestamp: string; readonly event: AgentEvent; readonly redacted: boolean; readonly metadata?: Readonly>; } /** An event record returned by an {@link AgentEventSource}. */ export interface DurableAgentEventRecord extends AgentEventRecord { readonly runId: string; readonly sequence: number; } export interface AgentEventEnvelope { readonly record: DurableAgentEventRecord; /** Opaque cursor immediately after `record`. */ readonly cursor: string; } export interface AgentEventSourcePage { readonly items: readonly AgentEventEnvelope[]; readonly nextCursor?: string; /** True only after every event preceding a terminal event has been returned. */ readonly terminal: boolean; } /** Exact-owned, per-run durable event read. `after` is exclusive. */ export interface AgentEventSourceRead { readonly ownership: OwnershipScope; readonly sessionId: string; readonly runId: string; readonly after?: string; readonly limit?: number; readonly signal?: AbortSignal; } export interface AgentEventSourceCleanup { readonly ownership: OwnershipScope; readonly before: string; readonly limit?: number; readonly signal?: AbortSignal; } export interface AgentEventSourceOptions { readonly maxEventBytes?: number; readonly maxPageSize?: number; readonly maxCursorBytes?: number; readonly maxQueuedEvents?: number; readonly maxSubscribers?: number; readonly pollIntervalMs?: number; readonly reconnectInitialMs?: number; readonly reconnectMaxMs?: number; readonly maxRetainedEventsPerRun?: number; readonly maxRetentionAgeMs?: number; } /** Optional durable event capability. `RunLedger` remains a write-only contract. */ export interface AgentEventSource { append(record: AgentEventRecord): Promise; page(input: AgentEventSourceRead): Promise; subscribe(input: AgentEventSourceRead): AsyncIterable; cleanup(input: AgentEventSourceCleanup): Promise<{ readonly deleted: number; }>; } export type ToolCallStatus = "started" | "finished" | "error" | "blocked"; /** Stored tool-call row. The `result` payload should be redacted before storage when secrets are present. */ export interface ToolCallRecord extends OwnershipScope { readonly id: string; readonly sessionId: string; readonly runId?: string; readonly entryId?: string; readonly toolCallId: string; readonly name: string; readonly arguments: JsonObject; readonly result?: ToolResult; readonly status?: ToolCallStatus; readonly reason?: string; readonly progress?: unknown; readonly progressMetadata?: Readonly>; readonly progressAt?: string; readonly startedAt: string; readonly finishedAt?: string; readonly redacted: boolean; readonly metadata?: Readonly>; } export type UsageScope = "provider_turn" | "run_total"; /** Stored usage row. `scope` prevents provider-turn and aggregate totals from being summed together. */ export interface UsageRecord extends OwnershipScope { readonly id: string; readonly sessionId: string; readonly runId?: string; readonly entryId?: string; readonly scope: UsageScope; readonly turn?: number; readonly attempt?: number; readonly usage: Usage; readonly recordedAt: string; readonly metadata?: Readonly>; } /** Host-implemented write-side ledger for runs, events, tool calls, and usage. */ export interface RunLedger { appendRun(record: RunRecord): Promise | void; appendEvent(record: AgentEventRecord): Promise | void; appendToolCall(record: ToolCallRecord): Promise | void; appendUsage(record: UsageRecord): Promise | void; } /** Union of records that may be handed to a {@link RunLedger}. */ export type RunLedgerRecord = RunRecord | AgentEventRecord | ToolCallRecord | UsageRecord; export type RunLedgerDurability = "write_through" | "flush_on_terminal" | "buffered"; export interface RunLedgerFlushResult { readonly accepted: number; readonly flushed: number; readonly buffered: number; } /** Optional durability seam implemented by bounded ledger adapters. */ export interface FlushableRunLedger extends RunLedger { readonly durability: RunLedgerDurability; flush(): Promise; status(): RunLedgerFlushResult; dispose(options?: { readonly flush?: boolean; }): Promise; } /** Immutable human feedback linked to an existing owned run/trace and optional evaluations. */ export interface ProviderTurnResult { readonly content: readonly ContentBlock[]; readonly calls: readonly ToolCallContent[]; readonly messageId?: string; readonly started: boolean; readonly usage?: Usage; /** * Provenance for turns that did not come from the provider (plan 096): * `{ deterministic: { middleware } }`. Copied onto the assistant `Message.metadata`, so it * serializes with the transcript and survives replay. Absent for provider turns. */ readonly metadata?: Readonly>; } export {};