import { PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition, BudgetTracker, CustomTool, GoalLoopAgent, GoalOptions, runGoalLoop, GoalEvent, GoalResult, InlineSkill, Agent as Agent$1, ListAgentsOptions, ListResult, SDKAgentInfo } from '@theokit/sdk'; export { BudgetTracker, CustomTool, DiagnosticsSink, GenerateObjectError, GoalEvent, GoalLoopAgent, GoalOptions, GoalResult, InlineSkill, JudgeCredentialError, JudgeResult, LayerOrderError, McpAuthConfig, McpHttpServerConfig, McpOAuthConfig, McpServerConfig, McpStdioServerConfig, Plugin, PluginsSettings, Provider, ProviderRoutingSettings, RunEvent, SDKAgent, SessionRecord, SessionStore, Squad, StreamObjectError, Tool, ToolError, ToolResultContentBlock, TrustLevel, TrustPosture, TrustPostureInput, TrustSource, UngatedCapabilityError, Verdict, WiredEntity, applySecurityFloor, auditEnvReachability, foldLayers, recordWiring, resolveTrustPosture, setDiagnosticsSink, verifyLayerOrdering } from '@theokit/sdk'; import { b as MainLoopMeta, B as BudgetOptions, R as ReasoningEffort, T as ToolOptions, A as ApprovalOptions, H as HumanInTheLoopOptions } from './types-DdltPCj2.js'; export { c as AgentOptions, d as MainLoopOptions, M as McpServersMap, e as PolicyHandler, f as TimeoutAction, g as ToolboxOptions } from './types-DdltPCj2.js'; import { C as ContextWindowOptions, S as SkillsOptions, A as AgentManifestEntry, H as HitlDecision, s as streamAgentUIMessages, a as ApprovalPosture, b as AgentModule } from './bridge-entry-BxJWDpQP.js'; export { c as APPROVAL_MODES, d as AfterToolCallContext, e as AgentBuilder, f as AgentDefinitionError, g as AgentExecutionContext, h as AgentManifest, i as AgentManifestSource, j as AgentManifestTool, k as AgentRoute, l as AgentRouteContext, m as AgentRunInfo, n as AgentsPluginOptions, o as ApiErrorContext, p as ApiErrorDecision, q as ApiErrorPolicy, r as ApprovalMode, t as ApprovalRequest, B as BeforeToolCallContext, u as CompiledContextWindow, v as ContextualTool, D as DefinitionOrThunk, w as DelegationTimeoutError, E as EphemeralAgent, L as LLMCallContext, M as McpApprovalSpec, x as McpFileError, y as McpRegistryConfig, z as McpRequestContext, F as McpSelection, P as PermissionsPluginOptions, G as ProcessInputContext, R as RuntimeOverrides, I as SdkAgentHandle, J as SdkMessage, K as SdkSendOptions, N as SdkTurnHandle, O as Segment, Q as ShouldAutoApproveOptions, T as ToolCallVeto, U as ToolHooks, V as ToolHooksPlugin, W as WRITE_SCOPED_TOOLS, X as agentsPlugin, Y as applyPosture, Z as buildModelSelection, _ as compileAgentModule, $ as compileContextWindow, a0 as compileLoadedAgentModule, a1 as compileProjectContext, a2 as compileSkills, a3 as createAgentExecutionContext, a4 as createApiErrorHandler, a5 as createPermissionsPlugin, a6 as createSdkAgentStream, a7 as createThinkTagExtractor, a8 as createToolHooksPlugin, a9 as extractThinkTagStream, aa as generateAgentManifest, ab as generateAgentRoutes, ac as isAgentContext, ad as loadMcpJson, ae as loadPersonalMcpServers, af as mcpRegistry, ag as mcpToolApprovals, ah as projectContextMetadataOnlyKnobs, ai as reasoningEffortOf, aj as resolveMcpServers, ak as runWithApiErrorHandling, al as shouldAutoApprove, am as toAgentFactory, an as translateSdkEvent, ao as withClockCap, ap as withEphemeralAgent } from './bridge-entry-BxJWDpQP.js'; import { TheokitAgentError } from '@theokit/sdk/errors'; export * from '@theokit/sdk/errors'; export { ConfigurationError, BudgetExceededError as WindowBudgetExceededError } from '@theokit/sdk/errors'; import { G as Guardrail, C as CompiledAgentOptions, a as CompiledTool } from './agent-compiler-BMpuJFAI.js'; export { b as AGENT_BRAND, A as AgentDefinition, c as CompatImportUnsupportedError, d as CostBudgetExceededError, D as DefineAgentConfig, e as GuardrailAction, f as GuardrailError, g as GuardrailPhase, h as GuardrailResult, i as GuardrailViolationError, H as HookApprovalGate, j as HookApprovalRequest, k as HookGateUnsupportedError, I as InferAgentInput, l as InferAgentToolNames, M as MalformedGuardrailResultError, S as SkillsRequestContext, m as SkillsSelection, T as ToolWalkResult, n as ToolboxWalkResult, U as UnreadableTextPayloadError, o as compileAgentDefinition, p as compileTools, q as isAgentDefinition, r as resolveEnabledSkills } from './agent-compiler-BMpuJFAI.js'; import { S as SettingSourcesSelection } from './setting-sources-gate-BJJiKq33.js'; export { C as CompatSurface, a as GatedCompatSource, G as GatedSettingSource, P as ProjectSettingsGrant, R as ResolvedCompatSource, b as SettingSourceCapability, U as UntrustedSettingSourceError, r as resolveCompatSources, c as resolveSettingSources } from './setting-sources-gate-BJJiKq33.js'; import { L as LoopStrategy, R as ReflectionStrategy, b as RoundStreamFactory, S as StreamEvent, c as DelegationResult } from './delegation-scoring-CURe4oSL.js'; export { A as AgentStopReason, d as AgentStreamEvent, e as AgentTurnMetadata, f as ApprovalRequiredEvent, g as ArtifactChunkEvent, h as ArtifactStartEvent, B as BackgroundDelegation, i as BudgetExceededError, C as CheckpointSavedEvent, j as DEFAULT_MAX_ITERATIONS, k as DelegateFn, a as DelegateOptions, l as DelegationBudgetCostUnknownError, m as DelegationBudgetExceededError, n as DelegationError, o as DelegationPort, D as DelegationTarget, p as DoneEvent, E as ErrorEvent, F as FileEditEvent, I as IterationEvent, q as LoopFinishReason, r as LoopOutcome, s as LoopStrategyConfig, P as PartialToolCallEvent, t as ReflectionContext, u as ReflectionResult, v as ReflectionStrategyConfig, w as RunStartedEvent, x as ScoreVerdict, y as ScoredDelegation, z as Scorer, G as StateUpdateEvent, T as TextDeltaEvent, H as ThinkingEvent, J as ToolCallEvent, K as ToolResultEvent, M as delegate, N as delegateBackground, O as delegateWithScoring, Q as isApprovalRequired, U as isDone, V as isError, W as isPartialToolCall, X as isTextDelta, Y as isToolCall, Z as isToolResult, _ as ladderReflectionStrategy, $ as loopStrategyConfigSchema, a0 as noopReflectionStrategy, a1 as presentUIMessageStream, a2 as reflectionStrategyConfigSchema, a3 as resolveLoopStrategy, a4 as streamAgentResponse } from './delegation-scoring-CURe4oSL.js'; import { RetryOptions } from '@theokit/sdk/retry'; export * from '@theokit/sdk/retry'; export { RetryOptions } from '@theokit/sdk/retry'; import { CompressibleMessage } from '@theokit/sdk/compaction'; export { CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN, CompressibleMessage, ContextWindowMarginError, ContextWindowSource, EffectiveContextWindow, resolveEffectiveContextWindow } from '@theokit/sdk/compaction'; import { z } from 'zod'; export { SubAgent } from '@theokit/sdk/a2a'; export { assertNoSymlinkEscape, isForbiddenPath, safePathJoin } from '@theokit/sdk/path-safety'; export * from '@theokit/sdk/concurrency'; export * from '@theokit/sdk/messages'; export * from '@theokit/sdk/models'; import { DiscoverSubagentsOptions } from '@theokit/sdk/subagents-loader'; export { DiscoverSubagentsOptions, AgentDefinition as SubagentDefinition, discoverSubagents, loadSubagentDefinition } from '@theokit/sdk/subagents-loader'; export { H as HookHandlers } from './hook-handlers-Cw2FsnE5.js'; import { WireChunk } from '@theokit/presenter/wire'; export { WireChunk, WireDataPart } from '@theokit/presenter/wire'; export { ContentChunk, LifecycleItem, LifecycleVocabulary, TurnLifecycle, TurnOutcome, foldTurnLifecycle } from '@theokit/presenter'; import '@theokit/http'; import '@theokit/sdk/sandbox'; /** * M9 (theokit-ai-first) — built-in guardrail detectors. * * Each factory returns a {@link Guardrail}. None call an LLM (G2 / sdk-runtime.md): * `outputModeration` takes an INJECTED predicate so the provider call (if any) lives in the * consumer's code, never in `packages/`. */ /** Rough token estimate — ~4 chars/token (documented heuristic; exact counting is provider-specific). */ declare function estimateTokens(text: string): number; interface PromptInjectionOptions { /** Additional project-specific trigger phrases (compared lowercased, substring). */ extra?: readonly string[]; } /** Blocks input containing a known injection trigger phrase. */ declare function promptInjectionDetector(options?: PromptInjectionOptions): Guardrail; interface PiiOptions { /** When true (default), matched PII is replaced with `[REDACTED]`. */ redact?: boolean; /** Placeholder token. Default `[REDACTED]`. */ placeholder?: string; } /** Redacts CPF, email and phone numbers from input. */ declare function piiDetector(options?: PiiOptions): Guardrail; /** NFKC-normalizes and strips zero-width / RTL-override characters. */ declare function unicodeNormalizer(): Guardrail; interface CostGuardOptions { /** Cumulative input-token budget per guard instance (per session — one guard per run). */ maxTokens: number; } /** * Enforces a cumulative input-token budget. Stateful: one instance accumulates across the calls * it sees within a run. Throws {@link CostBudgetExceededError} fail-fast when exceeded. */ declare function costGuard(options: CostGuardOptions): Guardrail; interface OutputModerationOptions { /** * Injected predicate — returns `true` when the text is prohibited. The provider call (OpenAI * moderation API, a classifier, etc.) lives HERE, in consumer code — never inside `packages/` * (G2). Keeps the module runtime-free. */ moderate: (text: string) => boolean | Promise; } /** Blocks model output the injected predicate flags as prohibited. */ declare function outputModeration(options: OutputModerationOptions): Guardrail; /** * M9 (theokit-ai-first) — the guardrail pipeline: apply guards in order at a boundary phase. * * Fail-fast (error-handling.md): a `block` throws {@link GuardrailViolationError} immediately, and a * `redact` with no replacement throws {@link MalformedGuardrailResultError} — B-008, where that case * used to pass the original text through in silence. A well-formed `redact` threads its replacement * into the next guard. Independent of the SDK runtime — this runs at the framework boundary. */ /** * Run every guard's `checkInput` in order against `text`. Returns the (possibly redacted) text. * Throws on the first `block`, or on a `redact` that supplies no replacement. Guards without * `checkInput` are skipped. */ declare function runInputGuards(text: string, guards: readonly Guardrail[]): Promise; /** * Run every guard's `checkOutput` in order against `text`. Returns the (possibly redacted) text. * Throws on the first `block`, or on a `redact` that supplies no replacement. Guards without * `checkOutput` are skipped. */ declare function runOutputGuards(text: string, guards: readonly Guardrail[]): Promise; /** * Wrap `inner`, moderating its accumulated text output. * * @param inner the source stream (yields events, returns a result). * @param guards the guardrails; only those with `checkOutput` participate. * @param extractText pulls the human-visible text out of an event (return `undefined` for non-text). * @param rebuildText builds ONE event carrying the moderated text, GIVEN the text-carrying event it * replaces. Required, not optional (B-012): optional would let this function * compute a redaction it cannot apply, which is the defect it was added to remove. * * **`extractText` MUST match exactly one event kind.** This is the parameter's * real contract and it is a constraint, not a convenience. * * When it matches several, they COLLAPSE INTO ONE. Measured against the built * artifact: `[thinking('CoT: the key is sk-abc'), message(' Here you go.')]` * yields a single `message` reading `"CoT: the key is [R] Here you go."` — the * model's private reasoning inside a visible event, and no `thinking` event * survives. Reverse the order and the visible answer is swallowed into a * `thinking` event instead. * * `replaced` does NOT prevent that, and an earlier version of this docblock, of * the changeset and of a test comment all said it did. What it buys is narrower * and worth having: the surviving event keeps the KIND and the metadata of the * text-carrying event it replaces, instead of being rebuilt from the text alone. * Without it, `[thinking, message]` collapsed into whatever kind `rebuildText` * hard-coded; with it, the caller chooses. The collapse itself is unchanged. * * So a consumer who wants reasoning moderated must run a SECOND * `moderateOutputStream` over that kind, not widen one `extractText` to cover * both. * * `replaced` is ALWAYS an event, and used to be typed `E | undefined` for a case * that cannot happen. The absence check below returns before `runOutputGuards` is * ever called when no event carried text, so by the time `rebuildText` runs there * is always a text-carrying event to replace. Proof, from the accumulation loop: * `accumulated` grows only inside `if (text !== undefined)`, and `textAt` records * that same predicate — so `!textAt.includes(true)` implies `accumulated === ''`, * the absence check fires, and everything after it has `textAt.includes(true)`. * The package's own test already pinned the opposite of the old wording * (`rebuildText is never called for a channel that is not there`), and three * shipping artifacts described the unreachable case as a live one. * * Note the boundary that IS real — an event whose extracted text is the EMPTY * STRING is still text-carrying, and can be the one replaced. For * `[text('secret'), text('')]` the moderated string lands on the trailing empty * delta, so a `{ ...replaced }` caller inherits the terminator's metadata rather * than the content-bearing event's. * @param rebuildResult applies the moderated text to the generator's RETURN value. * * A stream has two channels and this function moderated one of them for a * release. The events were redacted; `step.value` — the aggregate a caller * reads from `run()`, or from the generator's return — was accumulated * upstream from the PRE-moderation events and carried the original text. * Measured against the built artifact: the guard computed `"the key is [R]"` * and `run().response` was `"the key is sk-abc123"`. * * That is this function's own defect, verbatim, one channel over: the * redaction was computed and not applied. Required for the same reason * `rebuildText` is — optional would restore it under a nicer name — and * passed rather than re-derived, because re-running `runOutputGuards` on the * aggregate would apply a non-idempotent guard twice (a disclaimer appender * would append two disclaimers). * * Return `result` unchanged when it carries no moderated text. That is * correct and not a no-op only in that case; when it DOES carry the text, * returning it unchanged drops the redaction, and no type can tell the two * apart. * */ declare function moderateOutputStream(inner: AsyncGenerator, guards: readonly Guardrail[], extractText: (event: E) => string | undefined, rebuildText: (text: string, replaced: E) => E, rebuildResult: (text: string, result: R) => R): AsyncGenerator; /** * The `extractText` for an event kind that announces itself as text — one implementation, used by * every seam that moderates a stream. * * B-021 existed because there were two hand-written copies of `typeof e.content === 'string'`, in * `AgentRunner.stream()` and in the served endpoint, and both returned `undefined` for a non-string. * `moderateOutputStream` reads `undefined` as "this event carries no text", so the payload was never * accumulated, never shown to a guard, and yielded verbatim — the DELIVER direction, with a guard * declared to stop exactly that. * * Two different questions were collapsed into one answer: * * | The event | What the extractor must say | * |---|---| * | another kind entirely | `undefined` — not this channel | * | this kind, content readable | the text | * | this kind, content unreadable | **throw** — a guard cannot examine it | * * The third row is the one that was missing, and it cannot be expressed by a return value that also * means "not this kind". Refused rather than coerced: coercing would moderate `"[object Object]"`, * consulting a guard about a string the model never produced while the real payload rides along * underneath. * * Reachable in practice rather than in theory — `StreamEvent` is `{ type: string; [key: string]: * unknown }`, `event-translator.ts` casts an unvalidated provider content block to `{ text?: string * }`, and a consumer-supplied `streamFactory` is a public option. * * Only consulted when a guard defines `checkOutput`: {@link moderateOutputStream} is a transparent * pass-through otherwise, so an agent that declared no guard never meets this error however * malformed the stream is. */ declare function textPayloadExtractor(kind: string, read: (event: E) => unknown): (event: E) => string | undefined; /** * TranscriptCompactionStrategy — a named, callable transcript-compaction authoring layer * (Strategy pattern, V4-F). Mirrors `ReflectionStrategy`/`LoopStrategy`: interface * + zod config schema + a `'token-budget'` default + `resolveCompactionStrategy`. * * The `'token-budget'` strategy DELEGATES to the SDK's `compactTranscript` (ADR D2 / * G2 / sdk-runtime.md — the SDK owns the algorithm; agents owns the named interface; * no reimplementation). Per ADR D1 it is CALLABLE by the app (exposed as * `AgentRunner.compaction`), NOT auto-invoked by the reflective loop — the SDK owns * per-turn context, so the app decides WHEN to compact and supplies the `summarize` * callback (its own LLM). EC-6: consumers whose transcript rows carry roles outside * the SDK's `CompressibleMessage` union (e.g. `'tool'`) cast at the call site, exactly * as the SDK's own type contract requires. */ /** Token budget mirrored from theocode's proven `DEFAULT_KEEP_TOKENS` (server/lib/compaction.ts). */ declare const DEFAULT_KEEP_TOKENS = 8000; /** * App-supplied summarizer: collapse the older window into one turn (the app's LLM). * Signature matches the SDK `compactTranscript` contract — receives the older window * AND the (optionally overridden) summary template. */ type Summarize = (older: CompressibleMessage[], template: string) => Promise; /** * Per-call options for {@link TranscriptCompactionStrategy.compact} — a faithful * pass-through of the SDK `CompactTranscriptOptions` knobs the app controls. Defaults * are the SDK's, EXCEPT `failSafe` which defaults `true` here: a thrown `summarize` * returns the ORIGINAL transcript + a structured warn instead of losing it — compaction * is an optimization, never a cause of data loss (error-handling discipline). The app * passes `failSafe: false` to opt into fail-fast propagation. */ interface CompactionCallOptions { /** Override the strategy's configured `keepTokens` for this call. */ readonly keepTokens?: number; /** Summarize the older window; if omitted, the SDK drops it (its documented contract). */ readonly summarize?: Summarize; /** Checkpoint marker (SDK default when omitted). */ readonly marker?: string; /** Summary template passed to `summarize` (SDK default when omitted). */ readonly summaryTemplate?: string; /** When true (DEFAULT here), a thrown `summarize` returns the original transcript + a warn. */ readonly failSafe?: boolean; } /** A named, callable compaction strategy. Pure of I/O except the delegated SDK call. */ interface TranscriptCompactionStrategy { /** Strategy identifier (e.g. `'token-budget'`). */ readonly name: string; /** The configured token budget (from `@Compaction` / `.compaction()` / default). */ readonly keepTokens: number; /** * Compact `messages` to the (optionally overridden) token budget via the SDK's * `compactTranscript`. Returns the compacted transcript; never mutates the input. */ compact(messages: CompressibleMessage[], options?: CompactionCallOptions): Promise; } /** * Serializable config for a TranscriptCompactionStrategy (SSoT per type-safety.md / G3). * `keepTokens` is REQUIRED for `'token-budget'` (EC-2 / G10 — no silent degradation * to the SDK's turn-count `keepRecent` default; the strategy is named for token budget). */ declare const compactionStrategyConfigSchema: z.ZodObject<{ name: z.ZodLiteral<"token-budget">; keepTokens: z.ZodNumber; }, z.core.$strip>; type CompactionStrategyConfig = z.infer; /** * Resolve a `@Compaction` / `.compaction()` declaration to a concrete strategy. * Throws (Zod) on an unknown name or a missing/invalid `keepTokens` (EC-2/EC-5 — * fail-fast, mirrors `resolveLoopStrategy`). The returned strategy's `compact` * delegates to `compactTranscript`, defaulting `keepTokens` to the configured value. */ declare function resolveCompactionStrategy(name: string, config: { keepTokens?: number; }): TranscriptCompactionStrategy; /** * The default `'token-budget'` strategy (what `@Compaction('token-budget')` without * an explicit budget resolves to). Carries {@link DEFAULT_KEEP_TOKENS}; the app may * override per call via `compact(messages, { keepTokens })`. */ declare const tokenBudgetCompactionStrategy: TranscriptCompactionStrategy; /** * AgentRunner — the imperative twin of `@MainLoop` (plan ADR D4, V4-B). * * `AgentRunner.fromSpec(spec).reflection().stream().build()` resolves the loop strategy from * an already-compiled spec (the capability-authored agent). `delegate()` shares the same runtime. * `build()` is the compile boundary (no I/O, no IoC — standalone, mirrors * Spring's `ChatClient.builder(...).build()`); `stream()`/`run()` do the I/O via * `runReflectiveLoopStream` (the SAME loop `delegate()` drains — DRY, ADR 0031). * V4-D-stream: `stream()` yields events live (SSE-first); `run()` drains it to a result. */ /** * Resolves the credential at the start of the stream, instead of demanding the value ready before the call. * * M74 — the credential injection point was ALREADY per run; what blocked it was the type. With a * `string`, the caller must hold the value beforehand, so the *moment* is per run but the *value* is * frozen earlier — and a short-lived OAuth bearer crosses the whole run without being re-fetched. It * was the structural cause of a silent turn in production. */ type CredentialResolver = () => string | Promise; /** Options for {@link AgentRunner.run}. */ interface AgentRunnerRunOptions { /** * The LLM API key, or a resolver called when the stream starts. * * `string` remains valid and is the path for anyone holding an API key — it does not expire, and * demanding a resolver there would be ceremony with no gain. The resolver exists for credentials * that EXPIRE. */ readonly apiKey: string | CredentialResolver; /** Session id override (default: a fresh isolated id). */ readonly sessionId?: string; /** * The run's USD ceiling across rounds: a number, or `{ maxCostUsd }`. The first round always * runs, because no earlier round exists to project its cost from; when that round alone passes * the ceiling, the run then stops with `DelegationBudgetExceededError`. Every later round is * projected at the last round's cost, and the run stops before a round the ceiling cannot cover. * `window`, and a ceiling (either spelling) that is `NaN` or not a number, are refused at the * call with a `DelegationError`; a ceiling of 0 or below throws `DelegationBudgetExceededError` * at the call, before any round; `Infinity` is no ceiling. */ readonly budget?: number | BudgetOptions; /** Cancellation — aborts stop the reflective loop from re-entering. */ readonly signal?: AbortSignal; /** * V4-J: per-run tool override. When provided, REPLACES the build-time * `compiled.tools` for this call only (e.g. a consumer that selects tools by * request mode/permission). Absent ⇒ the agent's compiled tools (unchanged). */ readonly tools?: readonly CompiledTool[]; /** * V4-L.2 (Axis-A SWAP): per-run model override. Merge-over-compiled — * `opts.model ?? compiled.model ?? default`. Absent ⇒ the compiled model. */ readonly model?: string; /** * M1 (Axis-A SWAP): per-run extended-thinking effort. Merge-over-compiled — * `opts.reasoningEffort ?? compiled.reasoningEffort` (resolved in the adapter, single site). * Mapped to the SDK `ModelSelection.params` so the provider reasons (surfaced as `thinking` * StreamEvents). Absent ⇒ the compiled reasoning effort (or none). */ readonly reasoningEffort?: ReasoningEffort; /** * M2 (Axis-A SWAP): per-run opt-in to convert inline `…` text into `thinking` * events. Merge-over-compiled (`opts.parseThinkTags ?? compiled.parseThinkTags ?? false`). For * models that emit reasoning as inline tags (qwen/deepseek) instead of a native reasoning param. */ readonly parseThinkTags?: boolean; /** * theocode#32 (Axis-A SWAP): per-run opt-in to strip a leaked Hermes `` * tool-call dialect out of the text stream. Merge-over-compiled * (`opts.stripToolDialect ?? compiled.stripToolDialect ?? false`). For models (qwen/qwen3-coder) * that leak tool calls as text instead of native `tool_calls`. */ readonly stripToolDialect?: boolean; /** * theokit#58 (Axis-A SWAP): per-run opt-in to RECOVER a leaked Hermes `` * tool-call dialect so the call EXECUTES (enables the SDK route's `extractToolCallsFromContent`). * Merge-over-compiled (`opts.recoverLeakedToolCalls ?? compiled.recoverLeakedToolCalls ?? false`). * Sibling of {@link stripToolDialect} (display-only); typically enabled together. Has effect only * when {@link providers} routes a provider. */ readonly recoverLeakedToolCalls?: boolean; /** * V4-L.2 (Axis-A SWAP): per-run working directory, forwarded into * `Agent.create({ local: { cwd } })` so the SDK populates `SystemPromptContext.cwd` * (read by a `SystemPromptResolver` / `@ProjectContext`). Absent ⇒ no `local.cwd`. */ readonly cwd?: string; /** * SDK 4.0 (SE40): per-run root of the native `.jsonl` session transcript, forwarded into * `Agent.create({ local: { baseDir } })`. Absent ⇒ the SDK default (`~/.theokit`). */ readonly baseDir?: string; /** * V4-L.2 (Axis-A SWAP): per-run loop-ceiling override. When provided, the loop * strategy is re-resolved with this ceiling for this call only (zod-validated — * `< 1` throws, never a silent unbounded loop). Absent ⇒ the build-time ceiling. */ readonly maxIterations?: number; /** * V4-L.3 (Axis-A SWAP): per-run plugins (e.g. permission gate by request mode). * Accepts EITHER named-plugin discovery settings (`{ enabled: [...] }`) OR an * array of code `Plugin` objects (`[permissionPlugin, cachePlugin]`). Both are * forwarded RAW through the duck-typed `Agent.create` bridge to the SDK runtime, * which accepts either form (mirrors the @theokit/sdk `AgentOptions.plugins` widen). */ readonly plugins?: PluginsSettings | readonly Plugin[]; /** V4-L.3 (Axis-A SWAP): per-run provider routing. */ readonly providers?: ProviderRoutingSettings; /** V4-L.3 (Axis-A SWAP): per-run sub-agent definitions (opts-only; @SubAgents stays deferred). */ readonly agents?: Record; /** * V4-L.3 (Axis-A SWAP): per-run SDK budget tracker — caps the INNER SDK tool-loop per * send. Distinct from {@link AgentRunnerRunOptions.budget} (the OUTER reflective-loop USD ceiling). */ readonly budgetTracker?: BudgetTracker; /** * V4-Q: pre-built SDK `CustomTool[]` forwarded RAW to `Agent.create.tools` (appended after the * agent's compiled tools), bypassing `defineTool`. For an app whose tools come from imperative * SDK factories (no `@Tool` compile path / no recoverable Zod schema). Distinct from `tools` * (which REPLACES the compiled `CompiledTool[]`). */ readonly sdkTools?: readonly CustomTool[]; /** * V4-R: inject the per-round stream factory, driving the reflective loop with a caller-provided * stream INSTEAD of the SDK adapter (tests / custom transport). When set, the SDK-create options * (`tools`/`sdkTools`/`model`/`cwd`/`plugins`/...) are NOT used for this call — the consumer owns * the stream. Absent ⇒ `createSdkAgentStream` (the default runtime). */ readonly streamFactory?: RoundStreamFactory; /** * V4-P: per-round transient retry. When set, the START of each reflective round (factory * creation + first event, before any event is yielded) is wrapped in the SDK `withRetry` — * a 429/5xx/network blip is recovered without re-applying an edit. Absent ⇒ single attempt. * Default `isRetryable` is the SDK `isTransientError`. */ readonly retry?: RetryOptions; } /** * A built, runnable agent. Construct via {@link AgentRunner.fromSpec} — the * constructor takes already-resolved state and is an internal detail. */ /** Already-resolved state handed to the {@link AgentRunner} constructor (internal). */ interface AgentRunnerState { readonly compiled: CompiledAgentOptions; readonly agentName: string; /** The resolved terminal-decision strategy (parity with `delegate()`). */ readonly loopStrategy: LoopStrategy; /** * M54 — true when `loopStrategy` came from `.loopStrategy(custom)` rather than a built-in name. * A custom must NOT be re-resolved by name (its name is outside the `z.enum`); a per-run * `maxIterations` override applies to it as a runner ceiling instead (see `stream`). Optional and * defaults to `false`: a state built directly (tests, `delegate()`) is a by-name built-in. */ readonly loopStrategyIsCustom?: boolean; /** The resolved between-round reflection (default or `.reflection(custom)` override). */ readonly reflectionStrategy: ReflectionStrategy; /** Recorded streaming preference (see {@link AgentRunner.streamEnabled}). */ readonly streamEnabled: boolean; /** The resolved compaction strategy, or `undefined` when none is declared (EC-4). */ readonly compaction?: TranscriptCompactionStrategy; } declare class AgentRunner { private readonly compiled; private readonly agentName; /** The resolved terminal-decision strategy (parity with `delegate()`). */ readonly loopStrategy: LoopStrategy; /** M54 — whether {@link loopStrategy} is a caller-injected custom (see {@link AgentRunnerState}). */ private readonly loopStrategyIsCustom; /** The resolved between-round reflection (default or `.reflection(custom)` override). */ readonly reflectionStrategy: ReflectionStrategy; /** * Recorded streaming preference. The reflective loop currently always streams via * the SDK `Run.stream()`; a non-streaming collect mode is future work — the flag is * captured + exposed here, not yet branched on (honest per G10: documented, not a * silent no-op). */ readonly streamEnabled: boolean; /** * V4-F: the resolved compaction strategy (from `@Compaction` or `.compaction()`), * or `undefined` when neither is declared — compaction is opt-in (EC-4). CALLABLE * by the app (ADR D1: `runner.compaction?.compact(messages, { summarize })`); the * reflective loop does NOT auto-invoke it (the SDK owns per-turn context). */ readonly compaction?: TranscriptCompactionStrategy; constructor(state: AgentRunnerState); /** Start a fluent builder from an already-compiled spec. */ static fromSpec(spec: AgentRunnerSpec): AgentRunnerBuilder; /** * V4-D-stream: stream the agent's events LIVE across the reflective loop, returning * the aggregated {@link DelegationResult} as the generator's return value. This is the * on-ramp for streaming-first apps (SSE) — `runReflectiveLoopStream` yields every * round's events before the loop terminates. `streamEnabled` is honored: when the * builder set `.stream(false)`, callers should use {@link run} instead. */ stream(message: string, opts: AgentRunnerRunOptions): AsyncGenerator; /** The core stream path, after input guardrails have run (M9). */ private streamUnguarded; /** Run the agent to a terminal result via the shared reflective loop (collect mode). */ /** * Apply a per-call `maxIterations` override (M54 D4). A custom strategy must NOT be re-resolved by * name — its name is outside the `z.enum`, which would throw — and its `shouldContinue` closure * must survive; since the runner enforces the ceiling via `round < loop.maxIterations` (T1.1), * overriding just that field bounds a custom without touching its logic. A built-in keeps the * by-name re-resolution (zod fail-loud on `< 1`) — unchanged, zero-behavior. */ private resolvePerRunLoop; run(message: string, opts: AgentRunnerRunOptions): Promise; } /** * M53 — what the runner actually needs in order to run: an already-compiled agent plus the two * loop knobs. It used to derive all of this from `walkAgentMetadata`, which chained the runner to * the decorator surface. `strategy` and `compaction` are the two non-waist channels ADR 0002 keeps * (the builder's `.compaction()` already outranked the decorator; this just names the input). */ /** * The already-compiled agent the runner executes. Field-compatible with `SubAgentSpec` on purpose — * one spec drives both `AgentRunner.fromSpec` and `delegate`. */ interface AgentRunnerSpec { readonly name: string; readonly compiled: CompiledAgentOptions; readonly strategy?: MainLoopMeta['strategy']; readonly maxIterations?: number; readonly compaction?: { name: string; keepTokens?: number; }; } /** Fluent builder — accumulates config; `build()` is the compile boundary. */ declare class AgentRunnerBuilder { private readonly spec; private reflectionOverride?; private streamEnabled; private compactionOverride?; private loopStrategyOverride?; constructor(spec: AgentRunnerSpec); /** Override the default reflection strategy (OCP — plan Drawback #2). No arg ⇒ keep default. */ reflection(strategy?: ReflectionStrategy): this; /** * M54 — inject a custom terminal-decision strategy (the fourth OCP axis, alongside * `.reflection()`/`.compaction()`/`streamFactory`). WINS over the strategy the spec's name would * resolve to, exactly as `.compaction()` outranks the spec. The runner caps ANY strategy at * `custom.maxIterations` (T1.1), so a `shouldContinue: () => true` still terminates — never an * infinite loop. * * @example * ```ts * // Stop as soon as the confidence in the last round crosses 0.9, else run to the ceiling. * const stopWhenConfident: LoopStrategy = { * name: 'confident', * maxIterations: 8, * shouldContinue: (o) => !o.responseText.includes('confidence: high'), * } * AgentRunner.fromSpec(spec).loopStrategy(stopWhenConfident).build() * ``` */ loopStrategy(custom: LoopStrategy): this; /** Record the streaming preference (see {@link AgentRunner.streamEnabled}). */ stream(enabled?: boolean): this; /** * V4-F: declare the compaction strategy (e.g. `.compaction('token-budget', { keepTokens: 8000 })`). * Resolved + validated at {@link build} (EC-5 — fail-fast there, not here). This builder * call WINS over a `@Compaction` decorator on the same agent (EC-1 — explicit override). */ compaction(name: string, options?: { keepTokens?: number; }): this; /** Resolve strategies from the spec — the compile→execute boundary (no I/O). */ build(): AgentRunner; } /** * M59 — `GoalRunner`, the OO twin of the SDK's free `runGoalLoop`, parallel to {@link AgentRunner}. * * The SDK ships goal orchestration as a free function: `runGoalLoop(agent, goal, options, deps)` drives * a goal to completion (Codex states + token budget, an LLM judge as the completion oracle), streaming * `GoalEvent`s and resolving a `GoalResult`. This class imposes the layer's OO shape on it so the * consumer authors `new GoalRunner(agent).run(goal, options)` instead of a bare function call — the same * `SDK → Theokit → AgentBuilder` boundary the M58 barrels established, here ENRICHING (a contract) an * orchestration primitive rather than passing a pure one through. * * It DELEGATES, never reimplements (parsimony Rung 9): `run` forwards verbatim to `runGoalLoop`, so the * emitted `GoalEvent` stream and the final `GoalResult` are identical to calling the SDK directly. The * parity test pins that by construction. */ /** The optional 4th arg of `runGoalLoop` (the SDK's internal `RunUntilDeps` — judge/clock overrides). */ type GoalRunnerDeps = Parameters[3]; declare class GoalRunner { private readonly agent; constructor(agent: GoalLoopAgent); /** * Drive `goal` to completion against the bound agent. Returns the SAME async generator `runGoalLoop` * returns — yielding `GoalEvent`s, resolving a `GoalResult`. `deps` (judge/clock overrides) threads * straight through; a test seam for the judge lives there, exactly as on the free function. */ run(goal: string, options?: GoalOptions, deps?: GoalRunnerDeps): AsyncGenerator; } /** * M69 — render one {@link GoalEvent} as a line, exhaustively and safely. * * ## Why this exists * * `GoalEvent` is a closed discriminated union of five variants. Every consumer that renders a goal * run switched on it, and TypeScript made that switch exhaustive against the types they had * installed — which is precisely the problem: the day the SDK adds a sixth variant in a minor, each * of those switches is silently non-exhaustive at runtime while still compiling. * * So every consumer wrote the same default branch for an event it could not name. This function is * that branch, written once, where the knowledge belongs. * * ## Exhaustive-safe means both halves * * **Compile time:** the `never` assignment at the end of the switch fails the build if a variant is * added to the union — here, in the one file that claims to know them all, rather than in every * consumer. * * **Run time:** an event whose `type` this build does not recognise is still formatted, and the line * says so. A render path that throws on a forward-compatible event turns an SDK minor into a * crashed UI; a line that pretends to understand it is worse, because nobody notices. The honest * output names the type and marks it unrecognised. * * The milestone allowed marking the published union OPEN instead. That was rejected: an open union * makes the default branch *required*, which is the opposite of the stated goal — the consumer * stops writing it. */ declare function formatGoalEvent(event: GoalEvent): string; /** * B-002 FR-001..003 — run work BEFORE compaction rewrites the transcript, and await it. * * A Decorator over {@link TranscriptCompactionStrategy} rather than a field on the call options or * on the strategy config (plan ADR-1). The requirement is REGISTRATION: a consumer registers once * and every `compact` on that strategy carries the handler, where a per-call option is silently * absent from whichever call site forgot it. The strategy config is the serializable shape, and a * function is not serializable. * * The decorated value satisfies the same interface, so every existing consumer accepts it unchanged. * * ## What this seam does NOT cover * * The SDK's auto-compaction path. When usage crosses its threshold the SDK compacts inside * `persistTurnToTranscript`, builds its own summarizer, and fires `onCompact` afterwards — there is * no consumer callback on that path and none can be added from here. Stated rather than left to be * discovered by a handler that never fires; tracked upstream as `usetheokit/theokit-sdk#653`. */ /** * Work to run before the transcript is rewritten. * * Receives a READONLY view of the pre-compaction transcript, and an `AbortSignal` that fires when the * bound below is reached. The signal is additive, never the bound itself: signalling is not stopping, * and a handler that ignores it still holds nothing up — the timeout is what releases compaction. * What the signal buys is a COOPERATIVE handler being able to drop work that is now pointless * instead of running on, detached, after the decorator stopped waiting for it. * * Receives a readonly view of the pre-compaction transcript — the reason the handler exists is to * read what compaction is about to destroy. The array is a copy: `compact` documents that it never * mutates its input, and handing a caller the live array would open a mutation path through that * contract whose damage surfaces later, in the compacted output, pointing at nothing. */ type PreCompactionHandler = (messages: readonly CompressibleMessage[], signal: AbortSignal) => void | Promise; /** How a failed handler is reported, and how long one may take. */ interface PreCompactionOptions { /** * How long the handler may take before it is abandoned. Default {@link DEFAULT_HANDLER_TIMEOUT_MS}. * * A bound is required rather than optional: without one a handler that never resolves holds the * compaction forever and the run meets the context wall instead — the outcome the seam exists to * avoid. Generous by default, because a handler doing real persistence is slow, not broken. */ readonly timeoutMs?: number; /** * Called with the typed error when the handler fails or times out. * * Reported, never swallowed, and never fatal: compaction proceeds either way, because a run that * cannot compact is worse off than one whose handler failed. Omitting this is opting into silence. */ readonly onError?: (error: PreCompactionHandlerError) => void; } /** Default bound on a handler: generous, because slow is not the same as hung. */ declare const DEFAULT_HANDLER_TIMEOUT_MS = 30000; /** * A pre-compaction handler rejected, threw, or exceeded its bound. Compaction proceeded anyway. * * Extends `TheokitAgentError` and not plain `Error`, because this package's error taxonomy is what * `isTransientError` reads: an error outside it is invisible to every classifier downstream. The * first version of this class extended `Error` and `tests/unit/error-taxonomy.test.ts` refused it — * a gate worth more than the convention it enforces, since the failure it prevents is silent. * * `code` is stable so a caller can branch on the reason without matching message text. */ declare class PreCompactionHandlerError extends TheokitAgentError { readonly name = "PreCompactionHandlerError"; /** `'timeout'` when the bound was exceeded, `'threw'` when the handler failed on its own. */ readonly reason: 'timeout' | 'threw'; constructor(message: string, reason: 'timeout' | 'threw', options?: { readonly cause?: unknown; }); } /** * Wrap `strategy` so `handler` runs, and is awaited, before the transcript is rewritten. * * Wrapping twice runs both handlers, outermost first — composition is the point of a decorator, and * the alternative (a list the decorator manages) makes ordering implicit. */ declare function withPreCompaction(strategy: TranscriptCompactionStrategy, handler: PreCompactionHandler, options?: PreCompactionOptions): TranscriptCompactionStrategy; /** * B-079 + B-080 — which decomposition the judge reads. * * `GoalOptions.subgoals` is fed to the judge prompt and is supplied by the CALLER. Measured * 2026-09-14, `packages/agents/src` produced it in **0** files, so the agent was graded against a * breakdown somebody else wrote — and a wrong breakdown was charged to the agent as failure. * * ## Why this is a named function rather than a `??` * * The reviewer decided on 2026-09-14 that the AGENT's decomposition wins: a caller's list is a * starting value, never a verdict. Written inline, that rule would live in whichever order the * arguments happened to be spread, and the same defect would come back with an accidental cause * instead of a decided one. A function can be named, tested, and FAILED when inverted. * * ## `[]` and `undefined` are different instructions * * An empty array says "no subgoals"; absence says "nothing was specified". Collapsing them would * make a caller who deliberately passed `[]` indistinguishable from one who passed nothing, and the * judge reads those differently. */ /** * The decomposition the judge should read. * * @param callerSubgoals what the embedder passed in `GoalOptions.subgoals`, if anything * @param declared what the agent declared through `task_declare` this run */ declare function resolveDecomposition(callerSubgoals: readonly string[] | undefined, declared: readonly string[]): readonly string[] | undefined; /** * M52 — the capability layer: object-oriented, composable authoring that produces the EXISTING narrow * waist (`CompiledAgentOptions`), which `assembleM8CreateOptions` already turns into `Agent.create` * options. No new spec and no new adapter were invented (ADR-1/ADR-2) — a third representation would be * the very duplication this initiative removes. */ /** Which capability contributed which fields — makes the wiring inspectable as DATA. */ interface ProvenanceEntry { readonly capability: string; readonly contributed: readonly string[]; } /** The mutable draft a capability enriches. `tools`/`agents` are pre-seeded (required in the waist). */ interface CompiledAgentOptionsDraft extends Partial> { tools: CompiledAgentOptions['tools']; agents: CompiledAgentOptions['agents']; readonly provenance: ProvenanceEntry[]; } /** * **Strategy + value-level Decorator.** N independent ways to enrich an agent (model, tools, skills, * MCP, HITL…), added or removed without touching the builder — a central `switch` would violate OCP. */ interface Capability { /** Stable identity — used for provenance and conflict messages. */ readonly name: string; apply(draft: CompiledAgentOptionsDraft): void; } /** Two capabilities set the same scalar field to different values — a composition bug, never last-wins. */ /** * M80 — extends {@link TheokitAgentError}, not plain `Error`. * * `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is * INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is * stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy * nobody chose. */ declare class CapabilityConflictError extends TheokitAgentError { readonly name = "CapabilityConflictError"; constructor(field: string, previous: unknown, next: unknown, capability: string); } /** * A fresh draft. `stream` is deliberately NOT seeded: a pre-seeded value would make * `setOnce(draft, 'stream', false, …)` throw a conflict against a default nobody declared, so * `stream: false` would be structurally unreachable. The default is applied at finalize instead. */ declare function createDraft(): CompiledAgentOptionsDraft; /** A draft that has been finalized — the waist's required `stream` is settled. */ type FinalizedDraft = CompiledAgentOptionsDraft & { stream: boolean; }; /** Apply capabilities in declaration order (deterministic) and return the draft. */ declare function applyCapabilities(capabilities: readonly Capability[], draft?: CompiledAgentOptionsDraft): FinalizedDraft; /** Set a scalar exactly once — fail-fast on a conflicting redeclaration (Rule 8). */ declare function setOnce(draft: CompiledAgentOptionsDraft, field: K, value: CompiledAgentOptionsDraft[K], capability: string): void; /** Sets the model id (and optional reasoning effort). CLASS: it validates and can conflict. */ declare class ModelCapability implements Capability { private readonly id; private readonly reasoningEffort?; readonly name = "model"; constructor(id: string, reasoningEffort?: CompiledAgentOptionsDraft['reasoningEffort']); apply(draft: CompiledAgentOptionsDraft): void; } /** Adds tools. CLASS: it ACCUMULATES (never overwrites), which is behavior worth owning. */ declare class ToolsCapability implements Capability { #private; readonly name = "tools"; constructor(tools: readonly CompiledTool[]); apply(draft: CompiledAgentOptionsDraft): void; } /** * Enables skills by name (or inline). M57: a CLASS now (was a factory function). Validation moves to * the constructor — fail-fast at authoring, the same place `ModelCapability`/`AgentConfigCapability` * validate. The `apply` body (delegate + merge) is unchanged, so the compiled output is identical. */ declare class SkillsCapability implements Capability { #private; readonly name = "skills"; constructor(entries: readonly (string | InlineSkill)[]); apply(draft: CompiledAgentOptionsDraft): void; } /** * M52 — resolution + composition. The registry is what unlocks FILE-BASED authoring (a config lists * capability names): resolving name → capability without a switch that grows per feature (OCP). */ /** Fail-fast with the known set — never `undefined` leaking into the pipeline. */ /** * M80 — extends {@link TheokitAgentError}, not plain `Error`. * * `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is * INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is * stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy * nobody chose. */ declare class UnknownCapabilityError extends TheokitAgentError { readonly name = "UnknownCapabilityError"; constructor(requested: string, known: readonly string[]); } /** **Registry + Factory Method.** */ declare class CapabilityRegistry { #private; register(name: string, factory: (arg: unknown) => Capability): this; has(name: string): boolean; names(): string[]; resolve(name: string, arg?: unknown): Capability; } /** * **Composite** — a preset behaves like ONE capability, so a caller says `codingAgent()` instead of * spreading an array at the call site. Members apply in declaration order (deterministic). */ declare class CapabilityPreset implements Capability { #private; readonly name: string; constructor(name: string, members: readonly Capability[]); apply(draft: CompiledAgentOptionsDraft): void; } /** * M53 — the capabilities that replace the waist-bound agent decorators, one per field the decorator * pipeline produces today. * * M57 reverses ADR 0001 § 4 (which kept the pure-assignment ones as a factory function to avoid * "13 near-identical classes"): the authoring surface is now 100% classes, aligned with the SDK's * `X.create()`/class shape. The `FieldCapability` base keeps the assignment ones DRY (one line each); * the behaviour-carrying ones are written out. Rationale in ADR 0005. */ /** * Base for a capability whose only job is to assign one waist field — no validation, no merge, no * precedence. M57: this replaces the `fieldCapability(name, field)` factory function with a class, so * the authoring surface is 100% classes (aligned with the SDK's `X.create()` and the existing * `ModelCapability`). The subclasses below are one line each; the shared `apply` lives here (DRY). * NOT the Template-Method the ADR-0001 refused — that was inheritance of variable *behaviour* * (`shouldContinue`); here the base carries *data* (name/field) and `apply` is identical for all. */ declare abstract class FieldCapability implements Capability { private readonly value; abstract readonly name: string; protected abstract readonly field: K; constructor(value: NonNullable); apply(draft: CompiledAgentOptionsDraft): void; } /** `@Memory` → `memory`. */ declare class MemoryCapability extends FieldCapability<'memory'> { readonly name = "memory"; protected readonly field: "memory"; } /** * `@ContextWindow` → `context`. DELEGATES to `compileContextWindow`, which is the canonical * `ContextWindowOptions → ContextSettings` conversion (it also reports the metadata-only knobs). * Taking a pre-converted value here would duplicate that knowledge — the exact divergence the M52 * zero-behavior proof caught in `skills`. */ declare class ContextWindowCapability implements Capability { private readonly options; readonly name = "context-window"; constructor(options: ContextWindowOptions); apply(draft: CompiledAgentOptionsDraft): void; } /** `@ProjectContext` → `projectContext`. */ declare class ProjectContextCapability extends FieldCapability<'projectContext'> { readonly name = "project-context"; protected readonly field: "projectContext"; } /** `@MCP` → `mcpServers`. */ declare class McpServersCapability extends FieldCapability<'mcpServers'> { readonly name = "mcp"; protected readonly field: "mcpServers"; } /** * #825 — `.subagents({...})` → `subagents`, reaching `AgentOptions.agents`. * * A capability rather than builder-only wiring, because `capability-zero-behavior.test.ts` derives * both sides of the waist and demands they agree: a field the builder can set and no capability can * express puts the decorator path one field behind, which is the gap that test exists to pin. It has * made the same demand three times before and been right every time. */ declare class SubagentsCapability extends FieldCapability<'subagents'> { readonly name = "subagents"; protected readonly field: "subagents"; } /** `@Guardrails` → `guardrails`. */ declare class GuardrailsCapability extends FieldCapability<'guardrails'> { readonly name = "guardrails"; protected readonly field: "guardrails"; } /** * `@Checkpoint` → `checkpoint`. Carries the non-durable WARNING the metadata walk used to emit: only * `'filesystem'` selects the SDK's durable store, so any other storage cannot resume across * requests. The warning moves WITH the feature — a declared checkpoint that silently cannot resume * is exactly the kind of no-op this project refuses to ship. * * ## This is RUN-STATE checkpointing. It is not file undo, and the name is shared (B-059) * * What this saves is the conversation: enough to RESUME a run. It does not snapshot the files an * agent edited and cannot restore one. * * The distinction is written here because the word is the whole problem. Measured 2026-09-11: * `rewindFiles`, `rewind_files`, `restoreFile` and `backup` return 0 files in this package, 0 in the * SDK's `.d.ts` and 0 in `@theokit/sdk-tools`, while `checkpoint` returns six — all of them this * subject. **Any parity checklist that greps for `checkpoint` is satisfied by the wrong one**, and * reports a capability that does not exist. * * So a consumer building an interactive coding agent implements snapshot and restore themselves. * There is no pre-write seam on the edit tools to hang it on either, which is the part that makes it * a feature rather than a wiring job — and the reason it is stated here instead of half-built. * * Pinned by `tests/unit/run-state-checkpointing-is-not-file-undo.test.ts`, which goes red if a file * surface ever appears — at which point this section should go with it. */ declare class CheckpointCapability implements Capability { private readonly options; readonly name = "checkpoint"; constructor(options: CompiledAgentOptions['checkpoint']); apply(draft: CompiledAgentOptionsDraft): void; } /** * `@HumanInTheLoop` → `hitl`, keyed `"_"` — the same key `compileHitlGates` mints * via `toolRuntimeName`. The separator is `_`, not `.`: the dot is outside the charset the SDK * accepts, and a gate keyed with a dot silently failed to match its tool (theokit#145). */ declare class HumanInTheLoopCapability extends FieldCapability<'hitl'> { readonly name = "human-in-the-loop"; protected readonly field: "hitl"; } /** * `@SubAgents` → `agents`. MERGES instead of `setOnce`: `agents` is a pre-seeded collection on the * draft (`createDraft` gives it `{}`), so a `setOnce` would conflict against the seed itself — the * same trap the pre-seeded `stream` sprang in M52. Merging also lets a preset declare a baseline * child set that a call site extends. * * ## How far this reaches * * **What it populates IS projected into `Agent.create`.** `assembleM8CreateOptions` forwards * `compiled.agents` to `Agent.create({ agents })`, so declaring a sub-agent through this capability * spawns one. * * That was not true until B-034. `M8CreateOptions` had no `agents` field, `agent-compiler.ts` * recorded the gap as ADR D3 — "a resolver here is carried, not invoked" — and declaring a sub-agent * through this capability compiled cleanly and spawned nothing, while the class crossed the public * barrel alongside `SubagentDefinition`, `discoverSubagents`, `loadSubagentDefinition` and * `listSubagentNames`. A consumer read the barrel, assembled the authoring chain and met silence: * the "the type crossed, the capability did not" shape `bridge/index.ts` names four times by issue * number. The deferral was a decision; the consumer discovering it at runtime was not. * * The children are SDK `AgentDefinition`s (`SubagentDefinition` on the barrel), the same shape the * per-run door `RuntimeOverrides.agents` always took. A per-run value still WINS over this one — * `sdk-adapter.ts` spreads `...m8, ...extra`, and a per-run override that lost to a compile-time * value would be the opposite of what "override" promises. */ declare class SubAgentsCapability implements Capability { private readonly children; readonly name = "sub-agents"; constructor(children: CompiledAgentOptions['agents']); apply(draft: CompiledAgentOptionsDraft): void; } /** * `@Skills({ include, autoDiscover })` → `skills`. Delegates to `compileSkills` (same reason as * `contextWindow`). Distinct from the M52 `skills([...])`, which takes the plain name/inline list. */ declare class SkillsOptionsCapability implements Capability { private readonly options; readonly name = "skills"; constructor(options: SkillsOptions); apply(draft: CompiledAgentOptionsDraft): void; } /** * `.settingSources({ user, project })` → the resolved SDK roots. * * NOT a `FieldCapability` (M68). A raw pass-through here would let a bare `'project'` string reach * `CompiledAgentOptions` — and `project` reads `/.theokit/`, **including `hooks.json`, which * executes shell**. Resolving through the gate is what makes the compiled value unable to express a * root that no posture authorized. * * The refusal happens at `apply()` — build time — rather than at run assembly, per * `error-handling.md` § 3: validate at the entry, fail before the value travels. */ declare class SettingSourcesCapability implements Capability { private readonly selection; readonly name = "setting-sources"; constructor(selection: SettingSourcesSelection); apply(draft: CompiledAgentOptionsDraft): void; } /** * #686 — the pre-spawn hook approval gate. A capability so the two compile paths agree: the waist * distinguishes "not declared" from "declared", and a field only `defineAgent` could set would make * anyone building through capabilities silently ungated. */ declare class HookApprovalCapability extends FieldCapability<'hookApproval'> { readonly name = "hook-approval"; protected readonly field: "hookApproval"; } /** * B-060 — `sessionStore`, the store the SDK resumes from. * * A `FieldCapability` like its neighbours: one field, set once. There is nothing to merge — two * declared stores is a contradiction about where history lives, not a composition. */ declare class SessionStoreCapability extends FieldCapability<'sessionStore'> { readonly name = "session-store"; protected readonly field: "sessionStore"; } /** * B-056 — `canUseTool`, the seam that sees an `ask` verdict. * * A `FieldCapability`: one gate, set once. Two gates would be two answers to one question, and * composing them would mean inventing a precedence nobody declared. */ declare class CanUseToolCapability extends FieldCapability<'canUseTool'> { readonly name = "can-use-tool"; protected readonly field: "canUseTool"; } /** * B-072 — OpenTelemetry settings, the door onto a tracer the SDK already runs. * * A `FieldCapability` because telemetry is one setting block set once: two of them would be two * answers to "which service name do these spans carry", and composing them would mean inventing a * precedence nobody declared — the same reasoning `CanUseToolCapability` records above. * * It exists because the waist gained `telemetry` and `capability-zero-behavior.test.ts` refuses to * compile while a waist field has no capability expressing it. That gate is the reason this is a * whole door rather than half of one: the projection alone would have let `defineAgent` reach the * SDK while the capability path could not, and the two paths are asserted deep-equal. */ declare class TelemetryCapability extends FieldCapability<'telemetry'> { readonly name = "telemetry"; protected readonly field: "telemetry"; } declare class PluginsCapability extends FieldCapability<'plugins'> { readonly name = "plugins"; protected readonly field: "plugins"; } declare class RunContextCapability extends FieldCapability<'runContext'> { readonly name = "run-context"; protected readonly field: "runContext"; } declare class SkillsResolverCapability extends FieldCapability<'skillsResolver'> { readonly name = "skills-resolver"; protected readonly field: "skillsResolver"; } /** The scalar agent config (name/route are HTTP concerns, never agent config). */ interface AgentConfig { readonly systemPrompt?: CompiledAgentOptions['systemPrompt']; readonly parseThinkTags?: boolean; readonly stripToolDialect?: boolean; readonly recoverLeakedToolCalls?: boolean; readonly stream?: boolean; readonly maxIterations?: number; readonly timeoutMs?: number; } /** * Scalar waist fields (formerly the `@Agent` options). CLASS, not a factory: it validates, and it is the one * capability that writes fields another capability may legitimately override (see * {@link MainLoopCapability}). */ declare class AgentConfigCapability implements Capability { private readonly config; readonly name = "agent-config"; constructor(config: AgentConfig); apply(draft: CompiledAgentOptionsDraft): void; } /** * `@MainLoop({ maxIterations, timeoutMs })` → the same two fields `@Agent` can write. * * PRECEDENCE, preserved deliberately: `compileAgent` resolves these as * `mainLoop.x ?? agentConfig.x` — the main-loop declaration WINS when both are present. A plain * `setOnce` would raise a conflict where the pipeline has a defined winner, so this capability * OVERRIDES instead. That is the one place in the layer where a later write beats an earlier one, * and it exists to keep behavior identical, not for convenience. */ declare class MainLoopCapability implements Capability { private readonly config; readonly name = "main-loop"; constructor(config: { maxIterations?: number; timeoutMs?: number; }); apply(draft: CompiledAgentOptionsDraft): void; } /** * M69 — the composed shape of an agent, as a value the construction sites can consume. * * ## What this replaces * * `applyCapabilities` returns a `FinalizedDraft`: `Partial` plus a MUTABLE * `provenance` array. That is the compiler's working surface — exactly right for capabilities, * which enrich it in place — and it was also the only thing the capability layer handed back. * * So a caller that wanted the small answer ("which tools does this agent have, on which model, and * who declared them?") had to depend on the entire compiled-options shape and receive an array it * could push into. The three construction sites — the `AgentBuilder`, `Agent.create`, and roles * loaded from disk — all need that same answer, and none of them should be handed the draft to get * it. * * ## Why four fields * * `{ tools, model, reasoningEffort, provenance }` is what a caller composes and reasons about: what * the agent can do, on which model, at what effort, and where each of those came from. Everything * else in the compiled options is downstream projection. Publishing the narrow value is what keeps * the wide internal one free to change — the reason it was internal in the first place. * * `provenance` is what makes the shape auditable rather than merely descriptive: two capabilities * may both touch `tools`, and without it a reader cannot tell which one to go edit. */ interface AgentShape { /** Identity of the agent this shape describes. */ readonly name: string; /** * Tools the composed capabilities contributed, in declaration order. * * `readonly CompiledTool[]`, not the draft's own `CompiledTool[]`: inheriting the draft's type * would publish a MUTABLE array, which is the half of the problem this value exists to fix. The * draft is mutable because capabilities enrich it in place; what the construction sites receive * must not be. */ readonly tools: readonly CompiledTool[]; /** Model id, when some capability declared one. */ readonly model?: string; /** Extended-thinking effort, when declared. */ readonly reasoningEffort?: ReasoningEffort; /** Which capability contributed which field. */ readonly provenance: readonly ProvenanceEntry[]; } /** * Compose `members` into a published {@link AgentShape}. * * A projection of `applyCapabilities`, never a second implementation — so it inherits the set-once * discipline: a conflicting redeclaration still throws `CapabilityConflictError` rather than * resolving silently. A narrower return type that swallowed the conflict would be a downgrade * disguised as ergonomics. * * The result is frozen, including its arrays. The draft is mutable by design; the published value * must not be, or the shape becomes a shared mutable and the next reader cannot tell whether what * they hold is what was declared. */ declare function declareAgentShape(name: string, members: readonly Capability[]): AgentShape; /** * M53 — tools without `@Toolbox`/`@Tool`. * * A toolbox class declares its tools as DATA (`static tools`) and keeps its handlers as ordinary * methods; the capability takes an INSTANCE. That preserves what the decorators actually bought — * grouping under a namespace and handlers bound to the instance (so a toolbox can hold state and * injected dependencies) — with no metadata reflection at all. * * The compilation itself is NOT reimplemented: it delegates to `compileTools`, the same function the * decorator path calls, so namespacing (`toolRuntimeName`), handler binding and the fail-fast checks * stay in one place. * * @example * ```ts * class SupportTools { * static tools: ToolDeclaration[] = [ * { name: 'search', description: 'Search tickets', input: z.object({ q: z.string() }), method: 'search' }, * ] * async search({ q }: { q: string }): Promise { return `found ${q}` } * } * * const agent = applyCapabilities([ * new ModelCapability('openai/gpt-5.4'), * new ToolboxCapability(new SupportTools(), { namespace: 'support' }), * ]) * ``` */ interface ToolDeclaration extends ToolOptions { /** Method on the toolbox instance that implements this tool. */ readonly method: string; /** Require human approval before the tool runs (surfaced in the manifest). */ readonly approval?: ApprovalOptions; /** Gate the tool behind human-in-the-loop (M4). */ readonly hitl?: HumanInTheLoopOptions; /** Manifest-only observability flags. */ readonly trace?: boolean; readonly audit?: boolean; } /** A toolbox instance whose class declares its tools. */ interface ToolboxSource { readonly constructor: { tools?: readonly ToolDeclaration[]; }; } interface ToolboxOptions { /** * Prefix for every tool name (`"_"`), as `@Toolbox({ namespace })` did. * The separator is `_`, not `.` — the dot is outside the charset the SDK accepts (theokit#145). */ readonly namespace?: string; /** Declarations, when they are not on the class as `static tools`. */ readonly tools?: readonly ToolDeclaration[]; } declare class ToolboxCapability implements Capability { #private; readonly name = "toolbox"; constructor(instance: object, options?: ToolboxOptions); /** * M56 — the public `compile()` is GONE. It had zero callers anywhere in the monorepo and was kept * only because deleting a public method is breaking; that concession is exactly the dead surface * M55 set out to remove, preserved inside the milestone that removed it. `apply()` is the one path. */ apply(draft: CompiledAgentOptionsDraft): void; } /** * M91 — `Toolset`: a named, immutable collection of tools, with a resolution policy that fails loud. * * ## Why in the layer * * The layer already publishes the `sandbox` and `interactive` seams; this is the counterpart that was * missing. Without it the consumer wrote its own — agent-builder's `agents/tools/registry.ts`, 170 * LoC — and the policy that matters (failing loud on an unknown name **and** on a duplicate) stayed * outside the framework, where the next consumer would have to rediscover it. * * ## What it does NOT do, and why * * **It does not prefix a namespace.** That is what disqualified `ToolboxCapability` from this same * directory for this role: a tool's name is a **contract with the model**, and prefixing changes what * the model sees. * * **It does not build tools.** Which tools, with which options and under which scope is the * consumer's decision — the layer knows nobody's `projectRoot` and nobody's sandbox posture. The * `Toolset` receives entries already built and owns only the **resolution policy**. That split is * what stops the primitive from becoming a second copy of the consumer's registry. * * ## Why fail loud in both cases * * An **unknown** name: a role that declares `run_shell` in a whitelist and gets silence ends up * without the tool and nobody notices. A **duplicate** name: registers the same tool twice in * `Agent.create`, with no signal at all. In both, the result is an **unobservable** change of * authority — which is exactly what a whitelist exists to prevent. */ /** The minimum `Toolset` needs to know about a tool: that it has a name. */ interface NamedTool { readonly name: string; } /** * @deprecated Renamed to `NamedTool`. This alias exists so a consumer pinned to the previous minor * keeps compiling; it will be removed in the next major. */ type ToolComNome = NamedTool; /** * U-3 — inside the SDK hierarchy, not beside it. * * It extended `Error` directly, so `catch (e instanceof TheokitAgentError)` — how consumers tell an * SDK failure from any other throw — missed it, leaving name or message matching as the only way to * recognise it. A consumer reported having to write a translateError() shim for exactly that. * * This layer already settled the same argument in M61, when two `ConfigurationError` classes (one * `extends Error`, one `extends TheokitAgentError`) made an `instanceof` catch one path and silently * miss the other. Same defect, same package; it was simply left standing here. * * `code` stays a public readonly field rather than moving into the base options, so every existing * `new ToolsetError(msg, 'unknown_tool')` and every `err.code` read is unchanged. */ declare class ToolsetError extends TheokitAgentError { readonly code: 'unknown_tool' | 'duplicate_tool'; readonly name = "ToolsetError"; constructor(message: string, code: 'unknown_tool' | 'duplicate_tool'); } declare class Toolset { #private; private constructor(); /** * Builds from tools that are already instantiated. Fails loud on a duplicate name **at construction** * — not at resolution: a descriptor with two tools of the same name is wrong the moment it is * written, and deferring the error to the first `resolve` hides half the cases. */ static from(tools: readonly T[]): Toolset; /** One tool by name. Throws with the name in the error — never returns `undefined` silently. */ get(name: string): T; /** * Resolves a whitelist. Fails loud on an unknown name **and** on a duplicate within the list itself: * a team never silently grants a tool the role did not declare, nor silently drops one it did. */ resolve(names: readonly string[]): readonly T[]; /** The known names, in registration order. */ names(): readonly string[]; /** All the tools, in registration order. */ all(): readonly T[]; } /** * M15 (theokit-ai-first) — A2A agent card generation (ADR-0040 § D2, home/discovery concern). * * Produces an [A2A](https://github.com/google/A2A)-spec Agent Card from the framework's * `AgentManifestEntry`, so other systems can discover a TheoKit agent's capabilities over HTTP at * `/.well-known//agent-card.json`. Pure data transform — no LLM, no runtime (G2). */ /** A single capability exposed by an A2A agent (maps from a TheoKit tool). */ interface A2ASkill { id: string; name: string; description: string; } /** A2A agent-card capabilities block. */ interface A2ACapabilities { streaming: boolean; pushNotifications: boolean; stateTransitionHistory: boolean; } /** An A2A-spec Agent Card (the subset TheoKit advertises). */ interface AgentCard { name: string; description: string; url: string; version: string; capabilities: A2ACapabilities; defaultInputModes: string[]; defaultOutputModes: string[]; skills: A2ASkill[]; } interface BuildAgentCardOptions { /** Absolute base URL of the deployment (e.g. `https://app.example.com`). A trailing slash is trimmed. */ baseUrl: string; /** Human description of the agent. Defaults to a generated sentence when omitted (spec requires non-empty). */ description?: string; } /** Build an A2A agent card from a manifest entry. */ declare function buildAgentCard(entry: AgentManifestEntry, options: BuildAgentCardOptions): AgentCard; /** The A2A discovery path for an agent: `/.well-known//agent-card.json`. */ declare function wellKnownCardPath(agentName: string): string; /** * M16 (theokit-ai-first) — MCP server manifest generation (ADR-0040 § D2, home concern). * * Exposes a TheoKit agent's tools to external MCP clients as `tools/list` descriptors, so the app * can advertise its agents over its OWN HTTP routes. Pure data transform — no LLM, no runtime, and * NO stdio transport (that stays SDK-side per sdk-runtime.md). Serving these over `GET /mcp` and the * JSON-RPC envelope are follow-ups (mount path). */ /** The MCP protocol revision these descriptors target. */ declare const MCP_PROTOCOL_VERSION = "2024-11-05"; /** A JSON-schema object (the shape MCP expects for a tool's `inputSchema`). */ interface McpJsonSchema { type: 'object'; properties: Record; required?: string[]; } /** An MCP `tools/list` tool descriptor. */ interface McpToolDescriptor { name: string; description: string; inputSchema: McpJsonSchema; } /** MCP `initialize` server info. */ interface McpServerInfo { name: string; version: string; protocolVersion: string; } /** * Map an agent's tools to MCP tool descriptors. The manifest tool carries name + description; the * per-tool JSON schema is not retained in the manifest, so a permissive empty-object schema is * emitted (MCP clients accept it and pass through arbitrary args). Wiring the real per-tool schema * is a follow-up once the manifest carries it. */ declare function buildMcpToolDescriptors(entry: AgentManifestEntry): McpToolDescriptor[]; /** Build the MCP `initialize` server-info block for an agent. */ declare function mcpServerInfo(entry: AgentManifestEntry): McpServerInfo; /** * M11 (theokit-ai-first) — {resource, thread} conversation scoping (ADR-0040 § D2, home concern). * * Maps a request's (resource, thread) pair to a deterministic, collision-safe conversation id so * multi-tenant apps isolate history without hand-building `user-${id}-thread-${id}` strings. This * is the app's request→conversation mapping — NOT the SDK's storage engine (which the derived id is * simply handed to). Background compression of long histories stays SDK-side. * * Encoding: each component is `encodeURIComponent`-escaped and joined with `/`. Since * `encodeURIComponent` escapes a raw `/` to `%2F`, the separator is unambiguous — `('a/b','c')` and * `('a','b/c')` derive DIFFERENT ids (collision-safe). Reversible via {@link parseConversationId}. */ /** Derive a deterministic conversation id from a (resource, thread) pair. Fails fast on empty input. */ declare function deriveConversationId(resource: string, thread: string): string; /** * Reverse a derived conversation id back to its (resource, thread). Returns `null` for a value that * is not a derived scope id (no separator, or an empty component) — callers treat that as "opaque id, * not scoped". */ declare function parseConversationId(id: string): { resource: string; thread: string; } | null; /** * M17 (theokit-ai-first) — ACP (Agent Client Protocol) stdio framing. * * ACP talks to a coding agent (Claude Code, Amp, Codex) over stdio as newline-delimited JSON. This * is the transport-agnostic CORE: encode a message to a line, and decode a byte/char stream that may * split a message across chunks. Pure — no subprocess, no Node API. The subprocess spawn lives in the * adapter layer (G8) / SDK; `createACPTool` (wrapping this codec + an injected transport) is a * follow-up once the adapter ships. */ /** Serialize a message to a single newline-terminated JSON line. */ declare function encodeAcpMessage(message: unknown): string; /** * Incremental decoder for newline-delimited JSON. Feed it chunks with {@link push}; it buffers a * partial trailing line across calls and returns every WHOLE message parsed so far. Blank lines are * skipped. A completed non-JSON line fails fast with a typed error (error-handling.md) — a corrupt * frame must never be silently dropped. */ declare class AcpMessageDecoder { private buffer; /** Feed a chunk; returns the messages completed by this chunk (possibly empty). */ push(chunk: string): unknown[]; } /** * M17 (theokit-ai-first) — ACP client: JSON-RPC over the stdio framing. * * Drives a coding agent (Claude Code, Amp, Codex) over an INJECTED {@link AcpTransport}. The * subprocess spawn is a Node API and lives in the adapter layer (G8); this client is transport- * agnostic and testable. It correlates responses to requests by `id`, dispatches server→client * requests (e.g. `session/request_permission`) to a registered handler, replying with its decision, * and delivers notifications (a `method` with no `id`, e.g. `session/update`) to their handler. */ /** The stdio channel to the coding-agent subprocess (abstracted for testability + G8). */ interface AcpTransport { /** Write one already-encoded (newline-terminated) line to the agent's stdin. */ send(line: string): void; /** Subscribe to raw lines/chunks from the agent's stdout. */ subscribe(onData: (chunk: string) => void): void; /** * Report a channel that closed on its own (the process exited or failed). Optional: a transport * that has it lets the client reject the requests no reply will ever answer. */ onClose?(listener: (cause: Error) => void): void; } /** * The agent wrote a stdout line that does not decode to a JSON-RPC message: it is not JSON, it is * JSON but not an object (`null`, a number, a string, an array), or it is an object that is not a * response, a request or a notification. `line` is the line, trimmed. Code `ACP_PROTOCOL_ERROR`. */ declare class AcpProtocolError extends TheokitAgentError { readonly line: string; readonly name = "AcpProtocolError"; constructor(line: string, options?: { cause?: unknown; }); } /** The transport closed; `cause` is what the transport reported. Code `ACP_CONNECTION_CLOSED`. */ declare class AcpConnectionClosedError extends TheokitAgentError { readonly name = "AcpConnectionClosedError"; constructor(cause: Error); } /** Return a value or a Promise — `unknown` already includes `Promise`; `await` handles both. */ type ServerRequestHandler = (params: unknown) => unknown; /** Called with a notification's `params`; nothing is sent back. A returned promise is watched. */ type NotificationHandler = (params: unknown) => void | Promise; declare class AcpClient { private readonly transport; private nextId; private readonly pending; private readonly handlers; private readonly notificationHandlers; private buffer; private closed; constructor(transport: AcpTransport); /** Send a JSON-RPC request and resolve with its `result` (or reject on `error`). */ request(method: string, params: unknown): Promise; /** Register a handler for a server→client request method (e.g. `session/request_permission`). */ onRequest(method: string, handler: ServerRequestHandler): void; /** Register a notification handler; one that throws or rejects is reported. */ onNotification(method: string, handler: NotificationHandler): void; private receive; private fail; private dispatch; private notify; private handleServerRequest; } /** * M81 — the names of the subagents defined under `/.theokit/agents/*.md`. * * ## Why one line deserves to exist * * It is a SELECTOR over `discoverSubagents`, exactly as `loadSubagentDefinition` already is — and * that module says why in its own words: *"one parser is the whole point"*. * * What was missing is not the logic; it is the REACH. A product that wants an inventory of * subagents for a `/agents` command had no name-shaped answer to reach for, so it wrote a second * reader over the same directory. Two readers of one convention disagree eventually — about * frontmatter, about which files count, about what an absent directory means — and the disagreement * shows up as a command that lists an agent the runtime cannot find. * * Sorted, because an inventory whose order changes per filesystem is an inventory nobody can diff. */ declare function listSubagentNames(cwd: string, options?: DiscoverSubagentsOptions): Promise; /** An inline approval request handed to the caller's `awaitApproval` (the Ink/Tauri prompt). */ interface InProcessApprovalRequest { approvalId: string; toolName: string; opts: HumanInTheLoopOptions; } /** Resolve one gated-tool approval inline (approve/deny, or a structured {@link HitlDecision}). */ type InProcessAwaitApproval = (req: InProcessApprovalRequest) => Promise; interface StreamAgentTurnInProcessInput { message: string; /** * What a consumer is told a failure was (usetheokit/theokit#390). * * Declared here as well as on the HTTP entry point because the parity gate is right: a masking * default that applied over HTTP and not in-process would make "does the server's raw text * escape?" depend on which transport the caller picked — a rule nobody could hold, and the exact * asymmetry `docs/program/three-target-parity.md` exists to refuse. * * Absent ⇒ masked to a fixed string, the same default the HTTP path takes. */ onError?: Parameters[2]['onError']; /** * M35 (multimodal) — images to send alongside the text. Threaded to the SDK's structured * `SDKUserMessage { text, images }` send form. Absent ⇒ the string send path is byte-unchanged. */ images?: Parameters[2]['images']; /** Resume key; a fresh id per run when omitted. */ sessionId?: string; /** * Inline HITL resolver — required IFF the agent has `@HumanInTheLoop`-gated tools. Omitting it for a * gated agent is a fail-fast error, never a silent bypass (Rule 8, the #99 lesson). */ awaitApproval?: InProcessAwaitApproval; /** * M96 — the declared {@link ApprovalPosture}, ADDITIVE by design (ADR D2 of the M96 plan). * * Omitting it preserves today's behaviour byte for byte, including the fail-closed refusal above: * this bridge was already the CORRECT side of the divergence the milestone closes, so breaking its * signature would charge five call sites — one of them outside this repo — a migration that fixes * no defect. What it lacked was the other half: the permissive posture was INEXPRESSIBLE here * while `toAgentFactory` reached it by omission. Naming it closes that asymmetry. */ approvals?: ApprovalPosture; /** Labels a fail-fast `AgentDefinitionError` (the file path). */ source?: string; /** Abort signal forwarded to the SDK stream (client disconnect / window close). */ signal?: AbortSignal; /** * theokit#189 — observe the SDK's typed `RunEvent`s for this turn. * * `agent-endpoint.ts` already threaded this sink on the HTTP path (theokit#132); this entry point * — the one an EMBEDDED surface uses — declared no field for it, so the sink had no way in and * every `RunEvent` was unobservable in-process. `streamAgentUIMessages` accepted it at the far end * the whole time; the hop in between simply did not pass it. * * Nothing failed while it was missing, because a sink nobody can install emits nothing to compare * against. That is what made it survive: the absence had no observable consequence to test. * * Absent ⇒ the key is omitted from the SDK call entirely, so the stream is byte-identical to * before. */ onRunEvent?: Parameters[2]['onRunEvent']; /** * theokit#474 — per-turn transient retry: a 429/5xx/network blip that kills the turn before it * produced anything is recovered instead of ending it. * * The same shape as theokit#189 above, and one layer deeper. `AgentRunnerRunOptions.retry` has * carried this option since V4-P, so a reader of the package concludes the capability exists — * but it belongs to the reflective loop, and an EMBEDDED surface does not run one: a TUI and a CLI * both come through here, one SDK turn at a time, and had no way to ask for a second attempt. A * transient ended the turn, and the person at the keyboard retyped the prompt. * * It is not the same hop `onRunEvent` was. There the far end already accepted the field and the * middle simply did not pass it; here `streamAgentUIMessages` had no `retry` parameter and the SDK * reports a provider failure as the run's terminal `error` EVENT rather than as a rejection, so * the wrapper the loop uses would have compiled, shipped, and never fired. What was added is in * `turn-retry.ts`, along with the invariant that makes retrying safe: the window closes on the * FIRST event, so nothing has reached the caller and no tool has run. * * Absent ⇒ the key is omitted from the SDK call entirely, so the stream is byte-identical to * before and the turn is a single attempt. */ retry?: Parameters[2]['retry']; /** * theokit#475 — expose the run's REAL token usage to tool handlers as `ctx.usage`, so a tool can * answer "how much context is left?" from the provider's own numbers. * * Read it with `readRunUsage` from `@theokit/agents/usage`. It reports `undefined` until the first * provider report arrives: "not known yet" and "zero tokens" are different facts, and only one of * them is ever true. * * Absent ⇒ handlers receive exactly the ctx they did before. */ exposeUsageToTools?: Parameters[2]['exposeUsageToTools']; } /** Injectable stream fn (defaults to the real SDK bridge) — lets tests drive a deterministic stream. */ interface StreamAgentTurnDeps { stream: typeof streamAgentUIMessages; } /** * Thrown when a gated agent is run in-process without an `awaitApproval` resolver. Refusing loudly is * the correct posture: silently running a `@HumanInTheLoop`-gated tool with no human gate is exactly * the #99 class of bug. Typed so callers can catch it distinctly. */ /** * M80 — extends {@link TheokitAgentError}, not plain `Error`. * * `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is * INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is * stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy * nobody chose. */ declare class InProcessApprovalRequiredError extends TheokitAgentError { readonly name = "InProcessApprovalRequiredError"; constructor(toolNames: readonly string[]); } /** * Run a compiled agent in-process and return its `UIMessageChunk` stream. `apiKey` is resolved by the * caller (same contract as the HTTP mount). Validation + compile happen SYNCHRONOUSLY (so a gated * agent without a resolver throws at call time, not lazily on first iteration); the returned value is * the SDK's `streamAgentUIMessages` generator. */ declare function streamAgentTurnInProcess(mod: AgentModule, apiKey: string, input: StreamAgentTurnInProcessInput, deps?: StreamAgentTurnDeps): AsyncGenerator; type ListOptionsWithoutPagination = ListAgentsOptions & { limit?: never; cursor?: never; }; /** * @deprecated Renamed to `ListOptionsWithoutPagination`. This alias exists so a consumer pinned to * the previous minor keeps compiling; it will be removed in the next major. */ type ListOptionsWithoutPaginationAlias = ListOptionsWithoutPagination; /** * M71 — `Agent.delete` clears the REGISTRY ENTRY and never touches the transcript on disk. * * That asymmetry is not visible from the name, and the consumer that hit it had to discover it by * measuring: it called `delete`, believed the session was gone, and found the `.jsonl` still there. * A method whose name promises removal and delivers half of it is the kind of thing this layer is * supposed to say out loud — the same reason the `list` narrowing above carries its own note. * * The whole answer is `deleteSession` in `@theokit/agents/session`, which returns * `{ registryRemoved, transcriptRemoved }` precisely so the two stores are impossible to confuse, * and refuses by default when the session is protected. Reach for that unless you specifically want * the registry alone. * * Kept reachable rather than removed: narrowing it away would break a consumer that legitimately * wants only the registry entry gone, and this layer's rule is that enriching never reduces. */ type AgentWithNarrowedList = Omit & { list(options?: ListOptionsWithoutPagination): Promise, 'nextCursor'>>; }; /** * @deprecated Renamed to `AgentWithNarrowedList`. This alias exists so a consumer pinned to the * previous minor keeps compiling; it will be removed in the next major. */ type AgentWithNarrowedListAlias = AgentWithNarrowedList; declare const Agent: AgentWithNarrowedList; export { type A2ACapabilities, type A2ASkill, AcpClient, AcpConnectionClosedError, AcpMessageDecoder, AcpProtocolError, type AcpTransport, Agent, type AgentCard, type AgentConfig, AgentConfigCapability, AgentManifestEntry, AgentModule, AgentRunner, AgentRunnerBuilder, type AgentRunnerRunOptions, type AgentShape, type AgentWithNarrowedListAlias, ApprovalOptions, ApprovalPosture, BudgetOptions, type BuildAgentCardOptions, CanUseToolCapability, type Capability, CapabilityConflictError, CapabilityPreset, CapabilityRegistry, CheckpointCapability, type CompactionCallOptions, type CompactionStrategyConfig, CompiledAgentOptions, type CompiledAgentOptionsDraft, CompiledTool, ContextWindowCapability, ContextWindowOptions, type CostGuardOptions, DEFAULT_HANDLER_TIMEOUT_MS, DEFAULT_KEEP_TOKENS, DelegationResult, FieldCapability, type FinalizedDraft, GoalRunner, type GoalRunnerDeps, Guardrail, GuardrailsCapability, HitlDecision, HookApprovalCapability, HumanInTheLoopCapability, HumanInTheLoopOptions, type InProcessApprovalRequest, InProcessApprovalRequiredError, type InProcessAwaitApproval, type ListOptionsWithoutPaginationAlias, LoopStrategy, MCP_PROTOCOL_VERSION, MainLoopCapability, MainLoopMeta, type McpJsonSchema, type McpServerInfo, McpServersCapability, type McpToolDescriptor, MemoryCapability, ModelCapability, type NamedTool, type OutputModerationOptions, type PiiOptions, PluginsCapability, type PreCompactionHandler, PreCompactionHandlerError, type PreCompactionOptions, ProjectContextCapability, type PromptInjectionOptions, type ProvenanceEntry, ReasoningEffort, ReflectionStrategy, RoundStreamFactory, RunContextCapability, SessionStoreCapability, SettingSourcesCapability, SettingSourcesSelection, SkillsCapability, SkillsOptions, SkillsOptionsCapability, SkillsResolverCapability, type StreamAgentTurnDeps, type StreamAgentTurnInProcessInput, StreamEvent, SubAgentsCapability, SubagentsCapability, type Summarize, TelemetryCapability, type ToolComNome, type ToolDeclaration, ToolOptions, ToolboxCapability, type ToolboxSource, ToolsCapability, Toolset, ToolsetError, type TranscriptCompactionStrategy, UnknownCapabilityError, applyCapabilities, buildAgentCard, buildMcpToolDescriptors, compactionStrategyConfigSchema, costGuard, createDraft, declareAgentShape, deriveConversationId, encodeAcpMessage, estimateTokens, formatGoalEvent, listSubagentNames, mcpServerInfo, moderateOutputStream, outputModeration, parseConversationId, piiDetector, promptInjectionDetector, resolveCompactionStrategy, resolveDecomposition, runInputGuards, runOutputGuards, setOnce, streamAgentTurnInProcess, streamAgentUIMessages, textPayloadExtractor, tokenBudgetCompactionStrategy, unicodeNormalizer, wellKnownCardPath, withPreCompaction };