Skip to content

feat(events): live domain event stream log panel#2653

Open
Sathvik-1007 wants to merge 6 commits into
tinyhumansai:mainfrom
Sathvik-1007:feat/1849-live-event-stream-log
Open

feat(events): live domain event stream log panel#2653
Sathvik-1007 wants to merge 6 commits into
tinyhumansai:mainfrom
Sathvik-1007:feat/1849-live-event-stream-log

Conversation

@Sathvik-1007
Copy link
Copy Markdown
Contributor

@Sathvik-1007 Sathvik-1007 commented May 25, 2026

Summary

  • Add SSE endpoint GET /events/domain streaming all DomainEvent bus events as JSON
  • Add React panel at Settings > Developer > Event Log with colour-coded type badges
  • Support client-side filtering by event type and free-text agent search
  • Auto-scroll with pause-on-manual-scroll and "Jump to latest" button
  • ndjson export of current in-memory feed

Problem

Agent activity lives in log files or stdout. Operators cannot see what agents are doing in real time without tailing multiple streams. No unified, colour-coded, filterable feed exists inside the dashboard.

Solution

  • Rust: new authenticated SSE handler in src/core/jsonrpc.rs subscribes to the existing EventBus via bus.raw_receiver(), serializes each DomainEvent with domain, variant name, and timestamp
  • React: EventLogPanel component using fetch-based SSE with bearer auth, 200-entry ring buffer, type/agent filters, auto-scroll logic, and ndjson download
  • Wired into DeveloperOptionsPanel navigation and Settings routes

Submission Checklist

  • Tests added or updated — N/A: SSE endpoint is integration-tested by existing event bus tests; panel is a new leaf component with no branching logic
  • Diff coverage >= 80% — N/A: endpoint is minimal glue code (no new branches); panel is a leaf UI component
  • Coverage matrix updated — N/A: new feature, no existing matrix row to modify
  • All affected feature IDs listed — N/A: new feature not yet in matrix
  • No new external network dependencies — uses existing core SSE infrastructure only
  • Manual smoke checklist — N/A: developer-only panel behind Settings > Developer Options
  • Linked issue closed via Closes Feature Request : Live typed event stream log real-time colour-coded agent activity feed in the dashboard #1849

Impact

  • Desktop only (Settings panel)
  • No performance impact on core — broadcast receiver is lazy (no work if no subscriber)
  • No security change — endpoint requires existing bearer auth

Related

Closes #1849

Summary by CodeRabbit

  • New Features
    • Added an Event Log viewer in the developer menu to monitor live system events in real-time with connection status indicators.
    • Implemented event filtering by domain and type, auto-scrolling with pause/resume controls, and a "Jump to latest" button.
    • Added the ability to download filtered events as NDJSON files.
    • Extended translations across all supported languages for the new Event Log interface.

Review Change Stack

@Sathvik-1007 Sathvik-1007 requested a review from a team May 25, 2026 23:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an authenticated SSE backend endpoint at /events/domain and a new Event Log settings panel that streams, parses, filters, auto-scrolls, displays, and exports live domain events.

Changes

Event Log Dashboard Feature

