@tekmidian/pai 0.49.0 → 0.51.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/dist/{aibroker-client-D5NT0S1N.mjs → aibroker-client-Bu72yPKj.mjs} +1 -1
- package/dist/{aibroker-client-Bn9SnGMa.mjs → aibroker-client-CDIXmq-e.mjs} +1 -1
- package/dist/{aibroker-client-Bn9SnGMa.mjs.map → aibroker-client-CDIXmq-e.mjs.map} +1 -1
- package/dist/{chain-CNSa0A3G.mjs → chain-BBbVbWVv.mjs} +4 -4
- package/dist/{chain-CNSa0A3G.mjs.map → chain-BBbVbWVv.mjs.map} +1 -1
- package/dist/cli/index.mjs +14 -14
- package/dist/cli/program.mjs +14 -14
- package/dist/config-Bn9jpblO.mjs +653 -0
- package/dist/config-Bn9jpblO.mjs.map +1 -0
- package/dist/{config-DxMZjpvY.mjs → config-DYXARgk8.mjs} +180 -151
- package/dist/config-DYXARgk8.mjs.map +1 -0
- package/dist/config-RjeVGJ7K.mjs +3 -0
- package/dist/{context-handover-cache-B9NKSjwR.mjs → context-handover-cache-yOuK9RIk.mjs} +5 -5
- package/dist/{context-handover-cache-B9NKSjwR.mjs.map → context-handover-cache-yOuK9RIk.mjs.map} +1 -1
- package/dist/daemon/index.mjs +13 -12
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{daemon-DZ4Q0jrs.mjs → daemon-CBTQYtHF.mjs} +49 -30
- package/dist/daemon-CBTQYtHF.mjs.map +1 -0
- package/dist/daemon-Vf7pHnjR.mjs +25 -0
- package/dist/daemon-mcp/index.mjs +186 -23
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/factory-Ba8j9K7q.mjs +3 -0
- package/dist/{factory-DNYAqjH0.mjs → factory-Bt7TWQje.mjs} +3 -3
- package/dist/{factory-DNYAqjH0.mjs.map → factory-Bt7TWQje.mjs.map} +1 -1
- package/dist/{fallback-IeR2FrFn.mjs → fallback-CIGspCSi.mjs} +260 -10
- package/dist/fallback-CIGspCSi.mjs.map +1 -0
- package/dist/hooks/capture-all-events.mjs +80 -8
- package/dist/hooks/capture-all-events.mjs.map +4 -4
- package/dist/hooks/context-compression-hook.mjs +54 -39
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/post-compact-inject.mjs +54 -39
- package/dist/hooks/post-compact-inject.mjs.map +4 -4
- package/dist/hooks/route-agents-to-worker.mjs +204 -109
- package/dist/hooks/route-agents-to-worker.mjs.map +4 -4
- package/dist/hooks/whisper-rules.mjs +7613 -9
- package/dist/hooks/whisper-rules.mjs.map +4 -4
- package/dist/hooks/worker-proxy.mjs +204 -109
- package/dist/hooks/worker-proxy.mjs.map +4 -4
- package/dist/hooks/worker-status-line.mjs +211 -116
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/hooks/worker-supervision.mjs +208 -113
- package/dist/hooks/worker-supervision.mjs.map +4 -4
- package/dist/{kg-entity-BSjM5xZh.mjs → kg-entity-BSW7ra8i.mjs} +1 -1
- package/dist/{kg-entity-BSjM5xZh.mjs.map → kg-entity-BSW7ra8i.mjs.map} +1 -1
- package/dist/main-resolver-BTastpp4.mjs +7 -0
- package/dist/{main-resolver-DvYu9jbl.mjs → main-resolver-BmZPCmgj.mjs} +3 -3
- package/dist/{main-resolver-DvYu9jbl.mjs.map → main-resolver-BmZPCmgj.mjs.map} +1 -1
- package/dist/{planner-Cn8HmT7l.mjs → planner-BiH9msqq.mjs} +6 -6
- package/dist/{planner-Cn8HmT7l.mjs.map → planner-BiH9msqq.mjs.map} +1 -1
- package/dist/{program-D9-wfmkZ.mjs → program-srUeFUfW.mjs} +5806 -5615
- package/dist/program-srUeFUfW.mjs.map +1 -0
- package/dist/query-feedback-Bm6XvCmg.mjs +3 -0
- package/dist/{query-feedback-CYyOGi3y.mjs → query-feedback-CTs_jx6i.mjs} +1 -1
- package/dist/{query-feedback-CYyOGi3y.mjs.map → query-feedback-CTs_jx6i.mjs.map} +1 -1
- package/dist/{run-Cls0YGgV.mjs → run-TChOnMO_.mjs} +1388 -1183
- package/dist/run-TChOnMO_.mjs.map +1 -0
- package/dist/{server-Ch99xt5K.mjs → server-R9UkCn3v.mjs} +42 -3
- package/dist/server-R9UkCn3v.mjs.map +1 -0
- package/dist/session-keepalive-BuG3wvik.mjs +579 -0
- package/dist/session-keepalive-BuG3wvik.mjs.map +1 -0
- package/dist/skills/VaultContext/SKILL.md +1 -1
- package/dist/{state-DnYGRmS7.mjs → state-Ca0ltLgI.mjs} +1 -1
- package/dist/{state-PJrgfDLW.mjs → state-DwrsOoMi.mjs} +1 -1
- package/dist/{state-PJrgfDLW.mjs.map → state-DwrsOoMi.mjs.map} +1 -1
- package/dist/{tools-B77WHeVZ.mjs → tools-BEqiJt_j.mjs} +13 -13
- package/dist/{tools-B77WHeVZ.mjs.map → tools-BEqiJt_j.mjs.map} +1 -1
- package/dist/{tools-NnR_n-Ja.mjs → tools-BwsOTmjh.mjs} +2 -2
- package/dist/{wakeup-UrhiW-KU.mjs → wakeup-Yk5lQ0jb.mjs} +1 -1
- package/dist/{wakeup-UrhiW-KU.mjs.map → wakeup-Yk5lQ0jb.mjs.map} +1 -1
- package/dist/{work-queue-worker-BA5IDBwQ.mjs → work-queue-worker-B9zVWImP.mjs} +3 -3
- package/dist/{work-queue-worker-BA5IDBwQ.mjs.map → work-queue-worker-B9zVWImP.mjs.map} +1 -1
- package/dist/work-queue-worker-D-DnQ7oh.mjs +14 -0
- package/dist/{zettelkasten-BBjA7GcP.mjs → zettelkasten-DezbXghl.mjs} +2 -2
- package/dist/{zettelkasten-BBjA7GcP.mjs.map → zettelkasten-DezbXghl.mjs.map} +1 -1
- package/docs/cache-keepalive.md +138 -0
- package/docs/commands/README.md +7 -0
- package/docs/commands/audit.md +1 -1
- package/docs/commands/config.md +84 -0
- package/docs/commands/daemon.md +6 -0
- package/docs/commands/worker.md +37 -2
- package/docs/config.md +171 -0
- package/docs/model-catalogue.md +502 -0
- package/docs/provider-independence-details.md +1 -1
- package/docs/task-bus.md +1 -1
- package/docs/worker.md +33 -5
- package/docs/workers-config.md +105 -12
- package/package.json +1 -1
- package/src/hooks/ts/capture-all-events.test.ts +71 -0
- package/src/hooks/ts/capture-all-events.ts +10 -3
- package/src/hooks/ts/lib/context-fill.test.ts +124 -46
- package/src/hooks/ts/lib/context-fill.ts +57 -14
- package/src/hooks/ts/user-prompt/whisper-rules.test.ts +56 -1
- package/src/hooks/ts/user-prompt/whisper-rules.ts +24 -0
- package/statusline-command.sh +103 -16
- package/dist/config-DCu8THKi.mjs +0 -228
- package/dist/config-DCu8THKi.mjs.map +0 -1
- package/dist/config-DeqFqa1N.mjs +0 -3
- package/dist/config-DxMZjpvY.mjs.map +0 -1
- package/dist/daemon-CYpVy_Dw.mjs +0 -24
- package/dist/daemon-DZ4Q0jrs.mjs.map +0 -1
- package/dist/factory-47Qf_df7.mjs +0 -3
- package/dist/fallback-IeR2FrFn.mjs.map +0 -1
- package/dist/indexer-C5Le7XE7.mjs +0 -1
- package/dist/main-resolver-CnfnWa8C.mjs +0 -7
- package/dist/program-D9-wfmkZ.mjs.map +0 -1
- package/dist/query-feedback-C7rSfiXU.mjs +0 -3
- package/dist/run-Cls0YGgV.mjs.map +0 -1
- package/dist/server-Ch99xt5K.mjs.map +0 -1
- package/dist/work-queue-worker-DLM2wlqM.mjs +0 -14
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
# Model catalogue for PAI providers (2026-09-20)
|
|
2
|
+
|
|
3
|
+
Every row below was checked against the provider's own docs/pricing page via
|
|
4
|
+
WebFetch, or — where the official page didn't render a usable table for the
|
|
5
|
+
fetch summarizer, or officially wasn't reachable — against a WebSearch
|
|
6
|
+
synthesis of third-party trackers, marked "3rd-party" in the Source column.
|
|
7
|
+
Anything neither source confirmed is UNKNOWN. Prices are list/pay-as-you-go,
|
|
8
|
+
USD, as of today; providers change these often — re-check before relying on
|
|
9
|
+
a number for billing.
|
|
10
|
+
|
|
11
|
+
Context on what PAI can run today (verified in this worktree, not assumed):
|
|
12
|
+
|
|
13
|
+
- `WorkerProtocol` is `"anthropic" | "openai"` (`src/workers/config.ts:37`).
|
|
14
|
+
`"openai"` runs through PAI's local proxy (`src/workers/proxy/`), which
|
|
15
|
+
translates Anthropic Messages ⇄ OpenAI Chat Completions — **not** the
|
|
16
|
+
Responses API.
|
|
17
|
+
- `MODEL_CAPABILITIES` is the closed set `["default", "fast", "image"]`
|
|
18
|
+
(`src/workers/config.ts:261`). There is **no** open-set `models: {…,
|
|
19
|
+
vision, longcontext, reasoning}` and **no** top-level `capabilities:`
|
|
20
|
+
preference map in this codebase today — the spec's mention of both is
|
|
21
|
+
forward-looking (a parallel worker's WIP), not current state. The nearest
|
|
22
|
+
existing equivalents are `tags:` (`code, vision, image-gen, long-context,
|
|
23
|
+
fast, reasoning` — routing filters, not model ids) and `classes.<name>` /
|
|
24
|
+
`classes.<name>.requireTags`.
|
|
25
|
+
- There is **no `image` engine**. `WorkerEngine` is `"claude" | "codex"`
|
|
26
|
+
only (`src/workers/config.ts:40`). A provider's `models.image` id is real
|
|
27
|
+
config (`glm.models.image: example-paint` is already set in the live
|
|
28
|
+
`workers.yaml`) but nothing in `run.ts` treats it specially: the "image"
|
|
29
|
+
class just launches Claude Code or Codex with `--model <that id>` over the
|
|
30
|
+
normal chat protocol. **No code path calls an images-generation endpoint**
|
|
31
|
+
(`POST {url}/images/generations` or equivalent). Until that engine lands,
|
|
32
|
+
none of the image-generation APIs in §1.11 are reachable through
|
|
33
|
+
`pai worker run` — see §2 and §5.
|
|
34
|
+
|
|
35
|
+
## 1. Provider families
|
|
36
|
+
|
|
37
|
+
### 1.1 Anthropic
|
|
38
|
+
|
|
39
|
+
Source: https://platform.claude.com/docs/en/models/overview (redirects from
|
|
40
|
+
docs.anthropic.com; fetched verbatim).
|
|
41
|
+
|
|
42
|
+
| Model id | For | Context | Max output | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
43
|
+
|---|---|---|---|---|---|---|---|
|
|
44
|
+
| `claude-fable-5-1` | reasoning, longcontext | 1M | 128K | $10 / $50 | anthropic | api.anthropic.com | Adaptive thinking always on; knowledge cutoff Jun 2026 |
|
|
45
|
+
| `claude-opus-5` | default (complex) | 1M | 128K | $5 / $25 | anthropic | api.anthropic.com | |
|
|
46
|
+
| `claude-sonnet-5` | default | 1M | 128K | $2 / $10 | anthropic | api.anthropic.com | PAI's `NATIVE_ANTHROPIC_MODELS.default` |
|
|
47
|
+
| `claude-haiku-4-5-20251001` | fast | 200K | 64K | $1 / $5 | anthropic | api.anthropic.com | PAI's `NATIVE_ANTHROPIC_MODELS.fast`; vision on all four |
|
|
48
|
+
|
|
49
|
+
All four: text+image input, vision, tool use, native to PAI's `protocol:
|
|
50
|
+
"anthropic"` — no proxy, no translation, this is what `ANTHROPIC_NATIVE`
|
|
51
|
+
already runs on.
|
|
52
|
+
|
|
53
|
+
### 1.2 OpenAI
|
|
54
|
+
|
|
55
|
+
Sources: https://developers.openai.com/api/docs/models (redirects from
|
|
56
|
+
platform.openai.com/docs/models; WebFetch, some entries cross-checked by
|
|
57
|
+
WebSearch since the fetch summarizer produced a couple of clearly-fabricated
|
|
58
|
+
codenames on the first pass — see caveat below) and
|
|
59
|
+
https://developers.openai.com/api/docs/models/gpt-6-astra (fetched directly,
|
|
60
|
+
verbatim numbers).
|
|
61
|
+
|
|
62
|
+
| Model id | For | Context | Max output | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
63
|
+
|---|---|---|---|---|---|---|---|
|
|
64
|
+
| `gpt-6-astra` | default (flagship) | 1.05M | 128K | $10 / $50 | openai-chat *(Chat Completions listed "Supported") / openai-responses for tool calling* | api.openai.com/v1 | Tool calling requires the Responses API per OpenAI's own migration guide — a plain chat run works over Chat Completions, but PAI workers that use tools would lose them through the proxy today |
|
|
65
|
+
| `gpt-5.1` | default (legacy) | 400K | 128K | UNKNOWN (legacy pricing page not fetched) | openai-chat | api.openai.com/v1 | Still listed, "previous flagship" |
|
|
66
|
+
| `gpt-5-mini` | fast | 272K–400K (sources disagree) | 128K | $0.25 / $2.00 | openai-chat | api.openai.com/v1 | 3rd-party cross-check |
|
|
67
|
+
| `gpt-5-nano` | fast | 272K–400K (sources disagree) | 128K | $0.05 / $0.40 | openai-chat | api.openai.com/v1 | 3rd-party cross-check |
|
|
68
|
+
| `gpt-image-2` (snapshot `gpt-image-2-2026-04-21`) | image | n/a | n/a | ~$0.006 / $0.053 / $0.211 per 1024×1024 image at low/med/high quality (metered as output image tokens, not a flat per-image price) | images-api | api.openai.com/v1/images/generations | 3rd-party; current flagship image model, replaces `gpt-image-1.5` |
|
|
69
|
+
| `gpt-image-1-mini` | image | n/a | n/a | ~$0.005 / $0.011 / $0.036 per image (low/med/high, 1024×1024) | images-api | api.openai.com/v1/images/generations | 3rd-party |
|
|
70
|
+
|
|
71
|
+
**Caveat on this table:** the first WebFetch against `developers.openai.com/api/docs/models`
|
|
72
|
+
returned model ids (`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`,
|
|
73
|
+
`gpt-daybreak-red-latest`, `gpt-daybreak-blue-latest`) that could not be
|
|
74
|
+
corroborated by a follow-up WebSearch and read as fabricated by the
|
|
75
|
+
page-summarizing model — they are **not** included above. `gpt-6-astra` and
|
|
76
|
+
the GPT-5.x ids *were* corroborated independently (direct fetch of its own
|
|
77
|
+
model page, plus multiple WebSearch hits referencing it as "the current
|
|
78
|
+
flagship" and giving matching numbers), so those are kept. Treat any OpenAI
|
|
79
|
+
model id not in the table above, that you see in a single search result, as
|
|
80
|
+
unverified until you load its own `/docs/models/<id>` page directly.
|
|
81
|
+
|
|
82
|
+
### 1.3 Google Gemini
|
|
83
|
+
|
|
84
|
+
Sources: https://ai.google.dev/gemini-api/docs/models (WebFetch),
|
|
85
|
+
https://ai.google.dev/gemini-api/docs/pricing (WebFetch, verbatim numbers),
|
|
86
|
+
WebSearch cross-check against ai.google.dev/gemini-api/docs/gemini-3 and
|
|
87
|
+
OpenRouter listings.
|
|
88
|
+
|
|
89
|
+
| Model id | For | Context | Vision | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
90
|
+
|---|---|---|---|---|---|---|---|
|
|
91
|
+
| `gemini-3-pro-preview` | default | 1,048,576 | yes | UNKNOWN (deprecated, shut down 2026-03-09) | openai-chat *(via compat layer)* or native REST | generativelanguage.googleapis.com | Superseded by `gemini-3.1-pro-preview` |
|
|
92
|
+
| `gemini-3.5-flash` | default/fast | 1,048,576 | yes | $1.50 / $9.00 | openai-chat or native REST | generativelanguage.googleapis.com | |
|
|
93
|
+
| `gemini-3.5-flash-lite` | fast | 1,048,576 | yes | $0.30 / $2.50 | openai-chat or native REST | generativelanguage.googleapis.com | text/image/video/audio input |
|
|
94
|
+
| `gemini-3.8-flash` | default/fast | UNKNOWN | yes | $0.75 / $3.75 (promo through 2026-12-31, then $1.50/$7.50) | openai-chat or native REST | generativelanguage.googleapis.com | Latest in the 3.x Flash line per docs |
|
|
95
|
+
| `gemini-3.1-flash-image` ("Nano Banana 2") | image | UNKNOWN | yes (image in/out) | $0.50/1M input; image output ≈$0.045/0.5K-px image, $0.067/1K-px image | images-api-ish *(REST `generateContent`, not OpenAI images schema)* | generativelanguage.googleapis.com | Real Google-used nickname; verified by 2 independent WebSearch results |
|
|
96
|
+
| `gemini-3.1-flash-lite-image` ("Nano Banana 2 Lite") | image | UNKNOWN | yes | $0.25/1M input; ≈$0.0336/1K-px image output | images-api-ish | generativelanguage.googleapis.com | |
|
|
97
|
+
|
|
98
|
+
Google publishes an OpenAI-compatibility shim
|
|
99
|
+
(`https://generativelanguage.googleapis.com/v1beta/openai/`) documented on
|
|
100
|
+
the same models page, which is why the Chat-family entries above list
|
|
101
|
+
`openai-chat` as usable — PAI's proxy targets exactly that shape.
|
|
102
|
+
|
|
103
|
+
### 1.4 xAI (Grok)
|
|
104
|
+
|
|
105
|
+
Source: https://docs.x.ai/docs/models (WebFetch; ids like
|
|
106
|
+
`grok-4.20-0309-reasoning` look unusual but xAI does use dated build
|
|
107
|
+
suffixes — not independently cross-checked, flagged accordingly).
|
|
108
|
+
|
|
109
|
+
| Model id | For | Context | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
110
|
+
|---|---|---|---|---|---|---|
|
|
111
|
+
| `grok-4.6` | default | 500K | $2.00–4.00 / $6.00–12.00 (tiered past 200K prompt) | openai-chat | api.x.ai/v1 | Docs recommend this as default |
|
|
112
|
+
| `grok-4.3` | longcontext | 1M | $1.25–2.50 / $2.50–5.00 | openai-chat | api.x.ai/v1 | UNVERIFIED beyond single fetch |
|
|
113
|
+
| `grok-build-0.1` | fast/coding | 256K | $1.00–2.00 / $2.00–4.00 | openai-chat | api.x.ai/v1 | UNVERIFIED beyond single fetch |
|
|
114
|
+
| `grok-imagine-image-2.0` | image | n/a | $0.04/image | images-api (xAI-specific schema, not OpenAI images) | api.x.ai/v1 | UNVERIFIED beyond single fetch |
|
|
115
|
+
|
|
116
|
+
xAI's API is documented as OpenAI-Chat-Completions-shaped for the text
|
|
117
|
+
models (this is well-established from xAI's long-standing SDK compat, not
|
|
118
|
+
just this fetch).
|
|
119
|
+
|
|
120
|
+
### 1.5 Mistral
|
|
121
|
+
|
|
122
|
+
Sources: https://docs.mistral.ai/getting-started/models/models_overview/,
|
|
123
|
+
https://mistral.ai/pricing, https://mistral.ai/pricing/api — none of the
|
|
124
|
+
three rendered a full table for the fetch tool; numbers below are the
|
|
125
|
+
fragments the fetches did surface, explicitly marked incomplete.
|
|
126
|
+
|
|
127
|
+
| Model id | For | Context | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
128
|
+
|---|---|---|---|---|---|---|
|
|
129
|
+
| `mistral-large-latest` (Large 3) | default | UNKNOWN | $0.5 / $1.5 | openai-chat | api.mistral.ai/v1 | Exact API id string not confirmed — page named the model "Mistral Large 3", not its API slug |
|
|
130
|
+
| `mistral-medium-latest` (Medium 3.5) | default | UNKNOWN | $1.5 / $7.5 | openai-chat | api.mistral.ai/v1 | Same caveat |
|
|
131
|
+
| `mistral-small-latest` (Small 4) | fast | UNKNOWN | $0.15 / $0.6 | openai-chat | api.mistral.ai/v1 | Same caveat |
|
|
132
|
+
| `codestral-latest` | coding | UNKNOWN | $0.3 / $0.9 | openai-chat | api.mistral.ai/v1 | Same caveat |
|
|
133
|
+
| `ministral-3b-latest` / `ministral-8b-latest` | fast | UNKNOWN | $0.1/$0.1, $0.15/$0.15 | openai-chat | api.mistral.ai/v1 | Same caveat |
|
|
134
|
+
|
|
135
|
+
Mistral's La Plateforme API id strings could not be confirmed from the pages
|
|
136
|
+
fetched (they showed marketing names, not `models/list`-style ids); before
|
|
137
|
+
using any of these, hit `GET https://api.mistral.ai/v1/models` to get exact
|
|
138
|
+
ids. Everything else (pricing, context) is UNKNOWN or from the fragment
|
|
139
|
+
above — do not treat this row group as fully verified.
|
|
140
|
+
|
|
141
|
+
### 1.6 DeepSeek
|
|
142
|
+
|
|
143
|
+
Source: https://api-docs.deepseek.com/quick_start/pricing (WebFetch,
|
|
144
|
+
verbatim).
|
|
145
|
+
|
|
146
|
+
| Model id | For | Context | Max output | Input / Output per 1M | Vision | Protocol | Base URL |
|
|
147
|
+
|---|---|---|---|---|---|---|---|
|
|
148
|
+
| `deepseek-flash` | default/fast | 1M | 384K | $0.15 / $0.60 (off-peak; peak hours 01:00–04:00 & 06:00–10:00 UTC Mon–Fri double the rate) | yes | openai-chat | api.deepseek.com |
|
|
149
|
+
| `deepseek-v4-pro` | default (reasoning) | 1M | 384K | $0.66 / $1.98 (off-peak) | no | openai-chat | api.deepseek.com |
|
|
150
|
+
|
|
151
|
+
Docs explicitly say both accept "OpenAI Format" requests — this is a clean
|
|
152
|
+
`protocol: openai` target for PAI's proxy.
|
|
153
|
+
|
|
154
|
+
### 1.7 Zhipu / Z.ai (GLM)
|
|
155
|
+
|
|
156
|
+
Sources: https://docs.z.ai/api-reference/llm/chat-completion (WebFetch)
|
|
157
|
+
cross-checked by WebSearch against OpenRouter/Requesty/Together listings.
|
|
158
|
+
The live `workers.yaml` in this environment already configures `glm` (real
|
|
159
|
+
key present — not reproduced here) against Z.ai's **Anthropic-compatible**
|
|
160
|
+
endpoint, confirming the second protocol row is real, not just documented.
|
|
161
|
+
|
|
162
|
+
| Model id | For | Context | Max output | Input / Output per 1M | Protocol | Base URL |
|
|
163
|
+
|---|---|---|---|---|---|---|
|
|
164
|
+
| `glm-5.3` | default | 1,048,576 | 128K | $1.40 / $4.40 ($0.26 cached input) | anthropic **or** openai-chat | `https://api.z.ai/api/anthropic` (anthropic) or `https://api.z.ai/api/paas/v4` (openai-chat, `POST /chat/completions`) |
|
|
165
|
+
| `glm-5.3-flash` | fast | UNKNOWN | 128K | UNKNOWN | anthropic or openai-chat | same |
|
|
166
|
+
| `glm-5.2` | default (prior) | 1,048,576 | 131,072 | ~$0.49–1.56 depending on host (Z.ai direct cheapest) | anthropic or openai-chat | same |
|
|
167
|
+
| `glm-4.6v` / `glm-4.5v` | vision | UNKNOWN | UNKNOWN | UNKNOWN | anthropic or openai-chat | same |
|
|
168
|
+
|
|
169
|
+
This is the one family already proven end-to-end: 284 of 495 recorded
|
|
170
|
+
worker runs in this environment's ledger used `provider: glm` — see §5.
|
|
171
|
+
|
|
172
|
+
### 1.8 Moonshot (Kimi)
|
|
173
|
+
|
|
174
|
+
Sources: https://platform.moonshot.ai/docs/pricing → redirects to
|
|
175
|
+
https://platform.kimi.ai/docs/pricing (WebFetch). The live `workers.yaml`
|
|
176
|
+
configures `kimi` against `https://api.kimi.ai/coding/` (an
|
|
177
|
+
Anthropic-compatible endpoint distinct from the general Moonshot platform
|
|
178
|
+
API below — confirmed by the live config using `protocol: anthropic`
|
|
179
|
+
implicitly, i.e. no `protocol:`/`upstream_url` set for it).
|
|
180
|
+
|
|
181
|
+
| Model id | For | Context | Input / Output per 1M | Protocol | Base URL |
|
|
182
|
+
|---|---|---|---|---|---|
|
|
183
|
+
| `kimi-k3` | default | 1,048,576 | $3.00 / $15.00 ($0.30 cached input) | anthropic (coding endpoint) or openai-chat (general platform) | `https://api.kimi.ai/coding/` (anthropic) or `https://api.moonshot.ai/v1` (openai-chat) |
|
|
184
|
+
| `kimi-k2.7-code` | default (cheaper) | 262,144 | $0.95 / $4.00 | openai-chat | api.moonshot.ai/v1 |
|
|
185
|
+
| `kimi-k2.7-code-highspeed` | fast | 262,144 | $1.90 / $8.00 | openai-chat | api.moonshot.ai/v1 |
|
|
186
|
+
| `kimi-k2.6` | default (older) | 262,144 | $0.95 / $4.00 | openai-chat | api.moonshot.ai/v1 |
|
|
187
|
+
|
|
188
|
+
12 of 495 recorded runs in this environment used `provider: kimi` — see §5.
|
|
189
|
+
The fetched doc didn't state explicitly which of the two base URLs is
|
|
190
|
+
OpenAI- vs Anthropic-shaped; the live config's usage (no `protocol:` field
|
|
191
|
+
= defaults to `"anthropic"`) is the confirmation for the coding endpoint.
|
|
192
|
+
|
|
193
|
+
### 1.9 Alibaba Qwen (DashScope / Model Studio)
|
|
194
|
+
|
|
195
|
+
Source: WebSearch synthesis (official docs page
|
|
196
|
+
https://www.alibabacloud.com/help/en/model-studio/qwen-api-via-dashscope
|
|
197
|
+
was found but not directly fetched — 3rd-party pricing trackers used for
|
|
198
|
+
numbers).
|
|
199
|
+
|
|
200
|
+
| Model id | For | Context | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
201
|
+
|---|---|---|---|---|---|---|
|
|
202
|
+
| `qwen3.8-max` | default (flagship) | 1M | $2.00 / $6.00 ($0.25 cached) | anthropic, openai-chat, or DashScope-native (all three documented) | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` (openai-chat) | GA 2026-08-03; multi-region (Beijing/Singapore/Tokyo/Frankfurt/Virginia) |
|
|
203
|
+
| `qwen3-max` | default (prior) | 262K | $0.78–3.00 (tiered) / up to $3.90 | same three | same | |
|
|
204
|
+
| `qwen3.5-plus` | default (mid) | 256K (rate doubles above) | $0.40 / $2.40 | same | same | |
|
|
205
|
+
| `qwen3.5-flash` | fast | UNKNOWN | $0.10 / $0.40 | same | same | |
|
|
206
|
+
|
|
207
|
+
The "OpenAI-, Anthropic-, and DashScope-compatible endpoints" claim came up
|
|
208
|
+
independently in the WebSearch synthesis for `qwen3.8-max`; if accurate,
|
|
209
|
+
Qwen could run with `protocol: anthropic` (no proxy) exactly like GLM/Kimi —
|
|
210
|
+
worth confirming with one live `curl` before configuring it that way, since
|
|
211
|
+
it wasn't checked against the primary doc page directly.
|
|
212
|
+
|
|
213
|
+
### 1.10 Meta Llama via hosted APIs
|
|
214
|
+
|
|
215
|
+
Sources: https://console.groq.com/docs/models (WebFetch, verbatim ids),
|
|
216
|
+
WebSearch synthesis for Together AI / Fireworks AI (official model-list
|
|
217
|
+
pages didn't render Llama ids for the fetch tool; numbers are 3rd-party).
|
|
218
|
+
|
|
219
|
+
| Model id | Host | Context | Input / Output per 1M | Protocol | Base URL | Notes |
|
|
220
|
+
|---|---|---|---|---|---|---|
|
|
221
|
+
| `llama-3.1-8b-instant` | Groq | 131,072 | UNKNOWN (moved to enterprise-only per one 3rd-party source, unconfirmed) | openai-chat | api.groq.com/openai/v1 | |
|
|
222
|
+
| `llama-3.3-70b-versatile` | Groq | 131,072 | UNKNOWN (same caveat) | openai-chat | api.groq.com/openai/v1 | |
|
|
223
|
+
| `openai/gpt-oss-120b` | Groq | 131,072 | $0.15 / $0.60 (3rd-party) | openai-chat | api.groq.com/openai/v1 | Not a Llama model, but Groq's current cheap/fast default per one source |
|
|
224
|
+
| `meta-llama/Llama-3.3-70B-Instruct-Turbo` | Together AI | UNKNOWN | ~$1.04/$1.04 (3rd-party, rising from ~$0.88 mid-2026) | openai-chat | api.together.xyz/v1 | Exact id not directly confirmed on together.ai/models fetch — verify via their `/models` list endpoint |
|
|
225
|
+
| Llama 3.1 70B–class | Fireworks AI | UNKNOWN | ~$0.90/$0.90 flat for >16B models (3rd-party) | openai-chat | api.fireworks.ai/inference/v1 | Exact id not confirmed |
|
|
226
|
+
|
|
227
|
+
All three (Groq, Together, Fireworks) are documented OpenAI-Chat-Completions
|
|
228
|
+
compatible — this family is the cleanest `protocol: openai` fit once ids are
|
|
229
|
+
confirmed against each provider's `/v1/models` endpoint.
|
|
230
|
+
|
|
231
|
+
### 1.11 Image-generation APIs
|
|
232
|
+
|
|
233
|
+
| Provider | Model id | Price | API shape | Base URL | Source |
|
|
234
|
+
|---|---|---|---|---|---|
|
|
235
|
+
| OpenAI | `gpt-image-2` | see §1.2 | `POST /v1/images/generations` (OpenAI images schema) | api.openai.com | WebSearch, multiple corroborating |
|
|
236
|
+
| Google | `gemini-3.1-flash-image` | see §1.3 | `POST /v1beta/models/{model}:generateContent` (Gemini schema, image parts in/out — **not** the OpenAI images schema) | generativelanguage.googleapis.com | WebFetch pricing page |
|
|
237
|
+
| Black Forest Labs | `flux-2-pro`, `flux-2-klein-4b`, `flux-2-klein-9b`, `flux-2-flex`, `flux-2-max` | $0.014–$0.07/megapixel, credit-based (1 credit = $0.01) | BFL-specific REST, async job polling | api.bfl.ai | WebSearch (docs.bfl.ml, bfl.ai/pricing) |
|
|
238
|
+
| Stability AI | Stable Image Ultra / Core / SD3.5 (Medium/Large/Flash/Large-Turbo) | $0.025–$0.08/image, credit-based (1 credit = $0.01) | Stability REST (`POST /v2beta/stable-image/generate/...`) | api.stability.ai | WebSearch (official pricing page returned only a title to the fetch tool) |
|
|
239
|
+
| Ideogram | `ideogram-4.0`, `ideogram-3.0`, `ideogram-p-image` | $0.02–$0.10/image by version/quality tier | Ideogram REST | api.ideogram.ai | WebSearch |
|
|
240
|
+
| Recraft | Recraft V3 / V4 (Styles Pro, Styles Vector) | $0.04 raster / $0.08 vector / $0.10–$0.055 for style variants | Recraft REST, API-unit billed | external.api.recraft.ai | WebSearch |
|
|
241
|
+
| Replicate (gateway) | e.g. `black-forest-labs/flux-1.1-pro`, `ideogram-ai/ideogram-v3-quality` | pass-through per-model, e.g. $0.04 and $0.09/image respectively | Replicate REST (`POST /v1/predictions`), async | api.replicate.com | WebFetch (replicate.com/pricing) |
|
|
242
|
+
|
|
243
|
+
None of these speak the OpenAI Chat Completions or Messages protocol —
|
|
244
|
+
they're all their own REST job/response shapes (some sync, some async
|
|
245
|
+
job-polling). PAI's proxy translates Anthropic↔OpenAI-chat; it does not
|
|
246
|
+
translate to any of these images schemas, and there is no `engine: image`
|
|
247
|
+
runner today (see the note at the top of this document and §2/§5).
|
|
248
|
+
|
|
249
|
+
## 2. What PAI can use today, with a small change, or not at all
|
|
250
|
+
|
|
251
|
+
**Usable today, unchanged** (`protocol: anthropic`, no proxy, no engine
|
|
252
|
+
work):
|
|
253
|
+
- Anthropic (native, already the default)
|
|
254
|
+
- Z.ai GLM via `https://api.z.ai/api/anthropic` — proven live (§1.7, §5)
|
|
255
|
+
- Moonshot Kimi via `https://api.kimi.ai/coding/` — proven live (§1.8, §5)
|
|
256
|
+
- Alibaba Qwen, *if* its Anthropic-compatible endpoint holds up under a real
|
|
257
|
+
`curl` test (claimed in 3rd-party sources, not confirmed against Alibaba's
|
|
258
|
+
own doc page — do one `pai worker providers test` before trusting it)
|
|
259
|
+
|
|
260
|
+
**Usable today through `protocol: openai` (the existing proxy), unchanged**,
|
|
261
|
+
provided the provider's tool-calling still works over Chat Completions
|
|
262
|
+
(untested end-to-end — see §5):
|
|
263
|
+
- DeepSeek (`api.deepseek.com`, docs say "OpenAI Format" explicitly)
|
|
264
|
+
- Z.ai GLM's OpenAI-compatible endpoint (`/api/paas/v4`) as an alternative
|
|
265
|
+
to the Anthropic one
|
|
266
|
+
- Moonshot's general platform endpoint (`api.moonshot.ai/v1`)
|
|
267
|
+
- xAI Grok (`api.x.ai/v1`)
|
|
268
|
+
- Groq, Together AI, Fireworks AI (Llama and others)
|
|
269
|
+
- OpenAI itself, for models that don't require the Responses API for tool
|
|
270
|
+
calls (`gpt-5.1`, `gpt-5-mini`, `gpt-5-nano`); `gpt-6-astra` would lose
|
|
271
|
+
tool-calling through Chat Completions per OpenAI's own docs
|
|
272
|
+
- Google Gemini via its documented OpenAI-compatibility shim
|
|
273
|
+
(`.../v1beta/openai/`)
|
|
274
|
+
- Mistral, once exact model ids are confirmed via `GET /v1/models`
|
|
275
|
+
|
|
276
|
+
**Needs a small change:**
|
|
277
|
+
- **Codex CLI providers** (`engine: codex`) already exist as a config
|
|
278
|
+
option (`WorkerEngine`, `src/workers/config.ts:40`) — no OpenAI-Responses
|
|
279
|
+
work needed for a ChatGPT-plan provider, just `pai worker providers add
|
|
280
|
+
<name> --engine codex`.
|
|
281
|
+
- **OpenAI Responses-only models** (`gpt-6-astra` with tools, and any future
|
|
282
|
+
model that drops Chat Completions tool support) need the proxy's
|
|
283
|
+
translator (`src/workers/proxy/translate.ts`) extended to speak Responses
|
|
284
|
+
as well as Chat Completions — real work, not config.
|
|
285
|
+
|
|
286
|
+
**Cannot be used at all today:**
|
|
287
|
+
- Every image-generation API in §1.11 (OpenAI images, Google Imagen/Nano
|
|
288
|
+
Banana, Flux, Stability, Ideogram, Recraft, Replicate) — none speak
|
|
289
|
+
Anthropic Messages or OpenAI Chat Completions, and no `engine: image` (or
|
|
290
|
+
equivalent images-job runner) exists in this codebase to call them. A
|
|
291
|
+
provider's `models.image` field is accepted by config validation today,
|
|
292
|
+
but nothing consumes it as an image request — it's just the id `run.ts`
|
|
293
|
+
passes to `--model` on a normal chat run, which will simply fail (or
|
|
294
|
+
silently run as a chat model, if the id also happens to answer chat) on
|
|
295
|
+
a real image-only endpoint.
|
|
296
|
+
|
|
297
|
+
## 3. `workers.yaml` snippets
|
|
298
|
+
|
|
299
|
+
All of these are commented out and use placeholder key files under
|
|
300
|
+
`~/.claude/pai/keys/<name>` (the on-disk field is `key_file`; `keysDir()` in
|
|
301
|
+
`src/workers/config.ts:1050` resolves to `paiHomePath("keys")`, i.e.
|
|
302
|
+
`~/.claude/pai/keys`). Every snippet below was validated to parse without
|
|
303
|
+
throwing via `readWorkersYaml()` against a temp file — see §3 validation
|
|
304
|
+
output. None of this was written into the live `~/.claude/pai/workers.yaml`.
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
# --- OpenAI, via the PAI proxy (protocol: openai) ---
|
|
308
|
+
# providers:
|
|
309
|
+
# openai:
|
|
310
|
+
# protocol: openai
|
|
311
|
+
# upstream_url: "https://api.openai.com/v1"
|
|
312
|
+
# key_file: "~/.claude/pai/keys/openai"
|
|
313
|
+
# models:
|
|
314
|
+
# default: gpt-5.1 # gpt-6-astra needs Responses API for tools — see docs/model-catalogue.md §2
|
|
315
|
+
# fast: gpt-5-mini
|
|
316
|
+
# tier: 4
|
|
317
|
+
|
|
318
|
+
# --- Google Gemini, via its OpenAI-compatibility shim ---
|
|
319
|
+
# providers:
|
|
320
|
+
# gemini:
|
|
321
|
+
# protocol: openai
|
|
322
|
+
# upstream_url: "https://generativelanguage.googleapis.com/v1beta/openai"
|
|
323
|
+
# key_file: "~/.claude/pai/keys/gemini"
|
|
324
|
+
# models:
|
|
325
|
+
# default: gemini-3.5-flash
|
|
326
|
+
# fast: gemini-3.5-flash-lite
|
|
327
|
+
# tags: [vision, long-context]
|
|
328
|
+
# tier: 2
|
|
329
|
+
|
|
330
|
+
# --- xAI Grok ---
|
|
331
|
+
# providers:
|
|
332
|
+
# xai:
|
|
333
|
+
# protocol: openai
|
|
334
|
+
# upstream_url: "https://api.x.ai/v1"
|
|
335
|
+
# key_file: "~/.claude/pai/keys/xai"
|
|
336
|
+
# models:
|
|
337
|
+
# default: grok-4.6
|
|
338
|
+
# fast: grok-build-0.1
|
|
339
|
+
# tier: 3
|
|
340
|
+
|
|
341
|
+
# --- Mistral (confirm exact model ids via GET /v1/models before use) ---
|
|
342
|
+
# providers:
|
|
343
|
+
# mistral:
|
|
344
|
+
# protocol: openai
|
|
345
|
+
# upstream_url: "https://api.mistral.ai/v1"
|
|
346
|
+
# key_file: "~/.claude/pai/keys/mistral"
|
|
347
|
+
# models:
|
|
348
|
+
# default: mistral-large-latest
|
|
349
|
+
# fast: mistral-small-latest
|
|
350
|
+
# tier: 2
|
|
351
|
+
|
|
352
|
+
# --- DeepSeek ---
|
|
353
|
+
# providers:
|
|
354
|
+
# deepseek:
|
|
355
|
+
# protocol: openai
|
|
356
|
+
# upstream_url: "https://api.deepseek.com"
|
|
357
|
+
# key_file: "~/.claude/pai/keys/deepseek"
|
|
358
|
+
# models:
|
|
359
|
+
# default: deepseek-v4-pro
|
|
360
|
+
# fast: deepseek-flash
|
|
361
|
+
# tier: 1
|
|
362
|
+
|
|
363
|
+
# --- Zhipu / Z.ai GLM (native anthropic — same shape as the live glm provider) ---
|
|
364
|
+
# providers:
|
|
365
|
+
# glm2:
|
|
366
|
+
# url: "https://api.z.ai/api/anthropic"
|
|
367
|
+
# key_file: "~/.claude/pai/keys/glm2"
|
|
368
|
+
# models:
|
|
369
|
+
# default: glm-5.3
|
|
370
|
+
# fast: glm-5.3-flash
|
|
371
|
+
# tier: 2
|
|
372
|
+
|
|
373
|
+
# --- Moonshot Kimi (native anthropic, coding endpoint — same shape as the live kimi provider) ---
|
|
374
|
+
# providers:
|
|
375
|
+
# kimi2:
|
|
376
|
+
# url: "https://api.kimi.ai/coding/"
|
|
377
|
+
# key_file: "~/.claude/pai/keys/kimi2"
|
|
378
|
+
# models:
|
|
379
|
+
# default: kimi-k3
|
|
380
|
+
# tier: 3
|
|
381
|
+
|
|
382
|
+
# --- Alibaba Qwen (verify anthropic-compatible endpoint before relying on this) ---
|
|
383
|
+
# providers:
|
|
384
|
+
# qwen:
|
|
385
|
+
# protocol: openai
|
|
386
|
+
# upstream_url: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
387
|
+
# key_file: "~/.claude/pai/keys/qwen"
|
|
388
|
+
# models:
|
|
389
|
+
# default: qwen3.8-max
|
|
390
|
+
# fast: qwen3.5-flash
|
|
391
|
+
# tier: 3
|
|
392
|
+
|
|
393
|
+
# --- Meta Llama via Groq ---
|
|
394
|
+
# providers:
|
|
395
|
+
# groq:
|
|
396
|
+
# protocol: openai
|
|
397
|
+
# upstream_url: "https://api.groq.com/openai/v1"
|
|
398
|
+
# key_file: "~/.claude/pai/keys/groq"
|
|
399
|
+
# models:
|
|
400
|
+
# default: openai/gpt-oss-120b
|
|
401
|
+
# fast: llama-3.1-8b-instant
|
|
402
|
+
# tier: 1
|
|
403
|
+
|
|
404
|
+
# --- Preference example: today's mechanism (classes, not a capabilities: map) ---
|
|
405
|
+
# No top-level `capabilities:` block exists yet (see docs/model-catalogue.md).
|
|
406
|
+
# The current equivalent of "prefer an image provider for image, Claude for
|
|
407
|
+
# everything else" is per-class routing:
|
|
408
|
+
# classes:
|
|
409
|
+
# image: glm2/image # once an image engine exists — see §2, §5
|
|
410
|
+
# implement: anthropic
|
|
411
|
+
# draft: anthropic
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Validation
|
|
415
|
+
|
|
416
|
+
Ran a temp vitest (`src/workers/model-catalogue-snippets.test.ts`, added on
|
|
417
|
+
this branch) that writes each uncommented provider block above into an
|
|
418
|
+
isolated `workers.yaml` (via `PAI_WORKERS_YAML`) and calls
|
|
419
|
+
`readWorkersYaml()` from `src/workers/workers-config.ts`, asserting it does
|
|
420
|
+
not throw and that `data.providers.<name>.protocol` /
|
|
421
|
+
`.upstreamUrl` match what's intended. Output:
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
$ bunx vitest run src/workers/model-catalogue-snippets.test.ts
|
|
425
|
+
|
|
426
|
+
RUN v4.0.18 <worktree>
|
|
427
|
+
|
|
428
|
+
✓ src/workers/model-catalogue-snippets.test.ts (9 tests) 11ms
|
|
429
|
+
|
|
430
|
+
Test Files 1 passed (1)
|
|
431
|
+
Tests 9 passed (9)
|
|
432
|
+
Start at 18:49:03
|
|
433
|
+
Duration 208ms (transform 83ms, setup 21ms, import 96ms, tests 11ms, environment 0ms)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
All 9 snippets (`openai`, `gemini`, `xai`, `mistral`, `deepseek`, `glm2`,
|
|
437
|
+
`kimi2`, `qwen`, `groq`) parsed without a `WorkersConfigError` and reported
|
|
438
|
+
the expected `protocol`/`upstream_url`. Re-run with the command above to
|
|
439
|
+
reproduce (run `bun install` first if `node_modules` is missing).
|
|
440
|
+
|
|
441
|
+
## 4. How to add one (today's real CLI, verified against `--help`)
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
# 1. Save the key
|
|
445
|
+
mkdir -p ~/.claude/pai/keys && chmod 700 ~/.claude/pai/keys
|
|
446
|
+
printf '%s' 'sk-...' > ~/.claude/pai/keys/deepseek && chmod 600 ~/.claude/pai/keys/deepseek
|
|
447
|
+
|
|
448
|
+
# 2. Add the provider (flags confirmed via `pai worker providers add --help`)
|
|
449
|
+
pai worker providers add deepseek \
|
|
450
|
+
--protocol openai --upstream-url https://api.deepseek.com \
|
|
451
|
+
--key-file ~/.claude/pai/keys/deepseek \
|
|
452
|
+
--model deepseek-v4-pro --fast-model deepseek-flash \
|
|
453
|
+
--cost-tier 1
|
|
454
|
+
|
|
455
|
+
# 3. Set the model per capability (no `pai worker model image ...` shorthand
|
|
456
|
+
# beyond what `model` already does — capabilities are default/fast/image)
|
|
457
|
+
pai worker model image example-paint --provider deepseek # only meaningful once an image engine exists — see §2
|
|
458
|
+
|
|
459
|
+
# 4. Point a class at it (there is no `pai worker capability image <name>` —
|
|
460
|
+
# that command doesn't exist; classes are the current mechanism)
|
|
461
|
+
# Edit workers.yaml: classes.image: deepseek/image
|
|
462
|
+
# or: pai worker classes # to see current routing, then edit by hand
|
|
463
|
+
|
|
464
|
+
# 5. Run against it
|
|
465
|
+
pai worker run --provider deepseek -p "…" --allowedTools 'Read,Edit,Bash'
|
|
466
|
+
# or, once a class points at it:
|
|
467
|
+
pai worker run --class image -p "…"
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
`pai worker model` and `pai worker classes` are real (`pai worker model
|
|
471
|
+
--help`, `pai worker --help`); `pai worker capability` is **not** a command
|
|
472
|
+
in this codebase — the task's suggested walkthrough
|
|
473
|
+
(`pai worker capability image <name>`) doesn't exist yet, so step 4 above
|
|
474
|
+
uses what does.
|
|
475
|
+
|
|
476
|
+
## 5. State of the OpenAI-protocol path
|
|
477
|
+
|
|
478
|
+
Fact, not assumption, gathered from this environment's own ledger and test
|
|
479
|
+
suite:
|
|
480
|
+
|
|
481
|
+
- **495 recorded worker runs** in `~/.claude/pai/logs/workers/*.status`
|
|
482
|
+
(this machine's ledger) break down as `anthropic`: 199, `glm`: 284,
|
|
483
|
+
`kimi`: 12. **Zero** used a provider with `protocol: "openai"` — `glm` and
|
|
484
|
+
`kimi` are both configured in the live `workers.yaml` against
|
|
485
|
+
Anthropic-compatible endpoints (`api.z.ai/api/anthropic`,
|
|
486
|
+
`api.kimi.ai/coding/`), not through the proxy.
|
|
487
|
+
- `src/workers/proxy/server.test.ts` and `translate.test.ts` (36 test cases
|
|
488
|
+
total) exercise the Anthropic↔OpenAI translation and the proxy's HTTP
|
|
489
|
+
server exclusively against an in-process mock upstream
|
|
490
|
+
(`server.test.ts:96` "non-streaming: translates both directions ... passes
|
|
491
|
+
the keyFile token upstream" spins up a local fake server, not a real
|
|
492
|
+
OpenAI-compatible API).
|
|
493
|
+
- No file under `docs/`, no CHANGELOG entry, and no `.status`/`.jsonl`
|
|
494
|
+
ledger line names a provider with `upstream_url` set that actually ran.
|
|
495
|
+
|
|
496
|
+
**Conclusion:** the `protocol: openai` proxy path is implemented and unit-
|
|
497
|
+
tested against synthetic upstreams, but as of 2026-09-20 no worker run in
|
|
498
|
+
this environment's history has completed through it against a real
|
|
499
|
+
OpenAI-Chat-Completions provider. The first live use of any provider in
|
|
500
|
+
§1.2–§1.6, §1.9, §1.10 above (all `openai-chat` protocol) would be this
|
|
501
|
+
codebase's first real exercise of that path — worth a `pai worker providers
|
|
502
|
+
test <name>` smoke run before depending on it for real work.
|
|
@@ -194,7 +194,7 @@ session, context intact; returns the new worker id. Not for running workers.
|
|
|
194
194
|
Providers, model roles and class routing live in `~/.claude/pai/workers.yaml`
|
|
195
195
|
(the primary, hand-editable mechanism — see **docs/workers-config.md**).
|
|
196
196
|
Everything else worker-related still lives in the `workers` section of
|
|
197
|
-
`~/.claude/pai/config.json` (`readWorkersSection` / `writeWorkersSection`,
|
|
197
|
+
`~/.claude/pai/config.yaml` (or `config.json` until you run `pai config yaml`) (`readWorkersSection` / `writeWorkersSection`,
|
|
198
198
|
`src/workers/config.ts:619`); every sentence and tool above writes it
|
|
199
199
|
atomically — no hand-editing.
|
|
200
200
|
|
package/docs/task-bus.md
CHANGED
package/docs/worker.md
CHANGED
|
@@ -67,7 +67,7 @@ annotated example, how to add a provider, the load order, and
|
|
|
67
67
|
`pai worker config migrate` for configs still on the old JSON shape or an
|
|
68
68
|
old `workers.yaml` location). Everything else worker-related (pane, log
|
|
69
69
|
dir, routing cooldown, cache-keepalive cadence, fallback) stays in
|
|
70
|
-
`~/.claude/pai/config.json`'s `workers` section.
|
|
70
|
+
`~/.claude/pai/config.yaml` (or `config.json` until you run `pai config yaml`)'s `workers` section.
|
|
71
71
|
|
|
72
72
|
Quick summary of workers.yaml:
|
|
73
73
|
|
|
@@ -215,6 +215,27 @@ so it is unavailable for codex workers (their thread id is kept, but
|
|
|
215
215
|
`pai worker resume` refuses with an explanation). `providers test` reports
|
|
216
216
|
`codex not installed` (exit 0) when the CLI is missing.
|
|
217
217
|
|
|
218
|
+
## The image engine
|
|
219
|
+
|
|
220
|
+
Claude cannot generate images; a provider that can sets `engine: "image"`
|
|
221
|
+
and `--capability image` runs it directly instead of spawning any process:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
pai worker providers add pictures --engine image \
|
|
225
|
+
--url https://api.example.com/v1 --key sk-… --model example-image-model
|
|
226
|
+
pai worker model image example-image-model --provider pictures
|
|
227
|
+
pai worker run --capability image -p "a red circle on white" --out ./circle.png
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
This POSTs `{model, prompt, size, n: 1, response_format: "b64_json"}` to
|
|
231
|
+
`{url}/images/generations`, decodes the PNG, and writes it — no worktree, no
|
|
232
|
+
MCP, no follow pane. `--capability` (alias `--for`) picks the provider by
|
|
233
|
+
capability instead of by class/`--provider`; see `docs/workers-config.md`'s
|
|
234
|
+
"Capabilities" section for the full resolution order, `pai worker
|
|
235
|
+
capability` (cross-provider preference) vs. `pai worker model` (one
|
|
236
|
+
provider's own model ids), and what happens with no image provider
|
|
237
|
+
configured.
|
|
238
|
+
|
|
218
239
|
## Daily use
|
|
219
240
|
|
|
220
241
|
```
|
|
@@ -236,8 +257,11 @@ pai worker log [all|tail|<id>] # raw streams + routing ledger
|
|
|
236
257
|
```
|
|
237
258
|
|
|
238
259
|
Classes pick the provider for a task class: `--class implement|research|spotcheck|…`
|
|
239
|
-
(`--role` still works as its alias). `--
|
|
240
|
-
|
|
260
|
+
(`--role` still works as its alias). `--capability <name>` (alias `--for`)
|
|
261
|
+
picks the provider by capability instead — e.g. `--capability image` runs
|
|
262
|
+
the configured image engine (above) regardless of the active provider or
|
|
263
|
+
class. `--no-pane` suppresses the iTerm follow pane; `--provider <name>`
|
|
264
|
+
bypasses classes and capabilities entirely. If you bring your own
|
|
241
265
|
`--append-system-prompt`, the worker contract below is added alongside it, not
|
|
242
266
|
instead.
|
|
243
267
|
|
|
@@ -282,7 +306,11 @@ to the pai commands (`pai worker install` moves any previous versions to
|
|
|
282
306
|
|
|
283
307
|
## Routing
|
|
284
308
|
|
|
285
|
-
A run resolves its provider as: `--provider` > `--class
|
|
309
|
+
A run resolves its provider as: `--provider` > `--capability`/a class implying
|
|
310
|
+
one > `--class` > `active`. `--capability` (and a class whose implied
|
|
311
|
+
capability is not `default` and names no provider of its own, e.g. `image`)
|
|
312
|
+
resolves cross-provider through `capabilities:` instead of this chain — see
|
|
313
|
+
`docs/workers-config.md`'s "Capabilities" section.
|
|
286
314
|
|
|
287
315
|
With `active: "auto"`, providers are tried in `routing.order` (or the class's
|
|
288
316
|
own `order`), skipping:
|
|
@@ -318,7 +346,7 @@ What `on` does:
|
|
|
318
346
|
`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`.
|
|
319
347
|
- Pins the top-level `model` key to the provider's default model.
|
|
320
348
|
- Saves the replaced values under `workers.fallback.saved` in
|
|
321
|
-
`~/.claude/pai/config.json` and writes a `FALLBACK-ACTIVE.md` note into the
|
|
349
|
+
`~/.claude/pai/config.yaml` (or `config.json` until you run `pai config yaml`) and writes a `FALLBACK-ACTIVE.md` note into the
|
|
322
350
|
workers log dir telling running sessions what to do.
|
|
323
351
|
|
|
324
352
|
Notes:
|