@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4

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 (235) hide show
  1. package/README.en.md +122 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +4 -35
  4. package/lib/abort-B7izMMna.mjs +51 -0
  5. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  6. package/lib/abort-dIkZBV7Q.mjs +51 -0
  7. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  8. package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
  9. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  10. package/lib/anthropic-BWsZFzU8.mjs +262 -0
  11. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  12. package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
  13. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  14. package/lib/anthropic-sCMH7JID.mjs +262 -0
  15. package/lib/anthropic-tTntD8BD.mjs +262 -0
  16. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  17. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  18. package/lib/api-key-login-CpzSezsi.mjs +157 -0
  19. package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
  20. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  21. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  22. package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
  23. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  24. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  25. package/lib/bun-shim.mjs +252 -12
  26. package/lib/bundled-references-CSuBco5p.mjs +55 -0
  27. package/lib/bundled-references-Cavaffah.mjs +55 -0
  28. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  29. package/lib/callback-server-BEFNf-jf.mjs +398 -0
  30. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  31. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  32. package/lib/client.js +111 -41
  33. package/lib/cursor-B3zg7EHj.mjs +273 -0
  34. package/lib/cursor-B6TUEmgP.mjs +135 -0
  35. package/lib/cursor-BIQfBC6V.mjs +135 -0
  36. package/lib/cursor-D8gvtTL3.mjs +135 -0
  37. package/lib/cursor-DNk6eXDd.mjs +5470 -0
  38. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  39. package/lib/cursor-MjSm74IJ.mjs +273 -0
  40. package/lib/cursor-aJrXeYCb.mjs +273 -0
  41. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  42. package/lib/device-code-DBo3B5nh.mjs +51 -0
  43. package/lib/device-code-DIb0FU-H.mjs +51 -0
  44. package/lib/device-code-OI_tQcmc.mjs +51 -0
  45. package/lib/devin-BHZZyMhO.mjs +95 -0
  46. package/lib/devin-BK7DHeca.mjs +114 -0
  47. package/lib/devin-CfMp3cXS.mjs +95 -0
  48. package/lib/devin-CldyPD8K.mjs +95 -0
  49. package/lib/devin-CzRpTUOA.mjs +114 -0
  50. package/lib/devin-D9zR5B_R.mjs +542 -0
  51. package/lib/devin-DXOeNyU7.mjs +542 -0
  52. package/lib/devin-Q1yem3lp.mjs +114 -0
  53. package/lib/devin-vNZTNUON.mjs +542 -0
  54. package/lib/error-B3bevhrs.mjs +1449 -0
  55. package/lib/error-Dd8DIqs-.mjs +1449 -0
  56. package/lib/error-yCSG0mGC.mjs +1449 -0
  57. package/lib/event-stream-BDPi64mK.mjs +151 -0
  58. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  59. package/lib/event-stream-loUa0s1T.mjs +151 -0
  60. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  61. package/lib/github-copilot-4GaMtQmg.mjs +208 -0
  62. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  63. package/lib/github-copilot-B2HGSIJK.mjs +104 -0
  64. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  65. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  66. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  67. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  68. package/lib/gitlab-duo-akICyfeD.mjs +155 -0
  69. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  70. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  71. package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
  72. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  73. package/lib/google-BS4T25Pn.mjs +30 -0
  74. package/lib/google-TFe-7-of.mjs +30 -0
  75. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  76. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  77. package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
  78. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  79. package/lib/google-auth-De7_s3eo.mjs +232 -0
  80. package/lib/google-auth-DhqpOYrX.mjs +232 -0
  81. package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
  82. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  83. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  84. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  85. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  86. package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
  87. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  88. package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
  89. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  90. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  91. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  92. package/lib/google-shared-DzhCb9b0.mjs +760 -0
  93. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  94. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  95. package/lib/google-vertex-kscbkyRb.mjs +99 -0
  96. package/lib/google-zyDOG9x7.mjs +30 -0
  97. package/lib/identity-Da1GPU9a.mjs +219 -0
  98. package/lib/identity-DnB63pS7.mjs +219 -0
  99. package/lib/identity-xRP7_eSR.mjs +219 -0
  100. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  101. package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
  102. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  103. package/lib/index.mjs +4608 -3935
  104. package/lib/kimi--wUOWER5.mjs +236 -0
  105. package/lib/kimi-DMVI-zrZ.mjs +236 -0
  106. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  107. package/lib/markit-BL3cH47U.mjs +1417 -0
  108. package/lib/markit-BNiNY6SE.mjs +1417 -0
  109. package/lib/markit-M0jhziqU.mjs +1417 -0
  110. package/lib/minimax-code-BK-3eBbz.mjs +53 -0
  111. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  112. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  113. package/lib/models-CfT4coYT.mjs +104660 -0
  114. package/lib/models-D_XnT6ay.mjs +104660 -0
  115. package/lib/models-SGASygJ3.mjs +104660 -0
  116. package/lib/ollama-BQMGPxtV.mjs +589 -0
  117. package/lib/ollama-DPzBmq89.mjs +589 -0
  118. package/lib/ollama-DoBz5SFm.mjs +589 -0
  119. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  120. package/lib/openai-codex-CQL_kvYL.mjs +255 -0
  121. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  122. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  123. package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
  124. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  125. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  126. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  127. package/lib/openai-completions-i8doczAk.mjs +1360 -0
  128. package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
  129. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  130. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  131. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  132. package/lib/openai-responses-DTkBiiy-.mjs +867 -0
  133. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  134. package/lib/opencode-DaJjcUbf.mjs +38 -0
  135. package/lib/opencode-DhMolSoB.mjs +38 -0
  136. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  137. package/lib/perplexity-9b-RQ0mV.mjs +194 -0
  138. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  139. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  140. package/lib/proxy-DDqrmjjC.mjs +190 -0
  141. package/lib/proxy-ZtUcl6r5.mjs +190 -0
  142. package/lib/proxy-pM_NIv-H.mjs +190 -0
  143. package/lib/request-debug-HJMoJncL.mjs +183 -0
  144. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  145. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  146. package/lib/scrapers-CL-WgdU1.mjs +9198 -0
  147. package/lib/scrapers-CVptboMs.mjs +9198 -0
  148. package/lib/scrapers-CipyKyCH.mjs +9198 -0
  149. package/lib/scrapers-DGfrYhtw.mjs +9198 -0
  150. package/lib/scrapers-DSUPYoUF.mjs +9198 -0
  151. package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
  152. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  153. package/lib/shell-snapshot-fn-env.sh +67 -43
  154. package/lib/src-BgpusnsB.mjs +5076 -0
  155. package/lib/src-DTid0g4K.mjs +5001 -0
  156. package/lib/src-lDmkSRbm.mjs +5006 -0
  157. package/lib/stream-BlldLkVq.mjs +10236 -0
  158. package/lib/stream-CRtexYLe.mjs +10236 -0
  159. package/lib/stream-C_RAoxJC.mjs +10236 -0
  160. package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
  161. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  162. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  163. package/lib/turndown-DN7ByzEI.mjs +667 -0
  164. package/lib/types/client/locales.d.ts +1 -1
  165. package/lib/types/config/fields.d.ts +1 -1
  166. package/lib/types/config/settings.d.ts +25 -3
  167. package/lib/types/config/truncate.d.ts +9 -5
  168. package/lib/types/tools/bash/background.d.ts +1 -1
  169. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  170. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  171. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  172. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  173. package/lib/types/tools/bash/render.d.ts +4 -3
  174. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  175. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  176. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  177. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  178. package/lib/types/tools/bash/which.d.ts +20 -0
  179. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  180. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  181. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  182. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  183. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  184. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  185. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  186. package/lib/types/tools/omp/sdk.d.ts +6 -0
  187. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  188. package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
  189. package/lib/types/tools/omp/tools/read.d.ts +2 -8
  190. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  191. package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
  192. package/lib/types/tools/read/adapter/index.d.ts +4 -1
  193. package/lib/types/tools/read-image/index.d.ts +4 -0
  194. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  195. package/lib/types/tools/shared/bun-shim.d.ts +39 -3
  196. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  197. package/lib/types/tools/shared/image-bridge.d.ts +98 -0
  198. package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
  199. package/lib/types/tools/shared/session-state.d.ts +9 -3
  200. package/lib/utils-2Wq2eATG.mjs +8119 -0
  201. package/lib/utils-BnX8O3vi.mjs +12303 -0
  202. package/lib/utils-Bw139LTz.mjs +8119 -0
  203. package/lib/utils-CE8N8P4Q.mjs +12315 -0
  204. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  205. package/lib/utils-C_MrQ_0z.mjs +12301 -0
  206. package/lib/utils-CiGN7OHR.mjs +12315 -0
  207. package/lib/utils-Cp76gCyk.mjs +8119 -0
  208. package/lib/utils-D0GRDgAr.mjs +12315 -0
  209. package/lib/utils-D0Z1fyoO.mjs +12299 -0
  210. package/lib/utils-D2YknRk4.mjs +51 -0
  211. package/lib/utils-DppGHXQB.mjs +51 -0
  212. package/lib/utils-DzXZDfYc.mjs +51 -0
  213. package/lib/utils-W8WdSBpX.mjs +12315 -0
  214. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  215. package/lib/vision-guard-BDD4OrKo.mjs +92 -0
  216. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  217. package/lib/wafer-CgtPHerf.mjs +17 -0
  218. package/lib/wafer-DRU0EjZX.mjs +17 -0
  219. package/lib/wafer-cBtrn6q9.mjs +17 -0
  220. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  221. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  222. package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
  223. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  224. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  225. package/lib/xiaomi-Dd87KSg5.mjs +157 -0
  226. package/lib/zai-7DWMkEqM.mjs +203 -0
  227. package/lib/zai-C59YnomG.mjs +203 -0
  228. package/lib/zai-CFeOt-53.mjs +203 -0
  229. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  230. package/lib/zip-D36ZKsP8.mjs +1316 -0
  231. package/lib/zip-D6QXpvaJ.mjs +1316 -0
  232. package/package.json +14 -10
  233. package/presets/package.json +1 -1
  234. package/presets/tool-plus-ptc/preset.yml +1 -1
  235. package/presets/tool-plus-standard/preset.yml +1 -1
