This commit is contained in:
@@ -220,6 +220,8 @@ test('agent-tui embeds operating contract appendix', async (t) => {
|
||||
t.ok(TUI.includes('verification_hints'))
|
||||
t.ok(TUI.includes('NEVER ASK'))
|
||||
t.ok(TUI.includes('YOU RUN THE TOOLS'))
|
||||
t.ok(TUI.includes('YOU CAN EXECUTE'))
|
||||
t.ok(TUI.includes('There is no bash, shell, cli, or terminal tool'))
|
||||
t.ok(TUI.includes('The user never runs your tools'))
|
||||
t.ok(TUI.includes('discord_send_message'))
|
||||
t.ok(TUI.includes('DISCORD CHANNEL'))
|
||||
|
||||
@@ -93,3 +93,87 @@ test('finalize keeps same tool with different args', () => {
|
||||
const out = bareAgentFinalizeToolCalls(acc)
|
||||
assert.equal(out.length, 2)
|
||||
})
|
||||
|
||||
test('finalize aliases leaked bash tool onto run_command', () => {
|
||||
const { bareAgentMergeToolCallDelta, bareAgentFinalizeToolCalls } = loadToolCallFns()
|
||||
const acc = new Map()
|
||||
bareAgentMergeToolCallDelta(acc, {
|
||||
index: 0,
|
||||
id: 'b1',
|
||||
function: { name: 'bash', arguments: '{"command":"curl http://api.ipify.org"}' }
|
||||
})
|
||||
const out = bareAgentFinalizeToolCalls(acc)
|
||||
assert.equal(out.length, 1)
|
||||
assert.equal(out[0].function.name, 'run_command')
|
||||
assert.equal(JSON.parse(out[0].function.arguments).command, 'curl http://api.ipify.org')
|
||||
})
|
||||
|
||||
test('finalize coerces bash code field to run_command command', () => {
|
||||
const { bareAgentMergeToolCallDelta, bareAgentFinalizeToolCalls } = loadToolCallFns()
|
||||
const acc = new Map()
|
||||
bareAgentMergeToolCallDelta(acc, {
|
||||
index: 0,
|
||||
id: 'b2',
|
||||
function: { name: 'shell', arguments: '{"code":"ip addr show"}' }
|
||||
})
|
||||
const out = bareAgentFinalizeToolCalls(acc)
|
||||
assert.equal(out.length, 1)
|
||||
assert.equal(out[0].function.name, 'run_command')
|
||||
assert.equal(JSON.parse(out[0].function.arguments).command, 'ip addr show')
|
||||
})
|
||||
|
||||
test('extract recovers fenced bash dumps as run_command', () => {
|
||||
const { bareAgentExtractToolCallsFromText, bareAgentStripToolCallsFromText } =
|
||||
loadToolCallFns()
|
||||
const text =
|
||||
'I cannot execute commands directly, but I can help you use available tools. For IP checks, try:\n\n```bash\ncurl http://api.ipify.org\n```\n\nOr check network settings with:\n\n```bash\nip addr show\n```\n\nLet me know if you need help with other commands!'
|
||||
const out = bareAgentExtractToolCallsFromText(text)
|
||||
assert.equal(out.length, 2)
|
||||
assert.equal(out[0].function.name, 'run_command')
|
||||
assert.equal(JSON.parse(out[0].function.arguments).command, 'curl http://api.ipify.org')
|
||||
assert.equal(JSON.parse(out[1].function.arguments).command, 'ip addr show')
|
||||
const stripped = bareAgentStripToolCallsFromText(text)
|
||||
assert.equal(stripped.includes('```bash'), false)
|
||||
})
|
||||
|
||||
test('extract recovers unfenced instruction-dump shell lines', () => {
|
||||
const { bareAgentExtractToolCallsFromText, bareAgentLooksLikeInstructionDump } =
|
||||
loadToolCallFns()
|
||||
const text =
|
||||
'I cannot execute commands directly, but I can help you use available tools. For IP checks, try:\n\ncurl http://api.ipify.org\n\nOr check network settings with:\n\nip addr show\n\nLet me know if you need help with other commands!'
|
||||
assert.equal(bareAgentLooksLikeInstructionDump(text), true)
|
||||
const out = bareAgentExtractToolCallsFromText(text)
|
||||
const cmds = out.map((c) => JSON.parse(c.function.arguments).command)
|
||||
assert.ok(cmds.includes('curl http://api.ipify.org'))
|
||||
assert.ok(cmds.includes('ip addr show'))
|
||||
})
|
||||
|
||||
test('extract recovers invoke XML bash alias', () => {
|
||||
const { bareAgentExtractToolCallsFromText } = loadToolCallFns()
|
||||
const text =
|
||||
'<invoke name="bash"><parameter name="command">uname -a</parameter></invoke>'
|
||||
const out = bareAgentExtractToolCallsFromText(text)
|
||||
assert.equal(out.length, 1)
|
||||
assert.equal(out[0].function.name, 'run_command')
|
||||
assert.equal(JSON.parse(out[0].function.arguments).command, 'uname -a')
|
||||
})
|
||||
|
||||
test('instruction dump detector and DIY typo match screenshot phrasing', () => {
|
||||
const { bareAgentLooksLikeInstructionDump, bareAgentLooksLikeDoItYourself } =
|
||||
loadToolCallFns()
|
||||
assert.equal(
|
||||
bareAgentLooksLikeInstructionDump(
|
||||
'I cannot execute commands directly, but I can help you use available tools. For IP checks, try:'
|
||||
),
|
||||
true
|
||||
)
|
||||
assert.equal(bareAgentLooksLikeDoItYourself('run the command yourself'), true)
|
||||
assert.equal(bareAgentLooksLikeDoItYourself('run the commanf yourself'), true)
|
||||
})
|
||||
|
||||
test('extract ignores javascript fences that are not shell', () => {
|
||||
const { bareAgentExtractToolCallsFromText } = loadToolCallFns()
|
||||
const text = 'Here is the patch:\n```js\nconst x = 1\n```'
|
||||
const out = bareAgentExtractToolCallsFromText(text)
|
||||
assert.equal(out.length, 0)
|
||||
})
|
||||
|
||||
@@ -127,3 +127,44 @@ test('run_command captures nonzero status through sh -c wrapper', async (t) => {
|
||||
t.ok(out.ok)
|
||||
t.ok(String(out.stdout_stderr || '').includes('EXIT:1'))
|
||||
})
|
||||
|
||||
async function callNamed(ctx, toolName, args) {
|
||||
const s = load()
|
||||
const dispatch = /** @type {(o: object) => Promise<string>} */ (s.bareAgentDispatchTool)
|
||||
const raw = await dispatch({
|
||||
ctx,
|
||||
paths: { cmdOut: '/tmp/agent.out', dir: '/tmp' },
|
||||
toolName,
|
||||
argsJson: JSON.stringify(args),
|
||||
configRef: { current: {} },
|
||||
appendProgress: () => {},
|
||||
signal: null,
|
||||
bareWebRunTool: async () => ({ ok: false }),
|
||||
bareWebFmtErr: (e) => String(e)
|
||||
})
|
||||
return JSON.parse(raw)
|
||||
}
|
||||
|
||||
test('bash alias dispatches to run_command', async (t) => {
|
||||
const { ctx, seen } = makeCtx()
|
||||
const out = await callNamed(ctx, 'bash', { command: 'echo hi' })
|
||||
t.ok(out.ok)
|
||||
t.ok(seen.length >= 1)
|
||||
t.ok(seen[0].startsWith('echo hi > '))
|
||||
})
|
||||
|
||||
test('shell alias coerces code field onto run_command', async (t) => {
|
||||
const { ctx, seen } = makeCtx()
|
||||
const out = await callNamed(ctx, 'shell', { code: 'ip addr show' })
|
||||
t.ok(out.ok)
|
||||
t.ok(seen.length >= 1)
|
||||
t.ok(String(seen[0]).includes('ip addr show'))
|
||||
})
|
||||
|
||||
test('run_command accepts cmd alias field', async (t) => {
|
||||
const { ctx, seen } = makeCtx()
|
||||
const out = await callNamed(ctx, 'run_command', { cmd: 'echo hi' })
|
||||
t.ok(out.ok)
|
||||
t.ok(seen.length >= 1)
|
||||
t.ok(seen[0].startsWith('echo hi > '))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user