@dudko.dev/agent-web 0.0.18 → 0.0.20

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