openclaw / src /media-understanding /echo-transcript.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
253e783 verified
Raw History Blame Contribute Delete
2.95 kB
// Transcript echo delivery sends best-effort preflight audio transcripts back
// through deliverable message channels.
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/types.js";
import { logVerbose, shouldLogVerbose } from "../globals.js";
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
import { isDeliverableMessageChannel } from "../utils/message-channel.js";
// The message runtime is heavy and only needed when echo delivery actually
// proceeds to a deliverable channel.
const loadMessageRuntime = createLazyRuntimeModule(() => import("../channels/message/runtime.js"));
/** Default operator-visible transcript echo format for preflight audio transcription. */
export const DEFAULT_ECHO_TRANSCRIPT_FORMAT = '📝 "{transcript}"';
function formatEchoTranscript(transcript: string, format: string): string {
// Function replacer keeps `$` sequences in the transcript literal instead of
// being parsed as String.prototype.replace substitution patterns.
return format.replace("{transcript}", () => transcript);
}
/** Sends a best-effort transcript echo back to the originating deliverable chat. */
export async function sendTranscriptEcho(params: {
ctx: MsgContext;
cfg: OpenClawConfig;
transcript: string;
format?: string;
logSuccess?: boolean;
failureLogPrefix?: string;
}): Promise<void> {
const { ctx, cfg, transcript } = params;
const channel = ctx.Provider ?? ctx.Surface ?? "";
const to = ctx.OriginatingTo ?? ctx.From ?? "";
if (!channel || !to) {
if (shouldLogVerbose()) {
logVerbose("media: echo-transcript skipped (no channel/to resolved from ctx)");
}
return;
}
const normalizedChannel = normalizeLowercaseStringOrEmpty(channel);
if (!isDeliverableMessageChannel(normalizedChannel)) {
if (shouldLogVerbose()) {
logVerbose(
`media: echo-transcript skipped (channel "${normalizedChannel}" is not deliverable)`,
);
}
return;
}
const text = formatEchoTranscript(transcript, params.format ?? DEFAULT_ECHO_TRANSCRIPT_FORMAT);
try {
const { sendDurableMessageBatchCore } = await loadMessageRuntime();
const send = await sendDurableMessageBatchCore({
cfg,
channel: normalizedChannel,
to,
accountId: ctx.AccountId ?? undefined,
threadId: ctx.MessageThreadId ?? undefined,
payloads: [{ text }],
bestEffort: true,
durability: "best_effort",
});
if (send.status === "failed") {
throw send.error;
}
if ((params.logSuccess ?? true) && shouldLogVerbose()) {
logVerbose(`media: echo-transcript sent to ${normalizedChannel}/${to}`);
}
} catch (err) {
const prefix = params.failureLogPrefix ?? "media: echo-transcript delivery failed";
logVerbose(`${prefix}: ${String(err)}`);
}
}