@dudko.dev/agent-web 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/llm/generate.ts","../src/llm/util.ts","../src/memory/compress.ts","../src/providers/types.ts","../src/providers/registry.ts","../src/prompts.ts","../src/tools/mode.ts","../src/tools/types.ts","../src/tools/prompted.ts","../src/llm/tool-loop.ts","../src/agent/loop-types.ts","../src/parse.ts","../src/agent/internal.ts","../src/agent/executor.ts","../src/agent/schemas.ts","../src/agent/planner.ts","../src/agent/replanner.ts","../src/agent/synthesizer.ts","../src/logger.ts","../src/agent/runner.ts","../src/providers/capabilities.ts","../src/secrets/store.ts","../src/tools/define.ts","../src/memory/store.ts","../src/memory/sessions.ts"],"sourcesContent":["import type { IStepResult } from './agent/loop-types.js'\nimport type { ContextStore } from './memory/store.js'\nimport type { AgentLoggerSink, LogLevel } from './logger.js'\nimport type { ModelInput, StageInput } from './providers/types.js'\nimport type { Prompts } from './prompts.js'\nimport type { CredentialStore } from './secrets/store.js'\nimport type { AgentToolSet } from './tools/types.js'\n\n/** Force a tool-calling strategy, or let the agent pick per model ('auto'). */\nexport type ToolMode = 'auto' | 'native' | 'prompted'\n\n/**\n * When to consult the replanner after an executed step (given `replan` is on):\n * 'failure' — after a blocked step or a failed tool call (default);\n * 'always' — after every step, so the replanner can react to problems the host\n * surfaces via `describeState` (one extra model call per step);\n * predicate — decides per step result; closes over host state if needed, and\n * falls back to 'failure' behaviour if it throws.\n */\nexport type ReplanTrigger =\n 'failure' | 'always' | ((result: IStepResult) => boolean | Promise<boolean>)\n\n/**\n * 'all' — the executor sees the full ToolSet on every step.\n * 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner\n * must populate them). Empty means a reasoning-only step.\n */\nexport type ToolSelectionStrategy = 'all' | 'plan-narrowed'\n\n/** Per-phase generation budgets (max output tokens). */\nexport interface PhaseBudgets {\n planner?: number\n executor?: number\n replanner?: number\n synthesizer?: number\n}\n\nexport interface BrowserAgentConfig {\n /** The default (executor) model: a ready AI SDK model, or a ProviderModelSpec to resolve. */\n model: ModelInput\n /** Optional per-stage model overrides. A partial override inherits base provider/creds. */\n planner?: StageInput\n synthesizer?: StageInput\n /** Fetches API keys for ProviderModelSpec models. Default: none (inline keys only). */\n credentials?: CredentialStore\n /** Propagated to the openai-compatible provider name and the MCP client. */\n clientName?: string\n\n /** Host tools the executor may call (an AI SDK ToolSet; use defineTool). */\n tools?: AgentToolSet\n /** Whitelist: only these tool names from `tools` are mounted (default: all). */\n availableTools?: string[]\n /** Blacklist: these tool names are removed after the whitelist is applied. */\n excludedTools?: string[]\n /** Force native/prompted tool-calling; 'auto' picks per model (default 'auto'). */\n toolMode?: ToolMode\n toolSelectionStrategy?: ToolSelectionStrategy\n\n /** Prepended to every phase's system prompt. */\n systemPrompt?: string\n /** Override any phase prompt builder. */\n prompts?: Partial<Prompts>\n /** Serialize the host's current world state into prompt context (grounding). */\n describeState?: () => string | Promise<string>\n\n /**\n * Persist the transcript (e.g. new IndexedDBStore()). The last few messages\n * are also read back into the planner prompt, so follow-up goals can refer\n * to earlier turns.\n */\n memory?: ContextStore\n sessionId?: string\n\n /** Hard cap on executed steps incl. replans (default 8). */\n maxIterations?: number\n /** Cap on tool-calling rounds inside one executor call, both modes (default 4). */\n maxStepsPerTask?: number\n /** Cap on replanner \"revise\" decisions per run (default 2). */\n maxRevisions?: number\n /** Per-call timeout so a hang can't freeze a run (default 120000). */\n chatTimeoutMs?: number\n budgets?: PhaseBudgets\n temperature?: number\n\n /** Master switch for the replan phase (default true). */\n replan?: boolean\n /** What triggers the replanner when it is on (default 'failure'). */\n replanAfter?: ReplanTrigger\n /** Write a final natural-language summary (default true). */\n synthesize?: boolean\n /** Compress stored history past this many chars (0 = off, default 12000). */\n compressAfterChars?: number\n\n /** Verbosity: 'silent' | 'error' | 'warn' (default) | 'info' | 'debug'. */\n logLevel?: LogLevel\n /** Console-like sink the logs go to (default: the global console). */\n logger?: AgentLoggerSink\n}\n\nexport interface ResolvedConfig {\n clientName: string\n sessionId: string\n toolMode: ToolMode\n toolSelectionStrategy: ToolSelectionStrategy\n maxIterations: number\n maxStepsPerTask: number\n maxRevisions: number\n chatTimeoutMs: number\n budgets: Required<PhaseBudgets>\n temperature: number | undefined\n replan: boolean\n replanAfter: ReplanTrigger\n synthesize: boolean\n compressAfterChars: number\n logLevel: LogLevel\n}\n\nexport const resolveConfig = (c: BrowserAgentConfig): ResolvedConfig => ({\n clientName: c.clientName ?? 'agent-web',\n sessionId: c.sessionId ?? 'default',\n toolMode: c.toolMode ?? 'auto',\n toolSelectionStrategy: c.toolSelectionStrategy ?? 'all',\n maxIterations: c.maxIterations ?? 8,\n maxStepsPerTask: c.maxStepsPerTask ?? 4,\n maxRevisions: c.maxRevisions ?? 2,\n chatTimeoutMs: c.chatTimeoutMs ?? 120_000,\n budgets: {\n planner: c.budgets?.planner ?? 800,\n executor: c.budgets?.executor ?? 1200,\n replanner: c.budgets?.replanner ?? 400,\n synthesizer: c.budgets?.synthesizer ?? 400,\n },\n temperature: c.temperature,\n replan: c.replan ?? true,\n replanAfter: c.replanAfter ?? 'failure',\n synthesize: c.synthesize ?? true,\n compressAfterChars: c.compressAfterChars ?? 12_000,\n logLevel: c.logLevel ?? 'warn',\n})\n","import {\n generateObject,\n generateText,\n streamText,\n type LanguageModel,\n type ModelMessage,\n type ToolSet,\n} from 'ai'\nimport type { ZodType } from 'zod'\nimport { promptOf, timeoutSignal } from './util.js'\n\n/** Options shared by the low-level generation helpers. Provide `prompt` OR `messages`. */\nexport interface GenerateOptions {\n system?: string\n prompt?: string\n messages?: ModelMessage[]\n tools?: ToolSet\n maxOutputTokens?: number\n temperature?: number\n abortSignal?: AbortSignal\n /** Time-box the call; combined with `abortSignal` (0/undefined = no timeout). */\n timeoutMs?: number\n}\n\n/**\n * One-shot text generation. Thin, provider-agnostic wrapper over the AI SDK's\n * `generateText` — the same call works against a cloud model, a local WebLLM\n * model, or Chrome/Edge built-in AI. Returns the full AI SDK result (`.text`,\n * `.usage`, `.toolCalls`, `.steps`, …).\n */\nexport const generate = (\n model: LanguageModel,\n opts: GenerateOptions = {},\n): ReturnType<typeof generateText> =>\n generateText({\n model,\n system: opts.system,\n ...promptOf(opts),\n tools: opts.tools,\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n })\n\n/** Streaming text generation. Returns the AI SDK `streamText` result (`.textStream`, `.fullStream`). */\nexport const stream = (\n model: LanguageModel,\n opts: GenerateOptions = {},\n): ReturnType<typeof streamText> =>\n streamText({\n model,\n system: opts.system,\n ...promptOf(opts),\n tools: opts.tools,\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n })\n\n/**\n * Structured output constrained to a Zod schema, via the AI SDK's\n * `generateObject`. Cloud models and WebLLM both support this; tiny local\n * models can be unreliable — the agent's prompted mode is the fallback.\n * Returns the AI SDK result (`.object`, `.usage`).\n */\nexport const generateStructured = <OBJECT>(\n model: LanguageModel,\n schema: ZodType<OBJECT>,\n opts: GenerateOptions = {},\n) =>\n generateObject({\n model,\n schema,\n system: opts.system,\n ...promptOf(opts),\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n })\n","import type { ModelMessage } from 'ai'\nimport type { IUsage } from '../agent/loop-types.js'\n\n/** Truncate to `max` characters, ellipsising the overflow. */\nexport const clip = (s: string, max: number): string =>\n s.length > max ? `${s.slice(0, max - 1)}…` : s\n\n/**\n * The AI SDK prompt is `{ prompt } XOR { messages }` — passing both keys (even\n * with one undefined) breaks the discriminated union. Pick exactly one.\n */\nexport const promptOf = (opts: {\n prompt?: string\n messages?: ModelMessage[]\n}): { prompt: string } | { messages: ModelMessage[] } =>\n opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? '' }\n\n/** Normalise the AI SDK usage shape (fields can be undefined) into IUsage. */\nexport const normalizeUsage = (u?: {\n inputTokens?: number\n outputTokens?: number\n totalTokens?: number\n}): IUsage => {\n const inputTokens = u?.inputTokens ?? 0\n const outputTokens = u?.outputTokens ?? 0\n return {\n inputTokens,\n outputTokens,\n totalTokens: u?.totalTokens ?? inputTokens + outputTokens,\n }\n}\n\n/**\n * Combine the caller's AbortSignal with a timeout so a hung generation can't\n * freeze a run. Returns the original signal when no timeout is set. Uses the\n * standard `AbortSignal.timeout`/`AbortSignal.any` (Node ≥ 20, modern browsers).\n */\nexport const timeoutSignal = (signal?: AbortSignal, ms?: number): AbortSignal | undefined => {\n if (!ms || ms <= 0) return signal\n const timeout = AbortSignal.timeout(ms)\n if (!signal) return timeout\n return typeof AbortSignal.any === 'function' ? AbortSignal.any([signal, timeout]) : signal\n}\n","import type { LanguageModel } from 'ai'\nimport { generate } from '../llm/generate.js'\nimport type { StoredMessage } from './store.js'\n\nexport interface CompressOptions {\n /** Compress once the transcript exceeds this many characters (0 = never). */\n maxChars?: number\n /** How many most-recent messages to keep verbatim. */\n keepRecent?: number\n /** Time-box the summarisation call so it can never hang the caller. */\n timeoutMs?: number\n abortSignal?: AbortSignal\n}\n\nconst totalChars = (msgs: StoredMessage[]): number => msgs.reduce((n, m) => n + m.content.length, 0)\n\n/**\n * When the transcript grows too long, summarise everything except the last\n * `keepRecent` messages into a single system message (via the model), so the\n * session stays within the model's context window. Returns the same array\n * unchanged when no compression is needed; never throws.\n */\nexport const compressHistory = async (\n messages: StoredMessage[],\n model: LanguageModel,\n opts: CompressOptions = {},\n): Promise<StoredMessage[]> => {\n const maxChars = opts.maxChars ?? 12_000\n const keepRecent = opts.keepRecent ?? 6\n if (maxChars <= 0 || messages.length <= keepRecent + 1 || totalChars(messages) <= maxChars) {\n return messages\n }\n const head = messages.slice(0, messages.length - keepRecent)\n const tail = messages.slice(messages.length - keepRecent)\n const transcript = head\n .map((m) => `${m.role}: ${m.content}`)\n .join('\\n')\n .slice(0, 8000)\n try {\n const result = await generate(model, {\n system:\n 'Summarize the following conversation into a compact set of durable facts and decisions. Output plain text only.',\n prompt: transcript,\n maxOutputTokens: 400,\n timeoutMs: opts.timeoutMs,\n abortSignal: opts.abortSignal,\n })\n const clean = (result.text || '').trim()\n if (!clean) return messages\n const summaryMsg: StoredMessage = {\n role: 'system',\n content: `Summary of earlier conversation:\\n${clean}`,\n ts: head[0]?.ts,\n }\n return [summaryMsg, ...tail]\n } catch {\n return messages\n }\n}\n","import type { LanguageModel } from 'ai'\n\n/**\n * Providers the browser registry can resolve from a spec. This is deliberately\n * a browser-safe subset of the Node sibling's list: Amazon Bedrock (SigV4\n * signing), Google Vertex (ADC via google-auth-library) and Cloudflare\n * (Worker bindings / process.env) are Node-only and omitted; Azure folds into\n * `openai-compatible`. `web-llm` is the local WebGPU pseudo-provider (no API\n * key). Any other runtime — Chrome/Edge built-in AI, a custom LanguageModel —\n * is passed to the agent directly and never touches this registry.\n */\nexport type ProviderType =\n | 'openai'\n | 'anthropic'\n | 'google'\n | 'openai-compatible'\n | 'xai'\n | 'deepseek'\n | 'gateway'\n | 'web-llm'\n\n/** A model described by provider + id, resolved through the registry (+ vault). */\nexport interface ProviderModelSpec {\n providerType: ProviderType\n /** Model id, e.g. \"gpt-4o-mini\", \"claude-haiku-4-5\", \"Llama-3.2-3B-Instruct-q4f16_1-MLC\". */\n model: string\n /** Provider endpoint override. Required for `openai-compatible`; a proxy URL for the rest. */\n baseURL?: string\n /** Id under which the API key is stored in the CredentialStore / vault. Preferred. */\n credentialRef?: string\n /**\n * Dev-only inline API key. Prefer `credentialRef` so the key lives encrypted\n * in the vault, not on a long-lived config object. Using this logs a warning.\n */\n apiKey?: string\n /** Extra request headers merged into the provider factory (e.g. a proxy auth header). */\n headers?: Record<string, string>\n /** Escape hatch spread into the SDK factory after baseURL / apiKey / headers. */\n providerOptions?: Record<string, unknown>\n}\n\n/**\n * A per-stage override that inherits the base provider + credentials and\n * changes only the fields it sets (typically just `model`). Distinguished from\n * a full ProviderModelSpec by the absence of `providerType`.\n */\nexport interface StageOverride {\n model?: string\n baseURL?: string\n credentialRef?: string\n apiKey?: string\n headers?: Record<string, string>\n providerOptions?: Record<string, unknown>\n}\n\n/** What a caller hands us for a model: a ready AI SDK model, or a spec to resolve. */\nexport type ModelInput = LanguageModel | ProviderModelSpec\n\n/** A model input, plus the partial-override form usable for per-stage layering. */\nexport type StageInput = ModelInput | StageOverride\n\n/** Outcome of resolving one stage: either a ready model, or a fully-resolved spec. */\nexport type ResolvedStage =\n { type: 'direct'; model: LanguageModel } | { type: 'spec'; spec: ProviderModelSpec }\n\n/** True for a ready AI SDK model: a gateway model-id string or a LanguageModelV* object. */\nexport const isDirectModel = (m: unknown): m is LanguageModel =>\n typeof m === 'string' || (typeof m === 'object' && m !== null && 'specificationVersion' in m)\n\n/** True for a full provider spec (carries the `providerType` discriminator). */\nexport const isProviderSpec = (m: unknown): m is ProviderModelSpec =>\n typeof m === 'object' &&\n m !== null &&\n !isDirectModel(m) &&\n typeof (m as { providerType?: unknown }).providerType === 'string'\n","import type { LanguageModel } from 'ai'\nimport type { CredentialStore } from '../secrets/store.js'\nimport {\n isDirectModel,\n isProviderSpec,\n type ModelInput,\n type ProviderModelSpec,\n type ProviderType,\n type ResolvedStage,\n type StageInput,\n type StageOverride,\n} from './types.js'\n\n// Providers whose endpoint the SDK cannot imply and must be given explicitly.\nconst REQUIRES_BASE_URL: ReadonlySet<ProviderType> = new Set<ProviderType>(['openai-compatible'])\n\n// Providers that authenticate without an API key.\nconst NO_KEY: ReadonlySet<ProviderType> = new Set<ProviderType>(['web-llm'])\n\n// provider -> npm package for the dynamic import and the \"please install X\"\n// message. `gateway` (ships in `ai`) and `web-llm` (its own adapter) are not here.\nconst PROVIDER_PACKAGE: Record<Exclude<ProviderType, 'gateway' | 'web-llm'>, string> = {\n openai: '@ai-sdk/openai',\n anthropic: '@ai-sdk/anthropic',\n google: '@ai-sdk/google',\n 'openai-compatible': '@ai-sdk/openai-compatible',\n xai: '@ai-sdk/xai',\n deepseek: '@ai-sdk/deepseek',\n}\n\nconst loadProvider = async <T>(pkg: string): Promise<T> => {\n try {\n // A variable dynamic import of an optional peer. Both bundler hints are\n // required: without `webpackIgnore` webpack emits \"Critical dependency:\n // the request of a dependency is an expression\" (an error under CI) and\n // tries to build a context module; without `@vite-ignore` Vite warns.\n // Bundlers thus leave the import to the runtime — bundler-less pages map\n // the bare specifier via an import map (see README), and hosts that never\n // use cloud providers (e.g. local WebLLM only) are unaffected.\n return (await import(/* webpackIgnore: true */ /* @vite-ignore */ pkg)) as T\n } catch {\n throw new Error(\n `Provider package \"${pkg}\" is not installed. Add it to your app: npm install ${pkg}`,\n )\n }\n}\n\nconst normalizeSpec = (spec: ProviderModelSpec): ProviderModelSpec => {\n if (REQUIRES_BASE_URL.has(spec.providerType) && !spec.baseURL) {\n throw new Error(`provider \"${spec.providerType}\" requires a baseURL (point it at your server)`)\n }\n return spec\n}\n\n/**\n * Resolve one stage to either a ready model or a fully-resolved spec, layering\n * an optional override on the base:\n * - a direct model (or full spec) override wins outright;\n * - a partial StageOverride inherits the base provider + credentials, changing\n * only the fields it sets (e.g. `{ model: 'gpt-4o-mini' }`);\n * - a full-spec override that switches provider MUST carry its own key\n * (credentialRef/apiKey) — inheriting a key across vendors is a footgun.\n */\nexport const resolveStage = (\n base: ModelInput,\n override: StageInput | undefined,\n stageName: string,\n): ResolvedStage => {\n if (override !== undefined && isDirectModel(override)) {\n return { type: 'direct', model: override }\n }\n if (override !== undefined && isProviderSpec(override)) {\n if (\n isProviderSpec(base) &&\n override.providerType !== base.providerType &&\n !override.credentialRef &&\n !override.apiKey &&\n !NO_KEY.has(override.providerType)\n ) {\n throw new Error(\n `${stageName}: provider \"${override.providerType}\" differs from the base \"${base.providerType}\"; set ${stageName}.credentialRef or apiKey (cross-provider key inheritance is unsafe)`,\n )\n }\n return { type: 'spec', spec: normalizeSpec(override) }\n }\n\n // No override, or a partial StageOverride to layer onto the base.\n if (isDirectModel(base)) {\n if (override && Object.keys(override).length > 0) {\n throw new Error(\n `${stageName}: cannot layer a partial override onto a direct model — pass a full model or ProviderModelSpec for ${stageName}`,\n )\n }\n return { type: 'direct', model: base }\n }\n if (!isProviderSpec(base)) {\n throw new Error(`${stageName}: base model must be a LanguageModel or a ProviderModelSpec`)\n }\n\n const ov = (override ?? {}) as StageOverride\n const merged: ProviderModelSpec = {\n providerType: base.providerType,\n model: ov.model ?? base.model,\n baseURL: ov.baseURL ?? base.baseURL,\n credentialRef: ov.credentialRef ?? base.credentialRef,\n apiKey: ov.apiKey ?? base.apiKey,\n headers: ov.headers ?? base.headers,\n providerOptions: ov.providerOptions ?? base.providerOptions,\n }\n return { type: 'spec', spec: normalizeSpec(merged) }\n}\n\nconst resolveApiKey = async (\n spec: ProviderModelSpec,\n credentials?: CredentialStore,\n): Promise<string | undefined> => {\n if (spec.apiKey) {\n console.warn(\n `[agent-web] using an inline apiKey for provider \"${spec.providerType}\"; prefer credentialRef so the key stays in the encrypted vault`,\n )\n return spec.apiKey\n }\n if (spec.credentialRef) {\n if (!credentials) {\n throw new Error(\n `credentialRef \"${spec.credentialRef}\" is set but no CredentialStore was provided to the agent`,\n )\n }\n const key = await credentials.getApiKey(spec.credentialRef)\n if (!key) {\n throw new Error(\n `no API key found in the CredentialStore for credentialRef \"${spec.credentialRef}\"`,\n )\n }\n return key\n }\n return undefined\n}\n\n/**\n * Turn a resolved stage into an AI SDK `LanguageModel`. Direct models pass\n * through untouched; specs are built by dynamically importing the provider's\n * optional-peer package and fetching the API key from the CredentialStore.\n */\nexport const buildModelFromStage = async (\n resolved: ResolvedStage,\n credentials?: CredentialStore,\n clientName = 'agent-web',\n): Promise<LanguageModel> => {\n if (resolved.type === 'direct') return resolved.model\n const spec = resolved.spec\n const providerOptions = spec.providerOptions ?? {}\n const apiKey = await resolveApiKey(spec, credentials)\n\n switch (spec.providerType) {\n case 'web-llm': {\n const { createWebLLMModel } = await import('./webllm.js')\n return createWebLLMModel(spec.model, providerOptions)\n }\n case 'gateway': {\n // The Vercel AI Gateway ships inside `ai` — no separate peer to install.\n const { createGateway } = await import('ai')\n const provider = createGateway({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'openai': {\n const { createOpenAI } = await loadProvider<typeof import('@ai-sdk/openai')>(\n PROVIDER_PACKAGE.openai,\n )\n const provider = createOpenAI({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'anthropic': {\n const { createAnthropic } = await loadProvider<typeof import('@ai-sdk/anthropic')>(\n PROVIDER_PACKAGE.anthropic,\n )\n const provider = createAnthropic({\n baseURL: spec.baseURL || undefined,\n apiKey,\n // Anthropic's SDK refuses browser calls unless this opt-in header is\n // set; host headers may override it.\n headers: { 'anthropic-dangerous-direct-browser-access': 'true', ...spec.headers },\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'google': {\n const { createGoogleGenerativeAI } = await loadProvider<typeof import('@ai-sdk/google')>(\n PROVIDER_PACKAGE.google,\n )\n const provider = createGoogleGenerativeAI({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'openai-compatible': {\n const { createOpenAICompatible } = await loadProvider<\n typeof import('@ai-sdk/openai-compatible')\n >(PROVIDER_PACKAGE['openai-compatible'])\n const provider = createOpenAICompatible({\n name: clientName,\n baseURL: spec.baseURL as string,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'xai': {\n const { createXai } = await loadProvider<typeof import('@ai-sdk/xai')>(PROVIDER_PACKAGE.xai)\n const provider = createXai({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'deepseek': {\n const { createDeepSeek } = await loadProvider<typeof import('@ai-sdk/deepseek')>(\n PROVIDER_PACKAGE.deepseek,\n )\n const provider = createDeepSeek({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n }\n}\n\n/** Resolve a single ModelInput straight to a LanguageModel (no per-stage layering). */\nexport const resolveModel = (\n input: ModelInput,\n credentials?: CredentialStore,\n clientName?: string,\n): Promise<LanguageModel> =>\n buildModelFromStage(resolveStage(input, undefined, 'model'), credentials, clientName)\n","/**\n * Default phase prompts. Each builder returns `{ system, prompt }` strings.\n * Because the agent runs in two tool-modes, the builders switch on `ctx.mode`:\n *\n * - `native` — the model calls tools / emits schema-constrained JSON via the\n * AI SDK, so the prompts describe the task and let the SDK enforce structure.\n * - `prompted` — weak local models can't do that reliably, so the prompts spell\n * out an exact JSON shape and (for the executor) include a tool catalogue;\n * the output is salvaged by parse.ts.\n *\n * Override any builder via `BrowserAgentConfig.prompts`.\n */\n\nimport { clip } from './llm/util.js'\n\nexport type ToolCallMode = 'native' | 'prompted'\n\nexport interface PromptParts {\n system: string\n prompt: string\n}\n\nexport interface PlannerPromptContext {\n goal: string\n state?: string\n toolCatalog: string\n mode: ToolCallMode\n /** Prior session messages (oldest first), for resolving references to earlier turns. */\n history?: { role: string; content: string }[]\n}\nexport interface ExecutorPromptContext {\n goal: string\n state?: string\n step: string\n index: number\n total: number\n toolCatalog: string\n done: string[]\n mode: ToolCallMode\n}\nexport interface ReplannerPromptContext {\n goal: string\n state?: string\n done: string[]\n remaining: string[]\n mode: ToolCallMode\n}\nexport interface SynthesizerPromptContext {\n goal: string\n state?: string\n done: string[]\n}\n\nexport interface Prompts {\n planner(ctx: PlannerPromptContext): PromptParts\n executor(ctx: ExecutorPromptContext): PromptParts\n replanner(ctx: ReplannerPromptContext): PromptParts\n synthesizer(ctx: SynthesizerPromptContext): PromptParts\n}\n\nconst numbered = (items: string[], empty: string): string =>\n items.length ? items.map((s, i) => `${i + 1}. ${s}`).join('\\n') : empty\n\nconst stateBlock = (state?: string): string => (state && state.trim() ? `\\n\\nSTATE:\\n${state}` : '')\n\n// The last few session messages, capped so a long transcript can't crowd out\n// the goal (memory compression keeps the full story in a summary message).\nconst historyBlock = (history?: { role: string; content: string }[]): string => {\n if (!history || history.length === 0) return ''\n const lines = history.slice(-8).map((m) => `${m.role}: ${clip(m.content, 400)}`)\n return `\\n\\nCONVERSATION SO FAR:\\n${lines.join('\\n')}`\n}\n\n// --- planner ---------------------------------------------------------------\n\nconst PLANNER_NATIVE = `You are the PLANNER of a tool-using agent that changes a workspace step by step.\nProduce a brief \"thought\" and an ordered \"steps\" list (1–6 DISTINCT, self-contained steps) grounded in the current STATE and the available TOOLS.\nIf the user only greets, thanks, makes small talk, asks a question, or is unclear: return an EMPTY steps list and put a short, friendly answer in \"thought\".\nIf a CONVERSATION SO FAR section is present, use it to resolve references to earlier turns.\nNever repeat or pad steps.`\n\nconst PLANNER_PROMPTED = `You are the PLANNER of a tool-using agent that changes a workspace step by step.\n\nReply with a single JSON object, nothing else:\n{ \"reply\": string, \"plan\": string[] }\n- Only produce a \"plan\" when the user CLEARLY asks to build, do, or change something. For a greeting, small talk, thanks, a question, or an unclear/empty request: set \"plan\": [] and put a short, friendly \"reply\".\n- For a real goal: \"reply\" is one short sentence; \"plan\" is 1–6 DISTINCT, self-contained steps. Never repeat or pad steps.\n- Plan realistic steps the available TOOLS can perform, grounded in the current STATE.\n- If a CONVERSATION SO FAR section is present, use it to resolve references to earlier turns.`\n\n// --- executor --------------------------------------------------------------\n\nconst EXECUTOR_NATIVE = `You are the EXECUTOR of a tool-using agent. Carry out ONLY the current step by calling the provided tools.\nBuild on the current STATE — do not repeat work that is already there.\nWhen the step is done, reply with one short human sentence describing what you did (no JSON).\nIf you CANNOT complete the step (a needed tool is missing or an input is unavailable), explain why in one sentence and include the token [BLOCKER].`\n\nconst EXECUTOR_PROMPTED = `You are the EXECUTOR of a tool-using agent. Carry out ONLY the current step by emitting tool calls.\n\nReply with a single JSON object, nothing else:\n{ \"reply\": string, \"actions\": [ { \"tool\": string, \"args\": object } ] }\n- \"actions\" are the tool calls for THIS step ([] if none are needed). Use ONLY tools from the TOOLS list; \"args\" must match the tool's parameters.\n- Build on the current STATE — do not repeat work that is already there.\n- \"reply\" is one short human sentence (no JSON) describing what you did.\n- After your actions run you will see their TOOL RESULTS and may continue the same step; finish with \"actions\": [] once it is done.\n- If you CANNOT complete the step, set \"actions\": [] and put the token [BLOCKER] in \"reply\" with a short reason.`\n\n// --- replanner -------------------------------------------------------------\n\nconst REPLANNER_NATIVE = `You are the REPLANNER. After an executed step, decide whether to keep going, revise the remaining steps, or finish.\n\"continue\": the remaining steps still fit. \"revise\": provide a better \"plan\" for the REMAINING work (never repeat done work). \"finish\": the goal is already met.\nJudge from the current STATE vs the goal. Prefer \"continue\".`\n\nconst REPLANNER_PROMPTED = `You are the REPLANNER. After each executed step you decide whether to keep going, revise the remaining steps, or finish.\n\nReply with a single JSON object, nothing else:\n{ \"decision\": \"continue\" | \"revise\" | \"finish\", \"reason\": string, \"plan\": string[] }\n- \"continue\": remaining steps still fit — proceed (omit \"plan\").\n- \"revise\": replace the REMAINING steps with a better list in \"plan\"; never repeat done work.\n- \"finish\": the goal is already met — stop (omit \"plan\").\nJudge from the current STATE vs the goal. Prefer \"continue\".`\n\nconst SYNTHESIZER_SYSTEM = `You are the SYNTHESIZER. In 1–3 short, friendly sentences, tell the user what was done to meet their goal. Be concrete. Output plain text only — no JSON, no code.`\n\nexport const defaultPrompts: Prompts = {\n planner: (ctx) => ({\n system: ctx.mode === 'prompted' ? PLANNER_PROMPTED : PLANNER_NATIVE,\n prompt: `GOAL: ${ctx.goal}${historyBlock(ctx.history)}${stateBlock(ctx.state)}\\n\\nTOOLS:\\n${ctx.toolCatalog}`,\n }),\n executor: (ctx) => ({\n system: ctx.mode === 'prompted' ? EXECUTOR_PROMPTED : EXECUTOR_NATIVE,\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n ctx.mode === 'prompted' ? `TOOLS:\\n${ctx.toolCatalog}` : '',\n ctx.done.length ? `Already done:\\n${numbered(ctx.done, '')}` : '',\n `STEP ${ctx.index}/${ctx.total}: ${ctx.step}`,\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n replanner: (ctx) => ({\n system: ctx.mode === 'prompted' ? REPLANNER_PROMPTED : REPLANNER_NATIVE,\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n `Already done:\\n${numbered(ctx.done, '(nothing yet)')}`,\n `Remaining plan:\\n${numbered(ctx.remaining, '(none)')}`,\n 'Decide: continue, revise, or finish.',\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n synthesizer: (ctx) => ({\n system: SYNTHESIZER_SYSTEM,\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n `What was done:\\n${numbered(ctx.done, '(no changes)')}`,\n 'Write the final summary for the user.',\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n}\n\n/** Prepend a host-supplied systemPrompt to a phase system prompt, if present. */\nexport const withSystem = (base: string, extra?: string): string =>\n extra && extra.trim() ? `${extra.trim()}\\n\\n${base}` : base\n","import type { LanguageModel } from 'ai'\nimport type { ToolMode } from '../config.js'\n\n// Local / on-device runtimes whose tiny models are unreliable at native\n// function-calling and JSON-schema output — default them to the prompted path.\nconst LOCAL_RE = /web-?llm|mlc|browser-ai|transformers|nano|built-?in/i\n\n/**\n * Decide the tool-calling strategy for a resolved model. An explicit\n * config.toolMode of 'native'/'prompted' always wins; 'auto' (default) inspects\n * the model's provider id — local/on-device runtimes → 'prompted', cloud → 'native'.\n * A string model is a gateway model id (\"openai/gpt-4o\") — always cloud; the\n * LOCAL_RE must not see it, or model names like \"gpt-5-nano\" would match `nano`.\n */\nexport const selectToolMode = (\n model: LanguageModel,\n mode: ToolMode = 'auto',\n): 'native' | 'prompted' => {\n if (mode === 'native' || mode === 'prompted') return mode\n if (typeof model === 'string') return 'native'\n const provider = (model as { provider?: string }).provider ?? ''\n return LOCAL_RE.test(provider) ? 'prompted' : 'native'\n}\n","import type { Tool, ToolSet } from 'ai'\n\n/**\n * The canonical tool shape is the AI SDK `Tool` — the same object the native\n * tool-calling path passes straight to `streamText({ tools })`, and the same\n * shape MCP tools take. We add one optional field, `promptHint`, a short\n * human-readable parameter hint (e.g. \"{ text: string, x?: number }\") used only\n * by the prompted/salvage path when it renders the tool catalogue into a text\n * prompt for weak local models.\n */\nexport type AgentTool = Tool & { promptHint?: string }\n\n/** A named collection of tools — a plain AI SDK ToolSet, usable directly. */\nexport type AgentToolSet = ToolSet\n\n/** Read the optional promptHint attached by defineTool, if any. */\nexport const promptHintOf = (tool: Tool): string | undefined =>\n typeof (tool as { promptHint?: unknown }).promptHint === 'string'\n ? (tool as { promptHint?: string }).promptHint\n : undefined\n","import type { ModelMessage, ToolSet } from 'ai'\nimport type { RawAction } from '../parse.js'\nimport type { IToolCall } from '../agent/loop-types.js'\nimport { promptHintOf, type AgentToolSet } from './types.js'\n\n/**\n * Render a ToolSet into a plain-text catalogue for the prompted/salvage path:\n * `- name(hint): description`. The hint comes from `defineTool({ promptHint })`\n * when present; weak local models lean on it to fill args correctly.\n */\nexport const renderCatalog = (tools: AgentToolSet): string => {\n const names = Object.keys(tools)\n if (names.length === 0) return '(no tools)'\n return names\n .map((name) => {\n const t = tools[name]\n const hint = promptHintOf(t) ?? ''\n const desc = typeof t.description === 'string' ? t.description : ''\n return `- ${name}(${hint}): ${desc}`\n })\n .join('\\n')\n}\n\ninterface DispatchContext {\n abortSignal?: AbortSignal\n messages?: ModelMessage[]\n toolCallId?: string\n}\n\n/**\n * Validate and execute a single salvaged tool call against the ToolSet, using\n * the tool's OWN `execute` and `inputSchema` — the identical implementation the\n * native path calls. Unknown tools, schema-invalid args, and thrown errors all\n * become a failed IToolCall rather than throwing.\n */\nexport const dispatch = async (\n action: RawAction,\n tools: ToolSet,\n ctx: DispatchContext = {},\n): Promise<IToolCall> => {\n const t = tools[action.tool]\n if (!t) {\n return {\n name: action.tool,\n input: action.args,\n output: `unknown tool \"${action.tool}\"`,\n ok: false,\n }\n }\n let input: unknown = action.args\n const schema = (t as { inputSchema?: unknown }).inputSchema\n // Best-effort Zod validation (a jsonSchema() input has no safeParse — the\n // tool's execute is expected to guard those itself).\n if (schema && typeof (schema as { safeParse?: unknown }).safeParse === 'function') {\n const parsed = (\n schema as {\n safeParse: (v: unknown) => { success: boolean; data?: unknown; error?: { message: string } }\n }\n ).safeParse(input)\n if (!parsed.success) {\n return {\n name: action.tool,\n input,\n output: `invalid args for \"${action.tool}\": ${parsed.error?.message ?? 'schema validation failed'}`,\n ok: false,\n }\n }\n input = parsed.data\n }\n const execute = (t as { execute?: (i: unknown, o: unknown) => unknown }).execute\n if (typeof execute !== 'function') {\n return { name: action.tool, input, output: `tool \"${action.tool}\" has no execute`, ok: false }\n }\n try {\n const output = await execute(input, {\n toolCallId: ctx.toolCallId ?? `prompted-${action.tool}`,\n messages: ctx.messages ?? [],\n abortSignal: ctx.abortSignal,\n })\n return { name: action.tool, input, output, ok: true }\n } catch (err) {\n return {\n name: action.tool,\n input,\n output: err instanceof Error ? err.message : 'tool error',\n ok: false,\n }\n }\n}\n","import {\n generateText,\n stepCountIs,\n streamText,\n type LanguageModel,\n type ModelMessage,\n type ToolSet,\n} from 'ai'\nimport { addUsage, BLOCKER, emptyUsage, type IToolCall, type IUsage } from '../agent/loop-types.js'\nimport { parseExecutorResponse } from '../parse.js'\nimport { dispatch } from '../tools/prompted.js'\nimport { clip, normalizeUsage, promptOf, timeoutSignal } from './util.js'\n\nexport interface ToolLoopCallbacks {\n onTextDelta?: (delta: string) => void\n onToolCall?: (name: string, input: unknown) => void\n onToolResult?: (name: string, output: unknown, ok: boolean) => void\n}\n\nexport interface ToolLoopOptions {\n /** 'native' = SDK function-calling; 'prompted' = parse JSON out of plain text. */\n mode: 'native' | 'prompted'\n system?: string\n prompt?: string\n messages?: ModelMessage[]\n /** In native mode: the callable tools. In prompted mode: used to dispatch salvaged calls. */\n tools: ToolSet\n /**\n * Restrict callable tools to these names (plan-narrowed). Native mode passes\n * them to the SDK's `activeTools`; prompted mode bounds `dispatch` to them.\n */\n activeTools?: string[]\n /** Cap on tool-calling rounds within this call, in both modes (default 4). */\n maxSteps?: number\n maxOutputTokens?: number\n temperature?: number\n abortSignal?: AbortSignal\n timeoutMs?: number\n callbacks?: ToolLoopCallbacks\n}\n\nexport interface ToolLoopResult {\n text: string\n toolCalls: IToolCall[]\n usage: IUsage\n}\n\n/**\n * Run tool-calling in whichever mode the model needs, returning a normalised\n * result. Native mode streams the SDK's multi-step function-calling; prompted\n * mode salvages `{ reply, actions }` JSON out of plain text, dispatches each\n * action through the tool's own execute, then feeds the TOOL RESULTS back and\n * lets the model continue the same task — up to `maxSteps` rounds in both\n * modes. Both modes call the exact same tool implementations.\n */\nexport const runToolLoop = (\n model: LanguageModel,\n opts: ToolLoopOptions,\n): Promise<ToolLoopResult> =>\n opts.mode === 'prompted' ? runPrompted(model, opts) : runNative(model, opts)\n\nconst runNative = async (model: LanguageModel, opts: ToolLoopOptions): Promise<ToolLoopResult> => {\n const toolCalls: IToolCall[] = []\n const pending = new Map<string, { name: string; input: unknown }>()\n\n const result = streamText({\n model,\n tools: opts.tools,\n ...(opts.activeTools ? { activeTools: opts.activeTools } : {}),\n stopWhen: stepCountIs(opts.maxSteps ?? 4),\n system: opts.system,\n ...promptOf(opts),\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n })\n\n for await (const part of result.fullStream) {\n switch (part.type) {\n case 'text-delta':\n if (part.text) opts.callbacks?.onTextDelta?.(part.text)\n break\n case 'tool-call':\n pending.set(part.toolCallId, { name: part.toolName, input: part.input })\n opts.callbacks?.onToolCall?.(part.toolName, part.input)\n break\n case 'tool-result': {\n const known = pending.get(part.toolCallId)\n toolCalls.push({\n name: part.toolName,\n input: known?.input ?? part.input,\n output: part.output,\n ok: true,\n })\n opts.callbacks?.onToolResult?.(part.toolName, part.output, true)\n pending.delete(part.toolCallId)\n break\n }\n case 'tool-error': {\n const known = pending.get(part.toolCallId)\n toolCalls.push({\n name: part.toolName,\n input: known?.input ?? part.input,\n output: part.error,\n ok: false,\n })\n opts.callbacks?.onToolResult?.(part.toolName, part.error, false)\n pending.delete(part.toolCallId)\n break\n }\n case 'error':\n throw part.error instanceof Error ? part.error : new Error(String(part.error))\n }\n }\n\n const [text, usage] = await Promise.all([result.text, result.usage])\n return { text: text.trim(), toolCalls, usage: normalizeUsage(usage) }\n}\n\n/** JSON one-liner for a tool input/output; never throws (circular → String). */\nconst asJson = (value: unknown): string => {\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n}\n\n/** One round's results + the continue-or-finish contract for the next round. */\nconst toolResultsPrompt = (results: IToolCall[]): string => {\n const lines = results.map(\n (r) =>\n `- ${r.name} ${clip(asJson(r.input), 160)} → ${r.ok ? 'ok' : 'FAILED'}: ${clip(asJson(r.output), 400)}`,\n )\n return `TOOL RESULTS:\n${lines.join('\\n')}\n\nContinue THIS step using the results above. Reply with a single JSON object, nothing else:\n{ \"reply\": string, \"actions\": [ { \"tool\": string, \"args\": object } ] }\n- If the step is now complete: \"actions\": [] and a short outcome in \"reply\".\n- Otherwise emit ONLY the remaining or corrective calls — never repeat a successful call.`\n}\n\nconst runPrompted = async (\n model: LanguageModel,\n opts: ToolLoopOptions,\n): Promise<ToolLoopResult> => {\n // Prompted mode does NOT pass tools to the SDK — the tool catalogue is\n // already rendered into the prompt (see tools/prompted.ts renderCatalog); the\n // model replies with JSON, which we salvage and dispatch ourselves.\n //\n // After a round's actions run, the model is shown their TOOL RESULTS and may\n // continue the same task (react to a read-tool's output, fix a failed call)\n // until it returns no actions, signals [BLOCKER], re-emits a batch it already\n // ran, or `maxSteps` rounds are spent. Without this feedback a prompted model\n // never learns what its calls returned — a read-tool would be write-only. Set\n // maxSteps: 1 for the old single-round behaviour.\n const maxRounds = Math.max(1, opts.maxSteps ?? 4)\n const active = opts.activeTools\n const tools = active\n ? Object.fromEntries(Object.entries(opts.tools).filter(([name]) => active.includes(name)))\n : opts.tools\n\n // One watchdog for the WHOLE call (as native mode does with its single\n // stream), so a slow local model can't run up to maxRounds × timeoutMs; every\n // round's generation and every dispatch share this one deadline.\n const signal = timeoutSignal(opts.abortSignal, opts.timeoutMs)\n\n // The conversation grows across rounds: the model's own raw reply, then a\n // user message with the results — the standard chat shape every model knows.\n const messages: ModelMessage[] = opts.messages\n ? [...opts.messages]\n : [{ role: 'user', content: opts.prompt ?? '' }]\n const toolCalls: IToolCall[] = []\n // Every batch this loop has dispatched, so an exact repeat is caught even\n // when it isn't consecutive (A→B→A oscillation, not just A→A stutter).\n const seen = new Set<string>()\n let usage = emptyUsage()\n let text = ''\n\n for (let round = 1; round <= maxRounds; round += 1) {\n if (signal?.aborted) break\n const result = await generateText({\n model,\n system: opts.system,\n messages,\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n abortSignal: signal,\n })\n usage = addUsage(usage, normalizeUsage(result.usage))\n\n const parsed = parseExecutorResponse(result.text)\n // The LAST round's reply wins — an empty final reply is left empty (the\n // executor's summaryOf fills it in) rather than surfacing a stale, often\n // future-tense reply from an earlier round. Never the raw JSON envelope.\n text = parsed.reply\n\n // [BLOCKER] in any round is authoritative: the model says it cannot finish,\n // so preserve that reply (the executor detects the sentinel to drive the\n // replanner) and stop WITHOUT dispatching this round's speculative actions.\n if (parsed.reply.includes(BLOCKER)) break\n if (parsed.actions.length === 0) break\n\n // A batch this loop already ran is a stutter, not progress — re-running it\n // would apply every side effect again.\n const batch = asJson(parsed.actions)\n if (seen.has(batch)) break\n seen.add(batch)\n\n const results: IToolCall[] = []\n for (const action of parsed.actions) {\n if (signal?.aborted) break // stop mid-batch the moment the caller aborts\n opts.callbacks?.onToolCall?.(action.tool, action.args)\n const rec = await dispatch(action, tools, { abortSignal: signal })\n toolCalls.push(rec)\n results.push(rec)\n opts.callbacks?.onToolResult?.(rec.name, rec.output, rec.ok)\n }\n\n if (round === maxRounds || signal?.aborted) break\n messages.push({ role: 'assistant', content: result.text })\n messages.push({ role: 'user', content: toolResultsPrompt(results) })\n }\n\n // Prompted mode can't stream, so surface the final reply ONCE (not per round)\n // — a consumer accumulating deltas (as native mode's fragments require) would\n // otherwise concatenate every round's full reply.\n if (text) opts.callbacks?.onTextDelta?.(text)\n\n return { text, toolCalls, usage }\n}\n","/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */\nexport interface IPlanStep {\n id: string\n description: string\n expectedOutcome?: string\n /** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */\n suggestedTools?: string[]\n /** Set by the pipeline when suggestedTools were named but all were unknown. */\n requiresTools?: boolean\n}\n\nexport interface IPlan {\n thought: string\n steps: IPlanStep[]\n}\n\nexport interface IUsage {\n inputTokens: number\n outputTokens: number\n totalTokens: number\n}\n\nexport interface IToolCall {\n name: string\n input: unknown\n output: unknown\n ok: boolean\n}\n\nexport interface IStepResult {\n step: IPlanStep\n summary: string\n toolCalls: IToolCall[]\n /** True when the executor signalled it could not complete the step ([BLOCKER]). */\n blocked: boolean\n}\n\n/**\n * Sentinel the executor emits when it cannot complete a step. Language-agnostic\n * and shared by the tool loop (which must preserve it across prompted rounds)\n * and `splitBlocker` (which strips it and drives the replanner).\n */\nexport const BLOCKER = '[BLOCKER]'\n\nexport const emptyUsage = (): IUsage => ({ inputTokens: 0, outputTokens: 0, totalTokens: 0 })\n\nexport const addUsage = (a: IUsage, b: IUsage): IUsage => ({\n inputTokens: a.inputTokens + b.inputTokens,\n outputTokens: a.outputTokens + b.outputTokens,\n totalTokens: a.totalTokens + b.totalTokens,\n})\n","/**\n * Robust parsing of model output. Small in-browser models emit JSON wrapped in\n * prose or code fences, truncate it mid-token when they loop, or drift to plain\n * text. Every parser here is defensive: it salvages what it can and NEVER\n * throws, and it never surfaces raw JSON as user-facing text. This is the\n * backbone of the \"prompted\" tool-mode (see tools/mode.ts).\n */\n\n/** A tool the executor asked to run. */\nexport interface RawAction {\n tool: string\n args: Record<string, unknown>\n}\n\nexport type ReplanDecision = 'continue' | 'revise' | 'finish'\n\nconst stripFences = (text: string): string => (text || '').replace(/```(?:json)?/gi, '').trim()\n\n/** Extracts the first balanced {...} or [...] block, respecting strings. */\nconst extractBalanced = (text: string, open: '{' | '['): string | undefined => {\n const close = open === '{' ? '}' : ']'\n const start = text.indexOf(open)\n if (start < 0) return undefined\n let depth = 0\n let inStr = false\n let esc = false\n for (let i = start; i < text.length; i += 1) {\n const c = text[i]\n if (inStr) {\n if (esc) esc = false\n else if (c === '\\\\') esc = true\n else if (c === '\"') inStr = false\n continue\n }\n if (c === '\"') inStr = true\n else if (c === open) depth += 1\n else if (c === close) {\n depth -= 1\n if (depth === 0) return text.slice(start, i + 1)\n }\n }\n return undefined\n}\n\nconst tryParse = (s: string | undefined): unknown => {\n if (!s) return undefined\n try {\n return JSON.parse(s)\n } catch {\n return undefined\n }\n}\n\n/** True when a string is (or is dominated by) raw JSON — kept out of the UI. */\nexport const looksLikeJson = (s: string): boolean => {\n const t = (s || '').trim()\n return (\n t.startsWith('{') ||\n t.startsWith('[') ||\n /\"(tool|args|plan|reply|actions|decision)\"\\s*:/.test(t)\n )\n}\n\nconst asObject = (text: string): Record<string, unknown> | undefined => {\n const v = tryParse(text) ?? tryParse(extractBalanced(text, '{'))\n return v && typeof v === 'object' && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : undefined\n}\n\n/** Trim, drop empties, de-duplicate (case-insensitive), cap length. */\nexport const normalizeSteps = (arr: unknown, cap = 12): string[] => {\n if (!Array.isArray(arr)) return []\n const seen: Record<string, boolean> = {}\n const out: string[] = []\n for (const s of arr) {\n if (out.length >= cap || typeof s !== 'string') continue\n const step = s.trim()\n const key = step.toLowerCase()\n if (!step || seen[key]) continue\n seen[key] = true\n out.push(step)\n }\n return out\n}\n\n/** Decode a JSON string body (\\\" \\\\n \\\\uXXXX …); falls back to the raw text. */\nconst decodeJsonString = (body: string): string => {\n const v = tryParse(`\"${body}\"`)\n return typeof v === 'string' ? v : body\n}\n\n/**\n * Pull \"...\"-quoted strings out of a (possibly truncated) named array. The scan\n * is bounded to the array itself — from its `[` to the matching `]`, or the end\n * of the text when truncated — so values of LATER fields are never swept in.\n */\nconst salvageStringArray = (text: string, field: string): string[] => {\n const m = new RegExp(`\"${field}\"\\\\s*:\\\\s*\\\\[`).exec(text)\n if (!m) return []\n const out: string[] = []\n let i = m.index + m[0].length\n while (i < text.length && text[i] !== ']') {\n if (text[i] !== '\"') {\n i += 1\n continue\n }\n let j = i + 1\n let esc = false\n while (j < text.length && (esc || text[j] !== '\"')) {\n esc = !esc && text[j] === '\\\\'\n j += 1\n }\n if (j >= text.length) break // truncated mid-string — drop the fragment\n out.push(decodeJsonString(text.slice(i + 1, j)))\n i = j + 1\n }\n return out\n}\n\nconst salvageString = (text: string, field: string): string => {\n const m = text.match(new RegExp(`\"${field}\"\\\\s*:\\\\s*\"((?:[^\"\\\\\\\\]|\\\\\\\\.)*)\"`))\n return m ? decodeJsonString(m[1]).trim() : ''\n}\n\n// --- planner ---------------------------------------------------------------\n\nexport interface PlannerResult {\n reply: string\n plan: string[]\n}\n\nexport const parsePlannerResponse = (raw: string): PlannerResult => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj) {\n const reply = typeof obj.reply === 'string' ? obj.reply.trim() : ''\n return { reply, plan: normalizeSteps(obj.plan) }\n }\n if (/\"plan\"\\s*:/.test(text)) {\n return {\n reply: salvageString(text, 'reply'),\n plan: normalizeSteps(salvageStringArray(text, 'plan')),\n }\n }\n return { reply: looksLikeJson(text) ? '' : text.trim(), plan: [] }\n}\n\n// --- executor (tool calls) -------------------------------------------------\n\nexport interface ExecutorResult {\n reply: string\n actions: RawAction[]\n}\n\nconst toActions = (value: unknown): RawAction[] => {\n if (!Array.isArray(value)) return []\n const out: RawAction[] = []\n for (const a of value) {\n if (a && typeof a === 'object' && typeof (a as { tool?: unknown }).tool === 'string') {\n const rec = a as { tool: string; args?: unknown }\n out.push({\n tool: rec.tool,\n args:\n rec.args && typeof rec.args === 'object' && !Array.isArray(rec.args)\n ? (rec.args as Record<string, unknown>)\n : {},\n })\n }\n }\n return out\n}\n\nexport const parseExecutorResponse = (raw: string): ExecutorResult => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj) {\n const reply = typeof obj.reply === 'string' ? obj.reply.trim() : ''\n return { reply, actions: toActions(obj.actions) }\n }\n // Bare actions array.\n const arr = tryParse(extractBalanced(text, '['))\n if (Array.isArray(arr)) {\n const actions = toActions(arr)\n return { reply: '', actions }\n }\n return { reply: looksLikeJson(text) ? '' : text.trim(), actions: [] }\n}\n\n// --- replanner -------------------------------------------------------------\n\nexport interface ReplannerResult {\n decision: ReplanDecision\n reason: string\n plan: string[]\n}\n\nexport const parseReplannerResponse = (raw: string): ReplannerResult => {\n const obj = asObject(stripFences(raw))\n const decision: ReplanDecision =\n obj?.decision === 'revise' || obj?.decision === 'finish' ? obj.decision : 'continue'\n const reason = typeof obj?.reason === 'string' ? obj.reason.trim() : ''\n return { decision, reason, plan: normalizeSteps(obj?.plan) }\n}\n\n// --- plain text (synthesizer / chat answers) -------------------------------\n\n/** Extracts a clean human sentence, never raw JSON. */\nexport const parsePlainText = (raw: string): string => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj && typeof obj.reply === 'string') return obj.reply.trim()\n return looksLikeJson(text) ? '' : text.trim()\n}\n","import type { LanguageModel } from 'ai'\nimport type { BrowserAgentConfig, ResolvedConfig } from '../config.js'\nimport type { AgentEvent } from '../events.js'\nimport type { StoredMessage } from '../memory/store.js'\nimport type { Prompts, ToolCallMode } from '../prompts.js'\nimport { withSystem } from '../prompts.js'\nimport type { AgentToolSet } from '../tools/types.js'\nimport type { AgentLogger } from '../logger.js'\n\n/** Everything the phase functions (planner/executor/replanner/synthesizer) share. */\nexport interface AgentContext {\n config: ResolvedConfig\n raw: BrowserAgentConfig\n plannerModel: LanguageModel\n executorModel: LanguageModel\n synthesizerModel: LanguageModel\n /** Tool-mode for the planner/replanner (from the planner model). */\n plannerMode: ToolCallMode\n /** Tool-mode for the executor (from the executor model). */\n executorMode: ToolCallMode\n tools: AgentToolSet\n toolCatalog: string\n prompts: Prompts\n emit: (event: AgentEvent) => void\n /** Leveled logger (config.logLevel over config.logger ?? console). */\n log: AgentLogger\n signal?: AbortSignal\n /** Current world state for grounding, or undefined when no describeState is configured. */\n state: () => Promise<string | undefined>\n /** Session transcript loaded from memory BEFORE this run's goal was appended. */\n history?: StoredMessage[]\n}\n\n/** Prepend the host's systemPrompt to a phase system prompt. */\nexport const systemFor = (ctx: AgentContext, base: string): string =>\n withSystem(base, ctx.raw.systemPrompt)\n\nexport const aborted = (ctx: AgentContext): boolean => ctx.signal?.aborted === true\n","import type { ReplanTrigger } from '../config.js'\nimport { runToolLoop } from '../llm/tool-loop.js'\nimport { timeoutSignal } from '../llm/util.js'\nimport { renderCatalog } from '../tools/prompted.js'\nimport { BLOCKER, type IPlanStep, type IStepResult, type IUsage } from './loop-types.js'\nimport { systemFor, type AgentContext } from './internal.js'\n\n/**\n * Split the executor's reply into a clean summary and a structural `blocked`\n * flag. The [BLOCKER] sentinel — emitted by the executor when it can't complete\n * a step — is language-agnostic and drives the replanner; we strip every copy\n * so it never leaks into downstream prompts.\n */\nexport const splitBlocker = (raw: string): { summary: string; blocked: boolean } => {\n if (!raw.includes(BLOCKER)) return { summary: raw.trim(), blocked: false }\n return { summary: raw.split(BLOCKER).join('').trim(), blocked: true }\n}\n\nconst activeToolNames = (ctx: AgentContext, step: IPlanStep): string[] | undefined => {\n if (ctx.config.toolSelectionStrategy !== 'plan-narrowed') return undefined\n const suggested = step.suggestedTools ?? []\n const known = suggested.filter((n) => ctx.tools[n])\n // A step that named tools but all were unknown still wants tools: fall back to\n // the full set rather than stalling with zero.\n if (known.length === 0 && suggested.length > 0) return Object.keys(ctx.tools)\n return known\n}\n\nconst summaryOf = (text: string, toolCallCount: number): string => {\n if (text.length > 0) return text\n return toolCallCount > 0 ? `Executed ${toolCallCount} tool call(s).` : 'Step produced no output.'\n}\n\n/** Execute one plan step: run the tool loop (native or prompted) and emit events. */\nexport const executeStep = async (\n ctx: AgentContext,\n goal: string,\n step: IPlanStep,\n index: number,\n total: number,\n done: string[],\n): Promise<{ result: IStepResult; usage: IUsage }> => {\n const state = await ctx.state()\n // Under plan-narrowed selection the prompted path must also see the narrowed\n // catalogue — the prompt is its only tool surface (native mode gets the SDK's\n // activeTools instead and never renders the catalogue).\n const active = activeToolNames(ctx, step)\n const toolCatalog =\n active === undefined\n ? ctx.toolCatalog\n : renderCatalog(Object.fromEntries(active.map((name) => [name, ctx.tools[name]])))\n const parts = ctx.prompts.executor({\n goal,\n state,\n step: step.description,\n index,\n total,\n toolCatalog,\n done,\n mode: ctx.executorMode,\n })\n\n const loop = await runToolLoop(ctx.executorModel, {\n mode: ctx.executorMode,\n system: systemFor(ctx, parts.system),\n prompt: parts.prompt,\n tools: ctx.tools,\n activeTools: active,\n maxSteps: ctx.config.maxStepsPerTask,\n maxOutputTokens: ctx.config.budgets.executor,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n callbacks: {\n onTextDelta: (delta) => ctx.emit({ type: 'step.text-delta', step, delta }),\n onToolCall: (name, input) => {\n ctx.log.info(`tool call: ${name}`, input)\n ctx.emit({ type: 'step.tool-call', step, name, input })\n },\n onToolResult: (name, output, ok) => {\n ctx.log.debug(`tool result: ${name} ${ok ? 'ok' : 'FAILED'}`, output)\n ctx.emit({ type: 'step.tool-result', step, name, output, ok })\n },\n },\n })\n ctx.log.debug('executor text:', loop.text)\n\n const { summary, blocked } = splitBlocker(loop.text)\n return {\n result: {\n step,\n summary: summaryOf(summary, loop.toolCalls.length),\n toolCalls: loop.toolCalls,\n blocked,\n },\n usage: loop.usage,\n }\n}\n\n/**\n * The replanner runs when a step was blocked or a tool call failed and stayed\n * failed. A failure that a LATER call to the same tool retried successfully is\n * resolved — the prompted feedback loop (and native multi-step) let the model\n * self-correct within the step, so it must not force a replan.\n */\nexport const shouldReplan = (result: IStepResult): boolean => {\n if (result.blocked) return true\n const { toolCalls } = result\n return toolCalls.some(\n (c, i) => !c.ok && !toolCalls.slice(i + 1).some((later) => later.ok && later.name === c.name),\n )\n}\n\n/** Bound a host `replanAfter` predicate by the same watchdog/abort as a model call. */\nexport interface ReplanWantedOptions {\n signal?: AbortSignal\n timeoutMs?: number\n /** Called with whatever a host predicate threw before falling back to 'failure'. */\n onError?: (err: unknown) => void\n}\n\n/**\n * Resolve the configured `replanAfter` trigger for one step result. 'failure'\n * is the classic `shouldReplan`; 'always' consults the replanner after every\n * step; a host predicate decides per result. A predicate that throws, rejects,\n * or outlives the watchdog/abort falls back to 'failure' behaviour so a buggy\n * or hung predicate can never stall the run (its throw is surfaced via onError).\n */\nexport const replanWanted = async (\n trigger: ReplanTrigger,\n result: IStepResult,\n opts: ReplanWantedOptions = {},\n): Promise<boolean> => {\n if (trigger === 'always') return true\n if (typeof trigger !== 'function') return shouldReplan(result)\n\n const fallback = (): boolean => shouldReplan(result)\n // Never rejects: a sync throw or async rejection resolves to the fallback.\n const decided = (async () => {\n try {\n return Boolean(await trigger(result))\n } catch (err) {\n opts.onError?.(err)\n return fallback()\n }\n })()\n\n const guard = timeoutSignal(opts.signal, opts.timeoutMs)\n if (!guard) return decided\n return Promise.race([\n decided,\n new Promise<boolean>((resolve) => {\n if (guard.aborted) resolve(fallback())\n else guard.addEventListener('abort', () => resolve(fallback()), { once: true })\n }),\n ])\n}\n","import { z } from 'zod'\n\n/**\n * Structured-output schemas for the native path (generateObject). Kept free of\n * `.max()`/`.min()` constraints — some providers reject or mis-handle them in\n * JSON-schema mode; we cap/clean in code instead (see parse.ts normalizeSteps).\n */\nexport const PlanStepSchema = z.object({\n description: z.string(),\n expectedOutcome: z.string().optional(),\n suggestedTools: z.array(z.string()).optional(),\n})\n\nexport const PlanSchema = z.object({\n /** One short sentence. For a greeting/question/unclear request, holds the answer and steps is empty. */\n thought: z.string(),\n steps: z.array(PlanStepSchema),\n})\n\nexport const ReplanSchema = z.object({\n decision: z.enum(['continue', 'revise', 'finish']),\n reason: z.string(),\n /** Replacement for the REMAINING steps when decision is 'revise'. */\n plan: z.array(z.string()).optional(),\n})\n\nexport type PlanShape = z.infer<typeof PlanSchema>\nexport type ReplanShape = z.infer<typeof ReplanSchema>\n","import { generate, generateStructured } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { parsePlannerResponse } from '../parse.js'\nimport type { ToolCallMode } from '../prompts.js'\nimport type { IPlan, IUsage } from './loop-types.js'\nimport { systemFor, type AgentContext } from './internal.js'\nimport { PlanSchema } from './schemas.js'\n\nconst toSteps = (\n raw: { description: string; expectedOutcome?: string; suggestedTools?: string[] }[],\n): IPlan['steps'] =>\n raw\n .filter((s) => s.description && s.description.trim())\n .map((s, i) => ({\n id: `s${i + 1}`,\n description: s.description.trim(),\n expectedOutcome: s.expectedOutcome,\n suggestedTools: s.suggestedTools,\n }))\n\n/**\n * Build the initial plan. Native mode uses generateObject(PlanSchema); prompted\n * mode salvages `{ reply, plan }` from plain text. Native failures (a weak model\n * that can't satisfy the schema) fall back to the prompted parse rather than\n * throwing, so the run degrades gracefully. An empty `steps` list signals the\n * runner to answer directly (greeting / question / unclear).\n */\nexport const createPlan = async (\n ctx: AgentContext,\n goal: string,\n /** Extra instruction appended to the goal (used by the empty-plan retry). */\n nudge?: string,\n): Promise<{ plan: IPlan; usage: IUsage }> => {\n const state = await ctx.state()\n const effectiveGoal = nudge ? `${goal}\\n\\n${nudge}` : goal\n const commonFor = (mode: ToolCallMode) => {\n const parts = ctx.prompts.planner({\n goal: effectiveGoal,\n state,\n toolCatalog: ctx.toolCatalog,\n mode,\n history: ctx.history,\n })\n return {\n system: systemFor(ctx, parts.system),\n prompt: parts.prompt,\n maxOutputTokens: ctx.config.budgets.planner,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n }\n }\n\n if (ctx.plannerMode === 'native') {\n try {\n const result = await generateStructured(ctx.plannerModel, PlanSchema, commonFor('native'))\n ctx.log.debug('planner (native):', result.object)\n return {\n plan: { thought: result.object.thought, steps: toSteps(result.object.steps) },\n usage: normalizeUsage(result.usage),\n }\n } catch (err) {\n // Graceful degradation: fall back to the salvage parser instead of failing.\n ctx.log.warn('planner: native structured output failed, salvaging:', asMessage(err))\n ctx.emit({ type: 'retry', phase: 'plan', attempt: 1, error: asMessage(err) })\n }\n }\n\n // The prompted path — also the fallback after a native failure. Rendered with\n // mode 'prompted' so the model gets explicit JSON-shape instructions even\n // when the schema-constrained call just failed.\n const result = await generate(ctx.plannerModel, commonFor('prompted'))\n const parsed = parsePlannerResponse(result.text)\n ctx.log.debug('planner (prompted) raw:', result.text)\n ctx.log.debug('planner (prompted) parsed:', parsed)\n return {\n plan: {\n thought: parsed.reply,\n steps: toSteps(parsed.plan.map((description) => ({ description }))),\n },\n usage: normalizeUsage(result.usage),\n }\n}\n\nconst asMessage = (err: unknown): string => (err instanceof Error ? err.message : String(err))\n","import { generate, generateStructured } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { parseReplannerResponse, type ReplanDecision } from '../parse.js'\nimport type { ToolCallMode } from '../prompts.js'\nimport type { IUsage } from './loop-types.js'\nimport { emptyUsage } from './loop-types.js'\nimport { systemFor, type AgentContext } from './internal.js'\nimport { ReplanSchema } from './schemas.js'\n\nexport interface ReplanOutcome {\n decision: ReplanDecision\n reason: string\n /** Replacement remaining steps (descriptions) when decision is 'revise'. */\n plan: string[]\n usage: IUsage\n}\n\n/**\n * Decide whether to continue, revise the remaining plan, or finish, after a\n * blocked/failed step. Native mode uses generateObject(ReplanSchema); prompted\n * mode salvages the decision from text. Any failure degrades to 'continue' so a\n * flaky replanner never aborts the run.\n */\nexport const decideReplan = async (\n ctx: AgentContext,\n goal: string,\n done: string[],\n remaining: string[],\n): Promise<ReplanOutcome> => {\n const state = await ctx.state()\n const commonFor = (mode: ToolCallMode) => {\n const parts = ctx.prompts.replanner({ goal, state, done, remaining, mode })\n return {\n system: systemFor(ctx, parts.system),\n prompt: parts.prompt,\n maxOutputTokens: ctx.config.budgets.replanner,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n }\n }\n\n if (ctx.plannerMode === 'native') {\n try {\n const result = await generateStructured(ctx.plannerModel, ReplanSchema, commonFor('native'))\n return {\n decision: result.object.decision,\n reason: result.object.reason,\n plan: result.object.plan ?? [],\n usage: normalizeUsage(result.usage),\n }\n } catch {\n /* fall through to the prompted salvage below */\n }\n }\n\n try {\n // The prompted path — also the fallback after a native failure, re-rendered\n // with explicit JSON-shape instructions.\n const result = await generate(ctx.plannerModel, commonFor('prompted'))\n const parsed = parseReplannerResponse(result.text)\n return {\n decision: parsed.decision,\n reason: parsed.reason,\n plan: parsed.plan,\n usage: normalizeUsage(result.usage),\n }\n } catch {\n return { decision: 'continue', reason: 'replanner unavailable', plan: [], usage: emptyUsage() }\n }\n}\n","import { stream } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { looksLikeJson, parsePlainText } from '../parse.js'\nimport type { IUsage } from './loop-types.js'\nimport { systemFor, type AgentContext } from './internal.js'\n\n/**\n * Write the final natural-language summary of what the run accomplished,\n * streaming it as `final.text-delta` events. Plain text only (parsePlainText\n * strips any stray JSON; deltas are suppressed entirely when the model drifts\n * into JSON, so raw structure never reaches a UI). Falls back to a default\n * sentence if the model returns nothing usable.\n */\nexport const synthesizeAnswer = async (\n ctx: AgentContext,\n goal: string,\n done: string[],\n): Promise<{ text: string; usage: IUsage }> => {\n const state = await ctx.state()\n const parts = ctx.prompts.synthesizer({ goal, state, done })\n const result = stream(ctx.synthesizerModel, {\n system: systemFor(ctx, parts.system),\n prompt: parts.prompt,\n maxOutputTokens: ctx.config.budgets.synthesizer,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n })\n\n let text = ''\n let verdict: 'unknown' | 'emit' | 'suppress' = 'unknown'\n for await (const delta of result.textStream) {\n text += delta\n if (verdict === 'unknown') {\n const lead = text.trimStart()\n if (!lead) continue\n verdict = looksLikeJson(lead) ? 'suppress' : 'emit'\n if (verdict === 'emit') ctx.emit({ type: 'final.text-delta', delta: text })\n } else if (verdict === 'emit') {\n ctx.emit({ type: 'final.text-delta', delta })\n }\n }\n\n const clean = parsePlainText(text)\n return {\n text: clean || 'Done — the changes have been applied.',\n usage: normalizeUsage(await result.usage),\n }\n}\n","/**\n * Leveled logging for the agent. The host passes a console-like sink and a\n * level; everything below the level is a no-op. Default: 'warn' onto the\n * global console — silent in normal operation, but salvage fallbacks, empty\n * plans, degraded tool modes and failed tool calls stay visible.\n *\n * Set `logLevel: 'debug'` to see every phase's raw model output, parsed\n * results and tool dispatches — the first thing to reach for when the agent\n * \"says it did something but nothing happened\".\n */\n\nexport type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug'\n\n/** Console-compatible sink (pass `console`, or your own collector). */\nexport interface AgentLoggerSink {\n error(...args: unknown[]): void\n warn(...args: unknown[]): void\n info(...args: unknown[]): void\n debug(...args: unknown[]): void\n}\n\nexport interface AgentLogger extends AgentLoggerSink {\n readonly level: LogLevel\n}\n\nconst WEIGHT: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n}\n\nconst PREFIX = '[agent-web]'\n\nconst noop = (): void => undefined\n\nexport const createLogger = (\n level: LogLevel = 'warn',\n sink: AgentLoggerSink = console,\n): AgentLogger => {\n const at = (min: LogLevel, fn: (...args: unknown[]) => void) =>\n WEIGHT[level] >= WEIGHT[min] ? (...args: unknown[]) => fn.call(sink, PREFIX, ...args) : noop\n return {\n level,\n error: at('error', sink.error),\n warn: at('warn', sink.warn),\n info: at('info', sink.info),\n debug: at('debug', sink.debug),\n }\n}\n","import type { LanguageModel } from 'ai'\nimport type { BrowserAgentConfig } from '../config.js'\nimport { resolveConfig } from '../config.js'\nimport type { AgentEvent, AgentEventHandler, Phase } from '../events.js'\nimport { compressHistory } from '../memory/compress.js'\nimport type { StoredMessage } from '../memory/store.js'\nimport { buildModelFromStage, resolveStage } from '../providers/registry.js'\nimport { defaultPrompts, type Prompts } from '../prompts.js'\nimport { selectToolMode } from '../tools/mode.js'\nimport { renderCatalog } from '../tools/prompted.js'\nimport type { AgentToolSet } from '../tools/types.js'\nimport { executeStep, replanWanted } from './executor.js'\nimport type { AgentContext } from './internal.js'\nimport {\n addUsage,\n emptyUsage,\n type IPlan,\n type IPlanStep,\n type IStepResult,\n type IUsage,\n} from './loop-types.js'\nimport { createPlan } from './planner.js'\nimport { decideReplan } from './replanner.js'\nimport { synthesizeAnswer } from './synthesizer.js'\nimport { createLogger } from '../logger.js'\n\nexport interface RunOptions {\n onEvent?: AgentEventHandler\n signal?: AbortSignal\n /** Override the config's sessionId for this run. */\n sessionId?: string\n}\n\nexport interface RunResult {\n goal: string\n final: string\n plan: IPlan\n trace: IStepResult[]\n steps: number\n /** Total successful tool calls across the run. */\n applied: number\n stopped: boolean\n usage: IUsage\n}\n\nexport interface Agent {\n run(goal: string, opts?: RunOptions): Promise<RunResult>\n /** The resolved models, for hosts that want to reuse them (e.g. warm-up). */\n readonly models: {\n planner: LanguageModel\n executor: LanguageModel\n synthesizer: LanguageModel\n }\n}\n\nconst errMessage = (err: unknown): string => (err instanceof Error ? err.message : String(err))\n\n/** Apply the config's availableTools whitelist and excludedTools blacklist. */\nconst filterTools = (\n all: AgentToolSet,\n available?: string[],\n excluded?: string[],\n): AgentToolSet => {\n let entries = Object.entries(all)\n if (available && available.length > 0) entries = entries.filter(([n]) => available.includes(n))\n if (excluded && excluded.length > 0) entries = entries.filter(([n]) => !excluded.includes(n))\n return Object.fromEntries(entries)\n}\n\n/**\n * Create a headless plan → execute → replan → synthesize agent. Models are\n * resolved eagerly (dynamic provider imports + vault key fetch), so this is\n * async. Each `run` streams typed AgentEvents for any UI to render.\n */\nexport const createAgent = async (config: BrowserAgentConfig): Promise<Agent> => {\n const cfg = resolveConfig(config)\n // Build the executor once; a stage without an override reuses it instead of\n // constructing a second identical model (for web-llm that would mean loading\n // the same weights into the GPU again).\n const buildStage = (override: BrowserAgentConfig['planner'], stageName: string) =>\n buildModelFromStage(\n resolveStage(config.model, override, stageName),\n config.credentials,\n cfg.clientName,\n )\n const executorP = buildStage(undefined, 'executor')\n const [executorModel, plannerModel, synthesizerModel] = await Promise.all([\n executorP,\n config.planner === undefined ? executorP : buildStage(config.planner, 'planner'),\n config.synthesizer === undefined ? executorP : buildStage(config.synthesizer, 'synthesizer'),\n ])\n\n const plannerMode = selectToolMode(plannerModel, cfg.toolMode)\n const executorMode = selectToolMode(executorModel, cfg.toolMode)\n const tools: AgentToolSet = filterTools(\n config.tools ?? {},\n config.availableTools,\n config.excludedTools,\n )\n const toolCatalog = renderCatalog(tools)\n const prompts: Prompts = { ...defaultPrompts, ...config.prompts }\n const log = createLogger(cfg.logLevel, config.logger)\n log.info(\n `agent ready — tools: [${Object.keys(tools).join(', ') || 'none'}], planner mode: ${plannerMode}, executor mode: ${executorMode}`,\n )\n\n const run = async (goal: string, opts: RunOptions = {}): Promise<RunResult> => {\n const emit = (event: AgentEvent): void => {\n try {\n opts.onEvent?.(event)\n } catch {\n /* a bad handler must not break the run */\n }\n }\n const text = goal.trim()\n const sessionId = opts.sessionId ?? cfg.sessionId\n let usage = emptyUsage()\n const result: RunResult = {\n goal: text,\n final: '',\n plan: { thought: '', steps: [] },\n trace: [],\n steps: 0,\n applied: 0,\n stopped: false,\n usage,\n }\n if (!text) return result\n\n const state = async (): Promise<string | undefined> =>\n config.describeState ? config.describeState() : undefined\n const isAborted = (): boolean => opts.signal?.aborted === true\n const bumpUsage = (u: IUsage, phase: Phase): void => {\n usage = addUsage(usage, u)\n result.usage = usage\n emit({ type: 'usage', phase, usage: u })\n }\n const remember = async (msg: StoredMessage): Promise<void> => {\n if (!config.memory) return\n try {\n await config.memory.append(sessionId, msg)\n } catch {\n /* persistence is best-effort */\n }\n }\n\n emit({ type: 'run.start', goal: text })\n // Read back the session transcript BEFORE appending the current goal, so\n // the planner can resolve references to earlier turns (\"make it bigger\").\n let history: StoredMessage[] = []\n if (config.memory) {\n try {\n history = await config.memory.load(sessionId)\n } catch {\n /* persistence is best-effort */\n }\n }\n const ctx: AgentContext = {\n config: cfg,\n raw: config,\n plannerModel,\n executorModel,\n synthesizerModel,\n plannerMode,\n executorMode,\n tools,\n toolCatalog,\n prompts,\n emit,\n log,\n signal: opts.signal,\n state,\n history,\n }\n await remember({ role: 'user', content: text })\n log.info('run:', text)\n\n try {\n // 1) PLAN\n let planned = await createPlan(ctx, text)\n bumpUsage(planned.usage, 'plan')\n if (isAborted()) {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n\n // Small models sometimes return an empty plan for a clearly actionable\n // goal — and put a hallucinated \"done!\" into the thought, so the run\n // would claim success while never touching a tool. Give the planner one\n // nudged retry before treating the turn as conversational.\n if (planned.plan.steps.length === 0 && text.split(/\\s+/).length > 2) {\n log.warn(\n 'planner returned no steps for a multi-word goal — retrying with a nudge. thought:',\n planned.plan.thought,\n )\n const retried = await createPlan(\n ctx,\n text,\n 'NOTE: If the message above asks to build, add, change, clear or delete ANYTHING, you MUST output 1-6 concrete steps. Output an empty plan ONLY for a pure greeting or question.',\n )\n bumpUsage(retried.usage, 'plan')\n if (retried.plan.steps.length > 0) planned = retried\n }\n result.plan = planned.plan\n if (isAborted()) {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n\n // Greeting / question / unclear → answer directly, run no tools.\n if (planned.plan.steps.length === 0) {\n log.info('no plan — answering directly (no tools will run)')\n const answer = planned.plan.thought.trim() || \"Tell me what you'd like to do.\"\n emit({ type: 'final', text: answer })\n await remember({ role: 'assistant', content: answer })\n result.final = answer\n return result\n }\n log.info(\n `plan (${planned.plan.steps.length} steps):`,\n planned.plan.steps.map((s) => s.description),\n )\n emit({ type: 'plan.created', plan: planned.plan })\n planned.plan.steps.forEach((step, index) => emit({ type: 'plan.step-added', step, index }))\n\n // 2) EXECUTE → REPLAN\n const done: string[] = []\n let remaining: IPlanStep[] = [...planned.plan.steps]\n let iter = 0\n let revisions = 0\n while (remaining.length > 0 && iter < cfg.maxIterations) {\n if (isAborted()) {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n iter += 1\n const step = remaining.shift() as IPlanStep\n const stepNo = done.length + 1\n const total = stepNo + remaining.length\n emit({ type: 'step.start', step, index: stepNo, total })\n\n let stepResult: IStepResult\n try {\n const out = await executeStep(ctx, text, step, stepNo, total, done)\n bumpUsage(out.usage, 'execute')\n stepResult = out.result\n } catch (err) {\n // A user abort surfaces as a thrown AbortError — that is a stop, not\n // a step failure.\n if (isAborted()) {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n emit({ type: 'error', phase: 'execute', error: errMessage(err) })\n stepResult = { step, summary: errMessage(err), toolCalls: [], blocked: true }\n }\n\n result.trace.push(stepResult)\n const applied = stepResult.toolCalls.filter((c) => c.ok).length\n const failed = stepResult.toolCalls.length - applied\n result.applied += applied\n result.steps = stepNo\n log.info(\n `step ${stepNo}/${total} \"${step.description}\" — ${stepResult.toolCalls.length} tool call(s), ${applied} ok${failed ? `, ${failed} FAILED` : ''}${stepResult.blocked ? ', BLOCKED' : ''}`,\n )\n if (stepResult.toolCalls.length === 0) {\n log.warn(`step ${stepNo} made no tool calls — nothing changed in this step`)\n }\n stepResult.toolCalls\n .filter((c) => !c.ok)\n .forEach((c) => log.warn(`tool ${c.name} failed:`, c.output))\n log.debug(`step ${stepNo} detail:`, stepResult)\n emit({ type: 'step.complete', step, result: stepResult })\n done.push(\n `${step.description} — ${applied} applied${failed ? `, ${failed} failed` : ''}${stepResult.blocked ? ', blocked' : ''}`,\n )\n\n // 2b) REPLAN — by default after a blocked / failed step; `replanAfter`\n // can widen the trigger ('always', or a host predicate reacting to\n // e.g. issues surfaced through describeState). Also runs when the\n // triggering step was the last one — 'revise' can add remedial steps.\n // A host predicate is watchdog- and abort-bounded; re-check abort after\n // it (it may await slow state) before spending a replanner call.\n const wantReplan =\n cfg.replan &&\n iter < cfg.maxIterations &&\n revisions < cfg.maxRevisions &&\n !isAborted() &&\n (await replanWanted(cfg.replanAfter, stepResult, {\n signal: ctx.signal,\n timeoutMs: cfg.chatTimeoutMs,\n onError: (err) => log.warn('replanAfter predicate threw — using the failure rule', err),\n }))\n if (wantReplan && !isAborted()) {\n const decision = await decideReplan(\n ctx,\n text,\n done,\n remaining.map((s) => s.description),\n )\n bumpUsage(decision.usage, 'replan')\n emit({ type: 'replan.decision', mode: decision.decision, reason: decision.reason })\n if (decision.decision === 'finish') break\n if (decision.decision === 'revise' && decision.plan.length > 0) {\n revisions += 1\n remaining = decision.plan\n .slice(0, cfg.maxIterations - iter)\n .map((description, i) => ({ id: `r${iter}-${i + 1}`, description }))\n emit({\n type: 'plan.revised',\n plan: { thought: planned.plan.thought, steps: remaining },\n reason: decision.reason,\n })\n }\n }\n }\n\n if (isAborted()) {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n\n // 3) SYNTHESIZE\n let summary = 'Done — the changes have been applied.'\n if (cfg.synthesize) {\n try {\n const synth = await synthesizeAnswer(ctx, text, done)\n bumpUsage(synth.usage, 'synthesize')\n if (synth.text) summary = synth.text\n } catch {\n /* keep the default */\n }\n }\n log.info(`done — ${result.applied} tool call(s) applied over ${result.steps} step(s)`)\n emit({ type: 'final', text: summary })\n await remember({ role: 'assistant', content: summary })\n result.final = summary\n\n // 4) COMPRESS persisted history\n if (config.memory && cfg.compressAfterChars > 0) {\n try {\n const transcript = await config.memory.load(sessionId)\n const compacted = await compressHistory(transcript, synthesizerModel, {\n maxChars: cfg.compressAfterChars,\n timeoutMs: cfg.chatTimeoutMs,\n abortSignal: opts.signal,\n })\n if (compacted !== transcript) await config.memory.replace(sessionId, compacted)\n } catch {\n /* best-effort */\n }\n }\n return result\n } catch (err) {\n emit({ type: 'error', phase: 'run', error: errMessage(err) })\n result.final = errMessage(err)\n return result\n }\n }\n\n return {\n run,\n models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel },\n }\n}\n","import type { ProviderType } from './types.js'\n\n// Cloud providers are reliable at native function-calling and JSON-schema\n// structured output. Local WebGPU models (web-llm) technically support both,\n// but tiny (1–3B) models are unreliable at them, so we default local models to\n// the prompted/salvage path (overridable via config.toolMode).\nconst CLOUD: ReadonlySet<ProviderType> = new Set<ProviderType>([\n 'openai',\n 'anthropic',\n 'google',\n 'openai-compatible',\n 'xai',\n 'deepseek',\n 'gateway',\n])\n\n/** Whether native tool-calling is reliable enough to be the default for a provider. */\nexport const supportsNativeTools = (p: ProviderType): boolean => CLOUD.has(p)\n\n/** Whether native structured output (generateObject) is the default for a provider. */\nexport const supportsStructuredOutput = (p: ProviderType): boolean => CLOUD.has(p)\n\n/**\n * Whether calling this provider straight from a browser origin with a BYOK key\n * is expected to work (CORS + browser-access policy). Hosts can use this to\n * warn users before a direct call fails.\n *\n * - `google`: Gemini's endpoint is CORS-enabled — the most reliable direct BYOK path.\n * - `gateway` / `openai-compatible`: the host controls the endpoint / CORS.\n * - `anthropic`: works, but only with the direct-browser-access header, which\n * the registry injects automatically.\n * - `openai`: api.openai.com does NOT reliably send CORS for browser calls —\n * route through a proxy `baseURL` or the gateway.\n * - `xai` / `deepseek`: unreliable from the browser; prefer a proxy.\n */\nexport const directBrowserOk = (p: ProviderType): boolean =>\n p === 'google' || p === 'gateway' || p === 'openai-compatible' || p === 'anthropic'\n","import { IndexedDBVault, type VaultOptions } from './vault.js'\n\n/**\n * The seam the provider registry uses to fetch API keys at model-build time.\n * Swap in any backend: the encrypted vault (default), an in-memory map (tests /\n * SSR), or a `fetch` to your own short-lived-token endpoint.\n */\nexport interface CredentialStore {\n getApiKey(ref: string): Promise<string | undefined>\n setApiKey(ref: string, key: string): Promise<void>\n deleteApiKey(ref: string): Promise<void>\n}\n\n/** Default CredentialStore: encrypted, IndexedDB-backed (see IndexedDBVault). */\nexport class VaultCredentialStore implements CredentialStore {\n private readonly vault: IndexedDBVault\n\n constructor(opts: VaultOptions = {}) {\n this.vault = new IndexedDBVault(opts)\n }\n\n getApiKey(ref: string): Promise<string | undefined> {\n return this.vault.getSecret(ref)\n }\n setApiKey(ref: string, key: string): Promise<void> {\n return this.vault.setSecret(ref, key)\n }\n deleteApiKey(ref: string): Promise<void> {\n return this.vault.deleteSecret(ref)\n }\n}\n\n/** Non-persistent CredentialStore for tests / SSR / ephemeral sessions. */\nexport class MemoryCredentialStore implements CredentialStore {\n private readonly map = new Map<string, string>()\n\n constructor(initial?: Record<string, string>) {\n if (initial) for (const [k, v] of Object.entries(initial)) this.map.set(k, v)\n }\n\n async getApiKey(ref: string): Promise<string | undefined> {\n return this.map.get(ref)\n }\n async setApiKey(ref: string, key: string): Promise<void> {\n this.map.set(ref, key)\n }\n async deleteApiKey(ref: string): Promise<void> {\n this.map.delete(ref)\n }\n}\n","import { tool, type Tool } from 'ai'\nimport type { AgentTool } from './types.js'\n\n/**\n * Define a host tool. Thin wrapper over the AI SDK `tool()`: pass a\n * `description`, an `inputSchema` (a Zod schema or the result of `jsonSchema()`),\n * and an `execute` function. The returned tool works unchanged on the native\n * tool-calling path.\n *\n * Generic over INPUT/OUTPUT so the schema's inferred type flows into\n * `execute(input)` — `Parameters<typeof tool>[0]` must NOT be used here: with\n * an overloaded `tool()` it resolves to the last overload (`Tool<never, never>`),\n * which rejects every real schema and types `execute` as `undefined`.\n *\n * Optionally add `promptHint` — a short parameter hint like\n * \"{ text: string, x?: number }\" — which the prompted/salvage path shows to\n * weak local models that can't do native function-calling.\n *\n * @example\n * const tools = {\n * add_text: defineTool({\n * description: 'Add a text block to the page.',\n * inputSchema: z.object({ text: z.string(), x: z.number().optional() }),\n * promptHint: '{ text: string, x?: number }',\n * execute: async ({ text, x }) => addTextBlock(text, x),\n * }),\n * }\n */\nexport const defineTool = <INPUT = unknown, OUTPUT = unknown>(\n config: Tool<INPUT, OUTPUT> & { promptHint?: string },\n): AgentTool => {\n const { promptHint, ...rest } = config\n const t = tool(rest as Tool<INPUT, OUTPUT>) as AgentTool\n if (promptHint) t.promptHint = promptHint\n return t\n}\n","export interface StoredMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n ts?: number\n}\n\n/** Persists an agent session's transcript. Swap in any backend. */\nexport interface ContextStore {\n load(sessionId: string): Promise<StoredMessage[]>\n append(sessionId: string, message: StoredMessage): Promise<void>\n replace(sessionId: string, messages: StoredMessage[]): Promise<void>\n clear(sessionId: string): Promise<void>\n}\n\n/** Non-persistent fallback (tests, SSR, private mode). */\nexport class MemoryStore implements ContextStore {\n private readonly data = new Map<string, StoredMessage[]>()\n\n async load(sessionId: string): Promise<StoredMessage[]> {\n return (this.data.get(sessionId) ?? []).slice()\n }\n async append(sessionId: string, message: StoredMessage): Promise<void> {\n const arr = this.data.get(sessionId) ?? []\n arr.push(message)\n this.data.set(sessionId, arr)\n }\n async replace(sessionId: string, messages: StoredMessage[]): Promise<void> {\n this.data.set(sessionId, messages.slice())\n }\n async clear(sessionId: string): Promise<void> {\n this.data.delete(sessionId)\n }\n}\n","import { openAgentWebDB, SESSIONS_STORE } from '../storage/db.js'\nimport type { ContextStore, StoredMessage } from './store.js'\n\nexport interface IndexedDBStoreOptions {\n /** Database name, forwarded to the shared IDB owner (default 'agent-web'). */\n dbName?: string\n}\n\n/**\n * IndexedDB-backed transcript store — one record (message array) per session,\n * in the shared `sessions` object store (see storage/db.ts). Also exposes\n * session utilities: list and delete.\n */\nexport class IndexedDBStore implements ContextStore {\n private readonly dbName?: string\n\n constructor(opts: IndexedDBStoreOptions = {}) {\n this.dbName = opts.dbName\n }\n\n async load(sessionId: string): Promise<StoredMessage[]> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n const value = (await db.get(SESSIONS_STORE, sessionId)) as StoredMessage[] | undefined\n return Array.isArray(value) ? value : []\n }\n\n async replace(sessionId: string, messages: StoredMessage[]): Promise<void> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n await db.put(SESSIONS_STORE, messages, sessionId)\n }\n\n async append(sessionId: string, message: StoredMessage): Promise<void> {\n const current = await this.load(sessionId)\n current.push(message)\n await this.replace(sessionId, current)\n }\n\n async clear(sessionId: string): Promise<void> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n await db.delete(SESSIONS_STORE, sessionId)\n }\n\n /** List all stored session ids. */\n async listSessions(): Promise<string[]> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n return (await db.getAllKeys(SESSIONS_STORE)).map(String)\n }\n}\n"],"mappings":"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","names":["createWebLLMModel","tool","generateText","streamText","streamText","generateText","result"]}
1
+ {"version":3,"sources":["../src/caching.ts","../src/llm/generate.ts","../src/llm/util.ts","../src/memory/compress.ts","../src/config.ts","../src/limits.ts","../src/providers/types.ts","../src/providers/registry.ts","../src/prompts.ts","../src/skills.ts","../src/tools/approval.ts","../src/tools/mode.ts","../src/tools/types.ts","../src/tools/prompted.ts","../src/tools/search.ts","../src/tools/wrap.ts","../src/llm/tool-loop.ts","../src/agent/loop-types.ts","../src/parse.ts","../src/llm/context-editing.ts","../src/thinking.ts","../src/images.ts","../src/agent/internal.ts","../src/agent/executor.ts","../src/agent/schemas.ts","../src/agent/planner.ts","../src/agent/replanner.ts","../src/agent/synthesizer.ts","../src/logger.ts","../src/providers/capabilities.ts","../src/agent/runner.ts","../src/subagent/tool.ts","../src/subagent/protocol.ts","../src/subagent/worker.ts","../src/secrets/store.ts","../src/files/vfs.ts","../src/files/tools.ts","../src/tools/define.ts","../src/memory/store.ts","../src/memory/sessions.ts"],"sourcesContent":["import type { SystemModelMessage } from 'ai'\nimport type { ProviderOptionsMap } from './thinking.js'\n\n/**\n * Prompt caching. Every stage's SYSTEM prompt holds only run-stable content\n * (role, domain context, skills, tool catalogue) and the dynamic parts go to\n * the user prompt — so OpenAI's and Gemini's automatic prefix caches hit.\n * Anthropic caches only behind an explicit breakpoint, placed on the system\n * message; OpenAI additionally routes by `promptCacheKey`. Other providers\n * ignore option keys that are not theirs.\n */\nexport type PromptCachingSetting = boolean | { ttl?: '5m' | '1h'; key?: string }\n\nexport interface ResolvedCaching {\n enabled: boolean\n ttl?: '5m' | '1h'\n key?: string\n}\n\nexport const resolveCaching = (s: PromptCachingSetting | undefined): ResolvedCaching => {\n if (s === false) return { enabled: false }\n if (s === undefined || s === true) return { enabled: true }\n return { enabled: true, ttl: s.ttl, key: s.key }\n}\n\n/** The system prompt as the AI SDK `instructions`, with a cache breakpoint when enabled. */\nexport const cachedInstructions = (\n system: string,\n caching: ResolvedCaching,\n): string | SystemModelMessage =>\n caching.enabled\n ? {\n role: 'system',\n content: system,\n providerOptions: {\n anthropic: {\n cacheControl: { type: 'ephemeral', ...(caching.ttl ? { ttl: caching.ttl } : {}) },\n },\n },\n }\n : system\n\n/** Call-level provider options for caching (OpenAI cache routing key). */\nexport const cachingProviderOptions = (\n caching: ResolvedCaching,\n clientName: string,\n stage: string,\n): ProviderOptionsMap | undefined =>\n caching.enabled\n ? { openai: { promptCacheKey: caching.key ?? `${clientName}:${stage}` } }\n : undefined\n\n/** An Anthropic cache breakpoint (other providers ignore the key). */\nconst breakpoint = (ttl?: '5m' | '1h') => ({\n anthropic: { cacheControl: { type: 'ephemeral' as const, ...(ttl ? { ttl } : {}) } },\n})\n\n/** The message without an Anthropic breakpoint (other provider options kept). */\nconst withoutBreakpoint = <M extends { providerOptions?: unknown }>(m: M): M => {\n const own = m.providerOptions as Record<string, Record<string, unknown>> | undefined\n if (!own?.anthropic || !('cacheControl' in own.anthropic)) return m\n const { cacheControl: _drop, ...anthropic } = own.anthropic\n const { anthropic: _old, ...rest } = own\n const providerOptions = Object.keys(anthropic).length ? { ...rest, anthropic } : rest\n const { providerOptions: _po, ...base } = m as M & { providerOptions?: unknown }\n return (Object.keys(providerOptions).length ? { ...base, providerOptions } : base) as M\n}\n\n/**\n * The conversation with a rolling cache breakpoint on its LAST message — the\n * agent-loop pattern Claude Code uses: every tool-calling round re-sends the\n * rounds before it, and with the breakpoint moved to the newest message each\n * request reads all of them from the cache and writes only the new tail.\n * Earlier message breakpoints are removed (the SDK carries a round's messages\n * into the next one), so a request holds at most two: system + newest —\n * Anthropic rejects more than four.\n */\nexport const withRollingBreakpoint = <M extends { providerOptions?: unknown }>(\n messages: M[],\n caching: ResolvedCaching,\n): M[] => {\n if (!caching.enabled || messages.length === 0) return messages\n const out = messages.map((m, i) => (i < messages.length - 1 ? withoutBreakpoint(m) : m))\n const last = out[out.length - 1]\n const own = (last.providerOptions ?? {}) as Record<string, Record<string, unknown>>\n out[out.length - 1] = {\n ...last,\n providerOptions: {\n ...own,\n anthropic: { ...own.anthropic, ...breakpoint(caching.ttl).anthropic },\n },\n }\n return out\n}\n","import {\n generateObject,\n generateText,\n streamText,\n type LanguageModel,\n type ModelMessage,\n type SystemModelMessage,\n type ToolSet,\n} from 'ai'\nimport type { ZodType } from 'zod'\nimport type { ProviderOptionsMap, ThinkingLevel } from '../thinking.js'\nimport { promptOf, timeoutSignal } from './util.js'\n\n/** Options shared by the low-level generation helpers. Provide `prompt` OR `messages`. */\nexport interface GenerateOptions {\n /** The system prompt — a string, or a SystemModelMessage (e.g. with a cache breakpoint). */\n system?: string | SystemModelMessage\n prompt?: string\n messages?: ModelMessage[]\n tools?: ToolSet\n maxOutputTokens?: number\n temperature?: number\n /** Portable thinking level (see `resolveThinking`). */\n reasoning?: ThinkingLevel\n /** Provider-keyed options (thinking budgets, cache keys, …). */\n providerOptions?: ProviderOptionsMap\n abortSignal?: AbortSignal\n /** Time-box the call; combined with `abortSignal` (0/undefined = no timeout). */\n timeoutMs?: number\n}\n\n/** The settings every helper forwards; omits undefined keys the SDK would reject. */\nconst callSettings = (opts: GenerateOptions) => ({\n ...(opts.system !== undefined ? { instructions: opts.system } : {}),\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n ...(opts.reasoning ? { reasoning: opts.reasoning } : {}),\n ...(opts.providerOptions ? { providerOptions: opts.providerOptions as never } : {}),\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n})\n\n/**\n * One-shot text generation. Thin, provider-agnostic wrapper over the AI SDK's\n * `generateText` — the same call works against a cloud model, a local WebLLM\n * model, or Chrome/Edge built-in AI. Returns the full AI SDK result (`.text`,\n * `.usage`, `.toolCalls`, `.steps`, …).\n */\nexport const generate = (\n model: LanguageModel,\n opts: GenerateOptions = {},\n): ReturnType<typeof generateText> =>\n generateText({\n model,\n ...callSettings(opts),\n ...promptOf(opts),\n tools: opts.tools,\n })\n\n/** Streaming text generation. Returns the AI SDK `streamText` result (`.textStream`, `.fullStream`). */\nexport const stream = (\n model: LanguageModel,\n opts: GenerateOptions = {},\n): ReturnType<typeof streamText> =>\n streamText({\n model,\n ...callSettings(opts),\n ...promptOf(opts),\n tools: opts.tools,\n })\n\n/**\n * Structured output constrained to a Zod schema, via the AI SDK's\n * `generateObject`. Cloud models and WebLLM both support this; tiny local\n * models can be unreliable — the agent's prompted mode is the fallback.\n * Returns the AI SDK result (`.object`, `.usage`).\n */\nexport const generateStructured = <OBJECT>(\n model: LanguageModel,\n schema: ZodType<OBJECT>,\n opts: GenerateOptions = {},\n) =>\n generateObject({\n model,\n schema,\n ...callSettings(opts),\n ...promptOf(opts),\n })\n","import type { ModelMessage } from 'ai'\nimport type { IUsage } from '../agent/loop-types.js'\n\n/** Truncate to `max` characters, ellipsising the overflow. */\nexport const clip = (s: string, max: number): string =>\n s.length > max ? `${s.slice(0, max - 1)}…` : s\n\n/**\n * The AI SDK prompt is `{ prompt } XOR { messages }` — passing both keys (even\n * with one undefined) breaks the discriminated union. Pick exactly one.\n */\nexport const promptOf = (opts: {\n prompt?: string\n messages?: ModelMessage[]\n}): { prompt: string } | { messages: ModelMessage[] } =>\n opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? '' }\n\n/** The AI SDK usage shape, every field optional (providers omit what they don't report). */\nexport interface SdkUsageLike {\n inputTokens?: number\n outputTokens?: number\n totalTokens?: number\n inputTokenDetails?: { cacheReadTokens?: number; cacheWriteTokens?: number }\n outputTokenDetails?: { reasoningTokens?: number }\n /** Pre-v6 flat fields, still emitted by some providers. */\n reasoningTokens?: number\n cachedInputTokens?: number\n}\n\n/** Normalise the AI SDK usage shape (fields can be undefined) into IUsage. */\nexport const normalizeUsage = (u?: SdkUsageLike): IUsage => {\n const inputTokens = u?.inputTokens ?? 0\n const outputTokens = u?.outputTokens ?? 0\n return {\n inputTokens,\n outputTokens,\n totalTokens: u?.totalTokens ?? inputTokens + outputTokens,\n reasoningTokens: u?.outputTokenDetails?.reasoningTokens ?? u?.reasoningTokens ?? 0,\n cachedInputTokens: u?.inputTokenDetails?.cacheReadTokens ?? u?.cachedInputTokens ?? 0,\n cacheWriteTokens: u?.inputTokenDetails?.cacheWriteTokens ?? 0,\n }\n}\n\n/**\n * Combine the caller's AbortSignal with a timeout so a hung generation can't\n * freeze a run. Returns the original signal when no timeout is set. Uses the\n * standard `AbortSignal.timeout`/`AbortSignal.any` (Node ≥ 20, modern browsers).\n */\nexport const timeoutSignal = (signal?: AbortSignal, ms?: number): AbortSignal | undefined => {\n if (!ms || ms <= 0) return signal\n const timeout = AbortSignal.timeout(ms)\n if (!signal) return timeout\n return typeof AbortSignal.any === 'function' ? AbortSignal.any([signal, timeout]) : signal\n}\n","import type { LanguageModel } from 'ai'\nimport { generate } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport type { IUsage } from '../agent/loop-types.js'\nimport type { StoredMessage } from './store.js'\n\n/**\n * Context compaction. A model's window is finite and every token in it is paid\n * for on every call, so long transcripts and long runs are folded into a\n * summary: the oldest material is summarised by a model, the most recent is\n * kept verbatim.\n */\nexport interface CompactionConfig {\n /** Compact automatically before planning and between steps (default true). */\n auto?: boolean\n /** The model's context window, in tokens (default 128 000). */\n contextWindowTokens?: number\n /** Compact once the estimated context exceeds this (default: half the window). */\n thresholdTokens?: number\n /** Transcript messages kept verbatim (default 4). */\n keepRecentTurns?: number\n /** Executed steps kept verbatim in the run's trace (default 3). */\n keepRecentSteps?: number\n /** Output cap of a summary call (default 1024). */\n summaryMaxTokens?: number\n /** Cap on ONE tool result as the model sees it, in chars (default 20 000; 0 = no cap). */\n maxToolOutputChars?: number\n /**\n * Inside one step's tool loop: once its context passes this many tokens,\n * replace the oldest tool results with one-line stubs (context editing;\n * default: a quarter of the window; 0 = never).\n */\n clearToolResultsAfterTokens?: number\n /** Most recent tool results kept verbatim when clearing (default 3). */\n keepToolResults?: number\n}\n\nexport interface ResolvedCompaction {\n auto: boolean\n contextWindowTokens: number\n thresholdTokens: number\n keepRecentTurns: number\n keepRecentSteps: number\n summaryMaxTokens: number\n maxToolOutputChars: number\n clearToolResultsAfterTokens: number\n keepToolResults: number\n}\n\nexport const resolveCompaction = (c: CompactionConfig | undefined): ResolvedCompaction => {\n const contextWindowTokens = c?.contextWindowTokens ?? 128_000\n return {\n auto: c?.auto ?? true,\n contextWindowTokens,\n thresholdTokens: c?.thresholdTokens ?? Math.floor(contextWindowTokens / 2),\n keepRecentTurns: c?.keepRecentTurns ?? 4,\n keepRecentSteps: c?.keepRecentSteps ?? 3,\n summaryMaxTokens: c?.summaryMaxTokens ?? 1024,\n maxToolOutputChars: c?.maxToolOutputChars ?? 20_000,\n clearToolResultsAfterTokens:\n c?.clearToolResultsAfterTokens ?? Math.floor(contextWindowTokens / 4),\n keepToolResults: c?.keepToolResults ?? 3,\n }\n}\n\n/** Cheap, provider-independent token estimate (~4 chars per token). */\nexport const estimateTokens = (text: string): number => Math.ceil((text ?? '').length / 4)\n\nconst messageTokens = (msgs: StoredMessage[]): number =>\n msgs.reduce((n, m) => n + estimateTokens(`${m.role}: ${m.content}\\n`), 0)\n\nexport interface CompressOptions {\n /** Compress once the transcript exceeds this many characters (0 = never). */\n maxChars?: number\n /** Compress once the transcript's estimated tokens exceed this (wins over maxChars). */\n thresholdTokens?: number\n /** How many most-recent messages to keep verbatim. */\n keepRecent?: number\n /** Output cap of the summary call. */\n summaryMaxTokens?: number\n /** Compact even when below the threshold (manual \"compact now\"). */\n force?: boolean\n /** Time-box the summarisation call so it can never hang the caller. */\n timeoutMs?: number\n abortSignal?: AbortSignal\n /** Receives the summary call's token usage. */\n onUsage?: (usage: IUsage) => void\n}\n\nconst SUMMARY_SYSTEM =\n 'Summarize the following conversation into a compact set of durable facts, decisions, ' +\n 'identifiers, open tasks and user preferences. Keep names, numbers and IDs verbatim. ' +\n 'Output plain text only.'\n\n/**\n * When the transcript grows too long, summarise everything except the last\n * `keepRecent` messages into a single system message (via the model), so the\n * session stays within the model's context window. Returns the same array\n * unchanged when no compression is needed; never throws.\n */\nexport const compressHistory = async (\n messages: StoredMessage[],\n model: LanguageModel,\n opts: CompressOptions = {},\n): Promise<StoredMessage[]> => {\n const keepRecent = opts.keepRecent ?? 6\n if (messages.length <= keepRecent + 1) return messages\n if (!opts.force) {\n if (opts.thresholdTokens !== undefined) {\n if (opts.thresholdTokens <= 0 || messageTokens(messages) <= opts.thresholdTokens) {\n return messages\n }\n } else {\n const maxChars = opts.maxChars ?? 12_000\n const chars = messages.reduce((n, m) => n + m.content.length, 0)\n if (maxChars <= 0 || chars <= maxChars) return messages\n }\n }\n const head = messages.slice(0, messages.length - keepRecent)\n const tail = messages.slice(messages.length - keepRecent)\n // The newest part of the head matters most; keep the tail end of it when it\n // has to be cut to fit the summariser's own window.\n const transcript = head\n .map((m) => `${m.role}: ${m.content}`)\n .join('\\n')\n .slice(-48_000)\n try {\n const result = await generate(model, {\n system: SUMMARY_SYSTEM,\n prompt: transcript,\n maxOutputTokens: opts.summaryMaxTokens ?? 400,\n timeoutMs: opts.timeoutMs,\n abortSignal: opts.abortSignal,\n })\n opts.onUsage?.(normalizeUsage(result.usage))\n const clean = (result.text || '').trim()\n if (!clean) return messages\n const summaryMsg: StoredMessage = {\n role: 'system',\n content: `Summary of earlier conversation:\\n${clean}`,\n ts: head[0]?.ts,\n }\n return [summaryMsg, ...tail]\n } catch {\n return messages\n }\n}\n\n/** Alias with the sibling package's name; same behaviour as compressHistory. */\nexport const compactHistory = compressHistory\n\nconst TRACE_SYSTEM =\n 'Summarize these completed agent steps into a compact progress note: what was done, ' +\n 'what was found (keep names, numbers and IDs verbatim) and what failed. Plain text only.'\n\n/**\n * Fold the oldest entries of a run's step log into one summary entry, keeping\n * the last `keepRecent` verbatim. Returns the input unchanged when it fits the\n * threshold or on any failure; never throws.\n */\nexport const compactSteps = async (\n done: string[],\n model: LanguageModel,\n opts: CompressOptions & { thresholdTokens: number },\n): Promise<string[]> => {\n const keepRecent = opts.keepRecent ?? 3\n if (done.length <= keepRecent + 1) return done\n if (!opts.force && estimateTokens(done.join('\\n')) <= opts.thresholdTokens) return done\n const head = done.slice(0, done.length - keepRecent)\n try {\n const result = await generate(model, {\n system: TRACE_SYSTEM,\n prompt: head.map((d, i) => `${i + 1}. ${d}`).join('\\n'),\n maxOutputTokens: opts.summaryMaxTokens ?? 600,\n timeoutMs: opts.timeoutMs,\n abortSignal: opts.abortSignal,\n })\n opts.onUsage?.(normalizeUsage(result.usage))\n const clean = (result.text || '').trim()\n if (!clean) return done\n return [`Summary of ${head.length} earlier step(s): ${clean}`, ...done.slice(head.length)]\n } catch {\n return done\n }\n}\n\nexport { messageTokens as estimateMessagesTokens }\n","import type { IStepResult } from './agent/loop-types.js'\nimport type { PromptCachingSetting } from './caching.js'\nimport type { TokenLimits } from './limits.js'\nimport {\n resolveCompaction,\n type CompactionConfig,\n type ResolvedCompaction,\n} from './memory/compress.js'\nimport type { ContextStore } from './memory/store.js'\nimport type { AgentLoggerSink, LogLevel } from './logger.js'\nimport type { ModelInput, StageInput } from './providers/types.js'\nimport type { Prompts } from './prompts.js'\nimport type { CredentialStore } from './secrets/store.js'\nimport type { Skill } from './skills.js'\nimport type { ThinkingSetting, ThinkingStage } from './thinking.js'\nimport type { ToolApprovalConfig } from './tools/approval.js'\nimport type { AgentToolSet } from './tools/types.js'\n\n/** Force a tool-calling strategy, or let the agent pick per model ('auto'). */\nexport type ToolMode = 'auto' | 'native' | 'prompted'\n\n/**\n * When to consult the replanner after an executed step (given `replan` is on):\n * 'failure' — after a blocked step or a failed tool call (default);\n * 'always' — after every step, so the replanner can react to problems the host\n * surfaces via `describeState` (one extra model call per step);\n * predicate — decides per step result; closes over host state if needed, and\n * falls back to 'failure' behaviour if it throws.\n */\nexport type ReplanTrigger =\n 'failure' | 'always' | ((result: IStepResult) => boolean | Promise<boolean>)\n\n/**\n * 'all' — the executor sees the full ToolSet on every step.\n * 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner\n * must populate them). Empty means a reasoning-only step.\n * 'search' — for large catalogues: the executor starts with the step's\n * suggestedTools plus a `find_tools` meta-tool that activates\n * more on demand; the planner sees a condensed catalogue.\n * 'auto' — 'all' up to `toolSearchThreshold` tools, 'search' above (default).\n */\nexport type ToolSelectionStrategy = 'all' | 'plan-narrowed' | 'search' | 'auto'\n\n/** Per-phase generation budgets (max output tokens). */\nexport interface PhaseBudgets {\n planner?: number\n executor?: number\n replanner?: number\n synthesizer?: number\n}\n\nexport interface BrowserAgentConfig {\n /** The default (executor) model: a ready AI SDK model, or a ProviderModelSpec to resolve. */\n model: ModelInput\n /** Optional per-stage model overrides. A partial override inherits base provider/creds. */\n planner?: StageInput\n synthesizer?: StageInput\n /** Fetches API keys for ProviderModelSpec models. Default: none (inline keys only). */\n credentials?: CredentialStore\n /** Propagated to the openai-compatible provider name and the MCP client. */\n clientName?: string\n\n /** Host tools the executor may call (an AI SDK ToolSet; use defineTool). */\n tools?: AgentToolSet\n /** Whitelist: only these tool names from `tools` are mounted (default: all). */\n availableTools?: string[]\n /** Blacklist: these tool names are removed after the whitelist is applied. */\n excludedTools?: string[]\n /** Force native/prompted tool-calling; 'auto' picks per model (default 'auto'). */\n toolMode?: ToolMode\n /** How the executor sees the tool catalogue (default 'auto'). */\n toolSelectionStrategy?: ToolSelectionStrategy\n /** Catalogue size above which 'auto' switches to 'search' (default 40). */\n toolSearchThreshold?: number\n /** Consent policy for tool calls: autopilot, ask before writes, ask always, read-only. */\n toolApproval?: ToolApprovalConfig\n\n /** Reusable instruction bundles (SKILL.md) the planner/executor can pull in. */\n skills?: Skill[]\n\n /** Prepended to every phase's system prompt. */\n systemPrompt?: string\n /** Override any phase prompt builder. */\n prompts?: Partial<Prompts>\n /** Serialize the host's current world state into prompt context (grounding). */\n describeState?: () => string | Promise<string>\n\n /**\n * Persist the transcript (e.g. new IndexedDBStore()). The last few messages\n * are also read back into the planner prompt, so follow-up goals can refer\n * to earlier turns.\n */\n memory?: ContextStore\n sessionId?: string\n\n /** Hard cap on executed steps incl. replans (default 8). */\n maxIterations?: number\n /** Cap on tool-calling rounds inside one executor call, both modes (default 4). */\n maxStepsPerTask?: number\n /** Cap on replanner \"revise\" decisions per run (default 2). */\n maxRevisions?: number\n /** Cap on tool calls per run (default: unlimited). */\n maxToolCalls?: number\n /** Cap on the steps of one plan (default 8). */\n maxPlanSteps?: number\n /** Per-call timeout so a hang can't freeze a run (default 120000). */\n chatTimeoutMs?: number\n /** Legacy per-phase output caps; `limits.perCall` wins when both are set. */\n budgets?: PhaseBudgets\n /** Run-level token budgets (input / output / thinking / total) + per-call output caps. */\n limits?: TokenLimits\n temperature?: number\n\n /** Thinking for every stage: true, a level ('low'…'xhigh'), or { level, budgetTokens }. */\n thinking?: ThinkingSetting\n /** Per-stage thinking; a stage entry wins over `thinking`. */\n stageThinking?: Partial<Record<ThinkingStage, ThinkingSetting>>\n /**\n * Whether the model accepts images. Default: inferred (`supportsImages`) —\n * local/prompted models are text-only; unknown models are tried and a\n * refusal is reported as ImagesNotSupportedError.\n */\n vision?: boolean\n /** Per-kind override of what the model takes as attachments (`images` wins over `vision`). */\n inputs?: { images?: boolean; pdf?: boolean; files?: boolean }\n /** Provider prompt caching (default true): stable system prefixes + Anthropic breakpoints. */\n promptCaching?: PromptCachingSetting\n /** Context compaction (auto + manual `agent.compact()`); see CompactionConfig. */\n compaction?: CompactionConfig\n\n /** Master switch for the replan phase (default true). */\n replan?: boolean\n /** What triggers the replanner when it is on (default 'failure'). */\n replanAfter?: ReplanTrigger\n /** Write a final natural-language summary (default true). */\n synthesize?: boolean\n /**\n * Legacy: compress stored history past this many chars after each run\n * (0 = off). Used only when `compaction` is not set.\n */\n compressAfterChars?: number\n\n /** Verbosity: 'silent' | 'error' | 'warn' (default) | 'info' | 'debug'. */\n logLevel?: LogLevel\n /** Console-like sink the logs go to (default: the global console). */\n logger?: AgentLoggerSink\n}\n\nexport interface ResolvedConfig {\n clientName: string\n sessionId: string\n toolMode: ToolMode\n toolSelectionStrategy: ToolSelectionStrategy\n toolSearchThreshold: number\n maxIterations: number\n maxStepsPerTask: number\n maxRevisions: number\n maxToolCalls: number\n maxPlanSteps: number\n chatTimeoutMs: number\n /** Effective per-call output caps (limits.perCall over budgets). */\n budgets: Required<PhaseBudgets> & { compaction: number }\n limits: TokenLimits\n temperature: number | undefined\n replan: boolean\n replanAfter: ReplanTrigger\n synthesize: boolean\n compressAfterChars: number\n compaction: ResolvedCompaction\n logLevel: LogLevel\n}\n\nexport const resolveConfig = (c: BrowserAgentConfig): ResolvedConfig => ({\n clientName: c.clientName ?? 'agent-web',\n sessionId: c.sessionId ?? 'default',\n toolMode: c.toolMode ?? 'auto',\n toolSelectionStrategy: c.toolSelectionStrategy ?? 'auto',\n toolSearchThreshold: c.toolSearchThreshold ?? 40,\n maxIterations: c.maxIterations ?? 8,\n maxStepsPerTask: c.maxStepsPerTask ?? 4,\n maxRevisions: c.maxRevisions ?? 2,\n maxToolCalls: c.maxToolCalls ?? 0,\n maxPlanSteps: c.maxPlanSteps ?? 8,\n chatTimeoutMs: c.chatTimeoutMs ?? 120_000,\n budgets: {\n planner: c.limits?.perCall?.planner ?? c.budgets?.planner ?? 800,\n executor: c.limits?.perCall?.executor ?? c.budgets?.executor ?? 1200,\n replanner: c.limits?.perCall?.replanner ?? c.budgets?.replanner ?? 400,\n synthesizer: c.limits?.perCall?.synthesizer ?? c.budgets?.synthesizer ?? 400,\n compaction: c.limits?.perCall?.compaction ?? c.compaction?.summaryMaxTokens ?? 1024,\n },\n limits: c.limits ?? {},\n temperature: c.temperature,\n replan: c.replan ?? true,\n replanAfter: c.replanAfter ?? 'failure',\n synthesize: c.synthesize ?? true,\n compressAfterChars: c.compressAfterChars ?? 12_000,\n compaction: resolveCompaction(c.compaction),\n logLevel: c.logLevel ?? 'warn',\n})\n","import type { IUsage } from './agent/loop-types.js'\n\n/**\n * Run-level token budgets. Every cap is cumulative over one `run()` and soft:\n * it is checked between steps and at every tool-calling round inside a step,\n * so a run stops at the next boundary after crossing it and then writes its\n * final answer (synthesis still runs, bounded by `perCall.synthesizer`).\n */\nexport interface TokenLimits {\n /** Cumulative input (prompt) tokens per run. */\n maxInputTokens?: number\n /** Cumulative output tokens per run, thinking included. */\n maxOutputTokens?: number\n /** Cumulative thinking tokens per run. */\n maxReasoningTokens?: number\n /** Cumulative input + output tokens per run. */\n maxTotalTokens?: number\n /** Max output tokens of ONE model call, per phase (wins over the legacy `budgets`). */\n perCall?: {\n planner?: number\n executor?: number\n replanner?: number\n synthesizer?: number\n compaction?: number\n }\n}\n\nexport type LimitKind = 'input' | 'output' | 'reasoning' | 'total' | 'tool-calls'\n\nexport interface LimitBreach {\n kind: LimitKind\n tokens: number\n cap: number\n}\n\nconst over = (value: number | undefined, cap: number | undefined): boolean =>\n typeof cap === 'number' && cap > 0 && (value ?? 0) >= cap\n\n/**\n * The first cap the usage has reached, or undefined. Order: total, input,\n * output, reasoning — the broadest budget is reported first. Pure.\n */\nexport const checkLimits = (\n usage: IUsage,\n limits: TokenLimits | undefined,\n): LimitBreach | undefined => {\n if (!limits) return undefined\n if (over(usage.totalTokens, limits.maxTotalTokens)) {\n return { kind: 'total', tokens: usage.totalTokens, cap: limits.maxTotalTokens as number }\n }\n if (over(usage.inputTokens, limits.maxInputTokens)) {\n return { kind: 'input', tokens: usage.inputTokens, cap: limits.maxInputTokens as number }\n }\n if (over(usage.outputTokens, limits.maxOutputTokens)) {\n return { kind: 'output', tokens: usage.outputTokens, cap: limits.maxOutputTokens as number }\n }\n if (over(usage.reasoningTokens, limits.maxReasoningTokens)) {\n return {\n kind: 'reasoning',\n tokens: usage.reasoningTokens ?? 0,\n cap: limits.maxReasoningTokens as number,\n }\n }\n return undefined\n}\n\n/** Raised by a tool call that would exceed `maxToolCalls`. */\nexport class ToolBudgetError extends Error {\n constructor(cap: number) {\n super(\n `Tool-call budget exhausted (${cap} per run). Do not call more tools; report what you have.`,\n )\n this.name = 'ToolBudgetError'\n }\n\n toJSON(): string {\n return this.message\n }\n}\n","import type { LanguageModel } from 'ai'\n\n/**\n * Providers the browser registry can resolve from a spec. This is deliberately\n * a browser-safe subset of the Node sibling's list: Amazon Bedrock (SigV4\n * signing), Google Vertex (ADC via google-auth-library) and Cloudflare\n * (Worker bindings / process.env) are Node-only and omitted; Azure folds into\n * `openai-compatible`. `web-llm` is the local WebGPU pseudo-provider (no API\n * key). Any other runtime — Chrome/Edge built-in AI, a custom LanguageModel —\n * is passed to the agent directly and never touches this registry.\n */\nexport type ProviderType =\n | 'openai'\n | 'anthropic'\n | 'google'\n | 'openai-compatible'\n | 'xai'\n | 'deepseek'\n | 'gateway'\n | 'web-llm'\n\n/** A model described by provider + id, resolved through the registry (+ vault). */\nexport interface ProviderModelSpec {\n providerType: ProviderType\n /** Model id, e.g. \"gpt-4o-mini\", \"claude-haiku-4-5\", \"Llama-3.2-3B-Instruct-q4f16_1-MLC\". */\n model: string\n /** Provider endpoint override. Required for `openai-compatible`; a proxy URL for the rest. */\n baseURL?: string\n /** Id under which the API key is stored in the CredentialStore / vault. Preferred. */\n credentialRef?: string\n /**\n * Dev-only inline API key. Prefer `credentialRef` so the key lives encrypted\n * in the vault, not on a long-lived config object. Using this logs a warning.\n */\n apiKey?: string\n /** Extra request headers merged into the provider factory (e.g. a proxy auth header). */\n headers?: Record<string, string>\n /** Escape hatch spread into the SDK factory after baseURL / apiKey / headers. */\n providerOptions?: Record<string, unknown>\n}\n\n/**\n * A per-stage override that inherits the base provider + credentials and\n * changes only the fields it sets (typically just `model`). Distinguished from\n * a full ProviderModelSpec by the absence of `providerType`.\n */\nexport interface StageOverride {\n model?: string\n baseURL?: string\n credentialRef?: string\n apiKey?: string\n headers?: Record<string, string>\n providerOptions?: Record<string, unknown>\n}\n\n/** What a caller hands us for a model: a ready AI SDK model, or a spec to resolve. */\nexport type ModelInput = LanguageModel | ProviderModelSpec\n\n/** A model input, plus the partial-override form usable for per-stage layering. */\nexport type StageInput = ModelInput | StageOverride\n\n/** Outcome of resolving one stage: either a ready model, or a fully-resolved spec. */\nexport type ResolvedStage =\n { type: 'direct'; model: LanguageModel } | { type: 'spec'; spec: ProviderModelSpec }\n\n/** True for a ready AI SDK model: a gateway model-id string or a LanguageModelV* object. */\nexport const isDirectModel = (m: unknown): m is LanguageModel =>\n typeof m === 'string' || (typeof m === 'object' && m !== null && 'specificationVersion' in m)\n\n/** True for a full provider spec (carries the `providerType` discriminator). */\nexport const isProviderSpec = (m: unknown): m is ProviderModelSpec =>\n typeof m === 'object' &&\n m !== null &&\n !isDirectModel(m) &&\n typeof (m as { providerType?: unknown }).providerType === 'string'\n","import type { LanguageModel } from 'ai'\nimport type { CredentialStore } from '../secrets/store.js'\nimport {\n isDirectModel,\n isProviderSpec,\n type ModelInput,\n type ProviderModelSpec,\n type ProviderType,\n type ResolvedStage,\n type StageInput,\n type StageOverride,\n} from './types.js'\n\n// Providers whose endpoint the SDK cannot imply and must be given explicitly.\nconst REQUIRES_BASE_URL: ReadonlySet<ProviderType> = new Set<ProviderType>(['openai-compatible'])\n\n// Providers that authenticate without an API key.\nconst NO_KEY: ReadonlySet<ProviderType> = new Set<ProviderType>(['web-llm'])\n\n// provider -> npm package for the dynamic import and the \"please install X\"\n// message. `gateway` (ships in `ai`) and `web-llm` (its own adapter) are not here.\nconst PROVIDER_PACKAGE: Record<Exclude<ProviderType, 'gateway' | 'web-llm'>, string> = {\n openai: '@ai-sdk/openai',\n anthropic: '@ai-sdk/anthropic',\n google: '@ai-sdk/google',\n 'openai-compatible': '@ai-sdk/openai-compatible',\n xai: '@ai-sdk/xai',\n deepseek: '@ai-sdk/deepseek',\n}\n\nconst loadProvider = async <T>(pkg: string): Promise<T> => {\n try {\n // A variable dynamic import of an optional peer. Both bundler hints are\n // required: without `webpackIgnore` webpack emits \"Critical dependency:\n // the request of a dependency is an expression\" (an error under CI) and\n // tries to build a context module; without `@vite-ignore` Vite warns.\n // Bundlers thus leave the import to the runtime — bundler-less pages map\n // the bare specifier via an import map (see README), and hosts that never\n // use cloud providers (e.g. local WebLLM only) are unaffected.\n return (await import(/* webpackIgnore: true */ /* @vite-ignore */ pkg)) as T\n } catch {\n throw new Error(\n `Provider package \"${pkg}\" is not installed. Add it to your app: npm install ${pkg}`,\n )\n }\n}\n\nconst normalizeSpec = (spec: ProviderModelSpec): ProviderModelSpec => {\n if (REQUIRES_BASE_URL.has(spec.providerType) && !spec.baseURL) {\n throw new Error(`provider \"${spec.providerType}\" requires a baseURL (point it at your server)`)\n }\n return spec\n}\n\n/**\n * Resolve one stage to either a ready model or a fully-resolved spec, layering\n * an optional override on the base:\n * - a direct model (or full spec) override wins outright;\n * - a partial StageOverride inherits the base provider + credentials, changing\n * only the fields it sets (e.g. `{ model: 'gpt-4o-mini' }`);\n * - a full-spec override that switches provider MUST carry its own key\n * (credentialRef/apiKey) — inheriting a key across vendors is a footgun.\n */\nexport const resolveStage = (\n base: ModelInput,\n override: StageInput | undefined,\n stageName: string,\n): ResolvedStage => {\n if (override !== undefined && isDirectModel(override)) {\n return { type: 'direct', model: override }\n }\n if (override !== undefined && isProviderSpec(override)) {\n if (\n isProviderSpec(base) &&\n override.providerType !== base.providerType &&\n !override.credentialRef &&\n !override.apiKey &&\n !NO_KEY.has(override.providerType)\n ) {\n throw new Error(\n `${stageName}: provider \"${override.providerType}\" differs from the base \"${base.providerType}\"; set ${stageName}.credentialRef or apiKey (cross-provider key inheritance is unsafe)`,\n )\n }\n return { type: 'spec', spec: normalizeSpec(override) }\n }\n\n // No override, or a partial StageOverride to layer onto the base.\n if (isDirectModel(base)) {\n if (override && Object.keys(override).length > 0) {\n throw new Error(\n `${stageName}: cannot layer a partial override onto a direct model — pass a full model or ProviderModelSpec for ${stageName}`,\n )\n }\n return { type: 'direct', model: base }\n }\n if (!isProviderSpec(base)) {\n throw new Error(`${stageName}: base model must be a LanguageModel or a ProviderModelSpec`)\n }\n\n const ov = (override ?? {}) as StageOverride\n const merged: ProviderModelSpec = {\n providerType: base.providerType,\n model: ov.model ?? base.model,\n baseURL: ov.baseURL ?? base.baseURL,\n credentialRef: ov.credentialRef ?? base.credentialRef,\n apiKey: ov.apiKey ?? base.apiKey,\n headers: ov.headers ?? base.headers,\n providerOptions: ov.providerOptions ?? base.providerOptions,\n }\n return { type: 'spec', spec: normalizeSpec(merged) }\n}\n\nconst resolveApiKey = async (\n spec: ProviderModelSpec,\n credentials?: CredentialStore,\n): Promise<string | undefined> => {\n if (spec.apiKey) {\n console.warn(\n `[agent-web] using an inline apiKey for provider \"${spec.providerType}\"; prefer credentialRef so the key stays in the encrypted vault`,\n )\n return spec.apiKey\n }\n if (spec.credentialRef) {\n if (!credentials) {\n throw new Error(\n `credentialRef \"${spec.credentialRef}\" is set but no CredentialStore was provided to the agent`,\n )\n }\n const key = await credentials.getApiKey(spec.credentialRef)\n if (!key) {\n throw new Error(\n `no API key found in the CredentialStore for credentialRef \"${spec.credentialRef}\"`,\n )\n }\n return key\n }\n return undefined\n}\n\n/**\n * Turn a resolved stage into an AI SDK `LanguageModel`. Direct models pass\n * through untouched; specs are built by dynamically importing the provider's\n * optional-peer package and fetching the API key from the CredentialStore.\n */\nexport const buildModelFromStage = async (\n resolved: ResolvedStage,\n credentials?: CredentialStore,\n clientName = 'agent-web',\n): Promise<LanguageModel> => {\n if (resolved.type === 'direct') return resolved.model\n const spec = resolved.spec\n const providerOptions = spec.providerOptions ?? {}\n const apiKey = await resolveApiKey(spec, credentials)\n\n switch (spec.providerType) {\n case 'web-llm': {\n const { createWebLLMModel } = await import('./webllm.js')\n return createWebLLMModel(spec.model, providerOptions)\n }\n case 'gateway': {\n // The Vercel AI Gateway ships inside `ai` — no separate peer to install.\n const { createGateway } = await import('ai')\n const provider = createGateway({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'openai': {\n const { createOpenAI } = await loadProvider<typeof import('@ai-sdk/openai')>(\n PROVIDER_PACKAGE.openai,\n )\n const provider = createOpenAI({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'anthropic': {\n const { createAnthropic } = await loadProvider<typeof import('@ai-sdk/anthropic')>(\n PROVIDER_PACKAGE.anthropic,\n )\n const provider = createAnthropic({\n baseURL: spec.baseURL || undefined,\n apiKey,\n // Anthropic's SDK refuses browser calls unless this opt-in header is\n // set; host headers may override it.\n headers: { 'anthropic-dangerous-direct-browser-access': 'true', ...spec.headers },\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'google': {\n const { createGoogleGenerativeAI } = await loadProvider<typeof import('@ai-sdk/google')>(\n PROVIDER_PACKAGE.google,\n )\n const provider = createGoogleGenerativeAI({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'openai-compatible': {\n const { createOpenAICompatible } = await loadProvider<\n typeof import('@ai-sdk/openai-compatible')\n >(PROVIDER_PACKAGE['openai-compatible'])\n const provider = createOpenAICompatible({\n name: clientName,\n baseURL: spec.baseURL as string,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'xai': {\n const { createXai } = await loadProvider<typeof import('@ai-sdk/xai')>(PROVIDER_PACKAGE.xai)\n const provider = createXai({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n case 'deepseek': {\n const { createDeepSeek } = await loadProvider<typeof import('@ai-sdk/deepseek')>(\n PROVIDER_PACKAGE.deepseek,\n )\n const provider = createDeepSeek({\n baseURL: spec.baseURL || undefined,\n apiKey,\n headers: spec.headers,\n ...providerOptions,\n })\n return provider(spec.model)\n }\n }\n}\n\n/** Resolve a single ModelInput straight to a LanguageModel (no per-stage layering). */\nexport const resolveModel = (\n input: ModelInput,\n credentials?: CredentialStore,\n clientName?: string,\n): Promise<LanguageModel> =>\n buildModelFromStage(resolveStage(input, undefined, 'model'), credentials, clientName)\n","/**\n * Default phase prompts. Each builder returns `{ system, prompt }` strings.\n * Because the agent runs in two tool-modes, the builders switch on `ctx.mode`:\n *\n * - `native` — the model calls tools / emits schema-constrained JSON via the\n * AI SDK, so the prompts describe the task and let the SDK enforce structure.\n * - `prompted` — weak local models can't do that reliably, so the prompts spell\n * out an exact JSON shape and (for the executor) include a tool catalogue;\n * the output is salvaged by parse.ts.\n *\n * Layout matters for prompt caching: the SYSTEM part holds only what is stable\n * for a whole run (role, skills, the planner's tool catalogue), the user\n * prompt holds everything that changes (goal, state, history, progress), so a\n * provider's prefix cache can reuse the system part across calls.\n *\n * The agent is autonomous by design: it plans tool use for anything the tools\n * can do or look up, never asks the user for confirmation (consent is the\n * host's `toolApproval` policy), and states assumptions instead of asking.\n *\n * Override any builder via `BrowserAgentConfig.prompts`.\n */\n\nimport { clip } from './llm/util.js'\n\nexport type ToolCallMode = 'native' | 'prompted'\n\nexport interface PromptParts {\n system: string\n prompt: string\n}\n\nexport interface PlannerPromptContext {\n goal: string\n state?: string\n toolCatalog: string\n mode: ToolCallMode\n /** Prior session messages (oldest first), for resolving references to earlier turns. */\n history?: { role: string; content: string }[]\n /** \"- name: description\" index of the configured skills, when any. */\n skills?: string\n /** The catalogue is condensed and the executor can search the rest (large catalogues). */\n searchMode?: boolean\n}\nexport interface ExecutorPromptContext {\n goal: string\n state?: string\n step: string\n index: number\n total: number\n toolCatalog: string\n /** Earlier steps of this run, each with its outcome and key data. */\n done: string[]\n mode: ToolCallMode\n /** \"- name: description\" index of the configured skills, when any. */\n skills?: string\n /** Full instructions of the skills active in this run. */\n activeSkills?: string\n /** The executor can call find_tools to activate more tools. */\n searchMode?: boolean\n}\nexport interface ReplannerPromptContext {\n goal: string\n state?: string\n done: string[]\n remaining: string[]\n mode: ToolCallMode\n activeSkills?: string\n}\nexport interface SynthesizerPromptContext {\n goal: string\n state?: string\n done: string[]\n /** Excerpts of what the tools returned, for answering with real data. */\n findings?: string[]\n activeSkills?: string\n}\n\nexport interface Prompts {\n planner(ctx: PlannerPromptContext): PromptParts\n executor(ctx: ExecutorPromptContext): PromptParts\n replanner(ctx: ReplannerPromptContext): PromptParts\n synthesizer(ctx: SynthesizerPromptContext): PromptParts\n}\n\nconst numbered = (items: string[], empty: string): string =>\n items.length ? items.map((s, i) => `${i + 1}. ${s}`).join('\\n') : empty\n\nconst stateBlock = (state?: string): string => (state && state.trim() ? `\\n\\nSTATE:\\n${state}` : '')\n\n// The last few session messages, capped so a long transcript can't crowd out\n// the goal (memory compression keeps the full story in a summary message).\nconst historyBlock = (history?: { role: string; content: string }[]): string => {\n if (!history || history.length === 0) return ''\n const lines = history.slice(-8).map((m) => `${m.role}: ${clip(m.content, 400)}`)\n return `\\n\\nCONVERSATION SO FAR:\\n${lines.join('\\n')}`\n}\n\nconst section = (title: string, body?: string): string =>\n body && body.trim() ? `\\n\\n${title}:\\n${body.trim()}` : ''\n\n// --- planner ---------------------------------------------------------------\n\nconst PLANNER_RULES = `- Act autonomously: whenever the TOOLS can do the work or look up the answer, plan the steps — a question that needs data, a lookup or a check is a real goal too.\n- Never plan a step that asks the user something. If the request is ambiguous, pick the most reasonable interpretation and say which one you chose.\n- Plan realistic steps the available TOOLS can perform, grounded in the current STATE.\n- If a CONVERSATION SO FAR section is present, use it to resolve references to earlier turns.\n- Never repeat or pad steps.`\n\nconst PLANNER_NATIVE = `You are the PLANNER of an autonomous tool-using agent that works step by step.\nProduce a brief \"thought\" and an ordered \"steps\" list (1–6 DISTINCT, self-contained steps).\nReturn an EMPTY steps list ONLY for a pure greeting, thanks or small talk, or a question you can answer completely from the STATE and general knowledge without any tool — then put the answer itself in \"thought\".\n${PLANNER_RULES}`\n\nconst PLANNER_PROMPTED = `You are the PLANNER of an autonomous tool-using agent that works step by step.\n\nReply with a single JSON object, nothing else:\n{ \"reply\": string, \"plan\": string[], \"skills\": string[] }\n- For a real goal: \"reply\" is one short sentence; \"plan\" is 1–6 DISTINCT, self-contained steps.\n- Set \"plan\": [] ONLY for a pure greeting, thanks or small talk, or a question you can answer completely from the STATE and general knowledge without any tool — then put the answer itself in \"reply\".\n${PLANNER_RULES}`\n\nconst PLANNER_SKILLS = `\\nIf a SKILLS list is present, list the names of the skills that apply to this goal in \"skills\" (or leave it empty).`\n\nconst PLANNER_SEARCH = `\\nThe TOOLS list may be abbreviated: the executor can search the full catalogue, so describe WHAT to do; name tools only when you see them listed.`\n\n// --- executor --------------------------------------------------------------\n\nconst EXECUTOR_RULES = `- Work autonomously: never ask the user questions or for confirmation. Look things up with the tools, choose sensible defaults, and state any assumption in your reply. Permission to run tools is handled by the system, not by you.\n- Build on the current STATE and on the results of earlier steps — do not repeat work that is already done.`\n\nconst EXECUTOR_NATIVE = `You are the EXECUTOR of an autonomous tool-using agent. Carry out ONLY the current step by calling the provided tools.\n${EXECUTOR_RULES}\n- When the step is done, reply with a short factual summary of what you did and found, including the concrete data (names, ids, numbers, values) later steps or the final answer need. No JSON.\n- If you truly CANNOT complete the step (a needed tool is missing or was denied, credentials or data are unavailable), explain why in one sentence and include the token [BLOCKER].`\n\nconst EXECUTOR_PROMPTED = `You are the EXECUTOR of an autonomous tool-using agent. Carry out ONLY the current step by emitting tool calls.\n\nReply with a single JSON object, nothing else:\n{ \"reply\": string, \"actions\": [ { \"tool\": string, \"args\": object } ] }\n- \"actions\" are the tool calls for THIS step ([] if none are needed). Use ONLY tools from the TOOLS list; \"args\" must match the tool's parameters.\n${EXECUTOR_RULES}\n- \"reply\" is a short factual summary (no JSON) of what you did and found, with the concrete data later steps need.\n- After your actions run you will see their TOOL RESULTS and may continue the same step; finish with \"actions\": [] once it is done.\n- If you truly CANNOT complete the step, set \"actions\": [] and put the token [BLOCKER] in \"reply\" with a short reason.`\n\nconst EXECUTOR_SEARCH = `\\n- If a tool you need is not in your current tool list, call find_tools with keywords; the tools it returns become callable right after.`\n\nconst EXECUTOR_SKILLS = `\\n- If a skill from the SKILLS list covers this step, call load_skill to read it first (read_skill_file for its bundled files).`\n\n// --- replanner -------------------------------------------------------------\n\nconst REPLANNER_RULES = `Judge from the current STATE and the progress vs the goal. Prefer \"continue\".\nAfter a failure, prefer revising around it (another tool, another approach) over giving up; never add a step that asks the user something.`\n\nconst REPLANNER_NATIVE = `You are the REPLANNER of an autonomous agent. After an executed step, decide whether to keep going, revise the remaining steps, or finish.\n\"continue\": the remaining steps still fit. \"revise\": provide a better \"plan\" for the REMAINING work (never repeat done work). \"finish\": the goal is already met.\n${REPLANNER_RULES}`\n\nconst REPLANNER_PROMPTED = `You are the REPLANNER of an autonomous agent. After each executed step you decide whether to keep going, revise the remaining steps, or finish.\n\nReply with a single JSON object, nothing else:\n{ \"decision\": \"continue\" | \"revise\" | \"finish\", \"reason\": string, \"plan\": string[] }\n- \"continue\": remaining steps still fit — proceed (omit \"plan\").\n- \"revise\": replace the REMAINING steps with a better list in \"plan\"; never repeat done work.\n- \"finish\": the goal is already met — stop (omit \"plan\").\n${REPLANNER_RULES}`\n\nconst SYNTHESIZER_SYSTEM = `You are the SYNTHESIZER. Answer the user's goal from what the agent did and found.\n- Lead with the result: the concrete data, from the FINDINGS verbatim when accuracy matters (names, numbers, ids), then — briefly — what was changed.\n- Mention any assumption the agent made. If something could not be done, say so plainly and why.\n- Do not ask follow-up questions unless the goal genuinely cannot be completed without the user.\n- Be concise and friendly. Plain text (light markdown is fine) — no JSON, no code.`\n\nexport const defaultPrompts: Prompts = {\n planner: (ctx) => ({\n system:\n (ctx.mode === 'prompted' ? PLANNER_PROMPTED : PLANNER_NATIVE) +\n (ctx.skills ? PLANNER_SKILLS : '') +\n (ctx.searchMode ? PLANNER_SEARCH : '') +\n section('SKILLS', ctx.skills) +\n `\\n\\nTOOLS:\\n${ctx.toolCatalog}`,\n prompt: `GOAL: ${ctx.goal}${historyBlock(ctx.history)}${stateBlock(ctx.state)}`,\n }),\n executor: (ctx) => ({\n system:\n (ctx.mode === 'prompted' ? EXECUTOR_PROMPTED : EXECUTOR_NATIVE) +\n (ctx.searchMode ? EXECUTOR_SEARCH : '') +\n (ctx.skills ? EXECUTOR_SKILLS : '') +\n section('SKILLS', ctx.skills) +\n section('ACTIVE SKILL INSTRUCTIONS', ctx.activeSkills),\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n ctx.mode === 'prompted' ? `TOOLS:\\n${ctx.toolCatalog}` : '',\n ctx.done.length ? `Already done:\\n${numbered(ctx.done, '')}` : '',\n `STEP ${ctx.index}/${ctx.total}: ${ctx.step}`,\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n replanner: (ctx) => ({\n system:\n (ctx.mode === 'prompted' ? REPLANNER_PROMPTED : REPLANNER_NATIVE) +\n section('ACTIVE SKILL INSTRUCTIONS', ctx.activeSkills),\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n `Already done:\\n${numbered(ctx.done, '(nothing yet)')}`,\n `Remaining plan:\\n${numbered(ctx.remaining, '(none)')}`,\n 'Decide: continue, revise, or finish.',\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n synthesizer: (ctx) => ({\n system: SYNTHESIZER_SYSTEM + section('ACTIVE SKILL INSTRUCTIONS', ctx.activeSkills),\n prompt: [\n `GOAL: ${ctx.goal}`,\n stateBlock(ctx.state).trimStart(),\n `What was done:\\n${numbered(ctx.done, '(no changes)')}`,\n ctx.findings?.length ? `FINDINGS (tool results):\\n${ctx.findings.join('\\n')}` : '',\n 'Write the final answer for the user.',\n ]\n .filter(Boolean)\n .join('\\n\\n'),\n }),\n}\n\n/** Prepend a host-supplied systemPrompt to a phase system prompt, if present. */\nexport const withSystem = (base: string, extra?: string): string =>\n extra && extra.trim() ? `${extra.trim()}\\n\\n${base}` : base\n","import { jsonSchema, tool, type ToolSet } from 'ai'\nimport { clip } from './llm/util.js'\n\n/**\n * Skills — reusable instruction bundles in the agentskills.io shape\n * (`SKILL.md` with `name`/`description` frontmatter, a markdown body, optional\n * bundled text files). Progressive disclosure: only the one-line index sits in\n * the prompts; a skill's full instructions enter the context when the planner\n * selects it or the executor loads it with `load_skill`.\n */\nexport interface Skill {\n /** Stable id: lowercase letters, digits and dashes, 1–64 chars. */\n name: string\n /** When to use it — the only part always shown to the model. */\n description: string\n /** Full instructions (the markdown body of SKILL.md). */\n content: string\n /** Bundled text resources, addressed by skill-relative POSIX paths. */\n files?: { path: string; content: string }[]\n}\n\nexport const SKILL_NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/\n\n/** Names of the built-in skill tools (reserved when skills are configured). */\nexport const SKILL_TOOL_NAMES = ['load_skill', 'read_skill_file'] as const\n\n/** Validate a skill definition and return it (throws a precise error). */\nexport const defineSkill = (skill: Skill): Skill => {\n if (!skill || typeof skill !== 'object') throw new Error('skill must be an object')\n if (typeof skill.name !== 'string' || !SKILL_NAME_RE.test(skill.name)) {\n throw new Error(\n `skill name ${JSON.stringify(skill.name)} is invalid: use 1-64 lowercase letters, digits and dashes`,\n )\n }\n if (typeof skill.description !== 'string' || !skill.description.trim()) {\n throw new Error(`skill \"${skill.name}\" needs a description`)\n }\n if (typeof skill.content !== 'string') {\n throw new Error(`skill \"${skill.name}\" needs a content string`)\n }\n for (const f of skill.files ?? []) {\n if (typeof f?.path !== 'string' || !f.path || f.path.startsWith('/') || f.path.includes('..')) {\n throw new Error(`skill \"${skill.name}\": invalid file path ${JSON.stringify(f?.path)}`)\n }\n }\n return skill\n}\n\nconst unquote = (v: string): string => {\n const t = v.trim()\n if (t.length >= 2 && t.startsWith('\"') && t.endsWith('\"')) {\n try {\n return JSON.parse(t) as string\n } catch {\n return t.slice(1, -1)\n }\n }\n if (t.length >= 2 && t.startsWith(\"'\") && t.endsWith(\"'\")) {\n return t.slice(1, -1).replace(/''/g, \"'\")\n }\n return t\n}\n\n/**\n * Parse the small YAML subset SKILL.md frontmatter uses: `key: value` pairs,\n * single/double-quoted values, and `>` / `|` block scalars. Unknown keys are\n * kept (as strings) but ignored by the agent.\n */\nconst parseFrontmatter = (block: string): Record<string, string> => {\n const out: Record<string, string> = {}\n const lines = block.split(/\\r?\\n/)\n for (let i = 0; i < lines.length; i += 1) {\n const m = /^([A-Za-z0-9_-]+):\\s*(.*)$/.exec(lines[i])\n if (!m) continue\n const [, key, rest] = m\n if (rest === '>' || rest === '|' || rest === '>-' || rest === '|-') {\n const body: string[] = []\n while (i + 1 < lines.length && (/^\\s+\\S/.test(lines[i + 1]) || lines[i + 1] === '')) {\n body.push(lines[i + 1].trim())\n i += 1\n }\n out[key] = rest.startsWith('>') ? body.filter(Boolean).join(' ') : body.join('\\n').trim()\n continue\n }\n out[key] = unquote(rest)\n }\n return out\n}\n\n/**\n * Parse a SKILL.md document into a {@link Skill}. Frontmatter must provide\n * `name` and `description`; the markdown body becomes `content`.\n */\nexport const parseSkillMarkdown = (\n markdown: string,\n files?: { path: string; content: string }[],\n): Skill => {\n const text = (markdown ?? '').replace(/^/, '')\n const m = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/.exec(text)\n if (!m) throw new Error('SKILL.md must start with a --- frontmatter block (name, description)')\n const meta = parseFrontmatter(m[1])\n return defineSkill({\n name: meta.name ?? '',\n description: meta.description ?? '',\n content: m[2].trim(),\n ...(files?.length ? { files } : {}),\n })\n}\n\nexport interface LoadSkillOptions {\n /** Bundled files to fetch, relative to the SKILL.md URL. */\n files?: string[]\n fetch?: typeof fetch\n}\n\n/** Fetch a SKILL.md (and optionally its bundled files) over HTTP. */\nexport const loadSkillFromUrl = async (\n url: string,\n opts: LoadSkillOptions = {},\n): Promise<Skill> => {\n const fetchFn = opts.fetch ?? globalThis.fetch\n const res = await fetchFn(url)\n if (!res.ok) throw new Error(`could not fetch ${url}: HTTP ${res.status}`)\n const markdown = await res.text()\n const files: { path: string; content: string }[] = []\n for (const path of opts.files ?? []) {\n const r = await fetchFn(new URL(path, url).toString())\n if (!r.ok) throw new Error(`could not fetch skill file ${path}: HTTP ${r.status}`)\n files.push({ path, content: await r.text() })\n }\n return parseSkillMarkdown(markdown, files)\n}\n\n/** \"- name: description\" lines for the prompts. */\nexport const renderSkillIndex = (skills: Skill[]): string =>\n skills.map((s) => `- ${s.name}: ${s.description.replace(/\\s+/g, ' ').trim()}`).join('\\n')\n\nconst ACTIVE_SKILLS_BUDGET = 24_000\n\n/** The full instructions of the active skills, within a total character budget. */\nexport const renderActiveSkills = (skills: Skill[]): string => {\n let budget = ACTIVE_SKILLS_BUDGET\n const parts: string[] = []\n for (const s of skills) {\n if (budget <= 0) break\n const files = s.files?.length\n ? `\\n(bundled files, read with read_skill_file: ${s.files.map((f) => f.path).join(', ')})`\n : ''\n const block = clip(`### Skill: ${s.name}\\n${s.content}${files}`, budget)\n budget -= block.length\n parts.push(block)\n }\n return parts.join('\\n\\n')\n}\n\n/**\n * The built-in `load_skill` / `read_skill_file` tools. `onLoad` fires when a\n * skill is loaded so the runner can keep it active for later steps.\n */\nexport const createSkillTools = (skills: Skill[], onLoad?: (skill: Skill) => void): ToolSet => {\n const byName = new Map(skills.map((s) => [s.name, s]))\n const known = skills.map((s) => s.name).join(', ')\n const loadSkill = tool({\n description:\n 'Load the full instructions of a skill from the SKILLS list before doing work it covers.',\n inputSchema: jsonSchema<{ name: string }>({\n type: 'object',\n properties: { name: { type: 'string', description: 'The skill name' } },\n required: ['name'],\n additionalProperties: false,\n }),\n execute: async ({ name }) => {\n const skill = byName.get(name)\n if (!skill) throw new Error(`unknown skill \"${name}\"; available: ${known}`)\n onLoad?.(skill)\n return {\n name: skill.name,\n content: skill.content,\n files: (skill.files ?? []).map((f) => f.path),\n }\n },\n })\n const readFile = tool({\n description: \"Read one of a skill's bundled files (paths are listed by load_skill).\",\n inputSchema: jsonSchema<{ name: string; path: string }>({\n type: 'object',\n properties: {\n name: { type: 'string', description: 'The skill name' },\n path: { type: 'string', description: 'The file path, relative to the skill' },\n },\n required: ['name', 'path'],\n additionalProperties: false,\n }),\n execute: async ({ name, path }) => {\n const skill = byName.get(name)\n if (!skill) throw new Error(`unknown skill \"${name}\"; available: ${known}`)\n const file = skill.files?.find((f) => f.path === path)\n if (!file) {\n const listed = (skill.files ?? []).map((f) => f.path).join(', ') || 'none'\n throw new Error(`skill \"${name}\" has no file \"${path}\"; files: ${listed}`)\n }\n return file.content\n },\n })\n for (const t of [loadSkill, readFile]) {\n ;(t as { readOnly?: boolean }).readOnly = true\n ;(t as { promptHint?: string }).promptHint =\n t === loadSkill ? '{ name: string }' : '{ name: string, path: string }'\n }\n return { load_skill: loadSkill, read_skill_file: readFile }\n}\n","import type { Tool } from 'ai'\nimport type { IPlanStep } from '../agent/loop-types.js'\n\n/**\n * Tool consent. Every tool call passes a gate that decides allow / ask / deny:\n *\n * - `autopilot` — run everything (default; explicit `rules` still apply);\n * - `ask-writes` — run read-only tools, ask before anything that may change state;\n * - `ask-all` — ask before every call;\n * - `read-only` — run read-only tools, refuse the rest without asking.\n *\n * A tool is read-only when its MCP annotations say so (`readOnlyHint`) or the\n * host marked it (`defineTool({ readOnly: true })` / `markReadOnly`). Unknown =\n * may write: the safe assumption.\n */\nexport type ToolApprovalMode = 'autopilot' | 'ask-writes' | 'ask-all' | 'read-only'\nexport type ToolPermission = 'allow' | 'ask' | 'deny'\n\nexport const TOOL_APPROVAL_MODES: readonly ToolApprovalMode[] = [\n 'autopilot',\n 'ask-writes',\n 'ask-all',\n 'read-only',\n]\n\nexport interface ToolApprovalRequest {\n /** Unique per request — echo it back from a UI. */\n id: string\n toolName: string\n input: unknown\n readOnly: boolean\n step?: IPlanStep\n}\n\n/**\n * `true`/`false`, or an object. `remember: true` on an approval allows this\n * tool for the rest of the agent's life (\"always allow\").\n */\nexport type ToolApprovalDecision =\n boolean | { approved: boolean; reason?: string; remember?: boolean }\n\nexport interface ToolApprovalConfig {\n /** Default policy (default 'autopilot'). */\n mode?: ToolApprovalMode\n /**\n * Per-tool overrides by exact name or `*` glob, e.g. `{ 'github__delete_*': 'deny' }`.\n * They win over the mode — an explicit 'ask' still asks under autopilot.\n */\n rules?: Record<string, ToolPermission>\n /** Resolves an approval request (a UI prompt, a policy service, …). */\n onRequest?: (req: ToolApprovalRequest) => ToolApprovalDecision | Promise<ToolApprovalDecision>\n /** No decision within this many ms → deny. Default: wait indefinitely. */\n timeoutMs?: number\n}\n\n/** Raised by a denied tool call; recorded as a failed call the replanner sees. */\nexport class ToolDeniedError extends Error {\n constructor(reason?: string) {\n super(\n `Tool call denied by the user${reason ? `: ${reason}` : ''}. Do not retry it; continue without it, or report what is blocked.`,\n )\n this.name = 'ToolDeniedError'\n }\n\n toJSON(): string {\n return this.message\n }\n}\n\n/** Mark a tool as read-only so `ask-writes` / `read-only` let it through. Returns it. */\nexport const markReadOnly = <T extends object>(tool: T, readOnly = true): T => {\n ;(tool as { readOnly?: boolean }).readOnly = readOnly\n return tool\n}\n\nexport const isReadOnlyTool = (tool: Tool | undefined): boolean =>\n (tool as { readOnly?: unknown } | undefined)?.readOnly === true\n\nconst globToRegExp = (glob: string): RegExp =>\n new RegExp(\n `^${glob\n .split('*')\n .map((s) => s.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('.*')}$`,\n )\n\n/** The most specific matching rule: an exact name, else the longest glob. Pure. */\nexport const matchRule = (\n rules: Record<string, ToolPermission> | undefined,\n toolName: string,\n): ToolPermission | undefined => {\n if (!rules) return undefined\n if (Object.hasOwn(rules, toolName)) return rules[toolName]\n let best: { len: number; perm: ToolPermission } | undefined\n for (const [pattern, perm] of Object.entries(rules)) {\n if (!pattern.includes('*')) continue\n if (!globToRegExp(pattern).test(toolName)) continue\n const len = pattern.replace(/\\*/g, '').length\n if (!best || len > best.len) best = { len, perm }\n }\n return best?.perm\n}\n\n/**\n * What the gate does for one call, before any human is involved. Order:\n * remembered \"always allow\" → most specific rule → mode default. Pure.\n */\nexport const decideToolPermission = (opts: {\n toolName: string\n readOnly: boolean\n mode: ToolApprovalMode\n rules?: Record<string, ToolPermission>\n remembered?: ReadonlySet<string>\n}): ToolPermission => {\n if (opts.remembered?.has(opts.toolName)) return 'allow'\n const rule = matchRule(opts.rules, opts.toolName)\n if (rule) return rule\n switch (opts.mode) {\n case 'autopilot':\n return 'allow'\n case 'read-only':\n return opts.readOnly ? 'allow' : 'deny'\n case 'ask-writes':\n return opts.readOnly ? 'allow' : 'ask'\n case 'ask-all':\n return 'ask'\n }\n}\n\nconst normalizeDecision = (\n d: ToolApprovalDecision,\n): { approved: boolean; reason?: string; remember?: boolean } =>\n typeof d === 'boolean'\n ? { approved: d }\n : { approved: Boolean(d?.approved), reason: d?.reason, remember: d?.remember }\n\n/** Mutable approval state shared by every run of one agent. */\nexport interface ApprovalState {\n mode: ToolApprovalMode\n readonly config: ToolApprovalConfig\n /** Tools the user chose to \"always allow\". */\n readonly remembered: Set<string>\n}\n\nexport const createApprovalState = (config: ToolApprovalConfig | undefined): ApprovalState => ({\n mode: config?.mode ?? 'autopilot',\n config: config ?? {},\n remembered: new Set<string>(),\n})\n\nlet seq = 0\n\nexport interface ApprovalEvents {\n requested: (req: ToolApprovalRequest) => void\n resolved: (r: {\n id: string\n name: string\n approved: boolean\n reason?: string\n automatic: boolean\n }) => void\n}\n\n/**\n * Run the gate for one call. Resolves when the call may proceed; throws\n * {@link ToolDeniedError} otherwise. `alwaysAllow` short-circuits (built-ins).\n */\nexport const gateToolCall = async (\n state: ApprovalState,\n call: { toolName: string; input: unknown; readOnly: boolean; step?: IPlanStep },\n events: ApprovalEvents,\n signal?: AbortSignal,\n): Promise<void> => {\n const permission = decideToolPermission({\n toolName: call.toolName,\n readOnly: call.readOnly,\n mode: state.mode,\n rules: state.config.rules,\n remembered: state.remembered,\n })\n if (permission === 'allow') return\n const id = `approval-${Date.now().toString(36)}-${(seq += 1)}`\n if (permission === 'deny') {\n const reason =\n state.mode === 'read-only' && !matchRule(state.config.rules, call.toolName)\n ? 'the agent is in read-only mode'\n : 'blocked by policy'\n events.resolved({ id, name: call.toolName, approved: false, reason, automatic: true })\n throw new ToolDeniedError(reason)\n }\n const onRequest = state.config.onRequest\n if (!onRequest) {\n const reason = 'no approval handler configured'\n events.resolved({ id, name: call.toolName, approved: false, reason, automatic: true })\n throw new ToolDeniedError(reason)\n }\n const req: ToolApprovalRequest = { id, ...call }\n events.requested(req)\n let decision: { approved: boolean; reason?: string; remember?: boolean }\n try {\n decision = normalizeDecision(\n await withDeadline(Promise.resolve(onRequest(req)), state.config.timeoutMs, signal),\n )\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err)\n events.resolved({ id, name: call.toolName, approved: false, reason, automatic: true })\n throw new ToolDeniedError(reason)\n }\n if (decision.approved && decision.remember) state.remembered.add(call.toolName)\n events.resolved({\n id,\n name: call.toolName,\n approved: decision.approved,\n reason: decision.reason,\n automatic: false,\n })\n if (!decision.approved) throw new ToolDeniedError(decision.reason)\n}\n\nconst withDeadline = <T>(\n p: Promise<T>,\n timeoutMs: number | undefined,\n signal?: AbortSignal,\n): Promise<T> => {\n if ((!timeoutMs || timeoutMs <= 0) && !signal) return p\n return new Promise<T>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const done = () => {\n if (timer !== undefined) clearTimeout(timer)\n signal?.removeEventListener('abort', onAbort)\n }\n const onAbort = () => {\n done()\n reject(new Error('the run was stopped while waiting for approval'))\n }\n if (signal?.aborted) return onAbort()\n signal?.addEventListener('abort', onAbort, { once: true })\n if (timeoutMs && timeoutMs > 0) {\n timer = setTimeout(() => {\n done()\n reject(new Error(`no approval decision within ${timeoutMs} ms`))\n }, timeoutMs)\n }\n p.then(\n (v) => {\n done()\n resolve(v)\n },\n (e) => {\n done()\n reject(e)\n },\n )\n })\n}\n","import type { LanguageModel } from 'ai'\nimport type { ToolMode } from '../config.js'\n\n// Local / on-device runtimes whose tiny models are unreliable at native\n// function-calling and JSON-schema output — default them to the prompted path.\nconst LOCAL_RE = /web-?llm|mlc|browser-ai|transformers|nano|built-?in/i\n\n/**\n * Decide the tool-calling strategy for a resolved model. An explicit\n * config.toolMode of 'native'/'prompted' always wins; 'auto' (default) inspects\n * the model's provider id — local/on-device runtimes → 'prompted', cloud → 'native'.\n * A string model is a gateway model id (\"openai/gpt-4o\") — always cloud; the\n * LOCAL_RE must not see it, or model names like \"gpt-5-nano\" would match `nano`.\n */\nexport const selectToolMode = (\n model: LanguageModel,\n mode: ToolMode = 'auto',\n): 'native' | 'prompted' => {\n if (mode === 'native' || mode === 'prompted') return mode\n if (typeof model === 'string') return 'native'\n const provider = (model as { provider?: string }).provider ?? ''\n return LOCAL_RE.test(provider) ? 'prompted' : 'native'\n}\n","import type { Tool, ToolSet } from 'ai'\n\n/**\n * The canonical tool shape is the AI SDK `Tool` — the same object the native\n * tool-calling path passes straight to `streamText({ tools })`, and the same\n * shape MCP tools take. We add one optional field, `promptHint`, a short\n * human-readable parameter hint (e.g. \"{ text: string, x?: number }\") used only\n * by the prompted/salvage path when it renders the tool catalogue into a text\n * prompt for weak local models.\n */\nexport type AgentTool = Tool & { promptHint?: string; readOnly?: boolean }\n\n/** A named collection of tools — a plain AI SDK ToolSet, usable directly. */\nexport type AgentToolSet = ToolSet\n\n/** Read the optional promptHint attached by defineTool, if any. */\nexport const promptHintOf = (tool: Tool): string | undefined =>\n typeof (tool as { promptHint?: unknown }).promptHint === 'string'\n ? (tool as { promptHint?: string }).promptHint\n : undefined\n","import type { ModelMessage, ToolSet } from 'ai'\nimport type { RawAction } from '../parse.js'\nimport type { IToolCall } from '../agent/loop-types.js'\nimport { promptHintOf, type AgentToolSet } from './types.js'\n\n/**\n * Render a ToolSet into a plain-text catalogue for the prompted/salvage path:\n * `- name(hint): description`. The hint comes from `defineTool({ promptHint })`\n * when present, else from `hintOf` (the agent derives one from the tool's JSON\n * schema, so MCP tools get one too); weak local models lean on it to fill args.\n */\nexport const renderCatalog = (\n tools: AgentToolSet,\n hintOf?: (name: string) => string | undefined,\n): string => {\n const names = Object.keys(tools)\n if (names.length === 0) return '(no tools)'\n return names\n .map((name) => {\n const t = tools[name]\n const hint = promptHintOf(t) ?? hintOf?.(name) ?? ''\n const desc = typeof t.description === 'string' ? t.description : ''\n return `- ${name}(${hint}): ${desc}`\n })\n .join('\\n')\n}\n\ninterface DispatchContext {\n abortSignal?: AbortSignal\n messages?: ModelMessage[]\n toolCallId?: string\n}\n\n/**\n * Validate and execute a single salvaged tool call against the ToolSet, using\n * the tool's OWN `execute` and `inputSchema` — the identical implementation the\n * native path calls. Unknown tools, schema-invalid args, and thrown errors all\n * become a failed IToolCall rather than throwing.\n */\nexport const dispatch = async (\n action: RawAction,\n tools: ToolSet,\n ctx: DispatchContext = {},\n): Promise<IToolCall> => {\n const t = tools[action.tool]\n if (!t) {\n return {\n name: action.tool,\n input: action.args,\n output: `unknown tool \"${action.tool}\"`,\n ok: false,\n }\n }\n let input: unknown = action.args\n const schema = (t as { inputSchema?: unknown }).inputSchema\n // Best-effort Zod validation (a jsonSchema() input has no safeParse — the\n // tool's execute is expected to guard those itself).\n if (schema && typeof (schema as { safeParse?: unknown }).safeParse === 'function') {\n const parsed = (\n schema as {\n safeParse: (v: unknown) => { success: boolean; data?: unknown; error?: { message: string } }\n }\n ).safeParse(input)\n if (!parsed.success) {\n return {\n name: action.tool,\n input,\n output: `invalid args for \"${action.tool}\": ${parsed.error?.message ?? 'schema validation failed'}`,\n ok: false,\n }\n }\n input = parsed.data\n }\n const execute = (t as { execute?: (i: unknown, o: unknown) => unknown }).execute\n if (typeof execute !== 'function') {\n return { name: action.tool, input, output: `tool \"${action.tool}\" has no execute`, ok: false }\n }\n try {\n const output = await execute(input, {\n toolCallId: ctx.toolCallId ?? `prompted-${action.tool}`,\n messages: ctx.messages ?? [],\n abortSignal: ctx.abortSignal,\n })\n return { name: action.tool, input, output, ok: true }\n } catch (err) {\n return {\n name: action.tool,\n input,\n output: err instanceof Error ? err.message : 'tool error',\n ok: false,\n }\n }\n}\n","import { jsonSchema, tool, type Tool, type ToolSet } from 'ai'\nimport { isReadOnlyTool } from './approval.js'\n\n/**\n * Tool search for large catalogues. Several MCP servers easily add up to\n * hundreds of tools — sending every schema on every call wastes the context\n * window (and OpenAI rejects more than 128 tools outright). In 'search' mode\n * the executor starts each step with a handful of tools and a `find_tools`\n * meta-tool that activates more on demand.\n */\nexport interface ToolCatalogEntry {\n name: string\n description: string\n /** The MCP server a tool came from (\"server__tool\" prefix), when known. */\n server?: string\n readOnly?: boolean\n}\n\nexport const FIND_TOOLS_NAME = 'find_tools'\n\n/** Build catalogue entries from a ToolSet (\"server__tool\" names yield a server). */\nexport const toolCatalogOf = (tools: ToolSet): ToolCatalogEntry[] =>\n Object.entries(tools).map(([name, t]) => {\n const sep = name.indexOf('__')\n return {\n name,\n description: typeof t.description === 'string' ? t.description : '',\n ...(sep > 0 ? { server: name.slice(0, sep) } : {}),\n readOnly: isReadOnlyTool(t as Tool),\n }\n })\n\n/** Lowercased word tokens; snake_case, kebab-case and camelCase are split. */\nexport const tokenize = (s: string): string[] =>\n (s ?? '')\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter(Boolean)\n\nconst hits = (term: string, words: string[]): boolean =>\n words.some(\n (w) =>\n w === term ||\n (term.length >= 3 && (w.startsWith(term) || (term.startsWith(w) && w.length >= 3))),\n )\n\nexport interface SearchToolsOptions {\n /** Only tools from this server. */\n server?: string\n /** Max results (default 8, capped at 20). */\n limit?: number\n /** Names to leave out (e.g. already active). */\n exclude?: ReadonlySet<string>\n}\n\n/**\n * Rank catalogue entries against a keyword query: each query term scores\n * 3 for a name hit, 2 for a server hit and 1 for a description hit (prefix\n * matching for terms of 3+ chars). Ties keep catalogue order; zero scores are\n * dropped. Pure and deterministic — no embeddings, no model call.\n */\nexport const searchTools = (\n catalog: ToolCatalogEntry[],\n query: string,\n opts: SearchToolsOptions = {},\n): ToolCatalogEntry[] => {\n const terms = [...new Set(tokenize(query))]\n const limit = Math.min(Math.max(1, opts.limit ?? 8), 20)\n const server = opts.server?.toLowerCase()\n const scored: { entry: ToolCatalogEntry; score: number; index: number }[] = []\n catalog.forEach((entry, index) => {\n if (opts.exclude?.has(entry.name)) return\n if (server && entry.server?.toLowerCase() !== server) return\n const nameWords = tokenize(\n entry.server ? entry.name.slice(entry.server.length + 2) : entry.name,\n )\n const serverWords = tokenize(entry.server ?? '')\n const descWords = tokenize(entry.description)\n let score = 0\n for (const term of terms) {\n if (hits(term, nameWords)) score += 3\n if (hits(term, serverWords)) score += 2\n if (hits(term, descWords)) score += 1\n }\n // A server filter with an empty query lists that server's tools.\n if (terms.length === 0 && server) score = 1\n if (score > 0) scored.push({ entry, score, index })\n })\n scored.sort((a, b) => b.score - a.score || a.index - b.index)\n return scored.slice(0, limit).map((s) => s.entry)\n}\n\n/**\n * The planner's view of a large catalogue: grouped by server, short\n * descriptions, within a character budget.\n */\nexport const renderSearchCatalog = (catalog: ToolCatalogEntry[], budget = 12_000): string => {\n if (catalog.length === 0) return '(no tools)'\n const groups = new Map<string, ToolCatalogEntry[]>()\n for (const e of catalog) {\n const key = e.server ?? '(host)'\n groups.set(key, [...(groups.get(key) ?? []), e])\n }\n const lines: string[] = []\n let used = 0\n let shown = 0\n for (const [server, entries] of groups) {\n const head = `[${server}] ${entries.length} tool(s)`\n if (used + head.length > budget) break\n lines.push(head)\n used += head.length + 1\n for (const e of entries) {\n const desc = e.description.replace(/\\s+/g, ' ').trim().slice(0, 60)\n const line = `- ${e.name}${desc ? `: ${desc}` : ''}`\n if (used + line.length > budget) break\n lines.push(line)\n used += line.length + 1\n shown += 1\n }\n }\n const rest = catalog.length - shown\n if (rest > 0)\n lines.push(`… ${rest} more tool(s) — the executor can find them with ${FIND_TOOLS_NAME}`)\n return lines.join('\\n')\n}\n\n/**\n * The `find_tools` meta-tool. `onFound` receives the matched names so the\n * caller can activate them (native: prepareStep activeTools; prompted: the\n * next round's catalogue).\n */\nexport const createFindToolsTool = (\n catalog: () => ToolCatalogEntry[],\n onFound: (query: string, names: string[]) => void,\n hintOf?: (name: string) => string | undefined,\n): Tool => {\n const t = tool({\n description:\n 'Search the full tool catalogue by keywords and make the matching tools callable from the next step on. ' +\n 'Use it whenever the tool you need is not in your current tool list.',\n inputSchema: jsonSchema<{ query: string; server?: string; limit?: number }>({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Keywords: what the tool should do' },\n server: { type: 'string', description: 'Optional: only tools of this MCP server' },\n limit: { type: 'number', description: 'Max results (default 8, max 20)' },\n },\n required: ['query'],\n additionalProperties: false,\n }),\n execute: async ({ query, server, limit }) => {\n const found = searchTools(catalog(), query, { server, limit })\n onFound(\n query,\n found.map((f) => f.name),\n )\n return {\n tools: found.map((f) => ({\n name: f.name,\n description: f.description,\n ...(f.server ? { server: f.server } : {}),\n readOnly: Boolean(f.readOnly),\n ...(hintOf?.(f.name) ? { args: hintOf(f.name) } : {}),\n })),\n note: found.length\n ? 'These tools are now callable.'\n : 'No tool matched; try other keywords or a server name.',\n }\n },\n })\n ;(t as { readOnly?: boolean }).readOnly = true\n ;(t as { promptHint?: string }).promptHint = '{ query: string, server?: string, limit?: number }'\n return t\n}\n","import { asSchema, type Tool, type ToolSet } from 'ai'\nimport type { IPlanStep, IUsage } from '../agent/loop-types.js'\nimport type { AgentEvent } from '../events.js'\nimport { ToolBudgetError } from '../limits.js'\nimport {\n decideToolPermission,\n gateToolCall,\n isReadOnlyTool,\n type ApprovalState,\n} from './approval.js'\nimport { promptHintOf } from './types.js'\n\n/**\n * What a tool's `execute` can reach of the run that called it, passed as\n * `options.agentRun`. Subagent tools use it to stream nested events and to\n * charge their usage to the parent run.\n */\nexport interface ToolRunContext {\n emit: (event: AgentEvent) => void\n /** The plan step being executed, when there is one. */\n step?: IPlanStep\n signal?: AbortSignal\n /** Add tokens spent on the parent's behalf (e.g. by a subagent) to the run. */\n addUsage: (usage: IUsage) => void\n /**\n * Run the agent's consent gate for a call made on its behalf (e.g. a host\n * tool a subagent calls). Resolves when allowed, throws ToolDeniedError.\n */\n approve: (toolName: string, input: unknown, readOnly: boolean) => Promise<void>\n}\n\n/** Read the run context the agent passes to a tool's execute (undefined outside a run). */\nexport const toolRunContextOf = (options: unknown): ToolRunContext | undefined =>\n (options as { agentRun?: ToolRunContext } | undefined)?.agentRun\n\nconst truncated = (s: string, max: number): string =>\n s.length > max ? `${s.slice(0, max)}… [truncated ${s.length - max} chars]` : s\n\nconst toText = (v: unknown): string => {\n if (typeof v === 'string') return v\n try {\n return JSON.stringify(v) ?? String(v)\n } catch {\n return String(v)\n }\n}\n\ntype ToModelOutput = NonNullable<Tool['toModelOutput']>\n\n/**\n * Cap what the MODEL sees of a tool result at `maxChars` (the raw output still\n * reaches events and the trace). A tool's own `toModelOutput` runs first.\n */\nexport const limitModelOutput = (\n original: Tool['toModelOutput'],\n maxChars: number,\n): ToModelOutput =>\n (async (opts: Parameters<ToModelOutput>[0]) => {\n const base = original\n ? await original(opts)\n : typeof opts.output === 'string'\n ? ({ type: 'text', value: opts.output } as const)\n : ({ type: 'json', value: (opts.output ?? null) as never } as const)\n if (base.type === 'text' || base.type === 'error-text') {\n return { ...base, value: truncated(base.value, maxChars) }\n }\n if (base.type === 'json' || base.type === 'error-json') {\n const text = toText(base.value)\n if (text.length <= maxChars) return base\n return {\n type: base.type === 'json' ? 'text' : 'error-text',\n value: truncated(text, maxChars),\n }\n }\n return base\n }) as ToModelOutput\n\nexport interface WrapToolsOptions {\n approval: ApprovalState\n /** Names that skip the gate and the call budget (built-in meta-tools). */\n builtins: ReadonlySet<string>\n emit: (event: AgentEvent) => void\n step: () => IPlanStep | undefined\n signal?: AbortSignal\n addUsage: (usage: IUsage) => void\n /** Called before each counted call; throw to refuse it. */\n countCall: () => void\n maxToolOutputChars: number\n}\n\n/**\n * Wrap every tool for one run: the consent gate, the tool-call budget, the\n * model-facing output cap, and the run context passed as `options.agentRun`.\n * When the gate allows a call synchronously, `execute` is invoked without an\n * extra await, so a streaming tool keeps returning its iterable.\n */\nexport const wrapToolsForRun = (tools: ToolSet, o: WrapToolsOptions): ToolSet => {\n const out: ToolSet = {}\n const gate = (toolName: string, input: unknown, readOnly: boolean, signal?: AbortSignal) =>\n gateToolCall(\n o.approval,\n { toolName, input, readOnly, step: o.step() },\n {\n requested: (req) =>\n o.emit({\n type: 'tool.approval-requested',\n id: req.id,\n name: req.toolName,\n input: req.input,\n readOnly: req.readOnly,\n step: req.step,\n }),\n resolved: (r) => o.emit({ type: 'tool.approval-resolved', ...r }),\n },\n signal ?? o.signal,\n )\n for (const [name, t] of Object.entries(tools)) {\n const execute = (t as { execute?: (input: unknown, options: unknown) => unknown }).execute\n const builtin = o.builtins.has(name)\n const readOnly = builtin || isReadOnlyTool(t)\n const wrapped: Record<string, unknown> = { ...t }\n if (o.maxToolOutputChars > 0) {\n wrapped.toModelOutput = limitModelOutput(t.toModelOutput, o.maxToolOutputChars)\n }\n if (typeof execute === 'function') {\n wrapped.execute = (input: unknown, options: unknown) => {\n const run = (): unknown => {\n if (!builtin) o.countCall()\n const agentRun: ToolRunContext = {\n emit: o.emit,\n step: o.step(),\n signal: o.signal,\n addUsage: o.addUsage,\n approve: (toolName, toolInput, ro) => gate(toolName, toolInput, ro),\n }\n return execute.call(t, input, { ...(options as object), agentRun })\n }\n if (builtin) return run()\n const permission = decideToolPermission({\n toolName: name,\n readOnly,\n mode: o.approval.mode,\n rules: o.approval.config.rules,\n remembered: o.approval.remembered,\n })\n if (permission === 'allow') return run()\n return gate(\n name,\n input,\n readOnly,\n (options as { abortSignal?: AbortSignal } | undefined)?.abortSignal,\n ).then(run)\n }\n }\n out[name] = wrapped as Tool\n }\n return out\n}\n\n/** Throws ToolBudgetError once `cap` calls were made (cap ≤ 0 = unlimited). */\nexport const createCallCounter = (cap: number | undefined) => {\n let calls = 0\n return {\n count: (): void => {\n if (cap && cap > 0 && calls >= cap) throw new ToolBudgetError(cap)\n calls += 1\n },\n get calls() {\n return calls\n },\n get exhausted() {\n return Boolean(cap && cap > 0 && calls >= cap)\n },\n }\n}\n\ntype JsonSchemaLike = {\n type?: string | string[]\n properties?: Record<string, JsonSchemaLike>\n required?: string[]\n items?: JsonSchemaLike\n enum?: unknown[]\n}\n\nconst typeHint = (s: JsonSchemaLike | undefined, depth: number): string => {\n if (!s) return 'any'\n if (Array.isArray(s.enum) && s.enum.length > 0 && s.enum.length <= 8) {\n return s.enum.map((v) => JSON.stringify(v)).join(' | ')\n }\n const type = Array.isArray(s.type) ? s.type.find((x) => x !== 'null') : s.type\n if (type === 'array') return `${typeHint(s.items, depth)}[]`\n if (type === 'object' || s.properties) {\n if (depth > 1 || !s.properties) return 'object'\n return objectHint(s, depth + 1)\n }\n return type ?? 'any'\n}\n\nconst objectHint = (s: JsonSchemaLike, depth = 0): string => {\n const required = new Set(s.required ?? [])\n const props = Object.entries(s.properties ?? {})\n if (props.length === 0) return '{}'\n return `{ ${props\n .slice(0, 12)\n .map(([k, v]) => `${k}${required.has(k) ? '' : '?'}: ${typeHint(v, depth)}`)\n .join(', ')}${props.length > 12 ? ', …' : ''} }`\n}\n\n/**\n * A short parameter hint (\"{ text: string, x?: number }\") derived from a\n * tool's JSON schema — so tools without a hand-written `promptHint` (every MCP\n * tool) still tell a prompted model what to pass. Undefined when unknown.\n */\nexport const schemaHintOf = async (t: Tool): Promise<string | undefined> => {\n const own = promptHintOf(t)\n if (own) return own\n try {\n const schema = (await asSchema(t.inputSchema as never).jsonSchema) as JsonSchemaLike\n return schema && typeof schema === 'object' ? objectHint(schema) : undefined\n } catch {\n return undefined\n }\n}\n","import {\n generateText,\n stepCountIs,\n streamText,\n type LanguageModel,\n type ModelMessage,\n type StopCondition,\n type SystemModelMessage,\n type ToolSet,\n} from 'ai'\nimport { addUsage, BLOCKER, emptyUsage, type IToolCall, type IUsage } from '../agent/loop-types.js'\nimport { withRollingBreakpoint, type ResolvedCaching } from '../caching.js'\nimport { parseExecutorResponse } from '../parse.js'\nimport type { ProviderOptionsMap, ThinkingLevel } from '../thinking.js'\nimport { dispatch } from '../tools/prompted.js'\nimport {\n createToolResultClearer,\n type ClearedInfo,\n type ToolResultClearing,\n} from './context-editing.js'\nimport { clip, normalizeUsage, promptOf, timeoutSignal } from './util.js'\n\nexport interface ToolLoopCallbacks {\n onTextDelta?: (delta: string) => void\n /** The model's streamed thoughts (native mode, thinking enabled). */\n onReasoningDelta?: (delta: string) => void\n onToolCall?: (name: string, input: unknown) => void\n onToolResult?: (name: string, output: unknown, ok: boolean) => void\n /** Older tool results were replaced with stubs (see `clearToolResults`). */\n onToolResultsCleared?: (info: ClearedInfo) => void\n}\n\nexport interface ToolLoopOptions {\n /** 'native' = SDK function-calling; 'prompted' = parse JSON out of plain text. */\n mode: 'native' | 'prompted'\n system?: string | SystemModelMessage\n prompt?: string\n messages?: ModelMessage[]\n /** In native mode: the callable tools. In prompted mode: used to dispatch salvaged calls. */\n tools: ToolSet\n /**\n * Restrict callable tools to these names (plan-narrowed / search). Native mode\n * passes them to the SDK's `activeTools`; prompted mode bounds `dispatch` to\n * them. A function is re-read before every round, so a tool that activates\n * others (find_tools) takes effect on the next round.\n */\n activeTools?: string[] | (() => string[])\n /**\n * Prompted mode: render catalogue lines for tools that became active during\n * the call, so the model learns their names and parameters.\n */\n describeTools?: (names: string[]) => string\n /** Cap on tool-calling rounds within this call, in both modes (default 4). */\n maxSteps?: number\n /**\n * Checked with the usage of the rounds so far, at every round boundary —\n * return true to stop (e.g. a run-level token budget is spent).\n */\n shouldStop?: (usageSoFar: IUsage) => boolean\n maxOutputTokens?: number\n temperature?: number\n reasoning?: ThinkingLevel\n providerOptions?: ProviderOptionsMap\n abortSignal?: AbortSignal\n timeoutMs?: number\n /**\n * Prompt caching: with it enabled, every round moves a cache breakpoint to\n * the newest message, so the rounds before it are read from the cache.\n */\n caching?: ResolvedCaching\n /** Clear the oldest tool results once the loop's context grows past a threshold. */\n clearToolResults?: ToolResultClearing\n callbacks?: ToolLoopCallbacks\n}\n\nexport interface ToolLoopResult {\n text: string\n toolCalls: IToolCall[]\n usage: IUsage\n /** True when `shouldStop` cut the call short. */\n stoppedByBudget?: boolean\n}\n\n/**\n * Run tool-calling in whichever mode the model needs, returning a normalised\n * result. Native mode streams the SDK's multi-step function-calling; prompted\n * mode salvages `{ reply, actions }` JSON out of plain text, dispatches each\n * action through the tool's own execute, then feeds the TOOL RESULTS back and\n * lets the model continue the same task — up to `maxSteps` rounds in both\n * modes. Both modes call the exact same tool implementations.\n */\nexport const runToolLoop = (\n model: LanguageModel,\n opts: ToolLoopOptions,\n): Promise<ToolLoopResult> =>\n opts.mode === 'prompted' ? runPrompted(model, opts) : runNative(model, opts)\n\nconst activeOf = (opts: ToolLoopOptions): string[] | undefined =>\n typeof opts.activeTools === 'function' ? opts.activeTools() : opts.activeTools\n\nconst callExtras = (opts: ToolLoopOptions) => ({\n ...(opts.system !== undefined ? { instructions: opts.system } : {}),\n maxOutputTokens: opts.maxOutputTokens,\n temperature: opts.temperature,\n ...(opts.reasoning ? { reasoning: opts.reasoning } : {}),\n ...(opts.providerOptions ? { providerOptions: opts.providerOptions as never } : {}),\n})\n\nconst runNative = async (model: LanguageModel, opts: ToolLoopOptions): Promise<ToolLoopResult> => {\n const toolCalls: IToolCall[] = []\n const pending = new Map<string, { name: string; input: unknown }>()\n let stoppedByBudget = false\n\n const stopWhen: StopCondition<ToolSet>[] = [stepCountIs(opts.maxSteps ?? 4)]\n if (opts.shouldStop) {\n const shouldStop = opts.shouldStop\n stopWhen.push(({ steps }) => {\n const used = steps.reduce((u, s) => addUsage(u, normalizeUsage(s.usage)), emptyUsage())\n if (!shouldStop(used)) return false\n stoppedByBudget = true\n return true\n })\n }\n const initialActive = activeOf(opts)\n const dynamic = typeof opts.activeTools === 'function'\n const caching = opts.caching?.enabled ? opts.caching : undefined\n const clear = opts.clearToolResults\n ? createToolResultClearer(opts.clearToolResults, opts.callbacks?.onToolResultsCleared)\n : undefined\n const editMessages = caching || clear\n\n const result = streamText({\n model,\n tools: opts.tools,\n ...(initialActive ? { activeTools: initialActive } : {}),\n // Before every round: re-read the active set so tools activated mid-call\n // (find_tools) become callable; clear stale tool results; move the cache\n // breakpoint to the newest message.\n ...(dynamic || editMessages\n ? {\n prepareStep: ({ messages }: { messages: ModelMessage[] }) => {\n let next = clear ? clear(messages) : messages\n if (caching) next = withRollingBreakpoint(next, caching)\n return {\n ...(dynamic ? { activeTools: activeOf(opts) } : {}),\n ...(editMessages ? { messages: next } : {}),\n }\n },\n }\n : {}),\n stopWhen,\n ...callExtras(opts),\n ...promptOf(opts),\n abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs),\n })\n\n for await (const part of result.fullStream) {\n switch (part.type) {\n case 'text-delta':\n if (part.text) opts.callbacks?.onTextDelta?.(part.text)\n break\n case 'reasoning-delta':\n if (part.text) opts.callbacks?.onReasoningDelta?.(part.text)\n break\n case 'tool-call':\n pending.set(part.toolCallId, { name: part.toolName, input: part.input })\n opts.callbacks?.onToolCall?.(part.toolName, part.input)\n break\n case 'tool-result': {\n const known = pending.get(part.toolCallId)\n toolCalls.push({\n name: part.toolName,\n input: known?.input ?? part.input,\n output: part.output,\n ok: true,\n })\n opts.callbacks?.onToolResult?.(part.toolName, part.output, true)\n pending.delete(part.toolCallId)\n break\n }\n case 'tool-error': {\n const known = pending.get(part.toolCallId)\n toolCalls.push({\n name: part.toolName,\n input: known?.input ?? part.input,\n output: part.error,\n ok: false,\n })\n opts.callbacks?.onToolResult?.(part.toolName, part.error, false)\n pending.delete(part.toolCallId)\n break\n }\n case 'error':\n throw part.error instanceof Error ? part.error : new Error(String(part.error))\n }\n }\n\n const [text, usage] = await Promise.all([result.text, result.usage])\n return { text: text.trim(), toolCalls, usage: normalizeUsage(usage), stoppedByBudget }\n}\n\n/** JSON one-liner for a tool input/output; never throws (circular → String). */\nconst asJson = (value: unknown): string => {\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n}\n\n/** One round's results + the continue-or-finish contract for the next round. */\nconst toolResultsPrompt = (results: IToolCall[], newTools: string): string => {\n const lines = results.map(\n (r) =>\n `- ${r.name} ${clip(asJson(r.input), 160)} → ${r.ok ? 'ok' : 'FAILED'}: ${clip(asJson(r.output), 400)}`,\n )\n return `TOOL RESULTS:\n${lines.join('\\n')}\n${newTools ? `\\nTOOLS NOW AVAILABLE (call them by these exact names):\\n${newTools}\\n` : ''}\nContinue THIS step using the results above. Reply with a single JSON object, nothing else:\n{ \"reply\": string, \"actions\": [ { \"tool\": string, \"args\": object } ] }\n- If the step is now complete: \"actions\": [] and a short outcome in \"reply\".\n- Otherwise emit ONLY the remaining or corrective calls — never repeat a successful call.`\n}\n\nconst runPrompted = async (\n model: LanguageModel,\n opts: ToolLoopOptions,\n): Promise<ToolLoopResult> => {\n // Prompted mode does NOT pass tools to the SDK — the tool catalogue is\n // already rendered into the prompt (see tools/prompted.ts renderCatalog); the\n // model replies with JSON, which we salvage and dispatch ourselves.\n //\n // After a round's actions run, the model is shown their TOOL RESULTS and may\n // continue the same task (react to a read-tool's output, fix a failed call)\n // until it returns no actions, signals [BLOCKER], re-emits a batch it already\n // ran, or `maxSteps` rounds are spent. Without this feedback a prompted model\n // never learns what its calls returned — a read-tool would be write-only. Set\n // maxSteps: 1 for the old single-round behaviour.\n const maxRounds = Math.max(1, opts.maxSteps ?? 4)\n const callable = (): ToolSet => {\n const active = activeOf(opts)\n return active\n ? Object.fromEntries(Object.entries(opts.tools).filter(([name]) => active.includes(name)))\n : opts.tools\n }\n\n // One watchdog for the WHOLE call (as native mode does with its single\n // stream), so a slow local model can't run up to maxRounds × timeoutMs; every\n // round's generation and every dispatch share this one deadline.\n const signal = timeoutSignal(opts.abortSignal, opts.timeoutMs)\n\n // The conversation grows across rounds: the model's own raw reply, then a\n // user message with the results — the standard chat shape every model knows.\n const messages: ModelMessage[] = opts.messages\n ? [...opts.messages]\n : [{ role: 'user', content: opts.prompt ?? '' }]\n const toolCalls: IToolCall[] = []\n // Every batch this loop has dispatched, so an exact repeat is caught even\n // when it isn't consecutive (A→B→A oscillation, not just A→A stutter).\n const seen = new Set<string>()\n let usage = emptyUsage()\n let text = ''\n let stoppedByBudget = false\n\n for (let round = 1; round <= maxRounds; round += 1) {\n if (signal?.aborted) break\n if (opts.shouldStop?.(usage)) {\n stoppedByBudget = true\n break\n }\n const before = new Set(Object.keys(callable()))\n const result = await generateText({\n model,\n ...callExtras(opts),\n messages: opts.caching ? withRollingBreakpoint(messages, opts.caching) : messages,\n abortSignal: signal,\n })\n usage = addUsage(usage, normalizeUsage(result.usage))\n\n const parsed = parseExecutorResponse(result.text)\n // The LAST round's reply wins — an empty final reply is left empty (the\n // executor's summaryOf fills it in) rather than surfacing a stale, often\n // future-tense reply from an earlier round. Never the raw JSON envelope.\n text = parsed.reply\n\n // [BLOCKER] in any round is authoritative: the model says it cannot finish,\n // so preserve that reply (the executor detects the sentinel to drive the\n // replanner) and stop WITHOUT dispatching this round's speculative actions.\n if (parsed.reply.includes(BLOCKER)) break\n if (parsed.actions.length === 0) break\n\n // A batch this loop already ran is a stutter, not progress — re-running it\n // would apply every side effect again.\n const batch = asJson(parsed.actions)\n if (seen.has(batch)) break\n seen.add(batch)\n\n const results: IToolCall[] = []\n for (const action of parsed.actions) {\n if (signal?.aborted) break // stop mid-batch the moment the caller aborts\n opts.callbacks?.onToolCall?.(action.tool, action.args)\n // Re-read per action: an earlier action of this batch may have\n // activated more tools (find_tools).\n const rec = await dispatch(action, callable(), { abortSignal: signal })\n toolCalls.push(rec)\n results.push(rec)\n opts.callbacks?.onToolResult?.(rec.name, rec.output, rec.ok)\n }\n\n if (round === maxRounds || signal?.aborted) break\n const added = Object.keys(callable()).filter((n) => !before.has(n))\n messages.push({ role: 'assistant', content: result.text })\n messages.push({\n role: 'user',\n content: toolResultsPrompt(\n results,\n added.length && opts.describeTools ? opts.describeTools(added) : '',\n ),\n })\n }\n\n // Prompted mode can't stream, so surface the final reply ONCE (not per round)\n // — a consumer accumulating deltas (as native mode's fragments require) would\n // otherwise concatenate every round's full reply.\n if (text) opts.callbacks?.onTextDelta?.(text)\n\n return { text, toolCalls, usage, stoppedByBudget }\n}\n","/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */\nexport interface IPlanStep {\n id: string\n description: string\n expectedOutcome?: string\n /** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */\n suggestedTools?: string[]\n /** Set by the pipeline when suggestedTools were named but all were unknown. */\n requiresTools?: boolean\n}\n\nexport interface IPlan {\n thought: string\n steps: IPlanStep[]\n}\n\nexport interface IUsage {\n inputTokens: number\n outputTokens: number\n totalTokens: number\n /** Output tokens spent thinking (a subset of outputTokens). */\n reasoningTokens?: number\n /** Input tokens served from the provider's prompt cache. */\n cachedInputTokens?: number\n /** Input tokens written to the provider's prompt cache. */\n cacheWriteTokens?: number\n}\n\nexport interface IToolCall {\n name: string\n input: unknown\n output: unknown\n ok: boolean\n}\n\nexport interface IStepResult {\n step: IPlanStep\n summary: string\n toolCalls: IToolCall[]\n /** True when the executor signalled it could not complete the step ([BLOCKER]). */\n blocked: boolean\n}\n\n/**\n * Sentinel the executor emits when it cannot complete a step. Language-agnostic\n * and shared by the tool loop (which must preserve it across prompted rounds)\n * and `splitBlocker` (which strips it and drives the replanner).\n */\nexport const BLOCKER = '[BLOCKER]'\n\nexport const emptyUsage = (): IUsage => ({\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n reasoningTokens: 0,\n cachedInputTokens: 0,\n cacheWriteTokens: 0,\n})\n\nexport const addUsage = (a: IUsage, b: IUsage): IUsage => ({\n inputTokens: a.inputTokens + b.inputTokens,\n outputTokens: a.outputTokens + b.outputTokens,\n totalTokens: a.totalTokens + b.totalTokens,\n reasoningTokens: (a.reasoningTokens ?? 0) + (b.reasoningTokens ?? 0),\n cachedInputTokens: (a.cachedInputTokens ?? 0) + (b.cachedInputTokens ?? 0),\n cacheWriteTokens: (a.cacheWriteTokens ?? 0) + (b.cacheWriteTokens ?? 0),\n})\n","/**\n * Robust parsing of model output. Small in-browser models emit JSON wrapped in\n * prose or code fences, truncate it mid-token when they loop, or drift to plain\n * text. Every parser here is defensive: it salvages what it can and NEVER\n * throws, and it never surfaces raw JSON as user-facing text. This is the\n * backbone of the \"prompted\" tool-mode (see tools/mode.ts).\n */\n\n/** A tool the executor asked to run. */\nexport interface RawAction {\n tool: string\n args: Record<string, unknown>\n}\n\nexport type ReplanDecision = 'continue' | 'revise' | 'finish'\n\n// Reasoning models running locally (Qwen3, DeepSeek-R1 distills) put their\n// chain of thought inline in <think> tags; it is never part of the answer.\nconst stripThinking = (text: string): string =>\n text.replace(/<think>[\\s\\S]*?<\\/think>/gi, '').replace(/^[\\s\\S]*?<\\/think>/i, '')\n\nconst stripFences = (text: string): string =>\n stripThinking(text || '')\n .replace(/```(?:json)?/gi, '')\n .trim()\n\n/** Extracts the first balanced {...} or [...] block, respecting strings. */\nconst extractBalanced = (text: string, open: '{' | '['): string | undefined => {\n const close = open === '{' ? '}' : ']'\n const start = text.indexOf(open)\n if (start < 0) return undefined\n let depth = 0\n let inStr = false\n let esc = false\n for (let i = start; i < text.length; i += 1) {\n const c = text[i]\n if (inStr) {\n if (esc) esc = false\n else if (c === '\\\\') esc = true\n else if (c === '\"') inStr = false\n continue\n }\n if (c === '\"') inStr = true\n else if (c === open) depth += 1\n else if (c === close) {\n depth -= 1\n if (depth === 0) return text.slice(start, i + 1)\n }\n }\n return undefined\n}\n\nconst tryParse = (s: string | undefined): unknown => {\n if (!s) return undefined\n try {\n return JSON.parse(s)\n } catch {\n return undefined\n }\n}\n\n/** True when a string is (or is dominated by) raw JSON — kept out of the UI. */\nexport const looksLikeJson = (s: string): boolean => {\n const t = (s || '').trim()\n return (\n t.startsWith('{') ||\n t.startsWith('[') ||\n /\"(tool|args|plan|reply|actions|decision)\"\\s*:/.test(t)\n )\n}\n\nconst asObject = (text: string): Record<string, unknown> | undefined => {\n const v = tryParse(text) ?? tryParse(extractBalanced(text, '{'))\n return v && typeof v === 'object' && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : undefined\n}\n\n/** Trim, drop empties, de-duplicate (case-insensitive), cap length. */\nexport const normalizeSteps = (arr: unknown, cap = 12): string[] => {\n if (!Array.isArray(arr)) return []\n const seen: Record<string, boolean> = {}\n const out: string[] = []\n for (const s of arr) {\n if (out.length >= cap || typeof s !== 'string') continue\n const step = s.trim()\n const key = step.toLowerCase()\n if (!step || seen[key]) continue\n seen[key] = true\n out.push(step)\n }\n return out\n}\n\n/** Decode a JSON string body (\\\" \\\\n \\\\uXXXX …); falls back to the raw text. */\nconst decodeJsonString = (body: string): string => {\n const v = tryParse(`\"${body}\"`)\n return typeof v === 'string' ? v : body\n}\n\n/**\n * Pull \"...\"-quoted strings out of a (possibly truncated) named array. The scan\n * is bounded to the array itself — from its `[` to the matching `]`, or the end\n * of the text when truncated — so values of LATER fields are never swept in.\n */\nconst salvageStringArray = (text: string, field: string): string[] => {\n const m = new RegExp(`\"${field}\"\\\\s*:\\\\s*\\\\[`).exec(text)\n if (!m) return []\n const out: string[] = []\n let i = m.index + m[0].length\n while (i < text.length && text[i] !== ']') {\n if (text[i] !== '\"') {\n i += 1\n continue\n }\n let j = i + 1\n let esc = false\n while (j < text.length && (esc || text[j] !== '\"')) {\n esc = !esc && text[j] === '\\\\'\n j += 1\n }\n if (j >= text.length) break // truncated mid-string — drop the fragment\n out.push(decodeJsonString(text.slice(i + 1, j)))\n i = j + 1\n }\n return out\n}\n\nconst salvageString = (text: string, field: string): string => {\n const m = text.match(new RegExp(`\"${field}\"\\\\s*:\\\\s*\"((?:[^\"\\\\\\\\]|\\\\\\\\.)*)\"`))\n return m ? decodeJsonString(m[1]).trim() : ''\n}\n\n// --- planner ---------------------------------------------------------------\n\nexport interface PlannerResult {\n reply: string\n plan: string[]\n /** Skill names the planner picked (empty when none / not asked). */\n skills: string[]\n}\n\nexport const parsePlannerResponse = (raw: string): PlannerResult => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj) {\n const reply = typeof obj.reply === 'string' ? obj.reply.trim() : ''\n return { reply, plan: normalizeSteps(obj.plan), skills: normalizeSteps(obj.skills) }\n }\n if (/\"plan\"\\s*:/.test(text)) {\n return {\n reply: salvageString(text, 'reply'),\n plan: normalizeSteps(salvageStringArray(text, 'plan')),\n skills: normalizeSteps(salvageStringArray(text, 'skills')),\n }\n }\n return { reply: looksLikeJson(text) ? '' : text.trim(), plan: [], skills: [] }\n}\n\n// --- executor (tool calls) -------------------------------------------------\n\nexport interface ExecutorResult {\n reply: string\n actions: RawAction[]\n}\n\nconst toActions = (value: unknown): RawAction[] => {\n if (!Array.isArray(value)) return []\n const out: RawAction[] = []\n for (const a of value) {\n if (a && typeof a === 'object' && typeof (a as { tool?: unknown }).tool === 'string') {\n const rec = a as { tool: string; args?: unknown }\n out.push({\n tool: rec.tool,\n args:\n rec.args && typeof rec.args === 'object' && !Array.isArray(rec.args)\n ? (rec.args as Record<string, unknown>)\n : {},\n })\n }\n }\n return out\n}\n\nexport const parseExecutorResponse = (raw: string): ExecutorResult => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj) {\n const reply = typeof obj.reply === 'string' ? obj.reply.trim() : ''\n return { reply, actions: toActions(obj.actions) }\n }\n // Bare actions array.\n const arr = tryParse(extractBalanced(text, '['))\n if (Array.isArray(arr)) {\n const actions = toActions(arr)\n return { reply: '', actions }\n }\n return { reply: looksLikeJson(text) ? '' : text.trim(), actions: [] }\n}\n\n// --- replanner -------------------------------------------------------------\n\nexport interface ReplannerResult {\n decision: ReplanDecision\n reason: string\n plan: string[]\n}\n\nexport const parseReplannerResponse = (raw: string): ReplannerResult => {\n const obj = asObject(stripFences(raw))\n const decision: ReplanDecision =\n obj?.decision === 'revise' || obj?.decision === 'finish' ? obj.decision : 'continue'\n const reason = typeof obj?.reason === 'string' ? obj.reason.trim() : ''\n return { decision, reason, plan: normalizeSteps(obj?.plan) }\n}\n\n// --- plain text (synthesizer / chat answers) -------------------------------\n\n/** Extracts a clean human sentence, never raw JSON. */\nexport const parsePlainText = (raw: string): string => {\n const text = stripFences(raw)\n const obj = asObject(text)\n if (obj && typeof obj.reply === 'string') return obj.reply.trim()\n return looksLikeJson(text) ? '' : text.trim()\n}\n","import type { ModelMessage } from 'ai'\nimport { estimateTokens } from '../memory/compress.js'\n\n/**\n * Context editing inside one tool loop — what Anthropic's\n * `clear_tool_uses` and Claude Code's micro-compaction do: once the loop's\n * conversation grows past `triggerTokens`, the OLDEST tool results are replaced\n * with a one-line stub (the calls themselves stay, so the model knows what it\n * did and can call again), keeping the `keep` most recent results verbatim.\n *\n * Clearing is sticky — a result cleared once stays cleared — so the prefix the\n * provider cached does not flip back and forth between rounds.\n */\nexport interface ToolResultClearing {\n /** Clear once the loop's estimated tokens exceed this. */\n triggerTokens: number\n /** Most recent tool results kept verbatim (default 3). */\n keep?: number\n}\n\nexport interface ClearedInfo {\n cleared: number\n beforeTokens: number\n afterTokens: number\n}\n\nconst STUB = (name: string): string =>\n `[${name} result cleared to save context — call the tool again if you still need it]`\n\nconst estimate = (messages: ModelMessage[]): number => {\n try {\n return estimateTokens(JSON.stringify(messages))\n } catch {\n return 0\n }\n}\n\n// A result's position in the conversation (\"message:part\"). The loop only\n// appends, so positions are stable — unlike tool call ids, which some servers\n// repeat across rounds.\nconst positionsOf = (messages: ModelMessage[]): string[] =>\n messages.flatMap((m, i) =>\n m.role === 'tool' && Array.isArray(m.content)\n ? (m.content as { type: string }[]).flatMap((p, j) =>\n p.type === 'tool-result' ? [`${i}:${j}`] : [],\n )\n : [],\n )\n\n/**\n * A stateful clearer for one loop: call it with each round's messages; it\n * returns the (possibly) edited copy and reports what it newly cleared.\n */\nexport const createToolResultClearer = (\n opts: ToolResultClearing,\n onCleared?: (info: ClearedInfo) => void,\n): ((messages: ModelMessage[]) => ModelMessage[]) => {\n const keep = Math.max(0, opts.keep ?? 3)\n const cleared = new Set<string>()\n\n const apply = (messages: ModelMessage[]): ModelMessage[] =>\n cleared.size === 0\n ? messages\n : messages.map((m, i) =>\n m.role === 'tool' && Array.isArray(m.content)\n ? {\n ...m,\n content: m.content.map((p, j) =>\n p.type === 'tool-result' && cleared.has(`${i}:${j}`)\n ? { ...p, output: { type: 'text' as const, value: STUB(p.toolName) } }\n : p,\n ),\n }\n : m,\n )\n\n return (messages) => {\n let edited = apply(messages)\n const before = estimate(edited)\n if (before <= opts.triggerTokens) return edited\n const positions = positionsOf(messages)\n let added = 0\n for (const pos of positions.slice(0, Math.max(0, positions.length - keep))) {\n if (!cleared.has(pos)) {\n cleared.add(pos)\n added += 1\n }\n }\n if (added === 0) return edited\n edited = apply(messages)\n onCleared?.({ cleared: added, beforeTokens: before, afterTokens: estimate(edited) })\n return edited\n }\n}\n","/**\n * Thinking (a.k.a. reasoning) activation, portable across providers.\n *\n * The AI SDK exposes a top-level `reasoning` level on every call and translates\n * it to each provider's native API (OpenAI reasoning effort, Anthropic adaptive\n * thinking, Gemini thinking level, …). An exact token budget is not portable,\n * so a `budgetTokens` is mapped to the provider-specific options of the two\n * providers that take one (Anthropic, Google); provider options win over the\n * portable level by the SDK's precedence rules.\n *\n * WebLLM ignores the portable level: its thinking models (Qwen3) are switched\n * by `extra_body.enable_thinking`, so every setting carries that too.\n */\n\nexport type ThinkingLevel =\n 'provider-default' | 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'\n\nexport interface ThinkingConfig {\n /** Portable effort level (default 'medium'). */\n level?: ThinkingLevel\n /** Exact thinking budget — mapped to Anthropic `thinking` / Google `thinkingConfig`. */\n budgetTokens?: number\n /** Stream the model's thoughts where the provider can (default true). */\n includeThoughts?: boolean\n}\n\n/**\n * `false`/undefined → leave the provider default alone; `true` → 'medium';\n * a level string → that level; an object → full control.\n */\nexport type ThinkingSetting = boolean | ThinkingLevel | ThinkingConfig\n\nexport type ThinkingStage = 'planner' | 'executor' | 'replanner' | 'synthesizer'\n\n/** Provider-keyed options, the shape of the AI SDK's `providerOptions`. */\nexport type ProviderOptionsMap = Record<string, Record<string, unknown>>\n\nexport interface ResolvedThinking {\n reasoning?: ThinkingLevel\n providerOptions?: ProviderOptionsMap\n}\n\nconst normalize = (setting: ThinkingSetting | undefined): ThinkingConfig | undefined => {\n if (setting === undefined || setting === false) return undefined\n if (setting === true) return { level: 'medium' }\n if (typeof setting === 'string') return { level: setting }\n return setting\n}\n\n/**\n * Turn a thinking setting into call options: the portable `reasoning` level\n * plus the provider-specific extras for an exact budget or streamed thoughts.\n * Pure — unit-tested.\n */\nexport const resolveThinking = (setting: ThinkingSetting | undefined): ResolvedThinking => {\n const cfg = normalize(setting)\n if (!cfg) return {}\n const level = cfg.level ?? 'medium'\n // WebLLM's key: a thinking model (Qwen3) thinks by default, so 'none' is the\n // only way to turn it off; a model without thinking ignores `true`.\n const webllm = (on: boolean) => ({ 'web-llm': { extra_body: { enable_thinking: on } } })\n if (level === 'none') return { reasoning: 'none', providerOptions: webllm(false) }\n const includeThoughts = cfg.includeThoughts !== false\n const budget = cfg.budgetTokens\n if (typeof budget === 'number' && budget > 0) {\n return {\n reasoning: level,\n providerOptions: {\n anthropic: { thinking: { type: 'enabled', budgetTokens: budget } },\n google: { thinkingConfig: { thinkingBudget: budget, includeThoughts } },\n ...webllm(true),\n },\n }\n }\n if (!includeThoughts) return { reasoning: level, providerOptions: webllm(true) }\n return {\n reasoning: level,\n providerOptions: {\n google: { thinkingConfig: { includeThoughts: true } },\n openai: { reasoningSummary: 'auto' },\n ...webllm(true),\n },\n }\n}\n\n/** The setting that applies to one stage: a stage entry wins over the top level. */\nexport const thinkingFor = (\n stage: ThinkingStage,\n top: ThinkingSetting | undefined,\n perStage: Partial<Record<ThinkingStage, ThinkingSetting>> | undefined,\n): ThinkingSetting | undefined => (perStage && stage in perStage ? perStage[stage] : top)\n\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\nconst deepMerge = (a: Record<string, unknown>, b: Record<string, unknown>) => {\n const out: Record<string, unknown> = { ...a }\n for (const [k, v] of Object.entries(b)) {\n out[k] = isPlainObject(out[k]) && isPlainObject(v) ? deepMerge(out[k], v) : v\n }\n return out\n}\n\n/**\n * Deep-merge provider-option maps left to right (later wins). Returns undefined\n * when there is nothing to send, so callers can spread it unconditionally.\n */\nexport const mergeProviderOptions = (\n ...maps: (ProviderOptionsMap | undefined)[]\n): ProviderOptionsMap | undefined => {\n let out: Record<string, unknown> | undefined\n for (const m of maps) {\n if (!m || Object.keys(m).length === 0) continue\n out = out ? deepMerge(out, m) : { ...m }\n }\n return out as ProviderOptionsMap | undefined\n}\n","import type { FilePart } from 'ai'\n\n/**\n * Attachments sent with a run: images, PDFs and other files the provider can\n * read, given as bytes / base64 / a data URL — or as an http(s) URL, which\n * providers that accept links (Gemini, Claude, OpenAI) fetch themselves and the\n * AI SDK downloads for the rest (from the browser: subject to CORS).\n */\nexport interface RunFile {\n /** Base64 (no prefix), a data URL (\"data:image/png;base64,…\"), raw bytes, or an http(s) URL. */\n data: string | Uint8Array | URL\n /** e.g. \"image/png\", \"application/pdf\" — read from a data URL when omitted. */\n mediaType?: string\n /** Shown in the transcript, in memory and in errors. */\n name?: string\n}\n\n/** An image attachment (same shape; kept as its own name for clarity). */\nexport type RunImage = RunFile\n\n/** The kinds of attachment the agent reasons about separately. */\nexport type AttachmentKind = 'image' | 'pdf' | 'file'\n\nconst DATA_URL_RE = /^data:([^;,]+)?;base64,(.*)$/s\nconst HTTP_RE = /^https?:\\/\\//i\n\n/** The media type of an attachment (declared, from a data URL, or from a URL's extension). */\nexport const mediaTypeOf = (f: RunFile): string | undefined => {\n if (f.mediaType) return f.mediaType\n if (typeof f.data === 'string') {\n const m = DATA_URL_RE.exec(f.data)\n if (m?.[1]) return m[1]\n }\n const url = f.data instanceof URL ? f.data.href : typeof f.data === 'string' ? f.data : ''\n if (HTTP_RE.test(url) || f.name) {\n const ext = (f.name ?? new URL(url, 'http://x').pathname).split('.').pop()?.toLowerCase()\n if (ext === 'pdf') return 'application/pdf'\n if (ext && ['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext)) {\n return `image/${ext === 'jpg' ? 'jpeg' : ext}`\n }\n }\n return undefined\n}\n\nexport const attachmentKind = (f: RunFile): AttachmentKind => {\n const mt = mediaTypeOf(f) ?? ''\n if (mt.startsWith('image/')) return 'image'\n if (mt === 'application/pdf') return 'pdf'\n return 'file'\n}\n\nconst KIND_LABEL: Record<AttachmentKind, string> = {\n image: 'images',\n pdf: 'PDF files',\n file: 'file attachments',\n}\n\nconst KIND_HINT: Record<AttachmentKind, string> = {\n image:\n 'Remove the image, or switch to a vision-capable model such as Gemini, Claude or GPT-4o/GPT-5.',\n pdf: 'Convert the PDF to text first (e.g. PDF → Markdown), or switch to a model that reads PDFs such as Gemini, Claude or GPT-4o/GPT-5.',\n file: 'Paste its text instead, or switch to a model that accepts this file type.',\n}\n\n/** Raised when attachments are sent to a model that cannot take them. */\nexport class AttachmentsNotSupportedError extends Error {\n readonly kind: AttachmentKind\n constructor(model: string, kind: AttachmentKind, detail?: string) {\n super(\n `The model \"${model}\" can't take ${KIND_LABEL[kind]}${detail ? ` (${detail})` : ''}. ${KIND_HINT[kind]}`,\n )\n this.name = 'AttachmentsNotSupportedError'\n this.kind = kind\n }\n\n toJSON(): string {\n return this.message\n }\n}\n\n/** The image flavour of {@link AttachmentsNotSupportedError}. */\nexport class ImagesNotSupportedError extends AttachmentsNotSupportedError {\n constructor(model: string, detail?: string) {\n super(model, 'image', detail)\n this.name = 'ImagesNotSupportedError'\n }\n}\n\n/** The error for a kind: images get the dedicated class. */\nexport const unsupportedAttachment = (\n model: string,\n kind: AttachmentKind,\n detail?: string,\n): AttachmentsNotSupportedError =>\n kind === 'image'\n ? new ImagesNotSupportedError(model, detail)\n : new AttachmentsNotSupportedError(model, kind, detail)\n\nconst dataOf = (f: RunFile): string | Uint8Array | URL => {\n if (typeof f.data === 'string') {\n const m = DATA_URL_RE.exec(f.data)\n if (m) return m[2]\n if (HTTP_RE.test(f.data)) return new URL(f.data)\n }\n return f.data\n}\n\n/**\n * An AI SDK file part (images included — the v7 SDK deprecates the separate\n * image part). An http(s) URL is passed as a URL: providers that accept links\n * fetch it themselves, and the SDK downloads it for the rest.\n */\nexport const toFilePart = (f: RunFile): FilePart => {\n const kind = attachmentKind(f)\n const mediaType = mediaTypeOf(f) ?? (kind === 'image' ? 'image' : 'application/octet-stream')\n return {\n type: 'file',\n data: dataOf(f),\n mediaType,\n ...(f.name ? { filename: f.name } : {}),\n }\n}\n\n/** Back-compat name. */\nexport const toImagePart = toFilePart\n\n/** A short, human label of a model for messages. */\nexport const modelLabel = (model: unknown): string => {\n if (typeof model === 'string') return model\n const m = model as { provider?: string; modelId?: string } | undefined\n return m?.modelId ? `${m.modelId}${m.provider ? ` (${m.provider})` : ''}` : 'this model'\n}\n\nconst REFUSAL_RE =\n /image|vision|multimodal|multi-modal|media type|mediatype|pdf|document|unsupported (file|content|part|mime)|does not support (file|content)|invalid content type|image_url|inline_?data|file_?data/i\n\n/** Does a provider error look like a refusal of attachment input? */\nexport const isAttachmentRefusal = (err: unknown): boolean =>\n REFUSAL_RE.test(err instanceof Error ? `${err.name} ${err.message}` : String(err))\n\n/** Back-compat name. */\nexport const isImageRefusal = isAttachmentRefusal\n","import type { LanguageModel, ModelMessage, SystemModelMessage } from 'ai'\nimport { cachedInstructions, cachingProviderOptions, type ResolvedCaching } from '../caching.js'\nimport type { BrowserAgentConfig, ResolvedConfig } from '../config.js'\nimport type { AgentEvent } from '../events.js'\nimport type { StoredMessage } from '../memory/store.js'\nimport type { Prompts, ToolCallMode } from '../prompts.js'\nimport { withSystem } from '../prompts.js'\nimport type { Skill } from '../skills.js'\nimport {\n mergeProviderOptions,\n resolveThinking,\n thinkingFor,\n type ProviderOptionsMap,\n type ThinkingLevel,\n type ThinkingStage,\n} from '../thinking.js'\nimport type { AgentToolSet } from '../tools/types.js'\nimport type { AgentLogger } from '../logger.js'\nimport {\n AttachmentsNotSupportedError,\n attachmentKind,\n isAttachmentRefusal,\n modelLabel,\n toFilePart,\n unsupportedAttachment,\n type RunFile,\n} from '../images.js'\nimport type { IPlanStep, IUsage } from './loop-types.js'\n\n/** The effective tool-selection strategy of a run ('auto' already resolved). */\nexport type EffectiveToolStrategy = 'all' | 'plan-narrowed' | 'search'\n\n/** Everything the phase functions (planner/executor/replanner/synthesizer) share. */\nexport interface AgentContext {\n config: ResolvedConfig\n raw: BrowserAgentConfig\n plannerModel: LanguageModel\n executorModel: LanguageModel\n synthesizerModel: LanguageModel\n /** Tool-mode for the planner/replanner (from the planner model). */\n plannerMode: ToolCallMode\n /** Tool-mode for the executor (from the executor model). */\n executorMode: ToolCallMode\n /** The run's tools (host + MCP + built-ins), already wrapped by the consent gate. */\n tools: AgentToolSet\n /** The catalogue as the planner sees it (condensed in search mode). */\n toolCatalog: string\n prompts: Prompts\n emit: (event: AgentEvent) => void\n /** Leveled logger (config.logLevel over config.logger ?? console). */\n log: AgentLogger\n signal?: AbortSignal\n /** Current world state for grounding, or undefined when no describeState is configured. */\n state: () => Promise<string | undefined>\n /** Session transcript loaded from memory BEFORE this run's goal was appended. */\n history?: StoredMessage[]\n\n /** Effective tool selection for this run. */\n strategy?: EffectiveToolStrategy\n /** Prompt caching, resolved. */\n caching?: ResolvedCaching\n /** All configured skills. */\n skills?: Skill[]\n /** Skills whose instructions are in play for this run. */\n activeSkills?: () => Skill[]\n /** Tools find_tools activated during this run (search mode). */\n discovered?: () => string[]\n /** Built-in tool names (find_tools, skill tools) — always callable. */\n builtinTools?: ReadonlySet<string>\n /** Parameter hint of a tool, for prompted catalogues. */\n toolHint?: (name: string) => string | undefined\n /** Run usage so far (for in-step budget checks). */\n usageSoFar?: () => IUsage\n /** True when the run's limits are reached given extra usage spent inside the current call. */\n overBudget?: (extra: IUsage) => boolean\n /** Tracks the step being executed (tools read it via their run context). */\n setCurrentStep?: (step: IPlanStep | undefined) => void\n /** Images / PDFs / files the user sent with this run's goal. */\n images?: RunFile[]\n}\n\n/**\n * The prompt of a stage call: plain text, or — when the run carries images — a\n * user message with the text and the images, so the model can see them.\n */\nexport const promptFor = (\n ctx: AgentContext,\n prompt: string,\n): { prompt: string } | { messages: ModelMessage[] } =>\n ctx.images?.length\n ? {\n messages: [\n {\n role: 'user',\n content: [{ type: 'text', text: prompt }, ...ctx.images.map(toFilePart)],\n },\n ],\n }\n : { prompt }\n\n/**\n * When a run carries attachments and a model call failed in a way that reads\n * like a refusal of them, the clear error to raise instead (else undefined).\n */\nexport const imageRefusal = (\n ctx: AgentContext,\n err: unknown,\n model: LanguageModel,\n): AttachmentsNotSupportedError | undefined => {\n if (\n !ctx.images?.length ||\n err instanceof AttachmentsNotSupportedError ||\n !isAttachmentRefusal(err)\n ) {\n return undefined\n }\n const kinds = new Set(ctx.images.map(attachmentKind))\n const kind = kinds.size === 1 ? [...kinds][0] : 'file'\n const detail = err instanceof Error ? err.message.slice(0, 160) : undefined\n return unsupportedAttachment(modelLabel(model), kind, detail && `the provider said: ${detail}`)\n}\n\n/** Prepend the host's systemPrompt to a phase system prompt. */\nexport const systemFor = (ctx: AgentContext, base: string): string =>\n withSystem(base, ctx.raw.systemPrompt)\n\nexport const aborted = (ctx: AgentContext): boolean => ctx.signal?.aborted === true\n\nexport interface StageCallOptions {\n system: string | SystemModelMessage\n reasoning?: ThinkingLevel\n providerOptions?: ProviderOptionsMap\n}\n\n/**\n * The per-stage call settings: the host systemPrompt + the phase system prompt\n * (as a cacheable message when prompt caching is on), the stage's thinking\n * level, and the merged provider options (thinking, caching).\n */\nexport const stageCall = (\n ctx: AgentContext,\n stage: ThinkingStage,\n baseSystem: string,\n): StageCallOptions => {\n const system = systemFor(ctx, baseSystem)\n const thinking = resolveThinking(thinkingFor(stage, ctx.raw.thinking, ctx.raw.stageThinking))\n const caching = ctx.caching ?? { enabled: false }\n const providerOptions = mergeProviderOptions(\n cachingProviderOptions(caching, ctx.config.clientName, stage),\n thinking.providerOptions,\n )\n return {\n system: cachedInstructions(system, caching),\n ...(thinking.reasoning ? { reasoning: thinking.reasoning } : {}),\n ...(providerOptions ? { providerOptions } : {}),\n }\n}\n","import type { ReplanTrigger } from '../config.js'\nimport { runToolLoop } from '../llm/tool-loop.js'\nimport { timeoutSignal } from '../llm/util.js'\nimport { renderActiveSkills, renderSkillIndex } from '../skills.js'\nimport { renderCatalog } from '../tools/prompted.js'\nimport { FIND_TOOLS_NAME } from '../tools/search.js'\nimport { BLOCKER, type IPlanStep, type IStepResult, type IUsage } from './loop-types.js'\nimport { imageRefusal, promptFor, stageCall, type AgentContext } from './internal.js'\n\n/**\n * Split the executor's reply into a clean summary and a structural `blocked`\n * flag. The [BLOCKER] sentinel — emitted by the executor when it can't complete\n * a step — is language-agnostic and drives the replanner; we strip every copy\n * so it never leaks into downstream prompts.\n */\nexport const splitBlocker = (raw: string): { summary: string; blocked: boolean } => {\n if (!raw.includes(BLOCKER)) return { summary: raw.trim(), blocked: false }\n return { summary: raw.split(BLOCKER).join('').trim(), blocked: true }\n}\n\n/**\n * The tool names the executor may call in this step, or undefined for \"all\".\n * 'plan-narrowed' → the step's suggestedTools; 'search' → built-ins, the\n * step's suggestedTools and tools discovered earlier in the run (find_tools\n * adds more while the step runs).\n */\nconst activeToolNames = (ctx: AgentContext, step: IPlanStep): string[] | undefined => {\n const strategy = ctx.strategy ?? ctx.config.toolSelectionStrategy\n const builtins = [...(ctx.builtinTools ?? [])].filter((n) => ctx.tools[n])\n const suggested = step.suggestedTools ?? []\n const known = suggested.filter((n) => ctx.tools[n])\n if (strategy === 'search') {\n const discovered = (ctx.discovered?.() ?? []).slice(-16)\n return [...new Set([...builtins, ...known, ...discovered])]\n }\n if (strategy !== 'plan-narrowed') return undefined\n // A step that named tools but all were unknown still wants tools: fall back to\n // the full set rather than stalling with zero.\n if (known.length === 0 && suggested.length > 0) return Object.keys(ctx.tools)\n return [...new Set([...known, ...builtins])]\n}\n\nconst summaryOf = (text: string, toolCallCount: number): string => {\n if (text.length > 0) return text\n return toolCallCount > 0 ? `Executed ${toolCallCount} tool call(s).` : 'Step produced no output.'\n}\n\n/** Catalogue lines (\"- name(hint): description\") for the given tool names. */\nconst catalogFor = (ctx: AgentContext, names: string[]): string =>\n renderCatalog(\n Object.fromEntries(names.filter((n) => ctx.tools[n]).map((n) => [n, ctx.tools[n]])),\n ctx.toolHint,\n )\n\n/** Execute one plan step: run the tool loop (native or prompted) and emit events. */\nexport const executeStep = async (\n ctx: AgentContext,\n goal: string,\n step: IPlanStep,\n index: number,\n total: number,\n done: string[],\n): Promise<{ result: IStepResult; usage: IUsage; stoppedByBudget?: boolean }> => {\n const state = await ctx.state()\n ctx.setCurrentStep?.(step)\n // Under plan-narrowed / search selection the prompted path must also see the\n // narrowed catalogue — the prompt is its only tool surface (native mode gets\n // the SDK's activeTools instead and never renders the catalogue).\n const initial = activeToolNames(ctx, step)\n const searchMode = (ctx.strategy ?? ctx.config.toolSelectionStrategy) === 'search'\n const toolCatalog = catalogFor(ctx, initial ?? Object.keys(ctx.tools))\n const active = ctx.activeSkills?.() ?? []\n const parts = ctx.prompts.executor({\n goal,\n state,\n step: step.description,\n index,\n total,\n toolCatalog,\n done,\n mode: ctx.executorMode,\n skills: ctx.skills?.length ? renderSkillIndex(ctx.skills) : undefined,\n activeSkills: active.length ? renderActiveSkills(active) : undefined,\n searchMode: searchMode && Boolean(ctx.tools[FIND_TOOLS_NAME]),\n })\n\n const loop = await runToolLoop(ctx.executorModel, {\n mode: ctx.executorMode,\n ...stageCall(ctx, 'executor', parts.system),\n ...promptFor(ctx, parts.prompt),\n tools: ctx.tools,\n // In search mode the active set grows while the step runs.\n activeTools: searchMode\n ? () => [...new Set([...(initial ?? []), ...(ctx.discovered?.() ?? [])])]\n : initial,\n describeTools: (names) => catalogFor(ctx, names),\n maxSteps: ctx.config.maxStepsPerTask,\n shouldStop: ctx.overBudget,\n maxOutputTokens: ctx.config.budgets.executor,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n caching: ctx.caching,\n ...(ctx.config.compaction.clearToolResultsAfterTokens > 0\n ? {\n clearToolResults: {\n triggerTokens: ctx.config.compaction.clearToolResultsAfterTokens,\n keep: ctx.config.compaction.keepToolResults,\n },\n }\n : {}),\n callbacks: {\n onToolResultsCleared: (info) => {\n ctx.log.info(`cleared ${info.cleared} stale tool result(s) from the step's context`)\n ctx.emit({\n type: 'context.compacted',\n scope: 'tool-results',\n beforeTokens: info.beforeTokens,\n afterTokens: info.afterTokens,\n })\n },\n onTextDelta: (delta) => ctx.emit({ type: 'step.text-delta', step, delta }),\n onReasoningDelta: (delta) => ctx.emit({ type: 'step.reasoning-delta', step, delta }),\n onToolCall: (name, input) => {\n ctx.log.info(`tool call: ${name}`, input)\n ctx.emit({ type: 'step.tool-call', step, name, input })\n },\n onToolResult: (name, output, ok) => {\n ctx.log.debug(`tool result: ${name} ${ok ? 'ok' : 'FAILED'}`, output)\n ctx.emit({ type: 'step.tool-result', step, name, output, ok })\n },\n },\n }).catch((err: unknown) => {\n throw imageRefusal(ctx, err, ctx.executorModel) ?? err\n })\n ctx.log.debug('executor text:', loop.text)\n\n const { summary, blocked } = splitBlocker(loop.text)\n return {\n result: {\n step,\n summary: summaryOf(summary, loop.toolCalls.length),\n toolCalls: loop.toolCalls,\n blocked,\n },\n usage: loop.usage,\n stoppedByBudget: loop.stoppedByBudget,\n }\n}\n\n/**\n * The replanner runs when a step was blocked or a tool call failed and stayed\n * failed. A failure that a LATER call to the same tool retried successfully is\n * resolved — the prompted feedback loop (and native multi-step) let the model\n * self-correct within the step, so it must not force a replan.\n */\nexport const shouldReplan = (result: IStepResult): boolean => {\n if (result.blocked) return true\n const { toolCalls } = result\n return toolCalls.some(\n (c, i) => !c.ok && !toolCalls.slice(i + 1).some((later) => later.ok && later.name === c.name),\n )\n}\n\n/** Bound a host `replanAfter` predicate by the same watchdog/abort as a model call. */\nexport interface ReplanWantedOptions {\n signal?: AbortSignal\n timeoutMs?: number\n /** Called with whatever a host predicate threw before falling back to 'failure'. */\n onError?: (err: unknown) => void\n}\n\n/**\n * Resolve the configured `replanAfter` trigger for one step result. 'failure'\n * is the classic `shouldReplan`; 'always' consults the replanner after every\n * step; a host predicate decides per result. A predicate that throws, rejects,\n * or outlives the watchdog/abort falls back to 'failure' behaviour so a buggy\n * or hung predicate can never stall the run (its throw is surfaced via onError).\n */\nexport const replanWanted = async (\n trigger: ReplanTrigger,\n result: IStepResult,\n opts: ReplanWantedOptions = {},\n): Promise<boolean> => {\n if (trigger === 'always') return true\n if (typeof trigger !== 'function') return shouldReplan(result)\n\n const fallback = (): boolean => shouldReplan(result)\n // Never rejects: a sync throw or async rejection resolves to the fallback.\n const decided = (async () => {\n try {\n return Boolean(await trigger(result))\n } catch (err) {\n opts.onError?.(err)\n return fallback()\n }\n })()\n\n const guard = timeoutSignal(opts.signal, opts.timeoutMs)\n if (!guard) return decided\n return Promise.race([\n decided,\n new Promise<boolean>((resolve) => {\n if (guard.aborted) resolve(fallback())\n else guard.addEventListener('abort', () => resolve(fallback()), { once: true })\n }),\n ])\n}\n","import { z } from 'zod'\n\n/**\n * Structured-output schemas for the native path (generateObject). Kept free of\n * `.max()`/`.min()` constraints — some providers reject or mis-handle them in\n * JSON-schema mode; we cap/clean in code instead (see parse.ts normalizeSteps).\n */\nexport const PlanStepSchema = z.object({\n description: z.string(),\n expectedOutcome: z.string().optional(),\n suggestedTools: z.array(z.string()).optional(),\n})\n\nexport const PlanSchema = z.object({\n /** One short sentence. For a greeting/small talk, holds the answer and steps is empty. */\n thought: z.string(),\n steps: z.array(PlanStepSchema),\n /** Names of the configured skills that apply to this goal. */\n skills: z.array(z.string()).optional(),\n})\n\nexport const ReplanSchema = z.object({\n decision: z.enum(['continue', 'revise', 'finish']),\n reason: z.string(),\n /** Replacement for the REMAINING steps when decision is 'revise'. */\n plan: z.array(z.string()).optional(),\n})\n\nexport type PlanShape = z.infer<typeof PlanSchema>\nexport type ReplanShape = z.infer<typeof ReplanSchema>\n","import { generate, generateStructured } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { parsePlannerResponse } from '../parse.js'\nimport type { ToolCallMode } from '../prompts.js'\nimport { renderSkillIndex } from '../skills.js'\nimport type { IPlan, IUsage } from './loop-types.js'\nimport { imageRefusal, promptFor, stageCall, type AgentContext } from './internal.js'\nimport { PlanSchema } from './schemas.js'\n\nconst toSteps = (\n raw: { description: string; expectedOutcome?: string; suggestedTools?: string[] }[],\n cap: number,\n): IPlan['steps'] =>\n raw\n .filter((s) => s.description && s.description.trim())\n .slice(0, Math.max(1, cap))\n .map((s, i) => ({\n id: `s${i + 1}`,\n description: s.description.trim(),\n expectedOutcome: s.expectedOutcome,\n suggestedTools: s.suggestedTools,\n }))\n\nexport interface PlanOutcome {\n plan: IPlan\n usage: IUsage\n /** Names of configured skills the planner picked (validated). */\n skills: string[]\n}\n\n/**\n * Build the initial plan. Native mode uses generateObject(PlanSchema); prompted\n * mode salvages `{ reply, plan }` from plain text. Native failures (a weak model\n * that can't satisfy the schema) fall back to the prompted parse rather than\n * throwing, so the run degrades gracefully. An empty `steps` list signals the\n * runner to answer directly (greeting / small talk).\n */\nexport const createPlan = async (\n ctx: AgentContext,\n goal: string,\n /** Extra instruction appended to the goal (used by the empty-plan retry). */\n nudge?: string,\n): Promise<PlanOutcome> => {\n const state = await ctx.state()\n const effectiveGoal = nudge ? `${goal}\\n\\n${nudge}` : goal\n const skillIndex = ctx.skills?.length ? renderSkillIndex(ctx.skills) : undefined\n const cap = ctx.config.maxPlanSteps\n const commonFor = (mode: ToolCallMode) => {\n const parts = ctx.prompts.planner({\n goal: effectiveGoal,\n state,\n toolCatalog: ctx.toolCatalog,\n mode,\n history: ctx.history,\n skills: skillIndex,\n searchMode: ctx.strategy === 'search',\n })\n return {\n ...stageCall(ctx, 'planner', parts.system),\n ...promptFor(ctx, parts.prompt),\n maxOutputTokens: ctx.config.budgets.planner,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n }\n }\n const validSkills = (names: string[] | undefined): string[] => {\n const known = new Set((ctx.skills ?? []).map((s) => s.name))\n const picked = [...new Set(names ?? [])]\n const kept = picked.filter((n) => known.has(n))\n if (kept.length < picked.length) {\n ctx.log.warn(\n 'planner picked unknown skills, dropped:',\n picked.filter((n) => !known.has(n)),\n )\n }\n return kept\n }\n\n if (ctx.plannerMode === 'native') {\n try {\n const result = await generateStructured(ctx.plannerModel, PlanSchema, commonFor('native'))\n ctx.log.debug('planner (native):', result.object)\n return {\n plan: { thought: result.object.thought, steps: toSteps(result.object.steps, cap) },\n usage: normalizeUsage(result.usage),\n skills: validSkills(result.object.skills),\n }\n } catch (err) {\n // An abort is a stop, not a schema failure — don't spend a fallback call.\n if (ctx.signal?.aborted) throw err\n // A refused image is not a schema problem either: say so clearly.\n const refused = imageRefusal(ctx, err, ctx.plannerModel)\n if (refused) throw refused\n // Graceful degradation: fall back to the salvage parser instead of failing.\n ctx.log.warn('planner: native structured output failed, salvaging:', asMessage(err))\n ctx.emit({ type: 'retry', phase: 'plan', attempt: 1, error: asMessage(err) })\n }\n }\n\n // The prompted path — also the fallback after a native failure. Rendered with\n // mode 'prompted' so the model gets explicit JSON-shape instructions even\n // when the schema-constrained call just failed.\n const result = await generate(ctx.plannerModel, commonFor('prompted')).catch((err: unknown) => {\n throw imageRefusal(ctx, err, ctx.plannerModel) ?? err\n })\n const parsed = parsePlannerResponse(result.text)\n ctx.log.debug('planner (prompted) raw:', result.text)\n ctx.log.debug('planner (prompted) parsed:', parsed)\n return {\n plan: {\n thought: parsed.reply,\n steps: toSteps(\n parsed.plan.map((description) => ({ description })),\n cap,\n ),\n },\n usage: normalizeUsage(result.usage),\n skills: validSkills(parsed.skills),\n }\n}\n\nconst asMessage = (err: unknown): string => (err instanceof Error ? err.message : String(err))\n","import { generate, generateStructured } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { parseReplannerResponse, type ReplanDecision } from '../parse.js'\nimport type { ToolCallMode } from '../prompts.js'\nimport { renderActiveSkills } from '../skills.js'\nimport type { IUsage } from './loop-types.js'\nimport { emptyUsage } from './loop-types.js'\nimport { stageCall, type AgentContext } from './internal.js'\nimport { ReplanSchema } from './schemas.js'\n\nexport interface ReplanOutcome {\n decision: ReplanDecision\n reason: string\n /** Replacement remaining steps (descriptions) when decision is 'revise'. */\n plan: string[]\n usage: IUsage\n}\n\n/**\n * Decide whether to continue, revise the remaining plan, or finish, after a\n * blocked/failed step. Native mode uses generateObject(ReplanSchema); prompted\n * mode salvages the decision from text. Any failure degrades to 'continue' so a\n * flaky replanner never aborts the run.\n */\nexport const decideReplan = async (\n ctx: AgentContext,\n goal: string,\n done: string[],\n remaining: string[],\n): Promise<ReplanOutcome> => {\n const state = await ctx.state()\n const active = ctx.activeSkills?.() ?? []\n const commonFor = (mode: ToolCallMode) => {\n const parts = ctx.prompts.replanner({\n goal,\n state,\n done,\n remaining,\n mode,\n activeSkills: active.length ? renderActiveSkills(active) : undefined,\n })\n return {\n ...stageCall(ctx, 'replanner', parts.system),\n prompt: parts.prompt,\n maxOutputTokens: ctx.config.budgets.replanner,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n }\n }\n\n if (ctx.plannerMode === 'native') {\n try {\n const result = await generateStructured(ctx.plannerModel, ReplanSchema, commonFor('native'))\n return {\n decision: result.object.decision,\n reason: result.object.reason,\n plan: result.object.plan ?? [],\n usage: normalizeUsage(result.usage),\n }\n } catch {\n /* fall through to the prompted salvage below */\n }\n }\n\n try {\n // The prompted path — also the fallback after a native failure, re-rendered\n // with explicit JSON-shape instructions.\n const result = await generate(ctx.plannerModel, commonFor('prompted'))\n const parsed = parseReplannerResponse(result.text)\n return {\n decision: parsed.decision,\n reason: parsed.reason,\n plan: parsed.plan,\n usage: normalizeUsage(result.usage),\n }\n } catch {\n return { decision: 'continue', reason: 'replanner unavailable', plan: [], usage: emptyUsage() }\n }\n}\n","import { stream } from '../llm/generate.js'\nimport { normalizeUsage } from '../llm/util.js'\nimport { looksLikeJson, parsePlainText } from '../parse.js'\nimport { renderActiveSkills } from '../skills.js'\nimport type { IUsage } from './loop-types.js'\nimport { imageRefusal, promptFor, stageCall, type AgentContext } from './internal.js'\n\n/**\n * Write the final natural-language answer of the run, streaming it as\n * `final.text-delta` events (and thoughts as `final.reasoning-delta`). Plain\n * text only (parsePlainText strips any stray JSON; deltas are suppressed\n * entirely when the model drifts into JSON, so raw structure never reaches a\n * UI). Falls back to a default sentence if the model returns nothing usable.\n */\nexport const synthesizeAnswer = async (\n ctx: AgentContext,\n goal: string,\n done: string[],\n /** Excerpts of what the tools returned — the data the answer is made of. */\n findings: string[] = [],\n): Promise<{ text: string; usage: IUsage }> => {\n const state = await ctx.state()\n const active = ctx.activeSkills?.() ?? []\n const parts = ctx.prompts.synthesizer({\n goal,\n state,\n done,\n findings,\n activeSkills: active.length ? renderActiveSkills(active) : undefined,\n })\n const result = stream(ctx.synthesizerModel, {\n ...stageCall(ctx, 'synthesizer', parts.system),\n ...promptFor(ctx, parts.prompt),\n maxOutputTokens: ctx.config.budgets.synthesizer,\n temperature: ctx.config.temperature,\n abortSignal: ctx.signal,\n timeoutMs: ctx.config.chatTimeoutMs,\n })\n\n let text = ''\n let verdict: 'unknown' | 'emit' | 'suppress' = 'unknown'\n for await (const part of result.fullStream) {\n if (part.type === 'reasoning-delta') {\n if (part.text) ctx.emit({ type: 'final.reasoning-delta', delta: part.text })\n continue\n }\n if (part.type === 'error') {\n const err = part.error instanceof Error ? part.error : new Error(String(part.error))\n throw imageRefusal(ctx, err, ctx.synthesizerModel) ?? err\n }\n if (part.type !== 'text-delta') continue\n const delta = part.text\n text += delta\n if (verdict === 'unknown') {\n const lead = text.trimStart()\n if (!lead) continue\n // Inline <think> blocks (local reasoning models) are not part of the answer.\n if (lead.startsWith('<think>') && !text.includes('</think>')) continue\n verdict = looksLikeJson(lead) ? 'suppress' : 'emit'\n if (verdict === 'emit') {\n const visible = text.includes('</think>')\n ? text.slice(text.lastIndexOf('</think>') + '</think>'.length).trimStart()\n : text\n if (visible) ctx.emit({ type: 'final.text-delta', delta: visible })\n }\n } else if (verdict === 'emit') {\n ctx.emit({ type: 'final.text-delta', delta })\n }\n }\n\n const clean = parsePlainText(text)\n return {\n text: clean || 'Done — the changes have been applied.',\n usage: normalizeUsage(await result.usage),\n }\n}\n","/**\n * Leveled logging for the agent. The host passes a console-like sink and a\n * level; everything below the level is a no-op. Default: 'warn' onto the\n * global console — silent in normal operation, but salvage fallbacks, empty\n * plans, degraded tool modes and failed tool calls stay visible.\n *\n * Set `logLevel: 'debug'` to see every phase's raw model output, parsed\n * results and tool dispatches — the first thing to reach for when the agent\n * \"says it did something but nothing happened\".\n */\n\nexport type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug'\n\n/** Console-compatible sink (pass `console`, or your own collector). */\nexport interface AgentLoggerSink {\n error(...args: unknown[]): void\n warn(...args: unknown[]): void\n info(...args: unknown[]): void\n debug(...args: unknown[]): void\n}\n\nexport interface AgentLogger extends AgentLoggerSink {\n readonly level: LogLevel\n}\n\nconst WEIGHT: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n}\n\nconst PREFIX = '[agent-web]'\n\nconst noop = (): void => undefined\n\nexport const createLogger = (\n level: LogLevel = 'warn',\n sink: AgentLoggerSink = console,\n): AgentLogger => {\n const at = (min: LogLevel, fn: (...args: unknown[]) => void) =>\n WEIGHT[level] >= WEIGHT[min] ? (...args: unknown[]) => fn.call(sink, PREFIX, ...args) : noop\n return {\n level,\n error: at('error', sink.error),\n warn: at('warn', sink.warn),\n info: at('info', sink.info),\n debug: at('debug', sink.debug),\n }\n}\n","import type { ProviderType } from './types.js'\n\n// Cloud providers are reliable at native function-calling and JSON-schema\n// structured output. Local WebGPU models (web-llm) technically support both,\n// but tiny (1–3B) models are unreliable at them, so we default local models to\n// the prompted/salvage path (overridable via config.toolMode).\nconst CLOUD: ReadonlySet<ProviderType> = new Set<ProviderType>([\n 'openai',\n 'anthropic',\n 'google',\n 'openai-compatible',\n 'xai',\n 'deepseek',\n 'gateway',\n])\n\n/** Whether native tool-calling is reliable enough to be the default for a provider. */\nexport const supportsNativeTools = (p: ProviderType): boolean => CLOUD.has(p)\n\n/** Whether native structured output (generateObject) is the default for a provider. */\nexport const supportsStructuredOutput = (p: ProviderType): boolean => CLOUD.has(p)\n\n/**\n * Whether calling this provider straight from a browser origin with a BYOK key\n * is expected to work (CORS + browser-access policy). Hosts can use this to\n * warn users before a direct call fails.\n *\n * - `google`: Gemini's endpoint is CORS-enabled — the most reliable direct BYOK path.\n * - `gateway` / `openai-compatible`: the host controls the endpoint / CORS.\n * - `anthropic`: works, but only with the direct-browser-access header, which\n * the registry injects automatically.\n * - `openai`: api.openai.com does NOT reliably send CORS for browser calls —\n * route through a proxy `baseURL` or the gateway.\n * - `xai` / `deepseek`: unreliable from the browser; prefer a proxy.\n */\nexport const directBrowserOk = (p: ProviderType): boolean =>\n p === 'google' || p === 'gateway' || p === 'openai-compatible' || p === 'anthropic'\n\n// Local / on-device runtimes: the prompted path is text-only.\nconst LOCAL_RE = /web-?llm|mlc|browser-ai|transformers|built-?in/i\n// Text-only model families under otherwise vision-capable providers.\nconst TEXT_ONLY_MODEL_RE =\n /gpt-3\\.5|o1-mini|o3-mini|deepseek|text-(davinci|embedding)|embedding|babbage|davinci|codestral/i\nconst VISION_PROVIDER_RE = /^(google|anthropic|openai|azure|xai|vertex|bedrock|gemini)/i\n// Providers that read PDFs natively (as file parts).\nconst PDF_PROVIDER_RE = /^(google|anthropic|openai|azure|vertex|bedrock|gemini)/i\n\n/**\n * Whether a model accepts image input: `true` (expected to), `false` (known\n * not to — local runtimes, DeepSeek, text-only families), or `undefined`\n * (unknown, e.g. an OpenAI-compatible server — the agent tries and turns a\n * provider refusal into a clear error). Override per agent with `vision`.\n */\nexport const supportsImages = (model: unknown): boolean | undefined => {\n if (typeof model === 'string') {\n // A gateway model id: \"provider/model\".\n const [provider = '', id = model] = model.includes('/') ? model.split('/', 2) : ['', model]\n if (TEXT_ONLY_MODEL_RE.test(id) || /deepseek/i.test(provider)) return false\n return VISION_PROVIDER_RE.test(provider) ? true : undefined\n }\n if (!model || typeof model !== 'object') return undefined\n const provider = String((model as { provider?: unknown }).provider ?? '')\n const id = String((model as { modelId?: unknown }).modelId ?? '')\n if (LOCAL_RE.test(provider)) return false\n if (/deepseek/i.test(provider) || TEXT_ONLY_MODEL_RE.test(id)) return false\n return VISION_PROVIDER_RE.test(provider) ? true : undefined\n}\n\n/**\n * Whether a model reads PDF files natively: `false` for local runtimes and\n * text-only families, `true` for Gemini, Claude and OpenAI's vision models,\n * `undefined` when unknown (tried; a refusal becomes a clear error).\n */\nexport const supportsPdf = (model: unknown): boolean | undefined => {\n const vision = supportsImages(model)\n if (vision === false) return false\n const provider =\n typeof model === 'string'\n ? (model.split('/')[0] ?? '')\n : String((model as { provider?: unknown } | undefined)?.provider ?? '')\n return PDF_PROVIDER_RE.test(provider) ? true : undefined\n}\n","import type { LanguageModel, ToolSet } from 'ai'\nimport { resolveCaching } from '../caching.js'\nimport type { BrowserAgentConfig } from '../config.js'\nimport { resolveConfig } from '../config.js'\nimport type { AgentEvent, AgentEventHandler, UsagePhase } from '../events.js'\nimport { checkLimits, type LimitBreach } from '../limits.js'\nimport { clip } from '../llm/util.js'\nimport {\n compactSteps,\n compressHistory,\n estimateMessagesTokens,\n estimateTokens,\n} from '../memory/compress.js'\nimport type { StoredMessage } from '../memory/store.js'\nimport { buildModelFromStage, resolveStage } from '../providers/registry.js'\nimport { defaultPrompts, type Prompts } from '../prompts.js'\nimport { createSkillTools, defineSkill, SKILL_TOOL_NAMES, type Skill } from '../skills.js'\nimport {\n createApprovalState,\n type ToolApprovalMode,\n TOOL_APPROVAL_MODES,\n} from '../tools/approval.js'\nimport { selectToolMode } from '../tools/mode.js'\nimport { renderCatalog } from '../tools/prompted.js'\nimport {\n createFindToolsTool,\n FIND_TOOLS_NAME,\n renderSearchCatalog,\n toolCatalogOf,\n type ToolCatalogEntry,\n} from '../tools/search.js'\nimport type { AgentToolSet } from '../tools/types.js'\nimport { createCallCounter, schemaHintOf, wrapToolsForRun } from '../tools/wrap.js'\nimport { executeStep, replanWanted } from './executor.js'\nimport type { AgentContext, EffectiveToolStrategy } from './internal.js'\nimport {\n addUsage,\n emptyUsage,\n type IPlan,\n type IPlanStep,\n type IStepResult,\n type IUsage,\n} from './loop-types.js'\nimport { createPlan } from './planner.js'\nimport { decideReplan } from './replanner.js'\nimport { synthesizeAnswer } from './synthesizer.js'\nimport { createLogger } from '../logger.js'\nimport {\n AttachmentsNotSupportedError,\n attachmentKind,\n modelLabel,\n unsupportedAttachment,\n type AttachmentKind,\n type RunFile,\n type RunImage,\n} from '../images.js'\nimport { supportsImages, supportsPdf } from '../providers/capabilities.js'\n\nexport interface RunOptions {\n onEvent?: AgentEventHandler\n signal?: AbortSignal\n /** Override the config's sessionId for this run. */\n sessionId?: string\n /**\n * Images sent with the goal (pasted screenshots, photos). They reach the\n * planner, the executor and the synthesizer of a vision-capable model; a\n * model known not to take images ends the run at once with\n * ImagesNotSupportedError's message (see `capabilities.images`).\n */\n images?: RunImage[]\n /**\n * Other attachments: PDFs and files the provider reads natively, as data or\n * as an http(s) URL. Same rules as `images`, per kind (`capabilities.pdf`,\n * `capabilities.files`).\n */\n files?: RunFile[]\n}\n\nexport interface RunResult {\n goal: string\n final: string\n plan: IPlan\n trace: IStepResult[]\n steps: number\n /** Total successful tool calls across the run. */\n applied: number\n stopped: boolean\n usage: IUsage\n /** Skills whose instructions were active in this run. */\n skills: string[]\n /** The limit that stopped the run early, if any. */\n budgetExceeded?: LimitBreach\n}\n\nexport interface CompactOptions {\n /** Session to compact (default: the config's sessionId). */\n sessionId?: string\n signal?: AbortSignal\n /** Compact even when below the threshold (default true for a manual call). */\n force?: boolean\n}\n\nexport interface CompactResult {\n compacted: boolean\n beforeTokens: number\n afterTokens: number\n usage: IUsage\n}\n\nexport interface Agent {\n run(goal: string, opts?: RunOptions): Promise<RunResult>\n /** Summarise the stored transcript (needs `memory`); returns the before/after size. */\n compact(opts?: CompactOptions): Promise<CompactResult>\n /** Switch the consent policy — e.g. the \"autopilot\" toggle. Applies to the next tool call. */\n setToolApprovalMode(mode: ToolApprovalMode): void\n readonly toolApprovalMode: ToolApprovalMode\n /** The tool catalogue (host + MCP tools after filtering). */\n listTools(): ToolCatalogEntry[]\n /** The effective tool selection ('auto' resolved by catalogue size). */\n readonly toolStrategy: EffectiveToolStrategy\n /** Configured skills (name + description). */\n readonly skills: { name: string; description: string }[]\n /**\n * What the executor model can take, per attachment kind: true / false, or\n * undefined when unknown (the run tries, and a provider refusal becomes a\n * clear error).\n */\n readonly capabilities: {\n images: boolean | undefined\n pdf: boolean | undefined\n files: boolean | undefined\n }\n /** The resolved models, for hosts that want to reuse them (e.g. warm-up). */\n readonly models: {\n planner: LanguageModel\n executor: LanguageModel\n synthesizer: LanguageModel\n }\n}\n\nconst errMessage = (err: unknown): string => (err instanceof Error ? err.message : String(err))\n\n/** Apply the config's availableTools whitelist and excludedTools blacklist. */\nconst filterTools = (\n all: AgentToolSet,\n available?: string[],\n excluded?: string[],\n): AgentToolSet => {\n let entries = Object.entries(all)\n if (available && available.length > 0) entries = entries.filter(([n]) => available.includes(n))\n if (excluded && excluded.length > 0) entries = entries.filter(([n]) => !excluded.includes(n))\n return Object.fromEntries(entries)\n}\n\nconst asJson = (v: unknown): string => {\n if (typeof v === 'string') return v\n try {\n return JSON.stringify(v) ?? String(v)\n } catch {\n return String(v)\n }\n}\n\n// Budget of the tool-result excerpts the synthesizer answers from.\nconst FINDING_CHARS = 600\nconst FINDINGS_BUDGET = 6_000\n\n/**\n * Create a headless plan → execute → replan → synthesize agent. Models are\n * resolved eagerly (dynamic provider imports + vault key fetch), so this is\n * async. Each `run` streams typed AgentEvents for any UI to render.\n */\nexport const createAgent = async (config: BrowserAgentConfig): Promise<Agent> => {\n const cfg = resolveConfig(config)\n // Build the executor once; a stage without an override reuses it instead of\n // constructing a second identical model (for web-llm that would mean loading\n // the same weights into the GPU again).\n const buildStage = (override: BrowserAgentConfig['planner'], stageName: string) =>\n buildModelFromStage(\n resolveStage(config.model, override, stageName),\n config.credentials,\n cfg.clientName,\n )\n const executorP = buildStage(undefined, 'executor')\n const [executorModel, plannerModel, synthesizerModel] = await Promise.all([\n executorP,\n config.planner === undefined ? executorP : buildStage(config.planner, 'planner'),\n config.synthesizer === undefined ? executorP : buildStage(config.synthesizer, 'synthesizer'),\n ])\n\n const plannerMode = selectToolMode(plannerModel, cfg.toolMode)\n const executorMode = selectToolMode(executorModel, cfg.toolMode)\n // Declaration order, never re-sorted: the host merges its tool sets in a\n // fixed order (so the cached prefix is stable), and a server's own order is\n // what small models were measured against (see the Node sibling's live gate).\n const baseTools: AgentToolSet = filterTools(\n config.tools ?? {},\n config.availableTools,\n config.excludedTools,\n )\n\n const skills: Skill[] = (config.skills ?? []).map(defineSkill)\n const skillNames = new Set<string>()\n for (const s of skills) {\n if (skillNames.has(s.name)) throw new Error(`duplicate skill name \"${s.name}\"`)\n skillNames.add(s.name)\n }\n\n const catalog = toolCatalogOf(baseTools)\n const strategy: EffectiveToolStrategy =\n cfg.toolSelectionStrategy === 'auto'\n ? catalog.length > cfg.toolSearchThreshold\n ? 'search'\n : 'all'\n : cfg.toolSelectionStrategy\n\n const reserved = [\n ...(skills.length ? SKILL_TOOL_NAMES : []),\n ...(strategy === 'search' ? [FIND_TOOLS_NAME] : []),\n ]\n for (const name of reserved) {\n if (Object.hasOwn(baseTools, name)) {\n throw new Error(\n `tool name \"${name}\" is reserved by the agent's built-in tools; rename your tool`,\n )\n }\n }\n const builtinTools = new Set<string>(reserved)\n\n // Parameter hints for prompted catalogues, derived once from the schemas.\n const hints = new Map<string, string>()\n await Promise.all(\n Object.entries(baseTools).map(async ([name, t]) => {\n const hint = await schemaHintOf(t)\n if (hint) hints.set(name, hint)\n }),\n )\n const toolHint = (name: string): string | undefined => hints.get(name)\n\n const plannerCatalog =\n strategy === 'search' ? renderSearchCatalog(catalog) : renderCatalog(baseTools, toolHint)\n const prompts: Prompts = { ...defaultPrompts, ...config.prompts }\n const caching = resolveCaching(config.promptCaching)\n // The prompted path is text-only; otherwise trust the host's `vision`, then\n // what is known about the model.\n const textOnly = executorMode === 'prompted'\n const accepts: Record<AttachmentKind, boolean | undefined> = {\n image:\n config.inputs?.images ?? config.vision ?? (textOnly ? false : supportsImages(executorModel)),\n pdf: config.inputs?.pdf ?? (textOnly ? false : supportsPdf(executorModel)),\n file: config.inputs?.files ?? (textOnly ? false : undefined),\n }\n const approval = createApprovalState(config.toolApproval)\n const log = createLogger(cfg.logLevel, config.logger)\n log.info(\n `agent ready — ${catalog.length} tool(s) (${strategy}), skills: [${[...skillNames].join(', ') || 'none'}], planner mode: ${plannerMode}, executor mode: ${executorMode}, approval: ${approval.mode}`,\n )\n\n const run = async (goal: string, opts: RunOptions = {}): Promise<RunResult> => {\n const emit = (event: AgentEvent): void => {\n try {\n opts.onEvent?.(event)\n } catch {\n /* a bad handler must not break the run */\n }\n }\n const text = goal.trim()\n const sessionId = opts.sessionId ?? cfg.sessionId\n let usage = emptyUsage()\n const result: RunResult = {\n goal: text,\n final: '',\n plan: { thought: '', steps: [] },\n trace: [],\n steps: 0,\n applied: 0,\n stopped: false,\n usage,\n skills: [],\n }\n if (!text) return result\n\n const state = async (): Promise<string | undefined> =>\n config.describeState ? config.describeState() : undefined\n const isAborted = (): boolean => opts.signal?.aborted === true\n const bumpUsage = (u: IUsage, phase: UsagePhase): void => {\n usage = addUsage(usage, u)\n result.usage = usage\n emit({ type: 'usage', phase, usage: u })\n }\n const remember = async (msg: StoredMessage): Promise<void> => {\n if (!config.memory) return\n try {\n await config.memory.append(sessionId, msg)\n } catch {\n /* persistence is best-effort */\n }\n }\n\n // ── per-run tool state: skills, discovered tools, call budget, current step\n const activeSkillNames = new Set<string>()\n const activateSkill = (name: string, by: 'plan' | 'tool'): void => {\n if (activeSkillNames.has(name) || !skillNames.has(name)) return\n activeSkillNames.add(name)\n result.skills = [...activeSkillNames]\n emit({ type: 'skill.activated', name, by })\n }\n const discovered: string[] = []\n let currentStep: IPlanStep | undefined\n const counter = createCallCounter(cfg.maxToolCalls)\n const builtins: ToolSet = {}\n if (skills.length) {\n Object.assign(\n builtins,\n createSkillTools(skills, (s) => activateSkill(s.name, 'tool')),\n )\n }\n if (strategy === 'search') {\n builtins[FIND_TOOLS_NAME] = createFindToolsTool(\n () => catalog,\n (query, names) => {\n for (const n of names) {\n const i = discovered.indexOf(n)\n if (i >= 0) discovered.splice(i, 1)\n discovered.push(n)\n }\n emit({ type: 'tools.discovered', step: currentStep, query, names })\n },\n toolHint,\n )\n }\n const tools = wrapToolsForRun(\n { ...baseTools, ...builtins },\n {\n approval,\n builtins: builtinTools,\n emit,\n step: () => currentStep,\n signal: opts.signal,\n addUsage: (u) => bumpUsage(u, 'subagent'),\n countCall: counter.count,\n maxToolOutputChars: cfg.compaction.maxToolOutputChars,\n },\n )\n\n let budgetExceeded: LimitBreach | undefined\n const breach = (extra?: IUsage): LimitBreach | undefined => {\n const b = checkLimits(extra ? addUsage(usage, extra) : usage, cfg.limits)\n if (b) return b\n if (counter.exhausted)\n return { kind: 'tool-calls', tokens: counter.calls, cap: cfg.maxToolCalls }\n return undefined\n }\n\n emit({ type: 'run.start', goal: text })\n const images = [...(opts.images ?? []), ...(opts.files ?? [])]\n const refused = images.map(attachmentKind).find((kind) => accepts[kind] === false)\n if (refused) {\n // Fail before spending a single token, with a message a user can act on.\n const err = unsupportedAttachment(\n modelLabel(executorModel),\n refused,\n textOnly ? 'it runs in the text-only prompted tool mode' : undefined,\n )\n log.warn(err.message)\n emit({ type: 'error', phase: 'run', error: err.message })\n result.final = err.message\n return result\n }\n // Read back the session transcript BEFORE appending the current goal, so\n // the planner can resolve references to earlier turns (\"make it bigger\").\n let history: StoredMessage[] = []\n if (config.memory) {\n try {\n history = await config.memory.load(sessionId)\n } catch {\n /* persistence is best-effort */\n }\n }\n // Auto-compaction of a long transcript BEFORE planning, so the run starts\n // within the window (configured `compaction` only; the legacy\n // compressAfterChars path compacts after the run, as it always did).\n if (config.memory && config.compaction && cfg.compaction.auto && history.length > 0) {\n const before = estimateMessagesTokens(history)\n if (before > cfg.compaction.thresholdTokens) {\n const compacted = await compressHistory(history, synthesizerModel, {\n thresholdTokens: cfg.compaction.thresholdTokens,\n keepRecent: cfg.compaction.keepRecentTurns,\n summaryMaxTokens: cfg.budgets.compaction,\n timeoutMs: cfg.chatTimeoutMs,\n abortSignal: opts.signal,\n onUsage: (u) => bumpUsage(u, 'compact'),\n })\n if (compacted !== history) {\n history = compacted\n await config.memory.replace(sessionId, compacted).catch(() => {})\n emit({\n type: 'context.compacted',\n scope: 'history',\n beforeTokens: before,\n afterTokens: estimateMessagesTokens(compacted),\n })\n }\n }\n }\n\n const ctx: AgentContext = {\n config: cfg,\n raw: config,\n plannerModel,\n executorModel,\n synthesizerModel,\n plannerMode,\n executorMode,\n tools,\n toolCatalog: plannerCatalog,\n prompts,\n emit,\n log,\n signal: opts.signal,\n state,\n history,\n strategy,\n caching,\n skills,\n activeSkills: () => skills.filter((s) => activeSkillNames.has(s.name)),\n discovered: () => discovered,\n builtinTools,\n toolHint,\n usageSoFar: () => usage,\n overBudget: (extra) => breach(extra) !== undefined,\n setCurrentStep: (step) => {\n currentStep = step\n },\n images: images.length ? images : undefined,\n }\n // Memory is text: an image is remembered by its name, not its pixels.\n await remember({\n role: 'user',\n content: images.length\n ? `${text}\\n[attached: ${images.map((f, i) => f.name ?? `${attachmentKind(f)} ${i + 1}`).join(', ')}]`\n : text,\n })\n log.info('run:', text, images.length ? `(+${images.length} image(s))` : '')\n\n const stop = (): RunResult => {\n emit({ type: 'stopped' })\n result.stopped = true\n return result\n }\n\n try {\n // 1) PLAN\n let planned = await createPlan(ctx, text)\n bumpUsage(planned.usage, 'plan')\n if (isAborted()) return stop()\n\n // Small models sometimes return an empty plan for a clearly actionable\n // goal — and put a hallucinated \"done!\" into the thought, so the run\n // would claim success while never touching a tool. Give the planner one\n // nudged retry before treating the turn as conversational.\n if (planned.plan.steps.length === 0 && text.split(/\\s+/).length > 2) {\n log.warn(\n 'planner returned no steps for a multi-word goal — retrying with a nudge. thought:',\n planned.plan.thought,\n )\n const retried = await createPlan(\n ctx,\n text,\n 'NOTE: If the message above asks to build, add, change, clear, delete, find, check or look up ANYTHING the tools can do, you MUST output 1-6 concrete steps. Output an empty plan ONLY for a pure greeting or small talk.',\n )\n bumpUsage(retried.usage, 'plan')\n if (retried.plan.steps.length > 0) planned = retried\n }\n result.plan = planned.plan\n if (isAborted()) return stop()\n\n // Greeting / small talk → answer directly, run no tools.\n if (planned.plan.steps.length === 0) {\n log.info('no plan — answering directly (no tools will run)')\n const answer = planned.plan.thought.trim() || \"Tell me what you'd like to do.\"\n emit({ type: 'final', text: answer })\n await remember({ role: 'assistant', content: answer })\n result.final = answer\n return result\n }\n log.info(\n `plan (${planned.plan.steps.length} steps):`,\n planned.plan.steps.map((s) => s.description),\n )\n emit({ type: 'plan.created', plan: planned.plan })\n planned.plan.steps.forEach((step, index) => emit({ type: 'plan.step-added', step, index }))\n for (const name of planned.skills) activateSkill(name, 'plan')\n\n // 2) EXECUTE → REPLAN\n let done: string[] = []\n const findings: string[] = []\n let remaining: IPlanStep[] = [...planned.plan.steps]\n let iter = 0\n let revisions = 0\n while (remaining.length > 0 && iter < cfg.maxIterations) {\n if (isAborted()) return stop()\n const hit = breach()\n if (hit) {\n budgetExceeded = hit\n result.budgetExceeded = hit\n log.warn(`${hit.kind} limit reached (${hit.tokens}/${hit.cap}) — writing the answer now`)\n emit({ type: 'budget.exceeded', ...hit })\n break\n }\n iter += 1\n const step = remaining.shift() as IPlanStep\n const stepNo = result.trace.length + 1\n const total = stepNo + remaining.length\n emit({ type: 'step.start', step, index: stepNo, total })\n\n let stepResult: IStepResult\n try {\n const out = await executeStep(ctx, text, step, stepNo, total, done)\n bumpUsage(out.usage, 'execute')\n stepResult = out.result\n } catch (err) {\n // A user abort surfaces as a thrown AbortError — that is a stop, not\n // a step failure.\n if (isAborted()) return stop()\n // A model that refuses the attachments can't do any step: end the run.\n if (err instanceof AttachmentsNotSupportedError) throw err\n emit({ type: 'error', phase: 'execute', error: errMessage(err) })\n stepResult = { step, summary: errMessage(err), toolCalls: [], blocked: true }\n } finally {\n currentStep = undefined\n }\n\n result.trace.push(stepResult)\n const applied = stepResult.toolCalls.filter((c) => c.ok).length\n const failed = stepResult.toolCalls.length - applied\n result.applied += applied\n result.steps = stepNo\n log.info(\n `step ${stepNo}/${total} \"${step.description}\" — ${stepResult.toolCalls.length} tool call(s), ${applied} ok${failed ? `, ${failed} FAILED` : ''}${stepResult.blocked ? ', BLOCKED' : ''}`,\n )\n if (stepResult.toolCalls.length === 0) {\n log.warn(`step ${stepNo} made no tool calls — nothing changed in this step`)\n }\n stepResult.toolCalls\n .filter((c) => !c.ok)\n .forEach((c) => log.warn(`tool ${c.name} failed:`, c.output))\n log.debug(`step ${stepNo} detail:`, stepResult)\n emit({ type: 'step.complete', step, result: stepResult })\n // The step's own summary carries the data later steps and the answer\n // need (\"found 3 open issues: #12, #15, #19\") — not just a count.\n const counts = stepResult.toolCalls.length\n ? ` [${applied} tool call(s) ok${failed ? `, ${failed} failed` : ''}]`\n : ''\n done.push(\n `${step.description} — ${clip(stepResult.summary, FINDING_CHARS)}${counts}${stepResult.blocked ? ' [blocked]' : ''}`,\n )\n for (const c of stepResult.toolCalls) {\n if (!c.ok || builtinTools.has(c.name)) continue\n findings.push(`- ${c.name}: ${clip(asJson(c.output), FINDING_CHARS)}`)\n }\n while (findings.join('\\n').length > FINDINGS_BUDGET && findings.length > 1) findings.shift()\n\n // Auto-compaction of the run's step log when it outgrows the threshold.\n if (cfg.compaction.auto) {\n const before = estimateTokens(done.join('\\n'))\n if (before > cfg.compaction.thresholdTokens) {\n const compacted = await compactSteps(done, synthesizerModel, {\n thresholdTokens: cfg.compaction.thresholdTokens,\n keepRecent: cfg.compaction.keepRecentSteps,\n summaryMaxTokens: cfg.budgets.compaction,\n timeoutMs: cfg.chatTimeoutMs,\n abortSignal: opts.signal,\n onUsage: (u) => bumpUsage(u, 'compact'),\n })\n if (compacted !== done) {\n done = compacted\n emit({\n type: 'context.compacted',\n scope: 'trace',\n beforeTokens: before,\n afterTokens: estimateTokens(done.join('\\n')),\n })\n }\n }\n }\n\n // 2b) REPLAN — by default after a blocked / failed step; `replanAfter`\n // can widen the trigger ('always', or a host predicate reacting to\n // e.g. issues surfaced through describeState). Also runs when the\n // triggering step was the last one — 'revise' can add remedial steps.\n // A host predicate is watchdog- and abort-bounded; re-check abort after\n // it (it may await slow state) before spending a replanner call.\n const wantReplan =\n cfg.replan &&\n iter < cfg.maxIterations &&\n revisions < cfg.maxRevisions &&\n !isAborted() &&\n !breach() &&\n (await replanWanted(cfg.replanAfter, stepResult, {\n signal: ctx.signal,\n timeoutMs: cfg.chatTimeoutMs,\n onError: (err) => log.warn('replanAfter predicate threw — using the failure rule', err),\n }))\n if (wantReplan && !isAborted()) {\n const decision = await decideReplan(\n ctx,\n text,\n done,\n remaining.map((s) => s.description),\n )\n bumpUsage(decision.usage, 'replan')\n emit({ type: 'replan.decision', mode: decision.decision, reason: decision.reason })\n if (decision.decision === 'finish') break\n if (decision.decision === 'revise' && decision.plan.length > 0) {\n revisions += 1\n remaining = decision.plan\n .slice(0, Math.min(cfg.maxPlanSteps, cfg.maxIterations - iter))\n .map((description, i) => ({ id: `r${iter}-${i + 1}`, description }))\n emit({\n type: 'plan.revised',\n plan: { thought: planned.plan.thought, steps: remaining },\n reason: decision.reason,\n })\n }\n }\n }\n // A limit reached on the very last step is still worth reporting.\n if (!budgetExceeded && remaining.length > 0) {\n const hit = breach()\n if (hit) {\n budgetExceeded = hit\n result.budgetExceeded = hit\n emit({ type: 'budget.exceeded', ...hit })\n }\n }\n\n if (isAborted()) return stop()\n\n // 3) SYNTHESIZE\n let summary = 'Done — the changes have been applied.'\n if (cfg.synthesize) {\n try {\n const synth = await synthesizeAnswer(ctx, text, done, findings)\n bumpUsage(synth.usage, 'synthesize')\n if (synth.text) summary = synth.text\n } catch (err) {\n if (isAborted()) return stop()\n if (err instanceof AttachmentsNotSupportedError) throw err\n /* keep the default */\n }\n }\n log.info(`done — ${result.applied} tool call(s) applied over ${result.steps} step(s)`)\n emit({ type: 'final', text: summary })\n await remember({ role: 'assistant', content: summary })\n result.final = summary\n\n // 4) COMPACT persisted history (legacy chars threshold, or the configured\n // compaction's token threshold).\n if (config.memory && (config.compaction ? cfg.compaction.auto : cfg.compressAfterChars > 0)) {\n try {\n const transcript = await config.memory.load(sessionId)\n const before = estimateMessagesTokens(transcript)\n const compacted = await compressHistory(transcript, synthesizerModel, {\n ...(config.compaction\n ? {\n thresholdTokens: cfg.compaction.thresholdTokens,\n keepRecent: cfg.compaction.keepRecentTurns,\n summaryMaxTokens: cfg.budgets.compaction,\n }\n : { maxChars: cfg.compressAfterChars }),\n timeoutMs: cfg.chatTimeoutMs,\n abortSignal: opts.signal,\n onUsage: (u) => bumpUsage(u, 'compact'),\n })\n if (compacted !== transcript) {\n await config.memory.replace(sessionId, compacted)\n emit({\n type: 'context.compacted',\n scope: 'history',\n beforeTokens: before,\n afterTokens: estimateMessagesTokens(compacted),\n })\n }\n } catch {\n /* best-effort */\n }\n }\n return result\n } catch (err) {\n if (isAborted()) return stop()\n emit({ type: 'error', phase: 'run', error: errMessage(err) })\n result.final = errMessage(err)\n return result\n }\n }\n\n const compact = async (o: CompactOptions = {}): Promise<CompactResult> => {\n const empty: CompactResult = {\n compacted: false,\n beforeTokens: 0,\n afterTokens: 0,\n usage: emptyUsage(),\n }\n if (!config.memory) return empty\n const sessionId = o.sessionId ?? cfg.sessionId\n const transcript = await config.memory.load(sessionId)\n const beforeTokens = estimateMessagesTokens(transcript)\n let usage = emptyUsage()\n const compacted = await compressHistory(transcript, synthesizerModel, {\n thresholdTokens: cfg.compaction.thresholdTokens,\n keepRecent: cfg.compaction.keepRecentTurns,\n summaryMaxTokens: cfg.budgets.compaction,\n force: o.force ?? true,\n timeoutMs: cfg.chatTimeoutMs,\n abortSignal: o.signal,\n onUsage: (u) => {\n usage = addUsage(usage, u)\n },\n })\n if (compacted === transcript)\n return { ...empty, beforeTokens, afterTokens: beforeTokens, usage }\n await config.memory.replace(sessionId, compacted)\n return { compacted: true, beforeTokens, afterTokens: estimateMessagesTokens(compacted), usage }\n }\n\n return {\n run,\n compact,\n setToolApprovalMode: (mode: ToolApprovalMode) => {\n if (!TOOL_APPROVAL_MODES.includes(mode)) {\n throw new Error(`unknown tool approval mode \"${mode}\" (${TOOL_APPROVAL_MODES.join(' | ')})`)\n }\n approval.mode = mode\n log.info(`tool approval mode → ${mode}`)\n },\n get toolApprovalMode() {\n return approval.mode\n },\n listTools: () => catalog.map((e) => ({ ...e })),\n toolStrategy: strategy,\n skills: skills.map((s) => ({ name: s.name, description: s.description })),\n capabilities: { images: accepts.image, pdf: accepts.pdf, files: accepts.file },\n models: { planner: plannerModel, executor: executorModel, synthesizer: synthesizerModel },\n }\n}\n","import { asSchema, jsonSchema, tool, type Tool, type ToolSet } from 'ai'\nimport type { IUsage } from '../agent/loop-types.js'\nimport { createAgent, type Agent } from '../agent/runner.js'\nimport type { BrowserAgentConfig } from '../config.js'\nimport type { AgentEvent } from '../events.js'\nimport { clip } from '../llm/util.js'\nimport type { ProviderModelSpec } from '../providers/types.js'\nimport type { CredentialStore } from '../secrets/store.js'\nimport { isReadOnlyTool } from '../tools/approval.js'\nimport type { AgentTool } from '../tools/types.js'\nimport { toolRunContextOf } from '../tools/wrap.js'\nimport {\n safePost,\n toCloneable,\n type ProxiedToolSpec,\n type WorkerLike,\n type WorkerToParent,\n} from './protocol.js'\n\n/** The serializable slice of BrowserAgentConfig a worker subagent can be built from. */\nexport type SubagentWorkerConfig = Pick<\n BrowserAgentConfig,\n | 'clientName'\n | 'systemPrompt'\n | 'availableTools'\n | 'excludedTools'\n | 'toolMode'\n | 'toolSelectionStrategy'\n | 'toolSearchThreshold'\n | 'skills'\n | 'maxIterations'\n | 'maxStepsPerTask'\n | 'maxRevisions'\n | 'maxToolCalls'\n | 'maxPlanSteps'\n | 'chatTimeoutMs'\n | 'budgets'\n | 'limits'\n | 'temperature'\n | 'thinking'\n | 'stageThinking'\n | 'promptCaching'\n | 'compaction'\n | 'replan'\n | 'synthesize'\n | 'logLevel'\n> & {\n /** The child's model, resolved inside the worker (by its `resolveModel`, or the registry). */\n model: ProviderModelSpec\n /** Consent policy inside the worker — mode and rules only (no callbacks cross threads). */\n toolApproval?: { mode?: 'autopilot' | 'read-only'; rules?: Record<string, 'allow' | 'deny'> }\n}\n\nexport interface SubagentToolOptions {\n /** Label for events and logs (the tool's KEY in your ToolSet is up to you). */\n name: string\n /** What the subagent is for — the parent model reads this to decide when to delegate. */\n description: string\n /** In-process subagent: a full config (models, tools, …) for the child agent. */\n config?: BrowserAgentConfig\n /**\n * Worker subagent: builds a fresh Worker per delegated task, e.g.\n * `() => new Worker(new URL('./agent.worker.ts', import.meta.url), { type: 'module' })`.\n * The worker module calls `serveSubagentWorker()`.\n */\n worker?: () => WorkerLike\n /** Worker subagent: the child's serializable config. */\n workerConfig?: SubagentWorkerConfig\n /**\n * Resolves `workerConfig.model.credentialRef` in the main thread; the key is\n * posted to the worker for that one task and never stored there.\n */\n credentials?: CredentialStore\n /**\n * Host tools the subagent may call. In-process they are merged into the\n * child's tools; with a worker they stay in the main thread and are called\n * over RPC. Either way each call passes the PARENT's consent gate.\n */\n tools?: ToolSet\n /** Parallel delegations allowed at once (default 4); extra calls queue. */\n maxConcurrent?: number\n /** Give up on one delegated task after this many ms (default: none). */\n timeoutMs?: number\n /** Cap on the text handed back to the parent model (default 8000 chars). */\n outputMaxChars?: number\n /** Mark the tool read-only for the parent's consent gate (default false). */\n readOnly?: boolean\n}\n\ninterface ChildOutcome {\n text: string\n usage: IUsage\n}\n\nconst abortError = (): Error => {\n const e = new Error('The subagent was aborted')\n e.name = 'AbortError'\n return e\n}\n\n/** A tiny FIFO semaphore: at most `size` holders, abort-aware waiting. */\nconst createSemaphore = (size: number) => {\n let active = 0\n const queue: (() => void)[] = []\n return async (signal?: AbortSignal): Promise<() => void> => {\n if (active >= size) {\n await new Promise<void>((resolve, reject) => {\n const go = () => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }\n const onAbort = () => {\n const i = queue.indexOf(go)\n if (i >= 0) queue.splice(i, 1)\n reject(abortError())\n }\n queue.push(go)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n }\n active += 1\n let released = false\n return () => {\n if (released) return\n released = true\n active -= 1\n queue.shift()?.()\n }\n }\n}\n\nlet seq = 0\n\n/**\n * Expose a subagent as a tool: the parent delegates `{ task }`, the child runs\n * its own plan → execute → synthesize loop — in this thread, or isolated in a\n * Web Worker — and its final answer comes back as the tool result. Several\n * delegations in one model step run in parallel (bounded by `maxConcurrent`).\n *\n * The parent sees `subagent.start` / `subagent.event` / `subagent.complete` /\n * `subagent.error` events, and the child's tokens are charged to the parent\n * run (a `usage` event with phase 'subagent'), so the parent's limits apply.\n */\nexport const createSubagentTool = (opts: SubagentToolOptions): AgentTool => {\n if (!opts.config === !opts.worker) {\n throw new Error(\n `subagent \"${opts.name}\": pass exactly one of \\`config\\` (in-process) or \\`worker\\``,\n )\n }\n if (opts.worker && !opts.workerConfig) {\n throw new Error(`subagent \"${opts.name}\": a worker subagent needs \\`workerConfig\\``)\n }\n const acquire = createSemaphore(Math.max(1, opts.maxConcurrent ?? 4))\n const outputMax = opts.outputMaxChars ?? 8_000\n\n const gatedHostTools = (\n approve: ((name: string, input: unknown, readOnly: boolean) => Promise<void>) | undefined,\n ): ToolSet =>\n Object.fromEntries(\n Object.entries(opts.tools ?? {}).map(([name, t]) => {\n const execute = (t as { execute?: (i: unknown, o: unknown) => unknown }).execute\n if (typeof execute !== 'function' || !approve) return [name, t]\n return [\n name,\n {\n ...t,\n execute: async (input: unknown, o: unknown) => {\n await approve(name, input, isReadOnlyTool(t as Tool))\n return execute.call(t, input, o)\n },\n },\n ]\n }),\n )\n\n const runInProcess = async (\n task: string,\n signal: AbortSignal | undefined,\n forward: (e: AgentEvent) => void,\n hostTools: ToolSet,\n ): Promise<ChildOutcome> => {\n const config = opts.config as BrowserAgentConfig\n // One child per task: its host tools are gated by THIS parent run. A\n // direct model (incl. a loaded WebLLM engine) is passed through, not rebuilt.\n const agent: Agent = await createAgent({ ...config, tools: { ...config.tools, ...hostTools } })\n let runError: string | undefined\n const result = await agent.run(task, {\n signal,\n onEvent: (e) => {\n if (e.type === 'error' && e.phase === 'run') runError = e.error\n forward(e)\n },\n })\n if (result.stopped) throw abortError()\n if (runError) throw new Error(runError)\n return { text: result.final, usage: result.usage }\n }\n\n const proxiedSpecs = async (): Promise<ProxiedToolSpec[]> =>\n Promise.all(\n Object.entries(opts.tools ?? {}).map(async ([name, t]) => ({\n name,\n description: typeof t.description === 'string' ? t.description : '',\n inputSchema: toCloneable(await asSchema(t.inputSchema as never).jsonSchema),\n readOnly: isReadOnlyTool(t as Tool),\n })),\n )\n\n const workerConfigFor = async (): Promise<Record<string, unknown>> => {\n const cfg = opts.workerConfig as SubagentWorkerConfig\n let model: ProviderModelSpec = { ...cfg.model }\n if (model.credentialRef && !model.apiKey && opts.credentials) {\n const apiKey = await opts.credentials.getApiKey(model.credentialRef)\n if (!apiKey)\n throw new Error(`no API key stored under \"${model.credentialRef}\" for the subagent`)\n model = { ...model, apiKey }\n }\n return toCloneable({ ...cfg, model }) as Record<string, unknown>\n }\n\n const runInWorker = async (\n task: string,\n signal: AbortSignal | undefined,\n forward: (e: AgentEvent) => void,\n hostTools: ToolSet,\n ): Promise<ChildOutcome> => {\n if (signal?.aborted) throw abortError()\n const [config, proxied] = await Promise.all([workerConfigFor(), proxiedSpecs()])\n const worker = (opts.worker as () => WorkerLike)()\n return new Promise<ChildOutcome>((resolve, reject) => {\n let settled = false\n const finish = (fn: () => void): void => {\n if (settled) return\n settled = true\n signal?.removeEventListener('abort', onAbort)\n worker.removeEventListener?.('message', onMessage)\n worker.removeEventListener?.('error', onError)\n // A worker is single-use: terminating frees its memory and any engine.\n worker.terminate?.()\n fn()\n }\n const onAbort = (): void => {\n safePost(worker, { type: 'abort' })\n finish(() => reject(abortError()))\n }\n const onError = (ev: { message?: string }): void =>\n finish(() => reject(new Error(`subagent worker failed: ${ev?.message ?? 'unknown error'}`)))\n const callHostTool = async (callId: string, name: string, input: unknown): Promise<void> => {\n const t = hostTools[name] as { execute?: (i: unknown, o: unknown) => unknown } | undefined\n try {\n if (!t || typeof t.execute !== 'function') throw new Error(`unknown host tool \"${name}\"`)\n const output = await t.execute(input, {\n toolCallId: callId,\n messages: [],\n abortSignal: signal,\n })\n if (!settled) safePost(worker, { type: 'tool-result', callId, ok: true, output })\n } catch (err) {\n const output = err instanceof Error ? err.message : String(err)\n if (!settled) safePost(worker, { type: 'tool-result', callId, ok: false, output })\n }\n }\n const onMessage = (ev: { data: unknown }): void => {\n const msg = ev.data as WorkerToParent\n switch (msg?.type) {\n case 'event':\n forward(msg.event)\n break\n case 'tool-call':\n void callHostTool(msg.callId, msg.name, msg.input)\n break\n case 'done':\n finish(() => resolve({ text: msg.text, usage: msg.usage }))\n break\n case 'error':\n finish(() => reject(new Error(msg.error)))\n break\n }\n }\n worker.addEventListener('message', onMessage)\n worker.addEventListener('error', onError)\n signal?.addEventListener('abort', onAbort, { once: true })\n safePost(worker, { type: 'run', task, config, proxied })\n })\n }\n\n const t = tool({\n description: opts.description,\n inputSchema: jsonSchema<{ task: string }>({\n type: 'object',\n properties: {\n task: {\n type: 'string',\n description:\n 'A complete, self-contained task: the subagent sees nothing of your context except this text.',\n },\n },\n required: ['task'],\n additionalProperties: false,\n }),\n execute: async ({ task }, options) => {\n const runCtx = toolRunContextOf(options)\n const parentSignal =\n (options as { abortSignal?: AbortSignal } | undefined)?.abortSignal ?? runCtx?.signal\n const id = `${opts.name}-${(seq += 1)}`\n const release = await acquire(parentSignal)\n const emit = (e: AgentEvent) => runCtx?.emit(e)\n // One controller per task: the parent's abort and our own deadline both\n // stop the child (and its worker) the same way.\n const controller = new AbortController()\n const onParentAbort = () => controller.abort()\n parentSignal?.addEventListener('abort', onParentAbort, { once: true })\n if (parentSignal?.aborted) controller.abort()\n let timedOut = false\n const timer =\n opts.timeoutMs && opts.timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true\n controller.abort()\n }, opts.timeoutMs)\n : undefined\n emit({ type: 'subagent.start', id, name: opts.name, task })\n try {\n const forward = (event: AgentEvent) =>\n emit({ type: 'subagent.event', id, name: opts.name, event })\n const hostTools = gatedHostTools(runCtx?.approve)\n const run = opts.worker ? runInWorker : runInProcess\n const out = await run(task, controller.signal, forward, hostTools).catch((err: unknown) => {\n if (timedOut)\n throw new Error(`subagent \"${opts.name}\" timed out after ${opts.timeoutMs} ms`)\n throw err\n })\n runCtx?.addUsage(out.usage)\n emit({ type: 'subagent.complete', id, name: opts.name, text: out.text, usage: out.usage })\n return clip(out.text, outputMax)\n } catch (err) {\n emit({\n type: 'subagent.error',\n id,\n name: opts.name,\n error: err instanceof Error ? err.message : String(err),\n })\n throw err\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n parentSignal?.removeEventListener('abort', onParentAbort)\n release()\n }\n },\n }) as AgentTool\n t.promptHint = '{ task: string }'\n if (opts.readOnly) t.readOnly = true\n return t\n}\n","import type { IUsage } from '../agent/loop-types.js'\nimport type { AgentEvent } from '../events.js'\n\n/**\n * The wire protocol between a parent agent and a subagent running in a Web\n * Worker. Every message is structured-cloneable; anything that is not (an\n * Error, a function in a tool output) is flattened before it is posted.\n */\n\n/** A host tool the worker can call back into the main thread for. */\nexport interface ProxiedToolSpec {\n name: string\n description: string\n /** JSON Schema of the tool input. */\n inputSchema: unknown\n readOnly?: boolean\n}\n\nexport type ParentToWorker =\n | {\n type: 'run'\n task: string\n /** Serializable agent config (model is a ProviderModelSpec). */\n config: Record<string, unknown>\n proxied: ProxiedToolSpec[]\n }\n | { type: 'abort' }\n | { type: 'tool-result'; callId: string; ok: boolean; output: unknown }\n\nexport type WorkerToParent =\n | { type: 'event'; event: AgentEvent }\n | { type: 'tool-call'; callId: string; name: string; input: unknown }\n | { type: 'done'; text: string; usage: IUsage; steps: number }\n | { type: 'error'; error: string }\n\n/**\n * The slice of the Worker / DedicatedWorkerGlobalScope / MessagePort API we\n * use. Structural, so a real `Worker`, a worker's `self`, or a MessageChannel\n * port (tests) all fit.\n */\nexport interface MessageEndpoint {\n postMessage(message: unknown): void\n addEventListener(type: string, listener: (ev: any) => void): void\n removeEventListener?(type: string, listener: (ev: any) => void): void\n}\n\n/** A worker as the parent sees it. */\nexport interface WorkerLike extends MessageEndpoint {\n terminate?(): void\n}\n\n/** JSON-safe copy (Errors become their message, cycles become strings). */\nexport const toCloneable = (value: unknown): unknown => {\n try {\n return JSON.parse(\n JSON.stringify(value, (_k, v: unknown) => (v instanceof Error ? v.message : v)) ?? 'null',\n )\n } catch {\n return String(value)\n }\n}\n\n/** postMessage that never throws a DataCloneError: falls back to a JSON-safe copy. */\nexport const safePost = (target: { postMessage(m: unknown): void }, message: unknown): void => {\n try {\n target.postMessage(message)\n } catch {\n target.postMessage(toCloneable(message))\n }\n}\n","import { dynamicTool, jsonSchema, type LanguageModel, type ToolSet } from 'ai'\nimport { createAgent } from '../agent/runner.js'\nimport type { BrowserAgentConfig } from '../config.js'\nimport type { AgentEvent } from '../events.js'\nimport { buildModelFromStage, resolveStage } from '../providers/registry.js'\nimport type { ProviderModelSpec } from '../providers/types.js'\nimport { MemoryCredentialStore } from '../secrets/store.js'\nimport { markReadOnly } from '../tools/approval.js'\nimport {\n safePost,\n type MessageEndpoint,\n type ParentToWorker,\n type ProxiedToolSpec,\n} from './protocol.js'\n\nexport interface ServeSubagentOptions {\n /**\n * Build the child's model from its spec. Pass one when your bundler can't\n * resolve the core's dynamic provider imports inside a worker (Vite): import\n * the provider factories statically in the worker module and build here.\n * Default: the core registry (dynamic import of the optional peer).\n */\n resolveModel?: (spec: ProviderModelSpec) => LanguageModel | Promise<LanguageModel>\n /**\n * Worker-local tools — they run in the worker thread, so CPU-heavy work\n * (search, parsing, simulation) never blocks the page.\n */\n tools?: ToolSet\n /** The worker's message endpoint (default: the worker global scope). */\n scope?: MessageEndpoint\n}\n\n// The key arrives with the task and lives only in this in-memory store, so\n// the registry builds the model without the inline-key warning.\nconst SUBAGENT_REF = '__subagent__'\n\nconst defaultResolveModel = (spec: ProviderModelSpec): Promise<LanguageModel> => {\n const { apiKey, ...rest } = spec\n const credentials = apiKey ? new MemoryCredentialStore({ [SUBAGENT_REF]: apiKey }) : undefined\n return buildModelFromStage(\n resolveStage(apiKey ? { ...rest, credentialRef: SUBAGENT_REF } : rest, undefined, 'subagent'),\n credentials,\n )\n}\n\n/**\n * Serve subagent tasks inside a Web Worker. Call it once at the top of your\n * worker module; the parent's `createSubagentTool({ worker })` posts a task,\n * this builds a child agent (worker-local tools + the parent's host tools\n * proxied over RPC), runs it, streams its events back and answers with the\n * final text.\n *\n * ```ts\n * // agent.worker.ts\n * import { serveSubagentWorker } from '@dudko.dev/agent-web'\n * import { createGoogleGenerativeAI } from '@ai-sdk/google'\n * serveSubagentWorker({\n * resolveModel: (spec) => createGoogleGenerativeAI({ apiKey: spec.apiKey })(spec.model),\n * tools: { heavy_search: defineTool({ … }) },\n * })\n * ```\n */\nexport const serveSubagentWorker = (opts: ServeSubagentOptions = {}): void => {\n const scope = opts.scope ?? (globalThis as unknown as MessageEndpoint)\n let controller: AbortController | undefined\n const pending = new Map<string, { resolve: (v: unknown) => void; reject: (e: Error) => void }>()\n let callSeq = 0\n\n const proxy = (spec: ProxiedToolSpec) => {\n const t = dynamicTool({\n description: spec.description,\n inputSchema: jsonSchema(spec.inputSchema as Parameters<typeof jsonSchema>[0]),\n execute: (input, options) =>\n new Promise((resolve, reject) => {\n const callId = `call-${(callSeq += 1)}`\n const signal = options?.abortSignal\n if (signal?.aborted) return reject(new Error('aborted'))\n pending.set(callId, { resolve, reject })\n signal?.addEventListener(\n 'abort',\n () => {\n if (pending.delete(callId)) reject(new Error('aborted'))\n },\n { once: true },\n )\n safePost(scope, { type: 'tool-call', callId, name: spec.name, input })\n }),\n })\n return spec.readOnly ? markReadOnly(t) : t\n }\n\n const run = async (msg: Extract<ParentToWorker, { type: 'run' }>): Promise<void> => {\n controller = new AbortController()\n let runError: string | undefined\n try {\n const { model: spec, ...rest } = msg.config as { model: ProviderModelSpec } & Record<\n string,\n unknown\n >\n const model = await (opts.resolveModel ?? defaultResolveModel)(spec)\n const proxied = Object.fromEntries(msg.proxied.map((p) => [p.name, proxy(p)]))\n const agent = await createAgent({\n ...(rest as Partial<BrowserAgentConfig>),\n model,\n tools: { ...opts.tools, ...proxied },\n })\n const result = await agent.run(msg.task, {\n signal: controller.signal,\n onEvent: (event: AgentEvent) => {\n if (event.type === 'error' && event.phase === 'run') runError = event.error\n safePost(scope, { type: 'event', event })\n },\n })\n if (result.stopped) safePost(scope, { type: 'error', error: 'aborted' })\n else if (runError) safePost(scope, { type: 'error', error: runError })\n else\n safePost(scope, {\n type: 'done',\n text: result.final,\n usage: result.usage,\n steps: result.steps,\n })\n } catch (err) {\n safePost(scope, { type: 'error', error: err instanceof Error ? err.message : String(err) })\n }\n }\n\n scope.addEventListener('message', (ev: { data: unknown }) => {\n const msg = ev.data as ParentToWorker\n switch (msg?.type) {\n case 'run':\n void run(msg)\n break\n case 'abort':\n controller?.abort()\n for (const [id, p] of pending) {\n pending.delete(id)\n p.reject(new Error('aborted'))\n }\n break\n case 'tool-result': {\n const p = pending.get(msg.callId)\n if (!p) break\n pending.delete(msg.callId)\n if (msg.ok) p.resolve(msg.output)\n else\n p.reject(\n new Error(typeof msg.output === 'string' ? msg.output : JSON.stringify(msg.output)),\n )\n break\n }\n }\n })\n}\n","import { IndexedDBVault, type VaultOptions } from './vault.js'\n\n/**\n * The seam the provider registry uses to fetch API keys at model-build time.\n * Swap in any backend: the encrypted vault (default), an in-memory map (tests /\n * SSR), or a `fetch` to your own short-lived-token endpoint.\n */\nexport interface CredentialStore {\n getApiKey(ref: string): Promise<string | undefined>\n setApiKey(ref: string, key: string): Promise<void>\n deleteApiKey(ref: string): Promise<void>\n}\n\n/** Default CredentialStore: encrypted, IndexedDB-backed (see IndexedDBVault). */\nexport class VaultCredentialStore implements CredentialStore {\n private readonly vault: IndexedDBVault\n\n constructor(opts: VaultOptions = {}) {\n this.vault = new IndexedDBVault(opts)\n }\n\n getApiKey(ref: string): Promise<string | undefined> {\n return this.vault.getSecret(ref)\n }\n setApiKey(ref: string, key: string): Promise<void> {\n return this.vault.setSecret(ref, key)\n }\n deleteApiKey(ref: string): Promise<void> {\n return this.vault.deleteSecret(ref)\n }\n}\n\n/** Non-persistent CredentialStore for tests / SSR / ephemeral sessions. */\nexport class MemoryCredentialStore implements CredentialStore {\n private readonly map = new Map<string, string>()\n\n constructor(initial?: Record<string, string>) {\n if (initial) for (const [k, v] of Object.entries(initial)) this.map.set(k, v)\n }\n\n async getApiKey(ref: string): Promise<string | undefined> {\n return this.map.get(ref)\n }\n async setApiKey(ref: string, key: string): Promise<void> {\n this.map.set(ref, key)\n }\n async deleteApiKey(ref: string): Promise<void> {\n this.map.delete(ref)\n }\n}\n","import { FILES_STORE, openAgentWebDB } from '../storage/db.js'\n\n/**\n * A small virtual file system for the browser — the agent's (and the user's)\n * workspace: attachments the user drops in, reports the agent writes, images\n * pasted into the chat. Persistent in IndexedDB by default, in-memory on\n * request (tests, private mode). Paths are POSIX-like and always absolute\n * (\"/notes/todo.md\"); there are no real directories — a \"directory\" is a path\n * prefix.\n */\nexport interface VirtualFile {\n path: string\n /** Text, or base64 for binary content (see `encoding`). */\n content: string\n encoding: 'utf8' | 'base64'\n mimeType: string\n /** Size of the decoded content in bytes. */\n size: number\n updatedAt: number\n}\n\n/** A listing entry (no content). */\nexport type VirtualFileInfo = Omit<VirtualFile, 'content'>\n\nexport interface VirtualFileSystemOptions {\n /** Keep files in memory only (default false: IndexedDB). */\n memory?: boolean\n /** IndexedDB database name, forwarded to the shared owner (default 'agent-web'). */\n dbName?: string\n /** Isolates several file systems in one database (default 'default'). */\n namespace?: string\n /** Refuse a single file larger than this many bytes (default 10 MB). */\n maxFileBytes?: number\n}\n\nexport type VfsListener = (change: { type: 'write' | 'delete'; path: string }) => void\n\nconst MIME: Record<string, string> = {\n txt: 'text/plain',\n md: 'text/markdown',\n json: 'application/json',\n csv: 'text/csv',\n html: 'text/html',\n css: 'text/css',\n js: 'text/javascript',\n ts: 'text/typescript',\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n pdf: 'application/pdf',\n xml: 'application/xml',\n yaml: 'text/yaml',\n yml: 'text/yaml',\n}\n\n/** A best-effort MIME type from a file name. */\nexport const mimeFromPath = (path: string): string =>\n MIME[path.split('.').pop()?.toLowerCase() ?? ''] ?? 'application/octet-stream'\n\n/** True for MIME types the agent can read as text. */\nexport const isTextMime = (mime: string): boolean =>\n /^text\\/|json|xml|yaml|javascript|typescript|svg/.test(mime)\n\n/**\n * Normalise a path: absolute, forward slashes, no \".\" / \"..\" / empty segments.\n * Throws on a path that escapes the root.\n */\nexport const normalizePath = (input: string): string => {\n const parts: string[] = []\n for (const seg of String(input ?? '')\n .replace(/\\\\/g, '/')\n .split('/')) {\n if (!seg || seg === '.') continue\n if (seg === '..') {\n if (parts.length === 0) throw new Error(`path \"${input}\" escapes the root`)\n parts.pop()\n continue\n }\n parts.push(seg)\n }\n if (parts.length === 0) throw new Error('a file path is required')\n return `/${parts.join('/')}`\n}\n\nconst byteLength = (content: string, encoding: VirtualFile['encoding']): number =>\n encoding === 'base64'\n ? Math.floor((content.replace(/=+$/, '').length * 3) / 4)\n : new TextEncoder().encode(content).length\n\n/** Base64 of bytes, chunked so a large file can't blow the call stack. */\nexport const bytesToBase64 = (bytes: Uint8Array): string => {\n let bin = ''\n for (let i = 0; i < bytes.length; i += 0x8000) {\n bin += String.fromCharCode(...bytes.subarray(i, i + 0x8000))\n }\n return btoa(bin)\n}\n\nexport class VirtualFileSystem {\n private readonly memory?: Map<string, VirtualFile>\n private readonly dbName?: string\n private readonly ns: string\n private readonly maxFileBytes: number\n private readonly listeners = new Set<VfsListener>()\n\n constructor(opts: VirtualFileSystemOptions = {}) {\n if (opts.memory) this.memory = new Map()\n this.dbName = opts.dbName\n this.ns = opts.namespace ?? 'default'\n this.maxFileBytes = opts.maxFileBytes ?? 10 * 1024 * 1024\n }\n\n private key(path: string): string {\n return `${this.ns}:${path}`\n }\n\n /** Subscribe to writes and deletes (e.g. to refresh a file list). Returns an unsubscribe. */\n onChange(listener: VfsListener): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n private notify(type: 'write' | 'delete', path: string): void {\n for (const l of this.listeners) {\n try {\n l({ type, path })\n } catch {\n /* a bad listener must not break a write */\n }\n }\n }\n\n async write(\n path: string,\n content: string | Uint8Array,\n opts: { mimeType?: string; encoding?: VirtualFile['encoding'] } = {},\n ): Promise<VirtualFileInfo> {\n const p = normalizePath(path)\n const binary = content instanceof Uint8Array\n const encoding = binary ? 'base64' : (opts.encoding ?? 'utf8')\n const text = binary ? bytesToBase64(content) : content\n const size = binary ? content.length : byteLength(text, encoding)\n if (size > this.maxFileBytes) {\n throw new Error(`\"${p}\" is ${size} bytes; the limit is ${this.maxFileBytes}`)\n }\n const file: VirtualFile = {\n path: p,\n content: text,\n encoding,\n mimeType: opts.mimeType ?? mimeFromPath(p),\n size,\n updatedAt: Date.now(),\n }\n if (this.memory) this.memory.set(p, file)\n else {\n const db = await openAgentWebDB({ dbName: this.dbName })\n await db.put(FILES_STORE, file, this.key(p))\n }\n this.notify('write', p)\n const { content: _drop, ...info } = file\n return info\n }\n\n /** Store a data URL (\"data:image/png;base64,…\") as a file. */\n async writeDataUrl(path: string, dataUrl: string): Promise<VirtualFileInfo> {\n const m = /^data:([^;,]+)?(;base64)?,(.*)$/s.exec(dataUrl)\n if (!m) throw new Error('not a data URL')\n const mimeType = m[1] ?? 'application/octet-stream'\n return m[2]\n ? this.write(path, m[3], { mimeType, encoding: 'base64' })\n : this.write(path, decodeURIComponent(m[3]), { mimeType })\n }\n\n async read(path: string): Promise<VirtualFile | undefined> {\n const p = normalizePath(path)\n if (this.memory) return this.memory.get(p)\n const db = await openAgentWebDB({ dbName: this.dbName })\n return (await db.get(FILES_STORE, this.key(p))) as VirtualFile | undefined\n }\n\n /** The file as a data URL (for <img src>, downloads). */\n async readDataUrl(path: string): Promise<string | undefined> {\n const f = await this.read(path)\n if (!f) return undefined\n return f.encoding === 'base64'\n ? `data:${f.mimeType};base64,${f.content}`\n : `data:${f.mimeType};charset=utf-8,${encodeURIComponent(f.content)}`\n }\n\n async delete(path: string): Promise<boolean> {\n const p = normalizePath(path)\n let existed: boolean\n if (this.memory) existed = this.memory.delete(p)\n else {\n const db = await openAgentWebDB({ dbName: this.dbName })\n existed = (await db.get(FILES_STORE, this.key(p))) !== undefined\n await db.delete(FILES_STORE, this.key(p))\n }\n if (existed) this.notify('delete', p)\n return existed\n }\n\n /** Files under a prefix (\"/\" = all), sorted by path. */\n async list(prefix = '/'): Promise<VirtualFileInfo[]> {\n const dir = prefix === '/' ? '/' : `${normalizePath(prefix)}/`\n let files: VirtualFile[]\n if (this.memory) files = [...this.memory.values()]\n else {\n const db = await openAgentWebDB({ dbName: this.dbName })\n const range = IDBKeyRange.bound(`${this.ns}:`, `${this.ns}:￿`)\n files = (await db.getAll(FILES_STORE, range)) as VirtualFile[]\n }\n return files\n .filter((f) => dir === '/' || f.path.startsWith(dir))\n .map(({ content: _drop, ...info }) => info)\n .sort((a, b) => a.path.localeCompare(b.path))\n }\n\n /** Remove every file (of this namespace). */\n async clear(): Promise<void> {\n for (const f of await this.list()) await this.delete(f.path)\n }\n}\n","import { jsonSchema, tool, type ToolSet } from 'ai'\nimport { markReadOnly } from '../tools/approval.js'\nimport { isTextMime, type VirtualFileSystem } from './vfs.js'\n\nexport interface FileToolsOptions {\n /** Tool-name prefix (default 'fs_' → fs_list, fs_read, fs_write, fs_delete). */\n prefix?: string\n /** Mount only the read tools (default false). */\n readOnly?: boolean\n /** Cap on the text fs_read returns (default 50 000 chars; the rest is cut with a marker). */\n maxReadChars?: number\n}\n\n/**\n * Tools that give the agent the virtual file system: list, read, write and\n * delete. Listing and reading are marked read-only, so the `ask-writes`\n * consent mode lets them through and asks before writes and deletes.\n */\nexport const createFileTools = (vfs: VirtualFileSystem, opts: FileToolsOptions = {}): ToolSet => {\n const p = opts.prefix ?? 'fs_'\n const maxRead = opts.maxReadChars ?? 50_000\n const tools: ToolSet = {\n [`${p}list`]: markReadOnly(\n tool({\n description:\n 'List the files in the workspace (attachments the user added, files you wrote). Optionally only under a directory prefix.',\n inputSchema: jsonSchema<{ prefix?: string }>({\n type: 'object',\n properties: { prefix: { type: 'string', description: 'Directory prefix, e.g. \"/docs\"' } },\n additionalProperties: false,\n }),\n execute: async ({ prefix }) =>\n (await vfs.list(prefix || '/')).map((f) => ({\n path: f.path,\n mimeType: f.mimeType,\n size: f.size,\n })),\n }),\n ),\n [`${p}read`]: markReadOnly(\n tool({\n description: 'Read a text file from the workspace by its path.',\n inputSchema: jsonSchema<{ path: string }>({\n type: 'object',\n properties: { path: { type: 'string', description: 'Absolute path, e.g. \"/notes.md\"' } },\n required: ['path'],\n additionalProperties: false,\n }),\n execute: async ({ path }) => {\n const f = await vfs.read(path)\n if (!f) {\n const known = (await vfs.list()).map((x) => x.path).slice(0, 30)\n throw new Error(`no file \"${path}\"; files: ${known.join(', ') || 'none'}`)\n }\n if (f.encoding === 'base64' && !isTextMime(f.mimeType)) {\n return `\"${f.path}\" is a binary file (${f.mimeType}, ${f.size} bytes) and cannot be read as text.`\n }\n const text = f.encoding === 'base64' ? atob(f.content) : f.content\n return text.length > maxRead\n ? `${text.slice(0, maxRead)}… [truncated ${text.length - maxRead} chars]`\n : text\n },\n }),\n ),\n }\n if (opts.readOnly) return tools\n tools[`${p}write`] = tool({\n description:\n 'Write a text file to the workspace (creates or replaces it). Use it for reports, drafts, data the user should be able to open.',\n inputSchema: jsonSchema<{ path: string; content: string; mimeType?: string }>({\n type: 'object',\n properties: {\n path: { type: 'string', description: 'Absolute path, e.g. \"/reports/summary.md\"' },\n content: { type: 'string', description: 'The full file content' },\n mimeType: { type: 'string', description: 'Optional MIME type (guessed from the name)' },\n },\n required: ['path', 'content'],\n additionalProperties: false,\n }),\n execute: async ({ path, content, mimeType }) => {\n const info = await vfs.write(path, content, mimeType ? { mimeType } : {})\n return { written: info.path, size: info.size }\n },\n })\n tools[`${p}delete`] = tool({\n description: 'Delete a file from the workspace.',\n inputSchema: jsonSchema<{ path: string }>({\n type: 'object',\n properties: { path: { type: 'string' } },\n required: ['path'],\n additionalProperties: false,\n }),\n execute: async ({ path }) => ({ deleted: await vfs.delete(path) }),\n })\n return tools\n}\n","import { tool, type Tool } from 'ai'\nimport type { AgentTool } from './types.js'\n\n/**\n * Define a host tool. Thin wrapper over the AI SDK `tool()`: pass a\n * `description`, an `inputSchema` (a Zod schema or the result of `jsonSchema()`),\n * and an `execute` function. The returned tool works unchanged on the native\n * tool-calling path.\n *\n * Generic over INPUT/OUTPUT so the schema's inferred type flows into\n * `execute(input)` — `Parameters<typeof tool>[0]` must NOT be used here: with\n * an overloaded `tool()` it resolves to the last overload (`Tool<never, never>`),\n * which rejects every real schema and types `execute` as `undefined`.\n *\n * Optionally add `promptHint` — a short parameter hint like\n * \"{ text: string, x?: number }\" — which the prompted/salvage path shows to\n * weak local models that can't do native function-calling — and `readOnly:\n * true` for tools that never change state (the `ask-writes` and `read-only`\n * approval modes let those run without asking).\n *\n * @example\n * const tools = {\n * add_text: defineTool({\n * description: 'Add a text block to the page.',\n * inputSchema: z.object({ text: z.string(), x: z.number().optional() }),\n * promptHint: '{ text: string, x?: number }',\n * execute: async ({ text, x }) => addTextBlock(text, x),\n * }),\n * }\n */\nexport const defineTool = <INPUT = unknown, OUTPUT = unknown>(\n config: Tool<INPUT, OUTPUT> & { promptHint?: string; readOnly?: boolean },\n): AgentTool => {\n const { promptHint, readOnly, ...rest } = config\n const t = tool(rest as Tool<INPUT, OUTPUT>) as AgentTool\n if (promptHint) t.promptHint = promptHint\n // Read-only tools pass the consent gate in 'ask-writes' / 'read-only' modes.\n if (readOnly) t.readOnly = true\n return t\n}\n","export interface StoredMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n ts?: number\n}\n\n/** Persists an agent session's transcript. Swap in any backend. */\nexport interface ContextStore {\n load(sessionId: string): Promise<StoredMessage[]>\n append(sessionId: string, message: StoredMessage): Promise<void>\n replace(sessionId: string, messages: StoredMessage[]): Promise<void>\n clear(sessionId: string): Promise<void>\n}\n\n/** Non-persistent fallback (tests, SSR, private mode). */\nexport class MemoryStore implements ContextStore {\n private readonly data = new Map<string, StoredMessage[]>()\n\n async load(sessionId: string): Promise<StoredMessage[]> {\n return (this.data.get(sessionId) ?? []).slice()\n }\n async append(sessionId: string, message: StoredMessage): Promise<void> {\n const arr = this.data.get(sessionId) ?? []\n arr.push(message)\n this.data.set(sessionId, arr)\n }\n async replace(sessionId: string, messages: StoredMessage[]): Promise<void> {\n this.data.set(sessionId, messages.slice())\n }\n async clear(sessionId: string): Promise<void> {\n this.data.delete(sessionId)\n }\n}\n","import { openAgentWebDB, SESSIONS_STORE } from '../storage/db.js'\nimport type { ContextStore, StoredMessage } from './store.js'\n\nexport interface IndexedDBStoreOptions {\n /** Database name, forwarded to the shared IDB owner (default 'agent-web'). */\n dbName?: string\n}\n\n/**\n * IndexedDB-backed transcript store — one record (message array) per session,\n * in the shared `sessions` object store (see storage/db.ts). Also exposes\n * session utilities: list and delete.\n */\nexport class IndexedDBStore implements ContextStore {\n private readonly dbName?: string\n\n constructor(opts: IndexedDBStoreOptions = {}) {\n this.dbName = opts.dbName\n }\n\n async load(sessionId: string): Promise<StoredMessage[]> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n const value = (await db.get(SESSIONS_STORE, sessionId)) as StoredMessage[] | undefined\n return Array.isArray(value) ? value : []\n }\n\n async replace(sessionId: string, messages: StoredMessage[]): Promise<void> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n await db.put(SESSIONS_STORE, messages, sessionId)\n }\n\n async append(sessionId: string, message: StoredMessage): Promise<void> {\n const current = await this.load(sessionId)\n current.push(message)\n await this.replace(sessionId, current)\n }\n\n async clear(sessionId: string): Promise<void> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n await db.delete(SESSIONS_STORE, sessionId)\n }\n\n /** List all stored session ids. */\n async listSessions(): Promise<string[]> {\n const db = await openAgentWebDB({ dbName: this.dbName })\n return (await db.getAllKeys(SESSIONS_STORE)).map(String)\n }\n}\n"],"mappings":"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","names":["createWebLLMModel","tool","tool","jsonSchema","tool","tool","jsonSchema","generateText","streamText","streamText","generateText","result","LOCAL_RE","provider","id","asJson","asSchema","jsonSchema","tool","seq","t","asSchema","tool","jsonSchema","jsonSchema","jsonSchema","jsonSchema","tool","tool","jsonSchema","tool"]}