fix: prevent fractional chunk limits from stalling text splitting (#117727)

* fix: normalize fractional text chunk limits

* fix: normalize markdown chunk limits

* fix: normalize direct newline chunk limits

* fix(matrix): reuse progress-safe text chunker

* test(matrix): align runtime API guard

* test(matrix): keep outbound shard topology stable

* fix(matrix): preserve facade chunk compatibility

* test(matrix): keep runtime export guard stable

* fix(matrix): normalize render-aware chunk limits

* test(matrix): type real-send assertions

* fix(matrix): preserve one-unit event limits

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Simone
2026-08-02 11:53:31 +02:00
committed by GitHub
parent a75b134231
commit 3f9b4519a9
12 changed files with 221 additions and 39 deletions
@@ -157,7 +157,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";',
'export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";',
'export type { WizardPrompter } from "openclaw/plugin-sdk/setup";',
'export function chunkTextForOutbound(text: string, limit: number): string[] { const chunks: string[] = []; let remaining = text; while (remaining.length > limit) { const window = remaining.slice(0, limit); const splitAt = Math.max(window.lastIndexOf("\\n"), window.lastIndexOf(" ")); const breakAt = splitAt > 0 ? splitAt : limit; chunks.push(remaining.slice(0, breakAt).trimEnd()); remaining = remaining.slice(breakAt).trimStart(); } if (remaining.length > 0 || text.length === 0) { chunks.push(remaining); } return chunks; }',
'export function chunkTextForOutbound(text: string, limit: number): string[] { if (text.length === 0) { return [""]; } if (Number.isFinite(limit) && limit > 0 && !Number.isInteger(limit)) { return chunkTextForOutboundSdk(text, limit); } const chunks: string[] = []; let remaining = text; while (remaining.length > limit) { const window = remaining.slice(0, limit); const splitAt = Math.max(window.lastIndexOf("\\n"), window.lastIndexOf(" ")); const breakAt = splitAt > 0 ? splitAt : limit; chunks.push(remaining.slice(0, breakAt).trimEnd()); remaining = remaining.slice(breakAt).trimStart(); } if (remaining.length > 0) { chunks.push(remaining); } return chunks; }',
],
[bundledPluginFile({
rootDir: ROOT_DIR,