minimal-agent 0.12.0 → 0.14.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 (472) hide show
  1. package/README.md +6 -5
  2. package/package.json +62 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +204 -185
  16. package/plugins/workflow-runner/src/index.ts +249 -224
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +404 -467
  28. package/plugins/workflow-runner/src/runner.ts +491 -535
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +172 -152
  54. package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -105
  58. package/plugins/workflow-runner/src/types.ts +155 -520
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +542 -469
  68. package/plugins/workflow-runner/src/workflowState.ts +639 -589
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/skill-creator/scripts/run_eval.py +3 -2
  92. package/skills/ui-design/SKILL.md +5 -2
  93. package/skills/ui-design/references/layout-composition.md +1 -1
  94. package/skills/workflow-creator/SKILL.md +344 -0
  95. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  96. package/skills/workflow-creator/references/api.md +216 -0
  97. package/skills/workflow-creator/references/migration.md +103 -0
  98. package/skills/workflow-creator/references/patterns.md +779 -0
  99. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  100. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  101. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  102. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  103. package/src/advisor/advisorCoordinator.js +503 -0
  104. package/src/advisor/advisorCoordinator.ts +657 -0
  105. package/src/cli/configMenu.tsx +0 -1
  106. package/src/cli/print.js +44 -6
  107. package/src/cli/print.ts +73 -4
  108. package/src/cli/streamJson.js +5 -6
  109. package/src/cli/streamJson.ts +8 -4
  110. package/src/cli/wizards/advisorWizard.js +4 -2
  111. package/src/cli/wizards/advisorWizard.tsx +8 -2
  112. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  113. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  114. package/src/collaboration/taskFlow.js +115 -0
  115. package/src/collaboration/taskFlow.ts +169 -0
  116. package/src/config/configDefaults.js +41 -1
  117. package/src/config/configDefaults.ts +43 -1
  118. package/src/config/configDiagnostics.ts +2 -2
  119. package/src/config/configFile.js +40 -9
  120. package/src/config/configFile.ts +60 -11
  121. package/src/config/configService.js +443 -74
  122. package/src/config/configService.ts +723 -142
  123. package/src/config/numericLimits.js +22 -0
  124. package/src/config/numericLimits.ts +24 -0
  125. package/src/config.js +1 -0
  126. package/src/config.ts +3 -2
  127. package/src/context/budgetPlan.js +1 -1
  128. package/src/context/budgetPlan.ts +1 -1
  129. package/src/context/compact.js +7 -2
  130. package/src/context/compact.ts +9 -2
  131. package/src/context/microCompactLite.js +212 -13
  132. package/src/context/microCompactLite.ts +261 -12
  133. package/src/context/sessionRegistry.js +8 -1
  134. package/src/context/sessionRegistry.ts +18 -5
  135. package/src/context/toolResultArchive.js +72 -0
  136. package/src/context/toolResultArchive.ts +95 -0
  137. package/src/goal/errors.js +8 -0
  138. package/src/goal/errors.ts +18 -0
  139. package/src/goal/goalRuntime.js +344 -0
  140. package/src/goal/goalRuntime.ts +466 -0
  141. package/src/goal/goalStore.js +200 -0
  142. package/src/goal/goalStore.ts +219 -0
  143. package/src/goal/index.js +4 -0
  144. package/src/goal/index.ts +4 -0
  145. package/src/goal/statusMapping.js +71 -0
  146. package/src/goal/statusMapping.ts +95 -0
  147. package/src/goal/types.js +7 -0
  148. package/src/goal/types.ts +179 -0
  149. package/src/goal/workflowController.js +306 -0
  150. package/src/goal/workflowController.ts +360 -0
  151. package/src/harness/evidenceLedger.js +2 -0
  152. package/src/harness/evidenceLedger.ts +1 -0
  153. package/src/harness/stallGuard.js +9 -3
  154. package/src/harness/stallGuard.ts +7 -3
  155. package/src/images/imageResolver.js +161 -0
  156. package/src/images/imageResolver.ts +189 -0
  157. package/src/infra/verification.js +56 -20
  158. package/src/infra/verification.ts +87 -20
  159. package/src/llm/client.js +79 -21
  160. package/src/llm/client.ts +182 -35
  161. package/src/llm/gatewayClient.js +201 -0
  162. package/src/llm/gatewayClient.ts +299 -0
  163. package/src/llm/messageProvenance.js +46 -0
  164. package/src/llm/messageProvenance.ts +58 -0
  165. package/src/llm/modelProvider.js +1 -0
  166. package/src/llm/modelProvider.ts +22 -0
  167. package/src/llm/providers/anthropicFormat.js +108 -1
  168. package/src/llm/providers/anthropicFormat.ts +115 -4
  169. package/src/llm/providers/openaiFormat.js +9 -0
  170. package/src/llm/providers/openaiFormat.ts +12 -3
  171. package/src/loop.js +319 -54
  172. package/src/loop.ts +373 -57
  173. package/src/main.js +4 -1
  174. package/src/main.tsx +4 -1
  175. package/src/managedExecution/index.js +2 -0
  176. package/src/managedExecution/index.ts +2 -0
  177. package/src/managedExecution/registry.js +15 -0
  178. package/src/managedExecution/registry.ts +20 -0
  179. package/src/managedExecution/types.js +1 -0
  180. package/src/managedExecution/types.ts +86 -0
  181. package/src/modelRef.js +9 -0
  182. package/src/modelRef.ts +31 -0
  183. package/src/multimodal.js +14 -28
  184. package/src/multimodal.ts +17 -33
  185. package/src/net/lanDiscovery.js +65 -0
  186. package/src/net/lanDiscovery.ts +82 -0
  187. package/src/plugin-sdk.js +28 -3
  188. package/src/plugin-sdk.ts +39 -6
  189. package/src/plugins/pluginApi.ts +16 -1
  190. package/src/plugins/pluginLoader.js +4 -0
  191. package/src/plugins/pluginLoader.ts +6 -0
  192. package/src/plugins/pluginRunner.js +152 -9
  193. package/src/plugins/pluginRunner.ts +186 -8
  194. package/src/plugins/slashFallback.js +113 -0
  195. package/src/plugins/slashFallback.ts +137 -0
  196. package/src/prompts/policyRegistry.js +15 -8
  197. package/src/prompts/policyRegistry.ts +18 -8
  198. package/src/prompts/promptAssembly.js +103 -12
  199. package/src/prompts/promptAssembly.ts +114 -12
  200. package/src/prompts/skillList.js +21 -3
  201. package/src/prompts/skillList.ts +27 -2
  202. package/src/prompts/stableSystemPrompt.js +18 -0
  203. package/src/prompts/stableSystemPrompt.ts +33 -0
  204. package/src/runtime/agentRuntimeContext.js +8 -2
  205. package/src/runtime/agentRuntimeContext.ts +17 -4
  206. package/src/session/runAgentTurn.js +78 -12
  207. package/src/session/runAgentTurn.ts +105 -23
  208. package/src/session/runTurn.js +10 -9
  209. package/src/session/runTurn.ts +17 -8
  210. package/src/session/sessionState.ts +2 -0
  211. package/src/team/auth.js +186 -0
  212. package/src/team/auth.ts +298 -0
  213. package/src/team/cli.js +105 -0
  214. package/src/team/cli.ts +122 -0
  215. package/src/team/onlineToolContract.js +64 -0
  216. package/src/team/onlineToolContract.ts +109 -0
  217. package/src/team/toolPolicy.js +36 -0
  218. package/src/team/toolPolicy.ts +75 -0
  219. package/src/tools/advisor/advisor.js +148 -37
  220. package/src/tools/advisor/advisor.ts +161 -38
  221. package/src/tools/advisor/advisorDecision.js +71 -0
  222. package/src/tools/advisor/advisorDecision.ts +85 -0
  223. package/src/tools/agent/agent.js +18 -5
  224. package/src/tools/agent/agent.ts +21 -7
  225. package/src/tools/agent/agentControl.js +246 -0
  226. package/src/tools/agent/agentControl.ts +284 -0
  227. package/src/tools/agent/agentTaskService.js +40 -1
  228. package/src/tools/agent/agentTaskService.ts +44 -1
  229. package/src/tools/agent/agentTypes.js +14 -2
  230. package/src/tools/agent/agentTypes.ts +15 -2
  231. package/src/tools/applypatch/applyPatch.js +362 -0
  232. package/src/tools/applypatch/applyPatch.ts +428 -0
  233. package/src/tools/bash/bash.js +70 -18
  234. package/src/tools/bash/bash.ts +75 -20
  235. package/src/tools/capabilities.js +10 -5
  236. package/src/tools/capabilities.ts +10 -5
  237. package/src/tools/computeruse/computerIntent.js +32 -0
  238. package/src/tools/computeruse/computerIntent.ts +46 -0
  239. package/src/tools/computeruse/telemetryLog.js +12 -0
  240. package/src/tools/computeruse/telemetryLog.ts +16 -0
  241. package/src/tools/computeruse/vision/telemetry.js +1 -0
  242. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  243. package/src/tools/effectiveToolSet.js +4 -0
  244. package/src/tools/effectiveToolSet.ts +4 -0
  245. package/src/tools/index.js +21 -2
  246. package/src/tools/index.ts +33 -2
  247. package/src/tools/powershell/powershell.js +18 -1
  248. package/src/tools/powershell/powershell.ts +18 -2
  249. package/src/tools/presentresult/presentresult.js +6 -15
  250. package/src/tools/presentresult/presentresult.ts +6 -15
  251. package/src/tools/read/read.js +69 -11
  252. package/src/tools/read/read.ts +70 -11
  253. package/src/tools/shared/fileUtils.js +1 -2
  254. package/src/tools/shared/fileUtils.ts +1 -2
  255. package/src/tools/shared/permanentDeleteGuard.js +34 -3
  256. package/src/tools/shared/permanentDeleteGuard.ts +43 -6
  257. package/src/tools/shared/toolOutputStore.js +23 -1
  258. package/src/tools/shared/toolOutputStore.ts +22 -1
  259. package/src/tools/skill/skill.js +9 -3
  260. package/src/tools/skill/skill.ts +8 -4
  261. package/src/tools/toolPromptGuides.js +117 -0
  262. package/src/tools/toolPromptGuides.ts +137 -0
  263. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  264. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  265. package/src/tools/webbrowser/browser.js +27 -11
  266. package/src/tools/webbrowser/browser.ts +68 -24
  267. package/src/tools/webbrowser/browserAutomation.js +329 -0
  268. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  269. package/src/tools/webbrowser/browserAxState.js +97 -0
  270. package/src/tools/webbrowser/browserAxState.ts +142 -0
  271. package/src/tools/webbrowser/browserBatch.js +1578 -0
  272. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  273. package/src/tools/webbrowser/browserCdp.js +208 -0
  274. package/src/tools/webbrowser/browserCdp.ts +255 -0
  275. package/src/tools/webbrowser/browserConditions.js +24 -0
  276. package/src/tools/webbrowser/browserConditions.ts +45 -0
  277. package/src/tools/webbrowser/browserContent.js +281 -0
  278. package/src/tools/webbrowser/browserContent.ts +438 -0
  279. package/src/tools/webbrowser/browserControl.js +131 -30
  280. package/src/tools/webbrowser/browserControl.ts +210 -50
  281. package/src/tools/webbrowser/browserDaemon.js +22 -14
  282. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  283. package/src/tools/webbrowser/browserFrames.js +47 -0
  284. package/src/tools/webbrowser/browserFrames.ts +54 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  286. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  287. package/src/tools/webbrowser/browserLocator.js +140 -0
  288. package/src/tools/webbrowser/browserLocator.ts +194 -0
  289. package/src/tools/webbrowser/browserOutcome.js +10 -17
  290. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  291. package/src/tools/webbrowser/browserRecovery.js +58 -0
  292. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  293. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  294. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  295. package/src/tools/webbrowser/browserService.js +28 -2
  296. package/src/tools/webbrowser/browserService.ts +49 -9
  297. package/src/tools/webbrowser/browserStream.js +132 -33
  298. package/src/tools/webbrowser/browserStream.ts +224 -50
  299. package/src/tools/webbrowser/browserTabs.js +48 -15
  300. package/src/tools/webbrowser/browserTabs.ts +178 -96
  301. package/src/tools/webbrowser/webbrowser.js +683 -144
  302. package/src/tools/webbrowser/webbrowser.ts +979 -236
  303. package/src/tools/webfetch/preapproved.js +0 -2
  304. package/src/tools/webfetch/preapproved.ts +0 -2
  305. package/src/tools/websearch/websearch.js +129 -8
  306. package/src/tools/websearch/websearch.ts +138 -6
  307. package/src/types.ts +450 -42
  308. package/src/ui/App.js +377 -58
  309. package/src/ui/App.tsx +576 -111
  310. package/src/ui/LiveArea.js +14 -8
  311. package/src/ui/LiveArea.tsx +14 -10
  312. package/src/ui/MessageList.js +63 -20
  313. package/src/ui/MessageList.tsx +101 -16
  314. package/src/ui/ModelPicker.js +7 -4
  315. package/src/ui/ModelPicker.tsx +55 -8
  316. package/src/ui/hooks/useChat.js +152 -163
  317. package/src/ui/hooks/useChat.ts +396 -334
  318. package/src/ui/loginCommand.js +56 -0
  319. package/src/ui/loginCommand.ts +63 -0
  320. package/src/ui/toolProgress.js +41 -0
  321. package/src/ui/toolProgress.ts +44 -0
  322. package/src/web/browserBridge.js +20 -2
  323. package/src/web/browserBridge.ts +20 -2
  324. package/src/web/protocol.ts +1897 -194
  325. package/workflows/adaptive-research/workflow.mjs +86 -0
  326. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  327. package/workflows/e2e-llm/workflow.mjs +52 -0
  328. package/workflows/e2e-smoke/workflow.mjs +59 -0
  329. package/workflows/e2e-vision-schema/README.md +48 -0
  330. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  331. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  332. package/workflows/file-census/README.md +14 -0
  333. package/workflows/file-census/scripts/.gitkeep +2 -0
  334. package/workflows/file-census/workflow.mjs +110 -0
  335. package/workflows/goal/README.md +166 -0
  336. package/workflows/goal/prompts/audit.md +57 -0
  337. package/workflows/goal/prompts/contract.md +56 -0
  338. package/workflows/goal/prompts/iterate.md +37 -0
  339. package/workflows/goal/workflow.mjs +501 -0
  340. package/workflows/illustrate/README.md +90 -0
  341. package/workflows/illustrate/assets/engines.json +20 -0
  342. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  343. package/workflows/illustrate/assets/extract-bing.js +33 -0
  344. package/workflows/illustrate/assets/extract-google.js +31 -0
  345. package/workflows/illustrate/workflow.mjs +301 -0
  346. package/workflows/plan/workflow.mjs +389 -0
  347. package/workflows/question-crops/README.md +35 -0
  348. package/workflows/question-crops/prompts/inventory.md +23 -0
  349. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  350. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  351. package/workflows/question-crops/workflow.mjs +172 -0
  352. package/workflows/ralph-loop/workflow.mjs +162 -0
  353. package/workflows/research/DESIGN.md +449 -0
  354. package/workflows/research/README.md +74 -0
  355. package/workflows/research/prompts/s0-goal.md +43 -0
  356. package/workflows/research/prompts/s1-early-exit.md +22 -0
  357. package/workflows/research/prompts/s1-map.md +58 -0
  358. package/workflows/research/prompts/s2-options.md +53 -0
  359. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  360. package/workflows/research/prompts/s4-verify.md +74 -0
  361. package/workflows/research/prompts/s5-synthesis.md +81 -0
  362. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  363. package/workflows/research/prompts/s6-package.md +32 -0
  364. package/workflows/research/scripts/build-report.mjs +98 -0
  365. package/workflows/research/workflow.mjs +288 -0
  366. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  367. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  368. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  369. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  370. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  371. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  372. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  373. package/workflows/wrong-question-docx/README.md +55 -0
  374. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  375. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  376. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  377. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  378. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  379. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  380. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  381. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  382. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  383. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  384. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  385. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  386. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  387. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  388. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  389. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  390. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  391. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  392. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  393. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  394. package/plugins/workflow-runner/src/expressions.js +0 -618
  395. package/plugins/workflow-runner/src/expressions.ts +0 -622
  396. package/plugins/workflow-runner/src/loader.js +0 -573
  397. package/plugins/workflow-runner/src/loader.ts +0 -721
  398. package/plugins/workflow-runner/src/multimodal.js +0 -38
  399. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  400. package/plugins/workflow-runner/src/recovery.js +0 -119
  401. package/plugins/workflow-runner/src/recovery.ts +0 -149
  402. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  403. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  404. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
  405. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
  406. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  407. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  408. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  409. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  410. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  411. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  412. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  413. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  414. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
  415. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
  416. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
  417. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
  418. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  419. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  420. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  421. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  422. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  423. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  424. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
  425. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  426. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  427. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
  428. package/plugins/workflow-runner/test/expressions.test.ts +0 -397
  429. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  430. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  431. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  432. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  433. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  434. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  435. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  436. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  437. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  438. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  439. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
  440. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  441. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  442. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
  443. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -199
  468. package/workflows/schema.json +0 -176
  469. package/workflows/webppt.yaml +0 -496
  470. package/workflows/wechat-reading-shots.yaml +0 -315
  471. package/workflows/word.yaml +0 -720
  472. package/workflows/youtube-shorts.yaml +0 -202
