Skip to content

fix(connector): name the oh-my-pi session after COTAL_NAME at join - #6

Merged
mattwilkinsonn merged 6 commits into
zheng-connector-upstreamfrom
cotal-connector-session-title
Jul 25, 2026
Merged

fix(connector): name the oh-my-pi session after COTAL_NAME at join#6
mattwilkinsonn merged 6 commits into
zheng-connector-upstreamfrom
cotal-connector-session-title

Conversation

@sealedsecurity-bot

Copy link
Copy Markdown

Names the oh-my-pi mesh session after COTAL_NAME so every agent's pane/terminal title reflects who it is, instead of a generic auto-title.

Problem

The connector launcher forwards COTAL_NAME into the spawned session's environment, but the extension had no agent-reachable way to set the session (pane/terminal) title — so every agent showed a generic auto-title regardless of its mesh identity. In a multi-pane wave that makes panes indistinguishable.

Fix

In the session_start handler (extensions/connector-oh-my-pi/src/extension.ts), after the hasUI/identity guard and started = true, call pi.setSessionName(config.name) when a name is resolved. Properties:

  • Guarded — only sets when the session name is unset (!ctx.sessionManager.getSessionName()), so a resumed or manually-/rename'd session is never clobbered.
  • Best-effort — a setSessionName failure is caught and logged, never breaking the mesh-join (the title is cosmetic; the join is not).
  • Interactive-only — rides the existing hasUI gate, so subagent/print/RPC sessions stay off the mesh and untouched.

Test

Extends extensions/connector-oh-my-pi/oh-my-pi-extension.smoke.ts with session-name regression coverage (4 behaviors): title set when unset, no-clobber when already named, non-interactive skip, and best-effort on setSessionName rejection. Red-green demonstrated for the set + no-clobber cases. pnpm --filter @cotal-ai/oh-my-pi run smoke:extension → green; connector typecheck + build green.

Base

