feat(ui): name a session with a three-word slug - #197
Conversation
Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
senamakel has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
🚧 Files skipped from review as they are similar to previous changes (9)
📝 WalkthroughWalkthroughSession labels and TUI rail titles now use a shared slug utility. The utility filters words, handles contractions and filler terms, bounds scanning, and limits output. Session-history and rail tests now verify slugged labels and terminal-cell clipping. ChangesSession slugging
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant PromptOrThreadTitle
participant slug
participant SessionSummary
participant RailRenderer
PromptOrThreadTitle->>slug: prompt or title text
slug->>SessionSummary: optional session label
slug->>RailRenderer: normalized rail title
RailRenderer->>RailRenderer: clip to 48 terminal cells
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8cc717399f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # src/tui/src/ui/app/render/agents/rail/harness_line/layout.rs # src/tui/src/ui/app/render/agents/rail/rows.rs
…e string Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
senamakel has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Babysitter status: READY_FOR_APPROVAL Inspected head: Fixes pushed this loop:
Validation: CI: Rust SDK, Rust SDK (Windows), Vendored core resolution, E2E (docker + tmux + opencode), Coverage (>= 80% lines) — all SUCCESS. CodeRabbit: approved. Feedback: Codex's scan-bound finding fixed and replied in-thread (resolved). Greptile hit its trial credit limit on both passes (no actual findings to act on). CodeRabbit's first pass was rate-limited, its second pass approved with no comments. Note for reviewers: No unresolved threads, no changes requested. Handing off to |
… title openhuman#5412 landed as e29bfc66f, so the gitlink can move off the pre-merge pin. The core now names a thread in at most three ordinary words; this crate keeps rendering its own kebab slug for the rails. Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
senamakel has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30500fce13
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/tui/src/ui/app/render/agents/rail/rows.rs`:
- Around line 232-239: Update display_session_title to apply the rail’s
48-terminal-cell width limit to the slug result before returning it, preserving
safe Unicode boundaries and existing slug behavior. Add a regression test using
wide Unicode characters such as 界 that verifies the returned title does not
exceed 48 display cells.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cf22c56b-d244-4d36-b711-39b43e189b2f
📒 Files selected for processing (11)
src/sdk/src/session_history/README.mdsrc/sdk/src/session_history/summary.rssrc/sdk/src/session_history/tests.rssrc/sdk/src/session_history/types.rssrc/sdk/src/ui/util.rssrc/sdk/src/ui/util_tests.rssrc/tui/src/ui/app/render/agents/rail/harness_line/layout.rssrc/tui/src/ui/app/render/agents/rail/rows.rssrc/tui/src/ui/app/render/agents/rail/status_line_tests.rssrc/tui/src/ui/app/render/agents/rail/tests.rsvendor/openhuman
The row rendering now accounts for Unicode character widths when calculating layout, ensuring that multi-byte characters are displayed correctly without breaking alignment. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Session titles are now clipped to a maximum of 48 terminal cells in the agent rail rows, preventing overly long Unicode names from overflowing the row layout. This complements the existing character-based slug truncation by accounting for wide characters that occupy multiple columns. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Session titles are now truncated to fit the rail's width in terminal cells rather than characters, preventing wide characters from overflowing the pane. The clipping preserves whole grapheme sequences and appends an ellipsis when a title is cut short. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a test asserting that session titles made of wide characters are clipped a second time by display width, since the existing slug-based character ceiling does not account for double-width columns. Co-authored-by: Medulla <medulla@tinyhumans.ai>
The filler word list now includes common contractions like "let's", "I'm", and "you're" to prevent them from appearing in session slugs. Apostrophes are stripped before matching, so contractions are recognized in their letter-only form, ensuring conversational prompts produce cleaner slugs. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Slug generation now drops apostrophes from the source text instead of treating them as word separators, so contractions such as "don't" remain a single word in the resulting slug. The character scan bound is still applied before filtering, preserving the existing limit on work performed. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Apostrophes are now dropped instead of treated as word breaks, so contractions like "don't" remain a single word in session slugs. The documentation also clarifies that the slug length is measured in characters, not terminal cells, so callers rendering into fixed-width columns should clip the result again. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add tests confirming that apostrophes inside contractions are treated as word breaks without leaving orphaned letters behind, and that typographic apostrophes behave the same way. Co-authored-by: Medulla <medulla@tinyhumans.ai>
…record The merge of main recorded vendor/openhuman at e29bfc66, which neither parent points at: main and this branch both record 202b313e. The stray bump paired the newer core with the older tinyagents this tree vendors, and openhuman then failed to compile under --all-targets. Bumping the embedded core is its own change, and independent of this one: the slugging here shapes whatever title arrives, whether or not the core names threads in three words itself. Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
💡 Codex Review
When a running harness advertises a punctuation/control-only title such as "---", display_session_title now returns an empty string, but this map still resolves the task as Some(""). The lane consequently renders a dangling ·, and if this is the newest running task it also masks an older task with a meaningful title. Filter the displayed title when it is empty, as the status-line path already does.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Session titles that consist only of punctuation, such as "---", slugify to an empty string. Treating these as valid titles caused a dangling separator to be rendered and, because the newest running task takes precedence, could hide a real title from an older task. The title is now filtered out when empty. Co-authored-by: Medulla <medulla@tinyhumans.ai>
The session title rendering now delegates to the existing `lane_title` helper, which already handles the edge case where a title of pure punctuation slugs to an empty string. This avoids rendering a dangling separator and prevents an older task's real title from being hidden when the newest running task has no meaningful title. Co-authored-by: Medulla <medulla@tinyhumans.ai>
The thread name was previously converted to a string slice before being passed to the lane title function, which caused a borrow conflict. Now the closure borrows the title directly, avoiding the temporary dereference and fixing the compilation error. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added a helper that filters out empty or punctuation-only harness titles before rendering rail rows, preventing dangling separators and ensuring older tasks with meaningful titles are not hidden by newer empty ones. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add the missing `lane_title` import to the rail rendering tests so the test module can reference it, aligning the imports with the current code structure. Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a test asserting that titles which slug to nothing, such as punctuation-only or control-character strings, are not treated as lane titles. This prevents a dangling separator from being rendered and avoids masking older tasks that do have real titles. Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test previously asserted that all-filler input like "okay so the" produces no lane title, but the slugging logic actually generates a stable, non-empty slug for such input. The assertion now expects the generated slug to be returned, reflecting the actual behavior where filler text still yields a usable lane title. Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test for lane titles that slug to nothing now includes empty strings and whitespace with escape sequences, and clarifies that escape sequences alone still produce a slug from any alphanumeric content. This tightens the coverage around the edge cases that previously left the dangling separator behavior under-tested. Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Babysitter status: READY_FOR_APPROVAL Inspected head: Feedback worked this pass Codex's P2 on Rather than bury the rule in a closure, the fix names it as a seam so it is testable — the rail resolver now goes through pub(super) fn lane_title(title: &str) -> Option<String> {
let displayed = display_session_title(title);
(!displayed.is_empty()).then_some(displayed)
}Regression test
Validation on One caveat, not caused by this PR: three CI on the previous head: Rust SDK, Rust SDK (Windows), Vendored core resolution, E2E (docker + tmux + opencode), Coverage (>= 80% lines) all pass; CodeRabbit approved. Re-running against No unresolved review threads and no changes-requested verdicts. Greptile's trial has expired, so its "reviews" on this PR carry no findings. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Babysitter status: WAITING_ON_CI — blocked on a GitHub Actions runner outage, not on this PR. Inspected head: Review board: zero. No unresolved threads, no changes-requested verdicts. Nothing new arrived this pass — Greptile's trial has expired so its "reviews" carry no findings, and CodeRabbit's latest run posted no comments. Codex's P2 on Pushed this pass
The three failing checks were infrastructure, not code. Rust SDK, Coverage, and E2E all failed at exactly 15m02s on run
That is org-wide right now, not specific to this PR — the CI run for Local validation on
Correcting my own note from last pass. I previously reported three Outstanding: only a green CI run. No code or review work remains. |
The push of 643bcfb never produced a GitHub Actions workflow run: every other app created a check suite for that commit, github-actions did not. With no Rust SDK / Rust SDK (Windows) / E2E check present the ruleset cannot be satisfied, so the PR sits BLOCKED on absent checks rather than failing ones. This empty commit re-fires the synchronize event; it is squashed away on merge. Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Babysitter status: WAITING_ON_CI — blocked on GitHub Actions, not on this PR. Inspected head: Review board: zero. Why the merge is still BLOCKED. The
This is server-side, not branch-specific. The prior run on this branch ( What I tried, short of churning the diff: cancelling and then deleting the wedged run (both refused by the API), and closing/reopening the PR to re-fire the Local validation on
One honest caveat on that test run: the first invocation reported Outstanding: a GitHub Actions run that actually gets scheduled. There is no code or review work left. |
Summary
A session's name is now a three-word kebab slug —
fix-session-handoff— everywhere one is shown, instead of a truncated prompt or a whole harness sentence.Three surfaces, one rule:
medulla sessions, resume rows): the first human prompt was stored whole and cut at 72 chars. It is now slugged.fix-session-handoff.Problem
Every one of those slots is scanned, not read, and each was showing a string sized for something else. A prompt's leading words are usually conversational scaffolding ("okay so can you please…"), so the words that identify a session were exactly the ones truncation dropped; and the rail is measured against its widest row, so one long title widened the whole sidebar.
The two paths also disagreed with each other:
session_historytruncated at 72 chars with an ellipsis, the rail flattened control bytes and cut at 48 cells. Two shapes for one concept.Solution
medulla::ui::util::slugis the single shaper: split on every non-alphanumeric character, lowercase, drop filler words (okay,so,can,you,please,the…), keep the firstSLUG_MAX_WORDS(3), stop beforeSLUG_MAX_CHARS(48).Design notes:
display_session_title's hand-rolled control-byte scrub and width walk rather than sitting beside it.first_prompt_textstill returnsOption, so the(no prompt)fallback for a session with nothing usable is unchanged.The generator side is a matching change in tinyhumansai/openhuman#5412, which asks the model for the same shape and enforces it on the stored thread title. This PR is the consumer side and stands alone: it reshapes what medulla renders regardless of what any harness advertises.
Validation
cargo test— full workspace green (sdk + tui, unit/feature/e2e).cargo clippy --all-targets -- -D warnings— clean.cargo fmt --check— clean.New cases cover the slug rules (three-word cap, filler removal, all-filler fallback, punctuation/control-byte breaks, the length ceiling, empty input), the history label, and both rail surfaces.
Notes for reviewers
medulla::ui::util::{slug, SLUG_MAX_WORDS, SLUG_MAX_CHARS}added.session_history's internaltruncate_label/LABEL_MAXare gone;RecentSession.labelkeeps its type and its(no prompt)fallback, so themedulla sessionsJSON shape is unchanged — only the string is shorter.vendor/openhumangitlink now points ate29bfc66f, the merge of openhuman#5412. That PR shortens generated thread titles to at most three ordinary words ("Fix session handoff"); this crate keeps rendering its own kebab slug, which is the shape its terminal rails want. Fullcargo testre-run green against the bumped core.Summary by CodeRabbit
New Features
Documentation