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
|
@@ -16,16 +16,35 @@
|
|
|
16
16
|
* 设计原则:
|
|
17
17
|
* - 纯工具函数,无全局状态,无副作用(除了 shell 子进程)
|
|
18
18
|
* - 不依赖任何插件代码,可被 src/ 和 plugins/ 同时导入
|
|
19
|
-
* -
|
|
19
|
+
* - 工作目录隔离:相对路径以调用方给的 cwd 为锚,缺省 getWorkingDir()
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ cwd 参数不是可有可无的修饰:**验收必须和写入锚在同一个目录**。
|
|
22
|
+
* 会话进入 session worktree 后(EnterWorktree),写文件的工具跟着 worktree 走
|
|
23
|
+
* (loop.ts 按 sessionState.activeWorktree 重定向 cwd),验收若仍锚原 workspace,
|
|
24
|
+
* 就会在空目录里找产物 —— file_exists 恒 false,工作流被判失败并反复重试,
|
|
25
|
+
* 而产物其实好好躺在 worktree 里。调用方拿得到有效 cwd 时务必传进来。
|
|
20
26
|
* ============================================================
|
|
21
27
|
*/
|
|
22
28
|
|
|
23
29
|
import { existsSync, readFileSync } from 'node:fs';
|
|
24
30
|
import { spawn } from 'node:child_process';
|
|
25
31
|
import { sanitizeCredentialEnv } from '../config/configService.js';
|
|
32
|
+
import { CONFIG_LIMITS, normalizeLimited } from '../config/numericLimits.js';
|
|
26
33
|
|
|
27
34
|
import { getWorkingDir } from '../bootstrap/workingDir.js';
|
|
28
35
|
|
|
36
|
+
/**
|
|
37
|
+
* `shell:` 检查的默认超时——**唯一真值**。
|
|
38
|
+
*
|
|
39
|
+
* ⚠️ 这个数字此前在本文件里写了两份(`parseCheckString` 的构造处 + `runVerification`
|
|
40
|
+
* 的 `?? 30_000` 兜底),改一处漏一处就会出现「解析时 30s、执行时 60s」这种谁都看不出
|
|
41
|
+
* 的分裂。边界见 `config/numericLimits.ts::CONFIG_LIMITS.verifyShellTimeoutMs`。
|
|
42
|
+
*
|
|
43
|
+
* 为什么默认值不能太大:`verify()` 是工作流硬门,跑不完就阻塞整条流水线。
|
|
44
|
+
* 需要跑全量测试套件的场景应当缩到具体文件,或由调用方显式传 `defaultShellTimeoutMs`。
|
|
45
|
+
*/
|
|
46
|
+
export const DEFAULT_SHELL_CHECK_TIMEOUT_MS = 30_000;
|
|
47
|
+
|
|
29
48
|
export interface Check {
|
|
30
49
|
type: 'shell' | 'file_contains' | 'file_exists' | 'test_count';
|
|
31
50
|
command?: string;
|
|
@@ -57,7 +76,10 @@ function parseVerifyArg(arg: string): Check | null {
|
|
|
57
76
|
|
|
58
77
|
switch (type) {
|
|
59
78
|
case 'shell':
|
|
60
|
-
|
|
79
|
+
// ⚠️ 这里**不填** timeout:解析层只管语法,超时是策略、由 runVerification 决定。
|
|
80
|
+
// 曾经在这里写死 30_000,于是 `check.timeout ?? 默认值` 里的默认值永远走不到 ——
|
|
81
|
+
// 调用方传的超时被一个「解析时顺手填上的」值静默盖掉。
|
|
82
|
+
return { type: 'shell', command: value };
|
|
61
83
|
case 'file_exists':
|
|
62
84
|
return { type: 'file_exists', file: value };
|
|
63
85
|
case 'file_contains': {
|
|
@@ -128,12 +150,27 @@ interface ShellRunResult {
|
|
|
128
150
|
errored: boolean;
|
|
129
151
|
}
|
|
130
152
|
|
|
131
|
-
function runShell(
|
|
153
|
+
function runShell(
|
|
154
|
+
command: string,
|
|
155
|
+
timeout: number,
|
|
156
|
+
cwd: string,
|
|
157
|
+
): Promise<ShellRunResult> {
|
|
132
158
|
return new Promise((resolve) => {
|
|
133
159
|
const isWin = process.platform === 'win32';
|
|
160
|
+
const opts = { timeout, cwd, env: sanitizeCredentialEnv() };
|
|
161
|
+
// ⚠️ windowsVerbatimArguments: true 是必须的,不是可选优化:Node 给 cmd.exe/
|
|
162
|
+
// .bat 目标默认加一层它自己的参数转义(CVE-2024-27980 之后的安全加固),
|
|
163
|
+
// 会把 command 字符串里模型自己写好的转义(比如内嵌 PowerShell 单行脚本里的
|
|
164
|
+
// `\"..."`)再转义一遍,导致 cmd.exe 转交给子进程的字符串被改写、PowerShell
|
|
165
|
+
// 解析报 UnexpectedToken——文件内容明明字节级正确,check 却稳定失败。
|
|
166
|
+
// 已实测:一段合法的 `powershell -Command "...; Write-Host \"x\"; ..."`
|
|
167
|
+
// 不加这个选项必挂,加了立刻 exitCode 0;简单命令(echo/dir/bun --version)
|
|
168
|
+
// 行为不受影响。verify() 的 shell: 检查类型专供工作流的 hard_checks 使用,
|
|
169
|
+
// 命令来自可信的 LLM 契约草稿或用户输入,不是不可信的外部数据,
|
|
170
|
+
// 关掉这层转义不引入新的注入面。
|
|
134
171
|
const child = isWin
|
|
135
|
-
? spawn('cmd', ['/c', command], {
|
|
136
|
-
: spawn('bash', ['-c', command],
|
|
172
|
+
? spawn('cmd', ['/c', command], { ...opts, windowsVerbatimArguments: true })
|
|
173
|
+
: spawn('bash', ['-c', command], opts);
|
|
137
174
|
|
|
138
175
|
let stdout = '';
|
|
139
176
|
let stderr = '';
|
|
@@ -155,8 +192,12 @@ function runShell(command: string, timeout: number): Promise<ShellRunResult> {
|
|
|
155
192
|
});
|
|
156
193
|
}
|
|
157
194
|
|
|
158
|
-
export async function verifyShell(
|
|
159
|
-
|
|
195
|
+
export async function verifyShell(
|
|
196
|
+
command: string,
|
|
197
|
+
timeout: number,
|
|
198
|
+
cwd: string = getWorkingDir(),
|
|
199
|
+
): Promise<CheckResult> {
|
|
200
|
+
const r = await runShell(command, timeout, cwd);
|
|
160
201
|
if (r.errored) {
|
|
161
202
|
return {
|
|
162
203
|
check: { type: 'shell', command },
|
|
@@ -171,9 +212,12 @@ export async function verifyShell(command: string, timeout: number): Promise<Che
|
|
|
171
212
|
};
|
|
172
213
|
}
|
|
173
214
|
|
|
174
|
-
export function verifyFileExists(
|
|
175
|
-
|
|
176
|
-
|
|
215
|
+
export function verifyFileExists(
|
|
216
|
+
file: string,
|
|
217
|
+
cwd: string = getWorkingDir(),
|
|
218
|
+
): CheckResult {
|
|
219
|
+
// 相对路径以调用方给的 cwd 为锚(绝对路径识别含 UNC)
|
|
220
|
+
const resolved = isAbsolutePath(file) ? file : `${cwd}/${file}`;
|
|
177
221
|
const exists = existsSync(resolved);
|
|
178
222
|
return {
|
|
179
223
|
check: { type: 'file_exists', file },
|
|
@@ -182,8 +226,12 @@ export function verifyFileExists(file: string): CheckResult {
|
|
|
182
226
|
};
|
|
183
227
|
}
|
|
184
228
|
|
|
185
|
-
export function verifyFileContains(
|
|
186
|
-
|
|
229
|
+
export function verifyFileContains(
|
|
230
|
+
file: string,
|
|
231
|
+
pattern: string,
|
|
232
|
+
cwd: string = getWorkingDir(),
|
|
233
|
+
): CheckResult {
|
|
234
|
+
const resolved = isAbsolutePath(file) ? file : `${cwd}/${file}`;
|
|
187
235
|
try {
|
|
188
236
|
const content = readFileSync(resolved, 'utf8');
|
|
189
237
|
const regex = new RegExp(pattern);
|
|
@@ -203,11 +251,14 @@ export function verifyFileContains(file: string, pattern: string): CheckResult {
|
|
|
203
251
|
}
|
|
204
252
|
}
|
|
205
253
|
|
|
206
|
-
async function verifyTestCount(
|
|
254
|
+
async function verifyTestCount(
|
|
255
|
+
minCount: number,
|
|
256
|
+
cwd: string = getWorkingDir(),
|
|
257
|
+
): Promise<CheckResult> {
|
|
207
258
|
// 跨运行时:开发用 bun → bun test;npm 全局安装用 Node → npm test --silent
|
|
208
259
|
// 用 process.versions.bun 探测比 typeof Bun !== 'undefined' 更稳(不依赖全局类型)
|
|
209
260
|
const cmd = process.versions.bun ? 'bun test' : 'npm test --silent';
|
|
210
|
-
const r = await runShell(cmd, 60_000);
|
|
261
|
+
const r = await runShell(cmd, 60_000, cwd);
|
|
211
262
|
const combined = `${r.stdout}\n${r.stderr}`;
|
|
212
263
|
if (r.errored) {
|
|
213
264
|
return {
|
|
@@ -232,7 +283,16 @@ async function verifyTestCount(minCount: number): Promise<CheckResult> {
|
|
|
232
283
|
* 执行一组检查,返回聚合结果。
|
|
233
284
|
* 全部通过 → passed=true;任一失败 → passed=false + summary 列出失败项。
|
|
234
285
|
*/
|
|
235
|
-
export async function runVerification(
|
|
286
|
+
export async function runVerification(
|
|
287
|
+
checks: Check[],
|
|
288
|
+
cwd: string = getWorkingDir(),
|
|
289
|
+
options: { defaultShellTimeoutMs?: number } = {},
|
|
290
|
+
): Promise<VerifyResult> {
|
|
291
|
+
const shellTimeout = normalizeLimited(
|
|
292
|
+
options.defaultShellTimeoutMs,
|
|
293
|
+
CONFIG_LIMITS.verifyShellTimeoutMs,
|
|
294
|
+
DEFAULT_SHELL_CHECK_TIMEOUT_MS,
|
|
295
|
+
);
|
|
236
296
|
if (checks.length === 0) {
|
|
237
297
|
return { passed: true, details: [], summary: '无验证项' };
|
|
238
298
|
}
|
|
@@ -244,16 +304,20 @@ export async function runVerification(checks: Check[]): Promise<VerifyResult> {
|
|
|
244
304
|
|
|
245
305
|
switch (check.type) {
|
|
246
306
|
case 'shell':
|
|
247
|
-
result = await verifyShell(
|
|
307
|
+
result = await verifyShell(
|
|
308
|
+
check.command ?? '',
|
|
309
|
+
check.timeout ?? shellTimeout,
|
|
310
|
+
cwd,
|
|
311
|
+
);
|
|
248
312
|
break;
|
|
249
313
|
case 'file_exists':
|
|
250
|
-
result = verifyFileExists(check.file ?? '');
|
|
314
|
+
result = verifyFileExists(check.file ?? '', cwd);
|
|
251
315
|
break;
|
|
252
316
|
case 'file_contains':
|
|
253
|
-
result = verifyFileContains(check.file ?? '', check.pattern ?? '');
|
|
317
|
+
result = verifyFileContains(check.file ?? '', check.pattern ?? '', cwd);
|
|
254
318
|
break;
|
|
255
319
|
case 'test_count':
|
|
256
|
-
result = await verifyTestCount(check.minCount ?? 0);
|
|
320
|
+
result = await verifyTestCount(check.minCount ?? 0, cwd);
|
|
257
321
|
break;
|
|
258
322
|
default:
|
|
259
323
|
result = {
|
|
@@ -263,7 +327,10 @@ export async function runVerification(checks: Check[]): Promise<VerifyResult> {
|
|
|
263
327
|
};
|
|
264
328
|
}
|
|
265
329
|
|
|
266
|
-
|
|
330
|
+
// 回填**原始** check:各 verifier 只收散参(command/file/pattern),返回时会
|
|
331
|
+
// 自己重建一个残缺的 check 对象,把 timeout 这类字段丢掉。details 是给人排障和
|
|
332
|
+
// 给工作流做卡死指纹用的,它必须如实反映「这一条到底是按什么跑的」。
|
|
333
|
+
results.push({ ...result, check });
|
|
267
334
|
}
|
|
268
335
|
|
|
269
336
|
const allPassed = results.every((r) => r.passed);
|
package/src/llm/client.js
CHANGED
|
@@ -26,7 +26,9 @@
|
|
|
26
26
|
import { dlog } from '../utils/debugLog.js';
|
|
27
27
|
import { buildOpenAIRequest, createOpenAISSEParser, isImageInputRejected, isMaxTokensRejected, isPromptCacheKeyRejected, isResponseFormatUnsupported, } from './providers/openaiFormat.js';
|
|
28
28
|
import { promptMaterialHash, shortCacheScope } from './promptCache.js';
|
|
29
|
-
import { buildAnthropicRequest, createAnthropicSSEParser } from './providers/anthropicFormat.js';
|
|
29
|
+
import { buildAnthropicRequest, createAnthropicSSEParser, } from './providers/anthropicFormat.js';
|
|
30
|
+
import { chatGateway } from './gatewayClient.js';
|
|
31
|
+
import { prepareMessagesForProvider } from './messageProvenance.js';
|
|
30
32
|
/**
|
|
31
33
|
* 记住"这个 baseURL::model 不支持 response_format.json_schema",避免每次都先撞 400。
|
|
32
34
|
* 单进程内有效;每个 -p 子进程是全新进程 → 首个结构化调用吃一次 400 再退化,可接受。
|
|
@@ -133,7 +135,10 @@ export function _nextRetryDelayMs(retryAfterMs) {
|
|
|
133
135
|
}
|
|
134
136
|
/** 可重试的 HTTP 状态码。4xx 除 408/425/429 外不重试(重试无意义)。 */
|
|
135
137
|
function isRetryableStatus(status) {
|
|
136
|
-
return status === 408 ||
|
|
138
|
+
return (status === 408 ||
|
|
139
|
+
status === 425 ||
|
|
140
|
+
status === 429 ||
|
|
141
|
+
(status >= 500 && status < 600));
|
|
137
142
|
}
|
|
138
143
|
/** 鉴权类错误:明确告诉用户"key 失效/过期/无权访问",避免重试无意义。 */
|
|
139
144
|
function isClientAuthError(status) {
|
|
@@ -212,7 +217,9 @@ export function createIdleWatchdog(userSignal, timeoutMs = IDLE_TIMEOUT_MS) {
|
|
|
212
217
|
};
|
|
213
218
|
arm();
|
|
214
219
|
return {
|
|
215
|
-
signal: userSignal
|
|
220
|
+
signal: userSignal
|
|
221
|
+
? AbortSignal.any([userSignal, ctrl.signal])
|
|
222
|
+
: ctrl.signal,
|
|
216
223
|
kick: arm,
|
|
217
224
|
dispose: () => {
|
|
218
225
|
if (timer)
|
|
@@ -240,8 +247,34 @@ export function createIdleWatchdog(userSignal, timeoutMs = IDLE_TIMEOUT_MS) {
|
|
|
240
247
|
* }
|
|
241
248
|
* ```
|
|
242
249
|
*/
|
|
250
|
+
export function createModelProvider(provider) {
|
|
251
|
+
return {
|
|
252
|
+
source: provider.source === 'gateway' ? 'gateway' : 'local',
|
|
253
|
+
descriptor: provider,
|
|
254
|
+
stream: (request) => {
|
|
255
|
+
if (provider.source === 'gateway') {
|
|
256
|
+
if (request.responseFormat &&
|
|
257
|
+
provider.gatewayCapabilities?.structuredOutput === false) {
|
|
258
|
+
throw new Error('当前在线模型不支持结构化输出');
|
|
259
|
+
}
|
|
260
|
+
return chatGateway({
|
|
261
|
+
provider: provider,
|
|
262
|
+
messages: request.messages,
|
|
263
|
+
tools: request.tools,
|
|
264
|
+
signal: request.signal,
|
|
265
|
+
conversationMode: request.conversationMode,
|
|
266
|
+
responseFormat: request.responseFormat,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return streamLocal({ ...request, provider: provider });
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
}
|
|
243
273
|
export async function* chat(args) {
|
|
244
|
-
|
|
274
|
+
yield* createModelProvider(args.provider).stream(args);
|
|
275
|
+
}
|
|
276
|
+
async function* streamLocal(args) {
|
|
277
|
+
const { provider, messages, tools, signal, responseFormat, promptCache, conversationMode, cacheEdits, } = args;
|
|
245
278
|
const format = provider.apiFormat === 'anthropic' ? 'anthropic' : 'openai';
|
|
246
279
|
if (format === 'anthropic' && responseFormat) {
|
|
247
280
|
throw new Error('output_schema 结构化输出目前不支持 Anthropic Messages 格式的 provider' +
|
|
@@ -251,17 +284,14 @@ export async function* chat(args) {
|
|
|
251
284
|
// 过滤并清洁 messages 数组,剥离 timestamp, id, _ephemeral 等本地渲染元数据。
|
|
252
285
|
// 两种格式共用同一份清洗后的内部形状——Anthropic 分支的翻译(system 摘除/
|
|
253
286
|
// tool_calls→tool_use 等)在 buildAnthropicRequest 内部做,不在这里做。
|
|
254
|
-
let cleanedMessages = messages
|
|
255
|
-
.filter((m) => !(m.role === 'system' && m._ephemeral === true))
|
|
256
|
-
.map((m) => {
|
|
257
|
-
const { id, timestamp, attachments, browserReferences, display_metadata, ...rest } = m;
|
|
258
|
-
return rest;
|
|
259
|
-
});
|
|
287
|
+
let cleanedMessages = prepareMessagesForProvider(messages, conversationMode ?? 'private');
|
|
260
288
|
const includeUsage = process.env.MINIMAL_AGENT_DISABLE_USAGE !== '1';
|
|
261
289
|
const rfKey = `${provider.baseURL}::${provider.model}`;
|
|
262
290
|
// OpenAI 分支专属的「就地退化」状态;Anthropic 无此概念,两个 flag 恒为 false,
|
|
263
291
|
// 下面的退化 if 分支天然不会进入(不需要额外的 format 判断散落各处)。
|
|
264
|
-
let wantResponseFormat = format === 'openai' &&
|
|
292
|
+
let wantResponseFormat = format === 'openai' &&
|
|
293
|
+
responseFormat !== undefined &&
|
|
294
|
+
!rfUnsupported.has(rfKey);
|
|
265
295
|
let wantMaxTokens = format === 'openai' &&
|
|
266
296
|
typeof provider.maxTokens === 'number' &&
|
|
267
297
|
provider.maxTokens > 0 &&
|
|
@@ -278,7 +308,12 @@ export async function* chat(args) {
|
|
|
278
308
|
const textOnly = c.filter((p) => p.type === 'text');
|
|
279
309
|
const newContent = textOnly.length > 0
|
|
280
310
|
? textOnly.map((p) => ({ type: 'text', text: p.text }))
|
|
281
|
-
: [
|
|
311
|
+
: [
|
|
312
|
+
{
|
|
313
|
+
type: 'text',
|
|
314
|
+
text: '[图片内容未发送:当前模型不支持图片输入]',
|
|
315
|
+
},
|
|
316
|
+
];
|
|
282
317
|
return { ...m, content: newContent };
|
|
283
318
|
});
|
|
284
319
|
// 空闲 watchdog:每个 attempt 一只(重试前换新);fetch 等待期自动计时,
|
|
@@ -286,7 +321,12 @@ export async function* chat(args) {
|
|
|
286
321
|
let watchdog = createIdleWatchdog(signal);
|
|
287
322
|
const postChat = () => {
|
|
288
323
|
const req = format === 'anthropic'
|
|
289
|
-
? buildAnthropicRequest({
|
|
324
|
+
? buildAnthropicRequest({
|
|
325
|
+
provider,
|
|
326
|
+
cleanedMessages,
|
|
327
|
+
tools,
|
|
328
|
+
...(cacheEdits ? { cacheEdits } : {}),
|
|
329
|
+
})
|
|
290
330
|
: buildOpenAIRequest({
|
|
291
331
|
provider,
|
|
292
332
|
cleanedMessages,
|
|
@@ -298,7 +338,12 @@ export async function* chat(args) {
|
|
|
298
338
|
withPromptCacheKey: wantPromptCacheKey,
|
|
299
339
|
responseFormat,
|
|
300
340
|
});
|
|
301
|
-
return fetch(req.url, {
|
|
341
|
+
return fetch(req.url, {
|
|
342
|
+
method: 'POST',
|
|
343
|
+
headers: req.headers,
|
|
344
|
+
body: req.body,
|
|
345
|
+
signal: watchdog.signal,
|
|
346
|
+
});
|
|
302
347
|
};
|
|
303
348
|
const reqId = ++reqCounter;
|
|
304
349
|
dlog('llm', `req#${reqId} POST →`, {
|
|
@@ -315,7 +360,9 @@ export async function* chat(args) {
|
|
|
315
360
|
.map((message) => message.content)),
|
|
316
361
|
toolSchemaHash: promptMaterialHash(tools.map((tool) => ({
|
|
317
362
|
name: tool.name,
|
|
318
|
-
description: typeof tool.description === 'function'
|
|
363
|
+
description: typeof tool.description === 'function'
|
|
364
|
+
? tool.description()
|
|
365
|
+
: tool.description,
|
|
319
366
|
parameters: tool.parameters,
|
|
320
367
|
}))),
|
|
321
368
|
});
|
|
@@ -386,7 +433,8 @@ export async function* chat(args) {
|
|
|
386
433
|
errText = await resp.text().catch(() => '');
|
|
387
434
|
}
|
|
388
435
|
// 退化①:response_format.json_schema 不支持
|
|
389
|
-
if (wantResponseFormat &&
|
|
436
|
+
if (wantResponseFormat &&
|
|
437
|
+
isResponseFormatUnsupported(resp.status, errText)) {
|
|
390
438
|
// 记住该 model 不支持,单进程内后续结构化调用直接跳过 response_format(不再撞 400)。
|
|
391
439
|
rfUnsupported.add(rfKey);
|
|
392
440
|
console.warn(`[minimal-agent] provider model "${provider.model}" 不支持 response_format.json_schema,` +
|
|
@@ -399,7 +447,8 @@ export async function* chat(args) {
|
|
|
399
447
|
}
|
|
400
448
|
catch (e) {
|
|
401
449
|
// 退化二次 fetch 也网络错:把错误外提到外层重试循环
|
|
402
|
-
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
450
|
+
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
451
|
+
'break')
|
|
403
452
|
break;
|
|
404
453
|
continue;
|
|
405
454
|
}
|
|
@@ -419,7 +468,8 @@ export async function* chat(args) {
|
|
|
419
468
|
watchdog.kick();
|
|
420
469
|
}
|
|
421
470
|
catch (e) {
|
|
422
|
-
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
471
|
+
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
472
|
+
'break')
|
|
423
473
|
break;
|
|
424
474
|
continue;
|
|
425
475
|
}
|
|
@@ -432,9 +482,14 @@ export async function* chat(args) {
|
|
|
432
482
|
if (!imagesStripped && isImageInputRejected(resp.status, errText)) {
|
|
433
483
|
const hasImages = cleanedMessages.some((m) => {
|
|
434
484
|
const c = m.content;
|
|
435
|
-
return Array.isArray(c) &&
|
|
485
|
+
return (Array.isArray(c) &&
|
|
486
|
+
c.some((p) => p.type === 'image_url' || p.type === 'video_url'));
|
|
436
487
|
});
|
|
437
488
|
if (hasImages) {
|
|
489
|
+
if (args.visionPolicy === 'required') {
|
|
490
|
+
throw new Error(`当前模型拒绝了本轮必需的图片输入,已停止而未删除图片重试。` +
|
|
491
|
+
`请改用支持视觉的模型或检查模型配置。Provider 返回:${errText.slice(0, 500)}`);
|
|
492
|
+
}
|
|
438
493
|
console.warn(`[minimal-agent] provider model "${provider.model}" 不支持图片输入,` +
|
|
439
494
|
`已剥离图片重发(仅保留文本内容)。如该模型实际支持视觉,请在模型设置中确认。`);
|
|
440
495
|
cleanedMessages = stripImagesFromMessages(cleanedMessages);
|
|
@@ -444,7 +499,8 @@ export async function* chat(args) {
|
|
|
444
499
|
watchdog.kick();
|
|
445
500
|
}
|
|
446
501
|
catch (e) {
|
|
447
|
-
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
502
|
+
if ((await handleNetworkError(e, attempt, 'fallback fetch failed')) ===
|
|
503
|
+
'break')
|
|
448
504
|
break;
|
|
449
505
|
continue;
|
|
450
506
|
}
|
|
@@ -486,7 +542,9 @@ export async function* chat(args) {
|
|
|
486
542
|
const decoder = new TextDecoder();
|
|
487
543
|
/** 临时缓冲:HTTP chunk 不一定按行切,要自己拼 */
|
|
488
544
|
let buffer = '';
|
|
489
|
-
const parser = format === 'anthropic'
|
|
545
|
+
const parser = format === 'anthropic'
|
|
546
|
+
? createAnthropicSSEParser()
|
|
547
|
+
: createOpenAISSEParser();
|
|
490
548
|
try {
|
|
491
549
|
while (true) {
|
|
492
550
|
// 每次 read 前检查 abort:用户按 ESC/Ctrl+C 时 signal.aborted 为 true。
|