Add native OpenClaw Athena Talk plugin

This commit is contained in:
Mikei386
2026-09-15 23:00:56 +02:00
parent 6cacfc1dc8
commit 724e20fec0
8 changed files with 5212 additions and 23 deletions
+22 -10
View File
@@ -4,6 +4,7 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
const AUDIO_FORMAT = { encoding: "pcm16", sampleRateHz: 24000, channels: 1 } as const;
type ProviderConfig = {
modelProvider?: string;
baseUrl?: string;
apiKey?: string;
voice?: string;
@@ -20,13 +21,24 @@ function record(value: unknown): Record<string, any> {
: {};
}
function resolveModelProvider(cfg: unknown, requested?: unknown): Record<string, any> {
const providers = record(record(cfg).models).providers;
const requestedId = typeof requested === "string" ? requested.trim() : "";
if (requestedId) return record(record(providers)[requestedId]);
for (const id of ["athena", "llama-cpp", "openai"]) {
const candidate = record(record(providers)[id]);
if (typeof candidate.baseUrl === "string" && candidate.baseUrl.trim()) return candidate;
}
return {};
}
function resolveConfig(req: any): Required<ProviderConfig> {
const raw = record(req.providerConfig);
const modelProviders = record(record(req.cfg).models).providers;
const athena = record(record(modelProviders).athena);
const modelProvider = resolveModelProvider(req.cfg, raw.modelProvider);
return {
baseUrl: String(raw.baseUrl || athena.baseUrl || "http://192.168.1.212:8081/v1").replace(/\/$/, ""),
apiKey: String(raw.apiKey || athena.apiKey || ""),
modelProvider: String(raw.modelProvider || ""),
baseUrl: String(raw.baseUrl || modelProvider.baseUrl || "http://192.168.1.212:8081/v1").replace(/\/$/, ""),
apiKey: String(raw.apiKey || modelProvider.apiKey || ""),
voice: String(raw.voice || req.voice || "alloy"),
language: String(raw.language || req.language || "de"),
vadThreshold: Number(raw.vadThreshold ?? 0.018),
@@ -238,7 +250,8 @@ class AthenaTalkBridge {
private async transcribe(pcm: Buffer): Promise<string> {
const form = new FormData();
form.append("file", new Blob([wavFromPcm16(pcm)], { type: "audio/wav" }), "talk.wav");
const wavBytes = Uint8Array.from(wavFromPcm16(pcm));
form.append("file", new Blob([wavBytes], { type: "audio/wav" }), "talk.wav");
form.append("model", "whisper-1");
form.append("language", this.cfg.language);
const response = await fetch(`${this.cfg.baseUrl}/audio/transcriptions`, {
@@ -341,13 +354,12 @@ export default definePluginEntry({
supportsToolCalls: true,
supportsSessionResumption: false,
},
resolveConfig: ({ rawConfig }) => record(rawConfig),
isConfigured: ({ providerConfig, cfg }) => {
resolveConfig: ({ rawConfig }: { rawConfig: unknown }) => record(rawConfig),
isConfigured: ({ providerConfig, cfg }: { providerConfig: unknown; cfg: unknown }) => {
const raw = record(providerConfig);
const athena = record(record(record(cfg).models).providers).athena;
return Boolean(raw.baseUrl || record(athena).baseUrl);
return Boolean(raw.baseUrl || resolveModelProvider(cfg, raw.modelProvider).baseUrl);
},
createBridge: (req) => new AthenaTalkBridge(req, resolveConfig(req)),
createBridge: (req: any) => new AthenaTalkBridge(req, resolveConfig(req)),
} as any);
},
});