zidane 5.9.12 → 5.9.13
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 +15 -9
- package/docs/ARCHITECTURE.md +2 -2
- package/docs/CHAT.md +2 -2
- package/docs/SKILL.md +10 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Small, hookable core with sensible defaults. Three principles guide the design:
|
|
|
18
18
|
|
|
19
19
|
Everything below is in service of those:
|
|
20
20
|
|
|
21
|
-
- 🧠 **Providers** — Anthropic, OpenAI Codex, OpenRouter, Cerebras, plus `openaiCompat` (Baseten, Fireworks, Groq
|
|
21
|
+
- 🧠 **Providers** — Anthropic, OpenAI Codex, OpenRouter, Cerebras, Arcee, local LLMs, plus `openaiCompat` (Baseten, Fireworks, Groq). OAuth + API key with auto-refresh.
|
|
22
22
|
- 🪝 **Hookable turn loop** — every text/thinking delta, tool call, MCP, session, skill, spawn, OAuth, validation, and budget event is observable and (mostly) mutable.
|
|
23
23
|
- 🛠️ **First-class tools** — `shell`, `read_file`, `write_file`, `edit`, `multi_edit`, `glob`, `grep`, `spawn`, human-in-the-loop, plus any [MCP](https://modelcontextprotocol.io) server. Per-call gates, arg auto-coerce, hallucinated-tool fallback, error rewriting. Lazy MCP disclosure via `tool_search`. Optional `todowrite` / `todoread` for persistent task checkpointing across prompts.
|
|
24
24
|
- 🧮 **Per-tool concurrency** — every `ToolDef` carries `isConcurrencySafe` (default `false`); the dispatcher fans safe siblings out in parallel and barriers unsafe ones. Order is preserved at yield time. Cap via `behavior.maxConcurrentTools`.
|
|
@@ -121,7 +121,9 @@ Precedence: `run.behavior` > `agent.behavior` > defaults.
|
|
|
121
121
|
bun start \
|
|
122
122
|
--prompt "your task" \ # required
|
|
123
123
|
--model claude-opus-4-7 \ # model id
|
|
124
|
-
--provider anthropic \ # anthropic | openai | openrouter | cerebras
|
|
124
|
+
--provider anthropic \ # anthropic | openai | openrouter | cerebras | arcee | local | openai-compat
|
|
125
|
+
--base-url http://localhost:8000/v1 \ # local/openai-compat endpoint
|
|
126
|
+
--header "X-Route: dev" \ # extra header for local/openai-compat
|
|
125
127
|
--preset basic \ # preset name
|
|
126
128
|
--system "be concise" \ # system prompt
|
|
127
129
|
--thinking off \ # off | minimal | low | medium | high
|
|
@@ -129,6 +131,8 @@ bun start \
|
|
|
129
131
|
--mcp '{"name":"fs","transport":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-filesystem","."]}'
|
|
130
132
|
```
|
|
131
133
|
|
|
134
|
+
For `local` / `openai-compat`, `--base-url`, `--api-key-env`, `--headers-env`, `--header`, `--vision`, `--image-in-tool-result`, `--temperature`, and `--seed` apply; hosted providers ignore them.
|
|
135
|
+
|
|
132
136
|
`bun start --restate` runs the same start flow through a local Restate endpoint for durable-execution demos and fixture testing. It starts the service, probes readiness, registers the deployment, invokes `zidane-start-agent`, and exposes `run` / `status` / `history` handlers. See [docs/RESTATE.md](./docs/RESTATE.md) for production wiring and the advanced ReState flags.
|
|
133
137
|
|
|
134
138
|
## Providers
|
|
@@ -164,20 +168,22 @@ anthropic({
|
|
|
164
168
|
|
|
165
169
|
Fallback: `params.apiKey` > `params.access` > `ANTHROPIC_API_KEY` env > `.credentials.json`. `extraBetas` merge with OAuth defaults and de-dupe. `contextManagement` is sent as `context_management`; pair with the matching beta. Non-Anthropic equivalent: `behavior.compactStrategy: 'tail'`. Declares `capabilities.nativeWebSearch`: when the `web_search` tool is registered, the provider swaps in Anthropic's server-side `web_search_20250305` and streams results via `onServerToolUse` / `onServerToolResult`.
|
|
166
170
|
|
|
167
|
-
`extraBodyParams` passes un-typed Messages API fields through (factory options win on collision). Use when Anthropic ships a beta before zidane has a knob. `openaiCompat` accepts the same field (e.g. `reasoning_effort`, `metadata`, OpenRouter `provider` routing).
|
|
171
|
+
`extraHeaders` merges request headers for proxies/gateways; reserved Anthropic headers still win on collision. `extraBodyParams` passes un-typed Messages API fields through (factory options win on collision). Use when Anthropic ships a beta before zidane has a knob. `openaiCompat` accepts the same field (e.g. `reasoning_effort`, `metadata`, OpenRouter `provider` routing).
|
|
168
172
|
|
|
169
|
-
### OpenRouter / OpenAI / Cerebras
|
|
173
|
+
### OpenRouter / OpenAI / Cerebras / Arcee / Local
|
|
170
174
|
|
|
171
175
|
```ts
|
|
172
|
-
import { openrouter, openai, cerebras } from 'zidane/providers'
|
|
176
|
+
import { openrouter, openai, cerebras, arcee, local } from 'zidane/providers'
|
|
173
177
|
|
|
174
178
|
openrouter({ apiKey: 'sk-or-...', defaultModel: 'google/gemini-pro' })
|
|
175
179
|
openai() // OpenAI Codex OAuth
|
|
176
180
|
openai({ access: 'eyJ...', refresh: '...', expires: Date.now() + 3600_000, accountId: 'acct_123' })
|
|
177
181
|
cerebras({ apiKey: 'csk-...', defaultModel: 'zai-glm-4.7' })
|
|
182
|
+
arcee({ apiKey: 'arcee-...', defaultModel: 'trinity-large-thinking' })
|
|
183
|
+
local({ baseURL: 'http://localhost:8000/v1', defaultModel: 'qwen3-coder' })
|
|
178
184
|
```
|
|
179
185
|
|
|
180
|
-
Fallbacks: `params.apiKey` > `params.access` (Codex) > `<PROVIDER>_API_KEY` env > `.credentials.json` (Codex). Pass full OAuth fields on `openai()` to auto-refresh without reading `.credentials.json`.
|
|
186
|
+
Fallbacks: `params.apiKey` > `params.access` (Codex) > `<PROVIDER>_API_KEY` env > `.credentials.json` (Codex). `local` uses `LOCAL_LLM_BASE_URL`, `LOCAL_LLM_API_KEY`, and `LOCAL_LLM_DEFAULT_MODEL`. Pass full OAuth fields on `openai()` to auto-refresh without reading `.credentials.json`.
|
|
181
187
|
|
|
182
188
|
### OpenAI-compatible (custom endpoints)
|
|
183
189
|
|
|
@@ -196,7 +202,7 @@ openaiCompat({
|
|
|
196
202
|
})
|
|
197
203
|
```
|
|
198
204
|
|
|
199
|
-
`openrouter` and `
|
|
205
|
+
`openrouter`, `cerebras`, `arcee`, and `local` are thin wrappers with vendor/runtime defaults pinned. Use `openaiCompat` directly for new backends.
|
|
200
206
|
|
|
201
207
|
### Prompt caching
|
|
202
208
|
|
|
@@ -206,7 +212,7 @@ openaiCompat({
|
|
|
206
212
|
|---|---|
|
|
207
213
|
| `anthropic` | Honored natively. |
|
|
208
214
|
| `openrouter` | Forwarded; Anthropic + Gemini honor; OpenAI / DeepSeek / Grok / Groq / Moonshot cache automatically and ignore the markers. |
|
|
209
|
-
| `openaiCompat` |
|
|
215
|
+
| `arcee` / `local` / `openaiCompat` | Off by default for strict OpenAI-compatible schemas; use `openaiCompat({ cacheBreakpoints: true })` only for endpoints that honor `cache_control`. |
|
|
210
216
|
| `cerebras` | Off. |
|
|
211
217
|
| `openai` (Codex) | Not affected (pi-ai wire format). |
|
|
212
218
|
|
|
@@ -238,7 +244,7 @@ await agent.run({ prompt: 'just chat', tools: {} }) // no tools for one run
|
|
|
238
244
|
|
|
239
245
|
## Thinking
|
|
240
246
|
|
|
241
|
-
Named levels or exact budgets. Traces persist as `{ type: 'thinking', text }` blocks and stream via `stream:thinking`. Supported by Anthropic (native) and OpenRouter/
|
|
247
|
+
Named levels or exact budgets. Traces persist as `{ type: 'thinking', text }` blocks and stream via `stream:thinking`. Supported by Anthropic (native) and OpenRouter/Arcee (`reasoning_content`/`reasoning` SSE fields).
|
|
242
248
|
|
|
243
249
|
| Level | Default budget |
|
|
244
250
|
|---|---|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -312,7 +312,7 @@ Provider semantics:
|
|
|
312
312
|
|---|---|
|
|
313
313
|
| `anthropic` | Breakpoints honored natively. |
|
|
314
314
|
| `openrouter` | Breakpoints forwarded; Anthropic + Gemini routes honor them, others ignore. |
|
|
315
|
-
| `openaiCompat` | Factory-gated via `cacheBreakpoints: boolean` (default **off**). `openrouter` flips it on; bare `openaiCompat`
|
|
315
|
+
| `arcee` / `local` / `openaiCompat` | Factory-gated via `cacheBreakpoints: boolean` (default **off**). `openrouter` flips it on; Arcee/local/bare `openaiCompat` stay off so strict OpenAI-compatible endpoints don't reject unknown fields. |
|
|
316
316
|
| `cerebras` | Off (factory doesn't enable breakpoints). |
|
|
317
317
|
| `openai` (Codex) | Not affected — separate wire format (pi-ai). |
|
|
318
318
|
|
|
@@ -352,7 +352,7 @@ The built-in profiles (`buildBuildSystem` / `buildPlanSystem` in `zidane/chat`)
|
|
|
352
352
|
|
|
353
353
|
- `anthropic` — `applyAnthropicCacheBreakpoints(params, originalSystem)` splits string system prompts on the marker. The OAuth path skips the split (the canonical CC prompt occupies `params.system`; the user doctrine lives in an injected user message).
|
|
354
354
|
- `openaiCompat` — `toOAIMessages` strips the marker; `applyOAICacheBreakpoints(messages, originalSystem)` splits the leading system message into static + dynamic content parts when caching is on.
|
|
355
|
-
- `openai` (Codex), `cerebras`, and any cache-disabled route — marker is collapsed via `renderSystemForWire` so it never reaches the model.
|
|
355
|
+
- `openai` (Codex), `cerebras`, `arcee`, `local`, and any cache-disabled route — marker is collapsed via `renderSystemForWire` so it never reaches the model.
|
|
356
356
|
|
|
357
357
|
### Cache-break diagnosis
|
|
358
358
|
|
package/docs/CHAT.md
CHANGED
|
@@ -151,7 +151,7 @@ The table below indexes every named export; sections further down dive into the
|
|
|
151
151
|
| `project-root` | `findGitRoot(cwd)` — walks upward looking for `.git`, returns absolute path or `null`. Used for session scope tagging + export anchors. |
|
|
152
152
|
| `prompt-segments` | `splitPromptSegments(text, refs)` → `PromptSegment[]`. GUI maps the same segments to inline-block chip pills. |
|
|
153
153
|
| `project-user-paths` | `projectUserPaths({ subPath, cwd, home, prefix })` — shared search-order builder for project + user config discovery. Powers `defaultSkillScanPaths` (`'skills'`) and `defaultMcpsConfigPaths` (calls it twice, once per `mcps.json` / `mcp.json`); the same convention extends to any new discovery surface. |
|
|
154
|
-
| `providers` | `ProviderDescriptor` registry + helpers — `BUILTIN_PROVIDERS` (`anthropicDescriptor`, `openaiDescriptor`, `openrouterDescriptor`, `cerebrasDescriptor`, `localDescriptor`), `modelsForDescriptor`, `getModelInfo`, `getContextWindow`, `effectiveContextWindow`, `modelSupportsReasoning`, `OUTPUT_RESERVE_TOKENS`, `credKeyOf`, `piIdOf`. `cursorDescriptor` is exported but NOT in `BUILTIN_PROVIDERS` (OAuth works, inference not wired). See **Local provider**. |
|
|
154
|
+
| `providers` | `ProviderDescriptor` registry + helpers — `BUILTIN_PROVIDERS` (`anthropicDescriptor`, `openaiDescriptor`, `openrouterDescriptor`, `cerebrasDescriptor`, `arceeDescriptor`, `localDescriptor`), `modelsForDescriptor`, `getModelInfo`, `getContextWindow`, `effectiveContextWindow`, `modelSupportsReasoning`, `OUTPUT_RESERVE_TOKENS`, `credKeyOf`, `piIdOf`. `cursorDescriptor` is exported but NOT in `BUILTIN_PROVIDERS` (OAuth works, inference not wired). See **Local provider**. |
|
|
155
155
|
| `safe-mode` | Per-project safelist + matchers — `IMPLICITLY_SAFE_TOOLS`, `suggestSafelistEntry`, `addToSafelist`, `getSafelist`, `isOnSafelist`, `matchesSafelistEntry`, `readProjects`, `writeProjects`, `projectsFilePath`. |
|
|
156
156
|
| `safe-mode-context` | `SafeModeProvider` owns a FIFO approval queue. `useSafeModeQueue()` returns the live array; `useSafeModeActions()` returns stable `{ requestApproval, resolveHead, denyAll }`. |
|
|
157
157
|
| `session-export` | `renderSession`, `resolveSessionExportTarget`, `writeSessionExport`, `SessionExportFormat`, `SessionExportAnchor`, `SessionExportTarget`. |
|
|
@@ -186,7 +186,7 @@ resolveConfig({
|
|
|
186
186
|
projectDb: false,
|
|
187
187
|
cwd: process.cwd(), // override the project-root walk root
|
|
188
188
|
|
|
189
|
-
// Provider registry — defaults to BUILTIN_PROVIDERS (Anthropic + OpenAI + OpenRouter + Cerebras).
|
|
189
|
+
// Provider registry — defaults to BUILTIN_PROVIDERS (Anthropic + OpenAI + OpenRouter + Cerebras + Arcee + Local).
|
|
190
190
|
providers: { ...BUILTIN_PROVIDERS, mine: myDescriptor },
|
|
191
191
|
|
|
192
192
|
// Agent registry — defaults to BUILTIN_AGENTS (Build + Plan).
|
package/docs/SKILL.md
CHANGED
|
@@ -11,7 +11,7 @@ Minimal TypeScript agent loop built with Bun. Streams from an LLM, executes tool
|
|
|
11
11
|
|
|
12
12
|
## Core Concepts
|
|
13
13
|
|
|
14
|
-
- **Provider** — LLM backend (Anthropic, OpenAI Codex, OpenRouter, Cerebras). Streaming, format conversion, tool wiring. Anthropic + Codex support OAuth.
|
|
14
|
+
- **Provider** — LLM backend (Anthropic, OpenAI Codex, OpenRouter, Cerebras, Arcee, local LLMs). Streaming, format conversion, tool wiring. Anthropic + Codex support OAuth.
|
|
15
15
|
- **Preset** — `Partial<AgentOptions>` (tools, system, aliases, mcpServers, skills, behavior, hooks). `basicTools` ships `shell`, `readFile`, `writeFile`, `listFiles`, `edit`, `multiEdit`; the `basic` preset adds `spawn`. Override `tools: {}` for untrusted prompts.
|
|
16
16
|
- **Agent** — `createAgent()` returns one. Turn loop: prompt → LLM → tool calls → tool results → … until done or `maxTurns`.
|
|
17
17
|
- **Session** — Optional persistent turn history. Written incrementally.
|
|
@@ -85,11 +85,12 @@ Precedence: `run.behavior` > `agent.behavior` > defaults. `prompt` is required u
|
|
|
85
85
|
All providers accept runtime keys via params. Env vars are fallbacks. OAuth credentials are read from `.credentials.json` and auto-refreshed (populate via `bun run auth`).
|
|
86
86
|
|
|
87
87
|
```ts
|
|
88
|
-
import { anthropic, openai, openrouter, cerebras, openaiCompat } from 'zidane'
|
|
88
|
+
import { anthropic, openai, openrouter, cerebras, arcee, local, openaiCompat } from 'zidane'
|
|
89
89
|
|
|
90
90
|
anthropic({ apiKey: 'sk-ant-...', defaultModel: 'claude-opus-4-8' })
|
|
91
91
|
anthropic({ access: 'sk-ant-oat-...', refresh: '...', expires: 1234567890 }) // OAuth
|
|
92
92
|
anthropic({ apiKey: 'sk-ant-...', baseURL: 'https://gateway.corp/anthropic' }) // full proxy
|
|
93
|
+
anthropic({ apiKey: 'sk-ant-...', extraHeaders: { 'X-Route': 'claude-prod' } }) // proxy headers
|
|
93
94
|
anthropic({ // first-party betas
|
|
94
95
|
apiKey: 'sk-ant-...',
|
|
95
96
|
extraBetas: ['context-management-2025-06-27', 'token-efficient-tools-2026-03-28'],
|
|
@@ -105,6 +106,8 @@ anthropic({ /
|
|
|
105
106
|
openai({ apiKey: 'sk-...', defaultModel: 'gpt-5.5' }) // OpenAI Codex (OAuth too)
|
|
106
107
|
openrouter({ apiKey: 'sk-or-...', defaultModel: 'google/gemini-pro' })
|
|
107
108
|
cerebras({ apiKey: 'csk-...', defaultModel: 'zai-glm-4.7' })
|
|
109
|
+
arcee({ apiKey: 'arcee-...', defaultModel: 'trinity-large-thinking' })
|
|
110
|
+
local({ baseURL: 'http://localhost:8000/v1', defaultModel: 'qwen3-coder' })
|
|
108
111
|
|
|
109
112
|
// Public factory for any OpenAI-compatible endpoint:
|
|
110
113
|
openaiCompat({
|
|
@@ -115,9 +118,9 @@ openaiCompat({
|
|
|
115
118
|
})
|
|
116
119
|
```
|
|
117
120
|
|
|
118
|
-
Provider params types: `AnthropicParams`, `OpenAIParams`, `OpenRouterParams`, `CerebrasParams`, `OpenAICompatParams` — exported from `zidane`.
|
|
121
|
+
Provider params types: `AnthropicParams`, `OpenAIParams`, `OpenRouterParams`, `CerebrasParams`, `ArceeParams`, `LocalParams`, `OpenAICompatParams` — exported from `zidane`.
|
|
119
122
|
|
|
120
|
-
`openrouter` and `
|
|
123
|
+
`openrouter`, `cerebras`, `arcee`, and `local` are thin wrappers over `openaiCompat` with vendor/runtime defaults pinned. For new OAI-compatible backends (Baseten, Fireworks, Groq), use `openaiCompat` directly.
|
|
121
124
|
|
|
122
125
|
### Vision + image tool results
|
|
123
126
|
|
|
@@ -152,7 +155,7 @@ Flatten via `toolResultToText(result)`. MCP image blocks are auto-normalized via
|
|
|
152
155
|
|---|---|
|
|
153
156
|
| `anthropic` | Honored natively. |
|
|
154
157
|
| `openrouter` | Forwarded to Anthropic + Gemini routes; ignored by OpenAI / DeepSeek / Grok / Groq / Moonshot (those cache automatically). |
|
|
155
|
-
| `
|
|
158
|
+
| `arcee` / `local` / `openaiCompat` | Off by default so strict-schema endpoints don't reject unknown fields. Use `openaiCompat({ cacheBreakpoints: true })` only for hosts that honor `cache_control`. |
|
|
156
159
|
| `cerebras` | Off. |
|
|
157
160
|
| `openai` (Codex) | Not affected (pi-ai wire format). |
|
|
158
161
|
|
|
@@ -857,6 +860,7 @@ createSandboxContext(myProvider) // implement SandboxProvider (E2B, Rivet, …)
|
|
|
857
860
|
| `FileMapAdapter` | `{ get, save, delete }` — host-SDK seam for `createFileMapStore`. |
|
|
858
861
|
| `TracingHooksOptions` | `createTracingHooks` config (`startSpan`, `namespace?`). |
|
|
859
862
|
| `OpenAICompatParams` | `openaiCompat()` config (apiKey, baseURL, authHeader, extraHeaders, capabilities, cacheBreakpoints). |
|
|
863
|
+
| `ArceeParams` / `LocalParams` | OpenAI-compatible wrapper configs for Arcee Platform and self-hosted local endpoints. |
|
|
860
864
|
| `ValidationResult` | `{ valid, error?, coercedInput?, coercions?, droppedItems? }` — `validateToolArgs` output. `droppedItems` is keyed by field name and reports the original indexes of items dropped during recursive array validation. |
|
|
861
865
|
| `AgentHookMap` | `{ [event]: handler \| handler[] }` — agent-lifetime hooks on `AgentOptions.hooks`. |
|
|
862
866
|
| `RunHookMap` | Same shape, per-run scope (`agent.run({ hooks })`); handlers auto-detach. |
|
|
@@ -885,7 +889,7 @@ src/
|
|
|
885
889
|
zod.ts zodToJsonSchema (v4)
|
|
886
890
|
auth.ts OAuth login CLI
|
|
887
891
|
start.ts CLI entrypoint
|
|
888
|
-
providers/ anthropic, openai (Codex), openrouter, cerebras, openaiCompat + oauth helpers
|
|
892
|
+
providers/ anthropic, openai (Codex), openrouter, cerebras, arcee, local, openaiCompat + oauth helpers
|
|
889
893
|
presets/ basic, basicTools, definePreset, composePresets
|
|
890
894
|
tools/ Built-ins + skills tools + validation (auto-coerce)
|
|
891
895
|
session/ memory, sqlite, remote, file-map + converters
|