minimal-agent 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/package.json +60 -4
- package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
- package/plugins/cron-runner/src/commands.js +4 -4
- package/plugins/cron-runner/src/commands.ts +4 -4
- package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
- package/plugins/workflow-runner/commands/workflow.md +57 -90
- package/plugins/workflow-runner/commands/workflows.md +4 -4
- package/plugins/workflow-runner/plugin.js +24 -13
- package/plugins/workflow-runner/plugin.ts +28 -13
- package/plugins/workflow-runner/src/discovery.js +160 -0
- package/plugins/workflow-runner/src/discovery.ts +194 -0
- package/plugins/workflow-runner/src/goalAnchor.js +53 -0
- package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
- package/plugins/workflow-runner/src/index.js +197 -206
- package/plugins/workflow-runner/src/index.ts +248 -249
- package/plugins/workflow-runner/src/inputCoercion.js +40 -0
- package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
- package/plugins/workflow-runner/src/journal.js +224 -0
- package/plugins/workflow-runner/src/journal.ts +274 -0
- package/plugins/workflow-runner/src/jsonSchema.js +132 -0
- package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
- package/plugins/workflow-runner/src/moduleResolution.js +64 -0
- package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
- package/plugins/workflow-runner/src/resourceInputs.js +220 -0
- package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
- package/plugins/workflow-runner/src/runner.js +400 -489
- package/plugins/workflow-runner/src/runner.ts +488 -560
- package/plugins/workflow-runner/src/runtime/config.js +46 -0
- package/plugins/workflow-runner/src/runtime/config.ts +69 -0
- package/plugins/workflow-runner/src/runtime/context.js +1304 -0
- package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
- package/plugins/workflow-runner/src/runtime/exec.js +34 -0
- package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
- package/plugins/workflow-runner/src/runtime/flow.js +8 -0
- package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
- package/plugins/workflow-runner/src/runtime/fs.js +27 -0
- package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
- package/plugins/workflow-runner/src/runtime/model.js +6 -0
- package/plugins/workflow-runner/src/runtime/model.ts +8 -0
- package/plugins/workflow-runner/src/runtime/output.js +7 -0
- package/plugins/workflow-runner/src/runtime/output.ts +21 -0
- package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
- package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
- package/plugins/workflow-runner/src/runtime/state.js +16 -0
- package/plugins/workflow-runner/src/runtime/state.ts +19 -0
- package/plugins/workflow-runner/src/runtime/tools.js +3 -0
- package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
- package/plugins/workflow-runner/src/sandbox.js +141 -0
- package/plugins/workflow-runner/src/sandbox.ts +182 -0
- package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
- package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
- package/plugins/workflow-runner/src/taskIdentity.js +151 -307
- package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
- package/plugins/workflow-runner/src/toolRuntime.js +29 -8
- package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
- package/plugins/workflow-runner/src/types.js +7 -211
- package/plugins/workflow-runner/src/types.ts +154 -623
- package/plugins/workflow-runner/src/util.js +47 -0
- package/plugins/workflow-runner/src/util.ts +51 -0
- package/plugins/workflow-runner/src/workflowContext.js +20 -0
- package/plugins/workflow-runner/src/workflowContext.ts +58 -0
- package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
- package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
- package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
- package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
- package/plugins/workflow-runner/src/workflowState.js +474 -802
- package/plugins/workflow-runner/src/workflowState.ts +575 -970
- package/plugins/workflow-runner/test/api.test.ts +223 -0
- package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
- package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
- package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
- package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
- package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
- package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
- package/plugins/workflow-runner/test/discovery.test.ts +234 -0
- package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
- package/plugins/workflow-runner/test/goalController.test.ts +317 -0
- package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
- package/plugins/workflow-runner/test/listResources.test.ts +106 -0
- package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
- package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
- package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
- package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
- package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
- package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
- package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
- package/skills/pptx/examples/assets/cover-bg.svg +23 -0
- package/skills/pptx/examples/assets/icon-spark.svg +5 -0
- package/skills/ui-design/SKILL.md +5 -2
- package/skills/ui-design/references/layout-composition.md +1 -1
- package/skills/workflow-creator/SKILL.md +344 -0
- package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
- package/skills/workflow-creator/references/api.md +216 -0
- package/skills/workflow-creator/references/migration.md +103 -0
- package/skills/workflow-creator/references/patterns.md +779 -0
- package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
- package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
- package/skills/workflow-creator/scripts/validate.mjs +275 -0
- package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
- package/src/advisor/advisorCoordinator.js +503 -0
- package/src/advisor/advisorCoordinator.ts +657 -0
- package/src/cli/configMenu.tsx +0 -1
- package/src/cli/print.js +27 -6
- package/src/cli/print.ts +48 -4
- package/src/cli/streamJson.js +5 -6
- package/src/cli/streamJson.ts +8 -4
- package/src/cli/wizards/advisorWizard.js +4 -2
- package/src/cli/wizards/advisorWizard.tsx +8 -2
- package/src/cli/wizards/contextAdvisorWizard.js +5 -4
- package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
- package/src/collaboration/taskFlow.js +115 -0
- package/src/collaboration/taskFlow.ts +169 -0
- package/src/config/configDefaults.js +41 -1
- package/src/config/configDefaults.ts +43 -1
- package/src/config/configDiagnostics.ts +2 -2
- package/src/config/configFile.js +40 -9
- package/src/config/configFile.ts +60 -11
- package/src/config/configService.js +419 -74
- package/src/config/configService.ts +703 -145
- package/src/config/numericLimits.js +22 -0
- package/src/config/numericLimits.ts +24 -0
- package/src/config.js +1 -0
- package/src/config.ts +3 -2
- package/src/context/budgetPlan.js +1 -1
- package/src/context/budgetPlan.ts +1 -1
- package/src/context/compact.js +7 -2
- package/src/context/compact.ts +9 -2
- package/src/context/microCompactLite.js +212 -13
- package/src/context/microCompactLite.ts +261 -12
- package/src/context/sessionRegistry.js +8 -1
- package/src/context/sessionRegistry.ts +18 -5
- package/src/context/toolResultArchive.js +72 -0
- package/src/context/toolResultArchive.ts +95 -0
- package/src/goal/errors.js +8 -0
- package/src/goal/errors.ts +18 -0
- package/src/goal/goalRuntime.js +344 -0
- package/src/goal/goalRuntime.ts +466 -0
- package/src/goal/goalStore.js +200 -0
- package/src/goal/goalStore.ts +219 -0
- package/src/goal/index.js +4 -0
- package/src/goal/index.ts +4 -0
- package/src/goal/statusMapping.js +71 -0
- package/src/goal/statusMapping.ts +95 -0
- package/src/goal/types.js +7 -0
- package/src/goal/types.ts +179 -0
- package/src/goal/workflowController.js +306 -0
- package/src/goal/workflowController.ts +360 -0
- package/src/harness/evidenceLedger.js +2 -0
- package/src/harness/evidenceLedger.ts +1 -0
- package/src/harness/stallGuard.js +9 -3
- package/src/harness/stallGuard.ts +7 -3
- package/src/images/imageResolver.js +161 -0
- package/src/images/imageResolver.ts +189 -0
- package/src/infra/verification.js +34 -5
- package/src/infra/verification.ts +39 -4
- package/src/llm/client.js +79 -21
- package/src/llm/client.ts +182 -35
- package/src/llm/gatewayClient.js +201 -0
- package/src/llm/gatewayClient.ts +299 -0
- package/src/llm/messageProvenance.js +46 -0
- package/src/llm/messageProvenance.ts +58 -0
- package/src/llm/modelProvider.js +1 -0
- package/src/llm/modelProvider.ts +22 -0
- package/src/llm/providers/anthropicFormat.js +108 -1
- package/src/llm/providers/anthropicFormat.ts +115 -4
- package/src/llm/providers/openaiFormat.js +9 -0
- package/src/llm/providers/openaiFormat.ts +12 -3
- package/src/loop.js +319 -54
- package/src/loop.ts +373 -57
- package/src/main.js +4 -1
- package/src/main.tsx +4 -1
- package/src/managedExecution/index.js +2 -0
- package/src/managedExecution/index.ts +2 -0
- package/src/managedExecution/registry.js +15 -0
- package/src/managedExecution/registry.ts +20 -0
- package/src/managedExecution/types.js +1 -0
- package/src/managedExecution/types.ts +86 -0
- package/src/modelRef.js +9 -0
- package/src/modelRef.ts +31 -0
- package/src/multimodal.js +14 -28
- package/src/multimodal.ts +17 -33
- package/src/net/lanDiscovery.js +65 -0
- package/src/net/lanDiscovery.ts +82 -0
- package/src/plugin-sdk.js +28 -3
- package/src/plugin-sdk.ts +39 -6
- package/src/plugins/pluginApi.ts +16 -1
- package/src/plugins/pluginLoader.js +4 -0
- package/src/plugins/pluginLoader.ts +6 -0
- package/src/plugins/pluginRunner.js +139 -7
- package/src/plugins/pluginRunner.ts +173 -9
- package/src/plugins/slashFallback.js +113 -0
- package/src/plugins/slashFallback.ts +137 -0
- package/src/prompts/policyRegistry.js +12 -32
- package/src/prompts/policyRegistry.ts +15 -32
- package/src/prompts/promptAssembly.js +103 -12
- package/src/prompts/promptAssembly.ts +114 -12
- package/src/prompts/skillList.js +21 -3
- package/src/prompts/skillList.ts +27 -2
- package/src/prompts/stableSystemPrompt.js +18 -0
- package/src/prompts/stableSystemPrompt.ts +33 -0
- package/src/runtime/agentRuntimeContext.js +8 -2
- package/src/runtime/agentRuntimeContext.ts +17 -4
- package/src/session/runAgentTurn.js +78 -12
- package/src/session/runAgentTurn.ts +105 -23
- package/src/session/runTurn.js +10 -9
- package/src/session/runTurn.ts +17 -8
- package/src/session/sessionState.ts +2 -0
- package/src/team/auth.js +186 -0
- package/src/team/auth.ts +298 -0
- package/src/team/cli.js +105 -0
- package/src/team/cli.ts +122 -0
- package/src/team/onlineToolContract.js +64 -0
- package/src/team/onlineToolContract.ts +109 -0
- package/src/team/toolPolicy.js +36 -0
- package/src/team/toolPolicy.ts +75 -0
- package/src/tools/advisor/advisor.js +90 -46
- package/src/tools/advisor/advisor.ts +100 -47
- package/src/tools/advisor/advisorDecision.js +71 -0
- package/src/tools/advisor/advisorDecision.ts +85 -0
- package/src/tools/agent/agent.js +18 -5
- package/src/tools/agent/agent.ts +21 -7
- package/src/tools/agent/agentControl.js +246 -0
- package/src/tools/agent/agentControl.ts +284 -0
- package/src/tools/agent/agentTaskService.js +40 -1
- package/src/tools/agent/agentTaskService.ts +44 -1
- package/src/tools/agent/agentTypes.js +14 -2
- package/src/tools/agent/agentTypes.ts +15 -2
- package/src/tools/applypatch/applyPatch.js +362 -0
- package/src/tools/applypatch/applyPatch.ts +428 -0
- package/src/tools/bash/bash.js +22 -15
- package/src/tools/bash/bash.ts +23 -17
- package/src/tools/capabilities.js +10 -5
- package/src/tools/capabilities.ts +10 -5
- package/src/tools/computeruse/computerIntent.js +32 -0
- package/src/tools/computeruse/computerIntent.ts +46 -0
- package/src/tools/computeruse/telemetryLog.js +12 -0
- package/src/tools/computeruse/telemetryLog.ts +16 -0
- package/src/tools/computeruse/vision/telemetry.js +1 -0
- package/src/tools/computeruse/vision/telemetry.ts +1 -0
- package/src/tools/effectiveToolSet.js +4 -0
- package/src/tools/effectiveToolSet.ts +4 -0
- package/src/tools/index.js +21 -2
- package/src/tools/index.ts +33 -2
- package/src/tools/presentresult/presentresult.js +6 -15
- package/src/tools/presentresult/presentresult.ts +6 -15
- package/src/tools/read/read.js +62 -9
- package/src/tools/read/read.ts +63 -9
- package/src/tools/shared/fileUtils.js +1 -2
- package/src/tools/shared/fileUtils.ts +1 -2
- package/src/tools/shared/toolOutputStore.js +23 -1
- package/src/tools/shared/toolOutputStore.ts +22 -1
- package/src/tools/skill/skill.js +9 -3
- package/src/tools/skill/skill.ts +8 -4
- package/src/tools/toolPromptGuides.js +117 -0
- package/src/tools/toolPromptGuides.ts +137 -0
- package/src/tools/webbrowser/agentBrowserPath.js +19 -9
- package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
- package/src/tools/webbrowser/browser.js +27 -11
- package/src/tools/webbrowser/browser.ts +68 -24
- package/src/tools/webbrowser/browserAutomation.js +329 -0
- package/src/tools/webbrowser/browserAutomation.ts +467 -0
- package/src/tools/webbrowser/browserAxState.js +97 -0
- package/src/tools/webbrowser/browserAxState.ts +142 -0
- package/src/tools/webbrowser/browserBatch.js +1578 -0
- package/src/tools/webbrowser/browserBatch.ts +2382 -0
- package/src/tools/webbrowser/browserCdp.js +208 -0
- package/src/tools/webbrowser/browserCdp.ts +255 -0
- package/src/tools/webbrowser/browserConditions.js +24 -0
- package/src/tools/webbrowser/browserConditions.ts +45 -0
- package/src/tools/webbrowser/browserContent.js +281 -0
- package/src/tools/webbrowser/browserContent.ts +438 -0
- package/src/tools/webbrowser/browserControl.js +131 -34
- package/src/tools/webbrowser/browserControl.ts +210 -56
- package/src/tools/webbrowser/browserDaemon.js +22 -14
- package/src/tools/webbrowser/browserDaemon.ts +54 -21
- package/src/tools/webbrowser/browserFrames.js +47 -0
- package/src/tools/webbrowser/browserFrames.ts +54 -0
- package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
- package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
- package/src/tools/webbrowser/browserLocator.js +140 -0
- package/src/tools/webbrowser/browserLocator.ts +194 -0
- package/src/tools/webbrowser/browserOutcome.js +10 -17
- package/src/tools/webbrowser/browserOutcome.ts +48 -31
- package/src/tools/webbrowser/browserRecovery.js +58 -0
- package/src/tools/webbrowser/browserRecovery.ts +83 -0
- package/src/tools/webbrowser/browserRunRegistry.js +35 -3
- package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
- package/src/tools/webbrowser/browserService.js +28 -2
- package/src/tools/webbrowser/browserService.ts +49 -9
- package/src/tools/webbrowser/browserStream.js +132 -33
- package/src/tools/webbrowser/browserStream.ts +224 -50
- package/src/tools/webbrowser/browserTabs.js +48 -15
- package/src/tools/webbrowser/browserTabs.ts +178 -96
- package/src/tools/webbrowser/webbrowser.js +679 -144
- package/src/tools/webbrowser/webbrowser.ts +975 -236
- package/src/tools/webfetch/preapproved.js +0 -2
- package/src/tools/webfetch/preapproved.ts +0 -2
- package/src/tools/websearch/websearch.js +129 -8
- package/src/tools/websearch/websearch.ts +138 -6
- package/src/types.ts +440 -38
- package/src/ui/App.js +377 -58
- package/src/ui/App.tsx +576 -111
- package/src/ui/LiveArea.js +14 -8
- package/src/ui/LiveArea.tsx +14 -10
- package/src/ui/MessageList.js +63 -20
- package/src/ui/MessageList.tsx +101 -16
- package/src/ui/ModelPicker.js +7 -4
- package/src/ui/ModelPicker.tsx +55 -8
- package/src/ui/hooks/useChat.js +152 -163
- package/src/ui/hooks/useChat.ts +396 -334
- package/src/ui/loginCommand.js +56 -0
- package/src/ui/loginCommand.ts +63 -0
- package/src/ui/toolProgress.js +41 -0
- package/src/ui/toolProgress.ts +44 -0
- package/src/web/browserBridge.js +20 -2
- package/src/web/browserBridge.ts +20 -2
- package/src/web/protocol.ts +1897 -194
- package/workflows/adaptive-research/workflow.mjs +86 -0
- package/workflows/e2e-capabilities/workflow.mjs +102 -0
- package/workflows/e2e-llm/workflow.mjs +52 -0
- package/workflows/e2e-smoke/workflow.mjs +59 -0
- package/workflows/e2e-vision-schema/README.md +48 -0
- package/workflows/e2e-vision-schema/workflow.mjs +149 -0
- package/workflows/e2e-write-greet/workflow.mjs +37 -0
- package/workflows/file-census/README.md +14 -0
- package/workflows/file-census/scripts/.gitkeep +2 -0
- package/workflows/file-census/workflow.mjs +110 -0
- package/workflows/goal/README.md +166 -0
- package/workflows/goal/prompts/audit.md +57 -0
- package/workflows/goal/prompts/contract.md +56 -0
- package/workflows/goal/prompts/iterate.md +37 -0
- package/workflows/goal/workflow.mjs +501 -0
- package/workflows/illustrate/README.md +90 -0
- package/workflows/illustrate/assets/engines.json +20 -0
- package/workflows/illustrate/assets/extract-baidu.js +21 -0
- package/workflows/illustrate/assets/extract-bing.js +33 -0
- package/workflows/illustrate/assets/extract-google.js +31 -0
- package/workflows/illustrate/workflow.mjs +301 -0
- package/workflows/plan/workflow.mjs +389 -0
- package/workflows/question-crops/README.md +35 -0
- package/workflows/question-crops/prompts/inventory.md +23 -0
- package/workflows/question-crops/scripts/image-ops.mjs +305 -0
- package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
- package/workflows/question-crops/workflow.mjs +172 -0
- package/workflows/ralph-loop/workflow.mjs +162 -0
- package/workflows/research/README.md +74 -0
- package/workflows/research/prompts/s0-goal.md +43 -0
- package/workflows/research/prompts/s1-early-exit.md +22 -0
- package/workflows/research/prompts/s1-map.md +58 -0
- package/workflows/research/prompts/s2-options.md +53 -0
- package/workflows/research/prompts/s3-deep-dive.md +56 -0
- package/workflows/research/prompts/s4-verify.md +74 -0
- package/workflows/research/prompts/s5-synthesis.md +81 -0
- package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
- package/workflows/research/prompts/s6-package.md +32 -0
- package/workflows/research/scripts/build-report.mjs +98 -0
- package/workflows/research/workflow.mjs +288 -0
- package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
- package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
- package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
- package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
- package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
- package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
- package/workflows/wechat-reading-shots/workflow.mjs +266 -0
- package/workflows/wrong-question-docx/README.md +55 -0
- package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
- package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
- package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
- package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
- package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
- package/workflows/wrong-question-docx/workflow.mjs +485 -0
- package/plugins/workflow-runner/src/agentCommon.js +0 -354
- package/plugins/workflow-runner/src/agentCommon.ts +0 -435
- package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
- package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
- package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
- package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
- package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
- package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
- package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
- package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
- package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
- package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
- package/plugins/workflow-runner/src/dslManifest.js +0 -72
- package/plugins/workflow-runner/src/dslManifest.ts +0 -127
- package/plugins/workflow-runner/src/expressions.js +0 -639
- package/plugins/workflow-runner/src/expressions.ts +0 -640
- package/plugins/workflow-runner/src/loader.js +0 -573
- package/plugins/workflow-runner/src/loader.ts +0 -721
- package/plugins/workflow-runner/src/multimodal.js +0 -38
- package/plugins/workflow-runner/src/multimodal.ts +0 -64
- package/plugins/workflow-runner/src/recovery.js +0 -126
- package/plugins/workflow-runner/src/recovery.ts +0 -156
- package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
- package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
- package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
- package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
- package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
- package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
- package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
- package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
- package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
- package/plugins/workflow-runner/src/stepPipeline.js +0 -277
- package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
- package/plugins/workflow-runner/test/agent.test.ts +0 -587
- package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
- package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
- package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
- package/plugins/workflow-runner/test/context-files.test.ts +0 -320
- package/plugins/workflow-runner/test/e2e.test.ts +0 -370
- package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
- package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
- package/plugins/workflow-runner/test/expressions.test.ts +0 -439
- package/plugins/workflow-runner/test/foundation.test.ts +0 -126
- package/plugins/workflow-runner/test/graceful.test.ts +0 -139
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
- package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
- package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
- package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
- package/plugins/workflow-runner/test/loader.test.ts +0 -617
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
- package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
- package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
- package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
- package/plugins/workflow-runner/test/recovery.test.ts +0 -265
- package/plugins/workflow-runner/test/research.load.test.ts +0 -328
- package/plugins/workflow-runner/test/runner.test.ts +0 -911
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
- package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
- package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
- package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
- package/plugins/workflow-runner/test/word.load.test.ts +0 -208
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
- package/src/advisorState.js +0 -22
- package/src/cli/configWizard.js +0 -293
- package/src/tools/toolProgressBridge.js +0 -48
- package/workflows/adaptive-research.yaml +0 -50
- package/workflows/book-review-short.yaml +0 -125
- package/workflows/e2e-write-greet.yaml +0 -31
- package/workflows/illustrate.yaml +0 -227
- package/workflows/plan.yaml +0 -470
- package/workflows/ppt.yaml +0 -1670
- package/workflows/ralph-loop.yaml +0 -201
- package/workflows/research.yaml +0 -873
- package/workflows/schema.json +0 -176
- package/workflows/webppt.yaml +0 -496
- package/workflows/wechat-reading-shots.yaml +0 -315
- package/workflows/word.yaml +0 -720
- package/workflows/youtube-shorts.yaml +0 -202
- /package/workflows/{research.md → research/DESIGN.md} +0 -0
package/src/ui/App.js
CHANGED
|
@@ -7,36 +7,39 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* 不直接处理键盘输入,那是 InputBox 的事。
|
|
8
8
|
* ============================================================
|
|
9
9
|
*/
|
|
10
|
-
import React, { useDeferredValue } from 'react';
|
|
11
10
|
import { Box, Text } from 'ink';
|
|
11
|
+
import React, { useDeferredValue } from 'react';
|
|
12
12
|
import { getWorkingDir } from '../bootstrap/workingDir.js';
|
|
13
|
+
import { createCliComputerRun, readRecentComputerUseAudit, } from '../cli/computerUse.js';
|
|
13
14
|
import { ConfigMenu } from '../cli/configMenu.js';
|
|
14
15
|
import { configService } from '../config/configService.js';
|
|
15
16
|
import { listArchives, restoreArchive } from '../context/archive.js';
|
|
16
17
|
import { saveContext } from '../context/persistContext.js';
|
|
17
18
|
import { sessionFileFor } from '../context/sessionPath.js';
|
|
18
|
-
import { workspaceIndexService } from '../context/workspaceIndex.js';
|
|
19
|
-
import { memoryService } from '../memory/memoryService.js';
|
|
20
19
|
import { createSession, listSessionSummaries, updateSessionMetadata, } from '../context/sessionRegistry.js';
|
|
20
|
+
import { workspaceIndexService, } from '../context/workspaceIndex.js';
|
|
21
|
+
import { memoryService } from '../memory/memoryService.js';
|
|
22
|
+
import { legacyModelId, modelRefFromLegacy } from '../modelRef.js';
|
|
21
23
|
import { activatePlugins } from '../plugins/pluginLifecycle.js';
|
|
22
24
|
import { runAgentTurn } from '../session/runAgentTurn.js';
|
|
23
|
-
import {
|
|
24
|
-
import { createCliComputerRun, readRecentComputerUseAudit, } from '../cli/computerUse.js';
|
|
25
|
+
import { beginTeamLogin, clearTeamCredentials, fetchOnlineModels, fetchTeamSubscription, fetchTeamUsage, loadTeamCredentials, revokeTeamCredentials, } from '../team/auth.js';
|
|
25
26
|
import { computerUseService } from '../tools/computeruse/computerUseService.js';
|
|
26
|
-
import {
|
|
27
|
+
import { writeClipboardText } from '../utils/clipboardImage.js';
|
|
27
28
|
import { AskQuestion } from './AskQuestion.js';
|
|
28
29
|
import { InputBox } from './InputBox.js';
|
|
29
30
|
import { LiveArea } from './LiveArea.js';
|
|
30
|
-
import { QueuedMessagesBanner } from './QueuedMessagesBanner.js';
|
|
31
31
|
import { MessageList } from './MessageList.js';
|
|
32
32
|
import { ModelPicker } from './ModelPicker.js';
|
|
33
|
+
import { QueuedMessagesBanner } from './QueuedMessagesBanner.js';
|
|
33
34
|
import { SessionPicker } from './SessionPicker.js';
|
|
34
|
-
import { WorkspacePicker } from './WorkspacePicker.js';
|
|
35
35
|
import { StatusLine } from './StatusLine.js';
|
|
36
|
-
import {
|
|
36
|
+
import { WorkspacePicker } from './WorkspacePicker.js';
|
|
37
|
+
import { advisorHelpText, parseAdvisorCommand } from './advisorCommand.js';
|
|
37
38
|
import { parseComputerCommand } from './computerCommand.js';
|
|
38
39
|
import { useChat } from './hooks/useChat.js';
|
|
39
40
|
import { useTerminalSize } from './hooks/useTerminalSize.js';
|
|
41
|
+
import { isLogoutCommand, loginHelpText, parseLoginCommand, } from './loginCommand.js';
|
|
42
|
+
import { theme } from './theme.js';
|
|
40
43
|
/**
|
|
41
44
|
* ANSI escape: 清屏 + 光标归位。
|
|
42
45
|
*
|
|
@@ -56,6 +59,38 @@ function formatProviderName(apiFormat) {
|
|
|
56
59
|
return 'OpenAI兼容';
|
|
57
60
|
return apiFormat;
|
|
58
61
|
}
|
|
62
|
+
function toPickerModel(model) {
|
|
63
|
+
return {
|
|
64
|
+
id: legacyModelId({
|
|
65
|
+
source: 'gateway',
|
|
66
|
+
serverId: 'gateway',
|
|
67
|
+
modelId: model.id,
|
|
68
|
+
}),
|
|
69
|
+
apiFormat: model.apiFormat,
|
|
70
|
+
displayName: model.displayName,
|
|
71
|
+
model: model.model,
|
|
72
|
+
contextWindow: model.contextWindow,
|
|
73
|
+
maxTokens: model.maxTokens,
|
|
74
|
+
supportsVision: model.supportsVision,
|
|
75
|
+
enabled: true,
|
|
76
|
+
source: 'gateway',
|
|
77
|
+
isDefault: model.isDefault,
|
|
78
|
+
availability: model.availability,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function openTeamBrowser(url) {
|
|
82
|
+
const command = process.platform === 'darwin'
|
|
83
|
+
? ['open', url]
|
|
84
|
+
: process.platform === 'win32'
|
|
85
|
+
? ['cmd', '/c', 'start', '', url]
|
|
86
|
+
: ['xdg-open', url];
|
|
87
|
+
try {
|
|
88
|
+
Bun.spawn({ cmd: command, stdout: 'ignore', stderr: 'ignore' });
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* TUI prints the URL below */
|
|
92
|
+
}
|
|
93
|
+
}
|
|
59
94
|
export function App({ provider, initialHistory }) {
|
|
60
95
|
// v2 multi-session:持久化路径完全由 useChat 内部管控(按 activeSessionId 选文件)。
|
|
61
96
|
// App 不再传 onPersist —— 之前 App 端调 saveContext(messages) 会污染 default session。
|
|
@@ -74,13 +109,15 @@ export function App({ provider, initialHistory }) {
|
|
|
74
109
|
provider,
|
|
75
110
|
signal: controller.signal,
|
|
76
111
|
runAgentTurn,
|
|
77
|
-
})
|
|
112
|
+
})
|
|
113
|
+
.then((fn) => {
|
|
78
114
|
if (controller.signal.aborted) {
|
|
79
115
|
fn();
|
|
80
116
|
return;
|
|
81
117
|
}
|
|
82
118
|
cleanup = fn;
|
|
83
|
-
})
|
|
119
|
+
})
|
|
120
|
+
.catch((err) => {
|
|
84
121
|
console.warn(`[minimal-agent] plugin activation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
85
122
|
});
|
|
86
123
|
return () => {
|
|
@@ -160,13 +197,47 @@ export function App({ provider, initialHistory }) {
|
|
|
160
197
|
return;
|
|
161
198
|
const snap = await configService.getSnapshot();
|
|
162
199
|
const model = snap.config?.models.find((m) => m.id === modelId);
|
|
200
|
+
const selectedRef = modelRefFromLegacy(modelId);
|
|
201
|
+
const isGateway = selectedRef.source === 'gateway';
|
|
202
|
+
if (isGateway) {
|
|
203
|
+
const provider = await configService.providerForRef(selectedRef);
|
|
204
|
+
if (provider) {
|
|
205
|
+
const gatewayProvider = provider.source === 'gateway' ? provider : null;
|
|
206
|
+
if (!gatewayProvider)
|
|
207
|
+
return;
|
|
208
|
+
await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
|
|
209
|
+
modelId: null,
|
|
210
|
+
preferredModel: {
|
|
211
|
+
source: 'gateway',
|
|
212
|
+
serverId: gatewayProvider.gatewayUrl,
|
|
213
|
+
modelId: selectedRef.modelId,
|
|
214
|
+
},
|
|
215
|
+
effectiveModel: {
|
|
216
|
+
source: 'gateway',
|
|
217
|
+
serverId: gatewayProvider.gatewayUrl,
|
|
218
|
+
modelId: selectedRef.modelId,
|
|
219
|
+
},
|
|
220
|
+
restoreWhenAvailable: true,
|
|
221
|
+
});
|
|
222
|
+
chat.setProvider(provider);
|
|
223
|
+
forceRerender((v) => v + 1);
|
|
224
|
+
chat.ephemeralLine(`[/model] 当前 Session 已切换为在线模型 ${provider.name},下一轮对话生效。`);
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
163
228
|
if (!model) {
|
|
164
229
|
chat.ephemeralLine(`[/model] 未找到模型 "${modelId}"`);
|
|
165
230
|
return;
|
|
166
231
|
}
|
|
167
232
|
const newProvider = await configService.providerForModel(modelId);
|
|
168
233
|
if (newProvider) {
|
|
169
|
-
await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
|
|
234
|
+
await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
|
|
235
|
+
modelId: null,
|
|
236
|
+
preferredModel: { source: 'local', modelId },
|
|
237
|
+
effectiveModel: { source: 'local', modelId },
|
|
238
|
+
fallbackReason: undefined,
|
|
239
|
+
restoreWhenAvailable: false,
|
|
240
|
+
});
|
|
170
241
|
chat.setProvider(newProvider);
|
|
171
242
|
forceRerender((v) => v + 1);
|
|
172
243
|
chat.ephemeralLine(`[/model] 当前 Session 已切换为 ${model.displayName || model.model}(${formatProviderName(model.apiFormat)}),下一轮对话生效。`);
|
|
@@ -174,22 +245,100 @@ export function App({ provider, initialHistory }) {
|
|
|
174
245
|
}, [chat.activeSessionId, chat.setProvider, chat.ephemeralLine]);
|
|
175
246
|
React.useEffect(() => {
|
|
176
247
|
let cancelled = false;
|
|
177
|
-
void listSessionSummaries(getWorkingDir())
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
248
|
+
void listSessionSummaries(getWorkingDir())
|
|
249
|
+
.then(async (sessions) => {
|
|
250
|
+
const currentSession = sessions.find((session) => session.id === chat.activeSessionId);
|
|
251
|
+
const preferredModel = currentSession?.preferredModel ??
|
|
252
|
+
(currentSession?.modelId
|
|
253
|
+
? modelRefFromLegacy(currentSession.modelId)
|
|
254
|
+
: null);
|
|
255
|
+
let provider = null;
|
|
256
|
+
let fallbackReason = null;
|
|
257
|
+
if (preferredModel) {
|
|
258
|
+
const resolved = await configService.resolveModelRef(preferredModel);
|
|
259
|
+
provider = resolved.provider;
|
|
260
|
+
fallbackReason = resolved.fallbackReason;
|
|
261
|
+
if (!provider && preferredModel.source === 'gateway')
|
|
262
|
+
provider = await configService.providerForModel(null);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
provider = await configService.onlineDefaultProvider();
|
|
266
|
+
if (!provider)
|
|
267
|
+
provider = await configService.providerForModel(null);
|
|
268
|
+
}
|
|
269
|
+
if (cancelled)
|
|
270
|
+
return;
|
|
271
|
+
if (provider) {
|
|
272
|
+
const localModelId = currentSession?.preferredModel?.source === 'local'
|
|
273
|
+
? currentSession.preferredModel.modelId
|
|
274
|
+
: currentSession?.modelId &&
|
|
275
|
+
!currentSession.modelId.startsWith('online:')
|
|
276
|
+
? currentSession.modelId
|
|
277
|
+
: ((await configService.getSnapshot()).config?.baseModelId ??
|
|
278
|
+
provider.model);
|
|
279
|
+
const effectiveModel = provider.source === 'gateway'
|
|
280
|
+
? {
|
|
281
|
+
source: 'gateway',
|
|
282
|
+
serverId: provider.gatewayUrl ?? 'gateway',
|
|
283
|
+
modelId: provider.remoteModelId ?? provider.model,
|
|
284
|
+
}
|
|
285
|
+
: { source: 'local', modelId: localModelId };
|
|
286
|
+
const isGatewayPreference = preferredModel?.source === 'gateway';
|
|
287
|
+
const shouldPersist = (provider.source === 'gateway' && !preferredModel) ||
|
|
288
|
+
(isGatewayPreference &&
|
|
289
|
+
(currentSession?.effectiveModel?.source !==
|
|
290
|
+
effectiveModel.source ||
|
|
291
|
+
currentSession?.effectiveModel?.modelId !==
|
|
292
|
+
effectiveModel.modelId ||
|
|
293
|
+
currentSession.fallbackReason !== fallbackReason));
|
|
182
294
|
chat.setProvider(provider);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
295
|
+
if (shouldPersist ||
|
|
296
|
+
(isGatewayPreference && provider.source === 'local')) {
|
|
297
|
+
await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
|
|
298
|
+
...(provider.source === 'gateway' && !preferredModel
|
|
299
|
+
? { preferredModel: effectiveModel }
|
|
300
|
+
: {}),
|
|
301
|
+
effectiveModel,
|
|
302
|
+
fallbackReason: provider.source === 'local' ? fallbackReason : null,
|
|
303
|
+
restoreWhenAvailable: isGatewayPreference || provider.source === 'gateway',
|
|
304
|
+
}).catch(() => { });
|
|
305
|
+
if (isGatewayPreference && provider.source === 'local')
|
|
306
|
+
chat.ephemeralLine(`[/model] 在线模型暂不可用,已回退本地模型(${fallbackReason ?? 'offline'});服务恢复后将自动恢复。`);
|
|
307
|
+
else if (isGatewayPreference &&
|
|
308
|
+
provider.source === 'gateway' &&
|
|
309
|
+
currentSession?.fallbackReason)
|
|
310
|
+
chat.ephemeralLine(`[/model] 在线模型已恢复,当前 Session 已恢复在线模型 ${provider.name}。`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (preferredModel?.source === 'gateway') {
|
|
314
|
+
chat.ephemeralLine('[/model] 在线模型不可用,且未配置本地模型;请连接团队服务器或配置本地模型。');
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
.catch(() => { });
|
|
318
|
+
return () => {
|
|
319
|
+
cancelled = true;
|
|
320
|
+
};
|
|
321
|
+
}, [chat.activeSessionId, chat.setProvider, chat.ephemeralLine]);
|
|
186
322
|
const handleAdvisorModelSelect = React.useCallback(async (modelId) => {
|
|
187
323
|
setAdvisorModelPicker(null);
|
|
188
324
|
if (modelId === null) {
|
|
189
|
-
await configService.savePatch({
|
|
325
|
+
await configService.savePatch({
|
|
326
|
+
advisor: { modelId: null, enabled: false },
|
|
327
|
+
});
|
|
190
328
|
chat.ephemeralLine('[/advisor] 已关闭顾问模型。');
|
|
191
329
|
return;
|
|
192
330
|
}
|
|
331
|
+
const selectedRef = modelRefFromLegacy(modelId);
|
|
332
|
+
if (selectedRef.source === 'gateway') {
|
|
333
|
+
const provider = await configService.providerForRef(selectedRef);
|
|
334
|
+
if (!provider) {
|
|
335
|
+
chat.ephemeralLine('[/advisor] 在线模型不可用、未授权或设备凭据已过期。');
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
await configService.savePatch({ advisor: { modelId, enabled: true } });
|
|
339
|
+
chat.ephemeralLine(`[/advisor] 已设置顾问模型为 ${provider.name}(在线)。`);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
193
342
|
const snap = await configService.getSnapshot();
|
|
194
343
|
const model = snap.config?.models.find((m) => m.id === modelId);
|
|
195
344
|
if (!model) {
|
|
@@ -220,15 +369,23 @@ export function App({ provider, initialHistory }) {
|
|
|
220
369
|
*/
|
|
221
370
|
const handleSubmit = React.useCallback(async (text) => {
|
|
222
371
|
const trimmed = text.trim();
|
|
223
|
-
const isBareSessionCmd = trimmed === '/session' ||
|
|
372
|
+
const isBareSessionCmd = trimmed === '/session' ||
|
|
373
|
+
trimmed === '/sessions' ||
|
|
374
|
+
trimmed === '/resume';
|
|
224
375
|
const sessionArgMatch = /^\/(?:session|resume)\s+(.+)$/.exec(trimmed);
|
|
225
376
|
if (trimmed === '/workspaces') {
|
|
226
377
|
await openWorkspacePicker();
|
|
227
378
|
return;
|
|
228
379
|
}
|
|
229
380
|
if (trimmed === '/copy') {
|
|
230
|
-
const latest = [...historyRef.current]
|
|
231
|
-
|
|
381
|
+
const latest = [...historyRef.current]
|
|
382
|
+
.reverse()
|
|
383
|
+
.find((message) => message.role === 'assistant' &&
|
|
384
|
+
typeof message.content === 'string' &&
|
|
385
|
+
message.content.length > 0);
|
|
386
|
+
if (!latest ||
|
|
387
|
+
latest.role !== 'assistant' ||
|
|
388
|
+
typeof latest.content !== 'string') {
|
|
232
389
|
chat.ephemeralLine('[/copy] 当前会话还没有可复制的 AI 最终回复。');
|
|
233
390
|
return;
|
|
234
391
|
}
|
|
@@ -247,7 +404,7 @@ export function App({ provider, initialHistory }) {
|
|
|
247
404
|
if (sub === 'help') {
|
|
248
405
|
const helperAvailable = computerUseService.available();
|
|
249
406
|
let helperBackend = '未知';
|
|
250
|
-
|
|
407
|
+
const modeLabel = chat.computerUseMode;
|
|
251
408
|
try {
|
|
252
409
|
const workspace = await workspaceIndexService
|
|
253
410
|
.findByPath(getWorkingDir())
|
|
@@ -260,7 +417,9 @@ export function App({ provider, initialHistory }) {
|
|
|
260
417
|
allowedFileRoots: [getWorkingDir()],
|
|
261
418
|
supervised: true,
|
|
262
419
|
});
|
|
263
|
-
const resp = await computerUseService.request(context, {
|
|
420
|
+
const resp = await computerUseService.request(context, {
|
|
421
|
+
action: 'status',
|
|
422
|
+
});
|
|
264
423
|
if (resp.ok && resp.state?.backend) {
|
|
265
424
|
helperBackend = resp.state.backend;
|
|
266
425
|
}
|
|
@@ -358,7 +517,7 @@ export function App({ provider, initialHistory }) {
|
|
|
358
517
|
const apps = response.state?.windows
|
|
359
518
|
.map((window) => window.appId)
|
|
360
519
|
.filter((id, index, all) => all.indexOf(id) === index);
|
|
361
|
-
chat.ephemeralLine(`[/computer] 可见应用:${apps?.length ? apps.join('、') : response.content ?? '当前没有可见应用'}`);
|
|
520
|
+
chat.ephemeralLine(`[/computer] 可见应用:${apps?.length ? apps.join('、') : (response.content ?? '当前没有可见应用')}`);
|
|
362
521
|
return;
|
|
363
522
|
}
|
|
364
523
|
if (sub === 'permissions') {
|
|
@@ -366,11 +525,7 @@ export function App({ provider, initialHistory }) {
|
|
|
366
525
|
return;
|
|
367
526
|
}
|
|
368
527
|
// status
|
|
369
|
-
chat.ephemeralLine(`[/computer] 状态:\n
|
|
370
|
-
` 模式:${chat.computerUseMode}\n` +
|
|
371
|
-
` Helper:${computerUseService.available() ? '✅ 可用' : '❌ 不可用'}\n` +
|
|
372
|
-
` Backend:${response.state?.backend ?? '未知'}\n` +
|
|
373
|
-
` 提示:输入 /computer help 查看所有可用命令`);
|
|
528
|
+
chat.ephemeralLine(`[/computer] 状态:\n 模式:${chat.computerUseMode}\n Helper:${computerUseService.available() ? '✅ 可用' : '❌ 不可用'}\n Backend:${response.state?.backend ?? '未知'}\n 提示:输入 /computer help 查看所有可用命令`);
|
|
374
529
|
return;
|
|
375
530
|
}
|
|
376
531
|
if (computerCommand.matched) {
|
|
@@ -378,18 +533,24 @@ export function App({ provider, initialHistory }) {
|
|
|
378
533
|
return;
|
|
379
534
|
}
|
|
380
535
|
if (trimmed === '/memories') {
|
|
381
|
-
const workspace = await workspaceIndexService
|
|
536
|
+
const workspace = await workspaceIndexService
|
|
537
|
+
.findByPath(getWorkingDir())
|
|
538
|
+
.catch(() => null);
|
|
382
539
|
const records = await memoryService.recall('', workspace?.id, 100);
|
|
383
540
|
if (!records.length) {
|
|
384
541
|
chat.ephemeralLine('[/memories] 当前没有本机长期记忆。');
|
|
385
542
|
return;
|
|
386
543
|
}
|
|
387
|
-
chat.ephemeralLine(`[/memories] 本机长期记忆:\n${records
|
|
544
|
+
chat.ephemeralLine(`[/memories] 本机长期记忆:\n${records
|
|
545
|
+
.map((record) => ` ${record.id} · ${record.scope === 'personal' ? '个人' : '工作区'} · ${record.subject}: ${record.statement}`)
|
|
546
|
+
.join('\n')}\n使用 /forget-memory <id> 删除一条记忆。`);
|
|
388
547
|
return;
|
|
389
548
|
}
|
|
390
549
|
if (trimmed.startsWith('/forget-memory ')) {
|
|
391
550
|
const id = trimmed.slice('/forget-memory '.length).trim();
|
|
392
|
-
const workspace = await workspaceIndexService
|
|
551
|
+
const workspace = await workspaceIndexService
|
|
552
|
+
.findByPath(getWorkingDir())
|
|
553
|
+
.catch(() => null);
|
|
393
554
|
const records = await memoryService.recall('', workspace?.id, 100);
|
|
394
555
|
const record = records.find((item) => item.id === id);
|
|
395
556
|
if (!record) {
|
|
@@ -428,7 +589,9 @@ export function App({ provider, initialHistory }) {
|
|
|
428
589
|
.slice(0, 30)
|
|
429
590
|
.map((e) => ` ${e.id} · ${e.msgCount} msgs · ${e.firstUserPreview || '(empty)'}`)
|
|
430
591
|
.join('\n');
|
|
431
|
-
const tail = entries.length > 30
|
|
592
|
+
const tail = entries.length > 30
|
|
593
|
+
? `\n ...(共 ${entries.length} 条,仅显示前 30)`
|
|
594
|
+
: '';
|
|
432
595
|
chat.ephemeralLine(`[/list-archive] 归档列表(最新优先):\n${lines}${tail}`);
|
|
433
596
|
return;
|
|
434
597
|
}
|
|
@@ -466,33 +629,171 @@ export function App({ provider, initialHistory }) {
|
|
|
466
629
|
chat.ephemeralLine(`[tool result · #${hit.tool_call_id.slice(-8)} · 完整 ${hit.content.split('\n').length} 行]\n${hit.content}`);
|
|
467
630
|
return;
|
|
468
631
|
}
|
|
469
|
-
//
|
|
470
|
-
//
|
|
471
|
-
//
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
632
|
+
// ⚠️ 这里曾有一个 `/plan` 的硬编码特例(改写成 `/workflow plan`)。
|
|
633
|
+
// 已删 —— `src/plugins/slashFallback.ts` 把它通用化了:`/xxx` 没命中插件
|
|
634
|
+
// 命令时会按「工具 → skill → 工作流目录」继续找,所以 `/plan`、`/research`、
|
|
635
|
+
// `/pptx` 全都自动可用,加一条工作流不用再回来改 TUI。
|
|
636
|
+
// /model —— 列出已配置的基座模型并切换选择器;/model <id> 直接切换
|
|
637
|
+
// /login /logout —— 团队在线模型登录;不登录不影响本机模型(原 /team,改名理由见 loginCommand.ts)。
|
|
638
|
+
if (isLogoutCommand(trimmed)) {
|
|
639
|
+
// A standalone session can retain an old auth file from a previous
|
|
640
|
+
// team run. Only revoke over the network when the credential matches
|
|
641
|
+
// the currently configured server; otherwise just clear it locally.
|
|
642
|
+
const configuredServer = await configService.resolveTeamServerUrl();
|
|
643
|
+
if (configuredServer.value) {
|
|
644
|
+
const credentials = await loadTeamCredentials(configuredServer.value);
|
|
645
|
+
if (credentials)
|
|
646
|
+
await revokeTeamCredentials(credentials);
|
|
647
|
+
else
|
|
648
|
+
await clearTeamCredentials();
|
|
649
|
+
}
|
|
650
|
+
else {
|
|
651
|
+
// No configured server is the standalone boundary. Do not let
|
|
652
|
+
// revokeTeamCredentials() discover and contact a stale auth file.
|
|
653
|
+
await clearTeamCredentials();
|
|
654
|
+
}
|
|
655
|
+
chat.ephemeralLine('[/logout] 已登出并撤销本机设备授权;本地模型配置和 Session 未受影响。');
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
// 发起一次登录尝试。普通用户只使用发行版/配置中的服务端地址。
|
|
659
|
+
const attemptTeamLogin = async (server, sourceNote) => {
|
|
660
|
+
if (sourceNote)
|
|
661
|
+
chat.ephemeralLine(`[/login] ${sourceNote}`);
|
|
662
|
+
try {
|
|
663
|
+
const resolved = server
|
|
664
|
+
? { value: server, source: 'explicit' }
|
|
665
|
+
: await configService.resolveTeamServerUrl();
|
|
666
|
+
if (!resolved.value)
|
|
667
|
+
throw new Error('KakadeAI 登录服务暂时不可用,请稍后重试');
|
|
668
|
+
const login = await beginTeamLogin(resolved.value, 'minimal-agent TUI');
|
|
669
|
+
chat.ephemeralLine(`[/login] 已打开浏览器授权:${login.authorizeUrl}`);
|
|
670
|
+
await openTeamBrowser(login.authorizeUrl);
|
|
671
|
+
await login.complete();
|
|
672
|
+
chat.ephemeralLine('[/login] 登录完成;使用 /login models 查看在线模型。');
|
|
673
|
+
}
|
|
674
|
+
catch (error) {
|
|
675
|
+
chat.ephemeralLine(`[/login] ${error instanceof Error ? error.message : String(error)}`);
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
const loginCommand = parseLoginCommand(trimmed);
|
|
679
|
+
if (loginCommand.matched) {
|
|
680
|
+
if (loginCommand.command === 'help') {
|
|
681
|
+
chat.ephemeralLine(loginHelpText());
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (loginCommand.command === 'login') {
|
|
685
|
+
await attemptTeamLogin(loginCommand.server);
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
const configuredServer = await configService.resolveTeamServerUrl();
|
|
689
|
+
const credentials = configuredServer.value
|
|
690
|
+
? await loadTeamCredentials(configuredServer.value)
|
|
691
|
+
: null;
|
|
692
|
+
if (loginCommand.command === 'models') {
|
|
693
|
+
if (!credentials) {
|
|
694
|
+
chat.ephemeralLine('[/login models] 未登录;当前仅使用本机模型。输入 /login 登录。');
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
try {
|
|
698
|
+
const models = await fetchOnlineModels(credentials);
|
|
699
|
+
chat.ephemeralLine(models.length
|
|
700
|
+
? models
|
|
701
|
+
.map((model) => `${model.displayName} · ${model.model}${model.isDefault ? ' · 默认' : ''}${model.availability?.reason ? ` · ${model.availability.reason}` : ''}`)
|
|
702
|
+
.join('\n')
|
|
703
|
+
: '没有可用在线模型。');
|
|
704
|
+
}
|
|
705
|
+
catch (error) {
|
|
706
|
+
chat.ephemeralLine(`[/login models] ${error instanceof Error ? error.message : String(error)}`);
|
|
707
|
+
}
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (loginCommand.command === 'usage') {
|
|
711
|
+
if (!credentials) {
|
|
712
|
+
chat.ephemeralLine('[/login usage] 未登录。');
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
try {
|
|
716
|
+
const subscription = await fetchTeamSubscription(credentials);
|
|
717
|
+
const usage = await fetchTeamUsage(credentials);
|
|
718
|
+
chat.ephemeralLine(subscription
|
|
719
|
+
? `[/login usage] ${subscription.planName} · ${subscription.status}\n请求 ${subscription.requestCount}/${subscription.requestLimit} · 输入 ${subscription.inputTokens}/${subscription.inputTokenLimit} · 输出 ${subscription.outputTokens}/${subscription.outputTokenLimit}\n模型记录 ${usage.length} 条`
|
|
720
|
+
: '[/login usage] 当前没有有效订阅。');
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
chat.ephemeralLine(`[/login usage] ${error instanceof Error ? error.message : String(error)}`);
|
|
724
|
+
}
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (loginCommand.command === 'status') {
|
|
728
|
+
if (!credentials) {
|
|
729
|
+
chat.ephemeralLine('[/login status] 未登录;当前仅使用本机模型。输入 /login 登录。');
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
try {
|
|
733
|
+
const online = await fetchOnlineModels(credentials);
|
|
734
|
+
chat.ephemeralLine(`[/login status] 已连接 ${credentials.serverUrl};可用在线模型 ${online.length} 个。/logout 登出。`);
|
|
735
|
+
}
|
|
736
|
+
catch (error) {
|
|
737
|
+
chat.ephemeralLine(`[/login status] 设备凭据存在,但在线服务不可用:${error instanceof Error ? error.message : String(error)};当前使用本机模型。`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (loginCommand.command === 'tools') {
|
|
743
|
+
const current = (await listSessionSummaries(getWorkingDir())).find((session) => session.id === chat.activeSessionId);
|
|
744
|
+
const value = loginCommand.value;
|
|
745
|
+
if (!value || value === 'list') {
|
|
746
|
+
chat.ephemeralLine(`[/login tools] 当前 Session 类别:${current?.onlineToolCategories?.join(', ') || '未设置(使用服务器模型预设)'}\n可选:workspace web computer subagents integrations\n设置:/login tools workspace,web`);
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
const categories = [
|
|
750
|
+
...new Set(value.split(/[ ,]+/).filter(Boolean)),
|
|
751
|
+
];
|
|
752
|
+
const allowed = new Set([
|
|
753
|
+
'workspace',
|
|
754
|
+
'web',
|
|
755
|
+
'computer',
|
|
756
|
+
'subagents',
|
|
757
|
+
'integrations',
|
|
758
|
+
]);
|
|
759
|
+
if (categories.some((category) => !allowed.has(category))) {
|
|
760
|
+
chat.ephemeralLine('[/login tools] 类别无效,可用:workspace web computer subagents integrations');
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
await updateSessionMetadata(getWorkingDir(), chat.activeSessionId, {
|
|
764
|
+
onlineToolCategories: categories,
|
|
765
|
+
});
|
|
766
|
+
chat.ephemeralLine(`[/login tools] 已设置当前 Session 工具类别:${categories.join(', ') || '无'}`);
|
|
767
|
+
}
|
|
476
768
|
return;
|
|
477
769
|
}
|
|
478
|
-
void chat.submit(`/workflow plan "${goal}"`);
|
|
479
|
-
return;
|
|
480
770
|
}
|
|
481
|
-
// /model —— 列出已配置的基座模型并切换选择器;/model <id> 直接切换
|
|
482
771
|
const modelArgMatch = /^\/model(?:\s+(.+))?$/.exec(trimmed);
|
|
483
772
|
if (modelArgMatch) {
|
|
484
773
|
const arg = modelArgMatch[1]?.trim();
|
|
485
774
|
const models = await configService.models();
|
|
486
775
|
const enabledModels = models.filter((m) => m.enabled && m.apiKey);
|
|
487
|
-
|
|
776
|
+
const configuredServer = await configService.resolveTeamServerUrl();
|
|
777
|
+
const credentials = configuredServer.value
|
|
778
|
+
? await loadTeamCredentials(configuredServer.value)
|
|
779
|
+
: null;
|
|
780
|
+
const online = credentials
|
|
781
|
+
? await fetchOnlineModels(credentials).catch((error) => {
|
|
782
|
+
chat.ephemeralLine(`[/model] 在线模型暂时不可用:${error instanceof Error ? error.message : String(error)};仍可选择本机模型。`);
|
|
783
|
+
return [];
|
|
784
|
+
})
|
|
785
|
+
: [];
|
|
786
|
+
const onlinePickerModels = online.map(toPickerModel);
|
|
787
|
+
const pickerModels = [...enabledModels, ...onlinePickerModels];
|
|
788
|
+
if (pickerModels.length === 0) {
|
|
488
789
|
chat.ephemeralLine('[/model] 尚未配置任何模型,请先通过 Desktop 设置或 /config 添加模型。');
|
|
489
790
|
return;
|
|
490
791
|
}
|
|
491
792
|
if (arg) {
|
|
492
793
|
// 直接切换到指定模型(支持精确匹配 id 或模糊匹配 displayName/model)
|
|
493
|
-
const target =
|
|
794
|
+
const target = pickerModels.find((m) => m.id === arg || m.model === arg || m.displayName === arg);
|
|
494
795
|
if (!target) {
|
|
495
|
-
chat.ephemeralLine(`[/model] 未找到模型 "${arg}",可用模型:\n${
|
|
796
|
+
chat.ephemeralLine(`[/model] 未找到模型 "${arg}",可用模型:\n${pickerModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
|
|
496
797
|
return;
|
|
497
798
|
}
|
|
498
799
|
await handleBaseModelSelect(target.id);
|
|
@@ -501,7 +802,11 @@ export function App({ provider, initialHistory }) {
|
|
|
501
802
|
// 无参数:打开交互选择器
|
|
502
803
|
const currentSession = (await listSessionSummaries(getWorkingDir())).find((session) => session.id === chat.activeSessionId);
|
|
503
804
|
const snap = await configService.getSnapshot();
|
|
504
|
-
|
|
805
|
+
const currentRef = currentSession?.preferredModel;
|
|
806
|
+
const currentId = currentRef
|
|
807
|
+
? legacyModelId(currentRef)
|
|
808
|
+
: (currentSession?.modelId ?? snap.config?.baseModelId ?? null);
|
|
809
|
+
setBaseModelPicker({ models: pickerModels, currentId });
|
|
505
810
|
return;
|
|
506
811
|
}
|
|
507
812
|
// /advisor [help|status|on|off|ask|select] —— 与 Desktop 共用统一配置。
|
|
@@ -546,24 +851,40 @@ export function App({ provider, initialHistory }) {
|
|
|
546
851
|
if (sub === 'select') {
|
|
547
852
|
const models = await configService.models();
|
|
548
853
|
const enabledModels = models.filter((m) => m.enabled && m.apiKey);
|
|
549
|
-
|
|
854
|
+
const configuredServer = await configService.resolveTeamServerUrl();
|
|
855
|
+
const credentials = configuredServer.value
|
|
856
|
+
? await loadTeamCredentials(configuredServer.value)
|
|
857
|
+
: null;
|
|
858
|
+
const online = credentials
|
|
859
|
+
? await fetchOnlineModels(credentials).catch((error) => {
|
|
860
|
+
chat.ephemeralLine(`[/advisor] 在线顾问模型暂时不可用:${error instanceof Error ? error.message : String(error)};仍可选择本机顾问模型。`);
|
|
861
|
+
return [];
|
|
862
|
+
})
|
|
863
|
+
: [];
|
|
864
|
+
const pickerModels = [...enabledModels, ...online.map(toPickerModel)];
|
|
865
|
+
if (pickerModels.length === 0) {
|
|
550
866
|
chat.ephemeralLine('[/advisor] 尚未配置任何模型,请先添加模型。');
|
|
551
867
|
return;
|
|
552
868
|
}
|
|
553
869
|
if (note) {
|
|
554
870
|
// /advisor select <id> 直接指定模型
|
|
555
|
-
const target =
|
|
871
|
+
const target = pickerModels.find((m) => m.id === note || m.model === note || m.displayName === note);
|
|
556
872
|
if (!target) {
|
|
557
|
-
chat.ephemeralLine(`[/advisor] 未找到模型 "${note}",可用模型:\n${
|
|
873
|
+
chat.ephemeralLine(`[/advisor] 未找到模型 "${note}",可用模型:\n${pickerModels.map((m) => ` ${m.id} · ${m.displayName || m.model}`).join('\n')}`);
|
|
558
874
|
return;
|
|
559
875
|
}
|
|
560
|
-
await configService.savePatch({
|
|
876
|
+
await configService.savePatch({
|
|
877
|
+
advisor: { modelId: target.id, enabled: true },
|
|
878
|
+
});
|
|
561
879
|
chat.ephemeralLine(`[/advisor] 已设置顾问模型为 ${target.displayName || target.model}(${formatProviderName(target.apiFormat)})。`);
|
|
562
880
|
}
|
|
563
881
|
else {
|
|
564
882
|
// 无参数:打开交互选择器(含"关闭"选项)
|
|
565
883
|
const snap = await configService.getSnapshot();
|
|
566
|
-
setAdvisorModelPicker({
|
|
884
|
+
setAdvisorModelPicker({
|
|
885
|
+
models: pickerModels,
|
|
886
|
+
currentId: snap.config?.advisor?.modelId ?? null,
|
|
887
|
+
});
|
|
567
888
|
}
|
|
568
889
|
return;
|
|
569
890
|
}
|
|
@@ -603,7 +924,6 @@ export function App({ provider, initialHistory }) {
|
|
|
603
924
|
chat.activeSessionId,
|
|
604
925
|
chat.submit,
|
|
605
926
|
chat.runManualAdvisor,
|
|
606
|
-
chat.setProvider,
|
|
607
927
|
chat.computerUseMode,
|
|
608
928
|
chat.setComputerUseMode,
|
|
609
929
|
chat.stopComputerUse,
|
|
@@ -613,7 +933,6 @@ export function App({ provider, initialHistory }) {
|
|
|
613
933
|
handleSessionCreate,
|
|
614
934
|
openWorkspacePicker,
|
|
615
935
|
handleBaseModelSelect,
|
|
616
|
-
handleAdvisorModelSelect,
|
|
617
936
|
]);
|
|
618
937
|
// banner 改作为 Static items[0] 走 MessageList。原因:Ink 5 的 Static 约定
|
|
619
938
|
// 它必须是兄弟节点中第一个,否则 above-sibling 会跟 Static commit 一起被重打
|
|
@@ -621,7 +940,7 @@ export function App({ provider, initialHistory }) {
|
|
|
621
940
|
// 使用 getCurrentProvider() 获取最新 provider(/model 切换后实时显示)
|
|
622
941
|
const currentProvider = chat.getCurrentProvider();
|
|
623
942
|
const bannerText = `minimal-agent · ${currentProvider.name}/${currentProvider.model} · /model 切模型 · /computer 控制桌面 · /copy 复制回复 · /paste-image 添加图片 · /new 清空 · /compact 压缩 · Ctrl+C 中断`;
|
|
624
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { history: deferredHistory, compactGeneration: chat.compactGeneration, bannerText: bannerText, terminalRows: terminalRows }), _jsxs(Box, { flexDirection: "column", width: Math.max(1, terminalCols - 1), children: [_jsx(LiveArea, { progressStage: chat.progressStage, reasoningPreview: chat.reasoningPreview, streamingText: chat.streamingText, runningTools: chat.runningTools, pluginProgress: chat.pluginProgress, transientError: chat.transientError, terminalCols: terminalCols, terminalRows: terminalRows }), _jsx(QueuedMessagesBanner, { items: chat.queuedItems }), chat.pendingComputerIntervention && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.warning, paddingX: 1, marginBottom: 1, children: [_jsxs(Text, { color: theme.warning, children: ["\u9700\u8981\u4EBA\u5DE5\u64CD\u4F5C\uFF1A", chat.pendingComputerIntervention.sanitizedSummary] }), _jsx(Text, { dimColor: true, children: "\u8BF7\u76F4\u63A5\u5728\u76EE\u6807\u5E94\u7528\u4E2D\u5904\u7406\uFF1B\u654F\u611F\u5185\u5BB9\u4E0D\u4F1A\u8FDB\u5165\u7EC8\u7AEF\u6216\u6A21\u578B\u3002\u5B8C\u6210\u540E\u8F93\u5165 /computer resume\uFF0C\u53D6\u6D88\u8F93\u5165 /computer cancel\u3002" })] })), chat.error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.error, children: ["\u26A0 ", chat.error] }) })), chat.interrupted && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.warning, children: "\u26A1 \u64CD\u4F5C\u88AB\u7528\u6237\u4E2D\u65AD\uFF0C\u7B49\u5F85\u65B0\u7684\u4EFB\u52A1\u8F93\u5165..." }),
|
|
943
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(MessageList, { history: deferredHistory, compactGeneration: chat.compactGeneration, bannerText: bannerText, terminalRows: terminalRows }), _jsxs(Box, { flexDirection: "column", width: Math.max(1, terminalCols - 1), children: [_jsx(LiveArea, { progressStage: chat.progressStage, reasoningPreview: chat.reasoningPreview, streamingText: chat.streamingText, runningTools: chat.runningTools, pluginProgress: chat.pluginProgress, transientError: chat.transientError, terminalCols: terminalCols, terminalRows: terminalRows }), _jsx(QueuedMessagesBanner, { items: chat.queuedItems }), chat.pendingComputerIntervention && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.warning, paddingX: 1, marginBottom: 1, children: [_jsxs(Text, { color: theme.warning, children: ["\u9700\u8981\u4EBA\u5DE5\u64CD\u4F5C\uFF1A", chat.pendingComputerIntervention.sanitizedSummary] }), _jsx(Text, { dimColor: true, children: "\u8BF7\u76F4\u63A5\u5728\u76EE\u6807\u5E94\u7528\u4E2D\u5904\u7406\uFF1B\u654F\u611F\u5185\u5BB9\u4E0D\u4F1A\u8FDB\u5165\u7EC8\u7AEF\u6216\u6A21\u578B\u3002\u5B8C\u6210\u540E\u8F93\u5165 /computer resume\uFF0C\u53D6\u6D88\u8F93\u5165 /computer cancel\u3002" })] })), chat.error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.error, children: ["\u26A0 ", chat.error] }) })), chat.interrupted && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.warning, children: "\u26A1 \u64CD\u4F5C\u88AB\u7528\u6237\u4E2D\u65AD\uFF0C\u7B49\u5F85\u65B0\u7684\u4EFB\u52A1\u8F93\u5165..." }), _jsxs(Text, { dimColor: true, children: [' ', "\u8C03\u6574\u4E0A\u4E00\u6B21\u8BA1\u5212\uFF1A\u76F4\u63A5\u8BF4\u8C03\u6574\u5185\u5BB9 / \u91CD\u65B0\u8DD1 /plan \u76EE\u6807 / \u65B0\u4EFB\u52A1\u76F4\u63A5\u8BF4"] })] })), configMenuOpen ? (_jsx(ConfigMenu, { mode: "reconfigure", onDone: () => setConfigMenuOpen(false) })) : baseModelPicker ? (_jsx(ModelPicker, { models: baseModelPicker.models, currentModelId: baseModelPicker.currentId, title: "\u9009\u62E9\u57FA\u5EA7\u6A21\u578B", onSelect: handleBaseModelSelect, onCancel: () => setBaseModelPicker(null) })) : advisorModelPicker ? (_jsx(ModelPicker, { models: advisorModelPicker.models, currentModelId: advisorModelPicker.currentId, title: "\u9009\u62E9\u987E\u95EE\u6A21\u578B", nullOptionLabel: "\u25CB \u4E0D\u4F7F\u7528\u987E\u95EE\u6A21\u578B", onSelect: handleAdvisorModelSelect, onCancel: () => setAdvisorModelPicker(null) })) : workspacePicker ? (_jsx(WorkspacePicker, { workspaces: workspacePicker, currentPath: getWorkingDir(), currentSessionId: chat.activeSessionId, onSelect: handleWorkspaceSelect, onCancel: () => setWorkspacePicker(null) })) : sessionPicker ? (_jsx(SessionPicker, { sessions: sessionPicker, activeSessionId: chat.activeSessionId, onSelect: handleSessionSelect, onCreate: handleSessionCreate, onCancel: () => setSessionPicker(null) })) : chat.pendingAsk ? (_jsx(AskQuestion, { questions: chat.pendingAsk, source: chat.pendingAskSource, queuedCount: chat.pendingAskQueueCount, onAnswer: chat.answerAsk, onCancel: chat.cancelAsk })) : (
|
|
625
944
|
/* handleSubmit 包装做 slash 命令拦截,非命令透传 chat.submit */
|
|
626
945
|
_jsx(InputBox, { onSubmit: handleSubmit, disabled: chat.isLoading && !chat.pendingComputerIntervention, onAbort: chat.abort, onClear: handleClear, onCompact: chat.compactNow, onWorkspaces: openWorkspacePicker })), _jsx(StatusLine, { provider: currentProvider, history: chat.history, pluginProgress: chat.pluginProgress, contextUsage: chat.contextUsage })] })] }));
|
|
627
946
|
}
|