Skip to content

Live tool status, flat activity view, instant activation, real markdown typography - #147

Merged
ginccc merged 4 commits into
mainfrom
fix/operator-activation-and-failure-ux
Aug 14, 2026
Merged

Live tool status, flat activity view, instant activation, real markdown typography#147
ginccc merged 4 commits into
mainfrom
fix/operator-activation-and-failure-ux

Conversation

@ginccc

@ginccc ginccc commented Aug 14, 2026

Copy link
Copy Markdown
Member

Four UX fixes from dev-testing the operator, applying to every chat surface (main chat, drawer, operator page + drawer):

Live "Using {tool}…" status

Consumes the backend's new tool_call SSE event (EDDI#672, commit 9a5bfd874): the tool NAME is emitted right before each tool executes. Previously tool names arrived only in the turn-end toolTrace, so the status line said "Thinking…" through entire tool-using turns. New liveToolCalls list in both chat stores; ChatActivity prefers it over the lagging trace. Backends without the event fall back to the old trace scan.

Flat end-user resting view

The resting header now leads with {N} tool calls · {duration} and expands to a flat list of the calls themselves (args + status + copyable detail). The old shape — "1 step · 59.2s · 8 tool calls" over a langchain task row that had to be expanded again — was three layers of pipeline plumbing around the only content that mattered. Failed steps and cascade traces still break through and auto-expand; the debug surface is unchanged.

Activation blocks on deterministic checks only

Activation now ends at the gate read-back + gate-dry-run classification (both still fail-closed with rollback). The LLM probes — read canary and live write probe — run in the background via runPostActivationProbes once the operator is already usable; they were the bulk of a minute-long activation wait, and an inconclusive outcome proved nothing anyway. The write probe retains its power to tear the operator down on a proven gate breach (its write executed without pausing). enforceWriteCanaryGate is split into enforceGateDryRun (blocking) and runBackgroundWriteProbe (reporting, never throws). Deliberate semantic change: an inconclusive probe against an old backend (no gate-dry-run) now warns instead of rolling back a deployed operator.

Markdown finally renders properly

The prose classes every chat surface already wears were inert@tailwindcss/typography was never installed, so preflight-stripped headings, lists and tables stayed unstyled and every long reply rendered as a crowded wall. Also:

  • chat table styling: borders, cell padding, horizontal scroll contained inside the table
  • the bold repair (**bold ****bold**) now moves illegal inner whitespace outside the delimiters instead of swallowing it (**Panel ** | stays a valid table cell)
  • the operator system prompt gains a strict-markdown rule so the model stops emitting **bold ** at the source

Tests

5212 passing (22 new/reworked: live tool_call rendering, flat resting list, dry-run/background-probe split, activation-without-probes, i18n parity across 11 locales).

🤖 Generated with Claude Code

…markdown typography

Four UX fixes from dev-testing the operator, all applying to every chat surface:

- Live 'Using {tool}...' status: consume the backend's new tool_call SSE
  event (name only, emitted right before each tool executes). Tool names
  previously arrived only in the turn-end toolTrace, so the status line said
  'Thinking...' through entire tool-using turns. New liveToolCalls list in
  both stores, preferred by ChatActivity over the lagging trace.

- End-user resting view: the header now leads with '{N} tool calls - {dur}'
  and expands to a flat list of the calls themselves. The old shape ('1 step
  - 59.2s - 8 tool calls' over a langchain task row that had to be expanded
  again) was three layers of pipeline plumbing around the only content that
  mattered. Errors and cascades still break through; debug surface unchanged.

- Activation blocks on deterministic checks only: gate read-back plus the
  gate-dry-run classification (fail-closed rollback as before). The LLM
  probes - read canary and live write probe - run in the BACKGROUND via
  runPostActivationProbes after the operator is already usable; they were the
  bulk of a minute-long activation wait, and an inconclusive outcome proved
  nothing anyway. The write probe still tears the operator down on a PROVEN
  gate breach (write executed without pausing). enforceWriteCanaryGate split
  into enforceGateDryRun (blocking) + runBackgroundWriteProbe (reporting).
  Semantic change: unknown-on-old-backend now warns instead of rolling back.

- Markdown finally renders properly: the prose classes every chat surface
  already wears were inert - @tailwindcss/typography was never installed, so
  preflight-stripped headings/lists/tables stayed unstyled. Plugin added,
  chat table styling (borders, padding, self-contained horizontal scroll),
  bold-repair now moves illegal inner whitespace outside the delimiters
  instead of swallowing it, and the operator prompt gains a strict-markdown
  rule so the model stops emitting '**bold **' in the first place.
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 93 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 27f4c971-c318-4020-8019-cfea21db8d9e

📥 Commits

