@jacobbd/relay-ai 0.9.4 → 0.9.5
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/README.md +2 -0
- package/dist/{chunk-KDIY732Q.js → chunk-SCW2TYSG.js} +312 -338
- package/dist/chunk-SCW2TYSG.js.map +1 -0
- package/dist/cli.js +401 -64
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/{ui-command-OIY4243G.js → ui-command-Q6LBKVM3.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-KDIY732Q.js.map +0 -1
- /package/dist/{ui-command-OIY4243G.js.map → ui-command-Q6LBKVM3.js.map} +0 -0
|
@@ -11,7 +11,7 @@ import { join } from "path";
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
13
|
name: "@jacobbd/relay-ai",
|
|
14
|
-
version: "0.9.
|
|
14
|
+
version: "0.9.5",
|
|
15
15
|
publishConfig: {
|
|
16
16
|
access: "public"
|
|
17
17
|
},
|
|
@@ -1693,10 +1693,86 @@ function thinkingProviderOptions(npm) {
|
|
|
1693
1693
|
}
|
|
1694
1694
|
|
|
1695
1695
|
// src/codex/multi-agent.ts
|
|
1696
|
-
import { execFileSync } from "child_process";
|
|
1697
1696
|
import { mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
1698
1697
|
import { tmpdir } from "os";
|
|
1699
1698
|
import { join as join2 } from "path";
|
|
1699
|
+
|
|
1700
|
+
// src/codex/process.ts
|
|
1701
|
+
import spawn from "cross-spawn";
|
|
1702
|
+
function commandError(binaryPath, args, stdout, stderr, detail) {
|
|
1703
|
+
const error = new Error(`Command failed: ${binaryPath} ${args.join(" ")} (${detail})`);
|
|
1704
|
+
return Object.assign(error, { stdout, stderr });
|
|
1705
|
+
}
|
|
1706
|
+
function runCodexCommandSync(binaryPath, args, options = {}) {
|
|
1707
|
+
const result = spawn.sync(binaryPath, args, {
|
|
1708
|
+
encoding: "utf8",
|
|
1709
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1710
|
+
env: options.env,
|
|
1711
|
+
timeout: options.timeout,
|
|
1712
|
+
maxBuffer: options.maxBuffer
|
|
1713
|
+
});
|
|
1714
|
+
const stdout = result.stdout ?? "";
|
|
1715
|
+
const stderr = result.stderr ?? "";
|
|
1716
|
+
if (result.error) {
|
|
1717
|
+
throw Object.assign(result.error, { stdout, stderr });
|
|
1718
|
+
}
|
|
1719
|
+
if (result.status !== 0) {
|
|
1720
|
+
throw commandError(binaryPath, args, stdout, stderr, `exit ${result.status ?? result.signal ?? "unknown"}`);
|
|
1721
|
+
}
|
|
1722
|
+
return { stdout, stderr };
|
|
1723
|
+
}
|
|
1724
|
+
function runCodexCommand(binaryPath, args, options = {}) {
|
|
1725
|
+
return new Promise((resolve, reject) => {
|
|
1726
|
+
const child = spawn(binaryPath, args, {
|
|
1727
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1728
|
+
env: options.env
|
|
1729
|
+
});
|
|
1730
|
+
const stdoutChunks = [];
|
|
1731
|
+
const stderrChunks = [];
|
|
1732
|
+
let outputBytes = 0;
|
|
1733
|
+
let settled = false;
|
|
1734
|
+
const finishError = (error) => {
|
|
1735
|
+
if (settled) return;
|
|
1736
|
+
settled = true;
|
|
1737
|
+
reject(Object.assign(error, {
|
|
1738
|
+
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
1739
|
+
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
1740
|
+
}));
|
|
1741
|
+
};
|
|
1742
|
+
const collect = (target, chunk) => {
|
|
1743
|
+
target.push(chunk);
|
|
1744
|
+
outputBytes += chunk.length;
|
|
1745
|
+
if (options.maxBuffer !== void 0 && outputBytes > options.maxBuffer) {
|
|
1746
|
+
child.kill();
|
|
1747
|
+
finishError(commandError(binaryPath, args, "", "", `output exceeded ${options.maxBuffer} bytes`));
|
|
1748
|
+
}
|
|
1749
|
+
};
|
|
1750
|
+
child.stdout?.on("data", (chunk) => collect(stdoutChunks, chunk));
|
|
1751
|
+
child.stderr?.on("data", (chunk) => collect(stderrChunks, chunk));
|
|
1752
|
+
child.on("error", finishError);
|
|
1753
|
+
let timer;
|
|
1754
|
+
if (options.timeout !== void 0) {
|
|
1755
|
+
timer = setTimeout(() => {
|
|
1756
|
+
child.kill();
|
|
1757
|
+
finishError(commandError(binaryPath, args, "", "", `timed out after ${options.timeout}ms`));
|
|
1758
|
+
}, options.timeout);
|
|
1759
|
+
}
|
|
1760
|
+
child.on("close", (code, signal) => {
|
|
1761
|
+
if (timer) clearTimeout(timer);
|
|
1762
|
+
if (settled) return;
|
|
1763
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
1764
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
1765
|
+
if (code !== 0) {
|
|
1766
|
+
finishError(commandError(binaryPath, args, stdout, stderr, `exit ${code ?? signal ?? "unknown"}`));
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
settled = true;
|
|
1770
|
+
resolve({ stdout, stderr });
|
|
1771
|
+
});
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
// src/codex/multi-agent.ts
|
|
1700
1776
|
var CODEX_MULTI_AGENT_V2 = Object.freeze({
|
|
1701
1777
|
enabled: true,
|
|
1702
1778
|
max_concurrent_threads_per_session: 6,
|
|
@@ -1711,12 +1787,7 @@ function probeText(value) {
|
|
|
1711
1787
|
return `${result.stdout ?? ""}
|
|
1712
1788
|
${result.stderr ?? ""}`;
|
|
1713
1789
|
}
|
|
1714
|
-
function supportsMultiAgentV2(binaryPath, run3 = (path, args, env) =>
|
|
1715
|
-
encoding: "utf8",
|
|
1716
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1717
|
-
timeout: 1e4,
|
|
1718
|
-
env
|
|
1719
|
-
})) {
|
|
1790
|
+
function supportsMultiAgentV2(binaryPath, run3 = (path, args, env) => runCodexCommandSync(path, args, { timeout: 1e4, env })) {
|
|
1720
1791
|
const probeHome = mkdtempSync(join2(tmpdir(), "relay-codex-v2-probe-"));
|
|
1721
1792
|
try {
|
|
1722
1793
|
writeFileSync(join2(probeHome, "config.toml"), renderMultiAgentV2Feature(), { encoding: "utf8", mode: 384 });
|
|
@@ -2410,18 +2481,18 @@ function resolveServerAutostart(env = process.env) {
|
|
|
2410
2481
|
|
|
2411
2482
|
// src/launch.ts
|
|
2412
2483
|
import { execSync } from "child_process";
|
|
2413
|
-
import
|
|
2484
|
+
import spawn2 from "cross-spawn";
|
|
2414
2485
|
import { existsSync as existsSync3, appendFileSync } from "fs";
|
|
2415
2486
|
import { homedir as homedir3 } from "os";
|
|
2416
2487
|
import { join as join5 } from "path";
|
|
2417
2488
|
|
|
2418
2489
|
// src/binary-lookup.ts
|
|
2419
|
-
import { execFileSync
|
|
2490
|
+
import { execFileSync } from "child_process";
|
|
2420
2491
|
import { existsSync as existsSync2 } from "fs";
|
|
2421
2492
|
function findBinaryOnPath(name, fallbackPaths, options = {}) {
|
|
2422
2493
|
const isWindows2 = options.isWindows ?? process.platform === "win32";
|
|
2423
2494
|
const exists = options.exists ?? existsSync2;
|
|
2424
|
-
const runWhich = options.runWhich ?? ((binary, win) =>
|
|
2495
|
+
const runWhich = options.runWhich ?? ((binary, win) => execFileSync(win ? "where.exe" : "which", [binary], {
|
|
2425
2496
|
encoding: "utf8",
|
|
2426
2497
|
stdio: ["pipe", "pipe", "pipe"]
|
|
2427
2498
|
}));
|
|
@@ -2499,7 +2570,7 @@ function launchClaude(env, model, extraArgs) {
|
|
|
2499
2570
|
process.stdout.write = originalStdoutWrite;
|
|
2500
2571
|
process.stderr.write = originalStderrWrite;
|
|
2501
2572
|
};
|
|
2502
|
-
const child =
|
|
2573
|
+
const child = spawn2(claudePath, args, {
|
|
2503
2574
|
stdio: "inherit",
|
|
2504
2575
|
env
|
|
2505
2576
|
});
|
|
@@ -5141,9 +5212,9 @@ function claudeModelFamily(modelId) {
|
|
|
5141
5212
|
if (!normalized.startsWith("claude-")) return void 0;
|
|
5142
5213
|
return CLAUDE_MODEL_FAMILIES.find((family) => normalized.includes(family));
|
|
5143
5214
|
}
|
|
5144
|
-
function isClaudeAgentTool(
|
|
5145
|
-
if (
|
|
5146
|
-
const properties =
|
|
5215
|
+
function isClaudeAgentTool(tool3) {
|
|
5216
|
+
if (tool3.name !== "Agent" || !isRecord2(tool3.input_schema)) return false;
|
|
5217
|
+
const properties = tool3.input_schema.properties;
|
|
5147
5218
|
if (!isRecord2(properties)) return false;
|
|
5148
5219
|
return ["description", "prompt", "subagent_type"].every((name) => isRecord2(properties[name]));
|
|
5149
5220
|
}
|
|
@@ -5233,8 +5304,8 @@ function prepareClaudeAgentInput(input, routing) {
|
|
|
5233
5304
|
clientInput.prompt = appendSubagentRouteMarker(prompt, token);
|
|
5234
5305
|
return { input: clientInput, decision };
|
|
5235
5306
|
}
|
|
5236
|
-
function augmentClaudeAgentTool(
|
|
5237
|
-
const inputSchema = isRecord2(
|
|
5307
|
+
function augmentClaudeAgentTool(tool3, routing) {
|
|
5308
|
+
const inputSchema = isRecord2(tool3.input_schema) ? tool3.input_schema : {};
|
|
5238
5309
|
const properties = isRecord2(inputSchema.properties) ? inputSchema.properties : {};
|
|
5239
5310
|
const originalModel = isRecord2(properties.model) ? properties.model : {};
|
|
5240
5311
|
const smallCatalog = routing.models.length <= MAX_MODEL_CATALOG;
|
|
@@ -5250,8 +5321,8 @@ function augmentClaudeAgentTool(tool4, routing) {
|
|
|
5250
5321
|
}
|
|
5251
5322
|
const guidance = smallCatalog ? `Relay AI subagent model routing (default: ${routing.parentModelId}). ` + routing.models.map((model) => `${model.displayName}: ${model.id}`).join("; ") : `Relay AI subagent model routing (default: ${routing.parentModelId}). Other explicit model values must be exact ids from the current session catalog.`;
|
|
5252
5323
|
return {
|
|
5253
|
-
...
|
|
5254
|
-
description: [
|
|
5324
|
+
...tool3,
|
|
5325
|
+
description: [tool3.description?.trim(), guidance].filter(Boolean).join("\n\n"),
|
|
5255
5326
|
input_schema: {
|
|
5256
5327
|
...inputSchema,
|
|
5257
5328
|
properties: {
|
|
@@ -5583,11 +5654,7 @@ async function relayAnthropicMessages(res, messagesUrl, body, apiKey, clientWant
|
|
|
5583
5654
|
}
|
|
5584
5655
|
|
|
5585
5656
|
// src/antigravity/anthropic-to-cloudcode.ts
|
|
5586
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
5587
|
-
|
|
5588
|
-
// src/antigravity/request-adapter.ts
|
|
5589
5657
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5590
|
-
import { tool, jsonSchema } from "ai";
|
|
5591
5658
|
|
|
5592
5659
|
// src/proxy-shared.ts
|
|
5593
5660
|
function grabRoundTripSignature(part) {
|
|
@@ -5695,265 +5762,6 @@ function serializeToolResultContent(content) {
|
|
|
5695
5762
|
return JSON.stringify(content);
|
|
5696
5763
|
}
|
|
5697
5764
|
|
|
5698
|
-
// src/antigravity/request-adapter.ts
|
|
5699
|
-
var UNSUPPORTED_VOICE_MESSAGE = "Voice transcription isn\u2019t supported by Relay AI yet. Please type your message. Your coding session remains active.";
|
|
5700
|
-
var OMITTED_VOICE_TEXT = "[Voice recording omitted because transcription is not supported by Relay AI.]";
|
|
5701
|
-
function isSupportedImage(part) {
|
|
5702
|
-
return part.inlineData?.mimeType.toLowerCase().startsWith("image/") ?? false;
|
|
5703
|
-
}
|
|
5704
|
-
function isUnsupportedInlineData(part) {
|
|
5705
|
-
return !!part.inlineData && !isSupportedImage(part);
|
|
5706
|
-
}
|
|
5707
|
-
function sanitizeUnsupportedInlineData(ccReq) {
|
|
5708
|
-
const contents = ccReq.request?.contents ?? [];
|
|
5709
|
-
let latestUserIndex = -1;
|
|
5710
|
-
for (let i = contents.length - 1; i >= 0; i--) {
|
|
5711
|
-
if (contents[i].role === "user") {
|
|
5712
|
-
latestUserIndex = i;
|
|
5713
|
-
break;
|
|
5714
|
-
}
|
|
5715
|
-
}
|
|
5716
|
-
let latestUserTurnHasUnsupportedMedia = false;
|
|
5717
|
-
const sanitizedContents = contents.map((message, index) => ({
|
|
5718
|
-
...message,
|
|
5719
|
-
parts: message.parts.map((part) => {
|
|
5720
|
-
if (!isUnsupportedInlineData(part)) return part;
|
|
5721
|
-
if (index === latestUserIndex) latestUserTurnHasUnsupportedMedia = true;
|
|
5722
|
-
return { text: OMITTED_VOICE_TEXT };
|
|
5723
|
-
})
|
|
5724
|
-
}));
|
|
5725
|
-
return {
|
|
5726
|
-
request: {
|
|
5727
|
-
...ccReq,
|
|
5728
|
-
request: {
|
|
5729
|
-
...ccReq.request,
|
|
5730
|
-
contents: sanitizedContents
|
|
5731
|
-
}
|
|
5732
|
-
},
|
|
5733
|
-
latestUserTurnHasUnsupportedMedia
|
|
5734
|
-
};
|
|
5735
|
-
}
|
|
5736
|
-
function tracePartChars(part) {
|
|
5737
|
-
if (typeof part.text === "string") return part.text.length;
|
|
5738
|
-
if (part.type !== "tool-result") return void 0;
|
|
5739
|
-
const output = part.output;
|
|
5740
|
-
if (typeof output === "string") return output.length;
|
|
5741
|
-
if (output && typeof output === "object" && typeof output.value === "string") {
|
|
5742
|
-
return output.value.length;
|
|
5743
|
-
}
|
|
5744
|
-
try {
|
|
5745
|
-
return output === void 0 ? void 0 : JSON.stringify(output).length;
|
|
5746
|
-
} catch {
|
|
5747
|
-
return void 0;
|
|
5748
|
-
}
|
|
5749
|
-
}
|
|
5750
|
-
function summarizeSdkRequestForTrace(request) {
|
|
5751
|
-
const messages = request.messages.map((message) => {
|
|
5752
|
-
const content = message.content;
|
|
5753
|
-
if (typeof content === "string") {
|
|
5754
|
-
return { role: message.role, parts: [{ type: "text", chars: content.length }] };
|
|
5755
|
-
}
|
|
5756
|
-
const parts = Array.isArray(content) ? content.map((rawPart) => {
|
|
5757
|
-
const part = rawPart;
|
|
5758
|
-
const summary = {
|
|
5759
|
-
type: typeof part.type === "string" ? part.type : typeof rawPart
|
|
5760
|
-
};
|
|
5761
|
-
const chars = tracePartChars(part);
|
|
5762
|
-
if (chars !== void 0) summary.chars = chars;
|
|
5763
|
-
if (typeof part.toolName === "string") summary.toolName = part.toolName;
|
|
5764
|
-
if (typeof part.toolCallId === "string") summary.toolCallId = part.toolCallId;
|
|
5765
|
-
return summary;
|
|
5766
|
-
}) : [{ type: typeof content }];
|
|
5767
|
-
return { role: message.role, parts };
|
|
5768
|
-
});
|
|
5769
|
-
return {
|
|
5770
|
-
systemChars: request.system?.length ?? 0,
|
|
5771
|
-
messages,
|
|
5772
|
-
toolNames: Object.keys(request.tools ?? {}),
|
|
5773
|
-
...request.toolChoice ? { toolChoice: request.toolChoice } : {}
|
|
5774
|
-
};
|
|
5775
|
-
}
|
|
5776
|
-
var JSON_SCHEMA_TYPES = /* @__PURE__ */ new Map([
|
|
5777
|
-
["ARRAY", "array"],
|
|
5778
|
-
["BOOLEAN", "boolean"],
|
|
5779
|
-
["INTEGER", "integer"],
|
|
5780
|
-
["NULL", "null"],
|
|
5781
|
-
["NUMBER", "number"],
|
|
5782
|
-
["OBJECT", "object"],
|
|
5783
|
-
["STRING", "string"]
|
|
5784
|
-
]);
|
|
5785
|
-
function expandTextWithThinking(text4) {
|
|
5786
|
-
if (!text4.includes("<thinking>")) {
|
|
5787
|
-
return [{ type: "text", text: text4 }];
|
|
5788
|
-
}
|
|
5789
|
-
const out = [];
|
|
5790
|
-
const tokens = text4.split(/<thinking>([\s\S]*?)<\/thinking>/);
|
|
5791
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
5792
|
-
const token = tokens[i] ?? "";
|
|
5793
|
-
if (!token.trim()) continue;
|
|
5794
|
-
out.push({ type: i % 2 === 1 ? "reasoning" : "text", text: token });
|
|
5795
|
-
}
|
|
5796
|
-
return out.length > 0 ? out : [{ type: "text", text: text4 }];
|
|
5797
|
-
}
|
|
5798
|
-
function normalizeSchemaType(value) {
|
|
5799
|
-
if (typeof value === "string") {
|
|
5800
|
-
return JSON_SCHEMA_TYPES.get(value) ?? value;
|
|
5801
|
-
}
|
|
5802
|
-
if (Array.isArray(value)) {
|
|
5803
|
-
return value.map(normalizeSchemaType);
|
|
5804
|
-
}
|
|
5805
|
-
return value;
|
|
5806
|
-
}
|
|
5807
|
-
function normalizeJsonSchema(value) {
|
|
5808
|
-
if (Array.isArray(value)) {
|
|
5809
|
-
return value.map(normalizeJsonSchema);
|
|
5810
|
-
}
|
|
5811
|
-
if (!value || typeof value !== "object") {
|
|
5812
|
-
return value;
|
|
5813
|
-
}
|
|
5814
|
-
return Object.fromEntries(
|
|
5815
|
-
Object.entries(value).map(([key, child]) => [
|
|
5816
|
-
key,
|
|
5817
|
-
key === "type" ? normalizeSchemaType(child) : normalizeJsonSchema(child)
|
|
5818
|
-
])
|
|
5819
|
-
);
|
|
5820
|
-
}
|
|
5821
|
-
function translateTools(ccTools, options = {}) {
|
|
5822
|
-
if (!ccTools?.length) return void 0;
|
|
5823
|
-
const tools = {};
|
|
5824
|
-
let toolCount = 0;
|
|
5825
|
-
for (const t of ccTools) {
|
|
5826
|
-
if (t.functionDeclarations) {
|
|
5827
|
-
for (const fd of t.functionDeclarations) {
|
|
5828
|
-
if (options.maxTools !== void 0 && toolCount >= options.maxTools) break;
|
|
5829
|
-
tools[fd.name] = tool({
|
|
5830
|
-
description: fd.description || "",
|
|
5831
|
-
inputSchema: jsonSchema(
|
|
5832
|
-
normalizeJsonSchema(fd.parameters || { type: "object", properties: {} })
|
|
5833
|
-
)
|
|
5834
|
-
});
|
|
5835
|
-
toolCount++;
|
|
5836
|
-
}
|
|
5837
|
-
}
|
|
5838
|
-
}
|
|
5839
|
-
return Object.keys(tools).length > 0 ? tools : void 0;
|
|
5840
|
-
}
|
|
5841
|
-
function translateRequest(ccReq, options = {}) {
|
|
5842
|
-
const systemInstructions = [];
|
|
5843
|
-
const sdkMessages = [];
|
|
5844
|
-
const nameToIdList = /* @__PURE__ */ new Map();
|
|
5845
|
-
const fallbackAssistantReasoning = [...options.fallbackAssistantReasoning ?? []];
|
|
5846
|
-
const request = ccReq.request || {};
|
|
5847
|
-
if (request.systemInstruction?.parts) {
|
|
5848
|
-
for (const part of request.systemInstruction.parts) {
|
|
5849
|
-
if (part.text) {
|
|
5850
|
-
systemInstructions.push(part.text);
|
|
5851
|
-
}
|
|
5852
|
-
}
|
|
5853
|
-
}
|
|
5854
|
-
const contents = request.contents || [];
|
|
5855
|
-
for (const msg of contents) {
|
|
5856
|
-
const role = msg.role;
|
|
5857
|
-
if (role === "system") {
|
|
5858
|
-
for (const part of msg.parts) {
|
|
5859
|
-
if (part.text) {
|
|
5860
|
-
systemInstructions.push(part.text);
|
|
5861
|
-
}
|
|
5862
|
-
}
|
|
5863
|
-
continue;
|
|
5864
|
-
}
|
|
5865
|
-
const sdkRole = role === "model" ? "assistant" : "user";
|
|
5866
|
-
const hasFunctionCall = msg.parts.some((p8) => p8.functionCall);
|
|
5867
|
-
const hasAssistantReasoning = role === "model" && msg.parts.some((p8) => p8.thought || p8.text?.includes("<thinking>"));
|
|
5868
|
-
const hasComplexParts = msg.parts.some((p8) => p8.thought || p8.inlineData || p8.functionCall || p8.functionResponse);
|
|
5869
|
-
const singleText = msg.parts.length === 1 ? msg.parts[0]?.text : void 0;
|
|
5870
|
-
if (!hasComplexParts && singleText !== void 0 && !singleText.includes("<thinking>")) {
|
|
5871
|
-
sdkMessages.push({
|
|
5872
|
-
role: sdkRole,
|
|
5873
|
-
content: singleText
|
|
5874
|
-
});
|
|
5875
|
-
continue;
|
|
5876
|
-
}
|
|
5877
|
-
const contentParts = [];
|
|
5878
|
-
const toolResults = [];
|
|
5879
|
-
if (role === "model" && hasFunctionCall && !hasAssistantReasoning) {
|
|
5880
|
-
const fallback = fallbackAssistantReasoning.shift();
|
|
5881
|
-
if (fallback?.trim()) {
|
|
5882
|
-
contentParts.push({ type: "reasoning", text: fallback });
|
|
5883
|
-
}
|
|
5884
|
-
}
|
|
5885
|
-
for (const part of msg.parts) {
|
|
5886
|
-
if (part.text !== void 0) {
|
|
5887
|
-
if (part.thought) {
|
|
5888
|
-
contentParts.push({ type: "reasoning", text: part.text });
|
|
5889
|
-
} else {
|
|
5890
|
-
for (const piece of expandTextWithThinking(part.text)) {
|
|
5891
|
-
contentParts.push(piece);
|
|
5892
|
-
}
|
|
5893
|
-
}
|
|
5894
|
-
} else if (part.inlineData) {
|
|
5895
|
-
if (isSupportedImage(part)) {
|
|
5896
|
-
contentParts.push({
|
|
5897
|
-
type: "image",
|
|
5898
|
-
image: part.inlineData.data,
|
|
5899
|
-
mimeType: part.inlineData.mimeType
|
|
5900
|
-
});
|
|
5901
|
-
} else {
|
|
5902
|
-
contentParts.push({ type: "text", text: OMITTED_VOICE_TEXT });
|
|
5903
|
-
}
|
|
5904
|
-
} else if (part.functionCall) {
|
|
5905
|
-
const id = "call_" + randomUUID3().replace(/-/g, "");
|
|
5906
|
-
const name = part.functionCall.name;
|
|
5907
|
-
if (!nameToIdList.has(name)) nameToIdList.set(name, []);
|
|
5908
|
-
nameToIdList.get(name).push(id);
|
|
5909
|
-
contentParts.push({
|
|
5910
|
-
type: "tool-call",
|
|
5911
|
-
toolCallId: id,
|
|
5912
|
-
toolName: name,
|
|
5913
|
-
input: part.functionCall.args || {}
|
|
5914
|
-
});
|
|
5915
|
-
} else if (part.functionResponse) {
|
|
5916
|
-
const name = part.functionResponse.name;
|
|
5917
|
-
const idList = nameToIdList.get(name) || [];
|
|
5918
|
-
const id = idList.shift() || "call_" + randomUUID3().replace(/-/g, "");
|
|
5919
|
-
toolResults.push({
|
|
5920
|
-
type: "tool-result",
|
|
5921
|
-
toolCallId: id,
|
|
5922
|
-
toolName: name,
|
|
5923
|
-
output: { type: "text", value: serializeToolResultContent(part.functionResponse.response) }
|
|
5924
|
-
});
|
|
5925
|
-
}
|
|
5926
|
-
}
|
|
5927
|
-
if (toolResults.length > 0) {
|
|
5928
|
-
sdkMessages.push({
|
|
5929
|
-
role: "tool",
|
|
5930
|
-
content: toolResults
|
|
5931
|
-
});
|
|
5932
|
-
}
|
|
5933
|
-
if (contentParts.length > 0) {
|
|
5934
|
-
sdkMessages.push({
|
|
5935
|
-
role: sdkRole,
|
|
5936
|
-
content: contentParts
|
|
5937
|
-
});
|
|
5938
|
-
}
|
|
5939
|
-
}
|
|
5940
|
-
const system = systemInstructions.length > 0 ? systemInstructions.join("\n\n") : void 0;
|
|
5941
|
-
const tools = translateTools(request.tools, options);
|
|
5942
|
-
let toolChoice;
|
|
5943
|
-
const mode = request.toolConfig?.functionCallingConfig?.mode;
|
|
5944
|
-
if (mode === "ANY") {
|
|
5945
|
-
toolChoice = "required";
|
|
5946
|
-
} else if (mode === "AUTO" || tools) {
|
|
5947
|
-
toolChoice = "auto";
|
|
5948
|
-
}
|
|
5949
|
-
return {
|
|
5950
|
-
system,
|
|
5951
|
-
messages: sdkMessages,
|
|
5952
|
-
tools,
|
|
5953
|
-
toolChoice
|
|
5954
|
-
};
|
|
5955
|
-
}
|
|
5956
|
-
|
|
5957
5765
|
// src/antigravity/anthropic-to-cloudcode.ts
|
|
5958
5766
|
var DEFAULT_SAFETY_SETTINGS = [
|
|
5959
5767
|
{ category: "HARM_CATEGORY_HATE_SPEECH", threshold: "OFF" },
|
|
@@ -5963,7 +5771,6 @@ var DEFAULT_SAFETY_SETTINGS = [
|
|
|
5963
5771
|
];
|
|
5964
5772
|
var ANTIGRAVITY_USER_AGENT2 = "vscode/1.X.X (Antigravity/4.2.0)";
|
|
5965
5773
|
var MIN_ANTIGRAVITY_OUTPUT_TOKENS = 1024;
|
|
5966
|
-
var DISABLE_CLOUD_CODE_THINKING = { thinkingBudget: 0, includeThoughts: false };
|
|
5967
5774
|
var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
5968
5775
|
"$schema",
|
|
5969
5776
|
"$defs",
|
|
@@ -5973,6 +5780,7 @@ var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
5973
5780
|
"additionalProperties",
|
|
5974
5781
|
"propertyNames",
|
|
5975
5782
|
"patternProperties",
|
|
5783
|
+
"prefixItems",
|
|
5976
5784
|
"title",
|
|
5977
5785
|
"exclusiveMinimum",
|
|
5978
5786
|
"exclusiveMaximum",
|
|
@@ -6006,15 +5814,105 @@ var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
6006
5814
|
"examples",
|
|
6007
5815
|
"readOnly",
|
|
6008
5816
|
"writeOnly",
|
|
6009
|
-
"deprecated"
|
|
5817
|
+
"deprecated",
|
|
5818
|
+
// Codex app tool schemas can include this internal annotation. It is not a
|
|
5819
|
+
// JSON Schema keyword and Cloud Code's Schema protobuf rejects it.
|
|
5820
|
+
"encrypted"
|
|
6010
5821
|
]);
|
|
6011
|
-
|
|
5822
|
+
var CLOUD_CODE_SCHEMA_TYPES = /* @__PURE__ */ new Map([
|
|
5823
|
+
["array", "ARRAY"],
|
|
5824
|
+
["boolean", "BOOLEAN"],
|
|
5825
|
+
["integer", "INTEGER"],
|
|
5826
|
+
["null", "NULL"],
|
|
5827
|
+
["number", "NUMBER"],
|
|
5828
|
+
["object", "OBJECT"],
|
|
5829
|
+
["string", "STRING"]
|
|
5830
|
+
]);
|
|
5831
|
+
function normalizeCloudCodeSchemaType(value) {
|
|
5832
|
+
if (typeof value === "string") {
|
|
5833
|
+
return CLOUD_CODE_SCHEMA_TYPES.get(value.toLowerCase()) ?? value;
|
|
5834
|
+
}
|
|
5835
|
+
return value;
|
|
5836
|
+
}
|
|
5837
|
+
function isNullSchema(obj) {
|
|
5838
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return false;
|
|
5839
|
+
const type = obj.type;
|
|
5840
|
+
return type === "null" || type === "NULL" || Array.isArray(type) && type.every((value) => value === "null" || value === "NULL");
|
|
5841
|
+
}
|
|
5842
|
+
function resolveLocalSchemaRef(ref, root) {
|
|
5843
|
+
if (!ref.startsWith("#/$defs/")) return void 0;
|
|
5844
|
+
const name = ref.slice("#/$defs/".length).replace(/~1/g, "/").replace(/~0/g, "~");
|
|
5845
|
+
const defs = root.$defs;
|
|
5846
|
+
if (!defs || typeof defs !== "object" || Array.isArray(defs)) return void 0;
|
|
5847
|
+
return defs[name];
|
|
5848
|
+
}
|
|
5849
|
+
function stripDraftMeta(obj, root = void 0, resolvingRefs = /* @__PURE__ */ new Set()) {
|
|
6012
5850
|
if (!obj || typeof obj !== "object") return obj;
|
|
6013
|
-
if (Array.isArray(obj)) return obj.map(stripDraftMeta);
|
|
5851
|
+
if (Array.isArray(obj)) return obj.map((value) => stripDraftMeta(value, root, resolvingRefs));
|
|
5852
|
+
const source = obj;
|
|
5853
|
+
const schemaRoot = root ?? source;
|
|
5854
|
+
if (typeof source.$ref === "string") {
|
|
5855
|
+
const resolved = resolveLocalSchemaRef(source.$ref, schemaRoot);
|
|
5856
|
+
if (resolved !== void 0) {
|
|
5857
|
+
if (resolvingRefs.has(source.$ref)) return { type: "OBJECT" };
|
|
5858
|
+
const nextRefs = new Set(resolvingRefs);
|
|
5859
|
+
nextRefs.add(source.$ref);
|
|
5860
|
+
const dereferenced = stripDraftMeta(resolved, schemaRoot, nextRefs);
|
|
5861
|
+
if (dereferenced && typeof dereferenced === "object" && !Array.isArray(dereferenced)) {
|
|
5862
|
+
const siblings = { ...source };
|
|
5863
|
+
delete siblings.$ref;
|
|
5864
|
+
const sanitizedSiblings = stripDraftMeta(siblings, schemaRoot, resolvingRefs);
|
|
5865
|
+
return {
|
|
5866
|
+
...dereferenced,
|
|
5867
|
+
...sanitizedSiblings
|
|
5868
|
+
};
|
|
5869
|
+
}
|
|
5870
|
+
return dereferenced;
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
6014
5873
|
const out = {};
|
|
6015
|
-
for (const [k, v] of Object.entries(
|
|
5874
|
+
for (const [k, v] of Object.entries(source)) {
|
|
6016
5875
|
if (STRIP_KEYS.has(k) || k.startsWith("x-")) continue;
|
|
6017
|
-
|
|
5876
|
+
if (k === "properties" && v && typeof v === "object" && !Array.isArray(v)) {
|
|
5877
|
+
out.properties = Object.fromEntries(
|
|
5878
|
+
Object.entries(v).map(([name, schema]) => [
|
|
5879
|
+
name,
|
|
5880
|
+
stripDraftMeta(schema, schemaRoot, resolvingRefs)
|
|
5881
|
+
])
|
|
5882
|
+
);
|
|
5883
|
+
continue;
|
|
5884
|
+
}
|
|
5885
|
+
if (k === "type") {
|
|
5886
|
+
const types = (Array.isArray(v) ? v : [v]).map(normalizeCloudCodeSchemaType).filter((type) => typeof type === "string");
|
|
5887
|
+
const concreteType = types.find((type) => type !== "NULL");
|
|
5888
|
+
out.type = concreteType ?? "STRING";
|
|
5889
|
+
if (types.includes("NULL")) out.nullable = true;
|
|
5890
|
+
continue;
|
|
5891
|
+
}
|
|
5892
|
+
if (k === "enum" && Array.isArray(v)) {
|
|
5893
|
+
out.enum = v.filter((value) => value !== null && value !== void 0).map(String);
|
|
5894
|
+
continue;
|
|
5895
|
+
}
|
|
5896
|
+
if (k === "items" && Array.isArray(v)) {
|
|
5897
|
+
out.items = stripDraftMeta(v[0] ?? {}, schemaRoot, resolvingRefs);
|
|
5898
|
+
continue;
|
|
5899
|
+
}
|
|
5900
|
+
out[k] = stripDraftMeta(v, schemaRoot, resolvingRefs);
|
|
5901
|
+
}
|
|
5902
|
+
const union = Array.isArray(source.anyOf) ? source.anyOf : Array.isArray(source.oneOf) ? source.oneOf : void 0;
|
|
5903
|
+
if (union) {
|
|
5904
|
+
const nullable = union.some(isNullSchema);
|
|
5905
|
+
const alternatives = union.filter((branch) => !isNullSchema(branch)).map((branch) => stripDraftMeta(branch, schemaRoot, resolvingRefs)).filter((branch) => Boolean(branch) && typeof branch === "object" && !Array.isArray(branch));
|
|
5906
|
+
if (alternatives.length === 1) Object.assign(out, alternatives[0], out);
|
|
5907
|
+
else if (alternatives.length > 1) out.anyOf = alternatives;
|
|
5908
|
+
if (nullable) out.nullable = true;
|
|
5909
|
+
}
|
|
5910
|
+
if (!out.type) {
|
|
5911
|
+
if (out.properties && typeof out.properties === "object" && !Array.isArray(out.properties)) {
|
|
5912
|
+
out.type = "OBJECT";
|
|
5913
|
+
} else if (out.items && typeof out.items === "object" && !Array.isArray(out.items)) {
|
|
5914
|
+
out.type = "ARRAY";
|
|
5915
|
+
}
|
|
6018
5916
|
}
|
|
6019
5917
|
if (Array.isArray(out.required) && out.properties && typeof out.properties === "object") {
|
|
6020
5918
|
const props = out.properties;
|
|
@@ -6075,15 +5973,18 @@ function extractSystem(system) {
|
|
|
6075
5973
|
}
|
|
6076
5974
|
return void 0;
|
|
6077
5975
|
}
|
|
6078
|
-
function
|
|
5976
|
+
function translateTools(tools) {
|
|
6079
5977
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
6080
5978
|
const decls = [];
|
|
6081
5979
|
for (const t of tools) {
|
|
6082
5980
|
if (typeof t.name !== "string") continue;
|
|
5981
|
+
const translated = stripDraftMeta(t.input_schema ?? { type: "object", properties: {} });
|
|
5982
|
+
const parameters = translated && typeof translated === "object" && !Array.isArray(translated) ? translated : { type: "OBJECT", properties: {} };
|
|
5983
|
+
if (!parameters.type) parameters.type = "OBJECT";
|
|
6083
5984
|
decls.push({
|
|
6084
5985
|
name: t.name,
|
|
6085
5986
|
description: typeof t.description === "string" ? t.description : "",
|
|
6086
|
-
parameters
|
|
5987
|
+
parameters
|
|
6087
5988
|
});
|
|
6088
5989
|
}
|
|
6089
5990
|
return decls.length > 0 ? [{ functionDeclarations: decls }] : void 0;
|
|
@@ -6109,8 +6010,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6109
6010
|
}
|
|
6110
6011
|
if (typeof body.temperature === "number") generationConfig.temperature = body.temperature;
|
|
6111
6012
|
if (typeof body.top_p === "number") generationConfig.topP = body.top_p;
|
|
6112
|
-
|
|
6113
|
-
const ccTools = translateTools2(body.tools);
|
|
6013
|
+
const ccTools = translateTools(body.tools);
|
|
6114
6014
|
const systemInstruction = extractSystem(body.system);
|
|
6115
6015
|
const request = {
|
|
6116
6016
|
contents,
|
|
@@ -6124,7 +6024,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6124
6024
|
}
|
|
6125
6025
|
return {
|
|
6126
6026
|
project: projectId,
|
|
6127
|
-
requestId:
|
|
6027
|
+
requestId: randomUUID3(),
|
|
6128
6028
|
model: realModelId,
|
|
6129
6029
|
userAgent: ANTIGRAVITY_USER_AGENT2,
|
|
6130
6030
|
requestType: "agent",
|
|
@@ -6134,7 +6034,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6134
6034
|
}
|
|
6135
6035
|
|
|
6136
6036
|
// src/antigravity/cloudcode-to-anthropic.ts
|
|
6137
|
-
import { randomUUID as
|
|
6037
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
6138
6038
|
function writeEvent(res, event, data) {
|
|
6139
6039
|
res.write(`event: ${event}
|
|
6140
6040
|
data: ${JSON.stringify(data)}
|
|
@@ -6224,7 +6124,7 @@ function closeBlock(res, state) {
|
|
|
6224
6124
|
}
|
|
6225
6125
|
async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
6226
6126
|
const state = {
|
|
6227
|
-
messageId: `msg_${
|
|
6127
|
+
messageId: `msg_${randomUUID4().replace(/-/g, "").slice(0, 24)}`,
|
|
6228
6128
|
model,
|
|
6229
6129
|
blockIdx: 0,
|
|
6230
6130
|
textBlockOpen: false,
|
|
@@ -6313,7 +6213,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
6313
6213
|
closeBlock(res, state);
|
|
6314
6214
|
}
|
|
6315
6215
|
for (const tc of state.toolCalls) {
|
|
6316
|
-
const rawToolId = `toolu_${
|
|
6216
|
+
const rawToolId = `toolu_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
|
|
6317
6217
|
const toolId = encodeToolUseId(rawToolId, tc.signature);
|
|
6318
6218
|
writeEvent(res, "content_block_start", {
|
|
6319
6219
|
type: "content_block_start",
|
|
@@ -6364,7 +6264,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
6364
6264
|
}
|
|
6365
6265
|
async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
6366
6266
|
const text4 = await upstreamRes.text();
|
|
6367
|
-
const messageId = `msg_${
|
|
6267
|
+
const messageId = `msg_${randomUUID4().replace(/-/g, "").slice(0, 24)}`;
|
|
6368
6268
|
const content = [];
|
|
6369
6269
|
let stopReason = "end_turn";
|
|
6370
6270
|
let inputTokens = 0;
|
|
@@ -6393,7 +6293,7 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
6393
6293
|
else content.push({ type: "text", text: part.text });
|
|
6394
6294
|
} else if (part.functionCall && typeof part.functionCall === "object") {
|
|
6395
6295
|
const fc = part.functionCall;
|
|
6396
|
-
const rawToolId = `toolu_${
|
|
6296
|
+
const rawToolId = `toolu_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
|
|
6397
6297
|
content.push({
|
|
6398
6298
|
type: "tool_use",
|
|
6399
6299
|
id: encodeToolUseId(rawToolId, signature ?? pendingThoughtSignature),
|
|
@@ -6426,16 +6326,16 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
6426
6326
|
}
|
|
6427
6327
|
|
|
6428
6328
|
// src/proxy.ts
|
|
6429
|
-
import { randomUUID as
|
|
6329
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
6430
6330
|
|
|
6431
6331
|
// src/sdk-adapter.ts
|
|
6432
|
-
import { streamText, generateText, tool
|
|
6332
|
+
import { streamText, generateText, tool, jsonSchema } from "ai";
|
|
6433
6333
|
|
|
6434
6334
|
// src/tool-search.ts
|
|
6435
6335
|
var TOOL_SEARCH_TYPE_PREFIX = "tool_search_tool";
|
|
6436
|
-
function isToolSearchTool(
|
|
6437
|
-
if (typeof
|
|
6438
|
-
const name =
|
|
6336
|
+
function isToolSearchTool(tool3) {
|
|
6337
|
+
if (typeof tool3.type === "string" && tool3.type.startsWith(TOOL_SEARCH_TYPE_PREFIX)) return true;
|
|
6338
|
+
const name = tool3.name ?? "";
|
|
6439
6339
|
return name.includes("tool_search") || name === "ToolSearch";
|
|
6440
6340
|
}
|
|
6441
6341
|
function extractReferencedToolNames(messages) {
|
|
@@ -6474,16 +6374,16 @@ function resolveUpstreamTools(tools, messages) {
|
|
|
6474
6374
|
if (!tools?.length) return [];
|
|
6475
6375
|
const referenced = extractReferencedToolNames(messages);
|
|
6476
6376
|
const upstream = [];
|
|
6477
|
-
for (const
|
|
6478
|
-
if (isToolSearchTool(
|
|
6479
|
-
upstream.push(
|
|
6377
|
+
for (const tool3 of tools) {
|
|
6378
|
+
if (isToolSearchTool(tool3)) {
|
|
6379
|
+
upstream.push(tool3);
|
|
6480
6380
|
continue;
|
|
6481
6381
|
}
|
|
6482
|
-
if (
|
|
6483
|
-
if (referenced.has(
|
|
6382
|
+
if (tool3.defer_loading === true) {
|
|
6383
|
+
if (referenced.has(tool3.name)) upstream.push(tool3);
|
|
6484
6384
|
continue;
|
|
6485
6385
|
}
|
|
6486
|
-
upstream.push(
|
|
6386
|
+
upstream.push(tool3);
|
|
6487
6387
|
}
|
|
6488
6388
|
return upstream;
|
|
6489
6389
|
}
|
|
@@ -6730,12 +6630,12 @@ function stripNullInputs(input) {
|
|
|
6730
6630
|
}
|
|
6731
6631
|
return out;
|
|
6732
6632
|
}
|
|
6733
|
-
function
|
|
6633
|
+
function translateTools2(anthropicTools) {
|
|
6734
6634
|
if (!anthropicTools?.length) return void 0;
|
|
6735
6635
|
const tools = {};
|
|
6736
6636
|
for (const t of anthropicTools) {
|
|
6737
6637
|
if (!t.name || !t.input_schema) continue;
|
|
6738
|
-
tools[t.name] =
|
|
6638
|
+
tools[t.name] = tool({ description: t.description ?? "", inputSchema: jsonSchema(t.input_schema) });
|
|
6739
6639
|
}
|
|
6740
6640
|
return Object.keys(tools).length ? tools : void 0;
|
|
6741
6641
|
}
|
|
@@ -6746,7 +6646,7 @@ function translateToolChoice(tc) {
|
|
|
6746
6646
|
if (tc.type === "tool" && tc.name) return { type: "tool", toolName: tc.name };
|
|
6747
6647
|
return void 0;
|
|
6748
6648
|
}
|
|
6749
|
-
function
|
|
6649
|
+
function translateRequest(body, npm, options) {
|
|
6750
6650
|
const messages = body.messages ?? [];
|
|
6751
6651
|
annotateToolNames(messages);
|
|
6752
6652
|
const baseSystem = systemToString(body.system);
|
|
@@ -6783,7 +6683,7 @@ function translateRequest2(body, npm, options) {
|
|
|
6783
6683
|
return {
|
|
6784
6684
|
system: options?.openAiOAuth ? void 0 : systemText,
|
|
6785
6685
|
messages: translateMessages(messages, npm, options?.onDebug),
|
|
6786
|
-
tools:
|
|
6686
|
+
tools: translateTools2(upstreamTools.length ? upstreamTools : void 0),
|
|
6787
6687
|
toolChoice: translateToolChoice(body.tool_choice),
|
|
6788
6688
|
maxOutputTokens: options?.openAiOAuth ? void 0 : body.max_tokens,
|
|
6789
6689
|
temperature: body.temperature,
|
|
@@ -7119,7 +7019,7 @@ function lookupRoute(byAlias, id) {
|
|
|
7119
7019
|
return void 0;
|
|
7120
7020
|
}
|
|
7121
7021
|
function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
7122
|
-
const proxyToken =
|
|
7022
|
+
const proxyToken = randomUUID5();
|
|
7123
7023
|
silenceSdkWarnings();
|
|
7124
7024
|
if (routes.length === 0) {
|
|
7125
7025
|
return Promise.reject(new Error("Proxy catalog requires at least one route"));
|
|
@@ -7246,7 +7146,7 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
7246
7146
|
if (sessionId) {
|
|
7247
7147
|
subagentRouting.registerSubagentRoute = (modelId) => subagentRouteRegistry.register(sessionId, modelId);
|
|
7248
7148
|
}
|
|
7249
|
-
const params =
|
|
7149
|
+
const params = translateRequest(anthropicBody, route.npm, {
|
|
7250
7150
|
openAiOAuth,
|
|
7251
7151
|
maxTools: maxToolsForNpm(route.npm),
|
|
7252
7152
|
onDebug: (msg) => plog(() => msg),
|
|
@@ -10397,6 +10297,20 @@ async function refreshAntigravityOAuthModels(accessToken) {
|
|
|
10397
10297
|
}).finally(() => clearTimeout(timer));
|
|
10398
10298
|
if (!res.ok) continue;
|
|
10399
10299
|
const body = await res.json();
|
|
10300
|
+
const deprecatedModelIds = body.deprecatedModelIds && typeof body.deprecatedModelIds === "object" && !Array.isArray(body.deprecatedModelIds) ? body.deprecatedModelIds : {};
|
|
10301
|
+
const resolveUpstreamModelId = (id) => {
|
|
10302
|
+
let current = id;
|
|
10303
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10304
|
+
while (!seen.has(current)) {
|
|
10305
|
+
seen.add(current);
|
|
10306
|
+
const alias = deprecatedModelIds[current];
|
|
10307
|
+
if (!alias || typeof alias !== "object" || Array.isArray(alias)) break;
|
|
10308
|
+
const next = alias.newModelId;
|
|
10309
|
+
if (typeof next !== "string" || next.length === 0) break;
|
|
10310
|
+
current = next;
|
|
10311
|
+
}
|
|
10312
|
+
return current;
|
|
10313
|
+
};
|
|
10400
10314
|
const raw = body.models && typeof body.models === "object" && !Array.isArray(body.models) ? Object.entries(body.models).map(([id, model]) => ({ id, ...model })) : Array.isArray(body.models) ? body.models.filter((m) => typeof m.id === "string" && m.id.length > 0) : [];
|
|
10401
10315
|
if (raw.length === 0) continue;
|
|
10402
10316
|
const models = raw.filter((m) => typeof m.id === "string" && m.id.length > 0 && !isAntigravityCloudCodeHelperSlot(m.id)).map((m) => {
|
|
@@ -10409,7 +10323,7 @@ async function refreshAntigravityOAuthModels(accessToken) {
|
|
|
10409
10323
|
return {
|
|
10410
10324
|
id,
|
|
10411
10325
|
name,
|
|
10412
|
-
upstreamModelId: id,
|
|
10326
|
+
upstreamModelId: resolveUpstreamModelId(id),
|
|
10413
10327
|
family: isGemini ? "gemini" : id.split("-")[0] ?? id,
|
|
10414
10328
|
brand: isGemini ? "Google" : isClaude ? "Anthropic" : isOpenAi ? "OpenAI" : "Other",
|
|
10415
10329
|
contextWindow: maxTokens ?? resolveContextWindow(id),
|
|
@@ -11150,7 +11064,7 @@ async function askSaveServerPassword() {
|
|
|
11150
11064
|
import { createServer as createServer2 } from "http";
|
|
11151
11065
|
|
|
11152
11066
|
// src/openai-adapter.ts
|
|
11153
|
-
import { tool as
|
|
11067
|
+
import { tool as tool2, jsonSchema as jsonSchema2, streamText as streamText2, generateText as generateText2 } from "ai";
|
|
11154
11068
|
function translateOpenAiRequest(body) {
|
|
11155
11069
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
11156
11070
|
for (const msg of body.messages) {
|
|
@@ -11216,10 +11130,10 @@ function translateOpenAiRequest(body) {
|
|
|
11216
11130
|
tools = {};
|
|
11217
11131
|
for (const t of body.tools) {
|
|
11218
11132
|
if (t.type === "function" && t.function.name) {
|
|
11219
|
-
const schema = t.function.parameters ?
|
|
11220
|
-
tools[t.function.name] =
|
|
11133
|
+
const schema = t.function.parameters ? jsonSchema2(t.function.parameters) : void 0;
|
|
11134
|
+
tools[t.function.name] = tool2({
|
|
11221
11135
|
description: t.function.description ?? "",
|
|
11222
|
-
inputSchema: schema ??
|
|
11136
|
+
inputSchema: schema ?? jsonSchema2({ type: "object", properties: {} })
|
|
11223
11137
|
});
|
|
11224
11138
|
}
|
|
11225
11139
|
}
|
|
@@ -11509,7 +11423,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog, suba
|
|
|
11509
11423
|
if (sessionId) {
|
|
11510
11424
|
subagentRouting.registerSubagentRoute = (modelId) => subagentRouteRegistry.register(sessionId, modelId);
|
|
11511
11425
|
}
|
|
11512
|
-
const params =
|
|
11426
|
+
const params = translateRequest(body, model.npm, {
|
|
11513
11427
|
defaultEffort: anthropicEffortFromRequest(body) ? void 0 : model.defaultEffort,
|
|
11514
11428
|
openAiOAuth: model.npm === "@ai-sdk/openai" && model.authType === "oauth",
|
|
11515
11429
|
onDebug: plog,
|
|
@@ -12985,18 +12899,18 @@ ${pc6.dim("OpenCode CLI configs: use")} relay-ai providers import${pc6.dim(" (op
|
|
|
12985
12899
|
}
|
|
12986
12900
|
|
|
12987
12901
|
// src/codex/app-launch.ts
|
|
12988
|
-
import { execSync as execSync2, spawn as
|
|
12989
|
-
import { existsSync as existsSync11, readdirSync as readdirSync2, realpathSync, statSync as statSync3 } from "fs";
|
|
12902
|
+
import { execSync as execSync2, spawn as spawn3 } from "child_process";
|
|
12903
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync2, realpathSync, statSync as statSync3 } from "fs";
|
|
12990
12904
|
import { homedir as homedir7 } from "os";
|
|
12991
|
-
import { dirname as dirname5, join as join12 } from "path";
|
|
12905
|
+
import { dirname as dirname5, join as join12, win32 as winPath } from "path";
|
|
12992
12906
|
import * as p6 from "@clack/prompts";
|
|
12993
12907
|
|
|
12994
12908
|
// src/linux-display.ts
|
|
12995
|
-
import { execFileSync as
|
|
12909
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
12996
12910
|
import { readdirSync } from "fs";
|
|
12997
12911
|
function displayHasWindow(display, windowId) {
|
|
12998
12912
|
try {
|
|
12999
|
-
const output =
|
|
12913
|
+
const output = execFileSync2("xprop", ["-display", display, "-id", windowId, "WM_CLASS"], {
|
|
13000
12914
|
encoding: "utf8",
|
|
13001
12915
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13002
12916
|
});
|
|
@@ -13074,6 +12988,54 @@ function linuxEmbeddedCodexCandidates(appPath) {
|
|
|
13074
12988
|
function winLocalAppData() {
|
|
13075
12989
|
return process.env.LOCALAPPDATA ?? join12(homedir7(), "AppData", "Local");
|
|
13076
12990
|
}
|
|
12991
|
+
function windowsEmbeddedCodexCandidates(appPath, packageInstallLocations) {
|
|
12992
|
+
const candidates = [];
|
|
12993
|
+
if (appPath && !appPath.startsWith("shell:AppsFolder\\")) {
|
|
12994
|
+
const appDir = winPath.dirname(appPath);
|
|
12995
|
+
candidates.push(
|
|
12996
|
+
winPath.join(appDir, "resources", "codex.exe"),
|
|
12997
|
+
winPath.join(appDir, "app", "resources", "codex.exe")
|
|
12998
|
+
);
|
|
12999
|
+
}
|
|
13000
|
+
for (const installLocation of packageInstallLocations) {
|
|
13001
|
+
if (!installLocation.trim()) continue;
|
|
13002
|
+
candidates.push(
|
|
13003
|
+
winPath.join(installLocation, "app", "resources", "codex.exe"),
|
|
13004
|
+
winPath.join(installLocation, "resources", "codex.exe")
|
|
13005
|
+
);
|
|
13006
|
+
}
|
|
13007
|
+
return [...new Set(candidates)];
|
|
13008
|
+
}
|
|
13009
|
+
function windowsEmbeddedCodexCachePath(sourcePath, home = homedir7()) {
|
|
13010
|
+
const normalized = sourcePath.replaceAll("/", "\\");
|
|
13011
|
+
const match = normalized.match(/\\WindowsApps\\([^\\]+)\\/i);
|
|
13012
|
+
if (!match) return null;
|
|
13013
|
+
const packageDirectory = match[1].replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
13014
|
+
return winPath.join(home, ".relay-ai", "codex", "embedded-runtime", packageDirectory, "codex.exe");
|
|
13015
|
+
}
|
|
13016
|
+
function executableWindowsEmbeddedCodexPath(sourcePath) {
|
|
13017
|
+
const cachePath2 = windowsEmbeddedCodexCachePath(sourcePath);
|
|
13018
|
+
if (!cachePath2) return sourcePath;
|
|
13019
|
+
try {
|
|
13020
|
+
const sourceSize = statSync3(sourcePath).size;
|
|
13021
|
+
if (existsSync11(cachePath2) && statSync3(cachePath2).size === sourceSize) return cachePath2;
|
|
13022
|
+
mkdirSync8(winPath.dirname(cachePath2), { recursive: true });
|
|
13023
|
+
copyFileSync3(sourcePath, cachePath2);
|
|
13024
|
+
return statSync3(cachePath2).size === sourceSize ? cachePath2 : null;
|
|
13025
|
+
} catch {
|
|
13026
|
+
return null;
|
|
13027
|
+
}
|
|
13028
|
+
}
|
|
13029
|
+
function winCodexPackageInstallLocations() {
|
|
13030
|
+
try {
|
|
13031
|
+
const out = runPowerShell(
|
|
13032
|
+
"Get-AppxPackage -Name 'OpenAI.Codex' | Sort-Object Version -Descending | Select-Object -ExpandProperty InstallLocation"
|
|
13033
|
+
);
|
|
13034
|
+
return out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
13035
|
+
} catch {
|
|
13036
|
+
return [];
|
|
13037
|
+
}
|
|
13038
|
+
}
|
|
13077
13039
|
function winCodexExeCandidates() {
|
|
13078
13040
|
const local = winLocalAppData();
|
|
13079
13041
|
const bases = WIN_APP_NAMES.flatMap((name) => [
|
|
@@ -13143,14 +13105,25 @@ function findCodexApp(platform = process.platform) {
|
|
|
13143
13105
|
}
|
|
13144
13106
|
function findEmbeddedCodexBinary(platform = process.platform) {
|
|
13145
13107
|
const appPath = findCodexApp(platform);
|
|
13146
|
-
if (!appPath) return null;
|
|
13147
13108
|
if (platform === "darwin") {
|
|
13109
|
+
if (!appPath) return null;
|
|
13148
13110
|
const binary = join12(appPath, "Contents", "Resources", "codex");
|
|
13149
13111
|
return existsSync11(binary) ? binary : null;
|
|
13150
13112
|
}
|
|
13151
13113
|
if (platform === "linux") {
|
|
13114
|
+
if (!appPath) return null;
|
|
13152
13115
|
return linuxEmbeddedCodexCandidates(appPath).find((path) => existsSync11(path)) ?? null;
|
|
13153
13116
|
}
|
|
13117
|
+
if (platform === "win32") {
|
|
13118
|
+
const sourcePath = windowsEmbeddedCodexCandidates(appPath, winCodexPackageInstallLocations()).find((path) => {
|
|
13119
|
+
try {
|
|
13120
|
+
return existsSync11(path) && statSync3(path).isFile();
|
|
13121
|
+
} catch {
|
|
13122
|
+
return false;
|
|
13123
|
+
}
|
|
13124
|
+
});
|
|
13125
|
+
return sourcePath ? executableWindowsEmbeddedCodexPath(sourcePath) : null;
|
|
13126
|
+
}
|
|
13154
13127
|
return null;
|
|
13155
13128
|
}
|
|
13156
13129
|
function darwinIsRunning() {
|
|
@@ -13227,14 +13200,14 @@ function openCodexAppAt(path) {
|
|
|
13227
13200
|
}
|
|
13228
13201
|
if (process.platform === "win32") {
|
|
13229
13202
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13230
|
-
|
|
13203
|
+
spawn3("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13231
13204
|
} else {
|
|
13232
13205
|
runPowerShell(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13233
13206
|
}
|
|
13234
13207
|
return;
|
|
13235
13208
|
}
|
|
13236
13209
|
if (process.platform === "linux") {
|
|
13237
|
-
|
|
13210
|
+
spawn3(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
|
|
13238
13211
|
}
|
|
13239
13212
|
}
|
|
13240
13213
|
function openCodexApp() {
|
|
@@ -13278,7 +13251,7 @@ function winForceQuit() {
|
|
|
13278
13251
|
if (pids.length === 0) return;
|
|
13279
13252
|
runPowerShell(`Stop-Process -Id ${pids.join(",")} -Force -ErrorAction SilentlyContinue`);
|
|
13280
13253
|
}
|
|
13281
|
-
async function launchOrRestartCodexApp(prompt = "Restart ChatGPT Desktop to apply relay-ai settings?") {
|
|
13254
|
+
async function launchOrRestartCodexApp(prompt = "Restart ChatGPT Desktop to apply relay-ai settings?", assumeYes = false) {
|
|
13282
13255
|
const appPath = findCodexApp();
|
|
13283
13256
|
if (!isCodexAppRunning()) {
|
|
13284
13257
|
if (!appPath) {
|
|
@@ -13292,6 +13265,9 @@ async function launchOrRestartCodexApp(prompt = "Restart ChatGPT Desktop to appl
|
|
|
13292
13265
|
if (process.platform === "linux") {
|
|
13293
13266
|
p6.log.info("Restarting ChatGPT Desktop to apply relay-ai settings...");
|
|
13294
13267
|
linuxQuitGraceful();
|
|
13268
|
+
} else if (assumeYes) {
|
|
13269
|
+
if (process.platform === "darwin") darwinQuit();
|
|
13270
|
+
else if (process.platform === "win32") winQuitGraceful();
|
|
13295
13271
|
} else {
|
|
13296
13272
|
const restart = await p6.confirm({ message: prompt, initialValue: true });
|
|
13297
13273
|
if (p6.isCancel(restart) || !restart) {
|
|
@@ -13313,7 +13289,7 @@ function codexAppInstallHint() {
|
|
|
13313
13289
|
}
|
|
13314
13290
|
|
|
13315
13291
|
// src/claude-desktop/app-launch.ts
|
|
13316
|
-
import { execSync as execSync3, spawn as
|
|
13292
|
+
import { execSync as execSync3, spawn as spawn4 } from "child_process";
|
|
13317
13293
|
import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync12, statSync as statSync4 } from "fs";
|
|
13318
13294
|
import { homedir as homedir8 } from "os";
|
|
13319
13295
|
import { join as join13 } from "path";
|
|
@@ -13520,14 +13496,14 @@ function openClaudeAppAt(path) {
|
|
|
13520
13496
|
}
|
|
13521
13497
|
if (process.platform === "win32") {
|
|
13522
13498
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13523
|
-
|
|
13499
|
+
spawn4("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13524
13500
|
} else {
|
|
13525
13501
|
runPowerShell2(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13526
13502
|
}
|
|
13527
13503
|
return;
|
|
13528
13504
|
}
|
|
13529
13505
|
if (process.platform === "linux") {
|
|
13530
|
-
|
|
13506
|
+
spawn4(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
|
|
13531
13507
|
}
|
|
13532
13508
|
}
|
|
13533
13509
|
function openClaudeApp() {
|
|
@@ -13613,6 +13589,8 @@ export {
|
|
|
13613
13589
|
effortProviderOptions,
|
|
13614
13590
|
deepMergeProviderOptions,
|
|
13615
13591
|
thinkingProviderOptions,
|
|
13592
|
+
runCodexCommandSync,
|
|
13593
|
+
runCodexCommand,
|
|
13616
13594
|
renderMultiAgentV2Feature,
|
|
13617
13595
|
supportsMultiAgentV2,
|
|
13618
13596
|
CODEX_APP_PROVIDER_ID,
|
|
@@ -13763,10 +13741,6 @@ export {
|
|
|
13763
13741
|
splitToolUseId,
|
|
13764
13742
|
encodeToolUseId,
|
|
13765
13743
|
serializeToolResultContent,
|
|
13766
|
-
UNSUPPORTED_VOICE_MESSAGE,
|
|
13767
|
-
sanitizeUnsupportedInlineData,
|
|
13768
|
-
summarizeSdkRequestForTrace,
|
|
13769
|
-
translateRequest,
|
|
13770
13744
|
formatUpstreamErrorTrace,
|
|
13771
13745
|
formatUpstreamError,
|
|
13772
13746
|
upstreamHttpStatus,
|
|
@@ -13844,4 +13818,4 @@ export {
|
|
|
13844
13818
|
supportsClaudeTransparentMode,
|
|
13845
13819
|
buildHttpProxyRoutes
|
|
13846
13820
|
};
|
|
13847
|
-
//# sourceMappingURL=chunk-
|
|
13821
|
+
//# sourceMappingURL=chunk-SCW2TYSG.js.map
|