What changed: zcodeRules wrote api.type "anthropic-messages" into
provider_config.json, and zcodeProviderJSON wrote kind "anthropic" into
config.json, on every sync (magpie's start, any catalog change). A user who
switched the provider to OpenAI Chat Completions or Responses in ZCode had it
switched back the next time magpie started. zcodeFormat now reads the format
already there and keeps it, in both files: provider_config.json's api.type
(ZCode 3.14 on) or config.json's kind (older ZCode), the one written last
where they differ, mapped as ZCode maps them (anthropic-messages/anthropic,
openai-chat-completions/openai-compatible, openai-responses/openai). A new
provider, or a format ZCode doesn't have, is Anthropic Messages as before.
Why it's safe: magpie's gateway answers all three at the same base address.
Checked with ZCode 0.16.9's own agent CLI (glm/zcode.cjs -p, run from a
copy under a sandbox HOME, never ~/.zcode) against a sandbox gateway with
the DeepSeek provider: anthropic-messages asks /v1/messages,
openai-chat-completions /chat/completions, openai-responses /responses, and
a tool-using turn (Read a.txt) answered 200 on each, to deepseek-flash.
What was run:
- TestZCodeKeepsUserFormat (new): a format picked in provider_config.json,
for each of the three, survives two syncs and is carried to config.json's
kind; one picked in config.json is carried to provider_config.json; an
unknown one isn't kept. On the old zcode.go it fails: "picked
openai-chat-completions: kind "anthropic", api "anthropic-messages"".
- Sandbox, real binaries: provider_config.json set to openai-responses,
then `magpie zcode magpie`: the old build wrote anthropic-messages back,
this one kept openai-responses (config.json kind openai). Then
openai-chat-completions, resynced, and the real ZCode CLI ran a turn on the
file magpie wrote, served over /chat/completions.
- gofmt -l; GOOS=linux and GOOS=windows go vet -tags nogui ./internal/agent;
go test -tags nogui ./internal/agent under a temp HOME: ok.
The "bcww: Field required" 400 on Anthropic Messages is not part of this
commit: ZCode's real requests (captured from its CLI, plain and with web
search) to deepseek/deepseek-flash through magpie returned 200, and DeepSeek
answers schema errors in serde's words, not "Field required".
WorkBuddy's Settings > Models saves an edited custom model whole into
~/.workbuddy/models.json: reasoning.defaultEffort (absent for its Auto), and
the vendor of the provider it matches, which for magpie's entries is the
"Custom" provider's (WorkBuddy 5.x app.asar: inferProviderIdFromLocalCustomModel,
the form's save in ui-docs-viewer). buddyWrite knew its entries by vendor
"magpie" only, so a sync kept the edited entry as the user's and added
magpie's own with the same id and magpie's default effort; one set by hand
under vendor magpie was simply rewritten.
buddyWrite (WorkBuddy and CodeBuddy Code) now also knows magpie's entries by
their key (magpie-<agent>, or a NAS magpie's key already on its entries),
and keeps each model's defaultEffort (or the older reasoning.effort) while
the model still offers that level; WorkBuddy's Auto stays Auto. A new model
gets magpie's default; a model magpie no longer has is taken out, the edited
one included. The same rule (keptEffort) keeps a hand-set default in ZCode's
config.json (defaultVariant), Kimi Code's config.toml (default_effort) and
MiniMax Code's config.yaml (thinking.defaultEffort), which a sync rewrote too.
The composer's own effort pick is WorkBuddy's localStorage
(cb-effort:by-model), which magpie never touched.
Verified: kept_effort_test.go (TestWorkBuddy/CodeBuddy/ZCode/Kimi/MiniMax
KeepsTheUsersDefault*) fail on the old writers, WorkBuddy's with
"think/wide twice" and the rest with magpie's default back; pass with this,
-race -count=3. go test -tags nogui ./... green under a temp HOME; go vet,
GOOS=linux and GOOS=windows builds. Not tried in the real WorkBuddy app: the
fixture follows its save code, not a file it wrote.