feat(tui): add session controls and compact views
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":9,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_spill","name":"bash","arguments":"{\"command\":\"node -e \\\"process.stdout.write('SPILL_START-' + 'x'.repeat(2000) + '-SPILL_END')\\\"\",\"description\":\"Print large deterministic output\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[4,5,6,7,8],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":10,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","name":"bash","arguments":"{\"command\":\"node -e \\\"process.stdout.write('SPILL_START-' + 'x'.repeat(2000) + '-SPILL_END')\\\"\",\"description\":\"Print large deterministic output\"}"}}
|
||||
{"type":"tool/result","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","content":[{"type":"text","text":"SPILL_START-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-SPILL_END\n\n(Omitted 1417 bytes. Full formatted result stored at: /tmp/dsh-acp-snapshot-spill/session-2ef0a5f14624/b5e2b8c5e6a6-bash.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[10],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","content":[{"type":"text","text":"SPILL_START-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-SPILL_END\n\n(Omitted 1417 bytes. Full formatted result stored at: /tmp/dsh-acp-snapshot-spill/session-766ddb6deb99/b7b4bdfcf7aa-bash.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[10],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":12,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":13,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
|
||||
@@ -131,8 +131,8 @@
|
||||
{"type":"assistant/chunk","seq":129,"time":1783962245385,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":130,"time":1783962245385,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a command with sandbox_permissions set to danger-full-access, no prior run needed, justified as instructed."},{"type":"tool-call","id":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1501,"outputTokens":174,"cacheReadTokens":0,"reasoningTokens":28}},"sourceEventSeqs":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":131,"time":1783962245385,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
|
||||
{"type":"approval/asked","seq":132,"time":1783962245386,"data":{"id":"e2d45b4a-ff48-488d-aeb6-8edc9dc5c3de","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":133,"time":1783962245387,"data":{"id":"e2d45b4a-ff48-488d-aeb6-8edc9dc5c3de","outcome":"allowed-once"}}
|
||||
{"type":"approval/asked","seq":132,"time":1783962245386,"data":{"id":"69daf6e5-d7a8-442c-a624-9172517cba58","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":133,"time":1783962245387,"data":{"id":"69daf6e5-d7a8-442c-a624-9172517cba58","outcome":"allowed-once"}}
|
||||
{"type":"tool/result","seq":134,"time":1783962245399,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","content":[{"type":"text","text":"escalated\n"}],"isError":false},"sourceEventSeqs":[131],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":135,"time":1783962245400,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":136,"time":1783962245400,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -155,8 +155,8 @@
|
||||
{"type":"assistant/chunk","seq":153,"time":1783962246274,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":154,"time":1783962246274,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a specific command with `sandbox_permissions` set to `danger-full-access` and a specific justification. They explicitly said NOT to run it without sandbox_permissions first. Let me do exactly that."},{"type":"tool-call","id":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1509,"outputTokens":198,"cacheReadTokens":0,"reasoningTokens":48}},"sourceEventSeqs":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":155,"time":1783962246274,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
|
||||
{"type":"approval/asked","seq":156,"time":1783962246275,"data":{"id":"46c8dba4-52c9-4a6a-b6a6-5f34c95c28df","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":157,"time":1783962246275,"data":{"id":"46c8dba4-52c9-4a6a-b6a6-5f34c95c28df","outcome":"rejected"}}
|
||||
{"type":"approval/asked","seq":156,"time":1783962246275,"data":{"id":"78869d2f-1a83-4672-8a66-2a75d1ffe49f","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":157,"time":1783962246275,"data":{"id":"78869d2f-1a83-4672-8a66-2a75d1ffe49f","outcome":"rejected"}}
|
||||
{"type":"tool/result","seq":158,"time":1783962246275,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","content":[{"type":"text","text":"Error: the user rejected escalating this command to \"danger-full-access\""}],"isError":true},"sourceEventSeqs":[155],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":159,"time":1783962246276,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":160,"time":1783962246276,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -89,8 +89,8 @@
|
||||
{"type":"assistant/chunk","seq":87,"time":1784045703776,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":88,"time":1784045703780,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to create a file using the write tool with sandbox_permissions. Let me do that."},{"type":"tool-call","id":"call_00_Fnymmavpr4klMDy4Fdej3227","name":"write","arguments":"{\"file_path\": \"escalated.md\", \"content\": \"escalated\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to escalate this write\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3871,"outputTokens":132,"cacheReadTokens":0,"reasoningTokens":23}},"sourceEventSeqs":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":89,"time":1784045703780,"data":{"turn":1,"step":1,"callId":"call_00_Fnymmavpr4klMDy4Fdej3227","name":"write","arguments":"{\"file_path\": \"escalated.md\", \"content\": \"escalated\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to escalate this write\"}"}}
|
||||
{"type":"approval/asked","seq":90,"time":1784045703782,"data":{"id":"c37500b3-c252-4a9b-ad0d-9c4349419b30","toolName":"write","callId":"call_00_Fnymmavpr4klMDy4Fdej3227","reason":"escalate sandbox to danger-full-access: the user asked to escalate this write"}}
|
||||
{"type":"approval/decided","seq":91,"time":1784045703786,"data":{"id":"c37500b3-c252-4a9b-ad0d-9c4349419b30","outcome":"allowed-once"}}
|
||||
{"type":"approval/asked","seq":90,"time":1784045703782,"data":{"id":"50a67945-0145-4850-93bf-3552f2550b47","toolName":"write","callId":"call_00_Fnymmavpr4klMDy4Fdej3227","reason":"escalate sandbox to danger-full-access: the user asked to escalate this write"}}
|
||||
{"type":"approval/decided","seq":91,"time":1784045703786,"data":{"id":"50a67945-0145-4850-93bf-3552f2550b47","outcome":"allowed-once"}}
|
||||
{"type":"tool/result","seq":92,"time":1784045703798,"data":{"turn":1,"step":1,"callId":"call_00_Fnymmavpr4klMDy4Fdej3227","content":[{"type":"text","text":"<path>/var/folders/2g/b32ct0qn1d728l_v6tdkjytr0000gn/T/acp-snap-cwd-vmEGzd/escalated.md</path>\n<type>file</type>\n<content>\nCreated file\n</content>"}],"isError":false},"sourceEventSeqs":[89],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":93,"time":1784045703798,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":94,"time":1784045703799,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
{"type":"tool/call","seq":53,"time":1783352172557,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO\"}"}}
|
||||
{"type":"hook/invoked","seq":54,"time":1783352172558,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
|
||||
{"type":"hook/result","seq":55,"time":1783352172573,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"ask","exitCode":0,"durationMs":14.113374999999905}}
|
||||
{"type":"approval/asked","seq":56,"time":1783962235813,"data":{"id":"68f1e09d-f3e5-4e39-8a51-da082ba3ba99","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
|
||||
{"type":"approval/decided","seq":57,"time":1783962235813,"data":{"id":"68f1e09d-f3e5-4e39-8a51-da082ba3ba99","outcome":"rejected"}}
|
||||
{"type":"approval/asked","seq":56,"time":1783962235813,"data":{"id":"0ff46a23-8e38-46cd-9b1a-99bf363032a4","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
|
||||
{"type":"approval/decided","seq":57,"time":1783962235813,"data":{"id":"0ff46a23-8e38-46cd-9b1a-99bf363032a4","outcome":"rejected"}}
|
||||
{"type":"tool/result","seq":58,"time":1783962235814,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","content":[{"type":"text","text":"Error: the user rejected tool \"bash\""}],"isError":true},"sourceEventSeqs":[53],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":59,"time":1783962235814,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":60,"time":1783962235814,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -20,6 +20,8 @@ flowchart LR
|
||||
cfg --> plugin_cordis_web
|
||||
plugin_cordis_web_fetch_local["web-fetch-local<br/>@deepseek-ai/dsh-web-fetch-local"]
|
||||
cfg --> plugin_cordis_web_fetch_local
|
||||
plugin_cordis_token_meter["token-meter<br/>@deepseek-ai/dsh-token-meter"]
|
||||
cfg --> plugin_cordis_token_meter
|
||||
plugin_cordis_tui_agent["tui-agent<br/>@deepseek-ai/dsh-tui-demo"]
|
||||
cfg --> plugin_cordis_tui_agent
|
||||
plugin_cordis_tui_agent --> bundle_agent_core["@deepseek-ai/dsh-agent-spine-demo"]
|
||||
@@ -41,6 +43,7 @@ flowchart LR
|
||||
| `fs-local` | `@deepseek-ai/dsh-fs-local` |
|
||||
| `web` | `@deepseek-ai/dsh-web` |
|
||||
| `web-fetch-local` | `@deepseek-ai/dsh-web-fetch-local` |
|
||||
| `token-meter` | `@deepseek-ai/dsh-token-meter` |
|
||||
| `tui-agent` | `@deepseek-ai/dsh-tui-demo` |
|
||||
| `tool-cordis` | `@deepseek-ai/dsh-tool-cordis` |
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
- id: web-fetch-local
|
||||
name: '@deepseek-ai/dsh-web-fetch-local'
|
||||
|
||||
- id: token-meter
|
||||
name: '@deepseek-ai/dsh-token-meter'
|
||||
|
||||
# The app bundle pre-creates the self-referential demo's `main` agent.
|
||||
- id: tui-agent
|
||||
name: '@deepseek-ai/dsh-tui-demo'
|
||||
|
||||
@@ -10,7 +10,7 @@ pnpm run demo:tui
|
||||
|
||||
The command needs `DEEPSEEK_API_KEY` in the environment or gitignored repository-root `.env`. Set `RESUME_SESSION_ID` to reopen a persisted conversation under `./.sessions`.
|
||||
|
||||
The TUI renders Markdown history, reasoning, tool-owned terminal/diff/generic cards, token totals, and the latest todo list. Enter submits or steers while the agent runs; Ctrl+O expands cards, Ctrl+R toggles reasoning, Escape cancels, and `/help` lists commands. `ask_user_question` opens a keyboard-driven overlay.
|
||||
The TUI renders Markdown history, reasoning, tool-owned terminal/diff/generic cards, token totals, and the latest todo list. Long tool bodies keep a head/tail preview; Ctrl+O expands or collapses every card. Enter submits or steers while the agent runs, Ctrl+R toggles reasoning, Escape cancels, and `/help` lists commands. `/model` opens a keyboard selector for the current provider catalog; use Up/Down and Enter, or `/model <model>` and `/model <provider>/<model>` for direct selection. `ask_user_question` opens a wide bottom-left keyboard panel with batch progress and numbered options.
|
||||
|
||||
Run `pnpm run demo:code-mode tui` for the Code Mode overlay.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
welcome: 'TUI Code Mode ready. Give it a multi-tool task.'
|
||||
ui:
|
||||
showReasoning: true
|
||||
maxToolOutputLines: 12
|
||||
maxToolOutputLines: 6
|
||||
persona: |
|
||||
You are a coding agent powered by the {{model}} model.
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
welcome: 'TUI agent ready. Give it a coding task.'
|
||||
ui:
|
||||
showReasoning: true
|
||||
maxToolOutputLines: 12
|
||||
maxToolOutputLines: 6
|
||||
persona: |
|
||||
You are a coding agent powered by the {{model}} model.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Context } from 'cordis'
|
||||
import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
|
||||
import type { GenerateOptions, LlmModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm'
|
||||
import { CallId, LlmAdapter } from '@deepseek-ai/dsh-llm'
|
||||
|
||||
const CONTROL_PROBE = '\u001b]2;MODEL_CONTROLLED\u0007\u001b[999CMODEL_CURSOR\u009b31mMODEL_C1'
|
||||
@@ -18,7 +18,17 @@ function textChunks(text: string): StreamChunk[] {
|
||||
|
||||
/** Keyless two-step adapter for the real-PTY TUI conversation test. */
|
||||
class ScriptedTuiAdapter extends LlmAdapter {
|
||||
async * stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
|
||||
override listModels(provider: string): Promise<readonly LlmModelInfo[]> {
|
||||
return Promise.resolve([
|
||||
{ provider, id: 'tui-scripted-model', name: 'Scripted Base' },
|
||||
{ provider, id: 'tui-scripted-model-pro', name: 'Scripted Pro' },
|
||||
])
|
||||
}
|
||||
|
||||
override async * stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
|
||||
if (options.model !== 'tui-scripted-model-pro' || !options.system?.includes('tui-scripted-model-pro')) {
|
||||
throw new Error('the scripted TUI request did not apply the selected model to routing and prompt variables')
|
||||
}
|
||||
const hasToolResult = options.messages.at(-1)?.content.some(block => block.type === 'tool-result') ?? false
|
||||
if (hasToolResult) {
|
||||
for (const chunk of textChunks(FINAL_TEXT)) yield chunk
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
config:
|
||||
cwd: !!js process.cwd()
|
||||
|
||||
- id: token-meter
|
||||
name: '@deepseek-ai/dsh-token-meter'
|
||||
|
||||
- id: tui-agent
|
||||
name: '@deepseek-ai/dsh-tui-demo'
|
||||
config:
|
||||
@@ -21,5 +24,6 @@
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
welcome: 'scripted TUI ready.'
|
||||
persona: 'Scripted model {{model}}.'
|
||||
ui:
|
||||
showReasoning: true
|
||||
|
||||
@@ -67,7 +67,7 @@ buffer
|
||||
style 1-1 inverse
|
||||
28| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
29| "/workspace/project ↑3.0k ↓115 idle reasoning:on tools:compact"
|
||||
style 0-58 dim
|
||||
style 67-99 dim
|
||||
29| "/tmp/dsh-tui-snapshot-bash-te ↑3.0k ↓115 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-28 dim
|
||||
style 42-99 dim
|
||||
30-35| <blank>
|
||||
|
||||
@@ -73,7 +73,7 @@ buffer
|
||||
style 1-1 inverse
|
||||
30| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
31| "/workspace/project ↑3.1k ↓158 idle reasoning:on tools:compact"
|
||||
style 0-49 dim
|
||||
style 67-99 dim
|
||||
31| "/tmp/dsh-tui-snapshot-code-mo ↑3.1k ↓158 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-28 dim
|
||||
style 42-99 dim
|
||||
32-35| <blank>
|
||||
|
||||
@@ -111,6 +111,6 @@ buffer
|
||||
style 1-1 inverse
|
||||
48| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
49| "/workspace/project ↑18 ↓18 idle reasoning:on tools:compact"
|
||||
style 0-61 dim
|
||||
style 67-99 dim
|
||||
49| "/tmp/dsh-tui-snapshot-cordis-dyn ↑18 ↓18 7% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-31 dim
|
||||
style 42-99 dim
|
||||
|
||||
@@ -101,6 +101,6 @@ buffer
|
||||
style 1-1 inverse
|
||||
45| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
46| "/workspace/project ↑3.5k ↓227 idle reasoning:on tools:compact"
|
||||
style 0-56 dim
|
||||
style 67-99 dim
|
||||
46| "/tmp/dsh-tui-snapshot-dynamic ↑3.5k ↓227 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-28 dim
|
||||
style 42-99 dim
|
||||
|
||||
@@ -64,7 +64,7 @@ buffer
|
||||
style 1-1 inverse
|
||||
29| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
30| "/workspace/project ↑2.9k ↓41 idle reasoning:on tools:compact"
|
||||
style 0-62 dim
|
||||
style 67-99 dim
|
||||
30| "/tmp/dsh-tui-snapshot-multi-tu ↑2.9k ↓41 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-29 dim
|
||||
style 42-99 dim
|
||||
31-35| <blank>
|
||||
|
||||
@@ -86,6 +86,6 @@ buffer
|
||||
style 1-1 inverse
|
||||
37| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
38| "/workspace/project ↑20 ↓6 idle reasoning:on tools:compact"
|
||||
style 0-55 dim
|
||||
style 67-99 dim
|
||||
38| "/tmp/dsh-tui-snapshot-parallel-fi ↑20 ↓6 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-32 dim
|
||||
style 42-99 dim
|
||||
|
||||
@@ -76,6 +76,6 @@ buffer
|
||||
style 1-1 inverse
|
||||
34| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
35| "/workspace/project ↑3.1k ↓145 idle reasoning:on tools:compact"
|
||||
style 0-49 dim
|
||||
style 67-99 dim
|
||||
35| "/tmp/dsh-tui-snapshot-todo-pl ↑3.1k ↓145 3% context tools:compact deepseek-v4-flash(reasoning:on)"
|
||||
style 0-28 dim
|
||||
style 42-99 dim
|
||||
|
||||
@@ -25,7 +25,7 @@ describe.skipIf(process.platform === 'win32')('tui-agent keyless smoke (real Loa
|
||||
expect(output).toContain('\u001B[?2004l')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
it('streams a response, answers a user-question dialog, completes the tool round-trip, and exits cleanly', async () => {
|
||||
it('switches models, streams a response, answers a user-question dialog, and exits cleanly', async () => {
|
||||
const output = await runTuiPtySmoke({
|
||||
label: 'tui-agent conversation',
|
||||
tempDirPrefix: 'tui-agent-conversation-',
|
||||
@@ -33,7 +33,9 @@ describe.skipIf(process.platform === 'win32')('tui-agent keyless smoke (real Loa
|
||||
configPath: scriptedConfigPath,
|
||||
tsconfigPath,
|
||||
actions: [
|
||||
{ waitFor: 'scripted TUI ready.', send: 'exercise the TUI\r' },
|
||||
{ waitFor: 'scripted TUI ready.', send: '/model\r' },
|
||||
{ waitFor: 'Select model', send: '\x1b[B\r' },
|
||||
{ waitFor: 'Model selected: tui-scripted/tui-scripted-model-pro.', send: 'exercise the TUI\r' },
|
||||
{ waitFor: 'How should the scripted run proceed?', send: '\r' },
|
||||
{ waitFor: 'Decision received. Scripted TUI run complete.', send: '/exit\r' },
|
||||
],
|
||||
|
||||
@@ -14,6 +14,7 @@ import * as FsPolicy from '@deepseek-ai/dsh-fs-policy'
|
||||
import * as ToolFs from '@deepseek-ai/dsh-tool-fs'
|
||||
import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek'
|
||||
import { installLlmReplay, parseSessionLog } from '@deepseek-ai/dsh-llm-replay'
|
||||
import TokenMeterService from '@deepseek-ai/dsh-token-meter'
|
||||
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
import { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import SubagentService from '@deepseek-ai/dsh-subagent'
|
||||
@@ -168,6 +169,7 @@ async function mountScenarioContext(
|
||||
tools: { mode: scenario.composition === 'code' ? 'code' : scenario.composition === 'advanced' ? 'both' : 'native' },
|
||||
skills: { local: { agentsHome: join(cwd, '.agents') } },
|
||||
})
|
||||
await ctx.plugin(TokenMeterService)
|
||||
await ctx.plugin(LocalBashExecutor, { cwd, timeoutMs: 30_000 })
|
||||
await ctx.plugin(LocalFileSystem, { cwd: '/' })
|
||||
await ctx.plugin(FsPolicy)
|
||||
|
||||
Reference in New Issue
Block a user