nolo-cli 0.16.0-alpha.4 → 0.16.0-alpha.6

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 (96) hide show
  1. package/{_executeModel-TZUDMB24.js → _executeModel-XF7VJZ6O.js} +28 -28
  2. package/{action-GUOZYYGN.js → action-F5JACQBG.js} +4 -4
  3. package/{addContentAction-QDGHGUBH.js → addContentAction-AQXEYRBE.js} +3 -3
  4. package/{addDialogAgentAction-Z4YCYZIV.js → addDialogAgentAction-EJHHJZWW.js} +2 -2
  5. package/{agentDeleteCommand-EMXLYNAH.js → agentDeleteCommand-X35VSSVM.js} +17 -17
  6. package/{agentEmailCommands-A4U3WMMS.js → agentEmailCommands-LGMEEMQP.js} +34 -34
  7. package/{agentListCommands-HQZNTYEG.js → agentListCommands-LLQHUE4O.js} +19 -19
  8. package/{agentMachineCommands-VFFEYHWZ.js → agentMachineCommands-4Q5PFIKF.js} +17 -17
  9. package/{agentRecordCommands-MV6SFG6W.js → agentRecordCommands-XUYVG7BS.js} +33 -33
  10. package/{agentRunCommand-5M2V6PJT.js → agentRunCommand-NORLSA7L.js} +33 -33
  11. package/{agentRuntimeLocal-WGVEZMXW.js → agentRuntimeLocal-N56G2ZJK.js} +14 -14
  12. package/{agentSlice-ILWKFTS5.js → agentSlice-JE5BREZQ.js} +3 -3
  13. package/{appDeleteCommands-N5AHOOHG.js → appDeleteCommands-WHRYDQLZ.js} +18 -18
  14. package/{appDeployCommands-GDD4CHRI.js → appDeployCommands-USRWBT6T.js} +18 -18
  15. package/{appDeployStatusCommands-3ZQH2E2A.js → appDeployStatusCommands-R632IBVL.js} +18 -18
  16. package/{appGetCommands-U4BGN2SW.js → appGetCommands-PKGC2JWH.js} +18 -18
  17. package/{appListCommands-S5BF2T4A.js → appListCommands-OMRAEOAL.js} +18 -18
  18. package/{authCommand-WKMPIXR6.js → authCommand-P22WCVOP.js} +7 -7
  19. package/{chunk-WFFFQD6S.js → chunk-2B3BNWPC.js} +2 -2
  20. package/{chunk-SFXYKGK2.js → chunk-3S2VOMIF.js} +3 -3
  21. package/{chunk-MEZVPVXM.js → chunk-3STYIYRD.js} +2 -2
  22. package/{chunk-4QQFLN5C.js → chunk-4IF3B7WC.js} +4 -4
  23. package/{chunk-WIZX3ACC.js → chunk-4XR5OJ7J.js} +1 -1
  24. package/{chunk-OGGHETUE.js → chunk-5BP2BROQ.js} +18 -16
  25. package/{chunk-OLNFFJVY.js → chunk-6EFJQCL6.js} +560 -113
  26. package/{chunk-U7LEGLEB.js → chunk-6N4KODMN.js} +1 -1
  27. package/{chunk-3GSNWWY3.js → chunk-AKYTMRBP.js} +1 -1
  28. package/{chunk-2L6OCZ6Z.js → chunk-ASZ2C44S.js} +1 -1
  29. package/{chunk-VD24AND2.js → chunk-AWGYJBWX.js} +10 -10
  30. package/{chunk-CT3XKUX4.js → chunk-BH4AZ7S6.js} +24 -24
  31. package/{chunk-I4NUTIXT.js → chunk-BOPYCNN3.js} +1 -1
  32. package/{chunk-AO2YB7PG.js → chunk-BS5STUTA.js} +3 -3
  33. package/{chunk-7LFS3UL6.js → chunk-C2BYYSAO.js} +18 -6
  34. package/{chunk-W3574B3G.js → chunk-CI2G2Z2L.js} +1 -1
  35. package/{chunk-36GPBUJ2.js → chunk-CTZLNWT3.js} +3 -3
  36. package/{chunk-TTGAVETO.js → chunk-EABWT43X.js} +2 -2
  37. package/{chunk-NY6KTTLA.js → chunk-EFNMO3YF.js} +1 -1
  38. package/{chunk-WNUSEMPU.js → chunk-FJHD7FHN.js} +1 -1
  39. package/{chunk-XVP3C2KY.js → chunk-IWLUTMYX.js} +1 -1
  40. package/{chunk-3SCCWSA3.js → chunk-J2DR42U3.js} +13 -13
  41. package/{chunk-XXUNUXCS.js → chunk-J4VLNDI7.js} +1 -1
  42. package/{chunk-4MSDMVUW.js → chunk-KFEVY3ST.js} +10 -2
  43. package/{chunk-WNLPAOIT.js → chunk-KFHN5NGJ.js} +1 -1
  44. package/{chunk-ZODEA6YR.js → chunk-KOW2R4MZ.js} +17 -12
  45. package/{chunk-27DJM3CW.js → chunk-LJIJWXIT.js} +5 -5
  46. package/{chunk-524BDL33.js → chunk-LPWS7HMQ.js} +1 -15
  47. package/{chunk-NCMP6Q3I.js → chunk-NY5FDXZL.js} +3 -3
  48. package/{chunk-OOIN7HSO.js → chunk-OIX36K6R.js} +1 -1
  49. package/{chunk-ONELX7AM.js → chunk-QSWWWYGA.js} +1 -1
  50. package/{chunk-JS33TCQ3.js → chunk-RPDGJO4D.js} +2 -2
  51. package/{chunk-IKXL2HZ3.js → chunk-UALQTIWY.js} +1 -1
  52. package/{chunk-463YM7CS.js → chunk-XBOY5KZG.js} +21 -21
  53. package/{chunk-V2J635L5.js → chunk-XOIF2TNF.js} +2 -2
  54. package/{chunk-VPTJB4HM.js → chunk-XPC5C7BK.js} +0 -3
  55. package/{chunk-TY27RYCD.js → chunk-XQW4K7D3.js} +3 -3
  56. package/{chunk-N5424GSW.js → chunk-YJKXGHJ6.js} +1 -1
  57. package/{chunk-4CANFLI7.js → chunk-YLVJ7NB4.js} +2 -2
  58. package/{chunk-JKWWVF2I.js → chunk-YQMTILRW.js} +1 -1
  59. package/{chunk-2ZDQ5PN5.js → chunk-YXQA6X6I.js} +16 -16
  60. package/chunk-ZHXJ6M7T.js +27 -0
  61. package/{chunk-LTZL7WC3.js → chunk-ZRDWHLMQ.js} +1 -1
  62. package/{chunk-MRDODOWX.js → chunk-ZTRZ2O5B.js} +3 -3
  63. package/{chunk-VOVNQ4YU.js → chunk-ZVBKL6NS.js} +4 -4
  64. package/{createAgentAutomationAction-QHGTCNTZ.js → createAgentAutomationAction-MEYL7OTC.js} +13 -13
  65. package/{createDialogAction-BEO3QLUA.js → createDialogAction-OUK5YIH4.js} +14 -14
  66. package/{createPageAction-35EGISA5.js → createPageAction-NEBMC6AB.js} +13 -13
  67. package/{dbSlice-OP6UPXKA.js → dbSlice-7KQH6GOU.js} +2 -2
  68. package/{dialogCommands-V7UHKTXT.js → dialogCommands-L4LMXQAI.js} +18 -18
  69. package/{dialogSlice-PWTRW5CX.js → dialogSlice-BKRE6NDW.js} +13 -13
  70. package/{docCreateCommands-TNC5RGE6.js → docCreateCommands-C4HJCM47.js} +17 -17
  71. package/{docDeleteCommands-PDMKS5KK.js → docDeleteCommands-Y6W6A3W6.js} +18 -18
  72. package/{docReadCommands-GGAFPAUO.js → docReadCommands-2WUIDAR6.js} +17 -17
  73. package/{docStore-BIJALNX5.js → docStore-XIPSSX7U.js} +14 -14
  74. package/{docUpdateCommands-NCZK5UPH.js → docUpdateCommands-XVL2CBKE.js} +17 -17
  75. package/{getPricing-UGDJHI7M.js → getPricing-HXWUZAEN.js} +4 -4
  76. package/{handleSendMessageAction-EN7ZJLBM.js → handleSendMessageAction-NTDBIOMZ.js} +13 -13
  77. package/index.js +47 -47
  78. package/{machineCommands-WF2VFJD2.js → machineCommands-SXOARUBD.js} +32 -32
  79. package/{machineWsRunDispatch-7675PUSK.js → machineWsRunDispatch-OZQ4WNCE.js} +32 -32
  80. package/{models-LSCRJJ6P.js → models-DQUMNIGQ.js} +2 -2
  81. package/package.json +1 -1
  82. package/{read-HXHAZBKH.js → read-CN3TNXIP.js} +1 -1
  83. package/{readDocTool-VPBDTO4G.js → readDocTool-WF3675ED.js} +1 -1
  84. package/{readlineWorkspace-4VTHXHUB.js → readlineWorkspace-AM2FA7HS.js} +36 -36
  85. package/{removeDialogAgentAction-HUFVN35S.js → removeDialogAgentAction-YDHBFEGI.js} +5 -5
  86. package/{runAgentClientLoop-ZAZSFAAO.js → runAgentClientLoop-ISTTN5QO.js} +25 -25
  87. package/{setDialogExtraReferencesAction-2VLGWQKG.js → setDialogExtraReferencesAction-LR6MSIXO.js} +2 -2
  88. package/{setPrimaryDialogAgentAction-VB4UV2CC.js → setPrimaryDialogAgentAction-IIVDCY5C.js} +5 -5
  89. package/{settingSlice-7JYPQNAC.js → settingSlice-O23YDK2O.js} +3 -3
  90. package/{spaceCommands-IASX6FPL.js → spaceCommands-PYFLKEAW.js} +17 -17
  91. package/{spaceSlice-HGDO7QJK.js → spaceSlice-QER2OEYB.js} +13 -13
  92. package/{streamAgentChatTurn-KTDBTZUL.js → streamAgentChatTurn-VBXKG5JA.js} +29 -29
  93. package/{tools-IUKU5H6C.js → tools-XMFFOQXS.js} +19 -19
  94. package/{tuiSummaryLlmCaller-RV6ZXCLV.js → tuiSummaryLlmCaller-ENLQTJUV.js} +7 -7
  95. package/{updateDialogTitleAction-6R62F4XS.js → updateDialogTitleAction-QJEJGVZD.js} +13 -13
  96. package/chunk-BYXBJQAS.js +0 -0
