zidane 3.0.2 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -20
- package/dist/{agent-4zeSbdXy.d.ts → agent-Cq009tbG.d.ts} +134 -3
- package/dist/{chunk-D45PXTY2.js → chunk-3DUWP7YU.js} +65 -15
- package/dist/{chunk-2VM47IBI.js → chunk-ATMVSCGJ.js} +1 -1
- package/dist/{chunk-QFHGWKK3.js → chunk-EBSFBIP3.js} +428 -32
- package/dist/{chunk-2EQT4EHD.js → chunk-IUBBVF53.js} +4 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +4 -4
- package/dist/mcp.d.ts +2 -2
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +3 -3
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +1 -1
- package/dist/{sandbox-CW72eLDP.d.ts → sandbox-CLghrTLi.d.ts} +1 -1
- package/dist/session/sqlite.d.ts +2 -2
- package/dist/session.d.ts +2 -2
- package/dist/{skills-use-DhxQaluD.d.ts → skills-use-Bi6Dklye.d.ts} +1 -1
- package/dist/skills.d.ts +3 -3
- package/dist/tools.d.ts +5 -5
- package/dist/tools.js +2 -2
- package/dist/{types-BpvTmawk.d.ts → types-vA1a_ZX7.d.ts} +11 -0
- package/dist/types.d.ts +4 -4
- package/dist/{validation-CYISGVTn.d.ts → validation-BeQD94ft.d.ts} +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,25 +12,17 @@ Built to be embedded.
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- 💾 **
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- ⚡ **Prompt caching** — auto-injected `cache_control` breakpoints on Anthropic + OpenRouter routes; cache-read / cache-write surfaced on `TurnUsage`.
|
|
27
|
-
- 🚀 **Parallel MCP bootstrap** — every server connects concurrently with per-server timeouts; `agent.warmup()` + `eager: true` hide cold-start latency.
|
|
28
|
-
- 🎯 **Structured output** — force the final answer to match a JSON Schema (Zod v4 interop), no brittle parsing.
|
|
29
|
-
- 🧵 **Sub-agent spawning** — delegate to child agents with inherited or overridden preset; child stream/tool events bubble to the parent.
|
|
30
|
-
- 🧭 **Typed errors** — `AgentContextExceededError` / `AgentProviderError` / `AgentAbortedError` instead of sniffing error strings.
|
|
31
|
-
- 🔌 **Execution contexts** — run tools in-process, in Docker, or in a remote sandbox (E2B / Rivet / any `SandboxProvider`).
|
|
32
|
-
- 🪝 **Hookable everything** — typed hook events covering turn, stream, tool, MCP, session, skills, spawn, OAuth refresh, bootstrap timing, validation rejection / coercion, and budget overflow.
|
|
33
|
-
- 🧪 **1000+ tests, zero API keys** — mock providers + mock execution contexts; suite runs in under 2 seconds.
|
|
15
|
+
A small, hookable core with sensible defaults so most consumers don't write a single hook. Built around three principles: **token discipline by default** (cache, dedup, compaction, byte-accounting), **self-healing on the fault paths** (auto-coerce args, hallucinated-tool fallback, error rewriting), and **provider parity** (server-side features on Anthropic, client-side equivalents everywhere else).
|
|
16
|
+
|
|
17
|
+
- 🧠 **Multi-provider, multi-auth** — Anthropic, OpenAI Codex, OpenRouter, Cerebras, plus a generic `openaiCompat` factory (Baseten, Fireworks, Groq, local servers). OAuth + API key, auto-refreshing tokens. Anthropic accepts opt-in `extraBetas` and `contextManagement` for first-party features.
|
|
18
|
+
- 🪝 **Streaming, hookable turn loop** — text/thinking deltas, tool calls, MCP, sessions, skills, spawn, OAuth, validation, budgets — all observable (and most mutatable) via typed hook events.
|
|
19
|
+
- 🛠 **Tools first-class** — `shell`, `read_file`, `write_file`, `edit`, `multi_edit`, `glob`, `grep`, `spawn`, human-in-the-loop, plus any [MCP](https://modelcontextprotocol.io) server. Sequential or parallel, per-call gates (`tool:gate`), validation auto-coerce (`"true"` → `true`), hallucinated-tool fallback (`tool:unknown`), error rewriting (`tool:error` → `result`).
|
|
20
|
+
- ✂️ **Token-aware ergonomics** — paginated reads with a "how to page" footer, 8 KB tail-truncated `shell`, idempotent `write_file`; `outputBytes` surfaced on every tool/MCP hook. `behavior.toolOutputBudget` injects a "summarize" nudge when a turn's outputs exceed the cap.
|
|
21
|
+
- 🗜 **Context discipline** — auto-injected `cache_control` breakpoints (Anthropic + OpenRouter); server-side compaction via `context-management-2025-06-27` on Anthropic, `behavior.compactStrategy: 'tail'` on everyone else. Per-session `read_file` dedup + opt-in `requireReadBeforeEdit` guard kill stale-content edits.
|
|
22
|
+
- 🎯 **Reasoning + structured output** — thinking levels (`off` / `minimal` / `low` / `medium` / `high` / `adaptive`) with optional exact budgets; force the final answer to a JSON Schema (Zod v4 interop), no brittle parsing.
|
|
23
|
+
- 💾 **Sessions, skills, multimodal** — pluggable session stores (memory / SQLite / remote / file-map), incremental persistence; [Agent Skills](https://agentskills.io/specification) spec-aligned with `allowed-tools` enforcement + resume rehydration; images + documents via `PromptPart[]`, tools can return image blocks routed natively on vision providers or via companion messages elsewhere.
|
|
24
|
+
- 🧵 **Sub-agents + execution contexts** — delegate to child agents with inherited or overridden preset (child events bubble to the parent); run tools in-process, Docker, or any `SandboxProvider` (E2B / Rivet / custom). Parallel MCP bootstrap with `agent.warmup()` + `eager: true` to hide cold starts.
|
|
25
|
+
- 🧭 **Typed errors + 1000+ tests** — `AgentContextExceededError` / `AgentProviderError` / `AgentAbortedError` instead of sniffing strings. Suite runs in under 2s with mock providers + mock execution contexts, zero API keys.
|
|
34
26
|
|
|
35
27
|
> Upgrading from 2.x? See [`docs/migrate-from-v2.md`](./docs/migrate-from-v2.md) for the full list of behavior changes.
|
|
36
28
|
|
|
@@ -77,6 +69,11 @@ createAgent({
|
|
|
77
69
|
thinkingBudget: 10240, // exact thinking token budget
|
|
78
70
|
cache: true, // prompt-cache breakpoints on supported providers (default: true)
|
|
79
71
|
toolOutputBudget: 32768, // soft per-turn cap on tool-output bytes (off by default)
|
|
72
|
+
dedupReads: true, // dedup identical re-reads of the same file in `read_file` (default: true)
|
|
73
|
+
requireReadBeforeEdit: false, // refuse `edit` / `multi_edit` against unread or stale files (default: false)
|
|
74
|
+
compactStrategy: 'off', // client-side tail compaction for non-Anthropic providers — 'off' | 'tail' (default: 'off')
|
|
75
|
+
compactThreshold: 131_072, // bytes threshold that triggers tail compaction (default: 128 KiB)
|
|
76
|
+
compactKeepTurns: 4, // trailing turns left intact during compaction (default: 4)
|
|
80
77
|
},
|
|
81
78
|
execution: createProcessContext(), // where tools run
|
|
82
79
|
mcpServers: [], // MCP tool servers
|
|
@@ -141,10 +138,30 @@ anthropic({ apiKey: 'sk-ant-...' })
|
|
|
141
138
|
anthropic({ access: 'sk-ant-oat-...' }) // OAuth
|
|
142
139
|
anthropic({ access: 'sk-ant-oat-...', refresh: '...', expires: Date.now() + 3600_000 }) // auto-refresh
|
|
143
140
|
anthropic({ apiKey: '...', defaultModel: 'claude-sonnet-4-6' })
|
|
141
|
+
|
|
142
|
+
// Opt into first-party Anthropic betas + server-side context compaction:
|
|
143
|
+
anthropic({
|
|
144
|
+
apiKey: '...',
|
|
145
|
+
extraBetas: [
|
|
146
|
+
'context-management-2025-06-27', // server-side, token-accurate compaction
|
|
147
|
+
'token-efficient-tools-2026-03-28', // ~4.5% output token reduction
|
|
148
|
+
'interleaved-thinking-2025-05-14', // think between tool calls in one turn
|
|
149
|
+
],
|
|
150
|
+
contextManagement: {
|
|
151
|
+
edits: [{
|
|
152
|
+
type: 'clear_tool_uses_20250919',
|
|
153
|
+
trigger: { type: 'input_tokens', value: 180_000 },
|
|
154
|
+
clear_at_least: { type: 'input_tokens', value: 140_000 },
|
|
155
|
+
clear_tool_inputs: ['Read', 'Bash', 'Grep', 'Glob'],
|
|
156
|
+
}],
|
|
157
|
+
},
|
|
158
|
+
})
|
|
144
159
|
```
|
|
145
160
|
|
|
146
161
|
Fallback: `params.apiKey` > `params.access` > `ANTHROPIC_API_KEY` env > `.credentials.json`
|
|
147
162
|
|
|
163
|
+
`extraBetas` are merged with the OAuth defaults (`claude-code-20250219`, `oauth-2025-04-20`) and de-duped. `contextManagement` is sent on the request body as `context_management`; pair it with the `context-management-2025-06-27` beta. For non-Anthropic providers, see `behavior.compactStrategy: 'tail'` for the client-side fallback.
|
|
164
|
+
|
|
148
165
|
### OpenRouter
|
|
149
166
|
|
|
150
167
|
```ts
|
|
@@ -270,6 +287,7 @@ Extended reasoning with named levels or exact token budgets.
|
|
|
270
287
|
| `low` | 4,096 tokens |
|
|
271
288
|
| `medium` | 10,240 tokens |
|
|
272
289
|
| `high` | 32,768 tokens |
|
|
290
|
+
| `adaptive` | model self-budgets per turn |
|
|
273
291
|
|
|
274
292
|
```ts
|
|
275
293
|
// Named level
|
|
@@ -278,12 +296,18 @@ await agent.run({ prompt: 'solve this', thinking: 'high' })
|
|
|
278
296
|
// Exact budget (overrides level default)
|
|
279
297
|
await agent.run({ prompt: 'solve this', thinking: 'high', behavior: { thinkingBudget: 50000 } })
|
|
280
298
|
|
|
299
|
+
// Adaptive — model self-budgets, but `thinkingBudget` caps the response envelope
|
|
300
|
+
// (max_tokens) to soft-bound runaway thinking on Anthropic.
|
|
301
|
+
await agent.run({ prompt: 'solve this', thinking: 'adaptive', behavior: { thinkingBudget: 32000 } })
|
|
302
|
+
|
|
281
303
|
// Agent-level default
|
|
282
304
|
const agent = createAgent({ ...basic, provider, behavior: { thinkingBudget: 16384 } })
|
|
283
305
|
```
|
|
284
306
|
|
|
285
307
|
Thinking traces are stored in session turns as `{ type: 'thinking', text }` content blocks and streamed live via the `stream:thinking` hook. Supported by Anthropic (native) and OpenRouter/Cerebras (`reasoning_content`/`reasoning` SSE fields).
|
|
286
308
|
|
|
309
|
+
`adaptive` is Anthropic-specific (`thinking.type='adaptive'`) and avoids the `thinking.type='enabled'` deprecation warning on opus 4.6+. It has no native budget knob — when `thinkingBudget` is paired with `adaptive`, zidane caps `max_tokens = min(maxTokens, thinkingBudget)` so unbounded reasoning can't run away. Other providers fall back to no reasoning when `adaptive` is selected.
|
|
310
|
+
|
|
287
311
|
## Hooks
|
|
288
312
|
|
|
289
313
|
Every hook receives a mutable context object.
|
|
@@ -352,7 +376,11 @@ agent.hooks.hook('tool:gate', (ctx) => {
|
|
|
352
376
|
|
|
353
377
|
agent.hooks.hook('tool:before', (ctx) => { /* ctx.turnId, ctx.callId, ctx.name, ctx.input, ctx.coercions? */ })
|
|
354
378
|
agent.hooks.hook('tool:after', (ctx) => { /* + ctx.result, ctx.outputBytes, ctx.coercions? */ })
|
|
355
|
-
agent.hooks.hook('tool:error', (ctx) => {
|
|
379
|
+
agent.hooks.hook('tool:error', (ctx) => {
|
|
380
|
+
// + ctx.error. Mutate ctx.result to substitute the payload sent back to the
|
|
381
|
+
// model in place of the default `Tool error: <msg>` — useful for OSS-model
|
|
382
|
+
// error rewriting (collapse stack traces, prepend recovery hints).
|
|
383
|
+
})
|
|
356
384
|
agent.hooks.hook('tool:transform', (ctx) => {
|
|
357
385
|
// + ctx.result, ctx.isError, ctx.outputBytes (pre-mutation), ctx.coercions? — mutate result/isError to modify.
|
|
358
386
|
// Built-in tools already truncate; use this hook for consumer concerns the framework can't infer,
|
|
@@ -458,6 +486,30 @@ agent.hooks.hook('budget:exceeded', (ctx) => {
|
|
|
458
486
|
})
|
|
459
487
|
```
|
|
460
488
|
|
|
489
|
+
### Client-side context compaction (non-Anthropic)
|
|
490
|
+
|
|
491
|
+
For non-Anthropic providers (cerebras / openai-compat / openrouter on OSS models), `behavior.compactStrategy: 'tail'` elides older `tool_result` blocks from the wire-level message list once their combined size exceeds `compactThreshold`. The newest `compactKeepTurns` messages stay intact so the model retains the freshest tool context.
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
const agent = createAgent({
|
|
495
|
+
...basic,
|
|
496
|
+
provider: cerebras({ apiKey: '...' }),
|
|
497
|
+
behavior: {
|
|
498
|
+
compactStrategy: 'tail',
|
|
499
|
+
compactThreshold: 131_072, // 128 KiB; default
|
|
500
|
+
compactKeepTurns: 4, // default
|
|
501
|
+
},
|
|
502
|
+
})
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Anthropic users should prefer the server-side `context-management-2025-06-27` beta (token-accurate, configured via `anthropic({ extraBetas, contextManagement })`) — `'tail'` is a client-side approximation that exists because OSS-model providers have no server-side equivalent.
|
|
506
|
+
|
|
507
|
+
### Read dedup + read-before-edit guard
|
|
508
|
+
|
|
509
|
+
`behavior.dedupReads` (on by default) — `read_file` returns a short `"unchanged since the previous read"` stub instead of re-emitting bytes when the model re-reads the same file with the same slice. Per-session content-hash; requires a session.
|
|
510
|
+
|
|
511
|
+
`behavior.requireReadBeforeEdit` (off by default) — `edit` and `multi_edit` reject when the file hasn't been read in the session, or when its on-disk content has drifted since the last read. Eliminates the silent-corruption case where a model edits against bytes it "remembers" but no longer reflect reality. Recommended on for stricter eval-grade runs.
|
|
512
|
+
|
|
461
513
|
## Steering and Follow-up
|
|
462
514
|
|
|
463
515
|
### Steering
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hookable } from 'hookable';
|
|
2
|
-
import { b as ExecutionContext, c as ExecutionHandle } from './types-
|
|
2
|
+
import { b as ExecutionContext, c as ExecutionHandle } from './types-vA1a_ZX7.js';
|
|
3
3
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -216,6 +216,62 @@ interface AgentBehavior {
|
|
|
216
216
|
* starting value for OSS-model integrations is `32768`.
|
|
217
217
|
*/
|
|
218
218
|
toolOutputBudget?: number;
|
|
219
|
+
/**
|
|
220
|
+
* Deduplicate identical re-reads of the same file in `read_file`. When the
|
|
221
|
+
* model re-reads a file with the same slice and the bytes haven't changed
|
|
222
|
+
* since the last read in this session, the tool returns a short stub
|
|
223
|
+
* instead of re-emitting the full content. Pairs with the read-before-edit
|
|
224
|
+
* guard in `edit` / `multi_edit`.
|
|
225
|
+
*
|
|
226
|
+
* Requires a session (set via `createSession()`); without one, the flag is
|
|
227
|
+
* a no-op since per-session state has nowhere to live.
|
|
228
|
+
*
|
|
229
|
+
* Default: `true`.
|
|
230
|
+
*/
|
|
231
|
+
dedupReads?: boolean;
|
|
232
|
+
/**
|
|
233
|
+
* Require `read_file` before `edit` / `multi_edit` on the same path, and
|
|
234
|
+
* reject edits when the file has changed on disk since the last read in
|
|
235
|
+
* this session. Eliminates the silent-corruption failure mode where a
|
|
236
|
+
* model "remembers" stale content and applies a substring edit against
|
|
237
|
+
* bytes that have moved.
|
|
238
|
+
*
|
|
239
|
+
* Requires a session. Off by default to preserve back-compat — turn it on
|
|
240
|
+
* for stricter eval-grade runs.
|
|
241
|
+
*
|
|
242
|
+
* Default: `false`.
|
|
243
|
+
*/
|
|
244
|
+
requireReadBeforeEdit?: boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Client-side context compaction strategy. Use this for non-Anthropic
|
|
247
|
+
* providers (OSS via cerebras / openai-compat / openrouter) that don't
|
|
248
|
+
* have a server-side equivalent. Anthropic users should prefer the
|
|
249
|
+
* server-side `context-management-2025-06-27` beta — see
|
|
250
|
+
* `AnthropicParams.contextManagement`.
|
|
251
|
+
*
|
|
252
|
+
* - `'off'` (default) — no client-side compaction.
|
|
253
|
+
* - `'tail'` — when total tool-output bytes in the persisted history
|
|
254
|
+
* exceed `compactThreshold`, replace older `tool_result` outputs with a
|
|
255
|
+
* short stub, keeping the newest `compactKeepTurns` turns intact. The
|
|
256
|
+
* compaction is applied to the wire-level message list only; the
|
|
257
|
+
* underlying session turns are not modified.
|
|
258
|
+
*
|
|
259
|
+
* Default: `'off'`.
|
|
260
|
+
*/
|
|
261
|
+
compactStrategy?: 'off' | 'tail';
|
|
262
|
+
/**
|
|
263
|
+
* Soft byte threshold that triggers tail compaction when
|
|
264
|
+
* `compactStrategy === 'tail'`. Counts the post-`context:transform` bytes
|
|
265
|
+
* of `tool_result` outputs across all messages. Default: `131_072` (128
|
|
266
|
+
* KiB). Ignored when compaction is off.
|
|
267
|
+
*/
|
|
268
|
+
compactThreshold?: number;
|
|
269
|
+
/**
|
|
270
|
+
* Number of trailing turns to leave untouched during tail compaction. The
|
|
271
|
+
* most-recent `compactKeepTurns` user/assistant messages are not eligible
|
|
272
|
+
* for elision so the model keeps the freshest tool context. Default: `4`.
|
|
273
|
+
*/
|
|
274
|
+
compactKeepTurns?: number;
|
|
219
275
|
}
|
|
220
276
|
interface ImageContent {
|
|
221
277
|
type: 'image';
|
|
@@ -395,8 +451,24 @@ interface AgentRunOptions {
|
|
|
395
451
|
*/
|
|
396
452
|
depth?: number;
|
|
397
453
|
}
|
|
398
|
-
/**
|
|
399
|
-
|
|
454
|
+
/**
|
|
455
|
+
* Reason the provider gave for stopping the turn.
|
|
456
|
+
*
|
|
457
|
+
* - `'stop'` — natural turn end (`end_turn` / `stop_sequence`).
|
|
458
|
+
* - `'tool-calls'` — model emitted tool_use blocks.
|
|
459
|
+
* - `'length'` — `max_tokens` reached, or (Anthropic 4.6+) the response bumped
|
|
460
|
+
* against the model's context window mid-stream
|
|
461
|
+
* (`model_context_window_exceeded`). The partial response is preserved; the
|
|
462
|
+
* loop emits this reason so consumers can prune/retry.
|
|
463
|
+
* - `'content-filter'` — model refused.
|
|
464
|
+
* - `'pause'` — Anthropic `pause_turn`: a server-side mid-turn pause for very
|
|
465
|
+
* long thinking. The loop continues with a synthetic "Please continue."
|
|
466
|
+
* user message rather than terminating; consumers see the pause via this
|
|
467
|
+
* finish reason on the prior assistant turn.
|
|
468
|
+
* - `'error'` — provider classified the turn as failed.
|
|
469
|
+
* - `'other'` — unknown / unmapped.
|
|
470
|
+
*/
|
|
471
|
+
type TurnFinishReason = 'stop' | 'tool-calls' | 'length' | 'content-filter' | 'pause' | 'error' | 'other';
|
|
400
472
|
interface TurnUsage {
|
|
401
473
|
input: number;
|
|
402
474
|
output: number;
|
|
@@ -541,6 +613,18 @@ interface OAuthRefreshHookContext {
|
|
|
541
613
|
}
|
|
542
614
|
type SessionEndStatus = 'completed' | 'aborted' | 'error';
|
|
543
615
|
|
|
616
|
+
/**
|
|
617
|
+
* Server-side context-management config — the body of `context_management` on
|
|
618
|
+
* the Messages API. Typed loosely (Record-of-unknown) so we don't pin a specific
|
|
619
|
+
* SDK schema version: the v0.90 SDK does not yet type this field, but the wire
|
|
620
|
+
* format is stable behind the `context-management-2025-06-27` beta.
|
|
621
|
+
*
|
|
622
|
+
* See: https://docs.anthropic.com/en/docs/build-with-claude/context-management
|
|
623
|
+
*/
|
|
624
|
+
interface AnthropicContextManagement {
|
|
625
|
+
edits?: Array<Record<string, unknown>>;
|
|
626
|
+
[key: string]: unknown;
|
|
627
|
+
}
|
|
544
628
|
interface AnthropicParams {
|
|
545
629
|
apiKey?: string;
|
|
546
630
|
access?: string;
|
|
@@ -553,6 +637,43 @@ interface AnthropicParams {
|
|
|
553
637
|
* gateways, internal router).
|
|
554
638
|
*/
|
|
555
639
|
baseURL?: string;
|
|
640
|
+
/**
|
|
641
|
+
* Additional `anthropic-beta` flags to opt into. Merged with the OAuth-path
|
|
642
|
+
* defaults (`claude-code-20250219`, `oauth-2025-04-20`); duplicates are
|
|
643
|
+
* de-duped. Examples:
|
|
644
|
+
*
|
|
645
|
+
* - `'context-management-2025-06-27'` — server-side context compaction
|
|
646
|
+
* (token-accurate; pair with {@link AnthropicParams.contextManagement}).
|
|
647
|
+
* - `'token-efficient-tools-2026-03-28'` — terser tool_use wire format.
|
|
648
|
+
* - `'interleaved-thinking-2025-05-14'` — think between tool calls within
|
|
649
|
+
* one turn.
|
|
650
|
+
* - `'redact-thinking-2026-02-12'` — replace large thinking blocks with
|
|
651
|
+
* stubs server-side.
|
|
652
|
+
* - `'prompt-caching-scope-2026-01-05'` — extended prompt-cache scope.
|
|
653
|
+
*
|
|
654
|
+
* Honored on both the OAuth and API-key paths.
|
|
655
|
+
*/
|
|
656
|
+
extraBetas?: readonly string[];
|
|
657
|
+
/**
|
|
658
|
+
* Server-side context-management directive. Sent on the request body as
|
|
659
|
+
* `context_management`. Requires the `context-management-2025-06-27` beta —
|
|
660
|
+
* add it to {@link AnthropicParams.extraBetas}.
|
|
661
|
+
*
|
|
662
|
+
* Typed loosely so future Anthropic schema additions land without an SDK
|
|
663
|
+
* bump. A typical compaction edit:
|
|
664
|
+
*
|
|
665
|
+
* ```ts
|
|
666
|
+
* contextManagement: {
|
|
667
|
+
* edits: [{
|
|
668
|
+
* type: 'clear_tool_uses_20250919',
|
|
669
|
+
* trigger: { type: 'input_tokens', value: 180_000 },
|
|
670
|
+
* clear_at_least: { type: 'input_tokens', value: 140_000 },
|
|
671
|
+
* clear_tool_inputs: ['Read', 'Bash', 'Grep'],
|
|
672
|
+
* }],
|
|
673
|
+
* }
|
|
674
|
+
* ```
|
|
675
|
+
*/
|
|
676
|
+
contextManagement?: AnthropicContextManagement;
|
|
556
677
|
}
|
|
557
678
|
declare function anthropic(anthropicParams?: AnthropicParams): Provider;
|
|
558
679
|
|
|
@@ -1466,8 +1587,18 @@ interface AgentHooks {
|
|
|
1466
1587
|
outputBytes: number;
|
|
1467
1588
|
coercions?: readonly string[];
|
|
1468
1589
|
}) => void;
|
|
1590
|
+
/**
|
|
1591
|
+
* Fires when a tool throws during execution. Mutate `result` to substitute a
|
|
1592
|
+
* tool-output payload that gets sent back to the model in place of the
|
|
1593
|
+
* default `Tool error: <msg>` string — useful for OSS-model error rewriting
|
|
1594
|
+
* (collapse stack traces, hide internal paths, prepend recovery hints).
|
|
1595
|
+
*
|
|
1596
|
+
* The post-hook value flows through `tool:transform` like a normal output, so
|
|
1597
|
+
* downstream byte-budgeting and image-stripping still apply.
|
|
1598
|
+
*/
|
|
1469
1599
|
'tool:error': (ctx: ToolHookContext & {
|
|
1470
1600
|
error: Error;
|
|
1601
|
+
result?: string | ToolResultContent[];
|
|
1471
1602
|
}) => void;
|
|
1472
1603
|
'tool:transform': (ctx: ToolHookContext & {
|
|
1473
1604
|
result: string | ToolResultContent[];
|
|
@@ -132,6 +132,28 @@ async function loadAnthropicSdk() {
|
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
+
var OAUTH_DEFAULT_BETAS = ["claude-code-20250219", "oauth-2025-04-20"];
|
|
136
|
+
function resolveAnthropicBetas(isOAuth, extraBetas) {
|
|
137
|
+
const seen = /* @__PURE__ */ new Set();
|
|
138
|
+
const out = [];
|
|
139
|
+
if (isOAuth) {
|
|
140
|
+
for (const b of OAUTH_DEFAULT_BETAS) {
|
|
141
|
+
if (!seen.has(b)) {
|
|
142
|
+
seen.add(b);
|
|
143
|
+
out.push(b);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (extraBetas) {
|
|
148
|
+
for (const b of extraBetas) {
|
|
149
|
+
if (typeof b === "string" && b.length > 0 && !seen.has(b)) {
|
|
150
|
+
seen.add(b);
|
|
151
|
+
out.push(b);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return out.length > 0 ? out.join(",") : void 0;
|
|
156
|
+
}
|
|
135
157
|
function getConfiguredApiKey(anthropicParams) {
|
|
136
158
|
if (anthropicParams?.apiKey)
|
|
137
159
|
return anthropicParams.apiKey;
|
|
@@ -144,22 +166,31 @@ function getConfiguredApiKey(anthropicParams) {
|
|
|
144
166
|
return access;
|
|
145
167
|
throw new Error("No API key found. Run `bun run auth` first.");
|
|
146
168
|
}
|
|
147
|
-
function createClient(SDK, apiKey, isOAuth, baseURL) {
|
|
169
|
+
function createClient(SDK, apiKey, isOAuth, baseURL, extraBetas) {
|
|
148
170
|
const base = baseURL ? { baseURL } : {};
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
const betaHeader = resolveAnthropicBetas(isOAuth, extraBetas);
|
|
172
|
+
if (isOAuth) {
|
|
173
|
+
const defaultHeaders2 = {
|
|
174
|
+
"anthropic-dangerous-direct-browser-access": "true",
|
|
175
|
+
"user-agent": "zidane/2.0.0",
|
|
176
|
+
"x-app": "cli"
|
|
177
|
+
};
|
|
178
|
+
if (betaHeader)
|
|
179
|
+
defaultHeaders2["anthropic-beta"] = betaHeader;
|
|
180
|
+
return new SDK({
|
|
151
181
|
apiKey: null,
|
|
152
182
|
authToken: apiKey,
|
|
153
183
|
dangerouslyAllowBrowser: true,
|
|
154
|
-
defaultHeaders:
|
|
155
|
-
"anthropic-beta": "claude-code-20250219,oauth-2025-04-20",
|
|
156
|
-
"anthropic-dangerous-direct-browser-access": "true",
|
|
157
|
-
"user-agent": "zidane/2.0.0",
|
|
158
|
-
"x-app": "cli"
|
|
159
|
-
},
|
|
184
|
+
defaultHeaders: defaultHeaders2,
|
|
160
185
|
...base
|
|
161
|
-
}
|
|
162
|
-
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const defaultHeaders = betaHeader ? { "anthropic-beta": betaHeader } : void 0;
|
|
189
|
+
return new SDK({
|
|
190
|
+
apiKey,
|
|
191
|
+
...defaultHeaders ? { defaultHeaders } : {},
|
|
192
|
+
...base
|
|
193
|
+
});
|
|
163
194
|
}
|
|
164
195
|
var EFFORT_FOR_LEVEL = {
|
|
165
196
|
minimal: "low",
|
|
@@ -170,8 +201,11 @@ var EFFORT_FOR_LEVEL = {
|
|
|
170
201
|
function planAnthropicThinking(level, customBudget) {
|
|
171
202
|
if (level === "off")
|
|
172
203
|
return null;
|
|
173
|
-
if (level === "adaptive")
|
|
204
|
+
if (level === "adaptive") {
|
|
205
|
+
if (typeof customBudget === "number" && customBudget > 0)
|
|
206
|
+
return { kind: "adaptive", maxTokensCap: customBudget };
|
|
174
207
|
return { kind: "adaptive" };
|
|
208
|
+
}
|
|
175
209
|
if (customBudget !== void 0) {
|
|
176
210
|
return { kind: "enabled", budgetTokens: customBudget, maxTokensBump: customBudget };
|
|
177
211
|
}
|
|
@@ -187,11 +221,14 @@ function mapStopReason(stopReason) {
|
|
|
187
221
|
case "tool_use":
|
|
188
222
|
return "tool-calls";
|
|
189
223
|
case "max_tokens":
|
|
224
|
+
case "model_context_window_exceeded":
|
|
190
225
|
return "length";
|
|
191
226
|
case "refusal":
|
|
192
227
|
return "content-filter";
|
|
228
|
+
// 4.6+: server-side mid-turn pause for long thinking. The loop
|
|
229
|
+
// continues with a synthetic continue message rather than terminating.
|
|
193
230
|
case "pause_turn":
|
|
194
|
-
return "
|
|
231
|
+
return "pause";
|
|
195
232
|
default:
|
|
196
233
|
return "other";
|
|
197
234
|
}
|
|
@@ -384,7 +421,13 @@ function anthropic(anthropicParams) {
|
|
|
384
421
|
}
|
|
385
422
|
}
|
|
386
423
|
);
|
|
387
|
-
const client = createClient(
|
|
424
|
+
const client = createClient(
|
|
425
|
+
SDK,
|
|
426
|
+
apiKey,
|
|
427
|
+
apiKey.includes("sk-ant-oat"),
|
|
428
|
+
anthropicParams?.baseURL,
|
|
429
|
+
anthropicParams?.extraBetas
|
|
430
|
+
);
|
|
388
431
|
const system = isOAuth ? `You are Claude Code, Anthropic's official CLI for Claude.` : options.system;
|
|
389
432
|
const messages = isOAuth && options.system ? [
|
|
390
433
|
{ role: "user", content: [{ type: "text", text: options.system }] },
|
|
@@ -401,6 +444,10 @@ function anthropic(anthropicParams) {
|
|
|
401
444
|
messages: messages.map((m) => toAnthropic(m)),
|
|
402
445
|
stream: true
|
|
403
446
|
};
|
|
447
|
+
if (anthropicParams?.contextManagement) {
|
|
448
|
+
;
|
|
449
|
+
params.context_management = anthropicParams.contextManagement;
|
|
450
|
+
}
|
|
404
451
|
if (options.cache !== false)
|
|
405
452
|
applyAnthropicCacheBreakpoints(params);
|
|
406
453
|
const plan = planAnthropicThinking(thinking, options.thinkingBudget);
|
|
@@ -412,6 +459,8 @@ function anthropic(anthropicParams) {
|
|
|
412
459
|
params.thinking = { type: "adaptive" };
|
|
413
460
|
if (plan.effort)
|
|
414
461
|
params.output_config = { effort: plan.effort };
|
|
462
|
+
if (typeof plan.maxTokensCap === "number" && plan.maxTokensCap > 0)
|
|
463
|
+
params.max_tokens = Math.min(params.max_tokens, plan.maxTokensCap);
|
|
415
464
|
}
|
|
416
465
|
params.temperature = 1;
|
|
417
466
|
}
|
|
@@ -439,11 +488,12 @@ function anthropic(anthropicParams) {
|
|
|
439
488
|
const response = await s.finalMessage();
|
|
440
489
|
const toolCalls = response.content.filter((b) => b.type === "tool_use").map((b) => ({ id: b.id, name: b.name, input: b.input }));
|
|
441
490
|
const finishReason = mapStopReason(response.stop_reason);
|
|
491
|
+
const isPause = response.stop_reason === "pause_turn";
|
|
442
492
|
return {
|
|
443
493
|
assistantMessage: fromAnthropic({ role: "assistant", content: response.content }),
|
|
444
494
|
text,
|
|
445
495
|
toolCalls,
|
|
446
|
-
done: response.stop_reason === "end_turn" || toolCalls.length === 0,
|
|
496
|
+
done: !isPause && (response.stop_reason === "end_turn" || toolCalls.length === 0),
|
|
447
497
|
usage: {
|
|
448
498
|
input: response.usage.input_tokens,
|
|
449
499
|
output: response.usage.output_tokens,
|