shortcutxl 0.3.92 → 0.4.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 (407) hide show
  1. package/BINARY-INVENTORY.json +16 -16
  2. package/CHANGELOG.md +14 -0
  3. package/dist/ai/api-registry.d.ts +2 -0
  4. package/dist/ai/api-registry.js +7 -0
  5. package/dist/ai/providers/anthropic.js +311 -178
  6. package/dist/ai/providers/google-shared.d.ts +3 -1
  7. package/dist/ai/providers/google-shared.js +27 -12
  8. package/dist/ai/providers/google-vertex.js +3 -19
  9. package/dist/ai/providers/google.js +3 -19
  10. package/dist/ai/providers/openai-completions.js +2 -1
  11. package/dist/ai/providers/openai-responses.d.ts +3 -2
  12. package/dist/ai/providers/openai-responses.js +17 -6
  13. package/dist/ai/providers/provider-error-normalization.js +1 -0
  14. package/dist/ai/providers/simple-options.js +1 -0
  15. package/dist/ai/types.d.ts +6 -0
  16. package/dist/ai/utils/oauth/index.js +2 -2
  17. package/dist/app/agent-session-runtime-adapter.d.ts +1 -0
  18. package/dist/app/agent-session-runtime-adapter.js +5 -1
  19. package/dist/app/agent-session.d.ts +14 -3
  20. package/dist/app/agent-session.js +52 -30
  21. package/dist/app/auth/auth-storage.d.ts +44 -11
  22. package/dist/app/auth/auth-storage.js +125 -138
  23. package/dist/app/auth/mcp-oauth-state.d.ts +38 -5
  24. package/dist/app/auth/mcp-oauth-state.js +117 -18
  25. package/dist/app/auth/shortcut-account-routing.d.ts +56 -0
  26. package/dist/app/auth/shortcut-account-routing.js +254 -0
  27. package/dist/app/auth/shortcut-account-store.d.ts +35 -0
  28. package/dist/app/auth/shortcut-account-store.js +170 -0
  29. package/dist/app/auth/shortcut-oauth.d.ts +9 -1
  30. package/dist/app/auth/shortcut-oauth.js +51 -13
  31. package/dist/app/background-agents/shorty/execution.d.ts +5 -2
  32. package/dist/app/background-agents/shorty/execution.js +11 -5
  33. package/dist/app/background-agents/shorty/inspector/runtime.d.ts +1 -0
  34. package/dist/app/background-agents/shorty/inspector/runtime.js +50 -61
  35. package/dist/app/background-agents/shorty/runtime.js +3 -0
  36. package/dist/app/background-agents/shorty/types.d.ts +1 -0
  37. package/dist/app/connectors/secret-store.d.ts +13 -0
  38. package/dist/app/connectors/secret-store.js +84 -24
  39. package/dist/app/index.d.ts +1 -1
  40. package/dist/app/index.js +1 -2
  41. package/dist/app/local/tools/execute-code/executor.js +29 -11
  42. package/dist/app/local/tools/execute-code/tool.js +33 -17
  43. package/dist/app/mcp/auth-status.js +2 -1
  44. package/dist/app/mcp/connection.d.ts +17 -7
  45. package/dist/app/mcp/connection.js +113 -41
  46. package/dist/app/mcp/hosted-oauth-id.js +11 -1
  47. package/dist/app/mcp/hosted-oauth-provider.d.ts +36 -4
  48. package/dist/app/mcp/hosted-oauth-provider.js +271 -57
  49. package/dist/app/mcp/index.js +56 -19
  50. package/dist/app/mcp/install.d.ts +11 -1
  51. package/dist/app/mcp/install.js +35 -7
  52. package/dist/app/mcp/mcp-execute-tool.d.ts +5 -2
  53. package/dist/app/mcp/mcp-execute-tool.js +8 -2
  54. package/dist/app/mcp/oauth-discovery.d.ts +20 -0
  55. package/dist/app/mcp/oauth-discovery.js +62 -4
  56. package/dist/app/mcp/oauth-state-store.d.ts +51 -4
  57. package/dist/app/mcp/oauth-state-store.js +148 -31
  58. package/dist/app/mcp/startup-errors.d.ts +27 -0
  59. package/dist/app/mcp/startup-errors.js +231 -0
  60. package/dist/app/mcp/startup-report.d.ts +24 -0
  61. package/dist/app/mcp/startup-report.js +55 -0
  62. package/dist/app/mcp/transient-http.d.ts +3 -0
  63. package/dist/app/mcp/transient-http.js +5 -0
  64. package/dist/app/mcp/types.d.ts +12 -2
  65. package/dist/app/modes/action/agent.d.ts +1 -1
  66. package/dist/app/modes/skill-forge/agent.d.ts +1 -1
  67. package/dist/app/observability/client-logging/client-logger.d.ts +1 -0
  68. package/dist/app/observability/client-logging/client-logger.js +14 -0
  69. package/dist/app/observability/client-logging/desktop-startup.d.ts +30 -0
  70. package/dist/app/observability/client-logging/desktop-startup.js +125 -0
  71. package/dist/app/observability/client-logging/excel-diagnostics.d.ts +9 -0
  72. package/dist/app/observability/client-logging/excel-diagnostics.js +42 -0
  73. package/dist/app/observability/client-logging/session-events.d.ts +1 -0
  74. package/dist/app/observability/client-logging/session-events.js +85 -3
  75. package/dist/app/observability/client-logging/startup-events.d.ts +1 -1
  76. package/dist/app/observability/client-logging/startup-events.js +4 -4
  77. package/dist/app/observability/client-logging/transport.d.ts +1 -1
  78. package/dist/app/observability/client-logging/transport.js +7 -4
  79. package/dist/app/platform-api/auth.js +1 -2
  80. package/dist/app/platform-api/automation-context.d.ts +17 -0
  81. package/dist/app/platform-api/automation-context.js +101 -0
  82. package/dist/app/platform-api/client.d.ts +47 -2
  83. package/dist/app/platform-api/client.js +15 -5
  84. package/dist/app/platform-api/run.d.ts +21 -2
  85. package/dist/app/platform-api/run.js +12 -2
  86. package/dist/app/prompts/mog-cli.js +10 -8
  87. package/dist/app/providers/google-vertex-gateway.js +13 -114
  88. package/dist/app/providers/model-resolver.js +6 -3
  89. package/dist/app/providers/register-shortcut-provider.d.ts +1 -11
  90. package/dist/app/providers/register-shortcut-provider.js +98 -4
  91. package/dist/app/providers/shortcut-api-v2-transport.js +1 -2
  92. package/dist/app/providers/shortcut-llm-proxy-client.d.ts +1 -12
  93. package/dist/app/providers/shortcut-llm-proxy-client.js +4 -1
  94. package/dist/app/services/user-context.d.ts +8 -2
  95. package/dist/app/services/user-context.js +53 -28
  96. package/dist/app/session/run-agent-observability.d.ts +3 -3
  97. package/dist/app/session/session-models.d.ts +0 -7
  98. package/dist/app/session/session-models.js +2 -8
  99. package/dist/app/session/session-speed.d.ts +38 -0
  100. package/dist/app/session/session-speed.js +72 -0
  101. package/dist/app/session/session-title-generator.d.ts +19 -0
  102. package/dist/app/session/session-title-generator.js +68 -0
  103. package/dist/app/subagents/defaults.d.ts +1 -1
  104. package/dist/app/subagents/defaults.js +11 -2
  105. package/dist/app/sync/storage-client.js +5 -5
  106. package/dist/app/tools/task/runner.js +34 -9
  107. package/dist/app/tools/task/sidechain.d.ts +3 -0
  108. package/dist/app/tools/task/sidechain.js +10 -0
  109. package/dist/app/tools/task/task.js +1 -1
  110. package/dist/app/tools/web-search.d.ts +6 -0
  111. package/dist/app/tools/web-search.js +87 -8
  112. package/dist/app/workbook-context/workbook-summary.d.ts +16 -2
  113. package/dist/app/workbook-context/workbook-summary.js +95 -12
  114. package/dist/app/xll/connection-error.d.ts +17 -0
  115. package/dist/app/xll/connection-error.js +31 -0
  116. package/dist/app/xll/excel-target.d.ts +18 -1
  117. package/dist/app/xll/excel-target.js +95 -14
  118. package/dist/app/xll/session.d.ts +2 -1
  119. package/dist/app/xll/session.js +2 -2
  120. package/dist/cli/args.d.ts +1 -0
  121. package/dist/cli/args.js +11 -1
  122. package/dist/cli/gateway-setup.d.ts +4 -0
  123. package/dist/cli/gateway-setup.js +44 -0
  124. package/dist/cli/mcp-commands.js +29 -28
  125. package/dist/cli/platform-api-commands.d.ts +2 -1
  126. package/dist/cli/platform-api-commands.js +132 -11
  127. package/dist/cli.js +24219 -10950
  128. package/dist/constants.d.ts +1 -17
  129. package/dist/constants.js +1 -32
  130. package/dist/contracts/agent-api.d.ts +41 -4
  131. package/dist/contracts/agent-api.js +34 -6
  132. package/dist/contracts/agent-execute-code.d.ts +6 -0
  133. package/dist/contracts/agent-execute-code.js +10 -0
  134. package/dist/contracts/agent-failure.d.ts +1 -0
  135. package/dist/contracts/agent-failure.js +1 -0
  136. package/dist/contracts/agent-session-store.d.ts +3 -3
  137. package/dist/contracts/agent-session-store.js +5 -1
  138. package/dist/contracts/agent-snapshot.d.ts +13 -0
  139. package/dist/contracts/agent-snapshot.js +10 -1
  140. package/dist/contracts/agent-submit.d.ts +14 -1
  141. package/dist/contracts/agent-submit.js +23 -1
  142. package/dist/contracts/local-file-preview.d.ts +14 -0
  143. package/dist/contracts/local-file-preview.js +2 -0
  144. package/dist/contracts/model-call.d.ts +3 -2
  145. package/dist/contracts/model-stream.d.ts +21 -9
  146. package/dist/contracts/model-stream.js +63 -5
  147. package/dist/contracts/refusal-fallback.d.ts +13 -0
  148. package/dist/contracts/refusal-fallback.js +25 -0
  149. package/dist/contracts/task-terminal-output.d.ts +10 -0
  150. package/dist/contracts/task-terminal-output.js +30 -0
  151. package/dist/contracts/wire.d.ts +2 -2
  152. package/dist/core/agent-controller.d.ts +2 -2
  153. package/dist/core/agent-engine.d.ts +2 -2
  154. package/dist/core/agent-engine.js +4 -2
  155. package/dist/core/agent-loop.js +20 -3
  156. package/dist/core/agent-snapshot-builder.d.ts +2 -0
  157. package/dist/core/agent-snapshot-builder.js +9 -6
  158. package/dist/core/core-types.d.ts +11 -6
  159. package/dist/core/embedded-agent-facade.d.ts +2 -2
  160. package/dist/core/embedded-agent-facade.js +2 -2
  161. package/dist/core/pending-host-tool-requests.d.ts +1 -1
  162. package/dist/core/pending-host-tool-requests.js +5 -2
  163. package/dist/core/prompts/agent-guidelines.d.ts +1 -1
  164. package/dist/core/prompts/agent-guidelines.js +1 -0
  165. package/dist/core/run-failure.js +33 -9
  166. package/dist/core/session/compaction/compaction.d.ts +7 -4
  167. package/dist/core/session/compaction/compaction.js +65 -10
  168. package/dist/core/session/subagent-compaction.d.ts +70 -0
  169. package/dist/core/session/subagent-compaction.js +251 -0
  170. package/dist/core/session-schema.d.ts +3 -3
  171. package/dist/core/session-schema.js +10 -2
  172. package/dist/credits/shortcut-credits.js +3 -3
  173. package/dist/embedded-agent/anthropic-messages-transport.js +69 -16
  174. package/dist/embedded-agent/compose.js +264 -38
  175. package/dist/embedded-agent/context-review/agent.js +2 -2
  176. package/dist/embedded-agent/gateway-base-url.d.ts +5 -1
  177. package/dist/embedded-agent/gateway-base-url.js +6 -17
  178. package/dist/embedded-agent/google-vertex-transport.d.ts +6 -0
  179. package/dist/embedded-agent/google-vertex-transport.js +96 -52
  180. package/dist/embedded-agent/host-runtime-options.d.ts +10 -0
  181. package/dist/embedded-agent/host-runtime-options.js +84 -64
  182. package/dist/embedded-agent/host-tools/action-tool-names.d.ts +1 -1
  183. package/dist/embedded-agent/host-tools/action-tool-names.js +2 -1
  184. package/dist/embedded-agent/host-tools/build-tool-list.d.ts +2 -1
  185. package/dist/embedded-agent/host-tools/build-tool-list.js +55 -5
  186. package/dist/embedded-agent/host-tools/connector/contract.d.ts +21 -0
  187. package/dist/embedded-agent/host-tools/connector/contract.js +82 -0
  188. package/dist/embedded-agent/host-tools/connector/index.d.ts +2 -0
  189. package/dist/embedded-agent/host-tools/connector/index.js +2 -0
  190. package/dist/embedded-agent/host-tools/create-website/contract.js +2 -1
  191. package/dist/embedded-agent/host-tools/exa-web-search/contract.d.ts +7 -1
  192. package/dist/embedded-agent/host-tools/exa-web-search/contract.js +14 -3
  193. package/dist/embedded-agent/host-tools/exa-web-search/index.d.ts +1 -1
  194. package/dist/embedded-agent/host-tools/execute-bash-command/contract.js +11 -3
  195. package/dist/embedded-agent/host-tools/execute-code/classify.js +2 -7
  196. package/dist/embedded-agent/host-tools/execute-code/contract.d.ts +10 -0
  197. package/dist/embedded-agent/host-tools/execute-code/contract.js +21 -3
  198. package/dist/embedded-agent/host-tools/execute-code/raw-sdk-patterns.json +9 -0
  199. package/dist/embedded-agent/host-tools/get-tool-info/contract.d.ts +1 -1
  200. package/dist/embedded-agent/host-tools/get-tool-info/contract.js +9 -1
  201. package/dist/embedded-agent/host-tools/get-tool-info/shared.d.ts +2 -2
  202. package/dist/embedded-agent/host-tools/get-tool-info/shared.js +5 -1
  203. package/dist/embedded-agent/host-tools/index.d.ts +3 -0
  204. package/dist/embedded-agent/host-tools/index.js +3 -0
  205. package/dist/embedded-agent/host-tools/invoke-llm/contract.d.ts +1 -1
  206. package/dist/embedded-agent/host-tools/mcp/contract.d.ts +32 -3
  207. package/dist/embedded-agent/host-tools/mcp/contract.js +99 -12
  208. package/dist/embedded-agent/host-tools/mcp/index.d.ts +1 -1
  209. package/dist/embedded-agent/host-tools/mcp/index.js +1 -1
  210. package/dist/embedded-agent/host-tools/mode-host-tools.d.ts +2 -1
  211. package/dist/embedded-agent/host-tools/mode-host-tools.js +4 -3
  212. package/dist/embedded-agent/host-tools/modify-skill/contract.d.ts +4 -7
  213. package/dist/embedded-agent/host-tools/modify-skill/contract.js +55 -20
  214. package/dist/embedded-agent/host-tools/modify-skill/index.d.ts +1 -1
  215. package/dist/embedded-agent/host-tools/modify-skill/index.js +1 -1
  216. package/dist/embedded-agent/host-tools/read-skill/contract.d.ts +3 -12
  217. package/dist/embedded-agent/host-tools/read-skill/contract.js +21 -14
  218. package/dist/embedded-agent/host-tools/recurring-workflow/contract.d.ts +194 -0
  219. package/dist/embedded-agent/host-tools/recurring-workflow/contract.js +598 -0
  220. package/dist/embedded-agent/host-tools/recurring-workflow/index.d.ts +3 -0
  221. package/dist/embedded-agent/host-tools/recurring-workflow/index.js +3 -0
  222. package/dist/embedded-agent/host-tools/registry.d.ts +22 -3
  223. package/dist/embedded-agent/host-tools/registry.js +13 -1
  224. package/dist/embedded-agent/host-tools/report-review-item/contract.d.ts +35 -0
  225. package/dist/embedded-agent/host-tools/report-review-item/contract.js +153 -0
  226. package/dist/embedded-agent/host-tools/report-review-item/index.d.ts +3 -0
  227. package/dist/embedded-agent/host-tools/report-review-item/index.js +3 -0
  228. package/dist/embedded-agent/host-tools/request-credential/contract.d.ts +11 -2
  229. package/dist/embedded-agent/host-tools/request-credential/contract.js +52 -5
  230. package/dist/embedded-agent/host-tools/request-credential/index.d.ts +1 -1
  231. package/dist/embedded-agent/host-tools/request-credential/index.js +1 -1
  232. package/dist/embedded-agent/host-tools/request-oauth/contract.d.ts +11 -2
  233. package/dist/embedded-agent/host-tools/request-oauth/contract.js +52 -8
  234. package/dist/embedded-agent/host-tools/request-oauth/index.d.ts +1 -1
  235. package/dist/embedded-agent/host-tools/request-oauth/index.js +1 -1
  236. package/dist/embedded-agent/host-tools/switch-mode/contract.js +8 -3
  237. package/dist/embedded-agent/host-tools/task/agent-definition.d.ts +22 -0
  238. package/dist/embedded-agent/host-tools/task/agent-definition.js +13 -1
  239. package/dist/embedded-agent/host-tools/task/agents/document-reader.js +5 -0
  240. package/dist/embedded-agent/host-tools/task/contract.d.ts +11 -7
  241. package/dist/embedded-agent/host-tools/task/contract.js +70 -22
  242. package/dist/embedded-agent/host-tools/task/lifecycle.d.ts +12 -3
  243. package/dist/embedded-agent/host-tools/task/lifecycle.js +73 -22
  244. package/dist/embedded-agent/host-tools/task/manager.d.ts +28 -8
  245. package/dist/embedded-agent/host-tools/task/manager.js +78 -15
  246. package/dist/embedded-agent/host-tools/task/runner.d.ts +26 -2
  247. package/dist/embedded-agent/host-tools/task/runner.js +214 -31
  248. package/dist/embedded-agent/host-tools/task/send-message.d.ts +2 -1
  249. package/dist/embedded-agent/host-tools/task/send-message.js +22 -6
  250. package/dist/embedded-agent/host-tools/task/sidechain.d.ts +2 -0
  251. package/dist/embedded-agent/host-tools/task/sidechain.js +28 -1
  252. package/dist/embedded-agent/host-tools/timeouts.js +14 -1
  253. package/dist/embedded-agent/host-tools/tool-names.d.ts +3 -0
  254. package/dist/embedded-agent/host-tools/tool-names.js +3 -0
  255. package/dist/embedded-agent/index.d.ts +12 -5
  256. package/dist/embedded-agent/index.js +2 -1
  257. package/dist/embedded-agent/inspector/agent.js +4 -3
  258. package/dist/embedded-agent/inspector/coordinator.d.ts +5 -2
  259. package/dist/embedded-agent/inspector/coordinator.js +42 -5
  260. package/dist/embedded-agent/inspector/formatting-agent.d.ts +13 -0
  261. package/dist/embedded-agent/inspector/formatting-agent.js +47 -0
  262. package/dist/embedded-agent/inspector/run-agents.d.ts +5 -0
  263. package/dist/embedded-agent/inspector/run-agents.js +81 -0
  264. package/dist/embedded-agent/invoke-sse.d.ts +8 -0
  265. package/dist/embedded-agent/invoke-sse.js +104 -0
  266. package/dist/embedded-agent/model-catalog.d.ts +15 -0
  267. package/dist/embedded-agent/model-catalog.js +114 -0
  268. package/dist/embedded-agent/model-registry.d.ts +23 -25
  269. package/dist/embedded-agent/model-registry.js +14 -146
  270. package/dist/embedded-agent/openai-completions-transport.js +54 -15
  271. package/dist/embedded-agent/openai-responses-transport.js +42 -16
  272. package/dist/embedded-agent/prompt/build-user-message.d.ts +12 -4
  273. package/dist/embedded-agent/prompt/build-user-message.js +21 -4
  274. package/dist/embedded-agent/prompt/build.d.ts +7 -2
  275. package/dist/embedded-agent/prompt/build.js +14 -5
  276. package/dist/embedded-agent/prompt/expected-block-kinds.d.ts +5 -1
  277. package/dist/embedded-agent/prompt/expected-block-kinds.js +6 -0
  278. package/dist/embedded-agent/prompt/sections.d.ts +13 -0
  279. package/dist/embedded-agent/prompt/sections.js +35 -1
  280. package/dist/embedded-agent/prompt/user-turn-sections.js +3 -2
  281. package/dist/embedded-agent/provider-fast-mode.d.ts +1 -1
  282. package/dist/embedded-agent/provider-fast-mode.js +30 -7
  283. package/dist/embedded-agent/provider-native-request.js +4 -0
  284. package/dist/embedded-agent/refusal-fallback.d.ts +3 -0
  285. package/dist/embedded-agent/refusal-fallback.js +24 -0
  286. package/dist/embedded-agent/run-stats.d.ts +1 -1
  287. package/dist/embedded-agent/session-entry-builder.d.ts +1 -1
  288. package/dist/embedded-agent/session-store.d.ts +1 -1
  289. package/dist/embedded-agent/skill-model-selection.d.ts +32 -0
  290. package/dist/embedded-agent/skill-model-selection.js +56 -0
  291. package/dist/embedded-agent/stream-events.js +7 -0
  292. package/dist/embedded-agent/stream.d.ts +1 -1
  293. package/dist/embedded-agent/suggestions.d.ts +25 -1
  294. package/dist/embedded-agent/suggestions.js +164 -49
  295. package/dist/embedded-agent/task-notification-turn-queue.d.ts +1 -1
  296. package/dist/embedded-agent/task-notification-turn-queue.js +6 -2
  297. package/dist/embedded-agent/transport-errors.js +9 -2
  298. package/dist/embedded-agent/worker-bridge/dispatch.js +16 -3
  299. package/dist/embedded-agent/worker-bridge/host-client.d.ts +2 -2
  300. package/dist/embedded-agent/worker-bridge/host-client.js +74 -15
  301. package/dist/fast-mode.d.ts +3 -1
  302. package/dist/fast-mode.js +17 -0
  303. package/dist/main-helpers.js +28 -5
  304. package/dist/main.d.ts +1 -2
  305. package/dist/main.js +152 -47
  306. package/dist/model-ids.d.ts +30 -31
  307. package/dist/model-ids.js +37 -66
  308. package/dist/remote-control/approval-controller.d.ts +2 -1
  309. package/dist/remote-control/approval-controller.js +11 -3
  310. package/dist/remote-control/desktop-runtime.d.ts +3 -0
  311. package/dist/remote-control/desktop-runtime.js +3 -1
  312. package/dist/remote-control/whatsapp/controller.d.ts +2 -0
  313. package/dist/remote-control/whatsapp/controller.js +51 -60
  314. package/dist/remote-control/whatsapp/formatting.d.ts +2 -0
  315. package/dist/remote-control/whatsapp/formatting.js +23 -0
  316. package/dist/rpc/index.d.ts +2 -1
  317. package/dist/rpc/rpc-client.d.ts +12 -0
  318. package/dist/rpc/rpc-client.js +73 -3
  319. package/dist/rpc/rpc-host.d.ts +5 -1
  320. package/dist/rpc/rpc-host.js +26 -3
  321. package/dist/rpc/rpc-mode.d.ts +1 -1
  322. package/dist/rpc/rpc-types.d.ts +11 -0
  323. package/dist/rpc/startup-diagnostics.d.ts +20 -0
  324. package/dist/rpc/startup-diagnostics.js +32 -0
  325. package/dist/session-presentation.d.ts +25 -0
  326. package/dist/session-presentation.js +25 -0
  327. package/dist/shell/commands/mcp-command.js +16 -21
  328. package/dist/shell/components/primitives/footer.js +3 -3
  329. package/dist/shell/components/shorty-issues.js +3 -2
  330. package/dist/shell/dev/session-upload.d.ts +0 -11
  331. package/dist/shell/dev/session-upload.js +19 -6
  332. package/dist/shell/dev/trace-share-upload.js +6 -2
  333. package/dist/shell/interactive/auth-workflow.js +5 -4
  334. package/dist/shell/interactive/extension-ui-host.d.ts +156 -0
  335. package/dist/shell/interactive/extension-ui-host.js +580 -0
  336. package/dist/shell/interactive/interactive-mode.d.ts +7 -174
  337. package/dist/shell/interactive/interactive-mode.js +156 -1409
  338. package/dist/shell/interactive/interactive-selection-controller.d.ts +51 -0
  339. package/dist/shell/interactive/interactive-selection-controller.js +306 -0
  340. package/dist/shell/interactive/interactive-session-controller.d.ts +1 -0
  341. package/dist/shell/interactive/interactive-session-controller.js +3 -0
  342. package/dist/shell/interactive/slash-commands.js +1 -1
  343. package/dist/shell/interactive/transcript-renderer.d.ts +104 -0
  344. package/dist/shell/interactive/transcript-renderer.js +491 -0
  345. package/dist/shell/links/local-file-preview.d.ts +10 -0
  346. package/dist/shell/links/local-file-preview.js +121 -0
  347. package/dist/shell/presentation/session-terminal.d.ts +5 -0
  348. package/dist/shell/presentation/session-terminal.js +9 -0
  349. package/dist/shell/session-client.d.ts +7 -0
  350. package/dist/shell/session-client.js +8 -0
  351. package/dist/shortcut-deployment.d.ts +18 -0
  352. package/dist/shortcut-deployment.js +78 -0
  353. package/dist/shortcut-model-catalog.d.ts +1 -1
  354. package/dist/shortcut-model-catalog.js +13 -424
  355. package/dist/startup/interactive-commands.js +2 -2
  356. package/dist/startup/mog-cli.d.ts +8 -3
  357. package/dist/startup/mog-cli.js +39 -10
  358. package/dist/startup/mog-output-candidate.d.ts +43 -0
  359. package/dist/startup/mog-output-candidate.js +342 -0
  360. package/dist/startup/output-workbook.d.ts +4 -1
  361. package/dist/startup/output-workbook.js +28 -1
  362. package/dist/startup/shortcut-user-logger-context.js +1 -1
  363. package/dist/subagent-model-policy.d.ts +33 -11
  364. package/dist/subagent-model-policy.js +112 -21
  365. package/dist/subagent-thinking-policy.d.ts +7 -5
  366. package/dist/subagent-thinking-policy.js +22 -6
  367. package/dist/supported-models.d.ts +108 -0
  368. package/dist/supported-models.generated.d.ts +145 -0
  369. package/dist/supported-models.generated.js +2251 -0
  370. package/dist/supported-models.js +17 -0
  371. package/dist/tui/tab-color.d.ts +6 -0
  372. package/dist/tui/tab-color.js +23 -0
  373. package/dist/tui/tab-color.ts +28 -0
  374. package/dist/tui/terminal.d.ts +2 -0
  375. package/dist/tui/terminal.js +16 -1
  376. package/dist/utils/api-reference.js +11 -6
  377. package/native-app/main/chunks/config-CwtqLhpn.js +170 -0
  378. package/native-app/main/chunks/index-hcdtaSGg.js +25901 -0
  379. package/native-app/main/chunks/{linux-D5vrr6vD.js → linux-C5J5oKJy.js} +3 -3
  380. package/native-app/main/chunks/{mac-C1gONwcL.js → mac-Bt_bFwUg.js} +3 -3
  381. package/native-app/main/chunks/secret-store-CbWo_9sG.js +285 -0
  382. package/native-app/main/chunks/{setup-worker-protocol-P3bbcYzl.js → setup-worker-protocol-QUVpcuEb.js} +205 -7
  383. package/native-app/main/chunks/{shared-DpP_I5SO.js → shared-Q59yhreZ.js} +1 -21
  384. package/native-app/main/index.js +16080 -5443
  385. package/native-app/main/setup-worker.js +5 -5
  386. package/native-app/package.json +1 -1
  387. package/native-app/preload/index.cjs +21 -0
  388. package/native-app/renderer/assets/{index-DsYjsaRU.css → index-BVniXN5M.css} +371 -31
  389. package/native-app/renderer/assets/{index--fI2TmN5.js → index-DkKrXRl6.js} +1639 -203
  390. package/native-app/renderer/index.html +3 -3
  391. package/package.json +54 -1
  392. package/plugins/shortcutxl/references/PLATFORM_API.md +16 -0
  393. package/user-docs/dist/index.html +26 -0
  394. package/xll/ShortcutPowerPoint.dll +0 -0
  395. package/xll/ShortcutWord.dll +0 -0
  396. package/xll/ShortcutXL.xll +0 -0
  397. package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
  398. package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
  399. package/xll/python/Lib/site-packages/pip-26.2.dist-info/RECORD +3 -3
  400. package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
  401. package/xll/python/Scripts/httpx.exe +0 -0
  402. package/xll/python/Scripts/idna.exe +0 -0
  403. package/xll/python/Scripts/pip.exe +0 -0
  404. package/xll/python/Scripts/pip3.13.exe +0 -0
  405. package/xll/python/Scripts/pip3.exe +0 -0
  406. package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
  407. package/xll/python/Scripts/pywin32_testall.exe +0 -0
@@ -1,5 +1,6 @@
1
1
  import Anthropic from '@anthropic-ai/sdk';
2
2
  import { PROVIDER_REFUSAL_ERROR_CODE, safeModelStreamErrorMessage } from '../../contracts/model-stream.js';
3
+ import { isResponseModel } from '../../contracts/refusal-fallback.js';
3
4
  import { getEnvApiKey } from '../env-api-keys.js';
4
5
  import { assertModelSupportsReasoningLevel, calculateCost } from '../models.js';
5
6
  import { AssistantMessageEventStream } from '../utils/event-stream.js';
@@ -153,224 +154,356 @@ export const streamAnthropic = (model, context, options) => {
153
154
  stopReason: 'stop',
154
155
  timestamp: Date.now()
155
156
  };
157
+ let fallbackAttempted = false;
158
+ let servingModel = model;
159
+ let initialFallbackCache;
156
160
  try {
157
161
  const apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? '';
158
- const client = createClient(model, apiKey, options?.interleavedThinking ?? true, options?.headers, options?.fetchOptions, options?.fetch);
162
+ const client = createClient(model, apiKey, options?.interleavedThinking ?? true, options?.resolveRefusalFallbackModel
163
+ ? mergeHeaders(options.headers, {
164
+ 'anthropic-beta': 'fallback-credit-2026-07-01',
165
+ 'X-LLM-Refusal-Fallback': 'enabled'
166
+ })
167
+ : options?.headers, options?.fetchOptions, options?.fetch);
159
168
  const params = buildParams(model, context, options);
160
169
  options?.onPayload?.(params);
161
170
  // Consume raw events because this provider owns accumulation. The SDK's
162
171
  // MessageStream accumulator assumes usage is always present, but private
163
172
  // gateways can omit initial usage from otherwise valid response streams.
164
- const anthropicStream = await client.messages.create({ ...params, stream: true }, { signal: options?.signal });
165
- stream.push({ type: 'start', partial: output });
166
- const blocks = output.content;
167
- let uncachedInputTokens = 0;
168
- let providerStopReason;
169
- for await (const event of anthropicStream) {
170
- if (event.type === 'message_start') {
171
- // Capture initial token usage from message_start event
172
- // This ensures we have input token counts even if the stream is aborted early
173
- const usage = event.message.usage;
174
- uncachedInputTokens = usage?.input_tokens ?? 0;
175
- output.usage.output = usage?.output_tokens ?? 0;
176
- output.usage.cacheRead = usage?.cache_read_input_tokens ?? 0;
177
- output.usage.cacheWrite = usage?.cache_creation_input_tokens ?? 0;
178
- // Anthropic doesn't provide total_tokens; usage.input is normalized
179
- // to total input, including cache buckets.
180
- output.usage.input =
181
- uncachedInputTokens + output.usage.cacheRead + output.usage.cacheWrite;
182
- output.usage.totalTokens = output.usage.input + output.usage.output;
183
- calculateCost(model, output.usage);
184
- }
185
- else if (event.type === 'content_block_start') {
186
- if (event.content_block.type === 'text') {
187
- const block = {
188
- type: 'text',
189
- text: '',
190
- index: event.index
191
- };
192
- output.content.push(block);
193
- stream.push({
194
- type: 'text_start',
195
- contentIndex: output.content.length - 1,
196
- partial: output
197
- });
198
- }
199
- else if (event.content_block.type === 'thinking') {
200
- const block = {
201
- type: 'thinking',
202
- thinking: '',
203
- thinkingSignature: '',
204
- index: event.index
205
- };
206
- output.content.push(block);
207
- stream.push({
208
- type: 'thinking_start',
209
- contentIndex: output.content.length - 1,
210
- partial: output
211
- });
212
- }
213
- else if (event.content_block.type === 'redacted_thinking') {
214
- const block = {
215
- type: 'thinking',
216
- thinking: '[Reasoning redacted]',
217
- thinkingSignature: event.content_block.data,
218
- redacted: true,
219
- index: event.index
220
- };
221
- output.content.push(block);
222
- stream.push({
223
- type: 'thinking_start',
224
- contentIndex: output.content.length - 1,
225
- partial: output
226
- });
227
- }
228
- else if (event.content_block.type === 'tool_use') {
229
- const block = {
230
- type: 'toolCall',
231
- id: event.content_block.id,
232
- name: event.content_block.name,
233
- arguments: event.content_block.input ?? {},
234
- partialJson: '',
235
- index: event.index
236
- };
237
- output.content.push(block);
238
- stream.push({
239
- type: 'toolcall_start',
240
- contentIndex: output.content.length - 1,
241
- partial: output
242
- });
173
+ let requestParams = { ...params, stream: true };
174
+ let retryHeaders;
175
+ for (;;) {
176
+ const { data: anthropicStream, response } = await client.messages
177
+ .create(requestParams, {
178
+ signal: options?.signal,
179
+ ...(retryHeaders ? { maxRetries: 0 } : {}),
180
+ headers: retryHeaders
181
+ })
182
+ .withResponse();
183
+ const blocks = output.content;
184
+ let uncachedInputTokens = 0;
185
+ let providerStopReason;
186
+ let stopDetails;
187
+ let unsafeBoundary = false;
188
+ let completed = false;
189
+ for await (const event of anthropicStream) {
190
+ if (event.type === 'message_stop')
191
+ completed = true;
192
+ if (event.type === 'message_start') {
193
+ output.responseModel = isResponseModel(event.message.model)
194
+ ? event.message.model
195
+ : undefined;
196
+ if (output.refusalFallback) {
197
+ output.refusalFallback = {
198
+ ...output.refusalFallback,
199
+ servingModel: output.responseModel,
200
+ phase: 'streaming'
201
+ };
202
+ }
203
+ // Capture initial token usage from message_start event
204
+ // This ensures we have input token counts even if the stream is aborted early
205
+ const usage = event.message.usage;
206
+ uncachedInputTokens = usage?.input_tokens ?? 0;
207
+ output.usage.output = usage?.output_tokens ?? 0;
208
+ output.usage.cacheRead = usage?.cache_read_input_tokens ?? 0;
209
+ output.usage.cacheWrite = usage?.cache_creation_input_tokens ?? 0;
210
+ // Anthropic doesn't provide total_tokens; usage.input is normalized
211
+ // to total input, including cache buckets.
212
+ output.usage.input =
213
+ uncachedInputTokens + output.usage.cacheRead + output.usage.cacheWrite;
214
+ output.usage.totalTokens = output.usage.input + output.usage.output;
215
+ calculateCost(servingModel, output.usage);
216
+ if (fallbackAttempted)
217
+ initialFallbackCache = {
218
+ read: output.usage.cacheRead,
219
+ write: output.usage.cacheWrite
220
+ };
221
+ stream.push({ type: 'start', partial: output });
243
222
  }
244
- }
245
- else if (event.type === 'content_block_delta') {
246
- if (event.delta.type === 'text_delta') {
247
- const index = blocks.findIndex((b) => b.index === event.index);
248
- const block = blocks[index];
249
- if (block && block.type === 'text') {
250
- block.text += event.delta.text;
223
+ else if (event.type === 'content_block_start') {
224
+ if (!['text', 'thinking', 'redacted_thinking'].includes(event.content_block.type))
225
+ unsafeBoundary = true;
226
+ if (event.content_block.type === 'text') {
227
+ const block = {
228
+ type: 'text',
229
+ text: '',
230
+ index: event.index
231
+ };
232
+ output.content.push(block);
251
233
  stream.push({
252
- type: 'text_delta',
253
- contentIndex: index,
254
- delta: event.delta.text,
234
+ type: 'text_start',
235
+ contentIndex: output.content.length - 1,
255
236
  partial: output
256
237
  });
257
238
  }
258
- }
259
- else if (event.delta.type === 'thinking_delta') {
260
- const index = blocks.findIndex((b) => b.index === event.index);
261
- const block = blocks[index];
262
- if (block && block.type === 'thinking') {
263
- block.thinking += event.delta.thinking;
239
+ else if (event.content_block.type === 'thinking') {
240
+ const block = {
241
+ type: 'thinking',
242
+ thinking: '',
243
+ thinkingSignature: '',
244
+ index: event.index
245
+ };
246
+ output.content.push(block);
264
247
  stream.push({
265
- type: 'thinking_delta',
266
- contentIndex: index,
267
- delta: event.delta.thinking,
248
+ type: 'thinking_start',
249
+ contentIndex: output.content.length - 1,
268
250
  partial: output
269
251
  });
270
252
  }
271
- }
272
- else if (event.delta.type === 'input_json_delta') {
273
- const index = blocks.findIndex((b) => b.index === event.index);
274
- const block = blocks[index];
275
- if (block && block.type === 'toolCall') {
276
- block.partialJson += event.delta.partial_json;
277
- block.arguments = parseStreamingJson(block.partialJson);
253
+ else if (event.content_block.type === 'redacted_thinking') {
254
+ const block = {
255
+ type: 'thinking',
256
+ thinking: '[Reasoning redacted]',
257
+ thinkingSignature: event.content_block.data,
258
+ redacted: true,
259
+ index: event.index
260
+ };
261
+ output.content.push(block);
278
262
  stream.push({
279
- type: 'toolcall_delta',
280
- contentIndex: index,
281
- delta: event.delta.partial_json,
263
+ type: 'thinking_start',
264
+ contentIndex: output.content.length - 1,
282
265
  partial: output
283
266
  });
284
267
  }
268
+ else if (event.content_block.type === 'tool_use') {
269
+ const block = {
270
+ type: 'toolCall',
271
+ id: event.content_block.id,
272
+ name: event.content_block.name,
273
+ arguments: event.content_block.input ?? {},
274
+ partialJson: '',
275
+ index: event.index
276
+ };
277
+ output.content.push(block);
278
+ stream.push({
279
+ type: 'toolcall_start',
280
+ contentIndex: output.content.length - 1,
281
+ partial: output
282
+ });
283
+ }
284
+ }
285
+ else if (event.type === 'content_block_delta') {
286
+ if (event.delta.type === 'text_delta') {
287
+ const index = blocks.findIndex((b) => b.index === event.index);
288
+ const block = blocks[index];
289
+ if (block && block.type === 'text') {
290
+ block.text += event.delta.text;
291
+ stream.push({
292
+ type: 'text_delta',
293
+ contentIndex: index,
294
+ delta: event.delta.text,
295
+ partial: output
296
+ });
297
+ }
298
+ }
299
+ else if (event.delta.type === 'thinking_delta') {
300
+ const index = blocks.findIndex((b) => b.index === event.index);
301
+ const block = blocks[index];
302
+ if (block && block.type === 'thinking') {
303
+ block.thinking += event.delta.thinking;
304
+ stream.push({
305
+ type: 'thinking_delta',
306
+ contentIndex: index,
307
+ delta: event.delta.thinking,
308
+ partial: output
309
+ });
310
+ }
311
+ }
312
+ else if (event.delta.type === 'input_json_delta') {
313
+ const index = blocks.findIndex((b) => b.index === event.index);
314
+ const block = blocks[index];
315
+ if (block && block.type === 'toolCall') {
316
+ block.partialJson += event.delta.partial_json;
317
+ block.arguments = parseStreamingJson(block.partialJson);
318
+ stream.push({
319
+ type: 'toolcall_delta',
320
+ contentIndex: index,
321
+ delta: event.delta.partial_json,
322
+ partial: output
323
+ });
324
+ }
325
+ }
326
+ else if (event.delta.type === 'signature_delta') {
327
+ const index = blocks.findIndex((b) => b.index === event.index);
328
+ const block = blocks[index];
329
+ if (block && block.type === 'thinking') {
330
+ block.thinkingSignature = block.thinkingSignature || '';
331
+ block.thinkingSignature += event.delta.signature;
332
+ }
333
+ }
285
334
  }
286
- else if (event.delta.type === 'signature_delta') {
335
+ else if (event.type === 'content_block_stop') {
287
336
  const index = blocks.findIndex((b) => b.index === event.index);
288
337
  const block = blocks[index];
289
- if (block && block.type === 'thinking') {
290
- block.thinkingSignature = block.thinkingSignature || '';
291
- block.thinkingSignature += event.delta.signature;
338
+ if (block) {
339
+ delete block.index;
340
+ if (block.type === 'text') {
341
+ stream.push({
342
+ type: 'text_end',
343
+ contentIndex: index,
344
+ content: block.text,
345
+ partial: output
346
+ });
347
+ }
348
+ else if (block.type === 'thinking') {
349
+ stream.push({
350
+ type: 'thinking_end',
351
+ contentIndex: index,
352
+ content: block.thinking,
353
+ partial: output
354
+ });
355
+ }
356
+ else if (block.type === 'toolCall') {
357
+ block.arguments = parseStreamingJson(block.partialJson);
358
+ delete block.partialJson;
359
+ stream.push({
360
+ type: 'toolcall_end',
361
+ contentIndex: index,
362
+ toolCall: block,
363
+ partial: output
364
+ });
365
+ }
292
366
  }
293
367
  }
294
- }
295
- else if (event.type === 'content_block_stop') {
296
- const index = blocks.findIndex((b) => b.index === event.index);
297
- const block = blocks[index];
298
- if (block) {
299
- delete block.index;
300
- if (block.type === 'text') {
301
- stream.push({
302
- type: 'text_end',
303
- contentIndex: index,
304
- content: block.text,
305
- partial: output
306
- });
368
+ else if (event.type === 'message_delta') {
369
+ if (event.delta.stop_reason) {
370
+ providerStopReason = event.delta.stop_reason;
371
+ const details = event.delta.stop_details;
372
+ if (details && typeof details === 'object' && !Array.isArray(details))
373
+ stopDetails = details;
374
+ output.stopReason = mapStopReason(event.delta.stop_reason);
307
375
  }
308
- else if (block.type === 'thinking') {
309
- stream.push({
310
- type: 'thinking_end',
311
- contentIndex: index,
312
- content: block.thinking,
313
- partial: output
314
- });
376
+ // Only update usage fields if present (not null).
377
+ // Preserves input_tokens from message_start when proxies omit it in message_delta.
378
+ const usage = event.usage;
379
+ if (usage?.output_tokens != null) {
380
+ output.usage.output = usage.output_tokens;
315
381
  }
316
- else if (block.type === 'toolCall') {
317
- block.arguments = parseStreamingJson(block.partialJson);
318
- delete block.partialJson;
319
- stream.push({
320
- type: 'toolcall_end',
321
- contentIndex: index,
322
- toolCall: block,
323
- partial: output
324
- });
382
+ if (usage?.cache_read_input_tokens != null) {
383
+ output.usage.cacheRead = usage.cache_read_input_tokens;
384
+ }
385
+ if (usage?.cache_creation_input_tokens != null) {
386
+ output.usage.cacheWrite = usage.cache_creation_input_tokens;
325
387
  }
388
+ if (usage?.input_tokens != null) {
389
+ uncachedInputTokens = usage.input_tokens;
390
+ }
391
+ // Anthropic doesn't provide total_tokens; usage.input is normalized
392
+ // to total input, including cache buckets.
393
+ output.usage.input =
394
+ uncachedInputTokens + output.usage.cacheRead + output.usage.cacheWrite;
395
+ output.usage.totalTokens = output.usage.input + output.usage.output;
396
+ calculateCost(servingModel, output.usage);
326
397
  }
327
398
  }
328
- else if (event.type === 'message_delta') {
329
- if (event.delta.stop_reason) {
330
- providerStopReason = event.delta.stop_reason;
331
- output.stopReason = mapStopReason(event.delta.stop_reason);
332
- }
333
- // Only update usage fields if present (not null).
334
- // Preserves input_tokens from message_start when proxies omit it in message_delta.
335
- const usage = event.usage;
336
- if (usage?.output_tokens != null) {
337
- output.usage.output = usage.output_tokens;
338
- }
339
- if (usage?.cache_read_input_tokens != null) {
340
- output.usage.cacheRead = usage.cache_read_input_tokens;
341
- }
342
- if (usage?.cache_creation_input_tokens != null) {
343
- output.usage.cacheWrite = usage.cache_creation_input_tokens;
399
+ if (options?.signal?.aborted) {
400
+ throw new Error('Request was aborted');
401
+ }
402
+ if (!completed) {
403
+ throw new AnthropicTerminalStopError({ providerErrorType: 'network', retryable: false });
404
+ }
405
+ if (completed &&
406
+ providerStopReason === 'refusal' &&
407
+ !fallbackAttempted &&
408
+ !unsafeBoundary &&
409
+ ['cyber', 'bio', 'frontier_llm'].includes(String(stopDetails?.category)) &&
410
+ !('fallbacks' in params) &&
411
+ !('fallback_credit_token' in params)) {
412
+ const targetId = response.headers.get('X-LLM-Refusal-Fallback-Model');
413
+ const target = targetId ? options?.resolveRefusalFallbackModel?.(targetId) : undefined;
414
+ if (target &&
415
+ target.id !== model.id &&
416
+ target.api === model.api &&
417
+ target.baseUrl === model.baseUrl) {
418
+ const token = stopDetails?.fallback_credit_token;
419
+ const credit = typeof token === 'string' && token.length > 0;
420
+ // No tool block has appeared, so replaying this single uncommitted
421
+ // request is safe. The unchanged-body credit shape avoids mixing
422
+ // partial thinking from two models and is accepted without prefill.
423
+ requestParams = {
424
+ ...params,
425
+ model: target.id,
426
+ ...(credit ? { fallback_credit_token: token } : {})
427
+ };
428
+ retryHeaders = {
429
+ 'X-LLM-Refusal-Fallback': response.headers.get('X-LLM-Provider-Model') ?? model.id,
430
+ 'X-LLM-Refusal-Source-Id': response.headers.get('X-LLM-Refusal-Source-Id') ?? '',
431
+ 'X-LLM-Refusal-Category': String(stopDetails?.category),
432
+ 'X-LLM-Refusal-Credit': credit ? 'submitted' : 'unavailable',
433
+ 'X-Request-Id': crypto.randomUUID()
434
+ };
435
+ output.refusalFallback = {
436
+ requestedModel: model.id,
437
+ targetModel: target.id,
438
+ scope: 'response',
439
+ phase: 'attempting',
440
+ credit: credit ? 'pending' : 'unavailable'
441
+ };
442
+ output.responseModel = undefined;
443
+ fallbackAttempted = true;
444
+ servingModel = target;
445
+ output.model = target.id;
446
+ output.content = [];
447
+ output.stopReason = 'stop';
448
+ output.usage = {
449
+ input: 0,
450
+ output: 0,
451
+ cacheRead: 0,
452
+ cacheWrite: 0,
453
+ totalTokens: 0,
454
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
455
+ };
456
+ stream.push({ type: 'start', partial: output });
457
+ continue;
344
458
  }
345
- if (usage?.input_tokens != null) {
346
- uncachedInputTokens = usage.input_tokens;
459
+ }
460
+ if (output.stopReason === 'aborted' || output.stopReason === 'error') {
461
+ const details = anthropicTerminalStopErrorDetails(providerStopReason);
462
+ if (details) {
463
+ throw new AnthropicTerminalStopError(details);
347
464
  }
348
- // Anthropic doesn't provide total_tokens; usage.input is normalized
349
- // to total input, including cache buckets.
350
- output.usage.input =
351
- uncachedInputTokens + output.usage.cacheRead + output.usage.cacheWrite;
352
- output.usage.totalTokens = output.usage.input + output.usage.output;
353
- calculateCost(model, output.usage);
465
+ throw new Error('An unknown error occurred');
354
466
  }
355
- }
356
- if (options?.signal?.aborted) {
357
- throw new Error('Request was aborted');
358
- }
359
- if (output.stopReason === 'aborted' || output.stopReason === 'error') {
360
- const details = anthropicTerminalStopErrorDetails(providerStopReason);
361
- if (details) {
362
- throw new AnthropicTerminalStopError(details);
467
+ if (output.refusalFallback) {
468
+ // Submission alone is not proof of an offset (already-warm caches can
469
+ // have no repricing). Only confirm an observed matching bucket shift.
470
+ const shift = initialFallbackCache
471
+ ? initialFallbackCache.write - output.usage.cacheWrite
472
+ : 0;
473
+ const applied = initialFallbackCache !== undefined &&
474
+ shift > 0 &&
475
+ output.usage.cacheRead - initialFallbackCache.read === shift;
476
+ output.refusalFallback = {
477
+ ...output.refusalFallback,
478
+ phase: 'completed',
479
+ credit: output.refusalFallback.credit === 'pending'
480
+ ? applied
481
+ ? 'applied'
482
+ : 'unconfirmed'
483
+ : output.refusalFallback.credit
484
+ };
363
485
  }
364
- throw new Error('An unknown error occurred');
486
+ stream.push({ type: 'done', reason: output.stopReason, message: output });
487
+ stream.end();
488
+ break;
365
489
  }
366
- stream.push({ type: 'done', reason: output.stopReason, message: output });
367
- stream.end();
368
490
  }
369
491
  catch (error) {
370
492
  for (const block of output.content)
371
493
  delete block.index;
372
494
  output.stopReason = options?.signal?.aborted ? 'aborted' : 'error';
373
- applyNormalizedProviderError(output, error);
495
+ if (output.refusalFallback) {
496
+ output.refusalFallback = {
497
+ ...output.refusalFallback,
498
+ phase: options?.signal?.aborted ? 'cancelled' : 'failed',
499
+ credit: output.refusalFallback.credit === 'pending'
500
+ ? 'unconfirmed'
501
+ : output.refusalFallback.credit
502
+ };
503
+ }
504
+ applyNormalizedProviderError(output, fallbackAttempted && !options?.signal?.aborted
505
+ ? new AnthropicTerminalStopError({ code: PROVIDER_REFUSAL_ERROR_CODE, retryable: false })
506
+ : error);
374
507
  stream.push({ type: 'error', reason: output.stopReason, error: output });
375
508
  stream.end();
376
509
  }
@@ -2,12 +2,14 @@
2
2
  * Shared utilities for Google Generative AI and Google Cloud Code Assist providers.
3
3
  */
4
4
  import { type Content, FinishReason, FunctionCallingConfigMode, type Part } from '@google/genai';
5
- import type { Context, Model, StopReason, Tool } from '../types.js';
5
+ import type { Context, EnabledReasoningLevel, Model, StopReason, Tool } from '../types.js';
6
6
  type GoogleApiType = 'google-generative-ai' | 'google-vertex';
7
7
  /**
8
8
  * Mirrors Google's ThinkingLevel enum values.
9
9
  */
10
10
  export type GoogleThinkingLevel = 'THINKING_LEVEL_UNSPECIFIED' | 'MINIMAL' | 'LOW' | 'MEDIUM' | 'HIGH';
11
+ /** Serialize a declared thinking-level capability independently of model version. */
12
+ export declare function getGoogleThinkingLevel(effort: EnabledReasoningLevel): GoogleThinkingLevel;
11
13
  /**
12
14
  * Determines whether a streamed Gemini `Part` should be treated as "thinking".
13
15
  *
@@ -4,6 +4,22 @@
4
4
  import { FinishReason, FunctionCallingConfigMode } from '@google/genai';
5
5
  import { sanitizeSurrogates } from '../utils/sanitize-unicode.js';
6
6
  import { transformMessages } from './transform-messages.js';
7
+ /** Serialize a declared thinking-level capability independently of model version. */
8
+ export function getGoogleThinkingLevel(effort) {
9
+ switch (effort) {
10
+ case 'minimal':
11
+ return 'MINIMAL';
12
+ case 'low':
13
+ return 'LOW';
14
+ case 'medium':
15
+ return 'MEDIUM';
16
+ case 'high':
17
+ return 'HIGH';
18
+ case 'xhigh':
19
+ case 'max':
20
+ throw new Error(`Google thinking levels do not support reasoning level "${effort}".`);
21
+ }
22
+ }
7
23
  /**
8
24
  * Determines whether a streamed Gemini `Part` should be treated as "thinking".
9
25
  *
@@ -110,26 +126,27 @@ export function convertMessages(model, context) {
110
126
  else if (msg.role === 'assistant') {
111
127
  const parts = [];
112
128
  // Check if message is from same provider and model - only then keep thinking blocks
113
- const isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;
129
+ const isSameProviderAndModel = msg.provider === model.provider && msg.api === model.api && msg.model === model.id;
130
+ const firstToolCall = msg.content.find((block) => block.type === 'toolCall');
131
+ const hasSignedToolCalls = Boolean(resolveThoughtSignature(isSameProviderAndModel, firstToolCall?.thoughtSignature));
114
132
  for (const block of msg.content) {
115
133
  if (block.type === 'text') {
116
- // Skip empty text blocks - they can cause issues with some models.
117
- if (!block.text || block.text.trim() === '')
118
- continue;
119
134
  const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);
135
+ // Empty signed parts still carry provider replay state.
136
+ if (!thoughtSignature && (!block.text || block.text.trim() === ''))
137
+ continue;
120
138
  parts.push({
121
139
  text: sanitizeSurrogates(block.text),
122
140
  ...(thoughtSignature && { thoughtSignature })
123
141
  });
124
142
  }
125
143
  else if (block.type === 'thinking') {
126
- // Skip empty thinking blocks
127
- if (!block.thinking || block.thinking.trim() === '')
144
+ const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);
145
+ if (!thoughtSignature && (!block.thinking || block.thinking.trim() === ''))
128
146
  continue;
129
147
  // Only keep as thinking block if same provider AND same model
130
148
  // Otherwise convert to plain text (no tags to avoid model mimicking them)
131
149
  if (isSameProviderAndModel) {
132
- const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);
133
150
  parts.push({
134
151
  thought: true,
135
152
  text: sanitizeSurrogates(block.thinking),
@@ -144,12 +161,10 @@ export function convertMessages(model, context) {
144
161
  }
145
162
  else if (block.type === 'toolCall') {
146
163
  const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);
147
- // Gemini 3 requires thoughtSignature on all function calls when thinking mode is enabled.
148
- // When replaying history from providers without thought signatures,
149
- // convert unsigned function calls to text to avoid API validation errors.
150
- // We include a note telling the model this is historical context to prevent mimicry.
164
+ // Only the first parallel call needs a signature. If it is missing (foreign
165
+ // or older persisted history), retain the historical-text fallback for the batch.
151
166
  const isGemini3 = model.id.toLowerCase().includes('gemini-3');
152
- if (isGemini3 && !thoughtSignature) {
167
+ if (isGemini3 && !hasSignedToolCalls) {
153
168
  const argsStr = JSON.stringify(block.arguments ?? {}, null, 2);
154
169
  parts.push({
155
170
  text: `[Historical context: a different model called tool "${block.name}" with arguments: ${argsStr}. Do not mimic this format - use proper function calling.]`