agent-accelerator 0.6.0 → 0.6.5
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 +62 -16
- package/package.json +1 -1
- package/src/agent/agent.ts +96 -26
- package/src/agent/architecture.md +15 -12
- package/src/agent/context.ts +1 -0
- package/src/agent/defaults.ts +88 -0
- package/src/agent/delegation.ts +8 -3
- package/src/agent/loop.ts +34 -13
- package/src/agent/subagents-tool.ts +14 -21
- package/src/agent/usage-limit.ts +92 -0
- package/src/agent/worker.ts +17 -3
- package/src/agent/workers.ts +13 -1
- package/src/architecture.md +1 -0
- package/src/index.ts +9 -9
- package/src/prompts/additional-context.md +2 -0
- package/src/prompts/architecture.md +19 -0
- package/src/prompts/prompts.ts +81 -0
- package/src/prompts/reasoning-directive.md +5 -0
- package/src/prompts/structured-output.md +2 -0
- package/src/prompts/tool-bridge.md +1 -0
- package/src/prompts/tool-interrupted.md +1 -0
- package/src/prompts/tool-not-found.md +1 -0
- package/src/prompts/tool-repeat-blocked.md +1 -0
- package/src/prompts/tool-schema-error.md +1 -0
- package/src/prompts/tool-truncated-arguments.md +1 -0
- package/src/prompts/worker-failed.md +1 -0
- package/src/prompts/worker-replied.md +2 -0
- package/src/providers/architecture.md +8 -8
- package/src/providers/google.ts +82 -11
- package/src/providers/openai-compat.ts +17 -7
- package/src/providers/openai.ts +10 -4
- package/src/providers/openrouter.ts +185 -18
- package/src/providers.ts +59 -9
- package/src/scheduler/architecture.md +7 -7
- package/src/scheduler/scheduler.ts +40 -0
- package/src/scheduler/tool.ts +5 -9
- package/src/session/journal.ts +1 -0
- package/src/session/store.ts +4 -0
- package/src/tools/architecture.md +7 -6
- package/src/tools/executor.ts +60 -15
- package/src/tools/tool-content.ts +32 -0
- package/src/types/agent.ts +40 -6
- package/src/types/core.ts +4 -0
- package/src/types/message.ts +7 -0
- package/src/types/model.ts +4 -1
- package/src/types/scheduler.ts +4 -4
- package/src/types/tool.ts +2 -0
- package/src/utils/errors.ts +3 -3
- package/src/utils/headers.ts +1 -1
- /package/src/{scheduler/scheduled-actions.md → prompts/scheduled-actions-tool.md} +0 -0
- /package/src/{agent/subagents.md → prompts/subagents-tool.md} +0 -0
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Defining tools and running them.
|
|
4
4
|
|
|
5
|
-
| File | What it is
|
|
6
|
-
| :------------------- |
|
|
7
|
-
| `tool.ts` | `tool()` factory, name validation, `toStandardToolDeclarations`, option normalizers.
|
|
8
|
-
| `schema.ts` | Zod to JSON Schema, `$ref` resolution, `stripSchemaForGoogle`.
|
|
9
|
-
| `executor.ts` | `executeToolCalls`: validation, concurrency (8 global + per-tool), attempts, timeout, result cap, error scrubbing, `ctx.stop`, `tool.*` events, per-call logs.
|
|
10
|
-
| `
|
|
5
|
+
| File | What it is |
|
|
6
|
+
| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| `tool.ts` | `tool()` factory, name validation, `toStandardToolDeclarations`, option normalizers. |
|
|
8
|
+
| `schema.ts` | Zod to JSON Schema, `$ref` resolution, `stripSchemaForGoogle`. |
|
|
9
|
+
| `executor.ts` | `executeToolCalls`: validation, concurrency (8 global + per-tool), attempts, timeout, result cap, error scrubbing, `ctx.stop`, `tool.*` events, per-call logs. |
|
|
10
|
+
| `tool-content.ts` | `toolContent([...])`: a branded (private Symbol) tool result of text and media. The executor turns it into `result` (text) plus `parts` (inline data URLs), so only a tool's own code can produce media. |
|
|
11
|
+
| `subagent-result.ts` | The private-Symbol brand that marks a result as made by the SDK's delegation tools. |
|
|
11
12
|
|
|
12
13
|
## Invariants
|
|
13
14
|
|
package/src/tools/executor.ts
CHANGED
|
@@ -3,6 +3,10 @@ import { toJsonSafe } from "../utils/serialization.ts";
|
|
|
3
3
|
import { ConfigError } from "../types/errors.ts";
|
|
4
4
|
import { isTransientError } from "../utils/errors.ts";
|
|
5
5
|
import { isSubagentResult } from "./subagent-result.ts";
|
|
6
|
+
import { isToolContent, type ToolContent } from "./tool-content.ts";
|
|
7
|
+
import { normalizeMediaInput } from "../utils/media.ts";
|
|
8
|
+
import type { ContentPart } from "../types/message.ts";
|
|
9
|
+
import { DEFAULT_PROMPTS, fillPrompt, type Prompts } from "../prompts/prompts.ts";
|
|
6
10
|
import { isTruncatedArguments } from "../types/tool.ts";
|
|
7
11
|
import { telemetryBus } from "../telemetry.ts";
|
|
8
12
|
import type { ToolLogWriter } from "../session/tool-log.ts";
|
|
@@ -14,6 +18,8 @@ export interface ExecuteToolsOptions {
|
|
|
14
18
|
parallel?: boolean;
|
|
15
19
|
signal?: AbortSignal;
|
|
16
20
|
sessionId?: string;
|
|
21
|
+
/** The refusal texts shown to the model (`AgentConfig.prompts`); the shipped ones when unset. */
|
|
22
|
+
prompts?: Pick<Prompts, "toolTruncatedArguments" | "toolNotFound" | "toolSchemaError">;
|
|
17
23
|
/** Called the moment EACH call finishes (before the whole batch does), so a caller can save a result before the next tool is done. Never throws into the run. */
|
|
18
24
|
onResult?: (result: ToolResultRecord) => void;
|
|
19
25
|
/** Opens the log file of one call (only when the Agent persists to a folder); the executor writes its steps into it and `ctx.log` writes through it. */
|
|
@@ -232,10 +238,11 @@ export function shouldBlockRepeat(
|
|
|
232
238
|
* machine-readable code lives at `(result as any).errorCode` while the human
|
|
233
239
|
* prefix keeps plain-string consumers working.
|
|
234
240
|
*/
|
|
235
|
-
export function makeRepeatBlockedResult(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
export function makeRepeatBlockedResult(
|
|
242
|
+
call: ToolCallRecord,
|
|
243
|
+
template = DEFAULT_PROMPTS.toolRepeatBlocked
|
|
244
|
+
): ToolResultRecord {
|
|
245
|
+
const message = fillPrompt(template, { tool: call.name });
|
|
239
246
|
return {
|
|
240
247
|
id: call.id,
|
|
241
248
|
name: call.name,
|
|
@@ -477,6 +484,36 @@ async function executeAttempt(
|
|
|
477
484
|
}
|
|
478
485
|
}
|
|
479
486
|
|
|
487
|
+
// Turns a `toolContent` result into its text (what every provider sees) and its media as inline data URLs (what Google also sends); in: runSingle for a branded tool result, out: the result record's `result` and `parts`.
|
|
488
|
+
async function resolveToolContent(
|
|
489
|
+
content: ToolContent,
|
|
490
|
+
charLimit: number
|
|
491
|
+
): Promise<{ text: string; parts: ContentPart[] }> {
|
|
492
|
+
const texts: string[] = [];
|
|
493
|
+
const parts: ContentPart[] = [];
|
|
494
|
+
const kinds: string[] = [];
|
|
495
|
+
for (const raw of content.parts) {
|
|
496
|
+
const part = typeof raw === "string" ? ({ type: "text", text: raw } as const) : raw;
|
|
497
|
+
if (part.type === "text") {
|
|
498
|
+
texts.push(part.text);
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
const value = (part as unknown as Record<string, string | Uint8Array | ArrayBuffer>)[part.type]!;
|
|
502
|
+
const media = await normalizeMediaInput(value, (part as { mimeType?: string }).mimeType);
|
|
503
|
+
const filename = (part as { filename?: string }).filename;
|
|
504
|
+
parts.push({
|
|
505
|
+
type: part.type,
|
|
506
|
+
[part.type]: media.dataUrl,
|
|
507
|
+
mimeType: media.mimeType,
|
|
508
|
+
...(filename ? { filename } : {}),
|
|
509
|
+
...((part.type === "image" || part.type === "video") && part.resolution ? { resolution: part.resolution } : {}),
|
|
510
|
+
} as unknown as ContentPart);
|
|
511
|
+
kinds.push(media.mimeType);
|
|
512
|
+
}
|
|
513
|
+
const text = texts.join("\n") || (kinds.length > 0 ? `[media result: ${kinds.join(", ")}]` : "null");
|
|
514
|
+
return { text: truncateResultString(text, charLimit), parts };
|
|
515
|
+
}
|
|
516
|
+
|
|
480
517
|
/**
|
|
481
518
|
* Executes one or more tool calls in parallel or sequence, handling errors safely
|
|
482
519
|
*/
|
|
@@ -496,6 +533,7 @@ export async function executeToolCalls(options: ExecuteToolsOptions): Promise<To
|
|
|
496
533
|
onSubagentEvent,
|
|
497
534
|
onResult,
|
|
498
535
|
openToolLog,
|
|
536
|
+
prompts = DEFAULT_PROMPTS,
|
|
499
537
|
} = options;
|
|
500
538
|
assertNoToolCollisions(tools);
|
|
501
539
|
const globalSemaphore = new Semaphore(DEFAULT_TOOL_CONCURRENCY);
|
|
@@ -534,9 +572,7 @@ export async function executeToolCalls(options: ExecuteToolsOptions): Promise<To
|
|
|
534
572
|
return {
|
|
535
573
|
id: call.id,
|
|
536
574
|
name: call.name,
|
|
537
|
-
result:
|
|
538
|
-
`Error: Tool '${call.name}' arguments are truncated or incomplete and could not be parsed. ` +
|
|
539
|
-
"Call the tool again with the complete JSON arguments. Do not explain the error, just retry the call.",
|
|
575
|
+
result: fillPrompt(prompts.toolTruncatedArguments, { tool: call.name }),
|
|
540
576
|
isError: true,
|
|
541
577
|
durationMs: elapsedMs(startTime),
|
|
542
578
|
};
|
|
@@ -547,11 +583,11 @@ export async function executeToolCalls(options: ExecuteToolsOptions): Promise<To
|
|
|
547
583
|
|
|
548
584
|
if (!toolDef) {
|
|
549
585
|
trace("call_blocked", "warn", { reason: "tool_not_found", suggestion: resolved.suggestion });
|
|
550
|
-
const
|
|
586
|
+
const suggestion = resolved.suggestion ? ` Did you mean '${resolved.suggestion}'?` : "";
|
|
551
587
|
return {
|
|
552
588
|
id: call.id,
|
|
553
589
|
name: call.name,
|
|
554
|
-
result:
|
|
590
|
+
result: fillPrompt(prompts.toolNotFound, { tool: call.name, suggestion }),
|
|
555
591
|
isError: true,
|
|
556
592
|
durationMs: elapsedMs(startTime),
|
|
557
593
|
};
|
|
@@ -614,16 +650,12 @@ export async function executeToolCalls(options: ExecuteToolsOptions): Promise<To
|
|
|
614
650
|
? JSON.stringify(toolDef.parameters).slice(0, 800)
|
|
615
651
|
: undefined;
|
|
616
652
|
const detail = parseRes.error.message;
|
|
617
|
-
const
|
|
653
|
+
const expected = expectedParams ? ` Expected parameters: ${expectedParams}.` : "";
|
|
618
654
|
trace("call_blocked", "warn", { reason: "schema_validation", detail: parseRes.error.message });
|
|
619
655
|
return {
|
|
620
656
|
id: call.id,
|
|
621
657
|
name: call.name,
|
|
622
|
-
result:
|
|
623
|
-
`Schema validation error for tool '${call.name}': ${detail}` +
|
|
624
|
-
` Received argument keys: [${receivedKeys}].` +
|
|
625
|
-
hint +
|
|
626
|
-
` Fix the arguments and call the tool again with corrected JSON. Do not explain the error, just retry the call.`,
|
|
658
|
+
result: fillPrompt(prompts.toolSchemaError, { tool: call.name, detail, keys: receivedKeys, expected }),
|
|
627
659
|
isError: true,
|
|
628
660
|
durationMs: elapsedMs(startTime),
|
|
629
661
|
};
|
|
@@ -692,6 +724,19 @@ export async function executeToolCalls(options: ExecuteToolsOptions): Promise<To
|
|
|
692
724
|
log?.write({ phase: "result", result: isSubagentResult(rawResult) ? rawResult.xml : toJsonSafe(rawResult) });
|
|
693
725
|
const finishOk = (resultChars: number): void =>
|
|
694
726
|
trace("call_succeeded", "info", { attempts: attempt, durationMs: elapsedMs(executionStartTime), resultChars });
|
|
727
|
+
// Text and media from `toolContent`: the text is the result, the media rides in `parts` (inline data, set only here).
|
|
728
|
+
if (isToolContent(rawResult)) {
|
|
729
|
+
const { text, parts } = await resolveToolContent(rawResult, resultCharLimit(toolDef));
|
|
730
|
+
finishOk(text.length);
|
|
731
|
+
return {
|
|
732
|
+
id: call.id,
|
|
733
|
+
name: resolved.name,
|
|
734
|
+
result: text,
|
|
735
|
+
...(parts.length > 0 ? { parts } : {}),
|
|
736
|
+
isError: false,
|
|
737
|
+
durationMs: elapsedMs(executionStartTime),
|
|
738
|
+
};
|
|
739
|
+
}
|
|
695
740
|
if (rawResult === undefined) {
|
|
696
741
|
finishOk(4);
|
|
697
742
|
return {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tool result made of text and media. A tool returns `toolContent([...])` when the model should SEE a file (a chart
|
|
3
|
+
* image, a scanned page, a recording) and not only read text about it. The brand is a private Symbol, so only the
|
|
4
|
+
* tool's own code can produce it: JSON a tool fetched from the web can never become media for the provider.
|
|
5
|
+
*/
|
|
6
|
+
import type { ContentPart } from "../types/message.ts";
|
|
7
|
+
|
|
8
|
+
/** Parts a tool may return: plain strings (text) and the usual text, image, audio, video and file parts. */
|
|
9
|
+
export type ToolContentPart = string | Extract<ContentPart, { type: "text" | "image" | "audio" | "video" | "file" }>;
|
|
10
|
+
|
|
11
|
+
const TOOL_CONTENT_BRAND: unique symbol = Symbol("agent-accelerator.tool-content") as never;
|
|
12
|
+
|
|
13
|
+
/** What `toolContent` returns; the executor turns it into a tool result with `parts`. */
|
|
14
|
+
export interface ToolContent {
|
|
15
|
+
readonly parts: ToolContentPart[];
|
|
16
|
+
readonly [TOOL_CONTENT_BRAND]: true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Wraps text and media for a tool's return value, e.g.
|
|
21
|
+
* `return toolContent(["instrument.jpg", { type: "image", image: bytes, mimeType: "image/jpeg" }])`.
|
|
22
|
+
* Media may be bytes, a data URL, a path or a URL (the tool's own code is trusted with these). Google passes the media
|
|
23
|
+
* to the model inside the function result; other providers get the text only, with one warning.
|
|
24
|
+
*/
|
|
25
|
+
export function toolContent(parts: ToolContentPart[]): ToolContent {
|
|
26
|
+
return { parts: [...parts], [TOOL_CONTENT_BRAND]: true };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** True only for values made by {@link toolContent}. */
|
|
30
|
+
export function isToolContent(value: unknown): value is ToolContent {
|
|
31
|
+
return !!value && typeof value === "object" && (value as Record<symbol, unknown>)[TOOL_CONTENT_BRAND] === true;
|
|
32
|
+
}
|
package/src/types/agent.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { ThinkingLevel, CacheOption, ServiceTier } from "./core.ts";
|
|
|
4
4
|
import type { ModelProviderInstance } from "../providers/registry.ts";
|
|
5
5
|
import type { Agent } from "../agent/agent.ts";
|
|
6
6
|
import type { z } from "zod";
|
|
7
|
+
import type { PromptOverrides } from "../prompts/prompts.ts";
|
|
7
8
|
|
|
8
9
|
// ---------------------------------------------------------------------------
|
|
9
10
|
// Canonical option types (all additive; nothing renamed).
|
|
@@ -43,7 +44,12 @@ export interface AgentLogger {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/** Canonical tool-selection control. String form is the portable subset. */
|
|
46
|
-
export type ToolChoiceOption =
|
|
47
|
+
export type ToolChoiceOption =
|
|
48
|
+
| "auto"
|
|
49
|
+
| "none"
|
|
50
|
+
| "required"
|
|
51
|
+
| "validated"
|
|
52
|
+
| { mode?: "auto" | "none" | "required" | "validated"; tool?: string };
|
|
47
53
|
|
|
48
54
|
/** Canonical structured-output input. Zod, JSON Schema, or explicit form. */
|
|
49
55
|
export type StructuredOutputOption =
|
|
@@ -149,7 +155,10 @@ export interface AgentConfig {
|
|
|
149
155
|
* Canonical tool-selection control (`"auto"` default). `"none"` applies to
|
|
150
156
|
* every turn of a run; `"required"` and a pinned tool (`{ tool: "name" }`)
|
|
151
157
|
* apply to the FIRST model turn only, since forcing a tool call on every
|
|
152
|
-
* turn would make a run unable to finish.
|
|
158
|
+
* turn would make a run unable to finish. `"validated"` (Google only) lets the
|
|
159
|
+
* model decide whether to call a tool but makes it keep every call valid against
|
|
160
|
+
* the tool's schema; it holds for the whole run. Other providers ignore it
|
|
161
|
+
* with one warning.
|
|
153
162
|
*/
|
|
154
163
|
toolChoice?: ToolChoiceOption;
|
|
155
164
|
/** Google Interactions storage tier for the chain-TTL gate: `"free"` (23h, default) or `"paid"` (54d). */
|
|
@@ -215,12 +224,29 @@ export interface AgentConfig {
|
|
|
215
224
|
budget?: Budget;
|
|
216
225
|
/** Run + network limits. Turn/budget caps unlimited by default; network timeouts finite. */
|
|
217
226
|
limits?: AgentRunLimits;
|
|
227
|
+
/**
|
|
228
|
+
* A spending cap for the WHOLE chat, for its whole life: what the agent, all its workers (the `subagents` tool,
|
|
229
|
+
* `agent.workers` at any depth, fixed `subagents`) and their model calls cost, added up. It survives restarts: a
|
|
230
|
+
* persisted agent starts from what its saved sessions already spent. Once the total reaches `maxCostUsd` or
|
|
231
|
+
* `maxTotalTokens`, the next model call anywhere in the chat throws a `BudgetExceededError` ("Usage limit reached").
|
|
232
|
+
* Unlike `budget` (per run) it never resets. Scheduled actions are separate and never count. Models with unknown
|
|
233
|
+
* pricing add tokens but $0 to the cost. Unset = no cap.
|
|
234
|
+
*/
|
|
235
|
+
usageLimit?: Pick<Budget, "maxCostUsd" | "maxTotalTokens">;
|
|
218
236
|
/**
|
|
219
237
|
* The only models this agent may use, as `provider/model` strings compared as written. Unset (default) = any model.
|
|
220
238
|
* Checked when the Agent is built (also for a config an agent edited through {@link Agent.fromConfig}); a model
|
|
221
239
|
* outside the list throws a `ConfigError`. Workers and `subagentModel` are not affected.
|
|
222
240
|
*/
|
|
223
241
|
allowedModels?: string[];
|
|
242
|
+
/**
|
|
243
|
+
* Replaces single prompts the SDK puts in front of the model (the reasoning directive, tool refusals, the worker
|
|
244
|
+
* headers, the tool manuals ...). Every prompt you leave out keeps its default; see `DEFAULT_PROMPTS` for the names, the
|
|
245
|
+
* shipped text and the `{{placeholders}}` the SDK fills in. Keeping the original text is recommended: it is what the SDK
|
|
246
|
+
* is tested with, and a good reference for writing your own. Workers inherit it. A prompt is part of the cached prompt
|
|
247
|
+
* prefix when it is in the system prompt or a tool description, so change it once, not per run.
|
|
248
|
+
*/
|
|
249
|
+
prompts?: PromptOverrides;
|
|
224
250
|
}
|
|
225
251
|
|
|
226
252
|
/**
|
|
@@ -301,12 +327,20 @@ export interface DynamicSubagentsConfig {
|
|
|
301
327
|
/** Fixed reasoning level for all dynamic workers. The Main Agent cannot override it. Falls back to the parent level when omitted. */
|
|
302
328
|
thinkingLevel?: ThinkingLevel;
|
|
303
329
|
/**
|
|
304
|
-
* Spending cap of EACH worker (the `subagents` tool
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
330
|
+
* Spending cap of EACH chat worker (the `subagents` tool and `agent.workers`), set as that worker's own per-run
|
|
331
|
+
* `budget`: a spawn or a message is one run, and the usage of the worker's own workers counts toward it. Exceeding it
|
|
332
|
+
* fails that call with a budget error and leaves the worker open. Default: unlimited. Models with unknown pricing count
|
|
333
|
+
* $0 toward `maxCostUsd`. Passed down to the workers' own workers. Scheduled actions have their own cap:
|
|
334
|
+
* `scheduledActionBudget`.
|
|
308
335
|
*/
|
|
309
336
|
workerBudget?: Pick<Budget, "maxCostUsd" | "maxTotalTokens">;
|
|
337
|
+
/**
|
|
338
|
+
* Spending cap of EACH scheduled-action run, set as that run's own per-run `budget` (attempts included: a retry is part
|
|
339
|
+
* of the same run). Scheduled actions are detached from the chat, so neither `workerBudget` nor `usageLimit` applies to
|
|
340
|
+
* them. Exceeding it records a failed run. Default: unlimited. Models with unknown pricing count $0 toward
|
|
341
|
+
* `maxCostUsd`.
|
|
342
|
+
*/
|
|
343
|
+
scheduledActionBudget?: Pick<Budget, "maxCostUsd" | "maxTotalTokens">;
|
|
310
344
|
/**
|
|
311
345
|
* How many levels of workers may exist below this agent. Default: no limit. `1` = workers cannot start workers of their
|
|
312
346
|
* own; `3` = a worker may start workers that start workers. A worker with levels left gets its own `subagents` tool, and
|
package/src/types/core.ts
CHANGED
|
@@ -42,6 +42,10 @@ export interface TokenUsage {
|
|
|
42
42
|
cacheReadTokens?: number;
|
|
43
43
|
cacheWriteTokens?: number;
|
|
44
44
|
thinkingTokens?: number;
|
|
45
|
+
/** Media part of `inputTokens` (a subset, report only: pricing never reads it). OpenRouter reports audio and video. */
|
|
46
|
+
inputDetails?: { audioTokens?: number; videoTokens?: number };
|
|
47
|
+
/** Media part of `outputTokens` (a subset, report only). OpenRouter reports audio and image. */
|
|
48
|
+
outputDetails?: { audioTokens?: number; imageTokens?: number };
|
|
45
49
|
cost?: {
|
|
46
50
|
inputCost?: number;
|
|
47
51
|
outputCost?: number;
|
package/src/types/message.ts
CHANGED
|
@@ -12,6 +12,9 @@ export interface TextPart {
|
|
|
12
12
|
/** Detail level a provider spends on one image or video (more detail = more input tokens). Google (images and videos) and OpenRouter (images, as `image_url.detail`) honour it; other providers ignore it with a warning. */
|
|
13
13
|
export type MediaResolution = "low" | "medium" | "high" | "ultra_high";
|
|
14
14
|
|
|
15
|
+
/** How a provider reads a video: `"static"` (fixed-rate frames, the default) or `"agentic"` (the model navigates the timeline and loads only what the prompt needs). Only Google honours it, and agentic mode only on some Gemini models; other providers ignore it with a warning. */
|
|
16
|
+
export type VideoProcessing = "static" | "agentic";
|
|
17
|
+
|
|
15
18
|
/** Image content accepted as a URL, data, path, or binary value. */
|
|
16
19
|
export interface ImagePart {
|
|
17
20
|
type: "image";
|
|
@@ -55,6 +58,8 @@ export interface VideoPart {
|
|
|
55
58
|
mimeType?: string;
|
|
56
59
|
/** Detail level per frame (Google: `low`/`medium` 70, `high` 280 tokens). */
|
|
57
60
|
resolution?: MediaResolution;
|
|
61
|
+
/** How the video is read (Google: `"agentic"` lets the model explore a long video instead of loading every frame). */
|
|
62
|
+
processing?: VideoProcessing;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/** Assistant-generated structured tool invocation. */
|
|
@@ -89,6 +94,8 @@ export interface ToolResultPart {
|
|
|
89
94
|
logFile?: string;
|
|
90
95
|
/** The tool ended the run with `ctx.stop(reason)` (see `ToolExecutionContext.stop`). */
|
|
91
96
|
stopped?: boolean;
|
|
97
|
+
/** Media the tool returned with `toolContent` (inline data URLs; `result` holds its text). Google sends it to the model. */
|
|
98
|
+
parts?: ContentPart[];
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
/** Provider reasoning/thinking content. */
|
package/src/types/model.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ThinkingConfig, CacheOption, ServiceTier, TokenUsage } from "./cor
|
|
|
2
2
|
import type { ProviderContext, ProviderSteps } from "./message.ts";
|
|
3
3
|
import type { StandardToolDeclaration, ToolCallRecord } from "./tool.ts";
|
|
4
4
|
import type { AssistantMessageEventStream } from "../streaming/event-stream.ts";
|
|
5
|
+
import type { Prompts } from "../prompts/prompts.ts";
|
|
5
6
|
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
8
|
// Provider identity — battle-tested: matches models.dev provider keys
|
|
@@ -169,7 +170,7 @@ export interface ProviderRequestOptions {
|
|
|
169
170
|
cache?: CacheOption;
|
|
170
171
|
serviceTier?: ServiceTier;
|
|
171
172
|
tools?: StandardToolDeclaration[];
|
|
172
|
-
toolChoice?: "auto" | "none" | "required" | { type: "function"; function: { name: string } };
|
|
173
|
+
toolChoice?: "auto" | "none" | "required" | "validated" | { type: "function"; function: { name: string } };
|
|
173
174
|
signal?: AbortSignal;
|
|
174
175
|
sessionId?: string;
|
|
175
176
|
env?: Record<string, string>;
|
|
@@ -187,6 +188,8 @@ export interface ProviderRequestOptions {
|
|
|
187
188
|
maxOutputTokens?: number;
|
|
188
189
|
/** `fetch` implementation used for the provider request (defaults to global `fetch`). */
|
|
189
190
|
fetch?: typeof fetch;
|
|
191
|
+
/** The SDK prompts adapters put in a request (`AgentConfig.prompts`); defaults when unset. */
|
|
192
|
+
prompts?: Pick<Prompts, "structuredOutput" | "toolBridge">;
|
|
190
193
|
/** Base backoff delay in ms for provider retries (default 250). */
|
|
191
194
|
retryBaseDelayMs?: number;
|
|
192
195
|
/** Total time budget in ms for provider retries (default 30000). */
|
package/src/types/scheduler.ts
CHANGED
|
@@ -18,12 +18,12 @@ export interface ScheduleSpec {
|
|
|
18
18
|
/**
|
|
19
19
|
* What happens when the host program was not running at a delivery time. `"skip"`: move on to the next time (a one-shot
|
|
20
20
|
* is done). `"run"`: run it as soon as the program is back. Omitted: the action is marked `missed` and waits for
|
|
21
|
-
* `
|
|
21
|
+
* `agent.scheduled.run` or `agent.scheduled.skip`.
|
|
22
22
|
*/
|
|
23
23
|
onMissed?: "skip" | "run";
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/** What `
|
|
26
|
+
/** What `agent.scheduled.create` receives: dynamic sub-agent fields plus the schedule. */
|
|
27
27
|
export interface ScheduledActionInput {
|
|
28
28
|
role?: string;
|
|
29
29
|
instructions: string;
|
|
@@ -40,7 +40,7 @@ export interface ScheduledActionInput {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
/** What `
|
|
43
|
+
/** What `agent.scheduled.update` may change. `id` and the creating agent are immutable. */
|
|
44
44
|
export type ScheduledActionPatch = Partial<Omit<ScheduledActionInput, "scheduled_action">> & {
|
|
45
45
|
scheduled_action?: Partial<Omit<ScheduledActionInput["scheduled_action"], "id">>;
|
|
46
46
|
};
|
|
@@ -81,7 +81,7 @@ export interface ScheduledDelivery {
|
|
|
81
81
|
late: boolean;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/** Result of `
|
|
84
|
+
/** Result of `agent.scheduled.delete`. */
|
|
85
85
|
export type DeleteResult =
|
|
86
86
|
| { ok: true }
|
|
87
87
|
| { ok: false; reason: "not_found" }
|
package/src/types/tool.ts
CHANGED
|
@@ -153,6 +153,8 @@ export interface ToolResultRecord {
|
|
|
153
153
|
logFile?: string;
|
|
154
154
|
/** The tool ended the run with `ctx.stop(reason)`; `result` is the reason. */
|
|
155
155
|
stopped?: boolean;
|
|
156
|
+
/** Media returned with `toolContent`, as inline data URLs (`result` is its text). Set only by the executor. */
|
|
157
|
+
parts?: import("./message.ts").ContentPart[];
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
/**
|
package/src/utils/errors.ts
CHANGED
|
@@ -181,9 +181,9 @@ export function assertModalitiesSupported(context: ProviderContext, providerId:
|
|
|
181
181
|
* That wire has no video shape — only `input_text`/`input_image`/`input_file`
|
|
182
182
|
* exist in either vendor's Responses docs — so a video part sent as
|
|
183
183
|
* `input_file` lands in the router's document parser and 400s confusingly
|
|
184
|
-
* (`Failed to parse the file ... Provide a PDF document`, observed live
|
|
185
|
-
*
|
|
186
|
-
*
|
|
184
|
+
* (`Failed to parse the file ... Provide a PDF document`, observed live under
|
|
185
|
+
* the old OpenRouter Responses skin despite the catalog `video` flag, which is
|
|
186
|
+
* chat-transport oriented). Fail fast with
|
|
187
187
|
* a clear one-liner instead; video stays Gemini-only, and OpenRouter Chat
|
|
188
188
|
* Completions carries `video_url` natively (no guard there). Throws a `ValidationError`.
|
|
189
189
|
*/
|
package/src/utils/headers.ts
CHANGED
|
@@ -24,7 +24,7 @@ export function getPackageVersion(): string {
|
|
|
24
24
|
const v = (globalThis as any).process?.env?.npm_package_version;
|
|
25
25
|
if (typeof v === "string" && v) return v;
|
|
26
26
|
} catch {}
|
|
27
|
-
return "0.6.
|
|
27
|
+
return "0.6.5";
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// User-Agent string with version and platform; in: AGENT_ACCEL_USER_AGENT, out: a string.
|
|
File without changes
|
|
File without changes
|