From c920ed0af6ca7878c4482459c7d62f4c20fef47d Mon Sep 17 00:00:00 2001 From: Nickk'z Date: Sat, 7 Nov 2026 02:12:19 +0530 Subject: [PATCH] Use plain words in the labels around a thread Screen reader names and tooltips around a conversation used internal words: "Jump to turn 3", "Peek run", "Loading run", "Open spawned session", "Stops the current turn" and "The runtime does not report which model answered". They only make sense if you built the product. Each now says what the control does in everyday words. - Scroller rail: "Jump to a message" and "Jump to message N: ...". - Thread side pane: the stub header and loading state say Task, the error says task, and the preview button in All threads is "Preview task". - Spawned gateway children are "helper agent" everywhere, through the shared kind label in child-labels.ts; the inline fold now derives its link name from that label instead of a second hardcoded string, so it cannot drift from the Agents rail. - Send now (queue list and pill): "Stops what the agent is doing now and sends this message right away"; the pill reads "sends after the current reply". - Details rail: the row is "Model" and its tooltip says the model the task asked for, and that we are not told which model actually answered. Tests that matched the old strings are updated, and two guard the shared label and the Model row. Closes #339 --- frontend/app/lab/session-ui-showcase.test.tsx | 2 +- frontend/components/chat/child-labels.test.ts | 4 ++-- frontend/components/chat/child-labels.ts | 2 +- .../components/chat/conversation-grammar.test.tsx | 2 +- .../components/chat/session-details-rail.test.tsx | 7 +++++-- frontend/components/chat/session-details-rail.tsx | 4 ++-- frontend/components/chat/subagent-pane-body.test.tsx | 2 +- frontend/components/chat/subagent-pane-body.tsx | 4 ++-- frontend/components/chat/subagent-pane.tsx | 8 ++++---- frontend/components/chat/subagents-fold.test.tsx | 11 +++++++++-- frontend/components/chat/subagents-fold.tsx | 2 +- frontend/components/pro/queued-messages.tsx | 2 +- .../components/session-ui/agent-panel-row.test.tsx | 6 +++--- .../session-ui/message-scroller-rail.test.tsx | 2 +- .../components/session-ui/message-scroller-rail.tsx | 4 ++-- .../session-ui/queued-message-pill.test.tsx | 4 ++-- .../components/session-ui/queued-message-pill.tsx | 4 ++-- 17 files changed, 40 insertions(+), 30 deletions(-) diff --git a/frontend/app/lab/session-ui-showcase.test.tsx b/frontend/app/lab/session-ui-showcase.test.tsx index f6ef5fea0..6c8db8251 100644 --- a/frontend/app/lab/session-ui-showcase.test.tsx +++ b/frontend/app/lab/session-ui-showcase.test.tsx @@ -46,7 +46,7 @@ test("renders every ported session-ui piece from mock canonical nodes", () => { // Queued pill: honest FIFO copy, Send now only on the head message. expect(html).toContain('data-session-ui="queued-message-pill"'); - expect(html).toContain("Queued - sends after the current run"); + expect(html).toContain("Queued - sends after the current reply"); expect(html).toContain("Send now"); expect(html).toContain("Queued #2 - 1 reply ahead"); diff --git a/frontend/components/chat/child-labels.test.ts b/frontend/components/chat/child-labels.test.ts index c558a7967..0efb283d5 100644 --- a/frontend/components/chat/child-labels.test.ts +++ b/frontend/components/chat/child-labels.test.ts @@ -7,7 +7,7 @@ describe("childKindLabel", () => { expect(childKindLabel("bot_thread")).toBe("bot thread"); expect(childKindLabel("subagent")).toBe("subagent"); expect(childKindLabel("child_thread")).toBe("child thread"); - expect(childKindLabel("spawned_session")).toBe("spawned session"); + expect(childKindLabel("spawned_session")).toBe("helper agent"); }); }); @@ -16,7 +16,7 @@ describe("childGroupLabel", () => { expect(childGroupLabel({ subagent: 2, bot_thread: 1 })).toBe("2 subagents, 1 bot thread"); expect(childGroupLabel({ subagent: 1 })).toBe("1 subagent"); expect(childGroupLabel({ bot_thread: 2, spawned_session: 1, child_thread: 0 })).toBe( - "2 bot threads, 1 spawned session", + "2 bot threads, 1 helper agent", ); expect(childGroupLabel({})).toBe(""); }); diff --git a/frontend/components/chat/child-labels.ts b/frontend/components/chat/child-labels.ts index fe12b0442..729fdd003 100644 --- a/frontend/components/chat/child-labels.ts +++ b/frontend/components/chat/child-labels.ts @@ -10,7 +10,7 @@ const SINGULAR: Record = { subagent: "subagent", bot_thread: "bot thread", child_thread: "child thread", - spawned_session: "spawned session", + spawned_session: "helper agent", }; const ORDER: readonly ChildKind[] = ["subagent", "bot_thread", "child_thread", "spawned_session"]; diff --git a/frontend/components/chat/conversation-grammar.test.tsx b/frontend/components/chat/conversation-grammar.test.tsx index 1c74939d3..af1aaf870 100644 --- a/frontend/components/chat/conversation-grammar.test.tsx +++ b/frontend/components/chat/conversation-grammar.test.tsx @@ -217,7 +217,7 @@ test("a gateway child-session turn folds under its parent, never a second turn b // Its truth lives in the parent's subagent fold: honest serial Queued state // plus the open-as-own-session affordance. expect(html).toContain('data-testid="subagents-fold"'); - expect(html).toContain("1 spawned session"); + expect(html).toContain("1 helper agent"); expect(html).toContain("Delegated: audit the docs"); expect(html).toContain("Queued"); expect(html).toContain('href="/session/run-child"'); diff --git a/frontend/components/chat/session-details-rail.test.tsx b/frontend/components/chat/session-details-rail.test.tsx index 7addf7e31..e888f38db 100644 --- a/frontend/components/chat/session-details-rail.test.tsx +++ b/frontend/components/chat/session-details-rail.test.tsx @@ -106,7 +106,7 @@ describe("SessionDetailsRail", () => { expect(html).not.toContain("not reported"); }); - test("the runtime line presents the model as the one requested, not as the one that answered", () => { + test("the model line presents the model as the one requested, not as the one that answered", () => { // runs.model is what the plane asked the runtime for; no runtime reports // the model that answered, so the rail must not read as a fact. const html = renderToStaticMarkup( @@ -115,7 +115,10 @@ describe("SessionDetailsRail", () => { expect(html).toContain("Codex"); expect(html).toContain('data-testid="runtime-model-requested"'); expect(html).toContain(">requested<"); - expect(html).toContain("does not report which model answered"); + expect(html).toContain("We are not told which model actually answered"); + // Plain words for people (#339): no run, turn, session or runtime in the row or its tooltip. + expect(html).toContain("
Model
"); + expect(html).not.toContain("Runtime"); }); test("a thread with unloaded outline turns says its plan and totals are partial", () => { diff --git a/frontend/components/chat/session-details-rail.tsx b/frontend/components/chat/session-details-rail.tsx index a3c268be4..7c534049d 100644 --- a/frontend/components/chat/session-details-rail.tsx +++ b/frontend/components/chat/session-details-rail.tsx @@ -88,14 +88,14 @@ export function SessionDetailsRail({
{project || "No repository"} - + {/* The model is the one the plane asked the runtime for (the run row); no runtime reports back which model answered, so the rail says so instead of presenting the request as a fact. */} {engineDisplayLabel(newest.engine)} · {modelLabel(newest.model, newest.engine)}{" "} diff --git a/frontend/components/chat/subagent-pane-body.test.tsx b/frontend/components/chat/subagent-pane-body.test.tsx index f755f32bd..3f9124370 100644 --- a/frontend/components/chat/subagent-pane-body.test.tsx +++ b/frontend/components/chat/subagent-pane-body.test.tsx @@ -65,7 +65,7 @@ describe("run peek body", () => { test("loading and error shells are neutral unless the caller knows it is a child", () => { expect(renderToStaticMarkup(Loading)).toContain(">Thread<"); - expect(renderToStaticMarkup(Loading)).toContain(">Run<"); + expect(renderToStaticMarkup(Loading)).toContain(">Task<"); expect(renderToStaticMarkup(Loading)).toContain( ">Subagent<", ); diff --git a/frontend/components/chat/subagent-pane-body.tsx b/frontend/components/chat/subagent-pane-body.tsx index 6ace0ead3..686b0abe0 100644 --- a/frontend/components/chat/subagent-pane-body.tsx +++ b/frontend/components/chat/subagent-pane-body.tsx @@ -65,7 +65,7 @@ export default function SubagentPaneBody({ return (

- Couldn't load this run. + Couldn't load this task.

); @@ -73,7 +73,7 @@ export default function SubagentPaneBody({ if (!run) { return ( - + ); } diff --git a/frontend/components/chat/subagent-pane.tsx b/frontend/components/chat/subagent-pane.tsx index bbe22b627..3ce0aa782 100644 --- a/frontend/components/chat/subagent-pane.tsx +++ b/frontend/components/chat/subagent-pane.tsx @@ -101,7 +101,7 @@ export function PaneStub({ }: { children: React.ReactNode; childSession?: boolean; - label?: "Run"; + label?: "Task"; }) { return ( <> @@ -122,8 +122,8 @@ export function PaneStub({ const SubagentPaneBody = dynamic(() => import("@/components/chat/subagent-pane-body"), { ssr: false, loading: () => ( - - + + ), }); @@ -245,7 +245,7 @@ export function SubagentPeekButton({ return (