Skip to content

Commit d0ab0d9

Browse files
authored
refactor: share realtime voice activation helpers (#86615)
1 parent 170e0aa commit d0ab0d9

9 files changed

Lines changed: 548 additions & 364 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
66

77
### Changes
88

9+
- Voice: share activation-name matching and consult-transcript screening through the realtime voice SDK so Discord, browser voice, and meeting surfaces can reuse one implementation.
910
- Cron: default `cron.maxConcurrentRuns` to 8 so scheduled automations and their isolated agent turns can make progress in parallel without explicit configuration.
1011
- QA-Lab: add `qa coverage --match <query>` so focused proof selection can discover matching scenarios from existing metadata before running live or remote lanes.
1112
- Control UI: add an ephemeral Activity tab for sanitized live tool activity summaries without persisting raw telemetry. Fixes #12831. Thanks @BunsDev.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
390681a3d97af8c004db89ead136bd6cff693af5a0ddfe86a8e3c55a29a077eb plugin-sdk-api-baseline.json
2-
8dfaf69ee3d0a946bfdd1d8d97ef85262824d52c20854249f900db61f2a7f7b4 plugin-sdk-api-baseline.jsonl
1+
1d3e6177eeac57fc43736f7d5f76d8f825e1859ca625d268e97dc30b5567ea34 plugin-sdk-api-baseline.json
2+
6c093ff7c10bd81ee9d2c4fc5d07b206bc3a1f5acd0bad491cfc9e0df6689f6b plugin-sdk-api-baseline.jsonl

extensions/discord/src/doctor-contract.ts

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ import type {
33
ChannelDoctorLegacyConfigRule,
44
} from "openclaw/plugin-sdk/channel-contract";
55
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
6+
import {
7+
isSupportedRealtimeVoiceActivationName,
8+
normalizeRealtimeVoiceActivationNamePrefix,
9+
} from "openclaw/plugin-sdk/realtime-voice";
610
import { asObjectRecord, normalizeLegacyChannelAliases } from "openclaw/plugin-sdk/runtime-doctor";
711
import { resolveDiscordPreviewStreamMode } from "./preview-streaming.js";
812

913
const LEGACY_TTS_PROVIDER_KEYS = ["openai", "elevenlabs", "microsoft", "edge"] as const;
10-
const DISCORD_REALTIME_WAKE_NAME_MAX_WORDS = 2;
1114
type AgentBindingConfig = NonNullable<OpenClawConfig["bindings"]>[number];
1215

1316
function hasLegacyTtsProviderKeys(value: unknown): boolean {
@@ -78,31 +81,15 @@ function hasLegacyDiscordAccountGuildChannelAgentId(value: unknown): boolean {
7881
return Object.values(accounts).some((account) => hasLegacyDiscordGuildChannelAgentId(account));
7982
}
8083

81-
function realtimeWakeNameWordCount(value: string): number {
82-
return Array.from(value.matchAll(/[a-z0-9]+/gi)).length;
83-
}
84-
85-
function normalizeRealtimeWakeName(value: string): string | undefined {
86-
const words = Array.from(value.matchAll(/[a-z0-9]+/gi), (match) => match[0]);
87-
if (words.length === 0) {
88-
return undefined;
89-
}
90-
return words.slice(0, DISCORD_REALTIME_WAKE_NAME_MAX_WORDS).join(" ");
91-
}
92-
93-
function isSupportedRealtimeWakeName(value: string): boolean {
94-
const wordCount = realtimeWakeNameWordCount(value);
95-
return wordCount >= 1 && wordCount <= DISCORD_REALTIME_WAKE_NAME_MAX_WORDS;
96-
}
97-
9884
function hasUnsupportedRealtimeWakeNamesInVoice(value: unknown): boolean {
9985
const voice = asObjectRecord(value);
10086
const realtime = asObjectRecord(voice?.realtime);
10187
const wakeNames = realtime?.wakeNames;
10288
return Array.isArray(wakeNames)
10389
? wakeNames.length === 0 ||
10490
wakeNames.some(
105-
(wakeName) => typeof wakeName === "string" && !isSupportedRealtimeWakeName(wakeName),
91+
(wakeName) =>
92+
typeof wakeName === "string" && !isSupportedRealtimeVoiceActivationName(wakeName),
10693
)
10794
: false;
10895
}
@@ -231,10 +218,10 @@ function normalizeUnsupportedRealtimeWakeNames(
231218
let normalized = 0;
232219
let removed = 0;
233220
const nextWakeNames = wakeNames.flatMap((wakeName) => {
234-
if (typeof wakeName !== "string" || isSupportedRealtimeWakeName(wakeName)) {
221+
if (typeof wakeName !== "string" || isSupportedRealtimeVoiceActivationName(wakeName)) {
235222
return [wakeName];
236223
}
237-
const nextWakeName = normalizeRealtimeWakeName(wakeName);
224+
const nextWakeName = normalizeRealtimeVoiceActivationNamePrefix(wakeName);
238225
if (!nextWakeName) {
239226
removed += 1;
240227
return [];

0 commit comments

Comments
 (0)