Stacked on zheng-connector-upstream (PR #5, the zod-migrated SDK-16.3.12 connector that owns extension.ts's session_start handler). Retargets to sealed-fork when #5 merges.

Co-Authored-By: seal noreply@sealedsecurity.com

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seal-agent, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 659728d5-c422-4f28-a637-5e2705668961

📥 Commits

Reviewing files that changed from the base of the PR and between aacbea9 and 4222fdd.

📒 Files selected for processing (2)
  • extensions/connector-oh-my-pi/oh-my-pi-extension.smoke.ts
  • extensions/connector-oh-my-pi/src/extension.ts
📝 Walkthrough

Walkthrough

The OMP extension's session_start handler was changed to async, adding a detached best-effort session rename to config.name after mesh start, gated on interactivity and existing session name, with errors caught and logged. The corresponding smoke test was expanded to verify this behavior across several scenarios.

Changes

Session Title Rename on session_start

Layer / File(s) Summary
Async session_start handler with best-effort rename
extensions/connector-oh-my-pi/src/extension.ts
Handler is now async; after starting the mesh agent for interactive sessions, it conditionally sets the session name via setSessionName only if unset, catching and logging errors without blocking the mesh join.
Smoke test fake API and expanded scenarios
extensions/connector-oh-my-pi/oh-my-pi-extension.smoke.ts
Fake Pi API now records setSessionName calls and can simulate rejection; test rewritten with richer ctx shape and five scenarios covering non-interactive skip, unnamed/interactive rename, already-named skip, rename rejection, and getSessionName throw, using settle() to await detached work.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Pi
  participant Extension
  participant MeshAgent
  participant SessionManager

  Pi->>Extension: session_start(ctx)
  alt ctx.hasUI === false
    Extension-->>Pi: no-op, no rename
  else interactive
    Extension->>MeshAgent: start()
    Extension->>SessionManager: getSessionName()
    alt name is undefined
      Extension->>Pi: setSessionName(config.name)
      alt setSessionName rejects
        Extension->>Extension: catch and log warning
      end
    else name already set
      Note over Extension: skip rename
    end
  end
Loading

Poem

A rabbit hops through code so neat,
Renaming sessions, best-effort feat,
If names resist or reads go wrong,
The mesh join still sings its song 🎶
Hop, settle, test — all snug and tight! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: naming the oh-my-pi session from COTAL_NAME during join.
Description check ✅ Passed The description is directly related and matches the implementation and test changes in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cotal-connector-session-title

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR names interactive oh-my-pi mesh sessions after the configured Cotal identity.

  • Adds best-effort session naming after the mesh join starts.
  • Preserves existing manual or resumed session names.
  • Skips title work for non-interactive sessions.
  • Adds smoke coverage for the rename and join behavior.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
extensions/connector-oh-my-pi/src/extension.ts Starts the mesh agent before running guarded best-effort session naming.
extensions/connector-oh-my-pi/oh-my-pi-extension.smoke.ts Adds smoke coverage for unset names, existing names, non-interactive sessions, rejected renames, and guard-read failures.

Reviews (3): Last reviewed commit: "fix(connector): never gate the mesh-join..." | Re-trigger Greptile

Comment thread extensions/connector-oh-my-pi/src/extension.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files

Heads up: you’re close to your included review allowance. Set a flex budget so reviews don’t pause.

Fix all with cubic | Re-trigger cubic

Comment thread extensions/connector-oh-my-pi/src/extension.ts Outdated
mattwilkinsonn and others added 2 commits July 8, 2026 19:12
The launcher forwards COTAL_NAME but OMP had no agent-reachable way to set the session (pane/terminal) title, so every agent's title was wrong. The extension now calls `pi.setSessionName(config.name)` at session_start on the interactive branch, guarded on an unset name so a resumed or manually-renamed session is never clobbered, and best-effort so a title failure never breaks the mesh-join.

Co-Authored-By: seal <noreply@sealedsecurity.com>
greptile + cubic both flagged that `await pi.setSessionName()` ran before
agent.start(), so a getSessionName() throw (session manager not ready) or a
setSessionName() promise that stalls instead of rejecting would leave the pane
off the mesh. Start the join first (non-blocking background connect), then do
the title work in a detached fire-and-forget IIFE with getSessionName() inside
the try — a title failure of any kind can no longer block connect.

Smoke: flush the detached title work before asserting it (cases b/c/d no longer
race) and add case (e) — getSessionName() throws => agent.start still fires,
no rename, handler resolves. Red-green demonstrated: (e) reddens on the pre-fix
ordering, green after.

Co-Authored-By: seal <noreply@sealedsecurity.com>
@seal-agent
seal-agent force-pushed the cotal-connector-session-title branch from aacbea9 to 4222fdd Compare July 8, 2026 23:12
Hitting ESC to interrupt a running OMP turn while a cotal message was waiting bled
the message text into the editable composer instead of holding it for redelivery.

The connector delivered every inbound mesh message with deliverAs:"steer". When
idle that wakes a fresh turn, but a steer arriving while OMP is still tearing down
a user-interrupted (ESC) turn folds via agent.steer() into the editable pending-
message UI = the composer (agent-session.ts:7466; the ESC path latches
#advisorAutoResumeSuppressed at 7766-7768 and isStreaming stays true through the
unwind). The connector cannot observe the interrupt to guard against it —
AgentEndEvent carries no reason and ExtensionContext exposes no aborting signal —
so it must deliver in a mode that is hidden-from-composer by contract.

deliverAs:"nextTurn" is that mode (agent-session.ts:7458-7479): idle+triggerTurn
routes to the same #promptAgentInitiatedMessage fresh turn as steer, while the
still-unwinding case is parked in the hidden #queueHiddenNextTurnMessage queue and
redelivered on the next clean turn — never the composer. The connector never
intends a mid-turn fold (drive() early-returns while busy), so steer's only
distinguishing behavior was exactly the misroute frame; nextTurn loses zero
intended behavior and preserves ack-on-turn-end.

Regression: interactive-loop.smoke.ts test 9 models OMP's routing in FakeHost
(steer-during-interrupt -> composer; nextTurn -> hidden held queue) and asserts a
DM queued mid-turn lands HELD not composer, then is delivered + acked on the next
clean turn-end. Fails on the pre-fix steer envelope, passes after.

Co-Authored-By: seal <noreply@sealedsecurity.com>
mattwilkinsonn and others added 3 commits July 8, 2026 21:30
cubic P3 on #8: the ESC regression asserted the inbox drains on the next clean
turn-end, but FakeHost never modeled the held nextTurn content actually being
delivered into a turn — so it proved held-AND-acked, not held-AND-delivered (the
drain came purely from the connector's surfaced bookkeeping). A future regression
where the hidden queue never redelivers would still pass.

Model OMP's deferred continuation (#promptQueuedHiddenNextTurnMessages,
agent-session.ts:7323-7346) with FakeHost.flushHeld(): it drains the hidden
next-turn queue into consumed turn content, exactly as a clean redelivery does.
Test 9 now flushes the held message into a real turn and asserts it was consumed
BEFORE the clean turn-end acks it — so the ack is proven to follow an actual
delivery, closing cubic's gap and mirroring the real deliver-then-ack ordering.

Refs #3.

Co-Authored-By: seal <noreply@sealedsecurity.com>
…sage

Capture the coalescing invariant at the ack site (greptile P1 on #8): a future
reader touching ackSurfaced must see WHY a nextTurn message parked during an ESC
unwind can't be acked before it's consumed. OMP holds the wire-level agent_end
while #promptInFlightCount > 0 and lets a later one supersede it
(agent-session.ts:2787-2799), so a wire-level subscriber sees one agent_end at
the true settle — the interrupted turn and the deferred continuation collapse into
a single post-consume event. Backstop: ackSurfaced drains only front-matching ids,
so an unconsumed survivor redelivers (fails safe). Comment only, no behavior change.

Refs #3.

Co-Authored-By: seal <noreply@sealedsecurity.com>
fix(connector): deliver peer messages as nextTurn, not steer
@mattwilkinsonn
mattwilkinsonn merged commit 7f08d18 into zheng-connector-upstream Jul 25, 2026
13 checks passed
@mattwilkinsonn
mattwilkinsonn deleted the cotal-connector-session-title branch July 25, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants