feat(bash): shell tools reject a mismatched executor dialect at load
The seam gains ShellDialect ('bash' | 'powershell' - concrete shells, not
families: zsh or fish would be their own values, never 'bash'); bash-local
declares bash (bash-sandbox inherits), pwsh-local declares powershell, and
both tools throw at load when the mounted executor speaks another dialect -
previously tool-pwsh over bash-local handed PowerShell text to bash -c and
the deployment error surfaced as ordinary nonzero exits. Pinned by mismatch
tests on both tools; the parity note records the contract (both languages).
Also from the review round: the tool-bash README's managed-environment
section becomes a summary linking the owning dsh-bash-env contract (the
duplicated prose carried a stale owner in its example import), the
pwshOnly JSDoc drops the stale 'on PATH' phrasing, and the task-tools
contract comment in the two pwsh compositions is indented into its block.
This commit is contained in:
@@ -23,7 +23,7 @@ import AgentRegistry from '@deepseek-ai/dsh-agent'
|
||||
import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
import { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import { BashExecutor } from '@deepseek-ai/dsh-bash'
|
||||
import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult } from '@deepseek-ai/dsh-bash'
|
||||
import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult, ShellDialect } from '@deepseek-ai/dsh-bash'
|
||||
import * as ToolPwsh from '@deepseek-ai/dsh-tool-pwsh'
|
||||
import * as BashEnvPlugin from '@deepseek-ai/dsh-bash-env'
|
||||
import type { BashProcessRead } from '@deepseek-ai/dsh-bash'
|
||||
@@ -38,6 +38,8 @@ const testToolSignal = new AbortController().signal
|
||||
* handle.
|
||||
*/
|
||||
class FakeBash extends BashExecutor {
|
||||
readonly dialect: ShellDialect = 'powershell'
|
||||
|
||||
requests: BashExecRequest[] = []
|
||||
specs: BashExecSpec[] = []
|
||||
startCalls = 0
|
||||
@@ -199,6 +201,19 @@ async function callUntilText(
|
||||
}
|
||||
|
||||
describe('registration', () => {
|
||||
it('rejects an executor speaking another shell dialect at load', async () => {
|
||||
class BashDialectExecutor extends FakeBash {
|
||||
override readonly dialect = 'bash' as const
|
||||
}
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SystemPrompt)
|
||||
await ctx.plugin(ToolRegistry)
|
||||
await ctx.plugin(AgentRegistry)
|
||||
await ctx.plugin(BashEnvPlugin)
|
||||
await ctx.plugin(BashDialectExecutor)
|
||||
await expect(ctx.plugin(ToolPwsh)).rejects.toThrow("the mounted executor speaks 'bash', not powershell")
|
||||
})
|
||||
|
||||
it('registers the pwsh tool with its prompt section and schema', async () => {
|
||||
const { ctx } = await setup()
|
||||
const schema = ctx.tools.schemas().find(s => s.name === 'pwsh')
|
||||
|
||||
Reference in New Issue
Block a user