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.
- package/README.md +6 -5
- package/package.json +60 -4
- package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
- package/plugins/cron-runner/src/commands.js +4 -4
- package/plugins/cron-runner/src/commands.ts +4 -4
- package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
- package/plugins/workflow-runner/commands/workflow.md +57 -90
- package/plugins/workflow-runner/commands/workflows.md +4 -4
- package/plugins/workflow-runner/plugin.js +24 -13
- package/plugins/workflow-runner/plugin.ts +28 -13
- package/plugins/workflow-runner/src/discovery.js +160 -0
- package/plugins/workflow-runner/src/discovery.ts +194 -0
- package/plugins/workflow-runner/src/goalAnchor.js +53 -0
- package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
- package/plugins/workflow-runner/src/index.js +197 -206
- package/plugins/workflow-runner/src/index.ts +248 -249
- package/plugins/workflow-runner/src/inputCoercion.js +40 -0
- package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
- package/plugins/workflow-runner/src/journal.js +224 -0
- package/plugins/workflow-runner/src/journal.ts +274 -0
- package/plugins/workflow-runner/src/jsonSchema.js +132 -0
- package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
- package/plugins/workflow-runner/src/moduleResolution.js +64 -0
- package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
- package/plugins/workflow-runner/src/resourceInputs.js +220 -0
- package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
- package/plugins/workflow-runner/src/runner.js +400 -489
- package/plugins/workflow-runner/src/runner.ts +488 -560
- package/plugins/workflow-runner/src/runtime/config.js +46 -0
- package/plugins/workflow-runner/src/runtime/config.ts +69 -0
- package/plugins/workflow-runner/src/runtime/context.js +1304 -0
- package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
- package/plugins/workflow-runner/src/runtime/exec.js +34 -0
- package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
- package/plugins/workflow-runner/src/runtime/flow.js +8 -0
- package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
- package/plugins/workflow-runner/src/runtime/fs.js +27 -0
- package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
- package/plugins/workflow-runner/src/runtime/model.js +6 -0
- package/plugins/workflow-runner/src/runtime/model.ts +8 -0
- package/plugins/workflow-runner/src/runtime/output.js +7 -0
- package/plugins/workflow-runner/src/runtime/output.ts +21 -0
- package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
- package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
- package/plugins/workflow-runner/src/runtime/state.js +16 -0
- package/plugins/workflow-runner/src/runtime/state.ts +19 -0
- package/plugins/workflow-runner/src/runtime/tools.js +3 -0
- package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
- package/plugins/workflow-runner/src/sandbox.js +141 -0
- package/plugins/workflow-runner/src/sandbox.ts +182 -0
- package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
- package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
- package/plugins/workflow-runner/src/taskIdentity.js +151 -307
- package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
- package/plugins/workflow-runner/src/toolRuntime.js +29 -8
- package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
- package/plugins/workflow-runner/src/types.js +7 -211
- package/plugins/workflow-runner/src/types.ts +154 -623
- package/plugins/workflow-runner/src/util.js +47 -0
- package/plugins/workflow-runner/src/util.ts +51 -0
- package/plugins/workflow-runner/src/workflowContext.js +20 -0
- package/plugins/workflow-runner/src/workflowContext.ts +58 -0
- package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
- package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
- package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
- package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
- package/plugins/workflow-runner/src/workflowState.js +474 -802
- package/plugins/workflow-runner/src/workflowState.ts +575 -970
- package/plugins/workflow-runner/test/api.test.ts +223 -0
- package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
- package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
- package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
- package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
- package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
- package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
- package/plugins/workflow-runner/test/discovery.test.ts +234 -0
- package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
- package/plugins/workflow-runner/test/goalController.test.ts +317 -0
- package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
- package/plugins/workflow-runner/test/listResources.test.ts +106 -0
- package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
- package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
- package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
- package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
- package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
- package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
- package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
- package/skills/pptx/examples/assets/cover-bg.svg +23 -0
- package/skills/pptx/examples/assets/icon-spark.svg +5 -0
- package/skills/ui-design/SKILL.md +5 -2
- package/skills/ui-design/references/layout-composition.md +1 -1
- package/skills/workflow-creator/SKILL.md +344 -0
- package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
- package/skills/workflow-creator/references/api.md +216 -0
- package/skills/workflow-creator/references/migration.md +103 -0
- package/skills/workflow-creator/references/patterns.md +779 -0
- package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
- package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
- package/skills/workflow-creator/scripts/validate.mjs +275 -0
- package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
- package/src/advisor/advisorCoordinator.js +536 -0
- package/src/advisor/advisorCoordinator.ts +693 -0
- package/src/cli/configMenu.tsx +0 -1
- package/src/cli/print.js +27 -6
- package/src/cli/print.ts +48 -4
- package/src/cli/quickModelSetup.js +12 -1
- package/src/cli/quickModelSetup.tsx +15 -3
- package/src/cli/streamJson.js +5 -6
- package/src/cli/streamJson.ts +8 -4
- package/src/cli/wizards/advisorWizard.js +4 -2
- package/src/cli/wizards/advisorWizard.tsx +8 -2
- package/src/cli/wizards/contextAdvisorWizard.js +5 -4
- package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
- package/src/cli/wizards/providerPresets.js +18 -8
- package/src/cli/wizards/providerPresets.ts +18 -8
- package/src/collaboration/taskFlow.js +115 -0
- package/src/collaboration/taskFlow.ts +169 -0
- package/src/config/configDefaults.js +41 -1
- package/src/config/configDefaults.ts +43 -1
- package/src/config/configDiagnostics.ts +2 -2
- package/src/config/configFile.js +40 -9
- package/src/config/configFile.ts +60 -11
- package/src/config/configService.js +419 -74
- package/src/config/configService.ts +703 -145
- package/src/config/numericLimits.js +22 -0
- package/src/config/numericLimits.ts +24 -0
- package/src/config.js +1 -0
- package/src/config.ts +3 -2
- package/src/context/budgetPlan.js +1 -1
- package/src/context/budgetPlan.ts +1 -1
- package/src/context/compact.js +7 -2
- package/src/context/compact.ts +9 -2
- package/src/context/microCompactLite.js +212 -13
- package/src/context/microCompactLite.ts +261 -12
- package/src/context/sessionRegistry.js +8 -1
- package/src/context/sessionRegistry.ts +18 -5
- package/src/context/toolResultArchive.js +72 -0
- package/src/context/toolResultArchive.ts +95 -0
- package/src/goal/errors.js +8 -0
- package/src/goal/errors.ts +18 -0
- package/src/goal/goalRuntime.js +344 -0
- package/src/goal/goalRuntime.ts +466 -0
- package/src/goal/goalStore.js +200 -0
- package/src/goal/goalStore.ts +219 -0
- package/src/goal/index.js +4 -0
- package/src/goal/index.ts +4 -0
- package/src/goal/statusMapping.js +71 -0
- package/src/goal/statusMapping.ts +95 -0
- package/src/goal/types.js +7 -0
- package/src/goal/types.ts +179 -0
- package/src/goal/workflowController.js +306 -0
- package/src/goal/workflowController.ts +360 -0
- package/src/harness/evidenceLedger.js +2 -0
- package/src/harness/evidenceLedger.ts +1 -0
- package/src/harness/stallGuard.js +9 -3
- package/src/harness/stallGuard.ts +7 -3
- package/src/images/imageResolver.js +161 -0
- package/src/images/imageResolver.ts +189 -0
- package/src/infra/verification.js +34 -5
- package/src/infra/verification.ts +39 -4
- package/src/llm/client.js +79 -21
- package/src/llm/client.ts +182 -35
- package/src/llm/gatewayClient.js +201 -0
- package/src/llm/gatewayClient.ts +299 -0
- package/src/llm/messageProvenance.js +46 -0
- package/src/llm/messageProvenance.ts +58 -0
- package/src/llm/modelProvider.js +1 -0
- package/src/llm/modelProvider.ts +22 -0
- package/src/llm/providers/anthropicFormat.js +108 -1
- package/src/llm/providers/anthropicFormat.ts +115 -4
- package/src/llm/providers/openaiFormat.js +9 -0
- package/src/llm/providers/openaiFormat.ts +12 -3
- package/src/loop.js +328 -55
- package/src/loop.ts +382 -58
- package/src/main.js +4 -1
- package/src/main.tsx +4 -1
- package/src/managedExecution/index.js +2 -0
- package/src/managedExecution/index.ts +2 -0
- package/src/managedExecution/registry.js +15 -0
- package/src/managedExecution/registry.ts +20 -0
- package/src/managedExecution/types.js +1 -0
- package/src/managedExecution/types.ts +86 -0
- package/src/modelRef.js +9 -0
- package/src/modelRef.ts +31 -0
- package/src/multimodal.js +14 -28
- package/src/multimodal.ts +17 -33
- package/src/net/lanDiscovery.js +65 -0
- package/src/net/lanDiscovery.ts +82 -0
- package/src/plugin-sdk.js +28 -3
- package/src/plugin-sdk.ts +39 -6
- package/src/plugins/pluginApi.ts +16 -1
- package/src/plugins/pluginLoader.js +4 -0
- package/src/plugins/pluginLoader.ts +6 -0
- package/src/plugins/pluginRunner.js +139 -7
- package/src/plugins/pluginRunner.ts +173 -9
- package/src/plugins/slashFallback.js +113 -0
- package/src/plugins/slashFallback.ts +137 -0
- package/src/prompts/policyRegistry.js +12 -32
- package/src/prompts/policyRegistry.ts +15 -32
- package/src/prompts/promptAssembly.js +103 -12
- package/src/prompts/promptAssembly.ts +114 -12
- package/src/prompts/skillList.js +21 -3
- package/src/prompts/skillList.ts +27 -2
- package/src/prompts/stableSystemPrompt.js +18 -0
- package/src/prompts/stableSystemPrompt.ts +33 -0
- package/src/runtime/agentRuntimeContext.js +8 -2
- package/src/runtime/agentRuntimeContext.ts +17 -4
- package/src/session/runAgentTurn.js +78 -12
- package/src/session/runAgentTurn.ts +105 -23
- package/src/session/runTurn.js +10 -9
- package/src/session/runTurn.ts +17 -8
- package/src/session/sessionState.ts +2 -0
- package/src/team/auth.js +186 -0
- package/src/team/auth.ts +298 -0
- package/src/team/cli.js +105 -0
- package/src/team/cli.ts +122 -0
- package/src/team/onlineToolContract.js +64 -0
- package/src/team/onlineToolContract.ts +109 -0
- package/src/team/toolPolicy.js +36 -0
- package/src/team/toolPolicy.ts +75 -0
- package/src/tools/advisor/advisor.js +115 -50
- package/src/tools/advisor/advisor.ts +124 -51
- package/src/tools/advisor/advisorDecision.js +71 -0
- package/src/tools/advisor/advisorDecision.ts +85 -0
- package/src/tools/agent/agent.js +18 -5
- package/src/tools/agent/agent.ts +21 -7
- package/src/tools/agent/agentControl.js +246 -0
- package/src/tools/agent/agentControl.ts +284 -0
- package/src/tools/agent/agentTaskService.js +40 -1
- package/src/tools/agent/agentTaskService.ts +44 -1
- package/src/tools/agent/agentTypes.js +14 -2
- package/src/tools/agent/agentTypes.ts +15 -2
- package/src/tools/applypatch/applyPatch.js +362 -0
- package/src/tools/applypatch/applyPatch.ts +428 -0
- package/src/tools/bash/bash.js +22 -15
- package/src/tools/bash/bash.ts +23 -17
- package/src/tools/capabilities.js +10 -5
- package/src/tools/capabilities.ts +10 -5
- package/src/tools/computeruse/computerIntent.js +32 -0
- package/src/tools/computeruse/computerIntent.ts +46 -0
- package/src/tools/computeruse/telemetryLog.js +12 -0
- package/src/tools/computeruse/telemetryLog.ts +16 -0
- package/src/tools/computeruse/vision/telemetry.js +1 -0
- package/src/tools/computeruse/vision/telemetry.ts +1 -0
- package/src/tools/effectiveToolSet.js +4 -0
- package/src/tools/effectiveToolSet.ts +4 -0
- package/src/tools/index.js +21 -2
- package/src/tools/index.ts +33 -2
- package/src/tools/presentresult/presentresult.js +6 -15
- package/src/tools/presentresult/presentresult.ts +6 -15
- package/src/tools/read/read.js +62 -9
- package/src/tools/read/read.ts +63 -9
- package/src/tools/shared/fileUtils.js +1 -2
- package/src/tools/shared/fileUtils.ts +1 -2
- package/src/tools/shared/toolOutputStore.js +23 -1
- package/src/tools/shared/toolOutputStore.ts +22 -1
- package/src/tools/skill/skill.js +9 -3
- package/src/tools/skill/skill.ts +8 -4
- package/src/tools/toolPromptGuides.js +125 -0
- package/src/tools/toolPromptGuides.ts +146 -0
- package/src/tools/webbrowser/agentBrowserPath.js +19 -9
- package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
- package/src/tools/webbrowser/browser.js +27 -11
- package/src/tools/webbrowser/browser.ts +68 -24
- package/src/tools/webbrowser/browserAutomation.js +329 -0
- package/src/tools/webbrowser/browserAutomation.ts +467 -0
- package/src/tools/webbrowser/browserAxState.js +97 -0
- package/src/tools/webbrowser/browserAxState.ts +142 -0
- package/src/tools/webbrowser/browserBatch.js +1578 -0
- package/src/tools/webbrowser/browserBatch.ts +2382 -0
- package/src/tools/webbrowser/browserCdp.js +208 -0
- package/src/tools/webbrowser/browserCdp.ts +255 -0
- package/src/tools/webbrowser/browserConditions.js +24 -0
- package/src/tools/webbrowser/browserConditions.ts +45 -0
- package/src/tools/webbrowser/browserContent.js +281 -0
- package/src/tools/webbrowser/browserContent.ts +438 -0
- package/src/tools/webbrowser/browserControl.js +131 -34
- package/src/tools/webbrowser/browserControl.ts +210 -56
- package/src/tools/webbrowser/browserDaemon.js +22 -14
- package/src/tools/webbrowser/browserDaemon.ts +54 -21
- package/src/tools/webbrowser/browserFrames.js +47 -0
- package/src/tools/webbrowser/browserFrames.ts +54 -0
- package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
- package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
- package/src/tools/webbrowser/browserLocator.js +140 -0
- package/src/tools/webbrowser/browserLocator.ts +194 -0
- package/src/tools/webbrowser/browserOutcome.js +10 -17
- package/src/tools/webbrowser/browserOutcome.ts +48 -31
- package/src/tools/webbrowser/browserRecovery.js +58 -0
- package/src/tools/webbrowser/browserRecovery.ts +83 -0
- package/src/tools/webbrowser/browserRunRegistry.js +35 -3
- package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
- package/src/tools/webbrowser/browserService.js +28 -2
- package/src/tools/webbrowser/browserService.ts +49 -9
- package/src/tools/webbrowser/browserStream.js +132 -33
- package/src/tools/webbrowser/browserStream.ts +224 -50
- package/src/tools/webbrowser/browserTabs.js +48 -15
- package/src/tools/webbrowser/browserTabs.ts +178 -96
- package/src/tools/webbrowser/webbrowser.js +679 -144
- package/src/tools/webbrowser/webbrowser.ts +975 -236
- package/src/tools/webfetch/preapproved.js +0 -2
- package/src/tools/webfetch/preapproved.ts +0 -2
- package/src/tools/websearch/websearch.js +129 -8
- package/src/tools/websearch/websearch.ts +138 -6
- package/src/types.ts +459 -40
- package/src/ui/App.js +377 -58
- package/src/ui/App.tsx +576 -111
- package/src/ui/LiveArea.js +14 -8
- package/src/ui/LiveArea.tsx +14 -10
- package/src/ui/MessageList.js +63 -20
- package/src/ui/MessageList.tsx +101 -16
- package/src/ui/ModelPicker.js +7 -4
- package/src/ui/ModelPicker.tsx +55 -8
- package/src/ui/hooks/useChat.js +152 -163
- package/src/ui/hooks/useChat.ts +396 -334
- package/src/ui/loginCommand.js +56 -0
- package/src/ui/loginCommand.ts +63 -0
- package/src/ui/toolProgress.js +41 -0
- package/src/ui/toolProgress.ts +44 -0
- package/src/web/browserBridge.js +20 -2
- package/src/web/browserBridge.ts +20 -2
- package/src/web/protocol.ts +1897 -194
- package/workflows/adaptive-research/workflow.mjs +86 -0
- package/workflows/e2e-capabilities/workflow.mjs +102 -0
- package/workflows/e2e-llm/workflow.mjs +52 -0
- package/workflows/e2e-smoke/workflow.mjs +59 -0
- package/workflows/e2e-vision-schema/README.md +48 -0
- package/workflows/e2e-vision-schema/workflow.mjs +149 -0
- package/workflows/e2e-write-greet/workflow.mjs +37 -0
- package/workflows/file-census/README.md +14 -0
- package/workflows/file-census/scripts/.gitkeep +2 -0
- package/workflows/file-census/workflow.mjs +110 -0
- package/workflows/goal/README.md +166 -0
- package/workflows/goal/prompts/audit.md +57 -0
- package/workflows/goal/prompts/contract.md +56 -0
- package/workflows/goal/prompts/iterate.md +37 -0
- package/workflows/goal/workflow.mjs +501 -0
- package/workflows/illustrate/README.md +90 -0
- package/workflows/illustrate/assets/engines.json +20 -0
- package/workflows/illustrate/assets/extract-baidu.js +21 -0
- package/workflows/illustrate/assets/extract-bing.js +33 -0
- package/workflows/illustrate/assets/extract-google.js +31 -0
- package/workflows/illustrate/workflow.mjs +301 -0
- package/workflows/plan/workflow.mjs +389 -0
- package/workflows/question-crops/README.md +35 -0
- package/workflows/question-crops/prompts/inventory.md +23 -0
- package/workflows/question-crops/scripts/image-ops.mjs +305 -0
- package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
- package/workflows/question-crops/workflow.mjs +172 -0
- package/workflows/ralph-loop/workflow.mjs +162 -0
- package/workflows/research/README.md +74 -0
- package/workflows/research/prompts/s0-goal.md +43 -0
- package/workflows/research/prompts/s1-early-exit.md +22 -0
- package/workflows/research/prompts/s1-map.md +58 -0
- package/workflows/research/prompts/s2-options.md +53 -0
- package/workflows/research/prompts/s3-deep-dive.md +56 -0
- package/workflows/research/prompts/s4-verify.md +74 -0
- package/workflows/research/prompts/s5-synthesis.md +81 -0
- package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
- package/workflows/research/prompts/s6-package.md +32 -0
- package/workflows/research/scripts/build-report.mjs +98 -0
- package/workflows/research/workflow.mjs +288 -0
- package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
- package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
- package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
- package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
- package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
- package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
- package/workflows/wechat-reading-shots/workflow.mjs +266 -0
- package/workflows/wrong-question-docx/README.md +55 -0
- package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
- package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
- package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
- package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
- package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
- package/workflows/wrong-question-docx/workflow.mjs +485 -0
- package/plugins/workflow-runner/src/agentCommon.js +0 -354
- package/plugins/workflow-runner/src/agentCommon.ts +0 -435
- package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
- package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
- package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
- package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
- package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
- package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
- package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
- package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
- package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
- package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
- package/plugins/workflow-runner/src/dslManifest.js +0 -72
- package/plugins/workflow-runner/src/dslManifest.ts +0 -127
- package/plugins/workflow-runner/src/expressions.js +0 -639
- package/plugins/workflow-runner/src/expressions.ts +0 -640
- package/plugins/workflow-runner/src/loader.js +0 -573
- package/plugins/workflow-runner/src/loader.ts +0 -721
- package/plugins/workflow-runner/src/multimodal.js +0 -38
- package/plugins/workflow-runner/src/multimodal.ts +0 -64
- package/plugins/workflow-runner/src/recovery.js +0 -126
- package/plugins/workflow-runner/src/recovery.ts +0 -156
- package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
- package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
- package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
- package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
- package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
- package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
- package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
- package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
- package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
- package/plugins/workflow-runner/src/stepPipeline.js +0 -277
- package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
- package/plugins/workflow-runner/test/agent.test.ts +0 -587
- package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
- package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
- package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
- package/plugins/workflow-runner/test/context-files.test.ts +0 -320
- package/plugins/workflow-runner/test/e2e.test.ts +0 -370
- package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
- package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
- package/plugins/workflow-runner/test/expressions.test.ts +0 -439
- package/plugins/workflow-runner/test/foundation.test.ts +0 -126
- package/plugins/workflow-runner/test/graceful.test.ts +0 -139
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
- package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
- package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
- package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
- package/plugins/workflow-runner/test/loader.test.ts +0 -617
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
- package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
- package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
- package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
- package/plugins/workflow-runner/test/recovery.test.ts +0 -265
- package/plugins/workflow-runner/test/research.load.test.ts +0 -328
- package/plugins/workflow-runner/test/runner.test.ts +0 -911
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
- package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
- package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
- package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
- package/plugins/workflow-runner/test/word.load.test.ts +0 -208
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
- package/src/advisorState.js +0 -22
- package/src/cli/configWizard.js +0 -293
- package/src/tools/toolProgressBridge.js +0 -48
- package/workflows/adaptive-research.yaml +0 -50
- package/workflows/book-review-short.yaml +0 -125
- package/workflows/e2e-write-greet.yaml +0 -31
- package/workflows/illustrate.yaml +0 -227
- package/workflows/plan.yaml +0 -470
- package/workflows/ppt.yaml +0 -1670
- package/workflows/ralph-loop.yaml +0 -201
- package/workflows/research.yaml +0 -873
- package/workflows/schema.json +0 -176
- package/workflows/webppt.yaml +0 -496
- package/workflows/wechat-reading-shots.yaml +0 -315
- package/workflows/word.yaml +0 -720
- package/workflows/youtube-shorts.yaml +0 -202
- /package/workflows/{research.md → research/DESIGN.md} +0 -0
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ============================================================
|
|
3
|
-
* stepExecutors/set.ts —— 确定性变量赋值
|
|
4
|
-
* ------------------------------------------------------------
|
|
5
|
-
* 从 `runner.ts::runSteps` 的内联块搬出来。搬出来的收益不只是「runner 短了 40 行」:
|
|
6
|
-
* 它现在走**统一的提交流水线**(`stepPipeline.ts::commitStep`),于是
|
|
7
|
-
* **`capture:` 自然生效了** —— 此前 set 从不调 `bindCapture`、checkpoint 里
|
|
8
|
-
* 记的是 `resolved` 而非 `collectCaptured(...)`,yaml 作者写了 `capture` 既不
|
|
9
|
-
* 报错也不生效,resume 时也回放不出来。典型的静默失效。
|
|
10
|
-
*
|
|
11
|
-
* ⚠️ 两个必须保住的语义:
|
|
12
|
-
* ① 写的是 `vars.setGlobal`(根帧)不是 `vars.set` —— set 步声明的是**工作流级**
|
|
13
|
-
* 变量,在循环体里写也必须活到循环之外。
|
|
14
|
-
* ② 顶层值若是单一 `"${EXPR}"` 模板走 `interpolateTyped` **保留类型**
|
|
15
|
-
* (布尔/数字/数组不字符串化成 "true",下游条件不必写 `== true || == 'true'` 防御);
|
|
16
|
-
* 多片段模板与嵌套结构走 `interpolateDeep`,行为不变。
|
|
17
|
-
* ============================================================
|
|
18
|
-
*/
|
|
19
|
-
import { interpolateDeep, interpolateTyped } from '../expressions.js';
|
|
20
|
-
export async function* execSetStep(step, vars) {
|
|
21
|
-
const missing = [];
|
|
22
|
-
const resolved = {};
|
|
23
|
-
for (const [k, v] of Object.entries(step.set ?? {})) {
|
|
24
|
-
resolved[k] =
|
|
25
|
-
typeof v === 'string'
|
|
26
|
-
? interpolateTyped(v, vars, { onMissing: (e) => missing.push(e) })
|
|
27
|
-
: interpolateDeep(v, vars, { onMissing: (e) => missing.push(e) });
|
|
28
|
-
}
|
|
29
|
-
if (missing.length > 0) {
|
|
30
|
-
yield {
|
|
31
|
-
type: 'warning',
|
|
32
|
-
message: `step "${step.id}": 模板变量未定义:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
for (const [k, v] of Object.entries(resolved)) {
|
|
36
|
-
vars.setGlobal(k, v);
|
|
37
|
-
}
|
|
38
|
-
const summary = Object.entries(resolved)
|
|
39
|
-
.map(([k, v]) => `${k}=${String(v).slice(0, 40)}`)
|
|
40
|
-
.join(', ');
|
|
41
|
-
// raw 就是赋值表本身 —— 这样 `capture: { <变量名>: <别名> }` 能取到刚赋的值。
|
|
42
|
-
// replayVars 让 checkpoint 记下这些赋值:resume 跳过本步时变量仍能回放
|
|
43
|
-
//(set 步通常没有 capture:,只靠 collectCaptured 会记成 {})。
|
|
44
|
-
return {
|
|
45
|
-
raw: { ...resolved },
|
|
46
|
-
replayVars: { ...resolved },
|
|
47
|
-
preview: `set: ${summary}`,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ============================================================
|
|
3
|
-
* stepExecutors/set.ts —— 确定性变量赋值
|
|
4
|
-
* ------------------------------------------------------------
|
|
5
|
-
* 从 `runner.ts::runSteps` 的内联块搬出来。搬出来的收益不只是「runner 短了 40 行」:
|
|
6
|
-
* 它现在走**统一的提交流水线**(`stepPipeline.ts::commitStep`),于是
|
|
7
|
-
* **`capture:` 自然生效了** —— 此前 set 从不调 `bindCapture`、checkpoint 里
|
|
8
|
-
* 记的是 `resolved` 而非 `collectCaptured(...)`,yaml 作者写了 `capture` 既不
|
|
9
|
-
* 报错也不生效,resume 时也回放不出来。典型的静默失效。
|
|
10
|
-
*
|
|
11
|
-
* ⚠️ 两个必须保住的语义:
|
|
12
|
-
* ① 写的是 `vars.setGlobal`(根帧)不是 `vars.set` —— set 步声明的是**工作流级**
|
|
13
|
-
* 变量,在循环体里写也必须活到循环之外。
|
|
14
|
-
* ② 顶层值若是单一 `"${EXPR}"` 模板走 `interpolateTyped` **保留类型**
|
|
15
|
-
* (布尔/数字/数组不字符串化成 "true",下游条件不必写 `== true || == 'true'` 防御);
|
|
16
|
-
* 多片段模板与嵌套结构走 `interpolateDeep`,行为不变。
|
|
17
|
-
* ============================================================
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import type { LoopEvent } from '../../../../src/plugin-sdk.js';
|
|
21
|
-
import { interpolateDeep, interpolateTyped } from '../expressions.js';
|
|
22
|
-
import type { StepDef, StepResult, VarStack } from '../types.js';
|
|
23
|
-
|
|
24
|
-
export async function* execSetStep(
|
|
25
|
-
step: StepDef,
|
|
26
|
-
vars: VarStack,
|
|
27
|
-
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
28
|
-
const missing: string[] = [];
|
|
29
|
-
const resolved: Record<string, unknown> = {};
|
|
30
|
-
for (const [k, v] of Object.entries(step.set ?? {})) {
|
|
31
|
-
resolved[k] =
|
|
32
|
-
typeof v === 'string'
|
|
33
|
-
? interpolateTyped(v, vars, { onMissing: (e) => missing.push(e) })
|
|
34
|
-
: interpolateDeep(v, vars, { onMissing: (e) => missing.push(e) });
|
|
35
|
-
}
|
|
36
|
-
if (missing.length > 0) {
|
|
37
|
-
yield {
|
|
38
|
-
type: 'warning',
|
|
39
|
-
message: `step "${step.id}": 模板变量未定义:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
40
|
-
} as LoopEvent;
|
|
41
|
-
}
|
|
42
|
-
for (const [k, v] of Object.entries(resolved)) {
|
|
43
|
-
vars.setGlobal(k, v);
|
|
44
|
-
}
|
|
45
|
-
const summary = Object.entries(resolved)
|
|
46
|
-
.map(([k, v]) => `${k}=${String(v).slice(0, 40)}`)
|
|
47
|
-
.join(', ');
|
|
48
|
-
// raw 就是赋值表本身 —— 这样 `capture: { <变量名>: <别名> }` 能取到刚赋的值。
|
|
49
|
-
// replayVars 让 checkpoint 记下这些赋值:resume 跳过本步时变量仍能回放
|
|
50
|
-
//(set 步通常没有 capture:,只靠 collectCaptured 会记成 {})。
|
|
51
|
-
return {
|
|
52
|
-
raw: { ...resolved },
|
|
53
|
-
replayVars: { ...resolved },
|
|
54
|
-
preview: `set: ${summary}`,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ============================================================
|
|
3
|
-
* plugins/workflow-runner/src/stepExecutors/skill.ts —— skill 步骤执行器
|
|
4
|
-
* ------------------------------------------------------------
|
|
5
|
-
* v0.9 重构:不再使用独立 subHistory 隔离子循环,而是委托主 TAOR 引擎
|
|
6
|
-
* (runQuery / src/loop.ts)在共享 ctx.history 上执行。
|
|
7
|
-
*
|
|
8
|
-
* 实现要点:
|
|
9
|
-
* - 双源查找:cwd/skills/<name>/SKILL.md 优先,packageRoot/skills/ fallback
|
|
10
|
-
* - SKILL.md body 作为用户提示的一部分(系统提示词已在 history[0])
|
|
11
|
-
* - 执行结果直接写入共享 ctx.history,上下文自然积累
|
|
12
|
-
* - 流式转发:runQuery yield 的事件直接透传给 UI
|
|
13
|
-
* - maxTurns 可在 step 里覆盖(默认 25)
|
|
14
|
-
*
|
|
15
|
-
* capture:{ text: var_name } / { result: var_name }
|
|
16
|
-
* ============================================================
|
|
17
|
-
*/
|
|
18
|
-
import { readFile, readdir } from 'node:fs/promises';
|
|
19
|
-
import { join } from 'node:path';
|
|
20
|
-
import { getResourceSearchPaths, } from '../../../../src/plugin-sdk.js';
|
|
21
|
-
import { describeLlmFailure, describeMaxTurnsCutoff, effectiveGoalAnchor, runStepQuery, } from '../agentCommon.js';
|
|
22
|
-
import { interpolate } from '../expressions.js';
|
|
23
|
-
import { effectiveWorkflowCwd } from '../toolRuntime.js';
|
|
24
|
-
function stripFrontmatter(content) {
|
|
25
|
-
return content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
26
|
-
}
|
|
27
|
-
function parseFrontmatterName(content) {
|
|
28
|
-
const m = content.match(/^---\n([\s\S]*?)\n---/);
|
|
29
|
-
if (!m)
|
|
30
|
-
return null;
|
|
31
|
-
const nm = m[1].match(/^name:\s*(.+)$/m);
|
|
32
|
-
if (!nm)
|
|
33
|
-
return null;
|
|
34
|
-
return nm[1].trim().replace(/^["']|["']$/g, '');
|
|
35
|
-
}
|
|
36
|
-
async function findSkillFile(skillName, cwd) {
|
|
37
|
-
const roots = getResourceSearchPaths('skills', import.meta.url, cwd);
|
|
38
|
-
for (const root of roots) {
|
|
39
|
-
let entries;
|
|
40
|
-
try {
|
|
41
|
-
entries = await readdir(root, { withFileTypes: true });
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
for (const e of entries) {
|
|
47
|
-
if (!e.isDirectory())
|
|
48
|
-
continue;
|
|
49
|
-
const skillFile = join(root, e.name, 'SKILL.md');
|
|
50
|
-
if (e.name === skillName)
|
|
51
|
-
return skillFile;
|
|
52
|
-
try {
|
|
53
|
-
const md = await readFile(skillFile, 'utf8');
|
|
54
|
-
if (parseFrontmatterName(md) === skillName)
|
|
55
|
-
return skillFile;
|
|
56
|
-
}
|
|
57
|
-
catch { }
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
export async function* execSkillStep(step, vars, ctx) {
|
|
63
|
-
if (!step.skill)
|
|
64
|
-
throw new Error(`step ${step.id}: 缺少 skill 字段`);
|
|
65
|
-
const skillName = interpolate(step.skill, vars);
|
|
66
|
-
const skillFile = await findSkillFile(skillName, effectiveWorkflowCwd(ctx));
|
|
67
|
-
if (!skillFile) {
|
|
68
|
-
throw new Error(`step ${step.id}: 未找到 skill "${skillName}"(cwd/skills/ 与 packageRoot/skills/ 双源均未命中)`);
|
|
69
|
-
}
|
|
70
|
-
const md = await readFile(skillFile, 'utf8');
|
|
71
|
-
const body = stripFrontmatter(md).trim();
|
|
72
|
-
// 构造用户提示:skill 指令 + 步骤 input
|
|
73
|
-
// 系统提示词已在 history[0] 中(含完整 skill 列表和描述),
|
|
74
|
-
// 这里不需要再拼 system message——把 SKILL.md body 作为操作指令即可
|
|
75
|
-
const missing = [];
|
|
76
|
-
const userInput = step.input
|
|
77
|
-
? interpolate(step.input, vars, { onMissing: (e) => missing.push(e) })
|
|
78
|
-
: `请按以下 SKILL "${skillName}" 的指示完成任务。`;
|
|
79
|
-
const fullPrompt = `【执行 Skill:${skillName}】\n\n${body}\n\n---\n\n当前任务:\n${userInput}`;
|
|
80
|
-
// 通用目标锚定(原始目标 + 补充要求):确保 skill 执行时也不偏离
|
|
81
|
-
const anchor = effectiveGoalAnchor(ctx);
|
|
82
|
-
const effectivePrompt = anchor ? `${anchor}\n\n${fullPrompt}` : fullPrompt;
|
|
83
|
-
const maxTurns = step.maxTurns ?? 25;
|
|
84
|
-
if (missing.length > 0) {
|
|
85
|
-
yield {
|
|
86
|
-
type: 'warning',
|
|
87
|
-
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
// 委托 TAOR 引擎在共享 history 上执行(共享消费层 runStepQuery)。
|
|
91
|
-
// suppressTurnDone:turn_done 是 runQuery 单次调用的终结标记,不是 workflow 终结,
|
|
92
|
-
// 外泄会导致 gateway broker / -p json 模式误判 workflow 中途结束。
|
|
93
|
-
const { rawText, aborted, sawLlmError, sawMaxTurns, llmErrorDetail } = yield* runStepQuery(effectivePrompt, step, ctx, {
|
|
94
|
-
maxTurns,
|
|
95
|
-
suppressTurnDone: true,
|
|
96
|
-
});
|
|
97
|
-
const trimmed = rawText.trim();
|
|
98
|
-
// P0-1:LLM 失败(超时/网络错)且本步无任何产出 → 抛异常,触发 runner 的 max_retries 重跑。
|
|
99
|
-
// 用户中断(aborted)不该被当成可重试失败,按现状返回空结果即可。
|
|
100
|
-
if (!trimmed && sawLlmError && !aborted) {
|
|
101
|
-
throw new Error(describeLlmFailure(step.id, llmErrorDetail));
|
|
102
|
-
}
|
|
103
|
-
// 撞 maxTurns 截断 → 截断时产出不可信,抛可重试失败(续作语义,同 agent.ts)
|
|
104
|
-
if (sawMaxTurns && !aborted) {
|
|
105
|
-
throw new Error(describeMaxTurnsCutoff(step.id, maxTurns));
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
raw: { text: trimmed, result: trimmed },
|
|
109
|
-
preview: trimmed.length > 200 ? `${trimmed.slice(0, 200)}...` : trimmed,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ============================================================
|
|
3
|
-
* plugins/workflow-runner/src/stepExecutors/skill.ts —— skill 步骤执行器
|
|
4
|
-
* ------------------------------------------------------------
|
|
5
|
-
* v0.9 重构:不再使用独立 subHistory 隔离子循环,而是委托主 TAOR 引擎
|
|
6
|
-
* (runQuery / src/loop.ts)在共享 ctx.history 上执行。
|
|
7
|
-
*
|
|
8
|
-
* 实现要点:
|
|
9
|
-
* - 双源查找:cwd/skills/<name>/SKILL.md 优先,packageRoot/skills/ fallback
|
|
10
|
-
* - SKILL.md body 作为用户提示的一部分(系统提示词已在 history[0])
|
|
11
|
-
* - 执行结果直接写入共享 ctx.history,上下文自然积累
|
|
12
|
-
* - 流式转发:runQuery yield 的事件直接透传给 UI
|
|
13
|
-
* - maxTurns 可在 step 里覆盖(默认 25)
|
|
14
|
-
*
|
|
15
|
-
* capture:{ text: var_name } / { result: var_name }
|
|
16
|
-
* ============================================================
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { readFile, readdir } from 'node:fs/promises';
|
|
20
|
-
import { join } from 'node:path';
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
type LoopEvent,
|
|
24
|
-
getResourceSearchPaths,
|
|
25
|
-
} from '../../../../src/plugin-sdk.js';
|
|
26
|
-
import {
|
|
27
|
-
describeLlmFailure,
|
|
28
|
-
describeMaxTurnsCutoff,
|
|
29
|
-
effectiveGoalAnchor,
|
|
30
|
-
runStepQuery,
|
|
31
|
-
} from '../agentCommon.js';
|
|
32
|
-
import { interpolate } from '../expressions.js';
|
|
33
|
-
import { effectiveWorkflowCwd } from '../toolRuntime.js';
|
|
34
|
-
import type { RunContext, StepDef, StepResult, VarStack } from '../types.js';
|
|
35
|
-
|
|
36
|
-
function stripFrontmatter(content: string): string {
|
|
37
|
-
return content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function parseFrontmatterName(content: string): string | null {
|
|
41
|
-
const m = content.match(/^---\n([\s\S]*?)\n---/);
|
|
42
|
-
if (!m) return null;
|
|
43
|
-
const nm = m[1].match(/^name:\s*(.+)$/m);
|
|
44
|
-
if (!nm) return null;
|
|
45
|
-
return nm[1].trim().replace(/^["']|["']$/g, '');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function findSkillFile(
|
|
49
|
-
skillName: string,
|
|
50
|
-
cwd: string,
|
|
51
|
-
): Promise<string | null> {
|
|
52
|
-
const roots = getResourceSearchPaths('skills', import.meta.url, cwd);
|
|
53
|
-
|
|
54
|
-
for (const root of roots) {
|
|
55
|
-
let entries: { name: string; isDirectory: () => boolean }[];
|
|
56
|
-
try {
|
|
57
|
-
entries = await readdir(root, { withFileTypes: true });
|
|
58
|
-
} catch {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
for (const e of entries) {
|
|
62
|
-
if (!e.isDirectory()) continue;
|
|
63
|
-
const skillFile = join(root, e.name, 'SKILL.md');
|
|
64
|
-
if (e.name === skillName) return skillFile;
|
|
65
|
-
try {
|
|
66
|
-
const md = await readFile(skillFile, 'utf8');
|
|
67
|
-
if (parseFrontmatterName(md) === skillName) return skillFile;
|
|
68
|
-
} catch {}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function* execSkillStep(
|
|
75
|
-
step: StepDef,
|
|
76
|
-
vars: VarStack,
|
|
77
|
-
ctx: RunContext,
|
|
78
|
-
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
79
|
-
if (!step.skill) throw new Error(`step ${step.id}: 缺少 skill 字段`);
|
|
80
|
-
const skillName = interpolate(step.skill, vars);
|
|
81
|
-
|
|
82
|
-
const skillFile = await findSkillFile(skillName, effectiveWorkflowCwd(ctx));
|
|
83
|
-
if (!skillFile) {
|
|
84
|
-
throw new Error(
|
|
85
|
-
`step ${step.id}: 未找到 skill "${skillName}"(cwd/skills/ 与 packageRoot/skills/ 双源均未命中)`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
const md = await readFile(skillFile, 'utf8');
|
|
89
|
-
const body = stripFrontmatter(md).trim();
|
|
90
|
-
|
|
91
|
-
// 构造用户提示:skill 指令 + 步骤 input
|
|
92
|
-
// 系统提示词已在 history[0] 中(含完整 skill 列表和描述),
|
|
93
|
-
// 这里不需要再拼 system message——把 SKILL.md body 作为操作指令即可
|
|
94
|
-
const missing: string[] = [];
|
|
95
|
-
const userInput = step.input
|
|
96
|
-
? interpolate(step.input, vars, { onMissing: (e) => missing.push(e) })
|
|
97
|
-
: `请按以下 SKILL "${skillName}" 的指示完成任务。`;
|
|
98
|
-
|
|
99
|
-
const fullPrompt = `【执行 Skill:${skillName}】\n\n${body}\n\n---\n\n当前任务:\n${userInput}`;
|
|
100
|
-
|
|
101
|
-
// 通用目标锚定(原始目标 + 补充要求):确保 skill 执行时也不偏离
|
|
102
|
-
const anchor = effectiveGoalAnchor(ctx);
|
|
103
|
-
const effectivePrompt = anchor ? `${anchor}\n\n${fullPrompt}` : fullPrompt;
|
|
104
|
-
|
|
105
|
-
const maxTurns = step.maxTurns ?? 25;
|
|
106
|
-
|
|
107
|
-
if (missing.length > 0) {
|
|
108
|
-
yield {
|
|
109
|
-
type: 'warning',
|
|
110
|
-
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// 委托 TAOR 引擎在共享 history 上执行(共享消费层 runStepQuery)。
|
|
115
|
-
// suppressTurnDone:turn_done 是 runQuery 单次调用的终结标记,不是 workflow 终结,
|
|
116
|
-
// 外泄会导致 gateway broker / -p json 模式误判 workflow 中途结束。
|
|
117
|
-
const { rawText, aborted, sawLlmError, sawMaxTurns, llmErrorDetail } =
|
|
118
|
-
yield* runStepQuery(effectivePrompt, step, ctx, {
|
|
119
|
-
maxTurns,
|
|
120
|
-
suppressTurnDone: true,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const trimmed = rawText.trim();
|
|
124
|
-
|
|
125
|
-
// P0-1:LLM 失败(超时/网络错)且本步无任何产出 → 抛异常,触发 runner 的 max_retries 重跑。
|
|
126
|
-
// 用户中断(aborted)不该被当成可重试失败,按现状返回空结果即可。
|
|
127
|
-
if (!trimmed && sawLlmError && !aborted) {
|
|
128
|
-
throw new Error(describeLlmFailure(step.id, llmErrorDetail));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 撞 maxTurns 截断 → 截断时产出不可信,抛可重试失败(续作语义,同 agent.ts)
|
|
132
|
-
if (sawMaxTurns && !aborted) {
|
|
133
|
-
throw new Error(describeMaxTurnsCutoff(step.id, maxTurns));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
raw: { text: trimmed, result: trimmed },
|
|
138
|
-
preview: trimmed.length > 200 ? `${trimmed.slice(0, 200)}...` : trimmed,
|
|
139
|
-
};
|
|
140
|
-
}
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ============================================================
|
|
3
|
-
* plugins/workflow-runner/src/stepExecutors/tool.ts —— tool step 执行
|
|
4
|
-
* ------------------------------------------------------------
|
|
5
|
-
* 把 step.args 递归 ${var} 插值后 JSON.stringify,转发到 executeTool。
|
|
6
|
-
* 失败(ok=false)抛 Error,让 runner 走 onError 处理。
|
|
7
|
-
*
|
|
8
|
-
* v2(P1 TUI 可见):本执行器改为 AsyncGenerator,在调 executeTool 前后
|
|
9
|
-
* yield 通用 tool_start / tool_end LoopEvent —— 这样 workflow 的 tool 步骤
|
|
10
|
-
* 在 TUI 里像普通 ReAct 工具调用一样显示(runningTools spinner + 人话描述)。
|
|
11
|
-
*
|
|
12
|
-
* v0.9.3(上下文统一修复):tool 步骤执行后把工具调用摘要写入 ctx.history,
|
|
13
|
-
* 让后续 agent/llm/skill 步骤(走 runQuery → LLM)能自然看到前面步骤的工作成果,
|
|
14
|
-
* 不再依赖 VarStack 变量插值作为唯一的信息传递通道。
|
|
15
|
-
* 这实现了"一套上下文"架构:workflow 的每一步都在共享的 TAOR history 中留痕。
|
|
16
|
-
*
|
|
17
|
-
* capture 字段(支持点路径):
|
|
18
|
-
* - `{ content: var_name }` 绑 ToolResult.content(工具回执文本)
|
|
19
|
-
* - `{ result: var_name }` 同义,给"无结构化字段"工具用
|
|
20
|
-
* - `{ args.content: var_name }` 绑插值后传给工具的入参(如真正写入的内容)
|
|
21
|
-
* - `{ args.<任意字段>: var_name }` 绑入参的具名字段
|
|
22
|
-
* ============================================================
|
|
23
|
-
*/
|
|
24
|
-
import { randomUUID } from 'node:crypto';
|
|
25
|
-
import { existsSync } from 'node:fs';
|
|
26
|
-
import { resolve } from 'node:path';
|
|
27
|
-
import { executeTool, getToolByName, recordRead, } from '../../../../src/plugin-sdk.js';
|
|
28
|
-
import { interpolateDeep } from '../expressions.js';
|
|
29
|
-
import { buildWorkflowToolContext, effectiveWorkflowCwd, } from '../toolRuntime.js';
|
|
30
|
-
import { safeArtifactPath } from '../types.js';
|
|
31
|
-
export async function* execToolStep(step, vars, ctx) {
|
|
32
|
-
if (!step.tool)
|
|
33
|
-
throw new Error(`step ${step.id}: 缺少 tool 字段`);
|
|
34
|
-
const tool = getToolByName(step.tool);
|
|
35
|
-
if (!tool)
|
|
36
|
-
throw new Error(`step ${step.id}: 未知工具 "${step.tool}"`);
|
|
37
|
-
if (!ctx.tools.some((available) => available.name === tool.name)) {
|
|
38
|
-
throw new Error(`step ${step.id}: 工具 "${tool.name}" 不在当前宿主授权的 Workflow 工具集中`);
|
|
39
|
-
}
|
|
40
|
-
// 未定义变量插值可见化(args 里静默空串会让工具拿到空路径/空内容)
|
|
41
|
-
const missing = [];
|
|
42
|
-
const args = interpolateDeep(step.args ?? {}, vars, {
|
|
43
|
-
onMissing: (e) => missing.push(e),
|
|
44
|
-
});
|
|
45
|
-
if (missing.length > 0) {
|
|
46
|
-
yield {
|
|
47
|
-
type: 'warning',
|
|
48
|
-
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
const argsJson = JSON.stringify(args);
|
|
52
|
-
const toolCallId = `wf_${step.id}`;
|
|
53
|
-
const argsPreview = argsJson.length > 80 ? `${argsJson.slice(0, 80)}…` : argsJson;
|
|
54
|
-
yield {
|
|
55
|
-
type: 'tool_start',
|
|
56
|
-
toolName: tool.name,
|
|
57
|
-
toolCallId,
|
|
58
|
-
argsPreview,
|
|
59
|
-
argsFriendly: friendlyToolDesc(tool.name, args),
|
|
60
|
-
};
|
|
61
|
-
// ════ 声明产物覆盖判定(解 Write/Edit 的 pre-read 守卫) ════
|
|
62
|
-
// 内核写类工具有「文件已存在必须先 Read」守卫(fileState 按会话隔离,
|
|
63
|
-
// 跨进程 / resume / 残留旧产物时可能为空)。确定性 tool 步的 args 是 yaml 作者
|
|
64
|
-
// 写死的,模型没有机会先 Read —— 目标文件若是工作流**声明的产物**
|
|
65
|
-
// (def 级 + step 级 artifacts:,= 工作流自己拥有、本就要覆盖的文件),
|
|
66
|
-
// 这里自动 pre-Read 一次解除守卫(管线动作,不 yield 事件、结果丢弃)。
|
|
67
|
-
// 非声明产物的盲写保护原样生效;pre-Read 失败也不拦,让写工具自己报错。
|
|
68
|
-
await preReadDeclaredArtifact(tool, args, step, ctx);
|
|
69
|
-
// 宿主能力按 `uses:` 切片后转发。`executeTool` 的第四参此前从未传过 ——
|
|
70
|
-
// 这正是「workflow 里 ComputerUse 恒失败」的末端表现。
|
|
71
|
-
const pendingProgress = [];
|
|
72
|
-
let wakeProgress;
|
|
73
|
-
const toolContext = buildWorkflowToolContext(step, ctx, toolCallId, (message, detail) => {
|
|
74
|
-
pendingProgress.push({
|
|
75
|
-
type: 'tool_progress',
|
|
76
|
-
toolName: tool.name,
|
|
77
|
-
toolCallId,
|
|
78
|
-
message,
|
|
79
|
-
detail,
|
|
80
|
-
});
|
|
81
|
-
wakeProgress?.();
|
|
82
|
-
});
|
|
83
|
-
if ('error' in toolContext) {
|
|
84
|
-
throw new Error(`step ${step.id}: ${toolContext.error}`);
|
|
85
|
-
}
|
|
86
|
-
const dispatch = ctx.executeTool ?? executeTool;
|
|
87
|
-
let settled = false;
|
|
88
|
-
let result;
|
|
89
|
-
void dispatch(tool.name, argsJson, ctx.signal, toolContext)
|
|
90
|
-
.then((value) => {
|
|
91
|
-
result = value;
|
|
92
|
-
})
|
|
93
|
-
.catch((error) => {
|
|
94
|
-
result = {
|
|
95
|
-
ok: false,
|
|
96
|
-
error: error instanceof Error ? error.message : String(error),
|
|
97
|
-
};
|
|
98
|
-
})
|
|
99
|
-
.finally(() => {
|
|
100
|
-
settled = true;
|
|
101
|
-
wakeProgress?.();
|
|
102
|
-
});
|
|
103
|
-
while (!settled || pendingProgress.length > 0) {
|
|
104
|
-
const progress = pendingProgress.shift();
|
|
105
|
-
if (progress) {
|
|
106
|
-
yield progress;
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
await new Promise((resolveWake) => {
|
|
110
|
-
wakeProgress = resolveWake;
|
|
111
|
-
if (settled || pendingProgress.length > 0)
|
|
112
|
-
resolveWake();
|
|
113
|
-
});
|
|
114
|
-
wakeProgress = undefined;
|
|
115
|
-
}
|
|
116
|
-
if (!result)
|
|
117
|
-
throw new Error(`step ${step.id}: 工具执行未返回结果`);
|
|
118
|
-
yield {
|
|
119
|
-
type: 'tool_end',
|
|
120
|
-
toolName: tool.name,
|
|
121
|
-
toolCallId,
|
|
122
|
-
ok: result.ok,
|
|
123
|
-
content: result.ok ? result.content : result.error,
|
|
124
|
-
metadata: result.metadata,
|
|
125
|
-
};
|
|
126
|
-
if (!result.ok) {
|
|
127
|
-
throw new Error(result.error);
|
|
128
|
-
}
|
|
129
|
-
const content = result.content;
|
|
130
|
-
// ════ v0.9.3:上下文统一 —— 把工具调用写入共享 history ════
|
|
131
|
-
// 后续 agent/llm/skill 步骤走 runQuery() 时,LLM 能在上下文中看到
|
|
132
|
-
// 这步做了什么(与正常 TAOR 循环中 tool_call → tool_result 的记录方式一致)。
|
|
133
|
-
// 只记录精简摘要(不把完整工具回执塞入 history,避免 token 浪费)。
|
|
134
|
-
const summary = content.length > 500
|
|
135
|
-
? `${content.slice(0, 500)}…(已截断,共 ${content.length} 字符)`
|
|
136
|
-
: content;
|
|
137
|
-
ctx.history.push({
|
|
138
|
-
role: 'assistant',
|
|
139
|
-
content: `[workflow:${step.id}] ✅ ${tool.name} 执行完成:${summary}`,
|
|
140
|
-
timestamp: Date.now(),
|
|
141
|
-
id: randomUUID(),
|
|
142
|
-
});
|
|
143
|
-
// ⚠️ 工具返回的图片**不能丢**。此前这里只取 content,`visionImages` 被静默丢弃 ——
|
|
144
|
-
// 于是任何「截图/看图」类工作流都拿不到产物,而且不会报错,只是后面的评估步没图可看。
|
|
145
|
-
// 取路径而不是整个 ImageInputSpec:yaml 侧要的是能 capture、能传给 llm 步 `images:`
|
|
146
|
-
// 的字符串;结构体传下去反而要每个消费方各自解包。
|
|
147
|
-
const images = (result.visionImages ?? [])
|
|
148
|
-
.map((image) => (typeof image.source === 'string' ? image.source : ''))
|
|
149
|
-
.filter((path) => path.length > 0);
|
|
150
|
-
return {
|
|
151
|
-
raw: {
|
|
152
|
-
content,
|
|
153
|
-
result: content,
|
|
154
|
-
args,
|
|
155
|
-
images,
|
|
156
|
-
metadata: result.metadata,
|
|
157
|
-
recovery: result.recovery,
|
|
158
|
-
sensitivity: result.sensitivity,
|
|
159
|
-
visionNote: result.visionNote,
|
|
160
|
-
},
|
|
161
|
-
preview: content.length > 200 ? `${content.slice(0, 200)}...` : content,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* 写类 tool 步的目标文件若命中【安全的声明产物】且已存在 → pre-Read 解除内核守卫。
|
|
166
|
-
*
|
|
167
|
-
* 路径归一化:artifacts 声明相对 cwd;args.file_path 可能是 ./相对 或 绝对,
|
|
168
|
-
* 双方都 resolve(cwd, …) 后比较(win32 文件系统大小写不敏感 → lowercase 比较;
|
|
169
|
-
* 其余平台保持大小写敏感,避免 Plan.md / plan.md 误判同文件)。
|
|
170
|
-
*
|
|
171
|
-
* 安全守卫(修复路径遍历):
|
|
172
|
-
* · 声明的 artifacts 路径先经 safeArtifactPath 校验【必须落在 cwd 内】,
|
|
173
|
-
* 越界声明直接从命中列表移除——不解守卫,让内核写保护照常生效(fail-closed)。
|
|
174
|
-
* · args.file_path 目标自身也做 cwd 内校验:目标越界(工作流步骤想写 cwd 外)
|
|
175
|
-
* → 同样不解守卫,让写工具在执行时自己报错(通常是权限/文件不存在提示,
|
|
176
|
-
* 而不是静默放行盲写,双重保险)。
|
|
177
|
-
*/
|
|
178
|
-
async function preReadDeclaredArtifact(tool, args, step, ctx) {
|
|
179
|
-
if (tool.isReadOnly !== false)
|
|
180
|
-
return; // 只对写类工具生效
|
|
181
|
-
if (typeof args.file_path !== 'string')
|
|
182
|
-
return;
|
|
183
|
-
const cwd = effectiveWorkflowCwd(ctx);
|
|
184
|
-
const norm = (p) => {
|
|
185
|
-
const abs = resolve(cwd, p);
|
|
186
|
-
return process.platform === 'win32' ? abs.toLowerCase() : abs;
|
|
187
|
-
};
|
|
188
|
-
// 1. 目标文件先过 cwd 安全关(越界直接不解守卫)
|
|
189
|
-
const targetRaw = String(args.file_path);
|
|
190
|
-
const targetSafe = safeArtifactPath(cwd, targetRaw);
|
|
191
|
-
if (targetSafe === null)
|
|
192
|
-
return;
|
|
193
|
-
const target = norm(targetSafe);
|
|
194
|
-
// 2. 声明产物过 cwd 安全关(过滤掉越界的声明)
|
|
195
|
-
const rawDeclared = [...(ctx.declaredArtifacts ?? []), ...(step.artifacts ?? [])];
|
|
196
|
-
const declaredAbs = [];
|
|
197
|
-
for (const raw of rawDeclared) {
|
|
198
|
-
const safe = safeArtifactPath(cwd, raw);
|
|
199
|
-
if (safe !== null)
|
|
200
|
-
declaredAbs.push(norm(safe));
|
|
201
|
-
}
|
|
202
|
-
if (!declaredAbs.some((a) => a === target))
|
|
203
|
-
return;
|
|
204
|
-
const abs = resolve(cwd, targetSafe);
|
|
205
|
-
if (!existsSync(abs))
|
|
206
|
-
return; // 新建文件不需要解守卫
|
|
207
|
-
// 直接登记一次「完整已读」状态解除内核 pre-read 守卫——不真正 Read 内容:
|
|
208
|
-
// 1. 声明产物本就要被本步整体覆盖,旧内容无需进上下文/烧 token;
|
|
209
|
-
// 2. 真 Read 大文件会触发字符上限截断(read.ts → recordRead({truncated:true})),
|
|
210
|
-
// 反而踩中 Write 的「截断禁写」硬守卫(write.ts: existsSync && wasTruncated → 拒绝),
|
|
211
|
-
// 正是本步要解除的同一道墙——曾导致 plan.yaml 回写变长的 PLAN.md 时 halt
|
|
212
|
-
// (首轮新建 PLAN.md 不存在直接放行,审批反馈后回写已存在的大 PLAN.md 被挡死)。
|
|
213
|
-
// 两道守卫(never-read + truncated)必须一并解除,声明产物的整体覆盖才算真正授权。
|
|
214
|
-
// recordRead 内部自带 statSync 失败兜底(返回 1、不抛),无需再包 try/catch。
|
|
215
|
-
recordRead(abs, { truncated: false }, ctx.sessionState?.fileReads);
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* 给 tool_start 生成人话描述(LiveArea spinner 行用)。
|
|
219
|
-
*/
|
|
220
|
-
function friendlyToolDesc(toolName, args) {
|
|
221
|
-
const key = ['file_path', 'command', 'query', 'pattern', 'path', 'url'].find((k) => typeof args[k] === 'string');
|
|
222
|
-
if (!key)
|
|
223
|
-
return toolName;
|
|
224
|
-
const val = String(args[key]);
|
|
225
|
-
const short = val.length > 60 ? `${val.slice(0, 60)}…` : val;
|
|
226
|
-
return `${toolName} ${short}`;
|
|
227
|
-
}
|