nolo-cli 0.105.0-alpha.2 → 0.105.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-4W7C3ACS.js → _executeModel-JXG5TLPE.js} +75 -68
  3. package/action-GVA5ARSJ.js +20 -0
  4. package/{addContentAction-O7R66HEX.js → addContentAction-J3DLDV64.js} +12 -11
  5. package/{addDialogAgentAction-74OA7KYP.js → addDialogAgentAction-PHIXJCF2.js} +18 -19
  6. package/{agentDeleteCommand-YB3S2LPY.js → agentDeleteCommand-2AWJGHXG.js} +117 -42
  7. package/{agentEmailCommands-J6YBHL42.js → agentEmailCommands-VV5OSILE.js} +98 -88
  8. package/agentListCommands-OQMRBDWP.js +742 -0
  9. package/{agentMachineCommands-2RWGEBA3.js → agentMachineCommands-3VLLR6RL.js} +48 -43
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-XPJYZSCE.js} +97 -2
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-B4T2DJ5H.js} +1 -1
  12. package/agentRecordCommands-GPIARVOW.js +138 -0
  13. package/agentRunCommand-LRJTZ7IM.js +167 -0
  14. package/{agentRunControl-AVJR4JW4.js → agentRunControl-3HWA2LLQ.js} +2 -2
  15. package/{agentRuntimeLocal-FRUE5P2V.js → agentRuntimeLocal-PV6AZOEU.js} +44 -39
  16. package/{agentSlice-6LBOYNKN.js → agentSlice-6R3JKS6I.js} +14 -13
  17. package/{appDeleteCommands-JPWTSFID.js → appDeleteCommands-WEX73P5R.js} +46 -41
  18. package/{appDeployCommands-YCVY2UYO.js → appDeployCommands-7BAXWA4M.js} +46 -41
  19. package/{appDeployStatusCommands-JMCEIKTI.js → appDeployStatusCommands-EJ6A2U4X.js} +46 -41
  20. package/{appGetCommands-EXWT3QAE.js → appGetCommands-SB355OEX.js} +46 -41
  21. package/{appListCommands-PKRLSWRE.js → appListCommands-TSZDPIKJ.js} +46 -41
  22. package/{authCommand-F4EFRRX6.js → authCommand-5PB3YRVV.js} +118 -24
  23. package/{authCommands-RGOGCPP6.js → authCommands-5RTUDYZW.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-SBBWTANC.js} +10 -8
  25. package/{chromeCommands-FZYAU75D.js → chromeCommands-AU5ZJXBG.js} +289 -37
  26. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-ZYTCMNHG.js} +156 -22
  27. package/{chunk-6OZ36FXI.js → chunk-27ONFIEY.js} +22 -4
  28. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  29. package/{chunk-HVURBGF3.js → chunk-2U3NHADM.js} +6 -6
  30. package/{chunk-53HEEOTT.js → chunk-2WJ57RJA.js} +83 -16
  31. package/{chunk-OIVSQH2O.js → chunk-3BXNTXYI.js} +299 -5
  32. package/{chunk-V4MJDUSR.js → chunk-3F424ASC.js} +2 -2
  33. package/{chunk-HJUYAD4A.js → chunk-3Q7NEHAR.js} +5 -5
  34. package/chunk-44CU7CKA.js +13545 -0
  35. package/{chunk-EYAQT56M.js → chunk-4DPP773Q.js} +2 -2
  36. package/chunk-4LCOCOR5.js +50 -0
  37. package/{chunk-JPGCXHNM.js → chunk-4LKMZ3RR.js} +1 -1
  38. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  39. package/{chunk-6D6VBVEW.js → chunk-4W24JM32.js} +80 -14
  40. package/{chunk-H62HCIUP.js → chunk-4WMMIL66.js} +35 -22
  41. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  42. package/{chunk-ZCYXJSTU.js → chunk-54VPQTOA.js} +66 -94
  43. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  44. package/chunk-5MMAK75Q.js +15 -0
  45. package/{chunk-7S4YWN7P.js → chunk-5UUIGN6I.js} +4 -4
  46. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  47. package/{chunk-GQBOR3G6.js → chunk-7KVZ5LDQ.js} +2 -2
  48. package/chunk-A4SQRTZ6.js +15 -0
  49. package/{chunk-L5UXH3B2.js → chunk-AFH5QC6R.js} +58 -9
  50. package/{chunk-AEOE4Z6Q.js → chunk-AFSY3ZMB.js} +39 -15
  51. package/chunk-AGIM7IMJ.js +147 -0
  52. package/{chunk-5UTFL4QJ.js → chunk-AOTBKDRK.js} +7 -0
  53. package/{chunk-NA35QHCF.js → chunk-AWVP7PPG.js} +1 -1
  54. package/{chunk-EEGDMATE.js → chunk-B7APRSPS.js} +86 -81
  55. package/{chunk-W324THOB.js → chunk-BB7LVBTS.js} +20 -11
  56. package/{chunk-6YTOJY35.js → chunk-BZ7NPA6G.js} +35 -2
  57. package/{chunk-5H7KJX7J.js → chunk-CFHWVEUJ.js} +5 -5
  58. package/chunk-CHOZJMJS.js +78 -0
  59. package/{chunk-ETI2NYVF.js → chunk-CNA27EMD.js} +4 -4
  60. package/{chunk-ACTMNVHM.js → chunk-CYSYR67N.js} +1 -1
  61. package/{chunk-WV42OMV7.js → chunk-D2GQE6AF.js} +8 -8
  62. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  63. package/{chunk-Q554LLSI.js → chunk-DMXLXZKL.js} +1 -1
  64. package/chunk-DZ7R5V3Y.js +164 -0
  65. package/{chunk-3VNWWVKB.js → chunk-E3YWHWCR.js} +50 -18
  66. package/{chunk-KQ4ONNQD.js → chunk-EKPKW6RM.js} +155 -8
  67. package/{chunk-2J5Y72GY.js → chunk-EP7BWZ4B.js} +1 -1
  68. package/{chunk-ABQYVJBJ.js → chunk-EV235ILT.js} +5 -5
  69. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  70. package/{chunk-3ZW5ZJMM.js → chunk-FGSJ3YMD.js} +23 -28
  71. package/{chunk-2F7RJC6L.js → chunk-FOXQ7BAB.js} +1 -1
  72. package/{chunk-SH43IESU.js → chunk-GGC55Q32.js} +199 -29
  73. package/chunk-GMZLP5DV.js +82 -0
  74. package/{chunk-DHDMC6FO.js → chunk-GSKPJIHY.js} +14 -9
  75. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  76. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  77. package/{chunk-QOKAKDPE.js → chunk-HIM3FCLF.js} +0 -1
  78. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  79. package/{chunk-VLTIYV3X.js → chunk-HP57OUJO.js} +4 -4
  80. package/{chunk-NXUYQBDZ.js → chunk-HYXABXCZ.js} +29 -78
  81. package/{chunk-DNCEALKX.js → chunk-IEJ5YDA4.js} +22 -29
  82. package/{chunk-O6OSWFZQ.js → chunk-IHPDK6UD.js} +6 -0
  83. package/{chunk-BP4XNZRM.js → chunk-JIXGJTBU.js} +4 -4
  84. package/{chunk-GPCZ7UXG.js → chunk-K6U4NKFJ.js} +1 -1
  85. package/{chunk-Z77CRGTW.js → chunk-KA5O5KQL.js} +1 -1
  86. package/{chunk-4OEFYTWL.js → chunk-L5WOICCV.js} +67 -48
  87. package/{chunk-LS2ZANRJ.js → chunk-LOCNXNOU.js} +1 -1
  88. package/chunk-LWLNLZC5.js +265 -0
  89. package/{chunk-H66KLASO.js → chunk-LWXE6IFU.js} +567 -519
  90. package/{chunk-PUOC4YRO.js → chunk-M7VLQGQP.js} +11 -0
  91. package/chunk-NKWIS6G2.js +442 -0
  92. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  93. package/{chunk-DJWMIXDZ.js → chunk-NSAFG343.js} +10 -10
  94. package/{chunk-UKZDAFYT.js → chunk-NSBID7PR.js} +6 -10
  95. package/{chunk-U7ISRJQO.js → chunk-NTR4SD3P.js} +845 -240
  96. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  97. package/chunk-NWENLDMM.js +42 -0
  98. package/chunk-O7SVKKLY.js +875 -0
  99. package/chunk-OCZKATRC.js +129 -0
  100. package/{chunk-VMFTFOWF.js → chunk-OKGVNZTL.js} +35 -8
  101. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  102. package/{chunk-JRQFUXY7.js → chunk-P5GCTVGV.js} +99 -22
  103. package/{chunk-PQFHGD77.js → chunk-QKTESDWK.js} +161 -14
  104. package/{chunk-U3JZVWIB.js → chunk-QMXJ5KDJ.js} +68 -46
  105. package/{chunk-GEPUP7OO.js → chunk-QYUBY3OZ.js} +3 -3
  106. package/{chunk-3BMYXEUW.js → chunk-R5AJODNI.js} +1 -1
  107. package/{chunk-J4MOO56S.js → chunk-RILRSUGC.js} +10 -2
  108. package/{chunk-OEVAY4J6.js → chunk-RWX7AY7J.js} +18 -20
  109. package/{chunk-YY7I6GQ3.js → chunk-S2NSK7AZ.js} +11 -9
  110. package/{chunk-IIVGDG4I.js → chunk-SJKULPGX.js} +13 -7
  111. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  112. package/chunk-TY3TIUJK.js +89 -0
  113. package/{chunk-I3TQJXQ7.js → chunk-U3C3IA32.js} +9 -2
  114. package/{chunk-UZGQNTVW.js → chunk-UA324D4O.js} +8 -6
  115. package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
  116. package/chunk-UWXDA7L5.js +8005 -0
  117. package/{chunk-3DII57IT.js → chunk-VCAQFMVN.js} +1 -1
  118. package/chunk-VIWDGTDA.js +8 -0
  119. package/chunk-VJVNU77E.js +83 -0
  120. package/{chunk-A6FMKU7M.js → chunk-VVJ2ENLY.js} +47 -67
  121. package/{chunk-UKWGR5SS.js → chunk-VY6VFGKR.js} +194 -1144
  122. package/{chunk-QDSINZM3.js → chunk-WJ3B6FX6.js} +1 -14
  123. package/{chunk-Q67DOFOO.js → chunk-Y3PMXGLH.js} +2 -0
  124. package/chunk-YK5MHOWM.js +915 -0
  125. package/chunk-YV25TM3R.js +780 -0
  126. package/{chunk-TOP2VXOR.js → chunk-YVU4XVJD.js} +5 -5
  127. package/{chunk-HVP6P5FV.js → chunk-Z5NGE5DH.js} +29 -9
  128. package/{chunk-LC43IGO4.js → chunk-ZBHR642M.js} +704 -950
  129. package/chunk-ZRAU6T47.js +56 -0
  130. package/{chunk-XPVRVN4U.js → chunk-ZSUDOTPL.js} +19 -17
  131. package/commandRegistry-QU62WJQX.js +833 -0
  132. package/{contentThunks-LXOZUD2Y.js → contentThunks-VGV3JJVB.js} +37 -35
  133. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  134. package/{createAgentAutomationAction-M5NDEIC6.js → createAgentAutomationAction-ZNVLI4WV.js} +39 -37
  135. package/createDialogAction-TTUA46DT.js +69 -0
  136. package/{createPageAction-WY5ZKP2M.js → createPageAction-KUFSC5XW.js} +46 -43
  137. package/{chunk-OWS6OYF4.js → cursorProvider-YGGNMVWX.js} +2751 -10172
  138. package/{dbSlice-XVWBAGYN.js → dbSlice-MYEETO73.js} +11 -10
  139. package/{deleteFile-YG6QMJLU.js → deleteFile-KESP65GC.js} +7 -6
  140. package/{dialogCommands-YVMHDEOX.js → dialogCommands-DRDPEOTL.js} +49 -45
  141. package/{dialogSlice-HSGREZGA.js → dialogSlice-V2SVSTIV.js} +41 -34
  142. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  143. package/{docCreateCommands-7UTWDYJU.js → docCreateCommands-M26CFDDQ.js} +48 -43
  144. package/{docDeleteCommands-GG6BJ4PS.js → docDeleteCommands-LRZHCKVX.js} +49 -44
  145. package/{docReadCommands-QHMQVSLP.js → docReadCommands-6QJSISHK.js} +47 -42
  146. package/{docStore-IIS36NGG.js → docStore-4RWAFNDM.js} +16 -12
  147. package/{docUpdateCommands-QPL6IVUK.js → docUpdateCommands-W4KU4U5T.js} +48 -43
  148. package/{fetchMessages-EIU7UFFK.js → fetchMessages-3PXAHKCR.js} +5 -5
  149. package/{getPricing-LUSEABA6.js → getPricing-NMMFT3YI.js} +4 -4
  150. package/{handleSendMessageAction-FEHCWMN2.js → handleSendMessageAction-VEWLGB5Z.js} +107 -41
  151. package/index.js +87 -884
  152. package/{lib-FRRS27KN.js → lib-PU2G2MSO.js} +523 -191
  153. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-UYCKO7YZ.js} +2 -2
  154. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-TU6OBC76.js} +9 -6
  155. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-VKWVOPPI.js} +1 -1
  156. package/{machineCommands-ERCXIPJC.js → machineCommands-AEHHCJEW.js} +92 -82
  157. package/machineWsRunDispatch-MY2KHS36.js +154 -0
  158. package/{memberThunks-QGFLFVCI.js → memberThunks-EE6TI3TV.js} +20 -18
  159. package/{models-T3SG6MJ5.js → models-ZPU5EDF4.js} +2 -2
  160. package/oauthTokenStore-ITEB663N.js +23 -0
  161. package/package.json +1 -1
  162. package/pdf-U6KSUEZZ.js +26435 -0
  163. package/processSpawn-SOAV3FEV.js +11 -0
  164. package/profileConfig-ZGOFORWV.js +43 -0
  165. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-TEBH7FDX.js} +7 -7
  166. package/{providerRegistry-757OWH3O.js → providerRegistry-CBJLNCET.js} +11 -7
  167. package/{read-COE3ZYR6.js → read-PJIT2YEJ.js} +7 -6
  168. package/{readDocTool-5USN4A6V.js → readDocTool-DRSXHGNL.js} +5 -3
  169. package/{readlineWorkspace-PXATJOED.js → readlineWorkspace-7Q6MITLV.js} +2605 -2031
  170. package/{removeDialogAgentAction-IX3MN2ZO.js → removeDialogAgentAction-IN4WUKJJ.js} +21 -25
  171. package/{runAgentClientLoop-UY76PPZM.js → runAgentClientLoop-H2JALUVD.js} +76 -70
  172. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-PIVSBZRZ.js} +4 -4
  173. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  174. package/{setDialogExtraReferencesAction-X4HCPNZL.js → setDialogExtraReferencesAction-VDRF7LPK.js} +15 -13
  175. package/{setPrimaryDialogAgentAction-4GMIQLOD.js → setPrimaryDialogAgentAction-RO6LIWJ4.js} +22 -26
  176. package/{chunk-AFUORTY4.js → settingThunks-3OPOLOIA.js} +226 -940
  177. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  178. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  179. package/{spaceCommands-BMXKR7H6.js → spaceCommands-UBLL5EF2.js} +51 -46
  180. package/{streamAgentChatTurn-3YVIO4KE.js → streamAgentChatTurn-FFJWW3FD.js} +214 -108
  181. package/{switchDialogAgentAction-N52LRPA3.js → switchDialogAgentAction-MVF2JNE7.js} +18 -19
  182. package/{tableCommands-O6NWHFKV.js → tableCommands-6U4BMLRR.js} +10 -10
  183. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-EJT6TMFG.js} +3 -3
  184. package/tools-AZRYLYNK.js +116 -0
  185. package/{tuiSummaryLlmCaller-WFRWERGK.js → tuiSummaryLlmCaller-7S5HJ3MT.js} +25 -22
  186. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  187. package/{updateDialogTitleAction-GF5T3VMK.js → updateDialogTitleAction-5WXTRUJM.js} +82 -44
  188. package/action-YVYQEAAV.js +0 -31
  189. package/agentListCommands-3GWH4E4G.js +0 -410
  190. package/agentRecordCommands-UOF6YM5M.js +0 -128
  191. package/agentRunCommand-AVBWVTAJ.js +0 -156
  192. package/browser-image-compression-MFDTD7K6.js +0 -1763
  193. package/chatQueueReduxAdapter-WFROMKD3.js +0 -186
  194. package/chunk-CQ3WA2NE.js +0 -299
  195. package/chunk-FQUHIG5X.js +0 -20782
  196. package/chunk-M76ECQRD.js +0 -13658
  197. package/chunk-MEYIRKDN.js +0 -8967
  198. package/chunk-Q5FJJ6XI.js +0 -103
  199. package/chunk-S7Z2HMCN.js +0 -25
  200. package/chunk-Y5GCAMGP.js +0 -9
  201. package/chunk-YPREESF4.js +0 -225
  202. package/createDialogAction-TDFOINOY.js +0 -65
  203. package/machineWsRunDispatch-OVA3G76V.js +0 -144
  204. package/settingSlice-ZQZVUPKK.js +0 -204
  205. package/syncMapping-N6RGXGBW.js +0 -437
  206. package/tools-Q6IBBG33.js +0 -110
  207. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  208. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
@@ -0,0 +1,915 @@
1
+ import {
2
+ streamSseDataValues
3
+ } from "./chunk-GMZLP5DV.js";
4
+ import {
5
+ getAntigravityUserAgent,
6
+ readAntigravityProjectId,
7
+ resolveAntigravityCloudCodeBaseUrl
8
+ } from "./chunk-UA324D4O.js";
9
+ import {
10
+ asOptionalTrimmedString
11
+ } from "./chunk-G3SUCT4W.js";
12
+
13
+ // packages/core/chat/upstreamErrorBody.ts
14
+ function parseUpstreamErrorBody(errorText, statusText) {
15
+ if (errorText) {
16
+ try {
17
+ const parsed = JSON.parse(errorText);
18
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
19
+ const error = parsed.error;
20
+ if (error && typeof error === "object" && !Array.isArray(error)) {
21
+ return parsed;
22
+ }
23
+ }
24
+ } catch {
25
+ }
26
+ }
27
+ return { error: { message: errorText || statusText } };
28
+ }
29
+
30
+ // packages/agent-runtime/antigravityCloudCodeProvider.ts
31
+ import { randomUUID } from "node:crypto";
32
+
33
+ // packages/agent-runtime/antigravityWireModel.ts
34
+ var WIRE_PROFILES = {
35
+ // Antigravity discovery exposes 3.7 Flash as one tiered wire model.
36
+ // The UI labels its effort variants (Low/Medium/High), but the literal
37
+ // -medium/-high ids return 404 from streamGenerateContent.
38
+ "gemini-3.7-flash-tiered": { modelEnum: "MODEL_PLACEHOLDER_M301", maxOutputTokens: 65536 },
39
+ // Gemini 3.8 Flash 沿用 3.7 的 tiered 兼容策略:仓库内暂无 Antigravity discovery
40
+ // 证据确认 3.8 的 wire modelEnum,禁止虚构,先只声明同档输出上限;enum 待
41
+ // discovery 证据到位后补齐。
42
+ "gemini-3.8-flash-tiered": { maxOutputTokens: 65536 },
43
+ "gemini-3.6-flash-low": { maxOutputTokens: 65536 },
44
+ "gemini-3.6-flash-medium": { maxOutputTokens: 65536 },
45
+ "gemini-3.6-flash-high": { maxOutputTokens: 65536 },
46
+ // 旧模型 wire 映射保留:存量自定义 agent 仍可能引用(注册表已下线不影响此处)。
47
+ "gemini-3.5-flash-extra-low": { modelEnum: "MODEL_PLACEHOLDER_M187", maxOutputTokens: 65536 },
48
+ "gemini-3.5-flash-low": { modelEnum: "MODEL_PLACEHOLDER_M20", maxOutputTokens: 65536 },
49
+ "gemini-3-flash-agent": { modelEnum: "MODEL_PLACEHOLDER_M132", maxOutputTokens: 65536 },
50
+ "gemini-3.1-pro-low": { modelEnum: "MODEL_PLACEHOLDER_M36", maxOutputTokens: 65535 },
51
+ "gemini-pro-agent": { modelEnum: "MODEL_PLACEHOLDER_M16", maxOutputTokens: 65535 },
52
+ "claude-sonnet-5": { maxOutputTokens: 64e3 },
53
+ "claude-sonnet-4-6": { maxOutputTokens: 64e3 },
54
+ "claude-opus-4-6-thinking": { maxOutputTokens: 64e3 },
55
+ "gemini-2.5-flash": { maxOutputTokens: 65536 },
56
+ "gemini-2.5-pro": { maxOutputTokens: 65536 }
57
+ };
58
+ function resolveAntigravityWireModel(logicalModelId) {
59
+ const id = logicalModelId.trim();
60
+ const lower = id.toLowerCase();
61
+ if (lower === "gemini-3.5-flash") {
62
+ const wireModelId = "gemini-3.5-flash-low";
63
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
64
+ }
65
+ if (lower === "gemini-3.7-flash" || ["gemini-3.7-flash-low", "gemini-3.7-flash-medium", "gemini-3.7-flash-high"].includes(lower)) {
66
+ const wireModelId = "gemini-3.7-flash-tiered";
67
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
68
+ }
69
+ if (lower === "gemini-3.8-flash" || ["gemini-3.8-flash-low", "gemini-3.8-flash-medium", "gemini-3.8-flash-high"].includes(lower)) {
70
+ const wireModelId = "gemini-3.8-flash-tiered";
71
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
72
+ }
73
+ if (lower === "gemini-3.6-flash") {
74
+ const wireModelId = "gemini-3.6-flash-low";
75
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
76
+ }
77
+ if (lower === "gemini-3.1-pro" || lower === "gemini-3.1-pro-preview") {
78
+ const wireModelId = "gemini-3.1-pro-low";
79
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
80
+ }
81
+ if (WIRE_PROFILES[id]) {
82
+ return { wireModelId: id, profile: WIRE_PROFILES[id] };
83
+ }
84
+ return { wireModelId: id };
85
+ }
86
+
87
+ // packages/agent-runtime/sseDataLine.ts
88
+ function parseSseDataLineJson(line) {
89
+ const trimmed = line.trim();
90
+ if (!trimmed.startsWith("data:")) return null;
91
+ const payload = trimmed.slice(5).trim();
92
+ if (!payload || payload === "[DONE]") return null;
93
+ try {
94
+ return JSON.parse(payload);
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ function parseSseDataLineObject(line) {
100
+ const parsed = parseSseDataLineJson(line);
101
+ return parsed && typeof parsed === "object" ? parsed : null;
102
+ }
103
+
104
+ // packages/agent-runtime/geminiNativeShared.ts
105
+ var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
106
+ function resolveGeminiModelQuirks(modelId) {
107
+ const lower = modelId.toLowerCase();
108
+ const isGemini3 = lower.includes("gemini-3");
109
+ const isStrictSignatureModel = lower.includes("gemini-3.5") || lower.includes("flash-preview");
110
+ const isClaude = lower.includes("claude");
111
+ return {
112
+ requiresThoughtSignature: isGemini3,
113
+ allowsThoughtSignatureSentinel: isGemini3 && !isStrictSignatureModel,
114
+ isClaudeCrossModel: isClaude
115
+ };
116
+ }
117
+ function isGemini3Model(modelId) {
118
+ return resolveGeminiModelQuirks(modelId).requiresThoughtSignature;
119
+ }
120
+ function messageText(content) {
121
+ if (typeof content === "string") return content;
122
+ if (!Array.isArray(content)) return "";
123
+ return content.filter(
124
+ (part) => part?.type === "text"
125
+ ).map((part) => part.text).join("\n").trim();
126
+ }
127
+ function parseDataUrlToInlineData(url) {
128
+ const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
129
+ url
130
+ );
131
+ if (!match) return null;
132
+ return { mimeType: match[1], data: match[2] };
133
+ }
134
+ function extractInlineDataParts(content) {
135
+ if (!Array.isArray(content)) return [];
136
+ const parts = [];
137
+ for (const part of content) {
138
+ if (!part || typeof part !== "object") continue;
139
+ if (part.type !== "image_url") continue;
140
+ const url = part.image_url?.url;
141
+ if (typeof url !== "string" || !url.trim()) continue;
142
+ const inline = parseDataUrlToInlineData(url);
143
+ if (inline) parts.push({ inlineData: inline });
144
+ }
145
+ return parts;
146
+ }
147
+ function convertOpenAiMessagesToGemini(messages, options) {
148
+ const contents = [];
149
+ const systemTexts = [];
150
+ let toolCallIndex = 0;
151
+ let pendingFunctionCalls = [];
152
+ const pushOrMergeContent = (role, parts) => {
153
+ if (parts.length === 0) return;
154
+ const last = contents[contents.length - 1];
155
+ if (last && last.role === role) {
156
+ last.parts.push(...parts);
157
+ } else {
158
+ contents.push({ role, parts });
159
+ }
160
+ };
161
+ const flushPendingFunctionCalls = () => {
162
+ if (pendingFunctionCalls.length === 0) return;
163
+ const dummyResponses = pendingFunctionCalls.map(
164
+ ({ name, id }) => ({
165
+ functionResponse: {
166
+ name,
167
+ response: { output: "{}" },
168
+ ...id ? { id } : {}
169
+ }
170
+ })
171
+ );
172
+ pendingFunctionCalls = [];
173
+ pushOrMergeContent("user", dummyResponses);
174
+ };
175
+ for (const raw of messages) {
176
+ if (!raw || typeof raw !== "object" || !("role" in raw)) continue;
177
+ const role = String(raw.role);
178
+ const content = "content" in raw ? raw.content : null;
179
+ if (role === "system") {
180
+ const text = messageText(
181
+ content
182
+ );
183
+ if (text) systemTexts.push(text);
184
+ continue;
185
+ }
186
+ if (role === "user") {
187
+ flushPendingFunctionCalls();
188
+ const text = messageText(
189
+ content
190
+ );
191
+ const imageParts = extractInlineDataParts(
192
+ content
193
+ );
194
+ if (!text && imageParts.length === 0) continue;
195
+ const parts = [];
196
+ if (text) parts.push({ text });
197
+ for (const img of imageParts) parts.push(img);
198
+ pushOrMergeContent("user", parts);
199
+ continue;
200
+ }
201
+ if (role === "assistant") {
202
+ flushPendingFunctionCalls();
203
+ const text = messageText(
204
+ content
205
+ );
206
+ const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
207
+ const parts = [];
208
+ if (text) {
209
+ parts.push({ text });
210
+ }
211
+ for (const call of toolCalls) {
212
+ const name = call?.function?.name?.trim();
213
+ if (!name) continue;
214
+ const id = call.id?.trim() || `${name}_${toolCallIndex++}`;
215
+ pendingFunctionCalls.push({ name, id });
216
+ const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
217
+ const isFirstFunctionCallPart = !parts.some(
218
+ (p) => "functionCall" in p
219
+ );
220
+ const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
221
+ const part = {
222
+ functionCall: {
223
+ name,
224
+ args: parseToolArgs(call.function?.arguments),
225
+ ...id ? { id } : {}
226
+ },
227
+ ...signature ? { thoughtSignature: signature } : {}
228
+ };
229
+ parts.push(part);
230
+ }
231
+ pushOrMergeContent("model", parts);
232
+ continue;
233
+ }
234
+ if (role === "tool") {
235
+ const toolCallId = "tool_call_id" in raw && typeof raw.tool_call_id === "string" ? raw.tool_call_id : "";
236
+ const rawName = "name" in raw && typeof raw.name === "string" ? raw.name.trim() : "";
237
+ const pendingIndex = pendingFunctionCalls.findIndex(
238
+ (p) => toolCallId ? p.id === toolCallId : rawName ? p.name === rawName : true
239
+ );
240
+ if (pendingIndex === -1) continue;
241
+ const [{ name, id }] = pendingFunctionCalls.splice(pendingIndex, 1);
242
+ const output = messageText(content) || "{}";
243
+ pushOrMergeContent("user", [
244
+ {
245
+ functionResponse: {
246
+ name,
247
+ response: { output },
248
+ // 保留 OpenAI tool_call_id:antigravity Cloud Code Assist 网关把
249
+ // Gemini contents 转成 Claude messages 时需要 functionResponse →
250
+ // tool_result 的 tool_use_id;缺 id 时网关报
251
+ // "tool_result.tool_use_id: Field required"(HTTP 400)。
252
+ ...id ? { id } : {}
253
+ }
254
+ }
255
+ ]);
256
+ }
257
+ }
258
+ flushPendingFunctionCalls();
259
+ if (contents.length > 0 && contents[0]?.role === "model") {
260
+ contents.unshift({
261
+ role: "user",
262
+ parts: [{ text: "Continue the conversation." }]
263
+ });
264
+ }
265
+ return { contents, systemTexts };
266
+ }
267
+ function parseToolArgs(raw) {
268
+ if (typeof raw === "string") {
269
+ try {
270
+ const parsed = JSON.parse(raw);
271
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
272
+ return parsed;
273
+ }
274
+ } catch {
275
+ }
276
+ }
277
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
278
+ return raw;
279
+ }
280
+ return {};
281
+ }
282
+ function sanitizeGeminiSchemaNode(node, active) {
283
+ const out = {};
284
+ if (!node || typeof node !== "object" || Array.isArray(node)) {
285
+ return { type: "string" };
286
+ }
287
+ if (active?.has(node)) {
288
+ return { type: "object", description: "(circular schema reference)" };
289
+ }
290
+ const seen = active ?? /* @__PURE__ */ new WeakSet();
291
+ seen.add(node);
292
+ try {
293
+ return sanitizeGeminiSchemaNodeInner(node, out, seen);
294
+ } finally {
295
+ seen.delete(node);
296
+ }
297
+ }
298
+ var enumMetaByNode = /* @__PURE__ */ new WeakMap();
299
+ function enumMetaOf(node) {
300
+ return node && typeof node === "object" ? enumMetaByNode.get(node) : void 0;
301
+ }
302
+ function rawEnumValues(src) {
303
+ if (Array.isArray(src.enum) && src.enum.length > 0) return src.enum;
304
+ if ("const" in src && src.const !== void 0) return [src.const];
305
+ return void 0;
306
+ }
307
+ function geminiEnumFields(values, baseDescription) {
308
+ if (values.every((v) => typeof v === "string")) {
309
+ return {
310
+ enum: [...new Set(values)],
311
+ description: baseDescription
312
+ };
313
+ }
314
+ if (values.every((v) => typeof v === "number" || typeof v === "boolean")) {
315
+ const allowed2 = [...new Set(values.map((v) => String(v)))].join(", ");
316
+ const note2 = `(allowed: ${allowed2})`;
317
+ return {
318
+ description: baseDescription ? `${baseDescription} ${note2}` : note2
319
+ };
320
+ }
321
+ const allowed = [...new Set(values.map(geminiEnumLiteral))].join(", ");
322
+ const note = `(allowed: ${allowed})`;
323
+ return {
324
+ description: baseDescription ? `${baseDescription} ${note}` : note
325
+ };
326
+ }
327
+ function geminiEnumLiteral(value) {
328
+ const json = JSON.stringify(value);
329
+ return json === void 0 ? String(value) : json;
330
+ }
331
+ function applyGeminiEnum(out, fields) {
332
+ if (fields.enum) out.enum = fields.enum;
333
+ if (fields.description !== void 0) out.description = fields.description;
334
+ }
335
+ function sanitizeGeminiSchemaNodeInner(src, out, seen) {
336
+ if (Array.isArray(src.type)) {
337
+ const firstNonNull = src.type.find((t) => t !== "null");
338
+ if (typeof firstNonNull === "string") out.type = firstNonNull;
339
+ out.nullable = true;
340
+ } else if (typeof src.type === "string") {
341
+ out.type = src.type;
342
+ }
343
+ if (typeof src.description === "string") out.description = src.description;
344
+ if (typeof src.minimum === "number") out.minimum = src.minimum;
345
+ if (typeof src.maximum === "number") out.maximum = src.maximum;
346
+ if (src.nullable === true) out.nullable = true;
347
+ const enumValues = rawEnumValues(src);
348
+ if (enumValues) {
349
+ const baseDescription = typeof src.description === "string" ? src.description : void 0;
350
+ enumMetaByNode.set(out, { values: enumValues, baseDescription });
351
+ applyGeminiEnum(out, geminiEnumFields(enumValues, baseDescription));
352
+ }
353
+ const variantBranches = [
354
+ ...Array.isArray(src.oneOf) ? src.oneOf : [],
355
+ ...Array.isArray(src.anyOf) ? src.anyOf : []
356
+ ];
357
+ if (variantBranches.length > 0) {
358
+ const mergedProperties = {};
359
+ let requiredIntersection;
360
+ for (const branch of variantBranches) {
361
+ const sanitized = sanitizeGeminiSchemaNode(branch, seen);
362
+ const branchProperties = sanitized.properties ?? {};
363
+ for (const [key, value] of Object.entries(branchProperties)) {
364
+ const previous = mergedProperties[key];
365
+ const prevMeta = enumMetaOf(previous);
366
+ const nextMeta = enumMetaOf(value);
367
+ if (prevMeta && nextMeta) {
368
+ const values = [...prevMeta.values, ...nextMeta.values];
369
+ const baseDescription = nextMeta.baseDescription ?? prevMeta.baseDescription;
370
+ const node = {
371
+ ...value
372
+ };
373
+ delete node.enum;
374
+ delete node.description;
375
+ applyGeminiEnum(node, geminiEnumFields(values, baseDescription));
376
+ enumMetaByNode.set(node, { values, baseDescription });
377
+ mergedProperties[key] = node;
378
+ } else {
379
+ mergedProperties[key] = value;
380
+ }
381
+ }
382
+ const branchRequired = Array.isArray(sanitized.required) ? sanitized.required : [];
383
+ requiredIntersection = requiredIntersection === void 0 ? [...branchRequired] : requiredIntersection.filter((r) => branchRequired.includes(r));
384
+ }
385
+ out.properties = {
386
+ ...out.properties ?? {},
387
+ ...mergedProperties
388
+ };
389
+ if (requiredIntersection !== void 0 && requiredIntersection.length > 0) {
390
+ out.required = requiredIntersection;
391
+ }
392
+ if (typeof out.type !== "string") out.type = "object";
393
+ }
394
+ if (Array.isArray(src.allOf)) {
395
+ for (const branch of src.allOf) {
396
+ const sanitized = sanitizeGeminiSchemaNode(branch, seen);
397
+ out.properties = {
398
+ ...out.properties ?? {},
399
+ ...sanitized.properties ?? {}
400
+ };
401
+ if (Array.isArray(sanitized.required)) {
402
+ out.required = [
403
+ .../* @__PURE__ */ new Set([
404
+ ...out.required ?? [],
405
+ ...sanitized.required ?? []
406
+ ])
407
+ ];
408
+ }
409
+ }
410
+ if (typeof out.type !== "string") out.type = "object";
411
+ }
412
+ if (src.properties && typeof src.properties === "object") {
413
+ const properties = {};
414
+ for (const [key, value] of Object.entries(
415
+ src.properties
416
+ )) {
417
+ properties[key] = sanitizeGeminiSchemaNode(value, seen);
418
+ }
419
+ out.properties = properties;
420
+ if (typeof out.type !== "string") out.type = "object";
421
+ }
422
+ if (Array.isArray(src.required)) {
423
+ const properties = out.properties ?? {};
424
+ const required = [...new Set(src.required)].filter(
425
+ (r) => typeof r === "string" && r in properties
426
+ );
427
+ if (required.length > 0) out.required = required;
428
+ }
429
+ if (src.items !== void 0) {
430
+ out.items = sanitizeGeminiSchemaNode(src.items, seen);
431
+ if (typeof out.type !== "string") out.type = "array";
432
+ }
433
+ if (typeof out.type !== "string") out.type = "object";
434
+ return out;
435
+ }
436
+ function convertOpenAiToolsToGemini(tools) {
437
+ if (!Array.isArray(tools) || tools.length === 0) return void 0;
438
+ const declarations = [];
439
+ for (const tool of tools) {
440
+ if (!tool || typeof tool !== "object" || !("function" in tool)) continue;
441
+ const fn = tool.function;
442
+ const name = typeof fn.name === "string" ? fn.name : "";
443
+ if (!name) continue;
444
+ declarations.push({
445
+ name,
446
+ description: typeof fn.description === "string" ? fn.description : "",
447
+ parameters: sanitizeGeminiSchemaNode(
448
+ fn.parameters ?? { type: "object", properties: {} }
449
+ )
450
+ });
451
+ }
452
+ if (declarations.length === 0) return void 0;
453
+ return [{ functionDeclarations: declarations }];
454
+ }
455
+ function createGeminiAccumulatorState() {
456
+ return {
457
+ text: "",
458
+ toolCalls: [],
459
+ reasoning: "",
460
+ events: []
461
+ };
462
+ }
463
+ function applyGeminiChunk(chunk, state, options) {
464
+ if (!chunk || typeof chunk !== "object") return;
465
+ const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
466
+ if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
467
+ const meta = response.usageMetadata;
468
+ const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
469
+ const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
470
+ const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
471
+ const cached = typeof meta.cachedContentTokenCount === "number" && Number.isFinite(meta.cachedContentTokenCount) ? (
472
+ // cached ⊆ prompt;对畸形上游防御性钳位,避免 cache_read > input 破坏归一化与计费
473
+ Math.min(Math.max(0, Math.floor(meta.cachedContentTokenCount)), prompt)
474
+ ) : 0;
475
+ state.usage = {
476
+ prompt_tokens: prompt,
477
+ completion_tokens: candidates2,
478
+ total_tokens: total,
479
+ ...cached > 0 ? { cache_read_input_tokens: cached } : {}
480
+ };
481
+ state.events.push({ kind: "usage", usage: state.usage });
482
+ }
483
+ const candidates = Array.isArray(response.candidates) ? response.candidates : [];
484
+ for (const candidate of candidates) {
485
+ if (!candidate || typeof candidate !== "object") continue;
486
+ const candidateFinishReason = candidate.finishReason;
487
+ if (typeof candidateFinishReason === "string" && candidateFinishReason.trim()) {
488
+ state.finishReason = candidateFinishReason.trim();
489
+ state.events.push({ kind: "finish", reason: state.finishReason });
490
+ }
491
+ const parts = Array.isArray(
492
+ candidate.content?.parts
493
+ ) ? candidate.content.parts : [];
494
+ for (const part of parts) {
495
+ if (!part || typeof part !== "object") continue;
496
+ const partSignature = part.thoughtSignature;
497
+ const isThought = Boolean(part.thought);
498
+ if ("text" in part && typeof part.text === "string") {
499
+ const piece = part.text;
500
+ if (!isThought) {
501
+ state.text += piece;
502
+ if (piece) {
503
+ state.events.push({ kind: "text", text: piece });
504
+ if (options?.onTextDelta) options.onTextDelta(piece);
505
+ }
506
+ } else {
507
+ state.reasoning += piece;
508
+ if (piece) {
509
+ state.events.push({ kind: "reasoning", text: piece });
510
+ if (options?.onReasoningDelta) options.onReasoningDelta(piece);
511
+ }
512
+ }
513
+ }
514
+ if (isThought && typeof partSignature === "string" && partSignature) {
515
+ state.pendingThoughtSignature = partSignature;
516
+ }
517
+ if ("functionCall" in part && part.functionCall) {
518
+ const call = part.functionCall;
519
+ const name = typeof call.name === "string" ? call.name : "tool";
520
+ const id = typeof call.id === "string" ? call.id : `${name}_${state.toolCalls.length}`;
521
+ const argsObj = call.args && typeof call.args === "object" ? call.args : {};
522
+ const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : state.pendingThoughtSignature;
523
+ state.pendingThoughtSignature = void 0;
524
+ const toolCall = {
525
+ id,
526
+ type: "function",
527
+ function: { name, arguments: JSON.stringify(argsObj) },
528
+ ...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
529
+ };
530
+ state.toolCalls.push(toolCall);
531
+ state.events.push({ kind: "tool_call", toolCall });
532
+ }
533
+ }
534
+ }
535
+ }
536
+ function accumulateGeminiChunks(chunks, options) {
537
+ const state = createGeminiAccumulatorState();
538
+ for (const chunk of chunks) {
539
+ applyGeminiChunk(chunk, state, options);
540
+ }
541
+ return {
542
+ text: state.text,
543
+ toolCalls: state.toolCalls,
544
+ usage: state.usage,
545
+ finishReason: state.finishReason,
546
+ reasoningContent: state.reasoning,
547
+ events: state.events
548
+ };
549
+ }
550
+ async function accumulateGeminiStream(stream, options) {
551
+ const state = createGeminiAccumulatorState();
552
+ for await (const chunk of stream) {
553
+ applyGeminiChunk(chunk, state, options);
554
+ }
555
+ return {
556
+ text: state.text,
557
+ toolCalls: state.toolCalls,
558
+ usage: state.usage,
559
+ finishReason: state.finishReason,
560
+ reasoningContent: state.reasoning,
561
+ events: state.events
562
+ };
563
+ }
564
+ function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
565
+ return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
566
+ }
567
+ function buildGeminiGenerateContentRequest(args) {
568
+ const { contents, systemTexts } = convertOpenAiMessagesToGemini(
569
+ args.messages,
570
+ { attachSkipThoughtSignature: args.attachSkipThoughtSignature }
571
+ );
572
+ const request = { contents };
573
+ if (systemTexts.length > 0) {
574
+ request.systemInstruction = {
575
+ role: "user",
576
+ parts: systemTexts.map((text) => ({ text }))
577
+ };
578
+ }
579
+ const toolsResult = convertOpenAiToolsToGemini(args.tools);
580
+ if (toolsResult) {
581
+ request.tools = toolsResult;
582
+ request.toolConfig = { functionCallingConfig: { mode: "AUTO" } };
583
+ }
584
+ const generationConfig = {};
585
+ if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
586
+ generationConfig.maxOutputTokens = args.maxTokens;
587
+ }
588
+ if (typeof args.temperature === "number") {
589
+ generationConfig.temperature = args.temperature;
590
+ }
591
+ if (Object.keys(generationConfig).length > 0) {
592
+ request.generationConfig = generationConfig;
593
+ }
594
+ return request;
595
+ }
596
+
597
+ // packages/agent-runtime/antigravityCloudCodeProvider.ts
598
+ var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
599
+ function buildCloudCodeAssistPayload(args) {
600
+ const projectId = readAntigravityProjectId(args.metadata);
601
+ if (!projectId) {
602
+ throw new Error(
603
+ "Antigravity OAuth credential is missing metadata.projectId. Re-run `nolo auth antigravity`."
604
+ );
605
+ }
606
+ const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
607
+ const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
608
+ const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
609
+ const quirks = resolveGeminiModelQuirks(model);
610
+ const isClaude = quirks.isClaudeCrossModel;
611
+ const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
612
+ attachSkipThoughtSignature: quirks.allowsThoughtSignatureSentinel
613
+ });
614
+ if (contents.length === 0) {
615
+ throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
616
+ }
617
+ const prompt = args.agentConfig.prompt?.trim();
618
+ if (prompt) systemTexts.unshift(prompt);
619
+ const request = { contents };
620
+ if (systemTexts.length > 0) {
621
+ request.systemInstruction = {
622
+ role: "user",
623
+ parts: systemTexts.map((text) => ({ text }))
624
+ };
625
+ }
626
+ const tools = convertOpenAiToolsToGemini(
627
+ Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
628
+ );
629
+ if (tools) {
630
+ request.tools = tools;
631
+ request.toolConfig = { functionCallingConfig: { mode: "AUTO" } };
632
+ }
633
+ const generationConfig = {};
634
+ if (profile?.maxOutputTokens) {
635
+ generationConfig.maxOutputTokens = profile.maxOutputTokens;
636
+ } else if (typeof args.agentConfig.max_tokens === "number" && args.agentConfig.max_tokens > 0) {
637
+ generationConfig.maxOutputTokens = args.agentConfig.max_tokens;
638
+ }
639
+ if (typeof args.agentConfig.temperature === "number") {
640
+ generationConfig.temperature = args.agentConfig.temperature;
641
+ }
642
+ if (Object.keys(generationConfig).length > 0) {
643
+ request.generationConfig = generationConfig;
644
+ }
645
+ const agentId = randomUUID();
646
+ const trajectoryId = randomUUID();
647
+ const step = 2;
648
+ const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
649
+ const labels = {
650
+ trajectory_id: trajectoryId,
651
+ last_step_index: String(step - 1),
652
+ used_claude: String(isClaude),
653
+ used_claude_conservative: String(isClaude)
654
+ };
655
+ if (profile?.modelEnum) {
656
+ labels.model_enum = profile.modelEnum;
657
+ }
658
+ request.labels = labels;
659
+ request.sessionId = `-${Math.floor(Math.random() * 9e15)}`;
660
+ return {
661
+ url: `${resolveAntigravityCloudCodeBaseUrl(args.agentConfig.customProviderUrl)}${STREAM_PATH}`,
662
+ envelope: {
663
+ project: projectId,
664
+ model,
665
+ request,
666
+ requestId,
667
+ requestType: "agent",
668
+ userAgent: "antigravity"
669
+ }
670
+ };
671
+ }
672
+ function resolveAntigravityFinishReason(upstream) {
673
+ const normalized = (upstream ?? "").trim().toUpperCase();
674
+ if (normalized === "MAX_TOKENS") return "length";
675
+ if (normalized === "SAFETY" || normalized === "RECITATION" || normalized === "PROHIBITED_CONTENT" || normalized === "BLOCKLIST") {
676
+ return "content_filter";
677
+ }
678
+ return "stop";
679
+ }
680
+ function normalizeAntigravityCompletion(decoded) {
681
+ const { text, toolCalls, usage, finishReason, reasoningContent, events } = decoded;
682
+ const normalizedFinishReason = (finishReason ?? "").trim().toUpperCase();
683
+ if (!text && !reasoningContent && toolCalls.length === 0 && !finishReason && !usage) {
684
+ const body = {
685
+ error: {
686
+ message: "antigravity upstream returned an empty stream (no content, finishReason or usage); channel degradation, not model emptiness"
687
+ },
688
+ provider_events: events
689
+ };
690
+ return {
691
+ status: 502,
692
+ text: "",
693
+ toolCalls: [],
694
+ providerEvents: events,
695
+ body
696
+ };
697
+ }
698
+ if (normalizedFinishReason === "MALFORMED_FUNCTION_CALL") {
699
+ const message2 = "antigravity upstream returned MALFORMED_FUNCTION_CALL (model generated an invalid function call or tool arguments were rejected by upstream)";
700
+ const providerFailure = {
701
+ kind: "provider_failure",
702
+ provider: "antigravity",
703
+ code: "MALFORMED_FUNCTION_CALL",
704
+ message: message2,
705
+ providerReason: "MALFORMED_FUNCTION_CALL",
706
+ retryable: false,
707
+ status: 502
708
+ };
709
+ return {
710
+ status: 502,
711
+ text: "",
712
+ toolCalls: [],
713
+ finishReason,
714
+ providerEvents: events,
715
+ providerFailure,
716
+ runtimeProviderFailure: {
717
+ message: providerFailure.message,
718
+ retryable: providerFailure.retryable
719
+ },
720
+ body: {
721
+ error: {
722
+ message: message2,
723
+ code: "MALFORMED_FUNCTION_CALL",
724
+ category: "malformed_function_call",
725
+ providerReason: "MALFORMED_FUNCTION_CALL",
726
+ retryable: false
727
+ },
728
+ provider_failure: providerFailure,
729
+ provider_events: events
730
+ }
731
+ };
732
+ }
733
+ const message = {
734
+ role: "assistant",
735
+ content: text || null
736
+ };
737
+ if (toolCalls.length > 0) message.tool_calls = toolCalls;
738
+ if (reasoningContent) message.reasoning_content = reasoningContent;
739
+ return {
740
+ status: 200,
741
+ text,
742
+ ...reasoningContent ? { reasoningContent } : {},
743
+ toolCalls,
744
+ ...usage ? { usage } : {},
745
+ ...finishReason ? { finishReason } : {},
746
+ providerEvents: events,
747
+ body: {
748
+ choices: [{
749
+ index: 0,
750
+ message,
751
+ finish_reason: toolCalls.length > 0 ? "tool_calls" : resolveAntigravityFinishReason(finishReason)
752
+ }],
753
+ ...usage ? { usage } : {},
754
+ provider_events: events
755
+ }
756
+ };
757
+ }
758
+ async function fetchAntigravityCloudCodeCompletion(args) {
759
+ const fetchImpl = args.fetchImpl ?? fetch;
760
+ const { url, envelope } = buildCloudCodeAssistPayload(args);
761
+ const response = await fetchImpl(url, {
762
+ method: "POST",
763
+ headers: {
764
+ Authorization: `Bearer ${args.accessToken}`,
765
+ "Content-Type": "application/json",
766
+ "User-Agent": getAntigravityUserAgent()
767
+ },
768
+ body: JSON.stringify(envelope),
769
+ signal: args.signal
770
+ });
771
+ if (!response.ok) {
772
+ const errorText = await response.text();
773
+ return {
774
+ status: response.status,
775
+ text: "",
776
+ toolCalls: [],
777
+ providerEvents: [],
778
+ // 保留上游结构:Antigravity 的限流 body 同样携带结构化的重置信息,
779
+ // 压成字符串会让冷却退化成 5 分钟默认值。
780
+ body: parseUpstreamErrorBody(errorText, response.statusText)
781
+ };
782
+ }
783
+ const chunkStream = streamSseDataValues(response, parseSseDataLineJson);
784
+ const { text, toolCalls, usage, finishReason, reasoningContent, events } = await accumulateGeminiStream(chunkStream, {
785
+ onTextDelta: args.onTextDelta,
786
+ onReasoningDelta: args.onReasoningDelta
787
+ });
788
+ const normalized = normalizeAntigravityCompletion({
789
+ text,
790
+ toolCalls,
791
+ usage,
792
+ finishReason,
793
+ reasoningContent,
794
+ events
795
+ });
796
+ if (normalized.status !== 200 || !text && toolCalls.length === 0) {
797
+ console.warn(
798
+ `[antigravity] empty completion: finishReason=${JSON.stringify(finishReason)} reasoningLen=${reasoningContent?.length ?? 0} usage=${JSON.stringify(usage) ?? "none"} model=${String(envelope.model)} base=${new URL(url).host}`
799
+ );
800
+ }
801
+ return normalized;
802
+ }
803
+
804
+ // packages/agent-runtime/devinOAuth.ts
805
+ import { existsSync, readFileSync } from "node:fs";
806
+ import { homedir } from "node:os";
807
+ import { join } from "node:path";
808
+ var DEVIN_CONNECT_URL = "https://server.codeium.com/exa.api_server_pb.ApiServerService/GetChatMessage";
809
+ function buildDevinAuthUrl(orgId) {
810
+ const cleanOrg = orgId?.trim();
811
+ if (cleanOrg) {
812
+ return `https://app.devin.ai/org/${encodeURIComponent(cleanOrg)}/settings/keys`;
813
+ }
814
+ return "https://app.devin.ai/settings/keys";
815
+ }
816
+ function extractDevinToken(input) {
817
+ const raw = input?.trim();
818
+ if (!raw) return null;
819
+ if (/^https?:\/\//i.test(raw)) {
820
+ try {
821
+ const url = new URL(raw);
822
+ const queryToken = url.searchParams.get("token") || url.searchParams.get("access_token") || url.searchParams.get("auth_token");
823
+ if (queryToken?.trim()) return queryToken.trim();
824
+ if (url.hash) {
825
+ const hashParams = new URLSearchParams(url.hash.replace(/^#/, ""));
826
+ const hashToken = hashParams.get("token") || hashParams.get("access_token") || hashParams.get("auth_token");
827
+ if (hashToken?.trim()) return hashToken.trim();
828
+ }
829
+ } catch {
830
+ }
831
+ }
832
+ return raw || null;
833
+ }
834
+ function parseDevinCredentialsToml(content) {
835
+ for (const line of content.split(/\r?\n/)) {
836
+ const cogMatch = line.match(/(cog_[A-Za-z0-9_-]+)/);
837
+ if (cogMatch?.[1]) {
838
+ return cogMatch[1].trim();
839
+ }
840
+ const match = line.match(
841
+ /^\s*(?:windsurf_api_key|devin_api_key|api_key|api_token|token)\s*=\s*"([^"]+)"\s*$/i
842
+ );
843
+ if (match?.[1]) {
844
+ return match[1].trim();
845
+ }
846
+ }
847
+ return null;
848
+ }
849
+ function detectLocalDevinCredentials(options) {
850
+ const baseHome = options?.homeDir || homedir();
851
+ const xdgData = process.env.XDG_DATA_HOME;
852
+ const candidateCliPaths = [
853
+ xdgData ? join(xdgData, "devin", "credentials.toml") : null,
854
+ join(baseHome, ".local", "share", "devin", "credentials.toml"),
855
+ process.env.APPDATA ? join(process.env.APPDATA, "devin", "credentials.toml") : null
856
+ ].filter((p) => Boolean(p));
857
+ for (const credPath of candidateCliPaths) {
858
+ if (existsSync(credPath)) {
859
+ try {
860
+ const content = readFileSync(credPath, "utf-8");
861
+ const token = parseDevinCredentialsToml(content);
862
+ if (token) {
863
+ return {
864
+ found: true,
865
+ token,
866
+ source: "devin-cli",
867
+ sourcePath: credPath
868
+ };
869
+ }
870
+ } catch {
871
+ }
872
+ }
873
+ }
874
+ const codeiumPath = join(baseHome, ".codeium", "config.json");
875
+ if (existsSync(codeiumPath)) {
876
+ try {
877
+ const parsed = JSON.parse(readFileSync(codeiumPath, "utf-8"));
878
+ const token = parsed.apiKey || parsed.api_key;
879
+ if (token?.trim()) {
880
+ return {
881
+ found: true,
882
+ token: token.trim(),
883
+ source: "codeium-config",
884
+ sourcePath: codeiumPath
885
+ };
886
+ }
887
+ } catch {
888
+ }
889
+ }
890
+ return { found: false };
891
+ }
892
+ function buildDevinOAuthCredential(token, now = Date.now()) {
893
+ return {
894
+ provider: "devin",
895
+ accessToken: token.trim(),
896
+ obtainedAt: now
897
+ };
898
+ }
899
+
900
+ export {
901
+ parseSseDataLineJson,
902
+ parseSseDataLineObject,
903
+ parseUpstreamErrorBody,
904
+ isGemini3Model,
905
+ accumulateGeminiChunks,
906
+ shouldUseGeminiNativeToolRoute,
907
+ buildGeminiGenerateContentRequest,
908
+ resolveAntigravityFinishReason,
909
+ fetchAntigravityCloudCodeCompletion,
910
+ DEVIN_CONNECT_URL,
911
+ buildDevinAuthUrl,
912
+ extractDevinToken,
913
+ detectLocalDevinCredentials,
914
+ buildDevinOAuthCredential
915
+ };