@dudko.dev/agent-web 0.0.6 → 0.0.7
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/README.md +4 -1
- package/dist/agent-web.js +69 -61
- package/dist/agent-web.js.map +1 -1
- package/dist/index.cjs +107 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -43
- package/dist/index.d.ts +76 -43
- package/dist/index.js +106 -29
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,39 @@ import { LanguageModel, ToolSet, Tool, ModelMessage, generateText, streamText }
|
|
|
3
3
|
import { z, ZodType } from 'zod';
|
|
4
4
|
import { IDBPDatabase } from 'idb';
|
|
5
5
|
|
|
6
|
+
/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */
|
|
7
|
+
interface IPlanStep {
|
|
8
|
+
id: string;
|
|
9
|
+
description: string;
|
|
10
|
+
expectedOutcome?: string;
|
|
11
|
+
/** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */
|
|
12
|
+
suggestedTools?: string[];
|
|
13
|
+
/** Set by the pipeline when suggestedTools were named but all were unknown. */
|
|
14
|
+
requiresTools?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface IPlan {
|
|
17
|
+
thought: string;
|
|
18
|
+
steps: IPlanStep[];
|
|
19
|
+
}
|
|
20
|
+
interface IUsage {
|
|
21
|
+
inputTokens: number;
|
|
22
|
+
outputTokens: number;
|
|
23
|
+
totalTokens: number;
|
|
24
|
+
}
|
|
25
|
+
interface IToolCall {
|
|
26
|
+
name: string;
|
|
27
|
+
input: unknown;
|
|
28
|
+
output: unknown;
|
|
29
|
+
ok: boolean;
|
|
30
|
+
}
|
|
31
|
+
interface IStepResult {
|
|
32
|
+
step: IPlanStep;
|
|
33
|
+
summary: string;
|
|
34
|
+
toolCalls: IToolCall[];
|
|
35
|
+
/** True when the executor signalled it could not complete the step ([BLOCKER]). */
|
|
36
|
+
blocked: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
6
39
|
interface StoredMessage {
|
|
7
40
|
role: 'system' | 'user' | 'assistant';
|
|
8
41
|
content: string;
|
|
@@ -245,6 +278,15 @@ declare const promptHintOf: (tool: Tool) => string | undefined;
|
|
|
245
278
|
|
|
246
279
|
/** Force a tool-calling strategy, or let the agent pick per model ('auto'). */
|
|
247
280
|
type ToolMode = 'auto' | 'native' | 'prompted';
|
|
281
|
+
/**
|
|
282
|
+
* When to consult the replanner after an executed step (given `replan` is on):
|
|
283
|
+
* 'failure' — after a blocked step or a failed tool call (default);
|
|
284
|
+
* 'always' — after every step, so the replanner can react to problems the host
|
|
285
|
+
* surfaces via `describeState` (one extra model call per step);
|
|
286
|
+
* predicate — decides per step result; closes over host state if needed, and
|
|
287
|
+
* falls back to 'failure' behaviour if it throws.
|
|
288
|
+
*/
|
|
289
|
+
type ReplanTrigger = 'failure' | 'always' | ((result: IStepResult) => boolean | Promise<boolean>);
|
|
248
290
|
/**
|
|
249
291
|
* 'all' — the executor sees the full ToolSet on every step.
|
|
250
292
|
* 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner
|
|
@@ -292,7 +334,7 @@ interface BrowserAgentConfig {
|
|
|
292
334
|
sessionId?: string;
|
|
293
335
|
/** Hard cap on executed steps incl. replans (default 8). */
|
|
294
336
|
maxIterations?: number;
|
|
295
|
-
/** Cap on
|
|
337
|
+
/** Cap on tool-calling rounds inside one executor call, both modes (default 4). */
|
|
296
338
|
maxStepsPerTask?: number;
|
|
297
339
|
/** Cap on replanner "revise" decisions per run (default 2). */
|
|
298
340
|
maxRevisions?: number;
|
|
@@ -300,8 +342,10 @@ interface BrowserAgentConfig {
|
|
|
300
342
|
chatTimeoutMs?: number;
|
|
301
343
|
budgets?: PhaseBudgets;
|
|
302
344
|
temperature?: number;
|
|
303
|
-
/**
|
|
345
|
+
/** Master switch for the replan phase (default true). */
|
|
304
346
|
replan?: boolean;
|
|
347
|
+
/** What triggers the replanner when it is on (default 'failure'). */
|
|
348
|
+
replanAfter?: ReplanTrigger;
|
|
305
349
|
/** Write a final natural-language summary (default true). */
|
|
306
350
|
synthesize?: boolean;
|
|
307
351
|
/** Compress stored history past this many chars (0 = off, default 12000). */
|
|
@@ -323,45 +367,13 @@ interface ResolvedConfig {
|
|
|
323
367
|
budgets: Required<PhaseBudgets>;
|
|
324
368
|
temperature: number | undefined;
|
|
325
369
|
replan: boolean;
|
|
370
|
+
replanAfter: ReplanTrigger;
|
|
326
371
|
synthesize: boolean;
|
|
327
372
|
compressAfterChars: number;
|
|
328
373
|
logLevel: LogLevel;
|
|
329
374
|
}
|
|
330
375
|
declare const resolveConfig: (c: BrowserAgentConfig) => ResolvedConfig;
|
|
331
376
|
|
|
332
|
-
/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */
|
|
333
|
-
interface IPlanStep {
|
|
334
|
-
id: string;
|
|
335
|
-
description: string;
|
|
336
|
-
expectedOutcome?: string;
|
|
337
|
-
/** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */
|
|
338
|
-
suggestedTools?: string[];
|
|
339
|
-
/** Set by the pipeline when suggestedTools were named but all were unknown. */
|
|
340
|
-
requiresTools?: boolean;
|
|
341
|
-
}
|
|
342
|
-
interface IPlan {
|
|
343
|
-
thought: string;
|
|
344
|
-
steps: IPlanStep[];
|
|
345
|
-
}
|
|
346
|
-
interface IUsage {
|
|
347
|
-
inputTokens: number;
|
|
348
|
-
outputTokens: number;
|
|
349
|
-
totalTokens: number;
|
|
350
|
-
}
|
|
351
|
-
interface IToolCall {
|
|
352
|
-
name: string;
|
|
353
|
-
input: unknown;
|
|
354
|
-
output: unknown;
|
|
355
|
-
ok: boolean;
|
|
356
|
-
}
|
|
357
|
-
interface IStepResult {
|
|
358
|
-
step: IPlanStep;
|
|
359
|
-
summary: string;
|
|
360
|
-
toolCalls: IToolCall[];
|
|
361
|
-
/** True when the executor signalled it could not complete the step ([BLOCKER]). */
|
|
362
|
-
blocked: boolean;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
377
|
type ReplanMode = 'continue' | 'revise' | 'finish';
|
|
366
378
|
type Phase = 'plan' | 'execute' | 'replan' | 'synthesize';
|
|
367
379
|
/**
|
|
@@ -560,8 +572,28 @@ declare const executeStep: (ctx: AgentContext, goal: string, step: IPlanStep, in
|
|
|
560
572
|
result: IStepResult;
|
|
561
573
|
usage: IUsage;
|
|
562
574
|
}>;
|
|
563
|
-
/**
|
|
575
|
+
/**
|
|
576
|
+
* The replanner runs when a step was blocked or a tool call failed and stayed
|
|
577
|
+
* failed. A failure that a LATER call to the same tool retried successfully is
|
|
578
|
+
* resolved — the prompted feedback loop (and native multi-step) let the model
|
|
579
|
+
* self-correct within the step, so it must not force a replan.
|
|
580
|
+
*/
|
|
564
581
|
declare const shouldReplan: (result: IStepResult) => boolean;
|
|
582
|
+
/** Bound a host `replanAfter` predicate by the same watchdog/abort as a model call. */
|
|
583
|
+
interface ReplanWantedOptions {
|
|
584
|
+
signal?: AbortSignal;
|
|
585
|
+
timeoutMs?: number;
|
|
586
|
+
/** Called with whatever a host predicate threw before falling back to 'failure'. */
|
|
587
|
+
onError?: (err: unknown) => void;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Resolve the configured `replanAfter` trigger for one step result. 'failure'
|
|
591
|
+
* is the classic `shouldReplan`; 'always' consults the replanner after every
|
|
592
|
+
* step; a host predicate decides per result. A predicate that throws, rejects,
|
|
593
|
+
* or outlives the watchdog/abort falls back to 'failure' behaviour so a buggy
|
|
594
|
+
* or hung predicate can never stall the run (its throw is surfaced via onError).
|
|
595
|
+
*/
|
|
596
|
+
declare const replanWanted: (trigger: ReplanTrigger, result: IStepResult, opts?: ReplanWantedOptions) => Promise<boolean>;
|
|
565
597
|
|
|
566
598
|
/**
|
|
567
599
|
* Robust parsing of model output. Small in-browser models emit JSON wrapped in
|
|
@@ -803,7 +835,7 @@ interface ToolLoopOptions {
|
|
|
803
835
|
* them to the SDK's `activeTools`; prompted mode bounds `dispatch` to them.
|
|
804
836
|
*/
|
|
805
837
|
activeTools?: string[];
|
|
806
|
-
/**
|
|
838
|
+
/** Cap on tool-calling rounds within this call, in both modes (default 4). */
|
|
807
839
|
maxSteps?: number;
|
|
808
840
|
maxOutputTokens?: number;
|
|
809
841
|
temperature?: number;
|
|
@@ -817,11 +849,12 @@ interface ToolLoopResult {
|
|
|
817
849
|
usage: IUsage;
|
|
818
850
|
}
|
|
819
851
|
/**
|
|
820
|
-
* Run
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
852
|
+
* Run tool-calling in whichever mode the model needs, returning a normalised
|
|
853
|
+
* result. Native mode streams the SDK's multi-step function-calling; prompted
|
|
854
|
+
* mode salvages `{ reply, actions }` JSON out of plain text, dispatches each
|
|
855
|
+
* action through the tool's own execute, then feeds the TOOL RESULTS back and
|
|
856
|
+
* lets the model continue the same task — up to `maxSteps` rounds in both
|
|
857
|
+
* modes. Both modes call the exact same tool implementations.
|
|
825
858
|
*/
|
|
826
859
|
declare const runToolLoop: (model: LanguageModel, opts: ToolLoopOptions) => Promise<ToolLoopResult>;
|
|
827
860
|
|
|
@@ -926,4 +959,4 @@ interface CompressOptions {
|
|
|
926
959
|
*/
|
|
927
960
|
declare const compressHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
|
|
928
961
|
|
|
929
|
-
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, IndexedDBVault, 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 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, 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, resolveConfig, resolveModel, resolveStage, runToolLoop, selectToolMode, shouldReplan, splitBlocker, stream, supportsNativeTools, supportsStructuredOutput, synthesizeAnswer, unloadWebLLMModel, withSystem };
|
|
962
|
+
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, IndexedDBVault, 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, type 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,39 @@ import { LanguageModel, ToolSet, Tool, ModelMessage, generateText, streamText }
|
|
|
3
3
|
import { z, ZodType } from 'zod';
|
|
4
4
|
import { IDBPDatabase } from 'idb';
|
|
5
5
|
|
|
6
|
+
/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */
|
|
7
|
+
interface IPlanStep {
|
|
8
|
+
id: string;
|
|
9
|
+
description: string;
|
|
10
|
+
expectedOutcome?: string;
|
|
11
|
+
/** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */
|
|
12
|
+
suggestedTools?: string[];
|
|
13
|
+
/** Set by the pipeline when suggestedTools were named but all were unknown. */
|
|
14
|
+
requiresTools?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface IPlan {
|
|
17
|
+
thought: string;
|
|
18
|
+
steps: IPlanStep[];
|
|
19
|
+
}
|
|
20
|
+
interface IUsage {
|
|
21
|
+
inputTokens: number;
|
|
22
|
+
outputTokens: number;
|
|
23
|
+
totalTokens: number;
|
|
24
|
+
}
|
|
25
|
+
interface IToolCall {
|
|
26
|
+
name: string;
|
|
27
|
+
input: unknown;
|
|
28
|
+
output: unknown;
|
|
29
|
+
ok: boolean;
|
|
30
|
+
}
|
|
31
|
+
interface IStepResult {
|
|
32
|
+
step: IPlanStep;
|
|
33
|
+
summary: string;
|
|
34
|
+
toolCalls: IToolCall[];
|
|
35
|
+
/** True when the executor signalled it could not complete the step ([BLOCKER]). */
|
|
36
|
+
blocked: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
6
39
|
interface StoredMessage {
|
|
7
40
|
role: 'system' | 'user' | 'assistant';
|
|
8
41
|
content: string;
|
|
@@ -245,6 +278,15 @@ declare const promptHintOf: (tool: Tool) => string | undefined;
|
|
|
245
278
|
|
|
246
279
|
/** Force a tool-calling strategy, or let the agent pick per model ('auto'). */
|
|
247
280
|
type ToolMode = 'auto' | 'native' | 'prompted';
|
|
281
|
+
/**
|
|
282
|
+
* When to consult the replanner after an executed step (given `replan` is on):
|
|
283
|
+
* 'failure' — after a blocked step or a failed tool call (default);
|
|
284
|
+
* 'always' — after every step, so the replanner can react to problems the host
|
|
285
|
+
* surfaces via `describeState` (one extra model call per step);
|
|
286
|
+
* predicate — decides per step result; closes over host state if needed, and
|
|
287
|
+
* falls back to 'failure' behaviour if it throws.
|
|
288
|
+
*/
|
|
289
|
+
type ReplanTrigger = 'failure' | 'always' | ((result: IStepResult) => boolean | Promise<boolean>);
|
|
248
290
|
/**
|
|
249
291
|
* 'all' — the executor sees the full ToolSet on every step.
|
|
250
292
|
* 'plan-narrowed' — the executor sees only a step's suggestedTools (the planner
|
|
@@ -292,7 +334,7 @@ interface BrowserAgentConfig {
|
|
|
292
334
|
sessionId?: string;
|
|
293
335
|
/** Hard cap on executed steps incl. replans (default 8). */
|
|
294
336
|
maxIterations?: number;
|
|
295
|
-
/** Cap on
|
|
337
|
+
/** Cap on tool-calling rounds inside one executor call, both modes (default 4). */
|
|
296
338
|
maxStepsPerTask?: number;
|
|
297
339
|
/** Cap on replanner "revise" decisions per run (default 2). */
|
|
298
340
|
maxRevisions?: number;
|
|
@@ -300,8 +342,10 @@ interface BrowserAgentConfig {
|
|
|
300
342
|
chatTimeoutMs?: number;
|
|
301
343
|
budgets?: PhaseBudgets;
|
|
302
344
|
temperature?: number;
|
|
303
|
-
/**
|
|
345
|
+
/** Master switch for the replan phase (default true). */
|
|
304
346
|
replan?: boolean;
|
|
347
|
+
/** What triggers the replanner when it is on (default 'failure'). */
|
|
348
|
+
replanAfter?: ReplanTrigger;
|
|
305
349
|
/** Write a final natural-language summary (default true). */
|
|
306
350
|
synthesize?: boolean;
|
|
307
351
|
/** Compress stored history past this many chars (0 = off, default 12000). */
|
|
@@ -323,45 +367,13 @@ interface ResolvedConfig {
|
|
|
323
367
|
budgets: Required<PhaseBudgets>;
|
|
324
368
|
temperature: number | undefined;
|
|
325
369
|
replan: boolean;
|
|
370
|
+
replanAfter: ReplanTrigger;
|
|
326
371
|
synthesize: boolean;
|
|
327
372
|
compressAfterChars: number;
|
|
328
373
|
logLevel: LogLevel;
|
|
329
374
|
}
|
|
330
375
|
declare const resolveConfig: (c: BrowserAgentConfig) => ResolvedConfig;
|
|
331
376
|
|
|
332
|
-
/** A single step of a plan. Mirrors the Node sibling's IPlanStep. */
|
|
333
|
-
interface IPlanStep {
|
|
334
|
-
id: string;
|
|
335
|
-
description: string;
|
|
336
|
-
expectedOutcome?: string;
|
|
337
|
-
/** Tools the planner thinks this step needs (drives 'plan-narrowed' selection). */
|
|
338
|
-
suggestedTools?: string[];
|
|
339
|
-
/** Set by the pipeline when suggestedTools were named but all were unknown. */
|
|
340
|
-
requiresTools?: boolean;
|
|
341
|
-
}
|
|
342
|
-
interface IPlan {
|
|
343
|
-
thought: string;
|
|
344
|
-
steps: IPlanStep[];
|
|
345
|
-
}
|
|
346
|
-
interface IUsage {
|
|
347
|
-
inputTokens: number;
|
|
348
|
-
outputTokens: number;
|
|
349
|
-
totalTokens: number;
|
|
350
|
-
}
|
|
351
|
-
interface IToolCall {
|
|
352
|
-
name: string;
|
|
353
|
-
input: unknown;
|
|
354
|
-
output: unknown;
|
|
355
|
-
ok: boolean;
|
|
356
|
-
}
|
|
357
|
-
interface IStepResult {
|
|
358
|
-
step: IPlanStep;
|
|
359
|
-
summary: string;
|
|
360
|
-
toolCalls: IToolCall[];
|
|
361
|
-
/** True when the executor signalled it could not complete the step ([BLOCKER]). */
|
|
362
|
-
blocked: boolean;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
377
|
type ReplanMode = 'continue' | 'revise' | 'finish';
|
|
366
378
|
type Phase = 'plan' | 'execute' | 'replan' | 'synthesize';
|
|
367
379
|
/**
|
|
@@ -560,8 +572,28 @@ declare const executeStep: (ctx: AgentContext, goal: string, step: IPlanStep, in
|
|
|
560
572
|
result: IStepResult;
|
|
561
573
|
usage: IUsage;
|
|
562
574
|
}>;
|
|
563
|
-
/**
|
|
575
|
+
/**
|
|
576
|
+
* The replanner runs when a step was blocked or a tool call failed and stayed
|
|
577
|
+
* failed. A failure that a LATER call to the same tool retried successfully is
|
|
578
|
+
* resolved — the prompted feedback loop (and native multi-step) let the model
|
|
579
|
+
* self-correct within the step, so it must not force a replan.
|
|
580
|
+
*/
|
|
564
581
|
declare const shouldReplan: (result: IStepResult) => boolean;
|
|
582
|
+
/** Bound a host `replanAfter` predicate by the same watchdog/abort as a model call. */
|
|
583
|
+
interface ReplanWantedOptions {
|
|
584
|
+
signal?: AbortSignal;
|
|
585
|
+
timeoutMs?: number;
|
|
586
|
+
/** Called with whatever a host predicate threw before falling back to 'failure'. */
|
|
587
|
+
onError?: (err: unknown) => void;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Resolve the configured `replanAfter` trigger for one step result. 'failure'
|
|
591
|
+
* is the classic `shouldReplan`; 'always' consults the replanner after every
|
|
592
|
+
* step; a host predicate decides per result. A predicate that throws, rejects,
|
|
593
|
+
* or outlives the watchdog/abort falls back to 'failure' behaviour so a buggy
|
|
594
|
+
* or hung predicate can never stall the run (its throw is surfaced via onError).
|
|
595
|
+
*/
|
|
596
|
+
declare const replanWanted: (trigger: ReplanTrigger, result: IStepResult, opts?: ReplanWantedOptions) => Promise<boolean>;
|
|
565
597
|
|
|
566
598
|
/**
|
|
567
599
|
* Robust parsing of model output. Small in-browser models emit JSON wrapped in
|
|
@@ -803,7 +835,7 @@ interface ToolLoopOptions {
|
|
|
803
835
|
* them to the SDK's `activeTools`; prompted mode bounds `dispatch` to them.
|
|
804
836
|
*/
|
|
805
837
|
activeTools?: string[];
|
|
806
|
-
/**
|
|
838
|
+
/** Cap on tool-calling rounds within this call, in both modes (default 4). */
|
|
807
839
|
maxSteps?: number;
|
|
808
840
|
maxOutputTokens?: number;
|
|
809
841
|
temperature?: number;
|
|
@@ -817,11 +849,12 @@ interface ToolLoopResult {
|
|
|
817
849
|
usage: IUsage;
|
|
818
850
|
}
|
|
819
851
|
/**
|
|
820
|
-
* Run
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
852
|
+
* Run tool-calling in whichever mode the model needs, returning a normalised
|
|
853
|
+
* result. Native mode streams the SDK's multi-step function-calling; prompted
|
|
854
|
+
* mode salvages `{ reply, actions }` JSON out of plain text, dispatches each
|
|
855
|
+
* action through the tool's own execute, then feeds the TOOL RESULTS back and
|
|
856
|
+
* lets the model continue the same task — up to `maxSteps` rounds in both
|
|
857
|
+
* modes. Both modes call the exact same tool implementations.
|
|
825
858
|
*/
|
|
826
859
|
declare const runToolLoop: (model: LanguageModel, opts: ToolLoopOptions) => Promise<ToolLoopResult>;
|
|
827
860
|
|
|
@@ -926,4 +959,4 @@ interface CompressOptions {
|
|
|
926
959
|
*/
|
|
927
960
|
declare const compressHistory: (messages: StoredMessage[], model: LanguageModel, opts?: CompressOptions) => Promise<StoredMessage[]>;
|
|
928
961
|
|
|
929
|
-
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, IndexedDBVault, 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 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, 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, resolveConfig, resolveModel, resolveStage, runToolLoop, selectToolMode, shouldReplan, splitBlocker, stream, supportsNativeTools, supportsStructuredOutput, synthesizeAnswer, unloadWebLLMModel, withSystem };
|
|
962
|
+
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, IndexedDBVault, 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, type 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 };
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ var resolveConfig = (c) => ({
|
|
|
23
23
|
},
|
|
24
24
|
temperature: c.temperature,
|
|
25
25
|
replan: c.replan ?? true,
|
|
26
|
+
replanAfter: c.replanAfter ?? "failure",
|
|
26
27
|
synthesize: c.synthesize ?? true,
|
|
27
28
|
compressAfterChars: c.compressAfterChars ?? 12e3,
|
|
28
29
|
logLevel: c.logLevel ?? "warn"
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
} from "ai";
|
|
37
38
|
|
|
38
39
|
// src/llm/util.ts
|
|
40
|
+
var clip = (s, max) => s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
39
41
|
var promptOf = (opts) => opts.messages ? { messages: opts.messages } : { prompt: opts.prompt ?? "" };
|
|
40
42
|
var normalizeUsage = (u) => {
|
|
41
43
|
const inputTokens = u?.inputTokens ?? 0;
|
|
@@ -308,7 +310,6 @@ var stateBlock = (state) => state && state.trim() ? `
|
|
|
308
310
|
|
|
309
311
|
STATE:
|
|
310
312
|
${state}` : "";
|
|
311
|
-
var clip = (s, max) => s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
312
313
|
var historyBlock = (history) => {
|
|
313
314
|
if (!history || history.length === 0) return "";
|
|
314
315
|
const lines = history.slice(-8).map((m) => `${m.role}: ${clip(m.content, 400)}`);
|
|
@@ -341,8 +342,9 @@ Reply with a single JSON object, nothing else:
|
|
|
341
342
|
- "actions" are the tool calls for THIS step ([] if none are needed). Use ONLY tools from the TOOLS list; "args" must match the tool's parameters.
|
|
342
343
|
- Build on the current STATE \u2014 do not repeat work that is already there.
|
|
343
344
|
- "reply" is one short human sentence (no JSON) describing what you did.
|
|
345
|
+
- After your actions run you will see their TOOL RESULTS and may continue the same step; finish with "actions": [] once it is done.
|
|
344
346
|
- If you CANNOT complete the step, set "actions": [] and put the token [BLOCKER] in "reply" with a short reason.`;
|
|
345
|
-
var REPLANNER_NATIVE = `You are the REPLANNER. After
|
|
347
|
+
var REPLANNER_NATIVE = `You are the REPLANNER. After an executed step, decide whether to keep going, revise the remaining steps, or finish.
|
|
346
348
|
"continue": the remaining steps still fit. "revise": provide a better "plan" for the REMAINING work (never repeat done work). "finish": the goal is already met.
|
|
347
349
|
Judge from the current STATE vs the goal. Prefer "continue".`;
|
|
348
350
|
var REPLANNER_PROMPTED = `You are the REPLANNER. After each executed step you decide whether to keep going, revise the remaining steps, or finish.
|
|
@@ -476,6 +478,15 @@ import {
|
|
|
476
478
|
streamText as streamText2
|
|
477
479
|
} from "ai";
|
|
478
480
|
|
|
481
|
+
// src/agent/loop-types.ts
|
|
482
|
+
var BLOCKER = "[BLOCKER]";
|
|
483
|
+
var emptyUsage = () => ({ inputTokens: 0, outputTokens: 0, totalTokens: 0 });
|
|
484
|
+
var addUsage = (a, b) => ({
|
|
485
|
+
inputTokens: a.inputTokens + b.inputTokens,
|
|
486
|
+
outputTokens: a.outputTokens + b.outputTokens,
|
|
487
|
+
totalTokens: a.totalTokens + b.totalTokens
|
|
488
|
+
});
|
|
489
|
+
|
|
479
490
|
// src/parse.ts
|
|
480
491
|
var stripFences = (text) => (text || "").replace(/```(?:json)?/gi, "").trim();
|
|
481
492
|
var extractBalanced = (text, open) => {
|
|
@@ -674,34 +685,74 @@ var runNative = async (model, opts) => {
|
|
|
674
685
|
const [text, usage] = await Promise.all([result.text, result.usage]);
|
|
675
686
|
return { text: text.trim(), toolCalls, usage: normalizeUsage(usage) };
|
|
676
687
|
};
|
|
688
|
+
var asJson = (value) => {
|
|
689
|
+
try {
|
|
690
|
+
return JSON.stringify(value) ?? String(value);
|
|
691
|
+
} catch {
|
|
692
|
+
return String(value);
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
var toolResultsPrompt = (results) => {
|
|
696
|
+
const lines = results.map(
|
|
697
|
+
(r) => `- ${r.name} ${clip(asJson(r.input), 160)} \u2192 ${r.ok ? "ok" : "FAILED"}: ${clip(asJson(r.output), 400)}`
|
|
698
|
+
);
|
|
699
|
+
return `TOOL RESULTS:
|
|
700
|
+
${lines.join("\n")}
|
|
701
|
+
|
|
702
|
+
Continue THIS step using the results above. Reply with a single JSON object, nothing else:
|
|
703
|
+
{ "reply": string, "actions": [ { "tool": string, "args": object } ] }
|
|
704
|
+
- If the step is now complete: "actions": [] and a short outcome in "reply".
|
|
705
|
+
- Otherwise emit ONLY the remaining or corrective calls \u2014 never repeat a successful call.`;
|
|
706
|
+
};
|
|
677
707
|
var runPrompted = async (model, opts) => {
|
|
678
|
-
const
|
|
679
|
-
model,
|
|
680
|
-
system: opts.system,
|
|
681
|
-
...promptOf(opts),
|
|
682
|
-
maxOutputTokens: opts.maxOutputTokens,
|
|
683
|
-
temperature: opts.temperature,
|
|
684
|
-
abortSignal: timeoutSignal(opts.abortSignal, opts.timeoutMs)
|
|
685
|
-
});
|
|
686
|
-
const parsed = parseExecutorResponse(result.text);
|
|
687
|
-
if (parsed.reply) opts.callbacks?.onTextDelta?.(parsed.reply);
|
|
708
|
+
const maxRounds = Math.max(1, opts.maxSteps ?? 4);
|
|
688
709
|
const active = opts.activeTools;
|
|
689
710
|
const tools = active ? Object.fromEntries(Object.entries(opts.tools).filter(([name]) => active.includes(name))) : opts.tools;
|
|
711
|
+
const signal = timeoutSignal(opts.abortSignal, opts.timeoutMs);
|
|
712
|
+
const messages = opts.messages ? [...opts.messages] : [{ role: "user", content: opts.prompt ?? "" }];
|
|
690
713
|
const toolCalls = [];
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
714
|
+
const seen = /* @__PURE__ */ new Set();
|
|
715
|
+
let usage = emptyUsage();
|
|
716
|
+
let text = "";
|
|
717
|
+
for (let round = 1; round <= maxRounds; round += 1) {
|
|
718
|
+
if (signal?.aborted) break;
|
|
719
|
+
const result = await generateText2({
|
|
720
|
+
model,
|
|
721
|
+
system: opts.system,
|
|
722
|
+
messages,
|
|
723
|
+
maxOutputTokens: opts.maxOutputTokens,
|
|
724
|
+
temperature: opts.temperature,
|
|
725
|
+
abortSignal: signal
|
|
726
|
+
});
|
|
727
|
+
usage = addUsage(usage, normalizeUsage(result.usage));
|
|
728
|
+
const parsed = parseExecutorResponse(result.text);
|
|
729
|
+
text = parsed.reply;
|
|
730
|
+
if (parsed.reply.includes(BLOCKER)) break;
|
|
731
|
+
if (parsed.actions.length === 0) break;
|
|
732
|
+
const batch = asJson(parsed.actions);
|
|
733
|
+
if (seen.has(batch)) break;
|
|
734
|
+
seen.add(batch);
|
|
735
|
+
const results = [];
|
|
736
|
+
for (const action of parsed.actions) {
|
|
737
|
+
if (signal?.aborted) break;
|
|
738
|
+
opts.callbacks?.onToolCall?.(action.tool, action.args);
|
|
739
|
+
const rec = await dispatch(action, tools, { abortSignal: signal });
|
|
740
|
+
toolCalls.push(rec);
|
|
741
|
+
results.push(rec);
|
|
742
|
+
opts.callbacks?.onToolResult?.(rec.name, rec.output, rec.ok);
|
|
743
|
+
}
|
|
744
|
+
if (round === maxRounds || signal?.aborted) break;
|
|
745
|
+
messages.push({ role: "assistant", content: result.text });
|
|
746
|
+
messages.push({ role: "user", content: toolResultsPrompt(results) });
|
|
696
747
|
}
|
|
697
|
-
|
|
748
|
+
if (text) opts.callbacks?.onTextDelta?.(text);
|
|
749
|
+
return { text, toolCalls, usage };
|
|
698
750
|
};
|
|
699
751
|
|
|
700
752
|
// src/agent/internal.ts
|
|
701
753
|
var systemFor = (ctx, base) => withSystem(base, ctx.raw.systemPrompt);
|
|
702
754
|
|
|
703
755
|
// src/agent/executor.ts
|
|
704
|
-
var BLOCKER = "[BLOCKER]";
|
|
705
756
|
var splitBlocker = (raw) => {
|
|
706
757
|
if (!raw.includes(BLOCKER)) return { summary: raw.trim(), blocked: false };
|
|
707
758
|
return { summary: raw.split(BLOCKER).join("").trim(), blocked: true };
|
|
@@ -766,15 +817,35 @@ var executeStep = async (ctx, goal, step, index, total, done) => {
|
|
|
766
817
|
usage: loop.usage
|
|
767
818
|
};
|
|
768
819
|
};
|
|
769
|
-
var shouldReplan = (result) =>
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
820
|
+
var shouldReplan = (result) => {
|
|
821
|
+
if (result.blocked) return true;
|
|
822
|
+
const { toolCalls } = result;
|
|
823
|
+
return toolCalls.some(
|
|
824
|
+
(c, i) => !c.ok && !toolCalls.slice(i + 1).some((later) => later.ok && later.name === c.name)
|
|
825
|
+
);
|
|
826
|
+
};
|
|
827
|
+
var replanWanted = async (trigger, result, opts = {}) => {
|
|
828
|
+
if (trigger === "always") return true;
|
|
829
|
+
if (typeof trigger !== "function") return shouldReplan(result);
|
|
830
|
+
const fallback = () => shouldReplan(result);
|
|
831
|
+
const decided = (async () => {
|
|
832
|
+
try {
|
|
833
|
+
return Boolean(await trigger(result));
|
|
834
|
+
} catch (err) {
|
|
835
|
+
opts.onError?.(err);
|
|
836
|
+
return fallback();
|
|
837
|
+
}
|
|
838
|
+
})();
|
|
839
|
+
const guard = timeoutSignal(opts.signal, opts.timeoutMs);
|
|
840
|
+
if (!guard) return decided;
|
|
841
|
+
return Promise.race([
|
|
842
|
+
decided,
|
|
843
|
+
new Promise((resolve) => {
|
|
844
|
+
if (guard.aborted) resolve(fallback());
|
|
845
|
+
else guard.addEventListener("abort", () => resolve(fallback()), { once: true });
|
|
846
|
+
})
|
|
847
|
+
]);
|
|
848
|
+
};
|
|
778
849
|
|
|
779
850
|
// src/agent/schemas.ts
|
|
780
851
|
import { z } from "zod";
|
|
@@ -1127,7 +1198,12 @@ var createAgent = async (config) => {
|
|
|
1127
1198
|
done.push(
|
|
1128
1199
|
`${step.description} \u2014 ${applied} applied${failed ? `, ${failed} failed` : ""}${stepResult.blocked ? ", blocked" : ""}`
|
|
1129
1200
|
);
|
|
1130
|
-
|
|
1201
|
+
const wantReplan = cfg.replan && iter < cfg.maxIterations && revisions < cfg.maxRevisions && !isAborted() && await replanWanted(cfg.replanAfter, stepResult, {
|
|
1202
|
+
signal: ctx.signal,
|
|
1203
|
+
timeoutMs: cfg.chatTimeoutMs,
|
|
1204
|
+
onError: (err) => log.warn("replanAfter predicate threw \u2014 using the failure rule", err)
|
|
1205
|
+
});
|
|
1206
|
+
if (wantReplan && !isAborted()) {
|
|
1131
1207
|
const decision = await decideReplan(
|
|
1132
1208
|
ctx,
|
|
1133
1209
|
text,
|
|
@@ -1452,6 +1528,7 @@ export {
|
|
|
1452
1528
|
preloadWebLLMModel,
|
|
1453
1529
|
promptHintOf,
|
|
1454
1530
|
renderCatalog,
|
|
1531
|
+
replanWanted,
|
|
1455
1532
|
resolveConfig,
|
|
1456
1533
|
resolveModel,
|
|
1457
1534
|
resolveStage,
|