Compare commits

...

1 Commits

Author SHA1 Message Date
Markus Hartung
e6cb82b27b fix(providers): scope Antigravity mitmAlias tier ids to the safe static alias (#11824) 2026-08-29 05:22:39 -03:00
3 changed files with 80 additions and 1 deletions

View File

@@ -0,0 +1 @@
- **fix(providers):** Antigravity's dynamic mitmAlias table no longer routes `gemini-3.7-flash-{high,medium,low}` to a literal tier-suffixed upstream id just because one connected account's own discovery listed it directly — those display ids always resolve through the safe `gemini-3.7-flash-tiered` static alias, so one account's Google-provisioned access no longer 404s every sibling account of the provider ([#11824](https://github.com/diegosouzapw/OmniRoute/issues/11824), [#11651](https://github.com/diegosouzapw/OmniRoute/issues/11651))

View File

@@ -387,6 +387,24 @@ export async function importManagedModels({
}
}
// #11824/#11651: `syncedIds` is a UNION across every connection of this provider
// (getSyncedAvailableModels), so an identity mapping derived above can route a
// display id to the literal tier-suffixed upstream id (e.g. "gemini-3.7-flash-high")
// just because ONE connected account's own discovery happens to list it directly.
// Google's Cloud Code Assist backend only allows those tier-suffixed ids on
// accounts/projects it specifically provisioned for them — every other account can
// only call the shared "-tiered" endpoint id. Since this mitmAlias table is global
// (not scoped per connection) and consulted first/authoritatively by
// cleanModelName(), letting one account's discovery win here silently 404s every
// sibling account. Force every display id that the static ANTIGRAVITY_MODEL_ALIASES
// table already knows only has a safe "-tiered" target to always resolve there,
// regardless of what any single connection's discovery reported.
for (const [displayId, safeTarget] of Object.entries(ANTIGRAVITY_MODEL_ALIASES)) {
if (safeTarget === "gemini-3.7-flash-tiered") {
mappings[displayId] = `antigravity/${safeTarget}`;
}
}
await setMitmAliasAll("antigravity", mappings);
}

View File

@@ -296,10 +296,70 @@ test("antigravity sync dynamically builds and saves mitmAlias mappings", async (
models.some((model) => model.id === "gemini-3.5-flash"),
false
);
assert.equal(mitmMappings["gemini-3.7-flash-high"], "antigravity/gemini-3.7-flash-high");
// #11824: gemini-3.7-flash-high is a known cross-account-unsafe display id (the
// tier-suffixed upstream id is only callable on Google projects specifically
// provisioned for it); it must always resolve through the static alias to the
// safe shared "-tiered" endpoint id, never as an identity mapping to the literal
// tier id — even when it appears directly in this connection's own discovery.
assert.equal(mitmMappings["gemini-3.7-flash-high"], "antigravity/gemini-3.7-flash-tiered");
assert.equal(mitmMappings["custom-antigravity-model"], "antigravity/custom-antigravity-model");
// Removed Antigravity 2.0 preview/agent aliases must not be reintroduced.
assert.equal(mitmMappings["gemini-3.5-flash-preview"], undefined);
assert.equal(mitmMappings["gemini-3-flash-agent"], undefined);
});
test("#11824: syncing account A's model catalog must not route account B's gemini-3.7-flash-high to an id B's own discovery never advertised", async () => {
const db = core.getDbInstance();
const now = "2026-08-27";
db.prepare(
"INSERT INTO provider_connections (id, provider, auth_type, name, is_active, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)"
).run("acct-a", "antigravity", "oauth", "Antigravity A", 1, now, now);
db.prepare(
"INSERT INTO provider_connections (id, provider, auth_type, name, is_active, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)"
).run("acct-b", "antigravity", "oauth", "Antigravity B", 1, now, now);
// Account A: Google has provisioned direct tier-suffixed callability for this
// project -- its own :fetchAvailableModels lists "gemini-3.7-flash-high" verbatim.
await importManagedModels({
providerId: "antigravity",
connectionId: "acct-a",
mode: "sync",
fetchedModels: [{ id: "gemini-3.7-flash-high", name: "Gemini 3.7 Flash High" }],
});
// Account B: Google has NOT provisioned the direct tier id for this project --
// its own :fetchAvailableModels only ever lists the tiered endpoint id.
await importManagedModels({
providerId: "antigravity",
connectionId: "acct-b",
mode: "sync",
fetchedModels: [{ id: "gemini-3.7-flash-tiered", name: "Gemini 3.7 Flash (Tiered)" }],
});
// Account B's OWN synced catalog never included the direct tier id.
const acctBOwnCatalog = await modelsDb.getSyncedAvailableModelsForConnection(
"antigravity",
"acct-b"
);
const acctBOwnIds = acctBOwnCatalog.map((m) => m.id);
assert.ok(
!acctBOwnIds.includes("gemini-3.7-flash-high"),
"precondition: account B's own discovery must not include the direct tier id"
);
// But the GLOBAL mitmAlias table used by cleanModelName() for EVERY connection
// (including B's requests) was rebuilt from the union of A + B, so it must not
// still route "gemini-3.7-flash-high" to the id only A supports.
const mitmMappings = await modelsDb.getMitmAlias("antigravity");
assert.notEqual(
mitmMappings["gemini-3.7-flash-high"],
"antigravity/gemini-3.7-flash-high",
"BUG: the shared mitmAlias table routes gemini-3.7-flash-high to the literal " +
"upstream id (only account A's project supports it) even for account B, " +
"whose own discovery never advertised that id -- this is what produces the " +
"per-account 404 reported in #11824/#11651."
);
assert.equal(mitmMappings["gemini-3.7-flash-high"], "antigravity/gemini-3.7-flash-tiered");
});