@@ -0,0 +1,850 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { o as readSseJson } from "./src-lDmkSRbm.mjs";
4
+ import { G as fetchWithRetry, L as GeminiCliApiError, S as classify, W as extractHttpStatusFromError, a as isTransientStatus, c as OAuthError, j as retriable, l as finalize, n as StreamTimeoutError, r as ValidationError, s as ProviderResponseError, t as ConfigurationError, v as AbortError } from "./error-yCSG0mGC.mjs";
5
+ import { M as normalizeSchemaForCCA, a as normalizeSystemPrompts } from "./utils-Bw139LTz.mjs";
6
+ import { t as calculateCost } from "./models-D_XnT6ay.mjs";
7
+ import { t as AssistantMessageEventStream } from "./event-stream-loUa0s1T.mjs";
8
+ import { i as getGeminiCliHeaders, n as getAntigravityUserAgent, t as getAntigravityModelWireProfile } from "./gemini-headers-DKUShltF.mjs";
9
+ import { i as getStreamFirstEventTimeoutMs, o as iterateWithIdleTimeout, t as armPreResponseTimeout } from "./idle-iterator-Baoyn3Hp.mjs";
10
+ import { t as StreamMarkupHealing } from "./stream-markup-healing-DMsxBx1L.mjs";
11
+ import { n as formatGoogleValidationRequiredMessage, t as extractGoogleValidationUrl } from "./google-validation-Cgbn3tWJ.mjs";
12
+ import { a as isThinkingPart, c as nextToolCallId, d as retainThoughtSignature, f as startTextOrThinkingBlock, i as hasMeaningfulGoogleContent, l as pushBlockEndEvent, n as convertMessages, o as mapStopReasonString, r as convertTools, s as mapToolChoice, u as pushToolCallEvents } from "./google-shared-CgKmmdO3.mjs";
13
+ import { scheduler } from "node:timers/promises";
14
+ import { createHash, randomBytes, randomUUID } from "node:crypto";
15
+ import { type } from "@oh-my-pi/omptype";
16
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-antigravity-forced-tool.md
17
+ var google_antigravity_forced_tool_default = "TOOL-ONLY TURN. This turn accepts a tool call and nothing else; a text reply here is discarded unread and you will be re-prompted. Emit the tool call now.\n";
18
+ //#endregion
19
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-gemini-cli.ts
20
+ /**
21
+ * Google Gemini CLI / Antigravity provider.
22
+ * Shared implementation for both google-gemini-cli and google-antigravity providers.
23
+ * Uses the Cloud Code Assist API endpoint to access Gemini and Claude models.
24
+ */
25
+ function isPlanningLeakPrefix(text) {
26
+ const trimmed = text.trimStart();
27
+ if (!trimmed.startsWith("{")) return false;
28
+ const afterBrace = trimmed.slice(1).trimStart();
29
+ if (afterBrace === "") return trimmed.length <= 100;
30
+ if (afterBrace[0] !== "\"") return false;
31
+ const nextQuoteIndex = afterBrace.indexOf("\"", 1);
32
+ if (nextQuoteIndex === -1) {
33
+ const keyPrefix = afterBrace.slice(1);
34
+ return "thought".startsWith(keyPrefix) && trimmed.length <= 100;
35
+ }
36
+ if (afterBrace.slice(1, nextQuoteIndex) !== "thought") return false;
37
+ const afterKey = afterBrace.slice(nextQuoteIndex + 1).trimStart();
38
+ if (afterKey === "") return trimmed.length <= 100;
39
+ if (afterKey[0] !== ":") return false;
40
+ return true;
41
+ }
42
+ function isPlanningLeakObject(parsed, toolNames) {
43
+ if (!parsed || typeof parsed !== "object") return false;
44
+ const record = parsed;
45
+ const hasThought = typeof record.thought === "string";
46
+ const isOmpTool = typeof record.call === "string" && toolNames.has(record.call);
47
+ const hasToolSignature = "_i" in record || "paths" in record || "command" in record || "path" in record && "content" in record;
48
+ return hasThought || isOmpTool || hasToolSignature;
49
+ }
50
+ function splitLeadingJsonObject(text) {
51
+ const prefixLength = text.length - text.trimStart().length;
52
+ const trimmed = text.slice(prefixLength);
53
+ if (!trimmed.startsWith("{")) return void 0;
54
+ let depth = 0;
55
+ let inString = false;
56
+ let escaped = false;
57
+ for (let index = 0; index < trimmed.length; index += 1) {
58
+ const ch = trimmed[index];
59
+ if (inString) {
60
+ if (escaped) {
61
+ escaped = false;
62
+ continue;
63
+ }
64
+ if (ch === "\\") {
65
+ escaped = true;
66
+ continue;
67
+ }
68
+ if (ch === "\"") inString = false;
69
+ continue;
70
+ }
71
+ if (ch === "\"") {
72
+ inString = true;
73
+ continue;
74
+ }
75
+ if (ch === "{") {
76
+ depth += 1;
77
+ continue;
78
+ }
79
+ if (ch !== "}") continue;
80
+ depth -= 1;
81
+ if (depth !== 0) continue;
82
+ const jsonText = trimmed.slice(0, index + 1);
83
+ return {
84
+ prefixLength: prefixLength + index + 1,
85
+ jsonText,
86
+ rest: trimmed.slice(index + 1)
87
+ };
88
+ }
89
+ }
90
+ function splitLeadingJsonObjectIgnoringQuotes(text) {
91
+ const prefixLength = text.length - text.trimStart().length;
92
+ const trimmed = text.slice(prefixLength);
93
+ if (!trimmed.startsWith("{")) return void 0;
94
+ let depth = 0;
95
+ for (let index = 0; index < trimmed.length; index += 1) {
96
+ const ch = trimmed[index];
97
+ if (ch === "{") depth += 1;
98
+ else if (ch === "}") {
99
+ depth -= 1;
100
+ if (depth === 0) return {
101
+ prefixLength: prefixLength + index + 1,
102
+ jsonText: trimmed.slice(0, index + 1),
103
+ rest: trimmed.slice(index + 1)
104
+ };
105
+ }
106
+ }
107
+ }
108
+ function consumePlanningBuffer(text, toolNames, isFinal = false) {
109
+ if (!isPlanningLeakPrefix(text)) return {
110
+ kind: "plain",
111
+ visibleText: text
112
+ };
113
+ let leading = splitLeadingJsonObject(text);
114
+ if (!leading) leading = splitLeadingJsonObjectIgnoringQuotes(text);
115
+ if (!leading) {
116
+ if (isFinal) {
117
+ const trimmed = text.trim();
118
+ const hasThoughtKey = trimmed.includes("\"thought\"");
119
+ const hasToolKey = Array.from(toolNames).some((name) => trimmed.includes(`"${name}"`));
120
+ const hasToolSignature = trimmed.includes("\"_i\"") || trimmed.includes("\"paths\"") || trimmed.includes("\"command\"") || trimmed.includes("\"path\"") && trimmed.includes("\"content\"");
121
+ if (hasThoughtKey || hasToolKey || hasToolSignature) return {
122
+ kind: "leak",
123
+ visibleText: ""
124
+ };
125
+ return {
126
+ kind: "plain",
127
+ visibleText: text
128
+ };
129
+ }
130
+ return { kind: "incomplete" };
131
+ }
132
+ let parsed;
133
+ try {
134
+ parsed = JSON.parse(leading.jsonText);
135
+ } catch {
136
+ const hasThoughtKey = leading.jsonText.includes("\"thought\"");
137
+ const hasToolKey = Array.from(toolNames).some((name) => leading.jsonText.includes(`"${name}"`));
138
+ const hasToolSignature = leading.jsonText.includes("\"_i\"") || leading.jsonText.includes("\"paths\"") || leading.jsonText.includes("\"command\"") || leading.jsonText.includes("\"path\"") && leading.jsonText.includes("\"content\"");
139
+ if (hasThoughtKey || hasToolKey || hasToolSignature) return {
140
+ kind: "leak",
141
+ visibleText: leading.rest
142
+ };
143
+ return {
144
+ kind: "plain",
145
+ visibleText: text
146
+ };
147
+ }
148
+ return isPlanningLeakObject(parsed, toolNames) ? {
149
+ kind: "leak",
150
+ visibleText: leading.rest
151
+ } : {
152
+ kind: "plain",
153
+ visibleText: text
154
+ };
155
+ }
156
+ const ANTIGRAVITY_PROVIDER_SESSION_STATE_KEY = "google-antigravity-session-state";
157
+ function getAntigravityProviderSessionState(providerSessionState) {
158
+ if (!providerSessionState) return void 0;
159
+ let existing = providerSessionState.get(ANTIGRAVITY_PROVIDER_SESSION_STATE_KEY);
160
+ if (!existing) {
161
+ existing = { close: () => {} };
162
+ providerSessionState.set(ANTIGRAVITY_PROVIDER_SESSION_STATE_KEY, existing);
163
+ }
164
+ return existing;
165
+ }
166
+ const DEFAULT_ENDPOINT = "https://cloudcode-pa.googleapis.com";
167
+ const ANTIGRAVITY_DAILY_ENDPOINT = "https://daily-cloudcode-pa.googleapis.com";
168
+ const ANTIGRAVITY_SANDBOX_ENDPOINT = "https://daily-cloudcode-pa.sandbox.googleapis.com";
169
+ const ANTIGRAVITY_ENDPOINT_FALLBACKS = [ANTIGRAVITY_DAILY_ENDPOINT, ANTIGRAVITY_SANDBOX_ENDPOINT];
170
+ const BASE_DELAY_MS = 1e3;
171
+ const FLASH_FIRST_EVENT_TIMEOUT_MS = 6e4;
172
+ const DEFAULT_FIRST_EVENT_TIMEOUT_MS = 3e5;
173
+ const FIRST_EVENT_TIMEOUT_ERROR = "Cloud Code Assist stream timed out while waiting for the first event";
174
+ const RATE_LIMIT_BUDGET_MS = 3e5;
175
+ const CLAUDE_THINKING_BETA_HEADER = "interleaved-thinking-2025-05-14";
176
+ const GOOGLE_GEMINI_REFRESH_SKEW_MS = 6e4;
177
+ const ANTIGRAVITY_REFRESH_SKEW_MS = 6e4;
178
+ function isClaudeModel(modelId) {
179
+ return modelId.toLowerCase().includes("claude");
180
+ }
181
+ function needsClaudeThinkingBetaHeader(model) {
182
+ return model.provider === "google-antigravity" && model.id.startsWith("claude-") && model.reasoning;
183
+ }
184
+ const optionalCredentialString = type("unknown").pipe((raw) => {
185
+ const out = type("string")(raw);
186
+ return out instanceof type.errors ? void 0 : out;
187
+ });
188
+ const innerCredentialsSchema = type({
189
+ "token?": optionalCredentialString,
190
+ "projectId?": optionalCredentialString,
191
+ "project_id?": optionalCredentialString,
192
+ "refreshToken?": optionalCredentialString,
193
+ "refresh?": optionalCredentialString,
194
+ "email?": optionalCredentialString,
195
+ "expiresAt?": "unknown",
196
+ "expires?": "unknown"
197
+ });
198
+ const geminiCliCredentialsSchema = type("unknown").pipe((raw) => {
199
+ const out = innerCredentialsSchema(raw);
200
+ return out instanceof type.errors ? {} : out;
201
+ });
202
+ function normalizeExpiryMs(value) {
203
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return;
204
+ return value < 1e10 ? value * 1e3 : value;
205
+ }
206
+ function parseGeminiCliCredentials(apiKeyRaw) {
207
+ const invalidCredentialsMessage = "Invalid Google Cloud Code Assist credentials. Use /login to re-authenticate.";
208
+ const missingCredentialsMessage = "Missing token or projectId in Google Cloud credentials. Use /login to re-authenticate.";
209
+ let rawCredentials;
210
+ try {
211
+ rawCredentials = JSON.parse(apiKeyRaw);
212
+ } catch {
213
+ throw new ValidationError(invalidCredentialsMessage);
214
+ }
215
+ const parsed = geminiCliCredentialsSchema(rawCredentials);
216
+ if (parsed instanceof type.errors) throw new ValidationError(invalidCredentialsMessage);
217
+ const projectId = parsed.projectId ?? parsed.project_id;
218
+ if (parsed.token === void 0 || projectId === void 0) throw new ValidationError(missingCredentialsMessage);
219
+ const refreshToken = parsed.refreshToken ?? parsed.refresh;
220
+ const expiresAt = normalizeExpiryMs(parsed.expiresAt ?? parsed.expires);
221
+ const email = parsed.email && parsed.email.length > 0 ? parsed.email : void 0;
222
+ return {
223
+ accessToken: parsed.token,
224
+ projectId,
225
+ refreshToken,
226
+ expiresAt,
227
+ email
228
+ };
229
+ }
230
+ function shouldRefreshGeminiCliCredentials(expiresAt, isAntigravity, nowMs = Date.now()) {
231
+ if (expiresAt === void 0) return false;
232
+ return nowMs + (isAntigravity ? ANTIGRAVITY_REFRESH_SKEW_MS : GOOGLE_GEMINI_REFRESH_SKEW_MS) >= expiresAt;
233
+ }
234
+ const streamGoogleGeminiCli = (model, context, options) => {
235
+ const stream = new AssistantMessageEventStream();
236
+ (async () => {
237
+ const startTime = performance.now();
238
+ let firstTokenTime;
239
+ const output = {
240
+ role: "assistant",
241
+ content: [],
242
+ api: "google-gemini-cli",
243
+ provider: model.provider,
244
+ model: model.id,
245
+ usage: {
246
+ input: 0,
247
+ output: 0,
248
+ cacheRead: 0,
249
+ cacheWrite: 0,
250
+ totalTokens: 0,
251
+ cost: {
252
+ input: 0,
253
+ output: 0,
254
+ cacheRead: 0,
255
+ cacheWrite: 0,
256
+ total: 0
257
+ }
258
+ },
259
+ stopReason: "stop",
260
+ timestamp: Date.now()
261
+ };
262
+ let rawRequestDump;
263
+ try {
264
+ const apiKeyRaw = options?.apiKey;
265
+ if (!apiKeyRaw) throw new ConfigurationError("Google Cloud Code Assist requires OAuth authentication. Use /login to authenticate.");
266
+ const isAntigravity = model.provider === "google-antigravity";
267
+ const parsedCredentials = parseGeminiCliCredentials(apiKeyRaw);
268
+ const { accessToken, projectId } = parsedCredentials;
269
+ if (shouldRefreshGeminiCliCredentials(parsedCredentials.expiresAt, isAntigravity) && parsedCredentials.expiresAt !== void 0 && Date.now() >= parsedCredentials.expiresAt) throw new OAuthError("OAuth token expired before request — please retry; AuthStorage will refresh on the next attempt.", {
270
+ kind: "token-refresh",
271
+ provider: model.provider
272
+ });
273
+ const baseUrl = model.baseUrl?.trim();
274
+ let endpoints;
275
+ const providerState = isAntigravity ? getAntigravityProviderSessionState(options?.providerSessionState) : void 0;
276
+ if (isAntigravity) {
277
+ const mode = options?.antigravityEndpointMode ?? "auto";
278
+ if (mode === "sandbox") {
279
+ endpoints = [ANTIGRAVITY_SANDBOX_ENDPOINT];
280
+ if (providerState) providerState.lastGoodEndpoint = void 0;
281
+ } else if (mode === "production") {
282
+ endpoints = [ANTIGRAVITY_DAILY_ENDPOINT];
283
+ if (providerState) providerState.lastGoodEndpoint = void 0;
284
+ } else if (baseUrl) {
285
+ const cleanUrl = baseUrl.replace(/\/+$/, "");
286
+ if (cleanUrl !== ANTIGRAVITY_DAILY_ENDPOINT && cleanUrl !== ANTIGRAVITY_SANDBOX_ENDPOINT) {
287
+ endpoints = [baseUrl];
288
+ if (providerState) providerState.lastGoodEndpoint = void 0;
289
+ } else {
290
+ const defaultFallbacks = [...ANTIGRAVITY_ENDPOINT_FALLBACKS];
291
+ const lastGood = providerState?.lastGoodEndpoint;
292
+ if (lastGood && defaultFallbacks.includes(lastGood)) endpoints = [lastGood, ...defaultFallbacks.filter((e) => e !== lastGood)];
293
+ else endpoints = defaultFallbacks;
294
+ }
295
+ } else {
296
+ const defaultFallbacks = [...ANTIGRAVITY_ENDPOINT_FALLBACKS];
297
+ const lastGood = providerState?.lastGoodEndpoint;
298
+ if (lastGood && defaultFallbacks.includes(lastGood)) endpoints = [lastGood, ...defaultFallbacks.filter((e) => e !== lastGood)];
299
+ else endpoints = defaultFallbacks;
300
+ }
301
+ } else endpoints = baseUrl ? [baseUrl] : [DEFAULT_ENDPOINT];
302
+ let requestBody = buildRequest(model, context, projectId, options, isAntigravity);
303
+ const replacementPayload = await options?.onPayload?.(requestBody, model);
304
+ if (replacementPayload !== void 0) requestBody = replacementPayload;
305
+ const headers = isAntigravity ? { "User-Agent": getAntigravityUserAgent() } : getGeminiCliHeaders(model.id);
306
+ const requestHeaders = {
307
+ Authorization: `Bearer ${accessToken}`,
308
+ "Content-Type": "application/json",
309
+ Accept: "text/event-stream",
310
+ ...headers,
311
+ ...needsClaudeThinkingBetaHeader(model) ? { "anthropic-beta": CLAUDE_THINKING_BETA_HEADER } : {},
312
+ ...options?.headers ?? {}
313
+ };
314
+ const requestBodyJson = JSON.stringify(requestBody);
315
+ rawRequestDump = {
316
+ provider: model.provider,
317
+ api: output.api,
318
+ model: model.id,
319
+ method: "POST",
320
+ body: requestBody,
321
+ headers: requestHeaders
322
+ };
323
+ const firstEventTimeoutMs = options?.streamFirstEventTimeoutMs ?? getStreamFirstEventTimeoutMs(void 0, model.id.includes("flash") ? FLASH_FIRST_EVENT_TIMEOUT_MS : DEFAULT_FIRST_EVENT_TIMEOUT_MS);
324
+ const callerSignal = options?.signal;
325
+ const toolNames = new Set(context.tools?.map((t) => t.name) ?? []);
326
+ const isFlashLeakModel = model.id.includes("flash");
327
+ let started = false;
328
+ let sawFinishReason = false;
329
+ let lastResponseId;
330
+ const ensureStarted = () => {
331
+ if (!started) {
332
+ if (!firstTokenTime) firstTokenTime = performance.now();
333
+ stream.push({
334
+ type: "start",
335
+ partial: output
336
+ });
337
+ started = true;
338
+ }
339
+ };
340
+ const resetOutput = () => {
341
+ output.content = [];
342
+ output.usage = {
343
+ input: 0,
344
+ output: 0,
345
+ cacheRead: 0,
346
+ cacheWrite: 0,
347
+ totalTokens: 0,
348
+ cost: {
349
+ input: 0,
350
+ output: 0,
351
+ cacheRead: 0,
352
+ cacheWrite: 0,
353
+ total: 0
354
+ }
355
+ };
356
+ output.stopReason = "stop";
357
+ output.errorMessage = void 0;
358
+ output.timestamp = Date.now();
359
+ sawFinishReason = false;
360
+ };
361
+ const streamResponse = async (activeResponse) => {
362
+ if (!activeResponse.body) throw new ProviderResponseError("No response body", {
363
+ provider: model.provider,
364
+ kind: "empty-body"
365
+ });
366
+ lastResponseId = void 0;
367
+ let currentBlock = null;
368
+ const blocks = output.content;
369
+ const blockIndex = () => blocks.length - 1;
370
+ const visibleTextHealing = new StreamMarkupHealing({ pattern: "thinking" });
371
+ let isBuffering = false;
372
+ let textBuffer = "";
373
+ let bufferedTextSignature;
374
+ let strippedPlanningLeak = false;
375
+ const endCurrentBlock = () => {
376
+ if (!currentBlock) return;
377
+ pushBlockEndEvent(currentBlock, blockIndex(), output, stream);
378
+ currentBlock = null;
379
+ };
380
+ const startTextBlock = () => {
381
+ let block = currentBlock;
382
+ if (block?.type !== "text") {
383
+ endCurrentBlock();
384
+ block = startTextOrThinkingBlock(false, output, stream, ensureStarted);
385
+ currentBlock = block;
386
+ }
387
+ return block;
388
+ };
389
+ const startThinkingBlock = () => {
390
+ let block = currentBlock;
391
+ if (block?.type !== "thinking") {
392
+ endCurrentBlock();
393
+ block = startTextOrThinkingBlock(true, output, stream, ensureStarted);
394
+ currentBlock = block;
395
+ }
396
+ return block;
397
+ };
398
+ const emitVisibleText = (delta, thoughtSignature) => {
399
+ if (!delta) return;
400
+ const block = startTextBlock();
401
+ block.text += delta;
402
+ block.textSignature = retainThoughtSignature(block.textSignature, thoughtSignature);
403
+ stream.push({
404
+ type: "text_delta",
405
+ contentIndex: blockIndex(),
406
+ delta,
407
+ partial: output
408
+ });
409
+ };
410
+ const emitVisibleThinking = (delta) => {
411
+ if (!delta) return;
412
+ const block = startThinkingBlock();
413
+ block.thinking += delta;
414
+ stream.push({
415
+ type: "thinking_delta",
416
+ contentIndex: blockIndex(),
417
+ delta,
418
+ partial: output
419
+ });
420
+ };
421
+ const emitHealingEvent = (event, thoughtSignature) => {
422
+ if (event.type === "text") emitVisibleText(event.text, thoughtSignature);
423
+ else if (event.type === "thinking") emitVisibleThinking(event.thinking);
424
+ };
425
+ const feedVisibleText = (delta, thoughtSignature) => {
426
+ for (const event of visibleTextHealing.feedEvents(delta)) emitHealingEvent(event, thoughtSignature);
427
+ };
428
+ const flushVisibleText = (thoughtSignature) => {
429
+ for (const event of visibleTextHealing.flushEvents()) emitHealingEvent(event, thoughtSignature);
430
+ };
431
+ const retainCurrentBlockThoughtSignature = (thoughtSignature) => {
432
+ const block = currentBlock;
433
+ if (!block) return;
434
+ if (block.type === "thinking") block.thinkingSignature = retainThoughtSignature(block.thinkingSignature, thoughtSignature);
435
+ else block.textSignature = retainThoughtSignature(block.textSignature, thoughtSignature);
436
+ };
437
+ const responseAbortController = new AbortController();
438
+ const responseSignal = options?.signal ? AbortSignal.any([options.signal, responseAbortController.signal]) : responseAbortController.signal;
439
+ const chunks = iterateWithIdleTimeout(readSseJson(activeResponse.body, responseSignal, (event) => options?.onSseEvent?.({
440
+ event: event.event,
441
+ data: event.data,
442
+ raw: [...event.raw]
443
+ }, model)), {
444
+ firstItemTimeoutMs: firstEventTimeoutMs,
445
+ errorMessage: FIRST_EVENT_TIMEOUT_ERROR,
446
+ firstItemErrorMessage: FIRST_EVENT_TIMEOUT_ERROR,
447
+ onFirstItemTimeout: () => responseAbortController.abort(new StreamTimeoutError(FIRST_EVENT_TIMEOUT_ERROR)),
448
+ abortSignal: options?.signal
449
+ });
450
+ for await (const chunk of chunks) {
451
+ if (chunk.error) {
452
+ const message = `Cloud Code Assist stream error: ${chunk.error.message || chunk.error.status || "unknown error"}`;
453
+ throw typeof chunk.error.code === "number" && chunk.error.code >= 400 ? new GeminiCliApiError(message, chunk.error.code) : new ProviderResponseError(message, {
454
+ provider: model.provider,
455
+ kind: "runtime"
456
+ });
457
+ }
458
+ const responseData = chunk.response;
459
+ if (!responseData) continue;
460
+ if (responseData.responseId) lastResponseId = responseData.responseId;
461
+ if (!responseData.candidates?.length && responseData.promptFeedback?.blockReason) {
462
+ const detail = responseData.promptFeedback.blockReasonMessage;
463
+ throw new ProviderResponseError(`Request blocked by Google (${responseData.promptFeedback.blockReason})${detail ? `: ${detail}` : ""}`, {
464
+ provider: model.provider,
465
+ kind: "content-blocked"
466
+ });
467
+ }
468
+ const candidate = responseData.candidates?.[0];
469
+ if (candidate?.content?.parts) for (const part of candidate.content.parts) {
470
+ if (part.text !== void 0 && part.text !== "") {
471
+ if (isThinkingPart(part)) {
472
+ flushVisibleText();
473
+ const block = startThinkingBlock();
474
+ block.thinking += part.text;
475
+ block.thinkingSignature = retainThoughtSignature(block.thinkingSignature, part.thoughtSignature);
476
+ stream.push({
477
+ type: "thinking_delta",
478
+ contentIndex: blockIndex(),
479
+ delta: part.text,
480
+ partial: output
481
+ });
482
+ } else {
483
+ if (isBuffering) {
484
+ textBuffer += part.text;
485
+ bufferedTextSignature = retainThoughtSignature(bufferedTextSignature, part.thoughtSignature);
486
+ } else if (isFlashLeakModel && part.text.trimStart().startsWith("{")) {
487
+ isBuffering = true;
488
+ textBuffer = part.text;
489
+ bufferedTextSignature = part.thoughtSignature;
490
+ } else feedVisibleText(part.text, part.thoughtSignature);
491
+ if (isBuffering) {
492
+ const buffered = consumePlanningBuffer(textBuffer, toolNames);
493
+ if (buffered.kind !== "incomplete") {
494
+ if (buffered.kind === "leak") strippedPlanningLeak = true;
495
+ const visibleSignature = bufferedTextSignature;
496
+ isBuffering = false;
497
+ textBuffer = "";
498
+ bufferedTextSignature = void 0;
499
+ feedVisibleText(buffered.visibleText, visibleSignature);
500
+ }
501
+ }
502
+ }
503
+ } else if (part.text === "" && part.thoughtSignature && !part.functionCall) retainCurrentBlockThoughtSignature(part.thoughtSignature);
504
+ if (part.functionCall) {
505
+ flushVisibleText();
506
+ endCurrentBlock();
507
+ isBuffering = false;
508
+ textBuffer = "";
509
+ const providedId = part.functionCall.id;
510
+ const toolCall = {
511
+ type: "toolCall",
512
+ id: !providedId || output.content.some((b) => b.type === "toolCall" && b.id === providedId) ? nextToolCallId(part.functionCall.name || "tool") : providedId,
513
+ name: part.functionCall.name || "",
514
+ arguments: part.functionCall.args ?? {},
515
+ ...part.thoughtSignature && { thoughtSignature: part.thoughtSignature }
516
+ };
517
+ output.content.push(toolCall);
518
+ ensureStarted();
519
+ pushToolCallEvents(toolCall, blockIndex(), output, stream);
520
+ }
521
+ }
522
+ if (candidate?.finishReason) {
523
+ sawFinishReason = true;
524
+ const mapped = mapStopReasonString(candidate.finishReason);
525
+ if ((mapped === "stop" || mapped === "length") && output.content.some((b) => b.type === "toolCall")) output.stopReason = "toolUse";
526
+ else {
527
+ output.stopReason = mapped;
528
+ if (mapped === "error") output.errorMessage = `Generation failed with finish reason: ${candidate.finishReason}`;
529
+ }
530
+ }
531
+ if (responseData.usageMetadata) {
532
+ const promptTokens = responseData.usageMetadata.promptTokenCount || 0;
533
+ const cacheReadTokens = responseData.usageMetadata.cachedContentTokenCount || 0;
534
+ const thinkingTokens = responseData.usageMetadata.thoughtsTokenCount || 0;
535
+ output.usage = {
536
+ input: promptTokens - cacheReadTokens,
537
+ output: (responseData.usageMetadata.candidatesTokenCount || 0) + thinkingTokens,
538
+ cacheRead: cacheReadTokens,
539
+ cacheWrite: 0,
540
+ totalTokens: responseData.usageMetadata.totalTokenCount || 0,
541
+ ...thinkingTokens > 0 ? { reasoningTokens: thinkingTokens } : {},
542
+ cost: {
543
+ input: 0,
544
+ output: 0,
545
+ cacheRead: 0,
546
+ cacheWrite: 0,
547
+ total: 0
548
+ }
549
+ };
550
+ calculateCost(model, output.usage);
551
+ }
552
+ }
553
+ if (isBuffering && textBuffer !== "") {
554
+ const buffered = consumePlanningBuffer(textBuffer, toolNames, true);
555
+ if (buffered.kind !== "incomplete") {
556
+ if (buffered.kind === "leak") strippedPlanningLeak = true;
557
+ feedVisibleText(buffered.visibleText, bufferedTextSignature);
558
+ }
559
+ bufferedTextSignature = void 0;
560
+ isBuffering = false;
561
+ textBuffer = "";
562
+ }
563
+ flushVisibleText(bufferedTextSignature);
564
+ endCurrentBlock();
565
+ return {
566
+ meaningful: hasMeaningfulGoogleContent(output),
567
+ strippedPlanningLeak
568
+ };
569
+ };
570
+ let receivedContent = false;
571
+ const hasThinkingOutput = () => output.content.some((block) => block.type === "thinking" && (block.thinking.trim().length > 0 || Boolean(block.thinkingSignature)));
572
+ for (let i = 0; i < endpoints.length; i++) {
573
+ const endpoint = endpoints[i];
574
+ const isLastEndpoint = i === endpoints.length - 1;
575
+ try {
576
+ started = false;
577
+ resetOutput();
578
+ const watchdog = armPreResponseTimeout(callerSignal, firstEventTimeoutMs);
579
+ let response;
580
+ try {
581
+ response = await fetchWithRetry(() => `${endpoint}/v1internal:streamGenerateContent?alt=sse`, {
582
+ method: "POST",
583
+ headers: requestHeaders,
584
+ body: requestBodyJson,
585
+ signal: watchdog.signal,
586
+ maxAttempts: isLastEndpoint ? 4 : 1,
587
+ defaultDelayMs: (attempt) => BASE_DELAY_MS * 2 ** attempt,
588
+ maxDelayMs: options?.maxRetryDelayMs ?? RATE_LIMIT_BUDGET_MS,
589
+ fetch: options?.fetch,
590
+ timeout: false
591
+ });
592
+ } finally {
593
+ watchdog.clear();
594
+ }
595
+ if (!response.ok) {
596
+ if (isTransientStatus(response.status)) {
597
+ if (!isLastEndpoint) continue;
598
+ }
599
+ const errorText = await response.text();
600
+ const validationUrl = extractGoogleValidationUrl(errorText);
601
+ const errorMessage = validationUrl ? formatGoogleValidationRequiredMessage(validationUrl, "retry your request", parsedCredentials.email) : errorText;
602
+ throw new GeminiCliApiError(`Cloud Code Assist API error (${response.status}): ${errorMessage}`, response.status, { headers: response.headers });
603
+ }
604
+ const requestUrl = response.url;
605
+ let currentResponse = response;
606
+ for (let emptyAttempt = 0; emptyAttempt <= 2; emptyAttempt++) {
607
+ if (options?.signal?.aborted) throw new AbortError("Request was aborted");
608
+ if (emptyAttempt > 0) {
609
+ const backoffMs = 500 * 2 ** (emptyAttempt - 1);
610
+ try {
611
+ await scheduler.wait(backoffMs, { signal: options?.signal });
612
+ } catch {
613
+ throw new AbortError("Request was aborted");
614
+ }
615
+ if (!requestUrl) throw new ConfigurationError("Missing request URL");
616
+ currentResponse = await (options?.fetch ?? fetch)(requestUrl, {
617
+ method: "POST",
618
+ headers: requestHeaders,
619
+ body: requestBodyJson,
620
+ signal: options?.signal
621
+ });
622
+ if (!currentResponse.ok) {
623
+ const retryErrorText = await currentResponse.text();
624
+ throw new GeminiCliApiError(`Cloud Code Assist API error (${currentResponse.status}): ${retryErrorText}`, currentResponse.status, { headers: currentResponse.headers });
625
+ }
626
+ }
627
+ const streamed = await streamResponse(currentResponse);
628
+ const thoughtOnly = hasThinkingOutput();
629
+ const acceptedSilence = options?.acceptEmptyResponse === true && !streamed.strippedPlanningLeak && (isLastEndpoint || thoughtOnly);
630
+ if (output.stopReason !== "stop" || streamed.meaningful || acceptedSilence) {
631
+ receivedContent = streamed.meaningful || acceptedSilence;
632
+ break;
633
+ }
634
+ if (thoughtOnly) break;
635
+ if (emptyAttempt < 2) resetOutput();
636
+ }
637
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new ProviderResponseError(output.errorMessage ?? "An unknown error occurred", {
638
+ provider: model.provider,
639
+ kind: "output"
640
+ });
641
+ if (!receivedContent) {
642
+ const thoughtOnly = hasThinkingOutput();
643
+ throw new ProviderResponseError(thoughtOnly ? "Cloud Code Assist API returned a thought-only response without final output" : "Cloud Code Assist API returned an empty response", {
644
+ provider: model.provider,
645
+ kind: thoughtOnly ? "empty-output" : "empty-body"
646
+ });
647
+ }
648
+ if (options?.signal?.aborted) throw new AbortError("Request was aborted");
649
+ if (!sawFinishReason) throw new ProviderResponseError("Cloud Code Assist stream ended without a finish reason (connection dropped or response truncated)", {
650
+ provider: model.provider,
651
+ kind: "incomplete-stream"
652
+ });
653
+ if (providerState && (options?.antigravityEndpointMode === "auto" || !options?.antigravityEndpointMode)) providerState.lastGoodEndpoint = endpoint;
654
+ if (providerState) providerState.lastExecutionId = lastResponseId;
655
+ break;
656
+ } catch (error) {
657
+ const status = extractHttpStatusFromError(error);
658
+ if (!isLastEndpoint && !started && (isTransientStatus(status) || status === void 0 && !(error instanceof ProviderResponseError && error.kind === "output") && retriable(classify(error)))) continue;
659
+ throw error;
660
+ }
661
+ }
662
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new ProviderResponseError(output.errorMessage ?? "An unknown error occurred", {
663
+ provider: model.provider,
664
+ kind: "output"
665
+ });
666
+ output.duration = performance.now() - startTime;
667
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
668
+ stream.push({
669
+ type: "done",
670
+ reason: output.stopReason,
671
+ message: output
672
+ });
673
+ stream.end();
674
+ } catch (error) {
675
+ const result = await finalize(error, {
676
+ api: model.api,
677
+ signal: options?.signal,
678
+ rawRequestDump
679
+ });
680
+ output.stopReason = result.stopReason;
681
+ output.errorStatus = result.status;
682
+ output.errorId = result.id;
683
+ output.errorMessage = result.message;
684
+ output.duration = performance.now() - startTime;
685
+ if (firstTokenTime) output.ttft = firstTokenTime - startTime;
686
+ stream.push({
687
+ type: "error",
688
+ reason: output.stopReason,
689
+ error: output
690
+ });
691
+ stream.end();
692
+ }
693
+ })();
694
+ return stream;
695
+ };
696
+ const INT63_MASK = (1n << 63n) - 1n;
697
+ const ANTIGRAVITY_RANDOM_BOUND = 9000000000000000000n;
698
+ function formatSignedDecimalSessionId(value) {
699
+ return `-${value.toString()}`;
700
+ }
701
+ function deriveSignedDecimalFromHash(text) {
702
+ const digest = createHash("sha256").update(text).digest();
703
+ let value = 0n;
704
+ for (let index = 0; index < 8; index += 1) value = value << 8n | BigInt(digest[index] ?? 0);
705
+ return formatSignedDecimalSessionId(value & INT63_MASK);
706
+ }
707
+ function randomBoundedInt63(maxExclusive) {
708
+ while (true) {
709
+ const bytes = randomBytes(8);
710
+ let value = 0n;
711
+ for (const byte of bytes) value = value << 8n | BigInt(byte);
712
+ value &= INT63_MASK;
713
+ if (value < maxExclusive) return value;
714
+ }
715
+ }
716
+ function randomSignedDecimalSessionId() {
717
+ return formatSignedDecimalSessionId(randomBoundedInt63(ANTIGRAVITY_RANDOM_BOUND));
718
+ }
719
+ function getFirstUserTextForAntigravitySession(context) {
720
+ for (const message of context.messages) {
721
+ if (message.role !== "user") continue;
722
+ if (typeof message.content === "string") return message.content;
723
+ if (Array.isArray(message.content)) return message.content.find((item) => item.type === "text")?.text;
724
+ return;
725
+ }
726
+ }
727
+ function deriveAntigravitySessionId(context) {
728
+ const text = getFirstUserTextForAntigravitySession(context);
729
+ if (text && text.trim().length > 0) return deriveSignedDecimalFromHash(text);
730
+ return randomSignedDecimalSessionId();
731
+ }
732
+ function normalizeAntigravityTools(tools) {
733
+ return tools?.map((tool) => ({
734
+ ...tool,
735
+ functionDeclarations: tool.functionDeclarations.map((declaration) => {
736
+ if ("parameters" in declaration) return declaration;
737
+ const { parametersJsonSchema, ...rest } = declaration;
738
+ return {
739
+ ...rest,
740
+ parameters: normalizeSchemaForCCA(parametersJsonSchema)
741
+ };
742
+ })
743
+ }));
744
+ }
745
+ /**
746
+ * Build the Antigravity request envelope (sessionId, structured requestId,
747
+ * labels) advancing the per-conversation session state. Mirrors the real
748
+ * `antigravity/hub` client: `requestId` is `agent/<agentId>/<ts>/<trajectoryId>/<step>`
749
+ * and `labels.last_step_index` trails the requestId step by one. Without session
750
+ * state (direct callers/tests) it falls back to ephemeral ids.
751
+ */
752
+ function buildAntigravityRequestEnvelope(model, context, wireModelId, state) {
753
+ if (state) {
754
+ state.agentId ??= randomUUID();
755
+ state.trajectoryId ??= randomUUID();
756
+ state.sessionId ??= randomSignedDecimalSessionId();
757
+ state.stepIndex = (state.stepIndex ?? 1) + 1;
758
+ }
759
+ const agentId = state?.agentId ?? randomUUID();
760
+ const trajectoryId = state?.trajectoryId ?? randomUUID();
761
+ const sessionId = state?.sessionId ?? deriveAntigravitySessionId(context);
762
+ const step = state?.stepIndex ?? 2;
763
+ const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
764
+ const isClaude = isClaudeModel(model.id);
765
+ const profile = getAntigravityModelWireProfile(wireModelId);
766
+ const labels = {};
767
+ if (state?.lastExecutionId) labels.last_execution_id = state.lastExecutionId;
768
+ labels.last_step_index = String(step - 1);
769
+ if (profile?.modelEnum !== void 0) labels.model_enum = profile.modelEnum;
770
+ labels.trajectory_id = trajectoryId;
771
+ labels.used_claude = String(isClaude);
772
+ labels.used_claude_conservative = String(isClaude);
773
+ return {
774
+ sessionId,
775
+ requestId,
776
+ labels
777
+ };
778
+ }
779
+ function buildRequest(model, context, projectId, options = {}, isAntigravity = false) {
780
+ const systemPrompts = normalizeSystemPrompts(context.systemPrompt);
781
+ const contents = convertMessages(model, context);
782
+ const generationConfig = {};
783
+ if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
784
+ if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
785
+ if (options.topP !== void 0) generationConfig.topP = options.topP;
786
+ if (options.topK !== void 0) generationConfig.topK = options.topK;
787
+ if (options.minP !== void 0) generationConfig.minP = options.minP;
788
+ if (options.presencePenalty !== void 0) generationConfig.presencePenalty = options.presencePenalty;
789
+ if (options.repetitionPenalty !== void 0) generationConfig.repetitionPenalty = options.repetitionPenalty;
790
+ if (options.thinking?.enabled && model.reasoning) {
791
+ generationConfig.thinkingConfig = { includeThoughts: !options.hideThinkingSummary };
792
+ if (options.thinking.level !== void 0) generationConfig.thinkingConfig.thinkingLevel = options.thinking.level;
793
+ else if (options.thinking.budgetTokens !== void 0) generationConfig.thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
794
+ } else if (options.thinking?.suppress && model.reasoning) {
795
+ const suppress = options.thinking.suppress;
796
+ generationConfig.thinkingConfig = { includeThoughts: false };
797
+ if ("level" in suppress) generationConfig.thinkingConfig.thinkingLevel = suppress.level;
798
+ else generationConfig.thinkingConfig.thinkingBudget = suppress.budget;
799
+ }
800
+ const request = { contents };
801
+ if (systemPrompts.length > 0) request.systemInstruction = {
802
+ ...isAntigravity ? { role: "user" } : {},
803
+ parts: systemPrompts.map((text) => ({ text }))
804
+ };
805
+ if (context.tools && context.tools.length > 0) {
806
+ const convertedTools = convertTools(context.tools, model);
807
+ request.tools = isAntigravity ? normalizeAntigravityTools(convertedTools) : convertedTools;
808
+ if (options.toolChoice) {
809
+ const choice = options.toolChoice;
810
+ if (typeof choice === "string") {
811
+ const mode = mapToolChoice(choice);
812
+ if (mode !== "AUTO") request.toolConfig = { functionCallingConfig: { mode } };
813
+ } else request.toolConfig = { functionCallingConfig: {
814
+ mode: "ANY",
815
+ allowedFunctionNames: [...choice.allowedFunctionNames]
816
+ } };
817
+ if (isAntigravity && !isClaudeModel(model.id) && request.toolConfig?.functionCallingConfig.mode === "ANY") contents.push({
818
+ role: "user",
819
+ parts: [{ text: google_antigravity_forced_tool_default }]
820
+ });
821
+ }
822
+ if (isAntigravity && !request.toolConfig) request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
823
+ }
824
+ if (isAntigravity && isClaudeModel(model.id)) request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
825
+ const wireModelId = options.requestModelId ?? model.requestModelId ?? model.id;
826
+ if (isAntigravity) {
827
+ const profile = getAntigravityModelWireProfile(wireModelId);
828
+ if (profile) generationConfig.maxOutputTokens = profile.maxOutputTokens;
829
+ const envelope = buildAntigravityRequestEnvelope(model, context, wireModelId, getAntigravityProviderSessionState(options.providerSessionState));
830
+ request.labels = envelope.labels;
831
+ if (Object.keys(generationConfig).length > 0) request.generationConfig = generationConfig;
832
+ request.sessionId = envelope.sessionId;
833
+ return {
834
+ project: projectId,
835
+ requestId: envelope.requestId,
836
+ request,
837
+ model: wireModelId,
838
+ userAgent: "antigravity",
839
+ requestType: "agent"
840
+ };
841
+ }
842
+ if (Object.keys(generationConfig).length > 0) request.generationConfig = generationConfig;
843
+ return {
844
+ project: projectId,
845
+ model: wireModelId,
846
+ request
847
+ };
848
+ }
849
+ //#endregion
850
+ export { streamGoogleGeminiCli };