nolo-cli 0.16.0-alpha.5 → 0.16.0-alpha.7

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 (35) hide show
  1. package/{agentDeleteCommand-7AI657MF.js → agentDeleteCommand-X35VSSVM.js} +4 -4
  2. package/{agentEmailCommands-KJJXDEGM.js → agentEmailCommands-LGMEEMQP.js} +5 -5
  3. package/{agentListCommands-HPXVKI4Q.js → agentListCommands-LLQHUE4O.js} +5 -5
  4. package/{agentMachineCommands-N3B2TVPV.js → agentMachineCommands-4Q5PFIKF.js} +4 -4
  5. package/{agentRecordCommands-M63W7DKA.js → agentRecordCommands-XUYVG7BS.js} +5 -5
  6. package/{agentRunCommand-JSXYRLUZ.js → agentRunCommand-NORLSA7L.js} +5 -5
  7. package/{agentRuntimeLocal-BILOZZYS.js → agentRuntimeLocal-N56G2ZJK.js} +1 -1
  8. package/{appDeleteCommands-NUJOKI4W.js → appDeleteCommands-WHRYDQLZ.js} +5 -5
  9. package/{appDeployCommands-A6N2FGQI.js → appDeployCommands-USRWBT6T.js} +5 -5
  10. package/{appDeployStatusCommands-7AM5QF3L.js → appDeployStatusCommands-R632IBVL.js} +5 -5
  11. package/{appGetCommands-5SKEWQ2M.js → appGetCommands-PKGC2JWH.js} +5 -5
  12. package/{appListCommands-DO3DRMFF.js → appListCommands-OMRAEOAL.js} +5 -5
  13. package/{chunk-Z7R7O2YU.js → chunk-2B3BNWPC.js} +1 -1
  14. package/{chunk-N7Y6Y4WV.js → chunk-6EFJQCL6.js} +545 -87
  15. package/{chunk-QSUEDDDQ.js → chunk-AKYTMRBP.js} +1 -1
  16. package/{chunk-4LDZJAM4.js → chunk-BS5STUTA.js} +2 -2
  17. package/{chunk-GYJSDXGN.js → chunk-C2BYYSAO.js} +5 -0
  18. package/{chunk-U27RSNNB.js → chunk-EFNMO3YF.js} +1 -1
  19. package/{chunk-YU3RHZQK.js → chunk-FJHD7FHN.js} +1 -1
  20. package/{chunk-VWLK6WAB.js → chunk-NY5FDXZL.js} +1 -1
  21. package/{chunk-QEZOL2ES.js → chunk-QSWWWYGA.js} +1 -1
  22. package/{chunk-SPNQ52KM.js → chunk-YLVJ7NB4.js} +2 -2
  23. package/{chunk-NNQCFBSX.js → chunk-YXQA6X6I.js} +5 -5
  24. package/{chunk-TCFMDZDB.js → chunk-ZRDWHLMQ.js} +1 -1
  25. package/{dialogCommands-MFSTNUJH.js → dialogCommands-L4LMXQAI.js} +5 -5
  26. package/{docCreateCommands-3BYOEDE4.js → docCreateCommands-C4HJCM47.js} +4 -4
  27. package/{docDeleteCommands-7SGOMJJC.js → docDeleteCommands-Y6W6A3W6.js} +5 -5
  28. package/{docReadCommands-GO2ODL3E.js → docReadCommands-2WUIDAR6.js} +4 -4
  29. package/{docUpdateCommands-7XUCR5T7.js → docUpdateCommands-XVL2CBKE.js} +4 -4
  30. package/index.js +40 -40
  31. package/{machineCommands-H7KTKQAT.js → machineCommands-SXOARUBD.js} +4 -4
  32. package/{machineWsRunDispatch-5QP2PLA6.js → machineWsRunDispatch-OZQ4WNCE.js} +4 -4
  33. package/package.json +1 -1
  34. package/{readlineWorkspace-PGZRQYIR.js → readlineWorkspace-AM2FA7HS.js} +8 -8
  35. package/{spaceCommands-IQQEG2MG.js → spaceCommands-PYFLKEAW.js} +4 -4
