Conversation
Matrix streams buffer-only (edit only at segment breaks / completion) by default, so short single-paragraph replies appear all at once. Add a streaming.matrix_progressive option (default false, preserving current behavior) that lets Matrix stream progressively via token-cadence m.replace edits, with the cursor still suppressed to avoid the tofu/white-box glyph some Matrix clients render. Also document connecting via Beeper (a hosted Matrix homeserver): a stdlib-only scripts/beeper_login.py helper that mints an access token via Beeper's org.matrix.login.jwt flow, plus a 'Connect via Beeper' guide and a 'Response Streaming' section in the Matrix docs, and list Matrix in the README platform line. - gateway/config.py: StreamingConfig.matrix_progressive (+ to_dict/from_dict) - gateway/run.py: honor it at both Matrix streaming sites - hermes_cli/config.py: surface it in DEFAULT_CONFIG (dashboard schema) - cli-config.yaml.example: document the new key - tests/gateway/test_config.py: defaults + coercion + roundtrip Signed-off-by: Chris Roth <chris@cjroth.com>
teknium1
left a comment
There was a problem hiding this comment.
Thanks for preserving the existing Matrix default while making the progressive path explicit. The premise is confirmed on current main: Matrix still forces buffer_only=True in both stream-consumer setup paths (gateway/run.py:16756 and gateway/run.py:18089).
Problems
- The PR changes both runtime branches (
gateway/run.py:16841,gateway/run.py:17847), but its tests only coverStreamingConfiground-tripping.GatewayStreamConsumerusesbuffer_onlyto suppress the interval/threshold edit path (gateway/stream_consumer.py:625-639), so add regression coverage for both branches. scripts/beeper_login.py:40adds a separate Beeper-specific authentication flow usingBEEPER-PRIVATE-API-PLEASE-DONT-USE. This vendor onboarding concern is independent from Matrix streaming and should be evaluated separately.
Suggested changes
- Exercise Matrix with the flag both off and on in each stream-consumer construction path, asserting the cursor remains empty and
buffer_onlyflips as intended. - Split the Beeper helper/docs into a separate change; add mocked HTTP-flow coverage if it remains in-tree.
Automated hermes-sweeper review.
| # Buffer-only (edit at segment breaks only) unless the | ||
| # operator opts into progressive streaming. Cursor stays | ||
| # suppressed either way to avoid the tofu-glyph artifact. | ||
| _buffer_only = not _scfg.matrix_progressive |
There was a problem hiding this comment.
Please add a runner-level regression test for this branch and the run_sync sibling: Matrix with the flag off must remain buffer-only, while the flag on must set buffer_only=False and retain the empty cursor. The added config tests do not exercise either runtime path.
| # Beeper's own clients and every community login script) — it is NOT a secret and | ||
| # NOT account-specific; it only gates the unauthenticated login endpoints. | ||
| BEEPER_API = "https://api.beeper.com" | ||
| BEEPER_BEARER = "BEEPER-PRIVATE-API-PLEASE-DONT-USE" |
There was a problem hiding this comment.
Please split this Beeper-specific authentication helper from the streaming change so its external API contract and maintenance scope can be reviewed independently.
What does this PR do?
On Matrix, response streaming is hardcoded to buffer-only mode (run.py sets _buffer_only = True for Platform.MATRIX at
both stream-consumer sites). That means the bot edits its reply only at segment breaks (paragraph boundaries) and on
completion — not on the time/character cadence used by other edit-capable platforms. The result: short,
single-paragraph replies appear all at once, reading as "no streaming," and there's no config knob to change it.
This PR adds a streaming.matrix_progressive option (default false, so existing behavior is unchanged) that lets Matrix
stream progressively via token-cadence m.replace edits. The streaming cursor stays suppressed on Matrix in both modes,
so you get a live-typing feel without the tofu/white-box glyph some Matrix clients render for the cursor.
I made this opt-in rather than flipping the default on purpose: the buffer-only default is deliberate (it keeps
m.replace edit traffic low and avoids the cursor artifact), so opt-in preserves current behavior for everyone while
letting operators who want live streaming turn it on and tune edit_interval / buffer_threshold for their homeserver's
rate limits.
It also documents connecting via Beeper (a hosted Matrix homeserver), since Beeper has no password login and trips
people up: a stdlib-only scripts/beeper_login.py helper that mints an access token through Beeper's
org.matrix.login.jwt flow, plus a "Connect via Beeper" guide and a "Response Streaming" section in the Matrix docs.
Related Issue
No existing issue tracks this specifically. It's adjacent to the Matrix streaming work in #37931. Happy to open a
tracking issue if preferred.
Fixes #
Type of Change
Changes Made
bool coercion.
(cursor stays suppressed).
dashboard/config schema.
How to Test
streaming:
enabled: true
matrix_progressive: true
"write a short paragraph about otters"). The reply should grow progressively via in-place edits, with no cursor glyph.
With matrix_progressive: false (default) the same reply updates only at paragraph breaks.
▎ Verified the progressive path live against Beeper (matrix.beeper.com) on Debian: replies stream via m.replace edits
▎ with the cursor suppressed (no tofu artifact).
Checklist
Code
etc.)
duplicate
Documentation & Housekeeping
change)
(https://github.com/NousResearch/hermes-agent/blob/main/CONTRIBUTING.md#cross-platform-compatibility) — or N/A
(pure-Python config + stdlib-only urllib helper)
Screenshots / Logs