Typed Snapshot: move Telegram preview styling out of pi transport #36

Merged
weiwen merged 1 commit from sandcastle/issue-32 into main 2026-07-06 01:09:56 +08:00
Owner

Summary

Introduces a typed Snapshot enum (Text(String) | Thinking(String)) in src/pi.rs to replace the raw String previously sent over the snapshot channel. This separates what the pi transport observed from how a given interface chooses to render it.

Key decisions:

  • The pi transport now emits raw content with no presentation logic — no emoji prefix, no character trim. Presentation is the caller's responsibility.
  • thinking_preview (emoji prefix + 3800-char tail trim) and its constant were moved verbatim from src/pi.rs to src/telegram/mod.rs, which is the only caller that needs Telegram-specific sizing.
  • The HTTP interface already discarded snapshots; its channel type annotation is updated to Snapshot for consistency (src/http.rs).
  • Tests in pi.rs were updated to assert on typed Snapshot variants; three focused unit tests for thinking_preview were added directly in src/telegram/mod.rs.

Reviewer should check:

  • The Snapshot enum variants and their doc comments in src/pi.rs.
  • That thinking_preview in src/telegram/mod.rs is functionally identical to what was removed from src/pi.rs.
  • The tokio::select! arms in deliver_response (telegram) correctly dispatch Snapshot::Text and Snapshot::Thinking.

Closes #32

## Summary Introduces a typed `Snapshot` enum (`Text(String)` | `Thinking(String)`) in `src/pi.rs` to replace the raw `String` previously sent over the snapshot channel. This separates *what* the pi transport observed from *how* a given interface chooses to render it. **Key decisions:** - The pi transport now emits raw content with no presentation logic — no emoji prefix, no character trim. Presentation is the caller's responsibility. - `thinking_preview` (emoji prefix + 3800-char tail trim) and its constant were moved verbatim from `src/pi.rs` to `src/telegram/mod.rs`, which is the only caller that needs Telegram-specific sizing. - The HTTP interface already discarded snapshots; its channel type annotation is updated to `Snapshot` for consistency (`src/http.rs`). - Tests in `pi.rs` were updated to assert on typed `Snapshot` variants; three focused unit tests for `thinking_preview` were added directly in `src/telegram/mod.rs`. **Reviewer should check:** - The `Snapshot` enum variants and their doc comments in `src/pi.rs`. - That `thinking_preview` in `src/telegram/mod.rs` is functionally identical to what was removed from `src/pi.rs`. - The `tokio::select!` arms in `deliver_response` (telegram) correctly dispatch `Snapshot::Text` and `Snapshot::Thinking`. Closes #32
RALPH: Typed Snapshot: move Telegram preview styling out of pi transport
All checks were successful
CI / check (pull_request) Successful in 2m5s
dff9573e94
Closes #32

Defines `pub enum Snapshot { Text(String), Thinking(String) }` in the pi
module with `PartialEq` so dedup stays in pi. The streaming channel
becomes `UnboundedSender<Snapshot>` end-to-end. Pi emits `Text` when the
assistant message carries text, else `Thinking` with the raw thinking
string — no emoji, no trim. The 💭 prefix and tail-trim (now
`thinking_preview()` + `THINKING_PREVIEW_CHAR_LIMIT`) move into
`telegram/mod.rs`, which renders `Text` as-is and `Thinking` via
`preview()`. HTTP path passes a detached channel and ignores it, no
behaviour change there.

Key decisions:
- `last_snapshot: Option<Snapshot>` replaces `last_snapshot: String`; dedup
  uses `Some(&snapshot) != last_snapshot.as_ref()` to avoid cloning for the
  comparison.
- Pi stream-parsing tests updated to assert `Snapshot::Text`/`Snapshot::Thinking`
  variants; `test_thinking_preview_tail_bounded` replaced by
  `test_thinking_emits_raw_text_without_trim_or_emoji` (pi no longer trims).
- Three new tests for `thinking_preview()` added to telegram module.

Files changed:
- src/pi.rs: Snapshot enum, remove THINKING_PREVIEW_CHAR_LIMIT/thinking_preview,
  retype channel, update read_agent_response + all tests
- src/session.rs: retype snapshot_tx parameter
- src/http.rs: explicit ::<Snapshot> on detached channel
- src/telegram/mod.rs: import Snapshot, add thinking_preview, retype channel,
  render Text/Thinking variants, new tests

Blockers/notes:
- No Rust toolchain in sandbox; CI must validate compilation and tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
Owner

rebase on main

rebase on main
weiwen force-pushed sandcastle/issue-32 from dff9573e94
All checks were successful
CI / check (pull_request) Successful in 2m5s
to ae3d410bfb
Some checks failed
CI / check (pull_request) Successful in 2m8s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 1s
2026-07-05 21:16:20 +08:00
Compare
weiwen force-pushed sandcastle/issue-32 from ae3d410bfb
Some checks failed
CI / check (pull_request) Successful in 2m8s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 1s
to c162d27155
Some checks failed
CI / check (pull_request) Failing after 2s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 0s
2026-07-05 21:20:24 +08:00
Compare
weiwen force-pushed sandcastle/issue-32 from c162d27155
Some checks failed
CI / check (pull_request) Failing after 2s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 0s
to 94b7f65cf3
Some checks failed
CI / check (pull_request) Successful in 2m27s
PR Triage — label changes-requested reviews / triage-review (pull_request) Has been cancelled
2026-07-05 21:31:43 +08:00
Compare
weiwen force-pushed sandcastle/issue-32 from 94b7f65cf3
Some checks failed
CI / check (pull_request) Successful in 2m27s
PR Triage — label changes-requested reviews / triage-review (pull_request) Has been cancelled
to 8aed3cb04f
Some checks failed
CI / check (pull_request) Successful in 2m22s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 1s
2026-07-05 22:15:15 +08:00
Compare
weiwen force-pushed sandcastle/issue-32 from 8aed3cb04f
Some checks failed
CI / check (pull_request) Successful in 2m22s
PR Triage — label changes-requested reviews / triage-review (pull_request) Failing after 1s
to bc71ab5b69
All checks were successful
CI / check (pull_request) Successful in 1m56s
PR Triage — label changes-requested reviews / triage-review (pull_request) Successful in 0s
2026-07-05 23:03:19 +08:00
Compare
weiwen force-pushed sandcastle/issue-32 from bc71ab5b69
All checks were successful
CI / check (pull_request) Successful in 1m56s
PR Triage — label changes-requested reviews / triage-review (pull_request) Successful in 0s
to ab4e4753a5
All checks were successful
CI / check (pull_request) Successful in 1m21s
PR Triage — label changes-requested reviews / triage-review (pull_request) Successful in 1s
2026-07-06 01:03:01 +08:00
Compare
weiwen merged commit 764560b5a1 into main 2026-07-06 01:09:56 +08:00
weiwen deleted branch sandcastle/issue-32 2026-07-06 01:09:56 +08:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
weiwen/evie!36
No description provided.