minimal-agent 0.13.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 (470) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  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 +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  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 +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  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 +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  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 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  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 +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  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/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +503 -0
  103. package/src/advisor/advisorCoordinator.ts +657 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/streamJson.js +5 -6
  108. package/src/cli/streamJson.ts +8 -4
  109. package/src/cli/wizards/advisorWizard.js +4 -2
  110. package/src/cli/wizards/advisorWizard.tsx +8 -2
  111. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  112. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  113. package/src/collaboration/taskFlow.js +115 -0
  114. package/src/collaboration/taskFlow.ts +169 -0
  115. package/src/config/configDefaults.js +41 -1
  116. package/src/config/configDefaults.ts +43 -1
  117. package/src/config/configDiagnostics.ts +2 -2
  118. package/src/config/configFile.js +40 -9
  119. package/src/config/configFile.ts +60 -11
  120. package/src/config/configService.js +419 -74
  121. package/src/config/configService.ts +703 -145
  122. package/src/config/numericLimits.js +22 -0
  123. package/src/config/numericLimits.ts +24 -0
  124. package/src/config.js +1 -0
  125. package/src/config.ts +3 -2
  126. package/src/context/budgetPlan.js +1 -1
  127. package/src/context/budgetPlan.ts +1 -1
  128. package/src/context/compact.js +7 -2
  129. package/src/context/compact.ts +9 -2
  130. package/src/context/microCompactLite.js +212 -13
  131. package/src/context/microCompactLite.ts +261 -12
  132. package/src/context/sessionRegistry.js +8 -1
  133. package/src/context/sessionRegistry.ts +18 -5
  134. package/src/context/toolResultArchive.js +72 -0
  135. package/src/context/toolResultArchive.ts +95 -0
  136. package/src/goal/errors.js +8 -0
  137. package/src/goal/errors.ts +18 -0
  138. package/src/goal/goalRuntime.js +344 -0
  139. package/src/goal/goalRuntime.ts +466 -0
  140. package/src/goal/goalStore.js +200 -0
  141. package/src/goal/goalStore.ts +219 -0
  142. package/src/goal/index.js +4 -0
  143. package/src/goal/index.ts +4 -0
  144. package/src/goal/statusMapping.js +71 -0
  145. package/src/goal/statusMapping.ts +95 -0
  146. package/src/goal/types.js +7 -0
  147. package/src/goal/types.ts +179 -0
  148. package/src/goal/workflowController.js +306 -0
  149. package/src/goal/workflowController.ts +360 -0
  150. package/src/harness/evidenceLedger.js +2 -0
  151. package/src/harness/evidenceLedger.ts +1 -0
  152. package/src/harness/stallGuard.js +9 -3
  153. package/src/harness/stallGuard.ts +7 -3
  154. package/src/images/imageResolver.js +161 -0
  155. package/src/images/imageResolver.ts +189 -0
  156. package/src/infra/verification.js +34 -5
  157. package/src/infra/verification.ts +39 -4
  158. package/src/llm/client.js +79 -21
  159. package/src/llm/client.ts +182 -35
  160. package/src/llm/gatewayClient.js +201 -0
  161. package/src/llm/gatewayClient.ts +299 -0
  162. package/src/llm/messageProvenance.js +46 -0
  163. package/src/llm/messageProvenance.ts +58 -0
  164. package/src/llm/modelProvider.js +1 -0
  165. package/src/llm/modelProvider.ts +22 -0
  166. package/src/llm/providers/anthropicFormat.js +108 -1
  167. package/src/llm/providers/anthropicFormat.ts +115 -4
  168. package/src/llm/providers/openaiFormat.js +9 -0
  169. package/src/llm/providers/openaiFormat.ts +12 -3
  170. package/src/loop.js +319 -54
  171. package/src/loop.ts +373 -57
  172. package/src/main.js +4 -1
  173. package/src/main.tsx +4 -1
  174. package/src/managedExecution/index.js +2 -0
  175. package/src/managedExecution/index.ts +2 -0
  176. package/src/managedExecution/registry.js +15 -0
  177. package/src/managedExecution/registry.ts +20 -0
  178. package/src/managedExecution/types.js +1 -0
  179. package/src/managedExecution/types.ts +86 -0
  180. package/src/modelRef.js +9 -0
  181. package/src/modelRef.ts +31 -0
  182. package/src/multimodal.js +14 -28
  183. package/src/multimodal.ts +17 -33
  184. package/src/net/lanDiscovery.js +65 -0
  185. package/src/net/lanDiscovery.ts +82 -0
  186. package/src/plugin-sdk.js +28 -3
  187. package/src/plugin-sdk.ts +39 -6
  188. package/src/plugins/pluginApi.ts +16 -1
  189. package/src/plugins/pluginLoader.js +4 -0
  190. package/src/plugins/pluginLoader.ts +6 -0
  191. package/src/plugins/pluginRunner.js +139 -7
  192. package/src/plugins/pluginRunner.ts +173 -9
  193. package/src/plugins/slashFallback.js +113 -0
  194. package/src/plugins/slashFallback.ts +137 -0
  195. package/src/prompts/policyRegistry.js +12 -32
  196. package/src/prompts/policyRegistry.ts +15 -32
  197. package/src/prompts/promptAssembly.js +103 -12
  198. package/src/prompts/promptAssembly.ts +114 -12
  199. package/src/prompts/skillList.js +21 -3
  200. package/src/prompts/skillList.ts +27 -2
  201. package/src/prompts/stableSystemPrompt.js +18 -0
  202. package/src/prompts/stableSystemPrompt.ts +33 -0
  203. package/src/runtime/agentRuntimeContext.js +8 -2
  204. package/src/runtime/agentRuntimeContext.ts +17 -4
  205. package/src/session/runAgentTurn.js +78 -12
  206. package/src/session/runAgentTurn.ts +105 -23
  207. package/src/session/runTurn.js +10 -9
  208. package/src/session/runTurn.ts +17 -8
  209. package/src/session/sessionState.ts +2 -0
  210. package/src/team/auth.js +186 -0
  211. package/src/team/auth.ts +298 -0
  212. package/src/team/cli.js +105 -0
  213. package/src/team/cli.ts +122 -0
  214. package/src/team/onlineToolContract.js +64 -0
  215. package/src/team/onlineToolContract.ts +109 -0
  216. package/src/team/toolPolicy.js +36 -0
  217. package/src/team/toolPolicy.ts +75 -0
  218. package/src/tools/advisor/advisor.js +90 -46
  219. package/src/tools/advisor/advisor.ts +100 -47
  220. package/src/tools/advisor/advisorDecision.js +71 -0
  221. package/src/tools/advisor/advisorDecision.ts +85 -0
  222. package/src/tools/agent/agent.js +18 -5
  223. package/src/tools/agent/agent.ts +21 -7
  224. package/src/tools/agent/agentControl.js +246 -0
  225. package/src/tools/agent/agentControl.ts +284 -0
  226. package/src/tools/agent/agentTaskService.js +40 -1
  227. package/src/tools/agent/agentTaskService.ts +44 -1
  228. package/src/tools/agent/agentTypes.js +14 -2
  229. package/src/tools/agent/agentTypes.ts +15 -2
  230. package/src/tools/applypatch/applyPatch.js +362 -0
  231. package/src/tools/applypatch/applyPatch.ts +428 -0
  232. package/src/tools/bash/bash.js +22 -15
  233. package/src/tools/bash/bash.ts +23 -17
  234. package/src/tools/capabilities.js +10 -5
  235. package/src/tools/capabilities.ts +10 -5
  236. package/src/tools/computeruse/computerIntent.js +32 -0
  237. package/src/tools/computeruse/computerIntent.ts +46 -0
  238. package/src/tools/computeruse/telemetryLog.js +12 -0
  239. package/src/tools/computeruse/telemetryLog.ts +16 -0
  240. package/src/tools/computeruse/vision/telemetry.js +1 -0
  241. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  242. package/src/tools/effectiveToolSet.js +4 -0
  243. package/src/tools/effectiveToolSet.ts +4 -0
  244. package/src/tools/index.js +21 -2
  245. package/src/tools/index.ts +33 -2
  246. package/src/tools/presentresult/presentresult.js +6 -15
  247. package/src/tools/presentresult/presentresult.ts +6 -15
  248. package/src/tools/read/read.js +62 -9
  249. package/src/tools/read/read.ts +63 -9
  250. package/src/tools/shared/fileUtils.js +1 -2
  251. package/src/tools/shared/fileUtils.ts +1 -2
  252. package/src/tools/shared/toolOutputStore.js +23 -1
  253. package/src/tools/shared/toolOutputStore.ts +22 -1
  254. package/src/tools/skill/skill.js +9 -3
  255. package/src/tools/skill/skill.ts +8 -4
  256. package/src/tools/toolPromptGuides.js +117 -0
  257. package/src/tools/toolPromptGuides.ts +137 -0
  258. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  259. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  260. package/src/tools/webbrowser/browser.js +27 -11
  261. package/src/tools/webbrowser/browser.ts +68 -24
  262. package/src/tools/webbrowser/browserAutomation.js +329 -0
  263. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  264. package/src/tools/webbrowser/browserAxState.js +97 -0
  265. package/src/tools/webbrowser/browserAxState.ts +142 -0
  266. package/src/tools/webbrowser/browserBatch.js +1578 -0
  267. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  268. package/src/tools/webbrowser/browserCdp.js +208 -0
  269. package/src/tools/webbrowser/browserCdp.ts +255 -0
  270. package/src/tools/webbrowser/browserConditions.js +24 -0
  271. package/src/tools/webbrowser/browserConditions.ts +45 -0
  272. package/src/tools/webbrowser/browserContent.js +281 -0
  273. package/src/tools/webbrowser/browserContent.ts +438 -0
  274. package/src/tools/webbrowser/browserControl.js +131 -34
  275. package/src/tools/webbrowser/browserControl.ts +210 -56
  276. package/src/tools/webbrowser/browserDaemon.js +22 -14
  277. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  278. package/src/tools/webbrowser/browserFrames.js +47 -0
  279. package/src/tools/webbrowser/browserFrames.ts +54 -0
  280. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  281. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  282. package/src/tools/webbrowser/browserLocator.js +140 -0
  283. package/src/tools/webbrowser/browserLocator.ts +194 -0
  284. package/src/tools/webbrowser/browserOutcome.js +10 -17
  285. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  286. package/src/tools/webbrowser/browserRecovery.js +58 -0
  287. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  288. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  289. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  290. package/src/tools/webbrowser/browserService.js +28 -2
  291. package/src/tools/webbrowser/browserService.ts +49 -9
  292. package/src/tools/webbrowser/browserStream.js +132 -33
  293. package/src/tools/webbrowser/browserStream.ts +224 -50
  294. package/src/tools/webbrowser/browserTabs.js +48 -15
  295. package/src/tools/webbrowser/browserTabs.ts +178 -96
  296. package/src/tools/webbrowser/webbrowser.js +679 -144
  297. package/src/tools/webbrowser/webbrowser.ts +975 -236
  298. package/src/tools/webfetch/preapproved.js +0 -2
  299. package/src/tools/webfetch/preapproved.ts +0 -2
  300. package/src/tools/websearch/websearch.js +129 -8
  301. package/src/tools/websearch/websearch.ts +138 -6
  302. package/src/types.ts +440 -38
  303. package/src/ui/App.js +377 -58
  304. package/src/ui/App.tsx +576 -111
  305. package/src/ui/LiveArea.js +14 -8
  306. package/src/ui/LiveArea.tsx +14 -10
  307. package/src/ui/MessageList.js +63 -20
  308. package/src/ui/MessageList.tsx +101 -16
  309. package/src/ui/ModelPicker.js +7 -4
  310. package/src/ui/ModelPicker.tsx +55 -8
  311. package/src/ui/hooks/useChat.js +152 -163
  312. package/src/ui/hooks/useChat.ts +396 -334
  313. package/src/ui/loginCommand.js +56 -0
  314. package/src/ui/loginCommand.ts +63 -0
  315. package/src/ui/toolProgress.js +41 -0
  316. package/src/ui/toolProgress.ts +44 -0
  317. package/src/web/browserBridge.js +20 -2
  318. package/src/web/browserBridge.ts +20 -2
  319. package/src/web/protocol.ts +1897 -194
  320. package/workflows/adaptive-research/workflow.mjs +86 -0
  321. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  322. package/workflows/e2e-llm/workflow.mjs +52 -0
  323. package/workflows/e2e-smoke/workflow.mjs +59 -0
  324. package/workflows/e2e-vision-schema/README.md +48 -0
  325. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  326. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  327. package/workflows/file-census/README.md +14 -0
  328. package/workflows/file-census/scripts/.gitkeep +2 -0
  329. package/workflows/file-census/workflow.mjs +110 -0
  330. package/workflows/goal/README.md +166 -0
  331. package/workflows/goal/prompts/audit.md +57 -0
  332. package/workflows/goal/prompts/contract.md +56 -0
  333. package/workflows/goal/prompts/iterate.md +37 -0
  334. package/workflows/goal/workflow.mjs +501 -0
  335. package/workflows/illustrate/README.md +90 -0
  336. package/workflows/illustrate/assets/engines.json +20 -0
  337. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  338. package/workflows/illustrate/assets/extract-bing.js +33 -0
  339. package/workflows/illustrate/assets/extract-google.js +31 -0
  340. package/workflows/illustrate/workflow.mjs +301 -0
  341. package/workflows/plan/workflow.mjs +389 -0
  342. package/workflows/question-crops/README.md +35 -0
  343. package/workflows/question-crops/prompts/inventory.md +23 -0
  344. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  345. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  346. package/workflows/question-crops/workflow.mjs +172 -0
  347. package/workflows/ralph-loop/workflow.mjs +162 -0
  348. package/workflows/research/README.md +74 -0
  349. package/workflows/research/prompts/s0-goal.md +43 -0
  350. package/workflows/research/prompts/s1-early-exit.md +22 -0
  351. package/workflows/research/prompts/s1-map.md +58 -0
  352. package/workflows/research/prompts/s2-options.md +53 -0
  353. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  354. package/workflows/research/prompts/s4-verify.md +74 -0
  355. package/workflows/research/prompts/s5-synthesis.md +81 -0
  356. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  357. package/workflows/research/prompts/s6-package.md +32 -0
  358. package/workflows/research/scripts/build-report.mjs +98 -0
  359. package/workflows/research/workflow.mjs +288 -0
  360. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  361. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  362. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  363. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  364. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  365. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  366. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  367. package/workflows/wrong-question-docx/README.md +55 -0
  368. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  369. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  370. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  371. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  372. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  373. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  374. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  375. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  376. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  377. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  378. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  379. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  380. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  381. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  382. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  383. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  384. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  385. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  386. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  387. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  388. package/plugins/workflow-runner/src/expressions.js +0 -639
  389. package/plugins/workflow-runner/src/expressions.ts +0 -640
  390. package/plugins/workflow-runner/src/loader.js +0 -573
  391. package/plugins/workflow-runner/src/loader.ts +0 -721
  392. package/plugins/workflow-runner/src/multimodal.js +0 -38
  393. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  394. package/plugins/workflow-runner/src/recovery.js +0 -126
  395. package/plugins/workflow-runner/src/recovery.ts +0 -156
  396. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  397. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  398. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  399. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  400. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  401. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  402. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  403. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  404. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  405. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  406. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  407. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  408. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  409. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  410. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  411. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  412. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  413. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  414. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  415. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  416. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  417. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  418. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  419. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  420. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  421. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  422. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  423. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  424. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  425. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  426. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  427. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  428. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  429. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  430. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  431. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  432. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  433. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  434. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  435. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  436. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  437. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  438. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  439. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  440. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  441. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  442. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  443. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  444. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  445. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  446. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  447. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  448. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  449. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  450. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  451. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  452. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  453. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  454. package/src/advisorState.js +0 -22
  455. package/src/cli/configWizard.js +0 -293
  456. package/src/tools/toolProgressBridge.js +0 -48
  457. package/workflows/adaptive-research.yaml +0 -50
  458. package/workflows/book-review-short.yaml +0 -125
  459. package/workflows/e2e-write-greet.yaml +0 -31
  460. package/workflows/illustrate.yaml +0 -227
  461. package/workflows/plan.yaml +0 -470
  462. package/workflows/ppt.yaml +0 -1670
  463. package/workflows/ralph-loop.yaml +0 -201
  464. package/workflows/research.yaml +0 -873
  465. package/workflows/schema.json +0 -176
  466. package/workflows/webppt.yaml +0 -496
  467. package/workflows/wechat-reading-shots.yaml +0 -315
  468. package/workflows/word.yaml +0 -720
  469. package/workflows/youtube-shorts.yaml +0 -202
  470. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -0,0 +1,208 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { toToolParameters } from '../../utils/zodToJson.js';
