Skip to content

Commit 079a704

Browse files
Alix-007steipete
andauthored
fix(voice-call): keep realtime context truncation UTF-16 safe (#101304)
* Fix UTF-16-safe realtime context truncation * test(voice-call): tighten UTF-16 context regression --------- Co-authored-by: Peter Steinberger <[email protected]>
1 parent 395fbb8 commit 079a704

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

extensions/voice-call/src/realtime-agent-context.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,28 @@ describe("buildRealtimeVoiceInstructions", () => {
9393
expect(instructions).toContain("### IDENTITY.md");
9494
expect(instructions).not.toContain("do not include");
9595
});
96+
97+
it("truncates injected context without splitting UTF-16 surrogate pairs", async () => {
98+
const agentId = "abc🚀tail";
99+
const expectedContext = "OpenClaw agent voice context:\n\n- Agent id: abc";
100+
const config = createConfig({
101+
agentContext: {
102+
enabled: true,
103+
maxChars: expectedContext.length + 33,
104+
includeIdentity: false,
105+
includeWorkspaceFiles: false,
106+
files: [],
107+
},
108+
});
109+
config.agentId = agentId;
110+
111+
const instructions = await buildRealtimeVoiceInstructions({
112+
baseInstructions: "Base voice instructions.",
113+
config,
114+
coreConfig: { agents: { list: [{ id: agentId }] } } as CoreConfig,
115+
agentRuntime: createAgentRuntime("/unused"),
116+
});
117+
118+
expect(instructions).toBe(`Base voice instructions.\n\n${expectedContext}\n[truncated]`);
119+
});
96120
});

extensions/voice-call/src/realtime-agent-context.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
33
import { buildRealtimeVoiceAgentConsultPolicyInstructions } from "openclaw/plugin-sdk/realtime-voice";
44
import { root } from "openclaw/plugin-sdk/security-runtime";
55
import { normalizeOptionalString as normalizeString } from "openclaw/plugin-sdk/string-coerce-runtime";
6+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
67
import type { VoiceCallConfig } from "./config.js";
78
import type { CoreAgentDeps, CoreConfig } from "./core-bridge.js";
89

@@ -22,7 +23,7 @@ function limitText(text: string, maxChars: number): string {
2223
if (text.length <= maxChars) {
2324
return text;
2425
}
25-
return `${text.slice(0, Math.max(0, maxChars - 32)).trimEnd()}\n[truncated]`;
26+
return `${truncateUtf16Safe(text, Math.max(0, maxChars - 32)).trimEnd()}\n[truncated]`;
2627
}
2728

2829
/** Read configured workspace context files through the safe workspace root. */

0 commit comments

Comments
 (0)