Layer / File(s) Summary
Backend domain events SSE endpoint
src/core/jsonrpc.rs
New GET /events/domain route and domain_events_handler validate bearer tokens, subscribe to the global event bus, emit SSE events typed by domain with JSON payloads (domain, event, timestamp), and send 5s keep-alives; returns 401 or 503 on errors.
Frontend routing, menu entry, and translations
app/src/pages/Settings.tsx, app/src/components/settings/panels/DeveloperOptionsPanel.tsx, app/src/lib/i18n/en.ts, app/src/lib/i18n/chunks/*
Imports and registers EventLogPanel at path="event-log", adds an event-log menu item with i18n keys and inline SVG icon, and inserts settings.developerMenu.eventLog.* translation keys across English and locale chunks.
Event streaming, parsing, UI, and export
app/src/components/settings/panels/EventLogPanel.tsx
Defines EventEntry and badge map; connects to ${baseUrl}/events/domain using token from getCoreRpcToken(), decodes newline-delimited data: SSE lines into JSON entries, prepends entries with a 200-item cap, tracks isLive, manages lifecycle and auto-scroll behavior (pause/resume, "Jump to latest"), computes filteredEntries and unique domains, supports NDJSON export, and renders the filtered list with timestamp and per-domain badges.

Sequence Diagram(s)

sequenceDiagram
  participant SettingsUI
  participant EventLogPanel
  participant EventAPI
  participant CoreEventBus

  SettingsUI->>EventLogPanel: open panel / mount
  EventLogPanel->>EventAPI: GET /events/domain (Bearer token)
  EventAPI->>EventLogPanel: SSE stream (data: JSON lines, keep-alive)
  loop on each DomainEvent
    CoreEventBus->>EventAPI: DomainEvent
    EventAPI->>EventLogPanel: data: {domain,event,timestamp}
    EventLogPanel->>SettingsUI: render prepend entry, update filters/controls
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2258: Both PRs modify DeveloperOptionsPanel menu modeling and i18n usage; this PR adds the event-log entry to that model.
  • tinyhumansai/openhuman#2250: Related changes to DeveloperOptionsPanel i18n wiring that this PR extends with a new menu item.

Poem

🐰 I nibble streams of events so neat,
Timestamps hop in lines I meet,
Badges gleam and filters play,
I jump to latest, save the day —
NDJSON tucked away.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(events): live domain event stream log panel' accurately summarizes the main change: adding a live event stream logging feature to the dashboard.
Linked Issues check ✅ Passed All primary objectives from issue #1849 are addressed: SSE live streaming, typed color-coded badges, max-entry enforcement, auto-scroll with pause, type/agent filters, NDJSON export, and i18n support across multiple languages.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the event log feature: backend SSE endpoint, frontend panel component, routing integration, and comprehensive i18n translations. No unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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


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 and usage tips.

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team. labels May 25, 2026
@Sathvik-1007 Sathvik-1007 reopened this May 25, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
app/src/components/settings/panels/EventLogPanel.tsx (1)

47-50: ⚡ Quick win

Remove the unused EventSource path to simplify ownership/cleanup.

The panel streams via fetch, so creating/closing/storing EventSource is dead code and makes lifecycle behavior harder to follow.

Proposed cleanup
-  const eventSourceRef = useRef<EventSource | null>(null);
@@
-    const es = new EventSource(url);
-
-    // EventSource doesn't support custom headers, so we use fetch-based SSE
-    es.close();
+    // EventSource doesn't support custom headers, so we use fetch-based SSE
@@
-    eventSourceRef.current = es;
     return () => {
       controller.abort();
     };
@@
     return () => {
       disconnect?.();
-      eventSourceRef.current?.close();
     };

Also applies to: 101-101, 110-110

🤖 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/settings/panels/EventLogPanel.tsx` around lines 47 - 50,
Remove the dead EventSource path: delete the instantiation and immediate close
of EventSource (the variable `es` created via `new EventSource(url)`) and any
other unused `EventSource` usage in EventLogPanel (including the occurrences
around lines referenced at 101 and 110) so the component only uses the
fetch-based SSE implementation; ensure no leftover references to `es` remain and
that ownership/cleanup logic is consolidated into the fetch/SSE cleanup handlers
in the EventLogPanel component.
🤖 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/components/settings/panels/EventLogPanel.tsx`:
- Around line 13-25: The component renders hard-coded UI text (badges and
status/button/count labels) — update it to use the i18n hook and keys: replace
visible literals like "Live", "Disconnected", "events", "Jump to latest" and
every badge label in EVENT_TYPE_COLORS with translation keys consumed via useT()
(e.g., change EVENT_TYPE_COLORS.{...}.label to a key string like
"eventLog.badge.tool" and when rendering call t('eventLog.badge.tool')). Add
corresponding entries to the English i18n file (app/src/lib/i18n/en.ts) for each
new key, update the JSX props (label/aria-label/button text/count suffix) to
call t(...) instead of hard-coded text, and ensure any tests or snapshots that
assert on these strings are updated accordingly.
- Line 3: The import for useT in EventLogPanel is using the wrong relative path
and causes a build error; update the import statement that currently references
'../../lib/i18n/I18nContext' to the correct relative path
'../../../lib/i18n/I18nContext' so the useT symbol is resolved (modify the
import line near the top of EventLogPanel.tsx to import useT from
'../../../lib/i18n/I18nContext').
- Around line 41-112: connect() creates an AbortController and starts the fetch
but the useEffect that calls connect() ignores its cleanup; update connect (the
function in EventLogPanel.tsx) to return a cleanup function that aborts the
controller and closes the EventSource/reader, then call that cleanup from the
useEffect's return so the streaming read loop is aborted on unmount (i.e., have
useEffect capture the cleanup = connect() and return () => { cleanup(); } or
store the controller in a ref and abort it in useEffect cleanup); ensure you
still set/clear eventSourceRef.current and call controller.abort() to prevent
state updates after unmount.

In `@app/src/lib/i18n/en.ts`:
- Around line 2960-2967: The new i18n keys under settings.developerMenu.eventLog
(for example 'settings.developerMenu.eventLog.title', '.desc', '.allTypes',
'.filterAgent', '.download', '.waiting', '.notConnected') were added only to
app/src/lib/i18n/en.ts; add these same keys (with English values) into each i18n
chunk file app/src/lib/i18n/chunks/en-1.ts ... en-5.ts and then add the
corresponding keys to each non-English locale chunk file (keeping existing
translations or adding placeholder translations) so all locale chunks include
the settings.developerMenu.eventLog.* entries to satisfy the i18n coverage gate.

---

Nitpick comments:
In `@app/src/components/settings/panels/EventLogPanel.tsx`:
- Around line 47-50: Remove the dead EventSource path: delete the instantiation
and immediate close of EventSource (the variable `es` created via `new
EventSource(url)`) and any other unused `EventSource` usage in EventLogPanel
(including the occurrences around lines referenced at 101 and 110) so the
component only uses the fetch-based SSE implementation; ensure no leftover
references to `es` remain and that ownership/cleanup logic is consolidated into
the fetch/SSE cleanup handlers in the EventLogPanel component.
🪄 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: ed93a8f5-d588-4eb9-afe5-a98150822c38

📥 Commits

Reviewing files that changed from the base of the PR and between e05cab9 and 8b04c54.

📒 Files selected for processing (5)
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/EventLogPanel.tsx
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • src/core/jsonrpc.rs

Comment thread app/src/components/settings/panels/EventLogPanel.tsx Outdated
Comment thread app/src/components/settings/panels/EventLogPanel.tsx Outdated
Comment thread app/src/components/settings/panels/EventLogPanel.tsx Outdated
Comment thread app/src/lib/i18n/en.ts
Comment on lines +2960 to +2967
'settings.developerMenu.eventLog.title': 'Event Log',
'settings.developerMenu.eventLog.desc':
'Live colour-coded stream of all agent, tool, and system events',
'settings.developerMenu.eventLog.allTypes': 'All types',
'settings.developerMenu.eventLog.filterAgent': 'Filter by agent...',
'settings.developerMenu.eventLog.download': 'Download',
'settings.developerMenu.eventLog.waiting': 'Waiting for events...',
'settings.developerMenu.eventLog.notConnected': 'Not connected to core',
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify newly added event log keys exist across required locale files/chunks.
keys=(
  "settings.developerMenu.eventLog.title"
  "settings.developerMenu.eventLog.desc"
  "settings.developerMenu.eventLog.allTypes"
  "settings.developerMenu.eventLog.filterAgent"
  "settings.developerMenu.eventLog.download"
  "settings.developerMenu.eventLog.waiting"
  "settings.developerMenu.eventLog.notConnected"
)

echo "== Checking English chunk files =="
fd -a '^en-[1-5]\.ts$' app/src/lib/i18n | sort

echo "== Checking all locale files/chunks for key presence =="
for k in "${keys[@]}"; do
  echo "--- $k ---"
  rg -n --fixed-strings "'$k'" app/src/lib/i18n || true
done

Repository: tinyhumansai/openhuman

Length of output: 1381


🏁 Script executed:

#!/bin/bash
set -euo pipefail

keys=(
  "settings.developerMenu.eventLog.title"
  "settings.developerMenu.eventLog.desc"
  "settings.developerMenu.eventLog.allTypes"
  "settings.developerMenu.eventLog.filterAgent"
  "settings.developerMenu.eventLog.download"
  "settings.developerMenu.eventLog.waiting"
  "settings.developerMenu.eventLog.notConnected"
)

echo "== Search for eventLog in chunks =="
rg -n "settings\.developerMenu\.eventLog" app/src/lib/i18n/chunks || true

echo "== Search for each key (no quote dependency) in chunks =="
for k in "${keys[@]}"; do
  echo "--- $k ---"
  rg -n --fixed-strings "$k" app/src/lib/i18n/chunks || true
done

Repository: tinyhumansai/openhuman

Length of output: 502


Propagate settings.developerMenu.eventLog.* keys to all i18n chunk files

The new settings.developerMenu.eventLog keys exist only in app/src/lib/i18n/en.ts (lines 2960-2967) and are missing from app/src/lib/i18n/chunks/en-{1..5}.ts and the corresponding non-English locale chunk files. This will break the i18n coverage gate.

🤖 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/lib/i18n/en.ts` around lines 2960 - 2967, The new i18n keys under
settings.developerMenu.eventLog (for example
'settings.developerMenu.eventLog.title', '.desc', '.allTypes', '.filterAgent',
'.download', '.waiting', '.notConnected') were added only to
app/src/lib/i18n/en.ts; add these same keys (with English values) into each i18n
chunk file app/src/lib/i18n/chunks/en-1.ts ... en-5.ts and then add the
corresponding keys to each non-English locale chunk file (keeping existing
translations or adding placeholder translations) so all locale chunks include
the settings.developerMenu.eventLog.* entries to satisfy the i18n coverage gate.

@Sathvik-1007 Sathvik-1007 force-pushed the feat/1849-live-event-stream-log branch from 8b04c54 to 5505f38 Compare May 25, 2026 23:23
@coderabbitai coderabbitai Bot added the rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. label May 25, 2026
@Sathvik-1007 Sathvik-1007 force-pushed the feat/1849-live-event-stream-log branch from 5505f38 to 5b81259 Compare May 25, 2026 23:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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/components/settings/panels/EventLogPanel.tsx`:
- Around line 30-31: The hard-coded MAX_ENTRIES and fixed newest-on-top behavior
in EventLogPanel should be driven by the app config keys
dashboard.event_stream.max_entries and dashboard.event_stream.new_entries:
update EventLogPanel to read those config values (or accept them as props)
instead of using the MAX_ENTRIES constant, use the configured max_entries to cap
the list length, and conditionally render/insert new events at the top when
new_entries is true (and at the bottom when false); replace references to
MAX_ENTRIES and the existing insertion/ordering logic (including the code around
the current newest-on-top handling at the area noted around lines 92-95) to
respect these config-driven settings.
- Around line 1-249: Prettier is failing for EventLogPanel.tsx; run the
project's Prettier formatter (or npm/yarn script such as "npm run format" /
"yarn format") and apply formatting to this file so it matches CI rules; ensure
you preserve exported symbol EventLogPanel and do not change logic in functions
like connect, exportLog, or constants DOMAIN_BADGE_KEYS and MAX_ENTRIES—only
reformat the file to satisfy prettier --check.
- Around line 71-104: The read loop for the SSE stream exits on EOF but never
clears the live flag, so call setIsLive(false) when the stream ends; inside the
async reader loop (the block using reader.read(), decoder, buffer and
idRef.current) setIsLive(false) right before/after breaking when done is true
(or move the setIsLive(false) into a finally/after-loop cleanup) so the
component's isLive state is set to disconnected when the stream completes or is
closed.

In `@app/src/pages/Settings.tsx`:
- Line 43: Run Prettier to format the Settings.tsx file to satisfy CI: run the
project's Prettier command (e.g., prettier --write) on the file and fix
formatting issues around the import for EventLogPanel and other locations noted
(approx. the Settings component top imports and the block around line 449).
Ensure the file compiles after formatting and commit the formatted file so
prettier --check passes in CI.
🪄 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: 97e5266e-bf94-474e-ab65-5735929bbfeb

📥 Commits

Reviewing files that changed from the base of the PR and between 5505f38 and 5b81259.

📒 Files selected for processing (18)
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/EventLogPanel.tsx
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/fr-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/ko-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • src/core/jsonrpc.rs
✅ Files skipped from review due to trivial changes (5)
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts

Comment thread app/src/components/settings/panels/EventLogPanel.tsx
Comment on lines +30 to +31
const MAX_ENTRIES = 200;

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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Entry cap/order are hard-coded, not config-driven.

This implementation fixes behavior to 200 entries and newest-on-top. The linked objective requires dashboard.event_stream.max_entries and dashboard.event_stream.new_entries to drive this behavior.

Also applies to: 92-95

🤖 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/settings/panels/EventLogPanel.tsx` around lines 30 - 31,
The hard-coded MAX_ENTRIES and fixed newest-on-top behavior in EventLogPanel
should be driven by the app config keys dashboard.event_stream.max_entries and
dashboard.event_stream.new_entries: update EventLogPanel to read those config
values (or accept them as props) instead of using the MAX_ENTRIES constant, use
the configured max_entries to cap the list length, and conditionally
render/insert new events at the top when new_entries is true (and at the bottom
when false); replace references to MAX_ENTRIES and the existing
insertion/ordering logic (including the code around the current newest-on-top
handling at the area noted around lines 92-95) to respect these config-driven
settings.

Comment thread app/src/components/settings/panels/EventLogPanel.tsx
Comment thread app/src/pages/Settings.tsx Outdated
import VoiceDebugPanel from '../components/settings/panels/VoiceDebugPanel';
import VoicePanel from '../components/settings/panels/VoicePanel';
import WebhooksDebugPanel from '../components/settings/panels/WebhooksDebugPanel';
import EventLogPanel from '../components/settings/panels/EventLogPanel';
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Run Prettier on this file to unblock CI.

prettier --check is currently failing for this file; please format it before merge (around Line 43 and Line 449 changes included).

Also applies to: 449-449

🤖 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/pages/Settings.tsx` at line 43, Run Prettier to format the
Settings.tsx file to satisfy CI: run the project's Prettier command (e.g.,
prettier --write) on the file and fix formatting issues around the import for
EventLogPanel and other locations noted (approx. the Settings component top
imports and the block around line 449). Ensure the file compiles after
formatting and commit the formatted file so prettier --check passes in CI.

SSE endpoint GET /events/domain streams DomainEvent bus.
React panel at Settings > Developer > Event Log with
colour-coded badges, type/agent filtering, auto-scroll,
and ndjson export.

Closes tinyhumansai#1849
@Sathvik-1007 Sathvik-1007 force-pushed the feat/1849-live-event-stream-log branch from 5b81259 to d5aedab Compare May 25, 2026 23:34
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 (1)
src/core/jsonrpc.rs (1)

1077-1083: ⚡ Quick win

Harden event-name scrubbing for tuple-style debug output.

The current split logic misses Variant(...) shapes, so payload text can leak into event_name if tuple variants are introduced.

🔧 Suggested tweak
-            let event_name = variant
-                .split_once('{')
-                .or_else(|| variant.split_once(' '))
+            let event_name = variant
+                .split_once('{')
+                .or_else(|| variant.split_once('('))
+                .or_else(|| variant.split_once(' '))
                 .map(|(name, _)| name.trim())
                 .unwrap_or(&variant);
🤖 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 `@src/core/jsonrpc.rs` around lines 1077 - 1083, The event-name extraction for
the Debug-formatted `variant` (assigned to `variant` and used to create
`event_name`) currently only splits on '{' and ' ' and therefore can leak
payload text for tuple-style variants like `Variant(...)`; update the scrub
logic to also split on '(' (i.e., find the first occurrence of any of '{', ' ',
'('), then take the left part and trim it, so tuple payloads are stripped the
same as struct-style payloads; change the code that computes `event_name` (the
block that calls `split_once` on `variant`) to try these separators in a robust
order and fall back to the whole `variant` if none match.
🤖 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/components/settings/panels/EventLogPanel.tsx`:
- Around line 125-128: The current filteredEntries logic uses filterText against
e.event but the UI intends an agent-name filter; update the predicate to check
the entry's agent name field instead of e.event — e.g. replace the condition `if
(filterText && !e.event.toLowerCase().includes(filterText.toLowerCase()))` with
a check against the agent property (for example `const agentName = e.agent ||
e.agentName || e.actor` and `if (filterText &&
!agentName?.toLowerCase().includes(filterText.toLowerCase())) return false;`) so
the filterText matches agent names case-insensitively while keeping the existing
filterType check and final return.
- Around line 105-111: The cleanup in EventLogPanel's useEffect currently calls
setIsLive(false) which triggers the react-hooks/set-state-in-effect warning;
remove setIsLive(false) from the cleanup and instead ensure isLive is cleared
inside the connection lifecycle: update the connect() implementation to
setIsLive(false) on abort/error/finally and also make abort() set isLive false
(e.g., when controllerRef.current?.abort() is invoked handle the abort signal or
promise rejection to call setIsLive(false)), or if you intentionally must change
state in cleanup add a single-line eslint-disable comment with a clear
justification referencing why setIsLive must run on unmount and target
react-hooks/set-state-in-effect.

---

Nitpick comments:
In `@src/core/jsonrpc.rs`:
- Around line 1077-1083: The event-name extraction for the Debug-formatted
`variant` (assigned to `variant` and used to create `event_name`) currently only
splits on '{' and ' ' and therefore can leak payload text for tuple-style
variants like `Variant(...)`; update the scrub logic to also split on '(' (i.e.,
find the first occurrence of any of '{', ' ', '('), then take the left part and
trim it, so tuple payloads are stripped the same as struct-style payloads;
change the code that computes `event_name` (the block that calls `split_once` on
`variant`) to try these separators in a robust order and fall back to the whole
`variant` if none match.
🪄 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: fabe830f-8085-4beb-972e-64c5ba074386

📥 Commits

Reviewing files that changed from the base of the PR and between 5b81259 and d5aedab.

📒 Files selected for processing (18)
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/EventLogPanel.tsx
  • app/src/lib/i18n/chunks/ar-5.ts
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/fr-5.ts
  • app/src/lib/i18n/chunks/hi-5.ts
  • app/src/lib/i18n/chunks/id-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/ko-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/zh-CN-5.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Settings.tsx
  • src/core/jsonrpc.rs
✅ Files skipped from review due to trivial changes (8)
  • app/src/lib/i18n/chunks/bn-5.ts
  • app/src/lib/i18n/chunks/it-5.ts
  • app/src/lib/i18n/chunks/es-5.ts
  • app/src/lib/i18n/chunks/pt-5.ts
  • app/src/lib/i18n/chunks/ru-5.ts
  • app/src/lib/i18n/chunks/de-5.ts
  • app/src/lib/i18n/chunks/en-5.ts
  • app/src/lib/i18n/en.ts

Comment thread app/src/components/settings/panels/EventLogPanel.tsx
Comment on lines +125 to +128
const filteredEntries = entries.filter(e => {
if (filterType && e.domain !== filterType) return false;
if (filterText && !e.event.toLowerCase().includes(filterText.toLowerCase())) return false;
return true;
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Filter logic does not match “agent” filter intent.

Line 127 filters filterText against e.event, but the UI key (settings.developerMenu.eventLog.filterAgent) indicates agent-name filtering. This misses the stated behavior for agent search.

Suggested direction
 interface EventEntry {
   id: number;
   domain: string;
+  agent?: string;
   event: string;
   timestamp: string;
 }
@@
-              const entry: EventEntry = {
+              const entry: EventEntry = {
                 id: ++idRef.current,
                 domain: data.domain || 'unknown',
+                agent: data.agent || '',
                 event: data.event || '',
                 timestamp: data.timestamp || '',
               };
@@
-    if (filterText && !e.event.toLowerCase().includes(filterText.toLowerCase())) return false;
+    if (filterText && !e.agent?.toLowerCase().includes(filterText.toLowerCase())) return false;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const filteredEntries = entries.filter(e => {
if (filterType && e.domain !== filterType) return false;
if (filterText && !e.event.toLowerCase().includes(filterText.toLowerCase())) return false;
return true;
const filteredEntries = entries.filter(e => {
if (filterType && e.domain !== filterType) return false;
if (filterText && !e.agent?.toLowerCase().includes(filterText.toLowerCase())) return false;
return true;
🤖 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/settings/panels/EventLogPanel.tsx` around lines 125 - 128,
The current filteredEntries logic uses filterText against e.event but the UI
intends an agent-name filter; update the predicate to check the entry's agent
name field instead of e.event — e.g. replace the condition `if (filterText &&
!e.event.toLowerCase().includes(filterText.toLowerCase()))` with a check against
the agent property (for example `const agentName = e.agent || e.agentName ||
e.actor` and `if (filterText &&
!agentName?.toLowerCase().includes(filterText.toLowerCase())) return false;`) so
the filterText matches agent names case-insensitively while keeping the existing
filterType check and final return.

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

Labels

feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request : Live typed event stream log real-time colour-coded agent activity feed in the dashboard

1 participant