@@ -48,6 +48,8 @@ test('spoken replies use harness text and strip HUD sidecars', () => {
|
||||
);
|
||||
assert.equal(spokenReply({}), '');
|
||||
assert.equal(spokenReply('[object Object]'), '');
|
||||
assert.equal(spokenReply({ text: '{"ok":true,"action":"type","name":"Discord"}' }), '');
|
||||
assert.equal(spokenReply({ text: 'Done. {"ok":true,"action":"click","ref":"r1"}' }), 'Done.');
|
||||
assert.equal(
|
||||
spokenReply({ text: '## Status\n- CPU is **fine**.\nUse `htop` if you want more.' }),
|
||||
'Status\n- CPU is fine.\nUse htop if you want more.',
|
||||
@@ -61,6 +63,21 @@ test('voice settings default TTS on and honor an explicit disable', () => {
|
||||
assert.equal(voiceSettings({ tts_enabled: false }).ttsEnabled, false);
|
||||
});
|
||||
|
||||
test('thought chunks forward SDK text onto Thinking', async () => {
|
||||
const daemon = new JarvisDaemon();
|
||||
const thoughts = [];
|
||||
daemon.on('Thinking', (text) => thoughts.push(text));
|
||||
try {
|
||||
daemon.harness.emit('agent_thought_chunk', { type: 'agent_thought_chunk', text: 'Considering the lookup.' });
|
||||
daemon.harness.emit('agent_thought_chunk', 'plain thought');
|
||||
daemon.harness.emit('agent_thought_chunk', { delta: ' via delta' });
|
||||
daemon.harness.emit('agent_thought_chunk', { text: '' });
|
||||
assert.deepEqual(thoughts, ['Considering the lookup.', 'plain thought', ' via delta']);
|
||||
} finally {
|
||||
await daemon.close();
|
||||
}
|
||||
});
|
||||
|
||||
test('ask extracts harness reply text instead of stringifying the object', async () => {
|
||||
const daemon = new JarvisDaemon();
|
||||
daemon.harness = { ask: async () => ({ ok: true, text: 'Hello there.', reason: 'stop' }), cancel() {}, close: async () => {} };
|
||||
@@ -216,3 +233,38 @@ test('cancel suppresses a late reply and revokes portal input', async () => {
|
||||
assert.deepEqual(replies, []); assert.equal(daemon.state, 'ARMED'); assert.equal(revoked, true);
|
||||
} finally { await daemon.close(); }
|
||||
});
|
||||
|
||||
test('mute ignores arm and does not return to listening after speech', async () => {
|
||||
const daemon = new JarvisDaemon();
|
||||
const muted = [];
|
||||
daemon.voiceLoop = {
|
||||
setMuted(value) { muted.push(Boolean(value)); },
|
||||
setPushToTalk(value) { this.ptt = value; },
|
||||
interrupt() {},
|
||||
status: { capture: false, wake: false, muted: false },
|
||||
metrics: { snapshot() { return {}; } },
|
||||
};
|
||||
try {
|
||||
daemon.setState('LISTENING');
|
||||
daemon.setMuted(true);
|
||||
assert.equal(daemon.muted, true);
|
||||
assert.equal(daemon.listenEnabled, false);
|
||||
assert.equal(daemon.state, 'ARMED');
|
||||
assert.deepEqual(muted, [true]);
|
||||
await daemon.arm();
|
||||
assert.equal(daemon.state, 'ARMED');
|
||||
daemon.setListening(true);
|
||||
assert.equal(daemon.state, 'ARMED');
|
||||
daemon.setState('SPEAKING');
|
||||
daemon._finishSpeech();
|
||||
assert.equal(daemon.state, 'ARMED');
|
||||
const status = JSON.parse(daemon.runtimeStatus());
|
||||
assert.equal(status.muted, true);
|
||||
assert.equal(status.voice.muted, true);
|
||||
daemon.setMuted(false);
|
||||
daemon.setListening(false);
|
||||
daemon.setState('SPEAKING');
|
||||
daemon._finishSpeech();
|
||||
assert.equal(daemon.state, 'ARMED');
|
||||
} finally { await daemon.close(); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user