@@ -3,12 +3,12 @@ import {
3
3
  refreshAntigravityOAuthToken,
4
4
  refreshOpenAiCodexToken,
5
5
  refreshXaiOAuthToken
6
- } from "./chunk-XXUNUXCS.js";
6
+ } from "./chunk-J4VLNDI7.js";
7
7
  import {
8
8
  buildLocalAgentLookupKeys,
9
9
  normalizeAgentHandle,
10
10
  shouldReadAgentKeyRemotely
11
- } from "./chunk-ONELX7AM.js";
11
+ } from "./chunk-QSWWWYGA.js";
12
12
  import {
13
13
  LOCAL_CODEX_AGENT_ID,
14
14
  LOCAL_CODEX_AGENT_KEY,
@@ -17,17 +17,17 @@ import {
17
17
  } from "./chunk-VHBWHNVT.js";
18
18
  import {
19
19
  inferCaptureIntent
20
- } from "./chunk-WNLPAOIT.js";
20
+ } from "./chunk-KFHN5NGJ.js";
21
21
  import {
22
22
  inlineImageUrlsForCustomProvider,
23
23
  prepareTools
24
- } from "./chunk-MEZVPVXM.js";
24
+ } from "./chunk-3STYIYRD.js";
25
25
  import {
26
26
  getAntigravityUserAgent,
27
27
  isAntigravityOAuthAgent,
28
28
  readAntigravityProjectId,
29
29
  resolveAntigravityCloudCodeBaseUrl
30
- } from "./chunk-W3574B3G.js";
30
+ } from "./chunk-CI2G2Z2L.js";
31
31
  import {
32
32
  FORCED_TOOLS,
33
33
  addDefaultLightWebToolsForConfiguredAgents,
@@ -47,7 +47,7 @@ import {
47
47
  readXhsProfileFunctionSchema,
48
48
  rememberMemoryFunctionSchema,
49
49
  resolveEffectiveEnabledPacks
50
- } from "./chunk-CT3XKUX4.js";
50
+ } from "./chunk-BH4AZ7S6.js";
51
51
  import {
52
52
  createDrainExhaustedResponse,
53
53
  isCoreDrainingBody,
@@ -59,13 +59,13 @@ import {
59
59
  } from "./chunk-OWOHNGCN.js";
60
60
  import {
61
61
  prepareTokenUsageData
62
- } from "./chunk-463YM7CS.js";
62
+ } from "./chunk-XBOY5KZG.js";
63
63
  import {
64
64
  BUILTIN_TITLE_LLM_CONFIG
65
- } from "./chunk-V2J635L5.js";
65
+ } from "./chunk-XOIF2TNF.js";
66
66
  import {
67
67
  fetchServerSyncedCredential
68
- } from "./chunk-VOVNQ4YU.js";
68
+ } from "./chunk-ZVBKL6NS.js";
69
69
  import {
70
70
  buildAgentRuntimeDialogWritePlan,
71
71
  buildLocalWorkspaceOpenAiTools,
@@ -76,9 +76,10 @@ import {
76
76
  executeLocalToolWithPolicy,
77
77
  executeOpenAiCompatibleChatCompletion,
78
78
  parseSseDataLineJson,
79
+ parseSseDataLineObject,
79
80
  readOpenAiCompatibleSseCompletion,
80
81
  resolveOpenAiCompatibleProviderConfig
81
- } from "./chunk-7LFS3UL6.js";
82
+ } from "./chunk-C2BYYSAO.js";
82
83
  import {
83
84
  buildPlatformChatCompletionRequest,
84
85
  canUsePlatformChatProvider,
@@ -88,17 +89,20 @@ import {
88
89
  resolveLegacyDeepSeekProxyChatFallback,
89
90
  resolvePlatformChatProviderConfig,
90
91
  shouldUsePlatformChatProvider
91
- } from "./chunk-ZODEA6YR.js";
92
+ } from "./chunk-KOW2R4MZ.js";
92
93
  import {
93
94
  resolveAgentRuntimeConfigFromRecord
94
95
  } from "./chunk-OIQPORYI.js";
