nolo-cli 0.16.0-alpha.9 → 0.16.0

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.
Files changed (74) hide show
  1. package/{_executeModel-ABTND4KZ.js → _executeModel-AVCA2NAV.js} +18 -19
  2. package/{agentDeleteCommand-ARMAV46L.js → agentDeleteCommand-QW5PUMDQ.js} +12 -13
  3. package/{agentEmailCommands-BKPZP4UP.js → agentEmailCommands-4ORVLGVQ.js} +23 -24
  4. package/{agentListCommands-5J7RRXUO.js → agentListCommands-YWBYRTYC.js} +14 -15
  5. package/{agentMachineCommands-VXWJXXPF.js → agentMachineCommands-JSQW4FOA.js} +12 -13
  6. package/{agentRecordCommands-INDJINPN.js → agentRecordCommands-AASIWOBT.js} +22 -23
  7. package/{agentRunCommand-KBN6HBY4.js → agentRunCommand-TB5BHXUH.js} +22 -23
  8. package/{agentRuntimeLocal-AH2RYWGP.js → agentRuntimeLocal-QNPNJRVH.js} +10 -11
  9. package/{agentSlice-R4PELU57.js → agentSlice-RUNXC62Y.js} +1 -1
  10. package/{authCommand-QU5BXRBH.js → authCommand-YFTR3347.js} +2 -8
  11. package/{chunk-ZVC2PCZN.js → chunk-33BJUVK4.js} +2 -2
  12. package/{chunk-BG7AP3Q7.js → chunk-3663CXZN.js} +11 -38
  13. package/{chunk-IFPY2BIE.js → chunk-3OIRVWXA.js} +10 -1
  14. package/{chunk-LSFAWXKC.js → chunk-3WGLLTK4.js} +3 -100
  15. package/{chunk-5Y5KEB7V.js → chunk-4FX6NVDW.js} +134 -1
  16. package/{chunk-QLWU2KOT.js → chunk-4IJYA27C.js} +1 -1
  17. package/{chunk-OELQ67TN.js → chunk-4L2OJPCU.js} +1 -1
  18. package/{chunk-HSLJ7QER.js → chunk-55NSNCFM.js} +1 -1
  19. package/{chunk-ZVDRAEZL.js → chunk-6EVITP2G.js} +250 -1
  20. package/{chunk-AFNJWHKL.js → chunk-7UKFVQ5W.js} +27 -84
  21. package/{chunk-VK2HVKAO.js → chunk-AUURUT6L.js} +193 -64
  22. package/{chunk-4N7QA72L.js → chunk-AVVZUXXC.js} +13 -34
  23. package/{chunk-2XA3QGOH.js → chunk-BEBNFWDU.js} +3 -3
  24. package/{chunk-4EME3YTO.js → chunk-DGEYDWEZ.js} +3 -3
  25. package/{chunk-XECKIDGJ.js → chunk-DPAB4FQ7.js} +126 -646
  26. package/{chunk-J3VQSU5W.js → chunk-EHLHSX7R.js} +2 -9
  27. package/{chunk-PEDT43JF.js → chunk-FRV6A633.js} +2 -2
  28. package/{chunk-VAT72PDP.js → chunk-FY233ZFU.js} +12 -13
  29. package/{chunk-LZYEWFPK.js → chunk-GSINCD4P.js} +4 -8
  30. package/{chunk-ZPPTWRPT.js → chunk-IGXREZW2.js} +1 -1
  31. package/{chunk-B4KT7RN2.js → chunk-JTMNCCWF.js} +2 -2
  32. package/{chunk-ASZ2C44S.js → chunk-LPEUV5RE.js} +2 -2
  33. package/{chunk-WVDAUR2S.js → chunk-M43KDE25.js} +1 -1
  34. package/{chunk-GWESD7AS.js → chunk-MR6ISAGB.js} +2 -2
  35. package/{chunk-LSHKV3S7.js → chunk-NSCHQQPU.js} +9 -9
  36. package/{chunk-F6JSVFHX.js → chunk-NVEWUJVX.js} +1 -1
  37. package/{chunk-R6ALN5F5.js → chunk-P3RIAYGG.js} +1 -1
  38. package/{chunk-FMYTM25W.js → chunk-PCTUYVUM.js} +1 -1
  39. package/{chunk-BHVBFI6B.js → chunk-S2LXHNHG.js} +3 -3
  40. package/{chunk-SGRDLYRZ.js → chunk-Z5JQNBNY.js} +1 -1
  41. package/{chunk-7HECYFOI.js → chunk-ZQBL7LIC.js} +22 -17
  42. package/{createAgentAutomationAction-3KKRAYGE.js → createAgentAutomationAction-FNHPSKKO.js} +4 -4
  43. package/{createDialogAction-S7NMQ4TZ.js → createDialogAction-TZCVQ3NU.js} +5 -5
  44. package/{createPageAction-2EFBT4LQ.js → createPageAction-EIGZ3BKT.js} +4 -4
  45. package/{dialogCommands-J7XFIQRD.js → dialogCommands-FO77J5DQ.js} +13 -14
  46. package/{dialogSlice-LNRRBUIC.js → dialogSlice-MM5U4KE2.js} +4 -4
  47. package/{docCreateCommands-MKO5WB34.js → docCreateCommands-I3BS3AZI.js} +15 -18
  48. package/{docDeleteCommands-RCBHRKUE.js → docDeleteCommands-Q2OPV52P.js} +14 -17
  49. package/{docReadCommands-66527P4G.js → docReadCommands-YOOFACYZ.js} +13 -16
  50. package/{docStore-67MYPX7P.js → docStore-NGYQ2JTR.js} +5 -5
  51. package/{docUpdateCommands-UT5HSLOJ.js → docUpdateCommands-2B32ITHN.js} +14 -17
  52. package/{handleSendMessageAction-VZ7226PB.js → handleSendMessageAction-JRZWWBKP.js} +4 -4
  53. package/index.js +43 -74
  54. package/{machineCommands-ATA7OSBJ.js → machineCommands-WRWF2ICZ.js} +21 -22
  55. package/{machineWsRunDispatch-ZDCZ645H.js → machineWsRunDispatch-ZX7Q3TWZ.js} +21 -22
  56. package/{models-5K5G2CZI.js → models-WQ5N4OJM.js} +1 -1
  57. package/package.json +1 -1
  58. package/{readlineWorkspace-UUNABTLB.js → readlineWorkspace-ZTGRGW46.js} +74 -75
  59. package/{runAgentClientLoop-2A577WBM.js → runAgentClientLoop-JZCOP7LG.js} +14 -15
  60. package/{spaceCommands-UNZVR2OS.js → spaceCommands-VV4GTPQK.js} +12 -13
  61. package/{spaceSlice-MC7FYPMZ.js → spaceSlice-DRWWZJP7.js} +4 -4
  62. package/{streamAgentChatTurn-IEKPNM33.js → streamAgentChatTurn-Y6WGATQR.js} +23 -21
  63. package/{tools-E6FHKTCF.js → tools-PUNBY3AH.js} +9 -9
  64. package/{tuiSummaryLlmCaller-QHPDD4WP.js → tuiSummaryLlmCaller-F64WLSAF.js} +3 -4
  65. package/{updateDialogTitleAction-SQJEEW2K.js → updateDialogTitleAction-YSR4TCMB.js} +4 -4
  66. package/appDeleteCommands-FRWMPQNS.js +0 -125
  67. package/appDeployCommands-IRF3T35Z.js +0 -164
  68. package/appDeployStatusCommands-ADFERYPU.js +0 -145
  69. package/appGetCommands-FTEOXWMS.js +0 -120
  70. package/appListCommands-WBY7UWYD.js +0 -123
  71. package/chunk-G63IH3ZK.js +0 -107
  72. package/chunk-GFUIQ4RY.js +0 -136
  73. package/chunk-KFEVY3ST.js +0 -255
  74. /package/{chunk-RK5NYQEL.js → chunk-XBS2WYJ2.js} +0 -0
@@ -3,12 +3,12 @@ import {
3
3
  refreshAntigravityOAuthToken,
4
4
  refreshOpenAiCodexToken,
5
5
  refreshXaiOAuthToken
6
- } from "./chunk-J3VQSU5W.js";
6
+ } from "./chunk-EHLHSX7R.js";
7
7
  import {
8
8
  buildLocalAgentLookupKeys,
9
9
  normalizeAgentHandle,
10
10
  shouldReadAgentKeyRemotely
11
- } from "./chunk-WVDAUR2S.js";
11
+ } from "./chunk-M43KDE25.js";
12
12
  import {
13
13
  LOCAL_CODEX_AGENT_ID,
14
14
  LOCAL_CODEX_AGENT_KEY,
@@ -21,13 +21,13 @@ import {
21
21
  import {
22
22
  inlineImageUrlsForCustomProvider,
23
23
  prepareTools
24
- } from "./chunk-PEDT43JF.js";
24
+ } from "./chunk-FRV6A633.js";
25
25
  import {
26
26
  getAntigravityUserAgent,
27
27
  isAntigravityOAuthAgent,
28
28
  readAntigravityProjectId,
29
29
  resolveAntigravityCloudCodeBaseUrl
30
- } from "./chunk-HSLJ7QER.js";
30
+ } from "./chunk-55NSNCFM.js";
31
31
  import {
32
32
  FORCED_TOOLS,
33
33
  addDefaultLightWebToolsForConfiguredAgents,
@@ -48,7 +48,7 @@ import {
48
48
  rememberMemoryFunctionSchema,
49
49
  resolveEffectiveEnabledPacks,
50
50
  resolveRunLabel
51
- } from "./chunk-7HECYFOI.js";
51
+ } from "./chunk-ZQBL7LIC.js";
52
52
  import {
53
53
  createDrainExhaustedResponse,
54
54
  isCoreDrainingBody,
@@ -60,13 +60,13 @@ import {
60
60
  } from "./chunk-OWOHNGCN.js";
61
61
  import {
62
62
  prepareTokenUsageData
63
- } from "./chunk-LSHKV3S7.js";
63
+ } from "./chunk-NSCHQQPU.js";
64
64
  import {
65
65
  BUILTIN_TITLE_LLM_CONFIG
66
66
  } from "./chunk-XOIF2TNF.js";
67
67
  import {
68
68
  fetchServerSyncedCredential
69
- } from "./chunk-BHVBFI6B.js";
69
+ } from "./chunk-S2LXHNHG.js";
70
70
  import {
71
71
  buildAgentRuntimeDialogWritePlan,
72
72
  buildLocalWorkspaceOpenAiTools,
@@ -77,10 +77,9 @@ import {
77
77
  executeLocalToolWithPolicy,
78
78
  executeOpenAiCompatibleChatCompletion,
79
79
  parseSseDataLineJson,
80
- parseSseDataLineObject,
81
80
  readOpenAiCompatibleSseCompletion,
82
81
  resolveOpenAiCompatibleProviderConfig
83
- } from "./chunk-AFNJWHKL.js";
82
+ } from "./chunk-7UKFVQ5W.js";
84
83
  import {
85
84
  buildPlatformChatCompletionRequest,
86
85
  canUsePlatformChatProvider,
@@ -89,20 +88,17 @@ import {
89
88
  readSseDataValues,
90
89
  resolvePlatformChatProviderConfig,
91
90
  shouldUsePlatformChatProvider
92
- } from "./chunk-4N7QA72L.js";
91
+ } from "./chunk-AVVZUXXC.js";
93
92
  import {
94
93
  resolveAgentRuntimeConfigFromRecord
95
94
  } from "./chunk-OIQPORYI.js";
96
95
  import {
96
+ parseToolArgumentsJson,
97
97
  summarizeToolArguments
98
- } from "./chunk-LZYEWFPK.js";
99
- import {
100
- convertMessagesToResponsesInput,
101
- toResponsesTools
102
- } from "./chunk-KFEVY3ST.js";
98
+ } from "./chunk-GSINCD4P.js";
103
99
  import {
104
100
  resolvePlatformAuthToken
105
- } from "./chunk-ZVDRAEZL.js";
101
+ } from "./chunk-6EVITP2G.js";
106
102
  import {
107
103
  buildLoadSkillExecutor,
108
104
  buildNoloWorkspaceCliToolExecutors,
@@ -110,7 +106,7 @@ import {
110
106
  canonicalizeToolNames,
111
107
  parseNoloWorkspaceToolArguments,
112
108
  resolveRuntimeToolSurfaceForAgent
113
- } from "./chunk-B4KT7RN2.js";
109
+ } from "./chunk-JTMNCCWF.js";
114
110
  import {
115
111
  clipCompactText
116
112
  } from "./chunk-5MMAK75Q.js";
@@ -156,6 +152,9 @@ import {
156
152
  import {
157
153
  DEFAULT_NOLO_SERVER_URL
158
154
  } from "./chunk-OLZBQWZU.js";
155
+ import {
156
+ asRecordOrEmpty
157
+ } from "./chunk-KX6YBIHG.js";
159
158
  import {
160
159
  createTokenKey,
161
160
  createUserKey,
@@ -167,9 +166,6 @@ import {
167
166
  import {
168
167
  asOptionalFiniteNumber
169
168
  } from "./chunk-WWC7I6TA.js";
170
- import {
171
- asTrimmedLowercaseString
172
- } from "./chunk-QSJ3HFEF.js";
173
169
  import {
174
170
  BUILTIN_NOLO_AGENT_KEY,
175
171
  PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
@@ -298,10 +294,6 @@ var STRINGS = {
298
294
  en: "Agent switch cancelled.",
299
295
  zh: "\u5DF2\u53D6\u6D88\u5207\u6362 agent\u3002"
300
296
  },
301
- agentPickerLoading: {
302
- en: "Loading agents\u2026",
303
- zh: "\u6B63\u5728\u52A0\u8F7D agent \u5217\u8868\u2026"
304
- },
305
297
  historyPickerTitle: {
306
298
  en: "Resume dialog (\u2191\u2193 Enter Esc)",
307
299
  zh: "\u6062\u590D\u5BF9\u8BDD\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
@@ -621,6 +613,10 @@ var STRINGS = {
621
613
  en: "tools",
622
614
  zh: "\u5DE5\u5177"
623
615
  },
616
+ contextFieldThinking: {
617
+ en: "thinking",
618
+ zh: "\u601D\u8003"
619
+ },
624
620
  contextFieldServer: {
625
621
  en: "server",
626
622
  zh: "\u670D\u52A1\u7AEF"
@@ -658,6 +654,7 @@ var STRINGS = {
658
654
  " /context Show workspace context and next actions",
659
655
  " /runtime <mode> Use auto, local, or server runtime",
660
656
  " /tools <mode> Control tool trace: hide, compact, verbose",
657
+ " /thinking <mode> Control thinking output: hide, marker, show",
661
658
  " /switch Pick an agent interactively (\u2191\u2193, Enter)",
662
659
  " /switch list List agents as text",
663
660
  " /switch <name> Switch directly by name, alias, or key (alias: /agent)",
@@ -694,6 +691,7 @@ var STRINGS = {
694
691
  " /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
695
692
  " /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
696
693
  " /tools <mode> \u5DE5\u5177\u8F68\u8FF9\u663E\u793A\uFF1Ahide\u3001compact\u3001verbose",
694
+ " /thinking <mode> \u601D\u8003\u8FC7\u7A0B\u663E\u793A\uFF1Ahide\u3001marker\u3001show",
697
695
  " /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
698
696
  " /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
699
697
  " /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
@@ -738,6 +736,12 @@ var STRINGS = {
738
736
  },
739
737
  toolsUsage: { en: "Usage: /tools <hide|compact|verbose>", zh: "\u7528\u6CD5\uFF1A/tools <hide|compact|verbose>" },
740
738
  toolsSet: { en: "Tool display: {0}", zh: "\u5DE5\u5177\u663E\u793A\uFF1A{0}" },
739
+ thinkingCurrent: {
740
+ en: "Thinking display: {0} (hide | marker | show)",
741
+ zh: "\u601D\u8003\u663E\u793A\uFF1A{0}\uFF08hide | marker | show\uFF09"
742
+ },
743
+ thinkingUsage: { en: "Usage: /thinking <hide|marker|show>", zh: "\u7528\u6CD5\uFF1A/thinking <hide|marker|show>" },
744
+ thinkingSet: { en: "Thinking display: {0}", zh: "\u601D\u8003\u663E\u793A\uFF1A{0}" },
741
745
  tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
742
746
  tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
743
747
  tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
@@ -2056,7 +2060,16 @@ function createCliStartAgentRunExecutor(deps = {}) {
2056
2060
 
2057
2061
  --- \u9644\u52A0\u8F93\u5165 ---
2058
2062
  ${JSON.stringify(args.input)}`;
2059
- const rawArgs = ["--agent", agentKey, "--msg-file", "PLACEHOLDER", "--bg"];
2063
+ const rawArgs = [
2064
+ "--agent",
2065
+ agentKey,
2066
+ "--msg-file",
2067
+ "PLACEHOLDER",
2068
+ "--bg",
2069
+ // 非持久化派发(review 等一次性任务):透传 --ephemeral,run 完成后不留
2070
+ // dialog 记录。与 web 端 runAgentBackground 的 ephemeral: true 对齐。
2071
+ ...args.ephemeral === true ? ["--ephemeral"] : []
2072
+ ];
2060
2073
  const agentName = typeof args.agentName === "string" && args.agentName.trim() ? args.agentName.trim() : typeof args.name === "string" && args.name.trim() ? args.name.trim() : void 0;
2061
2074
  const { runId } = await spawnLocalBackgroundRun(
2062
2075
  {
@@ -2435,22 +2448,19 @@ function resolveAntigravityWireModel(logicalModelId) {
2435
2448
  return { wireModelId: id };
2436
2449
  }
2437
2450
 
2438
- // packages/agent-runtime/geminiNativeShared.ts
2451
+ // packages/agent-runtime/antigravityCloudCodeProvider.ts
2452
+ var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
2439
2453
  var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
2440
- function isGemini3Model(modelId) {
2454
+ function isGemini3WireModel(modelId) {
2441
2455
  return modelId.includes("gemini-3");
2442
2456
  }
2443
2457
  function messageText(content) {
2444
2458
  if (typeof content === "string") return content;
2445
2459
  if (!Array.isArray(content)) return "";
2446
- return content.filter(
2447
- (part) => part?.type === "text"
2448
- ).map((part) => part.text).join("\n").trim();
2460
+ return content.filter((part) => part?.type === "text").map((part) => part.text).join("\n").trim();
2449
2461
  }
2450
2462
  function parseDataUrlToInlineData(url) {
2451
- const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
2452
- url
2453
- );
2463
+ const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(url);
2454
2464
  if (!match) return null;
2455
2465
  return { mimeType: match[1], data: match[2] };
2456
2466
  }
@@ -2467,7 +2477,7 @@ function extractInlineDataParts(content) {
2467
2477
  }
2468
2478
  return parts;
2469
2479
  }
2470
- function convertOpenAiMessagesToGemini(messages, options) {
2480
+ function convertOpenAiMessagesToCca(messages, options) {
2471
2481
  const contents = [];
2472
2482
  const systemTexts = [];
2473
2483
  const toolNamesById = /* @__PURE__ */ new Map();
@@ -2483,11 +2493,9 @@ function convertOpenAiMessagesToGemini(messages, options) {
2483
2493
  };
2484
2494
  const flushPendingFunctionCalls = () => {
2485
2495
  if (pendingFunctionCalls.length === 0) return;
2486
- const dummyResponses = pendingFunctionCalls.map(
2487
- ({ name }) => ({
2488
- functionResponse: { name, response: { output: "{}" } }
2489
- })
2490
- );
2496
+ const dummyResponses = pendingFunctionCalls.map(({ name }) => ({
2497
+ functionResponse: { name, response: { output: "{}" } }
2498
+ }));
2491
2499
  pendingFunctionCalls = [];
2492
2500
  pushOrMergeContent("user", dummyResponses);
2493
2501
  };
@@ -2496,17 +2504,13 @@ function convertOpenAiMessagesToGemini(messages, options) {
2496
2504
  const role = String(raw.role);
2497
2505
  const content = "content" in raw ? raw.content : null;
2498
2506
  if (role === "system") {
2499
- const text = messageText(
2500
- content
2501
- );
2507
+ const text = messageText(content);
2502
2508
  if (text) systemTexts.push(text);
2503
2509
  continue;
2504
2510
  }
2505
2511
  if (role === "user") {
2506
2512
  flushPendingFunctionCalls();
2507
- const text = messageText(
2508
- content
2509
- );
2513
+ const text = messageText(content);
2510
2514
  const imageParts = extractInlineDataParts(
2511
2515
  content
2512
2516
  );
@@ -2520,9 +2524,7 @@ function convertOpenAiMessagesToGemini(messages, options) {
2520
2524
  if (role === "assistant") {
2521
2525
  flushPendingFunctionCalls();
2522
2526
  const parts = [];
2523
- const text = messageText(
2524
- content
2525
- );
2527
+ const text = messageText(content);
2526
2528
  if (text) parts.push({ text });
2527
2529
  const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
2528
2530
  for (const call of toolCalls) {
@@ -2532,20 +2534,17 @@ function convertOpenAiMessagesToGemini(messages, options) {
2532
2534
  toolNamesById.set(id, name);
2533
2535
  pendingFunctionCalls.push({ name, id });
2534
2536
  const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
2535
- const isFirstFunctionCallPart = !parts.some(
2536
- (p) => "functionCall" in p
2537
- );
2538
- const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
2539
- const part = {
2537
+ const isFirstFunctionCallPart = !parts.some((p) => "functionCall" in p);
2538
+ parts.push({
2540
2539
  functionCall: {
2541
2540
  name,
2542
- args: parseToolArgs(call.function?.arguments),
2543
- ...id ? { id } : {}
2541
+ args: parseToolArgumentsJson(call.function?.arguments),
2542
+ id
2544
2543
  },
2545
- ...signature ? { thoughtSignature: signature } : {}
2546
- };
2547
- parts.push(part);
2544
+ ...realSignature ? { thoughtSignature: realSignature } : options.attachSkipThoughtSignature && isFirstFunctionCallPart ? { thoughtSignature: SKIP_THOUGHT_SIGNATURE } : {}
2545
+ });
2548
2546
  }
2547
+ if (parts.length === 0) continue;
2549
2548
  pushOrMergeContent("model", parts);
2550
2549
  continue;
2551
2550
  }
@@ -2563,39 +2562,14 @@ function convertOpenAiMessagesToGemini(messages, options) {
2563
2562
  }
2564
2563
  const output = messageText(content) || "{}";
2565
2564
  pushOrMergeContent("user", [
2566
- {
2567
- functionResponse: {
2568
- name,
2569
- response: { output },
2570
- // 保留 OpenAI tool_call_id:antigravity Cloud Code Assist 网关把
2571
- // Gemini contents 转成 Claude messages 时需要 functionResponse →
2572
- // tool_result 的 tool_use_id;缺 id 时网关报
2573
- // "tool_result.tool_use_id: Field required"(HTTP 400)。
2574
- ...toolCallId ? { id: toolCallId } : {}
2575
- }
2576
- }
2565
+ { functionResponse: { name, response: { output } } }
2577
2566
  ]);
2578
2567
  }
2579
2568
  }
2580
2569
  flushPendingFunctionCalls();
2581
2570
  return { contents, systemTexts };
2582
2571
  }
2583
- function parseToolArgs(raw) {
2584
- if (typeof raw === "string") {
2585
- try {
2586
- const parsed = JSON.parse(raw);
2587
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2588
- return parsed;
2589
- }
2590
- } catch {
2591
- }
2592
- }
2593
- if (raw && typeof raw === "object" && !Array.isArray(raw)) {
2594
- return raw;
2595
- }
2596
- return {};
2597
- }
2598
- function convertOpenAiToolsToGemini(tools) {
2572
+ function convertOpenAiTools(tools) {
2599
2573
  if (!Array.isArray(tools) || tools.length === 0) return void 0;
2600
2574
  const declarations = [];
2601
2575
  for (const tool of tools) {
@@ -2612,97 +2586,6 @@ function convertOpenAiToolsToGemini(tools) {
2612
2586
  if (declarations.length === 0) return void 0;
2613
2587
  return [{ functionDeclarations: declarations }];
2614
2588
  }
2615
- function accumulateGeminiChunks(chunks) {
2616
- let text = "";
2617
- const toolCalls = [];
2618
- let usage;
2619
- let pendingThoughtSignature;
2620
- for (const chunk of chunks) {
2621
- if (!chunk || typeof chunk !== "object") continue;
2622
- const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
2623
- if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
2624
- const meta = response.usageMetadata;
2625
- const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2626
- const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2627
- const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2628
- usage = {
2629
- prompt_tokens: prompt,
2630
- completion_tokens: candidates2,
2631
- total_tokens: total
2632
- };
2633
- }
2634
- const candidates = Array.isArray(response.candidates) ? response.candidates : [];
2635
- for (const candidate of candidates) {
2636
- if (!candidate || typeof candidate !== "object") continue;
2637
- const parts = Array.isArray(
2638
- candidate.content?.parts
2639
- ) ? candidate.content.parts : [];
2640
- for (const part of parts) {
2641
- if (!part || typeof part !== "object") continue;
2642
- const partSignature = part.thoughtSignature;
2643
- if ("text" in part && typeof part.text === "string") {
2644
- const piece = part.text;
2645
- if (!part.thought) {
2646
- text += piece;
2647
- }
2648
- }
2649
- if (part.thought && typeof partSignature === "string" && partSignature) {
2650
- pendingThoughtSignature = partSignature;
2651
- }
2652
- if ("functionCall" in part && part.functionCall) {
2653
- const call = part.functionCall;
2654
- const name = typeof call.name === "string" ? call.name : "tool";
2655
- const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
2656
- const argsObj = call.args && typeof call.args === "object" ? call.args : {};
2657
- const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
2658
- pendingThoughtSignature = void 0;
2659
- toolCalls.push({
2660
- id,
2661
- type: "function",
2662
- function: { name, arguments: JSON.stringify(argsObj) },
2663
- ...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
2664
- });
2665
- }
2666
- }
2667
- }
2668
- }
2669
- return { text, toolCalls, usage };
2670
- }
2671
- function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
2672
- return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
2673
- }
2674
- function buildGeminiGenerateContentRequest(args) {
2675
- const { contents, systemTexts } = convertOpenAiMessagesToGemini(
2676
- args.messages,
2677
- { attachSkipThoughtSignature: args.attachSkipThoughtSignature }
2678
- );
2679
- const request = { contents };
2680
- if (systemTexts.length > 0) {
2681
- request.systemInstruction = {
2682
- role: "user",
2683
- parts: systemTexts.map((text) => ({ text }))
2684
- };
2685
- }
2686
- const toolsResult = convertOpenAiToolsToGemini(args.tools);
2687
- if (toolsResult) {
2688
- request.tools = toolsResult;
2689
- request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
2690
- }
2691
- const generationConfig = {};
2692
- if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
2693
- generationConfig.maxOutputTokens = args.maxTokens;
2694
- }
2695
- if (typeof args.temperature === "number") {
2696
- generationConfig.temperature = args.temperature;
2697
- }
2698
- if (Object.keys(generationConfig).length > 0) {
2699
- request.generationConfig = generationConfig;
2700
- }
2701
- return request;
2702
- }
2703
-
2704
- // packages/agent-runtime/antigravityCloudCodeProvider.ts
2705
- var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
2706
2589
  function buildCloudCodeAssistPayload(args) {
2707
2590
  const projectId = readAntigravityProjectId(args.metadata);
2708
2591
  if (!projectId) {
@@ -2713,9 +2596,8 @@ function buildCloudCodeAssistPayload(args) {
2713
2596
  const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
2714
2597
  const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
2715
2598
  const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
2716
- const isClaude = model.toLowerCase().includes("claude");
2717
- const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
2718
- attachSkipThoughtSignature: isGemini3Model(model)
2599
+ const { contents, systemTexts } = convertOpenAiMessagesToCca(rawMessages, {
2600
+ attachSkipThoughtSignature: isGemini3WireModel(model)
2719
2601
  });
2720
2602
  if (contents.length === 0) {
2721
2603
  throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
@@ -2729,7 +2611,7 @@ function buildCloudCodeAssistPayload(args) {
2729
2611
  parts: systemTexts.map((text) => ({ text }))
2730
2612
  };
2731
2613
  }
2732
- const tools = convertOpenAiToolsToGemini(
2614
+ const tools = convertOpenAiTools(
2733
2615
  Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
2734
2616
  );
2735
2617
  if (tools) {
@@ -2752,6 +2634,7 @@ function buildCloudCodeAssistPayload(args) {
2752
2634
  const trajectoryId = randomUUID();
2753
2635
  const step = 2;
2754
2636
  const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
2637
+ const isClaude = model.toLowerCase().includes("claude");
2755
2638
  const labels = {
2756
2639
  trajectory_id: trajectoryId,
2757
2640
  last_step_index: String(step - 1),
@@ -2775,6 +2658,63 @@ function buildCloudCodeAssistPayload(args) {
2775
2658
  }
2776
2659
  };
2777
2660
  }
2661
+ function accumulateCcaChunks(chunks) {
2662
+ let text = "";
2663
+ const toolCalls = [];
2664
+ let usage;
2665
+ let pendingThoughtSignature;
2666
+ for (const chunk of chunks) {
2667
+ if (!chunk || typeof chunk !== "object") continue;
2668
+ const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
2669
+ if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
2670
+ const meta = response.usageMetadata;
2671
+ const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2672
+ const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2673
+ const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2674
+ usage = {
2675
+ prompt_tokens: prompt,
2676
+ completion_tokens: candidates2,
2677
+ total_tokens: total
2678
+ };
2679
+ }
2680
+ const candidates = Array.isArray(response.candidates) ? response.candidates : [];
2681
+ for (const candidate of candidates) {
2682
+ if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
2683
+ const content = candidate.content;
2684
+ if (!content || typeof content !== "object" || !("parts" in content)) continue;
2685
+ const parts = content.parts;
2686
+ if (!Array.isArray(parts)) continue;
2687
+ for (const part of parts) {
2688
+ if (!part || typeof part !== "object") continue;
2689
+ const partSignature = part.thoughtSignature;
2690
+ if ("text" in part && typeof part.text === "string") {
2691
+ const piece = part.text;
2692
+ if (!part.thought) {
2693
+ text += piece;
2694
+ }
2695
+ }
2696
+ if (part.thought && typeof partSignature === "string" && partSignature) {
2697
+ pendingThoughtSignature = partSignature;
2698
+ }
2699
+ if ("functionCall" in part && part.functionCall) {
2700
+ const call = part.functionCall;
2701
+ const name = typeof call.name === "string" ? call.name : "tool";
2702
+ const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
2703
+ const argsObj = asRecordOrEmpty(call.args);
2704
+ const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
2705
+ pendingThoughtSignature = void 0;
2706
+ toolCalls.push({
2707
+ id,
2708
+ type: "function",
2709
+ function: { name, arguments: JSON.stringify(argsObj) },
2710
+ ...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
2711
+ });
2712
+ }
2713
+ }
2714
+ }
2715
+ }
2716
+ return { text, toolCalls, usage };
2717
+ }
2778
2718
  async function readSseJsonChunks(response) {
2779
2719
  return readSseDataValues(response, parseSseDataLineJson);
2780
2720
  }
@@ -2799,7 +2739,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
2799
2739
  };
2800
2740
  }
2801
2741
  const chunks = await readSseJsonChunks(response);
2802
- const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
2742
+ const { text, toolCalls, usage } = accumulateCcaChunks(chunks);
2803
2743
  const message = {
2804
2744
  role: "assistant",
2805
2745
  content: text || null
@@ -2838,11 +2778,6 @@ var CLAUDE_CODE_IDENTITY_PATTERNS = [
2838
2778
  function stringValue(value) {
2839
2779
  return typeof value === "string" && value.length > 0 ? value : void 0;
2840
2780
  }
2841
- function isCacheControl(value) {
2842
- return Boolean(
2843
- value && typeof value === "object" && !Array.isArray(value) && typeof value.type === "string"
2844
- );
2845
- }
2846
2781
  function toAnthropicContent(content) {
2847
2782
  if (typeof content === "string") {
2848
2783
  return content.length > 0 ? [{ type: "text", text: content }] : [];
@@ -2853,23 +2788,17 @@ function toAnthropicContent(content) {
2853
2788
  if (!raw || typeof raw !== "object") continue;
2854
2789
  const part = raw;
2855
2790
  if ((part.type === "text" || part.type === "input_text") && typeof part.text === "string") {
2856
- if (part.text.length > 0) {
2857
- const block2 = { type: "text", text: part.text };
2858
- if (isCacheControl(part.cache_control)) block2.cache_control = part.cache_control;
2859
- blocks.push(block2);
2860
- }
2791
+ if (part.text.length > 0) blocks.push({ type: "text", text: part.text });
2861
2792
  continue;
2862
2793
  }
2863
2794
  if (part.type !== "image_url") continue;
2864
2795
  const imageUrl = typeof part.image_url === "string" ? part.image_url : stringValue(part.image_url?.url);
2865
2796
  if (!imageUrl) continue;
2866
2797
  const dataMatch = imageUrl.match(/^data:([^;,]+);base64,(.+)$/s);
2867
- const block = {
2798
+ blocks.push({
2868
2799
  type: "image",
2869
2800
  source: dataMatch ? { type: "base64", media_type: dataMatch[1], data: dataMatch[2] } : { type: "url", url: imageUrl }
2870
- };
2871
- if (isCacheControl(part.cache_control)) block.cache_control = part.cache_control;
2872
- blocks.push(block);
2801
+ });
2873
2802
  }
2874
2803
  return blocks;
2875
2804
  }
@@ -2903,15 +2832,7 @@ function buildAnthropicMessagesBody(args) {
2903
2832
  const message = raw;
2904
2833
  const role = String(message.role ?? "");
2905
2834
  if (role === "system" || role === "developer") {
2906
- const stablePrefixChars = Number(message.stable_prefix_chars);
2907
- if (typeof message.content === "string" && Number.isFinite(stablePrefixChars) && stablePrefixChars > 0 && stablePrefixChars <= message.content.length) {
2908
- const stable = message.content.slice(0, stablePrefixChars);
2909
- const dynamic = message.content.slice(stablePrefixChars);
2910
- system.push({ type: "text", text: stable, cache_control: { type: "ephemeral" } });
2911
- if (dynamic) system.push({ type: "text", text: dynamic });
2912
- } else {
2913
- system.push(...toAnthropicContent(message.content));
2914
- }
2835
+ system.push(...toAnthropicContent(message.content));
2915
2836
  continue;
2916
2837
  }
2917
2838
  if (role === "tool") {
@@ -2953,9 +2874,6 @@ function buildAnthropicMessagesBody(args) {
2953
2874
  if (!hasClaudeCodeIdentity(system)) {
2954
2875
  system.unshift({ type: "text", text: CLAUDE_CODE_SYSTEM_INSTRUCTION });
2955
2876
  }
2956
- if (system.length > 0 && !system.some((block) => isCacheControl(block.cache_control))) {
2957
- system[system.length - 1].cache_control = { type: "ephemeral" };
2958
- }
2959
2877
  const tools = Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools.flatMap((raw) => {
2960
2878
  if (!raw || typeof raw !== "object") return [];
2961
2879
  const fn = raw.function;
@@ -2970,16 +2888,6 @@ function buildAnthropicMessagesBody(args) {
2970
2888
  const model = stringValue(args.openAiBody.model) ?? args.agentConfig.model ?? "claude-sonnet-5";
2971
2889
  const maxTokensRaw = args.openAiBody.max_completion_tokens ?? args.openAiBody.max_tokens ?? args.agentConfig.max_tokens;
2972
2890
  const maxTokens = typeof maxTokensRaw === "number" && Number.isFinite(maxTokensRaw) ? Math.max(1, Math.floor(maxTokensRaw)) : 8192;
2973
- if (messages.length > 0) {
2974
- const lastMessage = messages[messages.length - 1];
2975
- const content = Array.isArray(lastMessage.content) ? lastMessage.content : [];
2976
- if (content.length > 0) {
2977
- const lastBlock = content[content.length - 1];
2978
- if (!isCacheControl(lastBlock.cache_control)) {
2979
- lastBlock.cache_control = { type: "ephemeral" };
2980
- }
2981
- }
2982
- }
2983
2891
  return {
2984
2892
  model,
2985
2893
  messages,
@@ -3011,8 +2919,6 @@ function mapAnthropicMessageToOpenAi(payload) {
3011
2919
  }
3012
2920
  const usage = payload.usage ?? {};
3013
2921
  const inputTokens = (typeof usage.input_tokens === "number" ? usage.input_tokens : 0) + (typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0) + (typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0);
3014
- const cacheCreationInputTokens = typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0;
3015
- const cacheReadInputTokens = typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0;
3016
2922
  const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : 0;
3017
2923
  const stopReason = String(payload.stop_reason ?? "");
3018
2924
  const message = { role: "assistant", content: text || null };
@@ -3028,16 +2934,9 @@ function mapAnthropicMessageToOpenAi(payload) {
3028
2934
  finish_reason: toolCalls.length > 0 || stopReason === "tool_use" ? "tool_calls" : stopReason === "max_tokens" ? "length" : "stop"
3029
2935
  }],
3030
2936
  usage: {
3031
- // prompt_tokens/input_tokens are total input, including cache read/write.
3032
- // Preserve Anthropic's components so normalization and billing can apply
3033
- // the correct cache prices without double-counting them.
3034
2937
  prompt_tokens: inputTokens,
3035
- input_tokens: inputTokens,
3036
2938
  completion_tokens: outputTokens,
3037
- output_tokens: outputTokens,
3038
- total_tokens: inputTokens + outputTokens,
3039
- cache_creation_input_tokens: cacheCreationInputTokens,
3040
- cache_read_input_tokens: cacheReadInputTokens
2939
+ total_tokens: inputTokens + outputTokens
3041
2940
  }
3042
2941
  };
3043
2942
  }
@@ -9112,262 +9011,6 @@ function isCursorOAuthAgent(agent) {
9112
9011
  return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
9113
9012
  }
9114
9013
 
9115
- // packages/agent-runtime/codexResponsesProvider.ts
9116
- import { randomUUID as randomUUID4 } from "node:crypto";
9117
- var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
9118
- var CODEX_CLIENT_VERSION = "0.144.1";
9119
- var CODEX_ORIGINATOR = "codex_cli_rs";
9120
- var CODEX_OPENAI_BETA = "responses=experimental";
9121
- var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
9122
- var CODEX_INSTALLATION_ID = randomUUID4();
9123
- function decodeCodexAccountId(accessToken) {
9124
- const parts = accessToken.split(".");
9125
- if (parts.length < 2) return void 0;
9126
- try {
9127
- const payload = JSON.parse(
9128
- Buffer.from(parts[1], "base64").toString("utf8")
9129
- );
9130
- const claim = payload[OPENAI_AUTH_CLAIM];
9131
- const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
9132
- return typeof value === "string" && value ? value : void 0;
9133
- } catch {
9134
- return void 0;
9135
- }
9136
- }
9137
- function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
9138
- const sessionId = randomUUID4();
9139
- const threadId = randomUUID4();
9140
- const windowId = randomUUID4();
9141
- const turnId = randomUUID4();
9142
- const turnMetadata = {
9143
- installation_id: installationId,
9144
- session_id: sessionId,
9145
- thread_id: threadId,
9146
- turn_id: turnId,
9147
- window_id: windowId,
9148
- request_kind: "turn",
9149
- turn_started_at_unix_ms: Date.now()
9150
- };
9151
- const turnMetadataJson = JSON.stringify(turnMetadata);
9152
- return {
9153
- sessionId,
9154
- threadId,
9155
- windowId,
9156
- turnId,
9157
- turnMetadataJson,
9158
- clientMetadata: {
9159
- "x-codex-installation-id": installationId,
9160
- session_id: sessionId,
9161
- thread_id: threadId,
9162
- "x-codex-window-id": windowId,
9163
- turn_id: turnId,
9164
- "x-codex-turn-metadata": turnMetadataJson
9165
- }
9166
- };
9167
- }
9168
- function buildCodexCompatibilityHeaders(identity, accountId) {
9169
- return {
9170
- Authorization: "",
9171
- // filled by caller with bearer token
9172
- "Content-Type": "application/json",
9173
- Accept: "text/event-stream",
9174
- "chatgpt-account-id": accountId,
9175
- "OpenAI-Beta": CODEX_OPENAI_BETA,
9176
- originator: CODEX_ORIGINATOR,
9177
- version: CODEX_CLIENT_VERSION,
9178
- session_id: identity.sessionId,
9179
- conversation_id: identity.sessionId,
9180
- "x-client-request-id": identity.sessionId,
9181
- "session-id": identity.sessionId,
9182
- "thread-id": identity.threadId,
9183
- "x-codex-window-id": identity.windowId,
9184
- "x-codex-turn-metadata": identity.turnMetadataJson
9185
- };
9186
- }
9187
- function collectInstructions(messages, agentPrompt) {
9188
- const systemTexts = [];
9189
- const prompt = agentPrompt?.trim();
9190
- if (prompt) systemTexts.push(prompt);
9191
- for (const raw of messages) {
9192
- if (!raw || typeof raw !== "object") continue;
9193
- const role = String(raw.role ?? "");
9194
- if (role !== "system" && role !== "developer") continue;
9195
- const content = raw.content;
9196
- const stringContent = asOptionalTrimmedString(content);
9197
- if (stringContent) {
9198
- systemTexts.push(stringContent);
9199
- } else if (Array.isArray(content)) {
9200
- const text = content.filter(
9201
- (p) => !!p && p.type === "text"
9202
- ).map((p) => p.text).join("\n").trim();
9203
- if (text) systemTexts.push(text);
9204
- }
9205
- }
9206
- return systemTexts.join("\n\n");
9207
- }
9208
- function collectStableInstructions(messages, fallbackPrompt) {
9209
- const systemTexts = [];
9210
- if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
9211
- for (const raw of messages) {
9212
- if (!raw || typeof raw !== "object") continue;
9213
- const message = raw;
9214
- const role = String(message.role ?? "");
9215
- if (role !== "system" && role !== "developer") continue;
9216
- if (typeof message.content === "string") {
9217
- const boundary = Number(message.stable_prefix_chars);
9218
- const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
9219
- if (text.trim()) systemTexts.push(text.trim());
9220
- }
9221
- }
9222
- return systemTexts.join("\n\n");
9223
- }
9224
- function stablePromptCacheKey(parts) {
9225
- const value = JSON.stringify(parts);
9226
- let hash = 2166136261;
9227
- for (let index = 0; index < value.length; index += 1) {
9228
- hash ^= value.charCodeAt(index);
9229
- hash = Math.imul(hash, 16777619) >>> 0;
9230
- }
9231
- return `nolo-codex-${hash.toString(16).padStart(8, "0")}`;
9232
- }
9233
- function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
9234
- const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
9235
- const nonSystem = rawMessages.filter((m) => {
9236
- const role = m && typeof m === "object" ? String(m.role) : "";
9237
- return role !== "system" && role !== "developer";
9238
- });
9239
- const input = convertMessagesToResponsesInput(nonSystem);
9240
- const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
9241
- const stableInstructions = collectStableInstructions(rawMessages, args.agentConfig.prompt);
9242
- const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
9243
- const tools = toResponsesTools(
9244
- Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
9245
- );
9246
- const body = {
9247
- model,
9248
- input,
9249
- stream: true,
9250
- store: false,
9251
- // Keep routing stable across turns and request UUIDs. Growing input/history
9252
- // is intentionally excluded; only stable request-prefix material belongs.
9253
- prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []]),
9254
- client_metadata: identity.clientMetadata
9255
- };
9256
- if (instructions) body.instructions = instructions;
9257
- if (tools && tools.length > 0) {
9258
- body.tools = tools;
9259
- body.tool_choice = "auto";
9260
- body.parallel_tool_calls = true;
9261
- }
9262
- return body;
9263
- }
9264
- function aggregateResponsesStream(events) {
9265
- let text = "";
9266
- const toolCalls = [];
9267
- let usage;
9268
- for (const ev of events) {
9269
- const type = String(ev.type ?? "");
9270
- if (type === "response.output_text.delta" && typeof ev.delta === "string") {
9271
- text += ev.delta;
9272
- continue;
9273
- }
9274
- if (type === "response.output_item.done") {
9275
- const item = ev.item;
9276
- if (item && item.type === "function_call") {
9277
- const name = typeof item.name === "string" ? item.name : "";
9278
- if (name) {
9279
- toolCalls.push({
9280
- id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
9281
- type: "function",
9282
- function: {
9283
- name,
9284
- arguments: typeof item.arguments === "string" ? item.arguments : "{}"
9285
- }
9286
- });
9287
- }
9288
- }
9289
- continue;
9290
- }
9291
- if (type === "response.completed") {
9292
- const response = ev.response;
9293
- const u = response?.usage;
9294
- if (u) {
9295
- const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
9296
- const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
9297
- const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
9298
- usage = {
9299
- prompt_tokens: prompt,
9300
- completion_tokens: completion,
9301
- total_tokens: total
9302
- };
9303
- }
9304
- }
9305
- }
9306
- return { text, toolCalls, usage };
9307
- }
9308
- async function readSseEvents(response) {
9309
- return readSseDataValues(response, (line) => {
9310
- const ev = parseSseDataLineObject(line);
9311
- return ev && !Array.isArray(ev) ? ev : null;
9312
- });
9313
- }
9314
- async function fetchCodexResponsesCompletion(args) {
9315
- const fetchImpl = args.fetchImpl ?? fetch;
9316
- const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
9317
- if (!accountId) {
9318
- return {
9319
- status: 401,
9320
- body: {
9321
- error: {
9322
- message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
9323
- }
9324
- }
9325
- };
9326
- }
9327
- const identity = createCodexRequestIdentity();
9328
- const body = buildCodexRequestBody(args, identity);
9329
- const headers = buildCodexCompatibilityHeaders(identity, accountId);
9330
- headers.Authorization = `Bearer ${args.accessToken}`;
9331
- const response = await fetchImpl(CODEX_RESPONSES_URL, {
9332
- method: "POST",
9333
- headers,
9334
- body: JSON.stringify(body),
9335
- signal: args.signal
9336
- });
9337
- if (!response.ok) {
9338
- const errorText = await response.text();
9339
- return {
9340
- status: response.status,
9341
- body: { error: { message: errorText || response.statusText } }
9342
- };
9343
- }
9344
- const events = await readSseEvents(response);
9345
- const { text, toolCalls, usage } = aggregateResponsesStream(events);
9346
- const message = {
9347
- role: "assistant",
9348
- content: text || null
9349
- };
9350
- if (toolCalls.length > 0) message.tool_calls = toolCalls;
9351
- return {
9352
- status: 200,
9353
- body: {
9354
- choices: [
9355
- {
9356
- index: 0,
9357
- message,
9358
- finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
9359
- }
9360
- ],
9361
- ...usage ? { usage } : {}
9362
- }
9363
- };
9364
- }
9365
- function isCodexOAuthAgent(agentConfig) {
9366
- if (!agentConfig) return false;
9367
- const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
9368
- return apiKeyRef === "chatgpt";
9369
- }
9370
-
9371
9014
  // packages/agent-runtime/oauthProviders.ts
9372
9015
  var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
9373
9016
  var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
@@ -10565,74 +10208,6 @@ function createCliLocalRuntimeAdapter(deps) {
10565
10208
  }
10566
10209
  };
10567
10210
  }
10568
- if (isCodexOAuthAgent(agentConfig)) {
10569
- const accessToken = await apiKeyRefResolver("chatgpt");
10570
- if (!accessToken) {
10571
- throw new Error(
10572
- 'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
10573
- );
10574
- }
10575
- const credential = readOAuthCredential("chatgpt");
10576
- const accountId = credential?.accountId;
10577
- const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
10578
- agentConfig,
10579
- deps.env,
10580
- buildProviderOpenAiTools,
10581
- additionalToolNames,
10582
- { hasUserChoice: Boolean(deps.requestUserChoice) }
10583
- );
10584
- logLocalRuntimeDiagnostic("provider.selected", {
10585
- agentKey: agentConfig.key,
10586
- transport: "codex-responses",
10587
- provider: "openai",
10588
- model: agentConfig.model ?? "gpt-5.6-sol",
10589
- hasApiKey: true
10590
- });
10591
- return {
10592
- model: agentConfig.model || "gpt-5.6-sol",
10593
- complete: async (messages, options) => {
10594
- const result = await fetchCodexResponsesCompletion({
10595
- agentConfig,
10596
- accessToken,
10597
- ...accountId ? { accountId } : {},
10598
- openAiBody: {
10599
- model: agentConfig.model || "gpt-5.6-sol",
10600
- messages,
10601
- stream: false,
10602
- ...tools2.length > 0 ? { tools: tools2 } : {}
10603
- },
10604
- fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
10605
- sleep: deps.sleep,
10606
- loopbackRequest
10607
- })
10608
- });
10609
- if (result.status < 200 || result.status >= 300) {
10610
- const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
10611
- throw new Error(
10612
- `local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
10613
- );
10614
- }
10615
- const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
10616
- const message = choice?.message ?? {};
10617
- const content = typeof message.content === "string" ? message.content : "";
10618
- const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
10619
- if (content && options?.onTextDelta) options.onTextDelta(content);
10620
- logLocalRuntimeDiagnostic("provider.request.result", {
10621
- agentKey: agentConfig.key,
10622
- transport: "codex-responses",
10623
- ok: true,
10624
- contentChars: content.length,
10625
- toolCallCount: tool_calls?.length ?? 0,
10626
- requestedToolNames: requestedToolNames2
10627
- });
10628
- return {
10629
- content,
10630
- ...tool_calls ? { tool_calls } : {},
10631
- trace: messages
10632
- };
10633
- }
10634
- };
10635
- }
10636
10211
  if (isCursorOAuthAgent(agentConfig)) {
10637
10212
  const accessToken = await apiKeyRefResolver("cursor");
10638
10213
  if (!accessToken) {
@@ -10702,101 +10277,6 @@ function createCliLocalRuntimeAdapter(deps) {
10702
10277
  }
10703
10278
  };
10704
10279
  }
10705
- if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
10706
- const providerConfig2 = await resolvePlatformChatProviderConfig({
10707
- agentConfig,
10708
- env: deps.env,
10709
- apiKeyRefResolver,
10710
- credentialBroker,
10711
- syncFetcher
10712
- });
10713
- const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
10714
- agentConfig,
10715
- deps.env,
10716
- buildProviderOpenAiTools,
10717
- additionalToolNames,
10718
- { hasUserChoice: Boolean(deps.requestUserChoice) }
10719
- );
10720
- if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
10721
- agentConfig.provider ?? "",
10722
- agentConfig.model ?? "",
10723
- tools2,
10724
- () => false
10725
- // CLI 端不区分 image 模型
10726
- )) {
10727
- logLocalRuntimeDiagnostic("provider.selected", {
10728
- agentKey: agentConfig.key,
10729
- transport: "gemini-native-tool",
10730
- apiSource: agentConfig.apiSource ?? null,
10731
- provider: providerConfig2.provider,
10732
- model: providerConfig2.model,
10733
- hasApiKey: Boolean(providerConfig2.apiKey)
10734
- });
10735
- return {
10736
- model: providerConfig2.model,
10737
- complete: async (messages, options) => {
10738
- const requestBody = buildGeminiGenerateContentRequest({
10739
- messages,
10740
- tools: tools2,
10741
- maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
10742
- temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
10743
- attachSkipThoughtSignature: true
10744
- });
10745
- const model = providerConfig2.model;
10746
- const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
10747
- logLocalRuntimeDiagnostic("provider.request.start", {
10748
- agentKey: agentConfig.key,
10749
- transport: "gemini-native-tool",
10750
- model,
10751
- messageCount: messages.length,
10752
- toolCount: tools2.length,
10753
- requestedToolNames: requestedToolNames2
10754
- });
10755
- const res = await fetchImpl(url, {
10756
- method: "POST",
10757
- headers: {
10758
- "Content-Type": "application/json",
10759
- "x-goog-api-key": providerConfig2.apiKey ?? ""
10760
- },
10761
- body: JSON.stringify(requestBody),
10762
- signal: AbortSignal.timeout(12e4)
10763
- });
10764
- if (!res.ok) {
10765
- const errText = await res.text();
10766
- logLocalRuntimeDiagnostic("provider.request.failed", {
10767
- agentKey: agentConfig.key,
10768
- transport: "gemini-native-tool",
10769
- status: res.status,
10770
- error: errText.slice(0, 200)
10771
- });
10772
- throw new Error(
10773
- `gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
10774
- );
10775
- }
10776
- const chunks = await readSseDataValues(res, parseSseDataLineJson);
10777
- const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
10778
- if (text && options?.onTextDelta) {
10779
- options.onTextDelta(text);
10780
- }
10781
- const result = {
10782
- content: text,
10783
- model,
10784
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
10785
- ...usage ? { usage } : {},
10786
- trace: messages
10787
- };
10788
- logLocalRuntimeDiagnostic("provider.request.result", {
10789
- agentKey: agentConfig.key,
10790
- transport: "gemini-native-tool",
10791
- ok: true,
10792
- contentChars: text.length,
10793
- toolCallCount: toolCalls.length
10794
- });
10795
- return result;
10796
- }
10797
- };
10798
- }
10799
- }
10800
10280
  if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
10801
10281
  const providerConfig2 = await resolvePlatformChatProviderConfig({
10802
10282
  agentConfig,