Skip to content

feat(intelligence): background agent command center UI (#3373)#3499

Merged
oxoxDev merged 7 commits into
tinyhumansai:mainfrom
oxoxDev:feat/3373-command-center-ui
Jun 9, 2026
Merged

feat(intelligence): background agent command center UI (#3373)#3499
oxoxDev merged 7 commits into
tinyhumansai:mainfrom
oxoxDev:feat/3373-command-center-ui

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds the Background Agent Command Center UI — a new "Agent Work" tab under Intelligence that lists recent agent runs grouped by status (needs-input / working / completed / failed / stopped).
  • Consumes the openhuman.agent_work_list RPC added in feat(agent_orchestration): background command-center run list (#3373) #3497; read-only.
  • New agentWorkApi client, IntelligenceAgentWorkTab component, tab registration, and i18n across all 14 locales.

⚠️ Stacked on #3497 (feat/3373-command-center). Until that merges, this PR's diff includes its backend commits. Will rebase onto main once #3497 lands. Review/merge #3497 first.

Problem

#3497 shipped the backend (agent_work_list) but nothing surfaces it. Users have no view of background agent runs grouped by what needs their attention.

Solution

  • app/src/services/api/agentWorkApi.ts — typed client over openhuman.agent_work_list.
  • app/src/components/intelligence/IntelligenceAgentWorkTab.tsx — fetch-on-mount, loading/error/empty states, five status sections, per-row agent/status/elapsed/cost/tokens, open-thread / open-worker actions. Component-local state (matches sibling tabs), no Redux slice.
  • app/src/pages/Intelligence.tsx — registers the agent-work tab (URL-param persistence preserved).
  • i18n keys added to en + 13 locales with real translations (parity-checked).

Submission Checklist

If a section does not apply, mark N/A with a one-line reason.

  • Tests added or updated (happy path + failure) — Vitest for the api client + tab (loading/error/empty/grouped).
  • Diff coverage ≥ 80% — verified by CI; locally typecheck + Vitest green.
  • N/A: Coverage matrix — UI for an already-tracked feature slice; no new feature row.
  • N/A: Feature IDs in Related — see above.
  • No new external network dependencies introduced.
  • N/A: Manual smoke checklist — additive read-only tab, no release-cut surface.
  • N/A: Closes #NNN — PR2 of multi-PR Build a background agent command center #3373; closes on the final slice.

Impact

  • Frontend only. New Intelligence tab; no backend, CLI, or mobile change. Read-only.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Commit & Branch

  • Branch: feat/3373-command-center-ui
  • Commit SHA: 598379b6c3eabea2f353b41967e14770c2d99d7e

Validation Run

  • pnpm typecheck — pass
  • pnpm lint — pass (0 errors in changed files)
  • Focused tests: vitest run IntelligenceAgentWorkTab.test.tsx agentWorkApi.test.ts — 8 passed
  • i18n parity (pnpm i18n:check) — pass
  • N/A: Rust fmt/check — no Rust changes in this PR

Behavior Changes

  • Intended: new read-only "Agent Work" Intelligence tab.
  • User-visible: users can browse background agent runs grouped by status.

Summary by CodeRabbit

  • New Features

    • New "Agent Work" tab in Intelligence showing background agent runs grouped by lifecycle (needs input, working, completed, failed, stopped); per-run details include agent identity, status/kind, elapsed time, tokens, cost, and jump-to-thread actions.
  • Tests

    • Added component and API test suites covering loading, empty/error states, data rendering, and input validation.
  • Documentation

    • Added localized UI copy for the agent-work view across multiple languages.

@oxoxDev oxoxDev self-assigned this Jun 8, 2026
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7dc9b7b4-cdc8-468b-a0e0-e4b8b43cdf75

📥 Commits

Reviewing files that changed from the base of the PR and between 5f943e8 and 6016943.

📒 Files selected for processing (17)
  • app/src/components/intelligence/IntelligenceAgentWorkTab.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/services/api/agentWorkApi.test.ts
  • app/src/services/api/agentWorkApi.ts
✅ Files skipped from review due to trivial changes (6)
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/pl.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • app/src/lib/i18n/pt.ts
  • app/src/services/api/agentWorkApi.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/components/intelligence/IntelligenceAgentWorkTab.tsx

📝 Walkthrough

Walkthrough

Adds a new Intelligence "agent-work" tab: typed frontend API client for openhuman.agent_work_list, component IntelligenceAgentWorkTab with formatting helpers and row actions, tests for API and UI, routing registration for the tab, and translations across many locales.

Changes

Agent Work Intelligence Tab

Layer / File(s) Summary
API data contract and RPC wrapper
app/src/services/api/agentWorkApi.ts
Defines AgentWorkBucket union and AgentWorkRow/AgentWorkGroup/AgentWorkResponse interfaces and implements agentWorkApi.list(limit?) with validation, RPC forwarding, and logging.
Agent work display component and formatting
app/src/components/intelligence/IntelligenceAgentWorkTab.tsx
Implements IntelligenceAgentWorkTab, AgentWorkRowItem, and exported helpers formatElapsed(), formatTokens(), formatCost(); handles fetch lifecycle, grouped rendering by bucket, formatting, and thread navigation actions.
Component tests
app/src/components/intelligence/IntelligenceAgentWorkTab.test.tsx
Vitest + React Testing Library suite covering mount fetch, loading/error/empty states, grouped-row rendering, formatting, and action buttons.
API tests
app/src/services/api/agentWorkApi.test.ts
Vitest suite mocking core RPC to verify parameter forwarding, input validation for limit, and that the grouped response is returned unchanged.
Intelligence tab routing and configuration
app/src/pages/Intelligence.tsx
Adds agent-work to the IntelligenceTab union and INTELLIGENCE_TABS, registers allTabs entry with localized label/description, imports and conditionally renders the new tab component.
Multilingual UI text for agent work tab
app/src/lib/i18n/{ar,bn,de,en,es,fr,hi,id,it,ko,pl,pt,ru,zh-CN}.ts
Adds memory.tab.agentWork/memory.tab.agentWorkDescription and the intelligence.agentWork.* namespace (subtitle, loading/error/empty, bucket labels, column headers, statuses, kinds, and open-thread/worker actions) across locale files.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant IntelligenceAgentWorkTab as AgentWorkTab Component
  participant agentWorkApi
  participant CoreRPC as openhuman.agent_work_list
  User->>IntelligenceAgentWorkTab: Navigate to agent-work tab
  IntelligenceAgentWorkTab->>IntelligenceAgentWorkTab: Show loading UI
  IntelligenceAgentWorkTab->>agentWorkApi: list(limit?)
  agentWorkApi->>CoreRPC: Call openhuman.agent_work_list
  CoreRPC-->>agentWorkApi: Return grouped response
  agentWorkApi-->>IntelligenceAgentWorkTab: Typed AgentWorkResponse
  IntelligenceAgentWorkTab->>IntelligenceAgentWorkTab: Group by bucket, format values
  IntelligenceAgentWorkTab->>IntelligenceAgentWorkTab: Render buckets with rows
  IntelligenceAgentWorkTab-->>User: Display agent work grouped by lifecycle state
  User->>IntelligenceAgentWorkTab: Click "open thread" button
  IntelligenceAgentWorkTab->>IntelligenceAgentWorkTab: Dispatch thread selection & loading
  IntelligenceAgentWorkTab->>IntelligenceAgentWorkTab: Navigate to /chat
  IntelligenceAgentWorkTab-->>User: Display thread details
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

working

Suggested reviewers

  • senamakel
  • graycyrus
  • sanil-23

Poem

🐰 I hopped to see agent queues align,
Buckets sorted, tokens in a line,
Costs and times neatly shown,
Tabs and tests now fully grown,
A tiny hop — the feature's fine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(intelligence): background agent command center UI' accurately describes the main change—adding a new UI feature for viewing background agent work.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@oxoxDev oxoxDev force-pushed the feat/3373-command-center-ui branch from 598379b to 5b6415b Compare June 8, 2026 18:13
@oxoxDev oxoxDev marked this pull request as ready for review June 8, 2026 18:14
@oxoxDev oxoxDev requested a review from a team June 8, 2026 18:14

@graycyrus graycyrus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@oxoxDev hey! the code looks clean overall, but E2E lane 2/4 is showing a CI failure, so I'll hold off on approving until that's green — let me know if you need any help sorting it out.

one thing I noticed while reviewing: across all 13 non-English locale files (ar, bn, de, es, fr, hi, id, it, ko, pl, pt, ru, zh-CN), the bucket status labels working, completed, failed, stopped and all five column headers (agent, status, elapsed, cost, tokens) are left as English strings. needs_input is properly translated in every locale — the inconsistency within the same key group makes this look like oversight rather than intentional convention. your i18n Coverage (parity) check passes because the keys exist, but the values are English fallbacks. if these terms are meant to stay in English project-wide, a note in the i18n guide would help future contributors; if not, worth translating before this ships.

everything else is solid — mount pattern, component-local state, five-bucket render loop, typed API client, and test coverage (loading/error/empty/grouped) all look correct. the 0ms defer for the loading paint matches the sibling tab's approach. once CI is green, this is good to go.

@oxoxDev

oxoxDev commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the careful review — both points addressed.

i18n: Good catch, that was an oversight. Pushed 5f943e8b translating all nine remaining values — bucket labels (working/completed/failed/stopped) and the five column headers (agent/status/elapsed/cost/tokens) — across all 13 non-English locales, so the whole agentWork key group is now consistent with the already-translated needsInput. For each file I reused that locale's existing vocabulary rather than a fresh dictionary pass (e.g. tokens follows each file's own settings.costDashboard.tokens: Fichas in es, Gettoni in it, Jetons in fr; loanwords like Agent/Status kept only where the file already keeps them). i18n:check parity stays green.

E2E lane 2/4: That red isn't from this PR — it's a known flaky shard. It failed on a different test each run (composio harness first, then mcp-tab-flow the next), and neither touches this change (Intelligence agent-work tab). Notably the current main tip is 2f324812e "fix(test): stabilize flaky mcp-tab-flow E2E (#3515)" and it still flakes there. The required aggregate Playwright E2E Gate is green. The new push kicks a fresh E2E run — happy to re-roll until the shard is green so it's not blocking your approval.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. labels Jun 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/src/components/intelligence/IntelligenceAgentWorkTab.tsx (2)

237-241: 🏗️ Heavy lift

Localize status and kind values before rendering.

Line 237 and Line 240 render backend enum-like values directly. Those are user-visible and should go through useT() mappings (with locale keys added across supported language files).

As per coding guidelines, use useT() from app/src/lib/i18n/I18nContext for all user-facing UI text and add translation keys to en.ts and all locale files.

🤖 Prompt for 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.

In `@app/src/components/intelligence/IntelligenceAgentWorkTab.tsx` around lines
237 - 241, In IntelligenceAgentWorkTab, don't render backend enum values
row.status and row.kind directly; import and call useT() from
app/src/lib/i18n/I18nContext in the IntelligenceAgentWorkTab component and
replace direct renders with localized mappings (e.g. map status and kind values
to translation keys like status.<value> and kind.<value> via useT()). Add the
corresponding keys and strings to en.ts and mirror them in all locale files, and
ensure the mapping accounts for unknown values (fallback to the raw value or a
generic key).

Source: Coding guidelines


213-219: ⚡ Quick win

Use an interface for AgentWorkRowItem props.

The inline object shape in the function signature should be promoted to a named interface to match project TypeScript conventions.

Proposed change
+interface AgentWorkRowItemProps {
+  row: AgentWorkRow;
+  onOpenThread: (threadId: string) => void;
+}
+
 function AgentWorkRowItem({
   row,
   onOpenThread,
-}: {
-  row: AgentWorkRow;
-  onOpenThread: (threadId: string) => void;
-}) {
+}: AgentWorkRowItemProps) {

As per coding guidelines, **/*.{ts,tsx}: Always use interface for defining object shapes in TypeScript.

🤖 Prompt for 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.

In `@app/src/components/intelligence/IntelligenceAgentWorkTab.tsx` around lines
213 - 219, The function AgentWorkRowItem currently types its props inline;
extract that inline object into a named interface (e.g., interface
AgentWorkRowItemProps) and update the function signature to accept (props:
AgentWorkRowItemProps) or destructure ({ row, onOpenThread }:
AgentWorkRowItemProps). Ensure the interface references the existing
AgentWorkRow type and the onOpenThread signature (onOpenThread: (threadId:
string) => void) so types remain identical and conform to the project convention
of using interfaces for prop shapes.

Source: Coding guidelines

🤖 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 `@app/src/services/api/agentWorkApi.ts`:
- Around line 64-69: The list method currently forwards any numeric limit to
callCoreRpc; add client-side validation in the list function to reject
non-integer or negative limits (e.g., if limit is provided ensure
Number.isInteger(limit) && limit >= 0) and throw a clear TypeError or RangeError
when invalid, otherwise pass params as now to openhuman.agent_work_list; update
the list function's parameter handling (referencing list, callCoreRpc, and
AgentWorkResponse) to enforce this check before making the RPC call.
- Around line 66-69: Replace direct frontend core RPC call via callCoreRpc with
the mandated relay invocation: instead of calling callCoreRpc({...}) in
agentWorkApi.ts (the call using method 'openhuman.agent_work_list' and params
built from limit), call the frontend invoke function with channel
'core_rpc_relay' and pass an object containing method and params (preserve the
same params logic for limit) so the relay proxies the core RPC; keep the
expected response shape (AgentWorkResponse) handling the same after the invoke
call.

---

Nitpick comments:
In `@app/src/components/intelligence/IntelligenceAgentWorkTab.tsx`:
- Around line 237-241: In IntelligenceAgentWorkTab, don't render backend enum
values row.status and row.kind directly; import and call useT() from
app/src/lib/i18n/I18nContext in the IntelligenceAgentWorkTab component and
replace direct renders with localized mappings (e.g. map status and kind values
to translation keys like status.<value> and kind.<value> via useT()). Add the
corresponding keys and strings to en.ts and mirror them in all locale files, and
ensure the mapping accounts for unknown values (fallback to the raw value or a
generic key).
- Around line 213-219: The function AgentWorkRowItem currently types its props
inline; extract that inline object into a named interface (e.g., interface
AgentWorkRowItemProps) and update the function signature to accept (props:
AgentWorkRowItemProps) or destructure ({ row, onOpenThread }:
AgentWorkRowItemProps). Ensure the interface references the existing
AgentWorkRow type and the onOpenThread signature (onOpenThread: (threadId:
string) => void) so types remain identical and conform to the project convention
of using interfaces for prop shapes.
🪄 Autofix (Beta)

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: 9408a2fa-f6e2-4eb9-9938-7b41d3b354b8

📥 Commits

Reviewing files that changed from the base of the PR and between 2f32481 and 5f943e8.

📒 Files selected for processing (19)
  • app/src/components/intelligence/IntelligenceAgentWorkTab.test.tsx
  • app/src/components/intelligence/IntelligenceAgentWorkTab.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/Intelligence.tsx
  • app/src/services/api/agentWorkApi.test.ts
  • app/src/services/api/agentWorkApi.ts

Comment thread app/src/services/api/agentWorkApi.ts
Comment thread app/src/services/api/agentWorkApi.ts
@oxoxDev

oxoxDev commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai triaged this round on #3499:

Accepted (pushed in 6016943):

  • Validate limit client-sideagentWorkApi.list rejects non-integer/non-positive limits before dispatch (+ unit test).
  • Localize status/kind → added intelligence.agentWork.status.* (8) + kind.* (5) keys, rendered via useT() with a raw-value fallback for unknown enums; translated across all 13 locales (i18n:check green).
  • Use an interface for props → extracted AgentWorkRowItemProps.

Skipped (with reason):

  • Use core_rpc_relay instead of callCoreRpccallCoreRpc is the mandated wrapper (coreRpcClient service); all services/api/* clients use it and none call invoke('core_rpc_relay') directly. Raw invoke would violate the "don't scatter invoke()" rule. Left as-is. (Details in the inline reply.)

vitest 9/9, typecheck clean.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@oxoxDev Thanks for the detailed triage — everything looks well-reasoned.

Accepted items (6016943): All three look solid — client-side guard on limit, full status/kind localization with fallback for unknown enums, and typed props interface. Happy with those.

callCoreRpc skip: Makes sense. If callCoreRpc in coreRpcClient is the canonical, enforced wrapper for all services/api/* clients, bypassing it via invoke('core_rpc_relay') would be the wrong direction. I'll retract that suggestion.

Nothing blocking on my end from this round. The i18n parity confirmation and the 9/9 vitest all passing is reassuring.

🐇✨


✏️ Learnings added
Learnt from: oxoxDev
URL: https://github.com/tinyhumansai/openhuman/pull/3499

Timestamp: 2026-06-09T07:45:35.949Z
Learning: In the tinyhumansai/openhuman codebase, the correct way to call backend RPCs from `app/src/services/api/*` clients is via the `callCoreRpc` helper (the `coreRpcClient` service wrapper). Direct use of `invoke('core_rpc_relay')` is explicitly prohibited by the project's "don't scatter invoke()" architectural rule. Do not suggest replacing `callCoreRpc` with raw `invoke` calls.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label Jun 9, 2026
@oxoxDev oxoxDev requested review from a team and graycyrus June 9, 2026 10:44
@oxoxDev

oxoxDev commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@graycyrus bro need approval here

@graycyrus graycyrus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The three follow-up commits close out everything from the first review.

i18n gap: all 13 non-English locales now have proper translations across every bucket, column, status, and kind key — no more English strings leaking through. STATUS_LABEL_KEY and KIND_LABEL_KEY extend the same constant-map pattern cleanly, and the fallback to the raw backend value means new Rust enum variants won't break the UI.

Limit validation: the guard in agentWorkApi.list is correct — strict positive-integer check before any RPC dispatch, test covers 0, -5, and 1.5 boundaries.

The core_rpc_relay pushback was also right and precisely explained — callCoreRpc is the correct abstraction and keeping it consistent with every other sibling API client is the right call.

CI is 100% green, no remaining issues. LGTM.

@oxoxDev oxoxDev merged commit d72f300 into tinyhumansai:main Jun 9, 2026
23 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants