@dudko.dev/agent-web 0.0.1
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/LICENSE +21 -0
- package/README.md +176 -0
- package/dist/chunk-R7H4HSYT.js +22 -0
- package/dist/chunk-R7H4HSYT.js.map +1 -0
- package/dist/index.cjs +1407 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +835 -0
- package/dist/index.d.ts +835 -0
- package/dist/index.js +1298 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.cjs +111 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.cts +47 -0
- package/dist/mcp.d.ts +47 -0
- package/dist/mcp.js +83 -0
- package/dist/mcp.js.map +1 -0
- package/dist/webllm-IM3UD6YI.js +9 -0
- package/dist/webllm-IM3UD6YI.js.map +1 -0
- package/package.json +152 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
import { LanguageModel, ToolSet, Tool, ModelMessage, generateText, streamText, tool } from 'ai';
|
|
3
|
+
import { z, ZodType } from 'zod';
|
|
4
|
+
import { IDBPDatabase } from 'idb';
|
|
5
|
+
|
|
6
|
+
interface StoredMessage {
|
|
7
|
+
role: 'system' | 'user' | 'assistant';
|
|
8
|
+
content: string;
|
|
9
|
+
ts?: number;
|
|
10
|
+
}
|
|
11
|
+
/** Persists an agent session's transcript. Swap in any backend. */
|
|
12
|
+
interface ContextStore {
|
|
13
|
+
load(sessionId: string): Promise<StoredMessage[]>;
|
|
14
|
+
append(sessionId: string, message: StoredMessage): Promise<void>;
|
|
15
|
+
replace(sessionId: string, messages: StoredMessage[]): Promise<void>;
|
|
16
|
+
clear(sessionId: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** Non-persistent fallback (tests, SSR, private mode). */
|
|
19
|
+
declare class MemoryStore implements ContextStore {
|
|
20
|
+
private readonly data;
|
|
21
|
+
load(sessionId: string): Promise<StoredMessage[]>;
|
|
22
|
+
append(sessionId: string, message: StoredMessage): Promise<void>;
|
|
23
|
+
replace(sessionId: string, messages: StoredMessage[]): Promise<void>;
|
|
24
|
+
clear(sessionId: string): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Providers the browser registry can resolve from a spec. This is deliberately
|
|
29
|
+
* a browser-safe subset of the Node sibling's list: Amazon Bedrock (SigV4
|
|
30
|
+
* signing), Google Vertex (ADC via google-auth-library) and Cloudflare
|
|
31
|
+
* (Worker bindings / process.env) are Node-only and omitted; Azure folds into
|
|
32
|
+
* `openai-compatible`. `web-llm` is the local WebGPU pseudo-provider (no API
|
|
33
|
+
* key). Any other runtime — Chrome/Edge built-in AI, a custom LanguageModel —
|
|
34
|
+
* is passed to the agent directly and never touches this registry.
|
|
35
|
+
*/
|
|
36
|
+
type ProviderType = 'openai' | 'anthropic' | 'google' | 'openai-compatible' | 'xai' | 'deepseek' | 'gateway' | 'web-llm';
|
|
37
|
+
/** A model described by provider + id, resolved through the registry (+ vault). */
|
|
38
|
+
interface ProviderModelSpec {
|
|
39
|
+
providerType: ProviderType;
|
|
40
|
+
/** Model id, e.g. "gpt-4o-mini", "claude-haiku-4-5", "Llama-3.2-3B-Instruct-q4f16_1-MLC". */
|
|
41
|
+
model: string;
|
|
42
|
+
/** Provider endpoint override. Required for `openai-compatible`; a proxy URL for the rest. */
|
|
43
|
+
baseURL?: string;
|
|
44
|
+
/** Id under which the API key is stored in the CredentialStore / vault. Preferred. */
|
|
45
|
+
credentialRef?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Dev-only inline API key. Prefer `credentialRef` so the key lives encrypted
|
|
48
|
+
* in the vault, not on a long-lived config object. Using this logs a warning.
|
|
49
|
+
*/
|
|
50
|
+
apiKey?: string;
|
|
51
|
+
/** Extra request headers merged into the provider factory (e.g. a proxy auth header). */
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
/** Escape hatch spread into the SDK factory after baseURL / apiKey / headers. */
|
|
54
|
+
providerOptions?: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A per-stage override that inherits the base provider + credentials and
|
|
58
|
+
* changes only the fields it sets (typically just `model`). Distinguished from
|
|
59
|
+
* a full ProviderModelSpec by the absence of `providerType`.
|
|
60
|
+
*/
|
|
61
|
+
interface StageOverride {
|
|
62
|
+
model?: string;
|
|
63
|
+
baseURL?: string;
|
|
64
|
+
credentialRef?: string;
|
|
65
|
+
apiKey?: string;
|
|
66
|
+
headers?: Record<string, string>;
|
|
67
|
+
providerOptions?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
/** What a caller hands us for a model: a ready AI SDK model, or a spec to resolve. */
|
|
70
|
+
type ModelInput = LanguageModel | ProviderModelSpec;
|
|
71
|
+
/** A model input, plus the partial-override form usable for per-stage layering. */
|
|
72
|
+
type StageInput = ModelInput | StageOverride;
|
|
73
|
+
/** Outcome of resolving one stage: either a ready model, or a fully-resolved spec. */
|
|
74
|
+
type ResolvedStage = {
|
|
75
|
+
type: 'direct';
|
|
76
|
+
model: LanguageModel;
|
|
77
|
+
} | {
|
|
78
|
+
type: 'spec';
|
|
79
|
+
spec: ProviderModelSpec;
|
|
80
|
+
};
|
|
81
|
+
/** True for a ready AI SDK model: a gateway model-id string or a LanguageModelV* object. */
|
|
82
|
+
declare const isDirectModel: (m: unknown) => m is LanguageModel;
|
|
83
|
+
/** True for a full provider spec (carries the `providerType` discriminator). */
|
|
84
|
+
declare const isProviderSpec: (m: unknown) => m is ProviderModelSpec;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Default phase prompts. Each builder returns `{ system, prompt }` strings.
|
|
88
|
+
* Because the agent runs in two tool-modes, the builders switch on `ctx.mode`:
|
|
89
|
+
*
|
|
90
|
+
* - `native` — the model calls tools / emits schema-constrained JSON via the
|
|
91
|
+
* AI SDK, so the prompts describe the task and let the SDK enforce structure.
|
|
92
|
+
* - `prompted` — weak local models can't do that reliably, so the prompts spell
|
|
93
|
+
* out an exact JSON shape and (for the executor) include a tool catalogue;
|
|
94
|
+
* the output is salvaged by parse.ts.
|
|
95
|
+
*
|
|
96
|
+
* Override any builder via `BrowserAgentConfig.prompts`.
|
|
97
|
+
*/
|
|
98
|
+
type ToolCallMode = 'native' | 'prompted';
|
|
99
|
+
interface PromptParts {
|
|
100
|
+
system: string;
|
|
101
|
+
prompt: string;
|
|
102
|
+
}
|
|
103
|
+
interface PlannerPromptContext {
|
|
104
|
+
goal: string;
|
|
105
|
+
state?: string;
|
|
106
|
+
toolCatalog: string;
|
|
107
|
+
mode: ToolCallMode;
|
|
108
|
+
}
|
|
109
|
+
interface ExecutorPromptContext {
|
|
110
|
+
goal: string;
|
|
111
|
+
state?: string;
|
|
112
|
+
step: string;
|
|
113
|
+
index: number;
|
|
114
|
+
total: number;
|
|
115
|
+
toolCatalog: string;
|
|
116
|
+
done: string[];
|
|
117
|
+
mode: ToolCallMode;
|
|
118
|
+
}
|
|
119
|
+
interface ReplannerPromptContext {
|
|
120
|
+
goal: string;
|
|
121
|
+
state?: string;
|
|
122
|
+
done: string[];
|
|
123
|
+
remaining: string[];
|
|
124
|
+
mode: ToolCallMode;
|
|
125
|
+
}
|
|
126
|
+
interface SynthesizerPromptContext {
|
|
127
|
+
goal: string;
|
|
128
|
+
state?: string;
|
|
129
|
+
done: string[];
|
|
130
|
+
}
|
|
131
|
+
interface Prompts {
|
|
132
|
+
planner(ctx: PlannerPromptContext): PromptParts;
|
|
133
|
+
executor(ctx: ExecutorPromptContext): PromptParts;
|
|
134
|
+
replanner(ctx: ReplannerPromptContext): PromptParts;
|
|
135
|
+
synthesizer(ctx: SynthesizerPromptContext): PromptParts;
|
|
136
|
+
}
|
|
137
|
+
declare const defaultPrompts: Prompts;
|
|
138
|
+
/** Prepend a host-supplied systemPrompt to a phase system prompt, if present. */
|
|
139
|
+
declare const withSystem: (base: string, extra?: string) => string;
|
|
140
|
+
|
|
141
|
+
interface VaultOptions {
|
|
142
|
+
/** Database name, forwarded to the shared IDB owner (default 'agent-web'). */
|
|
143
|
+
dbName?: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Encrypted key/value secret store backed by IndexedDB. Values are encrypted at
|
|
147
|
+
* rest with the non-extractable AES-GCM vault key (see crypto.ts).
|
|
148
|
+
*
|
|
149
|
+
* ── THREAT MODEL (read before shipping any app-owned key to a browser) ──
|
|
150
|
+
* This vault PROTECTS secrets **at rest** — an IndexedDB / disk dump yields
|
|
151
|
+
* only ciphertext — and against **casual DevTools inspection** — no plaintext
|
|
152
|
+
* key is stored, and the AES key cannot be exported even by in-page script.
|
|
153
|
+
*
|
|
154
|
+
* It does **NOT** defend against **active XSS on your origin**: any script that
|
|
155
|
+
* already runs on the page can call `getSecret()`, or use the live `CryptoKey`
|
|
156
|
+
* to decrypt. Browser storage is not a secrets manager.
|
|
157
|
+
*
|
|
158
|
+
* Therefore this vault is for the **end user's OWN key on their OWN device**
|
|
159
|
+
* (bring-your-own-key). A shared, app-owned key must NEVER reach the client —
|
|
160
|
+
* put it behind a server proxy (`ProviderModelSpec.baseURL`) or the Vercel AI
|
|
161
|
+
* Gateway instead.
|
|
162
|
+
*/
|
|
163
|
+
declare class IndexedDBVault {
|
|
164
|
+
private readonly dbName?;
|
|
165
|
+
constructor(opts?: VaultOptions);
|
|
166
|
+
private key;
|
|
167
|
+
/** Encrypt and store a secret string under `id`. */
|
|
168
|
+
setSecret(id: string, value: string): Promise<void>;
|
|
169
|
+
/** Fetch and decrypt a secret, or undefined if absent. */
|
|
170
|
+
getSecret(id: string): Promise<string | undefined>;
|
|
171
|
+
deleteSecret(id: string): Promise<void>;
|
|
172
|
+
listSecretIds(): Promise<string[]>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* The seam the provider registry uses to fetch API keys at model-build time.
|
|
177
|
+
* Swap in any backend: the encrypted vault (default), an in-memory map (tests /
|
|
178
|
+
* SSR), or a `fetch` to your own short-lived-token endpoint.
|
|
179
|
+
*/
|
|
180
|
+
interface CredentialStore {
|
|
181
|
+
getApiKey(ref: string): Promise<string | undefined>;
|
|
182
|
+
setApiKey(ref: string, key: string): Promise<void>;
|
|
183
|
+
deleteApiKey(ref: string): Promise<void>;
|
|
184
|
+
}
|
|
185
|
+
/** Default CredentialStore: encrypted, IndexedDB-backed (see IndexedDBVault). */
|
|
186
|
+
declare class VaultCredentialStore implements CredentialStore {
|
|
187
|
+
private readonly vault;
|
|
188
|
+
constructor(opts?: VaultOptions);
|
|
189
|
+
getApiKey(ref: string): Promise<string | undefined>;
|
|
190
|
+
setApiKey(ref: string, key: string): Promise<void>;
|
|
191
|
+
deleteApiKey(ref: string): Promise<void>;
|
|
192
|
+
}
|
|
193
|
+
/** Non-persistent CredentialStore for tests / SSR / ephemeral sessions. */
|
|
194
|
+
declare class MemoryCredentialStore implements CredentialStore {
|
|
195
|
+
private readonly map;
|
|
196
|
+
constructor(initial?: Record<string, string>);
|
|
197
|
+
getApiKey(ref: string): Promise<string | undefined>;
|
|
198
|
+
setApiKey(ref: string, key: string): Promise<void>;
|
|
199
|
+
deleteApiKey(ref: string): Promise<void>;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The canonical tool shape is the AI SDK `Tool` — the same object the native
|
|
204
|
+
* tool-calling path passes straight to `streamText({ tools })`, and the same
|
|
205
|
+
* shape MCP tools take. We add one optional field, `promptHint`, a short
|
|
206
|
+
* human-readable parameter hint (e.g. "{ text: string, x?: number }") used only
|
|
207
|
+
* by the prompted/salvage path when it renders the tool catalogue into a text
|
|
208
|
+
* prompt for weak local models.
|
|
209
|
+
*/
|
|
210
|
+
type AgentTool = Tool & {
|
|
211
|
+
promptHint?: string;
|
|
212
|
+
};
|
|
213
|
+
/** A named collection of tools — a plain AI SDK ToolSet, usable directly. */
|
|
214
|
+
type AgentToolSet = ToolSet;
|
|
215
|
+
/** Read the optional promptHint attached by defineTool, if any. */
|
|
216
|
+
declare const promptHintOf: (tool: Tool) => string | undefined;
|
|
217
|
+
|
|
218
|
+
/** Force a tool-calling strategy, or let the agent pick per model ('auto'). */
|
|
219
|
+
type ToolMode = 'auto' | 'native' | 'prompted';
|
|
220
|
+
/**
|
|
221
|
+
* 'all' — the executor sees the full ToolSet on every step.
|
|
222
|
+
* 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner
|
|
223
|
+
* must populate them). Empty means a reasoning-only step.
|
|
224
|
+
*/
|
|
225
|
+
type ToolSelectionStrategy = 'all' | 'plan-narrowed';
|
|
226
|
+
/** Per-phase generation budgets (max output tokens). */
|
|
227
|
+
interface PhaseBudgets {
|
|
228
|
+
planner?: number;
|
|
229
|
+
executor?: number;
|
|
230
|
+
replanner?: number;
|
|
231
|
+
synthesizer?: number;
|
|
232
|
+
}
|
|
233
|
+
interface BrowserAgentConfig {
|
|
234
|
+
/** The default (executor) model: a ready AI SDK model, or a ProviderModelSpec to resolve. */
|
|
235
|
+
model: ModelInput;
|
|
236
|
+
/** Optional per-stage model overrides. A partial override inherits base provider/creds. */
|
|
237
|
+
planner?: StageInput;
|
|
238
|
+
synthesizer?: StageInput;
|
|
239
|
+
/** Fetches API keys for ProviderModelSpec models. Default: none (inline keys only). */
|
|
240
|
+
credentials?: CredentialStore;
|
|
241
|
+
/** Propagated to the openai-compatible provider name and the MCP client. */
|
|
242
|
+
clientName?: string;
|
|
243
|
+
/** Host tools the executor may call (an AI SDK ToolSet; use defineTool). */
|
|
244
|
+
tools?: AgentToolSet;
|
|
245
|
+
availableTools?: string[];
|
|
246
|
+
excludedTools?: string[];
|
|
247
|
+
/** Force native/prompted tool-calling; 'auto' picks per model (default 'auto'). */
|
|
248
|
+
toolMode?: ToolMode;
|
|
249
|
+
toolSelectionStrategy?: ToolSelectionStrategy;
|
|
250
|
+
/** Prepended to every phase's system prompt. */
|
|
251
|
+
systemPrompt?: string;
|
|
252
|
+
/** Override any phase prompt builder. */
|
|
253
|
+
prompts?: Partial<Prompts>;
|
|
254
|
+
/** Serialize the host's current world state into prompt context (grounding). */
|
|
255
|
+
describeState?: () => string | Promise<string>;
|
|
256
|
+
/** Persist the transcript (e.g. new IndexedDBStore()). */
|
|
257
|
+
memory?: ContextStore;
|
|
258
|
+
sessionId?: string;
|
|
259
|
+
/** Hard cap on executed steps incl. replans (default 8). */
|
|
260
|
+
maxIterations?: number;
|
|
261
|
+
/** Cap on LLM steps inside a single native executor call (default 4). */
|
|
262
|
+
maxStepsPerTask?: number;
|
|
263
|
+
/** Cap on replanner "revise" decisions per run (default 2). */
|
|
264
|
+
maxRevisions?: number;
|
|
265
|
+
/** Per-call timeout so a hang can't freeze a run (default 120000). */
|
|
266
|
+
chatTimeoutMs?: number;
|
|
267
|
+
budgets?: PhaseBudgets;
|
|
268
|
+
temperature?: number;
|
|
269
|
+
/** Replan after a blocked/failed step (default true). */
|
|
270
|
+
replan?: boolean;
|
|
271
|
+
/** Write a final natural-language summary (default true). */
|
|
272
|
+
synthesize?: boolean;
|
|
273
|
+
/** Compress stored history past this many chars (0 = off, default 12000). */
|
|
274
|
+
compressAfterChars?: number;
|
|
275
|
+
}
|
|
276
|
+
interface ResolvedConfig {
|
|
277
|
+
clientName: string;
|
|
278
|
+
sessionId: string;
|
|
279
|
+
toolMode: ToolMode;
|
|
280
|
+
toolSelectionStrategy: ToolSelectionStrategy;
|
|
281
|
+
maxIterations: number;
|
|
282
|
+
maxStepsPerTask: number;
|
|
283
|
+
maxRevisions: number;
|
|
284
|
+
chatTimeoutMs: number;
|
|
285
|
+
budgets: Required<PhaseBudgets>;
|
|
286
|
+
temperature: number | undefined;
|
|
287
|
+
replan: boolean;
|
|
288
|
+
synthesize: boolean;
|
|
289
|
+
compressAfterChars: number;
|
|
290
|
+
}
|
|
291
|
+
declare const resolveConfig: (c: BrowserAgentConfig) => ResolvedConfig;
|
|
292
|
+
|
|
293
|
+
/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */
|
|
294
|
+
interface IPlanStep {
|
|
295
|
+
id: string;
|
|
296
|
+
description: string;
|
|
297
|
+
expectedOutcome?: string;
|
|
298
|
+
/** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */
|
|
299
|
+
suggestedTools?: string[];
|
|
300
|
+
/** Set by the pipeline when suggestedTools were named but all were unknown. */
|
|
301
|
+
requiresTools?: boolean;
|
|
302
|
+
}
|
|
303
|
+
interface IPlan {
|
|
304
|
+
thought: string;
|
|
305
|
+
steps: IPlanStep[];
|
|
306
|
+
}
|
|
307
|
+
interface IUsage {
|
|
308
|
+
inputTokens: number;
|
|
309
|
+
outputTokens: number;
|
|
310
|
+
totalTokens: number;
|
|
311
|
+
}
|
|
312
|
+
interface IToolCall {
|
|
313
|
+
name: string;
|
|
314
|
+
input: unknown;
|
|
315
|
+
output: unknown;
|
|
316
|
+
ok: boolean;
|
|
317
|
+
}
|
|
318
|
+
interface IStepResult {
|
|
319
|
+
step: IPlanStep;
|
|
320
|
+
summary: string;
|
|
321
|
+
toolCalls: IToolCall[];
|
|
322
|
+
/** True when the executor signalled it could not complete the step ([BLOCKER]). */
|
|
323
|
+
blocked: boolean;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
type ReplanMode = 'continue' | 'revise' | 'finish';
|
|
327
|
+
type Phase = 'plan' | 'execute' | 'replan' | 'synthesize';
|
|
328
|
+
/**
|
|
329
|
+
* Everything the agent does is streamed as a typed event so any UI (or none)
|
|
330
|
+
* can render progress. The final answer arrives as a `final` event; there is no
|
|
331
|
+
* built-in rendering. This is a browser-focused subset of the Node sibling's
|
|
332
|
+
* event taxonomy (no persistence/otel events), plus `model.load` for WebLLM
|
|
333
|
+
* weight-download progress.
|
|
334
|
+
*/
|
|
335
|
+
type AgentEvent = {
|
|
336
|
+
type: 'run.start';
|
|
337
|
+
goal: string;
|
|
338
|
+
} | {
|
|
339
|
+
type: 'model.load';
|
|
340
|
+
progress: number;
|
|
341
|
+
text: string;
|
|
342
|
+
} | {
|
|
343
|
+
type: 'plan.thought-delta';
|
|
344
|
+
delta: string;
|
|
345
|
+
} | {
|
|
346
|
+
type: 'plan.step-added';
|
|
347
|
+
step: IPlanStep;
|
|
348
|
+
index: number;
|
|
349
|
+
} | {
|
|
350
|
+
type: 'plan.created';
|
|
351
|
+
plan: IPlan;
|
|
352
|
+
} | {
|
|
353
|
+
type: 'plan.revised';
|
|
354
|
+
plan: IPlan;
|
|
355
|
+
reason: string;
|
|
356
|
+
} | {
|
|
357
|
+
type: 'step.start';
|
|
358
|
+
step: IPlanStep;
|
|
359
|
+
index: number;
|
|
360
|
+
total: number;
|
|
361
|
+
} | {
|
|
362
|
+
type: 'step.text-delta';
|
|
363
|
+
step: IPlanStep;
|
|
364
|
+
delta: string;
|
|
365
|
+
} | {
|
|
366
|
+
type: 'step.tool-call';
|
|
367
|
+
step: IPlanStep;
|
|
368
|
+
name: string;
|
|
369
|
+
input: unknown;
|
|
370
|
+
} | {
|
|
371
|
+
type: 'step.tool-result';
|
|
372
|
+
step: IPlanStep;
|
|
373
|
+
name: string;
|
|
374
|
+
output: unknown;
|
|
375
|
+
ok: boolean;
|
|
376
|
+
} | {
|
|
377
|
+
type: 'step.complete';
|
|
378
|
+
step: IPlanStep;
|
|
379
|
+
result: IStepResult;
|
|
380
|
+
} | {
|
|
381
|
+
type: 'replan.decision';
|
|
382
|
+
mode: ReplanMode;
|
|
383
|
+
reason: string;
|
|
384
|
+
} | {
|
|
385
|
+
type: 'final.text-delta';
|
|
386
|
+
delta: string;
|
|
387
|
+
} | {
|
|
388
|
+
type: 'final';
|
|
389
|
+
text: string;
|
|
390
|
+
} | {
|
|
391
|
+
type: 'usage';
|
|
392
|
+
phase: Phase;
|
|
393
|
+
usage: IUsage;
|
|
394
|
+
} | {
|
|
395
|
+
type: 'retry';
|
|
396
|
+
phase: Phase;
|
|
397
|
+
attempt: number;
|
|
398
|
+
error: string;
|
|
399
|
+
} | {
|
|
400
|
+
type: 'stopped';
|
|
401
|
+
} | {
|
|
402
|
+
type: 'error';
|
|
403
|
+
phase: Phase | 'run';
|
|
404
|
+
error: string;
|
|
405
|
+
};
|
|
406
|
+
type AgentEventHandler = (event: AgentEvent) => void;
|
|
407
|
+
|
|
408
|
+
interface RunOptions {
|
|
409
|
+
onEvent?: AgentEventHandler;
|
|
410
|
+
signal?: AbortSignal;
|
|
411
|
+
/** Override the config's sessionId for this run. */
|
|
412
|
+
sessionId?: string;
|
|
413
|
+
}
|
|
414
|
+
interface RunResult {
|
|
415
|
+
goal: string;
|
|
416
|
+
final: string;
|
|
417
|
+
plan: IPlan;
|
|
418
|
+
trace: IStepResult[];
|
|
419
|
+
steps: number;
|
|
420
|
+
/** Total successful tool calls across the run. */
|
|
421
|
+
applied: number;
|
|
422
|
+
stopped: boolean;
|
|
423
|
+
usage: IUsage;
|
|
424
|
+
}
|
|
425
|
+
interface Agent {
|
|
426
|
+
run(goal: string, opts?: RunOptions): Promise<RunResult>;
|
|
427
|
+
/** The resolved models, for hosts that want to reuse them (e.g. warm-up). */
|
|
428
|
+
readonly models: {
|
|
429
|
+
planner: LanguageModel;
|
|
430
|
+
executor: LanguageModel;
|
|
431
|
+
synthesizer: LanguageModel;
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Create a headless plan → execute → replan → synthesize agent. Models are
|
|
436
|
+
* resolved eagerly (dynamic provider imports + vault key fetch), so this is
|
|
437
|
+
* async. Each `run` streams typed AgentEvents for any UI to render.
|
|
438
|
+
*/
|
|
439
|
+
declare const createAgent: (config: BrowserAgentConfig) => Promise<Agent>;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Structured-output schemas for the native path (generateObject). Kept free of
|
|
443
|
+
* `.max()`/`.min()` constraints — some providers reject or mis-handle them in
|
|
444
|
+
* JSON-schema mode; we cap/clean in code instead (see parse.ts normalizeSteps).
|
|
445
|
+
*/
|
|
446
|
+
declare const PlanStepSchema: z.ZodObject<{
|
|
447
|
+
description: z.ZodString;
|
|
448
|
+
expectedOutcome: z.ZodOptional<z.ZodString>;
|
|
449
|
+
suggestedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
450
|
+
}, z.core.$strip>;
|
|
451
|
+
declare const PlanSchema: z.ZodObject<{
|
|
452
|
+
thought: z.ZodString;
|
|
453
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
454
|
+
description: z.ZodString;
|
|
455
|
+
expectedOutcome: z.ZodOptional<z.ZodString>;
|
|
456
|
+
suggestedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
457
|
+
}, z.core.$strip>>;
|
|
458
|
+
}, z.core.$strip>;
|
|
459
|
+
declare const ReplanSchema: z.ZodObject<{
|
|
460
|
+
decision: z.ZodEnum<{
|
|
461
|
+
continue: "continue";
|
|
462
|
+
revise: "revise";
|
|
463
|
+
finish: "finish";
|
|
464
|
+
}>;
|
|
465
|
+
reason: z.ZodString;
|
|
466
|
+
plan: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
467
|
+
}, z.core.$strip>;
|
|
468
|
+
type PlanShape = z.infer<typeof PlanSchema>;
|
|
469
|
+
type ReplanShape = z.infer<typeof ReplanSchema>;
|
|
470
|
+
|
|
471
|
+
/** Everything the phase functions (planner/executor/replanner/synthesizer) share. */
|
|
472
|
+
interface AgentContext {
|
|
473
|
+
config: ResolvedConfig;
|
|
474
|
+
raw: BrowserAgentConfig;
|
|
475
|
+
plannerModel: LanguageModel;
|
|
476
|
+
executorModel: LanguageModel;
|
|
477
|
+
synthesizerModel: LanguageModel;
|
|
478
|
+
/** Tool-mode for the planner/replanner (from the planner model). */
|
|
479
|
+
plannerMode: ToolCallMode;
|
|
480
|
+
/** Tool-mode for the executor (from the executor model). */
|
|
481
|
+
executorMode: ToolCallMode;
|
|
482
|
+
tools: AgentToolSet;
|
|
483
|
+
toolCatalog: string;
|
|
484
|
+
prompts: Prompts;
|
|
485
|
+
emit: (event: AgentEvent) => void;
|
|
486
|
+
signal?: AbortSignal;
|
|
487
|
+
/** Current world state for grounding, or undefined when no describeState is configured. */
|
|
488
|
+
state: () => Promise<string | undefined>;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Build the initial plan. Native mode uses generateObject(PlanSchema); prompted
|
|
493
|
+
* mode salvages `{ reply, plan }` from plain text. Native failures (a weak model
|
|
494
|
+
* that can't satisfy the schema) fall back to the prompted parse rather than
|
|
495
|
+
* throwing, so the run degrades gracefully. An empty `steps` list signals the
|
|
496
|
+
* runner to answer directly (greeting / question / unclear).
|
|
497
|
+
*/
|
|
498
|
+
declare const createPlan: (ctx: AgentContext, goal: string) => Promise<{
|
|
499
|
+
plan: IPlan;
|
|
500
|
+
usage: IUsage;
|
|
501
|
+
}>;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Split the executor's reply into a clean summary and a structural `blocked`
|
|
505
|
+
* flag. The [BLOCKER] sentinel — emitted by the executor when it can't complete
|
|
506
|
+
* a step — is language-agnostic and drives the replanner; we strip every copy
|
|
507
|
+
* so it never leaks into downstream prompts.
|
|
508
|
+
*/
|
|
509
|
+
declare const splitBlocker: (raw: string) => {
|
|
510
|
+
summary: string;
|
|
511
|
+
blocked: boolean;
|
|
512
|
+
};
|
|
513
|
+
/** Execute one plan step: run the tool loop (native or prompted) and emit events. */
|
|
514
|
+
declare const executeStep: (ctx: AgentContext, goal: string, step: IPlanStep, index: number, total: number, done: string[]) => Promise<{
|
|
515
|
+
result: IStepResult;
|
|
516
|
+
usage: IUsage;
|
|
517
|
+
}>;
|
|
518
|
+
/** The replanner runs when a step was blocked or any of its tool calls failed. */
|
|
519
|
+
declare const shouldReplan: (result: IStepResult) => boolean;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Robust parsing of model output. Small in-browser models emit JSON wrapped in
|
|
523
|
+
* prose or code fences, truncate it mid-token when they loop, or drift to plain
|
|
524
|
+
* text. Every parser here is defensive: it salvages what it can and NEVER
|
|
525
|
+
* throws, and it never surfaces raw JSON as user-facing text. This is the
|
|
526
|
+
* backbone of the "prompted" tool-mode (see tools/mode.ts).
|
|
527
|
+
*/
|
|
528
|
+
/** A tool the executor asked to run. */
|
|
529
|
+
interface RawAction {
|
|
530
|
+
tool: string;
|
|
531
|
+
args: Record<string, unknown>;
|
|
532
|
+
}
|
|
533
|
+
type ReplanDecision = 'continue' | 'revise' | 'finish';
|
|
534
|
+
/** True when a string is (or is dominated by) raw JSON — kept out of the UI. */
|
|
535
|
+
declare const looksLikeJson: (s: string) => boolean;
|
|
536
|
+
/** Trim, drop empties, de-duplicate (case-insensitive), cap length. */
|
|
537
|
+
declare const normalizeSteps: (arr: unknown, cap?: number) => string[];
|
|
538
|
+
interface PlannerResult {
|
|
539
|
+
reply: string;
|
|
540
|
+
plan: string[];
|
|
541
|
+
}
|
|
542
|
+
declare const parsePlannerResponse: (raw: string) => PlannerResult;
|
|
543
|
+
interface ExecutorResult {
|
|
544
|
+
reply: string;
|
|
545
|
+
actions: RawAction[];
|
|
546
|
+
}
|
|
547
|
+
declare const parseExecutorResponse: (raw: string) => ExecutorResult;
|
|
548
|
+
interface ReplannerResult {
|
|
549
|
+
decision: ReplanDecision;
|
|
550
|
+
reason: string;
|
|
551
|
+
plan: string[];
|
|
552
|
+
}
|
|
553
|
+
declare const parseReplannerResponse: (raw: string) => ReplannerResult;
|
|
554
|
+
/** Extracts a clean human sentence, never raw JSON. */
|
|
555
|
+
declare const parsePlainText: (raw: string) => string;
|
|
556
|
+
|
|
557
|
+
interface ReplanOutcome {
|
|
558
|
+
decision: ReplanDecision;
|
|
559
|
+
reason: string;
|
|
560
|
+
/** Replacement remaining steps (descriptions) when decision is 'revise'. */
|
|
561
|
+
plan: string[];
|
|
562
|
+
usage: IUsage;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Decide whether to continue, revise the remaining plan, or finish, after a
|
|
566
|
+
* blocked/failed step. Native mode uses generateObject(ReplanSchema); prompted
|
|
567
|
+
* mode salvages the decision from text. Any failure degrades to 'continue' so a
|
|
568
|
+
* flaky replanner never aborts the run.
|
|
569
|
+
*/
|
|
570
|
+
declare const decideReplan: (ctx: AgentContext, goal: string, done: string[], remaining: string[]) => Promise<ReplanOutcome>;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Write the final natural-language summary of what the run accomplished. Plain
|
|
574
|
+
* text only (parsePlainText strips any stray JSON). Falls back to a default
|
|
575
|
+
* sentence if the model returns nothing usable.
|
|
576
|
+
*/
|
|
577
|
+
declare const synthesizeAnswer: (ctx: AgentContext, goal: string, done: string[]) => Promise<{
|
|
578
|
+
text: string;
|
|
579
|
+
usage: IUsage;
|
|
580
|
+
}>;
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Resolve one stage to either a ready model or a fully-resolved spec, layering
|
|
584
|
+
* an optional override on the base:
|
|
585
|
+
* - a direct model (or full spec) override wins outright;
|
|
586
|
+
* - a partial StageOverride inherits the base provider + credentials, changing
|
|
587
|
+
* only the fields it sets (e.g. `{ model: 'gpt-4o-mini' }`);
|
|
588
|
+
* - a full-spec override that switches provider MUST carry its own key
|
|
589
|
+
* (credentialRef/apiKey) — inheriting a key across vendors is a footgun.
|
|
590
|
+
*/
|
|
591
|
+
declare const resolveStage: (base: ModelInput, override: StageInput | undefined, stageName: string) => ResolvedStage;
|
|
592
|
+
/**
|
|
593
|
+
* Turn a resolved stage into an AI SDK `LanguageModel`. Direct models pass
|
|
594
|
+
* through untouched; specs are built by dynamically importing the provider's
|
|
595
|
+
* optional-peer package and fetching the API key from the CredentialStore.
|
|
596
|
+
*/
|
|
597
|
+
declare const buildModelFromStage: (resolved: ResolvedStage, credentials?: CredentialStore, clientName?: string) => Promise<LanguageModel>;
|
|
598
|
+
/** Resolve a single ModelInput straight to a LanguageModel (no per-stage layering). */
|
|
599
|
+
declare const resolveModel: (input: ModelInput, credentials?: CredentialStore, clientName?: string) => Promise<LanguageModel>;
|
|
600
|
+
|
|
601
|
+
/** WebGPU feature-detect — WebLLM requires it. Call before offering local models. */
|
|
602
|
+
declare const isWebGPUAvailable: () => boolean;
|
|
603
|
+
interface WebLLMModelOptions {
|
|
604
|
+
/**
|
|
605
|
+
* Progress callback for weight download / engine init. `report.progress` is
|
|
606
|
+
* 0..1. Forwarded to WebLLM's `initProgressCallback`.
|
|
607
|
+
*/
|
|
608
|
+
initProgressCallback?: (report: {
|
|
609
|
+
progress: number;
|
|
610
|
+
text: string;
|
|
611
|
+
}) => void;
|
|
612
|
+
/** Any other @browser-ai/web-llm setting (temperature, worker handler, …). */
|
|
613
|
+
[k: string]: unknown;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Build an AI SDK `LanguageModel` backed by WebLLM (WebGPU) via the community
|
|
617
|
+
* provider `@browser-ai/web-llm` (an optional peer, dynamically imported so it
|
|
618
|
+
* is code-split and never loads until a local model is actually used). Accepts
|
|
619
|
+
* any WebLLM prebuilt model id, e.g. "Llama-3.2-3B-Instruct-q4f16_1-MLC".
|
|
620
|
+
*/
|
|
621
|
+
declare const createWebLLMModel: (model: string, options?: WebLLMModelOptions) => Promise<LanguageModel>;
|
|
622
|
+
|
|
623
|
+
/** Whether native tool-calling is reliable enough to be the default for a provider. */
|
|
624
|
+
declare const supportsNativeTools: (p: ProviderType) => boolean;
|
|
625
|
+
/** Whether native structured output (generateObject) is the default for a provider. */
|
|
626
|
+
declare const supportsStructuredOutput: (p: ProviderType) => boolean;
|
|
627
|
+
/**
|
|
628
|
+
* Whether calling this provider straight from a browser origin with a BYOK key
|
|
629
|
+
* is expected to work (CORS + browser-access policy). Hosts can use this to
|
|
630
|
+
* warn users before a direct call fails.
|
|
631
|
+
*
|
|
632
|
+
* - `google`: Gemini's endpoint is CORS-enabled — the most reliable direct BYOK path.
|
|
633
|
+
* - `gateway` / `openai-compatible`: the host controls the endpoint / CORS.
|
|
634
|
+
* - `anthropic`: works, but only with the direct-browser-access header, which
|
|
635
|
+
* the registry injects automatically.
|
|
636
|
+
* - `openai`: api.openai.com does NOT reliably send CORS for browser calls —
|
|
637
|
+
* route through a proxy `baseURL` or the gateway.
|
|
638
|
+
* - `xai` / `deepseek`: unreliable from the browser; prefer a proxy.
|
|
639
|
+
*/
|
|
640
|
+
declare const directBrowserOk: (p: ProviderType) => boolean;
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Fetch (or lazily create) the vault's AES-GCM key. The key is generated
|
|
644
|
+
* NON-EXTRACTABLE and stored as a live `CryptoKey` in IndexedDB — a CryptoKey
|
|
645
|
+
* is structured-cloneable, so it persists across reloads WITHOUT its raw bytes
|
|
646
|
+
* ever being exposed to JavaScript. Not even in-page script can read it out; it
|
|
647
|
+
* can only be used to encrypt / decrypt. That is what makes at-rest storage of
|
|
648
|
+
* the secrets meaningful (see IndexedDBVault's threat model).
|
|
649
|
+
*/
|
|
650
|
+
declare const getOrCreateVaultKey: (dbName?: string) => Promise<CryptoKey>;
|
|
651
|
+
interface EncryptedBlob {
|
|
652
|
+
/** 96-bit random IV, fresh per write. */
|
|
653
|
+
iv: Uint8Array;
|
|
654
|
+
ciphertext: ArrayBuffer;
|
|
655
|
+
}
|
|
656
|
+
/** Encrypt a JSON-serialisable value with a fresh 96-bit IV (AES-GCM). */
|
|
657
|
+
declare const encryptJSON: (key: CryptoKey, value: unknown) => Promise<EncryptedBlob>;
|
|
658
|
+
/** Decrypt a blob produced by encryptJSON. Throws if the key or blob don't match. */
|
|
659
|
+
declare const decryptJSON: <T = unknown>(key: CryptoKey, blob: EncryptedBlob) => Promise<T>;
|
|
660
|
+
|
|
661
|
+
interface AgentWebDBOptions {
|
|
662
|
+
/** Database name (default 'agent-web'). Use a distinct name to isolate apps. */
|
|
663
|
+
dbName?: string;
|
|
664
|
+
}
|
|
665
|
+
declare const KEYS_STORE = "keys";
|
|
666
|
+
declare const SECRETS_STORE = "secrets";
|
|
667
|
+
declare const SESSIONS_STORE = "sessions";
|
|
668
|
+
/**
|
|
669
|
+
* The single owner of the IndexedDB database. Every persistent store — the
|
|
670
|
+
* non-extractable crypto key, encrypted secrets, and session transcripts —
|
|
671
|
+
* lives under ONE database name + version. Centralising `openDB` here prevents
|
|
672
|
+
* the classic bug where two modules open the same DB name with different store
|
|
673
|
+
* sets and the second call throws a VersionError.
|
|
674
|
+
*/
|
|
675
|
+
declare const openAgentWebDB: (opts?: AgentWebDBOptions) => Promise<IDBPDatabase>;
|
|
676
|
+
|
|
677
|
+
/** Options shared by the low-level generation helpers. Provide `prompt` OR `messages`. */
|
|
678
|
+
interface GenerateOptions {
|
|
679
|
+
system?: string;
|
|
680
|
+
prompt?: string;
|
|
681
|
+
messages?: ModelMessage[];
|
|
682
|
+
tools?: ToolSet;
|
|
683
|
+
maxOutputTokens?: number;
|
|
684
|
+
temperature?: number;
|
|
685
|
+
abortSignal?: AbortSignal;
|
|
686
|
+
/** Time-box the call; combined with `abortSignal` (0/undefined = no timeout). */
|
|
687
|
+
timeoutMs?: number;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* One-shot text generation. Thin, provider-agnostic wrapper over the AI SDK's
|
|
691
|
+
* `generateText` — the same call works against a cloud model, a local WebLLM
|
|
692
|
+
* model, or Chrome/Edge built-in AI. Returns the full AI SDK result (`.text`,
|
|
693
|
+
* `.usage`, `.toolCalls`, `.steps`, …).
|
|
694
|
+
*/
|
|
695
|
+
declare const generate: (model: LanguageModel, opts?: GenerateOptions) => ReturnType<typeof generateText>;
|
|
696
|
+
/** Streaming text generation. Returns the AI SDK `streamText` result (`.textStream`, `.fullStream`). */
|
|
697
|
+
declare const stream: (model: LanguageModel, opts?: GenerateOptions) => ReturnType<typeof streamText>;
|
|
698
|
+
/**
|
|
699
|
+
* Structured output constrained to a Zod schema, via the AI SDK's
|
|
700
|
+
* `generateObject`. Cloud models and WebLLM both support this; tiny local
|
|
701
|
+
* models can be unreliable — the agent's prompted mode is the fallback.
|
|
702
|
+
* Returns the AI SDK result (`.object`, `.usage`).
|
|
703
|
+
*/
|
|
704
|
+
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>>;
|
|
705
|
+
|
|
706
|
+
interface ToolLoopCallbacks {
|
|
707
|
+
onTextDelta?: (delta: string) => void;
|
|
708
|
+
onToolCall?: (name: string, input: unknown) => void;
|
|
709
|
+
onToolResult?: (name: string, output: unknown, ok: boolean) => void;
|
|
710
|
+
}
|
|
711
|
+
interface ToolLoopOptions {
|
|
712
|
+
/** 'native' = SDK function-calling; 'prompted' = parse JSON out of plain text. */
|
|
713
|
+
mode: 'native' | 'prompted';
|
|
714
|
+
system?: string;
|
|
715
|
+
prompt?: string;
|
|
716
|
+
messages?: ModelMessage[];
|
|
717
|
+
/** In native mode: the callable tools. In prompted mode: used to dispatch salvaged calls. */
|
|
718
|
+
tools: ToolSet;
|
|
719
|
+
/** Native mode: restrict callable tools to these names (plan-narrowed). */
|
|
720
|
+
activeTools?: string[];
|
|
721
|
+
/** Native mode: cap on internal tool-calling steps (default 4). */
|
|
722
|
+
maxSteps?: number;
|
|
723
|
+
maxOutputTokens?: number;
|
|
724
|
+
temperature?: number;
|
|
725
|
+
abortSignal?: AbortSignal;
|
|
726
|
+
timeoutMs?: number;
|
|
727
|
+
callbacks?: ToolLoopCallbacks;
|
|
728
|
+
}
|
|
729
|
+
interface ToolLoopResult {
|
|
730
|
+
text: string;
|
|
731
|
+
toolCalls: IToolCall[];
|
|
732
|
+
usage: IUsage;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Run one round of tool-calling in whichever mode the model needs, returning a
|
|
736
|
+
* normalised result. Native mode streams the SDK's multi-step function-calling;
|
|
737
|
+
* prompted mode does a single generation, salvages a `{ reply, actions }` JSON
|
|
738
|
+
* from the text, and dispatches each action through the tool's own execute.
|
|
739
|
+
* Both call the exact same tool implementations.
|
|
740
|
+
*/
|
|
741
|
+
declare const runToolLoop: (model: LanguageModel, opts: ToolLoopOptions) => Promise<ToolLoopResult>;
|
|
742
|
+
|
|
743
|
+
/** Normalise the AI SDK usage shape (fields can be undefined) into IUsage. */
|
|
744
|
+
declare const normalizeUsage: (u?: {
|
|
745
|
+
inputTokens?: number;
|
|
746
|
+
outputTokens?: number;
|
|
747
|
+
totalTokens?: number;
|
|
748
|
+
}) => IUsage;
|
|
749
|
+
|
|
750
|
+
type ToolConfig = Parameters<typeof tool>[0];
|
|
751
|
+
/**
|
|
752
|
+
* Define a host tool. Thin wrapper over the AI SDK `tool()`: pass a
|
|
753
|
+
* `description`, an `inputSchema` (a Zod schema or the result of `jsonSchema()`),
|
|
754
|
+
* and an `execute` function. The returned tool works unchanged on the native
|
|
755
|
+
* tool-calling path.
|
|
756
|
+
*
|
|
757
|
+
* Optionally add `promptHint` — a short parameter hint like
|
|
758
|
+
* "{ text: string, x?: number }" — which the prompted/salvage path shows to
|
|
759
|
+
* weak local models that can't do native function-calling.
|
|
760
|
+
*
|
|
761
|
+
* @example
|
|
762
|
+
* const tools = {
|
|
763
|
+
* add_text: defineTool({
|
|
764
|
+
* description: 'Add a text block to the page.',
|
|
765
|
+
* inputSchema: z.object({ text: z.string(), x: z.number().optional() }),
|
|
766
|
+
* promptHint: '{ text: string, x?: number }',
|
|
767
|
+
* execute: async ({ text, x }) => addTextBlock(text, x),
|
|
768
|
+
* }),
|
|
769
|
+
* }
|
|
770
|
+
*/
|
|
771
|
+
declare const defineTool: (config: ToolConfig & {
|
|
772
|
+
promptHint?: string;
|
|
773
|
+
}) => AgentTool;
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Render a ToolSet into a plain-text catalogue for the prompted/salvage path:
|
|
777
|
+
* `- name(hint): description`. The hint comes from `defineTool({ promptHint })`
|
|
778
|
+
* when present; weak local models lean on it to fill args correctly.
|
|
779
|
+
*/
|
|
780
|
+
declare const renderCatalog: (tools: AgentToolSet) => string;
|
|
781
|
+
interface DispatchContext {
|
|
782
|
+
abortSignal?: AbortSignal;
|
|
783
|
+
messages?: ModelMessage[];
|
|
784
|
+
toolCallId?: string;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Validate and execute a single salvaged tool call against the ToolSet, using
|
|
788
|
+
* the tool's OWN `execute` and `inputSchema` — the identical implementation the
|
|
789
|
+
* native path calls. Unknown tools, schema-invalid args, and thrown errors all
|
|
790
|
+
* become a failed IToolCall rather than throwing.
|
|
791
|
+
*/
|
|
792
|
+
declare const dispatch: (action: RawAction, tools: ToolSet, ctx?: DispatchContext) => Promise<IToolCall>;
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Decide the tool-calling strategy for a resolved model. An explicit
|
|
796
|
+
* config.toolMode of 'native'/'prompted' always wins; 'auto' (default) inspects
|
|
797
|
+
* the model's provider id — local/on-device runtimes → 'prompted', cloud → 'native'.
|
|
798
|
+
*/
|
|
799
|
+
declare const selectToolMode: (model: LanguageModel, mode?: ToolMode) => "native" | "prompted";
|
|
800
|
+
|
|
801
|
+
interface IndexedDBStoreOptions {
|
|
802
|
+
/** Database name, forwarded to the shared IDB owner (default 'agent-web'). */
|
|
803
|
+
dbName?: string;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* IndexedDB-backed transcript store — one record (message array) per session,
|
|
807
|
+
* in the shared `sessions` object store (see storage/db.ts). Also exposes
|
|
808
|
+
* session utilities: list and delete.
|
|
809
|
+
*/
|
|
810
|
+
declare class IndexedDBStore implements ContextStore {
|
|
811
|
+
private readonly dbName?;
|
|
812
|
+
constructor(opts?: IndexedDBStoreOptions);
|
|
813
|
+
load(sessionId: string): Promise<StoredMessage[]>;
|
|
814
|
+
replace(sessionId: string, messages: StoredMessage[]): Promise<void>;
|
|
815
|
+
append(sessionId: string, message: StoredMessage): Promise<void>;
|
|
816
|
+
clear(sessionId: string): Promise<void>;
|
|
817
|
+
/** List all stored session ids. */
|
|
818
|
+
listSessions(): Promise<string[]>;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
interface CompressOptions {
|
|
822
|
+
/** Compress once the transcript exceeds this many characters (0 = never). */
|
|
823
|
+
maxChars?: number;
|
|
824
|
+
/** How many most-recent messages to keep verbatim. */
|
|
825
|
+
keepRecent?: number;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* When the transcript grows too long, summarise everything except the last
|
|
829
|
+
* `keepRecent` messages into a single system message (via the model), so the
|
|
830
|
+
* session stays within the model's context window. Returns the same array
|
|
831
|
+
* unchanged when no compression is needed; never throws.
|
|
832
|
+
*/
|
|
833
|
+
declare const compressHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
|
|
834
|
+
|
|
835
|
+
export { type Agent, type AgentContext, type AgentEvent, type AgentEventHandler, 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, IndexedDBVault, KEYS_STORE, 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 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, type VaultOptions, type WebLLMModelOptions, buildModelFromStage, compressHistory, createAgent, createPlan, createWebLLMModel, decideReplan, decryptJSON, defaultPrompts, defineTool, directBrowserOk, dispatch, encryptJSON, executeStep, generate, generateStructured, getOrCreateVaultKey, isDirectModel, isProviderSpec, isWebGPUAvailable, looksLikeJson, normalizeSteps, normalizeUsage, openAgentWebDB, parseExecutorResponse, parsePlainText, parsePlannerResponse, parseReplannerResponse, promptHintOf, renderCatalog, resolveConfig, resolveModel, resolveStage, runToolLoop, selectToolMode, shouldReplan, splitBlocker, stream, supportsNativeTools, supportsStructuredOutput, synthesizeAnswer, withSystem };
|