Watch
1
0
Fork
You've already forked souveraine
0

surface: per-agent TTS voice + turn clock + reply-handler fix

Speech resolves voice per active agent (agents[].voice_id from the list),
with the system voice as fallback — two agents on a host need not match.
Souveraine.qml carries voice_id into the agents map and adds a turn clock
(turnStartedAt/turnElapsedMs) + a 60s agent-inventory refresh. Ai.qml
declares pendingFilePath and imports qs.modules.common.functions so
StringUtils.ttsClean no longer aborts the stream-finished handler.
This commit is contained in:
Fimeg 2026-07-30 09:18:56 -04:00
commit 0ef239515f
4 changed files with 137 additions and 16 deletions

View file

@ -20,6 +20,25 @@ Item {
property var suggestionQuery: ""
property var suggestionList: []
// Turn clock formatting. A local 9B can take minutes on a cold prompt, so
// the readout has to stay legible from milliseconds to tens of minutes.
function formatTurnDuration(ms) {
if (ms < 1000)
return `${ms}ms`;
const seconds = ms / 1000;
if (seconds < 60)
return `${seconds.toFixed(1)}s`;
const minutes = Math.floor(seconds / 60);
const rest = Math.floor(seconds % 60);
return `${minutes}m ${rest < 10 ? "0" : ""}${rest}s`;
}
function formatClockTime(msEpoch) {
if (!msEpoch)
return "—";
return new Date(msEpoch).toLocaleTimeString(Qt.locale(), "HH:mm:ss");
}
onFocusChanged: focus => {
if (focus) {
root.inputField.forceActiveFocus();
@ -369,7 +388,18 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
visible: Ai.tokenCount.total > 0
icon: "token"
statusText: Ai.tokenCount.total
description: Translation.tr("Total token count\nInput: %1\nOutput: %2").arg(Ai.tokenCount.input).arg(Ai.tokenCount.output)
description: Translation.tr("Context estimate: %1 tokens\n(Local count of the conversation — not the provider's usage numbers)").arg(Ai.tokenCount.total)
}
StatusSeparator {
visible: Souveraine.turnStartedAt > 0
}
StatusItem {
visible: Souveraine.turnStartedAt > 0
icon: Souveraine.turnActive ? "hourglass_top" : "timer"
statusText: root.formatTurnDuration(Souveraine.turnElapsedMs)
description: Souveraine.turnActive
? Translation.tr("Waiting on the agent\nSent at %1").arg(root.formatClockTime(Souveraine.turnStartedAt))
: Translation.tr("Last turn took %1\nSent at %2").arg(root.formatTurnDuration(Souveraine.turnElapsedMs)).arg(root.formatClockTime(Souveraine.turnStartedAt))
}
}
}