mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
chore(compositions): mount bash-env and the pwsh tool in shipped and demo compositions
This commit is contained in:
@@ -154,6 +154,12 @@ 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.
|
||||
{ name: 'todo-write', hasModelTurn: true, recorded: true },
|
||||
{
|
||||
name: 'skill-load',
|
||||
|
||||
27
examples/acp-agent/tests/fixtures/bash/tool-pwsh/cordis.yml
vendored
Normal file
27
examples/acp-agent/tests/fixtures/bash/tool-pwsh/cordis.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Minimal tool-pwsh composition: real app boot path, real pwsh executor, real
|
||||
# foreground + background tool calls; driven by the package's loader.spec.ts.
|
||||
- id: system-prompt
|
||||
name: '@deepseek-ai/dsh-system-prompt'
|
||||
|
||||
- id: tools
|
||||
name: '@deepseek-ai/dsh-tools'
|
||||
|
||||
- id: subprocess
|
||||
name: '@deepseek-ai/dsh-subprocess-local'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-pwsh-local'
|
||||
config:
|
||||
graceMs: 200
|
||||
|
||||
- id: bash-env
|
||||
name: '@deepseek-ai/dsh-bash-env'
|
||||
|
||||
- id: tasks
|
||||
name: '@deepseek-ai/dsh-tasks-local'
|
||||
|
||||
- id: tool-tasks
|
||||
name: '@deepseek-ai/dsh-tool-tasks'
|
||||
|
||||
- id: tool-pwsh
|
||||
name: '@deepseek-ai/dsh-tool-pwsh'
|
||||
67
examples/acp-agent/tests/fixtures/bash/tool-pwsh/driver.ts
vendored
Normal file
67
examples/acp-agent/tests/fixtures/bash/tool-pwsh/driver.ts
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Test driver: boot the tool-pwsh Loader composition, execute one real
|
||||
* foreground and one real background pwsh command through the tool registry,
|
||||
* and persist the observed model-visible output to `./pwsh-loader-report.json`
|
||||
* for the package spec's inspect step.
|
||||
*/
|
||||
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import { boot, resolveConfigPath } from '@deepseek-ai/dsh-app-boot'
|
||||
import { CallId } from '@deepseek-ai/dsh-llm'
|
||||
|
||||
const configPath = process.argv[2]
|
||||
if (configPath === undefined) throw new Error('tool-pwsh driver requires a config path')
|
||||
|
||||
const ctx = await boot('tool-pwsh-loader-smoke', resolveConfigPath(configPath, undefined))
|
||||
try {
|
||||
const schema = ctx.tools.schemas().find(tool => tool.name === 'pwsh')
|
||||
if (schema === undefined) throw new Error('pwsh tool not registered by the composition')
|
||||
const prompt = (await ctx.systemPrompt.assemble()).sections.find(section => section.name === 'tool:pwsh')
|
||||
|
||||
const foreground = await ctx.tools.execute({
|
||||
signal: new AbortController().signal,
|
||||
callId: CallId('loader-fg'),
|
||||
name: 'pwsh',
|
||||
arguments: { command: 'Write-Output loader-ok', description: 'loader foreground' },
|
||||
})
|
||||
const foregroundText = foreground.content.filter(block => block.type === 'text').map(block => block.text).join('')
|
||||
|
||||
const background = await ctx.tools.execute({
|
||||
signal: new AbortController().signal,
|
||||
callId: CallId('loader-bg'),
|
||||
name: 'pwsh',
|
||||
arguments: {
|
||||
command: 'Start-Sleep -Milliseconds 200; Write-Output loader-bg-ok',
|
||||
description: 'loader background',
|
||||
run_in_background: true,
|
||||
},
|
||||
})
|
||||
const taskId = (background.value as { taskId: string }).taskId
|
||||
|
||||
// The output delta and the terminal status can land in separate reads
|
||||
// (Windows flushes the child pipe at exit), so accumulate both.
|
||||
let backgroundText = ''
|
||||
const deadline = Date.now() + 10_000
|
||||
while (Date.now() < deadline) {
|
||||
const read = await ctx.tools.execute({
|
||||
signal: new AbortController().signal,
|
||||
callId: CallId('loader-bg-read'),
|
||||
name: 'task_output',
|
||||
arguments: { task_id: taskId },
|
||||
})
|
||||
backgroundText += read.content.filter(block => block.type === 'text').map(block => block.text).join('')
|
||||
if (backgroundText.includes('loader-bg-ok') && backgroundText.includes('[status: completed')) break
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
}
|
||||
|
||||
await writeFile('./pwsh-loader-report.json', JSON.stringify({
|
||||
schemaHasRunInBackground: Object.hasOwn(schema.parameters.properties as object, 'run_in_background'),
|
||||
promptHasMarkerSection: prompt?.text.includes('Non-zero exits are reported as `[exit code: N]` markers') === true,
|
||||
// Normalize PowerShell's platform line endings (CRLF on Windows, LF elsewhere).
|
||||
foregroundText: foregroundText.replace(/\r\n/g, '\n'),
|
||||
backgroundText: backgroundText.replace(/\r\n/g, '\n'),
|
||||
}))
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
}
|
||||
37
examples/acp-agent/tests/pwsh.cordis.snapshot.yml
Normal file
37
examples/acp-agent/tests/pwsh.cordis.snapshot.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
# Minimal keyless composition: real app, pwsh executor, and pwsh tool; replayed model.
|
||||
- id: llm-replay
|
||||
name: '@deepseek-ai/dsh-llm-replay'
|
||||
config:
|
||||
providers:
|
||||
- id: deepseek-official
|
||||
name: DeepSeek
|
||||
models:
|
||||
- id: deepseek-v4-pro
|
||||
|
||||
- id: subprocess
|
||||
name: '@deepseek-ai/dsh-subprocess-local'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-pwsh-local'
|
||||
|
||||
- id: bash-env
|
||||
name: '@deepseek-ai/dsh-bash-env'
|
||||
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek-official
|
||||
model: deepseek-v4-pro
|
||||
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
|
||||
persistenceCompression: none
|
||||
workspaceContext: false
|
||||
skills:
|
||||
enabled: false
|
||||
toolTasks: false
|
||||
goals: false
|
||||
# The pwsh tool replaces the bundle's bash tool in this composition.
|
||||
toolBash: false
|
||||
persona: You are a concise snapshot agent working in {{cwd}}.
|
||||
|
||||
- id: tool-pwsh
|
||||
name: '@deepseek-ai/dsh-tool-pwsh'
|
||||
36
examples/acp-agent/tests/pwsh.cordis.yml
Normal file
36
examples/acp-agent/tests/pwsh.cordis.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Minimal live counterpart for the pwsh-tool-turn snapshot composition.
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
config:
|
||||
apiKey: !!js process.env.DEEPSEEK_API_KEY
|
||||
baseURL: !!js process.env.DEEPSEEK_BASE_URL
|
||||
models:
|
||||
- id: deepseek-v4-pro
|
||||
|
||||
- id: subprocess
|
||||
name: '@deepseek-ai/dsh-subprocess-local'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-pwsh-local'
|
||||
|
||||
- id: bash-env
|
||||
name: '@deepseek-ai/dsh-bash-env'
|
||||
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek-official
|
||||
model: deepseek-v4-pro
|
||||
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
|
||||
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
|
||||
workspaceContext: false
|
||||
skills:
|
||||
enabled: false
|
||||
toolTasks: false
|
||||
goals: false
|
||||
# The pwsh tool replaces the bundle's bash tool in this composition.
|
||||
toolBash: false
|
||||
persona: You are a concise snapshot agent working in {{cwd}}.
|
||||
|
||||
- id: tool-pwsh
|
||||
name: '@deepseek-ai/dsh-tool-pwsh'
|
||||
@@ -14,6 +14,7 @@
|
||||
"@deepseek-ai/dsh-agent-spine-demo": "workspace:*",
|
||||
"@deepseek-ai/dsh-app-boot": "workspace:*",
|
||||
"@deepseek-ai/dsh-bash": "workspace:*",
|
||||
"@deepseek-ai/dsh-bash-env": "workspace:*",
|
||||
"@deepseek-ai/dsh-bash-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-bash-sandbox": "workspace:*",
|
||||
"@deepseek-ai/dsh-cli-demo": "workspace:*",
|
||||
@@ -42,6 +43,7 @@
|
||||
"@deepseek-ai/dsh-plan-mode": "workspace:*",
|
||||
"@deepseek-ai/dsh-pty": "workspace:*",
|
||||
"@deepseek-ai/dsh-pty-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-pwsh-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-repeat-tool-guard": "workspace:*",
|
||||
"@deepseek-ai/dsh-repository-plugin": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-local": "workspace:*",
|
||||
@@ -81,6 +83,7 @@
|
||||
"@deepseek-ai/dsh-tool-goal": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-lsp": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-pty": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-pwsh": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-ralph": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-session-query": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-skill": "workspace:*",
|
||||
|
||||
Reference in New Issue
Block a user