95
96
  import {
96
- parseToolArgumentsJson,
97
97
  summarizeToolArguments
98
- } from "./chunk-MRDODOWX.js";
98
+ } from "./chunk-ZTRZ2O5B.js";
99
+ import {
100
+ convertMessagesToResponsesInput,
101
+ toResponsesTools
102
+ } from "./chunk-KFEVY3ST.js";
99
103
  import {
100
104
  resolvePlatformAuthToken
101
- } from "./chunk-27DJM3CW.js";
105
+ } from "./chunk-LJIJWXIT.js";
102
106
  import {
103
107
  buildLoadSkillExecutor,
104
108
  buildNoloWorkspaceCliToolExecutors,
@@ -152,9 +156,6 @@ import {
152
156
  import {
153
157
  DEFAULT_NOLO_SERVER_URL
154
158
  } from "./chunk-OLZBQWZU.js";
155
- import {
156
- asRecordOrEmpty
157
- } from "./chunk-KX6YBIHG.js";
158
159
  import {
159
160
  createTokenKey,
160
161
  createUserKey,
@@ -166,14 +167,16 @@ import {
166
167
  import {
167
168
  asOptionalFiniteNumber
168
169
  } from "./chunk-WWC7I6TA.js";
170
+ import {
171
+ asTrimmedLowercaseString
172
+ } from "./chunk-QSJ3HFEF.js";
169
173
  import {
170
174
  BUILTIN_NOLO_AGENT_KEY,
171
175
  PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
172
176
  PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
173
177
  PUBLIC_GLM_52_AGENT_KEY,
174
- PUBLIC_KIMI_K26_IMAGE_AGENT_KEY,
175
- PUBLIC_KIMI_K27_CODING_AGENT_KEY
176
- } from "./chunk-VPTJB4HM.js";
178
+ PUBLIC_KIMI_K26_IMAGE_AGENT_KEY
179
+ } from "./chunk-XPC5C7BK.js";
177
180
  import {
178
181
  asTrimmedString
179
182
  } from "./chunk-3EUW3WEO.js";
@@ -1466,14 +1469,14 @@ var BUILTIN_PLATFORM_AGENT_CONFIGS = {
1466
1469
  [PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY]: {
1467
1470
  key: PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
1468
1471
  name: "DeepSeek V4 Pro",
1469
- provider: "deepseek",
1472
+ provider: "nolo",
1470
1473
  model: "deepseek-v4-pro",
1471
1474
  apiSource: "platform",
1472
1475
  useServerProxy: true,
1473
1476
  rawRecord: {
1474
1477
  dbKey: PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
1475
1478
  isPublic: true,
1476
- provider: "deepseek",
1479
+ provider: "nolo",
1477
1480
  model: "deepseek-v4-pro",
1478
1481
  apiSource: "platform",
1479
1482
  useServerProxy: true
@@ -1511,22 +1514,6 @@ var BUILTIN_PLATFORM_AGENT_CONFIGS = {
1511
1514
  useServerProxy: true
1512
1515
  }
1513
1516
  },
1514
- [PUBLIC_KIMI_K27_CODING_AGENT_KEY]: {
1515
- key: PUBLIC_KIMI_K27_CODING_AGENT_KEY,
1516
- name: "Kimi K2.7 Coding",
1517
- provider: "nolo",
1518
- model: "kimi-k2.7-code",
1519
- apiSource: "platform",
1520
- useServerProxy: true,
1521
- rawRecord: {
1522
- dbKey: PUBLIC_KIMI_K27_CODING_AGENT_KEY,
1523
- isPublic: true,
1524
- provider: "nolo",
1525
- model: "kimi-k2.7-code",
1526
- apiSource: "platform",
1527
- useServerProxy: true
1528
- }
1529
- },
1530
1517
  [BUILTIN_NOLO_AGENT_KEY]: {
1531
1518
  key: BUILTIN_NOLO_AGENT_KEY,
1532
1519
  name: "Nolo",
@@ -2448,19 +2435,22 @@ function resolveAntigravityWireModel(logicalModelId) {
2448
2435
  return { wireModelId: id };
2449
2436
  }
2450
2437
 
2451
- // packages/agent-runtime/antigravityCloudCodeProvider.ts
2452
- var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
2438
+ // packages/agent-runtime/geminiNativeShared.ts
2453
2439
  var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
2454
- function isGemini3WireModel(modelId) {
2440
+ function isGemini3Model(modelId) {
2455
2441
  return modelId.includes("gemini-3");
2456
2442
  }
2457
2443
  function messageText(content) {
2458
2444
  if (typeof content === "string") return content;
2459
2445
  if (!Array.isArray(content)) return "";
2460
- return content.filter((part) => part?.type === "text").map((part) => part.text).join("\n").trim();
2446
+ return content.filter(
2447
+ (part) => part?.type === "text"
2448
+ ).map((part) => part.text).join("\n").trim();
2461
2449
  }
2462
2450
  function parseDataUrlToInlineData(url) {
2463
- const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(url);
2451
+ const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
2452
+ url
2453
+ );
2464
2454
  if (!match) return null;
2465
2455
  return { mimeType: match[1], data: match[2] };
2466
2456
  }
@@ -2477,7 +2467,7 @@ function extractInlineDataParts(content) {
2477
2467
  }
2478
2468
  return parts;
2479
2469
  }
2480
- function convertOpenAiMessagesToCca(messages, options) {
2470
+ function convertOpenAiMessagesToGemini(messages, options) {
2481
2471
  const contents = [];
2482
2472
  const systemTexts = [];
2483
2473
  const toolNamesById = /* @__PURE__ */ new Map();
@@ -2493,9 +2483,11 @@ function convertOpenAiMessagesToCca(messages, options) {
2493
2483
  };
2494
2484
  const flushPendingFunctionCalls = () => {
2495
2485
  if (pendingFunctionCalls.length === 0) return;
2496
- const dummyResponses = pendingFunctionCalls.map(({ name }) => ({
2497
- functionResponse: { name, response: { output: "{}" } }
2498
- }));
2486
+ const dummyResponses = pendingFunctionCalls.map(
2487
+ ({ name }) => ({
2488
+ functionResponse: { name, response: { output: "{}" } }
2489
+ })
2490
+ );
2499
2491
  pendingFunctionCalls = [];
2500
2492
  pushOrMergeContent("user", dummyResponses);
2501
2493
  };
@@ -2504,13 +2496,17 @@ function convertOpenAiMessagesToCca(messages, options) {
2504
2496
  const role = String(raw.role);
2505
2497
  const content = "content" in raw ? raw.content : null;
2506
2498
  if (role === "system") {
2507
- const text = messageText(content);
2499
+ const text = messageText(
2500
+ content
2501
+ );
2508
2502
  if (text) systemTexts.push(text);
2509
2503
  continue;
2510
2504
  }
2511
2505
  if (role === "user") {
2512
2506
  flushPendingFunctionCalls();
2513
- const text = messageText(content);
2507
+ const text = messageText(
2508
+ content
2509
+ );
2514
2510
  const imageParts = extractInlineDataParts(
2515
2511
  content
2516
2512
  );
@@ -2524,7 +2520,9 @@ function convertOpenAiMessagesToCca(messages, options) {
2524
2520
  if (role === "assistant") {
2525
2521
  flushPendingFunctionCalls();
2526
2522
  const parts = [];
2527
- const text = messageText(content);
2523
+ const text = messageText(
2524
+ content
2525
+ );
2528
2526
  if (text) parts.push({ text });
2529
2527
  const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
2530
2528
  for (const call of toolCalls) {
@@ -2534,17 +2532,20 @@ function convertOpenAiMessagesToCca(messages, options) {
2534
2532
  toolNamesById.set(id, name);
2535
2533
  pendingFunctionCalls.push({ name, id });
2536
2534
  const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
2537
- const isFirstFunctionCallPart = !parts.some((p) => "functionCall" in p);
2538
- parts.push({
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 = {
2539
2540
  functionCall: {
2540
2541
  name,
2541
- args: parseToolArgumentsJson(call.function?.arguments),
2542
- id
2542
+ args: parseToolArgs(call.function?.arguments),
2543
+ ...id ? { id } : {}
2543
2544
  },
2544
- ...realSignature ? { thoughtSignature: realSignature } : options.attachSkipThoughtSignature && isFirstFunctionCallPart ? { thoughtSignature: SKIP_THOUGHT_SIGNATURE } : {}
2545
- });
2545
+ ...signature ? { thoughtSignature: signature } : {}
2546
+ };
2547
+ parts.push(part);
2546
2548
  }
2547
- if (parts.length === 0) continue;
2548
2549
  pushOrMergeContent("model", parts);
2549
2550
  continue;
2550
2551
  }
@@ -2569,7 +2570,22 @@ function convertOpenAiMessagesToCca(messages, options) {
2569
2570
  flushPendingFunctionCalls();
2570
2571
  return { contents, systemTexts };
2571
2572
  }
2572
- function convertOpenAiTools(tools) {
2573
+ function parseToolArgs(raw) {
2574
+ if (typeof raw === "string") {
2575
+ try {
2576
+ const parsed = JSON.parse(raw);
2577
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2578
+ return parsed;
2579
+ }
2580
+ } catch {
2581
+ }
2582
+ }
2583
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
2584
+ return raw;
2585
+ }
2586
+ return {};
2587
+ }
2588
+ function convertOpenAiToolsToGemini(tools) {
2573
2589
  if (!Array.isArray(tools) || tools.length === 0) return void 0;
2574
2590
  const declarations = [];
2575
2591
  for (const tool of tools) {
@@ -2586,6 +2602,97 @@ function convertOpenAiTools(tools) {
2586
2602
  if (declarations.length === 0) return void 0;
2587
2603
  return [{ functionDeclarations: declarations }];
2588
2604
  }
2605
+ function accumulateGeminiChunks(chunks) {
2606
+ let text = "";
2607
+ const toolCalls = [];
2608
+ let usage;
2609
+ let pendingThoughtSignature;
2610
+ for (const chunk of chunks) {
2611
+ if (!chunk || typeof chunk !== "object") continue;
2612
+ const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
2613
+ if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
2614
+ const meta = response.usageMetadata;
2615
+ const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2616
+ const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2617
+ const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2618
+ usage = {
2619
+ prompt_tokens: prompt,
2620
+ completion_tokens: candidates2,
2621
+ total_tokens: total
2622
+ };
2623
+ }
2624
+ const candidates = Array.isArray(response.candidates) ? response.candidates : [];
2625
+ for (const candidate of candidates) {
2626
+ if (!candidate || typeof candidate !== "object") continue;
2627
+ const parts = Array.isArray(
2628
+ candidate.content?.parts
2629
+ ) ? candidate.content.parts : [];
2630
+ for (const part of parts) {
2631
+ if (!part || typeof part !== "object") continue;
2632
+ const partSignature = part.thoughtSignature;
2633
+ if ("text" in part && typeof part.text === "string") {
2634
+ const piece = part.text;
2635
+ if (!part.thought) {
2636
+ text += piece;
2637
+ }
2638
+ }
2639
+ if (part.thought && typeof partSignature === "string" && partSignature) {
2640
+ pendingThoughtSignature = partSignature;
2641
+ }
2642
+ if ("functionCall" in part && part.functionCall) {
2643
+ const call = part.functionCall;
2644
+ const name = typeof call.name === "string" ? call.name : "tool";
2645
+ const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
2646
+ const argsObj = call.args && typeof call.args === "object" ? call.args : {};
2647
+ const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
2648
+ pendingThoughtSignature = void 0;
2649
+ toolCalls.push({
2650
+ id,
2651
+ type: "function",
2652
+ function: { name, arguments: JSON.stringify(argsObj) },
2653
+ ...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
2654
+ });
2655
+ }
2656
+ }
2657
+ }
2658
+ }
2659
+ return { text, toolCalls, usage };
2660
+ }
2661
+ function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
2662
+ return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
2663
+ }
2664
+ function buildGeminiGenerateContentRequest(args) {
2665
+ const { contents, systemTexts } = convertOpenAiMessagesToGemini(
2666
+ args.messages,
2667
+ { attachSkipThoughtSignature: args.attachSkipThoughtSignature }
2668
+ );
2669
+ const request = { contents };
2670
+ if (systemTexts.length > 0) {
2671
+ request.systemInstruction = {
2672
+ role: "user",
2673
+ parts: systemTexts.map((text) => ({ text }))
2674
+ };
2675
+ }
2676
+ const toolsResult = convertOpenAiToolsToGemini(args.tools);
2677
+ if (toolsResult) {
2678
+ request.tools = toolsResult;
2679
+ request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
2680
+ }
2681
+ const generationConfig = {};
2682
+ if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
2683
+ generationConfig.maxOutputTokens = args.maxTokens;
2684
+ }
2685
+ if (typeof args.temperature === "number") {
2686
+ generationConfig.temperature = args.temperature;
2687
+ }
2688
+ if (Object.keys(generationConfig).length > 0) {
2689
+ request.generationConfig = generationConfig;
2690
+ }
2691
+ return request;
2692
+ }
2693
+
2694
+ // packages/agent-runtime/antigravityCloudCodeProvider.ts
2695
+ var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
2589
2696
  function buildCloudCodeAssistPayload(args) {
2590
2697
  const projectId = readAntigravityProjectId(args.metadata);
2591
2698
  if (!projectId) {
@@ -2596,8 +2703,8 @@ function buildCloudCodeAssistPayload(args) {
2596
2703
  const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
2597
2704
  const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
2598
2705
  const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
2599
- const { contents, systemTexts } = convertOpenAiMessagesToCca(rawMessages, {
2600
- attachSkipThoughtSignature: isGemini3WireModel(model)
2706
+ const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
2707
+ attachSkipThoughtSignature: isGemini3Model(model)
2601
2708
  });
2602
2709
  if (contents.length === 0) {
2603
2710
  throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
@@ -2611,7 +2718,7 @@ function buildCloudCodeAssistPayload(args) {
2611
2718
  parts: systemTexts.map((text) => ({ text }))
2612
2719
  };
2613
2720
  }
2614
- const tools = convertOpenAiTools(
2721
+ const tools = convertOpenAiToolsToGemini(
2615
2722
  Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
2616
2723
  );
2617
2724
  if (tools) {
@@ -2658,57 +2765,6 @@ function buildCloudCodeAssistPayload(args) {
2658
2765
  }
2659
2766
  };
2660
2767
  }
2661
- function accumulateCcaChunks(chunks) {
2662
- let text = "";
2663
- const toolCalls = [];
2664
- let usage;
2665
- for (const chunk of chunks) {
2666
- if (!chunk || typeof chunk !== "object") continue;
2667
- const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
2668
- if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
2669
- const meta = response.usageMetadata;
2670
- const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2671
- const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2672
- const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2673
- usage = {
2674
- prompt_tokens: prompt,
2675
- completion_tokens: candidates2,
2676
- total_tokens: total
2677
- };
2678
- }
2679
- const candidates = Array.isArray(response.candidates) ? response.candidates : [];
2680
- for (const candidate of candidates) {
2681
- if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
2682
- const content = candidate.content;
2683
- if (!content || typeof content !== "object" || !("parts" in content)) continue;
2684
- const parts = content.parts;
2685
- if (!Array.isArray(parts)) continue;
2686
- for (const part of parts) {
2687
- if (!part || typeof part !== "object") continue;
2688
- const partSignature = part.thoughtSignature;
2689
- if ("text" in part && typeof part.text === "string") {
2690
- const piece = part.text;
2691
- if (!part.thought) {
2692
- text += piece;
2693
- }
2694
- }
2695
- if ("functionCall" in part && part.functionCall) {
2696
- const call = part.functionCall;
2697
- const name = typeof call.name === "string" ? call.name : "tool";
2698
- const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
2699
- const argsObj = asRecordOrEmpty(call.args);
2700
- toolCalls.push({
2701
- id,
2702
- type: "function",
2703
- function: { name, arguments: JSON.stringify(argsObj) },
2704
- ...typeof partSignature === "string" && partSignature ? { thought_signature: partSignature } : {}
2705
- });
2706
- }
2707
- }
2708
- }
2709
- }
2710
- return { text, toolCalls, usage };
2711
- }
2712
2768
  async function readSseJsonChunks(response) {
2713
2769
  return readSseDataValues(response, parseSseDataLineJson);
2714
2770
  }
@@ -2733,7 +2789,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
2733
2789
  };
2734
2790
  }
2735
2791
  const chunks = await readSseJsonChunks(response);
2736
- const { text, toolCalls, usage } = accumulateCcaChunks(chunks);
2792
+ const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
2737
2793
  const message = {
2738
2794
  role: "assistant",
2739
2795
  content: text || null
@@ -9032,6 +9088,234 @@ function isCursorOAuthAgent(agent) {
9032
9088
  return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
9033
9089
  }
9034
9090
 
9091
+ // packages/agent-runtime/codexResponsesProvider.ts
9092
+ import { randomUUID as randomUUID4 } from "node:crypto";
9093
+ var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
9094
+ var CODEX_CLIENT_VERSION = "0.144.1";
9095
+ var CODEX_ORIGINATOR = "codex_cli_rs";
9096
+ var CODEX_OPENAI_BETA = "responses=experimental";
9097
+ var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
9098
+ var CODEX_INSTALLATION_ID = randomUUID4();
9099
+ function decodeCodexAccountId(accessToken) {
9100
+ const parts = accessToken.split(".");
9101
+ if (parts.length < 2) return void 0;
9102
+ try {
9103
+ const payload = JSON.parse(
9104
+ Buffer.from(parts[1], "base64").toString("utf8")
9105
+ );
9106
+ const claim = payload[OPENAI_AUTH_CLAIM];
9107
+ const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
9108
+ return typeof value === "string" && value ? value : void 0;
9109
+ } catch {
9110
+ return void 0;
9111
+ }
9112
+ }
9113
+ function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
9114
+ const sessionId = randomUUID4();
9115
+ const threadId = randomUUID4();
9116
+ const windowId = randomUUID4();
9117
+ const turnId = randomUUID4();
9118
+ const turnMetadata = {
9119
+ installation_id: installationId,
9120
+ session_id: sessionId,
9121
+ thread_id: threadId,
9122
+ turn_id: turnId,
9123
+ window_id: windowId,
9124
+ request_kind: "turn",
9125
+ turn_started_at_unix_ms: Date.now()
9126
+ };
9127
+ const turnMetadataJson = JSON.stringify(turnMetadata);
9128
+ return {
9129
+ sessionId,
9130
+ threadId,
9131
+ windowId,
9132
+ turnId,
9133
+ turnMetadataJson,
9134
+ clientMetadata: {
9135
+ "x-codex-installation-id": installationId,
9136
+ session_id: sessionId,
9137
+ thread_id: threadId,
9138
+ "x-codex-window-id": windowId,
9139
+ turn_id: turnId,
9140
+ "x-codex-turn-metadata": turnMetadataJson
9141
+ }
9142
+ };
9143
+ }
9144
+ function buildCodexCompatibilityHeaders(identity, accountId) {
9145
+ return {
9146
+ Authorization: "",
9147
+ // filled by caller with bearer token
9148
+ "Content-Type": "application/json",
9149
+ Accept: "text/event-stream",
9150
+ "chatgpt-account-id": accountId,
9151
+ "OpenAI-Beta": CODEX_OPENAI_BETA,
9152
+ originator: CODEX_ORIGINATOR,
9153
+ version: CODEX_CLIENT_VERSION,
9154
+ session_id: identity.sessionId,
9155
+ conversation_id: identity.sessionId,
9156
+ "x-client-request-id": identity.sessionId,
9157
+ "session-id": identity.sessionId,
9158
+ "thread-id": identity.threadId,
9159
+ "x-codex-window-id": identity.windowId,
9160
+ "x-codex-turn-metadata": identity.turnMetadataJson
9161
+ };
9162
+ }
9163
+ function collectInstructions(messages, agentPrompt) {
9164
+ const systemTexts = [];
9165
+ const prompt = agentPrompt?.trim();
9166
+ if (prompt) systemTexts.push(prompt);
9167
+ for (const raw of messages) {
9168
+ if (!raw || typeof raw !== "object") continue;
9169
+ const role = String(raw.role ?? "");
9170
+ if (role !== "system" && role !== "developer") continue;
9171
+ const content = raw.content;
9172
+ const stringContent = asOptionalTrimmedString(content);
9173
+ if (stringContent) {
9174
+ systemTexts.push(stringContent);
9175
+ } else if (Array.isArray(content)) {
9176
+ const text = content.filter(
9177
+ (p) => !!p && p.type === "text"
9178
+ ).map((p) => p.text).join("\n").trim();
9179
+ if (text) systemTexts.push(text);
9180
+ }
9181
+ }
9182
+ return systemTexts.join("\n\n");
9183
+ }
9184
+ function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
9185
+ const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
9186
+ const nonSystem = rawMessages.filter((m) => {
9187
+ const role = m && typeof m === "object" ? String(m.role) : "";
9188
+ return role !== "system" && role !== "developer";
9189
+ });
9190
+ const input = convertMessagesToResponsesInput(nonSystem);
9191
+ const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
9192
+ const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
9193
+ const tools = toResponsesTools(
9194
+ Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
9195
+ );
9196
+ const body = {
9197
+ model,
9198
+ input,
9199
+ stream: true,
9200
+ store: false,
9201
+ prompt_cache_key: identity.sessionId,
9202
+ client_metadata: identity.clientMetadata
9203
+ };
9204
+ if (instructions) body.instructions = instructions;
9205
+ if (tools && tools.length > 0) {
9206
+ body.tools = tools;
9207
+ body.tool_choice = "auto";
9208
+ body.parallel_tool_calls = true;
9209
+ }
9210
+ return body;
9211
+ }
9212
+ function aggregateResponsesStream(events) {
9213
+ let text = "";
9214
+ const toolCalls = [];
9215
+ let usage;
9216
+ for (const ev of events) {
9217
+ const type = String(ev.type ?? "");
9218
+ if (type === "response.output_text.delta" && typeof ev.delta === "string") {
9219
+ text += ev.delta;
9220
+ continue;
9221
+ }
9222
+ if (type === "response.output_item.done") {
9223
+ const item = ev.item;
9224
+ if (item && item.type === "function_call") {
9225
+ const name = typeof item.name === "string" ? item.name : "";
9226
+ if (name) {
9227
+ toolCalls.push({
9228
+ id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
9229
+ type: "function",
9230
+ function: {
9231
+ name,
9232
+ arguments: typeof item.arguments === "string" ? item.arguments : "{}"
9233
+ }
9234
+ });
9235
+ }
9236
+ }
9237
+ continue;
9238
+ }
9239
+ if (type === "response.completed") {
9240
+ const response = ev.response;
9241
+ const u = response?.usage;
9242
+ if (u) {
9243
+ const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
9244
+ const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
9245
+ const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
9246
+ usage = {
9247
+ prompt_tokens: prompt,
9248
+ completion_tokens: completion,
9249
+ total_tokens: total
9250
+ };
9251
+ }
9252
+ }
9253
+ }
9254
+ return { text, toolCalls, usage };
9255
+ }
9256
+ async function readSseEvents(response) {
9257
+ return readSseDataValues(response, (line) => {
9258
+ const ev = parseSseDataLineObject(line);
9259
+ return ev && !Array.isArray(ev) ? ev : null;
9260
+ });
9261
+ }
9262
+ async function fetchCodexResponsesCompletion(args) {
9263
+ const fetchImpl = args.fetchImpl ?? fetch;
9264
+ const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
9265
+ if (!accountId) {
9266
+ return {
9267
+ status: 401,
9268
+ body: {
9269
+ error: {
9270
+ message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
9271
+ }
9272
+ }
9273
+ };
9274
+ }
9275
+ const identity = createCodexRequestIdentity();
9276
+ const body = buildCodexRequestBody(args, identity);
9277
+ const headers = buildCodexCompatibilityHeaders(identity, accountId);
9278
+ headers.Authorization = `Bearer ${args.accessToken}`;
9279
+ const response = await fetchImpl(CODEX_RESPONSES_URL, {
9280
+ method: "POST",
9281
+ headers,
9282
+ body: JSON.stringify(body),
9283
+ signal: args.signal
9284
+ });
9285
+ if (!response.ok) {
9286
+ const errorText = await response.text();
9287
+ return {
9288
+ status: response.status,
9289
+ body: { error: { message: errorText || response.statusText } }
9290
+ };
9291
+ }
9292
+ const events = await readSseEvents(response);
9293
+ const { text, toolCalls, usage } = aggregateResponsesStream(events);
9294
+ const message = {
9295
+ role: "assistant",
9296
+ content: text || null
9297
+ };
9298
+ if (toolCalls.length > 0) message.tool_calls = toolCalls;
9299
+ return {
9300
+ status: 200,
9301
+ body: {
9302
+ choices: [
9303
+ {
9304
+ index: 0,
9305
+ message,
9306
+ finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
9307
+ }
9308
+ ],
9309
+ ...usage ? { usage } : {}
9310
+ }
9311
+ };
9312
+ }
9313
+ function isCodexOAuthAgent(agentConfig) {
9314
+ if (!agentConfig) return false;
9315
+ const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
9316
+ return apiKeyRef === "chatgpt";
9317
+ }
9318
+
9035
9319
  // packages/agent-runtime/oauthProviders.ts
9036
9320
  var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
9037
9321
  var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
@@ -10229,6 +10513,74 @@ function createCliLocalRuntimeAdapter(deps) {
10229
10513
  }
10230
10514
  };
10231
10515
  }
10516
+ if (isCodexOAuthAgent(agentConfig)) {
10517
+ const accessToken = await apiKeyRefResolver("chatgpt");
10518
+ if (!accessToken) {
10519
+ throw new Error(
10520
+ 'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
10521
+ );
10522
+ }
10523
+ const credential = readOAuthCredential("chatgpt");
10524
+ const accountId = credential?.accountId;
10525
+ const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
10526
+ agentConfig,
10527
+ deps.env,
10528
+ buildProviderOpenAiTools,
10529
+ additionalToolNames,
10530
+ { hasUserChoice: Boolean(deps.requestUserChoice) }
10531
+ );
10532
+ logLocalRuntimeDiagnostic("provider.selected", {
10533
+ agentKey: agentConfig.key,
10534
+ transport: "codex-responses",
10535
+ provider: "openai",
10536
+ model: agentConfig.model ?? "gpt-5.6-sol",
10537
+ hasApiKey: true
10538
+ });
10539
+ return {
10540
+ model: agentConfig.model || "gpt-5.6-sol",
10541
+ complete: async (messages, options) => {
10542
+ const result = await fetchCodexResponsesCompletion({
10543
+ agentConfig,
10544
+ accessToken,
10545
+ ...accountId ? { accountId } : {},
10546
+ openAiBody: {
10547
+ model: agentConfig.model || "gpt-5.6-sol",
10548
+ messages,
10549
+ stream: false,
10550
+ ...tools2.length > 0 ? { tools: tools2 } : {}
10551
+ },
10552
+ fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
10553
+ sleep: deps.sleep,
10554
+ loopbackRequest
10555
+ })
10556
+ });
10557
+ if (result.status < 200 || result.status >= 300) {
10558
+ const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
10559
+ throw new Error(
10560
+ `local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
10561
+ );
10562
+ }
10563
+ const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
10564
+ const message = choice?.message ?? {};
10565
+ const content = typeof message.content === "string" ? message.content : "";
10566
+ const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
10567
+ if (content && options?.onTextDelta) options.onTextDelta(content);
10568
+ logLocalRuntimeDiagnostic("provider.request.result", {
10569
+ agentKey: agentConfig.key,
10570
+ transport: "codex-responses",
10571
+ ok: true,
10572
+ contentChars: content.length,
10573
+ toolCallCount: tool_calls?.length ?? 0,
10574
+ requestedToolNames: requestedToolNames2
10575
+ });
10576
+ return {
10577
+ content,
10578
+ ...tool_calls ? { tool_calls } : {},
10579
+ trace: messages
10580
+ };
10581
+ }
10582
+ };
10583
+ }
10232
10584
  if (isCursorOAuthAgent(agentConfig)) {
10233
10585
  const accessToken = await apiKeyRefResolver("cursor");
10234
10586
  if (!accessToken) {
@@ -10298,6 +10650,101 @@ function createCliLocalRuntimeAdapter(deps) {
10298
10650
  }
10299
10651
  };
10300
10652
  }
10653
+ if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
10654
+ const providerConfig2 = await resolvePlatformChatProviderConfig({
10655
+ agentConfig,
10656
+ env: deps.env,
10657
+ apiKeyRefResolver,
10658
+ credentialBroker,
10659
+ syncFetcher
10660
+ });
10661
+ const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
10662
+ agentConfig,
10663
+ deps.env,
10664
+ buildProviderOpenAiTools,
10665
+ additionalToolNames,
10666
+ { hasUserChoice: Boolean(deps.requestUserChoice) }
10667
+ );
10668
+ if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
10669
+ agentConfig.provider ?? "",
10670
+ agentConfig.model ?? "",
10671
+ tools2,
10672
+ () => false
10673
+ // CLI 端不区分 image 模型
10674
+ )) {
10675
+ logLocalRuntimeDiagnostic("provider.selected", {
10676
+ agentKey: agentConfig.key,
10677
+ transport: "gemini-native-tool",
10678
+ apiSource: agentConfig.apiSource ?? null,
10679
+ provider: providerConfig2.provider,
10680
+ model: providerConfig2.model,
10681
+ hasApiKey: Boolean(providerConfig2.apiKey)
10682
+ });
10683
+ return {
10684
+ model: providerConfig2.model,
10685
+ complete: async (messages, options) => {
10686
+ const requestBody = buildGeminiGenerateContentRequest({
10687
+ messages,
10688
+ tools: tools2,
10689
+ maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
10690
+ temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
10691
+ attachSkipThoughtSignature: true
10692
+ });
10693
+ const model = providerConfig2.model;
10694
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
10695
+ logLocalRuntimeDiagnostic("provider.request.start", {
10696
+ agentKey: agentConfig.key,
10697
+ transport: "gemini-native-tool",
10698
+ model,
10699
+ messageCount: messages.length,
10700
+ toolCount: tools2.length,
10701
+ requestedToolNames: requestedToolNames2
10702
+ });
10703
+ const res = await fetchImpl(url, {
10704
+ method: "POST",
10705
+ headers: {
10706
+ "Content-Type": "application/json",
10707
+ "x-goog-api-key": providerConfig2.apiKey ?? ""
10708
+ },
10709
+ body: JSON.stringify(requestBody),
10710
+ signal: AbortSignal.timeout(12e4)
10711
+ });
10712
+ if (!res.ok) {
10713
+ const errText = await res.text();
10714
+ logLocalRuntimeDiagnostic("provider.request.failed", {
10715
+ agentKey: agentConfig.key,
10716
+ transport: "gemini-native-tool",
10717
+ status: res.status,
10718
+ error: errText.slice(0, 200)
10719
+ });
10720
+ throw new Error(
10721
+ `gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
10722
+ );
10723
+ }
10724
+ const chunks = await readSseDataValues(res, parseSseDataLineJson);
10725
+ const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
10726
+ if (text && options?.onTextDelta) {
10727
+ options.onTextDelta(text);
10728
+ }
10729
+ const result = {
10730
+ content: text,
10731
+ model,
10732
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
10733
+ ...usage ? { usage } : {},
10734
+ trace: messages
10735
+ };
10736
+ logLocalRuntimeDiagnostic("provider.request.result", {
10737
+ agentKey: agentConfig.key,
10738
+ transport: "gemini-native-tool",
10739
+ ok: true,
10740
+ contentChars: text.length,
10741
+ toolCallCount: toolCalls.length
10742
+ });
10743
+ return result;
10744
+ }
10745
+ };
10746
+ }
10747
+ }
10301
10748
  if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
10302
10749
  const providerConfig2 = await resolvePlatformChatProviderConfig({
10303
10750
  agentConfig,