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
|
@@ -27,10 +27,17 @@ import { z } from 'zod';
|
|
|
27
27
|
|
|
28
28
|
import { configService } from '../../config/configService.js';
|
|
29
29
|
import { CONFIG_LIMITS, normalizeLimited } from '../../config/numericLimits.js';
|
|
30
|
+
import { DEFAULT_ADVISOR_CONFIG } from '../../config/configDefaults.js';
|
|
30
31
|
import { countMessagesTokens } from '../../context/tokenCounter.js';
|
|
31
32
|
import { chat } from '../../llm/client.js';
|
|
32
33
|
import { derivePromptCacheContext } from '../../llm/promptCache.js';
|
|
33
|
-
import type {
|
|
34
|
+
import type {
|
|
35
|
+
AdvisorContextPacket,
|
|
36
|
+
Message,
|
|
37
|
+
Tool,
|
|
38
|
+
ToolCallContext,
|
|
39
|
+
ToolResult,
|
|
40
|
+
} from '../../types.js';
|
|
34
41
|
import { toToolParameters } from '../../utils/zodToJson.js';
|
|
35
42
|
import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
|
|
36
43
|
|
|
@@ -38,10 +45,14 @@ import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
|
|
|
38
45
|
const inputSchema = z.object({
|
|
39
46
|
note: z
|
|
40
47
|
.string()
|
|
41
|
-
|
|
48
|
+
// 上限只做护栏,不做实用约束:note 是顾问唯一能看到的「模型主动强调的证据」,
|
|
49
|
+
// 卡太低(曾经 2000 字符)会让完整方案+关键代码原文根本塞不进去。真正的预算
|
|
50
|
+
// 闸门在 buildAdvisorMessages -> fitAdvisorBudget(inputTokenBudget 配置 +
|
|
51
|
+
// 顾问 contextWindow 推导),note 超预算只会挤掉历史消息,不会炸请求。
|
|
52
|
+
.max(100_000, 'note 太长(>100000 字符)')
|
|
42
53
|
.optional()
|
|
43
54
|
.describe(
|
|
44
|
-
'
|
|
55
|
+
'可选。大多数情况下不需要填--你此前说过的方案/诊断已经在会话历史里,顾问会自动看到。' +
|
|
45
56
|
'只有需要额外强调、历史里没体现的点时才填一句话。',
|
|
46
57
|
),
|
|
47
58
|
});
|
|
@@ -50,12 +61,10 @@ type AdvisorInput = z.infer<typeof inputSchema>;
|
|
|
50
61
|
const parameters = toToolParameters(inputSchema);
|
|
51
62
|
|
|
52
63
|
// ---------------- 2. Description(给 LLM 看的工具说明) ----------------
|
|
53
|
-
const description =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- The advisor has no tool access and does a single read-only pass over the transcript — it cannot verify anything itself, only reason about what it's shown.
|
|
58
|
-
- If this tool errors (advisor not configured in shared settings, disabled, manual-only, or a call failure), that's not a signal to stop — treat it as "no second opinion available this time" and continue with your own judgment. Do not block or retry in a loop.`;
|
|
64
|
+
const description = `Consult an independently configured, read-only advisor model for a second opinion.
|
|
65
|
+
The advisor receives a bounded view of the current session. Usually omit note; use it only for decisive evidence or visual facts that are absent or easy to miss in history.
|
|
66
|
+
The result includes a full consultationId. After a successful automatic consultation, record the main Agent's evidence-based accept/partial/reject judgment with AdvisorDecision.
|
|
67
|
+
The advisor is neither a fact source nor an authority. If it is unavailable or fails, follow the returned degradation guidance and do not retry in a loop.`;
|
|
59
68
|
|
|
60
69
|
// ---------------- 3. 顾问 persona system prompt ----------------
|
|
61
70
|
const ADVISOR_SYSTEM_PROMPT = `你是一位经验丰富的全栈开发专家技术顾问,为正在独立执行任务的另一个 AI 助手提供第二意见评审。
|
|
@@ -64,6 +73,14 @@ const ADVISOR_SYSTEM_PROMPT = `你是一位经验丰富的全栈开发专家技
|
|
|
64
73
|
你会看到该助手当前会话中受预算约束的相关记录——包括首要需求、近期交流、它的思考过程、当前方案
|
|
65
74
|
和关键工具结果与执行结果,以及它现在想让你重点关注的内容(如果有)。
|
|
66
75
|
|
|
76
|
+
重要:你**没有工具访问权,无法自行验证任何事实**。你只是提供一个不同视角的怀疑和推理,
|
|
77
|
+
不能把自己的推测当成确定结论。每条指出的问题都要明确标注:
|
|
78
|
+
- 【有证据】:基于记录里明确出现的代码/测试结果/事实
|
|
79
|
+
- 【推断】:基于已有信息的合理推断,但未被证实
|
|
80
|
+
- 【存疑】:信息不足,需要执行助手回去核实
|
|
81
|
+
不要过度自信,不要给出确定性语气的未验证判断——执行助手会对你的意见逐条做验证,
|
|
82
|
+
夸大其词会被判定为误报。
|
|
83
|
+
|
|
67
84
|
审视时请做到:
|
|
68
85
|
- 像资深工程师做方案评审/代码评审一样直接、具体——发现问题就明说,不要无条件附和或说套话。
|
|
69
86
|
- 优先检查:方案是否遗漏了风险或边界情况、诊断是否真的找到了根因还是只是让症状消失、
|
|
@@ -76,7 +93,16 @@ const ADVISOR_SYSTEM_PROMPT = `你是一位经验丰富的全栈开发专家技
|
|
|
76
93
|
或换个方式绕开,都要点出来。
|
|
77
94
|
- 结论必须基于你在历史记录里看到的实际证据,不要脱离上下文给泛泛的通用建议;
|
|
78
95
|
被省略的记录(尤其工具结果原文)所涉及的判断,明说你无法核实。
|
|
79
|
-
- 篇幅精炼:只讲最关键的 1-3
|
|
96
|
+
- 篇幅精炼:只讲最关键的 1-3 点,不要复述历史、不要客套开场白。
|
|
97
|
+
|
|
98
|
+
关于「带着反证回来」的那一次咨询(助手被要求这样做,不是在质疑你):
|
|
99
|
+
当它说「我实测是 X,你上次建议 Y」时,它手里的是一手证据,你手里的是推理——
|
|
100
|
+
默认它的观测为真,然后只回答一个问题:**哪个约束更硬**。
|
|
101
|
+
- 你上次漏看了它给出的证据 → 直接认,并说清结论怎么变。
|
|
102
|
+
- 它的观测其实没测到你担心的那一层(测了被改的函数,而真实调用路径根本走不到)
|
|
103
|
+
→ 指出这个错位,并说要测什么才算数。
|
|
104
|
+
- 两者都成立、只是适用范围不同 → 说清各自的边界,别硬选一个。
|
|
105
|
+
不要为了显得一致而坚持原判,也不要因为被反驳就整个收回——两种都会让它失去判断依据。`;
|
|
80
106
|
|
|
81
107
|
// ---------------- 4. 消息构造(纯函数,单独导出可测) ----------------
|
|
82
108
|
|
|
@@ -88,8 +114,20 @@ const ADVISOR_SYSTEM_PROMPT = `你是一位经验丰富的全栈开发专家技
|
|
|
88
114
|
*/
|
|
89
115
|
const MAX_TOOL_RESULT_CHARS = 12_000;
|
|
90
116
|
|
|
117
|
+
/**
|
|
118
|
+
* 工具调用参数与思维链的截断上限——与 `fitAdvisorBudget` 的预算裁剪是两回事:
|
|
119
|
+
* 那个只在总量超预算时才生效、按消息整条丢弃;这两个是每条消息内部无条件应用的
|
|
120
|
+
* 字段级上限,不看当前预算是否宽裕。思维链截得比正文更狠:重思考模型的
|
|
121
|
+
* reasoning 常比 content 长几倍,不设限会把预算吃光、挤掉更该保留的工具结果原文。
|
|
122
|
+
* 未发现过当前取值导致顾问漏判的实例,因此只命名、不改值——真出现具体案例
|
|
123
|
+
* 再调,不做没有证据支撑的预防性放宽。
|
|
124
|
+
*/
|
|
125
|
+
const ADVISOR_TOOL_ARGS_TRUNCATE_CHARS = 2_000;
|
|
126
|
+
const ADVISOR_REASONING_TRUNCATE_CHARS = 2_000;
|
|
127
|
+
|
|
91
128
|
/** 归一化后的工具结果前缀;裁剪统计要靠它反查,两处必须共用同一常量。 */
|
|
92
129
|
const TOOL_RESULT_PREFIX = '[工具结果 ';
|
|
130
|
+
const CONTEXT_PACKET_PREFIX = '[Advisor 结构化上下文包]';
|
|
93
131
|
|
|
94
132
|
function truncateMiddle(value: string, limit = MAX_TOOL_RESULT_CHARS): string {
|
|
95
133
|
if (value.length <= limit) return value;
|
|
@@ -192,19 +230,17 @@ function normalizeAdvisorMessage(
|
|
|
192
230
|
}
|
|
193
231
|
if (message.role === 'assistant') {
|
|
194
232
|
const calls = message.tool_calls?.map((call) =>
|
|
195
|
-
`[调用工具 ${call.function.name}] ${truncateMiddle(call.function.arguments,
|
|
233
|
+
`[调用工具 ${call.function.name}] ${truncateMiddle(call.function.arguments, ADVISOR_TOOL_ARGS_TRUNCATE_CHARS)}`,
|
|
196
234
|
).join('\n');
|
|
197
235
|
// 思维链一并送给顾问:评审「方案对不对」很大程度上要看**它是怎么想到这个方案的**——
|
|
198
236
|
// 推理里的跳跃(把推断当已验证、跳过一个没排除的可能)在最终结论文本里往往看不出来。
|
|
199
|
-
// 截断比正文更狠(2000):重思考模型的 reasoning 常比 content 长几倍,不设限会把
|
|
200
|
-
// 预算吃光、反而挤掉更该保留的工具结果原文。
|
|
201
237
|
// reasoning_details(结构化数组)不传:结构因 provider 而异,既无法可靠脱敏也无法
|
|
202
238
|
// 稳定转成文本,传过去只会变成噪声。
|
|
203
239
|
const thinking = typeof message.reasoning_content === 'string' && message.reasoning_content.length > 0
|
|
204
240
|
? message.reasoning_content
|
|
205
241
|
: (typeof message.reasoning === 'string' ? message.reasoning : '');
|
|
206
242
|
const thinkingLine = thinking.length > 0
|
|
207
|
-
? `[思考过程]\n${truncateMiddle(thinking,
|
|
243
|
+
? `[思考过程]\n${truncateMiddle(thinking, ADVISOR_REASONING_TRUNCATE_CHARS)}`
|
|
208
244
|
: '';
|
|
209
245
|
return {
|
|
210
246
|
role: 'assistant',
|
|
@@ -226,20 +262,33 @@ function fitAdvisorBudget(messages: Message[], inputBudget: number): Message[] {
|
|
|
226
262
|
const system = messages[0]!;
|
|
227
263
|
const closing = messages[messages.length - 1]!;
|
|
228
264
|
const body = messages.slice(1, -1);
|
|
229
|
-
const
|
|
265
|
+
const packetIndex = body.findIndex((message) =>
|
|
266
|
+
message.role === 'user'
|
|
267
|
+
&& typeof message.content === 'string'
|
|
268
|
+
&& message.content.startsWith(CONTEXT_PACKET_PREFIX));
|
|
269
|
+
const firstUserIndex = body.findIndex((message, index) =>
|
|
270
|
+
index !== packetIndex && message.role === 'user');
|
|
230
271
|
const selected: Message[] = [];
|
|
231
272
|
let used = countMessagesTokens([system, closing]);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
273
|
+
for (const index of [packetIndex, firstUserIndex]) {
|
|
274
|
+
if (index < 0) continue;
|
|
275
|
+
const pinned = body[index]!;
|
|
276
|
+
selected.push(pinned);
|
|
277
|
+
used += countMessagesTokens([pinned]);
|
|
236
278
|
}
|
|
279
|
+
// 从最近往前收,**装不下就停**(break,不是 continue)。
|
|
280
|
+
//
|
|
281
|
+
// ⚠️ 曾经是 continue:一条大消息放不下就跳过它、继续往前捡更小的旧消息。
|
|
282
|
+
// 结果是给顾问一段**中间有洞**的对话 —— 而洞恰好开在信息量最大的地方(长工具
|
|
283
|
+
// 结果、完整方案文本),偏偏下面那句省略提示还写着「保留最初需求和最近相关记录」,
|
|
284
|
+
// 顾问于是把两条本不相邻的消息读成前后相接,在残缺的因果链上给出自信结论。
|
|
285
|
+
// 宁可少给,不可给错:连续的尾部 + 如实说明从哪里开始省略。
|
|
237
286
|
const recent: Message[] = [];
|
|
238
287
|
for (let index = body.length - 1; index >= 0; index--) {
|
|
239
|
-
if (index === firstUserIndex) continue;
|
|
288
|
+
if (index === firstUserIndex || index === packetIndex) continue;
|
|
240
289
|
const message = body[index]!;
|
|
241
290
|
const cost = countMessagesTokens([message]);
|
|
242
|
-
if (used + cost > inputBudget)
|
|
291
|
+
if (used + cost > inputBudget) break;
|
|
243
292
|
recent.unshift(message);
|
|
244
293
|
used += cost;
|
|
245
294
|
}
|
|
@@ -274,6 +323,7 @@ export function buildAdvisorMessages(
|
|
|
274
323
|
contextWindow?: number;
|
|
275
324
|
maxTokens?: number;
|
|
276
325
|
inputTokenBudget?: number;
|
|
326
|
+
contextPacket?: AdvisorContextPacket;
|
|
277
327
|
} = {},
|
|
278
328
|
): Message[] {
|
|
279
329
|
const imageBudget: AdvisorImageBudget = { count: 0, encodedBytes: 0 };
|
|
@@ -296,13 +346,19 @@ export function buildAdvisorMessages(
|
|
|
296
346
|
|
|
297
347
|
const messages: Message[] = [
|
|
298
348
|
{ role: 'system', content: ADVISOR_SYSTEM_PROMPT },
|
|
349
|
+
...(options.contextPacket
|
|
350
|
+
? [{
|
|
351
|
+
role: 'user' as const,
|
|
352
|
+
content: `${CONTEXT_PACKET_PREFIX}\n${JSON.stringify(options.contextPacket, null, 2)}`,
|
|
353
|
+
}]
|
|
354
|
+
: []),
|
|
299
355
|
...nonSystem,
|
|
300
356
|
{ role: 'user', content: closing },
|
|
301
357
|
];
|
|
302
358
|
const contextWindow = options.contextWindow ?? 128_000;
|
|
303
359
|
const maxTokens = options.maxTokens ?? 4096;
|
|
304
360
|
const configuredBudget = normalizeLimited(
|
|
305
|
-
options.inputTokenBudget, CONFIG_LIMITS.advisorInputTokenBudget,
|
|
361
|
+
options.inputTokenBudget, CONFIG_LIMITS.advisorInputTokenBudget, DEFAULT_ADVISOR_CONFIG.inputTokenBudget);
|
|
306
362
|
const providerBudget = Math.max(CONFIG_LIMITS.advisorInputTokenBudget.min, contextWindow - maxTokens - 4096);
|
|
307
363
|
const inputBudget = Math.min(configuredBudget, providerBudget);
|
|
308
364
|
return fitAdvisorBudget(messages, inputBudget);
|
|
@@ -342,39 +398,73 @@ export async function runAdvisor(
|
|
|
342
398
|
chatFn: typeof chat = chat,
|
|
343
399
|
runtime: { timeoutMs?: number } = {},
|
|
344
400
|
): Promise<ToolResult> {
|
|
401
|
+
const consultation = ctx?.advisorInvocation === 'agent'
|
|
402
|
+
? ctx.advisorRuntime?.beginConsultation()
|
|
403
|
+
: undefined;
|
|
404
|
+
const finish = (result: ToolResult): ToolResult => {
|
|
405
|
+
if (!consultation || !ctx?.advisorRuntime) return result;
|
|
406
|
+
const metadata = ctx.advisorRuntime.finishConsultation(consultation, result.ok);
|
|
407
|
+
return {
|
|
408
|
+
...result,
|
|
409
|
+
...(result.ok
|
|
410
|
+
? {
|
|
411
|
+
content: `consultationId: ${metadata.consultationId}\n调用 AdvisorDecision 时必须原样使用上面的完整 consultationId。\n\n${result.content}`,
|
|
412
|
+
}
|
|
413
|
+
: {}),
|
|
414
|
+
metadata,
|
|
415
|
+
};
|
|
416
|
+
};
|
|
345
417
|
const advisor = await configService.advisor();
|
|
346
418
|
if (!advisor) {
|
|
347
|
-
return {
|
|
419
|
+
return finish({
|
|
348
420
|
ok: false,
|
|
349
421
|
error:
|
|
350
422
|
'顾问模型未配置。请在设置 → 模型中完成专家顾问配置。' +
|
|
351
|
-
'
|
|
352
|
-
};
|
|
423
|
+
'本回合后续不要再次尝试调用 Advisor;可继续凭自己判断推进,不必等待顾问。',
|
|
424
|
+
});
|
|
353
425
|
}
|
|
354
426
|
|
|
355
427
|
if (!advisor.enabled) {
|
|
356
|
-
return {
|
|
428
|
+
return finish({
|
|
357
429
|
ok: false,
|
|
358
|
-
error:
|
|
359
|
-
|
|
430
|
+
error:
|
|
431
|
+
'顾问模型当前已关闭(/advisor on 开启)。' +
|
|
432
|
+
'本回合后续不要再次尝试调用 Advisor;可继续凭自己判断推进,不必等待顾问。',
|
|
433
|
+
});
|
|
360
434
|
}
|
|
361
435
|
|
|
362
436
|
if (advisor.mode === 'manual' && ctx?.advisorInvocation !== 'manual') {
|
|
363
|
-
return {
|
|
437
|
+
return finish({
|
|
438
|
+
ok: false,
|
|
439
|
+
error:
|
|
440
|
+
'顾问模型当前为"仅手动"模式;请使用 /advisor ask 发起咨询。' +
|
|
441
|
+
'本回合后续不要再次尝试自动调用 Advisor。',
|
|
442
|
+
});
|
|
364
443
|
}
|
|
365
444
|
|
|
366
|
-
|
|
445
|
+
// 复核豁免:有一个已成功、还没被 AdvisorDecision 结清的咨询时,这次调用是对它
|
|
446
|
+
// 的复核而不是一次新检查点的咨询——工具说明书要求"顾问意见与证据冲突时再问一次",
|
|
447
|
+
// 若复核也照常计费/受配额拦截,短任务(配额恒为 1)会在第二次调用直接撞墙,
|
|
448
|
+
// 而配额耗尽的处理是把这次咨询标记失败并**顺带结清 #pending 指向的检查点**——
|
|
449
|
+
// 模型想认真复核,反而因为差一点配额把本该把关的高风险检查点悄悄放行了。
|
|
450
|
+
// 豁免只覆盖第一次复核:协调器按 checkpoint 记录成功咨询次数,完成一次复核后
|
|
451
|
+
// canReconcileConsultation 会变为 false,后续调用重新受正常配额约束。
|
|
452
|
+
const isReconcile = ctx?.advisorInvocation === 'agent'
|
|
453
|
+
&& Boolean(ctx.advisorRuntime?.pendingConsultationId)
|
|
454
|
+
&& ctx.advisorRuntime?.canReconcileConsultation === true;
|
|
455
|
+
|
|
456
|
+
if (!isReconcile && ctx?.advisorCalls && ctx.advisorCalls.used >= ctx.advisorCalls.max) {
|
|
367
457
|
// ⚠️ 必须说明「配额会增长」:配额随本回合工作量上调(loop.ts::advisorQuotaFor),
|
|
368
458
|
// 若这里只说「已达上限」,模型会当成本回合的硬上限而不再尝试 —— 那样长回合里
|
|
369
459
|
// 「批次做完再复核一次」的配额永远不会被用到,增长机制等于没做。
|
|
370
|
-
return {
|
|
460
|
+
return finish({
|
|
371
461
|
ok: false,
|
|
372
462
|
error:
|
|
373
463
|
`本回合顾问咨询配额暂时用完(当前 ${ctx.advisorCalls.max} 次)。` +
|
|
374
464
|
'配额会随本回合的工作量增长,继续推进一段后可以再次咨询;现在请按已有意见继续。',
|
|
375
|
-
};
|
|
465
|
+
});
|
|
376
466
|
}
|
|
377
|
-
if (ctx?.advisorCalls) ctx.advisorCalls.used++;
|
|
467
|
+
if (!isReconcile && ctx?.advisorCalls) ctx.advisorCalls.used++;
|
|
378
468
|
|
|
379
469
|
const provider = advisor.provider;
|
|
380
470
|
const snapshot = await configService.getSnapshot();
|
|
@@ -394,6 +484,9 @@ export async function runAdvisor(
|
|
|
394
484
|
contextWindow: provider.contextWindow,
|
|
395
485
|
maxTokens: provider.maxTokens,
|
|
396
486
|
inputTokenBudget: advisor.inputTokenBudget,
|
|
487
|
+
...(ctx?.advisorRuntime
|
|
488
|
+
? { contextPacket: ctx.advisorRuntime.contextPacket(input.note) }
|
|
489
|
+
: {}),
|
|
397
490
|
});
|
|
398
491
|
|
|
399
492
|
// Advisor 是可降级的第二意见:使用独立、可配置的总时限,不影响主模型的流式时限。
|
|
@@ -457,23 +550,26 @@ export async function runAdvisor(
|
|
|
457
550
|
contextWindow: provider.contextWindow,
|
|
458
551
|
maxTokens: provider.maxTokens,
|
|
459
552
|
inputTokenBudget: advisor.inputTokenBudget,
|
|
553
|
+
...(ctx?.advisorRuntime
|
|
554
|
+
? { contextPacket: ctx.advisorRuntime.contextPacket(input.note) }
|
|
555
|
+
: {}),
|
|
460
556
|
}),
|
|
461
557
|
);
|
|
462
558
|
degradedWithoutImages = true;
|
|
463
559
|
}
|
|
464
560
|
} catch (e) {
|
|
465
561
|
if (timeoutController.signal.aborted && !signal?.aborted) {
|
|
466
|
-
return {
|
|
562
|
+
return finish({
|
|
467
563
|
ok: false,
|
|
468
564
|
error:
|
|
469
565
|
`顾问模型响应超过 ${Math.round(timeoutMs / 1000)}s 未完成,已跳过。` +
|
|
470
566
|
'可继续凭自己判断推进,不必等待顾问。',
|
|
471
|
-
};
|
|
567
|
+
});
|
|
472
568
|
}
|
|
473
|
-
return {
|
|
569
|
+
return finish({
|
|
474
570
|
ok: false,
|
|
475
571
|
error: `${classifyAdvisorError(e as Error)} 可继续凭自己判断推进,不必等待顾问。`,
|
|
476
|
-
};
|
|
572
|
+
});
|
|
477
573
|
} finally {
|
|
478
574
|
clearTimeout(timer);
|
|
479
575
|
}
|
|
@@ -489,7 +585,7 @@ export async function runAdvisor(
|
|
|
489
585
|
`\n\n... (输出超过 ${DEFAULT_MAX_RESULT_SIZE_CHARS} 字符,已截断)`;
|
|
490
586
|
}
|
|
491
587
|
|
|
492
|
-
return { ok: true, content };
|
|
588
|
+
return finish({ ok: true, content });
|
|
493
589
|
}
|
|
494
590
|
|
|
495
591
|
// 无宿主上下文的调用视为用户手动咨询;生产主循环使用 callWithContext。
|
|
@@ -507,6 +603,33 @@ export const advisorTool: Tool<AdvisorInput> = {
|
|
|
507
603
|
isConcurrencySafe: false,
|
|
508
604
|
maxResultSizeChars: DEFAULT_MAX_RESULT_SIZE_CHARS,
|
|
509
605
|
interruptBehavior: () => 'cancel',
|
|
606
|
+
/**
|
|
607
|
+
* 动态可用性探测:未配置 / 已关闭 / 仅手动模式 → 工具不暴露给模型。
|
|
608
|
+
* 对齐 ComputerUse / WebBrowser 的模式:关闭时工具直接从 LLM 视野消失,
|
|
609
|
+
* 避免"看到工具但调不了→反复尝试"的流畅度问题。
|
|
610
|
+
*
|
|
611
|
+
* signature 随 enabled/mode/modelId 变化,确保配置改动后工具集签名更新、
|
|
612
|
+
* 模型下一轮拿到的是新工具列表。
|
|
613
|
+
*/
|
|
614
|
+
resolveAvailability() {
|
|
615
|
+
// 走同步探测(读内存快照),不触发磁盘 IO;
|
|
616
|
+
// resolveAvailability 是工具集构造阶段的同步调用,不能 await。
|
|
617
|
+
const avail = configService.advisorAvailabilitySync();
|
|
618
|
+
|
|
619
|
+
// ⚠️ 安全兜底:如果 snapshot 尚未初始化(极端情况:工具集构造发生在任何
|
|
620
|
+
// configService 异步调用之前),宁可返回 available=true 让工具显示出来
|
|
621
|
+
// (调用时 runAdvisor 会做真正的 fresh reload 校验),也不能误判为
|
|
622
|
+
// "未配置" 导致 Advisor 从工具列表里消失——少一个工具比多一个工具严重得多。
|
|
623
|
+
if (avail.configured && !avail.enabled) {
|
|
624
|
+
return { available: false, signature: 'disabled' };
|
|
625
|
+
}
|
|
626
|
+
if (avail.configured && avail.mode === 'manual') {
|
|
627
|
+
return { available: false, signature: 'manual-only' };
|
|
628
|
+
}
|
|
629
|
+
// 未初始化 / 已配置且可用 → 都显示工具(未配置时调用会有明确错误提示)
|
|
630
|
+
// modelId 进签名:不同顾问模型 = 不同能力 = 工具语义不同。
|
|
631
|
+
return { available: true, signature: avail.modelId ?? 'initializing' };
|
|
632
|
+
},
|
|
510
633
|
call,
|
|
511
634
|
callWithContext: runAdvisor,
|
|
512
635
|
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { configService } from '../../config/configService.js';
|
|
3
|
+
import { toToolParameters } from '../../utils/zodToJson.js';
|
|
4
|
+
const inputSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
consultationId: z
|
|
7
|
+
.string()
|
|
8
|
+
.min(1)
|
|
9
|
+
.describe('Advisor 结果元数据中的 consultationId'),
|
|
10
|
+
decision: z.enum(['accept', 'partial', 'reject']),
|
|
11
|
+
rationale: z
|
|
12
|
+
.string()
|
|
13
|
+
.min(8)
|
|
14
|
+
.max(20_000)
|
|
15
|
+
.describe('主 Agent 基于代码、测试和用户约束作出的判断依据'),
|
|
16
|
+
acceptedPoints: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
17
|
+
rejectedPoints: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
18
|
+
verificationPlan: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
19
|
+
})
|
|
20
|
+
.superRefine((value, ctx) => {
|
|
21
|
+
if (value.decision === 'partial' &&
|
|
22
|
+
(!value.acceptedPoints?.length || !value.rejectedPoints?.length)) {
|
|
23
|
+
ctx.addIssue({
|
|
24
|
+
code: z.ZodIssueCode.custom,
|
|
25
|
+
path: ['decision'],
|
|
26
|
+
message: 'partial 必须同时列出 acceptedPoints 和 rejectedPoints',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (value.decision === 'reject' && !value.rejectedPoints?.length) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: z.ZodIssueCode.custom,
|
|
32
|
+
path: ['rejectedPoints'],
|
|
33
|
+
message: 'reject 必须列出被拒绝的顾问意见',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
async function callWithContext(input, _signal, context) {
|
|
38
|
+
if (!context.advisorRuntime) {
|
|
39
|
+
return { ok: false, error: '当前运行没有待处理的 Advisor 协调器状态。' };
|
|
40
|
+
}
|
|
41
|
+
return context.advisorRuntime.recordDecision(input);
|
|
42
|
+
}
|
|
43
|
+
export const advisorDecisionTool = {
|
|
44
|
+
name: 'AdvisorDecision',
|
|
45
|
+
description: "Records the main Agent's evidence-based decision after a successful Advisor consultation. " +
|
|
46
|
+
'Call it before resuming a deferred write, irreversible action, or final delivery. ' +
|
|
47
|
+
'The Advisor is a second opinion, not an authority: choose accept, partial, or reject based on primary evidence. ' +
|
|
48
|
+
'For partial/reject, explicitly identify rejected points and explain the code/test/user-constraint evidence.',
|
|
49
|
+
inputSchema,
|
|
50
|
+
parameters: toToolParameters(inputSchema),
|
|
51
|
+
isReadOnly: true,
|
|
52
|
+
isConcurrencySafe: false,
|
|
53
|
+
interruptBehavior: () => 'cancel',
|
|
54
|
+
resolveAvailability() {
|
|
55
|
+
const avail = configService.advisorAvailabilitySync();
|
|
56
|
+
if (avail.configured && (!avail.enabled || avail.mode === 'manual')) {
|
|
57
|
+
return {
|
|
58
|
+
available: false,
|
|
59
|
+
signature: avail.enabled ? 'manual-only' : 'disabled',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return { available: true, signature: avail.modelId ?? 'initializing' };
|
|
63
|
+
},
|
|
64
|
+
async call() {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
error: 'AdvisorDecision 只能在主 Agent 会话的 Advisor 咨询后调用。',
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
callWithContext,
|
|
71
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
import { configService } from '../../config/configService.js';
|
|
4
|
+
import type { Tool, ToolCallContext, ToolResult } from '../../types.js';
|
|
5
|
+
import { toToolParameters } from '../../utils/zodToJson.js';
|
|
6
|
+
|
|
7
|
+
const inputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
consultationId: z
|
|
10
|
+
.string()
|
|
11
|
+
.min(1)
|
|
12
|
+
.describe('Advisor 结果元数据中的 consultationId'),
|
|
13
|
+
decision: z.enum(['accept', 'partial', 'reject']),
|
|
14
|
+
rationale: z
|
|
15
|
+
.string()
|
|
16
|
+
.min(8)
|
|
17
|
+
.max(20_000)
|
|
18
|
+
.describe('主 Agent 基于代码、测试和用户约束作出的判断依据'),
|
|
19
|
+
acceptedPoints: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
20
|
+
rejectedPoints: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
21
|
+
verificationPlan: z.array(z.string().min(1).max(4_000)).max(20).optional(),
|
|
22
|
+
})
|
|
23
|
+
.superRefine((value, ctx) => {
|
|
24
|
+
if (
|
|
25
|
+
value.decision === 'partial' &&
|
|
26
|
+
(!value.acceptedPoints?.length || !value.rejectedPoints?.length)
|
|
27
|
+
) {
|
|
28
|
+
ctx.addIssue({
|
|
29
|
+
code: z.ZodIssueCode.custom,
|
|
30
|
+
path: ['decision'],
|
|
31
|
+
message: 'partial 必须同时列出 acceptedPoints 和 rejectedPoints',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (value.decision === 'reject' && !value.rejectedPoints?.length) {
|
|
35
|
+
ctx.addIssue({
|
|
36
|
+
code: z.ZodIssueCode.custom,
|
|
37
|
+
path: ['rejectedPoints'],
|
|
38
|
+
message: 'reject 必须列出被拒绝的顾问意见',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
type AdvisorDecisionInput = z.infer<typeof inputSchema>;
|
|
44
|
+
|
|
45
|
+
async function callWithContext(
|
|
46
|
+
input: AdvisorDecisionInput,
|
|
47
|
+
_signal: AbortSignal | undefined,
|
|
48
|
+
context: ToolCallContext,
|
|
49
|
+
): Promise<ToolResult> {
|
|
50
|
+
if (!context.advisorRuntime) {
|
|
51
|
+
return { ok: false, error: '当前运行没有待处理的 Advisor 协调器状态。' };
|
|
52
|
+
}
|
|
53
|
+
return context.advisorRuntime.recordDecision(input);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const advisorDecisionTool: Tool<AdvisorDecisionInput> = {
|
|
57
|
+
name: 'AdvisorDecision',
|
|
58
|
+
description:
|
|
59
|
+
"Records the main Agent's evidence-based decision after a successful Advisor consultation. " +
|
|
60
|
+
'Call it before resuming a deferred write, irreversible action, or final delivery. ' +
|
|
61
|
+
'The Advisor is a second opinion, not an authority: choose accept, partial, or reject based on primary evidence. ' +
|
|
62
|
+
'For partial/reject, explicitly identify rejected points and explain the code/test/user-constraint evidence.',
|
|
63
|
+
inputSchema,
|
|
64
|
+
parameters: toToolParameters(inputSchema),
|
|
65
|
+
isReadOnly: true,
|
|
66
|
+
isConcurrencySafe: false,
|
|
67
|
+
interruptBehavior: () => 'cancel',
|
|
68
|
+
resolveAvailability() {
|
|
69
|
+
const avail = configService.advisorAvailabilitySync();
|
|
70
|
+
if (avail.configured && (!avail.enabled || avail.mode === 'manual')) {
|
|
71
|
+
return {
|
|
72
|
+
available: false,
|
|
73
|
+
signature: avail.enabled ? 'manual-only' : 'disabled',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { available: true, signature: avail.modelId ?? 'initializing' };
|
|
77
|
+
},
|
|
78
|
+
async call(): Promise<ToolResult> {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
error: 'AdvisorDecision 只能在主 Agent 会话的 Advisor 咨询后调用。',
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
callWithContext,
|
|
85
|
+
};
|
package/src/tools/agent/agent.js
CHANGED
|
@@ -41,7 +41,7 @@ import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
|
|
|
41
41
|
import { SUBAGENT_EXCLUDED_TOOLS, resolveAgentType } from './agentTypes.js';
|
|
42
42
|
import { acquireSubagentLease, normalizeWriteScopes } from './coordinator.js';
|
|
43
43
|
import { commitWorktreeChanges, createAgentWorktree, hasWorktreeChanges, removeAgentWorktree, worktreeChangedFiles, worktreeDiffStat, } from './worktree.js';
|
|
44
|
-
import { appendAgentEvent, loadAgentRecord, saveAgentRecord } from './agentTaskService.js';
|
|
44
|
+
import { appendAgentEvent, attachAgentHistory, loadAgentRecord, saveAgentRecord } from './agentTaskService.js';
|
|
45
45
|
let corePromise = null;
|
|
46
46
|
/** 首次调用时才真正加载 loop/tools——此刻模块图早已初始化完毕,环安全。 */
|
|
47
47
|
function loadCore() {
|
|
@@ -234,7 +234,10 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
234
234
|
ctx.agentCalls.used++;
|
|
235
235
|
const { runQuery, ALL_TOOLS, executeTool } = await loadCore();
|
|
236
236
|
const def = resolveAgentType(input.agent_type);
|
|
237
|
-
// 轮数上限:AGENT_TOOL_MAX_TURNS
|
|
237
|
+
// 轮数上限:AGENT_TOOL_MAX_TURNS 可统一覆盖两种类型。默认值的唯一真值在
|
|
238
|
+
// config/configDefaults.ts::DEFAULT_SUBAGENTS_CONFIG(现为 explore 200 / general 100,
|
|
239
|
+
// 那里写了「只读的给宽、能写的给窄」的理由)。这条注释以前写着「explore 50」,
|
|
240
|
+
// 而代码早已是 200 —— 注释里复述数字必然漂移,所以现在只留指针。
|
|
238
241
|
const maxTurns = positiveInt(process.env.AGENT_TOOL_MAX_TURNS)
|
|
239
242
|
?? (def.type === 'explore' ? ctx.subagentConfig?.exploreMaxTurns : ctx.subagentConfig?.generalMaxTurns)
|
|
240
243
|
?? def.maxTurns;
|
|
@@ -312,6 +315,7 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
312
315
|
const history = deps.initialHistory?.length ? [...deps.initialHistory] : [
|
|
313
316
|
{ role: 'system', content: await buildSubSystemPrompt(cwd, def, subTools) },
|
|
314
317
|
];
|
|
318
|
+
deps.onHistoryReady?.(history);
|
|
315
319
|
const historyLenBefore = history.length;
|
|
316
320
|
const maxConcurrent = positiveInt(process.env.AGENT_TOOL_MAX_CONCURRENT) ?? ctx.subagentConfig?.maxConcurrent ?? 3;
|
|
317
321
|
let releaseLease = null;
|
|
@@ -407,8 +411,8 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
407
411
|
}
|
|
408
412
|
catch { /* executeTool will report malformed input */ }
|
|
409
413
|
const rawPath = typeof parsed.file_path === 'string' ? parsed.file_path : typeof parsed.path === 'string' ? parsed.path : undefined;
|
|
410
|
-
if (def.type === 'general' && !wt &&
|
|
411
|
-
return { ok: false, error:
|
|
414
|
+
if (def.type === 'general' && !wt && ['Bash', 'ApplyPatch'].includes(name) && writeScopes[0] !== rootScope[0]) {
|
|
415
|
+
return { ok: false, error: `声明了局部 write_scopes 时禁止 ${name}:无法可靠证明一次调用只写入批准范围。请改用单文件工具或使用整个工作目录范围。` };
|
|
412
416
|
}
|
|
413
417
|
if (def.type === 'general' && rawPath) {
|
|
414
418
|
if (isAbsolute(rawPath))
|
|
@@ -427,7 +431,14 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
427
431
|
changedFiles.add(relative(cwd, resolve(cwd, rawPath)).split(sep).join('/'));
|
|
428
432
|
}
|
|
429
433
|
}
|
|
430
|
-
|
|
434
|
+
const result = await baseExecute(name, args, s, c);
|
|
435
|
+
if (result.metadata?.kind === 'file_activity') {
|
|
436
|
+
for (const file of result.metadata.files) {
|
|
437
|
+
if (['created', 'modified', 'generated', 'deleted'].includes(file.activity))
|
|
438
|
+
changedFiles.add(file.relativePath);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return result;
|
|
431
442
|
};
|
|
432
443
|
// ---- 事件消费:子 LoopEvent 一律不外泄,折算成统计 + 步内进度 ----
|
|
433
444
|
let turns = 0;
|
|
@@ -672,6 +683,7 @@ export async function runManagedAgentTask(input, signal, ctx, deps = {}) {
|
|
|
672
683
|
abort,
|
|
673
684
|
completion,
|
|
674
685
|
events: new EventEmitter(),
|
|
686
|
+
inbox: [],
|
|
675
687
|
};
|
|
676
688
|
ctx.sessionState.agentTasks.tasks.set(id, task);
|
|
677
689
|
await saveAgentRecord(ctx, task);
|
|
@@ -703,6 +715,7 @@ export async function runManagedAgentTask(input, signal, ctx, deps = {}) {
|
|
|
703
715
|
await saveAgentRecord(ctx, task);
|
|
704
716
|
},
|
|
705
717
|
captureHistory: (history) => { captured = [...history]; },
|
|
718
|
+
onHistoryReady: (history) => attachAgentHistory(task, history),
|
|
706
719
|
});
|
|
707
720
|
task.result = result;
|
|
708
721
|
task.history = captured;
|