@@ -8,7 +8,7 @@ import {
8
8
  buildLocalAgentLookupKeys,
9
9
  normalizeAgentHandle,
10
10
  shouldReadAgentKeyRemotely
11
- } from "./chunk-QEZOL2ES.js";
11
+ } from "./chunk-QSWWWYGA.js";
12
12
  import {
13
13
  LOCAL_CODEX_AGENT_ID,
14
14
  LOCAL_CODEX_AGENT_KEY,
@@ -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-GYJSDXGN.js";
82
+ } from "./chunk-C2BYYSAO.js";
82
83
  import {
83
84
  buildPlatformChatCompletionRequest,
84
85
  canUsePlatformChatProvider,
@@ -93,9 +94,12 @@ import {
93
94
  resolveAgentRuntimeConfigFromRecord
94
95
  } from "./chunk-OIQPORYI.js";
95
96
  import {
96
- parseToolArgumentsJson,
97
97
  summarizeToolArguments
98
98
  } from "./chunk-ZTRZ2O5B.js";
99
+ import {
100
+ convertMessagesToResponsesInput,
101
+ toResponsesTools
102
+ } from "./chunk-KFEVY3ST.js";
99
103
  import {
100
104
  resolvePlatformAuthToken
101
105
  } from "./chunk-LJIJWXIT.js";
@@ -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,6 +167,9 @@ 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,
@@ -2431,19 +2435,22 @@ function resolveAntigravityWireModel(logicalModelId) {
2431
2435
  return { wireModelId: id };
2432
2436
  }
2433
2437
 
2434
- // packages/agent-runtime/antigravityCloudCodeProvider.ts
2435
- var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
2438
+ // packages/agent-runtime/geminiNativeShared.ts
2436
2439
  var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
2437
- function isGemini3WireModel(modelId) {
2440
+ function isGemini3Model(modelId) {
2438
2441
  return modelId.includes("gemini-3");
2439
2442
  }
2440
2443
  function messageText(content) {
2441
2444
  if (typeof content === "string") return content;
2442
2445
  if (!Array.isArray(content)) return "";
2443
- 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();
2444
2449
  }
2445
2450
  function parseDataUrlToInlineData(url) {
2446
- 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
+ );
2447
2454
  if (!match) return null;
2448
2455
  return { mimeType: match[1], data: match[2] };
2449
2456
  }
@@ -2460,7 +2467,7 @@ function extractInlineDataParts(content) {
2460
2467
  }
2461
2468
  return parts;
2462
2469
  }
