Skip to content

fix(inworld): use truncateUtf16Safe for error body and parse error truncation#102608

Merged
steipete merged 2 commits into
openclaw:mainfrom
lzyyzznl:fix/truncateUtf16Safe-inworld-tts
Jul 9, 2026
Merged

fix(inworld): use truncateUtf16Safe for error body and parse error truncation#102608
steipete merged 2 commits into
openclaw:mainfrom
lzyyzznl:fix/truncateUtf16Safe-inworld-tts

Conversation

@lzyyzznl

@lzyyzznl lzyyzznl commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

The Inworld speech plugin bounded HTTP error bodies and malformed NDJSON lines with raw UTF-16 slicing. Emoji at the 400- or 80-code-unit boundary could produce malformed diagnostic text.

Why This Change Was Made

Use the existing plugin-SDK truncateUtf16Safe helper at both diagnostic boundaries while retaining the byte caps, whitespace normalization, character limits, and ellipsis policy.

User Impact

Inworld TTS failures now produce valid Unicode diagnostics. Requests, streaming audio parsing, byte limits, voice behavior, authentication, and configuration are unchanged.

Evidence

  • node ../../node_modules/vitest/vitest.mjs run --config test/vitest/vitest.extensions.config.ts extensions/inworld/tts.test.ts — 28 passed
  • exact HTTP error-body assertion at the 400-unit emoji boundary
  • exact malformed-line assertion at the 80-unit emoji boundary
  • oxfmt, focused oxlint, git diff --check
  • fresh branch autoreview: clean, no actionable findings

No live credentialed call is needed because request construction and upstream response handling are unchanged; focused tests drive real Response bodies through both error paths.

Risk

Low. Two presentation-only substitutions using an established shared helper; no API, config, dependency, or state change.

AI-assisted

Initial patch generated with Claude Code; maintainer review added exact public-path regression coverage.

…uncation

Two .slice(0, N) truncation sites in the Inworld TTS extension may
cut UTF-16 surrogate pairs in half when the error body or parse error
message contains multi-byte characters such as emoji. Replace both
with truncateUtf16Safe to keep the truncated output valid Unicode.
@openclaw-barnacle openclaw-barnacle Bot added extensions: inworld Extension: inworld size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 6:19 AM ET / 10:19 UTC.

Summary
The PR replaces two raw Inworld TTS diagnostic truncations with truncateUtf16Safe from the plugin SDK text utility runtime.

PR surface: Source +1. Total +1 across 1 file.

Reproducibility: yes. from source inspection: a mocked Inworld HTTP error body or malformed stream line that places a surrogate pair across the 400- or 80-code-unit truncation boundary would return a dangling surrogate on current main. I did not run a live Inworld failure path in this read-only review.

Review metrics: none identified.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted terminal output, copied output, or logs from an Inworld TTS failure path containing a surrogate-pair character at the truncation boundary.
  • After adding proof, update the PR body so ClawSweeper can re-review automatically, or ask a maintainer to comment @clawsweeper re-review if it does not.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body has mechanical evidence but no after-fix real behavior proof from a real Inworld TTS run, terminal output, copied output, or redacted logs; private values such as API keys and endpoints should be redacted. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Contributor real-behavior proof is still missing; CI and existing tests do not replace proof from a real setup for an external PR.
  • [P1] The PR is mergeable but behind current main, so exact-head checks should refresh after proof or rebase.

Maintainer options:

  1. Decide the mitigation before merge
    Land the narrow helper replacement after the contributor adds redacted after-fix proof showing the Inworld TTS error or parse-error path preserves valid Unicode at a surrogate boundary.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] The remaining blocker is contributor-provided real behavior proof and refreshed exact-head review, not an automated code repair.

Security
Cleared: The diff is a one-file plugin runtime import and string-truncation replacement with no dependency, workflow, lockfile, secret-handling, package-resolution, or code-execution surface added.

Review details

Best possible solution:

Land the narrow helper replacement after the contributor adds redacted after-fix proof showing the Inworld TTS error or parse-error path preserves valid Unicode at a surrogate boundary.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: a mocked Inworld HTTP error body or malformed stream line that places a surrogate pair across the 400- or 80-code-unit truncation boundary would return a dangling surrogate on current main. I did not run a live Inworld failure path in this read-only review.

Is this the best way to solve the issue?

Yes for the code shape: using the exported truncateUtf16Safe helper at the two plugin-local diagnostic truncation sites is the narrowest maintainable fix. A local helper or new API surface would add unnecessary surface area.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 2f66c3c0c845.

Label changes

