Files
magpie/docs
wizzy-yangandwizzy-yang e5e87d980a 支持 Ante:把 magpie 作为 provider 写进 ~/.ante/catalog.json (#1210)
* agent: Ante takes magpie as a provider in ~/.ante/catalog.json

Ante (antigma.ai, AntigmaLabs/ante) is asked for in #1179. Its catalog is
~/.ante/catalog.json ($ANTE_HOME moves the folder), merged on top of the
providers it ships: a providers map keyed by the id --provider takes, each
with base_url, wire_style (AnthropicMessage, OpenAiCompatible, OpenAiResponse
or Gemini), an optional auth, and preferred_models, the ids its model picker
shows (docs.antigma.ai, reference/catalog-reference). magpie adds the entry
"magpie" at the gateway's /v1 on OpenAiCompatible, which is the wire style
Ante speaks Chat Completions with and what the gateway takes every model on,
and lists magpie's models in its preferred_models. The user's own providers
and the models section are left as they are, and magpie's entry goes again
when magpie steps out; a file magpie made goes with it.

No auth block is written. The gateway listens on loopback and lets any token
in from this machine (gateway.Token's own comment, lan.go's identifyCaller:
"Loopback takes any token"), and Ante counts a provider with no auth as
authenticated. A bearer env_key would mean putting the gateway's key into
Ante's environment, which the user would have to do themselves -- the same
decision Empryo's entry makes, which sends no key of the user's either. A
gateway shared on the local network is another matter, and the same one every
agent magpie wires has.

Two things are deliberately left off a model's entry. A routing group is not
told what it reasons at: which member answers, and what that member takes, is
the group's own to decide per turn, and magpieModels sets no APIs for a group
for the same reason. And support_vision is never written: Ante takes a model
as seeing images unless told otherwise, and what magpie knows is only as good
as a provider's own list -- a relay's models are often not described at all,
so writing false would have Ante drop the reader's images before the gateway,
which describes them to a model that can't see them itself
(provider.Described). No other agent magpie wires declares it either.

Ante ships macOS and Linux builds alone and suggests WSL on Windows, so the
Windows machine's Ante is usually the one in a distro: wslKinds gains it
beside Empryo, which also means the gateway address Ante is pointed at is the
one that distro reaches magpie on (place.base), and a distro not known to be
in mirrored networking gets the notice it already gets for the others.

TestAnte covers a user's own providers and models section kept as they are,
magpie's entry added and taken away, Sync repointing it, and a file magpie
made going again. TestAnteKeepsTheUsersFile covers a catalog magpie can't
parse costing magpie's provider and not the user's. TestAnteGroupSaysNoCapab
ilities covers a group declaring neither effort nor support_vision.
TestAnteEfforts covers the ladder: Ante's has no "none" or "minimal", its two
lowest, so both are its "min", and the rungs come out in Ante's order
whatever order magpie lists them in.

Tried with a real Ante 0.2.9 in WSL Ubuntu: magpie wrote the catalog, and
`ante catalog` then read 16 providers with magpie's among them, 39 models,
and Ante filled in support_vision: true for each itself. Ante then ran a real
turn through the gateway — `ante --provider magpie --model
group/auto-deepseek-v4-1-flash -p …` answered, and magpie's own usage log has
the request (ep /v1/chat/completions, req the group's id, served by one of its
members, out 10) — and so did a second model on another provider. The gateway
was reached over the Windows host's address from the distro (172.17.128.1),
this machine's own being on 127.0.0.1 alone, which is what notMirrored tells
the user about.

go vet, gofmt -l and go build (linux nogui, windows) pass. go test -tags
nogui ./internal/agent: 12 failures here, the same 12 on unmodified main (the
Windows ones AGENTS.md lists). ./internal/gui and ./internal/provider:
TestGatewayFixQuitsOnlyAMagpie, TestPurposeAssetMatchesUsage,
TestUpdateThatWontStart and TestLoginUsageClaudeAskedMeanwhile, all four on
unmodified main here too. docs/reference.md's adapter table gains Ante.

* agent: Ante keeps the user's own keys, reads ANTE_HOME, sends no effort it wasn't told to, and starts Ante on magpie (#1210)

Seven points from the review, each with a test that fails without it.

1. ANTE_HOME was in the file's own comment and in docs/reference.md but never read:
the path was fixed to $HOME/.ante, so a user who set it had magpie write a catalog
Ante does not look at. anteDir reads it through place.getenv, the way MiniMax Code
reads MINIMAX_DATA_DIR, so a distro's own ANTE_HOME - which magpie can't read -
still means ~/.ante there. "ANTE_HOME" joins agentenv.Vars so a sandbox clears it.

2. providers.magpie was written whole, so every key of the user's that magpie
doesn't write - the auth block a gateway shared on the LAN or reached from WSL
needs to send a key, http_headers, extra_body, stream_idle_timeout_secs,
thinking_display - went at the next sync, and an unchanged catalog was rewritten
every round. It goes through theirsKept and syncJSON now, as #1103 did for the
others: the user's keys in magpie's entry stay, preferred_models is magpie's list
alone, and a file that says the same as it does is left as it is.

3. The two files were written in separate steps, so a change that failed halfway
left Ante's catalog without magpie's entry and its settings still naming magpie.
Each field's Set and its Sync are wrapped in atomic(), as empryo, minimax and kimi
do.

4. The comment said Ante's "min" was the rung it sends no effort at, and folded
both magpie's "none" and its "minimal" into it. Ante's reference says what min is:
"OpenAI-compatible providers send the selected level as the same-named
reasoning_effort (min is sent as minimal)" - so min is a sent level, and magpie's
"none" has no rung of Ante's to fold into. Ante's "min" is magpie's "minimal"; a
model magpie knows only "none" of comes out as the empty list, which is Ante's own
way of saying it takes no effort setting at all.

5. The default was the highest rung the model takes, so every model magpie listed
ran at Ante's slowest and dearest level. No effort is written: "Omit for models
with no reasoning knob (Ante then sends no effort parameter and hides the effort
slider)".

6. Having magpie in the catalog never meant Ante used it. What a session starts on
is the provider and the model of ~/.ante/settings.json; with neither set Ante
"uses the first authenticated provider in catalog order", and Ante's own presets
come before magpie's entry - so while the user has any of those signed in, that is
the one picked and magpie is not. (Measured: nothing named in settings, two keyless
providers ordered aaa_other then magpie, and the request went to aaa_other's port;
settings provider=magpie and it went to magpie's.) magpie sets that pair now and
saves what it found there, so Disconnect hands it back; a provider the user picks in
Ante's own /providers while magpie is wired is theirs and stands, and Check says so
instead of keeping quiet. Ante's settings name the model apart from the provider, so
magpie writes the catalog id it put in preferred_models, un-prefixed, and reads a
bare id as magpie's only beside magpie's provider.

Tests lean on the package's own testenv, not a real ~/.ante.
TestAnteSyncKeepsTheUsersKeys is modelled on ad3b7fe5's
TestAirProviderWritesKeepCustomFields and goes both ways - sync and pick - and
wants an unchanged file to keep its mtime.

Tried with a real Ante 0.2.9 in WSL Ubuntu on this machine (Ante ships macOS and
Linux builds alone; there is no Windows Ante here). The strongest of these is the
whole of it: magpie's own Go code - ante(home).Connect(), then the model field -
wrote a catalog.json and settings.json into a temp folder, that folder was handed
to the real Ante as ANTE_HOME, and Ante ran a turn through it with no --provider,
no --model and nothing typed by hand.

- `ante doctor` read `home ok /tmp/ante-e2e` and `16 providers (1 authed), 108
  models` from ANTE_HOME, and magpie's entry came back with the base_url it was
  given: ANTE_HOME really moves the folder, and a base_url already ending in /v1
  is not doubled (the request went to /v1/chat/completions).
- What a session starts on is settings.json's provider, measured against two
  keyless providers each answering on its own port, so the logged port names the
  one Ante asked. Catalog ordered aaa_other then magpie, nothing named in
  settings: Ante asked 44331, aaa_other - the first authenticated in catalog
  order, exactly the review's "很可能选不到 magpie". settings provider=magpie: it
  asked 44220, magpie. settings provider=aaa_other: 44331 again, so a pick the
  user makes in Ante's own /providers overrules what magpie wrote, which is why
  stepping out leaves it rather than handing back the one magpie found. And with
  magpie the only authenticated provider, auto-detection does reach it - so the
  catalog entry is not useless, it is simply not enough while the user has any
  other provider signed in, which is every real install.
- What Ante sends for effort, from the same files: no reasoning_effort at all for
  a model with no effort written (item 5, as its reference says omitting it sends
  none); `--effort min` on a model sent `reasoning_effort: "minimal"` - Ante's min
  is magpie's minimal, exactly item 4; and a model Ante was told
  `"supported_efforts": []` for sent no reasoning_effort even when asked `--effort
  low`, which is what a none-only model now gets instead of a level that refuses
  it.
- The user's own keys inside magpie's entry are ones Ante reads, not decoration:
  `ante catalog` hands back the entry's auth, http_headers, extra_body,
  stream_idle_timeout_secs and thinking_display unchanged, and a bearer env_key
  there makes `ante doctor` count the provider as the one authed. That is item 2.
- The no-auth decision holds on Ante's side, isolated by doctor's counts: Ante's
  own presets alone read `15 providers (0 authed)`; a magpie with no auth block
  reads `(1 authed)`; the same magpie given a bearer env_key that isn't set drops
  back to `(0 authed)`; with the key set, `(1 authed)`. So an entry with no auth is
  authenticated and one that asks for a key the user doesn't have is not - writing
  an env_key, which the first version's comment considered, would have made magpie
  the one provider Ante refuses to auto-detect.
- Ante fills `support_vision: true` in for itself, as the PR's own note said, and
  a routing group declared with no capabilities at all still worked.

Not covered by that run: the stand-in server answered inside the distro, so this
proves Ante's config handling end to end, not a live magpie gateway relay (the
first commit's message records a real turn through one). Every probe used
ANTE_HOME into a temp folder; this machine's real ~/.ante gained no catalog.json
or settings.json.

What each fix failed without it, one test each: taking ANTE_HOME out ->
TestAnteHome "$ANTE_HOME ignored"; theirsKept out -> "the user's auth lost or
changed"; syncJSON out -> "an unchanged catalog was rewritten"; atomic out ->
"settings.json kept half of a change that failed"; the old min mapping ->
"anteEfforts([minimal high]) = [high], want [min high]"; a written default ->
"deepseek/pro: effort written"; settings never pointed at magpie -> TestAnte; a
model never written -> TestAnteModelField; Check left quiet -> "moved off magpie:
\"\""; handing magpie back over a pick the user made while wired ->
TestAnteKeepsWhatTheUserPickedWhileWired; never restoring the model ->
TestAnteConnectDisconnect "not put back"; Connect picking the model field instead
of magpie as provider -> "Connect left the user's model beside magpie's provider";
ANTE_HOME kept out of agentenv.Vars -> TestFolderVarsAreListed. Taking
preferred_models out of the whole list is the one mutation no test turns red on:
mergeTheirs cannot merge a JSON array (sync.go returns want for it), so the file
behaves the same either way and the argument is there for intent and for the other
keys, not for behaviour.

go vet ./... and go build ./... pass, as do GOOS=linux go build -tags nogui ./...
and GOOS=windows go build ./..., and gofmt is clean on LF content (this clone has
core.autocrlf and no .gitattributes, so gofmt -l reports every file).
go test -tags nogui ./internal/agent fails twelve tests, and an untouched worktree
of origin/main run the same command on this machine fails the same twelve, test for
test; ./internal/agentenv, ./internal/appdir and ./internal/edit pass, and every
Ante test passes at -count=5. The whole ./... was run on both: the failing sets are
alike, origin/main having one more, TestLoginUsageClaudeAskedMeanwhile, already
filed as #1228. None of those twelve is this change's, and none is fixed here.

* docs: agent-wiring records that Ante keeps the user's keys in magpie's entry and starts on settings.json's provider (#1210)

The two rules the review asked for, written where the repo keeps them - the same lines ad3b7fe5 (#1239) added for Air and 2d9db1b6 (#1242) for malformed configs. The Verification block gains the package's own Ante run, as #1239 added Air's.

---------

Co-authored-by: wizzy-yang <wizzy-yang@users.noreply.github.com>
2026-10-08 16:58:41 +08:00
..