Skip to content

fix(provider-core): long subagent titles no longer end in a broken character - #29906

Open
saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/thread-title-hunt
Open

saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/thread-title-hunt

Conversation

@saphid

@saphid saphid commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Problem

Subagent child threads are named from the task title or prompt. Anything over 72 characters is cut at 69 UTF-16 code units, then ... is added. If an emoji (or any other astral character) sits across that cut, the title keeps half a surrogate pair. It then shows as …aaaa�... everywhere the subagent thread title appears. This affects subagents from Codex, Claude, ACP providers, and app-owned delegated tasks, since they all call the same subagentThreadTitle helper.

Change

subagentThreadTitle now moves the cut back one code unit when it would split a surrogate pair. This is the same guard that #29163 added to its sibling, the create_threads threadTitle in OrchestratorMcpService.ts. Titles of 72 characters or fewer, and the parent-title fallback, are unchanged.

Scope and approval

Very small, focused fix for an obvious bug, so no prior issue: one helper gets the surrogate guard that was already merged for its twin in #29163, plus one regression test. Overlap search: the local PR index plus GitHub searches for subagentThreadTitle and "subagent title surrogate". The closest matches are #29163 (merged; the MCP create_threads sibling) and #29647 (open; restart-note labels in RestartBackgroundNote.ts). Neither touches this helper. #27990 changed subagent title jobs, not this text.

Verification

  • Red on main: vp test run src/server/subagentProjection.test.ts (packages/provider-core) failed with Expected: "a×68...", Received: "a×68�...".
  • Green after the fix: 1 test passed. The test also checks that an emoji fully before the cut is kept.
  • vp run check:changed: format, lint, knip, typecheck (26 packages), and tests (2 files) all passed.
  • Not checked: grapheme clusters (ZWJ emoji sequences can still be cut between their code points, same as the sibling), and whitespace in prompt-derived titles. Both are out of scope.

Reviewed with sol-loop: 1 round with GPT-6.1 Sol on high. Sol verdict: approved.

Created with Claude Opus 5.5 in Claude Code (T3 Code).

🤖 Generated with Claude Code

…aracter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at dd48efc

Macroscope's review found this PR approvable — Long subagent titles now avoid splitting a Unicode surrogate pair at the truncation boundary. The change is limited to title formatting and preserves existing length thresholds and fallback behavior.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The subagent thread title clipping logic now avoids splitting a surrogate pair. Tests cover the clipping boundary, including an emoji.

Changes: Subagent title clipping

Layer / File(s) Summary
Clipping boundary and tests
packages/provider-core/src/server/subagentProjection.ts, packages/provider-core/src/server/subagentProjection.test.ts
For titles longer than 72 code units, clipping backs up one code unit if the cutoff would split a surrogate pair, then adds .... Tests cover the boundary with and without an emoji.

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

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#29163: Applies the same surrogate-pair boundary adjustment to threadTitle in OrchestratorMcpService.ts.
  • pingdotgg/t3code#29563: Applies the same adjustment to titleFromMessage in apps/server/src/cli/thread.ts.
  • pingdotgg/t3code#27483: Applies the same boundary rule to sanitizeThreadTitle in textGenerationUtils.ts.

Suggested reviewers: juliusmarminge, maria-rcks

Merge Risk: Minimal · up to dd48e

This focused change addresses broken-character titles without introducing an identified merge risk.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main fix: preventing broken characters in long subagent titles.
Description check Passed The description includes complete Problem, Change, Scope and approval, and Verification sections. It explains the bug, fix, scope, regression test, validation results, limitations, and agent details.
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 a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

ast-grep (0.51.1)

ast-grep could not parse rule config: /ast-grep-rules/ast-grep-essentials/rules/typescript/security/insecure-allow-origin-typescript.yml

Usage-based review receipt

Note

This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 61c3794 and dd48efc.

Files selected for processing: 2
  • packages/provider-core/src/server/subagentProjection.test.ts
  • packages/provider-core/src/server/subagentProjection.ts

Limit details: You’ve used all 10 included reviews currently available.

@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified unchanged head dd48efcaca72071d571dbe74ab321e5f203c70b8 on linux. installed both checkouts with vp i, ran one background dev server at a time with isolated state, and used repo playwright with /usr/bin/google-chrome.

created a project pointing at a real git repository through the web app. sent composer messages using real codex gpt-6.1-sol parent and child turns through the local proxy. the parent used app-owned delegate_task, role general, without an explicit title.

  • on github/main (61c3794c32b0), a task beginning with 68 ascii characters followed by 😀 produced a persisted child title ending in a lone \ud83d plus .... the breadcrumb displayed a broken character.
  • on this head, the identical task produced 68 ascii characters plus ..., with no broken surrogate. the child returned TITLE-CHECK-OK.
  • an emoji after 67 ascii characters remained intact before .... ordinary ascii still clipped at 69 characters plus .... both children completed and delivered their results to the parent.
  • opened the child from its parent card, reloaded the browser, and sent a follow-up through the child composer. its title stayed intact and it returned CHILD-FOLLOWUP-OK.

vp test run packages/provider-core/src/server/subagentProjection.test.ts passed in blacksmith. vp run check:changed 61c3794c32b0eeebfac09add43e403618c65d2d7 passed there: format, lint, knip, 26 package typechecks, and two test files. existing github checks are green. no code changes were needed.

main: broken surrogate in the child breadcrumb

pr: matching task with a clean child breadcrumb

pr: real codex child follow-up completes with the title intact

runtime transcript with persisted titles and provider results

Not verified

native desktop, ios, and android clients were not exercised on this linux web setup. native codex spawn variants, other provider adapters, and relay/tunnel connections were not exercised. this verifies the app-owned codex delegation path through the shared title helper. grapheme-cluster preservation and repair of existing malformed titles are outside this change.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants