@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.
@@ -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.4",
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) => execFileSync(path, args, {
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 spawn from "cross-spawn";
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 as execFileSync2 } from "child_process";
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) => execFileSync2(win ? "where.exe" : "which", [binary], {
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 = spawn(claudePath, args, {
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(tool4) {
5145
- if (tool4.name !== "Agent" || !isRecord2(tool4.input_schema)) return false;
5146
- const properties = tool4.input_schema.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(tool4, routing) {
5237
- const inputSchema = isRecord2(tool4.input_schema) ? tool4.input_schema : {};
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
- ...tool4,
5254
- description: [tool4.description?.trim(), guidance].filter(Boolean).join("\n\n"),
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
- function stripDraftMeta(obj) {
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(obj)) {
5874
+ for (const [k, v] of Object.entries(source)) {
6016
5875
  if (STRIP_KEYS.has(k) || k.startsWith("x-")) continue;
6017
- out[k] = stripDraftMeta(v);
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 translateTools2(tools) {
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: stripDraftMeta(normalizeJsonSchema(t.input_schema ?? { type: "object", properties: {} }))
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
- generationConfig.thinkingConfig = DISABLE_CLOUD_CODE_THINKING;
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: randomUUID4(),
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 randomUUID5 } from "crypto";
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_${randomUUID5().replace(/-/g, "").slice(0, 24)}`,
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_${randomUUID5().replace(/-/g, "").slice(0, 16)}`;
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_${randomUUID5().replace(/-/g, "").slice(0, 24)}`;
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_${randomUUID5().replace(/-/g, "").slice(0, 16)}`;
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 randomUUID6 } from "crypto";
6329
+ import { randomUUID as randomUUID5 } from "crypto";
6430
6330
 
6431
6331
  // src/sdk-adapter.ts
6432
- import { streamText, generateText, tool as tool2, jsonSchema as jsonSchema2 } from "ai";
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(tool4) {
6437
- if (typeof tool4.type === "string" && tool4.type.startsWith(TOOL_SEARCH_TYPE_PREFIX)) return true;
6438
- const name = tool4.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 tool4 of tools) {
6478
- if (isToolSearchTool(tool4)) {
6479
- upstream.push(tool4);
6377
+ for (const tool3 of tools) {
6378
+ if (isToolSearchTool(tool3)) {
6379
+ upstream.push(tool3);
6480
6380
  continue;
6481
6381
  }
6482
- if (tool4.defer_loading === true) {
6483
- if (referenced.has(tool4.name)) upstream.push(tool4);
6382
+ if (tool3.defer_loading === true) {
6383
+ if (referenced.has(tool3.name)) upstream.push(tool3);
6484
6384
  continue;
6485
6385
  }
6486
- upstream.push(tool4);
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 translateTools3(anthropicTools) {
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] = tool2({ description: t.description ?? "", inputSchema: jsonSchema2(t.input_schema) });
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 translateRequest2(body, npm, options) {
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: translateTools3(upstreamTools.length ? upstreamTools : void 0),
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 = randomUUID6();
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 = translateRequest2(anthropicBody, route.npm, {
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 tool3, jsonSchema as jsonSchema3, streamText as streamText2, generateText as generateText2 } from "ai";
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 ? jsonSchema3(t.function.parameters) : void 0;
11220
- tools[t.function.name] = tool3({
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 ?? jsonSchema3({ type: "object", properties: {} })
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 = translateRequest2(body, model.npm, {
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 spawn2 } from "child_process";
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 execFileSync3 } from "child_process";
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 = execFileSync3("xprop", ["-display", display, "-id", windowId, "WM_CLASS"], {
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
- spawn2("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
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
- spawn2(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
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 spawn3 } from "child_process";
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
- spawn3("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
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
- spawn3(path, [], { stdio: "ignore", detached: true, env: linuxLaunchEnv() }).unref();
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-KDIY732Q.js.map
13821
+ //# sourceMappingURL=chunk-SCW2TYSG.js.map