test: pin that unsupported ACP client requests get an error, never a success

fs/* and terminal/* requests from an Agent that never was offered those
capabilities, and unknown methods, must each receive an error response. The
behaviour held partly through parameter validation; the test now states the
contract (no result field, numeric error code, unknown methods get -32601).
This commit is contained in:
Ryder Sun committed 2026-10-16 11:55:16 +08:00
1 parent 5641969445
commit 4a0915594f
1 file changed
+26 -12
@@ -5,11 +5,7 @@ const os = require('node:os')
const path = require('node:path')
const adapters = require('../../../src/agents/cli/cli-adapters.cjs')
const {
executable,
readJsonWhenReady,
within,
} = require('../../support/cli-adapters-test-helpers.cjs')
const { executable, within } = require('../../support/cli-adapters-test-helpers.cjs')
function noisyHermes(directory) {
return executable(directory, 'hermes-noisy-acp.cjs', `
@@ -26,8 +22,8 @@ input.on('line', (line) => {
let message
try { message = JSON.parse(line) } catch { return }
const sessionId = message.params?.sessionId || 'noisy-session'
if (message.id === 9001 && !message.method) {
fs.writeFileSync(process.env.MELDWORK_TEST_UNKNOWN_RESPONSE, JSON.stringify(message))
if (message.id >= 9001 && message.id <= 9004 && !message.method) {
fs.appendFileSync(process.env.MELDWORK_TEST_UNKNOWN_RESPONSE, JSON.stringify(message) + '\\n')
return
}
if (message.method === 'initialize') {
@@ -41,6 +37,11 @@ input.on('line', (line) => {
send({ jsonrpc: '2.0', method: '_vendor/progress', params: { done: 1 } })
send({ jsonrpc: '2.0', method: 'session/update', params: { sessionId, update: { sessionUpdate: 'brand_new_update_kind', payload: 1 } } })
send({ jsonrpc: '2.0', id: 9001, method: 'vendor/unknown_request', params: { sessionId } })
// Methods the client never advertised: a conforming Agent does not call
// them, a non-conforming one must get an error, never a made-up success.
send({ jsonrpc: '2.0', id: 9002, method: 'fs/read_text_file', params: { sessionId, path: '/etc/hosts' } })
send({ jsonrpc: '2.0', id: 9003, method: 'fs/write_text_file', params: { sessionId, path: '/tmp/x', content: 'x' } })
send({ jsonrpc: '2.0', id: 9004, method: 'terminal/create', params: { sessionId, command: 'id' } })
send({ jsonrpc: '2.0', method: 'session/update', params: { sessionId, update: {
sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: 'acp answer despite the noise' },
} } })
@@ -56,7 +57,7 @@ test('ACP turns survive banners, unknown notifications, new update kinds and unk
await adapters.shutdownAcpSessionRuntime?.()
fs.rmSync(directory, { recursive: true, force: true })
})
const unknownResponse = path.join(directory, 'unknown-response.json')
const unknownResponse = path.join(directory, 'unknown-responses.jsonl')
const agent = { kind: 'hermes', executable: noisyHermes(directory), name: 'Hermes' }
const result = await within(adapters.runAgent(agent, 'say something', directory, {
@@ -65,8 +66,21 @@ test('ACP turns survive banners, unknown notifications, new update kinds and unk
}), 10000)
assert.equal(result.text, 'acp answer despite the noise')
// The Agent is told the method is unknown instead of being left waiting.
const response = await readJsonWhenReady(unknownResponse)
assert.equal(response.id, 9001)
assert.equal(response.error?.code, -32601)
// Every request the client does not support is answered with an error, so
// the Agent is never left waiting and never receives a made-up success.
const deadline = Date.now() + 5000
let responses = []
while (Date.now() < deadline) {
try {
responses = fs.readFileSync(unknownResponse, 'utf8').trim().split('\n').filter(Boolean).map(line => JSON.parse(line))
} catch { /* not written yet */ }
if (responses.length >= 4) break
await new Promise(resolve => setTimeout(resolve, 20))
}
assert.deepEqual(responses.map(response => response.id).sort(), [9001, 9002, 9003, 9004])
for (const response of responses) {
assert.equal('result' in response, false, `request ${response.id} must not succeed`)
assert.equal(typeof response.error?.code, 'number')
}
assert.equal(responses.find(response => response.id === 9001).error.code, -32601)
})