agent-accelerator 0.2.0 → 0.4.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 +94 -14
- package/package.json +1 -1
- package/src/agent/agent.ts +1010 -104
- package/src/agent/context.ts +35 -0
- package/src/agent/delegation.ts +758 -40
- package/src/agent/loop.ts +811 -102
- package/src/agent/subagent.ts +59 -0
- package/src/index.ts +186 -59
- package/src/models/catalog-cache.ts +68 -25
- package/src/models/catalog.ts +101 -21
- package/src/providers/google.ts +99 -39
- package/src/providers/openai-compat.ts +140 -80
- package/src/providers/openai.ts +149 -69
- package/src/providers/openrouter.ts +106 -71
- package/src/providers/registry.ts +16 -12
- package/src/providers/shared.ts +132 -0
- package/src/providers.ts +14 -13
- package/src/session/store.ts +1285 -0
- package/src/streaming/event-stream.ts +156 -41
- package/src/tools/executor.ts +252 -16
- package/src/tools/tool.ts +147 -3
- package/src/types/agent.ts +253 -2
- package/src/types/core.ts +2 -1
- package/src/types/errors.ts +133 -0
- package/src/types/model.ts +1 -1
- package/src/types/response.ts +150 -3
- package/src/types/tool.ts +71 -0
- package/src/update-models.ts +8 -2
- package/src/utils/cache.ts +68 -1
- package/src/utils/env.ts +2 -6
- package/src/utils/headers.ts +153 -19
- package/src/utils/retry.ts +27 -13
- package/src/utils/session.ts +320 -0
- package/src/providers/openrouter-responses.ts +0 -949
- package/src/types/provider-payloads.ts +0 -352
package/README.md
CHANGED
|
@@ -126,16 +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`.
|
|
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"`. |
|
|
134
134
|
| `sessionId` | `string` | Stable identifier used for cache affinity. Auto-generated when omitted. |
|
|
135
135
|
| `headers` | `Record<string,string>` | Additional headers merged into every request. |
|
|
136
136
|
| `apiKey` | `string` | Overrides environment-based API-key lookup for this agent. |
|
|
137
137
|
| `baseUrl` | `string` | Overrides the default endpoint for this agent. |
|
|
138
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. |
|
|
139
140
|
|
|
140
141
|
When `dynamicSubagents.enabled` is set without a resolvable worker model, construction throws `SubAgentModelError`.
|
|
141
142
|
|
|
@@ -146,6 +147,12 @@ await agent.run(prompt, opts?) // non-streaming, or streaming when opts.stream i
|
|
|
146
147
|
agent.ask(prompt, optsOrBool?) // string deltas when streaming, otherwise same as run
|
|
147
148
|
agent.stream(prompt, opts?) // AssistantMessageEventStream
|
|
148
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)
|
|
149
156
|
```
|
|
150
157
|
|
|
151
158
|
`prompt` accepts `string | ContentPart[]`.
|
|
@@ -159,8 +166,9 @@ Use `ContentPart[]` when sending images, audio, or video alongside text.
|
|
|
159
166
|
| `stream` | When `true`, returns a stream instead of a regular response promise. |
|
|
160
167
|
| `onDelta(delta, event)` | Called for each text chunk. Use to render answers live. |
|
|
161
168
|
| `onThinkingDelta(delta, event)` | Called for each reasoning chunk. Use to render reasoning separately. |
|
|
162
|
-
| `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`. |
|
|
163
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. |
|
|
164
172
|
| `additionalContext` | Added only to the current user turn. Keeps the system prompt stable for better caching. |
|
|
165
173
|
| `sessionId` | Per-run session override. |
|
|
166
174
|
| `headers` | Per-run header merge. |
|
|
@@ -290,6 +298,8 @@ A `spawn_subagents` tool is injected with the following task shape:
|
|
|
290
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.
|
|
291
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.
|
|
292
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.
|
|
293
303
|
|
|
294
304
|
```ts
|
|
295
305
|
const res = await agent.run("Audit auth pipeline and write a threat model");
|
|
@@ -488,7 +498,7 @@ Turns chain statefully through `previous_interaction_id` per session, falling ba
|
|
|
488
498
|
Thinking levels map to `thinking_level`, with `thinking_summaries` enabled whenever thinking is active:
|
|
489
499
|
|
|
490
500
|
```text
|
|
491
|
-
minimal | low | medium | high (xhigh
|
|
501
|
+
minimal | low | medium | high (xhigh/max clamp to high; none is unsupported and omitted; dynamic omits)
|
|
492
502
|
```
|
|
493
503
|
|
|
494
504
|
Google-specific handling includes:
|
|
@@ -515,7 +525,7 @@ Every turn is stateless: the full history is sent explicitly with `store: false`
|
|
|
515
525
|
Thinking levels map to `reasoning.effort` verbatim:
|
|
516
526
|
|
|
517
527
|
```text
|
|
518
|
-
none | minimal | low | medium | high | xhigh (dynamic omits — server default)
|
|
528
|
+
none | minimal | low | medium | high | xhigh | max (dynamic omits — server default)
|
|
519
529
|
```
|
|
520
530
|
|
|
521
531
|
It also:
|
|
@@ -536,7 +546,7 @@ Session affinity is a top-level body `session_id` plus the `x-session-id` header
|
|
|
536
546
|
Thinking levels map to `reasoning.effort` verbatim:
|
|
537
547
|
|
|
538
548
|
```text
|
|
539
|
-
none | minimal | low | medium | high | xhigh (dynamic omits — server default)
|
|
549
|
+
none | minimal | low | medium | high | xhigh | max (dynamic omits — server default)
|
|
540
550
|
```
|
|
541
551
|
|
|
542
552
|
It also:
|
|
@@ -591,14 +601,15 @@ ThinkingLevel =
|
|
|
591
601
|
| "low"
|
|
592
602
|
| "medium"
|
|
593
603
|
| "high"
|
|
594
|
-
| "xhigh"
|
|
604
|
+
| "xhigh"
|
|
605
|
+
| "max";
|
|
595
606
|
```
|
|
596
607
|
|
|
597
608
|
### Thinking Levels
|
|
598
609
|
|
|
599
610
|
* `none` — disables thinking where supported.
|
|
600
611
|
* `dynamic` — allows the model to decide.
|
|
601
|
-
* `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.
|
|
602
613
|
|
|
603
614
|
Thinking can be configured on the `Agent` or through `ModelProvider.*(..., { thinkingLevel })`.
|
|
604
615
|
|
|
@@ -729,6 +740,7 @@ StreamEvent {
|
|
|
729
740
|
toolCall?,
|
|
730
741
|
toolResult?,
|
|
731
742
|
subagent?,
|
|
743
|
+
subagentTrackingId?,
|
|
732
744
|
usage?,
|
|
733
745
|
responseId?,
|
|
734
746
|
finishReason?,
|
|
@@ -754,12 +766,13 @@ tool_call_delta
|
|
|
754
766
|
tool_call_complete
|
|
755
767
|
tool_result
|
|
756
768
|
subagent_complete
|
|
769
|
+
subagent_delta
|
|
757
770
|
usage
|
|
758
771
|
done
|
|
759
772
|
error
|
|
760
773
|
```
|
|
761
774
|
|
|
762
|
-
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.
|
|
763
776
|
|
|
764
777
|
Use:
|
|
765
778
|
|
|
@@ -767,6 +780,7 @@ Use:
|
|
|
767
780
|
* `thinking_delta` for reasoning output.
|
|
768
781
|
* `tool_call_complete` / `tool_result` for tool progress.
|
|
769
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.
|
|
770
784
|
* `usage` for interim usage counts.
|
|
771
785
|
* `done` for final usage and completion information.
|
|
772
786
|
|
|
@@ -836,10 +850,33 @@ SubAgentExecutionMetadata {
|
|
|
836
850
|
toolCalls?,
|
|
837
851
|
raw?,
|
|
838
852
|
isError?,
|
|
839
|
-
error
|
|
853
|
+
error?,
|
|
854
|
+
trackingId?,
|
|
855
|
+
sessionId?,
|
|
856
|
+
parentSessionId?,
|
|
857
|
+
steps?
|
|
840
858
|
}
|
|
841
859
|
```
|
|
842
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
|
|
875
|
+
}
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
`agent.track(id)` returns these live; `partial` entries finalize when the worker's turn completes.
|
|
879
|
+
|
|
843
880
|
### TokenUsage
|
|
844
881
|
|
|
845
882
|
```ts
|
|
@@ -1089,6 +1126,8 @@ never in the gitignored snapshot.
|
|
|
1089
1126
|
## Utils
|
|
1090
1127
|
|
|
1091
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.
|
|
1092
1131
|
* `getEnv(key, fallback?)` — resolves an environment variable.
|
|
1093
1132
|
* `getApiKey(provider, explicit?, env?)` — resolves API keys using the configured environment lookup order.
|
|
1094
1133
|
* `buildSessionHeaders(provider, cache?, custom?, sessionId?)` — builds provider-specific affinity headers. Normally handled automatically.
|
|
@@ -1130,6 +1169,9 @@ bun run examples/08-multimodal_video.ts
|
|
|
1130
1169
|
|
|
1131
1170
|
bun run examples/10-document_markdown.ts
|
|
1132
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
|
|
1133
1175
|
```
|
|
1134
1176
|
|
|
1135
1177
|
Every example ends its `run()` with `.catch(fail)` (`examples/_shared.ts`),
|
|
@@ -1138,17 +1180,54 @@ so failures print one line and exit `1` — no stack dumps.
|
|
|
1138
1180
|
The chat example persists conversations to:
|
|
1139
1181
|
|
|
1140
1182
|
```text
|
|
1141
|
-
|
|
1183
|
+
sessions/<sessionId>/session.json (+ media/ for images, audio, video, files)
|
|
1142
1184
|
```
|
|
1143
1185
|
|
|
1144
|
-
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:
|
|
1145
1187
|
|
|
1146
|
-
|
|
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
|
+
```
|
|
1191
|
+
|
|
1192
|
+
It also displays per-turn and session totals on one line:
|
|
1147
1193
|
|
|
1148
1194
|
```text
|
|
1149
|
-
|
|
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);
|
|
1150
1222
|
```
|
|
1151
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
|
+
|
|
1152
1231
|
---
|
|
1153
1232
|
## Scripts and Structure
|
|
1154
1233
|
|
|
@@ -1164,6 +1243,7 @@ bun run update-models # refresh model catalog cache (supports --force, --ttl=24h
|
|
|
1164
1243
|
```text
|
|
1165
1244
|
src/
|
|
1166
1245
|
├── agent/ # Agent, context, loop, delegation, subagent
|
|
1246
|
+
├── session/ # Session persistence + telemetry (snapshots, hit rates, .session.json store)
|
|
1167
1247
|
├── providers/ # native REST adapters (google/openai/openrouter/openai-compat) + registry + canonical contract
|
|
1168
1248
|
├── models/ # Dynamic catalog cache, parser, verified overrides
|
|
1169
1249
|
├── data/ # Dynamic model catalog cache (gitignored, excluded from bundle)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-accelerator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "High-performance SDK for AI agents with a unified API across AI providers. Optimized for high cache hit rates, observability, and seamless agent orchestration. Built to power production-grade agentic systems and harnesses for teams at any scale.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sashvat Bharat",
|