@@ -1,30 +1,32 @@
1
- import {
2
- buildBaseSystemPrompt,
3
- buildTransientPromptBundle,
4
- } from '../prompts/system.js';
5
- import { ALL_TOOLS } from '../tools/index.js';
6
- import type { LoopEvent, Provider } from '../types.js';
7
- import { sessionFileFor } from '../context/sessionPath.js';
8
- import {
9
- getOrCreateSessionState,
10
- sessionStateKey,
11
- type SessionState,
12
- } from './sessionState.js';
13
- import { hydrateSessionWorktree } from '../tools/worktree/sessionWorktree.js';
14
- import { runTurn } from './runTurn.js';
15
1
  import { withWorkingDir } from '../bootstrap/workingDir.js';
2
+ import { configService } from '../config/configService.js';
3
+ import { sessionFileFor } from '../context/sessionPath.js';
16
4
  import {
17
5
  listSessionSummaries,
18
6
  updateSessionMetadata,
19
7
  } from '../context/sessionRegistry.js';
20
8
  import { workspaceIndexService } from '../context/workspaceIndex.js';
21
- import { configService } from '../config/configService.js';
22
9
  import { createPromptCacheContext } from '../llm/promptCache.js';
10
+ import { type ModelRef, modelRefFromLegacy } from '../modelRef.js';
11
+ import {
12
+ buildBaseSystemPrompt,
13
+ buildTransientPromptBundle,
14
+ } from '../prompts/system.js';
23
15
  import {
24
16
  createAgentRuntimeContext,
25
17
  filterToolsForRuntime,
26
18
  memoryContextFromRuntime,
27
19
  } from '../runtime/agentRuntimeContext.js';
