minimal-agent 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/README.md +6 -5
  2. package/package.json +62 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +204 -185
  16. package/plugins/workflow-runner/src/index.ts +249 -224
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +404 -467
  28. package/plugins/workflow-runner/src/runner.ts +491 -535
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +172 -152
  54. package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -105
  58. package/plugins/workflow-runner/src/types.ts +155 -520
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +542 -469
  68. package/plugins/workflow-runner/src/workflowState.ts +639 -589
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/skill-creator/scripts/run_eval.py +3 -2
  92. package/skills/ui-design/SKILL.md +5 -2
  93. package/skills/ui-design/references/layout-composition.md +1 -1
  94. package/skills/workflow-creator/SKILL.md +344 -0
  95. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  96. package/skills/workflow-creator/references/api.md +216 -0
  97. package/skills/workflow-creator/references/migration.md +103 -0
  98. package/skills/workflow-creator/references/patterns.md +779 -0
  99. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  100. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  101. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  102. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  103. package/src/advisor/advisorCoordinator.js +503 -0
  104. package/src/advisor/advisorCoordinator.ts +657 -0
  105. package/src/cli/configMenu.tsx +0 -1
  106. package/src/cli/print.js +44 -6
  107. package/src/cli/print.ts +73 -4
  108. package/src/cli/streamJson.js +5 -6
  109. package/src/cli/streamJson.ts +8 -4
  110. package/src/cli/wizards/advisorWizard.js +4 -2
  111. package/src/cli/wizards/advisorWizard.tsx +8 -2
  112. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  113. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  114. package/src/collaboration/taskFlow.js +115 -0
  115. package/src/collaboration/taskFlow.ts +169 -0
  116. package/src/config/configDefaults.js +41 -1
  117. package/src/config/configDefaults.ts +43 -1
  118. package/src/config/configDiagnostics.ts +2 -2
  119. package/src/config/configFile.js +40 -9
  120. package/src/config/configFile.ts +60 -11
  121. package/src/config/configService.js +443 -74
  122. package/src/config/configService.ts +723 -142
  123. package/src/config/numericLimits.js +22 -0
  124. package/src/config/numericLimits.ts +24 -0
  125. package/src/config.js +1 -0
  126. package/src/config.ts +3 -2
  127. package/src/context/budgetPlan.js +1 -1
  128. package/src/context/budgetPlan.ts +1 -1
  129. package/src/context/compact.js +7 -2
  130. package/src/context/compact.ts +9 -2
  131. package/src/context/microCompactLite.js +212 -13
  132. package/src/context/microCompactLite.ts +261 -12
  133. package/src/context/sessionRegistry.js +8 -1
  134. package/src/context/sessionRegistry.ts +18 -5
  135. package/src/context/toolResultArchive.js +72 -0
  136. package/src/context/toolResultArchive.ts +95 -0
  137. package/src/goal/errors.js +8 -0
  138. package/src/goal/errors.ts +18 -0
  139. package/src/goal/goalRuntime.js +344 -0
  140. package/src/goal/goalRuntime.ts +466 -0
  141. package/src/goal/goalStore.js +200 -0
  142. package/src/goal/goalStore.ts +219 -0
  143. package/src/goal/index.js +4 -0
  144. package/src/goal/index.ts +4 -0
  145. package/src/goal/statusMapping.js +71 -0
  146. package/src/goal/statusMapping.ts +95 -0
  147. package/src/goal/types.js +7 -0
  148. package/src/goal/types.ts +179 -0
  149. package/src/goal/workflowController.js +306 -0
  150. package/src/goal/workflowController.ts +360 -0
  151. package/src/harness/evidenceLedger.js +2 -0
  152. package/src/harness/evidenceLedger.ts +1 -0
  153. package/src/harness/stallGuard.js +9 -3
  154. package/src/harness/stallGuard.ts +7 -3
  155. package/src/images/imageResolver.js +161 -0
  156. package/src/images/imageResolver.ts +189 -0
  157. package/src/infra/verification.js +56 -20
  158. package/src/infra/verification.ts +87 -20
  159. package/src/llm/client.js +79 -21
  160. package/src/llm/client.ts +182 -35
  161. package/src/llm/gatewayClient.js +201 -0
  162. package/src/llm/gatewayClient.ts +299 -0
  163. package/src/llm/messageProvenance.js +46 -0
  164. package/src/llm/messageProvenance.ts +58 -0
  165. package/src/llm/modelProvider.js +1 -0
  166. package/src/llm/modelProvider.ts +22 -0
  167. package/src/llm/providers/anthropicFormat.js +108 -1
  168. package/src/llm/providers/anthropicFormat.ts +115 -4
  169. package/src/llm/providers/openaiFormat.js +9 -0
  170. package/src/llm/providers/openaiFormat.ts +12 -3
  171. package/src/loop.js +319 -54
  172. package/src/loop.ts +373 -57
  173. package/src/main.js +4 -1
  174. package/src/main.tsx +4 -1
  175. package/src/managedExecution/index.js +2 -0
  176. package/src/managedExecution/index.ts +2 -0
  177. package/src/managedExecution/registry.js +15 -0
  178. package/src/managedExecution/registry.ts +20 -0
  179. package/src/managedExecution/types.js +1 -0
  180. package/src/managedExecution/types.ts +86 -0
  181. package/src/modelRef.js +9 -0
  182. package/src/modelRef.ts +31 -0
  183. package/src/multimodal.js +14 -28
  184. package/src/multimodal.ts +17 -33
  185. package/src/net/lanDiscovery.js +65 -0
  186. package/src/net/lanDiscovery.ts +82 -0
  187. package/src/plugin-sdk.js +28 -3
  188. package/src/plugin-sdk.ts +39 -6
  189. package/src/plugins/pluginApi.ts +16 -1
  190. package/src/plugins/pluginLoader.js +4 -0
  191. package/src/plugins/pluginLoader.ts +6 -0
  192. package/src/plugins/pluginRunner.js +152 -9
  193. package/src/plugins/pluginRunner.ts +186 -8
  194. package/src/plugins/slashFallback.js +113 -0
  195. package/src/plugins/slashFallback.ts +137 -0
  196. package/src/prompts/policyRegistry.js +15 -8
  197. package/src/prompts/policyRegistry.ts +18 -8
  198. package/src/prompts/promptAssembly.js +103 -12
  199. package/src/prompts/promptAssembly.ts +114 -12
  200. package/src/prompts/skillList.js +21 -3
  201. package/src/prompts/skillList.ts +27 -2
  202. package/src/prompts/stableSystemPrompt.js +18 -0
  203. package/src/prompts/stableSystemPrompt.ts +33 -0
  204. package/src/runtime/agentRuntimeContext.js +8 -2
  205. package/src/runtime/agentRuntimeContext.ts +17 -4
  206. package/src/session/runAgentTurn.js +78 -12
  207. package/src/session/runAgentTurn.ts +105 -23
  208. package/src/session/runTurn.js +10 -9
  209. package/src/session/runTurn.ts +17 -8
  210. package/src/session/sessionState.ts +2 -0
  211. package/src/team/auth.js +186 -0
  212. package/src/team/auth.ts +298 -0
  213. package/src/team/cli.js +105 -0
  214. package/src/team/cli.ts +122 -0
  215. package/src/team/onlineToolContract.js +64 -0
  216. package/src/team/onlineToolContract.ts +109 -0
  217. package/src/team/toolPolicy.js +36 -0
  218. package/src/team/toolPolicy.ts +75 -0
  219. package/src/tools/advisor/advisor.js +148 -37
  220. package/src/tools/advisor/advisor.ts +161 -38
  221. package/src/tools/advisor/advisorDecision.js +71 -0
  222. package/src/tools/advisor/advisorDecision.ts +85 -0
  223. package/src/tools/agent/agent.js +18 -5
  224. package/src/tools/agent/agent.ts +21 -7
  225. package/src/tools/agent/agentControl.js +246 -0
  226. package/src/tools/agent/agentControl.ts +284 -0
  227. package/src/tools/agent/agentTaskService.js +40 -1
  228. package/src/tools/agent/agentTaskService.ts +44 -1
  229. package/src/tools/agent/agentTypes.js +14 -2
  230. package/src/tools/agent/agentTypes.ts +15 -2
  231. package/src/tools/applypatch/applyPatch.js +362 -0
  232. package/src/tools/applypatch/applyPatch.ts +428 -0
  233. package/src/tools/bash/bash.js +70 -18
  234. package/src/tools/bash/bash.ts +75 -20
  235. package/src/tools/capabilities.js +10 -5
  236. package/src/tools/capabilities.ts +10 -5
  237. package/src/tools/computeruse/computerIntent.js +32 -0
  238. package/src/tools/computeruse/computerIntent.ts +46 -0
  239. package/src/tools/computeruse/telemetryLog.js +12 -0
  240. package/src/tools/computeruse/telemetryLog.ts +16 -0
  241. package/src/tools/computeruse/vision/telemetry.js +1 -0
  242. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  243. package/src/tools/effectiveToolSet.js +4 -0
  244. package/src/tools/effectiveToolSet.ts +4 -0
  245. package/src/tools/index.js +21 -2
  246. package/src/tools/index.ts +33 -2
  247. package/src/tools/powershell/powershell.js +18 -1
  248. package/src/tools/powershell/powershell.ts +18 -2
  249. package/src/tools/presentresult/presentresult.js +6 -15
  250. package/src/tools/presentresult/presentresult.ts +6 -15
  251. package/src/tools/read/read.js +69 -11
  252. package/src/tools/read/read.ts +70 -11
  253. package/src/tools/shared/fileUtils.js +1 -2
  254. package/src/tools/shared/fileUtils.ts +1 -2
  255. package/src/tools/shared/permanentDeleteGuard.js +34 -3
  256. package/src/tools/shared/permanentDeleteGuard.ts +43 -6
  257. package/src/tools/shared/toolOutputStore.js +23 -1
  258. package/src/tools/shared/toolOutputStore.ts +22 -1
  259. package/src/tools/skill/skill.js +9 -3
  260. package/src/tools/skill/skill.ts +8 -4
  261. package/src/tools/toolPromptGuides.js +117 -0
  262. package/src/tools/toolPromptGuides.ts +137 -0
  263. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  264. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  265. package/src/tools/webbrowser/browser.js +27 -11
  266. package/src/tools/webbrowser/browser.ts +68 -24
  267. package/src/tools/webbrowser/browserAutomation.js +329 -0
  268. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  269. package/src/tools/webbrowser/browserAxState.js +97 -0
  270. package/src/tools/webbrowser/browserAxState.ts +142 -0
  271. package/src/tools/webbrowser/browserBatch.js +1578 -0
  272. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  273. package/src/tools/webbrowser/browserCdp.js +208 -0
  274. package/src/tools/webbrowser/browserCdp.ts +255 -0
  275. package/src/tools/webbrowser/browserConditions.js +24 -0
  276. package/src/tools/webbrowser/browserConditions.ts +45 -0
  277. package/src/tools/webbrowser/browserContent.js +281 -0
  278. package/src/tools/webbrowser/browserContent.ts +438 -0
  279. package/src/tools/webbrowser/browserControl.js +131 -30
  280. package/src/tools/webbrowser/browserControl.ts +210 -50
  281. package/src/tools/webbrowser/browserDaemon.js +22 -14
  282. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  283. package/src/tools/webbrowser/browserFrames.js +47 -0
  284. package/src/tools/webbrowser/browserFrames.ts +54 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  286. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  287. package/src/tools/webbrowser/browserLocator.js +140 -0
  288. package/src/tools/webbrowser/browserLocator.ts +194 -0
  289. package/src/tools/webbrowser/browserOutcome.js +10 -17
  290. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  291. package/src/tools/webbrowser/browserRecovery.js +58 -0
  292. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  293. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  294. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  295. package/src/tools/webbrowser/browserService.js +28 -2
  296. package/src/tools/webbrowser/browserService.ts +49 -9
  297. package/src/tools/webbrowser/browserStream.js +132 -33
  298. package/src/tools/webbrowser/browserStream.ts +224 -50
  299. package/src/tools/webbrowser/browserTabs.js +48 -15
  300. package/src/tools/webbrowser/browserTabs.ts +178 -96
  301. package/src/tools/webbrowser/webbrowser.js +683 -144
  302. package/src/tools/webbrowser/webbrowser.ts +979 -236
  303. package/src/tools/webfetch/preapproved.js +0 -2
  304. package/src/tools/webfetch/preapproved.ts +0 -2
  305. package/src/tools/websearch/websearch.js +129 -8
  306. package/src/tools/websearch/websearch.ts +138 -6
  307. package/src/types.ts +450 -42
  308. package/src/ui/App.js +377 -58
  309. package/src/ui/App.tsx +576 -111
  310. package/src/ui/LiveArea.js +14 -8
  311. package/src/ui/LiveArea.tsx +14 -10
  312. package/src/ui/MessageList.js +63 -20
  313. package/src/ui/MessageList.tsx +101 -16
  314. package/src/ui/ModelPicker.js +7 -4
  315. package/src/ui/ModelPicker.tsx +55 -8
  316. package/src/ui/hooks/useChat.js +152 -163
  317. package/src/ui/hooks/useChat.ts +396 -334
  318. package/src/ui/loginCommand.js +56 -0
  319. package/src/ui/loginCommand.ts +63 -0
  320. package/src/ui/toolProgress.js +41 -0
  321. package/src/ui/toolProgress.ts +44 -0
  322. package/src/web/browserBridge.js +20 -2
  323. package/src/web/browserBridge.ts +20 -2
  324. package/src/web/protocol.ts +1897 -194
  325. package/workflows/adaptive-research/workflow.mjs +86 -0
  326. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  327. package/workflows/e2e-llm/workflow.mjs +52 -0
  328. package/workflows/e2e-smoke/workflow.mjs +59 -0
  329. package/workflows/e2e-vision-schema/README.md +48 -0
  330. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  331. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  332. package/workflows/file-census/README.md +14 -0
  333. package/workflows/file-census/scripts/.gitkeep +2 -0
  334. package/workflows/file-census/workflow.mjs +110 -0
  335. package/workflows/goal/README.md +166 -0
  336. package/workflows/goal/prompts/audit.md +57 -0
  337. package/workflows/goal/prompts/contract.md +56 -0
  338. package/workflows/goal/prompts/iterate.md +37 -0
  339. package/workflows/goal/workflow.mjs +501 -0
  340. package/workflows/illustrate/README.md +90 -0
  341. package/workflows/illustrate/assets/engines.json +20 -0
  342. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  343. package/workflows/illustrate/assets/extract-bing.js +33 -0
  344. package/workflows/illustrate/assets/extract-google.js +31 -0
  345. package/workflows/illustrate/workflow.mjs +301 -0
  346. package/workflows/plan/workflow.mjs +389 -0
  347. package/workflows/question-crops/README.md +35 -0
  348. package/workflows/question-crops/prompts/inventory.md +23 -0
  349. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  350. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  351. package/workflows/question-crops/workflow.mjs +172 -0
  352. package/workflows/ralph-loop/workflow.mjs +162 -0
  353. package/workflows/research/DESIGN.md +449 -0
  354. package/workflows/research/README.md +74 -0
  355. package/workflows/research/prompts/s0-goal.md +43 -0
  356. package/workflows/research/prompts/s1-early-exit.md +22 -0
  357. package/workflows/research/prompts/s1-map.md +58 -0
  358. package/workflows/research/prompts/s2-options.md +53 -0
  359. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  360. package/workflows/research/prompts/s4-verify.md +74 -0
  361. package/workflows/research/prompts/s5-synthesis.md +81 -0
  362. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  363. package/workflows/research/prompts/s6-package.md +32 -0
  364. package/workflows/research/scripts/build-report.mjs +98 -0
  365. package/workflows/research/workflow.mjs +288 -0
  366. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  367. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  368. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  369. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  370. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  371. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  372. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  373. package/workflows/wrong-question-docx/README.md +55 -0
  374. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  375. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  376. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  377. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  378. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  379. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  380. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  381. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  382. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  383. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  384. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  385. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  386. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  387. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  388. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  389. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  390. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  391. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  392. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  393. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  394. package/plugins/workflow-runner/src/expressions.js +0 -618
  395. package/plugins/workflow-runner/src/expressions.ts +0 -622
  396. package/plugins/workflow-runner/src/loader.js +0 -573
  397. package/plugins/workflow-runner/src/loader.ts +0 -721
  398. package/plugins/workflow-runner/src/multimodal.js +0 -38
  399. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  400. package/plugins/workflow-runner/src/recovery.js +0 -119
  401. package/plugins/workflow-runner/src/recovery.ts +0 -149
  402. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  403. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  404. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
  405. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
  406. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  407. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  408. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  409. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  410. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  411. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  412. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  413. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  414. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
  415. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
  416. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
  417. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
  418. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  419. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  420. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  421. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  422. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  423. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  424. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
  425. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  426. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  427. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
  428. package/plugins/workflow-runner/test/expressions.test.ts +0 -397
  429. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  430. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  431. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  432. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  433. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  434. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  435. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  436. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  437. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  438. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  439. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
  440. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  441. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  442. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
  443. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -199
  468. package/workflows/schema.json +0 -176
  469. package/workflows/webppt.yaml +0 -496
  470. package/workflows/wechat-reading-shots.yaml +0 -315
  471. package/workflows/word.yaml +0 -720
  472. package/workflows/youtube-shorts.yaml +0 -202
@@ -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
+ }