minimal-agent 0.13.0 → 0.15.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 (474) 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 +536 -0
  103. package/src/advisor/advisorCoordinator.ts +693 -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/quickModelSetup.js +12 -1
  108. package/src/cli/quickModelSetup.tsx +15 -3
  109. package/src/cli/streamJson.js +5 -6
  110. package/src/cli/streamJson.ts +8 -4
  111. package/src/cli/wizards/advisorWizard.js +4 -2
  112. package/src/cli/wizards/advisorWizard.tsx +8 -2
  113. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  114. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  115. package/src/cli/wizards/providerPresets.js +18 -8
  116. package/src/cli/wizards/providerPresets.ts +18 -8
  117. package/src/collaboration/taskFlow.js +115 -0
  118. package/src/collaboration/taskFlow.ts +169 -0
  119. package/src/config/configDefaults.js +41 -1
  120. package/src/config/configDefaults.ts +43 -1
  121. package/src/config/configDiagnostics.ts +2 -2
  122. package/src/config/configFile.js +40 -9
  123. package/src/config/configFile.ts +60 -11
  124. package/src/config/configService.js +419 -74
  125. package/src/config/configService.ts +703 -145
  126. package/src/config/numericLimits.js +22 -0
  127. package/src/config/numericLimits.ts +24 -0
  128. package/src/config.js +1 -0
  129. package/src/config.ts +3 -2
  130. package/src/context/budgetPlan.js +1 -1
  131. package/src/context/budgetPlan.ts +1 -1
  132. package/src/context/compact.js +7 -2
  133. package/src/context/compact.ts +9 -2
  134. package/src/context/microCompactLite.js +212 -13
  135. package/src/context/microCompactLite.ts +261 -12
  136. package/src/context/sessionRegistry.js +8 -1
  137. package/src/context/sessionRegistry.ts +18 -5
  138. package/src/context/toolResultArchive.js +72 -0
  139. package/src/context/toolResultArchive.ts +95 -0
  140. package/src/goal/errors.js +8 -0
  141. package/src/goal/errors.ts +18 -0
  142. package/src/goal/goalRuntime.js +344 -0
  143. package/src/goal/goalRuntime.ts +466 -0
  144. package/src/goal/goalStore.js +200 -0
  145. package/src/goal/goalStore.ts +219 -0
  146. package/src/goal/index.js +4 -0
  147. package/src/goal/index.ts +4 -0
  148. package/src/goal/statusMapping.js +71 -0
  149. package/src/goal/statusMapping.ts +95 -0
  150. package/src/goal/types.js +7 -0
  151. package/src/goal/types.ts +179 -0
  152. package/src/goal/workflowController.js +306 -0
  153. package/src/goal/workflowController.ts +360 -0
  154. package/src/harness/evidenceLedger.js +2 -0
  155. package/src/harness/evidenceLedger.ts +1 -0
  156. package/src/harness/stallGuard.js +9 -3
  157. package/src/harness/stallGuard.ts +7 -3
  158. package/src/images/imageResolver.js +161 -0
  159. package/src/images/imageResolver.ts +189 -0
  160. package/src/infra/verification.js +34 -5
  161. package/src/infra/verification.ts +39 -4
  162. package/src/llm/client.js +79 -21
  163. package/src/llm/client.ts +182 -35
  164. package/src/llm/gatewayClient.js +201 -0
  165. package/src/llm/gatewayClient.ts +299 -0
  166. package/src/llm/messageProvenance.js +46 -0
  167. package/src/llm/messageProvenance.ts +58 -0
  168. package/src/llm/modelProvider.js +1 -0
  169. package/src/llm/modelProvider.ts +22 -0
  170. package/src/llm/providers/anthropicFormat.js +108 -1
  171. package/src/llm/providers/anthropicFormat.ts +115 -4
  172. package/src/llm/providers/openaiFormat.js +9 -0
  173. package/src/llm/providers/openaiFormat.ts +12 -3
  174. package/src/loop.js +328 -55
  175. package/src/loop.ts +382 -58
  176. package/src/main.js +4 -1
  177. package/src/main.tsx +4 -1
  178. package/src/managedExecution/index.js +2 -0
  179. package/src/managedExecution/index.ts +2 -0
  180. package/src/managedExecution/registry.js +15 -0
  181. package/src/managedExecution/registry.ts +20 -0
  182. package/src/managedExecution/types.js +1 -0
  183. package/src/managedExecution/types.ts +86 -0
  184. package/src/modelRef.js +9 -0
  185. package/src/modelRef.ts +31 -0
  186. package/src/multimodal.js +14 -28
  187. package/src/multimodal.ts +17 -33
  188. package/src/net/lanDiscovery.js +65 -0
  189. package/src/net/lanDiscovery.ts +82 -0
  190. package/src/plugin-sdk.js +28 -3
  191. package/src/plugin-sdk.ts +39 -6
  192. package/src/plugins/pluginApi.ts +16 -1
  193. package/src/plugins/pluginLoader.js +4 -0
  194. package/src/plugins/pluginLoader.ts +6 -0
  195. package/src/plugins/pluginRunner.js +139 -7
  196. package/src/plugins/pluginRunner.ts +173 -9
  197. package/src/plugins/slashFallback.js +113 -0
  198. package/src/plugins/slashFallback.ts +137 -0
  199. package/src/prompts/policyRegistry.js +12 -32
  200. package/src/prompts/policyRegistry.ts +15 -32
  201. package/src/prompts/promptAssembly.js +103 -12
  202. package/src/prompts/promptAssembly.ts +114 -12
  203. package/src/prompts/skillList.js +21 -3
  204. package/src/prompts/skillList.ts +27 -2
  205. package/src/prompts/stableSystemPrompt.js +18 -0
  206. package/src/prompts/stableSystemPrompt.ts +33 -0
  207. package/src/runtime/agentRuntimeContext.js +8 -2
  208. package/src/runtime/agentRuntimeContext.ts +17 -4
  209. package/src/session/runAgentTurn.js +78 -12
  210. package/src/session/runAgentTurn.ts +105 -23
  211. package/src/session/runTurn.js +10 -9
  212. package/src/session/runTurn.ts +17 -8
  213. package/src/session/sessionState.ts +2 -0
  214. package/src/team/auth.js +186 -0
  215. package/src/team/auth.ts +298 -0
  216. package/src/team/cli.js +105 -0
  217. package/src/team/cli.ts +122 -0
  218. package/src/team/onlineToolContract.js +64 -0
  219. package/src/team/onlineToolContract.ts +109 -0
  220. package/src/team/toolPolicy.js +36 -0
  221. package/src/team/toolPolicy.ts +75 -0
  222. package/src/tools/advisor/advisor.js +115 -50
  223. package/src/tools/advisor/advisor.ts +124 -51
  224. package/src/tools/advisor/advisorDecision.js +71 -0
  225. package/src/tools/advisor/advisorDecision.ts +85 -0
  226. package/src/tools/agent/agent.js +18 -5
  227. package/src/tools/agent/agent.ts +21 -7
  228. package/src/tools/agent/agentControl.js +246 -0
  229. package/src/tools/agent/agentControl.ts +284 -0
  230. package/src/tools/agent/agentTaskService.js +40 -1
  231. package/src/tools/agent/agentTaskService.ts +44 -1
  232. package/src/tools/agent/agentTypes.js +14 -2
  233. package/src/tools/agent/agentTypes.ts +15 -2
  234. package/src/tools/applypatch/applyPatch.js +362 -0
  235. package/src/tools/applypatch/applyPatch.ts +428 -0
  236. package/src/tools/bash/bash.js +22 -15
  237. package/src/tools/bash/bash.ts +23 -17
  238. package/src/tools/capabilities.js +10 -5
  239. package/src/tools/capabilities.ts +10 -5
  240. package/src/tools/computeruse/computerIntent.js +32 -0
  241. package/src/tools/computeruse/computerIntent.ts +46 -0
  242. package/src/tools/computeruse/telemetryLog.js +12 -0
  243. package/src/tools/computeruse/telemetryLog.ts +16 -0
  244. package/src/tools/computeruse/vision/telemetry.js +1 -0
  245. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  246. package/src/tools/effectiveToolSet.js +4 -0
  247. package/src/tools/effectiveToolSet.ts +4 -0
  248. package/src/tools/index.js +21 -2
  249. package/src/tools/index.ts +33 -2
  250. package/src/tools/presentresult/presentresult.js +6 -15
  251. package/src/tools/presentresult/presentresult.ts +6 -15
  252. package/src/tools/read/read.js +62 -9
  253. package/src/tools/read/read.ts +63 -9
  254. package/src/tools/shared/fileUtils.js +1 -2
  255. package/src/tools/shared/fileUtils.ts +1 -2
  256. package/src/tools/shared/toolOutputStore.js +23 -1
  257. package/src/tools/shared/toolOutputStore.ts +22 -1
  258. package/src/tools/skill/skill.js +9 -3
  259. package/src/tools/skill/skill.ts +8 -4
  260. package/src/tools/toolPromptGuides.js +125 -0
  261. package/src/tools/toolPromptGuides.ts +146 -0
  262. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  263. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  264. package/src/tools/webbrowser/browser.js +27 -11
  265. package/src/tools/webbrowser/browser.ts +68 -24
  266. package/src/tools/webbrowser/browserAutomation.js +329 -0
  267. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  268. package/src/tools/webbrowser/browserAxState.js +97 -0
  269. package/src/tools/webbrowser/browserAxState.ts +142 -0
  270. package/src/tools/webbrowser/browserBatch.js +1578 -0
  271. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  272. package/src/tools/webbrowser/browserCdp.js +208 -0
  273. package/src/tools/webbrowser/browserCdp.ts +255 -0
  274. package/src/tools/webbrowser/browserConditions.js +24 -0
  275. package/src/tools/webbrowser/browserConditions.ts +45 -0
  276. package/src/tools/webbrowser/browserContent.js +281 -0
  277. package/src/tools/webbrowser/browserContent.ts +438 -0
  278. package/src/tools/webbrowser/browserControl.js +131 -34
  279. package/src/tools/webbrowser/browserControl.ts +210 -56
  280. package/src/tools/webbrowser/browserDaemon.js +22 -14
  281. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  282. package/src/tools/webbrowser/browserFrames.js +47 -0
  283. package/src/tools/webbrowser/browserFrames.ts +54 -0
  284. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  286. package/src/tools/webbrowser/browserLocator.js +140 -0
  287. package/src/tools/webbrowser/browserLocator.ts +194 -0
  288. package/src/tools/webbrowser/browserOutcome.js +10 -17
  289. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  290. package/src/tools/webbrowser/browserRecovery.js +58 -0
  291. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  292. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  293. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  294. package/src/tools/webbrowser/browserService.js +28 -2
  295. package/src/tools/webbrowser/browserService.ts +49 -9
  296. package/src/tools/webbrowser/browserStream.js +132 -33
  297. package/src/tools/webbrowser/browserStream.ts +224 -50
  298. package/src/tools/webbrowser/browserTabs.js +48 -15
  299. package/src/tools/webbrowser/browserTabs.ts +178 -96
  300. package/src/tools/webbrowser/webbrowser.js +679 -144
  301. package/src/tools/webbrowser/webbrowser.ts +975 -236
  302. package/src/tools/webfetch/preapproved.js +0 -2
  303. package/src/tools/webfetch/preapproved.ts +0 -2
  304. package/src/tools/websearch/websearch.js +129 -8
  305. package/src/tools/websearch/websearch.ts +138 -6
  306. package/src/types.ts +459 -40
  307. package/src/ui/App.js +377 -58
  308. package/src/ui/App.tsx +576 -111
  309. package/src/ui/LiveArea.js +14 -8
  310. package/src/ui/LiveArea.tsx +14 -10
  311. package/src/ui/MessageList.js +63 -20
  312. package/src/ui/MessageList.tsx +101 -16
  313. package/src/ui/ModelPicker.js +7 -4
  314. package/src/ui/ModelPicker.tsx +55 -8
  315. package/src/ui/hooks/useChat.js +152 -163
  316. package/src/ui/hooks/useChat.ts +396 -334
  317. package/src/ui/loginCommand.js +56 -0
  318. package/src/ui/loginCommand.ts +63 -0
  319. package/src/ui/toolProgress.js +41 -0
  320. package/src/ui/toolProgress.ts +44 -0
  321. package/src/web/browserBridge.js +20 -2
  322. package/src/web/browserBridge.ts +20 -2
  323. package/src/web/protocol.ts +1897 -194
  324. package/workflows/adaptive-research/workflow.mjs +86 -0
  325. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  326. package/workflows/e2e-llm/workflow.mjs +52 -0
  327. package/workflows/e2e-smoke/workflow.mjs +59 -0
  328. package/workflows/e2e-vision-schema/README.md +48 -0
  329. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  330. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  331. package/workflows/file-census/README.md +14 -0
  332. package/workflows/file-census/scripts/.gitkeep +2 -0
  333. package/workflows/file-census/workflow.mjs +110 -0
  334. package/workflows/goal/README.md +166 -0
  335. package/workflows/goal/prompts/audit.md +57 -0
  336. package/workflows/goal/prompts/contract.md +56 -0
  337. package/workflows/goal/prompts/iterate.md +37 -0
  338. package/workflows/goal/workflow.mjs +501 -0
  339. package/workflows/illustrate/README.md +90 -0
  340. package/workflows/illustrate/assets/engines.json +20 -0
  341. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  342. package/workflows/illustrate/assets/extract-bing.js +33 -0
  343. package/workflows/illustrate/assets/extract-google.js +31 -0
  344. package/workflows/illustrate/workflow.mjs +301 -0
  345. package/workflows/plan/workflow.mjs +389 -0
  346. package/workflows/question-crops/README.md +35 -0
  347. package/workflows/question-crops/prompts/inventory.md +23 -0
  348. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  349. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  350. package/workflows/question-crops/workflow.mjs +172 -0
  351. package/workflows/ralph-loop/workflow.mjs +162 -0
  352. package/workflows/research/README.md +74 -0
  353. package/workflows/research/prompts/s0-goal.md +43 -0
  354. package/workflows/research/prompts/s1-early-exit.md +22 -0
  355. package/workflows/research/prompts/s1-map.md +58 -0
  356. package/workflows/research/prompts/s2-options.md +53 -0
  357. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  358. package/workflows/research/prompts/s4-verify.md +74 -0
  359. package/workflows/research/prompts/s5-synthesis.md +81 -0
  360. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  361. package/workflows/research/prompts/s6-package.md +32 -0
  362. package/workflows/research/scripts/build-report.mjs +98 -0
  363. package/workflows/research/workflow.mjs +288 -0
  364. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  365. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  366. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  367. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  368. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  369. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  370. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  371. package/workflows/wrong-question-docx/README.md +55 -0
  372. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  373. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  374. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  375. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  376. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  377. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  378. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  379. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  380. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  381. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  382. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  383. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  384. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  385. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  386. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  387. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  388. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  389. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  390. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  391. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  392. package/plugins/workflow-runner/src/expressions.js +0 -639
  393. package/plugins/workflow-runner/src/expressions.ts +0 -640
  394. package/plugins/workflow-runner/src/loader.js +0 -573
  395. package/plugins/workflow-runner/src/loader.ts +0 -721
  396. package/plugins/workflow-runner/src/multimodal.js +0 -38
  397. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  398. package/plugins/workflow-runner/src/recovery.js +0 -126
  399. package/plugins/workflow-runner/src/recovery.ts +0 -156
  400. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  401. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  402. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  403. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  404. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  405. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  406. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  407. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  408. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  409. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  410. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  411. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  412. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  413. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  414. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  415. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  416. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  417. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  418. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  419. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  420. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  421. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  422. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  423. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  424. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  425. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  426. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  427. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  428. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  429. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  430. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  431. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  432. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  433. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  434. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  435. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  436. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  437. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  438. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  439. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  440. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  441. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  442. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  443. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  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 -201
  468. package/workflows/research.yaml +0 -873
  469. package/workflows/schema.json +0 -176
  470. package/workflows/webppt.yaml +0 -496
  471. package/workflows/wechat-reading-shots.yaml +0 -315
  472. package/workflows/word.yaml +0 -720
  473. package/workflows/youtube-shorts.yaml +0 -202
  474. /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
+ }