minimal-agent 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/package.json +62 -5
- package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
- package/plugins/cron-runner/src/commands.js +4 -4
- package/plugins/cron-runner/src/commands.ts +4 -4
- package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
- package/plugins/workflow-runner/commands/workflow.md +57 -90
- package/plugins/workflow-runner/commands/workflows.md +4 -4
- package/plugins/workflow-runner/plugin.js +24 -13
- package/plugins/workflow-runner/plugin.ts +28 -13
- package/plugins/workflow-runner/src/discovery.js +160 -0
- package/plugins/workflow-runner/src/discovery.ts +194 -0
- package/plugins/workflow-runner/src/goalAnchor.js +53 -0
- package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
- package/plugins/workflow-runner/src/index.js +204 -185
- package/plugins/workflow-runner/src/index.ts +249 -224
- package/plugins/workflow-runner/src/inputCoercion.js +40 -0
- package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
- package/plugins/workflow-runner/src/journal.js +224 -0
- package/plugins/workflow-runner/src/journal.ts +274 -0
- package/plugins/workflow-runner/src/jsonSchema.js +132 -0
- package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
- package/plugins/workflow-runner/src/moduleResolution.js +64 -0
- package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
- package/plugins/workflow-runner/src/resourceInputs.js +220 -0
- package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
- package/plugins/workflow-runner/src/runner.js +404 -467
- package/plugins/workflow-runner/src/runner.ts +491 -535
- package/plugins/workflow-runner/src/runtime/config.js +46 -0
- package/plugins/workflow-runner/src/runtime/config.ts +69 -0
- package/plugins/workflow-runner/src/runtime/context.js +1304 -0
- package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
- package/plugins/workflow-runner/src/runtime/exec.js +34 -0
- package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
- package/plugins/workflow-runner/src/runtime/flow.js +8 -0
- package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
- package/plugins/workflow-runner/src/runtime/fs.js +27 -0
- package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
- package/plugins/workflow-runner/src/runtime/model.js +6 -0
- package/plugins/workflow-runner/src/runtime/model.ts +8 -0
- package/plugins/workflow-runner/src/runtime/output.js +7 -0
- package/plugins/workflow-runner/src/runtime/output.ts +21 -0
- package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
- package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
- package/plugins/workflow-runner/src/runtime/state.js +16 -0
- package/plugins/workflow-runner/src/runtime/state.ts +19 -0
- package/plugins/workflow-runner/src/runtime/tools.js +3 -0
- package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
- package/plugins/workflow-runner/src/sandbox.js +141 -0
- package/plugins/workflow-runner/src/sandbox.ts +182 -0
- package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
- package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
- package/plugins/workflow-runner/src/taskIdentity.js +172 -152
- package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
- package/plugins/workflow-runner/src/toolRuntime.js +29 -8
- package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
- package/plugins/workflow-runner/src/types.js +7 -105
- package/plugins/workflow-runner/src/types.ts +155 -520
- package/plugins/workflow-runner/src/util.js +47 -0
- package/plugins/workflow-runner/src/util.ts +51 -0
- package/plugins/workflow-runner/src/workflowContext.js +20 -0
- package/plugins/workflow-runner/src/workflowContext.ts +58 -0
- package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
- package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
- package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
- package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
- package/plugins/workflow-runner/src/workflowState.js +542 -469
- package/plugins/workflow-runner/src/workflowState.ts +639 -589
- package/plugins/workflow-runner/test/api.test.ts +223 -0
- package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
- package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
- package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
- package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
- package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
- package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
- package/plugins/workflow-runner/test/discovery.test.ts +234 -0
- package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
- package/plugins/workflow-runner/test/goalController.test.ts +317 -0
- package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
- package/plugins/workflow-runner/test/listResources.test.ts +106 -0
- package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
- package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
- package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
- package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
- package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
- package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
- package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
- package/skills/pptx/examples/assets/cover-bg.svg +23 -0
- package/skills/pptx/examples/assets/icon-spark.svg +5 -0
- package/skills/skill-creator/scripts/run_eval.py +3 -2
- package/skills/ui-design/SKILL.md +5 -2
- package/skills/ui-design/references/layout-composition.md +1 -1
- package/skills/workflow-creator/SKILL.md +344 -0
- package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
- package/skills/workflow-creator/references/api.md +216 -0
- package/skills/workflow-creator/references/migration.md +103 -0
- package/skills/workflow-creator/references/patterns.md +779 -0
- package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
- package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
- package/skills/workflow-creator/scripts/validate.mjs +275 -0
- package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
- package/src/advisor/advisorCoordinator.js +503 -0
- package/src/advisor/advisorCoordinator.ts +657 -0
- package/src/cli/configMenu.tsx +0 -1
- package/src/cli/print.js +44 -6
- package/src/cli/print.ts +73 -4
- package/src/cli/streamJson.js +5 -6
- package/src/cli/streamJson.ts +8 -4
- package/src/cli/wizards/advisorWizard.js +4 -2
- package/src/cli/wizards/advisorWizard.tsx +8 -2
- package/src/cli/wizards/contextAdvisorWizard.js +5 -4
- package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
- package/src/collaboration/taskFlow.js +115 -0
- package/src/collaboration/taskFlow.ts +169 -0
- package/src/config/configDefaults.js +41 -1
- package/src/config/configDefaults.ts +43 -1
- package/src/config/configDiagnostics.ts +2 -2
- package/src/config/configFile.js +40 -9
- package/src/config/configFile.ts +60 -11
- package/src/config/configService.js +443 -74
- package/src/config/configService.ts +723 -142
- package/src/config/numericLimits.js +22 -0
- package/src/config/numericLimits.ts +24 -0
- package/src/config.js +1 -0
- package/src/config.ts +3 -2
- package/src/context/budgetPlan.js +1 -1
- package/src/context/budgetPlan.ts +1 -1
- package/src/context/compact.js +7 -2
- package/src/context/compact.ts +9 -2
- package/src/context/microCompactLite.js +212 -13
- package/src/context/microCompactLite.ts +261 -12
- package/src/context/sessionRegistry.js +8 -1
- package/src/context/sessionRegistry.ts +18 -5
- package/src/context/toolResultArchive.js +72 -0
- package/src/context/toolResultArchive.ts +95 -0
- package/src/goal/errors.js +8 -0
- package/src/goal/errors.ts +18 -0
- package/src/goal/goalRuntime.js +344 -0
- package/src/goal/goalRuntime.ts +466 -0
- package/src/goal/goalStore.js +200 -0
- package/src/goal/goalStore.ts +219 -0
- package/src/goal/index.js +4 -0
- package/src/goal/index.ts +4 -0
- package/src/goal/statusMapping.js +71 -0
- package/src/goal/statusMapping.ts +95 -0
- package/src/goal/types.js +7 -0
- package/src/goal/types.ts +179 -0
- package/src/goal/workflowController.js +306 -0
- package/src/goal/workflowController.ts +360 -0
- package/src/harness/evidenceLedger.js +2 -0
- package/src/harness/evidenceLedger.ts +1 -0
- package/src/harness/stallGuard.js +9 -3
- package/src/harness/stallGuard.ts +7 -3
- package/src/images/imageResolver.js +161 -0
- package/src/images/imageResolver.ts +189 -0
- package/src/infra/verification.js +56 -20
- package/src/infra/verification.ts +87 -20
- package/src/llm/client.js +79 -21
- package/src/llm/client.ts +182 -35
- package/src/llm/gatewayClient.js +201 -0
- package/src/llm/gatewayClient.ts +299 -0
- package/src/llm/messageProvenance.js +46 -0
- package/src/llm/messageProvenance.ts +58 -0
- package/src/llm/modelProvider.js +1 -0
- package/src/llm/modelProvider.ts +22 -0
- package/src/llm/providers/anthropicFormat.js +108 -1
- package/src/llm/providers/anthropicFormat.ts +115 -4
- package/src/llm/providers/openaiFormat.js +9 -0
- package/src/llm/providers/openaiFormat.ts +12 -3
- package/src/loop.js +319 -54
- package/src/loop.ts +373 -57
- package/src/main.js +4 -1
- package/src/main.tsx +4 -1
- package/src/managedExecution/index.js +2 -0
- package/src/managedExecution/index.ts +2 -0
- package/src/managedExecution/registry.js +15 -0
- package/src/managedExecution/registry.ts +20 -0
- package/src/managedExecution/types.js +1 -0
- package/src/managedExecution/types.ts +86 -0
- package/src/modelRef.js +9 -0
- package/src/modelRef.ts +31 -0
- package/src/multimodal.js +14 -28
- package/src/multimodal.ts +17 -33
- package/src/net/lanDiscovery.js +65 -0
- package/src/net/lanDiscovery.ts +82 -0
- package/src/plugin-sdk.js +28 -3
- package/src/plugin-sdk.ts +39 -6
- package/src/plugins/pluginApi.ts +16 -1
- package/src/plugins/pluginLoader.js +4 -0
- package/src/plugins/pluginLoader.ts +6 -0
- package/src/plugins/pluginRunner.js +152 -9
- package/src/plugins/pluginRunner.ts +186 -8
- package/src/plugins/slashFallback.js +113 -0
- package/src/plugins/slashFallback.ts +137 -0
- package/src/prompts/policyRegistry.js +15 -8
- package/src/prompts/policyRegistry.ts +18 -8
- package/src/prompts/promptAssembly.js +103 -12
- package/src/prompts/promptAssembly.ts +114 -12
- package/src/prompts/skillList.js +21 -3
- package/src/prompts/skillList.ts +27 -2
- package/src/prompts/stableSystemPrompt.js +18 -0
- package/src/prompts/stableSystemPrompt.ts +33 -0
- package/src/runtime/agentRuntimeContext.js +8 -2
- package/src/runtime/agentRuntimeContext.ts +17 -4
- package/src/session/runAgentTurn.js +78 -12
- package/src/session/runAgentTurn.ts +105 -23
- package/src/session/runTurn.js +10 -9
- package/src/session/runTurn.ts +17 -8
- package/src/session/sessionState.ts +2 -0
- package/src/team/auth.js +186 -0
- package/src/team/auth.ts +298 -0
- package/src/team/cli.js +105 -0
- package/src/team/cli.ts +122 -0
- package/src/team/onlineToolContract.js +64 -0
- package/src/team/onlineToolContract.ts +109 -0
- package/src/team/toolPolicy.js +36 -0
- package/src/team/toolPolicy.ts +75 -0
- package/src/tools/advisor/advisor.js +148 -37
- package/src/tools/advisor/advisor.ts +161 -38
- package/src/tools/advisor/advisorDecision.js +71 -0
- package/src/tools/advisor/advisorDecision.ts +85 -0
- package/src/tools/agent/agent.js +18 -5
- package/src/tools/agent/agent.ts +21 -7
- package/src/tools/agent/agentControl.js +246 -0
- package/src/tools/agent/agentControl.ts +284 -0
- package/src/tools/agent/agentTaskService.js +40 -1
- package/src/tools/agent/agentTaskService.ts +44 -1
- package/src/tools/agent/agentTypes.js +14 -2
- package/src/tools/agent/agentTypes.ts +15 -2
- package/src/tools/applypatch/applyPatch.js +362 -0
- package/src/tools/applypatch/applyPatch.ts +428 -0
- package/src/tools/bash/bash.js +70 -18
- package/src/tools/bash/bash.ts +75 -20
- package/src/tools/capabilities.js +10 -5
- package/src/tools/capabilities.ts +10 -5
- package/src/tools/computeruse/computerIntent.js +32 -0
- package/src/tools/computeruse/computerIntent.ts +46 -0
- package/src/tools/computeruse/telemetryLog.js +12 -0
- package/src/tools/computeruse/telemetryLog.ts +16 -0
- package/src/tools/computeruse/vision/telemetry.js +1 -0
- package/src/tools/computeruse/vision/telemetry.ts +1 -0
- package/src/tools/effectiveToolSet.js +4 -0
- package/src/tools/effectiveToolSet.ts +4 -0
- package/src/tools/index.js +21 -2
- package/src/tools/index.ts +33 -2
- package/src/tools/powershell/powershell.js +18 -1
- package/src/tools/powershell/powershell.ts +18 -2
- package/src/tools/presentresult/presentresult.js +6 -15
- package/src/tools/presentresult/presentresult.ts +6 -15
- package/src/tools/read/read.js +69 -11
- package/src/tools/read/read.ts +70 -11
- package/src/tools/shared/fileUtils.js +1 -2
- package/src/tools/shared/fileUtils.ts +1 -2
- package/src/tools/shared/permanentDeleteGuard.js +34 -3
- package/src/tools/shared/permanentDeleteGuard.ts +43 -6
- package/src/tools/shared/toolOutputStore.js +23 -1
- package/src/tools/shared/toolOutputStore.ts +22 -1
- package/src/tools/skill/skill.js +9 -3
- package/src/tools/skill/skill.ts +8 -4
- package/src/tools/toolPromptGuides.js +117 -0
- package/src/tools/toolPromptGuides.ts +137 -0
- package/src/tools/webbrowser/agentBrowserPath.js +19 -9
- package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
- package/src/tools/webbrowser/browser.js +27 -11
- package/src/tools/webbrowser/browser.ts +68 -24
- package/src/tools/webbrowser/browserAutomation.js +329 -0
- package/src/tools/webbrowser/browserAutomation.ts +467 -0
- package/src/tools/webbrowser/browserAxState.js +97 -0
- package/src/tools/webbrowser/browserAxState.ts +142 -0
- package/src/tools/webbrowser/browserBatch.js +1578 -0
- package/src/tools/webbrowser/browserBatch.ts +2382 -0
- package/src/tools/webbrowser/browserCdp.js +208 -0
- package/src/tools/webbrowser/browserCdp.ts +255 -0
- package/src/tools/webbrowser/browserConditions.js +24 -0
- package/src/tools/webbrowser/browserConditions.ts +45 -0
- package/src/tools/webbrowser/browserContent.js +281 -0
- package/src/tools/webbrowser/browserContent.ts +438 -0
- package/src/tools/webbrowser/browserControl.js +131 -30
- package/src/tools/webbrowser/browserControl.ts +210 -50
- package/src/tools/webbrowser/browserDaemon.js +22 -14
- package/src/tools/webbrowser/browserDaemon.ts +54 -21
- package/src/tools/webbrowser/browserFrames.js +47 -0
- package/src/tools/webbrowser/browserFrames.ts +54 -0
- package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
- package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
- package/src/tools/webbrowser/browserLocator.js +140 -0
- package/src/tools/webbrowser/browserLocator.ts +194 -0
- package/src/tools/webbrowser/browserOutcome.js +10 -17
- package/src/tools/webbrowser/browserOutcome.ts +48 -31
- package/src/tools/webbrowser/browserRecovery.js +58 -0
- package/src/tools/webbrowser/browserRecovery.ts +83 -0
- package/src/tools/webbrowser/browserRunRegistry.js +35 -3
- package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
- package/src/tools/webbrowser/browserService.js +28 -2
- package/src/tools/webbrowser/browserService.ts +49 -9
- package/src/tools/webbrowser/browserStream.js +132 -33
- package/src/tools/webbrowser/browserStream.ts +224 -50
- package/src/tools/webbrowser/browserTabs.js +48 -15
- package/src/tools/webbrowser/browserTabs.ts +178 -96
- package/src/tools/webbrowser/webbrowser.js +683 -144
- package/src/tools/webbrowser/webbrowser.ts +979 -236
- package/src/tools/webfetch/preapproved.js +0 -2
- package/src/tools/webfetch/preapproved.ts +0 -2
- package/src/tools/websearch/websearch.js +129 -8
- package/src/tools/websearch/websearch.ts +138 -6
- package/src/types.ts +450 -42
- package/src/ui/App.js +377 -58
- package/src/ui/App.tsx +576 -111
- package/src/ui/LiveArea.js +14 -8
- package/src/ui/LiveArea.tsx +14 -10
- package/src/ui/MessageList.js +63 -20
- package/src/ui/MessageList.tsx +101 -16
- package/src/ui/ModelPicker.js +7 -4
- package/src/ui/ModelPicker.tsx +55 -8
- package/src/ui/hooks/useChat.js +152 -163
- package/src/ui/hooks/useChat.ts +396 -334
- package/src/ui/loginCommand.js +56 -0
- package/src/ui/loginCommand.ts +63 -0
- package/src/ui/toolProgress.js +41 -0
- package/src/ui/toolProgress.ts +44 -0
- package/src/web/browserBridge.js +20 -2
- package/src/web/browserBridge.ts +20 -2
- package/src/web/protocol.ts +1897 -194
- package/workflows/adaptive-research/workflow.mjs +86 -0
- package/workflows/e2e-capabilities/workflow.mjs +102 -0
- package/workflows/e2e-llm/workflow.mjs +52 -0
- package/workflows/e2e-smoke/workflow.mjs +59 -0
- package/workflows/e2e-vision-schema/README.md +48 -0
- package/workflows/e2e-vision-schema/workflow.mjs +149 -0
- package/workflows/e2e-write-greet/workflow.mjs +37 -0
- package/workflows/file-census/README.md +14 -0
- package/workflows/file-census/scripts/.gitkeep +2 -0
- package/workflows/file-census/workflow.mjs +110 -0
- package/workflows/goal/README.md +166 -0
- package/workflows/goal/prompts/audit.md +57 -0
- package/workflows/goal/prompts/contract.md +56 -0
- package/workflows/goal/prompts/iterate.md +37 -0
- package/workflows/goal/workflow.mjs +501 -0
- package/workflows/illustrate/README.md +90 -0
- package/workflows/illustrate/assets/engines.json +20 -0
- package/workflows/illustrate/assets/extract-baidu.js +21 -0
- package/workflows/illustrate/assets/extract-bing.js +33 -0
- package/workflows/illustrate/assets/extract-google.js +31 -0
- package/workflows/illustrate/workflow.mjs +301 -0
- package/workflows/plan/workflow.mjs +389 -0
- package/workflows/question-crops/README.md +35 -0
- package/workflows/question-crops/prompts/inventory.md +23 -0
- package/workflows/question-crops/scripts/image-ops.mjs +305 -0
- package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
- package/workflows/question-crops/workflow.mjs +172 -0
- package/workflows/ralph-loop/workflow.mjs +162 -0
- package/workflows/research/DESIGN.md +449 -0
- package/workflows/research/README.md +74 -0
- package/workflows/research/prompts/s0-goal.md +43 -0
- package/workflows/research/prompts/s1-early-exit.md +22 -0
- package/workflows/research/prompts/s1-map.md +58 -0
- package/workflows/research/prompts/s2-options.md +53 -0
- package/workflows/research/prompts/s3-deep-dive.md +56 -0
- package/workflows/research/prompts/s4-verify.md +74 -0
- package/workflows/research/prompts/s5-synthesis.md +81 -0
- package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
- package/workflows/research/prompts/s6-package.md +32 -0
- package/workflows/research/scripts/build-report.mjs +98 -0
- package/workflows/research/workflow.mjs +288 -0
- package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
- package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
- package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
- package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
- package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
- package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
- package/workflows/wechat-reading-shots/workflow.mjs +266 -0
- package/workflows/wrong-question-docx/README.md +55 -0
- package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
- package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
- package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
- package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
- package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
- package/workflows/wrong-question-docx/workflow.mjs +485 -0
- package/plugins/workflow-runner/src/agentCommon.js +0 -354
- package/plugins/workflow-runner/src/agentCommon.ts +0 -435
- package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
- package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
- package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
- package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
- package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
- package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
- package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
- package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
- package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
- package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
- package/plugins/workflow-runner/src/dslManifest.js +0 -72
- package/plugins/workflow-runner/src/dslManifest.ts +0 -127
- package/plugins/workflow-runner/src/expressions.js +0 -618
- package/plugins/workflow-runner/src/expressions.ts +0 -622
- package/plugins/workflow-runner/src/loader.js +0 -573
- package/plugins/workflow-runner/src/loader.ts +0 -721
- package/plugins/workflow-runner/src/multimodal.js +0 -38
- package/plugins/workflow-runner/src/multimodal.ts +0 -64
- package/plugins/workflow-runner/src/recovery.js +0 -119
- package/plugins/workflow-runner/src/recovery.ts +0 -149
- package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
- package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
- package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
- package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
- package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
- package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
- package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
- package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
- package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
- package/plugins/workflow-runner/src/stepPipeline.js +0 -277
- package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
- package/plugins/workflow-runner/test/agent.test.ts +0 -587
- package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
- package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
- package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
- package/plugins/workflow-runner/test/context-files.test.ts +0 -320
- package/plugins/workflow-runner/test/e2e.test.ts +0 -370
- package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
- package/plugins/workflow-runner/test/expressions.test.ts +0 -397
- package/plugins/workflow-runner/test/foundation.test.ts +0 -126
- package/plugins/workflow-runner/test/graceful.test.ts +0 -139
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
- package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
- package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
- package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
- package/plugins/workflow-runner/test/loader.test.ts +0 -617
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
- package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
- package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
- package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
- package/plugins/workflow-runner/test/recovery.test.ts +0 -265
- package/plugins/workflow-runner/test/runner.test.ts +0 -911
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
- package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
- package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
- package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
- package/plugins/workflow-runner/test/word.load.test.ts +0 -208
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
- package/src/advisorState.js +0 -22
- package/src/cli/configWizard.js +0 -293
- package/src/tools/toolProgressBridge.js +0 -48
- package/workflows/adaptive-research.yaml +0 -50
- package/workflows/book-review-short.yaml +0 -125
- package/workflows/e2e-write-greet.yaml +0 -31
- package/workflows/illustrate.yaml +0 -227
- package/workflows/plan.yaml +0 -470
- package/workflows/ppt.yaml +0 -1670
- package/workflows/ralph-loop.yaml +0 -199
- package/workflows/schema.json +0 -176
- package/workflows/webppt.yaml +0 -496
- package/workflows/wechat-reading-shots.yaml +0 -315
- package/workflows/word.yaml +0 -720
- package/workflows/youtube-shorts.yaml +0 -202
package/src/ui/LiveArea.js
CHANGED
|
@@ -8,7 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
* └ 内容区(0..N 行,有界):随阶段切换——
|
|
9
9
|
* thinking → reasoningPreview 尾部最近 N 行(gray dim,首行 💭)
|
|
10
10
|
* streaming → streamingText 尾部最近 N 行(默认亮色 = 答案是主角)
|
|
11
|
-
* tool_executing
|
|
11
|
+
* tool_executing →「当前正在」动作 + 可选独立进度行(gray dim)
|
|
12
12
|
* compacting/idle→ 无内容行
|
|
13
13
|
*
|
|
14
14
|
* ★ 暂态错误行(transientError):工作流步执行中 LLM 调用失败(会被该步重试)时,
|
|
@@ -34,10 +34,11 @@ import { Box, Text } from 'ink';
|
|
|
34
34
|
import { LIVE_RIGHT_MARGIN, clampWidthStart, wrapToDisplayLines, } from './liveViewport.js';
|
|
35
35
|
import { theme } from './theme.js';
|
|
36
36
|
import { figures } from './figures.js';
|
|
37
|
+
import { humanizeToolProgress } from './toolProgress.js';
|
|
37
38
|
const STAGE_LABELS = {
|
|
38
39
|
thinking: '思考中',
|
|
39
40
|
streaming: '回答中',
|
|
40
|
-
tool_executing: '
|
|
41
|
+
tool_executing: '工作中',
|
|
41
42
|
compacting: '压缩历史',
|
|
42
43
|
};
|
|
43
44
|
/** 动画 spinner 帧(charWidth 上界按 2 计;终端实际多为 1,算宽无害)。 */
|
|
@@ -69,15 +70,17 @@ function toolDesc(t) {
|
|
|
69
70
|
: `${t.toolName}(${t.argsPreview.length > TOOL_ARGS_MAX
|
|
70
71
|
? `${t.argsPreview.slice(0, TOOL_ARGS_MAX - 1)}…`
|
|
71
72
|
: t.argsPreview})`;
|
|
72
|
-
|
|
73
|
+
const readable = humanizeToolProgress(base);
|
|
74
|
+
return t.progress && t.progress.length > 0 ? `${readable} · ${t.progress}` : readable;
|
|
73
75
|
}
|
|
74
76
|
/** 不带 progress 的静态描述(蜂群树的描述行用;进度另起 ⎿ 行)。 */
|
|
75
77
|
function toolDescStatic(t) {
|
|
76
|
-
|
|
78
|
+
const base = t.argsFriendly && t.argsFriendly.length > 0
|
|
77
79
|
? t.argsFriendly
|
|
78
80
|
: `${t.toolName}(${t.argsPreview.length > TOOL_ARGS_MAX
|
|
79
81
|
? `${t.argsPreview.slice(0, TOOL_ARGS_MAX - 1)}…`
|
|
80
82
|
: t.argsPreview})`;
|
|
83
|
+
return humanizeToolProgress(base);
|
|
81
84
|
}
|
|
82
85
|
/**
|
|
83
86
|
* 蜂群树:runningTools 里有 ≥2 个并行的 Agent 子任务时,把 tool_executing
|
|
@@ -178,11 +181,14 @@ export function buildLiveView(props) {
|
|
|
178
181
|
contentDim = false; // 答案 = 主角,默认亮色
|
|
179
182
|
}
|
|
180
183
|
else if (stage === 'tool_executing' && runningTools.length > 0) {
|
|
181
|
-
// ≥2 个并行 Agent 子任务 →
|
|
184
|
+
// ≥2 个并行 Agent 子任务 → 蜂群树;普通工具用“当前正在”主行,长时
|
|
185
|
+
// progress 独占下一行,避免主行变长后把最关键的 15/31 等进度截掉。
|
|
182
186
|
const swarm = buildSwarmLines(runningTools, maxWidth, maxLines);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
const flatLines = runningTools.flatMap((tool) => [
|
|
188
|
+
` 当前正在:${toolDescStatic(tool)}`,
|
|
189
|
+
...(tool.progress ? [` ${figures.elbow} ${tool.progress}`] : []),
|
|
190
|
+
]);
|
|
191
|
+
contentLines = swarm ?? lastN(flatLines, maxLines).map((line) => clampWidthStart(line, maxWidth));
|
|
186
192
|
contentDim = true;
|
|
187
193
|
}
|
|
188
194
|
return {
|
package/src/ui/LiveArea.tsx
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* └ 内容区(0..N 行,有界):随阶段切换——
|
|
8
8
|
* thinking → reasoningPreview 尾部最近 N 行(gray dim,首行 💭)
|
|
9
9
|
* streaming → streamingText 尾部最近 N 行(默认亮色 = 答案是主角)
|
|
10
|
-
* tool_executing
|
|
10
|
+
* tool_executing →「当前正在」动作 + 可选独立进度行(gray dim)
|
|
11
11
|
* compacting/idle→ 无内容行
|
|
12
12
|
*
|
|
13
13
|
* ★ 暂态错误行(transientError):工作流步执行中 LLM 调用失败(会被该步重试)时,
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
import { theme } from './theme.js';
|
|
42
42
|
import { figures } from './figures.js';
|
|
43
43
|
import type { PluginProgressState } from './hooks/useChat.js';
|
|
44
|
+
import { humanizeToolProgress } from './toolProgress.js';
|
|
44
45
|
|
|
45
46
|
export interface LiveAreaProps {
|
|
46
47
|
progressStage: ProgressStage;
|
|
@@ -64,7 +65,7 @@ export interface LiveAreaProps {
|
|
|
64
65
|
const STAGE_LABELS: Record<Exclude<ProgressStage, 'idle'>, string> = {
|
|
65
66
|
thinking: '思考中',
|
|
66
67
|
streaming: '回答中',
|
|
67
|
-
tool_executing: '
|
|
68
|
+
tool_executing: '工作中',
|
|
68
69
|
compacting: '压缩历史',
|
|
69
70
|
};
|
|
70
71
|
|
|
@@ -103,18 +104,20 @@ function toolDesc(t: ToolStatusState): string {
|
|
|
103
104
|
? `${t.argsPreview.slice(0, TOOL_ARGS_MAX - 1)}…`
|
|
104
105
|
: t.argsPreview
|
|
105
106
|
})`;
|
|
106
|
-
|
|
107
|
+
const readable = humanizeToolProgress(base);
|
|
108
|
+
return t.progress && t.progress.length > 0 ? `${readable} · ${t.progress}` : readable;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
/** 不带 progress 的静态描述(蜂群树的描述行用;进度另起 ⎿ 行)。 */
|
|
110
112
|
function toolDescStatic(t: ToolStatusState): string {
|
|
111
|
-
|
|
113
|
+
const base = t.argsFriendly && t.argsFriendly.length > 0
|
|
112
114
|
? t.argsFriendly
|
|
113
115
|
: `${t.toolName}(${
|
|
114
116
|
t.argsPreview.length > TOOL_ARGS_MAX
|
|
115
117
|
? `${t.argsPreview.slice(0, TOOL_ARGS_MAX - 1)}…`
|
|
116
118
|
: t.argsPreview
|
|
117
119
|
})`;
|
|
120
|
+
return humanizeToolProgress(base);
|
|
118
121
|
}
|
|
119
122
|
|
|
120
123
|
/**
|
|
@@ -259,13 +262,14 @@ export function buildLiveView(
|
|
|
259
262
|
contentLines = lastN(wrapToDisplayLines(streamingText, maxWidth), maxLines);
|
|
260
263
|
contentDim = false; // 答案 = 主角,默认亮色
|
|
261
264
|
} else if (stage === 'tool_executing' && runningTools.length > 0) {
|
|
262
|
-
// ≥2 个并行 Agent 子任务 →
|
|
265
|
+
// ≥2 个并行 Agent 子任务 → 蜂群树;普通工具用“当前正在”主行,长时
|
|
266
|
+
// progress 独占下一行,避免主行变长后把最关键的 15/31 等进度截掉。
|
|
263
267
|
const swarm = buildSwarmLines(runningTools, maxWidth, maxLines);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
268
|
+
const flatLines = runningTools.flatMap((tool) => [
|
|
269
|
+
` 当前正在:${toolDescStatic(tool)}`,
|
|
270
|
+
...(tool.progress ? [` ${figures.elbow} ${tool.progress}`] : []),
|
|
271
|
+
]);
|
|
272
|
+
contentLines = swarm ?? lastN(flatLines, maxLines).map((line) => clampWidthStart(line, maxWidth));
|
|
269
273
|
contentDim = true;
|
|
270
274
|
}
|
|
271
275
|
|
package/src/ui/MessageList.js
CHANGED
|
@@ -20,8 +20,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
20
20
|
* v2 新增:
|
|
21
21
|
* - assistant 分支渲染 reasoning_content / reasoning(💭 dim gray);
|
|
22
22
|
* 窄终端(rows<28)折叠 2 行 + "▾ N 行 reasoning 折叠"
|
|
23
|
-
* -
|
|
24
|
-
*
|
|
23
|
+
* - 纯工具 assistant 每批只写一条「工作进展」并保留 /show 短 id;
|
|
24
|
+
* 成功的普通 tool result 不进入 scrollback,失败/顾问/Agent/交付仍保留
|
|
25
25
|
* - user 分支前插 turn 头横线 "────── Turn N · 14:32 · 8s · 6 tools ──────",
|
|
26
26
|
* turn 边界扫描结果由 useMemo 一次性算出,挂在 StaticItem 上
|
|
27
27
|
*
|
|
@@ -29,7 +29,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
29
29
|
* banner: 青色加粗 minimal-agent + 暗灰色 provider/快捷键提示
|
|
30
30
|
* user: 整条青色 + "> " 前缀(输入;前置 turn 横线,若 turnMeta 非空)
|
|
31
31
|
* assistant: reasoning 暗灰带 💭,content 绿色 ⏺ 锚点 + 默认亮色正文(输出),tool_calls 黄色
|
|
32
|
-
* tool:
|
|
32
|
+
* tool: 普通成功结果静默;高价值结果暗灰折叠,末尾提示用 /show 查看
|
|
33
33
|
* ============================================================
|
|
34
34
|
*/
|
|
35
35
|
import React from 'react';
|
|
@@ -40,6 +40,7 @@ import { splitThinkBlocks } from '../utils/stripThink.js';
|
|
|
40
40
|
import { figures } from './figures.js';
|
|
41
41
|
import { renderMarkdownLines } from './markdown.js';
|
|
42
42
|
import { theme } from './theme.js';
|
|
43
|
+
import { toolBatchSummary, toolHistoryVisibility } from './toolProgress.js';
|
|
43
44
|
/** 中断标记 user message 的固定内容(loop.ts 写入) */
|
|
44
45
|
const INTERRUPT_USER_CONTENT = '(用户按下了 ESC/Ctrl+C 中断了任务)';
|
|
45
46
|
const MAX_TOOL_PREVIEW_LINES = 3;
|
|
@@ -101,6 +102,16 @@ export function buildToolCallIndex(history) {
|
|
|
101
102
|
}
|
|
102
103
|
return map;
|
|
103
104
|
}
|
|
105
|
+
/** 按 consultationId 关联持久化决定,供历史重载时在顾问卡片下恢复展示。 */
|
|
106
|
+
export function buildAdvisorDecisionIndex(history) {
|
|
107
|
+
const decisions = new Map();
|
|
108
|
+
for (const message of history) {
|
|
109
|
+
if (message.role !== 'tool' || message.display_metadata?.kind !== 'advisor_decision')
|
|
110
|
+
continue;
|
|
111
|
+
decisions.set(message.display_metadata.consultationId, message.display_metadata);
|
|
112
|
+
}
|
|
113
|
+
return decisions;
|
|
114
|
+
}
|
|
104
115
|
/**
|
|
105
116
|
* 从 Agent 子任务报告的统计尾巴(agent.ts 固定格式
|
|
106
117
|
* 「(子任务「x」[type]:N 轮 · M 次工具调用,K 次失败)」)解析统计数。
|
|
@@ -217,6 +228,7 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
217
228
|
const items = React.useMemo(() => {
|
|
218
229
|
const turnMetas = summarizeTurn(history);
|
|
219
230
|
const toolIndex = buildToolCallIndex(history);
|
|
231
|
+
const advisorDecisions = buildAdvisorDecisionIndex(history);
|
|
220
232
|
return [
|
|
221
233
|
...(bannerText
|
|
222
234
|
? [
|
|
@@ -232,6 +244,10 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
232
244
|
msg: m,
|
|
233
245
|
turnMeta: turnMetas[idx],
|
|
234
246
|
toolMeta: m.role === 'tool' ? (toolIndex.get(m.tool_call_id) ?? null) : null,
|
|
247
|
+
advisorDecision: m.role === 'tool'
|
|
248
|
+
&& m.display_metadata?.kind === 'advisor_consultation'
|
|
249
|
+
? (advisorDecisions.get(m.display_metadata.consultationId) ?? null)
|
|
250
|
+
: null,
|
|
235
251
|
// 纯派生 key:有 id 用 id,没有就用 idx 兜底。绝不在 render 期 mutate 消息对象
|
|
236
252
|
// (<Static> 已 commit 的行永不重绘,key 仅在 append 对账时用,idx 已足够稳定)。
|
|
237
253
|
key: m.id ?? `message-${idx}`,
|
|
@@ -244,7 +260,7 @@ export const MessageList = React.memo(function MessageList({ history, compactGen
|
|
|
244
260
|
if (item.kind === 'banner') {
|
|
245
261
|
return _jsx(BannerRow, { text: item.text }, item.key);
|
|
246
262
|
}
|
|
247
|
-
return (_jsx(MessageRow, { message: item.msg, turnMeta: item.turnMeta, toolMeta: item.toolMeta, foldReasoning: foldReasoning }, item.key));
|
|
263
|
+
return (_jsx(MessageRow, { message: item.msg, turnMeta: item.turnMeta, toolMeta: item.toolMeta, advisorDecision: item.advisorDecision, foldReasoning: foldReasoning }, item.key));
|
|
248
264
|
} }, compactGeneration));
|
|
249
265
|
});
|
|
250
266
|
function BannerRow({ text }) {
|
|
@@ -255,7 +271,7 @@ function BannerRow({ text }) {
|
|
|
255
271
|
const tail = splitAt >= 0 ? text.slice(splitAt) : '';
|
|
256
272
|
return (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.user, bold: true, children: head }), tail.length > 0 && _jsx(Text, { color: theme.subtle, children: tail })] }));
|
|
257
273
|
}
|
|
258
|
-
function MessageRow({ message, turnMeta, toolMeta, foldReasoning, }) {
|
|
274
|
+
function MessageRow({ message, turnMeta, toolMeta, advisorDecision, foldReasoning, }) {
|
|
259
275
|
switch (message.role) {
|
|
260
276
|
case 'system': {
|
|
261
277
|
// v2.x:ephemeral system message 是 UI 临时提示(slash 命令输出等),
|
|
@@ -292,10 +308,17 @@ function MessageRow({ message, turnMeta, toolMeta, foldReasoning, }) {
|
|
|
292
308
|
truncatedCharsHint = `...(${omitted} 字省略)`;
|
|
293
309
|
}
|
|
294
310
|
const reasoningLines = reasoningText.length > 0 ? reasoningText.split('\n') : [];
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
311
|
+
// 纯工具回合的 reasoning 已在 LiveArea 实时看过;落进 scrollback 只会把
|
|
312
|
+
// “工具 → 工具 → 工具”重新放大。最终回答仍保留原有 reasoning 展示。
|
|
313
|
+
const toolOnly = tcCount > 0 && answer.trim().length === 0;
|
|
314
|
+
const visibleReasoningLines = toolOnly
|
|
315
|
+
? []
|
|
316
|
+
: foldReasoning
|
|
317
|
+
? reasoningLines.slice(0, 2)
|
|
318
|
+
: reasoningLines;
|
|
319
|
+
const hiddenReasoningCount = toolOnly
|
|
320
|
+
? 0
|
|
321
|
+
: reasoningLines.length - visibleReasoningLines.length;
|
|
299
322
|
return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [visibleReasoningLines.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [visibleReasoningLines.map((line, i) => (_jsx(Text, { color: theme.subtle, dimColor: true, wrap: "end", children: i === 0 ? `${figures.thought} ${line}` : ` ${line}` }, `r-${i}`))), hiddenReasoningCount > 0 && (_jsx(Text, { color: theme.subtle, dimColor: true, children: ` ${figures.fold} ${hiddenReasoningCount} 行 reasoning 折叠(终端高度 < ${NARROW_TERMINAL_ROWS})` })), truncatedCharsHint.length > 0 && (_jsx(Text, { color: theme.subtle, dimColor: true, children: ` ${truncatedCharsHint}` }))] })), buildAssistantDisplayLines(answer).map((line, i) => {
|
|
300
323
|
if (line.kind === 'fence') {
|
|
301
324
|
return (_jsx(Text, { color: theme.subtle, dimColor: true, wrap: line.wrap, children: line.content }, `a-${i}`));
|
|
@@ -306,33 +329,53 @@ function MessageRow({ message, turnMeta, toolMeta, foldReasoning, }) {
|
|
|
306
329
|
return line.prefix === '⏺ ' ? (_jsxs(Box, { children: [_jsx(Text, { color: theme.anchor, bold: true, wrap: line.wrap, children: line.prefix }), _jsx(Text, { wrap: line.wrap, children: line.content.length > 0 ? line.content : ' ' })] }, `a-${i}`)) : (_jsx(Text, { wrap: line.wrap, children: `${line.prefix}${line.content}`.length > 0
|
|
307
330
|
? `${line.prefix}${line.content}`
|
|
308
331
|
: ' ' }, `a-${i}`));
|
|
309
|
-
}), tcCount > 0 && (_jsx(Text, { color: theme.warning, dimColor: true, wrap: "end", children:
|
|
310
|
-
.map((tc) => tc.function.name)
|
|
311
|
-
.join(', ')}` }))] }));
|
|
332
|
+
}), tcCount > 0 && (_jsx(Text, { color: theme.warning, dimColor: true, wrap: "end", children: `${figures.corner} 工作进展 · ${toolBatchSummary(message.tool_calls ?? [])}` }))] }));
|
|
312
333
|
}
|
|
313
334
|
case 'tool': {
|
|
314
335
|
const lines = message.content.split('\n');
|
|
315
336
|
// 顾问意见给更高的预览上限,并用默认亮色而非 dim 灰 —— 它是另一个模型说的话,
|
|
316
337
|
// 不该和 grep 输出一样被视觉降级(见 MAX_ADVISOR_PREVIEW_LINES)。
|
|
317
|
-
const
|
|
318
|
-
|
|
338
|
+
const advisorMeta = message.display_metadata?.kind === 'advisor_consultation'
|
|
339
|
+
? message.display_metadata
|
|
340
|
+
: null;
|
|
341
|
+
const decisionMeta = message.display_metadata?.kind === 'advisor_decision'
|
|
342
|
+
? message.display_metadata
|
|
343
|
+
: null;
|
|
344
|
+
const inferredToolName = toolMeta?.toolName
|
|
345
|
+
?? (advisorMeta ? 'Advisor' : null)
|
|
346
|
+
?? (decisionMeta ? 'AdvisorDecision' : null)
|
|
347
|
+
?? (message.display_metadata?.kind === 'result_manifest' ? 'PresentResult' : null)
|
|
348
|
+
?? (message.display_metadata?.kind === 'agent' ? 'Agent' : undefined);
|
|
349
|
+
const isAdvisor = inferredToolName === 'Advisor';
|
|
350
|
+
const isAdvisorDecision = inferredToolName === 'AdvisorDecision';
|
|
351
|
+
const visibility = toolHistoryVisibility(inferredToolName, message.content);
|
|
352
|
+
const previewCap = toolPreviewCap(inferredToolName);
|
|
319
353
|
const previewLines = lines.slice(0, previewCap);
|
|
320
354
|
const hidden = Math.max(0, lines.length - previewCap);
|
|
321
355
|
const shortId = message.tool_call_id.slice(-8);
|
|
322
356
|
// 头行升级:有 toolMeta(发起方反查命中)显示人话描述;Agent 子任务
|
|
323
357
|
// 再解析统计尾巴显示 ✓ N 轮 · M 次工具。无 meta(历史重载等)兜底旧格式。
|
|
324
|
-
const stats =
|
|
358
|
+
const stats = inferredToolName === 'Agent' ? agentResultStats(message.content) : null;
|
|
325
359
|
const statsTail = stats
|
|
326
360
|
? ` ${figures.ok} ${stats.turns} 轮 · ${stats.tools} 次工具${stats.failed > 0 ? `(${stats.failed} 次失败)` : ''}`
|
|
327
361
|
: '';
|
|
328
362
|
// 顾问头行单独成文并去掉 dim:friendlyToolDescription 没有 Advisor 分支,
|
|
329
363
|
// 走兜底会显示成一串参数预览,看不出这是「第二个模型的独立意见」。
|
|
330
364
|
const headText = isAdvisor
|
|
331
|
-
? `[顾问意见 · #${shortId}]`
|
|
332
|
-
:
|
|
333
|
-
? `[${
|
|
334
|
-
:
|
|
335
|
-
|
|
365
|
+
? `[顾问意见 · ${advisorMeta?.checkpoint ?? 'manual'} · #${shortId}]`
|
|
366
|
+
: isAdvisorDecision
|
|
367
|
+
? `[顾问意见处理 · ${decisionMeta?.decision ?? 'unknown'} · #${shortId}]`
|
|
368
|
+
: toolMeta
|
|
369
|
+
? `[${toolMeta.friendly} · #${shortId}]${statsTail}`
|
|
370
|
+
: `[tool result · #${shortId}]`;
|
|
371
|
+
if (visibility === 'hidden')
|
|
372
|
+
return null;
|
|
373
|
+
if (visibility === 'compact') {
|
|
374
|
+
return (_jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsx(Text, { color: theme.subtle, dimColor: true, wrap: "end", children: headText }) }));
|
|
375
|
+
}
|
|
376
|
+
return (_jsx(Box, { marginBottom: 1, paddingLeft: 2, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, ...(isAdvisor ? {} : { dimColor: true }), wrap: "end", children: headText }), advisorMeta && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, wrap: "end", children: advisorMeta.status === 'completed'
|
|
377
|
+
? `咨询 ${advisorMeta.consultationId} · 版本 ${advisorMeta.taskVersion}/${advisorMeta.workVersion}/${advisorMeta.evidenceVersion}`
|
|
378
|
+
: `咨询 ${advisorMeta.consultationId} 未完成,检查点已降级放行` }), advisorMeta.status === 'completed' && !advisorDecision && (_jsx(Text, { color: theme.subtle, wrap: "end", children: "\u7B49\u5F85\u4E3B Agent \u8BC4\u4F30" })), advisorDecision && (_jsx(Text, { color: theme.subtle, wrap: "end", children: `${advisorDecision.decision} · ${advisorDecision.rationale}` })), advisorDecision?.verificationPlan.map((item) => (_jsx(Text, { color: theme.subtle, wrap: "end", children: `验证:${item}` }, `advisor-card-verify-${item}`)))] })), decisionMeta && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.subtle, wrap: "end", children: `关联咨询 ${decisionMeta.consultationId} · ${decisionMeta.rationale}` }), decisionMeta.verificationPlan.map((item) => (_jsx(Text, { color: theme.subtle, wrap: "end", children: `验证:${item}` }, `advisor-verify-${item}`)))] })), previewLines.map((line, i) => (_jsx(Text, { ...(isAdvisor ? {} : { color: theme.subtle }), wrap: "end", children: line.length > 0 ? line : ' ' }, `p-${i}`))), hidden > 0 && (_jsx(Text, { color: theme.subtle, dimColor: true, children: `... ${figures.fold} 完整 ${lines.length} 行(输入 /show ${shortId} 查看)` }))] }) }));
|
|
336
379
|
}
|
|
337
380
|
}
|
|
338
381
|
}
|
package/src/ui/MessageList.tsx
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* v2 新增:
|
|
20
20
|
* - assistant 分支渲染 reasoning_content / reasoning(💭 dim gray);
|
|
21
21
|
* 窄终端(rows<28)折叠 2 行 + "▾ N 行 reasoning 折叠"
|
|
22
|
-
* -
|
|
23
|
-
*
|
|
22
|
+
* - 纯工具 assistant 每批只写一条「工作进展」并保留 /show 短 id;
|
|
23
|
+
* 成功的普通 tool result 不进入 scrollback,失败/顾问/Agent/交付仍保留
|
|
24
24
|
* - user 分支前插 turn 头横线 "────── Turn N · 14:32 · 8s · 6 tools ──────",
|
|
25
25
|
* turn 边界扫描结果由 useMemo 一次性算出,挂在 StaticItem 上
|
|
26
26
|
*
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* banner: 青色加粗 minimal-agent + 暗灰色 provider/快捷键提示
|
|
29
29
|
* user: 整条青色 + "> " 前缀(输入;前置 turn 横线,若 turnMeta 非空)
|
|
30
30
|
* assistant: reasoning 暗灰带 💭,content 绿色 ⏺ 锚点 + 默认亮色正文(输出),tool_calls 黄色
|
|
31
|
-
* tool:
|
|
31
|
+
* tool: 普通成功结果静默;高价值结果暗灰折叠,末尾提示用 /show 查看
|
|
32
32
|
* ============================================================
|
|
33
33
|
*/
|
|
34
34
|
|
|
@@ -37,11 +37,12 @@ import { Box, Static, Text } from 'ink';
|
|
|
37
37
|
|
|
38
38
|
import { friendlyToolDescription } from '../loop.js';
|
|
39
39
|
import { contentToDisplayText, contentToPlainText } from '../multimodal.js';
|
|
40
|
-
import type { Message } from '../types.js';
|
|
40
|
+
import type { AdvisorDecisionMetadata, Message } from '../types.js';
|
|
41
41
|
import { splitThinkBlocks } from '../utils/stripThink.js';
|
|
42
42
|
import { figures } from './figures.js';
|
|
43
43
|
import { type MdLineKind, renderMarkdownLines } from './markdown.js';
|
|
44
44
|
import { theme } from './theme.js';
|
|
45
|
+
import { toolBatchSummary, toolHistoryVisibility } from './toolProgress.js';
|
|
45
46
|
|
|
46
47
|
/**
|
|
47
48
|
* Turn 元信息:每个非中断 user message 是一个 turn 的起点。
|
|
@@ -69,6 +70,7 @@ type StaticItem =
|
|
|
69
70
|
turnMeta: TurnMeta | null;
|
|
70
71
|
/** tool 消息的发起方人话描述(buildToolCallIndex 反查);其余消息 null */
|
|
71
72
|
toolMeta: ToolCallMeta | null;
|
|
73
|
+
advisorDecision: AdvisorDecisionMetadata | null;
|
|
72
74
|
key: string;
|
|
73
75
|
};
|
|
74
76
|
|
|
@@ -163,6 +165,18 @@ export function buildToolCallIndex(history: Message[]): Map<string, ToolCallMeta
|
|
|
163
165
|
return map;
|
|
164
166
|
}
|
|
165
167
|
|
|
168
|
+
/** 按 consultationId 关联持久化决定,供历史重载时在顾问卡片下恢复展示。 */
|
|
169
|
+
export function buildAdvisorDecisionIndex(
|
|
170
|
+
history: Message[],
|
|
171
|
+
): Map<string, AdvisorDecisionMetadata> {
|
|
172
|
+
const decisions = new Map<string, AdvisorDecisionMetadata>();
|
|
173
|
+
for (const message of history) {
|
|
174
|
+
if (message.role !== 'tool' || message.display_metadata?.kind !== 'advisor_decision') continue;
|
|
175
|
+
decisions.set(message.display_metadata.consultationId, message.display_metadata);
|
|
176
|
+
}
|
|
177
|
+
return decisions;
|
|
178
|
+
}
|
|
179
|
+
|
|
166
180
|
/**
|
|
167
181
|
* 从 Agent 子任务报告的统计尾巴(agent.ts 固定格式
|
|
168
182
|
* 「(子任务「x」[type]:N 轮 · M 次工具调用,K 次失败)」)解析统计数。
|
|
@@ -296,6 +310,7 @@ export const MessageList = React.memo(function MessageList({
|
|
|
296
310
|
const items: StaticItem[] = React.useMemo(() => {
|
|
297
311
|
const turnMetas = summarizeTurn(history);
|
|
298
312
|
const toolIndex = buildToolCallIndex(history);
|
|
313
|
+
const advisorDecisions = buildAdvisorDecisionIndex(history);
|
|
299
314
|
return [
|
|
300
315
|
...(bannerText
|
|
301
316
|
? [
|
|
@@ -311,6 +326,10 @@ export const MessageList = React.memo(function MessageList({
|
|
|
311
326
|
msg: m,
|
|
312
327
|
turnMeta: turnMetas[idx],
|
|
313
328
|
toolMeta: m.role === 'tool' ? (toolIndex.get(m.tool_call_id) ?? null) : null,
|
|
329
|
+
advisorDecision: m.role === 'tool'
|
|
330
|
+
&& m.display_metadata?.kind === 'advisor_consultation'
|
|
331
|
+
? (advisorDecisions.get(m.display_metadata.consultationId) ?? null)
|
|
332
|
+
: null,
|
|
314
333
|
// 纯派生 key:有 id 用 id,没有就用 idx 兜底。绝不在 render 期 mutate 消息对象
|
|
315
334
|
// (<Static> 已 commit 的行永不重绘,key 仅在 append 对账时用,idx 已足够稳定)。
|
|
316
335
|
key: m.id ?? `message-${idx}`,
|
|
@@ -334,6 +353,7 @@ export const MessageList = React.memo(function MessageList({
|
|
|
334
353
|
message={item.msg}
|
|
335
354
|
turnMeta={item.turnMeta}
|
|
336
355
|
toolMeta={item.toolMeta}
|
|
356
|
+
advisorDecision={item.advisorDecision}
|
|
337
357
|
foldReasoning={foldReasoning}
|
|
338
358
|
/>
|
|
339
359
|
);
|
|
@@ -362,11 +382,13 @@ function MessageRow({
|
|
|
362
382
|
message,
|
|
363
383
|
turnMeta,
|
|
364
384
|
toolMeta,
|
|
385
|
+
advisorDecision,
|
|
365
386
|
foldReasoning,
|
|
366
387
|
}: {
|
|
367
388
|
message: Message;
|
|
368
389
|
turnMeta: TurnMeta | null;
|
|
369
390
|
toolMeta?: ToolCallMeta | null;
|
|
391
|
+
advisorDecision?: AdvisorDecisionMetadata | null;
|
|
370
392
|
foldReasoning: boolean;
|
|
371
393
|
}): JSX.Element | null {
|
|
372
394
|
switch (message.role) {
|
|
@@ -436,11 +458,17 @@ function MessageRow({
|
|
|
436
458
|
}
|
|
437
459
|
const reasoningLines =
|
|
438
460
|
reasoningText.length > 0 ? reasoningText.split('\n') : [];
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const
|
|
443
|
-
|
|
461
|
+
// 纯工具回合的 reasoning 已在 LiveArea 实时看过;落进 scrollback 只会把
|
|
462
|
+
// “工具 → 工具 → 工具”重新放大。最终回答仍保留原有 reasoning 展示。
|
|
463
|
+
const toolOnly = tcCount > 0 && answer.trim().length === 0;
|
|
464
|
+
const visibleReasoningLines = toolOnly
|
|
465
|
+
? []
|
|
466
|
+
: foldReasoning
|
|
467
|
+
? reasoningLines.slice(0, 2)
|
|
468
|
+
: reasoningLines;
|
|
469
|
+
const hiddenReasoningCount = toolOnly
|
|
470
|
+
? 0
|
|
471
|
+
: reasoningLines.length - visibleReasoningLines.length;
|
|
444
472
|
|
|
445
473
|
return (
|
|
446
474
|
<Box flexDirection="column" marginBottom={1}>
|
|
@@ -503,9 +531,7 @@ function MessageRow({
|
|
|
503
531
|
})}
|
|
504
532
|
{tcCount > 0 && (
|
|
505
533
|
<Text color={theme.warning} dimColor wrap="end">
|
|
506
|
-
{
|
|
507
|
-
.map((tc) => tc.function.name)
|
|
508
|
-
.join(', ')}`}
|
|
534
|
+
{`${figures.corner} 工作进展 · ${toolBatchSummary(message.tool_calls ?? [])}`}
|
|
509
535
|
</Text>
|
|
510
536
|
)}
|
|
511
537
|
</Box>
|
|
@@ -515,31 +541,90 @@ function MessageRow({
|
|
|
515
541
|
const lines = message.content.split('\n');
|
|
516
542
|
// 顾问意见给更高的预览上限,并用默认亮色而非 dim 灰 —— 它是另一个模型说的话,
|
|
517
543
|
// 不该和 grep 输出一样被视觉降级(见 MAX_ADVISOR_PREVIEW_LINES)。
|
|
518
|
-
const
|
|
519
|
-
|
|
544
|
+
const advisorMeta = message.display_metadata?.kind === 'advisor_consultation'
|
|
545
|
+
? message.display_metadata
|
|
546
|
+
: null;
|
|
547
|
+
const decisionMeta = message.display_metadata?.kind === 'advisor_decision'
|
|
548
|
+
? message.display_metadata
|
|
549
|
+
: null;
|
|
550
|
+
const inferredToolName = toolMeta?.toolName
|
|
551
|
+
?? (advisorMeta ? 'Advisor' : null)
|
|
552
|
+
?? (decisionMeta ? 'AdvisorDecision' : null)
|
|
553
|
+
?? (message.display_metadata?.kind === 'result_manifest' ? 'PresentResult' : null)
|
|
554
|
+
?? (message.display_metadata?.kind === 'agent' ? 'Agent' : undefined);
|
|
555
|
+
const isAdvisor = inferredToolName === 'Advisor';
|
|
556
|
+
const isAdvisorDecision = inferredToolName === 'AdvisorDecision';
|
|
557
|
+
const visibility = toolHistoryVisibility(inferredToolName, message.content);
|
|
558
|
+
const previewCap = toolPreviewCap(inferredToolName);
|
|
520
559
|
const previewLines = lines.slice(0, previewCap);
|
|
521
560
|
const hidden = Math.max(0, lines.length - previewCap);
|
|
522
561
|
const shortId = message.tool_call_id.slice(-8);
|
|
523
562
|
// 头行升级:有 toolMeta(发起方反查命中)显示人话描述;Agent 子任务
|
|
524
563
|
// 再解析统计尾巴显示 ✓ N 轮 · M 次工具。无 meta(历史重载等)兜底旧格式。
|
|
525
564
|
const stats =
|
|
526
|
-
|
|
565
|
+
inferredToolName === 'Agent' ? agentResultStats(message.content) : null;
|
|
527
566
|
const statsTail = stats
|
|
528
567
|
? ` ${figures.ok} ${stats.turns} 轮 · ${stats.tools} 次工具${stats.failed > 0 ? `(${stats.failed} 次失败)` : ''}`
|
|
529
568
|
: '';
|
|
530
569
|
// 顾问头行单独成文并去掉 dim:friendlyToolDescription 没有 Advisor 分支,
|
|
531
570
|
// 走兜底会显示成一串参数预览,看不出这是「第二个模型的独立意见」。
|
|
532
571
|
const headText = isAdvisor
|
|
533
|
-
? `[顾问意见 · #${shortId}]`
|
|
572
|
+
? `[顾问意见 · ${advisorMeta?.checkpoint ?? 'manual'} · #${shortId}]`
|
|
573
|
+
: isAdvisorDecision
|
|
574
|
+
? `[顾问意见处理 · ${decisionMeta?.decision ?? 'unknown'} · #${shortId}]`
|
|
534
575
|
: toolMeta
|
|
535
576
|
? `[${toolMeta.friendly} · #${shortId}]${statsTail}`
|
|
536
577
|
: `[tool result · #${shortId}]`;
|
|
578
|
+
if (visibility === 'hidden') return null;
|
|
579
|
+
if (visibility === 'compact') {
|
|
580
|
+
return (
|
|
581
|
+
<Box marginBottom={1} paddingLeft={2}>
|
|
582
|
+
<Text color={theme.subtle} dimColor wrap="end">
|
|
583
|
+
{headText}
|
|
584
|
+
</Text>
|
|
585
|
+
</Box>
|
|
586
|
+
);
|
|
587
|
+
}
|
|
537
588
|
return (
|
|
538
589
|
<Box marginBottom={1} paddingLeft={2}>
|
|
539
590
|
<Box flexDirection="column">
|
|
540
591
|
<Text color={theme.subtle} {...(isAdvisor ? {} : { dimColor: true })} wrap="end">
|
|
541
592
|
{headText}
|
|
542
593
|
</Text>
|
|
594
|
+
{advisorMeta && (
|
|
595
|
+
<Box flexDirection="column">
|
|
596
|
+
<Text color={theme.subtle} wrap="end">
|
|
597
|
+
{advisorMeta.status === 'completed'
|
|
598
|
+
? `咨询 ${advisorMeta.consultationId} · 版本 ${advisorMeta.taskVersion}/${advisorMeta.workVersion}/${advisorMeta.evidenceVersion}`
|
|
599
|
+
: `咨询 ${advisorMeta.consultationId} 未完成,检查点已降级放行`}
|
|
600
|
+
</Text>
|
|
601
|
+
{advisorMeta.status === 'completed' && !advisorDecision && (
|
|
602
|
+
<Text color={theme.subtle} wrap="end">等待主 Agent 评估</Text>
|
|
603
|
+
)}
|
|
604
|
+
{advisorDecision && (
|
|
605
|
+
<Text color={theme.subtle} wrap="end">
|
|
606
|
+
{`${advisorDecision.decision} · ${advisorDecision.rationale}`}
|
|
607
|
+
</Text>
|
|
608
|
+
)}
|
|
609
|
+
{advisorDecision?.verificationPlan.map((item) => (
|
|
610
|
+
<Text key={`advisor-card-verify-${item}`} color={theme.subtle} wrap="end">
|
|
611
|
+
{`验证:${item}`}
|
|
612
|
+
</Text>
|
|
613
|
+
))}
|
|
614
|
+
</Box>
|
|
615
|
+
)}
|
|
616
|
+
{decisionMeta && (
|
|
617
|
+
<Box flexDirection="column">
|
|
618
|
+
<Text color={theme.subtle} wrap="end">
|
|
619
|
+
{`关联咨询 ${decisionMeta.consultationId} · ${decisionMeta.rationale}`}
|
|
620
|
+
</Text>
|
|
621
|
+
{decisionMeta.verificationPlan.map((item) => (
|
|
622
|
+
<Text key={`advisor-verify-${item}`} color={theme.subtle} wrap="end">
|
|
623
|
+
{`验证:${item}`}
|
|
624
|
+
</Text>
|
|
625
|
+
))}
|
|
626
|
+
</Box>
|
|
627
|
+
)}
|
|
543
628
|
{/* 逐行 wrap='end':整段默认 wrap 会注入真实换行,从预览复制会被硬断行 */}
|
|
544
629
|
{previewLines.map((line, i) => (
|
|
545
630
|
<Text key={`p-${i}`} {...(isAdvisor ? {} : { color: theme.subtle })} wrap="end">
|
package/src/ui/ModelPicker.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
2
|
import { Box, Text, useInput } from 'ink';
|
|
3
|
+
import { useState } from 'react';
|
|
4
4
|
import { theme } from './theme.js';
|
|
5
5
|
export function ModelPicker({ models, currentModelId, title, nullOptionLabel, onSelect, onCancel, }) {
|
|
6
|
-
const enabledModels = models.filter((m) => m.enabled && m.apiKey);
|
|
6
|
+
const enabledModels = models.filter((m) => m.enabled && (m.source === 'gateway' || m.apiKey));
|
|
7
7
|
const hasNullOption = Boolean(nullOptionLabel);
|
|
8
8
|
const nullIndex = hasNullOption ? enabledModels.length : -1;
|
|
9
9
|
const listLength = enabledModels.length + (hasNullOption ? 1 : 0);
|
|
@@ -35,7 +35,10 @@ export function ModelPicker({ models, currentModelId, title, nullOptionLabel, on
|
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
37
|
const target = enabledModels[idx];
|
|
38
|
-
if (target
|
|
38
|
+
if (target &&
|
|
39
|
+
(target.source !== 'gateway' ||
|
|
40
|
+
!target.availability ||
|
|
41
|
+
target.availability.state === 'available'))
|
|
39
42
|
onSelect(target.id);
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -44,7 +47,7 @@ export function ModelPicker({ models, currentModelId, title, nullOptionLabel, on
|
|
|
44
47
|
const active = i === idx;
|
|
45
48
|
const isCurrent = m.id === currentModelId;
|
|
46
49
|
const displayName = m.displayName || m.model;
|
|
47
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: active ? theme.user : undefined, children: [active ? '> ' : ' ', isCurrent ? '✓ ' : ' ',
|
|
50
|
+
return (_jsxs(Box, { flexDirection: "column", children: [i > 0 && enabledModels[i - 1]?.source !== m.source ? (_jsxs(Text, { color: theme.subtle, children: [' ', "\u2500\u2500 ", m.source === 'gateway' ? '团队在线模型' : '本机模型', " \u2500\u2500"] })) : null, _jsxs(Text, { color: active ? theme.user : undefined, children: [active ? '> ' : ' ', isCurrent ? '✓ ' : ' ', _jsxs(Text, { color: active ? theme.user : undefined, bold: isCurrent, children: [m.source === 'gateway' ? '🌐 ' : '', displayName, m.isDefault ? ' · 默认' : '', m.availability?.reason ? ` · ${m.availability.reason}` : ''] }), isCurrent ? _jsx(Text, { color: theme.subtle, children: " \uFF08\u5F53\u524D\uFF09" }) : null] }), _jsxs(Text, { color: theme.subtle, children: [' ', m.model, " \u00B7 ", formatContextWindow(m.contextWindow)] })] }, m.id));
|
|
48
51
|
}), hasNullOption && (_jsxs(Text, { color: idx === nullIndex ? theme.user : theme.subtle, children: [idx === nullIndex ? '> ' : ' ', !currentModelId ? '✓ ' : ' ', nullOptionLabel] }))] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.subtle, children: "\u2191\u2193 \u9009\u62E9 \u00B7 Enter \u786E\u8BA4 \u00B7 ESC \u53D6\u6D88" }) })] }));
|
|
49
52
|
}
|
|
50
53
|
function formatContextWindow(tokens) {
|