4
+ import { resolveAgentBrowserPath } from './agentBrowserPath.js';
5
+ import { BROWSER_SESSION, sessionArgs, spawnRunner } from './browser.js';
6
+ import { BROWSER_TAB_MARKER_KEY, getBrowserAutomation, } from './browserAutomation.js';
7
+ import { ensureDaemon } from './browserDaemon.js';
8
+ import { withBrowserRecovery } from './browserRecovery.js';
9
+ import { browserRunRegistry } from './browserRunRegistry.js';
10
+ import { browserService } from './browserService.js';
11
+ import { ensureConversationTab } from './browserTabs.js';
12
+ const inputSchema = z.object({
13
+ operation: z.enum(['send', 'read_events']),
14
+ method: z.string().optional(),
15
+ params: z.record(z.unknown()).optional(),
16
+ target: z
17
+ .string()
18
+ .optional()
19
+ .describe('Optional CDP session id for the currently claimed page target'),
20
+ after_sequence: z.number().int().nonnegative().optional(),
21
+ methods: z.array(z.string()).optional(),
22
+ limit: z.number().int().min(1).max(500).optional(),
23
+ timeout_ms: z.number().int().min(100).max(120_000).optional(),
24
+ });
25
+ const SAFE_BROWSER_CDP_METHODS = new Set([
26
+ 'Browser.getVersion',
27
+ 'Target.getTargets',
28
+ 'Target.getTargetInfo',
29
+ ]);
30
+ export function validateBrowserCdpMethod(method, params, pageTargetId) {
31
+ const domain = method.split('.', 1)[0];
32
+ const pageScoped = /^(Accessibility|DOM|Input|Log|Network|Page|Performance|Runtime|Security)\./.test(method);
33
+ if (!pageScoped && !SAFE_BROWSER_CDP_METHODS.has(method))
34
+ throw new Error(`BrowserCDP 不允许调用未授权的 CDP 方法:${method}`);
35
+ const targetId = params?.targetId;
36
+ if (targetId !== undefined && targetId !== pageTargetId)
37
+ throw new Error('BrowserCDP 只能访问当前会话认领的浏览器标签');
38
+ if (domain === 'Target' && targetId !== undefined && !pageTargetId)
39
+ throw new Error('BrowserCDP 缺少当前会话标签归属信息');
40
+ }
41
+ async function call(input, signal, _ctx = {}) {
42
+ const ctx = _ctx;
43
+ if (ctx.browserRun?.supervised !== true)
44
+ return {
45
+ ok: false,
46
+ error: 'BrowserCDP 仅可在 Desktop 的受监督浏览器会话中使用',
47
+ };
48
+ const conversationKey = ctx.browserRun.conversationKey ?? `headless:${process.pid}`;
49
+ const runId = ctx.browserRun.runId ?? ctx.toolCallId ?? randomUUID();
50
+ const run = browserRunRegistry.ensure({
51
+ conversationKey,
52
+ runId,
53
+ grants: ctx.browserRun.grants,
54
+ });
55
+ let cdp;
56
+ try {
57
+ try {
58
+ browserRunRegistry.requireGrant(run, 'interact');
59
+ }
60
+ catch (error) {
61
+ return {
62
+ ok: false,
63
+ error: error instanceof Error ? error.message : String(error),
64
+ };
65
+ }
66
+ const bin = await resolveAgentBrowserPath();
67
+ if (!bin)
68
+ return { ok: false, error: '内置浏览器不可用:未找到 agent-browser' };
69
+ let claimedTabId = run.activeTabId;
70
+ const tabMarker = `${conversationKey}:${run.runId}:${randomUUID()}`;
71
+ if (!claimedTabId) {
72
+ claimedTabId = await ensureConversationTab({
73
+ context: run,
74
+ sessionName: BROWSER_SESSION,
75
+ bin,
76
+ globals: sessionArgs(BROWSER_SESSION),
77
+ runner: spawnRunner,
78
+ signal,
79
+ });
80
+ }
81
+ else {
82
+ browserRunRegistry.assertTab(run, claimedTabId);
83
+ }
84
+ const serviceInput = {
85
+ sessionName: BROWSER_SESSION,
86
+ bin,
87
+ runner: spawnRunner,
88
+ signal,
89
+ };
90
+ let preferredUrl;
91
+ cdp = await browserService.exclusive(serviceInput, async (runCommand) => {
92
+ const switched = await runCommand([
93
+ ...sessionArgs(BROWSER_SESSION),
94
+ 'tab',
95
+ claimedTabId,
96
+ ]);
97
+ if (switched.code !== 0)
98
+ throw new Error(switched.stderr || '无法切换到本会话认领的浏览器标签');
99
+ const marked = await runCommand([
100
+ ...sessionArgs(BROWSER_SESSION),
101
+ 'eval',
102
+ `globalThis[${JSON.stringify(BROWSER_TAB_MARKER_KEY)}]=${JSON.stringify(tabMarker)}`,
103
+ ]);
104
+ if (marked.code !== 0)
105
+ throw new Error(marked.stderr || '无法标记当前浏览器会话标签');
106
+ const currentPage = await runCommand([
107
+ ...sessionArgs(BROWSER_SESSION),
108
+ 'get',
109
+ 'url',
110
+ ]);
111
+ preferredUrl =
112
+ currentPage.code === 0 ? currentPage.stdout.trim() : undefined;
113
+ return getBrowserAutomation(BROWSER_SESSION, bin, spawnRunner, signal, preferredUrl, tabMarker);
114
+ });
115
+ if (!cdp)
116
+ throw new Error('BrowserCDP 未能建立页面连接');
117
+ const currentCdp = () => {
118
+ if (!cdp)
119
+ throw new Error('BrowserCDP 页面连接不可用');
120
+ return cdp;
121
+ };
122
+ const runOperation = () => browserService.exclusive(serviceInput, async (runCommand) => {
123
+ const pageCdp = currentCdp();
124
+ const switched = await runCommand([
125
+ ...sessionArgs(BROWSER_SESSION),
126
+ 'tab',
127
+ claimedTabId,
128
+ ]);
129
+ if (switched.code !== 0)
130
+ throw new Error(switched.stderr || '当前浏览器标签已失效');
131
+ if (input.operation === 'read_events') {
132
+ const events = pageCdp.read(input.after_sequence, input.methods, input.limit);
133
+ return {
134
+ events,
135
+ next_sequence: events.at(-1)?.sequence ?? input.after_sequence ?? 0,
136
+ };
137
+ }
138
+ if (!input.method)
139
+ throw new Error('send requires method');
140
+ validateBrowserCdpMethod(input.method, input.params, pageCdp.attachedPageTargetId);
141
+ if (input.target && input.target !== pageCdp.attachedPageSessionId) {
142
+ throw new Error('BrowserCDP 只能操作当前会话认领页面;跨页面 target 已拒绝');
143
+ }
144
+ return pageCdp.send(input.method, input.params, input.target, input.timeout_ms ?? 30_000, signal);
145
+ });
146
+ const result = await withBrowserRecovery(runOperation, {
147
+ signal,
148
+ reconnect: async () => {
149
+ await ensureDaemon(BROWSER_SESSION, {
150
+ signal,
151
+ forceRestart: true,
152
+ });
153
+ },
154
+ rebindTab: async () => {
155
+ await browserService.exclusive(serviceInput, async (runCommand) => {
156
+ const switched = await runCommand([
157
+ ...sessionArgs(BROWSER_SESSION),
158
+ 'tab',
159
+ claimedTabId,
160
+ ]);
161
+ if (switched.code !== 0)
162
+ throw new Error('浏览器重启后当前会话标签不可恢复');
163
+ const marked = await runCommand([
164
+ ...sessionArgs(BROWSER_SESSION),
165
+ 'eval',
166
+ `globalThis[${JSON.stringify(BROWSER_TAB_MARKER_KEY)}]=${JSON.stringify(tabMarker)}`,
167
+ ]);
168
+ if (marked.code !== 0)
169
+ throw new Error('浏览器重启后无法标记当前会话标签');
170
+ const currentPage = await runCommand([
171
+ ...sessionArgs(BROWSER_SESSION),
172
+ 'get',
173
+ 'url',
174
+ ]);
175
+ preferredUrl =
176
+ currentPage.code === 0 ? currentPage.stdout.trim() : preferredUrl;
177
+ const previousCdp = currentCdp();
178
+ cdp = await getBrowserAutomation(BROWSER_SESSION, bin, spawnRunner, signal, preferredUrl, tabMarker);
179
+ previousCdp.close();
180
+ });
181
+ },
182
+ });
183
+ return {
184
+ ok: true,
185
+ content: JSON.stringify({ result, tab_id: claimedTabId }),
186
+ };
187
+ }
188
+ catch (error) {
189
+ return {
190
+ ok: false,
191
+ error: error instanceof Error ? error.message : String(error),
192
+ };
193
+ }
194
+ finally {
195
+ cdp?.close();
196
+ browserRunRegistry.finish(conversationKey, runId);
197
+ }
198
+ }
199
+ export const browserCdpTool = {
200
+ name: 'BrowserCDP',
201
+ description: 'Advanced raw CDP access for the visible supervised browser. Use only when BrowserBatch/WebBrowser cannot express the operation.',
202
+ inputSchema,
203
+ parameters: toToolParameters(inputSchema),
204
+ isReadOnly: false,
205
+ isConcurrencySafe: false,
206
+ call,
207
+ callWithContext: call,
208
+ };
@@ -0,0 +1,255 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import type { Tool, ToolCallContext, ToolResult } from '../../types.js';
4
+ import { toToolParameters } from '../../utils/zodToJson.js';
5
+ import { resolveAgentBrowserPath } from './agentBrowserPath.js';
6
+ import { BROWSER_SESSION, sessionArgs, spawnRunner } from './browser.js';
7
+ import {
8
+ BROWSER_TAB_MARKER_KEY,
9
+ getBrowserAutomation,
10
+ } from './browserAutomation.js';
11
+ import { ensureDaemon } from './browserDaemon.js';
12
+ import { withBrowserRecovery } from './browserRecovery.js';
13
+ import { browserRunRegistry } from './browserRunRegistry.js';
14
+ import { browserService } from './browserService.js';
15
+ import { ensureConversationTab } from './browserTabs.js';
16
+
17
+ const inputSchema = z.object({
18
+ operation: z.enum(['send', 'read_events']),
19
+ method: z.string().optional(),
20
+ params: z.record(z.unknown()).optional(),
21
+ target: z
22
+ .string()
23
+ .optional()
24
+ .describe('Optional CDP session id for the currently claimed page target'),
25
+ after_sequence: z.number().int().nonnegative().optional(),
26
+ methods: z.array(z.string()).optional(),
27
+ limit: z.number().int().min(1).max(500).optional(),
28
+ timeout_ms: z.number().int().min(100).max(120_000).optional(),
29
+ });
30
+ type Input = z.infer<typeof inputSchema>;
31
+
32
+ const SAFE_BROWSER_CDP_METHODS = new Set([
33
+ 'Browser.getVersion',
34
+ 'Target.getTargets',
35
+ 'Target.getTargetInfo',
36
+ ]);
37
+
38
+ export function validateBrowserCdpMethod(
39
+ method: string,
40
+ params: Record<string, unknown> | undefined,
41
+ pageTargetId: string | undefined,
42
+ ): void {
43
+ const domain = method.split('.', 1)[0];
44
+ const pageScoped =
45
+ /^(Accessibility|DOM|Input|Log|Network|Page|Performance|Runtime|Security)\./.test(
46
+ method,
47
+ );
48
+ if (!pageScoped && !SAFE_BROWSER_CDP_METHODS.has(method))
49
+ throw new Error(`BrowserCDP 不允许调用未授权的 CDP 方法:${method}`);
50
+ const targetId = params?.targetId;
51
+ if (targetId !== undefined && targetId !== pageTargetId)
52
+ throw new Error('BrowserCDP 只能访问当前会话认领的浏览器标签');
53
+ if (domain === 'Target' && targetId !== undefined && !pageTargetId)
54
+ throw new Error('BrowserCDP 缺少当前会话标签归属信息');
55
+ }
56
+
57
+ async function call(
58
+ input: Input,
59
+ signal?: AbortSignal,
60
+ _ctx: ToolCallContext = {},
61
+ ): Promise<ToolResult> {
62
+ const ctx = _ctx;
63
+ if (ctx.browserRun?.supervised !== true)
64
+ return {
65
+ ok: false,
66
+ error: 'BrowserCDP 仅可在 Desktop 的受监督浏览器会话中使用',
67
+ };
68
+ const conversationKey =
69
+ ctx.browserRun.conversationKey ?? `headless:${process.pid}`;
70
+ const runId = ctx.browserRun.runId ?? ctx.toolCallId ?? randomUUID();
71
+ const run = browserRunRegistry.ensure({
72
+ conversationKey,
73
+ runId,
74
+ grants: ctx.browserRun.grants,
75
+ });
76
+ let cdp: Awaited<ReturnType<typeof getBrowserAutomation>> | undefined;
77
+ try {
78
+ try {
79
+ browserRunRegistry.requireGrant(run, 'interact');
80
+ } catch (error) {
81
+ return {
82
+ ok: false,
83
+ error: error instanceof Error ? error.message : String(error),
84
+ };
85
+ }
86
+ const bin = await resolveAgentBrowserPath();
87
+ if (!bin)
88
+ return { ok: false, error: '内置浏览器不可用:未找到 agent-browser' };
89
+ let claimedTabId = run.activeTabId;
90
+ const tabMarker = `${conversationKey}:${run.runId}:${randomUUID()}`;
91
+ if (!claimedTabId) {
92
+ claimedTabId = await ensureConversationTab({
93
+ context: run,
94
+ sessionName: BROWSER_SESSION,
95
+ bin,
96
+ globals: sessionArgs(BROWSER_SESSION),
97
+ runner: spawnRunner,
98
+ signal,
99
+ });
100
+ } else {
101
+ browserRunRegistry.assertTab(run, claimedTabId);
102
+ }
103
+ const serviceInput = {
104
+ sessionName: BROWSER_SESSION,
105
+ bin,
106
+ runner: spawnRunner,
107
+ signal,
108
+ };
109
+ let preferredUrl: string | undefined;
110
+ cdp = await browserService.exclusive(serviceInput, async (runCommand) => {
111
+ const switched = await runCommand([
112
+ ...sessionArgs(BROWSER_SESSION),
113
+ 'tab',
114
+ claimedTabId!,
115
+ ]);
116
+ if (switched.code !== 0)
117
+ throw new Error(switched.stderr || '无法切换到本会话认领的浏览器标签');
118
+ const marked = await runCommand([
119
+ ...sessionArgs(BROWSER_SESSION),
120
+ 'eval',
121
+ `globalThis[${JSON.stringify(BROWSER_TAB_MARKER_KEY)}]=${JSON.stringify(tabMarker)}`,
122
+ ]);
123
+ if (marked.code !== 0)
124
+ throw new Error(marked.stderr || '无法标记当前浏览器会话标签');
125
+ const currentPage = await runCommand([
126
+ ...sessionArgs(BROWSER_SESSION),
127
+ 'get',
128
+ 'url',
129
+ ]);
130
+ preferredUrl =
131
+ currentPage.code === 0 ? currentPage.stdout.trim() : undefined;
132
+ return getBrowserAutomation(
133
+ BROWSER_SESSION,
134
+ bin,
135
+ spawnRunner,
136
+ signal,
137
+ preferredUrl,
138
+ tabMarker,
139
+ );
140
+ });
141
+ if (!cdp) throw new Error('BrowserCDP 未能建立页面连接');
142
+ const currentCdp = () => {
143
+ if (!cdp) throw new Error('BrowserCDP 页面连接不可用');
144
+ return cdp;
145
+ };
146
+ const runOperation = () =>
147
+ browserService.exclusive(serviceInput, async (runCommand) => {
148
+ const pageCdp = currentCdp();
149
+ const switched = await runCommand([
150
+ ...sessionArgs(BROWSER_SESSION),
151
+ 'tab',
152
+ claimedTabId!,
153
+ ]);
154
+ if (switched.code !== 0)
155
+ throw new Error(switched.stderr || '当前浏览器标签已失效');
156
+ if (input.operation === 'read_events') {
157
+ const events = pageCdp.read(
158
+ input.after_sequence,
159
+ input.methods,
160
+ input.limit,
161
+ );
162
+ return {
163
+ events,
164
+ next_sequence: events.at(-1)?.sequence ?? input.after_sequence ?? 0,
165
+ };
166
+ }
167
+ if (!input.method) throw new Error('send requires method');
168
+ validateBrowserCdpMethod(
169
+ input.method,
170
+ input.params,
171
+ pageCdp.attachedPageTargetId,
172
+ );
173
+ if (input.target && input.target !== pageCdp.attachedPageSessionId) {
174
+ throw new Error(
175
+ 'BrowserCDP 只能操作当前会话认领页面;跨页面 target 已拒绝',
176
+ );
177
+ }
178
+ return pageCdp.send(
179
+ input.method,
180
+ input.params,
181
+ input.target,
182
+ input.timeout_ms ?? 30_000,
183
+ signal,
184
+ );
185
+ });
186
+ const result = await withBrowserRecovery(runOperation, {
187
+ signal,
188
+ reconnect: async () => {
189
+ await ensureDaemon(BROWSER_SESSION, {
190
+ signal,
191
+ forceRestart: true,
192
+ });
193
+ },
194
+ rebindTab: async () => {
195
+ await browserService.exclusive(serviceInput, async (runCommand) => {
196
+ const switched = await runCommand([
197
+ ...sessionArgs(BROWSER_SESSION),
198
+ 'tab',
199
+ claimedTabId!,
200
+ ]);
201
+ if (switched.code !== 0)
202
+ throw new Error('浏览器重启后当前会话标签不可恢复');
203
+ const marked = await runCommand([
204
+ ...sessionArgs(BROWSER_SESSION),
205
+ 'eval',
206
+ `globalThis[${JSON.stringify(BROWSER_TAB_MARKER_KEY)}]=${JSON.stringify(tabMarker)}`,
207
+ ]);
208
+ if (marked.code !== 0)
209
+ throw new Error('浏览器重启后无法标记当前会话标签');
210
+ const currentPage = await runCommand([
211
+ ...sessionArgs(BROWSER_SESSION),
212
+ 'get',
213
+ 'url',
214
+ ]);
215
+ preferredUrl =
216
+ currentPage.code === 0 ? currentPage.stdout.trim() : preferredUrl;
217
+ const previousCdp = currentCdp();
218
+ cdp = await getBrowserAutomation(
219
+ BROWSER_SESSION,
220
+ bin,
221
+ spawnRunner,
222
+ signal,
223
+ preferredUrl,
224
+ tabMarker,
225
+ );
226
+ previousCdp.close();
227
+ });
228
+ },
229
+ });
230
+ return {
231
+ ok: true,
232
+ content: JSON.stringify({ result, tab_id: claimedTabId }),
233
+ };
234
+ } catch (error) {
235
+ return {
236
+ ok: false,
237
+ error: error instanceof Error ? error.message : String(error),
238
+ };
239
+ } finally {
240
+ cdp?.close();
241
+ browserRunRegistry.finish(conversationKey, runId);
242
+ }
243
+ }
244
+
245
+ export const browserCdpTool: Tool<Input> = {
246
+ name: 'BrowserCDP',
247
+ description:
248
+ 'Advanced raw CDP access for the visible supervised browser. Use only when BrowserBatch/WebBrowser cannot express the operation.',
249
+ inputSchema,
250
+ parameters: toToolParameters(inputSchema),
251
+ isReadOnly: false,
252
+ isConcurrencySafe: false,
253
+ call,
254
+ callWithContext: call,
255
+ };
@@ -0,0 +1,24 @@
1
+ export function conditionToScript(condition, targetExpression) {
2
+ switch (condition.type) {
3
+ case 'url':
4
+ return `(() => { const u = location.href; const p = ${JSON.stringify(condition.pattern)}; const parts = p.split('*'); if (parts.length === 1) return u === p; let at = 0; for (const [i, part] of parts.entries()) { if (!part) continue; const next = u.indexOf(part, at); if (next < 0 || (i === 0 && next !== 0) || (i === parts.length - 1 && next + part.length !== u.length)) return false; at = next + part.length; } return true; })()`;
5
+ case 'text':
6
+ return `(() => { const text = document.body?.innerText || ''; const expected = ${JSON.stringify(condition.value)}; return ${condition.exact === true ? 'text.trim()===expected' : 'text.includes(expected)'}; })()`;
7
+ case 'element-visible':
8
+ return `(() => { try { ${targetExpression(condition.locator, condition.selector)}; return true; } catch { return false; } })()`;
9
+ case 'element-hidden':
10
+ return `(() => { try { const e = ${targetExpression(condition.locator, condition.selector)}; return !e; } catch { return true; } })()`;
11
+ case 'load-state':
12
+ return condition.state === 'domcontentloaded'
13
+ ? `document.readyState !== 'loading'`
14
+ : condition.state === 'load'
15
+ ? `document.readyState === 'complete'`
16
+ : `document.readyState === 'complete' && performance.getEntriesByType('resource').every((entry) => (performance.now() - entry.startTime) > 250)`;
17
+ case 'download':
18
+ case 'new-tab':
19
+ case 'dialog':
20
+ throw new Error(`${condition.type} is an event condition and must be armed before the action`);
21
+ case 'page-change':
22
+ return `location.href + '|' + (document.body?.innerText || '').slice(0, 4000)`;
23
+ }
24
+ }
@@ -0,0 +1,45 @@
1
+ import type { BrowserLocator } from './browserLocator.js';
2
+
3
+ export type BrowserCondition =
4
+ | { type: 'url'; pattern: string }
5
+ | { type: 'text'; value: string; exact?: boolean }
6
+ | { type: 'element-visible'; locator?: BrowserLocator; selector?: string }
7
+ | { type: 'element-hidden'; locator?: BrowserLocator; selector?: string }
8
+ | { type: 'load-state'; state: 'domcontentloaded' | 'load' | 'networkidle' }
9
+ | { type: 'download'; filename?: string }
10
+ | { type: 'new-tab'; url?: string }
11
+ | {
12
+ type: 'dialog';
13
+ dialogType?: 'alert' | 'confirm' | 'prompt' | 'beforeunload';
14
+ }
15
+ | { type: 'page-change' };
16
+
17
+ export function conditionToScript(
18
+ condition: BrowserCondition,
19
+ targetExpression: (locator?: BrowserLocator, selector?: string) => string,
20
+ ): string {
21
+ switch (condition.type) {
22
+ case 'url':
23
+ return `(() => { const u = location.href; const p = ${JSON.stringify(condition.pattern)}; const parts = p.split('*'); if (parts.length === 1) return u === p; let at = 0; for (const [i, part] of parts.entries()) { if (!part) continue; const next = u.indexOf(part, at); if (next < 0 || (i === 0 && next !== 0) || (i === parts.length - 1 && next + part.length !== u.length)) return false; at = next + part.length; } return true; })()`;
24
+ case 'text':
25
+ return `(() => { const text = document.body?.innerText || ''; const expected = ${JSON.stringify(condition.value)}; return ${condition.exact === true ? 'text.trim()===expected' : 'text.includes(expected)'}; })()`;
26
+ case 'element-visible':
27
+ return `(() => { try { ${targetExpression(condition.locator, condition.selector)}; return true; } catch { return false; } })()`;
28
+ case 'element-hidden':
29
+ return `(() => { try { const e = ${targetExpression(condition.locator, condition.selector)}; return !e; } catch { return true; } })()`;
30
+ case 'load-state':
31
+ return condition.state === 'domcontentloaded'
32
+ ? `document.readyState !== 'loading'`
33
+ : condition.state === 'load'
34
+ ? `document.readyState === 'complete'`
35
+ : `document.readyState === 'complete' && performance.getEntriesByType('resource').every((entry) => (performance.now() - entry.startTime) > 250)`;
36
+ case 'download':
37
+ case 'new-tab':
38
+ case 'dialog':
39
+ throw new Error(
40
+ `${condition.type} is an event condition and must be armed before the action`,
41
+ );
42
+ case 'page-change':
43
+ return `location.href + '|' + (document.body?.innerText || '').slice(0, 4000)`;
44
+ }
45
+ }