minimal-agent 0.10.0 → 0.12.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 +11 -3
- package/package.json +52 -5
- package/plugins/computer_use/.claude-plugin/plugin.json +6 -0
- package/plugins/computer_use/README.md +94 -0
- package/plugins/computer_use/app/_template.md +142 -0
- package/plugins/computer_use/app/chrome.md +165 -0
- package/plugins/computer_use/app/finder.md +76 -0
- package/plugins/computer_use/app/macos-system-settings.md +81 -0
- package/plugins/computer_use/app/microsoft-excel.md +80 -0
- package/plugins/computer_use/app/microsoft-powerpoint.md +80 -0
- package/plugins/computer_use/app/microsoft-word.md +79 -0
- package/plugins/computer_use/app/wechat.md +413 -0
- package/plugins/computer_use/app/weread.md +319 -0
- package/plugins/computer_use/commands/computeruse.md +25 -0
- package/plugins/computer_use/commands/cu.md +9 -0
- package/plugins/computer_use/plugin.js +26 -0
- package/plugins/computer_use/plugin.ts +30 -0
- package/plugins/computer_use/src/capture.js +90 -0
- package/plugins/computer_use/src/capture.ts +104 -0
- package/plugins/computer_use/src/commands.js +91 -0
- package/plugins/computer_use/src/commands.ts +103 -0
- package/plugins/computer_use/src/daemon.js +134 -0
- package/plugins/computer_use/src/daemon.ts +161 -0
- package/plugins/computer_use/src/manuals.js +135 -0
- package/plugins/computer_use/src/manuals.ts +159 -0
- package/plugins/computer_use/src/verify.js +168 -0
- package/plugins/computer_use/src/verify.ts +219 -0
- package/plugins/computer_use/test/commands.test.ts +73 -0
- package/plugins/cron-runner/plugin.ts +38 -0
- package/plugins/cron-runner/src/commands.ts +373 -0
- package/plugins/cron-runner/src/cronTime.ts +155 -0
- package/plugins/cron-runner/src/lock.ts +79 -0
- package/plugins/cron-runner/src/runs.ts +99 -0
- package/plugins/cron-runner/src/scheduleEngine.ts +76 -0
- package/plugins/cron-runner/src/scheduler.ts +376 -0
- package/plugins/cron-runner/src/schema.ts +139 -0
- package/plugins/cron-runner/src/service.ts +193 -0
- package/plugins/cron-runner/src/store.ts +333 -0
- package/plugins/cron-runner/src/types.ts +141 -0
- package/plugins/cron-runner/test/cronTime.test.ts +41 -0
- package/plugins/cron-runner/test/plugin-integration.test.ts +47 -0
- package/plugins/cron-runner/test/scheduleEngine.test.ts +41 -0
- package/plugins/cron-runner/test/service.test.ts +76 -0
- package/plugins/cron-runner/test/store-and-scheduler.test.ts +501 -0
- package/plugins/workflow-runner/plugin.js +56 -2
- package/plugins/workflow-runner/plugin.ts +113 -0
- package/plugins/workflow-runner/src/agentCommon.js +43 -4
- package/plugins/workflow-runner/src/agentCommon.ts +435 -0
- package/plugins/workflow-runner/src/controlFlow/branch.js +40 -0
- package/plugins/workflow-runner/src/controlFlow/branch.ts +46 -0
- package/plugins/workflow-runner/src/controlFlow/loop.js +211 -0
- package/plugins/workflow-runner/src/controlFlow/loop.ts +248 -0
- package/plugins/workflow-runner/src/controlFlow/pause.js +129 -0
- package/plugins/workflow-runner/src/controlFlow/pause.ts +141 -0
- package/plugins/workflow-runner/src/controlFlow/signal.js +21 -0
- package/plugins/workflow-runner/src/controlFlow/signal.ts +29 -0
- package/plugins/workflow-runner/src/controlFlow/types.js +18 -0
- package/plugins/workflow-runner/src/controlFlow/types.ts +63 -0
- package/plugins/workflow-runner/src/dslManifest.ts +127 -0
- package/plugins/workflow-runner/src/expressions.ts +622 -0
- package/plugins/workflow-runner/src/index.js +13 -4
- package/plugins/workflow-runner/src/index.ts +338 -0
- package/plugins/workflow-runner/src/jsonPayload.ts +84 -0
- package/plugins/workflow-runner/src/loader.js +23 -0
- package/plugins/workflow-runner/src/loader.ts +721 -0
- package/plugins/workflow-runner/src/multimodal.js +2 -1
- package/plugins/workflow-runner/src/multimodal.ts +64 -0
- package/plugins/workflow-runner/src/recovery.ts +149 -0
- package/plugins/workflow-runner/src/runner.js +75 -659
- package/plugins/workflow-runner/src/runner.ts +604 -0
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +234 -0
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +50 -0
- package/plugins/workflow-runner/src/stepExecutors/echo.js +31 -0
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +38 -0
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +133 -0
- package/plugins/workflow-runner/src/stepExecutors/set.js +49 -0
- package/plugins/workflow-runner/src/stepExecutors/set.ts +56 -0
- package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +140 -0
- package/plugins/workflow-runner/src/stepExecutors/tool.js +80 -8
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +256 -0
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +68 -0
- package/plugins/workflow-runner/src/stepPipeline.js +277 -0
- package/plugins/workflow-runner/src/stepPipeline.ts +366 -0
- package/plugins/workflow-runner/src/taskIdentity.ts +405 -0
- package/plugins/workflow-runner/src/toolRuntime.js +48 -0
- package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
- package/plugins/workflow-runner/src/types.js +37 -1
- package/plugins/workflow-runner/src/types.ts +602 -0
- package/plugins/workflow-runner/src/workflowState.ts +733 -0
- package/plugins/workflow-runner/test/agent.test.ts +587 -0
- package/plugins/workflow-runner/test/agentLlmError.test.ts +373 -0
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +65 -0
- package/plugins/workflow-runner/test/captureMisbind.test.ts +99 -0
- package/plugins/workflow-runner/test/cli.e2e.test.ts +147 -0
- package/plugins/workflow-runner/test/context-files.test.ts +320 -0
- package/plugins/workflow-runner/test/e2e.test.ts +370 -0
- package/plugins/workflow-runner/test/engineRobustness.test.ts +226 -0
- package/plugins/workflow-runner/test/expressions.test.ts +397 -0
- package/plugins/workflow-runner/test/foundation.test.ts +126 -0
- package/plugins/workflow-runner/test/graceful.test.ts +139 -0
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +47 -0
- package/plugins/workflow-runner/test/hostCapability.test.ts +108 -0
- package/plugins/workflow-runner/test/illustrate.load.test.ts +183 -0
- package/plugins/workflow-runner/test/jsonPayload.test.ts +83 -0
- package/plugins/workflow-runner/test/loader.test.ts +617 -0
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +33 -0
- package/plugins/workflow-runner/test/multimodal.test.ts +342 -0
- package/plugins/workflow-runner/test/output-schema.test.ts +213 -0
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +87 -0
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +269 -0
- package/plugins/workflow-runner/test/ppt.load.test.ts +1220 -0
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +220 -0
- package/plugins/workflow-runner/test/recovery.test.ts +265 -0
- package/plugins/workflow-runner/test/runner.test.ts +911 -0
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +379 -0
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +71 -0
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +150 -0
- package/plugins/workflow-runner/test/stepPipeline.test.ts +114 -0
- package/plugins/workflow-runner/test/taskArbitration.test.ts +338 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +237 -0
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +270 -0
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +221 -0
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +29 -0
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
- package/plugins/workflow-runner/test/webppt.load.test.ts +250 -0
- package/plugins/workflow-runner/test/word.load.test.ts +208 -0
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +76 -0
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +207 -0
- package/skills/browser-automation/SKILL.md +9 -19
- package/skills/web-crawler/SKILL.md +9 -11
- package/src/askBridge.ts +249 -0
- package/src/bootstrap/cwdArg.js +10 -3
- package/src/bootstrap/cwdArg.ts +31 -0
- package/src/bootstrap/workingDir.ts +48 -0
- package/src/cli/args.js +70 -7
- package/src/cli/args.ts +146 -0
- package/src/cli/computerUse.js +185 -0
- package/src/cli/computerUse.ts +221 -0
- package/src/cli/configMenu.js +274 -202
- package/src/cli/configMenu.tsx +521 -0
- package/src/cli/memoryAccess.js +45 -0
- package/src/cli/memoryAccess.ts +53 -0
- package/src/cli/print.js +119 -5
- package/src/cli/print.ts +597 -0
- package/src/cli/quickModelSetup.js +60 -0
- package/src/cli/quickModelSetup.tsx +96 -0
- package/src/cli/streamJson.js +80 -4
- package/src/cli/streamJson.ts +433 -0
- package/src/cli/wizards/advisorWizard.js +1 -0
- package/src/cli/wizards/advisorWizard.tsx +195 -0
- package/src/cli/wizards/agentRuntimeWizard.js +84 -0
- package/src/cli/wizards/agentRuntimeWizard.tsx +134 -0
- package/src/cli/wizards/browserWizard.js +55 -0
- package/src/cli/wizards/browserWizard.tsx +77 -0
- package/src/cli/wizards/contextAdvisorWizard.js +84 -0
- package/src/cli/wizards/contextAdvisorWizard.tsx +124 -0
- package/src/cli/wizards/fieldForm.js +7 -4
- package/src/cli/wizards/fieldForm.tsx +250 -0
- package/src/cli/wizards/imageWizard.js +4 -5
- package/src/cli/wizards/imageWizard.tsx +96 -0
- package/src/cli/wizards/openRouterWizard.tsx +48 -0
- package/src/cli/wizards/providerPresets.js +1 -8
- package/src/cli/wizards/providerPresets.ts +106 -0
- package/src/cli/wizards/providerWizard.js +152 -205
- package/src/cli/wizards/providerWizard.tsx +266 -0
- package/src/cli/wizards/searchWizard.tsx +47 -0
- package/src/cli/wizards/ttsWizard.js +4 -3
- package/src/cli/wizards/ttsWizard.tsx +61 -0
- package/src/config/configDefaults.js +25 -0
- package/src/config/configDefaults.ts +33 -0
- package/src/config/configDiagnostics.js +117 -0
- package/src/config/configDiagnostics.ts +166 -0
- package/src/config/configFile.js +52 -32
- package/src/config/configFile.ts +633 -0
- package/src/config/configManagement.js +126 -0
- package/src/config/configManagement.ts +159 -0
- package/src/config/configService.js +66 -11
- package/src/config/configService.ts +554 -0
- package/src/config/numericLimits.js +61 -0
- package/src/config/numericLimits.ts +80 -0
- package/src/config.ts +109 -0
- package/src/context/agentHome.ts +11 -0
- package/src/context/archive.ts +144 -0
- package/src/context/budgetPlan.js +54 -0
- package/src/context/budgetPlan.ts +88 -0
- package/src/context/compact.js +179 -106
- package/src/context/compact.ts +584 -0
- package/src/context/contextBundle.js +119 -0
- package/src/context/contextBundle.ts +176 -0
- package/src/context/contextLock.ts +84 -0
- package/src/context/microCompactLite.ts +218 -0
- package/src/context/persistContext.ts +177 -0
- package/src/context/reactiveCompact.js +19 -4
- package/src/context/reactiveCompact.ts +240 -0
- package/src/context/recentDirs.ts +42 -0
- package/src/context/sessionPath.ts +206 -0
- package/src/context/sessionRegistry.js +8 -2
- package/src/context/sessionRegistry.ts +414 -0
- package/src/context/snipCompact.ts +163 -0
- package/src/context/tokenCounter.ts +106 -0
- package/src/context/workspaceIndex.js +2 -2
- package/src/context/workspaceIndex.ts +751 -0
- package/src/entry.compiled.tsx +20 -0
- package/src/harness/claimValidation.js +9 -0
- package/src/harness/claimValidation.ts +22 -0
- package/src/harness/evidenceLedger.js +92 -0
- package/src/harness/evidenceLedger.ts +96 -0
- package/src/harness/stallGuard.js +60 -0
- package/src/harness/stallGuard.ts +81 -0
- package/src/humanIntervention.js +129 -0
- package/src/humanIntervention.ts +216 -0
- package/src/infra/verification.ts +295 -0
- package/src/irreversible/rules.js +216 -0
- package/src/irreversible/rules.ts +261 -0
- package/src/llm/client.js +40 -3
- package/src/llm/client.ts +621 -0
- package/src/llm/promptCache.js +27 -0
- package/src/llm/promptCache.ts +41 -0
- package/src/llm/providers/anthropicFormat.js +41 -5
- package/src/llm/providers/anthropicFormat.ts +290 -0
- package/src/llm/providers/openaiFormat.js +186 -8
- package/src/llm/providers/openaiFormat.ts +428 -0
- package/src/loop.js +614 -63
- package/src/loop.ts +1454 -0
- package/src/main.js +67 -10
- package/src/main.tsx +344 -0
- package/src/memory/codec.js +204 -0
- package/src/memory/codec.ts +249 -0
- package/src/memory/constants.js +34 -0
- package/src/memory/constants.ts +50 -0
- package/src/memory/episodicMemory.js +684 -0
- package/src/memory/episodicMemory.ts +815 -0
- package/src/memory/fileStore.js +148 -0
- package/src/memory/fileStore.ts +184 -0
- package/src/memory/memoryService.js +570 -0
- package/src/memory/memoryService.ts +859 -0
- package/src/memory/migration.js +128 -0
- package/src/memory/migration.ts +160 -0
- package/src/memory/repository.js +789 -0
- package/src/memory/repository.ts +893 -0
- package/src/memory/retrieval.js +108 -0
- package/src/memory/retrieval.ts +145 -0
- package/src/memory/searchIndex.js +107 -0
- package/src/memory/searchIndex.ts +153 -0
- package/src/memory/topicView.js +82 -0
- package/src/memory/topicView.ts +95 -0
- package/src/memory/turnJournal.js +95 -0
- package/src/memory/turnJournal.ts +120 -0
- package/src/memory/types.js +2 -0
- package/src/memory/types.ts +186 -0
- package/src/messageQueue.ts +123 -0
- package/src/multimodal.js +128 -46
- package/src/multimodal.ts +349 -0
- package/src/plugin-sdk.js +21 -1
- package/src/plugin-sdk.ts +134 -0
- package/src/plugins/builtinPluginIds.js +47 -0
- package/src/plugins/builtinPluginIds.ts +51 -0
- package/src/plugins/builtinRegistry.ts +43 -0
- package/src/plugins/commandRouter.js +40 -26
- package/src/plugins/commandRouter.ts +261 -0
- package/src/plugins/hookEngine.ts +341 -0
- package/src/plugins/pluginApi.ts +133 -0
- package/src/plugins/pluginLifecycle.ts +34 -0
- package/src/plugins/pluginLoader.ts +147 -0
- package/src/plugins/pluginManifest.js +127 -0
- package/src/plugins/pluginManifest.ts +152 -0
- package/src/plugins/pluginRunner.js +47 -2
- package/src/plugins/pluginRunner.ts +207 -0
- package/src/plugins/transcript.ts +208 -0
- package/src/prompts/lint.js +169 -0
- package/src/prompts/lint.ts +220 -0
- package/src/prompts/pluginList.js +32 -16
- package/src/prompts/pluginList.ts +86 -0
- package/src/prompts/policyRegistry.js +318 -0
- package/src/prompts/policyRegistry.ts +358 -0
- package/src/prompts/projectInstructions.js +24 -0
- package/src/prompts/projectInstructions.ts +81 -0
- package/src/prompts/promptAssembly.js +311 -202
- package/src/prompts/promptAssembly.ts +510 -0
- package/src/prompts/skillList.js +106 -45
- package/src/prompts/skillList.ts +198 -0
- package/src/prompts/system.js +31 -6
- package/src/prompts/system.ts +81 -0
- package/src/runtime/agentRuntimeContext.js +53 -0
- package/src/runtime/agentRuntimeContext.ts +112 -0
- package/src/session/runAgentTurn.js +71 -12
- package/src/session/runAgentTurn.ts +181 -0
- package/src/session/runTurn.js +29 -0
- package/src/session/runTurn.ts +160 -0
- package/src/session/runtimeStore.js +149 -0
- package/src/session/runtimeStore.ts +197 -0
- package/src/session/sessionState.js +79 -3
- package/src/session/sessionState.ts +134 -0
- package/src/toolGate.ts +50 -0
- package/src/tools/advisor/advisor.js +76 -15
- package/src/tools/advisor/advisor.ts +512 -0
- package/src/tools/agent/agent.js +245 -29
- package/src/tools/agent/agent.ts +837 -0
- package/src/tools/agent/agentTaskService.js +60 -0
- package/src/tools/agent/agentTaskService.ts +113 -0
- package/src/tools/agent/agentTypes.js +20 -8
- package/src/tools/agent/agentTypes.ts +94 -0
- package/src/tools/agent/coordinator.ts +111 -0
- package/src/tools/agent/worktree.ts +296 -0
- package/src/tools/ask/ask.js +17 -0
- package/src/tools/ask/ask.ts +122 -0
- package/src/tools/bash/attachImage.js +223 -0
- package/src/tools/bash/attachImage.ts +281 -0
- package/src/tools/bash/bash.js +132 -14
- package/src/tools/bash/bash.ts +642 -0
- package/src/tools/bash/semantics.ts +103 -0
- package/src/tools/bash/warnings.js +17 -11
- package/src/tools/bash/warnings.ts +117 -0
- package/src/tools/capabilities.js +42 -0
- package/src/tools/capabilities.ts +69 -0
- package/src/tools/computeruse/accessibilityPermission.js +261 -0
- package/src/tools/computeruse/accessibilityPermission.ts +294 -0
- package/src/tools/computeruse/axSearch.js +96 -0
- package/src/tools/computeruse/axSearch.ts +120 -0
- package/src/tools/computeruse/axSnap.js +272 -0
- package/src/tools/computeruse/axSnap.ts +349 -0
- package/src/tools/computeruse/capabilityLabels.js +95 -0
- package/src/tools/computeruse/capabilityLabels.ts +115 -0
- package/src/tools/computeruse/computerUseService.js +2235 -0
- package/src/tools/computeruse/computerUseService.ts +2686 -0
- package/src/tools/computeruse/computeruse.js +2742 -0
- package/src/tools/computeruse/computeruse.ts +3265 -0
- package/src/tools/computeruse/diagnosticTrace.js +154 -0
- package/src/tools/computeruse/diagnosticTrace.ts +195 -0
- package/src/tools/computeruse/diagnostics.js +369 -0
- package/src/tools/computeruse/diagnostics.ts +453 -0
- package/src/tools/computeruse/grants.js +53 -0
- package/src/tools/computeruse/grants.ts +70 -0
- package/src/tools/computeruse/humanBoundary.js +159 -0
- package/src/tools/computeruse/humanBoundary.ts +199 -0
- package/src/tools/computeruse/intervention.js +77 -0
- package/src/tools/computeruse/intervention.ts +110 -0
- package/src/tools/computeruse/manualSchema.js +709 -0
- package/src/tools/computeruse/manualSchema.ts +916 -0
- package/src/tools/computeruse/observationImages.js +705 -0
- package/src/tools/computeruse/observationImages.ts +889 -0
- package/src/tools/computeruse/protocol.js +60 -0
- package/src/tools/computeruse/protocol.ts +515 -0
- package/src/tools/computeruse/telemetryLog.js +57 -0
- package/src/tools/computeruse/telemetryLog.ts +67 -0
- package/src/tools/computeruse/vision/appGuide.js +325 -0
- package/src/tools/computeruse/vision/appGuide.ts +482 -0
- package/src/tools/computeruse/vision/focus.js +291 -0
- package/src/tools/computeruse/vision/focus.ts +382 -0
- package/src/tools/computeruse/vision/frames.js +248 -0
- package/src/tools/computeruse/vision/frames.ts +329 -0
- package/src/tools/computeruse/vision/geometry.js +131 -0
- package/src/tools/computeruse/vision/geometry.ts +163 -0
- package/src/tools/computeruse/vision/imaging.js +201 -0
- package/src/tools/computeruse/vision/imaging.ts +281 -0
- package/src/tools/computeruse/vision/png.js +274 -0
- package/src/tools/computeruse/vision/png.ts +317 -0
- package/src/tools/computeruse/vision/raster.js +320 -0
- package/src/tools/computeruse/vision/raster.ts +408 -0
- package/src/tools/computeruse/vision/settle.js +131 -0
- package/src/tools/computeruse/vision/settle.ts +220 -0
- package/src/tools/computeruse/vision/telemetry.js +196 -0
- package/src/tools/computeruse/vision/telemetry.ts +241 -0
- package/src/tools/computeruse/visionOcr.js +115 -0
- package/src/tools/computeruse/visionOcr.ts +128 -0
- package/src/tools/computeruse/waitFor.js +237 -0
- package/src/tools/computeruse/waitFor.ts +291 -0
- package/src/tools/download/download.js +10 -6
- package/src/tools/download/download.ts +187 -0
- package/src/tools/edit/edit.js +30 -18
- package/src/tools/edit/edit.ts +349 -0
- package/src/tools/edit/multi-edit.js +25 -14
- package/src/tools/edit/multi-edit.ts +223 -0
- package/src/tools/effectiveToolSet.js +73 -0
- package/src/tools/effectiveToolSet.ts +91 -0
- package/src/tools/genimage/genimage.ts +257 -0
- package/src/tools/genspeech/genspeech.ts +83 -0
- package/src/tools/glob/glob.js +176 -29
- package/src/tools/glob/glob.ts +283 -0
- package/src/tools/grep/grep.js +61 -19
- package/src/tools/grep/grep.ts +239 -0
- package/src/tools/grep/rgPath.ts +206 -0
- package/src/tools/index.js +99 -5
- package/src/tools/index.ts +293 -0
- package/src/tools/lsp/config.js +113 -0
- package/src/tools/lsp/config.ts +113 -0
- package/src/tools/lsp/lsp.js +256 -0
- package/src/tools/lsp/lsp.ts +274 -0
- package/src/tools/lsp/service.js +303 -0
- package/src/tools/lsp/service.ts +296 -0
- package/src/tools/memory/memory.js +520 -0
- package/src/tools/memory/memory.ts +625 -0
- package/src/tools/memory/policy.js +53 -0
- package/src/tools/memory/policy.ts +72 -0
- package/src/tools/notebook/notebookEdit.js +114 -0
- package/src/tools/notebook/notebookEdit.ts +126 -0
- package/src/tools/powershell/powershell.js +210 -0
- package/src/tools/powershell/powershell.ts +239 -0
- package/src/tools/presentresult/presentresult.js +145 -0
- package/src/tools/presentresult/presentresult.ts +156 -0
- package/src/tools/read/read.js +371 -163
- package/src/tools/read/read.ts +558 -0
- package/src/tools/shared/diffSummary.js +44 -0
- package/src/tools/shared/diffSummary.ts +63 -0
- package/src/tools/shared/fileActivity.js +51 -0
- package/src/tools/shared/fileActivity.ts +66 -0
- package/src/tools/shared/fileMutationBus.js +13 -0
- package/src/tools/shared/fileMutationBus.ts +14 -0
- package/src/tools/shared/fileState.js +73 -65
- package/src/tools/shared/fileState.ts +145 -0
- package/src/tools/shared/fileUtils.js +81 -4
- package/src/tools/shared/fileUtils.ts +504 -0
- package/src/tools/shared/killTree.ts +50 -0
- package/src/tools/shared/permanentDeleteGuard.js +26 -0
- package/src/tools/shared/permanentDeleteGuard.ts +34 -0
- package/src/tools/shared/schemas.ts +20 -0
- package/src/tools/shared/toolOutputStore.js +97 -0
- package/src/tools/shared/toolOutputStore.ts +110 -0
- package/src/tools/skill/skill.js +86 -0
- package/src/tools/skill/skill.ts +94 -0
- package/src/tools/snip/snip.js +67 -0
- package/src/tools/snip/snip.ts +80 -0
- package/src/tools/tasks/backgroundTaskService.js +275 -0
- package/src/tools/tasks/backgroundTaskService.ts +369 -0
- package/src/tools/tasks/processEvidence.js +24 -0
- package/src/tools/tasks/processEvidence.ts +34 -0
- package/src/tools/tasks/taskManagement.js +163 -0
- package/src/tools/tasks/taskManagement.ts +180 -0
- package/src/tools/tasks/taskOutput.js +113 -0
- package/src/tools/tasks/taskOutput.ts +145 -0
- package/src/tools/tasks/taskStop.js +74 -0
- package/src/tools/tasks/taskStop.ts +99 -0
- package/src/tools/tasks/taskStore.js +46 -0
- package/src/tools/tasks/taskStore.ts +77 -0
- package/src/tools/terminal/terminalCapture.js +167 -0
- package/src/tools/terminal/terminalCapture.ts +179 -0
- package/src/tools/trash/trash.js +233 -0
- package/src/tools/trash/trash.ts +283 -0
- package/src/tools/types.js +1 -1
- package/src/tools/types.ts +24 -0
- package/src/tools/webbrowser/agentBrowserPath.ts +286 -0
- package/src/tools/webbrowser/browser.js +214 -11
- package/src/tools/webbrowser/browser.ts +293 -0
- package/src/tools/webbrowser/browserControl.js +153 -48
- package/src/tools/webbrowser/browserControl.ts +262 -0
- package/src/tools/webbrowser/browserDaemon.js +147 -39
- package/src/tools/webbrowser/browserDaemon.ts +270 -0
- package/src/tools/webbrowser/browserOutcome.js +273 -0
- package/src/tools/webbrowser/browserOutcome.ts +306 -0
- package/src/tools/webbrowser/browserRunRegistry.js +150 -0
- package/src/tools/webbrowser/browserRunRegistry.ts +179 -0
- package/src/tools/webbrowser/browserService.js +20 -6
- package/src/tools/webbrowser/browserService.ts +56 -0
- package/src/tools/webbrowser/browserStream.js +30 -1
- package/src/tools/webbrowser/browserStream.ts +216 -0
- package/src/tools/webbrowser/browserTabs.js +143 -0
- package/src/tools/webbrowser/browserTabs.ts +210 -0
- package/src/tools/webbrowser/webbrowser.js +831 -150
- package/src/tools/webbrowser/webbrowser.ts +1537 -0
- package/src/tools/webfetch/preapproved.ts +274 -0
- package/src/tools/webfetch/webfetch.js +24 -23
- package/src/tools/webfetch/webfetch.ts +383 -0
- package/src/tools/websearch/websearch.js +12 -11
- package/src/tools/websearch/websearch.ts +292 -0
- package/src/tools/worktree/sessionWorktree.js +128 -0
- package/src/tools/worktree/sessionWorktree.ts +158 -0
- package/src/tools/write/write.js +27 -44
- package/src/tools/write/write.ts +136 -0
- package/src/types.ts +960 -0
- package/src/ui/App.js +216 -12
- package/src/ui/App.tsx +879 -0
- package/src/ui/AskQuestion.tsx +300 -0
- package/src/ui/InputBox.js +77 -1
- package/src/ui/InputBox.tsx +567 -0
- package/src/ui/LiveArea.tsx +344 -0
- package/src/ui/MessageList.js +27 -6
- package/src/ui/MessageList.tsx +559 -0
- package/src/ui/ModelPicker.tsx +107 -0
- package/src/ui/QueuedMessagesBanner.tsx +51 -0
- package/src/ui/Root.js +6 -8
- package/src/ui/Root.tsx +100 -0
- package/src/ui/SessionPicker.tsx +169 -0
- package/src/ui/StatusLine.js +22 -1
- package/src/ui/StatusLine.tsx +145 -0
- package/src/ui/WorkspacePicker.tsx +84 -0
- package/src/ui/advisorCommand.js +54 -0
- package/src/ui/advisorCommand.ts +63 -0
- package/src/ui/computerCommand.js +19 -0
- package/src/ui/computerCommand.ts +35 -0
- package/src/ui/figures.ts +45 -0
- package/src/ui/hooks/askSlot.ts +112 -0
- package/src/ui/hooks/useChat.js +271 -7
- package/src/ui/hooks/useChat.ts +1578 -0
- package/src/ui/hooks/useInputHistory.ts +235 -0
- package/src/ui/hooks/usePasteHandler.ts +220 -0
- package/src/ui/hooks/useTerminalSize.ts +41 -0
- package/src/ui/hooks/useTextBuffer.ts +108 -0
- package/src/ui/hooks/useTokenUsage.ts +44 -0
- package/src/ui/liveViewport.ts +189 -0
- package/src/ui/markdown.ts +230 -0
- package/src/ui/textBuffer.ts +239 -0
- package/src/ui/theme.ts +35 -0
- package/src/utils/clipboardImage.js +358 -0
- package/src/utils/clipboardImage.ts +420 -0
- package/src/utils/debugLog.ts +50 -0
- package/src/utils/greenRoot.ts +35 -0
- package/src/utils/packageRoot.ts +40 -0
- package/src/utils/pathContains.js +28 -0
- package/src/utils/pathContains.ts +31 -0
- package/src/utils/resourcePaths.ts +71 -0
- package/src/utils/stripThink.ts +49 -0
- package/src/utils/zodToJson.ts +73 -0
- package/src/web/browserBridge.js +365 -66
- package/src/web/browserBridge.ts +672 -0
- package/src/web/protocol.ts +1804 -0
- package/vendor/computer-use/arm64-darwin/cu-helperd +0 -0
- package/workflows/ppt.yaml +13 -2
- package/workflows/wechat-reading-shots.yaml +315 -0
- package/workflows/word.yaml +11 -1
- package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
- /package/skills/ai-image/scripts/{generate_test.mjs → generate.selftest.mjs} +0 -0
- /package/skills/ai-image/scripts/{generate_from_plan_test.mjs → generate_from_plan.selftest.mjs} +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* plugins/workflow-runner/src/stepExecutors/agent.ts —— agent 步骤执行器
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* v0.9 重构:不再使用独立 miniReAct 子循环,而是委托主 TAOR 引擎
|
|
6
|
+
* (runQuery / src/loop.ts)执行。这样做的好处:
|
|
7
|
+
*
|
|
8
|
+
* 1. 上下文自然积累:每步的完整对话(user→assistant→tool→...)
|
|
9
|
+
* 都写入共享 history,后续步骤和用户对话都能看到
|
|
10
|
+
* 2. 工具/skills/插件信息来自系统提示词(history[0]),无需重复组装
|
|
11
|
+
* 3. 压缩自动生效:history 增长时 autoCompact / reactiveCompact 自动触发
|
|
12
|
+
* 4. Token 消耗透明:TUI status 行实时显示真实 token 数
|
|
13
|
+
* 5. 中断后上下文完整:已完成的步骤全在 history 里,可继续/调整
|
|
14
|
+
*
|
|
15
|
+
* 与 llm 步的区别:
|
|
16
|
+
* - agent 有 maxTurns 上限(默认 25),允许多轮工具调用
|
|
17
|
+
* - agent 的产出经过验证闸门(interpretMiniReActResult)
|
|
18
|
+
* - llm 只跑单轮 chat(maxTurns=1)
|
|
19
|
+
* ============================================================
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { LoopEvent } from '../../../../src/plugin-sdk.js';
|
|
23
|
+
import {
|
|
24
|
+
type StepQueryOutcome,
|
|
25
|
+
describeCaptureContract,
|
|
26
|
+
describeLlmFailure,
|
|
27
|
+
describeMaxTurnsCutoff,
|
|
28
|
+
effectiveGoalAnchor,
|
|
29
|
+
interpretMiniReActResult,
|
|
30
|
+
runStepQuery,
|
|
31
|
+
} from '../agentCommon.js';
|
|
32
|
+
import { evalExpr, interpolate } from '../expressions.js';
|
|
33
|
+
import { resolveWorkflowMultimodalOptions } from '../multimodal.js';
|
|
34
|
+
import type { RunContext, StepDef, StepResult, VarStack } from '../types.js';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 执行一个 agent 步骤:构造 step prompt → 委托 runQuery(TAOR) → 提取结果。
|
|
38
|
+
*
|
|
39
|
+
* runQuery 会:
|
|
40
|
+
* 1. 把 prompt 作为 user message push 进 ctx.history
|
|
41
|
+
* 2. 跑 TAOR 循环(调 LLM → 执行工具 → 喂回 → 直到模型不调工具)
|
|
42
|
+
* 3. 把所有 assistant / tool 消息 push 进 ctx.history
|
|
43
|
+
* 4. yield UI 事件(text_delta / tool_start / tool_end / ...)
|
|
44
|
+
*/
|
|
45
|
+
export async function* execAgentStep(
|
|
46
|
+
step: StepDef,
|
|
47
|
+
vars: VarStack,
|
|
48
|
+
ctx: RunContext,
|
|
49
|
+
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
50
|
+
// 默认 25(与 skill 步 skill.ts 对齐)。agent 步本就是「开放多工具任务」执行器,
|
|
51
|
+
// 弱模型常一轮只调一个工具(Read/Grep/Glob 各占一轮),旧默认 12 对探索类步骤
|
|
52
|
+
// (如 plan.yaml stage1_research)太紧——12 轮还没收集完就撞顶截断、误判失败。
|
|
53
|
+
// 这是安全阀不是性能阀;要更紧的步显式写小值即可。
|
|
54
|
+
const maxTurns = step.maxTurns ?? 25;
|
|
55
|
+
|
|
56
|
+
// 未定义变量插值可见化(裸 ${goal} 这类拼写/命名空间错的病根,静默空串会坑死下游)
|
|
57
|
+
const missing: string[] = [];
|
|
58
|
+
const iopts = { onMissing: (e: string) => missing.push(e) };
|
|
59
|
+
|
|
60
|
+
// 构造用户提示:包含步骤指令 + 变量 + capture 约束 + 内部标记防护
|
|
61
|
+
const userPrompt = `${interpolate(step.agent ?? '', vars, iopts)}${describeCaptureContract(step)}${step.input ? `\n\n上下文变量:${interpolate(step.input, vars, iopts)}` : ''}\n\n⚠️ 输出规范:直接输出你的工作成果即可,不要在输出中包含任何类似「放弃」、「GIVEUP」、「__AGENT__」或「[wf-internal」的内部标记文本。`;
|
|
62
|
+
|
|
63
|
+
// 如果有 output_schema,把 schema 约束嵌入 prompt(runQuery 不原生支持 responseFormat)
|
|
64
|
+
const schemaHint = step.output_schema
|
|
65
|
+
? `\n\n【结构化输出约束】请严格按照以下 JSON Schema 输出结果(不要包裹在 markdown 代码块中):\n${JSON.stringify(step.output_schema, null, 2)}`
|
|
66
|
+
: '';
|
|
67
|
+
|
|
68
|
+
const fullPrompt = userPrompt + schemaHint;
|
|
69
|
+
|
|
70
|
+
// 通用目标锚定(原始目标 + 累积的用户补充要求),前置注入 prompt。
|
|
71
|
+
// 确保每步 LLM 都能看到用户原始目标与运行中的补充要求,
|
|
72
|
+
// 避免长上下文 / fresh_context 导致目标被稀释或遗忘。
|
|
73
|
+
const anchor = effectiveGoalAnchor(ctx);
|
|
74
|
+
const effectivePrompt = anchor ? `${anchor}\n\n${fullPrompt}` : fullPrompt;
|
|
75
|
+
|
|
76
|
+
const multimodal = resolveWorkflowMultimodalOptions(step, vars, ctx, (e) =>
|
|
77
|
+
missing.push(e),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (missing.length > 0) {
|
|
81
|
+
yield {
|
|
82
|
+
type: 'warning',
|
|
83
|
+
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 委托 TAOR 引擎执行(共享消费层 runStepQuery:携带 sessionState 以启用上下文压缩,
|
|
88
|
+
// 并统一侦测终结错误——runQuery 遇 LLM 失败是 yield error 后 return 不 throw)。
|
|
89
|
+
const {
|
|
90
|
+
rawText,
|
|
91
|
+
sawToolCall,
|
|
92
|
+
toolNames,
|
|
93
|
+
toolOkCount,
|
|
94
|
+
toolFailCount,
|
|
95
|
+
aborted,
|
|
96
|
+
sawLlmError,
|
|
97
|
+
sawMaxTurns,
|
|
98
|
+
llmErrorDetail,
|
|
99
|
+
} = yield* runStepQuery(effectivePrompt, step, ctx, {
|
|
100
|
+
maxTurns,
|
|
101
|
+
...multimodal,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const stepResult: StepResult = {
|
|
105
|
+
raw: { text: rawText, result: rawText },
|
|
106
|
+
preview: rawText.length > 200 ? `${rawText.slice(0, 200)}...` : rawText,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// 用户中断导致的空产出:不过验证闸门(否则会误抛「放弃: 没有产出任何结果」),
|
|
110
|
+
// 直接返回当前(可能为空的)结果,由 runner 据 signal.aborted 收口(不当作可重试失败)。
|
|
111
|
+
if (aborted) return stepResult;
|
|
112
|
+
|
|
113
|
+
// P0-1(同 llm.ts / skill.ts):LLM 失败(超时/网络错)且本步无任何产出 →
|
|
114
|
+
// 抛「可重试失败」交给 runner 的 in-run retry。必须在验证闸门之前——
|
|
115
|
+
// 否则 provider 故障会被闸门误归因为「agent 步骤放弃: 没有产出任何结果」,
|
|
116
|
+
// 混淆「provider 失败(该重试)」与「模型真放弃/空答(诚实 halt)」。
|
|
117
|
+
if (!rawText.trim() && sawLlmError) {
|
|
118
|
+
// 抛错文案附带 provider 真实报错(经 runner 落 progress.md,刷屏后仍可排障)
|
|
119
|
+
throw new Error(describeLlmFailure(step.id, llmErrorDetail));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 撞 maxTurns 截断:截断时刻的文本是半截工作叙述,不是可信交付——
|
|
123
|
+
// 即使非空也不能过闸门(曾被静默当成功:半成品 PPTX 被整条链当真交付)。
|
|
124
|
+
// 抛可重试失败 → in-run retry 在共享 history 上续作(模型看到已有进度接着干)。
|
|
125
|
+
if (sawMaxTurns) {
|
|
126
|
+
throw new Error(describeMaxTurnsCutoff(step.id, maxTurns));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// done_when 验收兜底(K3/A2):弱模型常「宣告要干活」却不调工具就 end_turn
|
|
130
|
+
//(announce-not-do,2026-06-12 plan 工作流实跑事故的执行步烂尾根因之一)。
|
|
131
|
+
// yaml 作者声明确定性完成条件(如 fileExists('./doc/x.pptx')),不满足时
|
|
132
|
+
// 引擎自动 nudge 同一 agent 在共享 history 上继续干(看得到自己刚才的半截工作),
|
|
133
|
+
// 把「对抗模型不可靠」从每个 yaml 的 prompt 工程收回引擎单点。
|
|
134
|
+
if (step.done_when) {
|
|
135
|
+
const NUDGES = 2; // 提醒上限:超过说明模型真干不动,交给 onError/max_retries
|
|
136
|
+
let result = resultIfTextLooksDeliverable(step, rawText);
|
|
137
|
+
let lastOutcome = {
|
|
138
|
+
rawText,
|
|
139
|
+
sawToolCall,
|
|
140
|
+
toolNames,
|
|
141
|
+
toolOkCount,
|
|
142
|
+
toolFailCount,
|
|
143
|
+
};
|
|
144
|
+
for (let n = 0; ; n++) {
|
|
145
|
+
if (evalDoneWhen(step, vars)) {
|
|
146
|
+
return result ?? doneWhenSatisfiedResult(step);
|
|
147
|
+
}
|
|
148
|
+
if (n >= NUDGES) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`agent 步骤 "${step.id}" 完成条件未满足(done_when: ${step.done_when}),已提醒 ${NUDGES} 次仍未达成。${describeAttemptForDoneWhen(lastOutcome)}`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
yield {
|
|
154
|
+
type: 'warning',
|
|
155
|
+
message: `⏩ step "${step.id}" 完成条件未满足(${step.done_when}),提醒 agent 继续执行(第 ${n + 1}/${NUDGES} 次)。${describeAttemptForDoneWhen(lastOutcome)}`,
|
|
156
|
+
};
|
|
157
|
+
const nudge = yield* runStepQuery(
|
|
158
|
+
`检查发现这一步还没有真正完成:完成条件 \`${step.done_when}\` 仍不成立。不要解释、不要宣告计划——继续实际执行(调用工具落盘/操作),直到完成条件成立,然后给出简短完成报告。`,
|
|
159
|
+
step,
|
|
160
|
+
ctx,
|
|
161
|
+
{ maxTurns },
|
|
162
|
+
);
|
|
163
|
+
if (nudge.aborted) return result ?? stepResult;
|
|
164
|
+
if (!nudge.rawText.trim() && nudge.sawLlmError) {
|
|
165
|
+
throw new Error(describeLlmFailure(step.id, nudge.llmErrorDetail));
|
|
166
|
+
}
|
|
167
|
+
if (nudge.sawMaxTurns) {
|
|
168
|
+
throw new Error(describeMaxTurnsCutoff(step.id, maxTurns));
|
|
169
|
+
}
|
|
170
|
+
lastOutcome = nudge;
|
|
171
|
+
if (nudge.rawText.trim()) {
|
|
172
|
+
result = resultIfTextLooksDeliverable(step, nudge.rawText) ?? result;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 验证闸门:判断结果是"真交付"还是"放弃"。注意:带 done_when 的步骤已在上方
|
|
178
|
+
// 由确定性条件验收,避免"文件已落盘但最终空文本"或"还没落盘但空文本"绕过 nudge。
|
|
179
|
+
const outcome = interpretMiniReActResult(stepResult, !!step.output_schema);
|
|
180
|
+
if (!outcome.ok) throw new Error(`agent 步骤放弃: ${outcome.reason}`);
|
|
181
|
+
|
|
182
|
+
return outcome.value;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function evalDoneWhen(step: StepDef, vars: VarStack): boolean {
|
|
186
|
+
try {
|
|
187
|
+
return Boolean(evalExpr(step.done_when ?? '', vars));
|
|
188
|
+
} catch (e) {
|
|
189
|
+
// 表达式坏了是 yaml 作者错误:响亮失败(同 max_iterations 解析失败哲学),
|
|
190
|
+
// 不能静默当 false 把好结果 nudge 死、也不能静默当 true 放走烂尾。
|
|
191
|
+
throw new Error(
|
|
192
|
+
`step "${step.id}" 的 done_when 表达式求值失败: ${(e as Error).message}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function doneWhenSatisfiedResult(step: StepDef): StepResult {
|
|
198
|
+
const text = `完成条件已满足:${step.done_when}`;
|
|
199
|
+
return { raw: { text, result: text, content: text }, preview: text };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function resultIfTextLooksDeliverable(step: StepDef, text: string): StepResult | null {
|
|
203
|
+
if (!text.trim()) return null;
|
|
204
|
+
const outcome = interpretMiniReActResult(
|
|
205
|
+
{
|
|
206
|
+
raw: { text, result: text },
|
|
207
|
+
preview: text.length > 200 ? `${text.slice(0, 200)}...` : text,
|
|
208
|
+
},
|
|
209
|
+
!!step.output_schema,
|
|
210
|
+
);
|
|
211
|
+
return outcome.ok ? outcome.value : null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
type DoneWhenAttemptSummary = Pick<
|
|
215
|
+
StepQueryOutcome,
|
|
216
|
+
'rawText' | 'sawToolCall' | 'toolNames' | 'toolOkCount' | 'toolFailCount'
|
|
217
|
+
>;
|
|
218
|
+
|
|
219
|
+
function describeAttemptForDoneWhen(outcome: DoneWhenAttemptSummary): string {
|
|
220
|
+
const textState = outcome.rawText.trim()
|
|
221
|
+
? '本轮有文本报告'
|
|
222
|
+
: '本轮没有文本报告';
|
|
223
|
+
if (!outcome.sawToolCall) {
|
|
224
|
+
return `${textState},且没有观察到工具调用;请不要只宣告计划,必须调用工具完成产物。`;
|
|
225
|
+
}
|
|
226
|
+
const names = outcome.toolNames.length ? outcome.toolNames.join('、') : '未知工具';
|
|
227
|
+
const wrote = outcome.toolNames.some((name) =>
|
|
228
|
+
['Write', 'Edit', 'MultiEdit', 'Bash'].includes(name),
|
|
229
|
+
);
|
|
230
|
+
const writeHint = wrote
|
|
231
|
+
? '已观察到写入类工具调用,但完成条件仍未满足,请检查路径或实际写入结果'
|
|
232
|
+
: '未观察到写入类工具调用,请立即调用 Write/Edit/Bash 落盘产物';
|
|
233
|
+
return `${textState};本轮工具调用:${names}(成功 ${outcome.toolOkCount},失败 ${outcome.toolFailCount})。${writeHint}。`;
|
|
234
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* plugins/workflow-runner/src/stepExecutors/assert.ts —— assert step 执行
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* evalExpr(condition) → 真值通过;假值抛错(带 onFail 自定义信息)。
|
|
6
|
+
*
|
|
7
|
+
* v0.9.3(上下文统一修复):assert 步骤通过后也写入 ctx.history,
|
|
8
|
+
* 让后续 LLM 步骤能看到验证通过的信息(如"文件已存在""变量值符合预期"等)。
|
|
9
|
+
* ============================================================
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { evalExpr, interpolate } from '../expressions.js';
|
|
13
|
+
import type { RunContext, StepDef, StepResult, VarStack } from '../types.js';
|
|
14
|
+
|
|
15
|
+
export function execAssertStep(
|
|
16
|
+
step: StepDef,
|
|
17
|
+
vars: VarStack,
|
|
18
|
+
ctx: RunContext, // 必填:runner 唯一调用点(dispatchActionStep)始终传 ctx,
|
|
19
|
+
// 与 tool/agent/llm/skill 执行器签名对齐(编译期强制,不再可选)
|
|
20
|
+
): StepResult {
|
|
21
|
+
if (typeof step.condition !== 'string') {
|
|
22
|
+
throw new Error(`step ${step.id}: assert 缺少 condition`);
|
|
23
|
+
}
|
|
24
|
+
let ok: boolean;
|
|
25
|
+
try {
|
|
26
|
+
ok = Boolean(evalExpr(step.condition, vars));
|
|
27
|
+
} catch (e) {
|
|
28
|
+
throw new Error(`assert 表达式求值失败: ${(e as Error).message}`);
|
|
29
|
+
}
|
|
30
|
+
if (!ok) {
|
|
31
|
+
const msg = step.onFail
|
|
32
|
+
? interpolate(step.onFail, vars)
|
|
33
|
+
: `assertion failed: ${step.condition}`;
|
|
34
|
+
throw new Error(msg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ════ v0.9.3:上下文统一 —— assert 通过也留痕 ════
|
|
38
|
+
// 让后续 LLM 步骤知道某个前置条件/不变量已确认满足。
|
|
39
|
+
// ctx 必填(签名强制,runner 唯一调用点 dispatchActionStep 始终传),直接访问 history。
|
|
40
|
+
if (ctx.history) {
|
|
41
|
+
ctx.history.push({
|
|
42
|
+
role: 'assistant',
|
|
43
|
+
content: `[workflow:${step.id}] ✅ 断言通过:${step.condition}`,
|
|
44
|
+
timestamp: Date.now(),
|
|
45
|
+
id: crypto.randomUUID(),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { raw: { ok: true }, preview: 'assert passed' };
|
|
50
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* stepExecutors/echo.ts —— 确定性输出插值消息给用户
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 从 `runner.ts::runSteps` 的内联块搬出来。它的价值在于「不烧 LLM、零幻觉」:
|
|
6
|
+
* 完成报告用它而不是让模型复述。
|
|
7
|
+
*
|
|
8
|
+
* 搬出来之后走统一提交流水线,于是 **`capture:` 自然生效**(捕获它输出的文本)——
|
|
9
|
+
* 此前 echo 从不调 `bindCapture`、checkpoint 里记的是 `{}`,
|
|
10
|
+
* yaml 写了 `capture` 既不报错也不生效,resume 时也回放不出来。
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ 未定义变量按**空串**插值并发 warning(与 set 的「响亮报错」不同):
|
|
13
|
+
* echo 是给人看的文案,缺个变量不该让整条工作流停下,但也不能悄悄少一段。
|
|
14
|
+
* ============================================================
|
|
15
|
+
*/
|
|
16
|
+
import { truncate } from '../agentCommon.js';
|
|
17
|
+
import { interpolate } from '../expressions.js';
|
|
18
|
+
export async function* execEchoStep(step, vars) {
|
|
19
|
+
const missing = [];
|
|
20
|
+
const text = interpolate(step.message ?? '', vars, {
|
|
21
|
+
onMissing: (e) => missing.push(e),
|
|
22
|
+
});
|
|
23
|
+
if (missing.length > 0) {
|
|
24
|
+
yield {
|
|
25
|
+
type: 'warning',
|
|
26
|
+
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
yield { type: 'text', delta: text.endsWith('\n') ? text : `${text}\n` };
|
|
30
|
+
return { raw: { text, result: text }, preview: truncate(text, 200) };
|
|
31
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* stepExecutors/echo.ts —— 确定性输出插值消息给用户
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 从 `runner.ts::runSteps` 的内联块搬出来。它的价值在于「不烧 LLM、零幻觉」:
|
|
6
|
+
* 完成报告用它而不是让模型复述。
|
|
7
|
+
*
|
|
8
|
+
* 搬出来之后走统一提交流水线,于是 **`capture:` 自然生效**(捕获它输出的文本)——
|
|
9
|
+
* 此前 echo 从不调 `bindCapture`、checkpoint 里记的是 `{}`,
|
|
10
|
+
* yaml 写了 `capture` 既不报错也不生效,resume 时也回放不出来。
|
|
11
|
+
*
|
|
12
|
+
* ⚠️ 未定义变量按**空串**插值并发 warning(与 set 的「响亮报错」不同):
|
|
13
|
+
* echo 是给人看的文案,缺个变量不该让整条工作流停下,但也不能悄悄少一段。
|
|
14
|
+
* ============================================================
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { LoopEvent } from '../../../../src/plugin-sdk.js';
|
|
18
|
+
import { truncate } from '../agentCommon.js';
|
|
19
|
+
import { interpolate } from '../expressions.js';
|
|
20
|
+
import type { StepDef, StepResult, VarStack } from '../types.js';
|
|
21
|
+
|
|
22
|
+
export async function* execEchoStep(
|
|
23
|
+
step: StepDef,
|
|
24
|
+
vars: VarStack,
|
|
25
|
+
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
26
|
+
const missing: string[] = [];
|
|
27
|
+
const text = interpolate(step.message ?? '', vars, {
|
|
28
|
+
onMissing: (e: string) => missing.push(e),
|
|
29
|
+
});
|
|
30
|
+
if (missing.length > 0) {
|
|
31
|
+
yield {
|
|
32
|
+
type: 'warning',
|
|
33
|
+
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}`,
|
|
34
|
+
} as LoopEvent;
|
|
35
|
+
}
|
|
36
|
+
yield { type: 'text', delta: text.endsWith('\n') ? text : `${text}\n` };
|
|
37
|
+
return { raw: { text, result: text }, preview: truncate(text, 200) };
|
|
38
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* plugins/workflow-runner/src/stepExecutors/llm.ts —— llm 步骤执行器
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* v0.9 重构:不再使用独立 miniReAct 子循环或裸 chat(),而是委托主 TAOR 引擎
|
|
6
|
+
* (runQuery / src/loop.ts)执行。
|
|
7
|
+
*
|
|
8
|
+
* 与 agent 步的区别:
|
|
9
|
+
* - llm 默认单轮(maxTurns=1),不下发工具
|
|
10
|
+
* - 有 context_files 或 allowed_tools 时允许少量轮次读取文件后输出
|
|
11
|
+
* - output_schema 嵌入 prompt 作为结构化约束
|
|
12
|
+
* - 不经过 interpretMiniReActResult 验证闸门(直接信任 LLM 输出)
|
|
13
|
+
*
|
|
14
|
+
* capture:
|
|
15
|
+
* - `{ text: var_name }` 绑生成文本
|
|
16
|
+
* - `{ <field>: var_name }` 当 output_schema 存在时按 JSON 字段取值
|
|
17
|
+
* ============================================================
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { LoopEvent } from '../../../../src/plugin-sdk.js';
|
|
21
|
+
import {
|
|
22
|
+
describeLlmFailure,
|
|
23
|
+
describeMaxTurnsCutoff,
|
|
24
|
+
effectiveGoalAnchor,
|
|
25
|
+
runStepQuery,
|
|
26
|
+
} from '../agentCommon.js';
|
|
27
|
+
import { interpolate } from '../expressions.js';
|
|
28
|
+
import { extractJsonPayload } from '../jsonPayload.js';
|
|
29
|
+
import { resolveWorkflowMultimodalOptions } from '../multimodal.js';
|
|
30
|
+
import type { RunContext, StepDef, StepResult, VarStack } from '../types.js';
|
|
31
|
+
|
|
32
|
+
export async function* execLlmStep(
|
|
33
|
+
step: StepDef,
|
|
34
|
+
vars: VarStack,
|
|
35
|
+
ctx: RunContext,
|
|
36
|
+
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
37
|
+
if (typeof step.llm !== 'string') throw new Error(`step ${step.id}: 缺少 llm 字段`);
|
|
38
|
+
|
|
39
|
+
// 未定义变量插值可见化(静默空串是下游 prompt 留白的病根)
|
|
40
|
+
const missing: string[] = [];
|
|
41
|
+
const iopts = { onMissing: (e: string) => missing.push(e) };
|
|
42
|
+
|
|
43
|
+
const prompt = interpolate(step.llm, vars, iopts);
|
|
44
|
+
|
|
45
|
+
// 有 context_files → 在 prompt 中附上文件列表,runQuery 的 TAOR 循环中
|
|
46
|
+
// 模型可自主用 Read 工具读取(ALL_TOOLS 全量可用)
|
|
47
|
+
let fullPrompt = prompt;
|
|
48
|
+
if (step.context_files && step.context_files.length > 0) {
|
|
49
|
+
const fileList = step.context_files
|
|
50
|
+
.map((f) => `- ${interpolate(f.path, vars, iopts)}${f.hint ? ` — ${f.hint}` : ''}`)
|
|
51
|
+
.join('\n');
|
|
52
|
+
fullPrompt = `${prompt}\n\n**以下上下文文件可用,请用 Read 工具按需读取**:\n${fileList}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// output_schema 约束嵌入 prompt
|
|
56
|
+
const schemaHint = step.output_schema
|
|
57
|
+
? `\n\n【结构化输出约束】请严格按照以下 JSON Schema 输出有效 JSON 对象本身(不要 markdown 代码块包裹):\n${JSON.stringify(step.output_schema, null, 2)}`
|
|
58
|
+
: '';
|
|
59
|
+
|
|
60
|
+
fullPrompt += schemaHint;
|
|
61
|
+
|
|
62
|
+
// 通用目标锚定(原始目标 + 补充要求):同 agent.ts,确保每步 LLM 不偏离
|
|
63
|
+
const anchor = effectiveGoalAnchor(ctx);
|
|
64
|
+
const effectivePrompt = anchor ? `${anchor}\n\n${fullPrompt}` : fullPrompt;
|
|
65
|
+
|
|
66
|
+
const needsTools = !!step.context_files?.length || step.allowed_tools !== undefined;
|
|
67
|
+
const queryStep = needsTools ? step : { ...step, allowed_tools: [] };
|
|
68
|
+
|
|
69
|
+
// llm 步默认单轮;需要工具时允许多轮(读文件→输出)
|
|
70
|
+
const maxTurns = step.maxTurns ?? (step.context_files?.length ? 10 : 1);
|
|
71
|
+
|
|
72
|
+
const multimodal = resolveWorkflowMultimodalOptions(step, vars, ctx, (e) =>
|
|
73
|
+
missing.push(e),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (missing.length > 0) {
|
|
77
|
+
yield {
|
|
78
|
+
type: 'warning',
|
|
79
|
+
message: `step "${step.id}": 模板变量未定义,已按空串插值:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 委托 TAOR 引擎执行(共享消费层 runStepQuery:携带 sessionState 以启用上下文压缩,
|
|
84
|
+
// 并统一侦测终结错误——runQuery 遇 LLM 失败是 yield error 后 return 不 throw,
|
|
85
|
+
// 直透会让本步静默返回空文本、runner 的 in-run retry 不触发 → 产出空如空 PLAN.md)。
|
|
86
|
+
const { rawText, aborted, sawLlmError, sawMaxTurns, llmErrorDetail } =
|
|
87
|
+
yield* runStepQuery(effectivePrompt, queryStep, ctx, {
|
|
88
|
+
maxTurns,
|
|
89
|
+
...multimodal,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const trimmed = rawText.trim();
|
|
93
|
+
|
|
94
|
+
// P0-1:LLM 失败(超时/网络错)且本步无任何产出 → 抛异常,触发 runner 的 max_retries 重跑。
|
|
95
|
+
// 必须放在 output_schema 解析之前(空文本本就无法解析),且只在 !aborted 时抛
|
|
96
|
+
// (用户中断不该被当成可重试失败;aborted 时按现状返回空结果即可)。
|
|
97
|
+
if (!trimmed && sawLlmError && !aborted) {
|
|
98
|
+
throw new Error(describeLlmFailure(step.id, llmErrorDetail));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 撞 maxTurns 截断 → 截断时产出不可信,抛可重试失败(续作语义,同 agent.ts)
|
|
102
|
+
if (sawMaxTurns && !aborted) {
|
|
103
|
+
throw new Error(describeMaxTurnsCutoff(step.id, maxTurns));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 结构化输出模式:解析 JSON
|
|
107
|
+
if (step.output_schema) {
|
|
108
|
+
const payload = extractJsonPayload(trimmed);
|
|
109
|
+
let parsed: unknown;
|
|
110
|
+
try {
|
|
111
|
+
parsed = JSON.parse(payload);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`step ${step.id}: output_schema 要求 JSON 输出但解析失败: ${(e as Error).message}\n收到: ${trimmed.slice(0, 200)}`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
118
|
+
throw new Error(
|
|
119
|
+
`step ${step.id}: output_schema 要求对象输出,得到 ${typeof parsed}: ${trimmed.slice(0, 100)}`,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
raw: parsed as Record<string, unknown>,
|
|
124
|
+
preview: `[json] ${trimmed.slice(0, 180)}${trimmed.length > 180 ? '...' : ''}`,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 裸文本模式
|
|
129
|
+
return {
|
|
130
|
+
raw: { text: trimmed, result: trimmed },
|
|
131
|
+
preview: trimmed.length > 200 ? `${trimmed.slice(0, 200)}...` : trimmed,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* stepExecutors/set.ts —— 确定性变量赋值
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 从 `runner.ts::runSteps` 的内联块搬出来。搬出来的收益不只是「runner 短了 40 行」:
|
|
6
|
+
* 它现在走**统一的提交流水线**(`stepPipeline.ts::commitStep`),于是
|
|
7
|
+
* **`capture:` 自然生效了** —— 此前 set 从不调 `bindCapture`、checkpoint 里
|
|
8
|
+
* 记的是 `resolved` 而非 `collectCaptured(...)`,yaml 作者写了 `capture` 既不
|
|
9
|
+
* 报错也不生效,resume 时也回放不出来。典型的静默失效。
|
|
10
|
+
*
|
|
11
|
+
* ⚠️ 两个必须保住的语义:
|
|
12
|
+
* ① 写的是 `vars.setGlobal`(根帧)不是 `vars.set` —— set 步声明的是**工作流级**
|
|
13
|
+
* 变量,在循环体里写也必须活到循环之外。
|
|
14
|
+
* ② 顶层值若是单一 `"${EXPR}"` 模板走 `interpolateTyped` **保留类型**
|
|
15
|
+
* (布尔/数字/数组不字符串化成 "true",下游条件不必写 `== true || == 'true'` 防御);
|
|
16
|
+
* 多片段模板与嵌套结构走 `interpolateDeep`,行为不变。
|
|
17
|
+
* ============================================================
|
|
18
|
+
*/
|
|
19
|
+
import { interpolateDeep, interpolateTyped } from '../expressions.js';
|
|
20
|
+
export async function* execSetStep(step, vars) {
|
|
21
|
+
const missing = [];
|
|
22
|
+
const resolved = {};
|
|
23
|
+
for (const [k, v] of Object.entries(step.set ?? {})) {
|
|
24
|
+
resolved[k] =
|
|
25
|
+
typeof v === 'string'
|
|
26
|
+
? interpolateTyped(v, vars, { onMissing: (e) => missing.push(e) })
|
|
27
|
+
: interpolateDeep(v, vars, { onMissing: (e) => missing.push(e) });
|
|
28
|
+
}
|
|
29
|
+
if (missing.length > 0) {
|
|
30
|
+
yield {
|
|
31
|
+
type: 'warning',
|
|
32
|
+
message: `step "${step.id}": 模板变量未定义:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
for (const [k, v] of Object.entries(resolved)) {
|
|
36
|
+
vars.setGlobal(k, v);
|
|
37
|
+
}
|
|
38
|
+
const summary = Object.entries(resolved)
|
|
39
|
+
.map(([k, v]) => `${k}=${String(v).slice(0, 40)}`)
|
|
40
|
+
.join(', ');
|
|
41
|
+
// raw 就是赋值表本身 —— 这样 `capture: { <变量名>: <别名> }` 能取到刚赋的值。
|
|
42
|
+
// replayVars 让 checkpoint 记下这些赋值:resume 跳过本步时变量仍能回放
|
|
43
|
+
//(set 步通常没有 capture:,只靠 collectCaptured 会记成 {})。
|
|
44
|
+
return {
|
|
45
|
+
raw: { ...resolved },
|
|
46
|
+
replayVars: { ...resolved },
|
|
47
|
+
preview: `set: ${summary}`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* stepExecutors/set.ts —— 确定性变量赋值
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 从 `runner.ts::runSteps` 的内联块搬出来。搬出来的收益不只是「runner 短了 40 行」:
|
|
6
|
+
* 它现在走**统一的提交流水线**(`stepPipeline.ts::commitStep`),于是
|
|
7
|
+
* **`capture:` 自然生效了** —— 此前 set 从不调 `bindCapture`、checkpoint 里
|
|
8
|
+
* 记的是 `resolved` 而非 `collectCaptured(...)`,yaml 作者写了 `capture` 既不
|
|
9
|
+
* 报错也不生效,resume 时也回放不出来。典型的静默失效。
|
|
10
|
+
*
|
|
11
|
+
* ⚠️ 两个必须保住的语义:
|
|
12
|
+
* ① 写的是 `vars.setGlobal`(根帧)不是 `vars.set` —— set 步声明的是**工作流级**
|
|
13
|
+
* 变量,在循环体里写也必须活到循环之外。
|
|
14
|
+
* ② 顶层值若是单一 `"${EXPR}"` 模板走 `interpolateTyped` **保留类型**
|
|
15
|
+
* (布尔/数字/数组不字符串化成 "true",下游条件不必写 `== true || == 'true'` 防御);
|
|
16
|
+
* 多片段模板与嵌套结构走 `interpolateDeep`,行为不变。
|
|
17
|
+
* ============================================================
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { LoopEvent } from '../../../../src/plugin-sdk.js';
|
|
21
|
+
import { interpolateDeep, interpolateTyped } from '../expressions.js';
|
|
22
|
+
import type { StepDef, StepResult, VarStack } from '../types.js';
|
|
23
|
+
|
|
24
|
+
export async function* execSetStep(
|
|
25
|
+
step: StepDef,
|
|
26
|
+
vars: VarStack,
|
|
27
|
+
): AsyncGenerator<LoopEvent, StepResult, void> {
|
|
28
|
+
const missing: string[] = [];
|
|
29
|
+
const resolved: Record<string, unknown> = {};
|
|
30
|
+
for (const [k, v] of Object.entries(step.set ?? {})) {
|
|
31
|
+
resolved[k] =
|
|
32
|
+
typeof v === 'string'
|
|
33
|
+
? interpolateTyped(v, vars, { onMissing: (e) => missing.push(e) })
|
|
34
|
+
: interpolateDeep(v, vars, { onMissing: (e) => missing.push(e) });
|
|
35
|
+
}
|
|
36
|
+
if (missing.length > 0) {
|
|
37
|
+
yield {
|
|
38
|
+
type: 'warning',
|
|
39
|
+
message: `step "${step.id}": 模板变量未定义:${[...new Set(missing)].map((m) => `\${${m}}`).join('、')}(裸名请用 inputs.<name> 或先 capture/set)`,
|
|
40
|
+
} as LoopEvent;
|
|
41
|
+
}
|
|
42
|
+
for (const [k, v] of Object.entries(resolved)) {
|
|
43
|
+
vars.setGlobal(k, v);
|
|
44
|
+
}
|
|
45
|
+
const summary = Object.entries(resolved)
|
|
46
|
+
.map(([k, v]) => `${k}=${String(v).slice(0, 40)}`)
|
|
47
|
+
.join(', ');
|
|
48
|
+
// raw 就是赋值表本身 —— 这样 `capture: { <变量名>: <别名> }` 能取到刚赋的值。
|
|
49
|
+
// replayVars 让 checkpoint 记下这些赋值:resume 跳过本步时变量仍能回放
|
|
50
|
+
//(set 步通常没有 capture:,只靠 collectCaptured 会记成 {})。
|
|
51
|
+
return {
|
|
52
|
+
raw: { ...resolved },
|
|
53
|
+
replayVars: { ...resolved },
|
|
54
|
+
preview: `set: ${summary}`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
* capture:{ text: var_name } / { result: var_name }
|
|
16
16
|
* ============================================================
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
|
-
import { getResourceSearchPaths } from '../../../../src/plugin-sdk.js';
|
|
20
|
+
import { getResourceSearchPaths, } from '../../../../src/plugin-sdk.js';
|
|
21
21
|
import { describeLlmFailure, describeMaxTurnsCutoff, effectiveGoalAnchor, runStepQuery, } from '../agentCommon.js';
|
|
22
22
|
import { interpolate } from '../expressions.js';
|
|
23
|
+
import { effectiveWorkflowCwd } from '../toolRuntime.js';
|
|
23
24
|
function stripFrontmatter(content) {
|
|
24
25
|
return content.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
25
26
|
}
|
|
@@ -53,9 +54,7 @@ async function findSkillFile(skillName, cwd) {
|
|
|
53
54
|
if (parseFrontmatterName(md) === skillName)
|
|
54
55
|
return skillFile;
|
|
55
56
|
}
|
|
56
|
-
catch {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
57
|
+
catch { }
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
return null;
|
|
@@ -64,7 +63,7 @@ export async function* execSkillStep(step, vars, ctx) {
|
|
|
64
63
|
if (!step.skill)
|
|
65
64
|
throw new Error(`step ${step.id}: 缺少 skill 字段`);
|
|
66
65
|
const skillName = interpolate(step.skill, vars);
|
|
67
|
-
const skillFile = await findSkillFile(skillName, ctx
|
|
66
|
+
const skillFile = await findSkillFile(skillName, effectiveWorkflowCwd(ctx));
|
|
68
67
|
if (!skillFile) {
|
|
69
68
|
throw new Error(`step ${step.id}: 未找到 skill "${skillName}"(cwd/skills/ 与 packageRoot/skills/ 双源均未命中)`);
|
|
70
69
|
}
|