mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-18 21:22:28 +03:00
feat(oauth): add gemini-3.7-flash models for antigravity and agy providers (#10305)
* feat(oauth): add gemini-3.7-flash models with reasoning tiers for antigravity Support gemini-3.7-flash and its thinking tiers (low/medium/high) for antigravity and agy providers. - Define public models, pricing, modelSpecs, and CLI tool definitions - Map tiers to live upstream id gemini-3.7-flash-tiered - Configure defaultThinkingBudget (low: 1024, medium: 8192, high: 32768) - Allow executor fallback on upstream 404 and 5xx errors - Add unit tests in antigravity-model-aliases.test.ts * fix(oauth): expose gemini-3.7-flash as one callable antigravity/agy model Upstream (fetchAvailableModels on daily-cloudcode-pa) only accepts the single upstream id gemini-3.7-flash-tiered; the high/medium/low suffixed tier ids 404. Registering all four as distinct public model ids violates the base #3696 uniqueness invariant (no two ANTIGRAVITY_PUBLIC_MODELS entries may resolve to the same upstream id). Collapse to the single live gemini-3.7-flash public model (aliased to gemini-3.7-flash-tiered) and drop the tiered specs, pricing, free-catalog and CLI entries accordingly, keeping the leading public model order (Gemini 3.6 tiers first) intact. Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com> --------- Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com> Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com> Co-authored-by: Chewji9875 <Chewji9875@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -106,6 +106,18 @@ export const AGY_PUBLIC_MODELS = Object.freeze([
|
||||
supportsVision: true,
|
||||
toolCalling: true,
|
||||
},
|
||||
// Gemini 3.7 Flash: single callable public model (upstream exposes only
|
||||
// gemini-3.7-flash-tiered; suffixed tier ids 404). One entry so it does not
|
||||
// collide under the #3696 public-id uniqueness invariant.
|
||||
{
|
||||
id: "gemini-3.7-flash",
|
||||
name: "Gemini 3.7 Flash",
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 65536,
|
||||
supportsReasoning: true,
|
||||
supportsVision: true,
|
||||
toolCalling: true,
|
||||
},
|
||||
{
|
||||
id: "gemini-3.1-flash-lite",
|
||||
name: "Gemini 3.1 Flash Lite",
|
||||
|
||||
@@ -124,6 +124,18 @@ export const ANTIGRAVITY_PUBLIC_MODELS = Object.freeze([
|
||||
supportsVision: true,
|
||||
toolCalling: true,
|
||||
},
|
||||
// Gemini 3.7 Flash: Antigravity's live catalog exposes a single upstream id
|
||||
// gemini-3.7-flash-tiered; the suffixed tier ids 404 upstream. Kept as one
|
||||
// callable public model so it does not collide with the #3696 uniqueness invariant.
|
||||
{
|
||||
id: "gemini-3.7-flash",
|
||||
name: "Gemini 3.7 Flash",
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 65536,
|
||||
supportsReasoning: true,
|
||||
supportsVision: true,
|
||||
toolCalling: true,
|
||||
},
|
||||
{
|
||||
id: "gemini-3.1-flash-lite",
|
||||
name: "Gemini 3.1 Flash Lite",
|
||||
@@ -163,6 +175,12 @@ export const ANTIGRAVITY_PUBLIC_MODELS = Object.freeze([
|
||||
]);
|
||||
|
||||
export const ANTIGRAVITY_MODEL_ALIASES = Object.freeze({
|
||||
// Gemini 3.7 Flash: the live catalog (fetchAvailableModels on daily-cloudcode-pa)
|
||||
// exposes a single upstream id `gemini-3.7-flash-tiered`; the agy CLI maps all
|
||||
// display tiers (high/medium/low) to it. Verified 200 OK with thinking_level and
|
||||
// thinkingBudget configs. The suffixed ids 404 upstream ("Requested entity was not found").
|
||||
// Exposed as ONE callable model (see #3696: public ids must be unique upstream ids).
|
||||
"gemini-3.7-flash": "gemini-3.7-flash-tiered",
|
||||
// gemini-3.1-pro-low is not aliased: the upstream accepts it verbatim.
|
||||
// gemini-3.1-pro-high: the discovery slot returns HTTP 400 on v1internal;
|
||||
// the live upstream id is gemini-pro-agent (see ANTIGRAVITY_PUBLIC_MODELS).
|
||||
|
||||
@@ -26,6 +26,7 @@ export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [
|
||||
{ provider: "agy", modelId: "claude-sonnet-4-6", displayName: "Claude Sonnet 4.6 (Thinking)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-3.1-pro-low", displayName: "Gemini 3.1 Pro (Low)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-pro-agent", displayName: "Gemini 3.1 Pro (High)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-3.7-flash", displayName: "Gemini 3.7 Flash", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-3.6-flash-high", displayName: "Gemini 3.6 Flash (High)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-3.6-flash-medium", displayName: "Gemini 3.6 Flash (Medium)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
{ provider: "agy", modelId: "gemini-3.6-flash-low", displayName: "Gemini 3.6 Flash (Low)", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "agy", tos: "avoid" },
|
||||
|
||||
@@ -25,4 +25,5 @@ export const agyProvider: RegistryEntry = {
|
||||
},
|
||||
models: [...AGY_PUBLIC_MODELS],
|
||||
passthroughModels: true,
|
||||
liveCatalogAuthoritative: false,
|
||||
};
|
||||
|
||||
@@ -25,4 +25,5 @@ export const antigravityProvider: RegistryEntry = {
|
||||
},
|
||||
models: [...ANTIGRAVITY_PUBLIC_MODELS],
|
||||
passthroughModels: true,
|
||||
liveCatalogAuthoritative: false,
|
||||
};
|
||||
|
||||
@@ -521,6 +521,17 @@ export class AntigravityExecutor extends BaseExecutor {
|
||||
super("antigravity", PROVIDERS.antigravity);
|
||||
}
|
||||
|
||||
override shouldRetry(status: number, urlIndex: number): boolean {
|
||||
return (
|
||||
(status === HTTP_STATUS.RATE_LIMITED ||
|
||||
status === HTTP_STATUS.NOT_FOUND ||
|
||||
status === HTTP_STATUS.BAD_GATEWAY ||
|
||||
status === HTTP_STATUS.SERVICE_UNAVAILABLE ||
|
||||
status === HTTP_STATUS.GATEWAY_TIMEOUT) &&
|
||||
urlIndex + 1 < this.getFallbackCount()
|
||||
);
|
||||
}
|
||||
|
||||
buildUrl(model: string, _stream: boolean, urlIndex = 0): string {
|
||||
void model;
|
||||
const baseUrls = this.getBaseUrls();
|
||||
|
||||
@@ -239,6 +239,7 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
|
||||
acpSpawnable: false,
|
||||
baseUrlSupport: "none",
|
||||
modelAliases: [
|
||||
"gemini-3.7-flash",
|
||||
"gemini-3.6-flash-high",
|
||||
"gemini-3.6-flash-medium",
|
||||
"gemini-3.6-flash-low",
|
||||
@@ -252,6 +253,7 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
|
||||
"gpt-oss-120b-medium",
|
||||
],
|
||||
defaultModels: [
|
||||
createCliModel("gemini-3.7-flash", "Gemini 3.7 Flash"),
|
||||
createCliModel("gemini-3.6-flash-high", "Gemini 3.6 Flash High"),
|
||||
createCliModel("gemini-3.6-flash-medium", "Gemini 3.6 Flash Medium"),
|
||||
createCliModel("gemini-3.6-flash-low", "Gemini 3.6 Flash Low"),
|
||||
|
||||
@@ -174,6 +174,18 @@ export const MODEL_SPECS: Record<string, ModelSpec> = {
|
||||
thinkingBudgetCap: 0,
|
||||
},
|
||||
|
||||
// ── Gemini 3.7 Flash (Antigravity) — collapsed live id ──────────
|
||||
// Upstream (fetchAvailableModels on daily-cloudcode-pa) also serves this model as a
|
||||
// single `gemini-3.7-flash-tiered` id via the `gemini-3.7-flash` alias in
|
||||
// antigravityModelAliases.ts. Registered independently of the suffixed tier ids below
|
||||
// (#3696 uniqueness invariant: each public id resolves to a distinct upstream id).
|
||||
"gemini-3.7-flash": {
|
||||
...GEMINI_35_FLASH_MODEL_SPEC,
|
||||
defaultThinkingBudget: 8192,
|
||||
thinkingBudgetCap: 65536,
|
||||
supportsThinking: true,
|
||||
},
|
||||
|
||||
// ── Gemini 3.7 / 3.6 Flash (Antigravity live tiers) ─────────────
|
||||
// The model id itself selects the upstream 10k/4k/1k reasoning tier. Antigravity
|
||||
// still rejects client-supplied thinking parameters, so keep the explicit-parameter
|
||||
|
||||
@@ -319,6 +319,13 @@ export const DEFAULT_PRICING_OAUTH = {
|
||||
// downstream cost and quota calculations silently fall back to $0.
|
||||
// Pricing: $1.50 input / $7.50 output / $0.15 cached per MTok. Thinking tokens
|
||||
// billed at output rate.
|
||||
"gemini-3.7-flash": {
|
||||
input: 1.5,
|
||||
output: 7.5,
|
||||
cached: 0.15,
|
||||
reasoning: 7.5,
|
||||
cache_creation: 1.5,
|
||||
},
|
||||
"gemini-3.6-flash-low": {
|
||||
input: 1.5,
|
||||
output: 7.5,
|
||||
|
||||
@@ -18,6 +18,7 @@ function getPublicModel(id: string) {
|
||||
}
|
||||
|
||||
const EXPECTED_FLASH_TIERS = [
|
||||
["gemini-3.7-flash", "Gemini 3.7 Flash"],
|
||||
["gemini-3.7-flash-high", "Gemini 3.7 Flash (High)"],
|
||||
["gemini-3.7-flash-medium", "Gemini 3.7 Flash (Medium)"],
|
||||
["gemini-3.6-flash-low", "Gemini 3.6 Flash (Low)"],
|
||||
@@ -49,7 +50,11 @@ test("toClientAntigravityQuotaModelId preserves upstream Gemini Flash bucket IDs
|
||||
test("resolveAntigravityModelId maps the documented Antigravity aliases to upstream IDs", () => {
|
||||
assert.equal(resolveAntigravityModelId("gemini-3-pro-image-preview"), "gemini-3-pro-image");
|
||||
for (const [modelId] of EXPECTED_FLASH_TIERS) {
|
||||
assert.equal(resolveAntigravityModelId(modelId), modelId);
|
||||
// Only the collapsed gemini-3.7-flash id is aliased to the live upstream
|
||||
// gemini-3.7-flash-tiered id; the suffixed gemini-3.7-flash-high/medium tier ids
|
||||
// (like the 3.6/3.5 tiers) have no alias entry and pass through verbatim.
|
||||
const expected = modelId === "gemini-3.7-flash" ? "gemini-3.7-flash-tiered" : modelId;
|
||||
assert.equal(resolveAntigravityModelId(modelId), expected);
|
||||
}
|
||||
assert.equal(resolveAntigravityModelId("gemini-claude-sonnet-4-5"), "claude-sonnet-4-6");
|
||||
assert.equal(resolveAntigravityModelId("gemini-claude-sonnet-4-5-thinking"), "claude-sonnet-4-6");
|
||||
@@ -193,7 +198,7 @@ test("AntigravityExecutor.transformRequest preserves Gemini Flash upstream IDs",
|
||||
);
|
||||
|
||||
if (result instanceof Response) throw new Error("Unexpected Response from transformRequest");
|
||||
assert.equal(result.model, modelId);
|
||||
assert.equal(result.model, resolveAntigravityModelId(modelId));
|
||||
assert.deepEqual(result.request.contents, [{ role: "user", parts: [{ text: "Hello" }] }]);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user