@theokit/agents 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bridge/agent-execution-context.ts","../src/bridge/compile-context-window.ts","../src/bridge/compile-project-context.ts","../src/bridge/walk-agent-metadata.ts","../src/bridge/compile-skills.ts","../src/bridge/agent-compiler.ts","../src/bridge/agent-sse-handler.ts","../src/bridge/agent-stream-events.ts","../src/bridge/agent-route-generator.ts","../src/bridge/event-translator.ts","../src/bridge/model-selection.ts","../src/bridge/think-tag-extractor.ts","../src/bridge/tool-dialect-stripper.ts","../src/bridge/sdk-adapter.ts","../src/bridge/ui-message-stream-translator.ts","../src/loop/compaction-strategy.ts","../src/loop/loop-strategy.ts","../src/loop/reflection-strategy.ts","../src/bridge/delegation-types.ts","../src/loop/run-reflective-loop.ts","../src/loop/agent-runner.ts","../src/bridge/agent-orchestrator.ts","../src/manifest/agent-manifest.ts","../src/theokit-plugin.ts"],"sourcesContent":["/**\n * AgentExecutionContext — extends http-decorators' ExecutionContext with agent-specific methods.\n *\n * Per ADR D2 (LSP): any guard that accepts ExecutionContext works unchanged with\n * AgentExecutionContext. Agent-specific guards can narrow via isAgentContext().\n */\nimport type { ExecutionContext } from '@theokit/http'\n\nimport type { AgentOptions, ToolOptions } from '../types.js'\n\nexport interface AgentRunInfo {\n id: string\n startedAt: Date\n}\n\nexport interface AgentExecutionContext extends ExecutionContext {\n /** The agent's configuration from @Agent() decorator. */\n getAgent(): AgentOptions\n /** The current run information. */\n getRun(): AgentRunInfo\n /** The tool being called, or null if in the main agent handler. */\n getToolCall(): ToolOptions | null\n /** Type guard — always true for AgentExecutionContext. */\n isAgentContext(): true\n}\n\n/** Create an AgentExecutionContext from a base ExecutionContext + agent state. */\nexport function createAgentExecutionContext(\n base: ExecutionContext,\n agent: AgentOptions,\n run: AgentRunInfo,\n toolCall?: ToolOptions,\n): AgentExecutionContext {\n return {\n getRequest: () => base.getRequest(),\n getUrl: () => base.getUrl(),\n getClass: () => base.getClass(),\n getMethodName: () => base.getMethodName(),\n getAgent: () => agent,\n getRun: () => run,\n getToolCall: () => toolCall ?? null,\n isAgentContext: () => true as const,\n }\n}\n\n/** Narrow an ExecutionContext to AgentExecutionContext if it is one. */\nexport function isAgentContext(ctx: ExecutionContext): ctx is AgentExecutionContext {\n return 'isAgentContext' in ctx && (ctx as AgentExecutionContext).isAgentContext()\n}\n","/**\n * M8-1 — compile `@ContextWindow` metadata into the SDK's `ContextSettings`.\n *\n * Per sdk-runtime.md, the SDK owns session/transcript storage + compaction.\n * The bridge therefore maps the one knob the SDK natively exposes as a budget —\n * `maxTokens` → `ContextSettings.maxTokens` — and reports the strategy knobs that\n * have NO native `AgentOptions` equivalent (`compactionStrategy`, `preserveLastN`,\n * `preserveToolResults`, `preserveSystemPrompt`). Those are surfaced as\n * `metadataOnlyKnobs` so the walk can emit an honest `metadata-only` warning\n * (ADR D2) instead of silently dropping them (G10 — honest enforcement).\n */\nimport type { ContextSettings } from '@theokit/sdk'\n\nimport type { ContextWindowOptions } from '../decorators/context-window.js'\n\n/** `@ContextWindow` knobs with no native SDK `AgentOptions` mapping. */\nconst STRATEGY_KNOBS = [\n 'compactionStrategy',\n 'preserveLastN',\n 'preserveToolResults',\n 'preserveSystemPrompt',\n] as const\n\nexport interface CompiledContextWindow {\n /** SDK-shaped context budget passed to `Agent.create({ context })`. */\n context: ContextSettings\n /** Declared knobs the SDK does not expose — reported, never silently dropped. */\n metadataOnlyKnobs: string[]\n}\n\nexport function compileContextWindow(options: ContextWindowOptions): CompiledContextWindow {\n const context: ContextSettings = {}\n if (typeof options.maxTokens === 'number') {\n context.maxTokens = options.maxTokens\n }\n\n const opts = options as Record<string, unknown>\n const metadataOnlyKnobs = STRATEGY_KNOBS.filter((knob) => opts[knob] !== undefined)\n\n return { context, metadataOnlyKnobs }\n}\n","/**\n * M8-2 — compile `@ProjectContext` metadata into an SDK `SystemPromptResolver`.\n *\n * There is no native `AgentOptions` field that carries a repo map, so the bridge\n * composes the documented `systemPrompt` seam (`string | SystemPromptResolver`):\n * the resolver prepends `buildEnvContext` + `buildRepoMap` (`@theokit/sdk-tools`)\n * and the nearest `THEO.md` (`@theokit/sdk/project#readProjectInstructions`) to\n * the agent's base prompt (ADR D3). The SDK primitives are dynamically imported\n * so `@theokit/sdk-tools` stays an OPTIONAL peer — only loaded when a `@ProjectContext`\n * agent actually sends.\n *\n * Knobs with no primitive mapping (`indexStrategy`, `relevanceStrategy`,\n * `maxFilesInContext`, `includeExtensions`, `rootMarkers`) are reported via\n * {@link projectContextMetadataOnlyKnobs} so the walk warns honestly (G10).\n * Only `ignorePatterns` is forwarded (to `buildRepoMap`).\n */\nimport type { SystemPromptResolver } from '@theokit/sdk'\n\nimport type { ProjectContextOptions } from '../decorators/project-context.js'\n\n/** `@ProjectContext` knobs with no primitive mapping (reported, not executed). */\nconst UNMAPPED_KNOBS = [\n 'indexStrategy',\n 'relevanceStrategy',\n 'maxFilesInContext',\n 'includeExtensions',\n 'rootMarkers',\n] as const\n\nexport function projectContextMetadataOnlyKnobs(options: ProjectContextOptions): string[] {\n const opts = options as Record<string, unknown>\n return UNMAPPED_KNOBS.filter((knob) => opts[knob] !== undefined)\n}\n\n/**\n * Build a `SystemPromptResolver` that prepends env + repo map + project\n * instructions to `base`. `base` may itself be a {@link SystemPromptResolver}\n * (V4-L.1, ADR D2): it is resolved once with the same `promptCtx` and composed\n * (resolve-then-prepend). A failing base resolver propagates (fail-loud). When the\n * SDK provides no `cwd`, the resolver returns the resolved base unchanged (no\n * filesystem guess — keeps `packages/agents/src` free of direct Node `process`\n * access per G8; the repo map needs a real cwd).\n */\nexport function compileProjectContext(\n options: ProjectContextOptions,\n base?: string | SystemPromptResolver,\n): SystemPromptResolver {\n return async (promptCtx) => {\n const resolvedBase = typeof base === 'function' ? await base(promptCtx) : base\n const cwd = promptCtx.cwd\n if (!cwd) {\n return resolvedBase ?? ''\n }\n\n const { buildEnvContext, buildRepoMap } = await import('@theokit/sdk-tools')\n const { readProjectInstructions } = await import('@theokit/sdk/project')\n\n const env = buildEnvContext(cwd)\n const repoMap = buildRepoMap(cwd, { ignore: options.ignorePatterns })\n\n let instructions = ''\n try {\n instructions = (await readProjectInstructions(cwd)).content ?? ''\n } catch {\n // readProjectInstructions is best-effort: a missing/unreadable THEO.md must\n // never break a send. buildEnvContext/buildRepoMap are never-throw by contract.\n instructions = ''\n }\n\n return [env, repoMap, instructions, resolvedBase].filter(Boolean).join('\\n\\n')\n }\n}\n","/**\n * Walk decorator metadata on agent + toolbox classes.\n * Mirrors http-decorators' walkControllerMetadata() pattern.\n *\n * EC-1: throws if @Agent class is missing @MainLoop.\n * EC-4: throws on duplicate routes across agents.\n */\nimport 'reflect-metadata'\n\nimport { Reflector } from '@theokit/http'\n\nimport { getCompactionConfig } from '../decorators/compaction.js'\nimport type { CompactionDecoratorConfig } from '../decorators/compaction.js'\nimport { getContextWindowConfig } from '../decorators/context-window.js'\nimport type { ContextWindowOptions } from '../decorators/context-window.js'\nimport type { GatewayOptions } from '../decorators/gateway.js'\nimport { getGatewayConfig } from '../decorators/gateway.js'\nimport { getMcpConfig } from '../decorators/mcp.js'\nimport type { McpServersMap } from '../decorators/mcp.js'\nimport { getMemoryConfig } from '../decorators/memory.js'\nimport type { MemoryOptions } from '../decorators/memory.js'\nimport { Trace, Audit } from '../decorators/observability.js'\nimport { RequiresApproval, Budget } from '../decorators/policies.js'\nimport type { ProjectContextOptions } from '../decorators/project-context.js'\nimport { getProjectContextConfig } from '../decorators/project-context.js'\nimport { getSkillsConfig } from '../decorators/skills.js'\nimport type { SkillsOptions } from '../decorators/skills.js'\nimport { getSubAgents } from '../decorators/sub-agents.js'\nimport { getMeta } from '../metadata/index.js'\nimport {\n AGENT_CONFIG,\n AGENT_MAIN_LOOP,\n TOOLBOX_CONFIG,\n TOOL_CONFIG,\n TOOL_METHODS,\n} from '../metadata/keys.js'\nimport type {\n AgentOptions,\n MainLoopMeta,\n ToolboxOptions,\n ToolOptions,\n ApprovalOptions,\n BudgetOptions,\n} from '../types.js'\n\nimport { compileContextWindow } from './compile-context-window.js'\nimport { projectContextMetadataOnlyKnobs } from './compile-project-context.js'\n\n// http-decorators metadata keys for pipeline reuse\nconst USE_GUARDS = Symbol.for('theokit:http-decorators:use-guards')\nconst USE_INTERCEPTORS = Symbol.for('theokit:http-decorators:use-interceptors')\nconst USE_FILTERS = Symbol.for('theokit:http-decorators:use-filters')\n\n/**\n * Stable warning codes for agent pipeline metadata-only decorators.\n * Test by code, not by message string. Document in agent support matrix.\n */\nexport const AgentWarningCode = {\n INTERCEPTOR_METADATA_ONLY: 'THEO_AGENT_INTERCEPTOR_METADATA_ONLY',\n FILTER_METADATA_ONLY: 'THEO_AGENT_FILTER_METADATA_ONLY',\n BUDGET_TOP_LEVEL_METADATA_ONLY: 'THEO_AGENT_BUDGET_TOP_LEVEL_METADATA_ONLY',\n CONTEXT_STRATEGY_METADATA_ONLY: 'THEO_AGENT_CONTEXT_STRATEGY_METADATA_ONLY',\n PROJECT_CONTEXT_KNOB_METADATA_ONLY: 'THEO_AGENT_PROJECT_CONTEXT_KNOB_METADATA_ONLY',\n} as const\n\nconst reflectorInstance = new Reflector()\n\nexport interface AgentWalkResult {\n agentConfig: AgentOptions\n mainLoop: MainLoopMeta\n toolboxes: ToolboxWalkResult[]\n guards: Function[]\n interceptors: Function[]\n filters: Function[]\n route: string\n gateway?: GatewayOptions\n subAgentClasses: Function[]\n memory?: MemoryOptions\n skills?: SkillsOptions\n contextWindow?: ContextWindowOptions\n projectContext?: ProjectContextOptions\n mcpServers?: McpServersMap\n compaction?: CompactionDecoratorConfig\n}\n\nexport interface ToolboxWalkResult {\n class: Function\n namespace: string\n tools: ToolWalkResult[]\n guards: Function[]\n}\n\nexport interface ToolWalkResult {\n propertyKey: string | symbol\n config: ToolOptions\n guards: Function[]\n approval?: ApprovalOptions\n capabilities?: string[]\n budget?: BudgetOptions\n trace: boolean\n audit: boolean\n}\n\nfunction walkToolbox(ToolboxClass: Function): ToolboxWalkResult {\n const config = getMeta<ToolboxOptions>(TOOLBOX_CONFIG, ToolboxClass) ?? {}\n const methods = getMeta<(string | symbol)[]>(TOOL_METHODS, ToolboxClass) ?? []\n const classGuards = getMeta<Function[]>(USE_GUARDS, ToolboxClass) ?? []\n\n const tools: ToolWalkResult[] = methods.map((propertyKey) => {\n const toolConfig = getMeta<ToolOptions>(TOOL_CONFIG, ToolboxClass, propertyKey)\n if (!toolConfig) {\n throw new Error(\n `[@theokit/agents] Toolbox ${ToolboxClass.name}: method '${String(propertyKey)}' is in TOOL_METHODS but has no @Tool() config.`,\n )\n }\n\n const methodGuards = getMeta<Function[]>(USE_GUARDS, ToolboxClass, propertyKey) ?? []\n\n // Read typed decorator metadata via Reflector (not generic readTypedMeta)\n const ref = reflectorInstance\n\n const approvalVal = ref.get(RequiresApproval, ToolboxClass, propertyKey)\n const traceVal = ref.get(Trace, ToolboxClass, propertyKey)\n const auditVal = ref.get(Audit, ToolboxClass, propertyKey)\n\n return {\n propertyKey,\n config: toolConfig,\n guards: [...classGuards, ...methodGuards],\n approval:\n approvalVal && typeof approvalVal === 'object' && 'reason' in approvalVal\n ? approvalVal\n : undefined,\n capabilities: undefined, // read via RequiresCapability when needed\n budget: undefined, // read via Budget when needed\n trace: traceVal ?? false,\n audit: auditVal ?? false,\n }\n })\n\n return {\n class: ToolboxClass,\n namespace: config.namespace ?? '',\n tools,\n guards: classGuards,\n }\n}\n\n/**\n * Emit one `metadata-only` warning per M8 decorator whose declared knobs have no\n * native SDK mapping. Extracted from {@link walkAgentMetadata} to keep its\n * cyclomatic complexity within budget (G6).\n */\nfunction warnUnmappedDecoratorKnobs(\n agentName: string,\n contextWindow: ContextWindowOptions | undefined,\n projectContext: ProjectContextOptions | undefined,\n): void {\n if (contextWindow) {\n const { metadataOnlyKnobs } = compileContextWindow(contextWindow)\n if (metadataOnlyKnobs.length > 0) {\n console.warn(\n `[${AgentWarningCode.CONTEXT_STRATEGY_METADATA_ONLY}] Agent ${agentName}: ` +\n `@ContextWindow knob(s) ${metadataOnlyKnobs.join(', ')} are metadata-only — ` +\n `the SDK manages transcript compaction internally. Only maxTokens is forwarded ` +\n `to Agent.create({ context }).`,\n )\n }\n }\n\n if (projectContext) {\n const unmapped = projectContextMetadataOnlyKnobs(projectContext)\n if (unmapped.length > 0) {\n console.warn(\n `[${AgentWarningCode.PROJECT_CONTEXT_KNOB_METADATA_ONLY}] Agent ${agentName}: ` +\n `@ProjectContext knob(s) ${unmapped.join(', ')} are metadata-only — ` +\n `the repo map is composed via buildRepoMap/buildEnvContext/readProjectInstructions; ` +\n `only ignorePatterns is forwarded.`,\n )\n }\n }\n}\n\n/** WeakMap cache — metadata is immutable; walk once per class. */\nconst agentWalkCache = new WeakMap<Function, AgentWalkResult>()\n\n/**\n * Walk all metadata on an agent class and its toolboxes.\n * Memoized per AgentClass via WeakMap.\n *\n * @throws Error if @Agent is missing @MainLoop (EC-1)\n */\nexport function walkAgentMetadata(\n AgentClass: Function,\n toolboxClasses: Function[] = [],\n): AgentWalkResult {\n // Cache key is AgentClass only (toolboxes are typically stable per agent)\n if (toolboxClasses.length === 0) {\n const cached = agentWalkCache.get(AgentClass)\n if (cached) return cached\n }\n const agentConfig = getMeta<AgentOptions>(AGENT_CONFIG, AgentClass)\n if (!agentConfig) {\n throw new Error(`[@theokit/agents] Class ${AgentClass.name} is missing @Agent() decorator.`)\n }\n\n const mainLoop = getMeta<MainLoopMeta>(AGENT_MAIN_LOOP, AgentClass)\n if (!mainLoop) {\n throw new Error(\n `[@theokit/agents] Agent ${AgentClass.name} is missing @MainLoop() decorator. ` +\n `Decorate exactly one method with @MainLoop().`,\n )\n }\n\n const guards = getMeta<Function[]>(USE_GUARDS, AgentClass) ?? []\n\n // Interceptors and filters are read but NOT enforced in agent pipeline.\n // Agent pipeline only shares guards with HTTP; interceptors/filters have\n // different lifecycle semantics (HTTP wraps a single handler; agents run\n // a multi-step loop with tool calls, streaming, checkpoints).\n // Warn explicitly so developers don't expect enforcement silently.\n const interceptors = getMeta<Function[]>(USE_INTERCEPTORS, AgentClass) ?? []\n if (interceptors.length > 0) {\n console.warn(\n `[${AgentWarningCode.INTERCEPTOR_METADATA_ONLY}] Agent ${AgentClass.name}: ` +\n `@UseInterceptors is metadata-only on agents and will not execute. ` +\n `Agent pipeline shares guards with HTTP but uses a distinct execution model. ` +\n `Interceptors are reserved for future agent-specific lifecycle hooks.`,\n )\n }\n\n const filters = getMeta<Function[]>(USE_FILTERS, AgentClass) ?? []\n if (filters.length > 0) {\n console.warn(\n `[${AgentWarningCode.FILTER_METADATA_ONLY}] Agent ${AgentClass.name}: ` +\n `@UseFilters is metadata-only on agents and will not catch agent runtime errors. ` +\n `Agent errors flow through SSE error events, not HTTP exception filters. ` +\n `Filters are reserved for future agent-specific error handling.`,\n )\n }\n\n // @Budget on agent class: metadata-only for top-level agents.\n // Budget enforcement is active only in delegate() (sub-agent calls) where\n // the orchestrator clamps cost mid-stream. Top-level agent budget depends\n // on the SDK's cost reporting in DoneEvent.\n const agentBudget = reflectorInstance.get(Budget, AgentClass)\n if (agentBudget) {\n console.warn(\n `[${AgentWarningCode.BUDGET_TOP_LEVEL_METADATA_ONLY}] Agent ${AgentClass.name}: ` +\n `@Budget on top-level agents is metadata-only in this version. ` +\n `Budget enforcement currently applies to delegate() calls only. ` +\n `Top-level run enforcement will be wired through SDK cost tracking in a future release.`,\n )\n }\n\n const toolboxes = toolboxClasses.map(walkToolbox)\n const gateway = getGatewayConfig(AgentClass)\n const subAgentClasses = getSubAgents(AgentClass)\n const memory = getMemoryConfig(AgentClass)\n const skills = getSkillsConfig(AgentClass)\n const mcpServers = getMcpConfig(AgentClass)\n\n // M8: @ContextWindow + @ProjectContext have native SDK mappings for only a\n // subset of their knobs; warn once for the rest (honest enforcement, G10).\n const contextWindow = getContextWindowConfig(AgentClass)\n const projectContext = getProjectContextConfig(AgentClass)\n warnUnmappedDecoratorKnobs(AgentClass.name, contextWindow, projectContext)\n const compaction = getCompactionConfig(AgentClass)\n\n const result: AgentWalkResult = {\n agentConfig,\n mainLoop,\n toolboxes,\n guards,\n interceptors,\n filters,\n route: agentConfig.route,\n gateway,\n subAgentClasses,\n memory,\n skills,\n contextWindow,\n projectContext,\n mcpServers,\n compaction,\n }\n\n if (toolboxClasses.length === 0) {\n agentWalkCache.set(AgentClass, result)\n }\n return result\n}\n\n/**\n * Validate that no two agents share the same route prefix.\n *\n * @throws Error on duplicate routes (EC-4)\n */\nexport function validateUniqueRoutes(results: AgentWalkResult[]): void {\n const seen = new Map<string, string>()\n for (const r of results) {\n const existing = seen.get(r.route)\n if (existing) {\n throw new Error(\n `[@theokit/agents] Duplicate agent route '${r.route}': ` +\n `both '${existing}' and '${r.agentConfig.name}' declare it.`,\n )\n }\n seen.set(r.route, r.agentConfig.name)\n }\n}\n","/**\n * M8-3 — compile `@Skills` metadata into the SDK's `SkillsSettings`.\n *\n * Per sdk-runtime.md: the bridge COMPILES decorator metadata into a format the\n * SDK accepts; the SDK is the runtime. `Agent.create({ skills })` natively\n * discovers `.theokit/skills/<name>/SKILL.md` files and injects the `<skills>`\n * block — so giving `@Skills` runtime is a pure shape translation, not a\n * reimplementation of discovery.\n *\n * Mapping (ADR D4):\n * - `{ include }` → `{ enabled: include, autoInject: true }`\n * - `{ autoDiscover: true }` → `{ autoInject: true }` (enabled omitted ⇒ the SDK\n * enables every discovered skill)\n */\nimport type { SkillsSettings } from '@theokit/sdk'\n\nimport type { SkillsOptions } from '../decorators/skills.js'\n\nexport function compileSkills(options: SkillsOptions): SkillsSettings {\n if (options.autoDiscover) {\n return { autoInject: true }\n }\n return { enabled: options.include, autoInject: true }\n}\n","/**\n * Agent compiler — transforms decorator metadata into SDK calls.\n *\n * Per ADR D1: @Agent is a macro over Agent.create().\n * Per ADR D3: @Tool compiles to defineTool().\n *\n * EC-3: throws if toolbox instance is missing from the instances map.\n */\nimport type { ContextSettings, SkillsSettings, SystemPromptResolver } from '@theokit/sdk'\n\nimport { getAgentConfig } from '../decorators/agent.js'\nimport type { McpServersMap } from '../decorators/mcp.js'\nimport type { MemoryOptions } from '../decorators/memory.js'\nimport type { ProjectContextOptions } from '../decorators/project-context.js'\nimport type { ReasoningEffort } from '../types.js'\n\nimport { compileContextWindow } from './compile-context-window.js'\nimport { compileSkills } from './compile-skills.js'\nimport type { ToolboxWalkResult, AgentWalkResult } from './walk-agent-metadata.js'\n\n/** Minimal interface matching defineTool() result shape. */\nexport interface CompiledTool {\n name: string\n description: string\n inputSchema: unknown\n handler: (input: unknown) => string | Promise<string>\n}\n\n/**\n * Compile @Tool metadata into tool definitions.\n *\n * @param toolboxes - Walked toolbox metadata\n * @param toolboxInstances - Map of Toolbox class → instantiated object (for `this` binding)\n */\nexport function compileTools(\n toolboxes: ToolboxWalkResult[],\n toolboxInstances: Map<Function, object>,\n): CompiledTool[] {\n const tools: CompiledTool[] = []\n\n for (const tb of toolboxes) {\n // EC-3: guard against missing toolbox instance\n const instance = toolboxInstances.get(tb.class)\n if (!instance) {\n throw new Error(\n `[@theokit/agents] Toolbox ${tb.class.name} not instantiated — add to providers or pass instances.`,\n )\n }\n\n for (const tool of tb.tools) {\n const handler = (instance as Record<string | symbol, Function>)[tool.propertyKey]\n if (typeof handler !== 'function') {\n throw new Error(\n `[@theokit/agents] Toolbox ${tb.class.name}: '${String(tool.propertyKey)}' is not a function.`,\n )\n }\n\n const name = tb.namespace ? `${tb.namespace}.${tool.config.name}` : tool.config.name\n\n tools.push({\n name,\n description: tool.config.description,\n inputSchema: tool.config.input,\n handler: (input: unknown) => handler.call(instance, input) as string | Promise<string>,\n })\n }\n }\n\n return tools\n}\n\n/** Compiled sub-agent definition matching SDK AgentDefinition shape. */\nexport interface CompiledSubAgent {\n model?: string\n /**\n * V4-L.1: typed as the union for consistency with `AgentOptions.systemPrompt`,\n * so `compileSubAgents` carries whatever the sub-agent declared. Sub-agent\n * resolver EXECUTION is out of scope this slice (ADR D3): `compiled.agents` is\n * not spread into `Agent.create` by `createSdkAgentStream`; a resolver here is\n * carried, not invoked. Top-level agent resolvers are the supported path.\n */\n systemPrompt?: string | SystemPromptResolver\n}\n\n/** Compiled agent options ready for SDK Agent.create(). */\nexport interface CompiledAgentOptions {\n model?: string\n /** Extended-thinking effort declared via `@Agent({ reasoningEffort })`; mapped to SDK ModelSelection.params. */\n reasoningEffort?: ReasoningEffort\n /** Opt-in `<think>`-tag extraction declared via `@Agent({ parseThinkTags })` (M2); wraps the stream when true. */\n parseThinkTags?: boolean\n /** Opt-in tool-dialect stripping declared via `@Agent({ stripToolDialect })` (theocode#32); strips leaked `<function=…></tool_call>` from text when true. */\n stripToolDialect?: boolean\n /** Opt-in leaked-dialect recovery declared via `@Agent({ recoverLeakedToolCalls })` (theokit#58); enables the SDK route's `extractToolCallsFromContent` so leaked tool calls EXECUTE when true. */\n recoverLeakedToolCalls?: boolean\n /** Static prompt OR a per-request {@link SystemPromptResolver} (V4-L.1, Axis-B). */\n systemPrompt?: string | SystemPromptResolver\n tools: CompiledTool[]\n agents: Record<string, CompiledSubAgent>\n memory?: MemoryOptions\n skills?: SkillsSettings\n context?: ContextSettings\n /** Raw @ProjectContext config; the adapter builds the (async) systemPrompt resolver from it. */\n projectContext?: ProjectContextOptions\n mcpServers?: McpServersMap\n maxIterations?: number\n timeoutMs?: number\n stream: boolean\n}\n\n/**\n * Compile @SubAgents references into SDK agents map.\n * Each sub-agent class must have @Agent() metadata.\n */\nexport function compileSubAgents(subAgentClasses: Function[]): Record<string, CompiledSubAgent> {\n const agents: Record<string, CompiledSubAgent> = {}\n for (const cls of subAgentClasses) {\n const config = getAgentConfig(cls)\n if (!config) continue // validated at decoration time\n agents[config.name] = {\n model: config.model,\n systemPrompt: config.systemPrompt,\n }\n }\n return agents\n}\n\n/**\n * Compile @Agent metadata into SDK-compatible options.\n *\n * EC-7: agents without toolboxes produce tools: [].\n */\nexport function compileAgent(\n walkResult: AgentWalkResult,\n toolboxInstances = new Map<Function, object>(),\n): CompiledAgentOptions {\n const tools = compileTools(walkResult.toolboxes, toolboxInstances)\n const agents = compileSubAgents(walkResult.subAgentClasses)\n\n return {\n model: walkResult.agentConfig.model,\n reasoningEffort: walkResult.agentConfig.reasoningEffort,\n parseThinkTags: walkResult.agentConfig.parseThinkTags,\n stripToolDialect: walkResult.agentConfig.stripToolDialect,\n recoverLeakedToolCalls: walkResult.agentConfig.recoverLeakedToolCalls,\n systemPrompt: walkResult.agentConfig.systemPrompt,\n tools,\n agents,\n memory: walkResult.memory,\n skills: walkResult.skills ? compileSkills(walkResult.skills) : undefined,\n context: walkResult.contextWindow\n ? compileContextWindow(walkResult.contextWindow).context\n : undefined,\n projectContext: walkResult.projectContext,\n mcpServers: walkResult.mcpServers,\n maxIterations: walkResult.mainLoop.maxIterations ?? walkResult.agentConfig.maxIterations,\n timeoutMs: walkResult.mainLoop.timeoutMs ?? walkResult.agentConfig.timeoutMs,\n stream: walkResult.agentConfig.stream ?? true,\n }\n}\n","/**\n * SSE streaming handler — Web Standard Response with ReadableStream.\n *\n * Per ADR D4: SSE is the v1 transport.\n * Per EC-2: uses ReadableStream with controller.enqueue() instead of res.write().\n * Works natively on Node, Bun, Deno, CF Workers.\n */\n\n/** Minimal event shape matching SDK's SDKMessage discriminated union. */\nexport interface StreamEvent {\n type: string\n [key: string]: unknown\n}\n\nconst encoder = new TextEncoder()\n\n/**\n * Create a Web Standard Response that streams SSE events.\n * Each event becomes: `event: {type}\\ndata: {json}\\n\\n`\n */\nexport function streamAgentResponse(\n eventStream: AsyncIterable<StreamEvent>,\n): Response {\n const stream = new ReadableStream({\n async start(controller) {\n let closed = false\n const safeEnqueue = (chunk: Uint8Array) => {\n if (closed) return\n try { controller.enqueue(chunk) } catch { closed = true }\n }\n try {\n for await (const event of eventStream) {\n if (closed) break // eslint-disable-line @typescript-eslint/no-unnecessary-condition -- mutated by safeEnqueue catch\n const data = JSON.stringify(event)\n const frame = `event: ${event.type}\\ndata: ${data}\\n\\n`\n safeEnqueue(encoder.encode(frame))\n }\n } catch (err) {\n if (!closed) { // eslint-disable-line @typescript-eslint/no-unnecessary-condition -- mutated by safeEnqueue catch\n const errorEvent = {\n type: 'error',\n error: { message: err instanceof Error ? err.message : 'Internal agent error' },\n }\n const frame = `event: error\\ndata: ${JSON.stringify(errorEvent)}\\n\\n`\n safeEnqueue(encoder.encode(frame))\n }\n } finally {\n controller.close()\n }\n },\n })\n\n return new Response(stream, {\n status: 200,\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n 'connection': 'keep-alive',\n },\n })\n}\n","/**\n * Typed discriminated union for agent SSE stream events.\n *\n * Every event has a `type` field for discrimination.\n * Clients narrow via `if (event.type === 'text_delta') event.content`.\n */\n\n/** Partial text content from the LLM. */\nexport interface TextDeltaEvent {\n type: 'text_delta'\n content: string\n}\n\n/** Agent started a tool call. */\nexport interface ToolCallEvent {\n type: 'tool_call'\n callId: string\n toolName: string\n input: unknown\n}\n\n/**\n * Tool-call arguments streaming in incrementally (theokit-sdk#70). Emitted repeatedly as the\n * model generates a tool call's args, BEFORE they are committed. The same `callId` correlates to\n * the later `tool_call` (args committed) and `tool_result`. Consumers opt in to render tool-input\n * progressively; those that don't simply ignore this variant (it never replaces `tool_call`).\n */\nexport interface PartialToolCallEvent {\n type: 'partial_tool_call'\n callId: string\n toolName: string\n input: unknown\n}\n\n/** Tool execution completed. */\nexport interface ToolResultEvent {\n type: 'tool_result'\n callId: string\n toolName: string\n output: string\n durationMs: number\n isError: boolean\n}\n\n/** Extended thinking / reasoning (when model supports it). */\nexport interface ThinkingEvent {\n type: 'thinking'\n content: string\n}\n\n/** Agent loop iteration. */\nexport interface IterationEvent {\n type: 'iteration'\n step: number\n totalSteps: number | null\n}\n\n/** Human approval required before proceeding. */\nexport interface ApprovalRequiredEvent {\n type: 'approval_required'\n callId: string\n toolName: string\n question: string\n input?: unknown\n callbackUrl: string\n timeoutMs: number\n}\n\n/** Agent encountered an error. */\nexport interface ErrorEvent {\n type: 'error'\n code: string\n message: string\n retryable: boolean\n}\n\n/** Agent completed with a final result. */\nexport interface DoneEvent {\n type: 'done'\n result: string\n usage: {\n inputTokens: number\n outputTokens: number\n totalTokens: number\n /** V4-O: SDK reasoning/cache token buckets (0 when the provider omits them). */\n reasoningTokens?: number\n cacheReadTokens?: number\n cacheWriteTokens?: number\n }\n durationMs: number\n /** Total cost in USD for this agent run (EC-2: added for budget tracking). */\n cost?: number\n}\n\n/** Agent run started. */\nexport interface RunStartedEvent {\n type: 'run_started'\n runId: string\n agentName: string\n model?: string\n}\n\n/** Artifact generation started (code, document, diagram). */\nexport interface ArtifactStartEvent {\n type: 'artifact_start'\n artifactId: string\n mimeType: string\n filename?: string\n metadata?: Record<string, unknown>\n}\n\n/** Artifact content chunk (streamable artifacts). */\nexport interface ArtifactChunkEvent {\n type: 'artifact_chunk'\n artifactId: string\n chunk: string\n isLast: boolean\n}\n\n/** Real-time state update from @Observable channels. */\nexport interface StateUpdateEvent {\n type: 'state_update'\n channel: string\n data: unknown\n}\n\n/** Checkpoint saved (resumable agents). */\nexport interface CheckpointSavedEvent {\n type: 'checkpoint_saved'\n checkpointId: string\n step: number\n resumeToken: string\n}\n\n/** File edit produced by a code assistant tool. */\nexport interface FileEditEvent {\n type: 'file_edit'\n file: string\n format: 'search-replace' | 'unified-diff' | 'full-file' | 'line-range'\n search?: string\n replace?: string\n content?: string\n diff?: string\n startLine?: number\n endLine?: number\n}\n\n/** Discriminated union of all agent stream events. */\nexport type AgentStreamEvent =\n | RunStartedEvent\n | TextDeltaEvent\n | ToolCallEvent\n | PartialToolCallEvent\n | ToolResultEvent\n | ThinkingEvent\n | IterationEvent\n | ApprovalRequiredEvent\n | ArtifactStartEvent\n | ArtifactChunkEvent\n | StateUpdateEvent\n | CheckpointSavedEvent\n | FileEditEvent\n | ErrorEvent\n | DoneEvent\n\n/** Type guard helpers. */\nexport function isTextDelta(e: AgentStreamEvent): e is TextDeltaEvent {\n return e.type === 'text_delta'\n}\nexport function isToolCall(e: AgentStreamEvent): e is ToolCallEvent {\n return e.type === 'tool_call'\n}\nexport function isPartialToolCall(e: AgentStreamEvent): e is PartialToolCallEvent {\n return e.type === 'partial_tool_call'\n}\nexport function isToolResult(e: AgentStreamEvent): e is ToolResultEvent {\n return e.type === 'tool_result'\n}\nexport function isDone(e: AgentStreamEvent): e is DoneEvent {\n return e.type === 'done'\n}\nexport function isError(e: AgentStreamEvent): e is ErrorEvent {\n return e.type === 'error'\n}\nexport function isApprovalRequired(e: AgentStreamEvent): e is ApprovalRequiredEvent {\n return e.type === 'approval_required'\n}\n","/**\n * Auto-generate HTTP routes from @Agent metadata — Web Standard.\n *\n * Per ADR D5: @Agent({ route }) auto-generates two endpoints:\n * - POST {route}/chat — send message, receive SSE stream\n * - GET {route}/runs/:runId — get run status/result\n *\n * Routes are convention-based, generated at registration time.\n */\nimport type { CompiledAgentOptions } from './agent-compiler.js'\nimport { streamAgentResponse, type StreamEvent } from './agent-sse-handler.js'\nimport type { AgentWalkResult } from './walk-agent-metadata.js'\n\nexport interface AgentRoute {\n method: 'POST' | 'GET'\n path: string\n handler: (request: Request) => Promise<Response>\n}\n\nexport interface AgentRouteContext {\n walkResult: AgentWalkResult\n compiledOptions: CompiledAgentOptions\n createRun: (message: string, sessionId: string) => AsyncIterable<StreamEvent>\n getRun?: (runId: string) => Promise<{ id: string; status: string; result?: string } | null>\n}\n\n/** Generate HTTP routes for a single agent. Returns Web Standard handlers. */\nexport function generateAgentRoutes(ctx: AgentRouteContext): AgentRoute[] {\n const { walkResult, createRun, getRun } = ctx\n const basePath = walkResult.route.replace(/\\/$/, '')\n const routes: AgentRoute[] = []\n\n routes.push({\n method: 'POST',\n path: `${basePath}/chat`,\n handler: async (request) => {\n let body: Record<string, unknown> | null = null\n try {\n body = (await request.json()) as Record<string, unknown>\n } catch {\n /* empty */\n }\n\n const message = body?.message\n if (typeof message !== 'string' || message.length === 0) {\n return new Response(\n JSON.stringify({ error: { code: 'BAD_REQUEST', message: 'message field required' } }),\n { status: 400, headers: { 'content-type': 'application/json' } },\n )\n }\n\n const rawSessionId = body?.sessionId\n const sessionId = typeof rawSessionId === 'string' ? rawSessionId : `session-${Date.now()}`\n return streamAgentResponse(createRun(message, sessionId))\n },\n })\n\n if (getRun) {\n routes.push({\n method: 'GET',\n path: `${basePath}/runs/:runId`,\n handler: async (request) => {\n const url = new URL(request.url)\n const runId = url.pathname.split('/').pop() ?? ''\n const run = await getRun(runId)\n if (!run) {\n return new Response(\n JSON.stringify({ error: { code: 'NOT_FOUND', message: `Run ${runId} not found` } }),\n { status: 404, headers: { 'content-type': 'application/json' } },\n )\n }\n return new Response(JSON.stringify(run), {\n status: 200,\n headers: { 'content-type': 'application/json' },\n })\n },\n })\n }\n\n return routes\n}\n","/**\n * Translates @theokit/sdk SDKMessage events → TheoKit AgentStreamEvent.\n *\n * The SDK yields SDKMessage (system/assistant/tool_call/thinking/status).\n * TheoKit devtools + SSE handler expect AgentStreamEvent (run_started/text_delta/tool_call/done).\n * This module bridges the two — Adapter pattern (per sdk-integration-blueprint ADR-D2).\n */\nimport type { InteractionUpdate } from '@theokit/sdk'\n\nimport type { StreamEvent } from './agent-sse-handler.js'\n\n/** Minimal SDK message shape — duck-typed to avoid hard import of @theokit/sdk types. */\nexport interface SdkMessage {\n type: string\n [key: string]: unknown\n}\n\n/** Safely coerce unknown value to string. */\nfunction asString(value: unknown, fallback: string): string {\n if (typeof value === 'string') return value\n return fallback\n}\n\n/**\n * Serialize a tool's `result` into the `string` wire contract of ToolResultEvent.output (#41).\n * String passthrough; null/undefined → fallback; otherwise JSON (String() on throw — BigInt/circular).\n */\nfunction serializeToolOutput(value: unknown, fallback: string): string {\n if (typeof value === 'string') return value\n if (value === undefined || value === null) return fallback\n try {\n return JSON.stringify(value)\n } catch {\n // JSON.stringify throws on BigInt and circular refs. Preserve a BigInt's real value;\n // for anything non-serializable (circular object) base-to-string is uninformative, so\n // return the fallback rather than '[object Object]'.\n return typeof value === 'bigint' ? value.toString() : fallback\n }\n}\n\nfunction translateSystemEvent(msg: SdkMessage, runId: string): StreamEvent[] {\n return [\n {\n type: 'run_started',\n runId,\n agentName: asString(msg.agent_id, 'agent'),\n model: asString(msg.model, 'unknown'),\n },\n ]\n}\n\nfunction translateAssistantEvent(msg: SdkMessage): StreamEvent[] {\n const events: StreamEvent[] = []\n // Real SDKAssistantMessage (messages.ts:58): content lives at msg.message.content.\n const message = msg.message as { content?: unknown } | undefined\n const content = message?.content\n if (!Array.isArray(content)) return events\n\n for (const block of content) {\n const b = block as { type: string; text?: string; name?: string; input?: unknown; id?: string }\n if (b.type === 'text' && b.text) {\n events.push({ type: 'text_delta', content: b.text })\n }\n if (b.type === 'tool_use') {\n events.push({\n type: 'tool_call',\n callId: b.id ?? `tc-${Date.now()}`,\n toolName: b.name ?? 'unknown',\n input: b.input ?? {},\n })\n }\n }\n return events\n}\n\nfunction translateToolCallEvent(msg: SdkMessage): StreamEvent[] {\n // Real SDKToolUseMessage (messages.ts:89): call_id (not id), status running|completed|error,\n // tool output in `result` (no separate `error` field).\n const status = msg.status as string\n const callId = asString(msg.call_id, `tc-${Date.now()}`)\n const toolName = asString(msg.name, 'unknown')\n if (status === 'completed') {\n return [\n {\n type: 'tool_result',\n callId,\n toolName,\n output: serializeToolOutput(msg.result, ''),\n durationMs: 0,\n isError: false,\n },\n ]\n }\n if (status === 'error') {\n return [\n {\n type: 'tool_result',\n callId,\n toolName,\n output: serializeToolOutput(msg.result, 'Tool failed'),\n durationMs: 0,\n isError: true,\n },\n ]\n }\n if (status === 'running') {\n // #42: emit a tool_call at tool start so the UI shows the running card with its args.\n // theokit#58: the real SDKToolUseMessage carries the args in `args` (run-D22b53SU.d.ts:486;\n // live TC-DIAG confirmed `args={\"command\":…}`); `input`/`arguments` were never the SDK field\n // and resolved to `{}`, blanking the tool card. Read `args` first, keep the others as\n // defensive cross-shape fallbacks (error-handling.md).\n return [\n { type: 'tool_call', callId, toolName, input: msg.args ?? msg.input ?? msg.arguments ?? {} },\n ]\n }\n return [] // unknown status → no event\n}\n\nfunction translateStatusEvent(msg: SdkMessage): StreamEvent[] {\n // Real SDKStatusMessage (messages.ts:106): status is UPPERCASE cloud-run lifecycle;\n // error text (when present) is in `msg.message`. FINISHED/CANCELLED are terminal-clean;\n // ERROR/EXPIRED are terminal-failure (must surface — fail-loud, Unbreakable Rule 8);\n // CREATING/RUNNING are in-progress.\n const s = msg.status as string\n if (s === 'FINISHED' || s === 'CANCELLED') {\n return [\n {\n type: 'done',\n result: '',\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n durationMs: 0,\n cost: 0,\n },\n ]\n }\n if (s === 'ERROR' || s === 'EXPIRED') {\n return [\n {\n type: 'error',\n code: 'AGENT_ERROR',\n message: asString(msg.message, 'Agent error'),\n retryable: false,\n },\n ]\n }\n return []\n}\n\n/**\n * Translate a single SDK message to zero or more TheoKit stream events.\n * Returns an array because one SDK message may map to multiple TheoKit events.\n */\nexport function translateSdkEvent(msg: SdkMessage, runId: string): StreamEvent[] {\n switch (msg.type) {\n case 'system':\n return translateSystemEvent(msg, runId)\n case 'assistant':\n return translateAssistantEvent(msg)\n case 'tool_call':\n return translateToolCallEvent(msg)\n case 'thinking':\n // Real SDKThinkingMessage (messages.ts:73): reasoning text is in msg.text.\n return [{ type: 'thinking', content: asString(msg.text, '') }]\n case 'status':\n return translateStatusEvent(msg)\n default:\n return [] // Unknown message types silently ignored\n }\n}\n\n/**\n * #44 — Translate ONE real-time `onDelta` `InteractionUpdate` to zero or more StreamEvents, in\n * arrival order. This is the chronological path: routing `tool-call-started/completed` (and\n * `thinking-delta`) through `onDelta` — alongside `text-delta` — keeps tool/text/thinking\n * interleaved in true model order, instead of all-text-then-all-tools (the run.stream() buffer is\n * post-completion). Shapes per @theokit/sdk types/updates.ts: `ToolCall { callId, name, args?, result? }`.\n * `partial-tool-call` is surfaced as a DISTINCT `partial_tool_call` event (theokit-sdk#70) so\n * consumers can stream tool-input; it never duplicates `tool_call` (different lifecycle points).\n * Reuses `serializeToolOutput` for the tool-result `output` wire contract (#41 / DRY).\n */\nexport function translateInteractionUpdate(update: InteractionUpdate): StreamEvent[] {\n switch (update.type) {\n case 'text-delta':\n return update.text ? [{ type: 'text_delta', content: update.text }] : []\n case 'thinking-delta':\n return update.text ? [{ type: 'thinking', content: update.text }] : []\n case 'tool-call-started':\n return [\n {\n type: 'tool_call',\n callId: update.callId,\n toolName: update.toolCall.name,\n input: update.toolCall.args ?? {},\n },\n ]\n case 'partial-tool-call':\n // theokit-sdk#70 — surface the incremental args so consumers can stream tool-input.\n // A DISTINCT event type (not another `tool_call`): the partial fills the arg-streaming\n // window that `tool-call-started` (args committed) closes — it never duplicates `tool_call`.\n return [\n {\n type: 'partial_tool_call',\n callId: update.callId,\n toolName: update.toolCall.name,\n input: update.toolCall.args ?? {},\n },\n ]\n case 'tool-call-completed':\n return [\n {\n type: 'tool_result',\n callId: update.callId,\n toolName: update.toolCall.name,\n output: serializeToolOutput(update.toolCall.result, ''),\n durationMs: 0,\n isError: false,\n },\n ]\n default:\n return [] // thinking-completed, token-delta, step-*, etc. — not surfaced\n }\n}\n","/**\n * Model-selection mapping (M1 reasoning-visibility) — the single site that turns a\n * provider-agnostic `ReasoningEffort` into the SDK `ModelSelection`. Kept in its own small module\n * (not inside `sdk-adapter.ts`) so the adapter stays under the G6 500-LoC budget and the helper has\n * a focused home (per the plan's T1.1 \"or a small sibling\").\n */\nimport type { ModelSelection } from '@theokit/sdk'\n\nimport type { ReasoningEffort } from '../types.js'\n\n/**\n * Build the SDK `ModelSelection` for a model id + optional reasoning effort. With no (or empty)\n * effort it returns the bare `{ id }` — byte-identical to the prior behavior (backward-compat). With\n * an effort it adds the canonical reasoning param `{ id: 'thinking', value: effort }`. Pure.\n */\nexport function buildModelSelection(modelId: string, effort?: ReasoningEffort): ModelSelection {\n if (!effort) return { id: modelId }\n return { id: modelId, params: [{ id: 'thinking', value: effort }] }\n}\n","/**\n * `<think>`-tag reasoning extractor (M2 reasoning-visibility) — bridge middleware.\n *\n * Converts inline `<think>…</think>` in the assistant TEXT stream into `thinking` segments, so\n * models that emit reasoning as inline tags (qwen3-coder / deepseek-class) surface reasoning the\n * same way native-reasoning providers do (M1's `reasoningEffort`). Two exports:\n * - `createThinkTagExtractor` — the pure incremental splitter (handles a tag straddling a chunk\n * boundary); the testable core.\n * - `extractThinkTagStream` — a StreamEvent transform that applies the extractor to `text_delta`\n * events and passes every other event through unchanged (Phase 2).\n *\n * Opt-in: wired into `createSdkAgentStream` only when `parseThinkTags` is set (Phase 3) — default\n * off, because a code assistant can legitimately emit literal `<think>` in answer/code text.\n *\n * Reference patterns: Aider `reasoning_tags.py`, Vercel AI SDK `extract-reasoning-middleware.ts`\n * (blueprint `code-assistant-reasoning-ux` ADR-3).\n */\nimport type { StreamEvent } from './agent-sse-handler.js'\n\n/** The de-facto inline-reasoning tag (qwen/deepseek). Single change point if a second tag ever appears. */\nconst TAG = 'think'\nconst OPEN = `<${TAG}>`\nconst CLOSE = `</${TAG}>`\n\n/** A typed slice of the text stream: ordinary `text` vs extracted `thinking`. */\nexport interface Segment {\n kind: 'text' | 'thinking'\n content: string\n}\n\n/**\n * The length of the longest suffix of `s` that is a (proper) prefix of `delim` — i.e. how many\n * trailing chars of `s` could still grow into `delim` on the next chunk. A full match is never\n * counted here (the caller resolves full matches via `indexOf` first), so the search caps at\n * `delim.length - 1`. Returns 0 when the tail cannot extend to the delimiter (EC-1: a buffered\n * prefix like `<think` followed by `ers>` is NOT held — it is flushed as text).\n */\nfunction heldPrefixLength(s: string, delim: string): number {\n const max = Math.min(s.length, delim.length - 1)\n for (let k = max; k >= 1; k--) {\n if (s.slice(s.length - k) === delim.slice(0, k)) return k\n }\n return 0\n}\n\n/**\n * A pure, stateful, incremental `<think>` splitter. Feed it text chunks via `write`; it returns the\n * segments it can resolve so far, holding back only a tail that is still a viable prefix of the\n * active delimiter (so a tag split across two chunks is recognized). Call `end()` once the stream\n * is done to flush any buffered tail (a truncated `<think>` with no close is flushed as `thinking`,\n * so reasoning is never silently dropped).\n *\n * One instance per stream (per round); never shared — there is no cross-instance state.\n */\nexport function createThinkTagExtractor(): {\n write: (chunk: string) => Segment[]\n end: () => Segment[]\n} {\n let mode: 'text' | 'thinking' = 'text'\n let buffer = ''\n\n const write = (chunk: string): Segment[] => {\n buffer += chunk\n const out: Segment[] = []\n // Resolve every full delimiter currently in the buffer; stop when only a partial prefix remains.\n for (;;) {\n const delim = mode === 'text' ? OPEN : CLOSE\n const idx = buffer.indexOf(delim)\n if (idx !== -1) {\n const content = buffer.slice(0, idx)\n if (content) out.push({ kind: mode, content })\n buffer = buffer.slice(idx + delim.length)\n mode = mode === 'text' ? 'thinking' : 'text'\n continue\n }\n // No full delimiter: emit everything except a tail that could still become the delimiter.\n const keep = heldPrefixLength(buffer, delim)\n const emit = buffer.slice(0, buffer.length - keep)\n if (emit) out.push({ kind: mode, content: emit })\n buffer = buffer.slice(buffer.length - keep)\n break\n }\n return out\n }\n\n const end = (): Segment[] => {\n if (!buffer) return []\n const seg: Segment = { kind: mode, content: buffer }\n buffer = ''\n return [seg]\n }\n\n return { write, end }\n}\n\n/** Map an extractor segment to its StreamEvent (`thinking` segment → thinking event, else text_delta). */\nfunction segmentToEvent(seg: Segment): StreamEvent {\n return seg.kind === 'thinking'\n ? { type: 'thinking', content: seg.content }\n : { type: 'text_delta', content: seg.content }\n}\n\n/**\n * Stream transform: convert inline `<think>…</think>` carried in `text_delta` events into `thinking`\n * events, passing every other event (native `thinking`, `tool_call`, `done`, `error`, …) through\n * unchanged. A fresh extractor per call ⇒ per-stream (per-round) state; the extractor's mode persists\n * across interleaved non-text events (a reasoning block split by a tool call is not corrupted). On\n * source end, the extractor is flushed so a truncated `<think>` is still surfaced (as `thinking`).\n *\n * Non-string `text_delta.content` is passed through untouched (defensive — never throws). The\n * `end()` flush runs in a `finally`, so a buffered unclosed `<think>` is surfaced as `thinking`\n * even when the source errors mid-stream (the flushed segments are delivered before the error\n * re-propagates) — never silently dropped (Unbreakable Rule 8: fail loud, lose nothing).\n */\nexport async function* extractThinkTagStream(\n source: AsyncIterable<StreamEvent>,\n): AsyncGenerator<StreamEvent> {\n const extractor = createThinkTagExtractor()\n try {\n for await (const event of source) {\n if (event.type === 'text_delta' && typeof event.content === 'string') {\n for (const seg of extractor.write(event.content)) yield segmentToEvent(seg)\n } else {\n yield event\n }\n }\n } finally {\n for (const seg of extractor.end()) yield segmentToEvent(seg)\n }\n}\n","/**\n * Tool-dialect stripper (theocode#32) — bridge middleware.\n *\n * Neutralizes a model that leaks its Hermes tool-call dialect — `<function=NAME>…</function></tool_call>`\n * XML — into the assistant TEXT stream instead of emitting native `tool_calls` (qwen3-coder class). The\n * leaked block is STRIPPED out of the visible text; it is NEVER parsed back into a tool call (parsing a\n * provider-broken channel re-introduces the no-progress spin closed in theokit#53). Two exports:\n * - `createToolDialectStripper` — the pure incremental splitter (handles the OPEN `<function=` and the\n * CLOSE `</tool_call>` each straddling a chunk boundary); the testable core.\n * - `stripToolDialectStream` — a StreamEvent transform that applies the stripper to `text_delta` events\n * and passes every other event through unchanged.\n *\n * Opt-in: wired into `createSdkAgentStream` only when `stripToolDialect` is set — default off, because a\n * code assistant can legitimately emit a literal `<function=` substring in answer/code text.\n *\n * Sibling of `think-tag-extractor.ts` (same incremental-splitter shape): the only deltas are the\n * delimiter (a two-string OPEN…CLOSE pair, not a single `<think>` tag) and the disposition of matched\n * content (dropped, not re-routed to a `thinking` segment).\n *\n * Accepted best-effort limit (EC-5): if a leaked block's parameter value contains the literal substring\n * `</tool_call>`, the scanner closes at that inner occurrence and the trailing real `</function></tool_call>`\n * re-emits as text. This errs toward showing MORE text (never silently drops), matching the lossless\n * contract — same class as the think-tag scanner being fooled by `<thinkers>`-shaped content. Pinned by\n * `tool-dialect-stripper.test.ts:test_stripper_embedded_close_early_closes_then_text`.\n */\nimport type { StreamEvent } from './agent-sse-handler.js'\n\n/** The Hermes leak's open marker. Single change-point if a second tool-dialect opener ever appears. */\nconst OPEN = '<function='\n/** The Hermes leak's close marker — the whole `<function=…>` block is dropped up to and including this. */\nconst CLOSE = '</tool_call>'\n\n/** A typed slice of the surviving (non-leaked) text stream. Dropped leak content yields no segment. */\nexport interface Segment {\n kind: 'text'\n content: string\n}\n\n/**\n * The length of the longest suffix of `s` that is a (proper) prefix of `delim` — i.e. how many trailing\n * chars of `s` could still grow into `delim` on the next chunk. A full match is resolved by `indexOf`\n * first, so the search caps at `delim.length - 1`. Returns 0 when the tail cannot extend to the delimiter.\n */\nfunction heldPrefixLength(s: string, delim: string): number {\n const max = Math.min(s.length, delim.length - 1)\n for (let k = max; k >= 1; k--) {\n if (s.slice(s.length - k) === delim.slice(0, k)) return k\n }\n return 0\n}\n\n/**\n * A pure, stateful, incremental tool-dialect splitter. Feed it text chunks via `write`; it returns the\n * surviving text segments, dropping any resolved `<function=…></tool_call>` block and holding back only a\n * tail that is still a viable prefix of the active delimiter (so a delimiter split across two chunks is\n * recognized). Call `end()` once the stream is done: an UNCLOSED leak (saw `<function=`, never saw\n * `</tool_call>`) is flushed as text — lossless, never silently dropped (Unbreakable Rule 8).\n *\n * One instance per stream (per run); never shared — there is no cross-instance state.\n */\nexport function createToolDialectStripper(): {\n write: (chunk: string) => Segment[]\n end: () => Segment[]\n} {\n let mode: 'text' | 'stripping' = 'text'\n let buffer = ''\n // Accumulates the dropped-so-far leak content (including the OPEN marker) so an unclosed leak can be\n // flushed losslessly on end(). Reset to '' the moment a full OPEN…CLOSE pair resolves.\n let pendingLeak = ''\n\n const write = (chunk: string): Segment[] => {\n buffer += chunk\n const out: Segment[] = []\n for (;;) {\n if (mode === 'text') {\n const idx = buffer.indexOf(OPEN)\n if (idx !== -1) {\n const content = buffer.slice(0, idx)\n if (content) out.push({ kind: 'text', content })\n pendingLeak = OPEN\n buffer = buffer.slice(idx + OPEN.length)\n mode = 'stripping'\n continue\n }\n const keep = heldPrefixLength(buffer, OPEN)\n const emit = buffer.slice(0, buffer.length - keep)\n if (emit) out.push({ kind: 'text', content: emit })\n buffer = buffer.slice(buffer.length - keep)\n break\n }\n // stripping: scan for CLOSE, dropping everything in between (accumulated into pendingLeak).\n const idx = buffer.indexOf(CLOSE)\n if (idx !== -1) {\n buffer = buffer.slice(idx + CLOSE.length)\n pendingLeak = ''\n mode = 'text'\n continue\n }\n const keep = heldPrefixLength(buffer, CLOSE)\n pendingLeak += buffer.slice(0, buffer.length - keep)\n buffer = buffer.slice(buffer.length - keep)\n break\n }\n return out\n }\n\n const end = (): Segment[] => {\n // Lossless: an unclosed leak (still in stripping mode) flushes pendingLeak + the held CLOSE-prefix\n // as text; a held OPEN-prefix in text mode flushes as text. Never silently drop unconfirmed content.\n const leftover = mode === 'stripping' ? pendingLeak + buffer : buffer\n buffer = ''\n pendingLeak = ''\n return leftover ? [{ kind: 'text', content: leftover }] : []\n }\n\n return { write, end }\n}\n\n/**\n * Stream transform: strip a leaked `<function=…></tool_call>` Hermes tool-call dialect out of `text_delta`\n * events, passing every other event (native `thinking`, `tool_call`, `done`, `error`, `status`, …) through\n * unchanged. A fresh stripper per call ⇒ per-stream (per-round) state; the stripper's mode persists across\n * interleaved non-text events. Non-string `text_delta.content` is passed through untouched (defensive —\n * never coerced). The `end()` flush runs in a `finally`, so a buffered unclosed leak is surfaced as text\n * even when the source errors mid-stream (delivered before the error re-propagates) — Rule 8: lose nothing.\n */\nexport async function* stripToolDialectStream(\n source: AsyncIterable<StreamEvent>,\n): AsyncGenerator<StreamEvent> {\n const stripper = createToolDialectStripper()\n try {\n for await (const event of source) {\n if (event.type === 'text_delta' && typeof event.content === 'string') {\n for (const seg of stripper.write(event.content)) {\n yield { type: 'text_delta', content: seg.content }\n }\n } else {\n yield event\n }\n }\n } finally {\n for (const seg of stripper.end()) {\n yield { type: 'text_delta', content: seg.content }\n }\n }\n}\n","/**\n * SDK Adapter — bridges @theokit/agents decorators → @theokit/sdk runtime.\n *\n * Per rule sdk-runtime.md (INQUEBRÁVEL): @theokit/sdk is the ONLY agent runtime.\n * This adapter replaces llm-runner.ts (which called OpenRouter API directly).\n *\n * Flow: @Agent decorator → compileAgent() → createSdkAgentStream() → SDK Agent.create() → Run.stream()\n */\nimport type {\n AgentDefinition,\n BudgetTracker,\n ContextSettings,\n ConversationStorageAdapter,\n CustomTool,\n InteractionUpdate,\n Plugin,\n PluginsSettings,\n ProviderRoutingSettings,\n SkillsSettings,\n SystemPromptResolver,\n} from '@theokit/sdk'\n\nimport type { ReasoningEffort } from '../types.js'\n\nimport type { CompiledAgentOptions, CompiledTool } from './agent-compiler.js'\nimport type { StreamEvent } from './agent-sse-handler.js'\nimport { compileProjectContext } from './compile-project-context.js'\nimport {\n translateInteractionUpdate,\n translateSdkEvent,\n type SdkMessage,\n} from './event-translator.js'\nimport { buildModelSelection } from './model-selection.js'\nimport { extractThinkTagStream } from './think-tag-extractor.js'\nimport { stripToolDialectStream } from './tool-dialect-stripper.js'\n\n/** Extra `Agent.create()` options compiled from the M8 declarative decorators. */\ninterface M8CreateOptions {\n skills?: SkillsSettings\n context?: ContextSettings\n systemPrompt?: string | SystemPromptResolver\n /** SDK local options: settings source for SKILL.md discovery (EC-1) + per-run cwd (V4-L.2). */\n local?: { settingSources?: string[]; cwd?: string }\n}\n\n/**\n * Project the M8 fields from `CompiledAgentOptions` (the single compile site is\n * `agent-compiler.ts`, per sdk-runtime.md) into `Agent.create()` arguments. Only\n * the async `@ProjectContext` resolver is built here (it does I/O, so the compiler\n * keeps it raw). `applied` lists which decorators contributed, for the\n * observability log (wiring triad — runtime metric).\n */\nfunction assembleM8CreateOptions(compiled: CompiledAgentOptions): {\n options: M8CreateOptions\n applied: string[]\n} {\n const options: M8CreateOptions = {}\n const applied: string[] = []\n const base = compiled.systemPrompt\n\n if (compiled.skills) {\n options.skills = compiled.skills\n options.local = { settingSources: ['project'] }\n applied.push('skills')\n }\n if (compiled.context) {\n options.context = compiled.context\n applied.push('context')\n }\n if (compiled.projectContext) {\n options.systemPrompt = compileProjectContext(compiled.projectContext, base)\n applied.push('projectContext')\n } else if (base !== undefined) {\n options.systemPrompt = base\n }\n\n return { options, applied }\n}\n\n/**\n * Per-request overrides forwarded into `Agent.create` (V4-L.2 + V4-L.3). Bundled into\n * one object (rather than positional params) so the per-request surface can grow without\n * a parameter explosion. Each field is Axis-A SWAP — a value the app holds at call time.\n */\nexport interface RuntimeOverrides {\n /** Overrides the model for this call (`?? compiled.model ?? default`). */\n model?: string\n /**\n * Per-run extended-thinking effort (`?? compiled.reasoningEffort`). Mapped to the SDK\n * `ModelSelection.params` so the provider produces reasoning (surfaced as `thinking` StreamEvents).\n */\n reasoningEffort?: ReasoningEffort\n /**\n * Per-run opt-in (`?? compiled.parseThinkTags`): when true, wrap the event stream with the M2\n * `<think>`-tag extractor so inline `<think>…</think>` text becomes `thinking` StreamEvents.\n */\n parseThinkTags?: boolean\n /**\n * Per-run opt-in (`?? compiled.stripToolDialect`): when true, strip a leaked Hermes\n * `<function=…></tool_call>` tool-call dialect out of the assistant text stream (theocode#32).\n */\n stripToolDialect?: boolean\n /**\n * Per-run opt-in (`?? compiled.recoverLeakedToolCalls`): when true, enable the SDK chat route's\n * `extractToolCallsFromContent` so a leaked Hermes `<function=…></tool_call>` dialect is recovered\n * and EXECUTED (theokit#58). Sibling of {@link stripToolDialect}; has effect only when {@link providers}\n * routes a provider.\n */\n recoverLeakedToolCalls?: boolean\n /** Per-run cwd → `Agent.create({ local: { cwd } })` → `SystemPromptContext.cwd`. */\n cwd?: string\n /**\n * Per-run plugins (e.g. permission gate selected by request mode). Accepts EITHER\n * named-plugin discovery settings (`{ enabled: [...] }`) OR an array of code `Plugin`\n * objects, forwarded RAW through the duck-typed `Agent.create` bridge (mirrors the\n * @theokit/sdk `AgentOptions.plugins` widen).\n */\n plugins?: PluginsSettings | readonly Plugin[]\n /** Per-run provider routing. */\n providers?: ProviderRoutingSettings\n /** Per-run sub-agent definitions (opts-only; `compiled.agents` stays deferred — ADR D3). */\n agents?: Record<string, AgentDefinition>\n /** Per-run SDK budget tracker (inner tool-loop cap; distinct from the loop's USD `budget`). */\n budgetTracker?: BudgetTracker\n /**\n * V4-M: conversation store shared across the loop's rounds so history persists\n * (round N+1 sees rounds 1..N). Default `InMemoryConversationStorage` (per-run,\n * no disk). Pass a `FileSystemConversationStorage`/custom adapter for durable history.\n */\n conversationStorage?: ConversationStorageAdapter\n /**\n * V4-Q: pre-built SDK `CustomTool[]` forwarded RAW to `Agent.create.tools` (appended after the\n * compiled tools), bypassing `defineTool` (which requires a Zod schema). Lets an app whose tools\n * come from imperative SDK factories supply them without the `@Tool` compile path.\n */\n sdkTools?: readonly CustomTool[]\n}\n\n/**\n * V4-N.1: build the terminal `done` event from the SDK `RunResult` (real per-run token usage +\n * cost). Extracted from the stream generator to keep its complexity within budget (G6).\n */\nfunction realUsageDone(\n result: {\n result?: string\n usage?: {\n inputTokens?: number\n outputTokens?: number\n // V4-O: optional reasoning/cache buckets from the SDK TokenUsage.\n reasoningTokens?: number\n cacheReadTokens?: number\n cacheWriteTokens?: number\n }\n cost?: { amount?: number }\n },\n t0: number,\n): StreamEvent {\n const u = result.usage\n const inputTokens = u?.inputTokens ?? 0\n const outputTokens = u?.outputTokens ?? 0\n return {\n type: 'done',\n result: result.result ?? '',\n // V4-O: forward the SDK reasoning/cache buckets (0 when the provider omits them) so a\n // consumer keeps full per-turn usage through the loop into DelegationResult (passthrough — ADR D1).\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: u?.reasoningTokens ?? 0,\n cacheReadTokens: u?.cacheReadTokens ?? 0,\n cacheWriteTokens: u?.cacheWriteTokens ?? 0,\n },\n durationMs: Date.now() - t0,\n cost: result.cost?.amount ?? 0,\n }\n}\n\n/**\n * theokit#58: clone provider routing with `extractToolCallsFromContent` enabled on every route, so the\n * SDK recovers a leaked Hermes `<function=…></tool_call>` dialect that would otherwise be lost. The SDK\n * reads the flag off the chat route (routes[0]); marking all routes is fail-open — a non-leaking route\n * is unaffected (recovery only fires on a finish with ZERO native tool_calls carrying the dialect).\n */\nfunction withLeakedDialectRecovery(providers: ProviderRoutingSettings): ProviderRoutingSettings {\n return {\n ...providers,\n routes: providers.routes.map((route) => ({ ...route, extractToolCallsFromContent: true })),\n }\n}\n\n/**\n * Project the V4-L.3 per-request fields into the `Agent.create` extra surface (absent ⇒ no\n * key). Extracted from the stream generator to keep its cyclomatic complexity within budget (G6).\n * theokit#58: per-run `recoverLeakedToolCalls` (overrides compiled) opts the routed provider into\n * SDK leaked-dialect recovery by cloning the routes with `extractToolCallsFromContent`.\n */\nfunction buildExtraCreateOptions(\n overrides: RuntimeOverrides,\n compiled: CompiledAgentOptions,\n): Record<string, unknown> {\n const recoverLeakedToolCalls =\n overrides.recoverLeakedToolCalls ?? compiled.recoverLeakedToolCalls ?? false\n const extra: Record<string, unknown> = {}\n if (overrides.plugins !== undefined) extra.plugins = overrides.plugins\n if (overrides.providers !== undefined) {\n extra.providers = recoverLeakedToolCalls\n ? withLeakedDialectRecovery(overrides.providers)\n : overrides.providers\n }\n if (overrides.agents !== undefined) extra.agents = overrides.agents\n if (overrides.budgetTracker !== undefined) extra.budgetTracker = overrides.budgetTracker\n return extra\n}\n\n/** #40: tagged item flowing through the merge queue — an incremental delta or a complete SDK message. */\ntype MergeItem = { kind: 'delta'; event: StreamEvent } | { kind: 'sdk'; msg: SdkMessage }\n\n/** Minimal single-producer/single-consumer async queue (#40 — merge onDelta tokens with run.stream()). */\ninterface AsyncQueue<T> {\n push: (item: T) => void\n close: () => void\n [Symbol.asyncIterator]: () => AsyncIterator<T>\n}\n\nfunction createAsyncQueue<T>(): AsyncQueue<T> {\n const items: T[] = []\n let wake: (() => void) | null = null\n let closed = false\n return {\n push(item: T) {\n items.push(item)\n if (wake) {\n wake()\n wake = null\n }\n },\n close() {\n closed = true\n if (wake) {\n wake()\n wake = null\n }\n },\n async *[Symbol.asyncIterator]() {\n for (;;) {\n while (items.length > 0) {\n const next = items.shift()\n if (next !== undefined) yield next\n }\n if (closed) return\n await new Promise<void>((resolve) => {\n wake = resolve\n })\n }\n },\n }\n}\n\n/**\n * #44 dedup state — text/thinking by category flag (no per-event id); tool by callId Set, so a\n * `run.stream()` tool result whose callId onDelta only reported as `tool-call-started` (e.g. a tool\n * ERROR surfaced only via the stream) is NOT suppressed. `sawError` short-circuits the real-usage done.\n */\ninterface MergeState {\n sawTextDelta: boolean\n sawThinkingDelta: boolean\n emittedToolCallIds: Set<string>\n emittedToolResultIds: Set<string>\n sawError: boolean\n}\n\n/** Read a StreamEvent's `callId` as a string (the union is index-typed `unknown`). */\nfunction streamCallId(ev: StreamEvent): string {\n return typeof ev.callId === 'string' ? ev.callId : ''\n}\n\n/**\n * #44 — skip a run.stream() content event ONLY when onDelta already drove that exact (category, id).\n * Tool dedup is keyed by callId; an empty/missing callId never matches (returns false) so two distinct\n * id-less tool events cannot collide and wrongly suppress each other (favours a visible double-emit\n * over silent loss — fail-loud).\n */\nfunction isDuplicatedByDelta(ev: StreamEvent, state: MergeState): boolean {\n if (ev.type === 'text_delta') return state.sawTextDelta\n if (ev.type === 'thinking') return state.sawThinkingDelta\n if (ev.type === 'tool_call') {\n const id = streamCallId(ev)\n return id !== '' && state.emittedToolCallIds.has(id)\n }\n if (ev.type === 'tool_result') {\n const id = streamCallId(ev)\n return id !== '' && state.emittedToolResultIds.has(id)\n }\n return false\n}\n\n/**\n * #44: merge real-time content events (queued via onDelta — text/tool/thinking in chronological\n * arrival order) with the complete SDK messages from `run.stream()`. Deltas are yielded as they\n * arrive; the pump opens `run.stream()` (post-completion) for structural events (`run_started`/`done`)\n * + the no-onDelta fallback, deduped per-category (`isDuplicatedByDelta`) so nothing double-emits.\n * The `done` SDK event stays suppressed (real-usage `done` emitted by the caller after `run.wait()`);\n * errors set `state.sawError`. `openStream` is a thunk so the consumer drains CONCURRENTLY with\n * `send()` (the run only resolves after the loop completes). Extracted to keep the generator within G6.\n */\nasync function* mergeDeltaStream(\n queue: AsyncQueue<MergeItem>,\n openStream: () => Promise<AsyncGenerator<SdkMessage>>,\n runId: string,\n state: MergeState,\n): AsyncGenerator<StreamEvent> {\n // The catch is attached AT CREATION (not deferred to `await pump`): the consumer loop below is\n // paced by the external puller (SSE backpressure), so a send()/stream() rejection could otherwise\n // sit unhandled across macrotask gaps and crash the process (Node unhandledRejection). The captured\n // error is re-thrown after the drain so it still surfaces in the caller's try/catch as one error event.\n let pumpError: { thrown: unknown } | undefined\n const pump = (async () => {\n try {\n const stream = await openStream()\n for await (const msg of stream) queue.push({ kind: 'sdk', msg })\n } finally {\n queue.close()\n }\n })().catch((thrown: unknown) => {\n pumpError = { thrown }\n })\n for await (const item of queue) {\n if (item.kind === 'delta') {\n yield item.event\n continue\n }\n for (const out of translateSdkEvent(item.msg, runId)) {\n if (out.type === 'done') continue // suppressed; the real-usage done is emitted by the caller\n if (isDuplicatedByDelta(out, state)) continue // #44 per-category/callId dedup vs onDelta\n if (out.type === 'error') state.sawError = true\n yield out\n }\n }\n await pump // settled (handled at creation); re-throw any captured error into the generator's try/catch\n if (pumpError) throw pumpError.thrown\n}\n\n/**\n * #44 — build the onDelta sink: a fresh per-run dedup `MergeState` + the callback that routes every\n * content update (text/tool/thinking) into the merge queue in chronological arrival order, recording\n * per-category flags + per-callId Sets so the run.stream() fallback is deduped without losing\n * stream-only tool results. Extracted to keep `createSdkAgentStream` within the function-size budget.\n */\nfunction createDeltaSink(queue: AsyncQueue<MergeItem>): {\n state: MergeState\n onDelta: (d: { update: InteractionUpdate }) => void\n} {\n const state: MergeState = {\n sawTextDelta: false,\n sawThinkingDelta: false,\n emittedToolCallIds: new Set<string>(),\n emittedToolResultIds: new Set<string>(),\n sawError: false,\n }\n const onDelta = (d: { update: InteractionUpdate }) => {\n for (const event of translateInteractionUpdate(d.update)) {\n if (event.type === 'text_delta') state.sawTextDelta = true\n else if (event.type === 'thinking') state.sawThinkingDelta = true\n else if (event.type === 'tool_call') {\n const id = streamCallId(event)\n if (id !== '') state.emittedToolCallIds.add(id)\n } else if (event.type === 'tool_result') {\n const id = streamCallId(event)\n if (id !== '') state.emittedToolResultIds.add(id)\n }\n queue.push({ kind: 'delta', event })\n }\n }\n return { state, onDelta }\n}\n\n/**\n * Resolve the per-run opt-in text-transform flags, each `override ?? compiled ?? false` (mirrors `model`).\n */\nfunction resolveTextTransformFlags(\n compiled: CompiledAgentOptions,\n overrides: RuntimeOverrides,\n): { parseThinkTags: boolean; stripToolDialect: boolean } {\n return {\n parseThinkTags: overrides.parseThinkTags ?? compiled.parseThinkTags ?? false,\n stripToolDialect: overrides.stripToolDialect ?? compiled.stripToolDialect ?? false,\n }\n}\n\n/**\n * Compose the opt-in text-stream transforms over the merged event stream, in fixed order:\n * `<think>`-tag extraction (M2) first, then tool-dialect stripping (theocode#32) on the post-think\n * `text_delta`. Both default off ⇒ the merged stream is returned unchanged (byte-identical).\n */\nfunction applyTextTransforms(\n events: AsyncIterable<StreamEvent>,\n opts: { parseThinkTags: boolean; stripToolDialect: boolean },\n): AsyncIterable<StreamEvent> {\n let out = opts.parseThinkTags ? extractThinkTagStream(events) : events\n if (opts.stripToolDialect) out = stripToolDialectStream(out)\n return out\n}\n\n/**\n * Build the SDK tool list: compiled `@Tool`s lowered via `defineTool`, then any pre-built SDK\n * `CustomTool[]` appended RAW (V4-Q — already defined, must NOT re-run through `defineTool`).\n * Extracted from the stream generator to keep its function-size within budget (G6).\n */\nfunction buildSdkTools(\n compiledTools: CompiledTool[],\n defineTool: (spec: {\n name: string\n description: string\n inputSchema: unknown\n handler: (input: unknown) => string | Promise<string>\n }) => unknown,\n extraSdkTools: readonly CustomTool[] = [],\n): unknown[] {\n return [\n ...compiledTools.map((t) =>\n defineTool({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n handler: t.handler,\n }),\n ),\n ...extraSdkTools,\n ]\n}\n\n/**\n * Creates an agent stream factory using @theokit/sdk as the runtime.\n *\n * Returns a function that, given a message + sessionId, yields TheoKit\n * AgentStreamEvent via the SDK's Agent.create() + Run.stream() pipeline.\n */\nexport function createSdkAgentStream(\n compiled: CompiledAgentOptions,\n compiledTools: CompiledTool[],\n apiKey: string,\n overrides: RuntimeOverrides = {},\n) {\n const model = overrides.model ?? compiled.model ?? 'openai/gpt-4o-mini'\n // M1 reasoning-visibility: per-run effort overrides the compiled @Agent effort (mirrors `model`).\n const reasoningEffort = overrides.reasoningEffort ?? compiled.reasoningEffort\n // Per-run opt-in text-stream transforms (each overrides the compiled @Agent flag, mirrors `model`):\n // parseThinkTags (M2, <think> extraction), stripToolDialect (theocode#32, leaked-dialect strip).\n const { parseThinkTags, stripToolDialect } = resolveTextTransformFlags(compiled, overrides)\n // V4-M: ONE conversation store shared across the loop's rounds (closure-scoped per run)\n // so history persists across the per-round agent create/dispose. Defaults lazily to the\n // SDK's in-memory store (no disk) after the dynamic import; an app override wins.\n let storage: ConversationStorageAdapter | undefined = overrides.conversationStorage\n\n // `factoryOpts.disableTools` (step-cap force-close) → `tool_choice:\"none\"` at send-time.\n return (\n message: string,\n sessionId: string,\n factoryOpts?: { disableTools?: boolean },\n ): AsyncIterable<StreamEvent> => ({\n async *[Symbol.asyncIterator]() {\n const runId = `run-${Date.now()}`\n const t0 = Date.now()\n\n // Dynamic import — @theokit/sdk is optional peer dep\n let Agent: {\n getOrCreate: (\n id: string,\n opts: Record<string, unknown>,\n ) => Promise<{\n // #40: the SDK token-streams ONLY via send's onDelta callback (proven empirically);\n // run.stream() yields complete messages. The adapter merges both.\n send: (\n msg: string,\n // onDelta receives `{ update: InteractionUpdate }`; toolChoice gates tools for this send.\n opts?: {\n onDelta?: (d: { update: InteractionUpdate }) => void\n toolChoice?: 'auto' | 'none' | 'required'\n },\n ) => Promise<{\n stream: () => AsyncGenerator<SdkMessage>\n // V4-N.1: the SDK Run's terminal await — carries the real per-run token usage + cost.\n // V4-O: usage also carries optional reasoning/cache buckets (forwarded by realUsageDone).\n wait: () => Promise<{\n result?: string\n usage?: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: number\n cacheReadTokens?: number\n cacheWriteTokens?: number\n }\n cost?: { amount?: number }\n }>\n }>\n dispose: () => Promise<void>\n }>\n }\n let defineTool: (spec: {\n name: string\n description: string\n inputSchema: unknown\n handler: (input: unknown) => string | Promise<string>\n }) => unknown\n let InMemoryConversationStorage: new () => ConversationStorageAdapter\n\n try {\n const sdk = await import('@theokit/sdk')\n Agent = sdk.Agent\n defineTool = sdk.defineTool as typeof defineTool\n InMemoryConversationStorage = sdk.InMemoryConversationStorage\n } catch {\n yield {\n type: 'error',\n code: 'SDK_NOT_INSTALLED',\n message: 'Install @theokit/sdk: pnpm add @theokit/sdk',\n retryable: false,\n }\n return\n }\n\n const sdkTools = buildSdkTools(compiledTools, defineTool, overrides.sdkTools)\n\n // V4-N.1: declared outside the try so `finally` can dispose even when `run.wait()` rejects.\n let agent: Awaited<ReturnType<typeof Agent.getOrCreate>> | undefined\n try {\n // Project the compiled M8 decorator fields into native Agent.create args.\n const { options: m8, applied } = assembleM8CreateOptions(compiled)\n // V4-L.2: merge the per-run cwd into local (preserving any settingSources).\n if (overrides.cwd !== undefined) m8.local = { ...m8.local, cwd: overrides.cwd }\n // V4-L.3: forward the remaining per-request Agent.create surface (absent ⇒ no key).\n const extra = buildExtraCreateOptions(overrides, compiled)\n // V4-M: the shared store is the cross-round memory (survives per-round dispose).\n storage ??= new InMemoryConversationStorage()\n if (applied.length > 0) {\n // Wiring triad — runtime metric: observable proof the decorators fired.\n console.debug('[THEO_AGENT_M8_RUNTIME_APPLIED]', {\n skills: applied.includes('skills'),\n context: applied.includes('context'),\n projectContext: applied.includes('projectContext'),\n })\n }\n\n // V4-M: getOrCreate(sessionId) resumes the shared session so this round sees prior\n // rounds (M8 fields + per-request extra spread; absent ⇒ no key).\n agent = await Agent.getOrCreate(sessionId, {\n apiKey,\n model: buildModelSelection(model, reasoningEffort),\n tools: sdkTools,\n ...m8,\n ...extra,\n conversationStorage: storage,\n })\n\n // #44: token streaming in CHRONOLOGICAL ORDER. The SDK streams ALL content updates\n // (text/tool/thinking) in real time via send's onDelta; run.stream() replays the complete\n // messages post-completion. Route every content update through onDelta in arrival order so\n // the merge queue records them interleaved (not all-text-then-all-tools), and consume the\n // queue CONCURRENTLY with send (the run only resolves after the loop). run.stream() supplies\n // structural events + the no-onDelta fallback, deduped per-category/callId (isDuplicatedByDelta).\n const queue = createAsyncQueue<MergeItem>()\n const { state, onDelta } = createDeltaSink(queue)\n // Do NOT await send() before draining — onDelta fills the queue in real time during the run;\n // the consumer yields concurrently. openStream awaits the resolved Run for its post-completion\n // run.stream(). On send() rejection, openStream throws → pump closes the queue → the awaited\n // pump re-throws into the outer catch (error event) after any queued deltas have drained.\n // Step-cap force-close: a ceiling round passes `disableTools` → `tool_choice:\"none\"` for this send.\n const sendPromise = agent.send(\n message,\n factoryOpts?.disableTools === true ? { onDelta, toolChoice: 'none' } : { onDelta },\n )\n const openStream = async () => (await sendPromise).stream()\n\n // Opt-in text-stream transforms (parseThinkTags / stripToolDialect). Both off ⇒ the merged\n // stream is yielded unchanged (byte-identical) — see applyTextTransforms.\n const merged = mergeDeltaStream(queue, openStream, runId, state)\n for await (const event of applyTextTransforms(merged, {\n parseThinkTags,\n stripToolDialect,\n })) {\n yield event\n }\n\n // V4-N.1: the stream's `done` carries zero usage; it is suppressed in mergeDeltaStream and\n // ONE real-usage `done` is emitted after `run.wait()` (SDK RunResult.usage + cost). Errors\n // short-circuit it. Exactly-one-terminal on a clean run.\n if (!state.sawError) {\n yield realUsageDone(await (await sendPromise).wait(), t0)\n }\n } catch (err) {\n yield {\n type: 'error',\n code: 'SDK_ERROR',\n message: err instanceof Error ? err.message : 'SDK agent error',\n retryable: false,\n }\n } finally {\n // V4-N.1: always dispose — covers the new `run.wait()` reject path (LOW-1).\n await agent?.dispose()\n }\n },\n })\n}\n","import type { UIMessageChunk } from 'ai'\n\nimport type { AgentStreamEvent } from './agent-stream-events.js'\n\n/**\n * M0 (theokit-ai-first) — translate a theokit `AgentStreamEvent` stream into the\n * Vercel ai-sdk `UIMessageStream` protocol, TEXT ONLY.\n *\n * This is a PURE mapping (D1): it consumes the ALREADY-deduped bridge event\n * stream (downstream of `mergeDeltaStream`) and yields `UIMessageChunk`s. It\n * NEVER calls an LLM and does NOT re-run the agent loop (sdk-runtime.md / G2) —\n * `@theokit/sdk` remains the only runtime.\n *\n * Chunk sequence for a text run:\n *\n * start → text-start{id} → text-delta{id,delta}* → text-end{id} → finish\n *\n * Invariants:\n * - Exactly one `start` and one `finish` per run.\n * - `text-end` is emitted ONLY if a `text-start` was emitted (no orphan close).\n * - A single shared `id` (`opts.textId`) for the whole text block — injected for\n * deterministic tests (D3).\n * - Every emitted chunk carries ONLY the fields required by ai-sdk's\n * `uiMessageChunkSchema` (a z.strictObject union — extra keys are rejected).\n *\n * Error handling (error-handling.md — fail-clear, surface don't swallow, never\n * throw past the boundary): an `error` event OR a thrown/aborted underlying\n * iterable is SURFACED as an ai-sdk `error` chunk (`{ type: 'error', errorText }`),\n * then closes an open text (`text-end`) and terminates with `finish`. The error is\n * not re-thrown — the transport still produces a well-formed, terminated stream the\n * client can render as a failed turn.\n *\n * Tool / reasoning / file chunks are intentionally out of scope for M0 (YAGNI);\n * non-text events are ignored here and widen the mapping in M1.\n */\nexport async function* translateToUIMessageStream(\n events: AsyncIterable<AgentStreamEvent>,\n opts: { textId: string },\n): AsyncGenerator<UIMessageChunk, void, unknown> {\n yield { type: 'start' }\n let textOpen = false\n try {\n for await (const event of events) {\n if (event.type === 'text_delta') {\n if (!textOpen) {\n yield { type: 'text-start', id: opts.textId }\n textOpen = true\n }\n yield { type: 'text-delta', id: opts.textId, delta: event.content }\n } else if (event.type === 'error') {\n // Surface the agent-reported failure to the client as an ai-sdk error\n // chunk instead of silently swallowing it, then close gracefully.\n yield { type: 'error', errorText: event.message }\n break\n }\n // Non-text events (run_started, done, tool_*, thinking, …) produce no\n // text chunk in M0. `done`/end-of-stream close naturally below.\n }\n } catch (err) {\n // The underlying stream aborted/errored. Surface the failure as an error\n // chunk (structured, not console noise), then fall through to a graceful\n // close — never throw past the transport.\n yield { type: 'error', errorText: String(err) }\n }\n if (textOpen) {\n yield { type: 'text-end', id: opts.textId }\n }\n yield { type: 'finish' }\n}\n","/**\n * TranscriptCompactionStrategy — a named, callable transcript-compaction authoring layer\n * (Strategy pattern, V4-F). Mirrors `ReflectionStrategy`/`LoopStrategy`: interface\n * + zod config schema + a `'token-budget'` default + `resolveCompactionStrategy`.\n *\n * The `'token-budget'` strategy DELEGATES to the SDK's `compactTranscript` (ADR D2 /\n * G2 / sdk-runtime.md — the SDK owns the algorithm; agents owns the named interface;\n * no reimplementation). Per ADR D1 it is CALLABLE by the app (exposed as\n * `AgentRunner.compaction`), NOT auto-invoked by the reflective loop — the SDK owns\n * per-turn context, so the app decides WHEN to compact and supplies the `summarize`\n * callback (its own LLM). EC-6: consumers whose transcript rows carry roles outside\n * the SDK's `CompressibleMessage` union (e.g. `'tool'`) cast at the call site, exactly\n * as the SDK's own type contract requires.\n *\n * referencia: knowledge-base/references/mastra compaction (named strategy over a budget).\n */\nimport { compactTranscript, type CompressibleMessage } from '@theokit/sdk/compaction'\nimport { z } from 'zod'\n\nexport type { CompressibleMessage }\n\n/** Token budget mirrored from theocode's proven `DEFAULT_KEEP_TOKENS` (server/lib/compaction.ts). */\nexport const DEFAULT_KEEP_TOKENS = 8000\n\n/**\n * App-supplied summarizer: collapse the older window into one turn (the app's LLM).\n * Signature matches the SDK `compactTranscript` contract — receives the older window\n * AND the (optionally overridden) summary template.\n */\nexport type Summarize = (\n older: CompressibleMessage[],\n template: string,\n) => Promise<CompressibleMessage>\n\n/**\n * Per-call options for {@link TranscriptCompactionStrategy.compact} — a faithful\n * pass-through of the SDK `CompactTranscriptOptions` knobs the app controls. Defaults\n * are the SDK's, EXCEPT `failSafe` which defaults `true` here: a thrown `summarize`\n * returns the ORIGINAL transcript + a structured warn instead of losing it — compaction\n * is an optimization, never a cause of data loss (error-handling discipline). The app\n * passes `failSafe: false` to opt into fail-fast propagation.\n */\nexport interface CompactionCallOptions {\n /** Override the strategy's configured `keepTokens` for this call. */\n readonly keepTokens?: number\n /** Summarize the older window; if omitted, the SDK drops it (its documented contract). */\n readonly summarize?: Summarize\n /** Checkpoint marker (SDK default when omitted). */\n readonly marker?: string\n /** Summary template passed to `summarize` (SDK default when omitted). */\n readonly summaryTemplate?: string\n /** When true (DEFAULT here), a thrown `summarize` returns the original transcript + a warn. */\n readonly failSafe?: boolean\n}\n\n/** A named, callable compaction strategy. Pure of I/O except the delegated SDK call. */\nexport interface TranscriptCompactionStrategy {\n /** Strategy identifier (e.g. `'token-budget'`). */\n readonly name: string\n /** The configured token budget (from `@Compaction` / `.compaction()` / default). */\n readonly keepTokens: number\n /**\n * Compact `messages` to the (optionally overridden) token budget via the SDK's\n * `compactTranscript`. Returns the compacted transcript; never mutates the input.\n */\n compact(\n messages: CompressibleMessage[],\n options?: CompactionCallOptions,\n ): Promise<CompressibleMessage[]>\n}\n\n/**\n * Serializable config for a TranscriptCompactionStrategy (SSoT per type-safety.md / G3).\n * `keepTokens` is REQUIRED for `'token-budget'` (EC-2 / G10 — no silent degradation\n * to the SDK's turn-count `keepRecent` default; the strategy is named for token budget).\n */\nexport const compactionStrategyConfigSchema = z.object({\n name: z.literal('token-budget'),\n keepTokens: z.number().int().positive(),\n})\n\nexport type CompactionStrategyConfig = z.infer<typeof compactionStrategyConfigSchema>\n\n/**\n * Resolve a `@Compaction` / `.compaction()` declaration to a concrete strategy.\n * Throws (Zod) on an unknown name or a missing/invalid `keepTokens` (EC-2/EC-5 —\n * fail-fast, mirrors `resolveLoopStrategy`). The returned strategy's `compact`\n * delegates to `compactTranscript`, defaulting `keepTokens` to the configured value.\n */\nexport function resolveCompactionStrategy(\n name: string,\n config: { keepTokens?: number },\n): TranscriptCompactionStrategy {\n const cfg = compactionStrategyConfigSchema.parse({ name, keepTokens: config.keepTokens })\n return {\n name: cfg.name,\n keepTokens: cfg.keepTokens,\n compact: (messages, options) =>\n compactTranscript(messages, {\n keepTokens: options?.keepTokens ?? cfg.keepTokens,\n summarize: options?.summarize,\n marker: options?.marker,\n summaryTemplate: options?.summaryTemplate,\n // Default-safe: a thrown summarize keeps the transcript (app opts out via failSafe:false).\n failSafe: options?.failSafe ?? true,\n }),\n }\n}\n\n/**\n * The default `'token-budget'` strategy (what `@Compaction('token-budget')` without\n * an explicit budget resolves to). Carries {@link DEFAULT_KEEP_TOKENS}; the app may\n * override per call via `compact(messages, { keepTokens })`.\n */\nexport const tokenBudgetCompactionStrategy: TranscriptCompactionStrategy =\n resolveCompactionStrategy('token-budget', { keepTokens: DEFAULT_KEEP_TOKENS })\n","/**\n * LoopStrategy — the per-round terminal-decision contract that gives runtime to\n * `@MainLoop({ strategy })`.\n *\n * V4-A proved `@MainLoop`'s `strategy` field was metadata-only (declared +\n * compiled, never executed). This module is the foundation Phase 2's\n * `runReflectiveLoop` branches on. Modeled on Mastra's `agentic-loop`/`stopWhen`\n * (inverted) + `maxSteps` ceiling — NOT Spring's per-call Advisor (plan ADR D1).\n * Config is Zod-validated so an invalid `maxIterations` fails fast at resolve\n * time, never as a silent infinite loop at runtime (plan ADR D3).\n *\n * referencia: knowledge-base/references/mastra agentic-loop/index.ts (stopWhen + maxSteps).\n */\nimport { z } from 'zod'\n\nimport type { MainLoopMeta } from '../types.js'\n\n/** Why a single round ended (or, for the V4-D terminals, why the whole loop ended). */\nexport type LoopFinishReason =\n | 'tool-calls'\n | 'stop'\n | 'length'\n | 'error'\n // V4-D outer-loop terminals — set by runReflectiveLoop, not derived from a single round:\n | 'step_limit' // hit the maxIterations ceiling while the round still wanted to continue\n | 'no_progress' // the agent repeated the same round signature for K consecutive rounds\n\n/** Value object describing one round's result. */\nexport interface LoopOutcome {\n /** Why the round ended (the continuation signal). */\n readonly finishReason: LoopFinishReason\n /** 1-indexed round number that just completed. */\n readonly round: number\n /** Tool calls executed during the round (V4-N: `id` correlates the call to its result). */\n readonly toolCalls: readonly { id: string; name: string; input: unknown; output: string }[]\n /** Accumulated assistant text for the round. */\n readonly responseText: string\n}\n\n/** The terminal-decision contract. `shouldContinue` is the inverted `stopWhen`. */\nexport interface LoopStrategy {\n /** The originating `@MainLoop` strategy name. */\n readonly name: MainLoopMeta['strategy']\n /** Hard ceiling on rounds — guarantees termination. */\n readonly maxIterations: number\n /** True ⇒ re-enter for another round; false ⇒ terminate. Never true forever. */\n shouldContinue(outcome: LoopOutcome): boolean\n}\n\n/** Default round ceiling when `@MainLoop` declares no `maxIterations` (EC-3: finite, never Infinity). */\nexport const DEFAULT_MAX_ITERATIONS = 8\n\n/** Serializable config for a LoopStrategy. SSoT per type-safety.md (ADR D3). */\nexport const loopStrategyConfigSchema = z.object({\n name: z.enum(['simple-chat', 'plan-act-reflect', 'react']),\n maxIterations: z.number().int().min(1),\n})\n\nexport type LoopStrategyConfig = z.infer<typeof loopStrategyConfigSchema>\n\n/**\n * Map a `@MainLoop` strategy + ceiling to a concrete {@link LoopStrategy}.\n *\n * - `simple-chat` ⇒ exactly one round (`shouldContinue` always false).\n * - `react` ⇒ continue while the round ended on `tool-calls` AND the ceiling has not been reached\n * (`round < maxIterations`) — the reflection is `noop` (no feedback), so the strategy IS the gate.\n * - `plan-act-reflect` ⇒ DEFER continuation to the reflection (V4-S): `shouldContinue` is\n * `round < maxIterations`, so the loop continues iff the (custom) `ReflectionStrategy` returns\n * `continue: true` within the ceiling — letting a reflection extend even a terminal (`stop`)\n * round (e.g. \"you answered without editing — make the edit now\"). Backward-compatible with the\n * default `ladderReflectionStrategy`, which itself returns `continue: true` only on `tool-calls`,\n * so the observable behavior with the shipped ladder is unchanged.\n *\n * Throws (Zod) when `maxIterations < 1` — fail fast, never a silent infinite loop.\n */\nexport function resolveLoopStrategy(\n strategy: MainLoopMeta['strategy'],\n maxIterations: number = DEFAULT_MAX_ITERATIONS,\n): LoopStrategy {\n const cfg = loopStrategyConfigSchema.parse({ name: strategy, maxIterations })\n\n if (cfg.name === 'simple-chat') {\n return { name: cfg.name, maxIterations: cfg.maxIterations, shouldContinue: () => false }\n }\n\n if (cfg.name === 'plan-act-reflect') {\n // V4-S: defer to the reflection — the ceiling is the only hard bound; the ReflectionStrategy\n // decides whether to continue (so a custom strategy can extend a terminal round).\n return {\n name: cfg.name,\n maxIterations: cfg.maxIterations,\n shouldContinue: (outcome: LoopOutcome): boolean => outcome.round < cfg.maxIterations,\n }\n }\n\n return {\n name: cfg.name,\n maxIterations: cfg.maxIterations,\n shouldContinue: (outcome: LoopOutcome): boolean =>\n outcome.finishReason === 'tool-calls' && outcome.round < cfg.maxIterations,\n }\n}\n","/**\n * ReflectionStrategy — composes INTO the loop between rounds (the loop calls\n * `reflect()` then `LoopStrategy.shouldContinue()`).\n *\n * `'plan-act-reflect'` resolves to the `'ladder'` default shipped here; a custom\n * strategy may be supplied (OCP — plan Drawback #2). `reflect()` is pure (no\n * I/O, no LLM) — it inspects the round's outcome and returns feedback to inject\n * into the next round's prompt plus a `continue` hint. The hard round ceiling\n * lives in `LoopStrategy.shouldContinue` (maxIterations), NOT here.\n *\n * referencia: knowledge-base/references/mastra agentic-loop/index.ts (onIterationComplete → { feedback, continue }).\n */\nimport { z } from 'zod'\n\nimport type { LoopOutcome } from './loop-strategy.js'\n\n/** Result of reflecting on a completed round. */\nexport interface ReflectionResult {\n /** Optional text prepended to the next round's prompt. */\n readonly feedback?: string\n /** Hint: should the loop reflect-and-continue? (the ceiling still bounds it) */\n readonly continue: boolean\n}\n\n/**\n * V4-K: a per-run mutable scratch bag threaded to every `reflect()` call within one\n * `runReflectiveLoopStream` run, so a STATEFUL strategy can accumulate cumulative state\n * (counters, one-shot flags) across rounds. The framework owns the lifecycle (creates\n * one per run, passes the SAME ref each round) but writes NOTHING into it — the strategy\n * owns the contents. Generic by design: the framework cannot know app semantics (e.g.\n * what an \"edit\" is). A consumer narrows it locally (`ctx as MyState`).\n */\nexport type ReflectionContext = Record<string, unknown>\n\n/** Pluggable between-round reflection. Pure — never performs I/O. */\nexport interface ReflectionStrategy {\n /** Strategy identifier (e.g. `'ladder'`). */\n readonly name: string\n /**\n * Inspect the round outcome; return feedback + continue hint. `ctx` (V4-K) is the\n * per-run mutable scratch — optional for backward compatibility (shipped strategies\n * ignore it; stateful custom strategies accumulate in it across rounds).\n */\n reflect(outcome: LoopOutcome, ctx?: ReflectionContext): ReflectionResult\n}\n\n/** Serializable config for a ReflectionStrategy. SSoT per type-safety.md (ADR D3). */\nexport const reflectionStrategyConfigSchema = z.object({\n name: z.string().min(1),\n})\n\nexport type ReflectionStrategyConfig = z.infer<typeof reflectionStrategyConfigSchema>\n\n/**\n * The default `'ladder'` reflection (what `'plan-act-reflect'` resolves to).\n *\n * Continues with bounded templated feedback while the round ended on\n * `tool-calls`; terminates on any terminal `finishReason` (`stop`/`error`/\n * `length`). The feedback is a short fixed template (bounded — EC-5; context\n * growth is the SDK's responsibility, not the loop's).\n */\nexport const ladderReflectionStrategy: ReflectionStrategy = {\n name: 'ladder',\n reflect(outcome: LoopOutcome): ReflectionResult {\n if (outcome.finishReason === 'tool-calls') {\n return {\n feedback: `Tool results received (round ${outcome.round}). Reflect on whether the goal is met; if not, refine the approach and continue.`,\n continue: true,\n }\n }\n return { continue: false }\n },\n}\n\n/**\n * No-op reflection for `'react'` (multi-round WITHOUT reflection feedback).\n *\n * Returns `{ continue: true }` (no feedback) so the round-continuation decision\n * is delegated entirely to `LoopStrategy.shouldContinue` (i.e. `react` loops\n * while `finishReason === 'tool-calls'` under the ceiling). NOTE: the plan's\n * pseudo-code (Files-to-edit) sketched `{ continue: false }`, which would make\n * `react` single-shot — that contradicts the plan's own Deep Dives (\"`react`\n * still multi-rounds while finishReason==='tool-calls'\"); `continue: true` is\n * the behavior the resolved react LoopStrategy requires.\n */\nexport const noopReflectionStrategy: ReflectionStrategy = {\n name: 'noop',\n reflect(): ReflectionResult {\n return { continue: true }\n },\n}\n","/**\n * Shared delegation value types + typed errors.\n *\n * Extracted from `agent-orchestrator.ts` so BOTH the orchestrator (`delegate`)\n * and the loop driver (`loop/run-reflective-loop.ts`) can import them WITHOUT a\n * cycle (orchestrator → loop → delegation-types; orchestrator → delegation-types;\n * delegation-types has only a TYPE-ONLY import of `LoopFinishReason` (erased at\n * runtime → no runtime edge; `loop-strategy.ts` is a leaf importing only zod, so\n * no cycle — Acyclic Dependencies Principle, G1).\n * `agent-orchestrator.ts` re-exports these for backward compatibility.\n */\nimport type { LoopFinishReason } from '../loop/loop-strategy.js'\n\nexport interface DelegationResult {\n response: string\n toolCalls: { id: string; name: string; input: unknown; output: string }[]\n cost: number\n tokens: number\n /** V4-N: split token usage accumulated across rounds (`tokens` stays as the total). Absent for the single-shot path. */\n tokensInput?: number\n tokensOutput?: number\n /** V4-O: reasoning/cache token buckets accumulated across rounds (0 on any loop-driven run; the loop seeds them). Optional for type compat. */\n reasoningTokens?: number\n cacheReadTokens?: number\n cacheWriteTokens?: number\n /** Rounds the reflective loop ran (set by `runReflectiveLoop`; absent for the single-shot path). */\n rounds?: number\n /**\n * The loop's terminal reason (set by `runReflectiveLoop`): `'stop'`/`'length'` natural end,\n * `'step_limit'` (hit maxIterations), `'no_progress'` (stuck). Absent for the single-shot path. (V4-D)\n */\n finishReason?: LoopFinishReason\n}\n\nexport class BudgetExceededError extends Error {\n constructor(\n public readonly agentName: string,\n public readonly actualCost: number,\n public readonly budgetLimit: number,\n ) {\n super(\n `Agent \"${agentName}\" exceeded budget: $${actualCost.toFixed(4)} > $${budgetLimit.toFixed(4)}`,\n )\n this.name = 'BudgetExceededError'\n }\n}\n\nexport class DelegationError extends Error {\n constructor(\n public readonly agentName: string,\n public readonly cause: unknown,\n ) {\n super(\n `Delegation to agent \"${agentName}\" failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n )\n this.name = 'DelegationError'\n }\n}\n","/**\n * runReflectiveLoop — the multi-round reflective driver that gives `@MainLoop`\n * its runtime (closes the metadata-only gap, V4-A / plan ADR D2).\n *\n * Per round it consumes ONE SDK stream turn (the model call stays in the SDK —\n * the factory is `createSdkAgentStream(...)`, injected for testability), derives\n * a {@link LoopOutcome}, asks the {@link ReflectionStrategy} for feedback, then\n * the {@link LoopStrategy} whether to continue. Bounded by `maxIterations`\n * (forced terminal at the ceiling — never an infinite loop). The bridge owns the\n * loop; the SDK owns the model call (sdk-runtime.md / ADR 0031 — no second runtime).\n *\n * `runReflectiveLoop` is INTERNAL (not re-exported from the package barrel,\n * Drawback #4) — consumed by `delegate()` (T2.2) and `AgentRunner` (T3.1).\n *\n * referencia: knowledge-base/references/mastra agent.ts (re-enter the loop with feedback).\n */\n// V4-P: type-only import (erased at runtime) so the loop stays SDK-optional; the `withRetry`\n// VALUE is dynamic-imported inside consumeOneRound only when `retry` is configured.\nimport type { RetryOptions } from '@theokit/sdk/retry'\n\nimport type { StreamEvent } from '../bridge/agent-sse-handler.js'\nimport {\n BudgetExceededError,\n type DelegationResult,\n DelegationError,\n} from '../bridge/delegation-types.js'\n\nimport type { LoopFinishReason, LoopOutcome, LoopStrategy } from './loop-strategy.js'\nimport type { ReflectionContext, ReflectionStrategy } from './reflection-strategy.js'\n\n/** One SDK stream turn: `createSdkAgentStream(...)` returns this shape. */\n/**\n * Opens one round's SDK stream. `opts.disableTools` (step-cap force-close) asks the factory to\n * gate tools OFF for THIS round (the SDK adapter maps it to `tool_choice:\"none\"` at send-time, so a\n * cached agent — whose tools can't be un-registered — is still forced to a text summary). Optional +\n * ignored by injected test factories ⇒ backward-compatible.\n */\nexport type RoundStreamFactory = (\n message: string,\n sessionId: string,\n opts?: { disableTools?: boolean },\n) => AsyncIterable<StreamEvent>\n\n/** Per-round inputs bundled to keep helper signatures within the parameter budget (G6). */\ninterface RoundInputs {\n factory: RoundStreamFactory\n prompt: string\n sessionId: string\n signal: AbortSignal | undefined\n retry: RetryOptions | undefined\n}\n\n/** Strategies + options for {@link runReflectiveLoop}. */\nexport interface RunReflectiveLoopConfig {\n /** The terminal-decision strategy (resolved from `@MainLoop.strategy`). */\n readonly loop: LoopStrategy\n /** Between-round reflection (default `'ladder'` for `'plan-act-reflect'`). */\n readonly reflection: ReflectionStrategy\n /** Cumulative USD budget across ALL rounds (EC-4). Exceeding throws BudgetExceededError. */\n readonly budget?: number\n /** Cancellation — when aborted, the loop stops re-entering and advancing the in-flight stream. */\n readonly signal?: AbortSignal\n /** Name surfaced in typed errors. */\n readonly agentName?: string\n /**\n * V4-P: per-round transient retry. When set, the START of each round (factory creation + first\n * event, before any event is yielded → no re-applied edit) is wrapped in the SDK `withRetry`.\n * Absent ⇒ single attempt (backward-compatible). Default `isRetryable` is the SDK `isTransientError`.\n */\n readonly retry?: RetryOptions\n}\n\nfunction asString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback\n}\n\nfunction asNumber(value: unknown, fallback: number): number {\n return typeof value === 'number' ? value : fallback\n}\n\n/** Consecutive no-progress rounds before terminating with `'no_progress'` (K=2 tolerates one retry — V4-D). */\nconst NO_PROGRESS_THRESHOLD = 2\n\n/** Runtime metric key (wiring triad — G10): observable proof the loop ran, with terminal + round count. */\nconst MAINLOOP_METRIC = '[THEO_AGENT_MAINLOOP_RUNTIME_APPLIED]'\n\n/** The \"still working\" continuation signal — a tool-using turn re-enters the loop. */\nconst TOOL_CALLS: LoopFinishReason = 'tool-calls'\n\n/** Final-round graceful-degradation hint (V4-D step_limit — modeled on opencode MAX_STEPS_PROMPT). */\nconst STEP_LIMIT_HINT =\n 'This is your final round — do not call any more tools; summarize the work done so far and list any remaining tasks.'\n\n/**\n * Deterministic JSON: object keys are emitted in sorted order so two semantically\n * equal tool inputs serialize identically regardless of key insertion order (a\n * stuck-loop detector must not be fooled by re-ordered keys — review NF, robustness).\n */\nfunction stableStringify(value: unknown): string {\n if (value === undefined) return 'undefined'\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`\n const obj = value as Record<string, unknown>\n const entries = Object.keys(obj)\n .sort((a, b) => a.localeCompare(b))\n .map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`)\n return `{${entries.join(',')}}`\n}\n\n/**\n * A round's progress fingerprint = its tool-call set ONLY (name+input, SORTED so call\n * ORDER is irrelevant — EC-3; input keys canonicalized so KEY order is irrelevant too).\n * Two consecutive rounds with an equal signature made no new progress. The assistant\n * narration text is DELIBERATELY excluded (theokit#53): a model that re-runs identical\n * tool calls while rephrasing its prose (\"…e executá-lo.\" → \"Agora vou executar…\") would\n * otherwise evade the detector and spin. Mirrors opencode's `doom_loop`, which compares\n * tool name + JSON.stringify(input) and nothing else. Tool `output` is also excluded:\n * repeating the same call is no-progress even if the result text wobbles. (V4-D, ADR D2)\n */\nfunction roundSignature(toolCalls: readonly { name: string; input: unknown }[]): string {\n return toolCalls\n .map((tc) => `${tc.name}:${stableStringify(tc.input)}`)\n .sort((a, b) => a.localeCompare(b))\n .join(',')\n}\n\n/**\n * The loop's terminal reason: `'step_limit'` when the round wanted to continue\n * (tool-calls + reflection continue) but the `maxIterations` ceiling stopped it;\n * otherwise the round's own natural reason (`'stop'`/`'length'`). (V4-D, ADR D1)\n */\nfunction terminalReason(\n reflectionContinue: boolean,\n roundReason: LoopFinishReason,\n round: number,\n maxIterations: number,\n): LoopFinishReason {\n if (reflectionContinue && roundReason === TOOL_CALLS && round >= maxIterations)\n return 'step_limit'\n // A tool-using round that terminates BELOW the ceiling means a (custom) reflection chose to\n // stop while the turn could have continued — surface 'stop', never leak the per-round\n // 'tool-calls' signal as the loop's terminal reason (review NF; shipped ladder/noop never hit this).\n if (roundReason === TOOL_CALLS) return 'stop'\n return roundReason\n}\n\n/**\n * Default round-2+ continuation when the reflection produced no feedback (V4-M): the\n * persisted session (getOrCreate, sdk-adapter) already holds the prior turns, so a short\n * nudge is enough — re-sending the original task would duplicate it in the session.\n */\nconst CONTINUE_PROMPT =\n 'Continue from the prior turns above; finish the task and give a final answer.'\n\n/**\n * Build the round's prompt. V4-M: rounds carry conversation via the persisted SDK session,\n * so round 1 sends the original `message`; rounds 2+ send the reflection `feedback` (or a\n * default continuation) WITHOUT re-sending `message`. Final-round summary hint preserved (V4-D).\n */\nfunction buildPrompt(\n round: number,\n maxIterations: number,\n message: string,\n feedback: string | undefined,\n): string {\n const hint = round === maxIterations ? `${STEP_LIMIT_HINT}\\n\\n` : ''\n // Round 1 sends the original task; rounds 2+ rely on the persisted session (V4-M) and send\n // ONLY the reflection block (tag preserved) or a default continuation — never re-sending `message`.\n const continuation = feedback ? `[reflection] ${feedback}` : CONTINUE_PROMPT\n const body = round === 1 ? message : continuation\n return hint + body\n}\n\n/**\n * Consume one round, normalizing a RAW stream/iterator exception (not an `error` event —\n * e.g. the SDK dynamic import rejecting) into a typed `DelegationError` (M2). Typed errors\n * (`BudgetExceededError`/`DelegationError`) propagate unchanged.\n */\nasync function* consumeRoundOrThrow(\n inputs: RoundInputs,\n agentName: string,\n): AsyncGenerator<StreamEvent, RoundResult> {\n try {\n return yield* consumeOneRound(\n inputs.factory,\n inputs.prompt,\n inputs.sessionId,\n inputs.signal,\n inputs.retry,\n )\n } catch (err) {\n if (err instanceof BudgetExceededError || err instanceof DelegationError) throw err\n throw new DelegationError(agentName, err)\n }\n}\n\n/**\n * V4-N/V4-O: fold one round's usage into the accumulator — cost + total/split tokens (V4-N) and\n * the reasoning/cache buckets (V4-O). Extracted from the loop body to keep its complexity within\n * budget (G6); the optional `acc` fields default to 0 before adding.\n */\nfunction accumulateUsage(acc: DelegationResult, r: RoundResult): void {\n acc.cost += r.cost\n acc.tokens += r.tokens\n acc.tokensInput = (acc.tokensInput ?? 0) + r.tokensInput\n acc.tokensOutput = (acc.tokensOutput ?? 0) + r.tokensOutput\n acc.reasoningTokens = (acc.reasoningTokens ?? 0) + r.reasoningTokens\n acc.cacheReadTokens = (acc.cacheReadTokens ?? 0) + r.cacheReadTokens\n acc.cacheWriteTokens = (acc.cacheWriteTokens ?? 0) + r.cacheWriteTokens\n}\n\n/** Stamp the terminal state on the accumulator + emit the runtime metric (DRY for the 2 exit points). */\nfunction finalize(\n acc: DelegationResult,\n round: number,\n reason: LoopFinishReason,\n strategyName: string,\n): DelegationResult {\n acc.rounds = round\n acc.finishReason = reason\n console.debug(MAINLOOP_METRIC, { strategy: strategyName, rounds: round, terminal: reason })\n return acc\n}\n\n/** One round's accumulated facts + the signals needed to derive `finishReason`. */\ninterface RoundResult {\n responseText: string\n toolCalls: { id: string; name: string; input: unknown; output: string }[]\n cost: number\n tokens: number\n tokensInput: number\n tokensOutput: number\n // V4-O: reasoning/cache token buckets folded from the done event.\n reasoningTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n finishReason: LoopFinishReason\n errorMessage: string\n}\n\n/**\n * Derive the round's terminal signal from the events seen this round.\n *\n * Precedence (B1 — the load-bearing fix):\n * 1. error event ⇒ 'error'\n * 2. explicit done.finishReason==='tool-calls' ⇒ 'tool-calls' (if a future SDK adapter sets it)\n * 3. ANY tool_result seen ⇒ 'tool-calls' — the turn USED TOOLS (\"still working\"), so the\n * outer reflective loop should reflect + re-prompt. The real `@theokit/sdk` adapter ALWAYS\n * appends a terminal `done` WITHOUT finishReason after a turn (sdk-adapter.ts / event-translator.ts);\n * letting that `done` short-circuit a tool-using turn to 'stop' is exactly what made the loop\n * dead in production (single-round). tool_result therefore OUTRANKS the bare done. Bounded by\n * `maxIterations` so it can never spin.\n * 4. otherwise (pure-answer `done`, text-only, or empty round) ⇒ 'stop' (terminal). EC-1: a\n * degenerate/empty round defaults to 'stop', NEVER 'tool-calls'.\n *\n * This is an honest heuristic: the SDK runs the inner tool loop to completion per turn, so the\n * outer loop treats a tool-using turn as \"continue/reflect\" and a pure-text answer as \"done\".\n */\nfunction deriveFinishReason(signals: {\n sawError: boolean\n sawDone: boolean\n doneFinishReason: string\n sawToolResult: boolean\n}): LoopFinishReason {\n if (signals.sawError) return 'error'\n if (signals.sawDone && signals.doneFinishReason === TOOL_CALLS) return TOOL_CALLS\n if (signals.sawToolResult) return TOOL_CALLS\n return 'stop'\n}\n\n/** Mutable round signals used to derive the round's {@link LoopFinishReason}. */\ninterface RoundSignals {\n sawError: boolean\n sawDone: boolean\n doneFinishReason: string\n sawToolResult: boolean\n}\n\n/** V4-N: push a faithful `{id,name,input,output}` toolCall, correlating input from the tool_call. */\nfunction pushToolResult(\n event: StreamEvent,\n r: RoundResult,\n callInputs: Map<string, { name: string; input: unknown }>,\n): void {\n const id = asString(event.callId, '')\n const call = callInputs.get(id)\n r.toolCalls.push({\n id,\n name: call?.name ?? asString(event.toolName, 'unknown'),\n // Prefer the correlated tool_call input (real SDK shape); fall back to an input on the\n // result event itself (some streams/tests carry it there), else {}.\n input: call?.input ?? event.input ?? {},\n output: asString(event.output, ''),\n })\n}\n\n/** V4-N: fold a `done` event's cost + split/total token usage into the round (V4-O: + buckets). */\nfunction applyDone(event: StreamEvent, r: RoundResult): void {\n r.cost = asNumber(event.cost, 0)\n const usage = event.usage as\n | {\n totalTokens?: number\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: number\n cacheReadTokens?: number\n cacheWriteTokens?: number\n }\n | undefined\n r.tokens = usage?.totalTokens ?? 0\n r.tokensInput = usage?.inputTokens ?? 0\n r.tokensOutput = usage?.outputTokens ?? 0\n // V4-O: fold the reasoning/cache buckets (0 when the provider/adapter omits them).\n r.reasoningTokens = usage?.reasoningTokens ?? 0\n r.cacheReadTokens = usage?.cacheReadTokens ?? 0\n r.cacheWriteTokens = usage?.cacheWriteTokens ?? 0\n}\n\n/**\n * Fold ONE stream event into the round accumulator (V4-N: extracted from `consumeOneRound`\n * to keep its complexity within budget — G6).\n */\nfunction accumulateEvent(\n event: StreamEvent,\n r: RoundResult,\n signals: RoundSignals,\n callInputs: Map<string, { name: string; input: unknown }>,\n): void {\n if (event.type === 'text_delta' && typeof event.content === 'string') {\n r.responseText += event.content\n } else if (event.type === 'tool_call') {\n callInputs.set(asString(event.callId, ''), {\n name: asString(event.toolName, 'unknown'),\n input: event.input ?? {},\n })\n } else if (event.type === 'tool_result') {\n signals.sawToolResult = true\n pushToolResult(event, r, callInputs)\n } else if (event.type === 'done') {\n signals.sawDone = true\n signals.doneFinishReason = asString(event.finishReason, '')\n applyDone(event, r)\n } else if (event.type === 'error') {\n signals.sawError = true\n r.errorMessage = asString((event as { message?: unknown }).message, 'Unknown agent error')\n }\n}\n\n/**\n * Consume exactly one SDK stream turn and derive its {@link LoopFinishReason}.\n * V4-D-stream: an async generator — it `yield`s each event to the consumer LIVE\n * (so SSE-first apps see tokens/tool-calls incrementally) AND returns the\n * aggregated {@link RoundResult} as the generator's return value.\n */\n/**\n * V4-P: open the round's stream + read its first event. When `retry` is set, the whole START\n * (creation + first `next()`) is wrapped in the SDK `withRetry` (dynamic-imported to keep the\n * loop SDK-optional) — a transient before any event is yielded is recovered without re-applying\n * an edit. Once the first event is obtained, the caller iterates WITHOUT retry.\n */\nasync function startRound(\n factory: RoundStreamFactory,\n prompt: string,\n sessionId: string,\n signal: AbortSignal | undefined,\n retry: RetryOptions | undefined,\n): Promise<{ it: AsyncIterator<StreamEvent>; first: IteratorResult<StreamEvent> }> {\n const open = async () => {\n const it = factory(prompt, sessionId)[Symbol.asyncIterator]()\n try {\n return { it, first: await it.next() }\n } catch (err) {\n // The first event threw — release THIS attempt's iterator (run its finally → SDK dispose)\n // before `withRetry` opens a fresh stream, so a failed retry attempt leaks nothing.\n await it.return?.(undefined)\n throw err\n }\n }\n if (!retry) return open()\n const { withRetry } = await import('@theokit/sdk/retry')\n return withRetry(open, { ...retry, signal: retry.signal ?? signal })\n}\n\nasync function* consumeOneRound(\n factory: RoundStreamFactory,\n prompt: string,\n sessionId: string,\n signal: AbortSignal | undefined,\n retry: RetryOptions | undefined,\n): AsyncGenerator<StreamEvent, RoundResult> {\n const r: RoundResult = {\n responseText: '',\n toolCalls: [],\n cost: 0,\n tokens: 0,\n tokensInput: 0,\n tokensOutput: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n finishReason: 'stop',\n errorMessage: '',\n }\n const signals: RoundSignals = {\n sawError: false,\n sawDone: false,\n doneFinishReason: '',\n sawToolResult: false,\n }\n // V4-N: the tool-call `input` (command/args) lives ONLY on the `tool_call` event; the\n // `output` on the paired `tool_result`. Correlate by callId so toolCalls is faithful.\n const callInputs = new Map<string, { name: string; input: unknown }>()\n\n // V4-P: the round START (creation + first event) is retried when `retry` is set; once an\n // event is yielded we iterate without retry (a mid-stream throw may have applied an edit).\n const { it, first } = await startRound(factory, prompt, sessionId, signal, retry)\n let next = first\n while (!next.done) {\n if (signal?.aborted) {\n // Cancellation: release the underlying iterator (parity with `for await`'s `.return()`\n // on break — runs the factory generator's `finally`, e.g. the SDK adapter's dispose).\n await it.return?.(undefined)\n break\n }\n yield next.value // V4-D-stream: surface the event to the consumer before accumulating\n accumulateEvent(next.value, r, signals, callInputs)\n next = await it.next()\n }\n\n r.finishReason = deriveFinishReason(signals)\n return r\n}\n\n/**\n * Drive the reflective loop to a terminal {@link DelegationResult}.\n *\n * Terminates when: the reflection/strategy says stop, the `maxIterations` ceiling\n * is reached (via `loop.shouldContinue`), the signal aborts, or a degenerate round\n * resolves to `stop`. Throws `DelegationError` on a mid-round error event\n * (fail-fast, typed) and `BudgetExceededError` when cumulative cost crosses `budget`.\n */\nexport /**\n * Step-cap force-close: on the ceiling round (`round === maxIterations`) wrap the factory so it is\n * called with `disableTools: true` (the adapter maps it to `tool_choice:\"none\"` at send-time),\n * forcing the model to emit the closing summary STEP_LIMIT_HINT requests instead of more tool calls.\n * Below the ceiling, the factory is returned unchanged.\n */\nfunction ceilingRoundFactory(\n factory: RoundStreamFactory,\n round: number,\n maxIterations: number,\n): RoundStreamFactory {\n if (round !== maxIterations) return factory\n return (m, s) => factory(m, s, { disableTools: true })\n}\n\nexport async function* runReflectiveLoopStream(\n factory: RoundStreamFactory,\n message: string,\n sessionId: string,\n config: RunReflectiveLoopConfig,\n): AsyncGenerator<StreamEvent, DelegationResult> {\n const {\n loop,\n reflection,\n budget = Number.POSITIVE_INFINITY,\n signal,\n agentName = loop.name,\n retry,\n } = config\n const acc: DelegationResult = {\n response: '',\n toolCalls: [],\n cost: 0,\n tokens: 0,\n tokensInput: 0,\n tokensOutput: 0,\n reasoningTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n rounds: 0,\n }\n // V4-K: one mutable scratch bag per run, threaded to every reflect() so a stateful\n // strategy accumulates across rounds. The framework writes NOTHING into it.\n const reflectionContext: ReflectionContext = {}\n let round = 1\n let feedback: string | undefined\n let prevSig: string | undefined // V4-D: prior round's progress signature (no_progress detection)\n let stuck = 0 // V4-D: consecutive no-progress rounds\n\n while (!signal?.aborted) {\n const prompt = buildPrompt(round, loop.maxIterations, message, feedback)\n const roundFactory = ceilingRoundFactory(factory, round, loop.maxIterations)\n const r = yield* consumeRoundOrThrow(\n { factory: roundFactory, prompt, sessionId, signal, retry },\n agentName,\n )\n\n acc.response += r.responseText\n acc.toolCalls.push(...r.toolCalls)\n accumulateUsage(acc, r)\n\n if (r.finishReason === 'error') throw new DelegationError(agentName, r.errorMessage)\n if (Number.isFinite(budget) && acc.cost > budget) {\n throw new BudgetExceededError(agentName, acc.cost, budget)\n }\n\n // V4-D no_progress: only on would-continue rounds (EC-1: stop/error/length/empty already\n // terminate with their own reason), evaluated BEFORE the ceiling (EC-4: the earlier signal wins).\n // Require ≥1 tool call: a TOOL_CALLS round with an empty tool-call set (reachable only via the\n // dormant deriveFinishReason path 2 — done.finishReason==='tool-calls' with no tool_result) has\n // an empty signature; without this guard two such rounds would collide ('' === '') into a false\n // no_progress (theokit#53 review, architecture+tests LOW). An empty round made no tool progress\n // to compare — skip it (don't accumulate or reset).\n if (r.finishReason === TOOL_CALLS && r.toolCalls.length > 0) {\n const sig = roundSignature(r.toolCalls)\n stuck = sig === prevSig ? stuck + 1 : 0\n if (stuck >= NO_PROGRESS_THRESHOLD) return finalize(acc, round, 'no_progress', loop.name)\n prevSig = sig\n }\n\n const outcome: LoopOutcome = {\n finishReason: r.finishReason,\n round,\n toolCalls: r.toolCalls,\n responseText: r.responseText,\n }\n const reflectionResult = reflection.reflect(outcome, reflectionContext)\n if (!(reflectionResult.continue && loop.shouldContinue(outcome))) {\n const reason = terminalReason(\n reflectionResult.continue,\n r.finishReason,\n round,\n loop.maxIterations,\n )\n return finalize(acc, round, reason, loop.name)\n }\n\n feedback = reflectionResult.feedback\n round += 1\n }\n\n // Aborted before (re-)entering a round. L1: record the rounds that DID run\n // (round is 1-indexed and points at the next round, so `round - 1` ran).\n acc.rounds = round - 1\n return acc\n}\n\n/**\n * Collect-mode wrapper (backward-compatible): drains {@link runReflectiveLoopStream}\n * and returns ONLY the aggregated {@link DelegationResult}. `delegate()` and\n * `AgentRunner.run()` use this; streaming-first consumers use the generator directly.\n */\nexport async function runReflectiveLoop(\n factory: RoundStreamFactory,\n message: string,\n sessionId: string,\n config: RunReflectiveLoopConfig,\n): Promise<DelegationResult> {\n const gen = runReflectiveLoopStream(factory, message, sessionId, config)\n let res = await gen.next()\n while (!res.done) res = await gen.next()\n return res.value\n}\n","/**\n * AgentRunner — the imperative twin of `@MainLoop` (plan ADR D4, V4-B).\n *\n * `AgentRunner.builder(AgentClass).reflection().stream().build()` walks +\n * compiles the agent and resolves the SAME `{ compiled, loopStrategy }` that\n * `delegate()` resolves for the decorator path (two on-ramps, one runtime).\n * `build()` is the compile boundary (no I/O, no IoC — standalone, mirrors\n * Spring's `ChatClient.builder(...).build()`); `stream()`/`run()` do the I/O via\n * `runReflectiveLoopStream` (the SAME loop `delegate()` drains — DRY, ADR 0031).\n * V4-D-stream: `stream()` yields events live (SSE-first); `run()` drains it to a result.\n *\n * referencia: knowledge-base/references/spring-ai DefaultChatClientBuilder.java (build() returns standalone).\n */\nimport type {\n AgentDefinition,\n BudgetTracker,\n ConversationStorageAdapter,\n CustomTool,\n Plugin,\n PluginsSettings,\n ProviderRoutingSettings,\n} from '@theokit/sdk'\nimport type { RetryOptions } from '@theokit/sdk/retry'\n\nimport {\n type CompiledAgentOptions,\n type CompiledTool,\n compileAgent,\n} from '../bridge/agent-compiler.js'\nimport type { StreamEvent } from '../bridge/agent-sse-handler.js'\nimport type { DelegationResult } from '../bridge/delegation-types.js'\nimport { createSdkAgentStream } from '../bridge/sdk-adapter.js'\nimport { walkAgentMetadata } from '../bridge/walk-agent-metadata.js'\nimport type { ReasoningEffort } from '../types.js'\n\nimport {\n resolveCompactionStrategy,\n type TranscriptCompactionStrategy,\n} from './compaction-strategy.js'\nimport { type LoopStrategy, resolveLoopStrategy } from './loop-strategy.js'\nimport {\n ladderReflectionStrategy,\n noopReflectionStrategy,\n type ReflectionStrategy,\n} from './reflection-strategy.js'\nimport { type RoundStreamFactory, runReflectiveLoopStream } from './run-reflective-loop.js'\n\n/** Options for {@link AgentRunner.run}. */\nexport interface AgentRunnerRunOptions {\n /** LLM API key. */\n readonly apiKey: string\n /** Session id override (default: a fresh isolated id). */\n readonly sessionId?: string\n /** Cumulative USD budget across rounds. */\n readonly budget?: number\n /** Cancellation — aborts stop the reflective loop from re-entering. */\n readonly signal?: AbortSignal\n /**\n * V4-J: per-run tool override. When provided, REPLACES the build-time\n * `compiled.tools` for this call only (e.g. a consumer that selects tools by\n * request mode/permission). Absent ⇒ the agent's compiled tools (unchanged).\n */\n readonly tools?: readonly CompiledTool[]\n /**\n * V4-L.2 (Axis-A SWAP): per-run model override. Merge-over-compiled —\n * `opts.model ?? compiled.model ?? default`. Absent ⇒ the compiled model.\n */\n readonly model?: string\n /**\n * M1 (Axis-A SWAP): per-run extended-thinking effort. Merge-over-compiled —\n * `opts.reasoningEffort ?? compiled.reasoningEffort` (resolved in the adapter, single site).\n * Mapped to the SDK `ModelSelection.params` so the provider reasons (surfaced as `thinking`\n * StreamEvents). Absent ⇒ the compiled `@Agent({ reasoningEffort })` (or none).\n */\n readonly reasoningEffort?: ReasoningEffort\n /**\n * M2 (Axis-A SWAP): per-run opt-in to convert inline `<think>…</think>` text into `thinking`\n * events. Merge-over-compiled (`opts.parseThinkTags ?? compiled.parseThinkTags ?? false`). For\n * models that emit reasoning as inline tags (qwen/deepseek) instead of a native reasoning param.\n */\n readonly parseThinkTags?: boolean\n /**\n * theocode#32 (Axis-A SWAP): per-run opt-in to strip a leaked Hermes `<function=…></tool_call>`\n * tool-call dialect out of the text stream. Merge-over-compiled\n * (`opts.stripToolDialect ?? compiled.stripToolDialect ?? false`). For models (qwen/qwen3-coder)\n * that leak tool calls as text instead of native `tool_calls`.\n */\n readonly stripToolDialect?: boolean\n /**\n * theokit#58 (Axis-A SWAP): per-run opt-in to RECOVER a leaked Hermes `<function=…></tool_call>`\n * tool-call dialect so the call EXECUTES (enables the SDK route's `extractToolCallsFromContent`).\n * Merge-over-compiled (`opts.recoverLeakedToolCalls ?? compiled.recoverLeakedToolCalls ?? false`).\n * Sibling of {@link stripToolDialect} (display-only); typically enabled together. Has effect only\n * when {@link providers} routes a provider.\n */\n readonly recoverLeakedToolCalls?: boolean\n /**\n * V4-L.2 (Axis-A SWAP): per-run working directory, forwarded into\n * `Agent.create({ local: { cwd } })` so the SDK populates `SystemPromptContext.cwd`\n * (read by a `SystemPromptResolver` / `@ProjectContext`). Absent ⇒ no `local.cwd`.\n */\n readonly cwd?: string\n /**\n * V4-L.2 (Axis-A SWAP): per-run loop-ceiling override. When provided, the loop\n * strategy is re-resolved with this ceiling for this call only (zod-validated —\n * `< 1` throws, never a silent unbounded loop). Absent ⇒ the build-time ceiling.\n */\n readonly maxIterations?: number\n /**\n * V4-L.3 (Axis-A SWAP): per-run plugins (e.g. permission gate by request mode).\n * Accepts EITHER named-plugin discovery settings (`{ enabled: [...] }`) OR an\n * array of code `Plugin` objects (`[permissionPlugin, cachePlugin]`). Both are\n * forwarded RAW through the duck-typed `Agent.create` bridge to the SDK runtime,\n * which accepts either form (mirrors the @theokit/sdk `AgentOptions.plugins` widen).\n */\n readonly plugins?: PluginsSettings | readonly Plugin[]\n /** V4-L.3 (Axis-A SWAP): per-run provider routing. */\n readonly providers?: ProviderRoutingSettings\n /** V4-L.3 (Axis-A SWAP): per-run sub-agent definitions (opts-only; @SubAgents stays deferred). */\n readonly agents?: Record<string, AgentDefinition>\n /**\n * V4-L.3 (Axis-A SWAP): per-run SDK budget tracker — caps the INNER SDK tool-loop per\n * send. Distinct from {@link AgentRunnerRunOptions.budget} (the OUTER reflective-loop USD ceiling).\n */\n readonly budgetTracker?: BudgetTracker\n /**\n * V4-M: conversation store shared across the loop's rounds so history persists (round N+1\n * sees rounds 1..N). Default `InMemoryConversationStorage` (per-run, no disk). Pass a\n * `FileSystemConversationStorage`/custom adapter for durable cross-run history.\n */\n readonly conversationStorage?: ConversationStorageAdapter\n /**\n * V4-Q: pre-built SDK `CustomTool[]` forwarded RAW to `Agent.create.tools` (appended after the\n * agent's compiled tools), bypassing `defineTool`. For an app whose tools come from imperative\n * SDK factories (no `@Tool` compile path / no recoverable Zod schema). Distinct from `tools`\n * (which REPLACES the compiled `CompiledTool[]`).\n */\n readonly sdkTools?: readonly CustomTool[]\n /**\n * V4-R: inject the per-round stream factory, driving the reflective loop with a caller-provided\n * stream INSTEAD of the SDK adapter (tests / custom transport). When set, the SDK-create options\n * (`tools`/`sdkTools`/`model`/`cwd`/`plugins`/...) are NOT used for this call — the consumer owns\n * the stream. Absent ⇒ `createSdkAgentStream` (the default runtime).\n */\n readonly streamFactory?: RoundStreamFactory\n /**\n * V4-P: per-round transient retry. When set, the START of each reflective round (factory\n * creation + first event, before any event is yielded) is wrapped in the SDK `withRetry` —\n * a 429/5xx/network blip is recovered without re-applying an edit. Absent ⇒ single attempt.\n * Default `isRetryable` is the SDK `isTransientError`.\n */\n readonly retry?: RetryOptions\n}\n\n/**\n * A built, runnable agent. Construct via {@link AgentRunner.builder} — the\n * constructor takes already-resolved state and is an internal detail.\n */\n/** Already-resolved state handed to the {@link AgentRunner} constructor (internal). */\nexport interface AgentRunnerState {\n readonly compiled: CompiledAgentOptions\n readonly agentName: string\n /** The resolved terminal-decision strategy (parity with `delegate()`). */\n readonly loopStrategy: LoopStrategy\n /** The resolved between-round reflection (default or `.reflection(custom)` override). */\n readonly reflectionStrategy: ReflectionStrategy\n /** Recorded streaming preference (see {@link AgentRunner.streamEnabled}). */\n readonly streamEnabled: boolean\n /** The resolved compaction strategy, or `undefined` when none is declared (EC-4). */\n readonly compaction?: TranscriptCompactionStrategy\n}\n\nexport class AgentRunner {\n private readonly compiled: CompiledAgentOptions\n private readonly agentName: string\n /** The resolved terminal-decision strategy (parity with `delegate()`). */\n readonly loopStrategy: LoopStrategy\n /** The resolved between-round reflection (default or `.reflection(custom)` override). */\n readonly reflectionStrategy: ReflectionStrategy\n /**\n * Recorded streaming preference. The reflective loop currently always streams via\n * the SDK `Run.stream()`; a non-streaming collect mode is future work — the flag is\n * captured + exposed here, not yet branched on (honest per G10: documented, not a\n * silent no-op).\n */\n readonly streamEnabled: boolean\n /**\n * V4-F: the resolved compaction strategy (from `@Compaction` or `.compaction()`),\n * or `undefined` when neither is declared — compaction is opt-in (EC-4). CALLABLE\n * by the app (ADR D1: `runner.compaction?.compact(messages, { summarize })`); the\n * reflective loop does NOT auto-invoke it (the SDK owns per-turn context).\n */\n readonly compaction?: TranscriptCompactionStrategy\n\n constructor(state: AgentRunnerState) {\n this.compiled = state.compiled\n this.agentName = state.agentName\n this.loopStrategy = state.loopStrategy\n this.reflectionStrategy = state.reflectionStrategy\n this.streamEnabled = state.streamEnabled\n this.compaction = state.compaction\n }\n\n /** Start a fluent builder for `AgentClass`. */\n static builder(AgentClass: Function): AgentRunnerBuilder {\n return new AgentRunnerBuilder(AgentClass)\n }\n\n /**\n * V4-D-stream: stream the agent's events LIVE across the reflective loop, returning\n * the aggregated {@link DelegationResult} as the generator's return value. This is the\n * on-ramp for streaming-first apps (SSE) — `runReflectiveLoopStream` yields every\n * round's events before the loop terminates. `streamEnabled` is honored: when the\n * builder set `.stream(false)`, callers should use {@link run} instead.\n */\n stream(\n message: string,\n opts: AgentRunnerRunOptions,\n ): AsyncGenerator<StreamEvent, DelegationResult> {\n // V4-J: per-run tool override replaces compiled.tools for this call only.\n const tools = opts.tools ? [...opts.tools] : this.compiled.tools\n // Re-resolve the ceiling per call (zod fail-loud on `< 1`); preserve the strategy name.\n const loop =\n opts.maxIterations != null\n ? resolveLoopStrategy(this.loopStrategy.name, opts.maxIterations)\n : this.loopStrategy\n // V4-R: a caller-injected factory drives the loop directly (tests / custom transport); absent ⇒\n // the SDK adapter. V4-L.2 + V4-L.3 (Axis-A SWAP): the per-request overrides forwarded to Agent.create.\n // `model` resolves against compiled.model in the adapter (single resolution site).\n const streamFactory =\n opts.streamFactory ??\n createSdkAgentStream(this.compiled, tools, opts.apiKey, {\n model: opts.model,\n reasoningEffort: opts.reasoningEffort, // M1: per-run extended-thinking effort\n parseThinkTags: opts.parseThinkTags, // M2: per-run <think>-tag extraction opt-in\n stripToolDialect: opts.stripToolDialect, // theocode#32: per-run tool-dialect strip opt-in\n recoverLeakedToolCalls: opts.recoverLeakedToolCalls, // theokit#58: per-run leaked-dialect recovery opt-in\n cwd: opts.cwd,\n plugins: opts.plugins,\n providers: opts.providers,\n agents: opts.agents,\n budgetTracker: opts.budgetTracker,\n conversationStorage: opts.conversationStorage,\n sdkTools: opts.sdkTools, // V4-Q: pre-built SDK tools forwarded raw\n })\n const sessionId = opts.sessionId ?? `runner-${crypto.randomUUID()}`\n return runReflectiveLoopStream(streamFactory, message, sessionId, {\n loop,\n reflection: this.reflectionStrategy,\n budget: opts.budget,\n agentName: this.agentName,\n signal: opts.signal,\n retry: opts.retry, // V4-P: per-round transient retry (opt-in)\n })\n }\n\n /** Run the agent to a terminal result via the shared reflective loop (collect mode). */\n async run(message: string, opts: AgentRunnerRunOptions): Promise<DelegationResult> {\n const gen = this.stream(message, opts)\n let res = await gen.next()\n while (!res.done) res = await gen.next()\n return res.value\n }\n}\n\n/** Fluent builder — accumulates config; `build()` is the compile boundary. */\nexport class AgentRunnerBuilder {\n private reflectionOverride?: ReflectionStrategy\n private streamEnabled = true\n private compactionOverride?: { name: string; keepTokens?: number }\n\n constructor(private readonly AgentClass: Function) {}\n\n /** Override the default reflection strategy (OCP — plan Drawback #2). No arg ⇒ keep default. */\n reflection(strategy?: ReflectionStrategy): this {\n if (strategy) this.reflectionOverride = strategy\n return this\n }\n\n /** Record the streaming preference (see {@link AgentRunner.streamEnabled}). */\n stream(enabled = true): this {\n this.streamEnabled = enabled\n return this\n }\n\n /**\n * V4-F: declare the compaction strategy (e.g. `.compaction('token-budget', { keepTokens: 8000 })`).\n * Resolved + validated at {@link build} (EC-5 — fail-fast there, not here). This builder\n * call WINS over a `@Compaction` decorator on the same agent (EC-1 — explicit override).\n */\n compaction(name: string, options: { keepTokens?: number } = {}): this {\n this.compactionOverride = { name, keepTokens: options.keepTokens }\n return this\n }\n\n /** Walk + compile + resolve strategies — the compile→execute boundary (no I/O). */\n build(): AgentRunner {\n const walk = walkAgentMetadata(this.AgentClass, [])\n const toolboxInstances = new Map(\n walk.toolboxes.map((tb) => [tb.class, new (tb.class as new () => object)()]),\n )\n const compiled = compileAgent(walk, toolboxInstances)\n const loopStrategy = resolveLoopStrategy(walk.mainLoop.strategy, walk.mainLoop.maxIterations)\n const reflectionStrategy =\n this.reflectionOverride ??\n (walk.mainLoop.strategy === 'plan-act-reflect'\n ? ladderReflectionStrategy\n : noopReflectionStrategy)\n // V4-F: builder override WINS over the @Compaction decorator (EC-1); undefined when\n // neither declares it (EC-4 — opt-in). resolveCompactionStrategy fails fast (EC-5/EC-2).\n const compactionDecl = this.compactionOverride ?? walk.compaction\n const compaction = compactionDecl\n ? resolveCompactionStrategy(compactionDecl.name, { keepTokens: compactionDecl.keepTokens })\n : undefined\n return new AgentRunner({\n compiled,\n agentName: walk.agentConfig.name,\n loopStrategy,\n reflectionStrategy,\n streamEnabled: this.streamEnabled,\n compaction,\n })\n }\n}\n","/**\n * Multi-agent orchestration runtime.\n *\n * Provides `delegate()` — a function that lets a parent agent invoke a\n * sub-agent and receive its result. Handles budget clamping (D4), tool sharing,\n * toolbox auto-instantiation (EC-1), and routes the resolved `@MainLoop` strategy\n * through `runReflectiveLoop` — the SAME driver `AgentRunner.run()` uses, so both\n * on-ramps are one runtime (ADR D4). `simple-chat` ⇒ `shouldContinue:()=>false`\n * ⇒ exactly one round; `react`/`plan-act-reflect` ⇒ multi-round reflective loop.\n */\nimport type {\n AgentDefinition,\n BudgetTracker,\n ConversationStorageAdapter,\n CustomTool,\n PluginsSettings,\n ProviderRoutingSettings,\n} from '@theokit/sdk'\nimport type { RetryOptions } from '@theokit/sdk/retry'\n\nimport {\n ladderReflectionStrategy,\n noopReflectionStrategy,\n type ReflectionStrategy,\n resolveLoopStrategy,\n} from '../loop/index.js'\nimport { runReflectiveLoop } from '../loop/run-reflective-loop.js'\n\nimport { compileAgent, type CompiledTool } from './agent-compiler.js'\nimport { type DelegationResult, DelegationError } from './delegation-types.js'\nimport { createSdkAgentStream } from './sdk-adapter.js'\nimport { walkAgentMetadata } from './walk-agent-metadata.js'\n\n// Re-export the delegation value types for backward compatibility — they moved\n// to delegation-types.js to break the orchestrator↔loop import cycle (G1).\nexport { BudgetExceededError, type DelegationResult, DelegationError } from './delegation-types.js'\n\nexport interface DelegateOptions {\n /** Max USD for this sub-agent call. */\n budget?: number\n /** Parent's remaining budget (for clamping). */\n parentBudgetRemaining?: number\n /** Parent's tools (for sharing — sub-agent inherits these). */\n parentTools?: CompiledTool[]\n /** LLM API key (inherited from parent). */\n apiKey?: string\n /** Session ID override (default: crypto.randomUUID for isolation). */\n sessionId?: string\n /** Cancellation — aborts stop the reflective loop from re-entering. */\n signal?: AbortSignal\n // V4-T: per-run config parity with `AgentRunnerRunOptions` — a sub-agent inherits the parent's\n // runtime config (all optional; absent ⇒ today's behavior). Each field is already accepted by\n // `createSdkAgentStream`'s `RuntimeOverrides` / the loop's `RunReflectiveLoopConfig`.\n /** Per-run model override (`?? SubAgent @Agent model`). */\n model?: string\n /** Per-run working directory → `Agent.create({ local: { cwd } })`. */\n cwd?: string\n /** Per-run plugins (e.g. a read-only permission gate for an explore sub-agent). */\n plugins?: PluginsSettings\n /** Per-run provider routing (e.g. OpenRouter). */\n providers?: ProviderRoutingSettings\n /** Per-run sub-agent definitions. */\n agents?: Record<string, AgentDefinition>\n /** Per-run SDK budget tracker (inner tool-loop cap). */\n budgetTracker?: BudgetTracker\n /** Per-run conversation store (cross-round history). */\n conversationStorage?: ConversationStorageAdapter\n /** Per-run pre-built SDK tools forwarded raw (V4-Q). */\n sdkTools?: readonly CustomTool[]\n /** Per-round transient retry (V4-P). */\n retry?: RetryOptions\n /** Custom between-round reflection (default: ladder for `plan-act-reflect`, else noop). */\n reflection?: ReflectionStrategy\n /** Per-run loop-ceiling override (`?? SubAgent @MainLoop maxIterations`). */\n maxIterations?: number\n}\n\n/** Validate API key and throw DelegationError if missing. */\nfunction requireApiKey(opts: DelegateOptions, agentName: string): string {\n const apiKey = opts.apiKey ?? ''\n if (!apiKey) {\n throw new DelegationError(agentName, 'No API key provided. Pass apiKey in DelegateOptions.')\n }\n return apiKey\n}\n\n/** Merge parent tools with sub-agent tools (sub wins on collision). */\nfunction mergeTools(parentTools: CompiledTool[], subTools: CompiledTool[]): CompiledTool[] {\n const subToolNames = new Set(subTools.map((t) => t.name))\n const inherited = parentTools.filter((t) => !subToolNames.has(t.name))\n return [...inherited, ...subTools]\n}\n\n/**\n * Delegate a task to a sub-agent and collect its result.\n *\n * - Budget clamping: `min(parentBudgetRemaining, budget)` (D4)\n * - Tool sharing: parent tools merged with sub-agent tools (sub wins on collision)\n * - Toolbox auto-instantiation: sub-agent toolboxes instantiated without DI (EC-1)\n * - Session isolation: each delegation gets a unique session ID (EC-4)\n * - `@MainLoop` strategy runtime: routes through `runReflectiveLoop` (the same loop\n * `AgentRunner.run` uses — one runtime for both on-ramps, ADR D4). The runtime\n * metric (`THEO_AGENT_MAINLOOP_RUNTIME_APPLIED`) + typed-error + cumulative budget\n * all live in the shared driver, so they fire identically on both paths.\n */\nexport async function delegate(\n SubAgentClass: Function,\n message: string,\n opts: DelegateOptions = {},\n): Promise<DelegationResult> {\n const apiKey = requireApiKey(opts, SubAgentClass.name)\n\n // 1. Walk + compile sub-agent (EC-1: auto-instantiate toolboxes)\n const walk = walkAgentMetadata(SubAgentClass, [])\n const toolboxInstances = new Map(\n walk.toolboxes.map((tb) => [tb.class, new (tb.class as new () => object)()]),\n )\n const compiled = compileAgent(walk, toolboxInstances)\n\n // 2. Merge parent tools + clamp budget (D4)\n const allTools = mergeTools(opts.parentTools ?? [], compiled.tools)\n const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity)\n\n // 3. Build the stream factory (the model call stays in the SDK — ADR 0031) + session.\n // V4-T: forward the per-run config (parity with AgentRunner.stream); model opt wins over the\n // decorator; absent fields ⇒ no key (byte-identical to the pre-V4-T `{ model }`-only override).\n const streamFactory = createSdkAgentStream(compiled, allTools, apiKey, {\n model: opts.model ?? walk.agentConfig.model,\n cwd: opts.cwd,\n plugins: opts.plugins,\n providers: opts.providers,\n agents: opts.agents,\n budgetTracker: opts.budgetTracker,\n conversationStorage: opts.conversationStorage,\n sdkTools: opts.sdkTools,\n })\n const sessionId = opts.sessionId ?? `sub-${crypto.randomUUID()}`\n\n // 4. Resolve the @MainLoop strategy + reflection, then run the shared reflective loop.\n // V4-T: per-run maxIterations override (parity with AgentRunner.stream); absent ⇒ decorator ceiling.\n const loopStrategy = resolveLoopStrategy(\n walk.mainLoop.strategy,\n opts.maxIterations ?? walk.mainLoop.maxIterations,\n )\n // V4-T: a custom reflection wins; absent ⇒ the strategy-derived default (ladder/noop).\n const reflection =\n opts.reflection ??\n (loopStrategy.name === 'plan-act-reflect' ? ladderReflectionStrategy : noopReflectionStrategy)\n return runReflectiveLoop(streamFactory, message, sessionId, {\n loop: loopStrategy,\n reflection,\n budget,\n agentName: SubAgentClass.name,\n signal: opts.signal,\n retry: opts.retry, // V4-T: per-round transient retry (V4-P) on the delegate path\n })\n}\n","/**\n * Agent manifest generator — build-time JSON describing all agents, tools, guards, policies.\n *\n * Feeds: theokit agents list/inspect, TheoCloud deploy, UI agent consoles.\n */\nimport type { AgentWalkResult } from '../bridge/walk-agent-metadata.js'\n\nexport interface AgentManifest {\n version: '1.0'\n generatedAt: string\n agents: AgentManifestEntry[]\n}\n\nexport interface AgentManifestEntry {\n name: string\n route: string\n model?: string\n stream: boolean\n mainLoop: {\n method: string\n strategy: string\n }\n guards: string[]\n interceptors: string[]\n tools: AgentManifestTool[]\n gateway?: {\n platforms: string[]\n sessionStrategy: string\n }\n subAgents: string[]\n memory?: { provider: string; embeddings: boolean; fts: boolean; scope: string }\n skills?: string[]\n mcpServers?: string[]\n}\n\nexport interface AgentManifestTool {\n name: string\n description: string\n risk?: string\n approval: boolean\n capabilities?: string[]\n trace: boolean\n audit: boolean\n}\n\n/**\n * Generate a serializable agent manifest from walked metadata.\n * All Function references are converted to string names for JSON safety.\n */\nexport function generateAgentManifest(walkResults: AgentWalkResult[]): AgentManifest {\n return {\n version: '1.0',\n generatedAt: new Date().toISOString(),\n agents: walkResults.map((r) => ({\n name: r.agentConfig.name,\n route: r.route,\n model: r.agentConfig.model,\n stream: r.agentConfig.stream ?? true,\n mainLoop: {\n method: String(r.mainLoop.propertyKey),\n strategy: r.mainLoop.strategy,\n },\n guards: r.guards.map((g) => g.name),\n interceptors: r.interceptors.map((i) => i.name),\n tools: r.toolboxes.flatMap((tb) =>\n tb.tools.map((t) => ({\n name: tb.namespace ? `${tb.namespace}.${t.config.name}` : t.config.name,\n description: t.config.description,\n risk: t.config.risk,\n approval: t.approval !== undefined,\n capabilities: t.capabilities,\n trace: t.trace,\n audit: t.audit,\n })),\n ),\n gateway: r.gateway\n ? { platforms: r.gateway.platforms, sessionStrategy: r.gateway.sessionStrategy ?? 'per-user' }\n : undefined,\n subAgents: r.subAgentClasses.map((cls) => cls.name),\n memory: r.memory\n ? {\n provider: r.memory.provider ?? 'built-in',\n embeddings: r.memory.embeddings ?? false,\n fts: r.memory.fts ?? false,\n scope: r.memory.scope ?? 'per-user',\n }\n : undefined,\n skills: r.skills?.include,\n mcpServers: r.mcpServers ? Object.keys(r.mcpServers) : undefined,\n })),\n }\n}\n","/**\n * agentsPlugin() — TheoKit dev-server plugin for agent routes.\n *\n * Mirrors httpDecoratorsPlugin() pattern. Registers agent HTTP endpoints\n * (POST /chat, GET /runs/:id) via the TheoKit plugin hook system.\n *\n * Per ADR D6: structural { name, register } shape (no compile-time theokit dep).\n */\nimport 'reflect-metadata'\n\nimport { compileAgent, type CompiledAgentOptions } from './bridge/agent-compiler.js'\nimport { generateAgentRoutes, type AgentRoute } from './bridge/agent-route-generator.js'\nimport type { StreamEvent } from './bridge/agent-sse-handler.js'\nimport {\n walkAgentMetadata,\n validateUniqueRoutes,\n type AgentWalkResult,\n} from './bridge/walk-agent-metadata.js'\nimport { getMixins } from './decorators/mixin.js'\n\nexport interface AgentsPluginOptions {\n /** Agent classes decorated with @Agent(). */\n agents: Function[]\n /** Toolbox classes (or use @Mixin on agents). */\n toolboxes?: Function[]\n /** Factory that creates agent runs — bridges to SDK Agent.create() + agent.send(). */\n createRunFactory?: (\n compiled: CompiledAgentOptions,\n walkResult: AgentWalkResult,\n ) => (message: string, sessionId: string) => AsyncIterable<StreamEvent>\n}\n\ninterface PluginApp {\n addHook(name: string, fn: (ctx: { request: Request }) => Promise<Response | undefined>): void\n}\n\n/**\n * Create a TheoKit plugin that mounts agent routes.\n * Web Standard Request/Response — runtime-agnostic.\n */\nexport function agentsPlugin(opts: AgentsPluginOptions) {\n let routes: CompiledRoute[] | null = null\n\n return {\n name: '@theokit/agents',\n\n register(app: PluginApp) {\n app.addHook('onRequest', async (pluginCtx) => {\n routes ??= initRoutes(opts)\n\n const request = pluginCtx.request\n const url = new URL(request.url)\n const method = request.method.toUpperCase()\n\n const matched = matchRoute(routes, method, url.pathname)\n if (!matched) return // fall through\n\n return matched.handler(request)\n })\n },\n }\n}\n\n/** Initialize routes from agent metadata (once). */\nfunction initRoutes(opts: AgentsPluginOptions): CompiledRoute[] {\n const allRoutes: AgentRoute[] = []\n const walkResults: AgentWalkResult[] = []\n\n for (const AgentClass of opts.agents) {\n // Resolve toolboxes: explicit + @Mixin\n const mixins = getMixins(AgentClass)\n const toolboxes = [...(opts.toolboxes ?? []), ...mixins]\n\n const walkResult = walkAgentMetadata(AgentClass, toolboxes)\n walkResults.push(walkResult)\n\n const compiled = compileAgent(walkResult, new Map())\n const createRun = opts.createRunFactory\n ? opts.createRunFactory(compiled, walkResult)\n : defaultCreateRun(compiled)\n\n const agentRoutes = generateAgentRoutes({\n walkResult,\n compiledOptions: compiled,\n createRun,\n })\n\n allRoutes.push(...agentRoutes)\n }\n\n validateUniqueRoutes(walkResults)\n return compileRoutePatterns(allRoutes)\n}\n\n/** Default run factory — returns a mock stream when SDK not wired. */\nfunction defaultCreateRun(compiled: CompiledAgentOptions) {\n return async function* (_message: string, _sessionId: string): AsyncGenerator<StreamEvent> {\n await Promise.resolve() // yield to event loop for async contract\n yield {\n type: 'run_started',\n runId: `run-${Date.now()}`,\n agentName: compiled.model ?? 'unknown',\n }\n yield {\n type: 'error',\n code: 'SDK_NOT_WIRED',\n message:\n 'No createRunFactory provided — wire @theokit/sdk Agent.create() to enable real agent execution.',\n retryable: false,\n }\n }\n}\n\ninterface CompiledRoute extends AgentRoute {\n regex?: RegExp\n}\n\n/** Pre-compile route patterns for efficient matching. */\nfunction compileRoutePatterns(routes: AgentRoute[]): CompiledRoute[] {\n return routes.map((r) => {\n if (!r.path.includes(':')) return r\n const regexSource = r.path.replace(/:[^/]+/g, '[^/]+')\n return { ...r, regex: RegExp(`^${regexSource}$`) }\n })\n}\n\n/** Simple route matcher — checks method + path prefix. */\nfunction matchRoute(\n routes: CompiledRoute[],\n method: string,\n pathname: string,\n): CompiledRoute | undefined {\n return routes.find((r) => {\n if (r.method !== method) return false\n if (r.regex) return r.regex.test(pathname)\n return r.path === pathname\n })\n}\n"],"mappings":"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","names":["createAgentExecutionContext","base","agent","run","toolCall","getRequest","getUrl","getClass","getMethodName","getAgent","getRun","getToolCall","isAgentContext","ctx","STRATEGY_KNOBS","compileContextWindow","options","context","maxTokens","opts","metadataOnlyKnobs","filter","knob","undefined","UNMAPPED_KNOBS","projectContextMetadataOnlyKnobs","options","opts","filter","knob","undefined","compileProjectContext","base","promptCtx","resolvedBase","cwd","buildEnvContext","buildRepoMap","readProjectInstructions","env","repoMap","ignore","ignorePatterns","instructions","content","Boolean","join","Reflector","USE_GUARDS","Symbol","for","USE_INTERCEPTORS","USE_FILTERS","AgentWarningCode","INTERCEPTOR_METADATA_ONLY","FILTER_METADATA_ONLY","BUDGET_TOP_LEVEL_METADATA_ONLY","CONTEXT_STRATEGY_METADATA_ONLY","PROJECT_CONTEXT_KNOB_METADATA_ONLY","reflectorInstance","Reflector","walkToolbox","ToolboxClass","config","getMeta","TOOLBOX_CONFIG","methods","TOOL_METHODS","classGuards","tools","map","propertyKey","toolConfig","TOOL_CONFIG","Error","name","String","methodGuards","ref","approvalVal","get","RequiresApproval","traceVal","Trace","auditVal","Audit","guards","approval","undefined","capabilities","budget","trace","audit","class","namespace","warnUnmappedDecoratorKnobs","agentName","contextWindow","projectContext","metadataOnlyKnobs","compileContextWindow","length","console","warn","join","unmapped","projectContextMetadataOnlyKnobs","agentWalkCache","WeakMap","walkAgentMetadata","AgentClass","toolboxClasses","cached","agentConfig","AGENT_CONFIG","mainLoop","AGENT_MAIN_LOOP","interceptors","filters","agentBudget","Budget","toolboxes","gateway","getGatewayConfig","subAgentClasses","getSubAgents","memory","getMemoryConfig","skills","getSkillsConfig","mcpServers","getMcpConfig","getContextWindowConfig","getProjectContextConfig","compaction","getCompactionConfig","result","route","set","validateUniqueRoutes","results","seen","Map","r","existing","compileSkills","options","autoDiscover","autoInject","enabled","include","compileTools","toolboxes","toolboxInstances","tools","tb","instance","get","class","Error","name","tool","handler","propertyKey","String","namespace","config","push","description","inputSchema","input","call","compileSubAgents","subAgentClasses","agents","cls","getAgentConfig","model","systemPrompt","compileAgent","walkResult","Map","agentConfig","reasoningEffort","parseThinkTags","stripToolDialect","recoverLeakedToolCalls","memory","skills","compileSkills","undefined","context","contextWindow","compileContextWindow","projectContext","mcpServers","maxIterations","mainLoop","timeoutMs","stream","encoder","TextEncoder","streamAgentResponse","eventStream","stream","ReadableStream","start","controller","closed","safeEnqueue","chunk","enqueue","event","data","JSON","stringify","frame","type","encode","err","errorEvent","error","message","Error","close","Response","status","headers","isTextDelta","e","type","isToolCall","isPartialToolCall","isToolResult","isDone","isError","isApprovalRequired","generateAgentRoutes","ctx","walkResult","createRun","getRun","basePath","route","replace","routes","push","method","path","handler","request","body","json","message","length","Response","JSON","stringify","error","code","status","headers","rawSessionId","sessionId","Date","now","streamAgentResponse","url","URL","runId","pathname","split","pop","run","asString","value","fallback","serializeToolOutput","undefined","JSON","stringify","toString","translateSystemEvent","msg","runId","type","agentName","agent_id","model","translateAssistantEvent","events","message","content","Array","isArray","block","b","text","push","callId","id","Date","now","toolName","name","input","translateToolCallEvent","status","call_id","output","result","durationMs","isError","args","arguments","translateStatusEvent","s","usage","inputTokens","outputTokens","totalTokens","cost","code","retryable","translateSdkEvent","translateInteractionUpdate","update","toolCall","buildModelSelection","modelId","effort","id","params","value","TAG","OPEN","CLOSE","heldPrefixLength","s","delim","max","Math","min","length","k","slice","createThinkTagExtractor","mode","buffer","write","chunk","out","idx","indexOf","content","push","kind","keep","emit","end","seg","segmentToEvent","type","extractThinkTagStream","source","extractor","event","OPEN","CLOSE","heldPrefixLength","s","delim","max","Math","min","length","k","slice","createToolDialectStripper","mode","buffer","pendingLeak","write","chunk","out","idx","indexOf","content","push","kind","keep","emit","end","leftover","stripToolDialectStream","source","stripper","event","type","seg","assembleM8CreateOptions","compiled","options","applied","base","systemPrompt","skills","local","settingSources","push","context","projectContext","compileProjectContext","undefined","realUsageDone","result","t0","u","usage","inputTokens","outputTokens","type","totalTokens","reasoningTokens","cacheReadTokens","cacheWriteTokens","durationMs","Date","now","cost","amount","withLeakedDialectRecovery","providers","routes","map","route","extractToolCallsFromContent","buildExtraCreateOptions","overrides","recoverLeakedToolCalls","extra","plugins","agents","budgetTracker","createAsyncQueue","items","wake","closed","item","close","Symbol","asyncIterator","length","next","shift","Promise","resolve","streamCallId","ev","callId","isDuplicatedByDelta","state","sawTextDelta","sawThinkingDelta","id","emittedToolCallIds","has","emittedToolResultIds","mergeDeltaStream","queue","openStream","runId","pumpError","pump","stream","msg","kind","catch","thrown","event","out","translateSdkEvent","sawError","createDeltaSink","Set","onDelta","d","translateInteractionUpdate","update","add","resolveTextTransformFlags","parseThinkTags","stripToolDialect","applyTextTransforms","events","opts","extractThinkTagStream","stripToolDialectStream","buildSdkTools","compiledTools","defineTool","extraSdkTools","t","name","description","inputSchema","handler","createSdkAgentStream","apiKey","model","reasoningEffort","storage","conversationStorage","message","sessionId","factoryOpts","Agent","InMemoryConversationStorage","sdk","code","retryable","sdkTools","agent","m8","cwd","console","debug","includes","getOrCreate","buildModelSelection","tools","sendPromise","send","disableTools","toolChoice","merged","wait","err","Error","dispose","translateToUIMessageStream","events","opts","type","textOpen","event","id","textId","delta","content","errorText","message","err","String","compactTranscript","z","DEFAULT_KEEP_TOKENS","compactionStrategyConfigSchema","z","object","name","literal","keepTokens","number","int","positive","resolveCompactionStrategy","config","cfg","parse","compact","messages","options","compactTranscript","summarize","marker","summaryTemplate","failSafe","tokenBudgetCompactionStrategy","z","DEFAULT_MAX_ITERATIONS","loopStrategyConfigSchema","z","object","name","enum","maxIterations","number","int","min","resolveLoopStrategy","strategy","cfg","parse","shouldContinue","outcome","round","finishReason","z","reflectionStrategyConfigSchema","object","name","string","min","ladderReflectionStrategy","reflect","outcome","finishReason","feedback","round","continue","noopReflectionStrategy","BudgetExceededError","Error","agentName","actualCost","budgetLimit","toFixed","name","DelegationError","cause","message","String","asString","value","fallback","asNumber","NO_PROGRESS_THRESHOLD","MAINLOOP_METRIC","TOOL_CALLS","STEP_LIMIT_HINT","stableStringify","undefined","JSON","stringify","Array","isArray","map","join","obj","entries","Object","keys","sort","a","b","localeCompare","k","roundSignature","toolCalls","tc","name","input","terminalReason","reflectionContinue","roundReason","round","maxIterations","CONTINUE_PROMPT","buildPrompt","message","feedback","hint","continuation","body","consumeRoundOrThrow","inputs","agentName","consumeOneRound","factory","prompt","sessionId","signal","retry","err","BudgetExceededError","DelegationError","accumulateUsage","acc","r","cost","tokens","tokensInput","tokensOutput","reasoningTokens","cacheReadTokens","cacheWriteTokens","finalize","reason","strategyName","rounds","finishReason","console","debug","strategy","terminal","deriveFinishReason","signals","sawError","sawDone","doneFinishReason","sawToolResult","pushToolResult","event","callInputs","id","callId","call","get","push","toolName","output","applyDone","usage","totalTokens","inputTokens","outputTokens","accumulateEvent","type","content","responseText","set","errorMessage","startRound","open","it","Symbol","asyncIterator","first","next","return","withRetry","Map","done","aborted","ceilingRoundFactory","m","s","disableTools","runReflectiveLoopStream","config","loop","reflection","budget","Number","POSITIVE_INFINITY","response","reflectionContext","prevSig","stuck","roundFactory","isFinite","length","sig","outcome","reflectionResult","reflect","continue","shouldContinue","runReflectiveLoop","gen","res","AgentRunner","compiled","agentName","loopStrategy","reflectionStrategy","streamEnabled","compaction","state","builder","AgentClass","AgentRunnerBuilder","stream","message","opts","tools","loop","maxIterations","resolveLoopStrategy","name","streamFactory","createSdkAgentStream","apiKey","model","reasoningEffort","parseThinkTags","stripToolDialect","recoverLeakedToolCalls","cwd","plugins","providers","agents","budgetTracker","conversationStorage","sdkTools","sessionId","crypto","randomUUID","runReflectiveLoopStream","reflection","budget","signal","retry","run","gen","res","next","done","value","reflectionOverride","compactionOverride","strategy","enabled","options","keepTokens","build","walk","walkAgentMetadata","toolboxInstances","Map","toolboxes","map","tb","class","compileAgent","mainLoop","ladderReflectionStrategy","noopReflectionStrategy","compactionDecl","resolveCompactionStrategy","undefined","agentConfig","requireApiKey","opts","agentName","apiKey","DelegationError","mergeTools","parentTools","subTools","subToolNames","Set","map","t","name","inherited","filter","has","delegate","SubAgentClass","message","walk","walkAgentMetadata","toolboxInstances","Map","toolboxes","tb","class","compiled","compileAgent","allTools","tools","budget","Math","min","Infinity","parentBudgetRemaining","streamFactory","createSdkAgentStream","model","agentConfig","cwd","plugins","providers","agents","budgetTracker","conversationStorage","sdkTools","sessionId","crypto","randomUUID","loopStrategy","resolveLoopStrategy","mainLoop","strategy","maxIterations","reflection","ladderReflectionStrategy","noopReflectionStrategy","runReflectiveLoop","loop","signal","retry","generateAgentManifest","walkResults","version","generatedAt","Date","toISOString","agents","map","r","name","agentConfig","route","model","stream","mainLoop","method","String","propertyKey","strategy","guards","g","interceptors","i","tools","toolboxes","flatMap","tb","t","namespace","config","description","risk","approval","undefined","capabilities","trace","audit","gateway","platforms","sessionStrategy","subAgents","subAgentClasses","cls","memory","provider","embeddings","fts","scope","skills","include","mcpServers","Object","keys","agentsPlugin","opts","routes","name","register","app","addHook","pluginCtx","initRoutes","request","url","URL","method","toUpperCase","matched","matchRoute","pathname","handler","allRoutes","walkResults","AgentClass","agents","mixins","getMixins","toolboxes","walkResult","walkAgentMetadata","push","compiled","compileAgent","Map","createRun","createRunFactory","defaultCreateRun","agentRoutes","generateAgentRoutes","compiledOptions","validateUniqueRoutes","compileRoutePatterns","_message","_sessionId","Promise","resolve","type","runId","Date","now","agentName","model","code","message","retryable","map","r","path","includes","regexSource","replace","regex","RegExp","find","test"]}
package/dist/index.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  export { Agent, Artifact, ArtifactOptions, ArtifactResult, Audit, Budget, Checkpoint, CheckpointOptions, CheckpointState, CheckpointStorage, CheckpointStrategy, CommandPermissions, CompactionStrategy, Conversation, ConversationOptions, ConversationStorage, EditFormat, EditFormatType, FilesystemPermissions, Hook, HookEntry, HookPoint, HumanInTheLoop, HumanInTheLoopOptions, MainLoop, Mixin, Model, Observable, ObservableEntry, Policy, RequiresApproval, RequiresCapability, Sandbox, SandboxOptions, SubAgents, TimeoutAction, Tool, Toolbox, Trace, applyDecorators, getAgentConfig, getArtifactConfig, getCheckpointConfig, getConversationConfig, getHooks, getHooksByPoint, getHumanInTheLoopConfig, getMainLoop, getMixins, getObservableByChannel, getObservables, getSandboxConfig, getSubAgents, getToolConfig, getToolMethods, getToolboxConfig, isCommandAllowed, isPathAllowed } from './decorators.js';
2
2
  import { R as ReasoningEffort } from './skills-FcUdNDbn.js';
3
3
  export { A as AgentOptions, a as ApprovalOptions, B as BudgetOptions, C as Compaction, b as CompactionDecoratorConfig, c as ContextCompactionStrategy, d as ContextWindow, e as ContextWindowOptions, G as Gateway, f as GatewayOptions, I as IndexStrategy, M as MCP, g as MainLoopMeta, h as MainLoopOptions, i as McpServerConfig, j as McpServersMap, k as Memory, l as MemoryOptions, m as MemoryProvider, n as MemoryScope, P as PlatformName, o as PolicyHandler, p as ProjectContext, q as ProjectContextOptions, r as RelevanceStrategy, S as SessionStrategy, s as Skills, t as SkillsOptions, T as ToolOptions, u as ToolboxOptions, v as getCompactionConfig, w as getContextWindowConfig, x as getGatewayConfig, y as getMcpConfig, z as getMemoryConfig, D as getProjectContextConfig, E as getSkillsConfig, F as resolveSessionId } from './skills-FcUdNDbn.js';
4
- import { S as StreamEvent, L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, a as CompiledTool, D as DelegationResult } from './bridge-entry-SOr2jwm3.js';
5
- export { A as AgentExecutionContext, b as AgentManifest, c as AgentManifestEntry, d as AgentManifestTool, e as AgentRoute, f as AgentRouteContext, g as AgentRunInfo, h as AgentStreamEvent, i as AgentWalkResult, j as AgentWarningCode, k as AgentsPluginOptions, l as ApprovalRequiredEvent, m as ArtifactChunkEvent, n as ArtifactStartEvent, B as BudgetExceededError, o as CheckpointSavedEvent, p as CompiledContextWindow, q as DEFAULT_MAX_ITERATIONS, r as DelegateOptions, s as DelegationError, t as DoneEvent, E as ErrorEvent, F as FileEditEvent, I as IterationEvent, u as LoopFinishReason, v as LoopOutcome, w as LoopStrategyConfig, x as ReflectionContext, y as ReflectionResult, z as ReflectionStrategyConfig, G as RunStartedEvent, H as SdkMessage, J as Segment, K as StateUpdateEvent, T as TextDeltaEvent, M as ThinkingEvent, N as ToolCallEvent, O as ToolResultEvent, P as ToolWalkResult, Q as ToolboxWalkResult, U as agentsPlugin, V as buildModelSelection, W as compileAgent, X as compileContextWindow, Y as compileProjectContext, Z as compileSkills, _ as compileTools, $ as createAgentExecutionContext, a0 as createSdkAgentStream, a1 as createThinkTagExtractor, a2 as delegate, a3 as extractThinkTagStream, a4 as generateAgentManifest, a5 as generateAgentRoutes, a6 as isAgentContext, a7 as isApprovalRequired, a8 as isDone, a9 as isError, aa as isTextDelta, ab as isToolCall, ac as isToolResult, ad as ladderReflectionStrategy, ae as loopStrategyConfigSchema, af as noopReflectionStrategy, ag as projectContextMetadataOnlyKnobs, ah as reflectionStrategyConfigSchema, ai as resolveLoopStrategy, aj as streamAgentResponse, ak as translateSdkEvent, al as validateUniqueRoutes, am as walkAgentMetadata } from './bridge-entry-SOr2jwm3.js';
4
+ import { S as StreamEvent, L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, a as CompiledTool, D as DelegationResult } from './bridge-entry-QmUEnkn7.js';
5
+ export { A as AgentExecutionContext, b as AgentManifest, c as AgentManifestEntry, d as AgentManifestTool, e as AgentRoute, f as AgentRouteContext, g as AgentRunInfo, h as AgentStreamEvent, i as AgentWalkResult, j as AgentWarningCode, k as AgentsPluginOptions, l as ApprovalRequiredEvent, m as ArtifactChunkEvent, n as ArtifactStartEvent, B as BudgetExceededError, o as CheckpointSavedEvent, p as CompiledContextWindow, q as DEFAULT_MAX_ITERATIONS, r as DelegateOptions, s as DelegationError, t as DoneEvent, E as ErrorEvent, F as FileEditEvent, I as IterationEvent, u as LoopFinishReason, v as LoopOutcome, w as LoopStrategyConfig, P as PartialToolCallEvent, x as ReflectionContext, y as ReflectionResult, z as ReflectionStrategyConfig, G as RunStartedEvent, H as SdkMessage, J as Segment, K as StateUpdateEvent, T as TextDeltaEvent, M as ThinkingEvent, N as ToolCallEvent, O as ToolResultEvent, Q as ToolWalkResult, U as ToolboxWalkResult, V as agentsPlugin, W as buildModelSelection, X as compileAgent, Y as compileContextWindow, Z as compileProjectContext, _ as compileSkills, $ as compileTools, a0 as createAgentExecutionContext, a1 as createSdkAgentStream, a2 as createThinkTagExtractor, a3 as delegate, a4 as extractThinkTagStream, a5 as generateAgentManifest, a6 as generateAgentRoutes, a7 as isAgentContext, a8 as isApprovalRequired, a9 as isDone, aa as isError, ab as isPartialToolCall, ac as isTextDelta, ad as isToolCall, ae as isToolResult, af as ladderReflectionStrategy, ag as loopStrategyConfigSchema, ah as noopReflectionStrategy, ai as projectContextMetadataOnlyKnobs, aj as reflectionStrategyConfigSchema, ak as resolveLoopStrategy, al as streamAgentResponse, am as translateSdkEvent, an as translateToUIMessageStream, ao as validateUniqueRoutes, ap as walkAgentMetadata } from './bridge-entry-QmUEnkn7.js';
6
6
  import { PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition, BudgetTracker, ConversationStorageAdapter, CustomTool } from '@theokit/sdk';
7
7
  import { RetryOptions } from '@theokit/sdk/retry';
8
8
  import { CompressibleMessage } from '@theokit/sdk/compaction';
9
9
  export { CompressibleMessage } from '@theokit/sdk/compaction';
10
10
  import { z } from 'zod';
11
11
  import '@theokit/http';
12
+ import 'ai';
12
13
 
13
14
  /**
14
15
  * TranscriptCompactionStrategy — a named, callable transcript-compaction authoring layer
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ import {
55
55
  isApprovalRequired,
56
56
  isDone,
57
57
  isError,
58
+ isPartialToolCall,
58
59
  isTextDelta,
59
60
  isToolCall,
60
61
  isToolResult,
@@ -68,9 +69,10 @@ import {
68
69
  streamAgentResponse,
69
70
  tokenBudgetCompactionStrategy,
70
71
  translateSdkEvent,
72
+ translateToUIMessageStream,
71
73
  validateUniqueRoutes,
72
74
  walkAgentMetadata
73
- } from "./chunk-R7LKDSBF.js";
75
+ } from "./chunk-QR5PFBYT.js";
74
76
  import {
75
77
  Agent,
76
78
  Audit,
@@ -181,6 +183,7 @@ export {
181
183
  isCommandAllowed,
182
184
  isDone,
183
185
  isError,
186
+ isPartialToolCall,
184
187
  isPathAllowed,
185
188
  isTextDelta,
186
189
  isToolCall,
@@ -196,6 +199,7 @@ export {
196
199
  streamAgentResponse,
197
200
  tokenBudgetCompactionStrategy,
198
201
  translateSdkEvent,
202
+ translateToUIMessageStream,
199
203
  validateUniqueRoutes,
200
204
  walkAgentMetadata
201
205
  };