Skip to content

fix(gateway): use code-point budget for fallback chunk split boundary - #62901

Open
sprmn24 wants to merge 1 commit into
NousResearch:mainfrom
sprmn24:fix/stream-consumer-utf16-chunk-split
Open

fix(gateway): use code-point budget for fallback chunk split boundary#62901
sprmn24 wants to merge 1 commit into
NousResearch:mainfrom
sprmn24:fix/stream-consumer-utf16-chunk-split

Conversation

@sprmn24

@sprmn24 sprmn24 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

_split_text_chunks() correctly calculates _cp_budget (code-point boundary) via _custom_unit_to_cp() for adapters using custom length functions (e.g. UTF-16 unit counters). However, the fallback path when no suitable newline is found was using limit (raw platform units) instead of _cp_budget (code points) as the split boundary.

For adapters measuring UTF-16 units, emoji and other astral-plane characters count as 2 units each, so slicing at limit instead of _cp_budget can produce chunks that substantially exceed MAX_MESSAGE_LENGTH and fail delivery.

This PR fixes both the split boundary and the too-short newline guard to consistently use _cp_budget.

Related Issue

None

Type of Change

  • 🐛 Bug fix

Changes Made

  • gateway/stream_consumer.py L977-978: changed split_at < limit // 2split_at < _cp_budget // 2 and split_at = limitsplit_at = _cp_budget in _split_text_chunks()

How to Test

  1. Configure a UTF-16 length adapter (e.g. Telegram)
  2. Send a message containing emoji-heavy text that exceeds the platform limit
  3. Confirm all returned chunks satisfy len_fn(chunk) <= limit

Checklist

  • I have read the Contributing Guide
  • Commit messages follow Conventional Commits format
  • I have checked for duplicate PRs
  • This PR is scoped to a single fix
  • pytest tests/ -q passed
  • Platform: Windows 11 + WSL2 Ubuntu

Documentation & Housekeeping

  • README/docs update: N/A
  • cli-config.yaml.example: N/A
  • CONTRIBUTING.md/AGENTS.md: N/A
  • Cross-platform impact: N/A
  • Tool description/schema: N/A

Screenshots / Logs

N/A

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter P2 Medium — degraded but workaround exists duplicate This issue or pull request already exists labels Jul 11, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #42523 — same _cp_budget fix in the same _split_text_chunks() no-newline fallback (UTF-16 unit vs codepoint slice boundary). #42523 is the earliest open PR for this fix and is the canonical one. Also related to #55843 (same fix + regression tests, carries issue #55844). Part of the UTF-16 split cluster (#11467/#23455/#11170/#11522).

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating the fallback boundary mismatch. The proposed _cp_budget slice is correct for _split_text_chunks(): _custom_unit_to_cp() explicitly returns the largest code-point offset fitting the custom length budget (gateway/platforms/base.py:167-183).

Problems

  • The same unsafe fallback remains in the existing-message streaming overflow loop. It computes _cp_budget at gateway/stream_consumer.py:701-704, but falls back to _safe_limit as a Python slice offset at gateway/stream_consumer.py:705-707.
  • This PR adds no UTF-16 regression coverage. The existing fallback test (tests/gateway/test_stream_consumer.py:778-805) uses a MagicMock/default len() path and cannot assert the custom-unit chunk invariant.

Suggested changes

  • Add a direct UTF-16 no-newline regression asserting every _split_text_chunks() result satisfies utf16_len(chunk) <= limit and round-trips the input.
  • Apply the same _cp_budget boundary correction to the sibling streaming-edit fallback at gateway/stream_consumer.py:705-706.

Automated hermes-sweeper review.

if split_at < limit // 2:
split_at = limit
if split_at < _cp_budget // 2:
split_at = _cp_budget

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a direct UTF-16 regression for this branch: an emoji-only, no-newline input should produce only chunks whose utf16_len is within limit. The current fallback tests exercise default len() behavior and would not catch this unit/code-point mismatch.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 12, 2026
@sprmn24
sprmn24 force-pushed the fix/stream-consumer-utf16-chunk-split branch from 435dfc6 to c5c9383 Compare July 12, 2026 22:22
fix(gateway): use _cp_budget boundary in UTF-16 chunk split fallback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants