agent-accelerator 0.1.0 → 0.3.0
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 +174 -123
- package/{SYSTEM_PROMPT_AGENT.md → examples/prompts/SYSTEM_PROMPT_AGENT.md} +1 -1
- package/package.json +14 -9
- package/src/agent/agent.ts +385 -73
- package/src/agent/context.ts +1 -0
- package/src/agent/delegation.ts +443 -30
- package/src/agent/loop.ts +183 -53
- package/src/data/README.md +6 -6
- package/src/index.ts +163 -46
- package/src/models/catalog-cache.ts +60 -9
- package/src/models/catalog.ts +55 -8
- package/src/providers/google.ts +926 -0
- package/src/providers/openai-compat.ts +1147 -0
- package/src/providers/openai.ts +959 -0
- package/src/providers/openrouter-responses.ts +949 -0
- package/src/providers/openrouter.ts +1037 -0
- package/src/{ai-sdk → providers}/registry.ts +43 -55
- package/src/providers.ts +492 -0
- package/src/session/store.ts +806 -0
- package/src/streaming/sse-parser.ts +6 -4
- package/src/tools/executor.ts +23 -7
- package/src/tools/schema.ts +21 -11
- package/src/types/agent.ts +33 -2
- package/src/types/core.ts +3 -2
- package/src/types/message.ts +5 -0
- package/src/types/model.ts +3 -7
- package/src/types/provider-payloads.ts +2 -84
- package/src/types/response.ts +24 -0
- package/src/types/tool.ts +8 -0
- package/src/update-models.ts +56 -0
- package/src/utils/cache.ts +1 -1
- package/src/utils/documents.ts +517 -0
- package/src/utils/env.ts +0 -7
- package/src/{ai-sdk → utils}/errors.ts +61 -2
- package/src/utils/headers.ts +10 -20
- package/src/utils/media.ts +5 -2
- package/src/utils/retry.ts +89 -0
- package/src/utils/serialization.ts +15 -0
- package/src/utils/session.ts +36 -0
- package/src/ai-sdk/converters.ts +0 -342
- package/src/ai-sdk/executor.ts +0 -454
- package/src/ai-sdk/index.ts +0 -55
- package/src/ai-sdk/model-provider.ts +0 -303
- package/src/ai-sdk/options.ts +0 -306
- package/src/ai-sdk/provider.ts +0 -415
- package/src/tokens/counter.ts +0 -136
- /package/{SYSTEM_PROMPT.md → examples/prompts/SYSTEM_PROMPT.md} +0 -0
- /package/{SYSTEM_PROMPT_TOOLS.md → examples/prompts/SYSTEM_PROMPT_TOOLS.md} +0 -0
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Agent Accelerator
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/agent-accelerator)
|
|
3
4
|
[](https://github.com/sashvat-bharat/agent-accelerator)
|
|
4
5
|
[](https://opensource.org/licenses/MIT)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
> **Stability notice:** Agent Accelerator is pre-1.0 and under active development. Public APIs, provider transports, and configuration options may still change in breaking ways between releases. For production use, please pin your dependency to an exact version.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
A thin, typed transport SDK for calling LLMs through a single `Agent` interface.
|
|
9
10
|
|
|
10
|
-
Agent Accelerator supports `google`, `
|
|
11
|
+
Agent Accelerator supports `google`, `openrouter`, `openai`, and any OpenAI-compatible endpoint using `{PREFIX}_API_KEY` and `{PREFIX}_BASE_URL`.
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
```ts
|
|
@@ -45,7 +46,7 @@ yarn add agent-accelerator
|
|
|
45
46
|
|
|
46
47
|
Requires `bun` or `node 22+`.
|
|
47
48
|
|
|
48
|
-
Core dependencies are `zod
|
|
49
|
+
Core dependencies are `zod` only. Document conversion additionally uses the optional `@firecrawl/anydoc` peer. All provider transports are native REST (`fetch`, no SDK).
|
|
49
50
|
|
|
50
51
|
---
|
|
51
52
|
|
|
@@ -53,7 +54,6 @@ Core dependencies are `zod`, `ai`, and selected `@ai-sdk/*` provider packages us
|
|
|
53
54
|
|
|
54
55
|
```bash
|
|
55
56
|
GEMINI_API_KEY=...
|
|
56
|
-
OPENCODE_API_KEY=...
|
|
57
57
|
OPENROUTER_API_KEY=...
|
|
58
58
|
OPENAI_API_KEY=...
|
|
59
59
|
# or OPENAI_BASE_API_KEY=...
|
|
@@ -126,15 +126,17 @@ An `Agent` holds :
|
|
|
126
126
|
| `subagents` | `SubAgent[] \| Agent[]` | Pre-defined workers. Each worker becomes a callable tool. Useful for fixed roles such as researcher or critic. |
|
|
127
127
|
| `subagentModel` | `string \| ModelSpec \| ModelProviderInstance` | Developer-only model for dynamically spawned workers. Never choosable by the Main Agent. Overridden by `dynamicSubagents.model`. Falls back to `SUB_AGENT_MODEL`. |
|
|
128
128
|
| `dynamicSubagents` | `DynamicSubagentsConfig` | Enables and constrains LLM-spawned stateless workers: `{ enabled, model?, maxSpawn?, thinkingLevel?, tools?, timeout? }`. See [Dynamic delegation](#dynamic-delegation). |
|
|
129
|
-
| `thinkingLevel` | `ThinkingLevel` | `none \| dynamic \| minimal \| low \| medium \| high \| xhigh`. Validated against the model catalog before a request. |
|
|
129
|
+
| `thinkingLevel` | `ThinkingLevel` | `none \| dynamic \| minimal \| low \| medium \| high \| xhigh \| max`. Validated against the model catalog before a request. |
|
|
130
130
|
| `cache` | `CacheConfig` | `{ retention, sessionId, cachedContentId, ttlSeconds }`. Controls cache reuse. |
|
|
131
131
|
| `serviceTier` | `"flex" \| "priority"` | Cost / priority routing where supported. Omit for standard routing. |
|
|
132
|
-
| `
|
|
132
|
+
| `bypassInputFileModality` | `boolean` | When `true`, `file` parts are converted client-side to Markdown for models lacking native support. Capable models still receive files natively. Defaults to `false`. |
|
|
133
|
+
| `maxTurns` | `number` | Maximum model → tool → model loops per `run`. Infinite by default (`0` or omitted = no limit). Hitting a finite limit with pending tool calls warns and sets `finishReason: "max_turns"`. |
|
|
133
134
|
| `sessionId` | `string` | Stable identifier used for cache affinity. Auto-generated when omitted. |
|
|
134
135
|
| `headers` | `Record<string,string>` | Additional headers merged into every request. |
|
|
135
136
|
| `apiKey` | `string` | Overrides environment-based API-key lookup for this agent. |
|
|
136
137
|
| `baseUrl` | `string` | Overrides the default endpoint for this agent. |
|
|
137
138
|
| `stateless` | `boolean` | When `true`, history is cleared before and after each `run`. Useful for one-shot evaluators. Defaults to `false`. |
|
|
139
|
+
| `persist` | `{ dir?: string; file?: string }` | Durable sessions: rewrites the session file after every step (user/assistant/tool/sub-agent). `{ dir }` uses `sessions/<sessionId>/session.json`, `{ file }` a single `.session.json`. Writes are atomic and never fail a turn. |
|
|
138
140
|
|
|
139
141
|
When `dynamicSubagents.enabled` is set without a resolvable worker model, construction throws `SubAgentModelError`.
|
|
140
142
|
|
|
@@ -145,6 +147,12 @@ await agent.run(prompt, opts?) // non-streaming, or streaming when opts.stream i
|
|
|
145
147
|
agent.ask(prompt, optsOrBool?) // string deltas when streaming, otherwise same as run
|
|
146
148
|
agent.stream(prompt, opts?) // AssistantMessageEventStream
|
|
147
149
|
agent.reset() // clears messages + signatures, keeps config
|
|
150
|
+
agent.exportSession(telemetry?) // storable snapshot for saveSessionFile
|
|
151
|
+
agent.importSession(saved) // restores messages + config from loadSessionFile
|
|
152
|
+
agent.track(trackingId) // live snapshot of one sub-agent worker (`NAME-{TrackingID}`)
|
|
153
|
+
agent.listTrackedSubAgents() // TrackingIDs of known workers
|
|
154
|
+
agent.subscribeToSubAgent(id, fn) // live worker updates, returns unsubscribe fn
|
|
155
|
+
agent.persistNow() // rewrites the persist target now (no-op unless persist is set)
|
|
148
156
|
```
|
|
149
157
|
|
|
150
158
|
`prompt` accepts `string | ContentPart[]`.
|
|
@@ -158,8 +166,9 @@ Use `ContentPart[]` when sending images, audio, or video alongside text.
|
|
|
158
166
|
| `stream` | When `true`, returns a stream instead of a regular response promise. |
|
|
159
167
|
| `onDelta(delta, event)` | Called for each text chunk. Use to render answers live. |
|
|
160
168
|
| `onThinkingDelta(delta, event)` | Called for each reasoning chunk. Use to render reasoning separately. |
|
|
161
|
-
| `onEvent(event)` | Called for every event: `text_delta`, `thinking_delta`, `tool_call_complete`, `tool_result`, `subagent_complete`, `usage`, `done`, and `error`. |
|
|
169
|
+
| `onEvent(event)` | Called for every event: `text_delta`, `thinking_delta`, `tool_call_complete`, `tool_result`, `subagent_complete`, `subagent_delta`, `usage`, `done`, and `error`. |
|
|
162
170
|
| `wrapThinking` | Wraps reasoning as `<think>\n...\n</think>\n\n`, allowing UIs to render it without maintaining separate state. |
|
|
171
|
+
| `onTurn(turn)` | Called after every model/tool turn with `{ turns, text?, thinking?, toolCalls?, toolResults? }`. Drives sub-agent step logs and persistence. |
|
|
163
172
|
| `additionalContext` | Added only to the current user turn. Keeps the system prompt stable for better caching. |
|
|
164
173
|
| `sessionId` | Per-run session override. |
|
|
165
174
|
| `headers` | Per-run header merge. |
|
|
@@ -289,6 +298,8 @@ A `spawn_subagents` tool is injected with the following task shape:
|
|
|
289
298
|
- `tools` — developer-owned pool. Workers get zero tools unless the Main Agent grants a per-task `tools` subset by name (unknown names are ignored), keeping worker context small.
|
|
290
299
|
- `timeout` (ms) — `0` = no limit, `-1` = the Main Agent sets a per-task `timeoutMs`, `>0` = fixed limit for every worker. Timed-out workers report an error entry; the rest of the batch still completes.
|
|
291
300
|
- Workers are stateless: one task in, one result out, then shut down. No history, no recursion. The Main Agent cannot choose worker models or reasoning levels.
|
|
301
|
+
- Worker names use UPPER-KEBAB (`HBM-PRICING-ANALYST`). Each worker gets a system-generated 32-char TrackingID, displayed as `NAME-{TrackingID}` (e.g. `HBM-PRICING-ANALYST-9f2c…`).
|
|
302
|
+
- Workers stream internally: thinking/text deltas update the worker trace live (`agent.track(id)`, `subscribeToSubAgent`) and surface on the parent stream as `subagent_delta` events.
|
|
292
303
|
|
|
293
304
|
```ts
|
|
294
305
|
const res = await agent.run("Audit auth pipeline and write a threat model");
|
|
@@ -327,11 +338,12 @@ const agent = new Agent({
|
|
|
327
338
|
|
|
328
339
|
### Tool Helpers
|
|
329
340
|
|
|
330
|
-
* `tool({ name?, description, input?, parameters?, strict?, timeoutMs?, maxTries?, maxConcurrency?, execute })` — creates a `ToolDefinition`. Provide either a Zod `input` schema or raw JSON `parameters`. `execute(input, ctx)` may return arbitrary values; results are converted safely for model context. `timeoutMs` defaults to `0` (no time limit) and is a best-effort event-loop deadline; `ctx.signal` enables cooperative cancellation. `maxTries` accepts a number or numeric string; a positive value is the total attempt limit, while `0`/omitted
|
|
341
|
+
* `tool({ name?, description, input?, parameters?, strict?, timeoutMs?, maxTries?, maxConcurrency?, execute })` — creates a `ToolDefinition`. Provide either a Zod `input` schema or raw JSON `parameters`. `execute(input, ctx)` may return arbitrary values; results are converted safely for model context. `timeoutMs` defaults to `0` (no time limit) and is a best-effort event-loop deadline; `ctx.signal` enables cooperative cancellation. `maxTries` accepts a number or numeric string; a positive value is the total attempt limit, while `0`/omitted falls back to 3 attempts. `maxConcurrency` limits simultaneous calls for that tool (default pool: 8).
|
|
331
342
|
* `toStandardToolDeclarations(record | array)` — converts tools to `{ name, description, parameters }` for providers.
|
|
332
343
|
* `zodToJsonSchema(schema)` — converts Zod schemas using native conversion with a fallback extractor.
|
|
333
344
|
* `cleanJsonSchema(schema)` — removes `$schema`, `$defs`, and `definitions`, resolves `$ref`, and preserves explicit `additionalProperties`.
|
|
334
345
|
* `executeToolCalls({ tools, toolCalls, agentName?, parallel?, signal?, sessionId? })` — executes tool calls. Calls validate Zod input, use bounded parallelism, enforce per-tool timeouts, retry transient failures, recover namespace/camel-case tool-name aliases, and return `ToolResultRecord[]`. Missing tools and aborts are represented as error results rather than thrown.
|
|
346
|
+
* `convert_document_to_markdown` — built-in tool that converts document files (PDF/Word/PowerPoint/Excel/OpenDocument/RTF/EPUB/CSV, local path or URL) to Markdown for models without native document parsing. Requires the optional `@firecrawl/anydoc` peer.
|
|
335
347
|
|
|
336
348
|
The agent loop also blocks an identical tool name and argument set when the model requests it in the immediately following turn. The synthetic error is returned to the model so it can reuse the prior result or change its arguments.
|
|
337
349
|
|
|
@@ -386,7 +398,8 @@ for (const result of response.toolResults) {
|
|
|
386
398
|
name,
|
|
387
399
|
arguments,
|
|
388
400
|
rawArguments?,
|
|
389
|
-
thoughtSignature
|
|
401
|
+
thoughtSignature?,
|
|
402
|
+
callId?,
|
|
390
403
|
}
|
|
391
404
|
```
|
|
392
405
|
|
|
@@ -408,7 +421,6 @@ for (const result of response.toolResults) {
|
|
|
408
421
|
First-class provider IDs are:
|
|
409
422
|
|
|
410
423
|
* `google`
|
|
411
|
-
* `opencode`
|
|
412
424
|
* `openrouter`
|
|
413
425
|
* `openai`
|
|
414
426
|
|
|
@@ -417,9 +429,6 @@ Any other provider prefix is treated as an OpenAI-compatible custom provider.
|
|
|
417
429
|
### Model Strings
|
|
418
430
|
|
|
419
431
|
* `"google/<id>"` → Google AI Studio at `generativelanguage.googleapis.com`.
|
|
420
|
-
* `"opencode/<id>"` → OpenCode Zen at `opencode.ai/zen/v1`.
|
|
421
|
-
* `"opencode-go/<id>"` → OpenCode Go endpoint.
|
|
422
|
-
* OpenCode automatically selects Chat vs Responses API. Claude models and models using `api=openai-responses` use Responses.
|
|
423
432
|
* `"openrouter/<scope>/<model>"` or `"scope/model:variant"` → OpenRouter.
|
|
424
433
|
* `"openai/<id>"` → OpenAI.
|
|
425
434
|
* `"groq/<id>"`, `"ollama/<id>"`, etc. → custom providers using `{PREFIX}_API_KEY` and `{PREFIX}_BASE_URL`. The API key is optional for local endpoints.
|
|
@@ -437,7 +446,7 @@ An unknown prefix with no catalog match still routes to a custom provider, allow
|
|
|
437
446
|
* `getProvider("groq")` → returns a cached provider and automatically creates a custom provider for unknown prefixes.
|
|
438
447
|
* `ensureCustomProvider(prefix, { baseUrl?, apiKey?, name? })` → gets or creates a custom provider. Useful for multiple endpoints in one process.
|
|
439
448
|
* `normalizeProviderPrefix(s)` → lowercases and trims a provider prefix.
|
|
440
|
-
* `ModelProvider.GoogleGenAI(model, apiKey?, { thinkingLevel?, baseUrl? })` — same shape is available for `.
|
|
449
|
+
* `ModelProvider.GoogleGenAI(model, apiKey?, { thinkingLevel?, baseUrl? })` — same shape is available for `.OpenRouter`, `.OpenAI`, `.Custom`, `.OpenAICompatible`, and `.Generic`.
|
|
441
450
|
|
|
442
451
|
Each returns a `ModelProviderInstance`:
|
|
443
452
|
|
|
@@ -472,93 +481,82 @@ new Agent({
|
|
|
472
481
|
});
|
|
473
482
|
```
|
|
474
483
|
|
|
475
|
-
`
|
|
484
|
+
`Provider` is the provider contract containing `id`, `name`, `models`, `getModel`, `generate`, and `stream`.
|
|
476
485
|
|
|
477
|
-
Its catalog-first `getModel` behavior includes a
|
|
486
|
+
Its catalog-first `getModel` behavior includes a permissive fallback (`createGenericModelSpec`) so private model IDs never fail preflight.
|
|
478
487
|
|
|
479
|
-
|
|
488
|
+
Implement the `Provider` interface when adding a fully custom transport.
|
|
480
489
|
|
|
481
490
|
`ProviderRequestOptions { apiKey?, baseUrl?, headers?, thinking?, cache?, serviceTier?, tools?, toolChoice?, signal?, sessionId?, env? }` is the per-call options object passed to `generate`/`stream`. Agent builds it automatically.
|
|
482
491
|
|
|
483
492
|
### Google
|
|
484
493
|
|
|
485
|
-
`GoogleAIStudioProvider` and `GOOGLE_MODELS` provide Google
|
|
494
|
+
`GoogleInteractionsProvider` (aliased as `GoogleAIStudioProvider`) and `GOOGLE_MODELS` provide Google support over the Interactions API (`POST {baseUrl}/interactions`, streaming via `?alt=sse`).
|
|
486
495
|
|
|
487
|
-
|
|
496
|
+
Turns chain statefully through `previous_interaction_id` per session, falling back to stateless full-history sends when the session switches providers or models.
|
|
488
497
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
Thinking levels map to:
|
|
498
|
+
Thinking levels map to `thinking_level`, with `thinking_summaries` enabled whenever thinking is active:
|
|
492
499
|
|
|
493
500
|
```text
|
|
494
|
-
|
|
501
|
+
minimal | low | medium | high (xhigh/max clamp to high; none is unsupported and omitted; dynamic omits)
|
|
495
502
|
```
|
|
496
503
|
|
|
497
504
|
Google-specific handling includes:
|
|
498
505
|
|
|
499
506
|
* Isolating `thoughtSignature` per part for prefix stability.
|
|
500
507
|
* Converting JSON Schema to OpenAPI 3.0 through `stripSchemaForGoogle`.
|
|
501
|
-
*
|
|
508
|
+
* Implicit/automatic caching only — explicit retention and `cachedContentId` are warned about and dropped (the Interactions API defines no explicit cache primitives).
|
|
502
509
|
|
|
503
510
|
Helpers:
|
|
504
511
|
|
|
505
512
|
* `createExplicitCache({ model, systemInstruction?, contents?, tools?, displayName?, ttlSeconds?, expireTime?, apiKey?, baseUrl? })`
|
|
506
513
|
* `isValidThoughtSignature(sig)`
|
|
507
514
|
* `retainThoughtSignature(existing, incoming)`
|
|
515
|
+
* `extractGoogleThoughtSignature(obj)`
|
|
508
516
|
* `stripSchemaForGoogle(schema)`
|
|
517
|
+
* `clearInteractionChains(sessionId?)`
|
|
509
518
|
|
|
510
519
|
### OpenAI
|
|
511
520
|
|
|
512
|
-
`OpenAIProvider` and `OPENAI_MODELS` provide OpenAI support.
|
|
521
|
+
`OpenAIResponsesProvider` (aliased as `OpenAIProvider`) and `OPENAI_MODELS` provide OpenAI support over the Responses API (`POST {baseUrl}/responses`).
|
|
513
522
|
|
|
514
|
-
|
|
523
|
+
Every turn is stateless: the full history is sent explicitly with `store: false`, so no `previous_response_id`, `background`, or conversation chaining is ever used.
|
|
515
524
|
|
|
516
|
-
Thinking levels map to:
|
|
525
|
+
Thinking levels map to `reasoning.effort` verbatim:
|
|
517
526
|
|
|
518
527
|
```text
|
|
519
|
-
|
|
528
|
+
none | minimal | low | medium | high | xhigh | max (dynamic omits — server default)
|
|
520
529
|
```
|
|
521
530
|
|
|
522
531
|
It also:
|
|
523
532
|
|
|
524
|
-
* passes `service_tier
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
|
|
529
|
-
### OpenCode
|
|
530
|
-
|
|
531
|
-
`OpenCodeProvider` and `OPENCODE_MODELS` provide OpenCode support.
|
|
532
|
-
|
|
533
|
-
Requests include:
|
|
534
|
-
|
|
535
|
-
* `session_id`
|
|
536
|
-
* `prompt_cache_key`
|
|
537
|
-
* headers used for sticky routing
|
|
538
|
-
|
|
539
|
-
The provider handles both Chat and Responses payloads.
|
|
540
|
-
|
|
541
|
-
Transient `500`, `502`, `503`, and `529` errors are retried with thinking disabled, followed by an attempt using the alternate endpoint.
|
|
533
|
+
* passes `service_tier` (`flex` | `priority`);
|
|
534
|
+
* pins cache affinity with `prompt_cache_key` (clamped to 64 chars);
|
|
535
|
+
* rejects `video` parts up front with a one-line error (the Responses wire carries text/image/file only);
|
|
536
|
+
* never sends `temperature`, token caps, or background/conversation fields.
|
|
542
537
|
|
|
543
538
|
### OpenRouter
|
|
544
539
|
|
|
545
|
-
`OpenRouterProvider` and `OPENROUTER_MODELS` provide OpenRouter support.
|
|
540
|
+
`OpenRouterChatCompletionsProvider` (aliased as `OpenRouterProvider` / `OpenRouter`) and `OPENROUTER_MODELS` provide OpenRouter support over Chat Completions (`POST {baseUrl}/chat/completions`).
|
|
546
541
|
|
|
547
|
-
|
|
542
|
+
Every turn is stateless: the full `messages[]` array is sent explicitly — no chaining primitives exist on this endpoint.
|
|
548
543
|
|
|
549
|
-
|
|
550
|
-
* `prompt_cache_key`
|
|
544
|
+
Session affinity is a top-level body `session_id` plus the `x-session-id` header fallback (body takes precedence per OpenRouter docs).
|
|
551
545
|
|
|
552
|
-
Thinking
|
|
546
|
+
Thinking levels map to `reasoning.effort` verbatim:
|
|
553
547
|
|
|
554
548
|
```text
|
|
555
|
-
|
|
556
|
-
include_reasoning
|
|
549
|
+
none | minimal | low | medium | high | xhigh | max (dynamic omits — server default)
|
|
557
550
|
```
|
|
558
551
|
|
|
559
|
-
|
|
552
|
+
It also:
|
|
553
|
+
|
|
554
|
+
* passes `service_tier` (`flex` | `priority`);
|
|
555
|
+
* enables the `file-parser` plugin when file parts are present (remote file URLs are additionally surfaced in text);
|
|
556
|
+
* maps `tool_choice` (`auto` omitted; `none`, `required`, and function pins supported);
|
|
557
|
+
* reports `cached_tokens` / `cache_write_tokens` / reasoning tokens, preferring provider-reported `cost` when present.
|
|
560
558
|
|
|
561
|
-
`serviceTier`
|
|
559
|
+
`serviceTier` values other than `flex` / `priority` are omitted (standard routing).
|
|
562
560
|
|
|
563
561
|
### Custom
|
|
564
562
|
|
|
@@ -588,7 +586,6 @@ Examples include:
|
|
|
588
586
|
|
|
589
587
|
* `OpenAIChatCompletionRequest`
|
|
590
588
|
* `GoogleGenerateContentRequest`
|
|
591
|
-
* `OpenCodeChatRequest`
|
|
592
589
|
* `OpenRouterChatRequest`
|
|
593
590
|
|
|
594
591
|
---
|
|
@@ -604,14 +601,15 @@ ThinkingLevel =
|
|
|
604
601
|
| "low"
|
|
605
602
|
| "medium"
|
|
606
603
|
| "high"
|
|
607
|
-
| "xhigh"
|
|
604
|
+
| "xhigh"
|
|
605
|
+
| "max";
|
|
608
606
|
```
|
|
609
607
|
|
|
610
608
|
### Thinking Levels
|
|
611
609
|
|
|
612
610
|
* `none` — disables thinking where supported.
|
|
613
611
|
* `dynamic` — allows the model to decide.
|
|
614
|
-
* `minimal`, `low`, `medium`, `high`, `xhigh` — request increasing levels of reasoning where supported.
|
|
612
|
+
* `minimal`, `low`, `medium`, `high`, `xhigh`, `max` — request increasing levels of reasoning where supported.
|
|
615
613
|
|
|
616
614
|
Thinking can be configured on the `Agent` or through `ModelProvider.*(..., { thinkingLevel })`.
|
|
617
615
|
|
|
@@ -632,6 +630,7 @@ ThinkingConfig {
|
|
|
632
630
|
|
|
633
631
|
* `getModelThinkingInfo(provider, modelId)` → `{ supportsThinking, reasoningOptions?, allowedLevels, supportsDisable, description }`. Useful for building UI selectors.
|
|
634
632
|
* `validateModelThinking(provider, modelId, level)` → throws `ThinkingLevelError { provider, modelId, requestedLevel, allowedLevels, supportsThinking }` with a fix hint. Automatically called by `run` and `stream`. Catch it and use `err.allowedLevels` to offer valid options.
|
|
633
|
+
* `resolveEffectiveThinking(base, override?)` → resolves a per-run `thinkingLevel` override into a `ThinkingConfig` without mutating agent config.
|
|
635
634
|
* `getModelsForProvider("google")` → returns known model specifications.
|
|
636
635
|
|
|
637
636
|
Unknown models allow all thinking levels.
|
|
@@ -660,40 +659,40 @@ CacheRetention =
|
|
|
660
659
|
|
|
661
660
|
### Retention
|
|
662
661
|
|
|
663
|
-
* `implicit` — automatic prefix reuse without an explicit cache object or storage fee.
|
|
664
|
-
* `short` —
|
|
665
|
-
* `medium` — approximately 1 hour.
|
|
666
|
-
* `long` — approximately 12 hours for Google explicit caches and approximately 24 hours for prompt caching where supported.
|
|
662
|
+
* `implicit` — automatic prefix reuse without an explicit cache object or storage fee. This is the only retention the native adapters act on (by doing nothing special — stable prompts plus session affinity do the work).
|
|
663
|
+
* `short` / `medium` / `long` — TTL hints (`5m` / `1h` / `12h`) consumed only by the opt-in `createExplicitCache` helper. Provider adapters warn about and drop any non-`implicit` retention: none of the native transports expose retention control.
|
|
667
664
|
|
|
668
665
|
### Session Affinity
|
|
669
666
|
|
|
670
667
|
`sessionId` pins provider affinity using mechanisms such as:
|
|
671
668
|
|
|
672
|
-
* `x-session-id`
|
|
673
|
-
*
|
|
674
|
-
* `prompt_cache_key`
|
|
669
|
+
* `x-session-id` (+ `x-client-request-id`) headers — all providers, best effort
|
|
670
|
+
* top-level body `session_id` — OpenRouter (takes precedence over the header)
|
|
671
|
+
* `prompt_cache_key` — OpenAI only (custom endpoints get headers only; strict ones reject unknown body fields)
|
|
675
672
|
|
|
676
673
|
Reuse the same session ID across turns when cache affinity is desired.
|
|
677
674
|
|
|
678
|
-
In browser runtimes
|
|
679
|
-
still flows via `promptCacheKey` provider options, never via headers.
|
|
675
|
+
In browser runtimes custom `x-*` headers are stripped to avoid CORS preflights: OpenAI keeps affinity through its body key, while custom endpoints lose affinity entirely on browsers.
|
|
680
676
|
|
|
681
677
|
### Explicit Caches
|
|
682
678
|
|
|
683
|
-
`
|
|
679
|
+
`createExplicitCache` mints a Google `cachedContents/...` resource directly (TTL via `retention`/`ttlSeconds`).
|
|
680
|
+
|
|
681
|
+
`cachedContentId` is accepted and carried in context, but no native adapter currently sends it — explicit references are warned about and dropped, so stable prompts plus session affinity remain the cache-reuse path.
|
|
684
682
|
|
|
685
683
|
`ttlSeconds` overrides the retention mapping.
|
|
686
684
|
|
|
687
685
|
### Provider Cache Mechanisms
|
|
688
686
|
|
|
689
|
-
* **Google** keeps system prompts and tools stable and isolates signatures.
|
|
690
|
-
* **
|
|
687
|
+
* **Google** keeps system prompts and tools stable and isolates signatures (implicit caching only).
|
|
688
|
+
* **OpenAI** pins affinity with `prompt_cache_key`.
|
|
689
|
+
* **OpenRouter** pins affinity with body `session_id` plus headers (sticky routing from the first request).
|
|
690
|
+
* **Custom endpoints** get headers-only affinity; anything else cache-related is warned about and dropped.
|
|
691
691
|
|
|
692
692
|
The following cache helpers are exported:
|
|
693
693
|
|
|
694
|
-
* `applyAnthropicCacheControl`
|
|
695
|
-
* `getCacheControlForRetention`
|
|
696
694
|
* `getPromptCacheRetention`
|
|
695
|
+
* `retentionToTtlSeconds`
|
|
697
696
|
* `clampCacheKey`
|
|
698
697
|
|
|
699
698
|
For the best cache reuse, keep `instructions` and the tool set stable. Put changing data in user messages or `additionalContext`.
|
|
@@ -741,6 +740,7 @@ StreamEvent {
|
|
|
741
740
|
toolCall?,
|
|
742
741
|
toolResult?,
|
|
743
742
|
subagent?,
|
|
743
|
+
subagentTrackingId?,
|
|
744
744
|
usage?,
|
|
745
745
|
responseId?,
|
|
746
746
|
finishReason?,
|
|
@@ -766,12 +766,13 @@ tool_call_delta
|
|
|
766
766
|
tool_call_complete
|
|
767
767
|
tool_result
|
|
768
768
|
subagent_complete
|
|
769
|
+
subagent_delta
|
|
769
770
|
usage
|
|
770
771
|
done
|
|
771
772
|
error
|
|
772
773
|
```
|
|
773
774
|
|
|
774
|
-
Emitted in practice: `start`, `text_delta`, `thinking_delta`, `tool_call_complete`, `tool_result`, `subagent_complete`, `usage`, `done`, `error`. The rest exist in the type for forward compatibility.
|
|
775
|
+
Emitted in practice: `start`, `text_delta`, `thinking_delta`, `tool_call_complete`, `tool_result`, `subagent_complete`, `subagent_delta`, `usage`, `done`, `error`. The rest exist in the type for forward compatibility.
|
|
775
776
|
|
|
776
777
|
Use:
|
|
777
778
|
|
|
@@ -779,6 +780,7 @@ Use:
|
|
|
779
780
|
* `thinking_delta` for reasoning output.
|
|
780
781
|
* `tool_call_complete` / `tool_result` for tool progress.
|
|
781
782
|
* `subagent_complete` for each completed worker during streaming multi-agent runs.
|
|
783
|
+
* `subagent_delta` for live worker thinking/text (`subagentTrackingId` + `delta`/`thinkingDelta` + partials). Render per-worker; never merge into the parent answer.
|
|
782
784
|
* `usage` for interim usage counts.
|
|
783
785
|
* `done` for final usage and completion information.
|
|
784
786
|
|
|
@@ -808,8 +810,6 @@ AgentResponse {
|
|
|
808
810
|
text,
|
|
809
811
|
thinking?,
|
|
810
812
|
thoughtSignature?,
|
|
811
|
-
thinkingSignature?,
|
|
812
|
-
textSignature?,
|
|
813
813
|
toolCalls,
|
|
814
814
|
toolResults,
|
|
815
815
|
subagents,
|
|
@@ -850,10 +850,33 @@ SubAgentExecutionMetadata {
|
|
|
850
850
|
toolCalls?,
|
|
851
851
|
raw?,
|
|
852
852
|
isError?,
|
|
853
|
-
error
|
|
853
|
+
error?,
|
|
854
|
+
trackingId?,
|
|
855
|
+
sessionId?,
|
|
856
|
+
parentSessionId?,
|
|
857
|
+
steps?
|
|
858
|
+
}
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
`finishReason` is `"max_turns"` when a finite `maxTurns` limit stopped the run with tool calls still pending (plus a console warning naming the dropped tools).
|
|
862
|
+
|
|
863
|
+
### SubAgentStep
|
|
864
|
+
|
|
865
|
+
```ts
|
|
866
|
+
SubAgentStep {
|
|
867
|
+
turn,
|
|
868
|
+
type, // "assistant" | "tool_call" | "tool_result"
|
|
869
|
+
name?,
|
|
870
|
+
text?,
|
|
871
|
+
thinking?,
|
|
872
|
+
isError?,
|
|
873
|
+
timestamp,
|
|
874
|
+
partial? // true while the worker is still streaming this step
|
|
854
875
|
}
|
|
855
876
|
```
|
|
856
877
|
|
|
878
|
+
`agent.track(id)` returns these live; `partial` entries finalize when the worker's turn completes.
|
|
879
|
+
|
|
857
880
|
### TokenUsage
|
|
858
881
|
|
|
859
882
|
```ts
|
|
@@ -930,8 +953,8 @@ const res = await agent.run([...]).catch(fail);
|
|
|
930
953
|
|
|
931
954
|
Agent Accelerator features an adaptive, dynamically synchronized model catalog powered by [models.dev](https://models.dev). To avoid shipping a bloated 4.4 MB static JSON file with production builds, the SDK employs a high-performance **12-hour TTL local caching architecture**:
|
|
932
955
|
|
|
933
|
-
- **Automated 12-Hour Cache Validation**: When `.run()`, `.ask()`, or `.stream()` executes, the runtime checks `src/data/models
|
|
934
|
-
- **Git & Package Safety**: The dynamic cache file (`src/data/models
|
|
956
|
+
- **Automated 12-Hour Cache Validation**: When `.run()`, `.ask()`, or `.stream()` executes, the runtime checks `src/data/models.dev.json`. If the cache timestamp is within 12 hours, it reads from disk with zero network delay. When the TTL expires, it transparently synchronizes with `https://models.dev/api.json`.
|
|
957
|
+
- **Git & Package Safety**: The dynamic cache file (`src/data/models.dev.json`) is gitignored and excluded from production packages.
|
|
935
958
|
|
|
936
959
|
### Developer Catalog Controls
|
|
937
960
|
|
|
@@ -958,9 +981,9 @@ console.log(status.modelCount, status.providerCount, status.isExpired);
|
|
|
958
981
|
### CLI Refresh
|
|
959
982
|
|
|
960
983
|
```bash
|
|
961
|
-
bun run update-models
|
|
962
|
-
bun
|
|
963
|
-
bun
|
|
984
|
+
bun run update-models # Refresh model catalog (force or expired)
|
|
985
|
+
bun src/update-models.ts --force # Force re-download
|
|
986
|
+
bun src/update-models.ts --ttl=24h # Refresh with custom TTL
|
|
964
987
|
```
|
|
965
988
|
|
|
966
989
|
Upstream data lags on some inputs (e.g. `gpt-4o` accepts audio). Record
|
|
@@ -1025,15 +1048,8 @@ ModelCapabilities {
|
|
|
1025
1048
|
}
|
|
1026
1049
|
```
|
|
1027
1050
|
|
|
1028
|
-
When estimated input exceeds the available context budget, `Agent` trims the oldest middle history using:
|
|
1029
|
-
|
|
1030
|
-
```text
|
|
1031
|
-
context * 0.9 - maxOutput
|
|
1032
|
-
```
|
|
1033
|
-
|
|
1034
|
-
The beginning of the conversation and the most recent tail are preserved.
|
|
1035
|
-
|
|
1036
1051
|
---
|
|
1052
|
+
|
|
1037
1053
|
## Messages and Media
|
|
1038
1054
|
|
|
1039
1055
|
### Message
|
|
@@ -1092,7 +1108,7 @@ Supported content parts include:
|
|
|
1092
1108
|
|
|
1093
1109
|
`inferMimeType(path)` infers the MIME type from a file extension.
|
|
1094
1110
|
|
|
1095
|
-
Media normalization is handled automatically by providers (mapped to
|
|
1111
|
+
Media normalization is handled automatically by providers (mapped to provider-native media shapes). Thinking traces are echoed in follow-up turns only where accepted — strict endpoints receive tool calls without `reasoning_content`.
|
|
1096
1112
|
|
|
1097
1113
|
Provider matrix: text + image + wav/mp3 audio + PDF work on all supported
|
|
1098
1114
|
providers. Video works on Gemini only.
|
|
@@ -1106,40 +1122,31 @@ its verdict surfaces as a concise error (see [Errors](#errors)). Verified
|
|
|
1106
1122
|
catalog corrections live in `MODALITY_OVERRIDES` (`src/models/catalog.ts`),
|
|
1107
1123
|
never in the gitignored snapshot.
|
|
1108
1124
|
|
|
1109
|
-
---
|
|
1110
|
-
## Tokens
|
|
1111
|
-
|
|
1112
|
-
Token counting is heuristic only.
|
|
1113
|
-
|
|
1114
|
-
Actual billing information comes from `res.usage`.
|
|
1115
|
-
|
|
1116
|
-
Available helpers:
|
|
1117
|
-
|
|
1118
|
-
* `countTokens(string | Message[] | ProviderContext)` — useful for preflight sizing and history trimming.
|
|
1119
|
-
* `estimateTokensFromText(text)`
|
|
1120
|
-
* `estimateTokensFromMessage(msg)`
|
|
1121
|
-
* `estimateTokensFromPart(part)`
|
|
1122
|
-
|
|
1123
1125
|
---
|
|
1124
1126
|
## Utils
|
|
1125
1127
|
|
|
1126
1128
|
* `createSessionId(prefix="accel")` — creates a UUID-based session ID clamped to 64 characters for affinity.
|
|
1129
|
+
* `createTrackingId()` — system-generated 32-char TrackingID for one sub-agent worker (`NAME-{TrackingID}`).
|
|
1130
|
+
* `createChildSessionId(parentId, tag)` / `createFixedChildSessionId(parentId, name)` / `isSessionDescendant(child, parent)` — provider-safe (≤64 chars) child session IDs with parent-hash lineage.
|
|
1127
1131
|
* `getEnv(key, fallback?)` — resolves an environment variable.
|
|
1128
1132
|
* `getApiKey(provider, explicit?, env?)` — resolves API keys using the configured environment lookup order.
|
|
1129
1133
|
* `buildSessionHeaders(provider, cache?, custom?, sessionId?)` — builds provider-specific affinity headers. Normally handled automatically.
|
|
1134
|
+
* `withRetries(fn, { maxRetries?, maxRetryDelayMs?, signal?, label? })` / `isTransientError(err)` — bounded retries for transient provider failures (defaults: 2 retries, 5s cap, aborts never retried).
|
|
1135
|
+
* `convertDocumentToMarkdown(input, { filename?, format?, mimeType?, maxChars? })` — converts PDF/Word/PowerPoint/Excel/OpenDocument/RTF/EPUB/CSV to Markdown via the optional `@firecrawl/anydoc` peer. Throws `DocumentConversionError` on failure.
|
|
1136
|
+
* `convert_document_to_markdown` — built-in model-callable version of the above (returns a `<Document>` envelope); auto-registered with `bypassInputFileModality: true`.
|
|
1130
1137
|
* `z` — re-exported from Zod so tools do not require a separate Zod import.
|
|
1131
1138
|
|
|
1132
1139
|
---
|
|
1133
1140
|
## Examples
|
|
1134
1141
|
|
|
1135
1142
|
```bash
|
|
1136
|
-
bun run examples/
|
|
1143
|
+
bun run examples/05-chat.ts
|
|
1137
1144
|
# persistent CLI, /model "..." /level <lvl> /help /exit
|
|
1138
1145
|
|
|
1139
|
-
bun run examples/
|
|
1146
|
+
bun run examples/04-sub-agents.ts
|
|
1140
1147
|
# fixed researcher + critic pipeline
|
|
1141
1148
|
|
|
1142
|
-
bun run examples/
|
|
1149
|
+
bun run examples/03-multi_agent.ts
|
|
1143
1150
|
# dynamic spawn_subagents demo
|
|
1144
1151
|
|
|
1145
1152
|
bun run examples/01-metadata.ts
|
|
@@ -1148,17 +1155,23 @@ bun run examples/01-metadata.ts
|
|
|
1148
1155
|
bun run examples/02-function_calling.ts
|
|
1149
1156
|
# single tool call
|
|
1150
1157
|
|
|
1151
|
-
bun run examples/
|
|
1158
|
+
bun run examples/06-multimodal_image.ts [./photo.png]
|
|
1152
1159
|
# image input (remote URL default, local path optional)
|
|
1153
1160
|
|
|
1154
1161
|
bun run examples/07-multimodal_audio.ts
|
|
1155
1162
|
# audio input
|
|
1156
1163
|
|
|
1157
|
-
bun run examples/
|
|
1164
|
+
bun run examples/09-multimodal_document.ts
|
|
1158
1165
|
# PDF/file input
|
|
1159
1166
|
|
|
1160
|
-
bun run examples/
|
|
1167
|
+
bun run examples/08-multimodal_video.ts
|
|
1161
1168
|
# video input (video-capable model required)
|
|
1169
|
+
|
|
1170
|
+
bun run examples/10-document_markdown.ts
|
|
1171
|
+
# document → Markdown preprocessing (any model, optional @firecrawl/anydoc peer)
|
|
1172
|
+
|
|
1173
|
+
bun run examples/11-session-identity.ts
|
|
1174
|
+
# sub-agent TrackingIDs, live worker boxes, lineage, track(), durable sessions
|
|
1162
1175
|
```
|
|
1163
1176
|
|
|
1164
1177
|
Every example ends its `run()` with `.catch(fail)` (`examples/_shared.ts`),
|
|
@@ -1167,17 +1180,54 @@ so failures print one line and exit `1` — no stack dumps.
|
|
|
1167
1180
|
The chat example persists conversations to:
|
|
1168
1181
|
|
|
1169
1182
|
```text
|
|
1170
|
-
|
|
1183
|
+
sessions/<sessionId>/session.json (+ media/ for images, audio, video, files)
|
|
1171
1184
|
```
|
|
1172
1185
|
|
|
1173
|
-
It resumes
|
|
1186
|
+
It resumes the most recent session on next launch (legacy `.session.json`/`.session.jsonl` files still load) and prints a resume banner:
|
|
1187
|
+
|
|
1188
|
+
```text
|
|
1189
|
+
↺ Previous session loaded • accel-1a2b… (.session.json) • 12 messages • google/gemini-3.5-flash-lite • total-CH82.4% • $0.013 total
|
|
1190
|
+
```
|
|
1174
1191
|
|
|
1175
|
-
It also displays per-turn:
|
|
1192
|
+
It also displays per-turn and session totals on one line:
|
|
1176
1193
|
|
|
1177
1194
|
```text
|
|
1178
|
-
|
|
1195
|
+
↑turn ↓turn CRturn turn-CH% | ↑total ↓total CRtotal total-CH% $total(+turn) ctx%/window
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
### Session persistence
|
|
1199
|
+
|
|
1200
|
+
```ts
|
|
1201
|
+
import {
|
|
1202
|
+
Agent,
|
|
1203
|
+
loadSessionFile,
|
|
1204
|
+
saveSessionFile,
|
|
1205
|
+
SessionTelemetry,
|
|
1206
|
+
formatSessionBanner,
|
|
1207
|
+
} from "agent-accelerator";
|
|
1208
|
+
|
|
1209
|
+
const saved = loadSessionFile(".session.json");
|
|
1210
|
+
const telemetry = SessionTelemetry.fromSaved(saved);
|
|
1211
|
+
|
|
1212
|
+
const agent = new Agent({
|
|
1213
|
+
model: saved?.model ?? process.env.MODEL,
|
|
1214
|
+
sessionId: saved?.sessionId,
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
if (saved) agent.importSession(saved);
|
|
1218
|
+
|
|
1219
|
+
const res = await agent.run("Hello");
|
|
1220
|
+
telemetry.add(res.usage, agent.modelStringOrSpec as string);
|
|
1221
|
+
saveSessionFile(".session.json", agent, telemetry);
|
|
1179
1222
|
```
|
|
1180
1223
|
|
|
1224
|
+
* `agent.exportSession(telemetry)` / `agent.importSession(saved)` round-trip messages, system prompt, model, thinking level, instructions, cache, worker model, and sub-agent traces without touching `AgentContext` internals.
|
|
1225
|
+
* `SessionTelemetry` accumulates `input / output / cacheRead / cacheWrite / reasoning / cost`, with clamped `turnHitRate()` / `totalHitRate()`, a dual `formatBar(res)`, and `formatSessionBanner(saved, telemetry, path)` for startup.
|
|
1226
|
+
* Files are pretty-printed JSON (2-space indent), written atomically (temp + rename). Cost prefers provider-reported totals and falls back to catalog pricing.
|
|
1227
|
+
* Binary media (bytes, data URLs, base64) is extracted to `media/` on save via `saveSessionDir("sessions", agent, telemetry)` → `sessions/<sessionId>/{session.json, media/*}`; remote URLs and local paths stay references. `loadSessionDir(dir)` resolves `media/…` refs back to absolute paths, and `findLatestSessionDir("sessions")` resumes the most recent session.
|
|
1228
|
+
* Sub-agent traces persist in a dedicated `subagents` section keyed by TrackingID (`{ trackingId, name, sessionId, parentSessionId, status, task, turns, usage, steps, text }`). Files stay lean: redundant `rawArguments` and repeated step text are dropped on save (rebuilt/kept live in memory).
|
|
1229
|
+
* With `persist: { dir }` or `{ file }`, the session file is rewritten after every step, so a crash loses at most the in-flight step.
|
|
1230
|
+
|
|
1181
1231
|
---
|
|
1182
1232
|
## Scripts and Structure
|
|
1183
1233
|
|
|
@@ -1193,20 +1243,21 @@ bun run update-models # refresh model catalog cache (supports --force, --ttl=24h
|
|
|
1193
1243
|
```text
|
|
1194
1244
|
src/
|
|
1195
1245
|
├── agent/ # Agent, context, loop, delegation, subagent
|
|
1196
|
-
├──
|
|
1246
|
+
├── session/ # Session persistence + telemetry (snapshots, hit rates, .session.json store)
|
|
1247
|
+
├── providers/ # native REST adapters (google/openai/openrouter/openai-compat) + registry + canonical contract
|
|
1197
1248
|
├── models/ # Dynamic catalog cache, parser, verified overrides
|
|
1198
1249
|
├── data/ # Dynamic model catalog cache (gitignored, excluded from bundle)
|
|
1199
1250
|
├── tools/ # tool(), schema, executor
|
|
1200
1251
|
├── streaming/ # event stream, SSE parser
|
|
1201
|
-
├── tokens/ # estimator
|
|
1202
1252
|
├── types/ # agent, core, message, model, response, tool
|
|
1203
|
-
└── utils/ # base64, cache, env, headers, media, serialization, session
|
|
1253
|
+
└── utils/ # base64, cache, env, headers, media, serialization, session, thought-signature, documents, retry, errors
|
|
1204
1254
|
examples/
|
|
1205
|
-
├── 01-metadata.ts 02-function_calling.ts 03-
|
|
1206
|
-
├── 04-
|
|
1207
|
-
├── 07-multimodal_audio.ts 08-
|
|
1208
|
-
├── 09-
|
|
1209
|
-
|
|
1255
|
+
├── 01-metadata.ts 02-function_calling.ts 03-multi_agent.ts
|
|
1256
|
+
├── 04-sub-agents.ts 05-chat.ts 06-multimodal_image.ts
|
|
1257
|
+
├── 07-multimodal_audio.ts 08-multimodal_video.ts
|
|
1258
|
+
├── 09-multimodal_document.ts 10-document_markdown.ts
|
|
1259
|
+
├── files/ prompts/ research-agent.ts _shared.ts
|
|
1260
|
+
test/ # unit + mocked-provider tests mirroring src/
|
|
1210
1261
|
```
|
|
1211
1262
|
|
|
1212
1263
|
---
|
|
@@ -5,7 +5,7 @@ You are an Agent — you evaluate user objectives and decide whether to solve th
|
|
|
5
5
|
- Single-focus, factual, code-generation, or conversational prompts → Answer directly, concisely, and completely.
|
|
6
6
|
- Do NOT spawn sub-agents for trivial, single-step tasks.
|
|
7
7
|
2. **Delegate**:
|
|
8
|
-
|
|
8
|
+
- Complex research, multi-angle analysis, deep technical trade-offs, or parallel explorations → Invoke `spawn_subagents` with 2 to 4 focused sub-agents in a single batched call.
|
|
9
9
|
- For each sub-agent define:
|
|
10
10
|
- `name`: `UPPER_SNAKE_CASE` identifier describing domain focus (e.g., `MARKET_ANALYST`, `SYSTEMS_ARCHITECT`).
|
|
11
11
|
- `role`: Distinct specialized persona.
|