Add wakeword command routing and the reply-only agent client
This commit is contained in:
@@ -26,6 +26,7 @@ const state = {
|
||||
visibleGuildsSaved: null,
|
||||
timeZoneOverride: localStorage.getItem("veskslop-timezone") ?? "",
|
||||
speech: { provider: null, language: null, voice: null },
|
||||
commands: { wakeword: "!s" },
|
||||
profileDefaults: {},
|
||||
expressionDefault: null,
|
||||
scope: "guild",
|
||||
@@ -1788,6 +1789,45 @@ async function refreshAudio() {
|
||||
await refreshSpeech();
|
||||
}
|
||||
|
||||
/* Command wakeword (Settings -> Commands). */
|
||||
const WAKEWORD_CHOICES = ["!s", "!x", "!c", "!z", "!q", "!e", "!r", "!f", "!v", "!t", "!g", "!b"];
|
||||
|
||||
function fillWakewordControls() {
|
||||
const wakeword = state.commands?.wakeword || "!s";
|
||||
const select = $("#wakeword-select");
|
||||
const customRow = $("#wakeword-custom-row");
|
||||
if (!select || !customRow) return;
|
||||
|
||||
if (WAKEWORD_CHOICES.includes(wakeword)) {
|
||||
select.value = wakeword;
|
||||
customRow.hidden = true;
|
||||
} else {
|
||||
select.value = "custom";
|
||||
$("#wakeword-custom").value = wakeword;
|
||||
customRow.hidden = false;
|
||||
}
|
||||
|
||||
$("#wakeword-status").textContent = wakeword;
|
||||
}
|
||||
|
||||
async function saveWakeword(value) {
|
||||
const wakeword = String(value ?? "").trim();
|
||||
if (!wakeword || wakeword.length > 8 || /\s/.test(wakeword)) {
|
||||
toast("the wakeword must be 1-8 characters with no spaces", "error");
|
||||
fillWakewordControls();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const prefs = await VK.api.post("/api/preferences", { commands: { wakeword } });
|
||||
state.commands = prefs.commands ?? { wakeword };
|
||||
fillWakewordControls();
|
||||
} catch (error) {
|
||||
toast(`wakeword save failed: ${error.message}`, "error");
|
||||
fillWakewordControls();
|
||||
}
|
||||
}
|
||||
|
||||
/* Discord voice processing gates (Settings -> TTS panel). */
|
||||
function fillVoiceGates(voice) {
|
||||
const gates = voice ?? {};
|
||||
@@ -1846,7 +1886,9 @@ async function refreshSpeech() {
|
||||
try {
|
||||
const prefs = await VK.api.get("/api/preferences");
|
||||
state.speech = prefs.tts ?? { provider: null, language: null, voice: null, speed: null, pitch: null };
|
||||
state.commands = prefs.commands ?? { wakeword: "!s" };
|
||||
fillVoiceGates(prefs.voice);
|
||||
fillWakewordControls();
|
||||
} catch {
|
||||
// preferences are optional
|
||||
}
|
||||
@@ -2764,6 +2806,22 @@ function init() {
|
||||
$(id)?.addEventListener("change", () => void saveVoiceGates());
|
||||
}
|
||||
|
||||
$("#wakeword-select")?.addEventListener("change", () => {
|
||||
const value = $("#wakeword-select").value;
|
||||
if (value === "custom") {
|
||||
$("#wakeword-custom").value = WAKEWORD_CHOICES.includes(state.commands?.wakeword)
|
||||
? "!"
|
||||
: state.commands?.wakeword || "!";
|
||||
$("#wakeword-custom-row").hidden = false;
|
||||
$("#wakeword-custom").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
void saveWakeword(value);
|
||||
});
|
||||
$("#wakeword-custom")?.addEventListener("change", () => void saveWakeword($("#wakeword-custom").value));
|
||||
$("#wakeword-save")?.addEventListener("click", () => void saveWakeword($("#wakeword-custom").value));
|
||||
|
||||
$("#tts-duck").addEventListener("click", async () => {
|
||||
const on = !$("#tts-duck").classList.contains("vk-chip-on");
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user