@jacobbd/relay-ai 0.9.3 → 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-PVGAE7HA.js → chunk-SCW2TYSG.js} +316 -339
- 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-JQPEZAMN.js → ui-command-Q6LBKVM3.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-PVGAE7HA.js.map +0 -1
- /package/dist/{ui-command-JQPEZAMN.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
|
});
|
|
@@ -3746,8 +3817,11 @@ function buildChildEnv(baseUrl, model, apiKey, proxyPort, contextWindow2, enable
|
|
|
3746
3817
|
env["ANTHROPIC_API_KEY"] = apiKey;
|
|
3747
3818
|
const bareModel = stripOneMContextSuffix(model);
|
|
3748
3819
|
env["ANTHROPIC_MODEL"] = claudeCodeClientModelId(model, contextWindow2);
|
|
3749
|
-
|
|
3820
|
+
if (!enableGatewayDiscovery) {
|
|
3821
|
+
env["CLAUDE_CODE_MAX_CONTEXT_TOKENS"] = String(resolveContextWindow(bareModel, contextWindow2));
|
|
3822
|
+
}
|
|
3750
3823
|
if (enableGatewayDiscovery) {
|
|
3824
|
+
delete env["CLAUDE_CODE_MAX_CONTEXT_TOKENS"];
|
|
3751
3825
|
env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"] = "1";
|
|
3752
3826
|
}
|
|
3753
3827
|
applyClaudeCodeThirdPartyCompat(env);
|
|
@@ -5138,9 +5212,9 @@ function claudeModelFamily(modelId) {
|
|
|
5138
5212
|
if (!normalized.startsWith("claude-")) return void 0;
|
|
5139
5213
|
return CLAUDE_MODEL_FAMILIES.find((family) => normalized.includes(family));
|
|
5140
5214
|
}
|
|
5141
|
-
function isClaudeAgentTool(
|
|
5142
|
-
if (
|
|
5143
|
-
const properties =
|
|
5215
|
+
function isClaudeAgentTool(tool3) {
|
|
5216
|
+
if (tool3.name !== "Agent" || !isRecord2(tool3.input_schema)) return false;
|
|
5217
|
+
const properties = tool3.input_schema.properties;
|
|
5144
5218
|
if (!isRecord2(properties)) return false;
|
|
5145
5219
|
return ["description", "prompt", "subagent_type"].every((name) => isRecord2(properties[name]));
|
|
5146
5220
|
}
|
|
@@ -5230,8 +5304,8 @@ function prepareClaudeAgentInput(input, routing) {
|
|
|
5230
5304
|
clientInput.prompt = appendSubagentRouteMarker(prompt, token);
|
|
5231
5305
|
return { input: clientInput, decision };
|
|
5232
5306
|
}
|
|
5233
|
-
function augmentClaudeAgentTool(
|
|
5234
|
-
const inputSchema = isRecord2(
|
|
5307
|
+
function augmentClaudeAgentTool(tool3, routing) {
|
|
5308
|
+
const inputSchema = isRecord2(tool3.input_schema) ? tool3.input_schema : {};
|
|
5235
5309
|
const properties = isRecord2(inputSchema.properties) ? inputSchema.properties : {};
|
|
5236
5310
|
const originalModel = isRecord2(properties.model) ? properties.model : {};
|
|
5237
5311
|
const smallCatalog = routing.models.length <= MAX_MODEL_CATALOG;
|
|
@@ -5247,8 +5321,8 @@ function augmentClaudeAgentTool(tool4, routing) {
|
|
|
5247
5321
|
}
|
|
5248
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.`;
|
|
5249
5323
|
return {
|
|
5250
|
-
...
|
|
5251
|
-
description: [
|
|
5324
|
+
...tool3,
|
|
5325
|
+
description: [tool3.description?.trim(), guidance].filter(Boolean).join("\n\n"),
|
|
5252
5326
|
input_schema: {
|
|
5253
5327
|
...inputSchema,
|
|
5254
5328
|
properties: {
|
|
@@ -5580,11 +5654,7 @@ async function relayAnthropicMessages(res, messagesUrl, body, apiKey, clientWant
|
|
|
5580
5654
|
}
|
|
5581
5655
|
|
|
5582
5656
|
// src/antigravity/anthropic-to-cloudcode.ts
|
|
5583
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
5584
|
-
|
|
5585
|
-
// src/antigravity/request-adapter.ts
|
|
5586
5657
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5587
|
-
import { tool, jsonSchema } from "ai";
|
|
5588
5658
|
|
|
5589
5659
|
// src/proxy-shared.ts
|
|
5590
5660
|
function grabRoundTripSignature(part) {
|
|
@@ -5692,265 +5762,6 @@ function serializeToolResultContent(content) {
|
|
|
5692
5762
|
return JSON.stringify(content);
|
|
5693
5763
|
}
|
|
5694
5764
|
|
|
5695
|
-
// src/antigravity/request-adapter.ts
|
|
5696
|
-
var UNSUPPORTED_VOICE_MESSAGE = "Voice transcription isn\u2019t supported by Relay AI yet. Please type your message. Your coding session remains active.";
|
|
5697
|
-
var OMITTED_VOICE_TEXT = "[Voice recording omitted because transcription is not supported by Relay AI.]";
|
|
5698
|
-
function isSupportedImage(part) {
|
|
5699
|
-
return part.inlineData?.mimeType.toLowerCase().startsWith("image/") ?? false;
|
|
5700
|
-
}
|
|
5701
|
-
function isUnsupportedInlineData(part) {
|
|
5702
|
-
return !!part.inlineData && !isSupportedImage(part);
|
|
5703
|
-
}
|
|
5704
|
-
function sanitizeUnsupportedInlineData(ccReq) {
|
|
5705
|
-
const contents = ccReq.request?.contents ?? [];
|
|
5706
|
-
let latestUserIndex = -1;
|
|
5707
|
-
for (let i = contents.length - 1; i >= 0; i--) {
|
|
5708
|
-
if (contents[i].role === "user") {
|
|
5709
|
-
latestUserIndex = i;
|
|
5710
|
-
break;
|
|
5711
|
-
}
|
|
5712
|
-
}
|
|
5713
|
-
let latestUserTurnHasUnsupportedMedia = false;
|
|
5714
|
-
const sanitizedContents = contents.map((message, index) => ({
|
|
5715
|
-
...message,
|
|
5716
|
-
parts: message.parts.map((part) => {
|
|
5717
|
-
if (!isUnsupportedInlineData(part)) return part;
|
|
5718
|
-
if (index === latestUserIndex) latestUserTurnHasUnsupportedMedia = true;
|
|
5719
|
-
return { text: OMITTED_VOICE_TEXT };
|
|
5720
|
-
})
|
|
5721
|
-
}));
|
|
5722
|
-
return {
|
|
5723
|
-
request: {
|
|
5724
|
-
...ccReq,
|
|
5725
|
-
request: {
|
|
5726
|
-
...ccReq.request,
|
|
5727
|
-
contents: sanitizedContents
|
|
5728
|
-
}
|
|
5729
|
-
},
|
|
5730
|
-
latestUserTurnHasUnsupportedMedia
|
|
5731
|
-
};
|
|
5732
|
-
}
|
|
5733
|
-
function tracePartChars(part) {
|
|
5734
|
-
if (typeof part.text === "string") return part.text.length;
|
|
5735
|
-
if (part.type !== "tool-result") return void 0;
|
|
5736
|
-
const output = part.output;
|
|
5737
|
-
if (typeof output === "string") return output.length;
|
|
5738
|
-
if (output && typeof output === "object" && typeof output.value === "string") {
|
|
5739
|
-
return output.value.length;
|
|
5740
|
-
}
|
|
5741
|
-
try {
|
|
5742
|
-
return output === void 0 ? void 0 : JSON.stringify(output).length;
|
|
5743
|
-
} catch {
|
|
5744
|
-
return void 0;
|
|
5745
|
-
}
|
|
5746
|
-
}
|
|
5747
|
-
function summarizeSdkRequestForTrace(request) {
|
|
5748
|
-
const messages = request.messages.map((message) => {
|
|
5749
|
-
const content = message.content;
|
|
5750
|
-
if (typeof content === "string") {
|
|
5751
|
-
return { role: message.role, parts: [{ type: "text", chars: content.length }] };
|
|
5752
|
-
}
|
|
5753
|
-
const parts = Array.isArray(content) ? content.map((rawPart) => {
|
|
5754
|
-
const part = rawPart;
|
|
5755
|
-
const summary = {
|
|
5756
|
-
type: typeof part.type === "string" ? part.type : typeof rawPart
|
|
5757
|
-
};
|
|
5758
|
-
const chars = tracePartChars(part);
|
|
5759
|
-
if (chars !== void 0) summary.chars = chars;
|
|
5760
|
-
if (typeof part.toolName === "string") summary.toolName = part.toolName;
|
|
5761
|
-
if (typeof part.toolCallId === "string") summary.toolCallId = part.toolCallId;
|
|
5762
|
-
return summary;
|
|
5763
|
-
}) : [{ type: typeof content }];
|
|
5764
|
-
return { role: message.role, parts };
|
|
5765
|
-
});
|
|
5766
|
-
return {
|
|
5767
|
-
systemChars: request.system?.length ?? 0,
|
|
5768
|
-
messages,
|
|
5769
|
-
toolNames: Object.keys(request.tools ?? {}),
|
|
5770
|
-
...request.toolChoice ? { toolChoice: request.toolChoice } : {}
|
|
5771
|
-
};
|
|
5772
|
-
}
|
|
5773
|
-
var JSON_SCHEMA_TYPES = /* @__PURE__ */ new Map([
|
|
5774
|
-
["ARRAY", "array"],
|
|
5775
|
-
["BOOLEAN", "boolean"],
|
|
5776
|
-
["INTEGER", "integer"],
|
|
5777
|
-
["NULL", "null"],
|
|
5778
|
-
["NUMBER", "number"],
|
|
5779
|
-
["OBJECT", "object"],
|
|
5780
|
-
["STRING", "string"]
|
|
5781
|
-
]);
|
|
5782
|
-
function expandTextWithThinking(text4) {
|
|
5783
|
-
if (!text4.includes("<thinking>")) {
|
|
5784
|
-
return [{ type: "text", text: text4 }];
|
|
5785
|
-
}
|
|
5786
|
-
const out = [];
|
|
5787
|
-
const tokens = text4.split(/<thinking>([\s\S]*?)<\/thinking>/);
|
|
5788
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
5789
|
-
const token = tokens[i] ?? "";
|
|
5790
|
-
if (!token.trim()) continue;
|
|
5791
|
-
out.push({ type: i % 2 === 1 ? "reasoning" : "text", text: token });
|
|
5792
|
-
}
|
|
5793
|
-
return out.length > 0 ? out : [{ type: "text", text: text4 }];
|
|
5794
|
-
}
|
|
5795
|
-
function normalizeSchemaType(value) {
|
|
5796
|
-
if (typeof value === "string") {
|
|
5797
|
-
return JSON_SCHEMA_TYPES.get(value) ?? value;
|
|
5798
|
-
}
|
|
5799
|
-
if (Array.isArray(value)) {
|
|
5800
|
-
return value.map(normalizeSchemaType);
|
|
5801
|
-
}
|
|
5802
|
-
return value;
|
|
5803
|
-
}
|
|
5804
|
-
function normalizeJsonSchema(value) {
|
|
5805
|
-
if (Array.isArray(value)) {
|
|
5806
|
-
return value.map(normalizeJsonSchema);
|
|
5807
|
-
}
|
|
5808
|
-
if (!value || typeof value !== "object") {
|
|
5809
|
-
return value;
|
|
5810
|
-
}
|
|
5811
|
-
return Object.fromEntries(
|
|
5812
|
-
Object.entries(value).map(([key, child]) => [
|
|
5813
|
-
key,
|
|
5814
|
-
key === "type" ? normalizeSchemaType(child) : normalizeJsonSchema(child)
|
|
5815
|
-
])
|
|
5816
|
-
);
|
|
5817
|
-
}
|
|
5818
|
-
function translateTools(ccTools, options = {}) {
|
|
5819
|
-
if (!ccTools?.length) return void 0;
|
|
5820
|
-
const tools = {};
|
|
5821
|
-
let toolCount = 0;
|
|
5822
|
-
for (const t of ccTools) {
|
|
5823
|
-
if (t.functionDeclarations) {
|
|
5824
|
-
for (const fd of t.functionDeclarations) {
|
|
5825
|
-
if (options.maxTools !== void 0 && toolCount >= options.maxTools) break;
|
|
5826
|
-
tools[fd.name] = tool({
|
|
5827
|
-
description: fd.description || "",
|
|
5828
|
-
inputSchema: jsonSchema(
|
|
5829
|
-
normalizeJsonSchema(fd.parameters || { type: "object", properties: {} })
|
|
5830
|
-
)
|
|
5831
|
-
});
|
|
5832
|
-
toolCount++;
|
|
5833
|
-
}
|
|
5834
|
-
}
|
|
5835
|
-
}
|
|
5836
|
-
return Object.keys(tools).length > 0 ? tools : void 0;
|
|
5837
|
-
}
|
|
5838
|
-
function translateRequest(ccReq, options = {}) {
|
|
5839
|
-
const systemInstructions = [];
|
|
5840
|
-
const sdkMessages = [];
|
|
5841
|
-
const nameToIdList = /* @__PURE__ */ new Map();
|
|
5842
|
-
const fallbackAssistantReasoning = [...options.fallbackAssistantReasoning ?? []];
|
|
5843
|
-
const request = ccReq.request || {};
|
|
5844
|
-
if (request.systemInstruction?.parts) {
|
|
5845
|
-
for (const part of request.systemInstruction.parts) {
|
|
5846
|
-
if (part.text) {
|
|
5847
|
-
systemInstructions.push(part.text);
|
|
5848
|
-
}
|
|
5849
|
-
}
|
|
5850
|
-
}
|
|
5851
|
-
const contents = request.contents || [];
|
|
5852
|
-
for (const msg of contents) {
|
|
5853
|
-
const role = msg.role;
|
|
5854
|
-
if (role === "system") {
|
|
5855
|
-
for (const part of msg.parts) {
|
|
5856
|
-
if (part.text) {
|
|
5857
|
-
systemInstructions.push(part.text);
|
|
5858
|
-
}
|
|
5859
|
-
}
|
|
5860
|
-
continue;
|
|
5861
|
-
}
|
|
5862
|
-
const sdkRole = role === "model" ? "assistant" : "user";
|
|
5863
|
-
const hasFunctionCall = msg.parts.some((p8) => p8.functionCall);
|
|
5864
|
-
const hasAssistantReasoning = role === "model" && msg.parts.some((p8) => p8.thought || p8.text?.includes("<thinking>"));
|
|
5865
|
-
const hasComplexParts = msg.parts.some((p8) => p8.thought || p8.inlineData || p8.functionCall || p8.functionResponse);
|
|
5866
|
-
const singleText = msg.parts.length === 1 ? msg.parts[0]?.text : void 0;
|
|
5867
|
-
if (!hasComplexParts && singleText !== void 0 && !singleText.includes("<thinking>")) {
|
|
5868
|
-
sdkMessages.push({
|
|
5869
|
-
role: sdkRole,
|
|
5870
|
-
content: singleText
|
|
5871
|
-
});
|
|
5872
|
-
continue;
|
|
5873
|
-
}
|
|
5874
|
-
const contentParts = [];
|
|
5875
|
-
const toolResults = [];
|
|
5876
|
-
if (role === "model" && hasFunctionCall && !hasAssistantReasoning) {
|
|
5877
|
-
const fallback = fallbackAssistantReasoning.shift();
|
|
5878
|
-
if (fallback?.trim()) {
|
|
5879
|
-
contentParts.push({ type: "reasoning", text: fallback });
|
|
5880
|
-
}
|
|
5881
|
-
}
|
|
5882
|
-
for (const part of msg.parts) {
|
|
5883
|
-
if (part.text !== void 0) {
|
|
5884
|
-
if (part.thought) {
|
|
5885
|
-
contentParts.push({ type: "reasoning", text: part.text });
|
|
5886
|
-
} else {
|
|
5887
|
-
for (const piece of expandTextWithThinking(part.text)) {
|
|
5888
|
-
contentParts.push(piece);
|
|
5889
|
-
}
|
|
5890
|
-
}
|
|
5891
|
-
} else if (part.inlineData) {
|
|
5892
|
-
if (isSupportedImage(part)) {
|
|
5893
|
-
contentParts.push({
|
|
5894
|
-
type: "image",
|
|
5895
|
-
image: part.inlineData.data,
|
|
5896
|
-
mimeType: part.inlineData.mimeType
|
|
5897
|
-
});
|
|
5898
|
-
} else {
|
|
5899
|
-
contentParts.push({ type: "text", text: OMITTED_VOICE_TEXT });
|
|
5900
|
-
}
|
|
5901
|
-
} else if (part.functionCall) {
|
|
5902
|
-
const id = "call_" + randomUUID3().replace(/-/g, "");
|
|
5903
|
-
const name = part.functionCall.name;
|
|
5904
|
-
if (!nameToIdList.has(name)) nameToIdList.set(name, []);
|
|
5905
|
-
nameToIdList.get(name).push(id);
|
|
5906
|
-
contentParts.push({
|
|
5907
|
-
type: "tool-call",
|
|
5908
|
-
toolCallId: id,
|
|
5909
|
-
toolName: name,
|
|
5910
|
-
input: part.functionCall.args || {}
|
|
5911
|
-
});
|
|
5912
|
-
} else if (part.functionResponse) {
|
|
5913
|
-
const name = part.functionResponse.name;
|
|
5914
|
-
const idList = nameToIdList.get(name) || [];
|
|
5915
|
-
const id = idList.shift() || "call_" + randomUUID3().replace(/-/g, "");
|
|
5916
|
-
toolResults.push({
|
|
5917
|
-
type: "tool-result",
|
|
5918
|
-
toolCallId: id,
|
|
5919
|
-
toolName: name,
|
|
5920
|
-
output: { type: "text", value: serializeToolResultContent(part.functionResponse.response) }
|
|
5921
|
-
});
|
|
5922
|
-
}
|
|
5923
|
-
}
|
|
5924
|
-
if (toolResults.length > 0) {
|
|
5925
|
-
sdkMessages.push({
|
|
5926
|
-
role: "tool",
|
|
5927
|
-
content: toolResults
|
|
5928
|
-
});
|
|
5929
|
-
}
|
|
5930
|
-
if (contentParts.length > 0) {
|
|
5931
|
-
sdkMessages.push({
|
|
5932
|
-
role: sdkRole,
|
|
5933
|
-
content: contentParts
|
|
5934
|
-
});
|
|
5935
|
-
}
|
|
5936
|
-
}
|
|
5937
|
-
const system = systemInstructions.length > 0 ? systemInstructions.join("\n\n") : void 0;
|
|
5938
|
-
const tools = translateTools(request.tools, options);
|
|
5939
|
-
let toolChoice;
|
|
5940
|
-
const mode = request.toolConfig?.functionCallingConfig?.mode;
|
|
5941
|
-
if (mode === "ANY") {
|
|
5942
|
-
toolChoice = "required";
|
|
5943
|
-
} else if (mode === "AUTO" || tools) {
|
|
5944
|
-
toolChoice = "auto";
|
|
5945
|
-
}
|
|
5946
|
-
return {
|
|
5947
|
-
system,
|
|
5948
|
-
messages: sdkMessages,
|
|
5949
|
-
tools,
|
|
5950
|
-
toolChoice
|
|
5951
|
-
};
|
|
5952
|
-
}
|
|
5953
|
-
|
|
5954
5765
|
// src/antigravity/anthropic-to-cloudcode.ts
|
|
5955
5766
|
var DEFAULT_SAFETY_SETTINGS = [
|
|
5956
5767
|
{ category: "HARM_CATEGORY_HATE_SPEECH", threshold: "OFF" },
|
|
@@ -5960,7 +5771,6 @@ var DEFAULT_SAFETY_SETTINGS = [
|
|
|
5960
5771
|
];
|
|
5961
5772
|
var ANTIGRAVITY_USER_AGENT2 = "vscode/1.X.X (Antigravity/4.2.0)";
|
|
5962
5773
|
var MIN_ANTIGRAVITY_OUTPUT_TOKENS = 1024;
|
|
5963
|
-
var DISABLE_CLOUD_CODE_THINKING = { thinkingBudget: 0, includeThoughts: false };
|
|
5964
5774
|
var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
5965
5775
|
"$schema",
|
|
5966
5776
|
"$defs",
|
|
@@ -5970,6 +5780,7 @@ var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
5970
5780
|
"additionalProperties",
|
|
5971
5781
|
"propertyNames",
|
|
5972
5782
|
"patternProperties",
|
|
5783
|
+
"prefixItems",
|
|
5973
5784
|
"title",
|
|
5974
5785
|
"exclusiveMinimum",
|
|
5975
5786
|
"exclusiveMaximum",
|
|
@@ -6003,15 +5814,105 @@ var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
6003
5814
|
"examples",
|
|
6004
5815
|
"readOnly",
|
|
6005
5816
|
"writeOnly",
|
|
6006
|
-
"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"
|
|
6007
5821
|
]);
|
|
6008
|
-
|
|
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()) {
|
|
6009
5850
|
if (!obj || typeof obj !== "object") return obj;
|
|
6010
|
-
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
|
+
}
|
|
6011
5873
|
const out = {};
|
|
6012
|
-
for (const [k, v] of Object.entries(
|
|
5874
|
+
for (const [k, v] of Object.entries(source)) {
|
|
6013
5875
|
if (STRIP_KEYS.has(k) || k.startsWith("x-")) continue;
|
|
6014
|
-
|
|
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
|
+
}
|
|
6015
5916
|
}
|
|
6016
5917
|
if (Array.isArray(out.required) && out.properties && typeof out.properties === "object") {
|
|
6017
5918
|
const props = out.properties;
|
|
@@ -6072,15 +5973,18 @@ function extractSystem(system) {
|
|
|
6072
5973
|
}
|
|
6073
5974
|
return void 0;
|
|
6074
5975
|
}
|
|
6075
|
-
function
|
|
5976
|
+
function translateTools(tools) {
|
|
6076
5977
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
6077
5978
|
const decls = [];
|
|
6078
5979
|
for (const t of tools) {
|
|
6079
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";
|
|
6080
5984
|
decls.push({
|
|
6081
5985
|
name: t.name,
|
|
6082
5986
|
description: typeof t.description === "string" ? t.description : "",
|
|
6083
|
-
parameters
|
|
5987
|
+
parameters
|
|
6084
5988
|
});
|
|
6085
5989
|
}
|
|
6086
5990
|
return decls.length > 0 ? [{ functionDeclarations: decls }] : void 0;
|
|
@@ -6106,8 +6010,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6106
6010
|
}
|
|
6107
6011
|
if (typeof body.temperature === "number") generationConfig.temperature = body.temperature;
|
|
6108
6012
|
if (typeof body.top_p === "number") generationConfig.topP = body.top_p;
|
|
6109
|
-
|
|
6110
|
-
const ccTools = translateTools2(body.tools);
|
|
6013
|
+
const ccTools = translateTools(body.tools);
|
|
6111
6014
|
const systemInstruction = extractSystem(body.system);
|
|
6112
6015
|
const request = {
|
|
6113
6016
|
contents,
|
|
@@ -6121,7 +6024,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6121
6024
|
}
|
|
6122
6025
|
return {
|
|
6123
6026
|
project: projectId,
|
|
6124
|
-
requestId:
|
|
6027
|
+
requestId: randomUUID3(),
|
|
6125
6028
|
model: realModelId,
|
|
6126
6029
|
userAgent: ANTIGRAVITY_USER_AGENT2,
|
|
6127
6030
|
requestType: "agent",
|
|
@@ -6131,7 +6034,7 @@ function anthropicToCloudCode(body, realModelId, projectId) {
|
|
|
6131
6034
|
}
|
|
6132
6035
|
|
|
6133
6036
|
// src/antigravity/cloudcode-to-anthropic.ts
|
|
6134
|
-
import { randomUUID as
|
|
6037
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
6135
6038
|
function writeEvent(res, event, data) {
|
|
6136
6039
|
res.write(`event: ${event}
|
|
6137
6040
|
data: ${JSON.stringify(data)}
|
|
@@ -6221,7 +6124,7 @@ function closeBlock(res, state) {
|
|
|
6221
6124
|
}
|
|
6222
6125
|
async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
6223
6126
|
const state = {
|
|
6224
|
-
messageId: `msg_${
|
|
6127
|
+
messageId: `msg_${randomUUID4().replace(/-/g, "").slice(0, 24)}`,
|
|
6225
6128
|
model,
|
|
6226
6129
|
blockIdx: 0,
|
|
6227
6130
|
textBlockOpen: false,
|
|
@@ -6310,7 +6213,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
6310
6213
|
closeBlock(res, state);
|
|
6311
6214
|
}
|
|
6312
6215
|
for (const tc of state.toolCalls) {
|
|
6313
|
-
const rawToolId = `toolu_${
|
|
6216
|
+
const rawToolId = `toolu_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
|
|
6314
6217
|
const toolId = encodeToolUseId(rawToolId, tc.signature);
|
|
6315
6218
|
writeEvent(res, "content_block_start", {
|
|
6316
6219
|
type: "content_block_start",
|
|
@@ -6361,7 +6264,7 @@ async function streamCloudCodeToAnthropic(res, upstreamRes, model, log7) {
|
|
|
6361
6264
|
}
|
|
6362
6265
|
async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
6363
6266
|
const text4 = await upstreamRes.text();
|
|
6364
|
-
const messageId = `msg_${
|
|
6267
|
+
const messageId = `msg_${randomUUID4().replace(/-/g, "").slice(0, 24)}`;
|
|
6365
6268
|
const content = [];
|
|
6366
6269
|
let stopReason = "end_turn";
|
|
6367
6270
|
let inputTokens = 0;
|
|
@@ -6390,7 +6293,7 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
6390
6293
|
else content.push({ type: "text", text: part.text });
|
|
6391
6294
|
} else if (part.functionCall && typeof part.functionCall === "object") {
|
|
6392
6295
|
const fc = part.functionCall;
|
|
6393
|
-
const rawToolId = `toolu_${
|
|
6296
|
+
const rawToolId = `toolu_${randomUUID4().replace(/-/g, "").slice(0, 16)}`;
|
|
6394
6297
|
content.push({
|
|
6395
6298
|
type: "tool_use",
|
|
6396
6299
|
id: encodeToolUseId(rawToolId, signature ?? pendingThoughtSignature),
|
|
@@ -6423,16 +6326,16 @@ async function collectCloudCodeToAnthropic(upstreamRes, model, log7) {
|
|
|
6423
6326
|
}
|
|
6424
6327
|
|
|
6425
6328
|
// src/proxy.ts
|
|
6426
|
-
import { randomUUID as
|
|
6329
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
6427
6330
|
|
|
6428
6331
|
// src/sdk-adapter.ts
|
|
6429
|
-
import { streamText, generateText, tool
|
|
6332
|
+
import { streamText, generateText, tool, jsonSchema } from "ai";
|
|
6430
6333
|
|
|
6431
6334
|
// src/tool-search.ts
|
|
6432
6335
|
var TOOL_SEARCH_TYPE_PREFIX = "tool_search_tool";
|
|
6433
|
-
function isToolSearchTool(
|
|
6434
|
-
if (typeof
|
|
6435
|
-
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 ?? "";
|
|
6436
6339
|
return name.includes("tool_search") || name === "ToolSearch";
|
|
6437
6340
|
}
|
|
6438
6341
|
function extractReferencedToolNames(messages) {
|
|
@@ -6471,16 +6374,16 @@ function resolveUpstreamTools(tools, messages) {
|
|
|
6471
6374
|
if (!tools?.length) return [];
|
|
6472
6375
|
const referenced = extractReferencedToolNames(messages);
|
|
6473
6376
|
const upstream = [];
|
|
6474
|
-
for (const
|
|
6475
|
-
if (isToolSearchTool(
|
|
6476
|
-
upstream.push(
|
|
6377
|
+
for (const tool3 of tools) {
|
|
6378
|
+
if (isToolSearchTool(tool3)) {
|
|
6379
|
+
upstream.push(tool3);
|
|
6477
6380
|
continue;
|
|
6478
6381
|
}
|
|
6479
|
-
if (
|
|
6480
|
-
if (referenced.has(
|
|
6382
|
+
if (tool3.defer_loading === true) {
|
|
6383
|
+
if (referenced.has(tool3.name)) upstream.push(tool3);
|
|
6481
6384
|
continue;
|
|
6482
6385
|
}
|
|
6483
|
-
upstream.push(
|
|
6386
|
+
upstream.push(tool3);
|
|
6484
6387
|
}
|
|
6485
6388
|
return upstream;
|
|
6486
6389
|
}
|
|
@@ -6727,12 +6630,12 @@ function stripNullInputs(input) {
|
|
|
6727
6630
|
}
|
|
6728
6631
|
return out;
|
|
6729
6632
|
}
|
|
6730
|
-
function
|
|
6633
|
+
function translateTools2(anthropicTools) {
|
|
6731
6634
|
if (!anthropicTools?.length) return void 0;
|
|
6732
6635
|
const tools = {};
|
|
6733
6636
|
for (const t of anthropicTools) {
|
|
6734
6637
|
if (!t.name || !t.input_schema) continue;
|
|
6735
|
-
tools[t.name] =
|
|
6638
|
+
tools[t.name] = tool({ description: t.description ?? "", inputSchema: jsonSchema(t.input_schema) });
|
|
6736
6639
|
}
|
|
6737
6640
|
return Object.keys(tools).length ? tools : void 0;
|
|
6738
6641
|
}
|
|
@@ -6743,7 +6646,7 @@ function translateToolChoice(tc) {
|
|
|
6743
6646
|
if (tc.type === "tool" && tc.name) return { type: "tool", toolName: tc.name };
|
|
6744
6647
|
return void 0;
|
|
6745
6648
|
}
|
|
6746
|
-
function
|
|
6649
|
+
function translateRequest(body, npm, options) {
|
|
6747
6650
|
const messages = body.messages ?? [];
|
|
6748
6651
|
annotateToolNames(messages);
|
|
6749
6652
|
const baseSystem = systemToString(body.system);
|
|
@@ -6780,7 +6683,7 @@ function translateRequest2(body, npm, options) {
|
|
|
6780
6683
|
return {
|
|
6781
6684
|
system: options?.openAiOAuth ? void 0 : systemText,
|
|
6782
6685
|
messages: translateMessages(messages, npm, options?.onDebug),
|
|
6783
|
-
tools:
|
|
6686
|
+
tools: translateTools2(upstreamTools.length ? upstreamTools : void 0),
|
|
6784
6687
|
toolChoice: translateToolChoice(body.tool_choice),
|
|
6785
6688
|
maxOutputTokens: options?.openAiOAuth ? void 0 : body.max_tokens,
|
|
6786
6689
|
temperature: body.temperature,
|
|
@@ -7116,7 +7019,7 @@ function lookupRoute(byAlias, id) {
|
|
|
7116
7019
|
return void 0;
|
|
7117
7020
|
}
|
|
7118
7021
|
function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
7119
|
-
const proxyToken =
|
|
7022
|
+
const proxyToken = randomUUID5();
|
|
7120
7023
|
silenceSdkWarnings();
|
|
7121
7024
|
if (routes.length === 0) {
|
|
7122
7025
|
return Promise.reject(new Error("Proxy catalog requires at least one route"));
|
|
@@ -7243,7 +7146,7 @@ function startProxyCatalog(routes, defaultAliasId, debug = false) {
|
|
|
7243
7146
|
if (sessionId) {
|
|
7244
7147
|
subagentRouting.registerSubagentRoute = (modelId) => subagentRouteRegistry.register(sessionId, modelId);
|
|
7245
7148
|
}
|
|
7246
|
-
const params =
|
|
7149
|
+
const params = translateRequest(anthropicBody, route.npm, {
|
|
7247
7150
|
openAiOAuth,
|
|
7248
7151
|
maxTools: maxToolsForNpm(route.npm),
|
|
7249
7152
|
onDebug: (msg) => plog(() => msg),
|
|
@@ -10394,6 +10297,20 @@ async function refreshAntigravityOAuthModels(accessToken) {
|
|
|
10394
10297
|
}).finally(() => clearTimeout(timer));
|
|
10395
10298
|
if (!res.ok) continue;
|
|
10396
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
|
+
};
|
|
10397
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) : [];
|
|
10398
10315
|
if (raw.length === 0) continue;
|
|
10399
10316
|
const models = raw.filter((m) => typeof m.id === "string" && m.id.length > 0 && !isAntigravityCloudCodeHelperSlot(m.id)).map((m) => {
|
|
@@ -10406,7 +10323,7 @@ async function refreshAntigravityOAuthModels(accessToken) {
|
|
|
10406
10323
|
return {
|
|
10407
10324
|
id,
|
|
10408
10325
|
name,
|
|
10409
|
-
upstreamModelId: id,
|
|
10326
|
+
upstreamModelId: resolveUpstreamModelId(id),
|
|
10410
10327
|
family: isGemini ? "gemini" : id.split("-")[0] ?? id,
|
|
10411
10328
|
brand: isGemini ? "Google" : isClaude ? "Anthropic" : isOpenAi ? "OpenAI" : "Other",
|
|
10412
10329
|
contextWindow: maxTokens ?? resolveContextWindow(id),
|
|
@@ -11147,7 +11064,7 @@ async function askSaveServerPassword() {
|
|
|
11147
11064
|
import { createServer as createServer2 } from "http";
|
|
11148
11065
|
|
|
11149
11066
|
// src/openai-adapter.ts
|
|
11150
|
-
import { tool as
|
|
11067
|
+
import { tool as tool2, jsonSchema as jsonSchema2, streamText as streamText2, generateText as generateText2 } from "ai";
|
|
11151
11068
|
function translateOpenAiRequest(body) {
|
|
11152
11069
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
11153
11070
|
for (const msg of body.messages) {
|
|
@@ -11213,10 +11130,10 @@ function translateOpenAiRequest(body) {
|
|
|
11213
11130
|
tools = {};
|
|
11214
11131
|
for (const t of body.tools) {
|
|
11215
11132
|
if (t.type === "function" && t.function.name) {
|
|
11216
|
-
const schema = t.function.parameters ?
|
|
11217
|
-
tools[t.function.name] =
|
|
11133
|
+
const schema = t.function.parameters ? jsonSchema2(t.function.parameters) : void 0;
|
|
11134
|
+
tools[t.function.name] = tool2({
|
|
11218
11135
|
description: t.function.description ?? "",
|
|
11219
|
-
inputSchema: schema ??
|
|
11136
|
+
inputSchema: schema ?? jsonSchema2({ type: "object", properties: {} })
|
|
11220
11137
|
});
|
|
11221
11138
|
}
|
|
11222
11139
|
}
|
|
@@ -11506,7 +11423,7 @@ async function handleAnthropicMessages(req, res, options, modelCache, plog, suba
|
|
|
11506
11423
|
if (sessionId) {
|
|
11507
11424
|
subagentRouting.registerSubagentRoute = (modelId) => subagentRouteRegistry.register(sessionId, modelId);
|
|
11508
11425
|
}
|
|
11509
|
-
const params =
|
|
11426
|
+
const params = translateRequest(body, model.npm, {
|
|
11510
11427
|
defaultEffort: anthropicEffortFromRequest(body) ? void 0 : model.defaultEffort,
|
|
11511
11428
|
openAiOAuth: model.npm === "@ai-sdk/openai" && model.authType === "oauth",
|
|
11512
11429
|
onDebug: plog,
|
|
@@ -12982,18 +12899,18 @@ ${pc6.dim("OpenCode CLI configs: use")} relay-ai providers import${pc6.dim(" (op
|
|
|
12982
12899
|
}
|
|
12983
12900
|
|
|
12984
12901
|
// src/codex/app-launch.ts
|
|
12985
|
-
import { execSync as execSync2, spawn as
|
|
12986
|
-
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";
|
|
12987
12904
|
import { homedir as homedir7 } from "os";
|
|
12988
|
-
import { dirname as dirname5, join as join12 } from "path";
|
|
12905
|
+
import { dirname as dirname5, join as join12, win32 as winPath } from "path";
|
|
12989
12906
|
import * as p6 from "@clack/prompts";
|
|
12990
12907
|
|
|
12991
12908
|
// src/linux-display.ts
|
|
12992
|
-
import { execFileSync as
|
|
12909
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
12993
12910
|
import { readdirSync } from "fs";
|
|
12994
12911
|
function displayHasWindow(display, windowId) {
|
|
12995
12912
|
try {
|
|
12996
|
-
const output =
|
|
12913
|
+
const output = execFileSync2("xprop", ["-display", display, "-id", windowId, "WM_CLASS"], {
|
|
12997
12914
|
encoding: "utf8",
|
|
12998
12915
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12999
12916
|
});
|
|
@@ -13071,6 +12988,54 @@ function linuxEmbeddedCodexCandidates(appPath) {
|
|
|
13071
12988
|
function winLocalAppData() {
|
|
13072
12989
|
return process.env.LOCALAPPDATA ?? join12(homedir7(), "AppData", "Local");
|
|
13073
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
|
+
}
|
|
13074
13039
|
function winCodexExeCandidates() {
|
|
13075
13040
|
const local = winLocalAppData();
|
|
13076
13041
|
const bases = WIN_APP_NAMES.flatMap((name) => [
|
|
@@ -13140,14 +13105,25 @@ function findCodexApp(platform = process.platform) {
|
|
|
13140
13105
|
}
|
|
13141
13106
|
function findEmbeddedCodexBinary(platform = process.platform) {
|
|
13142
13107
|
const appPath = findCodexApp(platform);
|
|
13143
|
-
if (!appPath) return null;
|
|
13144
13108
|
if (platform === "darwin") {
|
|
13109
|
+
if (!appPath) return null;
|
|
13145
13110
|
const binary = join12(appPath, "Contents", "Resources", "codex");
|
|
13146
13111
|
return existsSync11(binary) ? binary : null;
|
|
13147
13112
|
}
|
|
13148
13113
|
if (platform === "linux") {
|
|
13114
|
+
if (!appPath) return null;
|
|
13149
13115
|
return linuxEmbeddedCodexCandidates(appPath).find((path) => existsSync11(path)) ?? null;
|
|
13150
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
|
+
}
|
|
13151
13127
|
return null;
|
|
13152
13128
|
}
|
|
13153
13129
|
function darwinIsRunning() {
|
|
@@ -13224,14 +13200,14 @@ function openCodexAppAt(path) {
|
|
|
13224
13200
|
}
|
|
13225
13201
|
if (process.platform === "win32") {
|
|
13226
13202
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13227
|
-
|
|
13203
|
+
spawn3("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13228
13204
|
} else {
|
|
13229
13205
|
runPowerShell(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13230
13206
|
}
|
|
13231
13207
|
return;
|
|
13232
13208
|
}
|
|
13233
13209
|
if (process.platform === "linux") {
|
|
13234
|
-
|
|
13210
|
+
spawn3(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
|
|
13235
13211
|
}
|
|
13236
13212
|
}
|
|
13237
13213
|
function openCodexApp() {
|
|
@@ -13275,7 +13251,7 @@ function winForceQuit() {
|
|
|
13275
13251
|
if (pids.length === 0) return;
|
|
13276
13252
|
runPowerShell(`Stop-Process -Id ${pids.join(",")} -Force -ErrorAction SilentlyContinue`);
|
|
13277
13253
|
}
|
|
13278
|
-
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) {
|
|
13279
13255
|
const appPath = findCodexApp();
|
|
13280
13256
|
if (!isCodexAppRunning()) {
|
|
13281
13257
|
if (!appPath) {
|
|
@@ -13289,6 +13265,9 @@ async function launchOrRestartCodexApp(prompt = "Restart ChatGPT Desktop to appl
|
|
|
13289
13265
|
if (process.platform === "linux") {
|
|
13290
13266
|
p6.log.info("Restarting ChatGPT Desktop to apply relay-ai settings...");
|
|
13291
13267
|
linuxQuitGraceful();
|
|
13268
|
+
} else if (assumeYes) {
|
|
13269
|
+
if (process.platform === "darwin") darwinQuit();
|
|
13270
|
+
else if (process.platform === "win32") winQuitGraceful();
|
|
13292
13271
|
} else {
|
|
13293
13272
|
const restart = await p6.confirm({ message: prompt, initialValue: true });
|
|
13294
13273
|
if (p6.isCancel(restart) || !restart) {
|
|
@@ -13310,7 +13289,7 @@ function codexAppInstallHint() {
|
|
|
13310
13289
|
}
|
|
13311
13290
|
|
|
13312
13291
|
// src/claude-desktop/app-launch.ts
|
|
13313
|
-
import { execSync as execSync3, spawn as
|
|
13292
|
+
import { execSync as execSync3, spawn as spawn4 } from "child_process";
|
|
13314
13293
|
import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync12, statSync as statSync4 } from "fs";
|
|
13315
13294
|
import { homedir as homedir8 } from "os";
|
|
13316
13295
|
import { join as join13 } from "path";
|
|
@@ -13517,14 +13496,14 @@ function openClaudeAppAt(path) {
|
|
|
13517
13496
|
}
|
|
13518
13497
|
if (process.platform === "win32") {
|
|
13519
13498
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13520
|
-
|
|
13499
|
+
spawn4("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13521
13500
|
} else {
|
|
13522
13501
|
runPowerShell2(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13523
13502
|
}
|
|
13524
13503
|
return;
|
|
13525
13504
|
}
|
|
13526
13505
|
if (process.platform === "linux") {
|
|
13527
|
-
|
|
13506
|
+
spawn4(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
|
|
13528
13507
|
}
|
|
13529
13508
|
}
|
|
13530
13509
|
function openClaudeApp() {
|
|
@@ -13610,6 +13589,8 @@ export {
|
|
|
13610
13589
|
effortProviderOptions,
|
|
13611
13590
|
deepMergeProviderOptions,
|
|
13612
13591
|
thinkingProviderOptions,
|
|
13592
|
+
runCodexCommandSync,
|
|
13593
|
+
runCodexCommand,
|
|
13613
13594
|
renderMultiAgentV2Feature,
|
|
13614
13595
|
supportsMultiAgentV2,
|
|
13615
13596
|
CODEX_APP_PROVIDER_ID,
|
|
@@ -13760,10 +13741,6 @@ export {
|
|
|
13760
13741
|
splitToolUseId,
|
|
13761
13742
|
encodeToolUseId,
|
|
13762
13743
|
serializeToolResultContent,
|
|
13763
|
-
UNSUPPORTED_VOICE_MESSAGE,
|
|
13764
|
-
sanitizeUnsupportedInlineData,
|
|
13765
|
-
summarizeSdkRequestForTrace,
|
|
13766
|
-
translateRequest,
|
|
13767
13744
|
formatUpstreamErrorTrace,
|
|
13768
13745
|
formatUpstreamError,
|
|
13769
13746
|
upstreamHttpStatus,
|
|
@@ -13841,4 +13818,4 @@ export {
|
|
|
13841
13818
|
supportsClaudeTransparentMode,
|
|
13842
13819
|
buildHttpProxyRoutes
|
|
13843
13820
|
};
|
|
13844
|
-
//# sourceMappingURL=chunk-
|
|
13821
|
+
//# sourceMappingURL=chunk-SCW2TYSG.js.map
|