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
package/src/tools/agent/agent.js
CHANGED
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
* src/tools/agent/agent.ts —— Agent 工具(fork 子 agent / 多 agent 并行)
|
|
4
4
|
* ------------------------------------------------------------
|
|
5
5
|
* 借鉴 Claude Code 官方 AgentTool/ForkAgent 的核心思想,按 minimal-agent
|
|
6
|
-
*
|
|
6
|
+
* 内核架构做可恢复的前台/后台等效实现:
|
|
7
7
|
* - 官方 fork = 「隔离 context 嵌套跑同一主循环 + 摘要回传(完整历史不进
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* - 同轮混入任一非并发安全工具(如 Edit)会整轮退化串行——这是想要的安全
|
|
13
|
-
* 语义(写操作与并行 fork 不该交错)。
|
|
8
|
+
* 父上下文)」。本工具在隔离 history 中嵌套运行同一主循环,并将私有历史、
|
|
9
|
+
* 进度和结果写入会话运行存储;前台、后台和重启后续接共用同一执行内核。
|
|
10
|
+
* - 同轮多个 Agent 调用仍由 loop.ts 的并行 worker 执行;write scopes 与可选
|
|
11
|
+
* worktree 负责隔离真正可并行的写任务。
|
|
14
12
|
*
|
|
15
13
|
* 已知限制(如实声明):
|
|
16
14
|
* - 子 agent 的 LoopEvent 不外泄:-p / stream-json 宿主只看到本工具的一对
|
|
@@ -27,18 +25,23 @@
|
|
|
27
25
|
* ============================================================
|
|
28
26
|
*/
|
|
29
27
|
import { randomUUID } from 'node:crypto';
|
|
28
|
+
import { EventEmitter } from 'node:events';
|
|
29
|
+
import { access } from 'node:fs/promises';
|
|
30
30
|
import { withAskSource } from '../../askBridge.js';
|
|
31
31
|
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
32
32
|
import { z } from 'zod';
|
|
33
33
|
import { getWorkingDir, withWorkingDir } from '../../bootstrap/workingDir.js';
|
|
34
|
+
import { derivePromptCacheContext } from '../../llm/promptCache.js';
|
|
34
35
|
import { createSessionState } from '../../session/sessionState.js';
|
|
35
|
-
import {
|
|
36
|
+
import { assembleStablePrompt, buildTransientPromptBundle, } from '../../prompts/promptAssembly.js';
|
|
37
|
+
import { createAgentRuntimeContext, filterToolsForRuntime, } from '../../runtime/agentRuntimeContext.js';
|
|
36
38
|
import { stripThinkBlocks } from '../../utils/stripThink.js';
|
|
37
39
|
import { toToolParameters } from '../../utils/zodToJson.js';
|
|
38
40
|
import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
|
|
39
41
|
import { SUBAGENT_EXCLUDED_TOOLS, resolveAgentType } from './agentTypes.js';
|
|
40
42
|
import { acquireSubagentLease, normalizeWriteScopes } from './coordinator.js';
|
|
41
43
|
import { commitWorktreeChanges, createAgentWorktree, hasWorktreeChanges, removeAgentWorktree, worktreeChangedFiles, worktreeDiffStat, } from './worktree.js';
|
|
44
|
+
import { appendAgentEvent, loadAgentRecord, saveAgentRecord } from './agentTaskService.js';
|
|
42
45
|
let corePromise = null;
|
|
43
46
|
/** 首次调用时才真正加载 loop/tools——此刻模块图早已初始化完毕,环安全。 */
|
|
44
47
|
function loadCore() {
|
|
@@ -77,24 +80,27 @@ const inputSchema = z.object({
|
|
|
77
80
|
.max(32)
|
|
78
81
|
.optional()
|
|
79
82
|
.describe('general 预计修改的工作目录相对路径。范围互不重叠时可并行;缺省时按整个工作目录串行。explore 不需要。'),
|
|
83
|
+
run_in_background: z.boolean().optional().describe('立即返回 agent_id,子任务在后台运行;用 TaskOutput/TaskStop 管理'),
|
|
84
|
+
resume_agent_id: z.string().regex(/^agent_[0-9a-f-]{36}$/i).optional().describe('继续当前会话中此前完成、中断或失败的 Agent 历史'),
|
|
80
85
|
});
|
|
81
86
|
const parameters = toToolParameters(inputSchema);
|
|
82
87
|
// ---------------- 2. Description(给 LLM 看的工具说明) ----------------
|
|
83
88
|
// 借鉴官方 AgentTool prompt 文案(任务书自包含 / 同轮并行 / 何时不用)。
|
|
84
|
-
const description = `- Launches
|
|
89
|
+
const description = `- Launches an isolated sub-agent for one self-contained task. Every run returns an agent_id; run_in_background=true continues without blocking, and resume_agent_id continues its persisted private history across user turns or an app restart.
|
|
85
90
|
- The sub-agent CANNOT see this conversation. The \`prompt\` must be fully self-contained: background, exact file paths, what to look for / do, and the expected output format.
|
|
86
91
|
- **To parallelize, emit multiple Agent calls in ONE assistant message** — they run concurrently. This is the main value of this tool.
|
|
92
|
+
- Background Agent progress/results are read with TaskOutput and stopped with TaskStop. Do not poll: TaskOutput(block=true) waits efficiently.
|
|
87
93
|
- Use for: exploring/researching several independent areas of a codebase at once, parallel information gathering from multiple sources, independent analyses that will be synthesized afterwards, and (with agent_type:'general') genuinely parallelizable write/execute work.
|
|
88
94
|
- Do NOT use for: single targeted lookups that one or two direct tool calls would answer (a fork starts cold and re-derives context — slower and costlier), or strictly sequential work. Only general execution agents may ask the user, and only when genuinely blocked.
|
|
89
95
|
- agent_type: 'explore' (default) = strictly read-only research; 'general' = read-write execution. For direct writes, declare relative write_scopes; disjoint scopes may run concurrently, overlapping or omitted scopes are serialized.
|
|
90
|
-
- isolation:'worktree' (general only): the sub-agent sees the repo's last COMMITTED state
|
|
91
|
-
- After sub-agents return you MUST synthesize: cross-check contradictions between reports, integrate into one conclusion — never just forward raw reports. A failed/timed-out fork is not a blocker: proceed with what you have and state the gap
|
|
96
|
+
- isolation:'worktree' (general only): the sub-agent sees the repo's last COMMITTED state. Never commit the user's work merely to expose uncommitted changes; instead keep the task in the current workspace or make the task self-contained. On completion its changes are committed only to a temporary branch; review before applying it to the user's workspace.
|
|
97
|
+
- After sub-agents return you MUST synthesize: cross-check contradictions between reports, integrate into one conclusion — never just forward raw reports. A failed/timed-out fork is not a blocker: proceed with what you have and state the gap.
|
|
98
|
+
- Each sub-task result carries coveredFiles: the actual files/URLs the sub-agent read, extracted from its tool-call history (not self-reported). Before trusting a conclusion, audit its coveredFiles for gaps/overlaps — if coverage looks too thin for what it claims, treat that conclusion as low-confidence.`;
|
|
92
99
|
// ---------------- 3. 子 agent 系统提示词(memoize,提示词缓存友好) ----------------
|
|
93
|
-
/**
|
|
100
|
+
/** 任务回传契约。能力与权限已经由 assembleBasePrompt profile 精确注入。 */
|
|
94
101
|
const SUBAGENT_COMMON_APPENDIX = `# 你是子 agent(fork 分身)
|
|
95
102
|
你是主 agent 派生出的子 agent,正在执行一个自包含的子任务:
|
|
96
103
|
- 你看不到主对话;任务书(用户消息)就是你的全部输入。
|
|
97
|
-
- explore 子任务不能向用户提问;general 仅在缺少关键输入或高风险取舍时使用 AskUserQuestion,最多两次。
|
|
98
104
|
- 你的**最后一条回复就是唯一回传主 agent 的报告**,必须自包含:结论 + 关键证据(文件路径/行号)+ 未尽事项。
|
|
99
105
|
不要输出「我完成了」这类无信息量收尾,也不要在报告里向主 agent 提问——它不会回复你。`;
|
|
100
106
|
/**
|
|
@@ -107,15 +113,18 @@ const SUBAGENT_COMMON_APPENDIX = `# 你是子 agent(fork 分身)
|
|
|
107
113
|
const PROMPT_CACHE_TTL_MS = 60_000;
|
|
108
114
|
const promptCache = new Map();
|
|
109
115
|
async function buildSubSystemPrompt(cwd, def, allTools) {
|
|
110
|
-
|
|
116
|
+
// Effective capabilities are part of prompt identity; a child must never
|
|
117
|
+
// reuse a cached parent-capability prompt (notably Desktop WebBrowser).
|
|
118
|
+
const key = `${cwd}::${def.type}::${allTools.map((tool) => tool.name).join(',')}`;
|
|
111
119
|
const hit = promptCache.get(key);
|
|
112
120
|
if (hit && Date.now() - hit.at < PROMPT_CACHE_TTL_MS)
|
|
113
121
|
return hit.value;
|
|
114
122
|
const allowedNames = def.resolveAllowedTools(allTools.map((t) => t.name));
|
|
115
123
|
const subTools = allTools.filter((t) => allowedNames.includes(t.name));
|
|
116
|
-
const base = await
|
|
124
|
+
const base = await assembleStablePrompt({
|
|
117
125
|
cwd,
|
|
118
126
|
tools: subTools,
|
|
127
|
+
profile: def.type === 'general' ? 'subagent-general' : 'subagent-explore',
|
|
119
128
|
includeProjectInstructions: true, // 子 agent 在同一仓库干活,项目约定必须继承
|
|
120
129
|
includePlugins: false, // 插件是宿主命令面,子 agent 不该被引去激活插件
|
|
121
130
|
});
|
|
@@ -123,6 +132,52 @@ async function buildSubSystemPrompt(cwd, def, allTools) {
|
|
|
123
132
|
promptCache.set(key, { value, at: Date.now() });
|
|
124
133
|
return value;
|
|
125
134
|
}
|
|
135
|
+
// ---------------- 3.5 覆盖度提取(客观,从工具调用历史推导) ----------------
|
|
136
|
+
/**
|
|
137
|
+
* 从子任务 history 中提取「实际读取/调研过的文件/目标」清单,
|
|
138
|
+
* 用于父 agent / 宿主做覆盖度自检,避免「以为覆盖了其实没覆盖」的幻觉。
|
|
139
|
+
*/
|
|
140
|
+
export function extractCoveredFiles(history, startIdx) {
|
|
141
|
+
const seen = new Set();
|
|
142
|
+
for (let i = startIdx; i < history.length; i++) {
|
|
143
|
+
const msg = history[i];
|
|
144
|
+
if (msg.role !== 'assistant' || !msg.tool_calls)
|
|
145
|
+
continue;
|
|
146
|
+
for (const tc of msg.tool_calls) {
|
|
147
|
+
const name = tc.function.name;
|
|
148
|
+
let args;
|
|
149
|
+
try {
|
|
150
|
+
args = JSON.parse(tc.function.arguments);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (!args)
|
|
156
|
+
continue;
|
|
157
|
+
if (name === 'Read' && typeof args.file_path === 'string') {
|
|
158
|
+
seen.add(args.file_path);
|
|
159
|
+
}
|
|
160
|
+
else if (name === 'Glob' && typeof args.pattern === 'string') {
|
|
161
|
+
seen.add(`glob:${args.pattern}`);
|
|
162
|
+
}
|
|
163
|
+
else if (name === 'Grep') {
|
|
164
|
+
const parts = ['grep:' + (typeof args.pattern === 'string' ? args.pattern : '?')];
|
|
165
|
+
if (typeof args.path === 'string')
|
|
166
|
+
parts.push(`path=${args.path}`);
|
|
167
|
+
if (typeof args.glob === 'string')
|
|
168
|
+
parts.push(`glob=${args.glob}`);
|
|
169
|
+
seen.add(parts.join(' '));
|
|
170
|
+
}
|
|
171
|
+
else if (name === 'WebFetch' && typeof args.url === 'string') {
|
|
172
|
+
seen.add(args.url);
|
|
173
|
+
}
|
|
174
|
+
else if (name === 'WebBrowser' && typeof args.url === 'string') {
|
|
175
|
+
seen.add(`browser:${args.url}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return [...seen].sort();
|
|
180
|
+
}
|
|
126
181
|
function positiveInt(value) {
|
|
127
182
|
const n = Number.parseInt(value ?? '', 10);
|
|
128
183
|
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
@@ -186,10 +241,10 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
186
241
|
// allowedTools 只裁「下发给模型的清单」;guardedExecute 是真正的硬防线(见下)。
|
|
187
242
|
const allowedTools = def.resolveAllowedTools(ALL_TOOLS.map((t) => t.name));
|
|
188
243
|
// ---- worktree 隔离(仅 general 显式要求时) ----
|
|
189
|
-
let wt = null;
|
|
244
|
+
let wt = deps.existingWorktree ?? null;
|
|
190
245
|
const isolation = input.isolation ?? ctx.subagentConfig?.defaultWriteIsolation ?? 'none';
|
|
191
|
-
if (def.type === 'general' && isolation === 'worktree') {
|
|
192
|
-
const created = await createAgentWorktree(`fork-${randomUUID().slice(0, 8)}
|
|
246
|
+
if (def.type === 'general' && isolation === 'worktree' && !wt) {
|
|
247
|
+
const created = await createAgentWorktree(`fork-${randomUUID().slice(0, 8)}`, ctx.cwd);
|
|
193
248
|
if (!created.ok) {
|
|
194
249
|
return {
|
|
195
250
|
ok: false,
|
|
@@ -197,8 +252,9 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
197
252
|
};
|
|
198
253
|
}
|
|
199
254
|
wt = created;
|
|
255
|
+
await deps.onWorktreeCreated?.(created);
|
|
200
256
|
}
|
|
201
|
-
const cwd = wt?.path ?? getWorkingDir();
|
|
257
|
+
const cwd = wt?.path ?? ctx.cwd ?? getWorkingDir();
|
|
202
258
|
let writeScopes;
|
|
203
259
|
try {
|
|
204
260
|
writeScopes = def.type === 'general'
|
|
@@ -211,6 +267,38 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
211
267
|
return { ok: false, error: error.message };
|
|
212
268
|
}
|
|
213
269
|
const rootScope = await normalizeWriteScopes(cwd, undefined);
|
|
270
|
+
const childMemoryAccess = ctx.memoryAccess === 'denied' || !ctx.memoryAccess
|
|
271
|
+
? 'denied'
|
|
272
|
+
: 'read-only';
|
|
273
|
+
const childRuntime = createAgentRuntimeContext({
|
|
274
|
+
surface: 'subagent',
|
|
275
|
+
profile: def.type === 'general' ? 'subagent-general' : 'subagent-explore',
|
|
276
|
+
cwd,
|
|
277
|
+
workspaceId: ctx.workspaceId,
|
|
278
|
+
sessionId: ctx.sessionId,
|
|
279
|
+
owner: childMemoryAccess === 'denied' ? 'untrusted' : 'local-owner',
|
|
280
|
+
memoryAccess: childMemoryAccess,
|
|
281
|
+
interactiveAsk: def.type === 'general',
|
|
282
|
+
toolGate: ctx.toolGate,
|
|
283
|
+
});
|
|
284
|
+
const subTools = filterToolsForRuntime(ALL_TOOLS.filter((tool) => allowedTools.includes(tool.name)), childRuntime);
|
|
285
|
+
const subToolNames = subTools.map((tool) => tool.name);
|
|
286
|
+
const childTransientBundle = await buildTransientPromptBundle({
|
|
287
|
+
cwd,
|
|
288
|
+
tools: subTools,
|
|
289
|
+
profile: childRuntime.profile,
|
|
290
|
+
includeProjectInstructions: true,
|
|
291
|
+
includePlugins: false,
|
|
292
|
+
runtime: {
|
|
293
|
+
surface: 'subagent',
|
|
294
|
+
cwd,
|
|
295
|
+
workspaceId: ctx.workspaceId,
|
|
296
|
+
sessionId: ctx.sessionId,
|
|
297
|
+
interactiveAsk: childRuntime.interactiveAsk,
|
|
298
|
+
memoryAccess: childMemoryAccess,
|
|
299
|
+
currentUserInput: input.prompt,
|
|
300
|
+
},
|
|
301
|
+
}).catch(() => undefined);
|
|
214
302
|
let lastPublishAt = 0;
|
|
215
303
|
const label = input.description;
|
|
216
304
|
const publish = (line, detail, force = false) => {
|
|
@@ -221,8 +309,8 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
221
309
|
ctx.reportProgress?.(line, detail);
|
|
222
310
|
};
|
|
223
311
|
// ---- 子 history:一条 system(压缩按 role 定位,必须存在)+ runQuery 自己 push 任务书 ----
|
|
224
|
-
const history = [
|
|
225
|
-
{ role: 'system', content: await buildSubSystemPrompt(cwd, def,
|
|
312
|
+
const history = deps.initialHistory?.length ? [...deps.initialHistory] : [
|
|
313
|
+
{ role: 'system', content: await buildSubSystemPrompt(cwd, def, subTools) },
|
|
226
314
|
];
|
|
227
315
|
const historyLenBefore = history.length;
|
|
228
316
|
const maxConcurrent = positiveInt(process.env.AGENT_TOOL_MAX_CONCURRENT) ?? ctx.subagentConfig?.maxConcurrent ?? 3;
|
|
@@ -353,20 +441,22 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
353
441
|
publish('正在分析任务', { kind: 'subagent', phase: 'analyzing' }, true);
|
|
354
442
|
const events = runQuery(input.prompt, {
|
|
355
443
|
provider: ctx.provider,
|
|
444
|
+
runtimeContext: childRuntime,
|
|
356
445
|
history,
|
|
357
446
|
maxTurns,
|
|
358
|
-
allowedTools,
|
|
447
|
+
allowedTools: subToolNames,
|
|
359
448
|
signal: combinedSignal,
|
|
360
449
|
sessionState: createSessionState(), // 独立会话态,不与主循环/其他分身串扰
|
|
361
450
|
toolGate: ctx.toolGate, // 继承主循环审批策略(不给可写子 agent 开审批后门)
|
|
362
451
|
chat: deps.chat,
|
|
363
452
|
executeTool: guardedExecute,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
453
|
+
memoryContext: {
|
|
454
|
+
access: childMemoryAccess,
|
|
455
|
+
workspaceId: ctx.workspaceId,
|
|
456
|
+
sessionId: ctx.sessionId,
|
|
457
|
+
},
|
|
458
|
+
transientBundle: childTransientBundle,
|
|
459
|
+
promptCache: derivePromptCacheContext(ctx.promptCache, `subagent:${ctx.toolCallId ?? input.description}`),
|
|
370
460
|
// 不传 transientContext:任务书必须自包含,父回合的瞬时上下文不该隐式泄入
|
|
371
461
|
});
|
|
372
462
|
for await (const ev of events) {
|
|
@@ -445,6 +535,7 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
445
535
|
finally {
|
|
446
536
|
stopTimeout();
|
|
447
537
|
releaseLease?.();
|
|
538
|
+
await deps.captureHistory?.(history);
|
|
448
539
|
}
|
|
449
540
|
// ---- 结局映射(直接查 signal 状态,不依赖事件旗标) ----
|
|
450
541
|
if (ownerCancelController.signal.aborted) {
|
|
@@ -505,6 +596,8 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
505
596
|
changedFiles.add(path);
|
|
506
597
|
report += await finalizeWorktree(wt, label);
|
|
507
598
|
}
|
|
599
|
+
// 覆盖度提取(客观,从 tool call 历史推导)——在截断之前,不受报告长度影响。
|
|
600
|
+
const coveredFiles = extractCoveredFiles(history, historyLenBefore);
|
|
508
601
|
if (report.length > DEFAULT_MAX_RESULT_SIZE_CHARS) {
|
|
509
602
|
report =
|
|
510
603
|
report.slice(0, DEFAULT_MAX_RESULT_SIZE_CHARS) +
|
|
@@ -523,6 +616,7 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
523
616
|
failedToolCalls: toolFail,
|
|
524
617
|
durationMs: Date.now() - startedAt,
|
|
525
618
|
changedFiles: [...changedFiles].sort(),
|
|
619
|
+
coveredFiles,
|
|
526
620
|
...(wt && changedFiles.size > 0 ? {
|
|
527
621
|
worktree: {
|
|
528
622
|
id: wt.branch.replace(/^agent\//, ''),
|
|
@@ -538,6 +632,128 @@ export async function runAgentTask(input, signal, ctx, deps = {}) {
|
|
|
538
632
|
async function call(input, signal) {
|
|
539
633
|
return runAgentTask(input, signal, {});
|
|
540
634
|
}
|
|
635
|
+
export async function runManagedAgentTask(input, signal, ctx, deps = {}) {
|
|
636
|
+
if (!ctx.sessionState)
|
|
637
|
+
return runAgentTask(input, signal, ctx);
|
|
638
|
+
const id = input.resume_agent_id ?? `agent_${randomUUID()}`;
|
|
639
|
+
let initialHistory;
|
|
640
|
+
let resumedWorktree;
|
|
641
|
+
let coreInput = { ...input, run_in_background: undefined, resume_agent_id: undefined };
|
|
642
|
+
if (input.resume_agent_id) {
|
|
643
|
+
const live = ctx.sessionState.agentTasks.tasks.get(id);
|
|
644
|
+
if (live?.status === 'running')
|
|
645
|
+
return { ok: false, error: `Agent ${id} 正在运行,不能并发恢复` };
|
|
646
|
+
const saved = await loadAgentRecord(ctx, id);
|
|
647
|
+
if (!saved)
|
|
648
|
+
return { ok: false, error: `找不到可恢复 Agent:${id}` };
|
|
649
|
+
initialHistory = saved.history;
|
|
650
|
+
resumedWorktree = saved.worktree && await access(saved.worktree.path)
|
|
651
|
+
.then(() => saved.worktree)
|
|
652
|
+
.catch(() => undefined);
|
|
653
|
+
coreInput = {
|
|
654
|
+
...saved.input,
|
|
655
|
+
prompt: input.prompt,
|
|
656
|
+
description: input.description || saved.description,
|
|
657
|
+
run_in_background: undefined,
|
|
658
|
+
resume_agent_id: undefined,
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
const abort = new AbortController();
|
|
662
|
+
const combined = signal ? AbortSignal.any([signal, abort.signal]) : abort.signal;
|
|
663
|
+
let settle;
|
|
664
|
+
const completion = new Promise((resolvePromise) => { settle = resolvePromise; });
|
|
665
|
+
const task = {
|
|
666
|
+
id,
|
|
667
|
+
status: 'running',
|
|
668
|
+
description: coreInput.description,
|
|
669
|
+
input: coreInput,
|
|
670
|
+
createdAt: Date.now(),
|
|
671
|
+
updatedAt: Date.now(),
|
|
672
|
+
abort,
|
|
673
|
+
completion,
|
|
674
|
+
events: new EventEmitter(),
|
|
675
|
+
};
|
|
676
|
+
ctx.sessionState.agentTasks.tasks.set(id, task);
|
|
677
|
+
await saveAgentRecord(ctx, task);
|
|
678
|
+
await appendAgentEvent(ctx, id, { phase: 'started', resumed: Boolean(input.resume_agent_id) });
|
|
679
|
+
const run = async () => {
|
|
680
|
+
let captured = initialHistory;
|
|
681
|
+
let lastPersistedProgressAt = 0;
|
|
682
|
+
const managedContext = {
|
|
683
|
+
...ctx,
|
|
684
|
+
reportProgress: (line, detail) => {
|
|
685
|
+
ctx.reportProgress?.(line, detail);
|
|
686
|
+
task.progress = line;
|
|
687
|
+
task.events.emit('change');
|
|
688
|
+
if (Date.now() - lastPersistedProgressAt >= 1_000) {
|
|
689
|
+
lastPersistedProgressAt = Date.now();
|
|
690
|
+
void saveAgentRecord(ctx, task).catch(() => undefined);
|
|
691
|
+
void appendAgentEvent(ctx, id, { phase: 'progress', message: line })
|
|
692
|
+
.catch(() => undefined);
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
};
|
|
696
|
+
try {
|
|
697
|
+
const result = await runAgentTask(coreInput, combined, managedContext, {
|
|
698
|
+
...deps,
|
|
699
|
+
initialHistory,
|
|
700
|
+
existingWorktree: resumedWorktree,
|
|
701
|
+
onWorktreeCreated: async (worktree) => {
|
|
702
|
+
task.worktree = worktree;
|
|
703
|
+
await saveAgentRecord(ctx, task);
|
|
704
|
+
},
|
|
705
|
+
captureHistory: (history) => { captured = [...history]; },
|
|
706
|
+
});
|
|
707
|
+
task.result = result;
|
|
708
|
+
task.history = captured;
|
|
709
|
+
task.status = abort.signal.aborted ? 'stopped' : result.ok ? 'completed' : 'failed';
|
|
710
|
+
if (task.worktree && !await access(task.worktree.path).then(() => true).catch(() => false)) {
|
|
711
|
+
task.worktree = undefined;
|
|
712
|
+
}
|
|
713
|
+
task.updatedAt = Date.now();
|
|
714
|
+
await saveAgentRecord(ctx, task);
|
|
715
|
+
await appendAgentEvent(ctx, id, { phase: task.status, ok: result.ok });
|
|
716
|
+
return result;
|
|
717
|
+
}
|
|
718
|
+
catch (error) {
|
|
719
|
+
task.status = abort.signal.aborted ? 'stopped' : 'failed';
|
|
720
|
+
task.result = { ok: false, error: error.message };
|
|
721
|
+
task.history = captured;
|
|
722
|
+
task.updatedAt = Date.now();
|
|
723
|
+
await saveAgentRecord(ctx, task).catch(() => undefined);
|
|
724
|
+
await appendAgentEvent(ctx, id, { phase: task.status, error: error.message })
|
|
725
|
+
.catch(() => undefined);
|
|
726
|
+
return task.result;
|
|
727
|
+
}
|
|
728
|
+
finally {
|
|
729
|
+
task.events.emit('change');
|
|
730
|
+
settle();
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
if (input.run_in_background) {
|
|
734
|
+
void run();
|
|
735
|
+
return {
|
|
736
|
+
ok: true,
|
|
737
|
+
content: `后台 Agent 已启动。agent_id=${id}\n使用 TaskOutput 获取进度/结果,TaskStop 停止。`,
|
|
738
|
+
metadata: {
|
|
739
|
+
kind: 'agent', agentId: id, status: 'running',
|
|
740
|
+
agentType: input.agent_type ?? 'explore', description: input.description,
|
|
741
|
+
isolation: input.isolation ?? 'none', turns: 0, toolCalls: 0,
|
|
742
|
+
failedToolCalls: 0, durationMs: 0, changedFiles: [],
|
|
743
|
+
},
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
const result = await run();
|
|
747
|
+
if (result.ok && result.metadata?.kind === 'agent') {
|
|
748
|
+
result.metadata.agentId = id;
|
|
749
|
+
result.metadata.status = 'completed';
|
|
750
|
+
result.content = `agent_id=${id}\n${result.content}`;
|
|
751
|
+
}
|
|
752
|
+
else if (!result.ok) {
|
|
753
|
+
result.error = `agent_id=${id}\n${result.error}`;
|
|
754
|
+
}
|
|
755
|
+
return result;
|
|
756
|
+
}
|
|
541
757
|
// ---------------- 5. 导出 ----------------
|
|
542
758
|
export const agentTool = {
|
|
543
759
|
name: 'Agent',
|
|
@@ -551,5 +767,5 @@ export const agentTool = {
|
|
|
551
767
|
maxResultSizeChars: DEFAULT_MAX_RESULT_SIZE_CHARS,
|
|
552
768
|
interruptBehavior: () => 'block',
|
|
553
769
|
call,
|
|
554
|
-
callWithContext:
|
|
770
|
+
callWithContext: runManagedAgentTask,
|
|
555
771
|
};
|