Reviewing files that changed from the base of the PR and between 30ff212 and 4d74e28.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (33)
  • package.json
  • src/components/chat/__tests__/chat-activity.test.tsx
  • src/components/chat/chat-activity.tsx
  • src/components/chat/chat-drawer.tsx
  • src/components/chat/chat-panel.tsx
  • src/components/groups/__tests__/format-markdown-text.test.ts
  • src/components/groups/group-utils.ts
  • src/components/operator/__tests__/operator-activation.test.tsx
  • src/components/operator/operator-activation.tsx
  • src/components/operator/operator-chat.tsx
  • src/components/operator/operator-drawer.tsx
  • src/hooks/__tests__/use-operator-activation.test.tsx
  • src/hooks/use-chat.ts
  • src/hooks/use-debug-events.ts
  • src/hooks/use-operator-chat.ts
  • src/hooks/use-operator.ts
  • src/i18n/locales/ar.json
  • src/i18n/locales/de.json
  • src/i18n/locales/en.json
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/hi.json
  • src/i18n/locales/ja.json
  • src/i18n/locales/ko.json
  • src/i18n/locales/pt.json
  • src/i18n/locales/th.json
  • src/i18n/locales/zh.json
  • src/index.css
  • src/lib/api/chat.ts
  • src/lib/operator/__tests__/write-canary.test.ts
  • src/lib/operator/system-prompt.ts
  • src/lib/operator/write-canary.ts
  • src/pages/operator.tsx
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/operator-activation-and-failure-ux

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.

ginccc added 2 commits August 14, 2026 10:37
…deps

npm ci on CI refused the previous lock: the typography install on Windows
skipped @emnapi/* (platform-conditional transitive deps), leaving the lock
out of sync with package.json on Linux runners.
npm 11 (local) omits lock entries for a bundled optional dep's own
dependencies; npm 10 (CI, node 20) requires them and refused npm ci.
Lock now written by npm@10 so both accept it.

Copilot AI 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.

Pull request overview

Improves operator/chat UX with live tool status, simplified activity details, faster activation, and styled Markdown.

Changes:

  • Handles live tool_call SSE events across chat surfaces.
  • Moves LLM activation probes to the background.
  • Adds Markdown typography, table styling, formatting repair, tests, and translations.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/pages/operator.tsx Starts background probes and surfaces results.
src/lib/operator/write-canary.ts Splits deterministic and background write checks.
src/lib/operator/system-prompt.ts Adds strict Markdown guidance.
src/lib/operator/__tests__/write-canary.test.ts Tests split probe behavior.
src/lib/api/chat.ts Adds the tool_call SSE type.
src/index.css Enables typography and table styling.
src/i18n/locales/zh.json Updates Chinese activation text.
src/i18n/locales/th.json Updates Thai activation text.
src/i18n/locales/pt.json Updates Portuguese activation text.
src/i18n/locales/ko.json Updates Korean activation text.
src/i18n/locales/ja.json Updates Japanese activation text.
src/i18n/locales/hi.json Updates Hindi activation text.
src/i18n/locales/fr.json Updates French activation text.
src/i18n/locales/es.json Updates Spanish activation text.
src/i18n/locales/en.json Updates canonical activation text.
src/i18n/locales/de.json Updates German activation text.
src/i18n/locales/ar.json Updates Arabic activation text.
src/hooks/use-operator.ts Runs post-activation probes asynchronously.
src/hooks/use-operator-chat.ts Tracks operator live tool calls.
src/hooks/use-debug-events.ts Stores current-turn tool names.
src/hooks/use-chat.ts Processes live tool-call events.
src/hooks/__tests__/use-operator-activation.test.tsx Tests non-blocking activation.
src/components/operator/operator-drawer.tsx Passes live tool state to chat.
src/components/operator/operator-chat.tsx Displays live operator activity.
src/components/operator/operator-activation.tsx Revises activation progress and warnings.
src/components/operator/__tests__/operator-activation.test.tsx Tests revised activation messaging.
src/components/groups/group-utils.ts Repairs malformed bold spacing.
src/components/groups/__tests__/format-markdown-text.test.ts Tests Markdown repairs.
src/components/chat/chat-panel.tsx Shows live tool activity.
src/components/chat/chat-drawer.tsx Shows live tool activity in the drawer.
src/components/chat/chat-activity.tsx Adds flat tool details and live status.
src/components/chat/__tests__/chat-activity.test.tsx Tests activity summaries and live calls.
package.json Adds Tailwind Typography.
package-lock.json Locks the new dependency graph.
Suppressed comments (1)

src/lib/operator/write-canary.ts:490

  • A resetOperator rejection does not prove the operator is still deployed. That function deletes the agent before clearing the config, so if only clearOperatorConfig() fails, this branch reports tornDown: false and tells the admin to remove an agent that is already gone while leaving the real problem—a stale config pointer—unreported. Preserve teardown progress or verify agent/config state before constructing this report.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/lib/operator/write-canary.ts Outdated
Comment on lines +476 to +477
try {
await resetOperator(config);
Comment thread src/pages/operator.tsx Outdated
Comment on lines +217 to +219
toast.error(
t("operator.toast.writeProbeFailed", "The approval gate did not hold — the operator was removed."),
);
…nest teardown toast

Both Copilot findings on #147, both correct:

- The write probe runs detached from activation, so a breach verdict can
  land after the operator was reconfigured (this page, another tab, another
  admin). resetOperator unconditionally cleared the shared platform.operator
  variable — run stale, that erased the REPLACEMENT operator's config. The
  teardown now clears shared state only when the stored config still names
  the probe's agent; a stale probe (or one that cannot READ the stored
  config — never clear shared state on a guess) removes only its own agent.

- The teardown-failed path warned 'still deployed - remove it manually' in
  report.message while the toast said 'the operator was removed'. The toast
  can be the only visible result after navigation; it now carries the
  report's own disposition.
@ginccc
ginccc merged commit b94ea2d into main Aug 14, 2026
4 checks passed
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