mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-28 18:33:37 +00:00
refactor: share speech normalization helpers
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
import {
|
||||
normalizeApplyTextNormalization,
|
||||
normalizeLanguageCode,
|
||||
normalizeSeed,
|
||||
requireInRange,
|
||||
} from "openclaw/plugin-sdk/speech-core";
|
||||
|
||||
const DEFAULT_ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
|
||||
|
||||
function isValidVoiceId(voiceId: string): boolean {
|
||||
@@ -12,47 +19,6 @@ function normalizeElevenLabsBaseUrl(baseUrl?: string): string {
|
||||
return trimmed.replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
function normalizeLanguageCode(code?: string): string | undefined {
|
||||
const trimmed = code?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = trimmed.toLowerCase();
|
||||
if (!/^[a-z]{2}$/.test(normalized)) {
|
||||
throw new Error("languageCode must be a 2-letter ISO 639-1 code (e.g. en, de, fr)");
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function normalizeApplyTextNormalization(mode?: string): "auto" | "on" | "off" | undefined {
|
||||
const trimmed = mode?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = trimmed.toLowerCase();
|
||||
if (normalized === "auto" || normalized === "on" || normalized === "off") {
|
||||
return normalized;
|
||||
}
|
||||
throw new Error("applyTextNormalization must be one of: auto, on, off");
|
||||
}
|
||||
|
||||
function normalizeSeed(seed?: number): number | undefined {
|
||||
if (seed == null) {
|
||||
return undefined;
|
||||
}
|
||||
const next = Math.floor(seed);
|
||||
if (!Number.isFinite(next) || next < 0 || next > 4_294_967_295) {
|
||||
throw new Error("seed must be between 0 and 4294967295");
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
function requireInRange(value: number, min: number, max: number, label: string): void {
|
||||
if (!Number.isFinite(value) || value < min || value > max) {
|
||||
throw new Error(`${label} must be between ${min} and ${max}`);
|
||||
}
|
||||
}
|
||||
|
||||
function assertElevenLabsVoiceSettings(settings: {
|
||||
stability: number;
|
||||
similarityBoost: number;
|
||||
|
||||
@@ -6,8 +6,7 @@ export { resolveReactionMessageId } from "../channels/plugins/actions/reaction-m
|
||||
export { optionalStringEnum, stringEnum } from "../agents/schema/typebox.js";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import type { TSchema } from "@sinclair/typebox";
|
||||
import { stringEnum } from "../agents/schema/typebox.js";
|
||||
export { optionalStringEnum, stringEnum } from "../agents/schema/typebox.js";
|
||||
import { stringEnum as createStringEnum } from "../agents/schema/typebox.js";
|
||||
|
||||
/** Schema helper for channels that expose button rows on the shared `message` tool. */
|
||||
export function createMessageToolButtonsSchema(): TSchema {
|
||||
@@ -17,7 +16,7 @@ export function createMessageToolButtonsSchema(): TSchema {
|
||||
Type.Object({
|
||||
text: Type.String(),
|
||||
callback_data: Type.String(),
|
||||
style: Type.Optional(stringEnum(["danger", "success", "primary"])),
|
||||
style: Type.Optional(createStringEnum(["danger", "success", "primary"])),
|
||||
}),
|
||||
),
|
||||
{
|
||||
|
||||
@@ -3,4 +3,10 @@
|
||||
export type { SpeechProviderPlugin } from "../plugins/types.js";
|
||||
export type { SpeechVoiceOption } from "../tts/provider-types.js";
|
||||
|
||||
export { parseTtsDirectives } from "../tts/tts-core.js";
|
||||
export {
|
||||
normalizeApplyTextNormalization,
|
||||
normalizeLanguageCode,
|
||||
normalizeSeed,
|
||||
parseTtsDirectives,
|
||||
requireInRange,
|
||||
} from "../tts/tts-core.js";
|
||||
|
||||
@@ -37,13 +37,13 @@ function trimToUndefined(value?: string): string | undefined {
|
||||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function requireInRange(value: number, min: number, max: number, label: string): void {
|
||||
export function requireInRange(value: number, min: number, max: number, label: string): void {
|
||||
if (!Number.isFinite(value) || value < min || value > max) {
|
||||
throw new Error(`${label} must be between ${min} and ${max}`);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeLanguageCode(code?: string): string | undefined {
|
||||
export function normalizeLanguageCode(code?: string): string | undefined {
|
||||
const trimmed = code?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
@@ -55,7 +55,7 @@ function normalizeLanguageCode(code?: string): string | undefined {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function normalizeApplyTextNormalization(mode?: string): "auto" | "on" | "off" | undefined {
|
||||
export function normalizeApplyTextNormalization(mode?: string): "auto" | "on" | "off" | undefined {
|
||||
const trimmed = mode?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
@@ -67,7 +67,7 @@ function normalizeApplyTextNormalization(mode?: string): "auto" | "on" | "off" |
|
||||
throw new Error("applyTextNormalization must be one of: auto, on, off");
|
||||
}
|
||||
|
||||
function normalizeSeed(seed?: number): number | undefined {
|
||||
export function normalizeSeed(seed?: number): number | undefined {
|
||||
if (seed == null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user