mirror of
https://github.com/Ryder-Sun/Meldwork.git
synced 2026-11-07 06:56:03 -10:00
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:
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)
|
||||
})
|
||||
Reference in new issue
Block a user