20
+ import { filterToolsForCategories } from '../team/toolPolicy.js';
21
+ import { ALL_TOOLS } from '../tools/index.js';
22
+ import { hydrateSessionWorktree } from '../tools/worktree/sessionWorktree.js';
23
+ import type { LoopEvent, Provider } from '../types.js';
24
+ import { runTurn } from './runTurn.js';
25
+ import {
26
+ type SessionState,
27
+ getOrCreateSessionState,
28
+ sessionStateKey,
29
+ } from './sessionState.js';
28
30
 
29
31
  export interface RunAgentTurnOptions {
30
32
  input: string;
@@ -59,6 +61,17 @@ export async function runAgentTurn(
59
61
  (item) => item.id === opts.sessionId,
60
62
  );
61
63
  let sessionModelId = session?.modelId;
64
+ const preferredModel = session?.preferredModel;
65
+ // Sessions created before source-aware model references were introduced may
66
+ // still carry only the legacy `online:<id>` value. Treat that value as the
67
+ // same gateway preference so fallback and recovery follow one state machine.
68
+ const storedModelRef =
69
+ preferredModel ??
70
+ (sessionModelId?.startsWith('online:')
71
+ ? modelRefFromLegacy(sessionModelId)
72
+ : undefined);
73
+ if (!opts.model && preferredModel?.source === 'local')
74
+ sessionModelId = preferredModel.modelId;
62
75
  if (!opts.model && !sessionModelId) {
63
76
  sessionModelId =
64
77
  (await configService.getSnapshot()).config?.baseModelId ?? undefined;
@@ -68,13 +81,56 @@ export async function runAgentTurn(
68
81
  }).catch(() => {});
69
82
  }
70
83
  }
71
- const sessionProvider =
72
- !opts.model && sessionModelId
73
- ? await configService.providerForModel(sessionModelId)
84
+ const gatewayResolution =
85
+ !opts.model && storedModelRef?.source === 'gateway'
86
+ ? await configService
87
+ .resolveModelRef(storedModelRef)
88
+ .catch(() => ({ provider: null, fallbackReason: 'offline' as const }))
89
+ : null;
90
+ const sessionProvider = !opts.model
91
+ ? (gatewayResolution?.provider ??
92
+ (await configService
93
+ .providerForRef(storedModelRef as ModelRef | null)
94
+ .catch(() => null)))
95
+ : null;
96
+ const localSessionModelId =
97
+ storedModelRef?.source === 'local'
98
+ ? storedModelRef.modelId
99
+ : sessionModelId && !sessionModelId.startsWith('online:')
100
+ ? sessionModelId
101
+ : undefined;
102
+ const legacySessionProvider =
103
+ !opts.model && !sessionProvider && localSessionModelId
104
+ ? await configService.providerForModel(localSessionModelId)
105
+ : null;
106
+ const fallbackProvider =
107
+ !opts.model && gatewayResolution && !gatewayResolution.provider
108
+ ? await configService.providerForModel(null).catch(() => null)
74
109
  : null;
75
110
  const provider = opts.model
76
111
  ? { ...opts.provider, model: opts.model }
77
- : (sessionProvider ?? opts.provider);
112
+ : (sessionProvider ??
113
+ fallbackProvider ??
114
+ legacySessionProvider ??
115
+ opts.provider);
116
+ if (
117
+ !opts.model &&
118
+ gatewayResolution &&
119
+ !gatewayResolution.provider &&
120
+ fallbackProvider
121
+ ) {
122
+ await updateSessionMetadata(opts.cwd, opts.sessionId, {
123
+ ...(storedModelRef?.source === 'gateway' && !preferredModel
124
+ ? { preferredModel: storedModelRef }
125
+ : {}),
126
+ effectiveModel: {
127
+ source: 'local',
128
+ modelId: localSessionModelId ?? fallbackProvider.model,
129
+ },
130
+ fallbackReason: gatewayResolution.fallbackReason,
131
+ restoreWhenAvailable: true,
132
+ }).catch(() => {});
133
+ }
78
134
  const workspace = await workspaceIndexService
79
135
  .register(opts.cwd)
80
136
  .catch(() => undefined);
@@ -117,7 +173,31 @@ export async function runAgentTurn(
117
173
  memoryAccess: opts.memoryAccess ?? 'denied',
118
174
  interactiveAsk: false,
119
175
  });
120
- const turnTools = filterToolsForRuntime(ALL_TOOLS, runtimeContext);
176
+ const runtimeTools = filterToolsForRuntime(ALL_TOOLS, runtimeContext);
177
+ const effectiveGatewayCategories =
178
+ provider.source === 'gateway'
179
+ ? [
180
+ ...new Set(
181
+ (
182
+ session?.onlineToolCategories ??
183
+ provider.gatewayDefaultToolCategories ??
184
+ provider.gatewayMaxToolCategories ??
185
+ []
186
+ ).filter(
187
+ (category) =>
188
+ provider.gatewayMaxToolCategories?.includes(category) ?? true,
189
+ ),
190
+ ),
191
+ ]
192
+ : undefined;
193
+ const turnProvider =
194
+ provider.source === 'gateway'
195
+ ? { ...provider, gatewayToolCategories: effectiveGatewayCategories }
196
+ : provider;
197
+ const turnTools =
198
+ provider.source === 'gateway'
199
+ ? filterToolsForCategories(runtimeTools, effectiveGatewayCategories)
200
+ : runtimeTools;
121
201
  const systemPrompt = await buildBaseSystemPrompt(effectiveCwd, turnTools);
