Add native OpenClaw Athena Talk plugin
This commit is contained in:
@@ -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);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user