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.
- package/README.md +6 -5
- package/package.json +62 -5
- 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 +204 -185
- package/plugins/workflow-runner/src/index.ts +249 -224
- 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 +404 -467
- package/plugins/workflow-runner/src/runner.ts +491 -535
- 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 +172 -152
- package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
- 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 -105
- package/plugins/workflow-runner/src/types.ts +155 -520
- 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 +542 -469
- package/plugins/workflow-runner/src/workflowState.ts +639 -589
- 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/skill-creator/scripts/run_eval.py +3 -2
- 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 +503 -0
- package/src/advisor/advisorCoordinator.ts +657 -0
- package/src/cli/configMenu.tsx +0 -1
- package/src/cli/print.js +44 -6
- package/src/cli/print.ts +73 -4
- 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/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 +443 -74
- package/src/config/configService.ts +723 -142
- 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 +56 -20
- package/src/infra/verification.ts +87 -20
- 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 +319 -54
- package/src/loop.ts +373 -57
- 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 +152 -9
- package/src/plugins/pluginRunner.ts +186 -8
- package/src/plugins/slashFallback.js +113 -0
- package/src/plugins/slashFallback.ts +137 -0
- package/src/prompts/policyRegistry.js +15 -8
- package/src/prompts/policyRegistry.ts +18 -8
- 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 +148 -37
- package/src/tools/advisor/advisor.ts +161 -38
- 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 +70 -18
- package/src/tools/bash/bash.ts +75 -20
- 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/powershell/powershell.js +18 -1
- package/src/tools/powershell/powershell.ts +18 -2
- package/src/tools/presentresult/presentresult.js +6 -15
- package/src/tools/presentresult/presentresult.ts +6 -15
- package/src/tools/read/read.js +69 -11
- package/src/tools/read/read.ts +70 -11
- package/src/tools/shared/fileUtils.js +1 -2
- package/src/tools/shared/fileUtils.ts +1 -2
- package/src/tools/shared/permanentDeleteGuard.js +34 -3
- package/src/tools/shared/permanentDeleteGuard.ts +43 -6
- 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 +117 -0
- package/src/tools/toolPromptGuides.ts +137 -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 -30
- package/src/tools/webbrowser/browserControl.ts +210 -50
- 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 +683 -144
- package/src/tools/webbrowser/webbrowser.ts +979 -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 +450 -42
- 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/DESIGN.md +449 -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 -618
- package/plugins/workflow-runner/src/expressions.ts +0 -622
- 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 -119
- package/plugins/workflow-runner/src/recovery.ts +0 -149
- 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 -41
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
- 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 -208
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
- package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
- 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 -147
- 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/engineRobustness.test.ts +0 -226
- package/plugins/workflow-runner/test/expressions.test.ts +0 -397
- 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 -87
- 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 -220
- package/plugins/workflow-runner/test/recovery.test.ts +0 -265
- package/plugins/workflow-runner/test/runner.test.ts +0 -911
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
- package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
- package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
- 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 -199
- 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
|
@@ -1,130 +1,177 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* plugins/workflow-runner/src/taskIdentity.ts —— 任务身份与状态目录布局
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 状态根目录优先级:
|
|
6
|
+
* 1. 环境变量 MINIMAL_AGENT_WORKFLOW_STATE_DIR(全局统一目录)
|
|
7
|
+
* 2. <cwd>/.minimal-agent-workflow/(默认)
|
|
8
|
+
*
|
|
9
|
+
* 目录结构(四级):
|
|
10
|
+
* <stateRoot>/<workflow>/<sessionId>/<taskId>/ ← 活动任务实例
|
|
11
|
+
* <stateRoot>/<workflow>/<sessionId>/<taskId>.done/ ← 成功归档
|
|
12
|
+
* <stateRoot>/<workflow>/<sessionId>/<taskId>.trash/ ← 产物淘汰回收
|
|
13
|
+
*
|
|
14
|
+
* ------------------------------------------------------------
|
|
15
|
+
* ⚠️ **为什么是 session 与 taskId 两层,而不是二选一**(这条改之前务必读完)
|
|
16
|
+
*
|
|
17
|
+
* legacy 的演进history是这样的:
|
|
18
|
+
* - Phase 2:加 taskId 实例层,根治「同名工作流跑新任务把旧状态清掉」
|
|
19
|
+
* - Phase 3:实例目录名**改成** sessionId,taskId 降级为记录字段,换来多
|
|
20
|
+
* session 真正并行
|
|
21
|
+
*
|
|
22
|
+
* Phase 3 用「换掉」而不是「叠加」,于是 Phase 2 解决的问题原样回来了:同一个
|
|
23
|
+
* session 里连着研究两个不同主题,第二次启动时前一次的声明产物会被归档进
|
|
24
|
+
* `.trash/`,工作目录里只剩最新一份。
|
|
25
|
+
*
|
|
26
|
+
* legacy 对此的补偿是「宿主没给显式 session 就自动生成一个带时间戳的」,但那让
|
|
27
|
+
* resume 彻底失效 —— 时间每次都不同,于是**每次运行都是一个新 session**,
|
|
28
|
+
* 断点续跑、completed 判定、语义仲裁全部够不着。实测复现过:同一个 goal 连跑
|
|
29
|
+
* 两次,产生两个独立的 `.done` 目录,第二次没有命中 completed 而是从头重跑。
|
|
30
|
+
*
|
|
31
|
+
* 两个维度本来就是正交的,不该二选一:
|
|
32
|
+
* - sessionId 管**并行隔离**(不同会话互不干扰)
|
|
33
|
+
* - taskId 管**任务身份**(同一件事 → 同一个目录 → 能 resume)
|
|
34
|
+
* 两层都留下,三个需求同时成立:
|
|
35
|
+
* 同 session 同 goal → 同目录 → resume ✓
|
|
36
|
+
* 同 session 换主题 → 不同目录 → **不覆盖** ✓
|
|
37
|
+
* 不同 session → 不同目录 → 并行 ✓
|
|
38
|
+
*
|
|
39
|
+
* 相应地本文件**不提供** `generateDefaultSessionId`:宿主给什么 session 就用
|
|
40
|
+
* 什么(含 `default`)。它当初存在的理由已由 taskId 层从结构上消除。
|
|
41
|
+
* ============================================================
|
|
42
|
+
*/
|
|
43
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
44
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
4
45
|
import { chat as sdkChat, executeTool as sdkExecuteTool, } from '../../../src/plugin-sdk.js';
|
|
5
|
-
import { truncate } from './agentCommon.js';
|
|
6
46
|
import { extractJsonPayload } from './jsonPayload.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// ------------------------------------------------------------
|
|
10
|
-
// <cwd>/.minimal-agent-workflow/<name>/ ← 每个工作流独立状态
|
|
11
|
-
// <cwd>/.minimal-agent-workflow/<name>.done/ ← 成功归档
|
|
12
|
-
// 曾经一个 cwd 单例目录:A(如 /plan)未完成时跑不同名工作流 B,
|
|
13
|
-
// init 的 new-task 路径会清掉 A 的声明产物 + 整个状态目录,A 永久失去
|
|
14
|
-
// resume 能力——与「不同任务中间文件互不干扰」需求直接冲突。
|
|
15
|
-
// 按名隔离后跨工作流互不可见,互踩从结构上消失。
|
|
16
|
-
// /new 的前缀清理(.minimal-agent*)作用于父目录,行为不变。
|
|
17
|
-
// ============================================================
|
|
18
|
-
/** 工作流状态目录的父目录名(/new 按 .minimal-agent 前缀整体清理)。 */
|
|
47
|
+
import { truncate } from './util.js';
|
|
48
|
+
/** 工作流状态目录的父目录名(落在 cwd 下时使用)。 */
|
|
19
49
|
export const WF_STATE_PARENT = '.minimal-agent-workflow';
|
|
20
|
-
/**
|
|
50
|
+
/** 全局统一状态目录的环境变量名。 */
|
|
51
|
+
export const WF_STATE_DIR_ENV = 'MINIMAL_AGENT_WORKFLOW_STATE_DIR';
|
|
52
|
+
/** 宿主未指定 session 时的缺省名。**不再**据此自动生成带时间戳的 session。 */
|
|
53
|
+
export const DEFAULT_SESSION_ID = 'default';
|
|
54
|
+
/**
|
|
55
|
+
* 解析状态根目录(绝对路径)。
|
|
56
|
+
* 环境变量允许写相对路径(用户可能写 `.wflow` 这类值),基于 process.cwd() 展开。
|
|
57
|
+
*/
|
|
58
|
+
export function resolveStateRoot(workingDir) {
|
|
59
|
+
const envDir = process.env[WF_STATE_DIR_ENV];
|
|
60
|
+
if (envDir?.trim()) {
|
|
61
|
+
const p = envDir.trim();
|
|
62
|
+
return isAbsolute(p) ? p : resolve(p);
|
|
63
|
+
}
|
|
64
|
+
return join(workingDir, WF_STATE_PARENT);
|
|
65
|
+
}
|
|
66
|
+
/** 清洗成安全目录名(保留字母数字 . _ -,其余换成 -)。 */
|
|
21
67
|
export function sanitizeWorkflowDirName(name) {
|
|
22
68
|
return name.replace(/[^\w.-]/g, '-');
|
|
23
69
|
}
|
|
24
|
-
/**
|
|
70
|
+
/** 某工作流的状态目录(其下按 session 再分)。 */
|
|
25
71
|
export function workflowStateDir(workingDir, workflowName) {
|
|
26
|
-
return join(workingDir,
|
|
72
|
+
return join(resolveStateRoot(workingDir), sanitizeWorkflowDirName(workflowName));
|
|
73
|
+
}
|
|
74
|
+
/** 某工作流在某 session 下的目录(其下按 taskId 再分)。 */
|
|
75
|
+
export function sessionStateDir(workingDir, workflowName, sessionId) {
|
|
76
|
+
return join(workflowStateDir(workingDir, workflowName), sanitizeWorkflowDirName(sessionId));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 一个具体任务实例的状态目录。
|
|
80
|
+
* 成功后改名 `<taskId>.done/`;产物淘汰归档到 `<taskId>.trash/`。
|
|
81
|
+
*/
|
|
82
|
+
export function taskInstanceDir(workingDir, workflowName, sessionId, taskId) {
|
|
83
|
+
return join(sessionStateDir(workingDir, workflowName, sessionId), sanitizeWorkflowDirName(taskId));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 归一化 goal:小写 → 去标点(保留中日韩/字母/数字/空格)→ 压缩空格 → 截断 200。
|
|
87
|
+
*
|
|
88
|
+
* 截断是刻意的:超长输入里靠后的细微差异不该让「同一件事」算成两个任务。
|
|
89
|
+
*/
|
|
90
|
+
function normalizeGoal(raw) {
|
|
91
|
+
return raw
|
|
92
|
+
.toLowerCase()
|
|
93
|
+
.replace(/[^\p{L}\p{N}\s]/gu, '')
|
|
94
|
+
.replace(/\s+/g, ' ')
|
|
95
|
+
.trim()
|
|
96
|
+
.slice(0, 200);
|
|
27
97
|
}
|
|
28
98
|
/**
|
|
29
|
-
*
|
|
99
|
+
* 任务身份 = SHA256(工作流名 + 归一化 goal) 前 16 位。
|
|
30
100
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* - 同 hash → 同一任务(无论隔了多久);hash 不同 → 不同任务。
|
|
34
|
-
* - recency(上次 startedAt 的时间窗口)【不】参与身份判定:30 分钟内换一个
|
|
35
|
-
* 完全不同的 goal 重跑同名 workflow,必须判「全新任务」清理重开,而不是
|
|
36
|
-
* 错误地 resume 旧任务把旧变量混进新目标(需求 3.2「不相关新任务自动清理重开」)。
|
|
37
|
-
* 旧版「时间窗口覆盖 hash 差异」是 bug,已移除。
|
|
101
|
+
* **纯函数,不读盘** —— 这是四级布局带来的简化:taskId 就是目录名,「是不是同一个
|
|
102
|
+
* 任务」等价于「那个目录在不在」,不必再扫描实例目录逐个比对记录字段。
|
|
38
103
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* - 去除多余空格(连续空格→单空格,首尾 trim)
|
|
43
|
-
* - 截断到 200 字符(防止超长输入导致不必要的差异)
|
|
104
|
+
* ⚠️ 时间**不参与**身份判定。半小时内换一个完全不同的 goal 重跑同名工作流,
|
|
105
|
+
* 必须判成全新任务,而不是 resume 旧任务把旧变量混进新目标里。legacy 早期
|
|
106
|
+
* 「时间窗口覆盖 hash 差异」的写法是 bug,已移除,别加回来。
|
|
44
107
|
*/
|
|
45
|
-
export function computeTaskId(workflowName, inputs,
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
hash: contentHash,
|
|
68
|
-
isSameTask: false,
|
|
69
|
-
reason: 'no_previous',
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
const stateContent = readFileSync(stateFilePath, 'utf-8');
|
|
74
|
-
const prevState = JSON.parse(stateContent);
|
|
75
|
-
// a. 不同 workflow 名 → 不同任务
|
|
76
|
-
if (prevState.name && prevState.name !== workflowName) {
|
|
77
|
-
return {
|
|
78
|
-
hash: contentHash,
|
|
79
|
-
isSameTask: false,
|
|
80
|
-
reason: 'different_workflow',
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
// b. 内容 hash 一致 → 同一任务(唯一权威信号,与时间无关)
|
|
84
|
-
if (prevState.taskId === contentHash) {
|
|
85
|
-
return {
|
|
86
|
-
hash: contentHash,
|
|
87
|
-
isSameTask: true,
|
|
88
|
-
reason: 'hash_match',
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
// c. hash 不一致 → 不同任务(goal 变了)。recency 不覆盖此判定(见函数头注)。
|
|
92
|
-
return {
|
|
93
|
-
hash: contentHash,
|
|
94
|
-
isSameTask: false,
|
|
95
|
-
reason: 'hash_diff',
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// 解析失败时返回默认结果
|
|
100
|
-
return {
|
|
101
|
-
hash: contentHash,
|
|
102
|
-
isSameTask: false,
|
|
103
|
-
reason: 'no_previous',
|
|
104
|
-
};
|
|
105
|
-
}
|
|
108
|
+
export function computeTaskId(workflowName, inputs, defs) {
|
|
109
|
+
const goal = normalizeGoal(extractGoal(inputs, defs));
|
|
110
|
+
const resourceFingerprint = typeof inputs.__resource_fingerprint === 'string'
|
|
111
|
+
? inputs.__resource_fingerprint.trim()
|
|
112
|
+
: '';
|
|
113
|
+
// Typed resource workflows also have processing parameters (format, range,
|
|
114
|
+
// language, etc.). Equal source bytes with different parameters must not hit
|
|
115
|
+
// completed before the script can observe the new arguments. Keep the legacy
|
|
116
|
+
// goal-only identity for workflows without resource bindings.
|
|
117
|
+
const parameters = resourceFingerprint
|
|
118
|
+
? (defs ?? [])
|
|
119
|
+
.filter((d) => d.type !== 'resource' && !['goal', 'requestText'].includes(d.name))
|
|
120
|
+
.map((d) => [d.name, inputs[d.name] ?? d.default ?? null])
|
|
121
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
122
|
+
: [];
|
|
123
|
+
// 资源是任务身份的一部分,而不是目标锚的一部分。这样模型仍只看到人类可读
|
|
124
|
+
// 目标,但同一句“帮我整理成 Word”配不同附件不会误命中上一份已完成产物。
|
|
125
|
+
const identity = resourceFingerprint
|
|
126
|
+
? `${workflowName} ${goal}\nresource:${resourceFingerprint}${parameters.length ? '\nparameters:' + JSON.stringify(parameters) : ''}`
|
|
127
|
+
: `${workflowName} ${goal}`;
|
|
128
|
+
return createHash('sha256').update(identity).digest('hex').slice(0, 16);
|
|
106
129
|
}
|
|
107
130
|
/**
|
|
108
|
-
* 从 inputs
|
|
131
|
+
* 从 inputs 里提取「目标」文本。**任务身份与目标锚共用这一份规则** ——
|
|
132
|
+
* 两处各写一套会让「拿来算 taskId 的目标」和「注入给模型的目标」指向不同的东西。
|
|
133
|
+
*
|
|
134
|
+
* 取值顺序:
|
|
135
|
+
* ① 名为 `goal` 的输入
|
|
136
|
+
* ② 第一个 **required** 的字符串输入(作者用 required 表达了「这是主要输入」)
|
|
137
|
+
* ③ 第一个非空字符串输入
|
|
138
|
+
* ④ 整体 JSON(保证恒有确定值)
|
|
109
139
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
140
|
+
* ⚠️ 第 ③ 条曾经写的是「长度 **> 2** 的字符串」。那条阈值是照拉丁文本想的
|
|
141
|
+
* (跳过 `ab`、语言代码之类),**对中文直接失效** —— `世界`、`调研` 这种两个字的
|
|
142
|
+
* 目标太常见了,会被跳过去落到 ④,于是 current.json 里记的目标变成一坨 JSON、
|
|
143
|
+
* 仲裁时喂给 LLM 的也是那坨 JSON。端到端实跑复现过(/workflow e2e-smoke 世界)。
|
|
114
144
|
*/
|
|
115
|
-
export function extractGoal(inputs) {
|
|
116
|
-
|
|
117
|
-
if (typeof inputs.goal === 'string') {
|
|
145
|
+
export function extractGoal(inputs, defs) {
|
|
146
|
+
if (typeof inputs.goal === 'string' && inputs.goal.trim()) {
|
|
118
147
|
return inputs.goal;
|
|
119
148
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (
|
|
149
|
+
for (const def of defs ?? []) {
|
|
150
|
+
const v = inputs[def.name];
|
|
151
|
+
if (def.type !== 'resource' &&
|
|
152
|
+
def.required &&
|
|
153
|
+
typeof v === 'string' &&
|
|
154
|
+
v.trim())
|
|
155
|
+
return v;
|
|
156
|
+
}
|
|
157
|
+
if (typeof inputs.requestText === 'string' && inputs.requestText.trim())
|
|
158
|
+
return inputs.requestText;
|
|
159
|
+
const resourceNames = new Set((defs ?? []).filter((d) => d.type === 'resource').map((d) => d.name));
|
|
160
|
+
for (const [name, value] of Object.entries(inputs)) {
|
|
161
|
+
if (resourceNames.has(name) || name === '__resource_fingerprint')
|
|
162
|
+
continue;
|
|
163
|
+
if (typeof value === 'string' && value.trim())
|
|
123
164
|
return value;
|
|
124
|
-
}
|
|
125
165
|
}
|
|
126
|
-
|
|
127
|
-
|
|
166
|
+
if (typeof inputs.__resource_fingerprint === 'string' &&
|
|
167
|
+
inputs.__resource_fingerprint.trim()) {
|
|
168
|
+
return `resource:${inputs.__resource_fingerprint}`;
|
|
169
|
+
}
|
|
170
|
+
const sanitized = { ...inputs };
|
|
171
|
+
for (const name of resourceNames)
|
|
172
|
+
if (name in sanitized)
|
|
173
|
+
sanitized[name] = '<resource>';
|
|
174
|
+
return JSON.stringify(sanitized);
|
|
128
175
|
}
|
|
129
176
|
/** 延续短语白名单(归一化后精确匹配;短输入再放宽到前缀匹配)。 */
|
|
130
177
|
const CONTINUATION_PHRASES = new Set([
|
|
@@ -146,49 +193,42 @@ const CONTINUATION_PHRASES = new Set([
|
|
|
146
193
|
'keep going',
|
|
147
194
|
'carry on',
|
|
148
195
|
]);
|
|
149
|
-
/**
|
|
196
|
+
/** 新输入是否是「延续上次任务」的指令(快路径,不花 LLM)。 */
|
|
150
197
|
export function isContinuationPhrase(rawGoal) {
|
|
151
198
|
const norm = normalizeGoal(rawGoal);
|
|
152
199
|
if (!norm)
|
|
153
200
|
return false;
|
|
154
201
|
if (CONTINUATION_PHRASES.has(norm))
|
|
155
202
|
return true;
|
|
156
|
-
//
|
|
157
|
-
|
|
203
|
+
// 短输入且以延续词开头(「继续干活」「continue please」)也算
|
|
204
|
+
return (norm.length <= 12 &&
|
|
158
205
|
(norm.startsWith('继续') ||
|
|
159
206
|
norm.startsWith('接着') ||
|
|
160
207
|
norm.startsWith('continue') ||
|
|
161
|
-
norm.startsWith('resume')))
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
return false;
|
|
208
|
+
norm.startsWith('resume')));
|
|
165
209
|
}
|
|
166
210
|
/**
|
|
167
|
-
*
|
|
168
|
-
* runner 在 state.init 前构建并传入;任何一级抛错都降级到下一级,绝不让仲裁本身 halt 工作流。
|
|
211
|
+
* 构建复合仲裁器。任何一级抛错都降级到下一级 —— **仲裁本身绝不 halt 工作流**。
|
|
169
212
|
*/
|
|
170
213
|
export function buildTaskArbitrator(deps) {
|
|
171
214
|
const note = (m) => {
|
|
172
215
|
deps.notes?.push(m);
|
|
173
216
|
};
|
|
174
217
|
return async (actx) => {
|
|
175
|
-
// a. 延续短语快路径
|
|
176
218
|
if (isContinuationPhrase(actx.newGoal)) {
|
|
177
219
|
note(`任务仲裁:新输入「${truncate(actx.newGoal, 40)}」命中延续短语 → 继续旧任务(目标:${truncate(actx.prevGoal, 60)})`);
|
|
178
220
|
return 'resume';
|
|
179
221
|
}
|
|
180
|
-
// b. LLM 单轮仲裁
|
|
181
222
|
try {
|
|
182
223
|
const verdict = await llmArbitrate(deps, actx);
|
|
183
224
|
if (verdict !== 'unsure') {
|
|
184
|
-
note(`任务仲裁:LLM 判定新输入${verdict === 'resume' ? '是旧任务的延续 → 续跑' : '是全新任务 →
|
|
225
|
+
note(`任务仲裁:LLM 判定新输入${verdict === 'resume' ? '是旧任务的延续 → 续跑' : '是全新任务 → 归档旧产物重开'}`);
|
|
185
226
|
return verdict;
|
|
186
227
|
}
|
|
187
228
|
}
|
|
188
229
|
catch {
|
|
189
230
|
// LLM 不可用 → 降级到提问
|
|
190
231
|
}
|
|
191
|
-
// c. AskUserQuestion(TUI 弹界面;非交互宿主 askBridge 自动选推荐项=全新开始)
|
|
192
232
|
try {
|
|
193
233
|
const verdict = await askUserArbitrate(deps, actx);
|
|
194
234
|
note(`任务仲裁:经用户确认 → ${verdict === 'resume' ? '继续旧任务' : '全新开始'}`);
|
|
@@ -197,21 +237,19 @@ export function buildTaskArbitrator(deps) {
|
|
|
197
237
|
catch {
|
|
198
238
|
// 提问被取消/不可用 → 兜底
|
|
199
239
|
}
|
|
200
|
-
// d. 兜底 = 旧红线行为(hash 不等 → new-task),最小惊讶
|
|
201
240
|
note('任务仲裁:无法判定(LLM 与提问均不可用)→ 按全新任务处理');
|
|
202
241
|
return 'new';
|
|
203
242
|
};
|
|
204
243
|
}
|
|
205
|
-
/** LLM
|
|
244
|
+
/** LLM 单轮仲裁 → {verdict, reason}。解析失败一律按 unsure,不猜。 */
|
|
206
245
|
async function llmArbitrate(deps, actx) {
|
|
207
246
|
const chatFn = deps.chat ?? sdkChat;
|
|
208
|
-
const progress = `${actx.completedStepIds.length}/${actx.totalSteps}`;
|
|
209
247
|
const prompt = [
|
|
210
248
|
`你是工作流引擎的任务身份仲裁器。同名工作流「${actx.workflowName}」存在一个未完成的旧任务,`,
|
|
211
|
-
|
|
249
|
+
'用户刚发起了一次新调用,新输入的文本与旧任务目标不同。请判断新输入是「旧任务的延续指令」还是「全新任务」。',
|
|
212
250
|
'',
|
|
213
251
|
`旧任务目标:${truncate(actx.prevGoal, 300)}`,
|
|
214
|
-
`旧任务进度:已完成 ${
|
|
252
|
+
`旧任务进度:已完成 ${actx.completedCalls} 次调用`,
|
|
215
253
|
actx.artifacts.length ? `旧任务产物:${actx.artifacts.join(', ')}` : '',
|
|
216
254
|
`新输入:${truncate(actx.newGoal, 300)}`,
|
|
217
255
|
'',
|
|
@@ -225,7 +263,12 @@ async function llmArbitrate(deps, actx) {
|
|
|
225
263
|
for await (const ev of chatFn({
|
|
226
264
|
provider: deps.provider,
|
|
227
265
|
messages: [
|
|
228
|
-
{
|
|
266
|
+
{
|
|
267
|
+
role: 'user',
|
|
268
|
+
content: prompt,
|
|
269
|
+
timestamp: Date.now(),
|
|
270
|
+
id: randomUUID(),
|
|
271
|
+
},
|
|
229
272
|
],
|
|
230
273
|
tools: [],
|
|
231
274
|
signal: deps.signal,
|
|
@@ -244,20 +287,19 @@ async function llmArbitrate(deps, actx) {
|
|
|
244
287
|
}
|
|
245
288
|
return 'unsure';
|
|
246
289
|
}
|
|
247
|
-
/**
|
|
290
|
+
/** 问用户。推荐项 = 全新开始(与兜底语义一致);非交互宿主自动按推荐项。 */
|
|
248
291
|
async function askUserArbitrate(deps, actx) {
|
|
249
292
|
const exec = deps.executeTool ?? sdkExecuteTool;
|
|
250
|
-
const progress = `${actx.completedStepIds.length}/${actx.totalSteps}`;
|
|
251
293
|
const args = {
|
|
252
294
|
questions: [
|
|
253
295
|
{
|
|
254
296
|
question: `检测到工作流「${actx.workflowName}」有一个未完成的任务(目标:${truncate(actx.prevGoal, 80)},` +
|
|
255
|
-
|
|
297
|
+
`已完成 ${actx.completedCalls} 次调用)。本次输入「${truncate(actx.newGoal, 80)}」是要继续该任务,还是开始全新任务?`,
|
|
256
298
|
header: '任务仲裁',
|
|
257
299
|
options: [
|
|
258
300
|
{
|
|
259
301
|
label: '全新开始 (推荐)',
|
|
260
|
-
description: '
|
|
302
|
+
description: '归档旧任务的中间产物,按本次输入重新规划执行',
|
|
261
303
|
},
|
|
262
304
|
{
|
|
263
305
|
label: '继续上次任务',
|
|
@@ -272,25 +314,3 @@ async function askUserArbitrate(deps, actx) {
|
|
|
272
314
|
throw new Error(r.error);
|
|
273
315
|
return r.content.includes('继续上次任务') ? 'resume' : 'new';
|
|
274
316
|
}
|
|
275
|
-
/**
|
|
276
|
-
* 归一化 goal 字符串
|
|
277
|
-
*
|
|
278
|
-
* 规则:
|
|
279
|
-
* - toLowerCase()
|
|
280
|
-
* - 去除所有标点符号(保留中文、英文、数字、空格)
|
|
281
|
-
* - 去除多余空格(连续空格→单空格)
|
|
282
|
-
* - 首尾 trim
|
|
283
|
-
* - 截断到 200 字符
|
|
284
|
-
*/
|
|
285
|
-
function normalizeGoal(raw) {
|
|
286
|
-
return (raw
|
|
287
|
-
.toLowerCase()
|
|
288
|
-
// 保留中文、英文、数字、空格,去除其他字符(标点等)
|
|
289
|
-
.replace(/[^\p{L}\p{N}\s]/gu, '')
|
|
290
|
-
// 连续空格替换为单空格
|
|
291
|
-
.replace(/\s+/g, ' ')
|
|
292
|
-
// 首尾去空格
|
|
293
|
-
.trim()
|
|
294
|
-
// 截断到 200 字符
|
|
295
|
-
.slice(0, 200));
|
|
296
|
-
}
|