122
202
  const transientBundle = await buildTransientPromptBundle({
123
203
  cwd: effectiveCwd,
@@ -137,7 +217,7 @@ export async function runAgentTurn(
137
217
  }).catch(() => {});
138
218
  for await (const ev of run({
139
219
  userInput: opts.input,
140
- provider,
220
+ provider: turnProvider,
141
221
  sessionFile,
142
222
  systemPrompt,
143
223
  ...(transientBundle ? { transientBundle } : {}),
@@ -154,6 +234,8 @@ export async function runAgentTurn(
154
234
  if (isEventLike(ev)) {
155
235
  events.push(ev);
156
236
  if (ev.type === 'text') result += ev.delta;
237
+ if (ev.type === 'assistant_draft_discarded' && ev.textLength > 0)
238
+ result = result.slice(0, Math.max(0, result.length - ev.textLength));
157
239
  if (ev.type === 'assistant_message') numTurns++;
158
240
  // compact_failed 是非致命(loop 压缩失败后 snip 兜底继续跑完,types.ts 有约定;
159
241
  // print.ts 同样特判)——不置 error,否则 cron 会把自愈轮误判失败。
@@ -175,7 +257,7 @@ export async function runAgentTurn(
175
257
  function isEventLike(ev: unknown): ev is LoopEvent {
176
258
  return Boolean(
177
259
  ev &&
178
- typeof ev === 'object' &&
179
- typeof (ev as { type?: unknown }).type === 'string',
260
+ typeof ev === 'object' &&
261
+ typeof (ev as { type?: unknown }).type === 'string',
180
262
  );
181
263
  }
@@ -18,14 +18,15 @@
18
18
  * 消息追加到 history,所以落盘的也是合法且完整的会话状态。
19
19
  * ============================================================
20
20
  */
21
- import { loadContext, saveContext } from '../context/persistContext.js';
22
21
  import { acquireContextLock } from '../context/contextLock.js';
22
+ import { loadContext, saveContext } from '../context/persistContext.js';
23
23
  import { startTurnJournal } from '../memory/turnJournal.js';
24
24
  import { runWithPlugins } from '../plugins/pluginRunner.js';
25
+ import { upsertStableSystemMessage } from '../prompts/stableSystemPrompt.js';
25
26
  /**
26
27
  * 已有历史时,用调用方新算好的 systemPrompt(含当前日期/实时扫描的 skills·plugins 清单/
27
28
  * 项目指令)替换旧的 system 消息,其余历史原样保留——与 ui/Root.tsx 的 TUI 启动逻辑、
28
- * workflow-runner::refreshWorkflowSystemPrompt 行为一致。堵上 headless 会话(cron-runner
29
+ * `refreshStableSystemPrompt()` 行为一致。堵上 headless 会话(cron-runner
29
30
  * 纯文本 action 等长期复用同一 sessionFile 的调用方)系统提示词只在首次开会话时生效、
30
31
  * 此后永久冻结的口子——此前的行为是"已有历史就完全忽略新 systemPrompt",日期/skills/
31
32
  * plugins/项目指令都不会再刷新,与"运行时实时扫描"的设计承诺矛盾。
@@ -41,13 +42,10 @@ import { runWithPlugins } from '../plugins/pluginRunner.js';
41
42
  * 既保住了"运行时实时扫描"的承诺,又不破坏缓存。
42
43
  */
43
44
  function buildInitialHistory(loaded, systemPrompt) {
44
- if (!loaded) {
45
- return systemPrompt ? [{ role: 'system', content: systemPrompt }] : [];
46
- }
47
- if (!systemPrompt)
48
- return loaded;
49
- const rest = loaded[0]?.role === 'system' ? loaded.slice(1) : loaded;
50
- return [{ role: 'system', content: systemPrompt }, ...rest];
45
+ const history = loaded ? [...loaded] : [];
46
+ if (systemPrompt)
47
+ upsertStableSystemMessage(history, systemPrompt);
48
+ return history;
51
49
  }
52
50
  export async function* runTurn(opts) {
53
51
  const persist = opts.persist !== false;
@@ -71,6 +69,7 @@ export async function* runTurn(opts) {
71
69
  maxTurns: opts.maxTurns,
72
70
  runtimeContext: opts.runtimeContext,
73
71
  allowedTools: opts.allowedTools,
72
+ availableTools: opts.availableTools,
74
73
  sessionState: opts.sessionState,
75
74
  chat: opts.chat,
76
75
  executeTool: opts.executeTool,
@@ -80,7 +79,9 @@ export async function* runTurn(opts) {
80
79
  transientBundle: opts.transientBundle,
81
80
  promptCache: opts.promptCache,
82
81
  userAttachments: opts.userAttachments,
82
+ inputResources: opts.inputResources,
83
83
  userMessageId: opts.userMessageId,
84
+ messageProvenance: opts.messageProvenance,
84
85
  userBrowserReferences: opts.userBrowserReferences,
85
86
  imageInputs: opts.imageInputs,
86
87
  parseInlineImages: opts.parseInlineImages,
@@ -19,11 +19,12 @@
19
19
  * ============================================================
20
20
  */
21
21
 
22
- import { loadContext, saveContext } from '../context/persistContext.js';
23
22
  import { acquireContextLock } from '../context/contextLock.js';
23
+ import { loadContext, saveContext } from '../context/persistContext.js';
24
24
  import { startTurnJournal } from '../memory/turnJournal.js';
25
25
  import type { PluginEvent } from '../plugins/pluginApi.js';
26
26
  import { runWithPlugins } from '../plugins/pluginRunner.js';
27
+ import { upsertStableSystemMessage } from '../prompts/stableSystemPrompt.js';
27
28
  import type {
28
29
  ImageDetail,
29
30
  ImageInputSpec,
@@ -45,6 +46,12 @@ export interface RunTurnOptions {
45
46
  maxTurns?: number;
46
47
  runtimeContext?: import('../runtime/agentRuntimeContext.js').AgentRuntimeContext;
47
48
  allowedTools?: import('../loop.js').RunQueryOptions['allowedTools'];
49
+ /**
50
+ * 本回合实际可调用的工具对象池(不只是名字)。缺省时 `loop.ts` 退回 `ALL_TOOLS`
51
+ * 静态注册表,装不下按回合动态构造的工具(群协作工具、每次都要闭包捕获当次
52
+ * owner/群 id/回复回调)。见 `pluginRunner.ts` 里这个字段的完整头注。
53
+ */
54
+ availableTools?: import('../loop.js').RunQueryOptions['availableTools'];
48
55
  /** DI:透传给 runWithPlugins→runQuery(仅测试用,生产不传走默认实现)。
49
56
  * 让测试用显式注入替代 mock.module(loop.js)——后者会全局泄漏污染其它测试文件。 */
50
57
  chat?: import('../plugins/pluginRunner.js').PluginRunnerOptions['chat'];
@@ -57,8 +64,10 @@ export interface RunTurnOptions {
57
64
  transientBundle?: import('../plugins/pluginRunner.js').PluginRunnerOptions['transientBundle'];
58
65
  promptCache?: import('../plugins/pluginRunner.js').PluginRunnerOptions['promptCache'];
59
66
  userAttachments?: MessageAttachmentRef[];
67
+ inputResources?: readonly import('../types.js').InvocationResource[];
60
68
  /** Stable message identity supplied by a host/runtime request. */
61
69
  userMessageId?: string;
70
+ messageProvenance?: import('../types.js').ConversationProvenance;
62
71
  userBrowserReferences?: MessageBrowserReference[];
63
72
  imageInputs?: ImageInputSpec[];
64
73
  parseInlineImages?: boolean;
@@ -77,7 +86,7 @@ export interface RunTurnOptions {
77
86
  /**
78
87
  * 已有历史时,用调用方新算好的 systemPrompt(含当前日期/实时扫描的 skills·plugins 清单/
79
88
  * 项目指令)替换旧的 system 消息,其余历史原样保留——与 ui/Root.tsx 的 TUI 启动逻辑、
80
- * workflow-runner::refreshWorkflowSystemPrompt 行为一致。堵上 headless 会话(cron-runner
89
+ * `refreshStableSystemPrompt()` 行为一致。堵上 headless 会话(cron-runner
81
90
  * 纯文本 action 等长期复用同一 sessionFile 的调用方)系统提示词只在首次开会话时生效、
82
91
  * 此后永久冻结的口子——此前的行为是"已有历史就完全忽略新 systemPrompt",日期/skills/
83
92
  * plugins/项目指令都不会再刷新,与"运行时实时扫描"的设计承诺矛盾。
@@ -96,12 +105,9 @@ function buildInitialHistory(
96
105
  loaded: Message[] | null,
97
106
  systemPrompt: string | undefined,
98
107
  ): Message[] {
99
- if (!loaded) {
100
- return systemPrompt ? [{ role: 'system', content: systemPrompt }] : [];
101
- }
102
- if (!systemPrompt) return loaded;
103
- const rest = loaded[0]?.role === 'system' ? loaded.slice(1) : loaded;
104
- return [{ role: 'system', content: systemPrompt }, ...rest];
108
+ const history = loaded ? [...loaded] : [];
109
+ if (systemPrompt) upsertStableSystemMessage(history, systemPrompt);
110
+ return history;
105
111
  }
106
112
 
107
113
  export async function* runTurn(
@@ -129,6 +135,7 @@ export async function* runTurn(
129
135
  maxTurns: opts.maxTurns,
130
136
  runtimeContext: opts.runtimeContext,
131
137
  allowedTools: opts.allowedTools,
138
+ availableTools: opts.availableTools,
132
139
  sessionState: opts.sessionState,
133
140
  chat: opts.chat,
134
141
  executeTool: opts.executeTool,
@@ -138,7 +145,9 @@ export async function* runTurn(
138
145
  transientBundle: opts.transientBundle,
139
146
  promptCache: opts.promptCache,
140
147
  userAttachments: opts.userAttachments,
148
+ inputResources: opts.inputResources,
141
149
  userMessageId: opts.userMessageId,
150
+ messageProvenance: opts.messageProvenance,
142
151
  userBrowserReferences: opts.userBrowserReferences,
143
152
  imageInputs: opts.imageInputs,
144
153
  parseInlineImages: opts.parseInlineImages,
@@ -31,6 +31,8 @@ export interface SessionState {
31
31
  fileReads: FileReadState;
32
32
  backgroundTasks: BackgroundTaskState;
33
33
  agentTasks: AgentTaskState;
34
+ /** Short-lived evidence that this Session actually used native desktop automation. */
35
+ computerAutomation?: { lastUsedAt: number };
34
36
  /** Main-agent worktree changes the effective cwd without changing workspace identity. */
35
37
  activeWorktree?: {
36
38
  id: string;
@@ -0,0 +1,186 @@
1
+ /** Minimal, opt-in team credential store. Standalone startup never imports or
2
+ * reads it; only explicit team commands / online-model resolution do. */
3
+ import { chmod, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
4
+ import { dirname, join } from 'node:path';
5
+ import { getConfigFilePath } from '../config/configFile.js';
6
+ const TEAM_REQUEST_TIMEOUT_MS = Math.max(3_000, Math.min(60_000, Number(process.env.MINIMAL_AGENT_TEAM_REQUEST_TIMEOUT_MS ?? 15_000)));
7
+ function authPath() {
8
+ return join(dirname(getConfigFilePath()), 'team-auth.json');
9
+ }
10
+ export function normalizeTeamServerUrl(value) {
11
+ const url = new URL(value.trim());
12
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
13
+ throw new Error('团队服务器必须使用 http(s) 地址');
14
+ const hostname = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
15
+ const isLocalDevelopmentHost = hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';
16
+ if (url.protocol === 'http:' &&
17
+ !isLocalDevelopmentHost &&
18
+ process.env.KAKADEAI_ALLOW_HTTP_TEAM_SERVER !== '1') {
19
+ throw new Error('团队服务器必须使用 HTTPS(开发环境可使用本机地址或显式允许 HTTP)');
20
+ }
21
+ url.search = '';
22
+ url.hash = '';
23
+ return url.toString().replace(/\/$/, '');
24
+ }
25
+ export async function loadTeamCredentials(expectedServerUrl) {
26
+ const rawServerUrl = process.env.KAKADEAI_SOCIAL_SERVER_URL;
27
+ // The Desktop shell deliberately injects an empty value in standalone mode.
28
+ // An empty environment value is an explicit opt-out and must not fall back
29
+ // to a stale team-auth.json left by an earlier team-mode run.
30
+ if (rawServerUrl !== undefined && !rawServerUrl.trim())
31
+ return null;
32
+ const serverUrl = rawServerUrl?.trim() ?? expectedServerUrl?.trim();
33
+ if (rawServerUrl?.trim() &&
34
+ expectedServerUrl?.trim() &&
35
+ normalizeTeamServerUrl(rawServerUrl) !==
36
+ normalizeTeamServerUrl(expectedServerUrl))
37
+ return null;
38
+ const deviceToken = process.env.KAKADEAI_TEAM_DEVICE_TOKEN?.trim();
39
+ if (serverUrl && deviceToken) {
40
+ return {
41
+ serverUrl: normalizeTeamServerUrl(serverUrl),
42
+ deviceToken,
43
+ ...(process.env.KAKADEAI_TEAM_DEVICE_LABEL
44
+ ? { deviceLabel: process.env.KAKADEAI_TEAM_DEVICE_LABEL }
45
+ : {}),
46
+ updatedAt: Date.now(),
47
+ };
48
+ }
49
+ try {
50
+ const raw = JSON.parse(await readFile(authPath(), 'utf8'));
51
+ if (!raw.serverUrl || !raw.deviceToken)
52
+ return null;
53
+ const storedServerUrl = normalizeTeamServerUrl(raw.serverUrl);
54
+ if (serverUrl && storedServerUrl !== normalizeTeamServerUrl(serverUrl))
55
+ return null;
56
+ return {
57
+ serverUrl: storedServerUrl,
58
+ deviceToken: raw.deviceToken,
59
+ ...(raw.deviceLabel ? { deviceLabel: raw.deviceLabel } : {}),
60
+ updatedAt: Number(raw.updatedAt) || 0,
61
+ };
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ export async function saveTeamCredentials(value) {
68
+ const path = authPath();
69
+ await mkdir(dirname(path), { recursive: true });
70
+ const temporary = `${path}.${process.pid}.tmp`;
71
+ await writeFile(temporary, `${JSON.stringify({ ...value, serverUrl: normalizeTeamServerUrl(value.serverUrl) }, null, 2)}\n`, { mode: 0o600 });
72
+ await chmod(temporary, 0o600).catch(() => { });
73
+ await rename(temporary, path);
74
+ await chmod(path, 0o600).catch(() => { });
75
+ }
76
+ export async function clearTeamCredentials() {
77
+ const path = authPath();
78
+ await writeFile(path, '{}\n', { mode: 0o600 }).catch(() => { });
79
+ }
80
+ /**
81
+ * Revoke exactly the credentials supplied by the caller, then clear the local
82
+ * copy. A null value is deliberately local-only: silently discovering an old
83
+ * team-auth.json here could make standalone logout contact a historical
84
+ * server. Callers that want remote revocation must first load credentials
85
+ * against the currently configured server.
86
+ */
87
+ export async function revokeTeamCredentials(credentials) {
88
+ if (credentials?.serverUrl && credentials.deviceToken) {
89
+ await fetch(`${credentials.serverUrl}/api/auth/device/logout`, {
90
+ method: 'POST',
91
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
92
+ }).catch(() => { });
93
+ }
94
+ await clearTeamCredentials();
95
+ }
96
+ export async function fetchOnlineModels(credentials) {
97
+ const response = await fetch(`${credentials.serverUrl}/api/models`, {
98
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
99
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
100
+ });
101
+ const body = (await response.json().catch(() => ({})));
102
+ if (!response.ok) {
103
+ const code = body.code ??
104
+ (response.status === 401
105
+ ? 'DEVICE_REVOKED'
106
+ : response.status === 403
107
+ ? 'MODEL_UNAVAILABLE'
108
+ : `HTTP_${response.status}`);
109
+ throw new Error(`[${code}] ${body.error ?? `读取在线模型失败(${response.status})`}`);
110
+ }
111
+ return (body.models ?? []).filter((model) => typeof model.id === 'string');
112
+ }
113
+ export async function fetchTeamSubscription(credentials) {
114
+ const response = await fetch(`${credentials.serverUrl}/api/account/subscription`, {
115
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
116
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
117
+ });
118
+ const body = (await response.json().catch(() => ({})));
119
+ if (!response.ok)
120
+ throw new Error(body.error ?? `读取订阅失败(${response.status})`);
121
+ return body.subscription ?? null;
122
+ }
123
+ export async function fetchTeamUsage(credentials) {
124
+ const response = await fetch(`${credentials.serverUrl}/api/account/usage`, {
125
+ headers: { authorization: `Bearer ${credentials.deviceToken}` },
126
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
127
+ });
128
+ const body = (await response.json().catch(() => ({})));
129
+ if (!response.ok)
130
+ throw new Error(body.error ?? `读取用量失败(${response.status})`);
131
+ return body.usage ?? [];
132
+ }
133
+ export async function resolveOnlineModel(modelId, expectedServerUrl) {
134
+ const credentials = await loadTeamCredentials(expectedServerUrl);
135
+ if (!credentials)
136
+ return null;
137
+ const models = await fetchOnlineModels(credentials);
138
+ const model = models.find((item) => item.id === modelId);
139
+ return model ? { credentials, model } : null;
140
+ }
141
+ export async function beginTeamLogin(serverUrl, deviceLabel = 'minimal-agent') {
142
+ const normalized = normalizeTeamServerUrl(serverUrl);
143
+ const start = await fetch(`${normalized}/api/auth/device/start`, {
144
+ method: 'POST',
145
+ headers: { 'content-type': 'application/json' },
146
+ body: JSON.stringify({ clientLabel: deviceLabel }),
147
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
148
+ });
149
+ const authorization = (await start.json().catch(() => ({})));
150
+ if (!start.ok ||
151
+ !authorization.requestId ||
152
+ !authorization.deviceCode ||
153
+ !authorization.authorizeUrl)
154
+ throw new Error(authorization.error ?? '无法发起团队登录');
155
+ return {
156
+ authorizeUrl: authorization.authorizeUrl,
157
+ complete: async () => {
158
+ const deadline = Date.now() + 10 * 60_000;
159
+ while (Date.now() < deadline) {
160
+ const poll = await fetch(`${normalized}/api/auth/device/poll?requestId=${encodeURIComponent(authorization.requestId)}`, {
161
+ headers: {
162
+ 'x-kakadeai-device-code': authorization.deviceCode,
163
+ },
164
+ signal: AbortSignal.timeout(TEAM_REQUEST_TIMEOUT_MS),
165
+ });
166
+ const result = (await poll.json().catch(() => ({})));
167
+ if (result.state === 'approved' && result.deviceToken) {
168
+ const credentials = {
169
+ serverUrl: normalized,
170
+ deviceToken: result.deviceToken,
171
+ deviceLabel,
172
+ updatedAt: Date.now(),
173
+ };
174
+ await saveTeamCredentials(credentials);
175
+ return credentials;
176
+ }
177
+ if (result.state === 'expired')
178
+ throw new Error('浏览器授权已过期,请重新登录');
179
+ if (!poll.ok && result.error)
180
+ throw new Error(result.error);
181
+ await new Promise((resolve) => setTimeout(resolve, 1500));
182
+ }
183
+ throw new Error('等待浏览器授权超时');
184
+ },
185
+ };
186
+ }