@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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as ai from 'ai';
2
- import { LanguageModel, ToolSet, Tool, ModelMessage, generateText, streamText } from 'ai';
2
+ import { LanguageModel, ToolSet, Tool, FilePart, SystemModelMessage, ModelMessage, generateText, streamText } from 'ai';
3
3
  import { V as VaultOptions } from './vault-BHlMmKXM.cjs';
4
4
  export { I as IndexedDBVault } from './vault-BHlMmKXM.cjs';
5
5
  import { z, ZodType } from 'zod';
@@ -23,6 +23,12 @@ interface IUsage {
23
23
  inputTokens: number;
24
24
  outputTokens: number;
25
25
  totalTokens: number;
26
+ /** Output tokens spent thinking (a subset of outputTokens). */
27
+ reasoningTokens?: number;
28
+ /** Input tokens served from the provider's prompt cache. */
29
+ cachedInputTokens?: number;
30
+ /** Input tokens written to the provider's prompt cache. */
31
+ cacheWriteTokens?: number;
26
32
  }
27
33
  interface IToolCall {
28
34
  name: string;
@@ -38,6 +44,126 @@ interface IStepResult {
38
44
  blocked: boolean;
39
45
  }
40
46
 
47
+ /**
48
+ * Thinking (a.k.a. reasoning) activation, portable across providers.
49
+ *
50
+ * The AI SDK exposes a top-level `reasoning` level on every call and translates
51
+ * it to each provider's native API (OpenAI reasoning effort, Anthropic adaptive
52
+ * thinking, Gemini thinking level, …). An exact token budget is not portable,
53
+ * so a `budgetTokens` is mapped to the provider-specific options of the two
54
+ * providers that take one (Anthropic, Google); provider options win over the
55
+ * portable level by the SDK's precedence rules.
56
+ *
57
+ * WebLLM ignores the portable level: its thinking models (Qwen3) are switched
58
+ * by `extra_body.enable_thinking`, so every setting carries that too.
59
+ */
60
+ type ThinkingLevel = 'provider-default' | 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
61
+ interface ThinkingConfig {
62
+ /** Portable effort level (default 'medium'). */
63
+ level?: ThinkingLevel;
64
+ /** Exact thinking budget — mapped to Anthropic `thinking` / Google `thinkingConfig`. */
65
+ budgetTokens?: number;
66
+ /** Stream the model's thoughts where the provider can (default true). */
67
+ includeThoughts?: boolean;
68
+ }
69
+ /**
70
+ * `false`/undefined → leave the provider default alone; `true` → 'medium';
71
+ * a level string → that level; an object → full control.
72
+ */
73
+ type ThinkingSetting = boolean | ThinkingLevel | ThinkingConfig;
74
+ type ThinkingStage = 'planner' | 'executor' | 'replanner' | 'synthesizer';
75
+ /** Provider-keyed options, the shape of the AI SDK's `providerOptions`. */
76
+ type ProviderOptionsMap = Record<string, Record<string, unknown>>;
77
+ interface ResolvedThinking {
78
+ reasoning?: ThinkingLevel;
79
+ providerOptions?: ProviderOptionsMap;
80
+ }
81
+ /**
82
+ * Turn a thinking setting into call options: the portable `reasoning` level
83
+ * plus the provider-specific extras for an exact budget or streamed thoughts.
84
+ * Pure — unit-tested.
85
+ */
86
+ declare const resolveThinking: (setting: ThinkingSetting | undefined) => ResolvedThinking;
87
+ /** The setting that applies to one stage: a stage entry wins over the top level. */
88
+ declare const thinkingFor: (stage: ThinkingStage, top: ThinkingSetting | undefined, perStage: Partial<Record<ThinkingStage, ThinkingSetting>> | undefined) => ThinkingSetting | undefined;
89
+ /**
90
+ * Deep-merge provider-option maps left to right (later wins). Returns undefined
91
+ * when there is nothing to send, so callers can spread it unconditionally.
92
+ */
93
+ declare const mergeProviderOptions: (...maps: (ProviderOptionsMap | undefined)[]) => ProviderOptionsMap | undefined;
94
+
95
+ /**
96
+ * Prompt caching. Every stage's SYSTEM prompt holds only run-stable content
97
+ * (role, domain context, skills, tool catalogue) and the dynamic parts go to
98
+ * the user prompt — so OpenAI's and Gemini's automatic prefix caches hit.
99
+ * Anthropic caches only behind an explicit breakpoint, placed on the system
100
+ * message; OpenAI additionally routes by `promptCacheKey`. Other providers
101
+ * ignore option keys that are not theirs.
102
+ */
103
+ type PromptCachingSetting = boolean | {
104
+ ttl?: '5m' | '1h';
105
+ key?: string;
106
+ };
107
+ interface ResolvedCaching {
108
+ enabled: boolean;
109
+ ttl?: '5m' | '1h';
110
+ key?: string;
111
+ }
112
+ declare const resolveCaching: (s: PromptCachingSetting | undefined) => ResolvedCaching;
113
+ /**
114
+ * The conversation with a rolling cache breakpoint on its LAST message — the
115
+ * agent-loop pattern Claude Code uses: every tool-calling round re-sends the
116
+ * rounds before it, and with the breakpoint moved to the newest message each
117
+ * request reads all of them from the cache and writes only the new tail.
118
+ * Earlier message breakpoints are removed (the SDK carries a round's messages
119
+ * into the next one), so a request holds at most two: system + newest —
120
+ * Anthropic rejects more than four.
121
+ */
122
+ declare const withRollingBreakpoint: <M extends {
123
+ providerOptions?: unknown;
124
+ }>(messages: M[], caching: ResolvedCaching) => M[];
125
+
126
+ /**
127
+ * Run-level token budgets. Every cap is cumulative over one `run()` and soft:
128
+ * it is checked between steps and at every tool-calling round inside a step,
129
+ * so a run stops at the next boundary after crossing it and then writes its
130
+ * final answer (synthesis still runs, bounded by `perCall.synthesizer`).
131
+ */
132
+ interface TokenLimits {
133
+ /** Cumulative input (prompt) tokens per run. */
134
+ maxInputTokens?: number;
135
+ /** Cumulative output tokens per run, thinking included. */
136
+ maxOutputTokens?: number;
137
+ /** Cumulative thinking tokens per run. */
138
+ maxReasoningTokens?: number;
139
+ /** Cumulative input + output tokens per run. */
140
+ maxTotalTokens?: number;
141
+ /** Max output tokens of ONE model call, per phase (wins over the legacy `budgets`). */
142
+ perCall?: {
143
+ planner?: number;
144
+ executor?: number;
145
+ replanner?: number;
146
+ synthesizer?: number;
147
+ compaction?: number;
148
+ };
149
+ }
150
+ type LimitKind = 'input' | 'output' | 'reasoning' | 'total' | 'tool-calls';
151
+ interface LimitBreach {
152
+ kind: LimitKind;
153
+ tokens: number;
154
+ cap: number;
155
+ }
156
+ /**
157
+ * The first cap the usage has reached, or undefined. Order: total, input,
158
+ * output, reasoning — the broadest budget is reported first. Pure.
159
+ */
160
+ declare const checkLimits: (usage: IUsage, limits: TokenLimits | undefined) => LimitBreach | undefined;
161
+ /** Raised by a tool call that would exceed `maxToolCalls`. */
162
+ declare class ToolBudgetError extends Error {
163
+ constructor(cap: number);
164
+ toJSON(): string;
165
+ }
166
+
41
167
  interface StoredMessage {
42
168
  role: 'system' | 'user' | 'assistant';
43
169
  content: string;
@@ -59,6 +185,86 @@ declare class MemoryStore implements ContextStore {
59
185
  clear(sessionId: string): Promise<void>;
60
186
  }
61
187
 
188
+ /**
189
+ * Context compaction. A model's window is finite and every token in it is paid
190
+ * for on every call, so long transcripts and long runs are folded into a
191
+ * summary: the oldest material is summarised by a model, the most recent is
192
+ * kept verbatim.
193
+ */
194
+ interface CompactionConfig {
195
+ /** Compact automatically before planning and between steps (default true). */
196
+ auto?: boolean;
197
+ /** The model's context window, in tokens (default 128 000). */
198
+ contextWindowTokens?: number;
199
+ /** Compact once the estimated context exceeds this (default: half the window). */
200
+ thresholdTokens?: number;
201
+ /** Transcript messages kept verbatim (default 4). */
202
+ keepRecentTurns?: number;
203
+ /** Executed steps kept verbatim in the run's trace (default 3). */
204
+ keepRecentSteps?: number;
205
+ /** Output cap of a summary call (default 1024). */
206
+ summaryMaxTokens?: number;
207
+ /** Cap on ONE tool result as the model sees it, in chars (default 20 000; 0 = no cap). */
208
+ maxToolOutputChars?: number;
209
+ /**
210
+ * Inside one step's tool loop: once its context passes this many tokens,
211
+ * replace the oldest tool results with one-line stubs (context editing;
212
+ * default: a quarter of the window; 0 = never).
213
+ */
214
+ clearToolResultsAfterTokens?: number;
215
+ /** Most recent tool results kept verbatim when clearing (default 3). */
216
+ keepToolResults?: number;
217
+ }
218
+ interface ResolvedCompaction {
219
+ auto: boolean;
220
+ contextWindowTokens: number;
221
+ thresholdTokens: number;
222
+ keepRecentTurns: number;
223
+ keepRecentSteps: number;
224
+ summaryMaxTokens: number;
225
+ maxToolOutputChars: number;
226
+ clearToolResultsAfterTokens: number;
227
+ keepToolResults: number;
228
+ }
229
+ declare const resolveCompaction: (c: CompactionConfig | undefined) => ResolvedCompaction;
230
+ /** Cheap, provider-independent token estimate (~4 chars per token). */
231
+ declare const estimateTokens: (text: string) => number;
232
+ declare const messageTokens: (msgs: StoredMessage[]) => number;
233
+ interface CompressOptions {
234
+ /** Compress once the transcript exceeds this many characters (0 = never). */
235
+ maxChars?: number;
236
+ /** Compress once the transcript's estimated tokens exceed this (wins over maxChars). */
237
+ thresholdTokens?: number;
238
+ /** How many most-recent messages to keep verbatim. */
239
+ keepRecent?: number;
240
+ /** Output cap of the summary call. */
241
+ summaryMaxTokens?: number;
242
+ /** Compact even when below the threshold (manual "compact now"). */
243
+ force?: boolean;
244
+ /** Time-box the summarisation call so it can never hang the caller. */
245
+ timeoutMs?: number;
246
+ abortSignal?: AbortSignal;
247
+ /** Receives the summary call's token usage. */
248
+ onUsage?: (usage: IUsage) => void;
249
+ }
250
+ /**
251
+ * When the transcript grows too long, summarise everything except the last
252
+ * `keepRecent` messages into a single system message (via the model), so the
253
+ * session stays within the model's context window. Returns the same array
254
+ * unchanged when no compression is needed; never throws.
255
+ */
256
+ declare const compressHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
257
+ /** Alias with the sibling package's name; same behaviour as compressHistory. */
258
+ declare const compactHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
259
+ /**
260
+ * Fold the oldest entries of a run's step log into one summary entry, keeping
261
+ * the last `keepRecent` verbatim. Returns the input unchanged when it fits the
262
+ * threshold or on any failure; never throws.
263
+ */
264
+ declare const compactSteps: (done: string[], model: LanguageModel, opts: CompressOptions & {
265
+ thresholdTokens: number;
266
+ }) => Promise<string[]>;
267
+
62
268
  /**
63
269
  * Leveled logging for the agent. The host passes a console-like sink and a
64
270
  * level; everything below the level is a no-op. Default: 'warn' onto the
@@ -151,6 +357,15 @@ declare const isProviderSpec: (m: unknown) => m is ProviderModelSpec;
151
357
  * out an exact JSON shape and (for the executor) include a tool catalogue;
152
358
  * the output is salvaged by parse.ts.
153
359
  *
360
+ * Layout matters for prompt caching: the SYSTEM part holds only what is stable
361
+ * for a whole run (role, skills, the planner's tool catalogue), the user
362
+ * prompt holds everything that changes (goal, state, history, progress), so a
363
+ * provider's prefix cache can reuse the system part across calls.
364
+ *
365
+ * The agent is autonomous by design: it plans tool use for anything the tools
366
+ * can do or look up, never asks the user for confirmation (consent is the
367
+ * host's `toolApproval` policy), and states assumptions instead of asking.
368
+ *
154
369
  * Override any builder via `BrowserAgentConfig.prompts`.
155
370
  */
156
371
  type ToolCallMode = 'native' | 'prompted';
@@ -168,6 +383,10 @@ interface PlannerPromptContext {
168
383
  role: string;
169
384
  content: string;
170
385
  }[];
386
+ /** "- name: description" index of the configured skills, when any. */
387
+ skills?: string;
388
+ /** The catalogue is condensed and the executor can search the rest (large catalogues). */
389
+ searchMode?: boolean;
171
390
  }
172
391
  interface ExecutorPromptContext {
173
392
  goal: string;
@@ -176,8 +395,15 @@ interface ExecutorPromptContext {
176
395
  index: number;
177
396
  total: number;
178
397
  toolCatalog: string;
398
+ /** Earlier steps of this run, each with its outcome and key data. */
179
399
  done: string[];
180
400
  mode: ToolCallMode;
401
+ /** "- name: description" index of the configured skills, when any. */
402
+ skills?: string;
403
+ /** Full instructions of the skills active in this run. */
404
+ activeSkills?: string;
405
+ /** The executor can call find_tools to activate more tools. */
406
+ searchMode?: boolean;
181
407
  }
182
408
  interface ReplannerPromptContext {
183
409
  goal: string;
@@ -185,11 +411,15 @@ interface ReplannerPromptContext {
185
411
  done: string[];
186
412
  remaining: string[];
187
413
  mode: ToolCallMode;
414
+ activeSkills?: string;
188
415
  }
189
416
  interface SynthesizerPromptContext {
190
417
  goal: string;
191
418
  state?: string;
192
419
  done: string[];
420
+ /** Excerpts of what the tools returned, for answering with real data. */
421
+ findings?: string[];
422
+ activeSkills?: string;
193
423
  }
194
424
  interface Prompts {
195
425
  planner(ctx: PlannerPromptContext): PromptParts;
@@ -228,6 +458,122 @@ declare class MemoryCredentialStore implements CredentialStore {
228
458
  deleteApiKey(ref: string): Promise<void>;
229
459
  }
230
460
 
461
+ /**
462
+ * Skills — reusable instruction bundles in the agentskills.io shape
463
+ * (`SKILL.md` with `name`/`description` frontmatter, a markdown body, optional
464
+ * bundled text files). Progressive disclosure: only the one-line index sits in
465
+ * the prompts; a skill's full instructions enter the context when the planner
466
+ * selects it or the executor loads it with `load_skill`.
467
+ */
468
+ interface Skill {
469
+ /** Stable id: lowercase letters, digits and dashes, 1–64 chars. */
470
+ name: string;
471
+ /** When to use it — the only part always shown to the model. */
472
+ description: string;
473
+ /** Full instructions (the markdown body of SKILL.md). */
474
+ content: string;
475
+ /** Bundled text resources, addressed by skill-relative POSIX paths. */
476
+ files?: {
477
+ path: string;
478
+ content: string;
479
+ }[];
480
+ }
481
+ /** Names of the built-in skill tools (reserved when skills are configured). */
482
+ declare const SKILL_TOOL_NAMES: readonly ["load_skill", "read_skill_file"];
483
+ /** Validate a skill definition and return it (throws a precise error). */
484
+ declare const defineSkill: (skill: Skill) => Skill;
485
+ /**
486
+ * Parse a SKILL.md document into a {@link Skill}. Frontmatter must provide
487
+ * `name` and `description`; the markdown body becomes `content`.
488
+ */
489
+ declare const parseSkillMarkdown: (markdown: string, files?: {
490
+ path: string;
491
+ content: string;
492
+ }[]) => Skill;
493
+ interface LoadSkillOptions {
494
+ /** Bundled files to fetch, relative to the SKILL.md URL. */
495
+ files?: string[];
496
+ fetch?: typeof fetch;
497
+ }
498
+ /** Fetch a SKILL.md (and optionally its bundled files) over HTTP. */
499
+ declare const loadSkillFromUrl: (url: string, opts?: LoadSkillOptions) => Promise<Skill>;
500
+ /** "- name: description" lines for the prompts. */
501
+ declare const renderSkillIndex: (skills: Skill[]) => string;
502
+ /** The full instructions of the active skills, within a total character budget. */
503
+ declare const renderActiveSkills: (skills: Skill[]) => string;
504
+ /**
505
+ * The built-in `load_skill` / `read_skill_file` tools. `onLoad` fires when a
506
+ * skill is loaded so the runner can keep it active for later steps.
507
+ */
508
+ declare const createSkillTools: (skills: Skill[], onLoad?: (skill: Skill) => void) => ToolSet;
509
+
510
+ /**
511
+ * Tool consent. Every tool call passes a gate that decides allow / ask / deny:
512
+ *
513
+ * - `autopilot` — run everything (default; explicit `rules` still apply);
514
+ * - `ask-writes` — run read-only tools, ask before anything that may change state;
515
+ * - `ask-all` — ask before every call;
516
+ * - `read-only` — run read-only tools, refuse the rest without asking.
517
+ *
518
+ * A tool is read-only when its MCP annotations say so (`readOnlyHint`) or the
519
+ * host marked it (`defineTool({ readOnly: true })` / `markReadOnly`). Unknown =
520
+ * may write: the safe assumption.
521
+ */
522
+ type ToolApprovalMode = 'autopilot' | 'ask-writes' | 'ask-all' | 'read-only';
523
+ type ToolPermission = 'allow' | 'ask' | 'deny';
524
+ declare const TOOL_APPROVAL_MODES: readonly ToolApprovalMode[];
525
+ interface ToolApprovalRequest {
526
+ /** Unique per request — echo it back from a UI. */
527
+ id: string;
528
+ toolName: string;
529
+ input: unknown;
530
+ readOnly: boolean;
531
+ step?: IPlanStep;
532
+ }
533
+ /**
534
+ * `true`/`false`, or an object. `remember: true` on an approval allows this
535
+ * tool for the rest of the agent's life ("always allow").
536
+ */
537
+ type ToolApprovalDecision = boolean | {
538
+ approved: boolean;
539
+ reason?: string;
540
+ remember?: boolean;
541
+ };
542
+ interface ToolApprovalConfig {
543
+ /** Default policy (default 'autopilot'). */
544
+ mode?: ToolApprovalMode;
545
+ /**
546
+ * Per-tool overrides by exact name or `*` glob, e.g. `{ 'github__delete_*': 'deny' }`.
547
+ * They win over the mode — an explicit 'ask' still asks under autopilot.
548
+ */
549
+ rules?: Record<string, ToolPermission>;
550
+ /** Resolves an approval request (a UI prompt, a policy service, …). */
551
+ onRequest?: (req: ToolApprovalRequest) => ToolApprovalDecision | Promise<ToolApprovalDecision>;
552
+ /** No decision within this many ms → deny. Default: wait indefinitely. */
553
+ timeoutMs?: number;
554
+ }
555
+ /** Raised by a denied tool call; recorded as a failed call the replanner sees. */
556
+ declare class ToolDeniedError extends Error {
557
+ constructor(reason?: string);
558
+ toJSON(): string;
559
+ }
560
+ /** Mark a tool as read-only so `ask-writes` / `read-only` let it through. Returns it. */
561
+ declare const markReadOnly: <T extends object>(tool: T, readOnly?: boolean) => T;
562
+ declare const isReadOnlyTool: (tool: Tool | undefined) => boolean;
563
+ /** The most specific matching rule: an exact name, else the longest glob. Pure. */
564
+ declare const matchRule: (rules: Record<string, ToolPermission> | undefined, toolName: string) => ToolPermission | undefined;
565
+ /**
566
+ * What the gate does for one call, before any human is involved. Order:
567
+ * remembered "always allow" → most specific rule → mode default. Pure.
568
+ */
569
+ declare const decideToolPermission: (opts: {
570
+ toolName: string;
571
+ readOnly: boolean;
572
+ mode: ToolApprovalMode;
573
+ rules?: Record<string, ToolPermission>;
574
+ remembered?: ReadonlySet<string>;
575
+ }) => ToolPermission;
576
+
231
577
  /**
232
578
  * The canonical tool shape is the AI SDK `Tool` — the same object the native
233
579
  * tool-calling path passes straight to `streamText({ tools })`, and the same
@@ -238,6 +584,7 @@ declare class MemoryCredentialStore implements CredentialStore {
238
584
  */
239
585
  type AgentTool = Tool & {
240
586
  promptHint?: string;
587
+ readOnly?: boolean;
241
588
  };
242
589
  /** A named collection of tools — a plain AI SDK ToolSet, usable directly. */
243
590
  type AgentToolSet = ToolSet;
@@ -259,8 +606,12 @@ type ReplanTrigger = 'failure' | 'always' | ((result: IStepResult) => boolean |
259
606
  * 'all' — the executor sees the full ToolSet on every step.
260
607
  * 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner
261
608
  * must populate them). Empty means a reasoning-only step.
609
+ * 'search' — for large catalogues: the executor starts with the step's
610
+ * suggestedTools plus a `find_tools` meta-tool that activates
611
+ * more on demand; the planner sees a condensed catalogue.
612
+ * 'auto' — 'all' up to `toolSearchThreshold` tools, 'search' above (default).
262
613
  */
263
- type ToolSelectionStrategy = 'all' | 'plan-narrowed';
614
+ type ToolSelectionStrategy = 'all' | 'plan-narrowed' | 'search' | 'auto';
264
615
  /** Per-phase generation budgets (max output tokens). */
265
616
  interface PhaseBudgets {
266
617
  planner?: number;
@@ -286,7 +637,14 @@ interface BrowserAgentConfig {
286
637
  excludedTools?: string[];
287
638
  /** Force native/prompted tool-calling; 'auto' picks per model (default 'auto'). */
288
639
  toolMode?: ToolMode;
640
+ /** How the executor sees the tool catalogue (default 'auto'). */
289
641
  toolSelectionStrategy?: ToolSelectionStrategy;
642
+ /** Catalogue size above which 'auto' switches to 'search' (default 40). */
643
+ toolSearchThreshold?: number;
644
+ /** Consent policy for tool calls: autopilot, ask before writes, ask always, read-only. */
645
+ toolApproval?: ToolApprovalConfig;
646
+ /** Reusable instruction bundles (SKILL.md) the planner/executor can pull in. */
647
+ skills?: Skill[];
290
648
  /** Prepended to every phase's system prompt. */
291
649
  systemPrompt?: string;
292
650
  /** Override any phase prompt builder. */
@@ -306,17 +664,47 @@ interface BrowserAgentConfig {
306
664
  maxStepsPerTask?: number;
307
665
  /** Cap on replanner "revise" decisions per run (default 2). */
308
666
  maxRevisions?: number;
667
+ /** Cap on tool calls per run (default: unlimited). */
668
+ maxToolCalls?: number;
669
+ /** Cap on the steps of one plan (default 8). */
670
+ maxPlanSteps?: number;
309
671
  /** Per-call timeout so a hang can't freeze a run (default 120000). */
310
672
  chatTimeoutMs?: number;
673
+ /** Legacy per-phase output caps; `limits.perCall` wins when both are set. */
311
674
  budgets?: PhaseBudgets;
675
+ /** Run-level token budgets (input / output / thinking / total) + per-call output caps. */
676
+ limits?: TokenLimits;
312
677
  temperature?: number;
678
+ /** Thinking for every stage: true, a level ('low'…'xhigh'), or { level, budgetTokens }. */
679
+ thinking?: ThinkingSetting;
680
+ /** Per-stage thinking; a stage entry wins over `thinking`. */
681
+ stageThinking?: Partial<Record<ThinkingStage, ThinkingSetting>>;
682
+ /**
683
+ * Whether the model accepts images. Default: inferred (`supportsImages`) —
684
+ * local/prompted models are text-only; unknown models are tried and a
685
+ * refusal is reported as ImagesNotSupportedError.
686
+ */
687
+ vision?: boolean;
688
+ /** Per-kind override of what the model takes as attachments (`images` wins over `vision`). */
689
+ inputs?: {
690
+ images?: boolean;
691
+ pdf?: boolean;
692
+ files?: boolean;
693
+ };
694
+ /** Provider prompt caching (default true): stable system prefixes + Anthropic breakpoints. */
695
+ promptCaching?: PromptCachingSetting;
696
+ /** Context compaction (auto + manual `agent.compact()`); see CompactionConfig. */
697
+ compaction?: CompactionConfig;
313
698
  /** Master switch for the replan phase (default true). */
314
699
  replan?: boolean;
315
700
  /** What triggers the replanner when it is on (default 'failure'). */
316
701
  replanAfter?: ReplanTrigger;
317
702
  /** Write a final natural-language summary (default true). */
318
703
  synthesize?: boolean;
319
- /** Compress stored history past this many chars (0 = off, default 12000). */
704
+ /**
705
+ * Legacy: compress stored history past this many chars after each run
706
+ * (0 = off). Used only when `compaction` is not set.
707
+ */
320
708
  compressAfterChars?: number;
321
709
  /** Verbosity: 'silent' | 'error' | 'warn' (default) | 'info' | 'debug'. */
322
710
  logLevel?: LogLevel;
@@ -328,22 +716,32 @@ interface ResolvedConfig {
328
716
  sessionId: string;
329
717
  toolMode: ToolMode;
330
718
  toolSelectionStrategy: ToolSelectionStrategy;
719
+ toolSearchThreshold: number;
331
720
  maxIterations: number;
332
721
  maxStepsPerTask: number;
333
722
  maxRevisions: number;
723
+ maxToolCalls: number;
724
+ maxPlanSteps: number;
334
725
  chatTimeoutMs: number;
335
- budgets: Required<PhaseBudgets>;
726
+ /** Effective per-call output caps (limits.perCall over budgets). */
727
+ budgets: Required<PhaseBudgets> & {
728
+ compaction: number;
729
+ };
730
+ limits: TokenLimits;
336
731
  temperature: number | undefined;
337
732
  replan: boolean;
338
733
  replanAfter: ReplanTrigger;
339
734
  synthesize: boolean;
340
735
  compressAfterChars: number;
736
+ compaction: ResolvedCompaction;
341
737
  logLevel: LogLevel;
342
738
  }
343
739
  declare const resolveConfig: (c: BrowserAgentConfig) => ResolvedConfig;
344
740
 
345
741
  type ReplanMode = 'continue' | 'revise' | 'finish';
346
742
  type Phase = 'plan' | 'execute' | 'replan' | 'synthesize';
743
+ /** Phases a `usage` event can be charged to: the four stages plus compaction and subagents. */
744
+ type UsagePhase = Phase | 'compact' | 'subagent';
347
745
  /**
348
746
  * Everything the agent does is streamed as a typed event so any UI (or none)
349
747
  * can render progress. The final answer arrives as a `final` event; there is no
@@ -381,6 +779,12 @@ type AgentEvent = {
381
779
  type: 'step.text-delta';
382
780
  step: IPlanStep;
383
781
  delta: string;
782
+ }
783
+ /** The executor model's streamed thoughts (thinking enabled + provider support). */
784
+ | {
785
+ type: 'step.reasoning-delta';
786
+ step: IPlanStep;
787
+ delta: string;
384
788
  } | {
385
789
  type: 'step.tool-call';
386
790
  step: IPlanStep;
@@ -403,18 +807,92 @@ type AgentEvent = {
403
807
  } | {
404
808
  type: 'final.text-delta';
405
809
  delta: string;
810
+ }
811
+ /** The synthesizer's streamed thoughts. */
812
+ | {
813
+ type: 'final.reasoning-delta';
814
+ delta: string;
406
815
  } | {
407
816
  type: 'final';
408
817
  text: string;
409
818
  } | {
410
819
  type: 'usage';
411
- phase: Phase;
820
+ phase: UsagePhase;
412
821
  usage: IUsage;
413
822
  } | {
414
823
  type: 'retry';
415
824
  phase: Phase;
416
825
  attempt: number;
417
826
  error: string;
827
+ }
828
+ /** A run-level limit was reached; the run stops executing and writes its answer. */
829
+ | {
830
+ type: 'budget.exceeded';
831
+ kind: LimitKind;
832
+ tokens: number;
833
+ cap: number;
834
+ }
835
+ /** Older context was summarised to fit the window. */
836
+ | {
837
+ type: 'context.compacted';
838
+ /** history = stored transcript; trace = the run's done steps; tool-results = stale results inside a step's tool loop. */
839
+ scope: 'history' | 'trace' | 'tool-results';
840
+ beforeTokens: number;
841
+ afterTokens: number;
842
+ }
843
+ /** A skill's instructions entered the context (picked by the planner, or loaded by a tool call). */
844
+ | {
845
+ type: 'skill.activated';
846
+ name: string;
847
+ by: 'plan' | 'tool';
848
+ }
849
+ /** find_tools activated more tools (large-catalogue search mode). */
850
+ | {
851
+ type: 'tools.discovered';
852
+ step?: IPlanStep;
853
+ query: string;
854
+ names: string[];
855
+ }
856
+ /** A tool call is waiting for the user's consent (see `toolApproval`). */
857
+ | {
858
+ type: 'tool.approval-requested';
859
+ id: string;
860
+ name: string;
861
+ input: unknown;
862
+ readOnly: boolean;
863
+ step?: IPlanStep;
864
+ }
865
+ /** A consent decision: from the user, or `automatic` (policy denial). */
866
+ | {
867
+ type: 'tool.approval-resolved';
868
+ id: string;
869
+ name: string;
870
+ approved: boolean;
871
+ reason?: string;
872
+ automatic: boolean;
873
+ } | {
874
+ type: 'subagent.start';
875
+ id: string;
876
+ name: string;
877
+ task: string;
878
+ }
879
+ /** An event of a running subagent, forwarded verbatim. */
880
+ | {
881
+ type: 'subagent.event';
882
+ id: string;
883
+ name: string;
884
+ event: AgentEvent;
885
+ } | {
886
+ type: 'subagent.complete';
887
+ id: string;
888
+ name: string;
889
+ text: string;
890
+ usage: IUsage;
891
+ } | {
892
+ type: 'subagent.error';
893
+ id: string;
894
+ name: string;
895
+ error: string;
418
896
  } | {
419
897
  type: 'stopped';
420
898
  } | {
@@ -424,11 +902,164 @@ type AgentEvent = {
424
902
  };
425
903
  type AgentEventHandler = (event: AgentEvent) => void;
426
904
 
905
+ /**
906
+ * Tool search for large catalogues. Several MCP servers easily add up to
907
+ * hundreds of tools — sending every schema on every call wastes the context
908
+ * window (and OpenAI rejects more than 128 tools outright). In 'search' mode
909
+ * the executor starts each step with a handful of tools and a `find_tools`
910
+ * meta-tool that activates more on demand.
911
+ */
912
+ interface ToolCatalogEntry {
913
+ name: string;
914
+ description: string;
915
+ /** The MCP server a tool came from ("server__tool" prefix), when known. */
916
+ server?: string;
917
+ readOnly?: boolean;
918
+ }
919
+ declare const FIND_TOOLS_NAME = "find_tools";
920
+ /** Build catalogue entries from a ToolSet ("server__tool" names yield a server). */
921
+ declare const toolCatalogOf: (tools: ToolSet) => ToolCatalogEntry[];
922
+ /** Lowercased word tokens; snake_case, kebab-case and camelCase are split. */
923
+ declare const tokenize: (s: string) => string[];
924
+ interface SearchToolsOptions {
925
+ /** Only tools from this server. */
926
+ server?: string;
927
+ /** Max results (default 8, capped at 20). */
928
+ limit?: number;
929
+ /** Names to leave out (e.g. already active). */
930
+ exclude?: ReadonlySet<string>;
931
+ }
932
+ /**
933
+ * Rank catalogue entries against a keyword query: each query term scores
934
+ * 3 for a name hit, 2 for a server hit and 1 for a description hit (prefix
935
+ * matching for terms of 3+ chars). Ties keep catalogue order; zero scores are
936
+ * dropped. Pure and deterministic — no embeddings, no model call.
937
+ */
938
+ declare const searchTools: (catalog: ToolCatalogEntry[], query: string, opts?: SearchToolsOptions) => ToolCatalogEntry[];
939
+ /**
940
+ * The planner's view of a large catalogue: grouped by server, short
941
+ * descriptions, within a character budget.
942
+ */
943
+ declare const renderSearchCatalog: (catalog: ToolCatalogEntry[], budget?: number) => string;
944
+ /**
945
+ * The `find_tools` meta-tool. `onFound` receives the matched names so the
946
+ * caller can activate them (native: prepareStep activeTools; prompted: the
947
+ * next round's catalogue).
948
+ */
949
+ declare const createFindToolsTool: (catalog: () => ToolCatalogEntry[], onFound: (query: string, names: string[]) => void, hintOf?: (name: string) => string | undefined) => Tool;
950
+
951
+ /**
952
+ * Attachments sent with a run: images, PDFs and other files the provider can
953
+ * read, given as bytes / base64 / a data URL — or as an http(s) URL, which
954
+ * providers that accept links (Gemini, Claude, OpenAI) fetch themselves and the
955
+ * AI SDK downloads for the rest (from the browser: subject to CORS).
956
+ */
957
+ interface RunFile {
958
+ /** Base64 (no prefix), a data URL ("data:image/png;base64,…"), raw bytes, or an http(s) URL. */
959
+ data: string | Uint8Array | URL;
960
+ /** e.g. "image/png", "application/pdf" — read from a data URL when omitted. */
961
+ mediaType?: string;
962
+ /** Shown in the transcript, in memory and in errors. */
963
+ name?: string;
964
+ }
965
+ /** An image attachment (same shape; kept as its own name for clarity). */
966
+ type RunImage = RunFile;
967
+ /** The kinds of attachment the agent reasons about separately. */
968
+ type AttachmentKind = 'image' | 'pdf' | 'file';
969
+ /** The media type of an attachment (declared, from a data URL, or from a URL's extension). */
970
+ declare const mediaTypeOf: (f: RunFile) => string | undefined;
971
+ declare const attachmentKind: (f: RunFile) => AttachmentKind;
972
+ /** Raised when attachments are sent to a model that cannot take them. */
973
+ declare class AttachmentsNotSupportedError extends Error {
974
+ readonly kind: AttachmentKind;
975
+ constructor(model: string, kind: AttachmentKind, detail?: string);
976
+ toJSON(): string;
977
+ }
978
+ /** The image flavour of {@link AttachmentsNotSupportedError}. */
979
+ declare class ImagesNotSupportedError extends AttachmentsNotSupportedError {
980
+ constructor(model: string, detail?: string);
981
+ }
982
+ /**
983
+ * An AI SDK file part (images included — the v7 SDK deprecates the separate
984
+ * image part). An http(s) URL is passed as a URL: providers that accept links
985
+ * fetch it themselves, and the SDK downloads it for the rest.
986
+ */
987
+ declare const toFilePart: (f: RunFile) => FilePart;
988
+ /** Back-compat name. */
989
+ declare const toImagePart: (f: RunFile) => FilePart;
990
+ /** Does a provider error look like a refusal of attachment input? */
991
+ declare const isAttachmentRefusal: (err: unknown) => boolean;
992
+ /** Back-compat name. */
993
+ declare const isImageRefusal: (err: unknown) => boolean;
994
+
995
+ /** The effective tool-selection strategy of a run ('auto' already resolved). */
996
+ type EffectiveToolStrategy = 'all' | 'plan-narrowed' | 'search';
997
+ /** Everything the phase functions (planner/executor/replanner/synthesizer) share. */
998
+ interface AgentContext {
999
+ config: ResolvedConfig;
1000
+ raw: BrowserAgentConfig;
1001
+ plannerModel: LanguageModel;
1002
+ executorModel: LanguageModel;
1003
+ synthesizerModel: LanguageModel;
1004
+ /** Tool-mode for the planner/replanner (from the planner model). */
1005
+ plannerMode: ToolCallMode;
1006
+ /** Tool-mode for the executor (from the executor model). */
1007
+ executorMode: ToolCallMode;
1008
+ /** The run's tools (host + MCP + built-ins), already wrapped by the consent gate. */
1009
+ tools: AgentToolSet;
1010
+ /** The catalogue as the planner sees it (condensed in search mode). */
1011
+ toolCatalog: string;
1012
+ prompts: Prompts;
1013
+ emit: (event: AgentEvent) => void;
1014
+ /** Leveled logger (config.logLevel over config.logger ?? console). */
1015
+ log: AgentLogger;
1016
+ signal?: AbortSignal;
1017
+ /** Current world state for grounding, or undefined when no describeState is configured. */
1018
+ state: () => Promise<string | undefined>;
1019
+ /** Session transcript loaded from memory BEFORE this run's goal was appended. */
1020
+ history?: StoredMessage[];
1021
+ /** Effective tool selection for this run. */
1022
+ strategy?: EffectiveToolStrategy;
1023
+ /** Prompt caching, resolved. */
1024
+ caching?: ResolvedCaching;
1025
+ /** All configured skills. */
1026
+ skills?: Skill[];
1027
+ /** Skills whose instructions are in play for this run. */
1028
+ activeSkills?: () => Skill[];
1029
+ /** Tools find_tools activated during this run (search mode). */
1030
+ discovered?: () => string[];
1031
+ /** Built-in tool names (find_tools, skill tools) — always callable. */
1032
+ builtinTools?: ReadonlySet<string>;
1033
+ /** Parameter hint of a tool, for prompted catalogues. */
1034
+ toolHint?: (name: string) => string | undefined;
1035
+ /** Run usage so far (for in-step budget checks). */
1036
+ usageSoFar?: () => IUsage;
1037
+ /** True when the run's limits are reached given extra usage spent inside the current call. */
1038
+ overBudget?: (extra: IUsage) => boolean;
1039
+ /** Tracks the step being executed (tools read it via their run context). */
1040
+ setCurrentStep?: (step: IPlanStep | undefined) => void;
1041
+ /** Images / PDFs / files the user sent with this run's goal. */
1042
+ images?: RunFile[];
1043
+ }
1044
+
427
1045
  interface RunOptions {
428
1046
  onEvent?: AgentEventHandler;
429
1047
  signal?: AbortSignal;
430
1048
  /** Override the config's sessionId for this run. */
431
1049
  sessionId?: string;
1050
+ /**
1051
+ * Images sent with the goal (pasted screenshots, photos). They reach the
1052
+ * planner, the executor and the synthesizer of a vision-capable model; a
1053
+ * model known not to take images ends the run at once with
1054
+ * ImagesNotSupportedError's message (see `capabilities.images`).
1055
+ */
1056
+ images?: RunImage[];
1057
+ /**
1058
+ * Other attachments: PDFs and files the provider reads natively, as data or
1059
+ * as an http(s) URL. Same rules as `images`, per kind (`capabilities.pdf`,
1060
+ * `capabilities.files`).
1061
+ */
1062
+ files?: RunFile[];
432
1063
  }
433
1064
  interface RunResult {
434
1065
  goal: string;
@@ -440,9 +1071,50 @@ interface RunResult {
440
1071
  applied: number;
441
1072
  stopped: boolean;
442
1073
  usage: IUsage;
1074
+ /** Skills whose instructions were active in this run. */
1075
+ skills: string[];
1076
+ /** The limit that stopped the run early, if any. */
1077
+ budgetExceeded?: LimitBreach;
1078
+ }
1079
+ interface CompactOptions {
1080
+ /** Session to compact (default: the config's sessionId). */
1081
+ sessionId?: string;
1082
+ signal?: AbortSignal;
1083
+ /** Compact even when below the threshold (default true for a manual call). */
1084
+ force?: boolean;
1085
+ }
1086
+ interface CompactResult {
1087
+ compacted: boolean;
1088
+ beforeTokens: number;
1089
+ afterTokens: number;
1090
+ usage: IUsage;
443
1091
  }
444
1092
  interface Agent {
445
1093
  run(goal: string, opts?: RunOptions): Promise<RunResult>;
1094
+ /** Summarise the stored transcript (needs `memory`); returns the before/after size. */
1095
+ compact(opts?: CompactOptions): Promise<CompactResult>;
1096
+ /** Switch the consent policy — e.g. the "autopilot" toggle. Applies to the next tool call. */
1097
+ setToolApprovalMode(mode: ToolApprovalMode): void;
1098
+ readonly toolApprovalMode: ToolApprovalMode;
1099
+ /** The tool catalogue (host + MCP tools after filtering). */
1100
+ listTools(): ToolCatalogEntry[];
1101
+ /** The effective tool selection ('auto' resolved by catalogue size). */
1102
+ readonly toolStrategy: EffectiveToolStrategy;
1103
+ /** Configured skills (name + description). */
1104
+ readonly skills: {
1105
+ name: string;
1106
+ description: string;
1107
+ }[];
1108
+ /**
1109
+ * What the executor model can take, per attachment kind: true / false, or
1110
+ * undefined when unknown (the run tries, and a provider refusal becomes a
1111
+ * clear error).
1112
+ */
1113
+ readonly capabilities: {
1114
+ images: boolean | undefined;
1115
+ pdf: boolean | undefined;
1116
+ files: boolean | undefined;
1117
+ };
446
1118
  /** The resolved models, for hosts that want to reuse them (e.g. warm-up). */
447
1119
  readonly models: {
448
1120
  planner: LanguageModel;
@@ -474,12 +1146,13 @@ declare const PlanSchema: z.ZodObject<{
474
1146
  expectedOutcome: z.ZodOptional<z.ZodString>;
475
1147
  suggestedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
476
1148
  }, z.core.$strip>>;
1149
+ skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
477
1150
  }, z.core.$strip>;
478
1151
  declare const ReplanSchema: z.ZodObject<{
479
1152
  decision: z.ZodEnum<{
1153
+ finish: "finish";
480
1154
  continue: "continue";
481
1155
  revise: "revise";
482
- finish: "finish";
483
1156
  }>;
484
1157
  reason: z.ZodString;
485
1158
  plan: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -487,43 +1160,22 @@ declare const ReplanSchema: z.ZodObject<{
487
1160
  type PlanShape = z.infer<typeof PlanSchema>;
488
1161
  type ReplanShape = z.infer<typeof ReplanSchema>;
489
1162
 
490
- /** Everything the phase functions (planner/executor/replanner/synthesizer) share. */
491
- interface AgentContext {
492
- config: ResolvedConfig;
493
- raw: BrowserAgentConfig;
494
- plannerModel: LanguageModel;
495
- executorModel: LanguageModel;
496
- synthesizerModel: LanguageModel;
497
- /** Tool-mode for the planner/replanner (from the planner model). */
498
- plannerMode: ToolCallMode;
499
- /** Tool-mode for the executor (from the executor model). */
500
- executorMode: ToolCallMode;
501
- tools: AgentToolSet;
502
- toolCatalog: string;
503
- prompts: Prompts;
504
- emit: (event: AgentEvent) => void;
505
- /** Leveled logger (config.logLevel over config.logger ?? console). */
506
- log: AgentLogger;
507
- signal?: AbortSignal;
508
- /** Current world state for grounding, or undefined when no describeState is configured. */
509
- state: () => Promise<string | undefined>;
510
- /** Session transcript loaded from memory BEFORE this run's goal was appended. */
511
- history?: StoredMessage[];
1163
+ interface PlanOutcome {
1164
+ plan: IPlan;
1165
+ usage: IUsage;
1166
+ /** Names of configured skills the planner picked (validated). */
1167
+ skills: string[];
512
1168
  }
513
-
514
1169
  /**
515
1170
  * Build the initial plan. Native mode uses generateObject(PlanSchema); prompted
516
1171
  * mode salvages `{ reply, plan }` from plain text. Native failures (a weak model
517
1172
  * that can't satisfy the schema) fall back to the prompted parse rather than
518
1173
  * throwing, so the run degrades gracefully. An empty `steps` list signals the
519
- * runner to answer directly (greeting / question / unclear).
1174
+ * runner to answer directly (greeting / small talk).
520
1175
  */
521
1176
  declare const createPlan: (ctx: AgentContext, goal: string,
522
1177
  /** Extra instruction appended to the goal (used by the empty-plan retry). */
523
- nudge?: string) => Promise<{
524
- plan: IPlan;
525
- usage: IUsage;
526
- }>;
1178
+ nudge?: string) => Promise<PlanOutcome>;
527
1179
 
528
1180
  /**
529
1181
  * Split the executor's reply into a clean summary and a structural `blocked`
@@ -539,6 +1191,7 @@ declare const splitBlocker: (raw: string) => {
539
1191
  declare const executeStep: (ctx: AgentContext, goal: string, step: IPlanStep, index: number, total: number, done: string[]) => Promise<{
540
1192
  result: IStepResult;
541
1193
  usage: IUsage;
1194
+ stoppedByBudget?: boolean;
542
1195
  }>;
543
1196
  /**
544
1197
  * The replanner runs when a step was blocked or a tool call failed and stayed
@@ -583,6 +1236,8 @@ declare const normalizeSteps: (arr: unknown, cap?: number) => string[];
583
1236
  interface PlannerResult {
584
1237
  reply: string;
585
1238
  plan: string[];
1239
+ /** Skill names the planner picked (empty when none / not asked). */
1240
+ skills: string[];
586
1241
  }
587
1242
  declare const parsePlannerResponse: (raw: string) => PlannerResult;
588
1243
  interface ExecutorResult {
@@ -615,17 +1270,257 @@ interface ReplanOutcome {
615
1270
  declare const decideReplan: (ctx: AgentContext, goal: string, done: string[], remaining: string[]) => Promise<ReplanOutcome>;
616
1271
 
617
1272
  /**
618
- * Write the final natural-language summary of what the run accomplished,
619
- * streaming it as `final.text-delta` events. Plain text only (parsePlainText
620
- * strips any stray JSON; deltas are suppressed entirely when the model drifts
621
- * into JSON, so raw structure never reaches a UI). Falls back to a default
622
- * sentence if the model returns nothing usable.
1273
+ * Write the final natural-language answer of the run, streaming it as
1274
+ * `final.text-delta` events (and thoughts as `final.reasoning-delta`). Plain
1275
+ * text only (parsePlainText strips any stray JSON; deltas are suppressed
1276
+ * entirely when the model drifts into JSON, so raw structure never reaches a
1277
+ * UI). Falls back to a default sentence if the model returns nothing usable.
623
1278
  */
624
- declare const synthesizeAnswer: (ctx: AgentContext, goal: string, done: string[]) => Promise<{
1279
+ declare const synthesizeAnswer: (ctx: AgentContext, goal: string, done: string[],
1280
+ /** Excerpts of what the tools returned — the data the answer is made of. */
1281
+ findings?: string[]) => Promise<{
625
1282
  text: string;
626
1283
  usage: IUsage;
627
1284
  }>;
628
1285
 
1286
+ /**
1287
+ * The wire protocol between a parent agent and a subagent running in a Web
1288
+ * Worker. Every message is structured-cloneable; anything that is not (an
1289
+ * Error, a function in a tool output) is flattened before it is posted.
1290
+ */
1291
+ /** A host tool the worker can call back into the main thread for. */
1292
+ interface ProxiedToolSpec {
1293
+ name: string;
1294
+ description: string;
1295
+ /** JSON Schema of the tool input. */
1296
+ inputSchema: unknown;
1297
+ readOnly?: boolean;
1298
+ }
1299
+ type ParentToWorker = {
1300
+ type: 'run';
1301
+ task: string;
1302
+ /** Serializable agent config (model is a ProviderModelSpec). */
1303
+ config: Record<string, unknown>;
1304
+ proxied: ProxiedToolSpec[];
1305
+ } | {
1306
+ type: 'abort';
1307
+ } | {
1308
+ type: 'tool-result';
1309
+ callId: string;
1310
+ ok: boolean;
1311
+ output: unknown;
1312
+ };
1313
+ type WorkerToParent = {
1314
+ type: 'event';
1315
+ event: AgentEvent;
1316
+ } | {
1317
+ type: 'tool-call';
1318
+ callId: string;
1319
+ name: string;
1320
+ input: unknown;
1321
+ } | {
1322
+ type: 'done';
1323
+ text: string;
1324
+ usage: IUsage;
1325
+ steps: number;
1326
+ } | {
1327
+ type: 'error';
1328
+ error: string;
1329
+ };
1330
+ /**
1331
+ * The slice of the Worker / DedicatedWorkerGlobalScope / MessagePort API we
1332
+ * use. Structural, so a real `Worker`, a worker's `self`, or a MessageChannel
1333
+ * port (tests) all fit.
1334
+ */
1335
+ interface MessageEndpoint {
1336
+ postMessage(message: unknown): void;
1337
+ addEventListener(type: string, listener: (ev: any) => void): void;
1338
+ removeEventListener?(type: string, listener: (ev: any) => void): void;
1339
+ }
1340
+ /** A worker as the parent sees it. */
1341
+ interface WorkerLike extends MessageEndpoint {
1342
+ terminate?(): void;
1343
+ }
1344
+
1345
+ /** The serializable slice of BrowserAgentConfig a worker subagent can be built from. */
1346
+ type SubagentWorkerConfig = Pick<BrowserAgentConfig, 'clientName' | 'systemPrompt' | 'availableTools' | 'excludedTools' | 'toolMode' | 'toolSelectionStrategy' | 'toolSearchThreshold' | 'skills' | 'maxIterations' | 'maxStepsPerTask' | 'maxRevisions' | 'maxToolCalls' | 'maxPlanSteps' | 'chatTimeoutMs' | 'budgets' | 'limits' | 'temperature' | 'thinking' | 'stageThinking' | 'promptCaching' | 'compaction' | 'replan' | 'synthesize' | 'logLevel'> & {
1347
+ /** The child's model, resolved inside the worker (by its `resolveModel`, or the registry). */
1348
+ model: ProviderModelSpec;
1349
+ /** Consent policy inside the worker — mode and rules only (no callbacks cross threads). */
1350
+ toolApproval?: {
1351
+ mode?: 'autopilot' | 'read-only';
1352
+ rules?: Record<string, 'allow' | 'deny'>;
1353
+ };
1354
+ };
1355
+ interface SubagentToolOptions {
1356
+ /** Label for events and logs (the tool's KEY in your ToolSet is up to you). */
1357
+ name: string;
1358
+ /** What the subagent is for — the parent model reads this to decide when to delegate. */
1359
+ description: string;
1360
+ /** In-process subagent: a full config (models, tools, …) for the child agent. */
1361
+ config?: BrowserAgentConfig;
1362
+ /**
1363
+ * Worker subagent: builds a fresh Worker per delegated task, e.g.
1364
+ * `() => new Worker(new URL('./agent.worker.ts', import.meta.url), { type: 'module' })`.
1365
+ * The worker module calls `serveSubagentWorker()`.
1366
+ */
1367
+ worker?: () => WorkerLike;
1368
+ /** Worker subagent: the child's serializable config. */
1369
+ workerConfig?: SubagentWorkerConfig;
1370
+ /**
1371
+ * Resolves `workerConfig.model.credentialRef` in the main thread; the key is
1372
+ * posted to the worker for that one task and never stored there.
1373
+ */
1374
+ credentials?: CredentialStore;
1375
+ /**
1376
+ * Host tools the subagent may call. In-process they are merged into the
1377
+ * child's tools; with a worker they stay in the main thread and are called
1378
+ * over RPC. Either way each call passes the PARENT's consent gate.
1379
+ */
1380
+ tools?: ToolSet;
1381
+ /** Parallel delegations allowed at once (default 4); extra calls queue. */
1382
+ maxConcurrent?: number;
1383
+ /** Give up on one delegated task after this many ms (default: none). */
1384
+ timeoutMs?: number;
1385
+ /** Cap on the text handed back to the parent model (default 8000 chars). */
1386
+ outputMaxChars?: number;
1387
+ /** Mark the tool read-only for the parent's consent gate (default false). */
1388
+ readOnly?: boolean;
1389
+ }
1390
+ /**
1391
+ * Expose a subagent as a tool: the parent delegates `{ task }`, the child runs
1392
+ * its own plan → execute → synthesize loop — in this thread, or isolated in a
1393
+ * Web Worker — and its final answer comes back as the tool result. Several
1394
+ * delegations in one model step run in parallel (bounded by `maxConcurrent`).
1395
+ *
1396
+ * The parent sees `subagent.start` / `subagent.event` / `subagent.complete` /
1397
+ * `subagent.error` events, and the child's tokens are charged to the parent
1398
+ * run (a `usage` event with phase 'subagent'), so the parent's limits apply.
1399
+ */
1400
+ declare const createSubagentTool: (opts: SubagentToolOptions) => AgentTool;
1401
+
1402
+ interface ServeSubagentOptions {
1403
+ /**
1404
+ * Build the child's model from its spec. Pass one when your bundler can't
1405
+ * resolve the core's dynamic provider imports inside a worker (Vite): import
1406
+ * the provider factories statically in the worker module and build here.
1407
+ * Default: the core registry (dynamic import of the optional peer).
1408
+ */
1409
+ resolveModel?: (spec: ProviderModelSpec) => LanguageModel | Promise<LanguageModel>;
1410
+ /**
1411
+ * Worker-local tools — they run in the worker thread, so CPU-heavy work
1412
+ * (search, parsing, simulation) never blocks the page.
1413
+ */
1414
+ tools?: ToolSet;
1415
+ /** The worker's message endpoint (default: the worker global scope). */
1416
+ scope?: MessageEndpoint;
1417
+ }
1418
+ /**
1419
+ * Serve subagent tasks inside a Web Worker. Call it once at the top of your
1420
+ * worker module; the parent's `createSubagentTool({ worker })` posts a task,
1421
+ * this builds a child agent (worker-local tools + the parent's host tools
1422
+ * proxied over RPC), runs it, streams its events back and answers with the
1423
+ * final text.
1424
+ *
1425
+ * ```ts
1426
+ * // agent.worker.ts
1427
+ * import { serveSubagentWorker } from '@dudko.dev/agent-web'
1428
+ * import { createGoogleGenerativeAI } from '@ai-sdk/google'
1429
+ * serveSubagentWorker({
1430
+ * resolveModel: (spec) => createGoogleGenerativeAI({ apiKey: spec.apiKey })(spec.model),
1431
+ * tools: { heavy_search: defineTool({ … }) },
1432
+ * })
1433
+ * ```
1434
+ */
1435
+ declare const serveSubagentWorker: (opts?: ServeSubagentOptions) => void;
1436
+
1437
+ /**
1438
+ * A small virtual file system for the browser — the agent's (and the user's)
1439
+ * workspace: attachments the user drops in, reports the agent writes, images
1440
+ * pasted into the chat. Persistent in IndexedDB by default, in-memory on
1441
+ * request (tests, private mode). Paths are POSIX-like and always absolute
1442
+ * ("/notes/todo.md"); there are no real directories — a "directory" is a path
1443
+ * prefix.
1444
+ */
1445
+ interface VirtualFile {
1446
+ path: string;
1447
+ /** Text, or base64 for binary content (see `encoding`). */
1448
+ content: string;
1449
+ encoding: 'utf8' | 'base64';
1450
+ mimeType: string;
1451
+ /** Size of the decoded content in bytes. */
1452
+ size: number;
1453
+ updatedAt: number;
1454
+ }
1455
+ /** A listing entry (no content). */
1456
+ type VirtualFileInfo = Omit<VirtualFile, 'content'>;
1457
+ interface VirtualFileSystemOptions {
1458
+ /** Keep files in memory only (default false: IndexedDB). */
1459
+ memory?: boolean;
1460
+ /** IndexedDB database name, forwarded to the shared owner (default 'agent-web'). */
1461
+ dbName?: string;
1462
+ /** Isolates several file systems in one database (default 'default'). */
1463
+ namespace?: string;
1464
+ /** Refuse a single file larger than this many bytes (default 10 MB). */
1465
+ maxFileBytes?: number;
1466
+ }
1467
+ type VfsListener = (change: {
1468
+ type: 'write' | 'delete';
1469
+ path: string;
1470
+ }) => void;
1471
+ /** A best-effort MIME type from a file name. */
1472
+ declare const mimeFromPath: (path: string) => string;
1473
+ /** True for MIME types the agent can read as text. */
1474
+ declare const isTextMime: (mime: string) => boolean;
1475
+ /**
1476
+ * Normalise a path: absolute, forward slashes, no "." / ".." / empty segments.
1477
+ * Throws on a path that escapes the root.
1478
+ */
1479
+ declare const normalizePath: (input: string) => string;
1480
+ /** Base64 of bytes, chunked so a large file can't blow the call stack. */
1481
+ declare const bytesToBase64: (bytes: Uint8Array) => string;
1482
+ declare class VirtualFileSystem {
1483
+ private readonly memory?;
1484
+ private readonly dbName?;
1485
+ private readonly ns;
1486
+ private readonly maxFileBytes;
1487
+ private readonly listeners;
1488
+ constructor(opts?: VirtualFileSystemOptions);
1489
+ private key;
1490
+ /** Subscribe to writes and deletes (e.g. to refresh a file list). Returns an unsubscribe. */
1491
+ onChange(listener: VfsListener): () => void;
1492
+ private notify;
1493
+ write(path: string, content: string | Uint8Array, opts?: {
1494
+ mimeType?: string;
1495
+ encoding?: VirtualFile['encoding'];
1496
+ }): Promise<VirtualFileInfo>;
1497
+ /** Store a data URL ("data:image/png;base64,…") as a file. */
1498
+ writeDataUrl(path: string, dataUrl: string): Promise<VirtualFileInfo>;
1499
+ read(path: string): Promise<VirtualFile | undefined>;
1500
+ /** The file as a data URL (for <img src>, downloads). */
1501
+ readDataUrl(path: string): Promise<string | undefined>;
1502
+ delete(path: string): Promise<boolean>;
1503
+ /** Files under a prefix ("/" = all), sorted by path. */
1504
+ list(prefix?: string): Promise<VirtualFileInfo[]>;
1505
+ /** Remove every file (of this namespace). */
1506
+ clear(): Promise<void>;
1507
+ }
1508
+
1509
+ interface FileToolsOptions {
1510
+ /** Tool-name prefix (default 'fs_' → fs_list, fs_read, fs_write, fs_delete). */
1511
+ prefix?: string;
1512
+ /** Mount only the read tools (default false). */
1513
+ readOnly?: boolean;
1514
+ /** Cap on the text fs_read returns (default 50 000 chars; the rest is cut with a marker). */
1515
+ maxReadChars?: number;
1516
+ }
1517
+ /**
1518
+ * Tools that give the agent the virtual file system: list, read, write and
1519
+ * delete. Listing and reading are marked read-only, so the `ask-writes`
1520
+ * consent mode lets them through and asks before writes and deletes.
1521
+ */
1522
+ declare const createFileTools: (vfs: VirtualFileSystem, opts?: FileToolsOptions) => ToolSet;
1523
+
629
1524
  /**
630
1525
  * Resolve one stage to either a ready model or a fully-resolved spec, layering
631
1526
  * an optional override on the base:
@@ -716,6 +1611,19 @@ declare const supportsStructuredOutput: (p: ProviderType) => boolean;
716
1611
  * - `xai` / `deepseek`: unreliable from the browser; prefer a proxy.
717
1612
  */
718
1613
  declare const directBrowserOk: (p: ProviderType) => boolean;
1614
+ /**
1615
+ * Whether a model accepts image input: `true` (expected to), `false` (known
1616
+ * not to — local runtimes, DeepSeek, text-only families), or `undefined`
1617
+ * (unknown, e.g. an OpenAI-compatible server — the agent tries and turns a
1618
+ * provider refusal into a clear error). Override per agent with `vision`.
1619
+ */
1620
+ declare const supportsImages: (model: unknown) => boolean | undefined;
1621
+ /**
1622
+ * Whether a model reads PDF files natively: `false` for local runtimes and
1623
+ * text-only families, `true` for Gemini, Claude and OpenAI's vision models,
1624
+ * `undefined` when unknown (tried; a refusal becomes a clear error).
1625
+ */
1626
+ declare const supportsPdf: (model: unknown) => boolean | undefined;
719
1627
 
720
1628
  /**
721
1629
  * Fetch (or lazily create) the vault's AES-GCM key. The key is generated
@@ -747,6 +1655,7 @@ interface AgentWebDBOptions {
747
1655
  declare const KEYS_STORE = "keys";
748
1656
  declare const SECRETS_STORE = "secrets";
749
1657
  declare const SESSIONS_STORE = "sessions";
1658
+ declare const FILES_STORE = "files";
750
1659
  /**
751
1660
  * The single owner of the IndexedDB database. Every persistent store — the
752
1661
  * non-extractable crypto key, encrypted secrets, and session transcripts —
@@ -758,12 +1667,17 @@ declare const openAgentWebDB: (opts?: AgentWebDBOptions) => Promise<IDBPDatabase
758
1667
 
759
1668
  /** Options shared by the low-level generation helpers. Provide `prompt` OR `messages`. */
760
1669
  interface GenerateOptions {
761
- system?: string;
1670
+ /** The system prompt — a string, or a SystemModelMessage (e.g. with a cache breakpoint). */
1671
+ system?: string | SystemModelMessage;
762
1672
  prompt?: string;
763
1673
  messages?: ModelMessage[];
764
1674
  tools?: ToolSet;
765
1675
  maxOutputTokens?: number;
766
1676
  temperature?: number;
1677
+ /** Portable thinking level (see `resolveThinking`). */
1678
+ reasoning?: ThinkingLevel;
1679
+ /** Provider-keyed options (thinking budgets, cache keys, …). */
1680
+ providerOptions?: ProviderOptionsMap;
767
1681
  abortSignal?: AbortSignal;
768
1682
  /** Time-box the call; combined with `abortSignal` (0/undefined = no timeout). */
769
1683
  timeoutMs?: number;
@@ -785,36 +1699,90 @@ declare const stream: (model: LanguageModel, opts?: GenerateOptions) => ReturnTy
785
1699
  */
786
1700
  declare const generateStructured: <OBJECT>(model: LanguageModel, schema: ZodType<OBJECT>, opts?: GenerateOptions) => Promise<ai.GenerateObjectResult<(OBJECT extends string ? "enum" : "object") extends infer T ? T extends (OBJECT extends string ? "enum" : "object") ? T extends "array" ? OBJECT[] : OBJECT : never : never>>;
787
1701
 
1702
+ /**
1703
+ * Context editing inside one tool loop — what Anthropic's
1704
+ * `clear_tool_uses` and Claude Code's micro-compaction do: once the loop's
1705
+ * conversation grows past `triggerTokens`, the OLDEST tool results are replaced
1706
+ * with a one-line stub (the calls themselves stay, so the model knows what it
1707
+ * did and can call again), keeping the `keep` most recent results verbatim.
1708
+ *
1709
+ * Clearing is sticky — a result cleared once stays cleared — so the prefix the
1710
+ * provider cached does not flip back and forth between rounds.
1711
+ */
1712
+ interface ToolResultClearing {
1713
+ /** Clear once the loop's estimated tokens exceed this. */
1714
+ triggerTokens: number;
1715
+ /** Most recent tool results kept verbatim (default 3). */
1716
+ keep?: number;
1717
+ }
1718
+ interface ClearedInfo {
1719
+ cleared: number;
1720
+ beforeTokens: number;
1721
+ afterTokens: number;
1722
+ }
1723
+ /**
1724
+ * A stateful clearer for one loop: call it with each round's messages; it
1725
+ * returns the (possibly) edited copy and reports what it newly cleared.
1726
+ */
1727
+ declare const createToolResultClearer: (opts: ToolResultClearing, onCleared?: (info: ClearedInfo) => void) => ((messages: ModelMessage[]) => ModelMessage[]);
1728
+
788
1729
  interface ToolLoopCallbacks {
789
1730
  onTextDelta?: (delta: string) => void;
1731
+ /** The model's streamed thoughts (native mode, thinking enabled). */
1732
+ onReasoningDelta?: (delta: string) => void;
790
1733
  onToolCall?: (name: string, input: unknown) => void;
791
1734
  onToolResult?: (name: string, output: unknown, ok: boolean) => void;
1735
+ /** Older tool results were replaced with stubs (see `clearToolResults`). */
1736
+ onToolResultsCleared?: (info: ClearedInfo) => void;
792
1737
  }
793
1738
  interface ToolLoopOptions {
794
1739
  /** 'native' = SDK function-calling; 'prompted' = parse JSON out of plain text. */
795
1740
  mode: 'native' | 'prompted';
796
- system?: string;
1741
+ system?: string | SystemModelMessage;
797
1742
  prompt?: string;
798
1743
  messages?: ModelMessage[];
799
1744
  /** In native mode: the callable tools. In prompted mode: used to dispatch salvaged calls. */
800
1745
  tools: ToolSet;
801
1746
  /**
802
- * Restrict callable tools to these names (plan-narrowed). Native mode passes
803
- * them to the SDK's `activeTools`; prompted mode bounds `dispatch` to them.
1747
+ * Restrict callable tools to these names (plan-narrowed / search). Native mode
1748
+ * passes them to the SDK's `activeTools`; prompted mode bounds `dispatch` to
1749
+ * them. A function is re-read before every round, so a tool that activates
1750
+ * others (find_tools) takes effect on the next round.
1751
+ */
1752
+ activeTools?: string[] | (() => string[]);
1753
+ /**
1754
+ * Prompted mode: render catalogue lines for tools that became active during
1755
+ * the call, so the model learns their names and parameters.
804
1756
  */
805
- activeTools?: string[];
1757
+ describeTools?: (names: string[]) => string;
806
1758
  /** Cap on tool-calling rounds within this call, in both modes (default 4). */
807
1759
  maxSteps?: number;
1760
+ /**
1761
+ * Checked with the usage of the rounds so far, at every round boundary —
1762
+ * return true to stop (e.g. a run-level token budget is spent).
1763
+ */
1764
+ shouldStop?: (usageSoFar: IUsage) => boolean;
808
1765
  maxOutputTokens?: number;
809
1766
  temperature?: number;
1767
+ reasoning?: ThinkingLevel;
1768
+ providerOptions?: ProviderOptionsMap;
810
1769
  abortSignal?: AbortSignal;
811
1770
  timeoutMs?: number;
1771
+ /**
1772
+ * Prompt caching: with it enabled, every round moves a cache breakpoint to
1773
+ * the newest message, so the rounds before it are read from the cache.
1774
+ */
1775
+ caching?: ResolvedCaching;
1776
+ /** Clear the oldest tool results once the loop's context grows past a threshold. */
1777
+ clearToolResults?: ToolResultClearing;
812
1778
  callbacks?: ToolLoopCallbacks;
813
1779
  }
814
1780
  interface ToolLoopResult {
815
1781
  text: string;
816
1782
  toolCalls: IToolCall[];
817
1783
  usage: IUsage;
1784
+ /** True when `shouldStop` cut the call short. */
1785
+ stoppedByBudget?: boolean;
818
1786
  }
819
1787
  /**
820
1788
  * Run tool-calling in whichever mode the model needs, returning a normalised
@@ -826,12 +1794,24 @@ interface ToolLoopResult {
826
1794
  */
827
1795
  declare const runToolLoop: (model: LanguageModel, opts: ToolLoopOptions) => Promise<ToolLoopResult>;
828
1796
 
829
- /** Normalise the AI SDK usage shape (fields can be undefined) into IUsage. */
830
- declare const normalizeUsage: (u?: {
1797
+ /** The AI SDK usage shape, every field optional (providers omit what they don't report). */
1798
+ interface SdkUsageLike {
831
1799
  inputTokens?: number;
832
1800
  outputTokens?: number;
833
1801
  totalTokens?: number;
834
- }) => IUsage;
1802
+ inputTokenDetails?: {
1803
+ cacheReadTokens?: number;
1804
+ cacheWriteTokens?: number;
1805
+ };
1806
+ outputTokenDetails?: {
1807
+ reasoningTokens?: number;
1808
+ };
1809
+ /** Pre-v6 flat fields, still emitted by some providers. */
1810
+ reasoningTokens?: number;
1811
+ cachedInputTokens?: number;
1812
+ }
1813
+ /** Normalise the AI SDK usage shape (fields can be undefined) into IUsage. */
1814
+ declare const normalizeUsage: (u?: SdkUsageLike) => IUsage;
835
1815
 
836
1816
  /**
837
1817
  * Define a host tool. Thin wrapper over the AI SDK `tool()`: pass a
@@ -846,7 +1826,9 @@ declare const normalizeUsage: (u?: {
846
1826
  *
847
1827
  * Optionally add `promptHint` — a short parameter hint like
848
1828
  * "{ text: string, x?: number }" — which the prompted/salvage path shows to
849
- * weak local models that can't do native function-calling.
1829
+ * weak local models that can't do native function-calling — and `readOnly:
1830
+ * true` for tools that never change state (the `ask-writes` and `read-only`
1831
+ * approval modes let those run without asking).
850
1832
  *
851
1833
  * @example
852
1834
  * const tools = {
@@ -860,14 +1842,16 @@ declare const normalizeUsage: (u?: {
860
1842
  */
861
1843
  declare const defineTool: <INPUT = unknown, OUTPUT = unknown>(config: Tool<INPUT, OUTPUT> & {
862
1844
  promptHint?: string;
1845
+ readOnly?: boolean;
863
1846
  }) => AgentTool;
864
1847
 
865
1848
  /**
866
1849
  * Render a ToolSet into a plain-text catalogue for the prompted/salvage path:
867
1850
  * `- name(hint): description`. The hint comes from `defineTool({ promptHint })`
868
- * when present; weak local models lean on it to fill args correctly.
1851
+ * when present, else from `hintOf` (the agent derives one from the tool's JSON
1852
+ * schema, so MCP tools get one too); weak local models lean on it to fill args.
869
1853
  */
870
- declare const renderCatalog: (tools: AgentToolSet) => string;
1854
+ declare const renderCatalog: (tools: AgentToolSet, hintOf?: (name: string) => string | undefined) => string;
871
1855
  interface DispatchContext {
872
1856
  abortSignal?: AbortSignal;
873
1857
  messages?: ModelMessage[];
@@ -890,6 +1874,39 @@ declare const dispatch: (action: RawAction, tools: ToolSet, ctx?: DispatchContex
890
1874
  */
891
1875
  declare const selectToolMode: (model: LanguageModel, mode?: ToolMode) => "native" | "prompted";
892
1876
 
1877
+ /**
1878
+ * What a tool's `execute` can reach of the run that called it, passed as
1879
+ * `options.agentRun`. Subagent tools use it to stream nested events and to
1880
+ * charge their usage to the parent run.
1881
+ */
1882
+ interface ToolRunContext {
1883
+ emit: (event: AgentEvent) => void;
1884
+ /** The plan step being executed, when there is one. */
1885
+ step?: IPlanStep;
1886
+ signal?: AbortSignal;
1887
+ /** Add tokens spent on the parent's behalf (e.g. by a subagent) to the run. */
1888
+ addUsage: (usage: IUsage) => void;
1889
+ /**
1890
+ * Run the agent's consent gate for a call made on its behalf (e.g. a host
1891
+ * tool a subagent calls). Resolves when allowed, throws ToolDeniedError.
1892
+ */
1893
+ approve: (toolName: string, input: unknown, readOnly: boolean) => Promise<void>;
1894
+ }
1895
+ /** Read the run context the agent passes to a tool's execute (undefined outside a run). */
1896
+ declare const toolRunContextOf: (options: unknown) => ToolRunContext | undefined;
1897
+ type ToModelOutput = NonNullable<Tool['toModelOutput']>;
1898
+ /**
1899
+ * Cap what the MODEL sees of a tool result at `maxChars` (the raw output still
1900
+ * reaches events and the trace). A tool's own `toModelOutput` runs first.
1901
+ */
1902
+ declare const limitModelOutput: (original: Tool["toModelOutput"], maxChars: number) => ToModelOutput;
1903
+ /**
1904
+ * A short parameter hint ("{ text: string, x?: number }") derived from a
1905
+ * tool's JSON schema — so tools without a hand-written `promptHint` (every MCP
1906
+ * tool) still tell a prompted model what to pass. Undefined when unknown.
1907
+ */
1908
+ declare const schemaHintOf: (t: Tool) => Promise<string | undefined>;
1909
+
893
1910
  interface IndexedDBStoreOptions {
894
1911
  /** Database name, forwarded to the shared IDB owner (default 'agent-web'). */
895
1912
  dbName?: string;
@@ -910,21 +1927,4 @@ declare class IndexedDBStore implements ContextStore {
910
1927
  listSessions(): Promise<string[]>;
911
1928
  }
912
1929
 
913
- interface CompressOptions {
914
- /** Compress once the transcript exceeds this many characters (0 = never). */
915
- maxChars?: number;
916
- /** How many most-recent messages to keep verbatim. */
917
- keepRecent?: number;
918
- /** Time-box the summarisation call so it can never hang the caller. */
919
- timeoutMs?: number;
920
- abortSignal?: AbortSignal;
921
- }
922
- /**
923
- * When the transcript grows too long, summarise everything except the last
924
- * `keepRecent` messages into a single system message (via the model), so the
925
- * session stays within the model's context window. Returns the same array
926
- * unchanged when no compression is needed; never throws.
927
- */
928
- declare const compressHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
929
-
930
- export { type Agent, type AgentContext, type AgentEvent, type AgentEventHandler, type AgentLogger, type AgentLoggerSink, type AgentTool, type AgentToolSet, type AgentWebDBOptions, type BrowserAgentConfig, type CompressOptions, type ContextStore, type CredentialStore, type EncryptedBlob, type ExecutorPromptContext, type ExecutorResult, type GenerateOptions, type IPlan, type IPlanStep, type IStepResult, type IToolCall, type IUsage, IndexedDBStore, type IndexedDBStoreOptions, KEYS_STORE, type LogLevel, MemoryCredentialStore, MemoryStore, type ModelInput, type Phase, type PhaseBudgets, PlanSchema, type PlanShape, PlanStepSchema, type PlannerPromptContext, type PlannerResult, type PromptParts, type Prompts, type ProviderModelSpec, type ProviderType, type RawAction, type ReplanDecision, type ReplanMode, ReplanSchema, type ReplanShape, type ReplanTrigger, type ReplannerPromptContext, type ReplannerResult, type ResolvedConfig, type ResolvedStage, type RunOptions, type RunResult, SECRETS_STORE, SESSIONS_STORE, type StageInput, type StageOverride, type StoredMessage, type SynthesizerPromptContext, type ToolCallMode, type ToolLoopCallbacks, type ToolLoopOptions, type ToolLoopResult, type ToolMode, type ToolSelectionStrategy, VaultCredentialStore, VaultOptions, type WebLLMModelOptions, buildModelFromStage, compressHistory, createAgent, createLogger, createPlan, createWebLLMModel, decideReplan, decryptJSON, defaultPrompts, defineTool, directBrowserOk, dispatch, encryptJSON, executeStep, generate, generateStructured, getOrCreateVaultKey, isDirectModel, isProviderSpec, isWebGPUAvailable, looksLikeJson, normalizeSteps, normalizeUsage, openAgentWebDB, parseExecutorResponse, parsePlainText, parsePlannerResponse, parseReplannerResponse, preloadWebLLMModel, promptHintOf, renderCatalog, replanWanted, resolveConfig, resolveModel, resolveStage, runToolLoop, selectToolMode, shouldReplan, splitBlocker, stream, supportsNativeTools, supportsStructuredOutput, synthesizeAnswer, unloadWebLLMModel, withSystem };
1930
+ export { type Agent, type AgentContext, type AgentEvent, type AgentEventHandler, type AgentLogger, type AgentLoggerSink, type AgentTool, type AgentToolSet, type AgentWebDBOptions, type AttachmentKind, AttachmentsNotSupportedError, type BrowserAgentConfig, type ClearedInfo, type CompactOptions, type CompactResult, type CompactionConfig, type CompressOptions, type ContextStore, type CredentialStore, type EffectiveToolStrategy, type EncryptedBlob, type ExecutorPromptContext, type ExecutorResult, FILES_STORE, FIND_TOOLS_NAME, type FileToolsOptions, type GenerateOptions, type IPlan, type IPlanStep, type IStepResult, type IToolCall, type IUsage, ImagesNotSupportedError, IndexedDBStore, type IndexedDBStoreOptions, KEYS_STORE, type LimitBreach, type LimitKind, type LoadSkillOptions, type LogLevel, MemoryCredentialStore, MemoryStore, type MessageEndpoint, type ModelInput, type ParentToWorker, type Phase, type PhaseBudgets, PlanSchema, type PlanShape, PlanStepSchema, type PlannerPromptContext, type PlannerResult, type PromptCachingSetting, type PromptParts, type Prompts, type ProviderModelSpec, type ProviderOptionsMap, type ProviderType, type ProxiedToolSpec, type RawAction, type ReplanDecision, type ReplanMode, ReplanSchema, type ReplanShape, type ReplanTrigger, type ReplannerPromptContext, type ReplannerResult, type ResolvedCaching, type ResolvedCompaction, type ResolvedConfig, type ResolvedStage, type ResolvedThinking, type RunFile, type RunImage, type RunOptions, type RunResult, SECRETS_STORE, SESSIONS_STORE, SKILL_TOOL_NAMES, type SearchToolsOptions, type ServeSubagentOptions, type Skill, type StageInput, type StageOverride, type StoredMessage, type SubagentToolOptions, type SubagentWorkerConfig, type SynthesizerPromptContext, TOOL_APPROVAL_MODES, type ThinkingConfig, type ThinkingLevel, type ThinkingSetting, type ThinkingStage, type TokenLimits, type ToolApprovalConfig, type ToolApprovalDecision, type ToolApprovalMode, type ToolApprovalRequest, ToolBudgetError, type ToolCallMode, type ToolCatalogEntry, ToolDeniedError, type ToolLoopCallbacks, type ToolLoopOptions, type ToolLoopResult, type ToolMode, type ToolPermission, type ToolResultClearing, type ToolRunContext, type ToolSelectionStrategy, type UsagePhase, VaultCredentialStore, VaultOptions, type VfsListener, type VirtualFile, type VirtualFileInfo, VirtualFileSystem, type VirtualFileSystemOptions, type WebLLMModelOptions, type WorkerLike, type WorkerToParent, attachmentKind, buildModelFromStage, bytesToBase64, checkLimits, compactHistory, compactSteps, compressHistory, createAgent, createFileTools, createFindToolsTool, createLogger, createPlan, createSkillTools, createSubagentTool, createToolResultClearer, createWebLLMModel, decideReplan, decideToolPermission, decryptJSON, defaultPrompts, defineSkill, defineTool, directBrowserOk, dispatch, encryptJSON, messageTokens as estimateMessagesTokens, estimateTokens, executeStep, generate, generateStructured, getOrCreateVaultKey, isAttachmentRefusal, isDirectModel, isImageRefusal, isProviderSpec, isReadOnlyTool, isTextMime, isWebGPUAvailable, limitModelOutput, loadSkillFromUrl, looksLikeJson, markReadOnly, matchRule, mediaTypeOf, mergeProviderOptions, mimeFromPath, normalizePath, normalizeSteps, normalizeUsage, openAgentWebDB, parseExecutorResponse, parsePlainText, parsePlannerResponse, parseReplannerResponse, parseSkillMarkdown, preloadWebLLMModel, promptHintOf, renderActiveSkills, renderCatalog, renderSearchCatalog, renderSkillIndex, replanWanted, resolveCaching, resolveCompaction, resolveConfig, resolveModel, resolveStage, resolveThinking, runToolLoop, schemaHintOf, searchTools, selectToolMode, serveSubagentWorker, shouldReplan, splitBlocker, stream, supportsImages, supportsNativeTools, supportsPdf, supportsStructuredOutput, synthesizeAnswer, thinkingFor, toFilePart, toImagePart, tokenize, toolCatalogOf, toolRunContextOf, unloadWebLLMModel, withRollingBreakpoint, withSystem };