2463
- function convertOpenAiMessagesToCca(messages, options) {
2470
+ function convertOpenAiMessagesToGemini(messages, options) {
2464
2471
  const contents = [];
2465
2472
  const systemTexts = [];
2466
2473
  const toolNamesById = /* @__PURE__ */ new Map();
@@ -2476,9 +2483,11 @@ function convertOpenAiMessagesToCca(messages, options) {
2476
2483
  };
2477
2484
  const flushPendingFunctionCalls = () => {
2478
2485
  if (pendingFunctionCalls.length === 0) return;
2479
- const dummyResponses = pendingFunctionCalls.map(({ name }) => ({
2480
- functionResponse: { name, response: { output: "{}" } }
2481
- }));
2486
+ const dummyResponses = pendingFunctionCalls.map(
2487
+ ({ name }) => ({
2488
+ functionResponse: { name, response: { output: "{}" } }
2489
+ })
2490
+ );
2482
2491
  pendingFunctionCalls = [];
2483
2492
  pushOrMergeContent("user", dummyResponses);
2484
2493
  };
@@ -2487,13 +2496,17 @@ function convertOpenAiMessagesToCca(messages, options) {
2487
2496
  const role = String(raw.role);
2488
2497
  const content = "content" in raw ? raw.content : null;
2489
2498
  if (role === "system") {
2490
- const text = messageText(content);
2499
+ const text = messageText(
2500
+ content
2501
+ );
2491
2502
  if (text) systemTexts.push(text);
2492
2503
  continue;
2493
2504
  }
2494
2505
  if (role === "user") {
2495
2506
  flushPendingFunctionCalls();
2496
- const text = messageText(content);
2507
+ const text = messageText(
2508
+ content
2509
+ );
2497
2510
  const imageParts = extractInlineDataParts(
2498
2511
  content
2499
2512
  );
@@ -2507,7 +2520,9 @@ function convertOpenAiMessagesToCca(messages, options) {
2507
2520
  if (role === "assistant") {
2508
2521
  flushPendingFunctionCalls();
2509
2522
  const parts = [];
2510
- const text = messageText(content);
2523
+ const text = messageText(
2524
+ content
2525
+ );
2511
2526
  if (text) parts.push({ text });
2512
2527
  const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
2513
2528
  for (const call of toolCalls) {
@@ -2517,17 +2532,20 @@ function convertOpenAiMessagesToCca(messages, options) {
2517
2532
  toolNamesById.set(id, name);
2518
2533
  pendingFunctionCalls.push({ name, id });
2519
2534
  const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
2520
- const isFirstFunctionCallPart = !parts.some((p) => "functionCall" in p);
2521
- 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 = {
2522
2540
  functionCall: {
2523
2541
  name,
2524
- args: parseToolArgumentsJson(call.function?.arguments),
2525
- id
2542
+ args: parseToolArgs(call.function?.arguments),
2543
+ ...id ? { id } : {}
2526
2544
  },
2527
- ...realSignature ? { thoughtSignature: realSignature } : options.attachSkipThoughtSignature && isFirstFunctionCallPart ? { thoughtSignature: SKIP_THOUGHT_SIGNATURE } : {}
2528
- });
2545
+ ...signature ? { thoughtSignature: signature } : {}
2546
+ };
2547
+ parts.push(part);
2529
2548
  }
2530
- if (parts.length === 0) continue;
2531
2549
  pushOrMergeContent("model", parts);
2532
2550
  continue;
2533
2551
  }
@@ -2552,7 +2570,22 @@ function convertOpenAiMessagesToCca(messages, options) {
2552
2570
  flushPendingFunctionCalls();
2553
2571
  return { contents, systemTexts };
2554
2572
  }
2555
- 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) {
2556
2589
  if (!Array.isArray(tools) || tools.length === 0) return void 0;
2557
2590
  const declarations = [];
2558
2591
  for (const tool of tools) {
@@ -2569,6 +2602,97 @@ function convertOpenAiTools(tools) {
2569
2602
  if (declarations.length === 0) return void 0;
2570
2603
  return [{ functionDeclarations: declarations }];
2571
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";
2572
2696
  function buildCloudCodeAssistPayload(args) {
2573
2697
  const projectId = readAntigravityProjectId(args.metadata);
2574
2698
  if (!projectId) {
@@ -2579,8 +2703,8 @@ function buildCloudCodeAssistPayload(args) {
2579
2703
  const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
2580
2704
  const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
2581
2705
  const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
2582
- const { contents, systemTexts } = convertOpenAiMessagesToCca(rawMessages, {
2583
- attachSkipThoughtSignature: isGemini3WireModel(model)
2706
+ const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
2707
+ attachSkipThoughtSignature: isGemini3Model(model)
2584
2708
  });
2585
2709
  if (contents.length === 0) {
2586
2710
  throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
@@ -2594,7 +2718,7 @@ function buildCloudCodeAssistPayload(args) {
2594
2718
  parts: systemTexts.map((text) => ({ text }))
2595
2719
  };
2596
2720
  }
2597
- const tools = convertOpenAiTools(
2721
+ const tools = convertOpenAiToolsToGemini(
2598
2722
  Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
2599
2723
  );
2600
2724
  if (tools) {
@@ -2641,63 +2765,6 @@ function buildCloudCodeAssistPayload(args) {
2641
2765
  }
2642
2766
  };
2643
2767
  }
2644
- function accumulateCcaChunks(chunks) {
2645
- let text = "";
2646
- const toolCalls = [];
2647
- let usage;
2648
- let pendingThoughtSignature;
2649
- for (const chunk of chunks) {
2650
- if (!chunk || typeof chunk !== "object") continue;
2651
- const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
2652
- if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
2653
- const meta = response.usageMetadata;
2654
- const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2655
- const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2656
- const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2657
- usage = {
2658
- prompt_tokens: prompt,
2659
- completion_tokens: candidates2,
2660
- total_tokens: total
2661
- };
2662
- }
2663
- const candidates = Array.isArray(response.candidates) ? response.candidates : [];
2664
- for (const candidate of candidates) {
2665
- if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
2666
- const content = candidate.content;
2667
- if (!content || typeof content !== "object" || !("parts" in content)) continue;
2668
- const parts = content.parts;
2669
- if (!Array.isArray(parts)) continue;
2670
- for (const part of parts) {
2671
- if (!part || typeof part !== "object") continue;
2672
- const partSignature = part.thoughtSignature;
2673
- if ("text" in part && typeof part.text === "string") {
2674
- const piece = part.text;
2675
- if (!part.thought) {
2676
- text += piece;
2677
- }
2678
- }
2679
- if (part.thought && typeof partSignature === "string" && partSignature) {
2680
- pendingThoughtSignature = partSignature;
2681
- }
2682
- if ("functionCall" in part && part.functionCall) {
2683
- const call = part.functionCall;
2684
- const name = typeof call.name === "string" ? call.name : "tool";
2685
- const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
2686
- const argsObj = asRecordOrEmpty(call.args);
2687
- const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
2688
- pendingThoughtSignature = void 0;
2689
- toolCalls.push({
2690
- id,
2691
- type: "function",
2692
- function: { name, arguments: JSON.stringify(argsObj) },
2693
- ...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
2694
- });
2695
- }
2696
- }
2697
- }
2698
- }
2699
- return { text, toolCalls, usage };
2700
- }
2701
2768
  async function readSseJsonChunks(response) {
2702
2769
  return readSseDataValues(response, parseSseDataLineJson);
2703
2770
  }
@@ -2722,7 +2789,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
2722
2789
  };
2723
2790
  }
2724
2791
  const chunks = await readSseJsonChunks(response);
2725
- const { text, toolCalls, usage } = accumulateCcaChunks(chunks);
2792
+ const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
2726
2793
  const message = {
2727
2794
  role: "assistant",
2728
2795
  content: text || null
@@ -9021,6 +9088,234 @@ function isCursorOAuthAgent(agent) {
9021
9088
  return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
9022
9089
  }
9023
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
+
9024
9319
  // packages/agent-runtime/oauthProviders.ts
9025
9320
  var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
9026
9321
  var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
@@ -10218,6 +10513,74 @@ function createCliLocalRuntimeAdapter(deps) {
10218
10513
  }
10219
10514
  };
10220
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
+ }
10221
10584
  if (isCursorOAuthAgent(agentConfig)) {
10222
10585
  const accessToken = await apiKeyRefResolver("cursor");
10223
10586
  if (!accessToken) {
@@ -10287,6 +10650,101 @@ function createCliLocalRuntimeAdapter(deps) {
10287
10650
  }
10288
10651
  };
10289
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
+ }
10290
10748
  if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
10291
10749
  const providerConfig2 = await resolvePlatformChatProviderConfig({
10292
10750
  agentConfig,