@jacobbd/relay-ai 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-IYYLLN5T.js → chunk-6CBNKM55.js} +866 -18
- package/dist/chunk-6CBNKM55.js.map +1 -0
- package/dist/{chunk-EJONCU3B.js → chunk-HXGZ4CTV.js} +13 -1
- package/dist/chunk-HXGZ4CTV.js.map +1 -0
- package/dist/cli.js +172 -671
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/{provider-templates-BPGB5V2L.js → provider-templates-4H3C4DRL.js} +2 -2
- package/dist/ui/public/app.js +71 -15
- package/dist/ui/public/provider-model-browser.js +4 -1
- package/dist/ui/public/style.css +7 -0
- package/dist/{ui-command-3CWMSARO.js → ui-command-S3TQKB3D.js} +32 -11
- package/dist/ui-command-S3TQKB3D.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-EJONCU3B.js.map +0 -1
- package/dist/chunk-IYYLLN5T.js.map +0 -1
- package/dist/ui-command-3CWMSARO.js.map +0 -1
- /package/dist/{provider-templates-BPGB5V2L.js.map → provider-templates-4H3C4DRL.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
appendCodexBodyDump,
|
|
18
18
|
authenticateProvider,
|
|
19
19
|
buildAntigravityChildEnv,
|
|
20
|
+
buildAntigravityRoutes,
|
|
20
21
|
buildAppCatalogFile,
|
|
21
22
|
buildCatalogFile,
|
|
22
23
|
buildCatalogRoutes,
|
|
@@ -25,6 +26,8 @@ import {
|
|
|
25
26
|
buildCodexAppRootConfig,
|
|
26
27
|
buildHttpProxyRoutes,
|
|
27
28
|
buildImportProviderList,
|
|
29
|
+
buildListExperimentsResponse,
|
|
30
|
+
buildListModelConfigsResponse,
|
|
28
31
|
buildVertexRuntimeConfig,
|
|
29
32
|
cachedModelToLocal,
|
|
30
33
|
catalogEntryFromModel,
|
|
@@ -42,6 +45,7 @@ import {
|
|
|
42
45
|
effectiveProviderBaseUrl,
|
|
43
46
|
effortProviderOptions,
|
|
44
47
|
encodeToolUseId,
|
|
48
|
+
evaluateAgySwitchCompatibility,
|
|
45
49
|
extractApiKey,
|
|
46
50
|
favoriteProviderDisplayName,
|
|
47
51
|
fetchAnthropicModels,
|
|
@@ -73,6 +77,7 @@ import {
|
|
|
73
77
|
hasApplicationDefaultCredentials,
|
|
74
78
|
httpProxyModelId,
|
|
75
79
|
injectClaudeIdentity,
|
|
80
|
+
injectRelayModels,
|
|
76
81
|
isClaudeAppRunning,
|
|
77
82
|
isCodexAppRunning,
|
|
78
83
|
isFreeStatus,
|
|
@@ -92,6 +97,7 @@ import {
|
|
|
92
97
|
makeRouteResolver,
|
|
93
98
|
makeTraceLogger,
|
|
94
99
|
maxToolsForNpm,
|
|
100
|
+
meetsContextFloor,
|
|
95
101
|
migrateGlobalOpencodeCredential,
|
|
96
102
|
migrateLegacyCloudProviders,
|
|
97
103
|
modelSelectOption,
|
|
@@ -137,6 +143,7 @@ import {
|
|
|
137
143
|
resolveProviderTemplate,
|
|
138
144
|
resolveProvidersForDisplay,
|
|
139
145
|
resolveRefreshCredential,
|
|
146
|
+
resolveRelayCatalogSlots,
|
|
140
147
|
routableModelsForTarget,
|
|
141
148
|
routeLookupIds,
|
|
142
149
|
runServerCommand,
|
|
@@ -165,14 +172,14 @@ import {
|
|
|
165
172
|
validateCustomEndpointUrl,
|
|
166
173
|
writeSecureLogLine,
|
|
167
174
|
zenRegistryStub
|
|
168
|
-
} from "./chunk-
|
|
175
|
+
} from "./chunk-6CBNKM55.js";
|
|
169
176
|
import {
|
|
170
177
|
filterTemplates,
|
|
171
178
|
init_provider_templates,
|
|
172
179
|
listAddableTemplates,
|
|
173
180
|
listSupportedTemplates,
|
|
174
181
|
listVisibleOAuthTemplates
|
|
175
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-HXGZ4CTV.js";
|
|
176
183
|
|
|
177
184
|
// src/cli.ts
|
|
178
185
|
import pc12 from "picocolors";
|
|
@@ -1538,7 +1545,16 @@ async function runTemplateAddFlow() {
|
|
|
1538
1545
|
]);
|
|
1539
1546
|
}
|
|
1540
1547
|
let baseUrlOverride;
|
|
1541
|
-
if (template.
|
|
1548
|
+
if (template.accountIdPrompt) {
|
|
1549
|
+
const accountInput = await p5.text({
|
|
1550
|
+
message: template.accountIdPrompt,
|
|
1551
|
+
placeholder: "e.g. 4ff191dac2d0bd7538cb1c9126594de3",
|
|
1552
|
+
validate: (v) => v.trim() ? void 0 : "Account ID is required"
|
|
1553
|
+
});
|
|
1554
|
+
if (p5.isCancel(accountInput)) return 0;
|
|
1555
|
+
const accountId = String(accountInput).trim();
|
|
1556
|
+
baseUrlOverride = template.defaultBaseUrl?.replace("{ACCOUNT_ID}", accountId);
|
|
1557
|
+
} else if (template.urlPrompt) {
|
|
1542
1558
|
const urlInput = await p5.text({
|
|
1543
1559
|
message: template.urlPrompt,
|
|
1544
1560
|
initialValue: template.defaultBaseUrl,
|
|
@@ -6468,655 +6484,6 @@ function formatCloudCodeChunk(opts) {
|
|
|
6468
6484
|
};
|
|
6469
6485
|
}
|
|
6470
6486
|
|
|
6471
|
-
// src/antigravity/slot-registry.ts
|
|
6472
|
-
var AGY_SLOT_VALIDATION_SOURCE = "AGY CLI 1.0.10 / Antigravity IDE 2.1.1 fixture capture 2026-06-23";
|
|
6473
|
-
var AGY_NATIVE_SLOT_REGISTRY = [
|
|
6474
|
-
{
|
|
6475
|
-
slotId: "gemini-3.5-flash-low",
|
|
6476
|
-
model: "MODEL_PLACEHOLDER_M20",
|
|
6477
|
-
role: "agent-switch",
|
|
6478
|
-
status: "validated",
|
|
6479
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6480
|
-
},
|
|
6481
|
-
{
|
|
6482
|
-
slotId: "gemini-3.5-flash-extra-low",
|
|
6483
|
-
model: "MODEL_PLACEHOLDER_M187",
|
|
6484
|
-
role: "agent-switch",
|
|
6485
|
-
status: "validated",
|
|
6486
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6487
|
-
},
|
|
6488
|
-
{
|
|
6489
|
-
slotId: "gemini-3.1-pro-low",
|
|
6490
|
-
model: "MODEL_PLACEHOLDER_M36",
|
|
6491
|
-
role: "agent-switch",
|
|
6492
|
-
status: "validated",
|
|
6493
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6494
|
-
},
|
|
6495
|
-
{
|
|
6496
|
-
slotId: "gemini-pro-agent",
|
|
6497
|
-
model: "MODEL_PLACEHOLDER_M16",
|
|
6498
|
-
role: "agent-switch",
|
|
6499
|
-
status: "validated",
|
|
6500
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6501
|
-
},
|
|
6502
|
-
{
|
|
6503
|
-
slotId: "claude-sonnet-4-6",
|
|
6504
|
-
model: "MODEL_PLACEHOLDER_M35",
|
|
6505
|
-
role: "agent-switch",
|
|
6506
|
-
status: "validated",
|
|
6507
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6508
|
-
},
|
|
6509
|
-
{
|
|
6510
|
-
slotId: "claude-opus-4-6-thinking",
|
|
6511
|
-
model: "MODEL_PLACEHOLDER_M26",
|
|
6512
|
-
role: "agent-switch",
|
|
6513
|
-
status: "validated",
|
|
6514
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6515
|
-
},
|
|
6516
|
-
{
|
|
6517
|
-
slotId: "gpt-oss-120b-medium",
|
|
6518
|
-
model: "MODEL_OPENAI_GPT_OSS_120B_MEDIUM",
|
|
6519
|
-
role: "agent-switch",
|
|
6520
|
-
status: "validated",
|
|
6521
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6522
|
-
},
|
|
6523
|
-
{
|
|
6524
|
-
slotId: "gemini-3-flash-agent",
|
|
6525
|
-
model: "MODEL_PLACEHOLDER_M132",
|
|
6526
|
-
role: "cascade-plan",
|
|
6527
|
-
status: "reserved",
|
|
6528
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6529
|
-
notes: "Visible in agentModelSorts, but reserved for cascade plan construction."
|
|
6530
|
-
},
|
|
6531
|
-
{
|
|
6532
|
-
slotId: "gemini-2.5-flash",
|
|
6533
|
-
model: "MODEL_GOOGLE_GEMINI_2_5_FLASH",
|
|
6534
|
-
role: "cascade-intent",
|
|
6535
|
-
status: "reserved",
|
|
6536
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6537
|
-
},
|
|
6538
|
-
{
|
|
6539
|
-
slotId: "gemini-2.5-flash-lite",
|
|
6540
|
-
model: "MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE",
|
|
6541
|
-
role: "cascade-fallback",
|
|
6542
|
-
status: "reserved",
|
|
6543
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6544
|
-
},
|
|
6545
|
-
{
|
|
6546
|
-
slotId: "gemini-3.1-pro-high",
|
|
6547
|
-
model: "MODEL_PLACEHOLDER_M37",
|
|
6548
|
-
role: "agent-switch",
|
|
6549
|
-
status: "candidate",
|
|
6550
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6551
|
-
notes: "Model-shaped fixture entry; requires live switching proof before promotion."
|
|
6552
|
-
},
|
|
6553
|
-
{
|
|
6554
|
-
slotId: "gemini-2.5-pro",
|
|
6555
|
-
model: "MODEL_GOOGLE_GEMINI_2_5_PRO",
|
|
6556
|
-
role: "agent-switch",
|
|
6557
|
-
status: "candidate",
|
|
6558
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6559
|
-
notes: "Model-shaped fixture entry; requires live switching proof before promotion."
|
|
6560
|
-
},
|
|
6561
|
-
{
|
|
6562
|
-
slotId: "gemini-2.5-flash-thinking",
|
|
6563
|
-
model: "MODEL_GOOGLE_GEMINI_2_5_FLASH_THINKING",
|
|
6564
|
-
role: "agent-switch",
|
|
6565
|
-
status: "candidate",
|
|
6566
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6567
|
-
notes: "Model-shaped fixture entry; requires live switching proof before promotion."
|
|
6568
|
-
},
|
|
6569
|
-
{
|
|
6570
|
-
slotId: "gemini-3-flash",
|
|
6571
|
-
model: "MODEL_PLACEHOLDER_M18",
|
|
6572
|
-
role: "command",
|
|
6573
|
-
status: "candidate",
|
|
6574
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6575
|
-
notes: "Command model in the fixture; not switch-safe without live proof."
|
|
6576
|
-
},
|
|
6577
|
-
{
|
|
6578
|
-
slotId: "gemini-3.1-flash-lite",
|
|
6579
|
-
model: "MODEL_PLACEHOLDER_M50",
|
|
6580
|
-
role: "cascade-checkpoint",
|
|
6581
|
-
status: "candidate",
|
|
6582
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6583
|
-
notes: "Checkpoint/search/commit slot; route as helper until live proof exists."
|
|
6584
|
-
},
|
|
6585
|
-
{
|
|
6586
|
-
slotId: "gemini-3.1-flash-image",
|
|
6587
|
-
model: "MODEL_PLACEHOLDER_M21",
|
|
6588
|
-
role: "image",
|
|
6589
|
-
status: "candidate",
|
|
6590
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE,
|
|
6591
|
-
notes: "Image generation slot; not switch-safe without live proof."
|
|
6592
|
-
},
|
|
6593
|
-
{
|
|
6594
|
-
slotId: "tab_jump_flash_lite_preview",
|
|
6595
|
-
model: "MODEL_PLACEHOLDER_M28",
|
|
6596
|
-
role: "tab",
|
|
6597
|
-
status: "unsafe",
|
|
6598
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6599
|
-
},
|
|
6600
|
-
{
|
|
6601
|
-
slotId: "tab_flash_lite_preview",
|
|
6602
|
-
model: "MODEL_PLACEHOLDER_M19",
|
|
6603
|
-
role: "tab",
|
|
6604
|
-
status: "unsafe",
|
|
6605
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6606
|
-
},
|
|
6607
|
-
{
|
|
6608
|
-
slotId: "chat_20706",
|
|
6609
|
-
model: "MODEL_CHAT_20706",
|
|
6610
|
-
role: "chat",
|
|
6611
|
-
status: "unsafe",
|
|
6612
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6613
|
-
},
|
|
6614
|
-
{
|
|
6615
|
-
slotId: "chat_23310",
|
|
6616
|
-
model: "MODEL_CHAT_23310",
|
|
6617
|
-
role: "chat",
|
|
6618
|
-
status: "unsafe",
|
|
6619
|
-
validatedWith: AGY_SLOT_VALIDATION_SOURCE
|
|
6620
|
-
}
|
|
6621
|
-
];
|
|
6622
|
-
var KNOWN_COMPATIBLE_AGY_VERSIONS = /* @__PURE__ */ new Set(["1.0.10"]);
|
|
6623
|
-
var KNOWN_INCOMPATIBLE_AGY_VERSIONS = /* @__PURE__ */ new Set(["1.0.9"]);
|
|
6624
|
-
function withFixtureModel(definition, model) {
|
|
6625
|
-
return model === definition.model ? definition : { ...definition, model };
|
|
6626
|
-
}
|
|
6627
|
-
function assertNoDuplicateSwitchEnums(fixture, definitions) {
|
|
6628
|
-
const seen = /* @__PURE__ */ new Map();
|
|
6629
|
-
for (const definition of definitions) {
|
|
6630
|
-
if (definition.status !== "validated") continue;
|
|
6631
|
-
const actualModel = fixture.models[definition.slotId]?.model;
|
|
6632
|
-
if (!actualModel) continue;
|
|
6633
|
-
const previousSlotId = seen.get(actualModel);
|
|
6634
|
-
if (previousSlotId) {
|
|
6635
|
-
throw new Error(
|
|
6636
|
-
`Duplicate AGY switch slot enum ${actualModel}: ${previousSlotId} and ${definition.slotId}`
|
|
6637
|
-
);
|
|
6638
|
-
}
|
|
6639
|
-
seen.set(actualModel, definition.slotId);
|
|
6640
|
-
}
|
|
6641
|
-
}
|
|
6642
|
-
function validateAgySlotRegistry(fixture) {
|
|
6643
|
-
assertNoDuplicateSwitchEnums(fixture, AGY_NATIVE_SLOT_REGISTRY);
|
|
6644
|
-
const switchSlots = [];
|
|
6645
|
-
const reservedSlots = [];
|
|
6646
|
-
const candidateSlots = [];
|
|
6647
|
-
const warnings = [];
|
|
6648
|
-
for (const definition of AGY_NATIVE_SLOT_REGISTRY) {
|
|
6649
|
-
const entry = fixture.models[definition.slotId];
|
|
6650
|
-
if (!entry) {
|
|
6651
|
-
if (definition.status === "validated" || definition.status === "reserved") {
|
|
6652
|
-
warnings.push(`AGY slot ${definition.slotId} missing from fixture`);
|
|
6653
|
-
}
|
|
6654
|
-
continue;
|
|
6655
|
-
}
|
|
6656
|
-
if (entry.model !== definition.model) {
|
|
6657
|
-
warnings.push(
|
|
6658
|
-
`AGY slot ${definition.slotId} expected ${definition.model} but fixture has ${entry.model}`
|
|
6659
|
-
);
|
|
6660
|
-
continue;
|
|
6661
|
-
}
|
|
6662
|
-
if (definition.status === "validated") {
|
|
6663
|
-
switchSlots.push(withFixtureModel(definition, entry.model));
|
|
6664
|
-
} else if (definition.status === "reserved") {
|
|
6665
|
-
reservedSlots.push(withFixtureModel(definition, entry.model));
|
|
6666
|
-
} else if (definition.status === "candidate") {
|
|
6667
|
-
candidateSlots.push(withFixtureModel(definition, entry.model));
|
|
6668
|
-
}
|
|
6669
|
-
}
|
|
6670
|
-
return { switchSlots, reservedSlots, candidateSlots, warnings };
|
|
6671
|
-
}
|
|
6672
|
-
function getValidatedAgySwitchSlots(fixture) {
|
|
6673
|
-
return validateAgySlotRegistry(fixture).switchSlots;
|
|
6674
|
-
}
|
|
6675
|
-
function evaluateAgySwitchCompatibility(opts) {
|
|
6676
|
-
const validation = validateAgySlotRegistry(opts.fixture);
|
|
6677
|
-
const shapeMatches = validation.warnings.length === 0 && validation.switchSlots.length > 0;
|
|
6678
|
-
const warnings = [];
|
|
6679
|
-
if (opts.versionReadError) {
|
|
6680
|
-
warnings.push(`Could not read agy --version (${opts.versionReadError}); validating AGY fixture shape instead.`);
|
|
6681
|
-
}
|
|
6682
|
-
if (opts.version && KNOWN_INCOMPATIBLE_AGY_VERSIONS.has(opts.version)) {
|
|
6683
|
-
return {
|
|
6684
|
-
mode: "single-model",
|
|
6685
|
-
validatedSwitchSlotCount: validation.switchSlots.length,
|
|
6686
|
-
warnings: [
|
|
6687
|
-
...warnings,
|
|
6688
|
-
`Known-incompatible AGY version ${opts.version}; falling back to single-model mode.`
|
|
6689
|
-
]
|
|
6690
|
-
};
|
|
6691
|
-
}
|
|
6692
|
-
if (!shapeMatches) {
|
|
6693
|
-
return {
|
|
6694
|
-
mode: "single-model",
|
|
6695
|
-
validatedSwitchSlotCount: validation.switchSlots.length,
|
|
6696
|
-
warnings: [
|
|
6697
|
-
...warnings,
|
|
6698
|
-
...validation.warnings,
|
|
6699
|
-
"AGY fixture shape does not match the validated slot registry; falling back to single-model mode."
|
|
6700
|
-
]
|
|
6701
|
-
};
|
|
6702
|
-
}
|
|
6703
|
-
if (opts.version && !KNOWN_COMPATIBLE_AGY_VERSIONS.has(opts.version)) {
|
|
6704
|
-
warnings.push(`Unvalidated AGY version ${opts.version}; fixture shape matches, so multi-model switching remains enabled.`);
|
|
6705
|
-
} else if (!opts.version && !opts.versionReadError) {
|
|
6706
|
-
warnings.push("AGY version is unknown; fixture shape matches, so multi-model switching remains enabled.");
|
|
6707
|
-
}
|
|
6708
|
-
return {
|
|
6709
|
-
mode: "multi-model",
|
|
6710
|
-
validatedSwitchSlotCount: validation.switchSlots.length,
|
|
6711
|
-
warnings
|
|
6712
|
-
};
|
|
6713
|
-
}
|
|
6714
|
-
|
|
6715
|
-
// src/antigravity/catalog.ts
|
|
6716
|
-
var RELAY_CASCADE_PLAN_MODEL = "MODEL_PLACEHOLDER_M132";
|
|
6717
|
-
var RELAY_AGENT_PLACEHOLDER = "MODEL_PLACEHOLDER_M20";
|
|
6718
|
-
var RELAY_CASCADE_CHECKPOINT_MODEL = "MODEL_PLACEHOLDER_M50";
|
|
6719
|
-
var RELAY_CASCADE_INTENT_MODEL = "MODEL_GOOGLE_GEMINI_2_5_FLASH";
|
|
6720
|
-
var RELAY_CASCADE_ANCHOR_ID = "gemini-3.5-flash-low";
|
|
6721
|
-
var RELAY_CASCADE_PLAN_ANCHOR_ID = "gemini-3-flash-agent";
|
|
6722
|
-
var RELAY_CASCADE_FALLBACK_ID = "gemini-2.5-flash-lite";
|
|
6723
|
-
var RELAY_CASCADE_INTENT_MODEL_ID = "gemini-2.5-flash";
|
|
6724
|
-
function withCascadeCheckpointer(entry, maxTokenLimit = 128e3) {
|
|
6725
|
-
const tokenThreshold = Math.min(5e4, Math.floor(maxTokenLimit * 0.75));
|
|
6726
|
-
const existingModelExperiments = entry.modelExperiments;
|
|
6727
|
-
entry.modelExperiments = {
|
|
6728
|
-
...existingModelExperiments,
|
|
6729
|
-
experiments: {
|
|
6730
|
-
...existingModelExperiments?.experiments ?? {},
|
|
6731
|
-
CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
|
|
6732
|
-
stringValue: JSON.stringify({
|
|
6733
|
-
strategy: "CHECKPOINT_STRATEGY_SAME_MODEL",
|
|
6734
|
-
max_token_limit: String(maxTokenLimit),
|
|
6735
|
-
token_threshold: String(tokenThreshold),
|
|
6736
|
-
max_overhead_ratio: "0.15",
|
|
6737
|
-
moving_window_size: "1",
|
|
6738
|
-
enabled: true,
|
|
6739
|
-
max_output_tokens: "16384",
|
|
6740
|
-
checkpoint_model: RELAY_CASCADE_CHECKPOINT_MODEL,
|
|
6741
|
-
use_last_planner_model: true,
|
|
6742
|
-
is_sync: true,
|
|
6743
|
-
max_user_requests: 10,
|
|
6744
|
-
include_last_user_message: true,
|
|
6745
|
-
include_conversation_log: false,
|
|
6746
|
-
include_running_task_snapshots: true,
|
|
6747
|
-
include_subagent_snapshots: true,
|
|
6748
|
-
include_artifact_snapshots: true,
|
|
6749
|
-
retry_config: {
|
|
6750
|
-
max_retries: 0,
|
|
6751
|
-
initial_sleep_duration_ms: 1e3,
|
|
6752
|
-
exponential_multiplier: 2,
|
|
6753
|
-
include_error_feedback: false
|
|
6754
|
-
}
|
|
6755
|
-
})
|
|
6756
|
-
}
|
|
6757
|
-
}
|
|
6758
|
-
};
|
|
6759
|
-
return entry;
|
|
6760
|
-
}
|
|
6761
|
-
function applyRouteContextBounds(entry, route) {
|
|
6762
|
-
const maxTokenLimit = route.contextWindow ?? 128e3;
|
|
6763
|
-
const maxOutputTokens = Math.min(entry.maxOutputTokens ?? 65536, maxTokenLimit);
|
|
6764
|
-
const checkpointTokenLimit = Math.min(
|
|
6765
|
-
128e3,
|
|
6766
|
-
Math.max(1, maxTokenLimit - maxOutputTokens)
|
|
6767
|
-
);
|
|
6768
|
-
entry.maxTokens = maxTokenLimit;
|
|
6769
|
-
entry.maxOutputTokens = maxOutputTokens;
|
|
6770
|
-
return withCascadeCheckpointer(entry, checkpointTokenLimit);
|
|
6771
|
-
}
|
|
6772
|
-
var RELAY_CASCADE_FALLBACK_ENTRY = withCascadeCheckpointer({
|
|
6773
|
-
displayName: "Gemini 3.1 Flash Lite",
|
|
6774
|
-
model: "MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE",
|
|
6775
|
-
apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
|
|
6776
|
-
modelProvider: "MODEL_PROVIDER_GOOGLE",
|
|
6777
|
-
tokenizerType: "LLAMA_WITH_SPECIAL",
|
|
6778
|
-
maxTokens: 1048576,
|
|
6779
|
-
maxOutputTokens: 65535,
|
|
6780
|
-
quotaInfo: { remainingFraction: 1 }
|
|
6781
|
-
});
|
|
6782
|
-
var RELAY_CASCADE_INTENT_MODEL_ENTRY = withCascadeCheckpointer({
|
|
6783
|
-
...RELAY_CASCADE_FALLBACK_ENTRY,
|
|
6784
|
-
model: RELAY_CASCADE_INTENT_MODEL
|
|
6785
|
-
});
|
|
6786
|
-
function planRelayCatalogSlots(catalog, routes, templateKey) {
|
|
6787
|
-
const validation = validateAgySlotRegistry(catalog);
|
|
6788
|
-
const switchSlots = getValidatedAgySwitchSlots(catalog);
|
|
6789
|
-
const templateSlot = switchSlots.find((slot) => slot.slotId === templateKey);
|
|
6790
|
-
const orderedSlots = templateSlot ? [templateSlot, ...switchSlots.filter((slot) => slot.slotId !== templateKey)] : switchSlots;
|
|
6791
|
-
if (routes.length > 0 && orderedSlots.length === 0) {
|
|
6792
|
-
throw new Error("No validated AGY switch slots are available for the selected launch route");
|
|
6793
|
-
}
|
|
6794
|
-
const switchableRoutes = routes.slice(0, orderedSlots.length);
|
|
6795
|
-
const skippedRoutes = routes.slice(orderedSlots.length);
|
|
6796
|
-
const slots = switchableRoutes.map((route, index) => ({
|
|
6797
|
-
slotId: orderedSlots[index].slotId,
|
|
6798
|
-
route
|
|
6799
|
-
}));
|
|
6800
|
-
return {
|
|
6801
|
-
slots,
|
|
6802
|
-
switchableRoutes,
|
|
6803
|
-
skippedRoutes,
|
|
6804
|
-
validation
|
|
6805
|
-
};
|
|
6806
|
-
}
|
|
6807
|
-
function resolveRelayCatalogSlots(catalog, routes, templateKey) {
|
|
6808
|
-
return planRelayCatalogSlots(catalog, routes, templateKey).slots;
|
|
6809
|
-
}
|
|
6810
|
-
function buildRelayCatalogEntry(route, template) {
|
|
6811
|
-
const entry = structuredClone(template);
|
|
6812
|
-
entry.displayName = route.displayName;
|
|
6813
|
-
entry.model = template.model ?? RELAY_AGENT_PLACEHOLDER;
|
|
6814
|
-
entry.requestedModelId = route.catalogId;
|
|
6815
|
-
entry.modelVersion = route.catalogId;
|
|
6816
|
-
entry.modelVersionId = route.catalogId;
|
|
6817
|
-
entry.quotaInfo = { remainingFraction: 1, resetTime: "2026-06-23T02:00:57Z" };
|
|
6818
|
-
return applyRouteContextBounds(entry, route);
|
|
6819
|
-
}
|
|
6820
|
-
function buildRelayCatalogSlotEntry(route, template) {
|
|
6821
|
-
const entry = structuredClone(template);
|
|
6822
|
-
entry.displayName = route.displayName;
|
|
6823
|
-
entry.quotaInfo = { remainingFraction: 1, resetTime: "2026-06-23T02:00:57Z" };
|
|
6824
|
-
delete entry.requestedModelId;
|
|
6825
|
-
delete entry.modelVersion;
|
|
6826
|
-
delete entry.modelVersionId;
|
|
6827
|
-
delete entry.isInternal;
|
|
6828
|
-
return applyRouteContextBounds(entry, route);
|
|
6829
|
-
}
|
|
6830
|
-
function injectRelayModels(fixture, routes, templateKey) {
|
|
6831
|
-
const result = structuredClone(fixture);
|
|
6832
|
-
const template = fixture.models[templateKey];
|
|
6833
|
-
if (!template) {
|
|
6834
|
-
throw new Error(`Template model "${templateKey}" not found in catalog fixture`);
|
|
6835
|
-
}
|
|
6836
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6837
|
-
for (const route of routes) {
|
|
6838
|
-
if (seen.has(route.catalogId)) {
|
|
6839
|
-
throw new Error(`Catalog ID collision: ${route.catalogId}`);
|
|
6840
|
-
}
|
|
6841
|
-
if (fixture.models[route.catalogId]) {
|
|
6842
|
-
throw new Error(`Catalog ID collision with native model: ${route.catalogId}`);
|
|
6843
|
-
}
|
|
6844
|
-
seen.add(route.catalogId);
|
|
6845
|
-
}
|
|
6846
|
-
if (routes.length > 0) {
|
|
6847
|
-
result.models[RELAY_CASCADE_ANCHOR_ID] ??= structuredClone(template);
|
|
6848
|
-
result.models[RELAY_CASCADE_FALLBACK_ID] ??= structuredClone(RELAY_CASCADE_FALLBACK_ENTRY);
|
|
6849
|
-
result.models[RELAY_CASCADE_INTENT_MODEL_ID] ??= structuredClone(RELAY_CASCADE_INTENT_MODEL_ENTRY);
|
|
6850
|
-
if (!result.models[RELAY_CASCADE_PLAN_ANCHOR_ID]) {
|
|
6851
|
-
const planAnchor = withCascadeCheckpointer(structuredClone(template));
|
|
6852
|
-
planAnchor.model = RELAY_CASCADE_PLAN_MODEL;
|
|
6853
|
-
result.models[RELAY_CASCADE_PLAN_ANCHOR_ID] = planAnchor;
|
|
6854
|
-
}
|
|
6855
|
-
const slotPlan = planRelayCatalogSlots(result, routes, templateKey);
|
|
6856
|
-
const slots = slotPlan.slots;
|
|
6857
|
-
for (const { slotId, route } of slots) {
|
|
6858
|
-
const slotTemplate = result.models[slotId] ?? template;
|
|
6859
|
-
if (result.models[slotId]) {
|
|
6860
|
-
result.models[slotId] = buildRelayCatalogSlotEntry(route, slotTemplate);
|
|
6861
|
-
}
|
|
6862
|
-
result.models[route.catalogId] = buildRelayCatalogEntry(route, slotTemplate);
|
|
6863
|
-
}
|
|
6864
|
-
result.defaultAgentModelId = slots[0]?.slotId ?? RELAY_CASCADE_ANCHOR_ID;
|
|
6865
|
-
result.agentModelSorts = [
|
|
6866
|
-
{
|
|
6867
|
-
displayName: "Recommended",
|
|
6868
|
-
groups: [{
|
|
6869
|
-
modelIds: slots.map((slot) => slot.slotId)
|
|
6870
|
-
}]
|
|
6871
|
-
}
|
|
6872
|
-
];
|
|
6873
|
-
return result;
|
|
6874
|
-
}
|
|
6875
|
-
if (!result.agentModelSorts?.[0]?.groups?.[0]) {
|
|
6876
|
-
result.agentModelSorts = [
|
|
6877
|
-
{
|
|
6878
|
-
displayName: "Recommended",
|
|
6879
|
-
groups: [{ modelIds: [] }]
|
|
6880
|
-
}
|
|
6881
|
-
];
|
|
6882
|
-
}
|
|
6883
|
-
return result;
|
|
6884
|
-
}
|
|
6885
|
-
function buildAntigravityRoutes(resolvedFavorites, maxRoutes = MAX_MODEL_CATALOG) {
|
|
6886
|
-
const routes = [];
|
|
6887
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6888
|
-
for (const fav of resolvedFavorites) {
|
|
6889
|
-
if (routes.length >= maxRoutes) break;
|
|
6890
|
-
const favModel = fav.model;
|
|
6891
|
-
const modelId = favModel.id;
|
|
6892
|
-
const catalogId = `relay-ai__${fav.providerId}__${modelId}`;
|
|
6893
|
-
if (seen.has(catalogId)) continue;
|
|
6894
|
-
seen.add(catalogId);
|
|
6895
|
-
const npm = favModel.npm || "@ai-sdk/openai-compatible";
|
|
6896
|
-
const upstreamModelId = favModel.upstreamModelId || modelId;
|
|
6897
|
-
const baseURL = favModel.apiBaseUrl || favModel.completionsUrl || void 0;
|
|
6898
|
-
const contextWindow = favModel.contextWindow;
|
|
6899
|
-
const modelFormat = favModel.modelFormat;
|
|
6900
|
-
routes.push({
|
|
6901
|
-
catalogId,
|
|
6902
|
-
providerId: fav.providerId,
|
|
6903
|
-
providerName: fav.providerName,
|
|
6904
|
-
modelId,
|
|
6905
|
-
upstreamModelId,
|
|
6906
|
-
displayName: `${favModel.name} (Relay)`,
|
|
6907
|
-
...modelFormat ? { modelFormat } : {},
|
|
6908
|
-
npm,
|
|
6909
|
-
apiKey: fav.apiKey,
|
|
6910
|
-
...fav.authType ? { authType: fav.authType } : {},
|
|
6911
|
-
...fav.oauthAccountId ? { oauthAccountId: fav.oauthAccountId } : {},
|
|
6912
|
-
...fav.providerData ? { providerData: fav.providerData } : {},
|
|
6913
|
-
baseURL,
|
|
6914
|
-
contextWindow
|
|
6915
|
-
});
|
|
6916
|
-
}
|
|
6917
|
-
return applyUniqueAntigravityRouteLabels(routes);
|
|
6918
|
-
}
|
|
6919
|
-
function routeBaseModelName(route) {
|
|
6920
|
-
const relayMatch = route.displayName.match(/^(.*) \(Relay(?: - .*)?\)$/);
|
|
6921
|
-
return relayMatch?.[1] ?? route.displayName;
|
|
6922
|
-
}
|
|
6923
|
-
function authKindLabel(route) {
|
|
6924
|
-
if (route.authType === "oauth") return "OAuth";
|
|
6925
|
-
if (route.authType === "api") return "API key";
|
|
6926
|
-
if (route.authType === "none") return "local";
|
|
6927
|
-
return "provider";
|
|
6928
|
-
}
|
|
6929
|
-
function duplicateCounts(values) {
|
|
6930
|
-
const counts = /* @__PURE__ */ new Map();
|
|
6931
|
-
for (const value of values) {
|
|
6932
|
-
counts.set(value, (counts.get(value) ?? 0) + 1);
|
|
6933
|
-
}
|
|
6934
|
-
return counts;
|
|
6935
|
-
}
|
|
6936
|
-
function assertUniqueRouteDisplayNames(routes) {
|
|
6937
|
-
const counts = duplicateCounts(routes.map((route) => route.displayName));
|
|
6938
|
-
const duplicate = [...counts.entries()].find(([, count]) => count > 1);
|
|
6939
|
-
if (duplicate) {
|
|
6940
|
-
throw new Error(`Duplicate AGY model label after disambiguation: ${duplicate[0]}`);
|
|
6941
|
-
}
|
|
6942
|
-
}
|
|
6943
|
-
function applyUniqueAntigravityRouteLabels(routes) {
|
|
6944
|
-
const baseNames = routes.map(routeBaseModelName);
|
|
6945
|
-
const baseNameCounts = duplicateCounts(baseNames);
|
|
6946
|
-
const upstreamCounts = duplicateCounts(routes.map((route) => route.upstreamModelId));
|
|
6947
|
-
const providerNameCounts = duplicateCounts(routes.map((route) => route.providerName));
|
|
6948
|
-
const labeled = routes.map((route, index) => {
|
|
6949
|
-
const baseName = baseNames[index];
|
|
6950
|
-
const needsSuffix = (baseNameCounts.get(baseName) ?? 0) > 1 || (upstreamCounts.get(route.upstreamModelId) ?? 0) > 1;
|
|
6951
|
-
if (!needsSuffix) {
|
|
6952
|
-
return { ...route, displayName: `${baseName} (Relay)` };
|
|
6953
|
-
}
|
|
6954
|
-
const providerName = route.providerName || route.providerId;
|
|
6955
|
-
const providerSuffix = (providerNameCounts.get(providerName) ?? 0) > 1 ? `${providerName} ${authKindLabel(route)}` : providerName;
|
|
6956
|
-
return {
|
|
6957
|
-
...route,
|
|
6958
|
-
displayName: `${baseName} (Relay - ${providerSuffix})`
|
|
6959
|
-
};
|
|
6960
|
-
});
|
|
6961
|
-
const firstPassCounts = duplicateCounts(labeled.map((route) => route.displayName));
|
|
6962
|
-
const withProviderIds = labeled.map((route) => {
|
|
6963
|
-
if ((firstPassCounts.get(route.displayName) ?? 0) <= 1) return route;
|
|
6964
|
-
return {
|
|
6965
|
-
...route,
|
|
6966
|
-
displayName: route.displayName.replace(/\)$/, ` - ${route.providerId})`)
|
|
6967
|
-
};
|
|
6968
|
-
});
|
|
6969
|
-
assertUniqueRouteDisplayNames(withProviderIds);
|
|
6970
|
-
return withProviderIds;
|
|
6971
|
-
}
|
|
6972
|
-
function routeLabels(routes) {
|
|
6973
|
-
assertUniqueRouteDisplayNames(routes);
|
|
6974
|
-
const labels = /* @__PURE__ */ new Map();
|
|
6975
|
-
for (const route of routes) {
|
|
6976
|
-
labels.set(route.catalogId, route.displayName);
|
|
6977
|
-
}
|
|
6978
|
-
return labels;
|
|
6979
|
-
}
|
|
6980
|
-
function buildClientModelConfigData(routes, catalog, templateKey = RELAY_CASCADE_ANCHOR_ID, precomputedSlots) {
|
|
6981
|
-
const catalogRoutes = routes.slice(0, MAX_MODEL_CATALOG);
|
|
6982
|
-
const slots = precomputedSlots ?? (catalog ? resolveRelayCatalogSlots(catalog, catalogRoutes, templateKey) : catalogRoutes.map((route) => ({ slotId: route.catalogId, route })));
|
|
6983
|
-
const labels = routeLabels(catalogRoutes);
|
|
6984
|
-
const clientModelConfigs = slots.map(({ slotId, route }) => {
|
|
6985
|
-
const entry = catalog?.models[slotId] ?? catalog?.models[route.catalogId] ?? catalog?.models[RELAY_CASCADE_ANCHOR_ID];
|
|
6986
|
-
const label = labels.get(route.catalogId) ?? route.displayName;
|
|
6987
|
-
return {
|
|
6988
|
-
label,
|
|
6989
|
-
modelOrAlias: {
|
|
6990
|
-
alias: slotId,
|
|
6991
|
-
choice: { case: "alias", value: slotId }
|
|
6992
|
-
},
|
|
6993
|
-
disabled: false,
|
|
6994
|
-
supportedMimeTypes: entry?.supportedMimeTypes ?? {},
|
|
6995
|
-
quotaInfo: entry?.quotaInfo ?? { remainingFraction: 1 },
|
|
6996
|
-
tagTitle: entry?.tagTitle,
|
|
6997
|
-
tagDescription: entry?.tagDescription,
|
|
6998
|
-
supportsThoughtCirculation: entry?.supportsThoughtCirculation ?? false
|
|
6999
|
-
};
|
|
7000
|
-
});
|
|
7001
|
-
return {
|
|
7002
|
-
clientModelConfigs,
|
|
7003
|
-
clientModelSorts: [
|
|
7004
|
-
{
|
|
7005
|
-
name: "Recommended",
|
|
7006
|
-
groups: [
|
|
7007
|
-
{
|
|
7008
|
-
groupName: "",
|
|
7009
|
-
modelLabels: clientModelConfigs.map((config) => config.label)
|
|
7010
|
-
}
|
|
7011
|
-
]
|
|
7012
|
-
}
|
|
7013
|
-
],
|
|
7014
|
-
defaultOverrideModelConfig: clientModelConfigs[0] ?? {}
|
|
7015
|
-
};
|
|
7016
|
-
}
|
|
7017
|
-
function buildListModelConfigsResponse(routes, catalog, templateKey = RELAY_CASCADE_ANCHOR_ID) {
|
|
7018
|
-
const catalogRoutes = routes.slice(0, MAX_MODEL_CATALOG);
|
|
7019
|
-
const slots = catalog ? resolveRelayCatalogSlots(catalog, catalogRoutes, templateKey) : catalogRoutes.map((route) => ({ slotId: route.catalogId, route }));
|
|
7020
|
-
const config = slots.map(({ slotId }) => ({
|
|
7021
|
-
requestedModelId: slotId,
|
|
7022
|
-
planModel: RELAY_CASCADE_PLAN_MODEL,
|
|
7023
|
-
requestedModel: catalog?.models[slotId]?.model ?? RELAY_AGENT_PLACEHOLDER
|
|
7024
|
-
}));
|
|
7025
|
-
return {
|
|
7026
|
-
...buildClientModelConfigData(routes, catalog, templateKey, slots),
|
|
7027
|
-
allowedModelConfigs: config,
|
|
7028
|
-
defaultAgentModelConfig: config[0] ?? {}
|
|
7029
|
-
};
|
|
7030
|
-
}
|
|
7031
|
-
var CURRENT_EXPERIMENT_IDS = [
|
|
7032
|
-
105979552,
|
|
7033
|
-
105979574,
|
|
7034
|
-
106015351,
|
|
7035
|
-
105979579,
|
|
7036
|
-
105867471,
|
|
7037
|
-
105979530,
|
|
7038
|
-
105995634,
|
|
7039
|
-
106121401,
|
|
7040
|
-
106100625,
|
|
7041
|
-
104638466,
|
|
7042
|
-
101868197,
|
|
7043
|
-
104817729,
|
|
7044
|
-
105695344,
|
|
7045
|
-
106064591,
|
|
7046
|
-
104913215,
|
|
7047
|
-
106324349,
|
|
7048
|
-
106309078,
|
|
7049
|
-
105821930,
|
|
7050
|
-
104922093,
|
|
7051
|
-
103012598,
|
|
7052
|
-
106143956,
|
|
7053
|
-
105856899,
|
|
7054
|
-
106312323,
|
|
7055
|
-
106064030,
|
|
7056
|
-
105746183,
|
|
7057
|
-
105757908,
|
|
7058
|
-
104892493,
|
|
7059
|
-
105822886,
|
|
7060
|
-
105785683,
|
|
7061
|
-
105721273,
|
|
7062
|
-
105897325,
|
|
7063
|
-
105658071,
|
|
7064
|
-
106240758,
|
|
7065
|
-
105943702,
|
|
7066
|
-
106106760,
|
|
7067
|
-
106283618,
|
|
7068
|
-
105620019,
|
|
7069
|
-
106038160,
|
|
7070
|
-
106309520,
|
|
7071
|
-
106281951,
|
|
7072
|
-
106264532,
|
|
7073
|
-
106222835,
|
|
7074
|
-
106094629,
|
|
7075
|
-
105887313,
|
|
7076
|
-
105849474,
|
|
7077
|
-
106032303,
|
|
7078
|
-
106228452,
|
|
7079
|
-
106113900,
|
|
7080
|
-
106121607,
|
|
7081
|
-
105979531,
|
|
7082
|
-
105979553,
|
|
7083
|
-
106015328,
|
|
7084
|
-
105867469,
|
|
7085
|
-
105979517,
|
|
7086
|
-
106121399,
|
|
7087
|
-
106100654,
|
|
7088
|
-
104638459,
|
|
7089
|
-
101551624,
|
|
7090
|
-
104673683,
|
|
7091
|
-
105695346,
|
|
7092
|
-
106064590,
|
|
7093
|
-
104913210,
|
|
7094
|
-
105821928,
|
|
7095
|
-
104922082,
|
|
7096
|
-
103012592,
|
|
7097
|
-
106064028,
|
|
7098
|
-
105746181,
|
|
7099
|
-
104892490,
|
|
7100
|
-
105822881,
|
|
7101
|
-
105721268,
|
|
7102
|
-
105895316,
|
|
7103
|
-
105658068,
|
|
7104
|
-
106240748,
|
|
7105
|
-
105943694,
|
|
7106
|
-
106283614,
|
|
7107
|
-
105620012,
|
|
7108
|
-
106038153,
|
|
7109
|
-
105887311,
|
|
7110
|
-
106032301,
|
|
7111
|
-
106113877,
|
|
7112
|
-
106121604
|
|
7113
|
-
];
|
|
7114
|
-
function buildListExperimentsResponse() {
|
|
7115
|
-
return {
|
|
7116
|
-
experimentIds: [...CURRENT_EXPERIMENT_IDS]
|
|
7117
|
-
};
|
|
7118
|
-
}
|
|
7119
|
-
|
|
7120
6487
|
// src/antigravity/fixtures/loadCodeAssist.json
|
|
7121
6488
|
var loadCodeAssist_default = {
|
|
7122
6489
|
currentTier: {
|
|
@@ -8551,6 +7918,22 @@ function respondJson(res, status, data) {
|
|
|
8551
7918
|
});
|
|
8552
7919
|
res.end(body);
|
|
8553
7920
|
}
|
|
7921
|
+
function parsePseudoToolCall(text4, knownToolNames) {
|
|
7922
|
+
const trimmed = text4.trim();
|
|
7923
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return null;
|
|
7924
|
+
try {
|
|
7925
|
+
const obj = JSON.parse(trimmed);
|
|
7926
|
+
if (obj && typeof obj === "object") {
|
|
7927
|
+
const name = obj.name || obj.type === "function" && typeof obj.function === "object" && obj.function?.name || obj.function_name;
|
|
7928
|
+
if (typeof name === "string" && knownToolNames.has(name)) {
|
|
7929
|
+
const args = obj.parameters || obj.arguments || obj.args || typeof obj.function === "object" && obj.function?.parameters || {};
|
|
7930
|
+
return { name, args: typeof args === "object" && args ? args : {} };
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
} catch {
|
|
7934
|
+
}
|
|
7935
|
+
return null;
|
|
7936
|
+
}
|
|
8554
7937
|
async function handleStreamingRequest(res, route, providerOptions, parsed, log14, options = {}) {
|
|
8555
7938
|
const sdkParams = applyClaudeCodeOAuthIdentity(route, translateRequest(parsed, {
|
|
8556
7939
|
...options.requestOptions,
|
|
@@ -8589,8 +7972,39 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
|
|
|
8589
7972
|
};
|
|
8590
7973
|
const thinkFilter = createThinkFilter();
|
|
8591
7974
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
7975
|
+
const knownToolNames = new Set(Object.keys(sdkParams.tools ?? {}));
|
|
8592
7976
|
let responseReasoning = "";
|
|
8593
7977
|
let sawToolCall = false;
|
|
7978
|
+
let textBuffer = "";
|
|
7979
|
+
let bufferingJsonText = false;
|
|
7980
|
+
const flushBufferedText = () => {
|
|
7981
|
+
if (!textBuffer) return;
|
|
7982
|
+
startSse();
|
|
7983
|
+
const chunk = formatCloudCodeChunk({
|
|
7984
|
+
text: textBuffer,
|
|
7985
|
+
modelVersion: route.catalogId,
|
|
7986
|
+
responseId
|
|
7987
|
+
});
|
|
7988
|
+
res.write(`data: ${JSON.stringify(chunk)}
|
|
7989
|
+
|
|
7990
|
+
`);
|
|
7991
|
+
textBuffer = "";
|
|
7992
|
+
bufferingJsonText = false;
|
|
7993
|
+
};
|
|
7994
|
+
const emitPseudoToolCall = (pseudoTool) => {
|
|
7995
|
+
sawToolCall = true;
|
|
7996
|
+
startSse();
|
|
7997
|
+
const chunk = formatCloudCodeChunk({
|
|
7998
|
+
functionCall: { name: pseudoTool.name, args: normalizeFunctionCallArgs(pseudoTool.args) },
|
|
7999
|
+
modelVersion: route.catalogId,
|
|
8000
|
+
responseId
|
|
8001
|
+
});
|
|
8002
|
+
res.write(`data: ${JSON.stringify(chunk)}
|
|
8003
|
+
|
|
8004
|
+
`);
|
|
8005
|
+
textBuffer = "";
|
|
8006
|
+
bufferingJsonText = false;
|
|
8007
|
+
};
|
|
8594
8008
|
for await (const part of fullStream) {
|
|
8595
8009
|
const p15 = part;
|
|
8596
8010
|
if (p15.type === "reasoning-delta" || p15.type === "reasoning") {
|
|
@@ -8607,15 +8021,27 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
|
|
|
8607
8021
|
}
|
|
8608
8022
|
if (text4) {
|
|
8609
8023
|
log14(`[gateway] text-delta: ${JSON.stringify(text4.slice(0, 500))}`);
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8024
|
+
if (!bufferingJsonText && (textBuffer + text4).trimStart().startsWith("{")) {
|
|
8025
|
+
bufferingJsonText = true;
|
|
8026
|
+
}
|
|
8027
|
+
if (bufferingJsonText) {
|
|
8028
|
+
textBuffer += text4;
|
|
8029
|
+
const pseudoTool = textBuffer.trimEnd().endsWith("}") ? parsePseudoToolCall(textBuffer, knownToolNames) : null;
|
|
8030
|
+
if (pseudoTool) {
|
|
8031
|
+
log14(`[gateway] parsed pseudo tool-call from text: ${pseudoTool.name}`);
|
|
8032
|
+
emitPseudoToolCall(pseudoTool);
|
|
8033
|
+
}
|
|
8034
|
+
} else {
|
|
8035
|
+
startSse();
|
|
8036
|
+
const chunk = formatCloudCodeChunk({
|
|
8037
|
+
text: text4,
|
|
8038
|
+
modelVersion: route.catalogId,
|
|
8039
|
+
responseId
|
|
8040
|
+
});
|
|
8041
|
+
res.write(`data: ${JSON.stringify(chunk)}
|
|
8617
8042
|
|
|
8618
8043
|
`);
|
|
8044
|
+
}
|
|
8619
8045
|
}
|
|
8620
8046
|
} else if (p15.type === "tool-input-start") {
|
|
8621
8047
|
const id = p15.id ?? p15.toolCallId;
|
|
@@ -8647,6 +8073,15 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
|
|
|
8647
8073
|
`);
|
|
8648
8074
|
} else if (p15.type === "finish") {
|
|
8649
8075
|
log14(`[gateway] finish: ${p15.finishReason ?? "unknown"}`);
|
|
8076
|
+
if (textBuffer) {
|
|
8077
|
+
const pseudoTool = parsePseudoToolCall(textBuffer, knownToolNames);
|
|
8078
|
+
if (pseudoTool) {
|
|
8079
|
+
log14(`[gateway] parsed pseudo tool-call on finish: ${pseudoTool.name}`);
|
|
8080
|
+
emitPseudoToolCall(pseudoTool);
|
|
8081
|
+
} else {
|
|
8082
|
+
flushBufferedText();
|
|
8083
|
+
}
|
|
8084
|
+
}
|
|
8650
8085
|
startSse();
|
|
8651
8086
|
const reason = mapFinishReason2(p15.finishReason ?? "");
|
|
8652
8087
|
const chunk = formatCloudCodeChunk({
|
|
@@ -8664,6 +8099,7 @@ async function handleStreamingRequest(res, route, providerOptions, parsed, log14
|
|
|
8664
8099
|
} else if (p15.type === "error") {
|
|
8665
8100
|
const message = formatUpstreamError(p15.error);
|
|
8666
8101
|
log14(`[gateway] stream provider error: ${message}`);
|
|
8102
|
+
flushBufferedText();
|
|
8667
8103
|
emitStreamError(res, route, responseId, message, startSse);
|
|
8668
8104
|
break;
|
|
8669
8105
|
} else if (p15.type === "reasoning-start" || p15.type === "reasoning-end") {
|
|
@@ -8773,10 +8209,17 @@ async function resolveAntigravityLaunchRoutes(opts) {
|
|
|
8773
8209
|
maxRoutes,
|
|
8774
8210
|
{ dropEmptyApiKey: true, trackCapacitySkipped: true }
|
|
8775
8211
|
);
|
|
8212
|
+
const tooSmall = resolved.slice(1).filter(
|
|
8213
|
+
(entry) => !meetsContextFloor("antigravity", entry.model.contextWindow)
|
|
8214
|
+
);
|
|
8215
|
+
const launchable = resolved.filter((entry) => !tooSmall.includes(entry));
|
|
8776
8216
|
return {
|
|
8777
|
-
routes: buildAntigravityRoutes(
|
|
8217
|
+
routes: buildAntigravityRoutes(launchable, maxRoutes),
|
|
8778
8218
|
apiKey,
|
|
8779
|
-
droppedFavorites
|
|
8219
|
+
droppedFavorites: [
|
|
8220
|
+
...droppedFavorites,
|
|
8221
|
+
...tooSmall.map((entry) => ({ providerId: entry.providerId, modelId: entry.model.id }))
|
|
8222
|
+
],
|
|
8780
8223
|
capacitySkippedFavorites
|
|
8781
8224
|
};
|
|
8782
8225
|
}
|
|
@@ -8906,9 +8349,35 @@ function prepareIdeProfile(profileDir, gatewayUrl) {
|
|
|
8906
8349
|
}
|
|
8907
8350
|
|
|
8908
8351
|
// src/antigravity/launch-ide.ts
|
|
8352
|
+
var LINUX_APP_PROFILE_DIR = join7(homedir7(), ".relay-ai", "antigravity", "app-profile");
|
|
8353
|
+
var LINUX_IDE_PROFILE_DIR = join7(homedir7(), ".relay-ai", "antigravity", "profile");
|
|
8909
8354
|
function sleep(ms) {
|
|
8910
8355
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
8911
8356
|
}
|
|
8357
|
+
function linuxAntigravityBinary() {
|
|
8358
|
+
const candidates = [
|
|
8359
|
+
"/usr/share/antigravity/antigravity",
|
|
8360
|
+
"/opt/antigravity/antigravity",
|
|
8361
|
+
join7(homedir7(), ".local", "share", "antigravity", "antigravity")
|
|
8362
|
+
];
|
|
8363
|
+
for (const candidate of candidates) {
|
|
8364
|
+
if (existsSync7(candidate)) return candidate;
|
|
8365
|
+
}
|
|
8366
|
+
return null;
|
|
8367
|
+
}
|
|
8368
|
+
function linuxKillByProfile(profileDir, signal) {
|
|
8369
|
+
const output = defaultProcessList();
|
|
8370
|
+
for (const line of output.split("\n")) {
|
|
8371
|
+
if (!line.includes(`--user-data-dir=${profileDir}`)) continue;
|
|
8372
|
+
const pid = Number.parseInt(line.trim().split(/\s+/)[0] ?? "", 10);
|
|
8373
|
+
if (Number.isFinite(pid) && pid > 0) {
|
|
8374
|
+
try {
|
|
8375
|
+
process.kill(pid, signal);
|
|
8376
|
+
} catch {
|
|
8377
|
+
}
|
|
8378
|
+
}
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8912
8381
|
function runPowerShell(script) {
|
|
8913
8382
|
return execSync4(`powershell.exe -NoProfile -Command ${JSON.stringify(script)}`, {
|
|
8914
8383
|
encoding: "utf8",
|
|
@@ -8944,9 +8413,10 @@ function winForceQuitProcess(exeName, profileDir) {
|
|
|
8944
8413
|
}
|
|
8945
8414
|
}
|
|
8946
8415
|
function defaultProcessList() {
|
|
8947
|
-
|
|
8416
|
+
const psArgs = process.platform === "linux" ? ["-eo", "pid=,args="] : ["-axo", "pid=,command="];
|
|
8417
|
+
if (process.platform !== "darwin" && process.platform !== "linux") return "";
|
|
8948
8418
|
try {
|
|
8949
|
-
return execFileSync3("ps",
|
|
8419
|
+
return execFileSync3("ps", psArgs, {
|
|
8950
8420
|
encoding: "utf8",
|
|
8951
8421
|
stdio: ["ignore", "pipe", "ignore"],
|
|
8952
8422
|
maxBuffer: 1024 * 1024 * 4
|
|
@@ -8958,11 +8428,17 @@ function defaultProcessList() {
|
|
|
8958
8428
|
function isAntigravityIdeRunning(profileDir, processList = defaultProcessList) {
|
|
8959
8429
|
if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity IDE.exe", profileDir);
|
|
8960
8430
|
const output = processList();
|
|
8431
|
+
if (process.platform === "linux") {
|
|
8432
|
+
return output.split("\n").some((line) => line.includes(`--user-data-dir=${profileDir}`));
|
|
8433
|
+
}
|
|
8961
8434
|
return output.split("\n").some((line) => line.includes("Antigravity IDE.app") && line.includes(`--user-data-dir=${profileDir}`));
|
|
8962
8435
|
}
|
|
8963
8436
|
function isAntigravityAppRunning(profileDir, processList = defaultProcessList) {
|
|
8964
8437
|
if (process.platform === "win32") return winIsProcessRunningForProfile("Antigravity.exe", profileDir);
|
|
8965
8438
|
const output = processList();
|
|
8439
|
+
if (process.platform === "linux") {
|
|
8440
|
+
return output.split("\n").some((line) => line.includes(`--user-data-dir=${profileDir}`));
|
|
8441
|
+
}
|
|
8966
8442
|
return output.split("\n").some((line) => line.includes("Antigravity.app") && line.includes(`--user-data-dir=${profileDir}`));
|
|
8967
8443
|
}
|
|
8968
8444
|
async function waitForAntigravityIdeQuit(profileDir, options = {}) {
|
|
@@ -8987,15 +8463,21 @@ async function waitForAntigravityAppQuit(profileDir, options = {}) {
|
|
|
8987
8463
|
}
|
|
8988
8464
|
function forceQuitAntigravityIde(profileDir) {
|
|
8989
8465
|
if (process.platform === "win32") winForceQuitProcess("Antigravity IDE.exe", profileDir);
|
|
8466
|
+
else if (process.platform === "linux") linuxKillByProfile(profileDir, "SIGKILL");
|
|
8990
8467
|
}
|
|
8991
8468
|
function forceQuitAntigravityApp(profileDir) {
|
|
8992
8469
|
if (process.platform === "win32") winForceQuitProcess("Antigravity.exe", profileDir);
|
|
8470
|
+
else if (process.platform === "linux") linuxKillByProfile(profileDir, "SIGKILL");
|
|
8993
8471
|
}
|
|
8994
8472
|
function quitAntigravityIdeGracefully() {
|
|
8995
8473
|
if (process.platform === "win32") {
|
|
8996
8474
|
winQuitProcess("Antigravity IDE.exe");
|
|
8997
8475
|
return;
|
|
8998
8476
|
}
|
|
8477
|
+
if (process.platform === "linux") {
|
|
8478
|
+
linuxKillByProfile(LINUX_IDE_PROFILE_DIR, "SIGTERM");
|
|
8479
|
+
return;
|
|
8480
|
+
}
|
|
8999
8481
|
if (process.platform !== "darwin") return;
|
|
9000
8482
|
try {
|
|
9001
8483
|
execFileSync3("osascript", ["-e", 'tell application "Antigravity IDE" to quit'], {
|
|
@@ -9012,6 +8494,10 @@ function quitAntigravityAppGracefully() {
|
|
|
9012
8494
|
winQuitProcess("Antigravity.exe");
|
|
9013
8495
|
return;
|
|
9014
8496
|
}
|
|
8497
|
+
if (process.platform === "linux") {
|
|
8498
|
+
linuxKillByProfile(LINUX_APP_PROFILE_DIR, "SIGTERM");
|
|
8499
|
+
return;
|
|
8500
|
+
}
|
|
9015
8501
|
if (process.platform !== "darwin") return;
|
|
9016
8502
|
try {
|
|
9017
8503
|
execFileSync3("osascript", ["-e", 'tell application "Antigravity" to quit'], {
|
|
@@ -9031,6 +8517,7 @@ function findAntigravityAppBinary() {
|
|
|
9031
8517
|
const winPath = join7(localAppData, "Programs", "Antigravity", "Antigravity.exe");
|
|
9032
8518
|
return existsSync7(winPath) ? winPath : null;
|
|
9033
8519
|
}
|
|
8520
|
+
if (process.platform === "linux") return linuxAntigravityBinary();
|
|
9034
8521
|
if (process.platform !== "darwin") return null;
|
|
9035
8522
|
const defaultPath = "/Applications/Antigravity.app/Contents/MacOS/Antigravity";
|
|
9036
8523
|
if (existsSync7(defaultPath)) return defaultPath;
|
|
@@ -9046,6 +8533,7 @@ function findAntigravityIdeBinary() {
|
|
|
9046
8533
|
const winPath = join7(localAppData, "Programs", "Antigravity IDE", "Antigravity IDE.exe");
|
|
9047
8534
|
return existsSync7(winPath) ? winPath : null;
|
|
9048
8535
|
}
|
|
8536
|
+
if (process.platform === "linux") return linuxAntigravityBinary();
|
|
9049
8537
|
if (process.platform !== "darwin") return null;
|
|
9050
8538
|
const defaultPath = "/Applications/Antigravity IDE.app/Contents/Resources/app/bin/antigravity-ide";
|
|
9051
8539
|
if (existsSync7(defaultPath)) return defaultPath;
|
|
@@ -9063,8 +8551,8 @@ function launchAntigravityApp(env, profileDir, gatewayUrl, extraArgs) {
|
|
|
9063
8551
|
};
|
|
9064
8552
|
const binaryPath = findAntigravityAppBinary();
|
|
9065
8553
|
if (!binaryPath) {
|
|
9066
|
-
console.error(
|
|
9067
|
-
console.error("Please make sure Antigravity is installed
|
|
8554
|
+
console.error("Antigravity app not found.");
|
|
8555
|
+
console.error("Please make sure Antigravity is installed.");
|
|
9068
8556
|
settle(127);
|
|
9069
8557
|
return;
|
|
9070
8558
|
}
|
|
@@ -9074,7 +8562,12 @@ function launchAntigravityApp(env, profileDir, gatewayUrl, extraArgs) {
|
|
|
9074
8562
|
...extraArgs
|
|
9075
8563
|
];
|
|
9076
8564
|
const child = spawn5(binaryPath, args, {
|
|
9077
|
-
|
|
8565
|
+
// GUI app: don't inherit the terminal's stdio (its Electron logs would
|
|
8566
|
+
// corrupt relay's interactive prompts) and detach into its own process
|
|
8567
|
+
// group so a Ctrl+C meant for the relay gateway doesn't also kill the app
|
|
8568
|
+
// mid-render. Mirrors the Claude Desktop launcher.
|
|
8569
|
+
stdio: "ignore",
|
|
8570
|
+
detached: true,
|
|
9078
8571
|
env
|
|
9079
8572
|
});
|
|
9080
8573
|
child.on("spawn", () => {
|
|
@@ -9093,8 +8586,8 @@ function launchAntigravityIde(env, profileDir, gatewayUrl, extraArgs) {
|
|
|
9093
8586
|
return new Promise((resolve2) => {
|
|
9094
8587
|
const binaryPath = findAntigravityIdeBinary();
|
|
9095
8588
|
if (!binaryPath) {
|
|
9096
|
-
console.error(
|
|
9097
|
-
console.error("Please make sure Antigravity IDE is installed
|
|
8589
|
+
console.error("Antigravity IDE not found.");
|
|
8590
|
+
console.error("Please make sure Antigravity IDE is installed.");
|
|
9098
8591
|
resolve2(127);
|
|
9099
8592
|
return;
|
|
9100
8593
|
}
|
|
@@ -9106,7 +8599,12 @@ function launchAntigravityIde(env, profileDir, gatewayUrl, extraArgs) {
|
|
|
9106
8599
|
...extraArgs
|
|
9107
8600
|
];
|
|
9108
8601
|
const child = spawn5(binaryPath, args, {
|
|
9109
|
-
|
|
8602
|
+
// GUI app: don't inherit the terminal's stdio (its Electron logs would
|
|
8603
|
+
// corrupt relay's interactive prompts) and detach into its own process
|
|
8604
|
+
// group so a Ctrl+C meant for the relay gateway doesn't also kill the app
|
|
8605
|
+
// mid-render. Mirrors the Claude Desktop launcher.
|
|
8606
|
+
stdio: "ignore",
|
|
8607
|
+
detached: true,
|
|
9110
8608
|
env
|
|
9111
8609
|
});
|
|
9112
8610
|
child.on("exit", (code) => {
|
|
@@ -10530,6 +10028,9 @@ function getClaudeDesktopHome() {
|
|
|
10530
10028
|
if (process.platform === "win32") {
|
|
10531
10029
|
return join11(process.env.LOCALAPPDATA || join11(homedir9(), "AppData", "Local"), "Claude-3p");
|
|
10532
10030
|
}
|
|
10031
|
+
if (process.platform === "linux") {
|
|
10032
|
+
return join11(process.env.XDG_CONFIG_HOME || join11(homedir9(), ".config"), "Claude-3p");
|
|
10033
|
+
}
|
|
10533
10034
|
return join11(homedir9(), "Library", "Application Support", "Claude-3p");
|
|
10534
10035
|
}
|
|
10535
10036
|
function getConfigLibraryPath() {
|
|
@@ -10903,7 +10404,7 @@ ${pc11.bold("Description:")}
|
|
|
10903
10404
|
Keep this terminal open while using Claude.
|
|
10904
10405
|
|
|
10905
10406
|
${pc11.bold("Platforms:")}
|
|
10906
|
-
macOS and
|
|
10407
|
+
macOS, Windows, and Linux.
|
|
10907
10408
|
|
|
10908
10409
|
${pc11.bold("Cleanup:")}
|
|
10909
10410
|
Ctrl+C stops the proxy and restores your previous Claude config.
|
|
@@ -13763,7 +13264,7 @@ Options:
|
|
|
13763
13264
|
--trace Write debug logs under ~/.relay-ai/logs/`);
|
|
13764
13265
|
return 0;
|
|
13765
13266
|
}
|
|
13766
|
-
const { runUiCommand } = await import("./ui-command-
|
|
13267
|
+
const { runUiCommand } = await import("./ui-command-S3TQKB3D.js");
|
|
13767
13268
|
return runUiCommand({ trace: parsed.trace, serverMode: parsed.uiServerMode });
|
|
13768
13269
|
}
|
|
13769
13270
|
if (parsed.command === "models") {
|