Label justifications:

  • P3: The PR fixes a small diagnostic text-truncation edge case in one bundled plugin with low blast radius.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body has mechanical evidence but no after-fix real behavior proof from a real Inworld TTS run, terminal output, copied output, or redacted logs; private values such as API keys and endpoints should be redacted. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +1. Total +1 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 3 2 +1
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 3 2 +1

What I checked:

  • Current-main error-body truncation: Current main still truncates the collapsed Inworld HTTP error snippet with collapsed.slice(0, INWORLD_ERROR_BODY_MAX_CHARS), which can leave a dangling surrogate before the ellipsis. (extensions/inworld/tts.ts:60, 2f66c3c0c845)
  • Current-main parse-error truncation: Current main still truncates the Inworld non-JSON stream parse diagnostic with trimmed.slice(0, 80), which has the same surrogate-pair boundary problem. (extensions/inworld/tts.ts:179, 2f66c3c0c845)
  • Helper contract: truncateUtf16Safe floors the limit and delegates to sliceUtf16Safe(input, 0, limit), whose boundary checks avoid returning dangling surrogate halves. (packages/normalization-core/src/utf16-slice.ts:44, 2f66c3c0c845)
  • Plugin SDK export: openclaw/plugin-sdk/text-utility-runtime already exports truncateUtf16Safe, and the subpath is listed in package exports and the plugin SDK entrypoint registry. (src/plugin-sdk/text-utility-runtime.ts:21, 2f66c3c0c845)
  • Adjacent Inworld tests: Existing tests cover Inworld HTTP error and malformed stream paths, but they do not prove the new surrogate-boundary behavior or a real Inworld setup after this PR. (extensions/inworld/tts.test.ts:421, 2f66c3c0c845)
  • Live PR proof state: The live PR is open, mergeable but behind, has the status: 📣 needs proof label, and the only ClawSweeper review comment asks for real behavior proof; no contributor proof has been added since. (3230669d953a)

Likely related people:

  • Alix-007: GitHub path history and live PR metadata show this account authored the Inworld bounded TTS/error-response read work containing the HTTP error-body truncation site. (role: recent area contributor; confidence: high; commits: 4c8470c0699c, dde714102644; files: extensions/inworld/tts.ts, extensions/inworld/tts.test.ts)
  • cshape: GitHub path history shows this account authored the original bundled Inworld speech provider work where the stream parse diagnostic path came from. (role: introduced behavior; confidence: high; commits: 0bcb4c95c185, e0a5e6a239f1; files: extensions/inworld/tts.ts, extensions/inworld/tts.test.ts, extensions/inworld/speech-provider.ts)
  • solodmd: GitHub path history shows this account recently changed the same Inworld TTS module for malformed API response handling. (role: recent area contributor; confidence: medium; commits: c914f896a236, a8d0a1ff9228; files: extensions/inworld/tts.ts)
  • steipete: Live PR metadata shows this account merged the original Inworld provider work, and GitHub path history shows recent normalization-helper work under this account. (role: reviewer/merger and adjacent helper contributor; confidence: medium; commits: 0bcb4c95c185, 062f88e3e3af, b22c36f1125c; files: extensions/inworld/tts.ts, packages/normalization-core/src/utf16-slice.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-09T09:38:29.051Z sha 3230669 :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 9, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Land-ready review complete on exact head 9c4307c68d338c304f2867bc3b09200a9d849b53.

  • Applied the shared UTF-16-safe truncator to both Inworld TTS diagnostic boundaries: the 400-unit HTTP error body and the 80-unit malformed NDJSON line preview.
  • Added exact response-path regressions with surrogate pairs crossing each limit; both retain the existing ellipsis and never emit a dangling surrogate.
  • Focused Inworld provider suite: 28 passed.
  • Static proof: focused oxfmt, oxlint, git diff --check; fresh autoreview clean.
  • Native prepare gate: exact-head hosted CI/Testbox passed; remote PR head tree matches the prepared tree.

No docs or changelog entry is required because this only repairs bounded provider diagnostics.

@steipete
steipete merged commit 0866391 into openclaw:main Jul 9, 2026
94 of 95 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
…uncation (openclaw#102608)

* fix(inworld): use truncateUtf16Safe for error body and parse error truncation

Two .slice(0, N) truncation sites in the Inworld TTS extension may
cut UTF-16 surrogate pairs in half when the error body or parse error
message contains multi-byte characters such as emoji. Replace both
with truncateUtf16Safe to keep the truncated output valid Unicode.

* test(inworld): cover UTF-16-safe TTS errors

Co-authored-by: lizeyu-xydt <[email protected]>

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: inworld Extension: inworld P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants