Skip to content

router: antigravity-agy / antigravity-ls leaves are never selected by routes (silent zero-expansion) #985

Closed
developing-today/code
#2735

Description

@dezren39

Defect

Routes never attempt antigravity-agy or antigravity-ls leaves. Direct sessions to both providers work (ledger history: antigravity-agy 21 successes, antigravity-ls 42 successes — all with route_id empty, i.e. direct pins/probes). Across all routed traffic there is not one attempt on either provider.

Evidence (2026-10-30, laptop)

  • workhorse-primary (route config in developing-today/code, .opencode/opencode.jsonc) has carried the leg antigravity-agy/gemini-4-argon#high at weight 2 of 4 since 2026-10-29. Zero attempts ever.
  • 2026-10-30: opencode-route/sonnet-plan#high (live door antigravity-ls/claude-sonnet-5-5) added to the same route (code PR Error message after each write anomalyco/opencode#2731), server restarted on the new config (config file mtime 07:17, restart 07:20). Six probe turns through workhorse: zero antigravity attempts — every turn went deepseek-flash doors → cline-pass → commandcode → muse/openai.
  • Both proxies are healthy: GET /v1/models on :18743 (agy) and :18745 (ls) return 200 with the expected catalogs (gemini-4-argon and claude-sonnet-5-5 present, spelled as configured).
  • Other direct-provider leaves in routes work fine (muse, openai, opencode-go.* are attempted constantly), so route expansion itself works — something about the antigravity providers makes their leaves silently expand to zero candidates (the config comments in code describe this exact symptom for a different route: "the route expanded to zero").

Impact

Two nearly-full pools (Antigravity Gemini ~99% remaining, Claude/GPT ~100% remaining) are unreachable for all routed work, including the temporary primary burn legs Drew ordered on 2026-10-29/30 (Argon, then Sonnet). Sessions can only reach these pools by pinning the provider directly.

Acceptance

  • A workhorse turn can land on antigravity-agy/gemini-4-argon and on antigravity-ls/claude-sonnet-5-5 via route selection, visible as route_attempt rows with route_id set and provider_id antigravity-*.
  • If a leaf cannot expand, the router logs/records why (no silent zero-expansion).
  • Related: the quota pre-gating issue (companion, filed the same day) — once gates exist, an idle-but-full pool and a walled pool must be distinguishable in candidacy.

Activity

  1. dezren39 commented on Oct 30, 2026

    @dezren39
    Author

    Diagnosis update (2026-10-30, from the live server + probes)

    The defect is in route expansion, and the pattern is now exact. The running server's expanded target lists (/api/model, settings.opencodeRoute.targets):

    Standalone routes keep their Antigravity leaves:

    • sonnet-plan → [antigravity-ls/claude-sonnet-5-5] ✓
    • argon-plan → [go×3 gemini-4-argon, antigravity-agy/gemini-4-argon] ✓
    • gemini-flash-plan → [antigravity-ls/gemini-3.8-flash] ✓
    • deepseek-flash-plan → includes both opendesign doors ✓

    The same leaves vanish when reached through a parent route:

    • workhorse-primary → deepseek doors (minus opendesign×2) + muse only. The direct antigravity-agy/gemini-4-argon#high leaf and the whole sonnet-plan contribution are gone.
    • specialist → sonnet-plan contributes nothing; argon-plan contributes only its 3 Go leaves (agy leaf gone); spark-plan contributes nothing.
    • summit → opus-plan nothing; argon-plan's agy leaf gone.
    • speed → gemini-flash-plan nothing; haiku-plan's opendesign leaf gone.
    • scout/workhorse → opendesign doors of deepseek-flash gone.

    Dropped-in-nesting providers: antigravity-agy, antigravity-ls, opendesign. Surviving: opencode-go.*, openai, openai.alternate, muse, cline-pass, commandcode. Notably, in /api/provider the dropped three are exactly the records with no integrationID (and no canonical/instanceOf) — the surviving set all carry integration/canonical metadata.

    Ruled out by direct experiment: the models themselves (agy gemini-4-argon is enabled with low/medium/high variants in the live catalog; a direct session pin with variant high succeeds; a session pinned to sonnet-plan as top-level route succeeds on antigravity-ls). Also ruled out: stale config (server restarted on the current file) and the leaves' variant pins (both models enumerate high natively).

    Prime suspect: the retarget/re-expansion path (retargetDefinition in packages/core/src/config/plugin/model-routes.ts, #236/#869) — a re-expansion computed with a definitions map in which these providers' model maps are empty or keyed differently replaces the transform-time expansion for parent routes, while un-retargeted standalone routes keep the correct one. The fix should make expansion consistent regardless of which pass computes it, and any leaf that still cannot expand should be diagnosable (no silent zero-expansion).

    Acceptance stands as filed; the six-probe ledger trail (sessions titled probe-, probe2-, probe3-rot-*) is in the laptop's route_attempt table.

  2. dezren39 commented on Oct 30, 2026

    @dezren39
    Author

    Root cause (confirmed by code read + live catalog comparison)

    expand() in packages/core/src/config/plugin/model-routes.ts prunes any leaf whose pinned or inherited variant is not natively enumerated on the provider-record Model.Info at expansion time:

    if (requested && !variant) continue

    Expansion runs against provider definitions before model transforms complete (the file's own retarget comment says so). For the proxy providers (antigravity-agy, antigravity-ls, opendesign) the record models carry no variants — their variant surfaces exist only in the post-transform runtime catalog (where /api/model shows low/medium/high on exactly these models). So:

    • A route target that pins a variant (antigravity-agy/gemini-4-argon#high, opencode-route/sonnet-plan#high inheriting high into the ls target, deepseek-flash#high inheriting into opendesign doors) silently expands to zero for those providers.
    • Unpinned references to the same providers survive — which is why sonnet-plan standalone (no variant requested; its probe session ran the ls leaf with variant null), gemini-flash-plan, opus-plan, and argon-plan all keep their leaves, and why direct session pins work (the runtime resolver sees the post-transform catalog).

    This also explains specialist/summit/speed losing whole subroutes (spark-plan under #max, gemini-flash-plan under speed) and deepseek-flash losing its two opendesign doors whenever it is nested under a #high reference.

    Suggested fix direction: expansion should not prune a leaf for an unproducible variant when the model itself exists in the record — the record is known-incomplete at that stage. Keep the leaf with its pinned ref and let variant resolution happen against the final catalog (the resolver already does this for direct pins); the retarget pass can re-prune if the completed catalog still cannot produce the variant. At minimum, a pruned-for-variant leaf must be diagnosable rather than silent.

  3. added a commit that references this issue on Oct 30, 2026
  4. dezren39 commented on Oct 30, 2026

    @dezren39
    Author

    Fixed and verified live (2026-10-30)

    Fix: PR #986 (merged, commit 03245ec), two repairs in packages/core/src/config/plugin/model-routes.ts:

    • expand(): a pinned/inherited variant the door's catalog exposes as a suffixed model id (<model>-<variant>) counts as producible, like a native variant or a remap. A variant with no native, remapped, or suffixed evidence still prunes.
    • retargetDefinition(): definition-stage entries are refreshed from the editor by their own ids, completing the documented definition-ids-union-current semantics for models the editor does not enumerate.

    Tests: four new regression tests; route family 221 pass, governance/session-model 17 pass, typecheck clean.

    Deployed: code PR anomalyco#2735 bumped the flake input; laptop switched to generation 516 running opencode 2.0.30+a8dfb81.

    Live verification (server's expanded targets, before → after):

    • workhorse-primary [6] → [10]: gains antigravity-agy/gemini-4-argon#high, antigravity-ls/claude-sonnet-5-5#high, and both opendesign doors.
    • specialist [6] → [9], summit [6] → [9], speed [13] → [17]: the same providers' leaves restored everywhere.

    Six fresh workhorse probe sessions (probe4-fix-*): five were served first-attempt by the Antigravity leaves (agy Argon ×3 successes, ls Sonnet ×2 successes), the sixth by opendesign — zero failed attempts across all six, where every pre-fix probe burned 5–6 dead attempts before succeeding. Sonnet and Argon are now in the primary workhorse rotation as ordered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions