mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 09:10:33 +00:00
* test(memory): lock qmd status counts regression * feat: make /tools show what the agent can use right now * fix: sync web ui slash commands with the shared registry * feat: add profile and unavailable counts to /tools * refine: keep /tools focused on available tools * fix: resolve /tools review regressions * fix: honor model compat in /tools inventory * fix: sync generated protocol models for /tools * fix: restore canonical slash command names * fix: avoid ci lint drift in google helper exports * perf: stop computing unused /tools unavailable counts * docs: clarify /tools runtime behavior
64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
import { Type } from "@sinclair/typebox";
|
|
import { SILENT_REPLY_TOKEN } from "../../auto-reply/tokens.js";
|
|
import type { OpenClawConfig } from "../../config/config.js";
|
|
import { loadConfig } from "../../config/config.js";
|
|
import { textToSpeech } from "../../tts/tts.js";
|
|
import type { GatewayMessageChannel } from "../../utils/message-channel.js";
|
|
import type { AnyAgentTool } from "./common.js";
|
|
import { readStringParam } from "./common.js";
|
|
|
|
const TtsToolSchema = Type.Object({
|
|
text: Type.String({ description: "Text to convert to speech." }),
|
|
channel: Type.Optional(
|
|
Type.String({ description: "Optional channel id to pick output format (e.g. telegram)." }),
|
|
),
|
|
});
|
|
|
|
export function createTtsTool(opts?: {
|
|
config?: OpenClawConfig;
|
|
agentChannel?: GatewayMessageChannel;
|
|
}): AnyAgentTool {
|
|
return {
|
|
label: "TTS",
|
|
name: "tts",
|
|
displaySummary: "Convert text to speech and return audio.",
|
|
description: `Convert text to speech. Audio is delivered automatically from the tool result — reply with ${SILENT_REPLY_TOKEN} after a successful call to avoid duplicate messages.`,
|
|
parameters: TtsToolSchema,
|
|
execute: async (_toolCallId, args) => {
|
|
const params = args as Record<string, unknown>;
|
|
const text = readStringParam(params, "text", { required: true });
|
|
const channel = readStringParam(params, "channel");
|
|
const cfg = opts?.config ?? loadConfig();
|
|
const result = await textToSpeech({
|
|
text,
|
|
cfg,
|
|
channel: channel ?? opts?.agentChannel,
|
|
});
|
|
|
|
if (result.success && result.audioPath) {
|
|
return {
|
|
content: [{ type: "text", text: "Generated audio reply." }],
|
|
details: {
|
|
audioPath: result.audioPath,
|
|
provider: result.provider,
|
|
media: {
|
|
mediaUrl: result.audioPath,
|
|
...(result.voiceCompatible ? { audioAsVoice: true } : {}),
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: result.error ?? "TTS conversion failed",
|
|
},
|
|
],
|
|
details: { error: result.error },
|
|
};
|
|
},
|
|
};
|
|
}
|