Play Weksa speech artifacts in Discord voice
This commit is contained in:
parent
0f1aba036f
commit
0e0e1d3044
10 changed files with 857 additions and 2 deletions
|
|
@ -70,6 +70,12 @@ REPO_FACE_GITHUB_ACTIONS_ENABLED=false
|
|||
REPO_FACE_WEKSA_SPEECH_ENABLED=false
|
||||
WEKSA_DAEMON_BASE_URL=http://127.0.0.1:8813
|
||||
WEKSA_DAEMON_TIMEOUT_MS=120000
|
||||
WEKSA_REPO_ROOT=E:/Projects/weksa
|
||||
REPO_FACE_DISCORD_VOICE_ENABLED=false
|
||||
REPO_FACE_DISCORD_VOICE_CHANNEL_ID=
|
||||
REPO_FACE_DISCORD_VOICE_OUTBOX_PATH=.voidbot/status/repo-face-voice-outbox.jsonl
|
||||
REPO_FACE_DISCORD_VOICE_PLAYED_PATH=.voidbot/status/repo-face-voice-played.jsonl
|
||||
REPO_FACE_DISCORD_VOICE_POLL_INTERVAL_MS=5000
|
||||
REPO_FACE_HEARTBEATS_ENABLED=false
|
||||
REPO_FACE_HEARTBEAT_STATE_PATH=.voidbot/status/repo-face-heartbeats.json
|
||||
REPO_FACE_HEARTBEAT_TASK_NAME=VoidBot Repo Face Heartbeats
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@
|
|||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"dependencies": {
|
||||
"@discordjs/voice": "^0.19.2",
|
||||
"@voidbot/config": "0.1.0",
|
||||
"@voidbot/core": "0.1.0",
|
||||
"@voidbot/providers": "0.1.0",
|
||||
"@voidbot/rag": "0.1.0",
|
||||
"@voidbot/shared": "0.1.0",
|
||||
"discord.js": "^14.19.0",
|
||||
"dotenv": "^16.4.0"
|
||||
"dotenv": "^16.4.0",
|
||||
"ffmpeg-static": "^5.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import {
|
|||
parseProviderOverride,
|
||||
replyEphemeral,
|
||||
} from "./discord-bot-handlers";
|
||||
import { startRepoFaceVoicePlayback } from "./repo-face-voice-playback";
|
||||
import {
|
||||
buildActorFromInteraction,
|
||||
buildChannelIndexingTarget,
|
||||
|
|
@ -92,6 +93,7 @@ export async function startBot(): Promise<void> {
|
|||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.GuildVoiceStates,
|
||||
GatewayIntentBits.MessageContent,
|
||||
],
|
||||
});
|
||||
|
|
@ -313,6 +315,7 @@ export async function startBot(): Promise<void> {
|
|||
client.once(Events.ClientReady, async (readyClient) => {
|
||||
console.log(`VoidBot connected as ${readyClient.user.tag}.`);
|
||||
await maybeRegisterCommands(config.botToken!, config.applicationId, config.developmentGuildId);
|
||||
startRepoFaceVoicePlayback(readyClient, config.repoFaceDiscordVoice);
|
||||
});
|
||||
|
||||
client.on(Events.MessageCreate, async (message) => {
|
||||
|
|
|
|||
142
apps/bot/src/repo-face-voice-playback.ts
Normal file
142
apps/bot/src/repo-face-voice-playback.ts
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import { existsSync } from "node:fs";
|
||||
|
||||
import {
|
||||
AudioPlayerStatus,
|
||||
VoiceConnectionStatus,
|
||||
createAudioPlayer,
|
||||
createAudioResource,
|
||||
entersState,
|
||||
joinVoiceChannel,
|
||||
type AudioPlayer,
|
||||
type VoiceConnection,
|
||||
} from "@discordjs/voice";
|
||||
import { ChannelType, type Client, type GuildBasedChannel } from "discord.js";
|
||||
|
||||
import {
|
||||
appendRepoFaceVoicePlayedEntry,
|
||||
loadRepoFaceVoiceOutboxEntries,
|
||||
loadRepoFaceVoicePlayedIds,
|
||||
type RepoFaceVoiceOutboxEntry,
|
||||
} from "@voidbot/core";
|
||||
|
||||
export interface RepoFaceVoicePlaybackOptions {
|
||||
enabled: boolean;
|
||||
channelId?: string;
|
||||
outboxPath: string;
|
||||
playedPath: string;
|
||||
pollIntervalMs: number;
|
||||
}
|
||||
|
||||
export function startRepoFaceVoicePlayback(
|
||||
client: Client,
|
||||
options: RepoFaceVoicePlaybackOptions,
|
||||
): void {
|
||||
if (!options.enabled) {
|
||||
return;
|
||||
}
|
||||
if (!options.channelId) {
|
||||
console.warn("Repo Face Discord voice playback enabled without REPO_FACE_DISCORD_VOICE_CHANNEL_ID.");
|
||||
return;
|
||||
}
|
||||
|
||||
const runtime = new RepoFaceVoicePlaybackRuntime(client, options);
|
||||
void runtime.poll();
|
||||
setInterval(() => {
|
||||
void runtime.poll();
|
||||
}, options.pollIntervalMs);
|
||||
}
|
||||
|
||||
class RepoFaceVoicePlaybackRuntime {
|
||||
private readonly player: AudioPlayer;
|
||||
private connection?: VoiceConnection;
|
||||
private active = false;
|
||||
|
||||
constructor(
|
||||
private readonly client: Client,
|
||||
private readonly options: RepoFaceVoicePlaybackOptions,
|
||||
) {
|
||||
this.player = createAudioPlayer();
|
||||
this.player.on("error", (error) => {
|
||||
console.warn(`Repo Face voice player error: ${error.message}`);
|
||||
this.active = false;
|
||||
});
|
||||
}
|
||||
|
||||
async poll(): Promise<void> {
|
||||
if (this.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = await loadRepoFaceVoiceOutboxEntries(this.options.outboxPath);
|
||||
if (entries.length === 0) {
|
||||
return;
|
||||
}
|
||||
const played = await loadRepoFaceVoicePlayedIds(this.options.playedPath);
|
||||
const entry = entries.find((candidate) => !played.has(candidate.id));
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.play(entry);
|
||||
}
|
||||
|
||||
private async play(entry: RepoFaceVoiceOutboxEntry): Promise<void> {
|
||||
if (!existsSync(entry.audioPath)) {
|
||||
console.warn(`Repo Face voice audio is missing for ${entry.id}: ${entry.audioPath}`);
|
||||
return;
|
||||
}
|
||||
this.active = true;
|
||||
try {
|
||||
const channel = await this.resolveVoiceChannel();
|
||||
const connection = await this.ensureConnection(channel);
|
||||
const resource = createAudioResource(entry.audioPath, {
|
||||
metadata: entry,
|
||||
});
|
||||
this.player.play(resource);
|
||||
connection.subscribe(this.player);
|
||||
await entersState(this.player, AudioPlayerStatus.Playing, 15_000);
|
||||
await entersState(this.player, AudioPlayerStatus.Idle, 180_000);
|
||||
await appendRepoFaceVoicePlayedEntry(this.options.playedPath, entry);
|
||||
console.log(
|
||||
`Played repo Face voice ${entry.id} for ${entry.displayName} in channel ${this.options.channelId}.`,
|
||||
);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.warn(`Repo Face voice playback failed for ${entry.id}: ${message}`);
|
||||
} finally {
|
||||
this.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async resolveVoiceChannel(): Promise<GuildBasedChannel> {
|
||||
const channel = await this.client.channels.fetch(this.options.channelId!);
|
||||
if (!channel || !("guild" in channel)) {
|
||||
throw new Error(`Configured voice channel ${this.options.channelId} was not found in a guild.`);
|
||||
}
|
||||
if (channel.type !== ChannelType.GuildVoice && channel.type !== ChannelType.GuildStageVoice) {
|
||||
throw new Error(`Configured channel ${this.options.channelId} is not a Discord voice/stage channel.`);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
private async ensureConnection(channel: GuildBasedChannel): Promise<VoiceConnection> {
|
||||
if (
|
||||
this.connection &&
|
||||
this.connection.joinConfig.channelId === channel.id &&
|
||||
this.connection.state.status !== VoiceConnectionStatus.Destroyed
|
||||
) {
|
||||
return this.connection;
|
||||
}
|
||||
if (!("voiceAdapterCreator" in channel.guild)) {
|
||||
throw new Error(`Guild for voice channel ${channel.id} does not expose a voice adapter.`);
|
||||
}
|
||||
this.connection = joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: channel.guild.id,
|
||||
adapterCreator: channel.guild.voiceAdapterCreator,
|
||||
selfDeaf: false,
|
||||
});
|
||||
await entersState(this.connection, VoiceConnectionStatus.Ready, 30_000);
|
||||
return this.connection;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import { isAbsolute, join, relative, resolve } from "node:path";
|
|||
import { loadConfig } from "@voidbot/config";
|
||||
import {
|
||||
applyRepoFacePostFatigueAfterSpeech,
|
||||
appendRepoFaceVoiceOutboxEntry,
|
||||
type AuditLog,
|
||||
buildVoidMcpServerConfig,
|
||||
createStateStorage,
|
||||
|
|
@ -19,6 +20,7 @@ import {
|
|||
loadFaceIdentityRegistry,
|
||||
loadSystemMessageCatalog,
|
||||
resolveRepoFaceStatePath,
|
||||
resolveWeksaArtifactPath,
|
||||
type SystemMessageCatalog,
|
||||
} from "@voidbot/core";
|
||||
import {
|
||||
|
|
@ -1508,6 +1510,28 @@ async function recordRepoIdentityWeksaSpeechReceipt(input: {
|
|||
messageId: string;
|
||||
receipt: WeksaMimoReceipt;
|
||||
}): Promise<void> {
|
||||
const audioPath = resolveWeksaArtifactPath(
|
||||
config.repoFaceWeksaSpeech.repoRoot,
|
||||
input.receipt.artifacts?.audio,
|
||||
);
|
||||
if (config.repoFaceDiscordVoice.enabled && audioPath) {
|
||||
await appendRepoFaceVoiceOutboxEntry(config.repoFaceDiscordVoice.outboxPath, {
|
||||
schemaVersion: "voidbot.repo_face_voice_outbox.v1",
|
||||
id: `repo-face:${input.identity.id}:${input.messageId}`,
|
||||
createdAt: new Date().toISOString(),
|
||||
identityId: input.identity.id,
|
||||
displayName: input.identity.displayName,
|
||||
repoName: input.identity.repoName,
|
||||
textChannelId: input.channelId,
|
||||
textMessageId: input.messageId,
|
||||
replyToMessageId: input.replyToMessageId,
|
||||
contentPreview: input.content.slice(0, 500),
|
||||
weksaRequestId: input.receipt.request_id,
|
||||
weksaReceiptArtifact: input.receipt.artifacts?.receipt,
|
||||
audioPath,
|
||||
audioBytes: input.receipt.provider_response?.audio_bytes,
|
||||
});
|
||||
}
|
||||
await auditLog.record({
|
||||
type: "repo_identity.weksa_speech_rendered",
|
||||
actorId: input.job.requester.id,
|
||||
|
|
|
|||
552
package-lock.json
generated
552
package-lock.json
generated
|
|
@ -22,13 +22,15 @@
|
|||
"name": "@voidbot/bot",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@discordjs/voice": "^0.19.2",
|
||||
"@voidbot/config": "0.1.0",
|
||||
"@voidbot/core": "0.1.0",
|
||||
"@voidbot/providers": "0.1.0",
|
||||
"@voidbot/rag": "0.1.0",
|
||||
"@voidbot/shared": "0.1.0",
|
||||
"discord.js": "^14.19.0",
|
||||
"dotenv": "^16.4.0"
|
||||
"dotenv": "^16.4.0",
|
||||
"ffmpeg-static": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"apps/worker": {
|
||||
|
|
@ -45,6 +47,21 @@
|
|||
"zod": "^3.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@derhuerst/http-basic": {
|
||||
"version": "8.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz",
|
||||
"integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caseless": "^0.12.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"http-response-object": "^3.0.1",
|
||||
"parse-cache-control": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.14.1.tgz",
|
||||
|
|
@ -150,6 +167,26 @@
|
|||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/voice": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.19.2.tgz",
|
||||
"integrity": "sha512-3yJ255e4ag3wfZu/DSxeOZK1UtnqNxnspmLaQetGT0pDkThNZoHs+Zg6dgZZ19JEVomXygvfHn9lNpICZuYtEA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@snazzah/davey": "^0.1.9",
|
||||
"@types/ws": "^8.18.1",
|
||||
"discord-api-types": "^0.38.41",
|
||||
"prism-media": "^1.3.5",
|
||||
"tslib": "^2.8.1",
|
||||
"ws": "^8.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.3.tgz",
|
||||
|
|
@ -185,6 +222,40 @@
|
|||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.0.tgz",
|
||||
"integrity": "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.0.tgz",
|
||||
"integrity": "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
|
||||
"integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
|
||||
|
|
@ -688,6 +759,24 @@
|
|||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz",
|
||||
"integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@qdrant/js-client-rest": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@qdrant/js-client-rest/-/js-client-rest-1.17.0.tgz",
|
||||
|
|
@ -748,6 +837,280 @@
|
|||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey/-/davey-0.1.11.tgz",
|
||||
"integrity": "sha512-oBN+msHzPnm1M5DDx3wVD7iBwpNXFUtkh2MrAbUJu0OhKjliLChi28hq++mu1+qdMpAVQO5JKAvQQxYVbyneiw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Snazzah"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@snazzah/davey-android-arm-eabi": "0.1.11",
|
||||
"@snazzah/davey-android-arm64": "0.1.11",
|
||||
"@snazzah/davey-darwin-arm64": "0.1.11",
|
||||
"@snazzah/davey-darwin-x64": "0.1.11",
|
||||
"@snazzah/davey-freebsd-x64": "0.1.11",
|
||||
"@snazzah/davey-linux-arm-gnueabihf": "0.1.11",
|
||||
"@snazzah/davey-linux-arm64-gnu": "0.1.11",
|
||||
"@snazzah/davey-linux-arm64-musl": "0.1.11",
|
||||
"@snazzah/davey-linux-x64-gnu": "0.1.11",
|
||||
"@snazzah/davey-linux-x64-musl": "0.1.11",
|
||||
"@snazzah/davey-wasm32-wasi": "0.1.11",
|
||||
"@snazzah/davey-win32-arm64-msvc": "0.1.11",
|
||||
"@snazzah/davey-win32-ia32-msvc": "0.1.11",
|
||||
"@snazzah/davey-win32-x64-msvc": "0.1.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-android-arm-eabi": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-android-arm-eabi/-/davey-android-arm-eabi-0.1.11.tgz",
|
||||
"integrity": "sha512-T1RYbNYKN6tLOcGIDKJd8OI6FBSEemwL7DOYdTMmhqfhhMr3YVN8WOhfoxGg63OcnpTN2e2c5tdY2bAx25RmQQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-android-arm64": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-android-arm64/-/davey-android-arm64-0.1.11.tgz",
|
||||
"integrity": "sha512-ksJn/x2VU8h6w9eku1HT96ugSRZ7lKVkKNKbFleaFN+U99DJaPM+gMu2YvnFU4V54HR06ZBnRihnVG6VLXQpDw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-darwin-arm64": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-darwin-arm64/-/davey-darwin-arm64-0.1.11.tgz",
|
||||
"integrity": "sha512-E1d7PbaaVMO3Lj9EiAPqOVbuV0xg5+PsHzHH097DDXiD1+zUDXvJaTnUWsnm5z50pJniHpi4GtaYmk+ieB/guA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-darwin-x64": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-darwin-x64/-/davey-darwin-x64-0.1.11.tgz",
|
||||
"integrity": "sha512-Tl4TI/LTmgJZepgbgVMYDi8RqlAkPtPg1OEBPl7a9Tn3AwR36Vs6lyIT1cs/lGy/ds/+B+mKI4rPObN1cyILTw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-freebsd-x64": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-freebsd-x64/-/davey-freebsd-x64-0.1.11.tgz",
|
||||
"integrity": "sha512-T8Iw9FXkuI1T+YBAFzh9v/TXf9IOTOSqnd/BFpTRTrlW72PR2lhIidzSmg027VxO7r5pX47iFwiOkb9I/NU/EA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-linux-arm-gnueabihf": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm-gnueabihf/-/davey-linux-arm-gnueabihf-0.1.11.tgz",
|
||||
"integrity": "sha512-1Txj+8pqA8uq/OGtaUaBFWAPnNMQzFgIywj0iA7EI4xZl+mab48/pv+YZ1pNb/suC6ynsW44oB9efiXSdcUAgA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-linux-arm64-gnu": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm64-gnu/-/davey-linux-arm64-gnu-0.1.11.tgz",
|
||||
"integrity": "sha512-ERzF5nM/IYW1BcN3wLXpEwBCGLFf0kGJUVhaV6yfiInz0tkU8UmvrrgpaMaACfMjIhfWdq5CcX+aTkXo/saNcg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-linux-arm64-musl": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm64-musl/-/davey-linux-arm64-musl-0.1.11.tgz",
|
||||
"integrity": "sha512-e6pX6Hiabtz99q+H/YHNkm9JVlpqN8HGh0qPib8G2+UY4/SSH8WvqWipk3v581dMy2oyCHt7MOoY1aU1P1N/xA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-linux-x64-gnu": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-linux-x64-gnu/-/davey-linux-x64-gnu-0.1.11.tgz",
|
||||
"integrity": "sha512-TW5bSoqChOJMbvsDb4wAATYrxmAXuNnse7wFNVSAJUaZKSeRfZbu3UAiPWSNn7GwLwSfU6hg322KZUn8IWCuvg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-linux-x64-musl": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-linux-x64-musl/-/davey-linux-x64-musl-0.1.11.tgz",
|
||||
"integrity": "sha512-5j6Pmc+Wzv5lSxVP6quA7teYRJXibkZqQyYGfTDnTsUOO5dPpcojpqlXlkhyvsA1OAQTj4uxbOCciN3cVWwzug==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-wasm32-wasi": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-wasm32-wasi/-/davey-wasm32-wasi-0.1.11.tgz",
|
||||
"integrity": "sha512-rKOwZ/0J8lp+4VEyOdMDBRP9KR+PksZpa9V1Qn0veMzy4FqTVKthkxwGqewheFe0SFg9fdvt798l/PBFrfDeZw==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-win32-arm64-msvc": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-win32-arm64-msvc/-/davey-win32-arm64-msvc-0.1.11.tgz",
|
||||
"integrity": "sha512-5fptJU4tX901m3mj0SHiBljMrPT4ZEsynbBhR7bK1yn9TY1jjyhN8EFi7QF5IWtUEni+0mia2BCMHZ5ZkmFZqQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-win32-ia32-msvc": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-win32-ia32-msvc/-/davey-win32-ia32-msvc-0.1.11.tgz",
|
||||
"integrity": "sha512-ualexn8SeLsiMHhWfzVrzRcjHgcBapg++FPaVgJJxoh2S/jCRiklXOu3luqIZdJdNKvhe2V9SwO/cImPeIIBKw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@snazzah/davey-win32-x64-msvc": {
|
||||
"version": "0.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@snazzah/davey-win32-x64-msvc/-/davey-win32-x64-msvc-0.1.11.tgz",
|
||||
"integrity": "sha512-muNhc8UKXtknzsH/w4AIkbPR2I8BuvApn0pDXar0IEvY8PCjqU/M8MPbOOEYwQVvQRMwVTgExtxzrkBPSXB4nA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
|
||||
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz",
|
||||
|
|
@ -833,6 +1196,18 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
|
|
@ -890,6 +1265,12 @@
|
|||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
|
|
@ -928,6 +1309,27 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
||||
"engines": [
|
||||
"node >= 6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.0.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
|
||||
|
|
@ -1106,6 +1508,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/env-paths": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
|
||||
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
|
|
@ -1297,6 +1708,22 @@
|
|||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ffmpeg-static": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.3.0.tgz",
|
||||
"integrity": "sha512-H+K6sW6TiIX6VGend0KQwthe+kaceeH/luE8dIZyOP35ik7ahYojDuqlTV1bOrtEwl01sy2HFNGQfi5IDJvotg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@derhuerst/http-basic": "^8.2.0",
|
||||
"env-paths": "^2.2.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"progress": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||
|
|
@ -1475,6 +1902,34 @@
|
|||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/http-response-object": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
|
||||
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^10.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/http-response-object/node_modules/@types/node": {
|
||||
"version": "10.17.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
|
||||
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
||||
|
|
@ -1678,6 +2133,11 @@
|
|||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-cache-control": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
|
||||
"integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
|
|
@ -1843,6 +2303,41 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prism-media": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.5.tgz",
|
||||
"integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@discordjs/opus": ">=0.8.0 <1.0.0",
|
||||
"ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0",
|
||||
"node-opus": "^0.3.3",
|
||||
"opusscript": "^0.0.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@discordjs/opus": {
|
||||
"optional": true
|
||||
},
|
||||
"ffmpeg-static": {
|
||||
"optional": true
|
||||
},
|
||||
"node-opus": {
|
||||
"optional": true
|
||||
},
|
||||
"opusscript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
|
@ -1895,6 +2390,20 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
|
|
@ -1930,6 +2439,26 @@
|
|||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
|
|
@ -2098,6 +2627,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
|
@ -2153,6 +2691,12 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
|
|
@ -2190,6 +2734,12 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ const envSchema = z.object({
|
|||
REPO_FACE_WEKSA_SPEECH_ENABLED: booleanFromEnv.default(false),
|
||||
WEKSA_DAEMON_BASE_URL: z.string().url().default("http://127.0.0.1:8813"),
|
||||
WEKSA_DAEMON_TIMEOUT_MS: z.coerce.number().int().positive().default(120000),
|
||||
WEKSA_REPO_ROOT: z.string().min(1).default("E:/Projects/weksa"),
|
||||
REPO_FACE_DISCORD_VOICE_ENABLED: booleanFromEnv.default(false),
|
||||
REPO_FACE_DISCORD_VOICE_CHANNEL_ID: optionalNonEmptyString,
|
||||
REPO_FACE_DISCORD_VOICE_OUTBOX_PATH: z.string().min(1).default(".voidbot/status/repo-face-voice-outbox.jsonl"),
|
||||
REPO_FACE_DISCORD_VOICE_PLAYED_PATH: z.string().min(1).default(".voidbot/status/repo-face-voice-played.jsonl"),
|
||||
REPO_FACE_DISCORD_VOICE_POLL_INTERVAL_MS: z.coerce.number().int().positive().default(5000),
|
||||
BIFROST_ROOT: z.string().min(1).default("E:/Projects/Bifrost"),
|
||||
BIFROST_DISCORD_CHANNEL_ID: optionalNonEmptyString,
|
||||
REPO_FACE_HEARTBEATS_ENABLED: booleanFromEnv.default(false),
|
||||
|
|
@ -190,6 +196,14 @@ export interface AppConfig {
|
|||
enabled: boolean;
|
||||
daemonBaseUrl: string;
|
||||
timeoutMs: number;
|
||||
repoRoot: string;
|
||||
};
|
||||
repoFaceDiscordVoice: {
|
||||
enabled: boolean;
|
||||
channelId?: string;
|
||||
outboxPath: string;
|
||||
playedPath: string;
|
||||
pollIntervalMs: number;
|
||||
};
|
||||
bifrostRoot: string;
|
||||
bifrostDiscordChannelId?: string;
|
||||
|
|
@ -436,6 +450,14 @@ export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig {
|
|||
enabled: parsed.REPO_FACE_WEKSA_SPEECH_ENABLED,
|
||||
daemonBaseUrl: parsed.WEKSA_DAEMON_BASE_URL.replace(/\/+$/, ""),
|
||||
timeoutMs: parsed.WEKSA_DAEMON_TIMEOUT_MS,
|
||||
repoRoot: resolve(parsed.WEKSA_REPO_ROOT),
|
||||
},
|
||||
repoFaceDiscordVoice: {
|
||||
enabled: parsed.REPO_FACE_DISCORD_VOICE_ENABLED,
|
||||
channelId: parsed.REPO_FACE_DISCORD_VOICE_CHANNEL_ID,
|
||||
outboxPath: resolve(parsed.REPO_FACE_DISCORD_VOICE_OUTBOX_PATH),
|
||||
playedPath: resolve(parsed.REPO_FACE_DISCORD_VOICE_PLAYED_PATH),
|
||||
pollIntervalMs: parsed.REPO_FACE_DISCORD_VOICE_POLL_INTERVAL_MS,
|
||||
},
|
||||
bifrostRoot: resolve(parsed.BIFROST_ROOT),
|
||||
bifrostDiscordChannelId: parsed.BIFROST_DISCORD_CHANNEL_ID,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export * from "./repo-discord-identities";
|
|||
export * from "./repo-face-heartbeat-queue";
|
||||
export * from "./repo-face-initializer";
|
||||
export * from "./repo-face-rest";
|
||||
export * from "./repo-face-voice-outbox";
|
||||
export * from "./situational-social-read";
|
||||
export * from "./state-storage";
|
||||
export * from "./style-pack-loader";
|
||||
|
|
|
|||
104
packages/core/src/repo-face-voice-outbox.ts
Normal file
104
packages/core/src/repo-face-voice-outbox.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { appendFile, mkdir, readFile } from "node:fs/promises";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
export interface RepoFaceVoiceOutboxEntry {
|
||||
schemaVersion: "voidbot.repo_face_voice_outbox.v1";
|
||||
id: string;
|
||||
createdAt: string;
|
||||
identityId: string;
|
||||
displayName: string;
|
||||
repoName: string;
|
||||
textChannelId: string;
|
||||
textMessageId: string;
|
||||
replyToMessageId?: string;
|
||||
contentPreview: string;
|
||||
weksaRequestId?: string;
|
||||
weksaReceiptArtifact?: string;
|
||||
audioPath: string;
|
||||
audioBytes?: number;
|
||||
}
|
||||
|
||||
export async function appendRepoFaceVoiceOutboxEntry(
|
||||
outboxPath: string,
|
||||
entry: RepoFaceVoiceOutboxEntry,
|
||||
): Promise<void> {
|
||||
await mkdir(dirname(outboxPath), { recursive: true });
|
||||
await appendFile(outboxPath, `${JSON.stringify(entry)}\n`, "utf8");
|
||||
}
|
||||
|
||||
export async function loadRepoFaceVoiceOutboxEntries(
|
||||
outboxPath: string,
|
||||
): Promise<RepoFaceVoiceOutboxEntry[]> {
|
||||
const content = await readFile(outboxPath, "utf8").catch((error: NodeJS.ErrnoException) => {
|
||||
if (error.code === "ENOENT") {
|
||||
return "";
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
return content
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean)
|
||||
.flatMap((line) => {
|
||||
try {
|
||||
const parsed = JSON.parse(line) as RepoFaceVoiceOutboxEntry;
|
||||
return parsed.schemaVersion === "voidbot.repo_face_voice_outbox.v1" &&
|
||||
typeof parsed.id === "string" &&
|
||||
typeof parsed.audioPath === "string"
|
||||
? [parsed]
|
||||
: [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function appendRepoFaceVoicePlayedEntry(
|
||||
playedPath: string,
|
||||
entry: RepoFaceVoiceOutboxEntry,
|
||||
): Promise<void> {
|
||||
await mkdir(dirname(playedPath), { recursive: true });
|
||||
await appendFile(
|
||||
playedPath,
|
||||
`${JSON.stringify({
|
||||
schemaVersion: "voidbot.repo_face_voice_played.v1",
|
||||
id: entry.id,
|
||||
playedAt: new Date().toISOString(),
|
||||
identityId: entry.identityId,
|
||||
textMessageId: entry.textMessageId,
|
||||
audioPath: entry.audioPath,
|
||||
})}\n`,
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
|
||||
export async function loadRepoFaceVoicePlayedIds(playedPath: string): Promise<Set<string>> {
|
||||
const content = await readFile(playedPath, "utf8").catch((error: NodeJS.ErrnoException) => {
|
||||
if (error.code === "ENOENT") {
|
||||
return "";
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
const ids = new Set<string>();
|
||||
for (const line of content.split(/\r?\n/)) {
|
||||
if (!line.trim()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(line) as { id?: string };
|
||||
if (typeof parsed.id === "string") {
|
||||
ids.add(parsed.id);
|
||||
}
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
export function resolveWeksaArtifactPath(weksaRepoRoot: string, artifactPath: string | undefined): string | undefined {
|
||||
if (!artifactPath) {
|
||||
return undefined;
|
||||
}
|
||||
return resolve(weksaRepoRoot, artifactPath);
|
||||
}
|
||||
|
|
@ -353,3 +353,4 @@
|
|||
{"ts":"2026-06-12T13:07:40Z","type":"implementation","status":"ok","note":"Raven Hugging Face token from gamecult-ops/huggingface-bifrost was installed into Ubuntu-24.04 at /root/.cache/huggingface/token, Vili now mounts/passes it into Kimodo containers, /health reports huggingFaceToken: present, Starfire smoke passes, and a Kimodo container verified gated metadata access to meta-llama/Meta-Llama-3-8B-Instruct. Token value was not logged."}
|
||||
{"ts":"2026-06-12T14:12:05Z","type":"verification","status":"ok","note":"Kimodo real generation now works on Raven through Vili. Direct smoke generated E:\\Projects\\Vili\\.vili\\artifacts\\kimodo-real-smoke-live\\motion.npz after first-run cache warmup. Vili HTTP POST /motion/generate succeeded for prompt 'A person gives a small friendly wave.' with duration=1, diffusionSteps=2, seed=10, producing E:\\Projects\\Vili\\.vili\\artifacts\\vili-1781273290152\\motion.npz. Key fixes: writable Hugging Face cache mount and file-based Kimodo input_folder/meta.json prompt handoff."}
|
||||
{"ts":"2026-06-12T16:01:29Z","type":"implementation","status":"ok","note":"Added gated repo Face Weksa speech projection after parent-approved Discord SAY delivery. Weksa remains utterance/MiMo artifact owner; VoidBot records audit receipts and text delivery stays authoritative if speech rendering fails."}
|
||||
{"ts":"2026-06-12T17:06:36Z","type":"verification","status":"ok","note":"Discord voice playback organ is live for Weksa MiMo artifacts. Bot consumed repo-face voice outbox entry manual-voice-smoke-1781283564, joined Aquarium voice channel 1505916699831046224, played E:\\\\Projects\\\\weksa\\\\.weksa\\\\speech-provider\\\\mimo\\\\metame-1513599037692182589-smoke-003-auto-feminine\\\\metame-1513599037692182589-smoke-003-auto-feminine.wav, and wrote repo-face-voice-played receipt."}
|
||||
|
|
|
|||
Loading…
Reference in a new issue