Files
aiturk-hermes-ide/apps/mobile/tests/voice-dispatch.test.mjs
T

50 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test'
import assert from 'node:assert/strict'
import { VoiceDispatchGate } from '../src/behavior.mjs'
import { VoiceSession } from '../src/voice.mjs'
test('IDE result cannot resurrect pending audio consent', async () => {
const voice = new VoiceSession({ onText() {} }); voice.ready = true; voice.send = () => {}
voice.audioTranscript = 'Bunu yap'; voice.dispatchGate.input('Bunu yap')
voice.result({ taskId: 'done', status: 'complete', text: 'Bunu yap' })
assert.equal(voice.audioTranscript, '')
assert.throws(() => voice.dispatchGate.claim('Bunu yap', 'execute'))
})
for (const phrase of ['Tamam, bunu yap.', 'Bu görevi gönder', 'Lütfen araştır', 'Şimdi başlat', 'Evet uygula']) {
test(`direct current instruction: ${phrase}`, () => {
const gate = new VoiceDispatchGate(); gate.input(phrase)
assert.equal(gate.claim(phrase, 'research'), 1)
assert.throws(() => gate.claim(phrase, 'research'))
})
}
for (const phrase of ['Bunu yapma', 'Bunu yap mı', 'Bunu yapabilir miyiz?', '“Bunu yap” dedi', 'Yapsak nasıl olur', 'Hayır, bekle', 'Tamam']) {
test(`discussion is not dispatch permission: ${phrase}`, () => {
const gate = new VoiceDispatchGate(); gate.input(phrase)
assert.throws(() => gate.claim(phrase, 'execute'))
})
}
test('old consent, unfinished speech, research escalation and stopped session fail closed', () => {
const gate = new VoiceDispatchGate(); gate.input('Bunu yap'); gate.input('Hayır bekle')
assert.throws(() => gate.claim('Bunu yap', 'execute'))
gate.input('Araştır'); assert.throws(() => gate.claim('Araştır', 'execute'))
gate.input('Bunu ', false); assert.throws(() => gate.claim('Araştır', 'research'))
gate.input('yap', true); assert.equal(gate.claim('Bunu yap', 'execute'), 4)
gate.invalidate(); assert.throws(() => gate.claim('Bunu yap', 'execute'))
})
test('voice dispatch uses actual user text once; no model-generated permission or success', async () => {
const sends = [], responses = []
const voice = new VoiceSession({ onText() {}, onDraft() {}, onSubmit: async (...args) => { sends.push(args); return { accepted: true, completed: false } } })
voice.send = frame => responses.push(frame)
const args = { intent: 'research', objective: 'İncele', scope: 'Android', context: 'Yeşil seçildi', constraints: 'Değiştirme', output: 'Rapor', completion: 'Kanıt', userInstruction: 'Araştır' }
const frame = { data: JSON.stringify({ toolCall: { functionCalls: [{ id: '1', name: 'submit_task', args }] } }) }
await voice.receive(frame); assert.equal(sends.length, 0)
await voice.receive({ data: JSON.stringify({ toolCall: { functionCalls: [{ id: 'draft', name: 'prepare_task', args }] } }) })
responses.length = 0
await voice.receive({ data: JSON.stringify({ serverContent: { inputTranscription: { text: 'Araştır' } } }) })
await voice.receive(frame); await voice.receive(frame)
assert.equal(sends.length, 1)
assert.deepEqual(responses[0].toolResponse.functionResponses[0].response, { accepted: true, completed: false })
assert.ok(responses[1].toolResponse.functionResponses[0].response.error)
})