test(acp): register and record the keyed pwsh-tool-turn snapshot scenario

This commit is contained in:
Huanqi Cao
2026-08-02 15:31:52 +08:00
parent 22c872097d
commit 64f9e68bd9
6 changed files with 98 additions and 6 deletions

View File

@@ -44,6 +44,7 @@ const SESSION_TITLE_CONFIG = fileURLToPath(new URL('../session-title.cordis.yml'
const LSP_CONFIG = fileURLToPath(new URL('./lsp.cordis.yml', import.meta.url))
const WEB_CONFIG = fileURLToPath(new URL('../web.cordis.yml', import.meta.url))
const FS_SEARCH_CONFIG = fileURLToPath(new URL('./fs-search.cordis.yml', import.meta.url))
const PWSH_CONFIG = fileURLToPath(new URL('./pwsh.cordis.yml', import.meta.url))
const SNAPSHOTS_DIR = join(dirname(fileURLToPath(import.meta.url)), 'snapshots')
const PACKED_CHUNKS_SOURCE = 'hook-cc-pretool-deny'
@@ -154,12 +155,17 @@ const SCENARIOS: Scenario[] = [
configPath: PTY_CONFIG,
},
{ name: 'bash-tool-turn', hasModelTurn: true, recorded: true },
// The pwsh-tool-turn scenario is NOT registered yet: its overlay
// (pwsh.cordis.yml / pwsh.cordis.snapshot.yml) swaps the bundle's bash tool
// for the PowerShell twin, so its header class needs its own prompt/tool
// sidecars and a recorded transcript. Both require a keyed environment
// (`test:snapshot:record`); the composition ships so the scenario can be
// registered and recorded in one keyed pass.
// The pwsh overlay (pwsh.cordis.yml / pwsh.cordis.snapshot.yml) swaps the
// bundle's bash tool for the PowerShell twin, so its header class pins its
// own prompt/tool sidecars and a recorded transcript.
{
name: 'pwsh-tool-turn',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
headerClass: 'pwsh',
configPath: PWSH_CONFIG,
},
{ name: 'todo-write', hasModelTurn: true, recorded: true },
{
name: 'skill-load',

View File

@@ -0,0 +1,7 @@
{
"steps": [
{ "op": "initialize" },
{ "op": "newSession" },
{ "op": "prompt", "text": "Use the pwsh tool to run exactly: Write-Output PWSH_OK. Then reply with the single word DONE and stop." }
]
}

View File

@@ -0,0 +1,32 @@
{"type":"session","version":0,"id":"1ec0d099-552b-44e1-8fb8-fd9742fbdc1c","createdAt":1785655505943,"cwd":"{{cwd}}","delegationDepth":0}
{"type":"turn/start","seq":0,"time":1785655505948,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
{"type":"user/message","seq":1,"time":1785655505948,"data":{"content":[{"type":"text","text":"Use the pwsh tool to run exactly: Write-Output PWSH_OK. Then reply with the single word DONE and stop."}],"source":{"kind":"user"},"role":"user","id":"e3bca81a-d4e4-46fb-aa30-916f785c27a0"},"surfaceOp":"append"}
{"type":"session/title","seq":2,"time":1785655505949,"data":{"title":"Use the pwsh tool to","messageSeqs":[1],"source":{"kind":"fallback"}}}
{"type":"step/start","seq":3,"time":1785655505971,"data":{"turn":1,"step":1}}
{"type":"request/header","seq":4,"time":1785655505972,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-pro"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":5,"time":1785655505972,"data":{"provider":"deepseek-official","model":"deepseek-v4-pro"}}
{"type":"assistant/chunk","seq":6,"time":1785655506674,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
{"type":"reasoning-chunks","seq0":7,"time0":1785655506674,"data":{"turn":1,"step":1,"index":0,"dt":[157,27,1,0,0,0,38,0,0,43,0,0,0,50,0,1,0,0,0,36,0,1,0,0],"texts":["The"," user"," wants"," me"," to"," run"," a"," PowerShell"," command"," that"," outputs"," \"","P","WS","H","_OK","\""," and"," then"," reply"," with"," \"","D","ONE","\"."]}}
{"type":"assistant/chunk","seq":32,"time":1785655507160,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
{"type":"tool-call-chunks","seq0":33,"time0":1785655507161,"data":{"turn":1,"step":1,"index":1,"dt":[51,0,0,0,0,32,0,0,0,55,1,0,0,0,74,0,0,0,1,45,0,42,0,0,0,0,54,0],"id":"call_00_oEhmLGLNsvlumiE0WkXD0511","name":"pwsh","args":["","{","\"","command","\"",": ","\"","Write","-","Output"," P","WS","H","_OK","\"",", ","\"","description","\"",": ","\"","Output"," P","WS","H","_OK"," string","\"","}"]}}
{"type":"assistant/chunk","seq":62,"time":1785655507601,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to run a PowerShell command that outputs \"PWSH_OK\" and then reply with \"DONE\"."}}}}
{"type":"assistant/chunk","seq":63,"time":1785655507602,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_oEhmLGLNsvlumiE0WkXD0511","name":"pwsh","arguments":"{\"command\": \"Write-Output PWSH_OK\", \"description\": \"Output PWSH_OK string\"}"}}}}
{"type":"assistant/chunk","seq":64,"time":1785655507602,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":816,"outputTokens":96,"cacheReadTokens":0,"reasoningTokens":25}}}}
{"type":"assistant/chunk","seq":65,"time":1785655507602,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":66,"time":1785655507604,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run a PowerShell command that outputs \"PWSH_OK\" and then reply with \"DONE\"."},{"type":"tool-call","id":"call_00_oEhmLGLNsvlumiE0WkXD0511","name":"pwsh","arguments":"{\"command\": \"Write-Output PWSH_OK\", \"description\": \"Output PWSH_OK string\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-pro"},"id":"4d81cc10-507e-49a8-96f4-aa3ae5ad2eb5"},"usage":{"inputTokens":816,"outputTokens":96,"cacheReadTokens":0,"reasoningTokens":25}},"sourceEventSeqs":[6,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],"surfaceOp":"append"}
{"type":"tool/call","seq":67,"time":1785655507605,"data":{"turn":1,"step":1,"callId":"call_00_oEhmLGLNsvlumiE0WkXD0511","name":"pwsh","arguments":"{\"command\": \"Write-Output PWSH_OK\", \"description\": \"Output PWSH_OK string\"}"}}
{"type":"tool/result","seq":68,"time":1785655507994,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_oEhmLGLNsvlumiE0WkXD0511"},"content":[{"type":"tool-result","toolCallId":"call_00_oEhmLGLNsvlumiE0WkXD0511","content":[{"type":"text","text":"PWSH_OK\r\n"}],"isError":false}],"role":"user","id":"84a96d55-5bd5-46fc-ab0d-918882c504e2"}},"sourceEventSeqs":[67],"surfaceOp":"append"}
{"type":"step/end","seq":69,"time":1785655507994,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":70,"time":1785655508000,"data":{"turn":1,"step":2}}
{"type":"assistant/chunk","seq":71,"time":1785655508608,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
{"type":"reasoning-chunks","seq0":72,"time0":1785655508608,"data":{"turn":1,"step":2,"index":0,"dt":[168,38,0,60,1,0,0,0,0,27,1,0,0,0,46,0,0,0,0,0,41],"texts":["The"," command"," successfully"," output"," \"","P","WS","H","_OK","\"."," Now"," I"," should"," reply"," with"," \"","D","ONE","\""," as"," instructed","."]}}
{"type":"assistant/chunk","seq":94,"time":1785655508990,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
{"type":"assistant/chunk","seq":95,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"D"}}}
{"type":"assistant/chunk","seq":96,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"ONE"}}}
{"type":"assistant/chunk","seq":97,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The command successfully output \"PWSH_OK\". Now I should reply with \"DONE\" as instructed."}}}}
{"type":"assistant/chunk","seq":98,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"DONE"}}}}
{"type":"assistant/chunk","seq":99,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":34,"outputTokens":25,"cacheReadTokens":896,"reasoningTokens":22}}}}
{"type":"assistant/chunk","seq":100,"time":1785655508991,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"assistant/message","seq":101,"time":1785655508991,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The command successfully output \"PWSH_OK\". Now I should reply with \"DONE\" as instructed."},{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-pro"},"id":"d8905016-347c-477a-a8f7-2b31839a8357"},"usage":{"inputTokens":34,"outputTokens":25,"cacheReadTokens":896,"reasoningTokens":22}},"sourceEventSeqs":[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],"surfaceOp":"append"}
{"type":"step/end","seq":102,"time":1785655508992,"data":{"turn":1,"step":2}}
{"type":"turn/end","seq":103,"time":1785655508992,"data":{"turn":1,"reason":{"kind":"completed"}}}

View File

@@ -0,0 +1,4 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"DONE"}}}}
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}

View File

@@ -0,0 +1,5 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are a concise snapshot agent working in {{cwd}}.
Non-zero exits are reported as `[exit code: N]` markers; investigate failures before moving on. On Windows a killed process settles as `[exit code: 1]` without a signal marker; treat a bare exit 1 after an interruption as a termination, not a command failure.

View File

@@ -0,0 +1,38 @@
{
"initial": [
{
"name": "pwsh",
"description": "Execute a PowerShell command (`pwsh -Command`) and return its stdout/stderr. Each call runs in a fresh pwsh process: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Paths use native Windows form (`C:\\...`); read environment variables with `$env:NAME`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$env:DSH_*` variables; inspect them when needed. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. On Windows a force-killed command settles as `[exit code: 1]` without a signal marker — treat it as an interruption, not a command failure. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.",
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The PowerShell command to execute."
},
"description": {
"type": "string",
"description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"Get-Process\" → \"List running processes\"."
},
"timeoutMs": {
"type": "number",
"description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."
},
"workdir": {
"type": "string",
"description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."
},
"run_in_background": {
"type": "boolean",
"description": "Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."
}
},
"required": [
"command",
"description"
]
}
}
],
"changes": []
}