Skip to content

Comments

Workers tab: full transcript viewer, live SSE streaming, introspection tool#192

Merged
jamiepine merged 12 commits intomainfrom
worker-tab
Feb 24, 2026
Merged

Workers tab: full transcript viewer, live SSE streaming, introspection tool#192
jamiepine merged 12 commits intomainfrom
worker-tab

Conversation

@jamiepine
Copy link
Member

@jamiepine jamiepine commented Feb 24, 2026

Summary

  • Two-column workers page at /agents/$agentId/workers replaces the "coming soon" placeholder. Left panel lists all worker runs across channels, right panel shows full detail with transcript.
  • Worker transcripts are persisted as gzipped JSON blobs on worker_runs at completion. Typical 30-message transcript compresses from ~15-50KB to ~3-8KB.
  • Running workers stream live transcripts via SSE — tool calls and results appear in real-time as the worker executes, not just after completion.
  • worker_inspect tool on branches lets the LLM retrieve a worker's full transcript to verify what it actually did. Useful for debugging thin results or answering "what did you check?"
  • Cancel button on the workers tab detail view for running workers, hitting the existing POST /channels/cancel API.
  • Worker completion messages now include the worker ID ([Worker {uuid} completed]: {result}) so the channel LLM can reference specific workers.
  • Channel prompt updated with guidance on cancel and worker_inspect tools.

Backend

New files:

  • migrations/20260223000001_worker_transcript.sqlworker_type, agent_id, transcript columns
  • migrations/20260224000001_worker_tool_calls.sqltool_calls column
  • src/conversation/worker_transcript.rs — serialize/deserialize Rig history to gzipped transcript blob
  • src/api/workers.rs — list + detail endpoints with StatusBlock live merge
  • src/tools/worker_inspect.rs — branch tool for transcript introspection

Key changes:

  • ProcessEvent::WorkerStarted now carries worker_type, WorkerComplete carries success
  • ProcessEvent::ToolStarted now carries args, ApiEvent::ToolCompleted now forwards result — enables live transcript on the frontend
  • Worker::run() persists transcript blob on all exit paths (success, failure, cancellation)
  • log_worker_completed writes 'done' vs 'failed' status based on the new success field (was always 'done' before)
  • Worker compaction recaps now truncate tool args and results to 200 bytes instead of dumping full HTML/JSON
  • Transcript serializer skips [System: compaction markers
  • Retrigger fallback: channel now sends the LLM's text response to the user when the reply tool wasn't used on a retrigger turn (was silently suppressing worker results)

Frontend

New files:

  • interface/src/routes/AgentWorkers.tsx — two-column worker viewer

Key changes:

  • useLiveContext now exposes activeWorkers (flat map), workerEventVersion (SSE counter), liveTranscripts (per-worker transcript accumulator from SSE tool events)
  • Workers tab synthesizes list entries and detail views from SSE state for workers that haven't hit the DB yet
  • Worker items in channel timeline are now links to the workers tab
  • Transcript steps animate in with a fade+slide on arrival
  • Markdown rendering on result text and action content via the existing Markdown component

Note

This PR adds a complete workers visibility layer with full transcript persistence and real-time streaming. Users can now inspect worker execution in detail from a dedicated tab, and branches can introspect worker transcripts programmatically for debugging and verification. The 29-file diff spans frontend/backend event streaming, database schema, API endpoints, and new introspection tooling.

Written by Tembo for commit 859f643.

jamiepine and others added 9 commits February 23, 2026 19:20
… worker list and detail views, transcript handling, and integration with live context
…ipt and improved error handling for missing data
…users to cancel running workers and update documentation to include cancellation instructions
…badge rendering; update cancellation logging in channel
@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Walkthrough

This PR extends worker management with transcript persistence, live status tracking, and new API endpoints. It introduces database migrations for storing worker transcripts and tool call counts, enriches events with metadata fields, adds frontend components for browsing and inspecting workers, implements a new worker_inspect tool, and wires transcript (de)serialization throughout the backend.

Changes

Cohort / File(s) Summary
Worker API & Endpoints
src/api/workers.rs, src/api/server.rs, src/api/state.rs
New worker listing and detail endpoints with support for status filtering, pagination, and live status merging from channel state blocks.
Worker Transcript Storage
src/conversation/worker_transcript.rs, src/conversation.rs, src/conversation/history.rs
New transcript serialization/deserialization with gzip compression; ProcessRunLogger now persists worker_type, agent_id, and success state; added list_worker_runs and get_worker_detail queries.
Database Migrations
migrations/20260223000001_worker_transcript.sql, migrations/20260224000001_worker_tool_calls.sql
Added worker_type, agent_id, transcript columns and tool_calls counter to worker_runs; indexed on (agent_id, started_at) for efficient queries.
Worker Inspection Tool
src/tools/worker_inspect.rs, src/tools.rs, src/prompts/text.rs, prompts/en/tools/worker_inspect_description.md.j2
New worker_inspect tool to query single worker transcripts or list recent workers; integrated into channel and cortex tool servers.
Event & State Enrichment
src/lib.rs, src/hooks/spacebot.rs, src/agent/channel.rs, src/agent/worker.rs
Extended ProcessEvent and ApiEvent variants with worker_type, success, and args/result fields; added transcript persistence on worker completion, cancellation, and failure paths.
Worker Tool Server Integration
src/agent/ingestion.rs, src/api/agents.rs, src/main.rs, tests/context_dump.rs
Updated create_branch_tool_server and create_cortex_chat_tool_server signatures to accept ProcessRunLogger, agent_id, workspace_dir, and sandbox; threaded through call sites.
Frontend Worker UI
interface/src/routes/AgentWorkers.tsx, interface/src/routes/ChannelDetail.tsx, interface/src/router.tsx
New AgentWorkers component with two-column list/detail view, status filtering, live SSE integration, transcript rendering, and tool result visualization; integrated router with /agents/$agentId/workers.
Live Context & State Management
interface/src/hooks/useLiveContext.tsx, interface/src/components/WebChatPanel.tsx
Extended LiveContextValue with activeWorkers, workerEventVersion, and liveTranscripts; added SSE message deduplication and aggregation in WebChatPanel.
Type Definitions
interface/src/api/client.ts, prompts/en/channel.md.j2
Extended event interfaces with optional worker_type, success, args, result fields; added ActionContent and TranscriptStep types; updated prompt guidance for worker_inspect and cancel capabilities.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Frontend as AgentWorkers UI
    participant API as Workers API
    participant DB as Database
    participant ToolServer as Tool Server
    participant WorkerInspectTool as worker_inspect Tool

    User->>Frontend: Request worker list
    Frontend->>API: GET /agents/workers?agentId=...
    API->>DB: list_worker_runs(agentId, status_filter)
    DB-->>API: WorkerRunRow[]
    API->>API: Merge live status from channel StatusBlocks
    API-->>Frontend: WorkerListResponse
    Frontend-->>User: Display worker list with live indicators

    User->>Frontend: Click worker for detail
    Frontend->>API: GET /agents/workers/detail?agentId=...&workerId=...
    API->>DB: get_worker_detail(workerId)
    DB-->>API: WorkerDetailRow (with compressed transcript)
    API->>API: Decompress transcript blob
    API-->>Frontend: WorkerDetailResponse
    Frontend->>Frontend: Render transcript steps + tool calls
    Frontend-->>User: Display worker details & transcript

    User->>ToolServer: Invoke worker_inspect tool
    ToolServer->>WorkerInspectTool: call({worker_id: "...", limit: 10})
    WorkerInspectTool->>DB: list_worker_runs or get_worker_detail
    DB-->>WorkerInspectTool: Worker data
    WorkerInspectTool->>WorkerInspectTool: Format transcript summary
    WorkerInspectTool-->>ToolServer: WorkerInspectOutput (summary text)
    ToolServer-->>User: Display transcript summary in chat
Loading
sequenceDiagram
    participant Worker as Worker Process
    participant RunLogger as ProcessRunLogger
    participant DB as SQLite Database
    participant EventBus as Event Bus / SSE

    rect rgba(100, 150, 200, 0.5)
    Note over Worker,EventBus: Worker Lifecycle Logging
    end

    Worker->>RunLogger: log_worker_started(worker_id, task, worker_type, agent_id)
    RunLogger->>DB: INSERT worker_runs (worker_id, agent_id, worker_type, task, ...)
    Worker->>EventBus: Emit ProcessEvent::WorkerStarted {worker_type, ...}

    loop Worker executing
        Worker->>RunLogger: log_tool_started(tool_name, args)
        RunLogger->>EventBus: Emit ProcessEvent::ToolStarted {args (truncated), ...}
        Worker->>RunLogger: log_tool_completed(tool_name, result)
        RunLogger->>EventBus: Emit ProcessEvent::ToolCompleted {result, ...}
    end

    Worker->>RunLogger: persist_transcript(history)
    RunLogger->>RunLogger: serialize_transcript() → gzip compress
    RunLogger->>DB: UPDATE worker_runs SET transcript=blob, tool_calls=count
    
    Worker->>RunLogger: log_worker_completed(worker_id, result, success)
    RunLogger->>DB: UPDATE worker_runs SET status=(...), result=..., completed_at=...
    RunLogger->>EventBus: Emit ProcessEvent::WorkerComplete {success, ...}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

This PR introduces substantial new functionality across frontend and backend: a 622-line AgentWorkers component, 221-line worker_inspect tool, 184-line workers API module, and extensive event system enrichment. The changes span multiple concerns (transcripts, live status, new endpoints, tool integration) with significant logic density, particularly around transcript serialization, live status merging, and component state management. The heterogeneous nature of frontend UI composition, backend database queries, event propagation, and tool integration demands careful reasoning across each subsystem.

Poem

🐰 A hop through the workers, transcripts in sight,
Live status dancing, all shimmering bright,
Tool calls inspected, from start until end,
Each run now recorded, a traceable friend!
The warren grows smarter—one transcript at a time.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main changes: workers tab with transcript viewer, live SSE streaming, and introspection tool capabilities.
Description check ✅ Passed The description comprehensively explains the changeset, covering summary, backend, and frontend changes with implementation details and rationale.
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.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch worker-tab

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.

# Conflicts:
#	src/api/agents.rs
#	src/tools.rs
@jamiepine jamiepine marked this pull request as ready for review February 24, 2026 10:33
…dump tests

- Introduced ProcessRunLogger to both dump_branch_context and dump_all_contexts functions.
- Updated branch tool server creation to include the new logger for improved process tracking.
Copy link

@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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
interface/src/routes/ChannelDetail.tsx (1)

80-101: ⚠️ Potential issue | 🟡 Minor

Avoid nesting the Cancel button inside the worker link.

Placing a <button> inside a <Link> (anchor) is invalid HTML and can cause accidental navigation or keyboard accessibility issues when cancelling. Move the cancel control outside the link (or use a non-interactive container for navigation).

💡 One way to separate the link and the cancel action
-				<Link
-					to="/agents/$agentId/workers"
-					params={{ agentId }}
-					search={{ worker: item.id }}
-					className="block rounded-md bg-amber-500/10 px-3 py-2 transition-colors hover:bg-amber-500/15"
-				>
-					<div className="flex min-w-0 items-center gap-2 overflow-hidden">
-						<div className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
-						<span className="text-sm font-medium text-amber-300">Worker</span>
-						<span className="min-w-0 flex-1 truncate text-sm text-ink-dull">{item.task}</span>
-						<CancelButton onClick={() => { api.cancelProcess(channelId, "worker", item.id).catch(console.warn); }} />
-					</div>
-					<div className="mt-1 flex min-w-0 items-center gap-3 overflow-hidden pl-4 text-tiny text-ink-faint">
-						<span className="truncate">{live.status}</span>
-						{live.currentTool && (
-							<span className="truncate text-amber-400/70">{live.currentTool}</span>
-						)}
-						{live.toolCalls > 0 && (
-							<span>{live.toolCalls} tool calls</span>
-						)}
-					</div>
-				</Link>
+				<div className="rounded-md bg-amber-500/10 px-3 py-2 transition-colors hover:bg-amber-500/15">
+					<Link
+						to="/agents/$agentId/workers"
+						params={{ agentId }}
+						search={{ worker: item.id }}
+						className="block"
+					>
+						<div className="flex min-w-0 items-center gap-2 overflow-hidden">
+							<div className="h-2 w-2 animate-pulse rounded-full bg-amber-400" />
+							<span className="text-sm font-medium text-amber-300">Worker</span>
+							<span className="min-w-0 flex-1 truncate text-sm text-ink-dull">{item.task}</span>
+						</div>
+						<div className="mt-1 flex min-w-0 items-center gap-3 overflow-hidden pl-4 text-tiny text-ink-faint">
+							<span className="truncate">{live.status}</span>
+							{live.currentTool && (
+								<span className="truncate text-amber-400/70">{live.currentTool}</span>
+							)}
+							{live.toolCalls > 0 && (
+								<span>{live.toolCalls} tool calls</span>
+							)}
+						</div>
+					</Link>
+					<div className="mt-2 flex justify-end">
+						<CancelButton onClick={() => { api.cancelProcess(channelId, "worker", item.id).catch(console.warn); }} />
+					</div>
+				</div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@interface/src/routes/ChannelDetail.tsx` around lines 80 - 101, The
CancelButton is currently nested inside the Link (the <Link ...> block rendering
the worker) which is invalid and can cause accidental navigation; move the
<CancelButton ... /> out of the Link so the Link only wraps the navigational
content (the divs showing worker info), render the CancelButton as a sibling
(e.g. immediately after the Link) and keep its onClick using
api.cancelProcess(channelId, "worker", item.id).catch(console.warn); to preserve
behavior, and add an onClick handler that calls event.stopPropagation() (and
ensure it is a real <button> with an accessible aria-label) so clicking cancel
won’t trigger the surrounding navigation.
🧹 Nitpick comments (2)
src/agent/channel.rs (1)

1448-1486: Duplication with the skipped && is_retrigger fallback block above (lines 1406–1437).

Both branches perform identical logic: trim → extract_reply_from_tool_syntax → derive source → normalize_discord_mention_tokens → log bot message → send. Consider extracting a send_retrigger_fallback(&self, response: &str) helper to DRY this up.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/channel.rs` around lines 1448 - 1486, The retrigger fallback logic
(trim → extract_reply_from_tool_syntax → derive source →
normalize_discord_mention_tokens → log bot message → send via response_tx) is
duplicated; refactor by adding a private helper method
send_retrigger_fallback(&self, response: &str) that encapsulates the flow (use
extract_reply_from_tool_syntax,
crate::tools::reply::normalize_discord_mention_tokens,
self.state.conversation_logger.log_bot_message, and self.response_tx.send) and
call it from both the skipped && is_retrigger block and the else if is_retrigger
block to remove duplication while preserving the existing logging and error
handling behavior.
src/tools/worker_inspect.rs (1)

34-34: JsonSchema derive on WorkerInspectArgs is unused.

The definition() method manually constructs the JSON schema (lines 65-80), so the JsonSchema derive on WorkerInspectArgs is dead code. Either use schemars::schema_for!(WorkerInspectArgs) inside definition() to stay DRY, or remove the derive.

Also applies to: 61-82

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tools/worker_inspect.rs` at line 34, The JsonSchema derive on
WorkerInspectArgs is redundant because definition() builds the schema manually;
fix by either removing the JsonSchema derive and any unused schemars imports, or
(preferred) use schemars::schema_for!(WorkerInspectArgs) inside
WorkerInspectArgs::definition() to return the generated schema and remove the
handcrafted schema block—ensure you update imports to include
schemars::schema_for and remove now-unused manual schema construction
(references: WorkerInspectArgs, definition(), JsonSchema).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@interface/src/components/WebChatPanel.tsx`:
- Around line 177-218: The SSE-sourced messages in sseMessages are not
deduplicated against the current messages array, causing duplicate IDs in
allMessages; fix this by filtering out any sseMessages whose id already exists
in messages before composing allMessages (e.g. compute a Set of message ids from
messages and either call
setSseMessages(prev=>prev.filter(m=>!messageIdSet.has(m.id))) inside the
messages effect or derive const filteredSse =
sseMessages.filter(m=>!messageIdSet.has(m.id)); then use const allMessages =
[...messages, ...filteredSse]; reference sseMessages, setSseMessages, messages,
and allMessages to locate the change.

In `@interface/src/routes/AgentWorkers.tsx`:
- Around line 103-175: The merge logic for mergedWorkers and mergedDetail uses
global activeWorkers and can surface SSE-only workers from other agents;
restrict activeWorkers to the current agent before overlay/synthesis by checking
agent affiliation (e.g., live.agent_id === currentAgentId or
channelAgentMap[live.channelId] === currentAgentId). Update the mergedWorkers
mapping and synthetic creation (symbols: mergedWorkers, activeWorkers, workers)
to filter Object.values(activeWorkers) and the overlay lookup
(activeWorkers[worker.id]) by agent, and likewise update mergedDetail (symbols:
mergedDetail, detailData, selectedWorkerId, activeWorkers) to only consider live
when the live entry matches the currentAgentId so synthesized detail views
cannot show cross-agent workers.

In `@src/agent/worker.rs`:
- Around line 479-511: persist_transcript currently serializes only the
in-memory history so transcripts become partial after compact_history drains
older messages; update the logic so drained messages are preserved and included
in what persist_transcript serializes—either (A) add a persistent/owned
transcript buffer (e.g., a Vec or String in the worker state) that
compact_history appends drained messages to before removing them, and then have
persist_transcript call
crate::conversation::worker_transcript::serialize_transcript on that combined
buffer + current history, or (B) call persist_transcript (or a new
persist_drained_messages helper that uses serialize_transcript) immediately
before compact_history removes messages so the drained messages are persisted to
worker_runs; modify persist_transcript, compact_history, and where
serialize_transcript is invoked to use this preserved transcript source instead
of only the history slice.

In `@src/api/workers.rs`:
- Around line 81-87: Clamp and validate pagination inputs before calling
logger.list_worker_runs: ensure limit is constrained to the range [0, 200] (e.g.
take query.limit, clamp to 0.min..200.max) and ensure offset is non‑negative
(clamp query.offset to >= 0) then convert to the expected numeric type for
list_worker_runs; replace the current let limit = query.limit.min(200) with
these validated values and pass the validated limit and offset into
list_worker_runs.

In `@src/conversation/history.rs`:
- Around line 453-487: The count query uses a WHERE template that expects the
status at parameter ?4 while count_q only binds two params, causing status
filtering to fail; update the code to use separate WHERE clauses or parameter
ordering for count and list (e.g., introduce where_clause_count = "WHERE
w.agent_id = ?1 AND w.status = ?2" and keep where_clause_list = "WHERE
w.agent_id = ?1 AND w.status = ?4"), then build count_query from
where_clause_count and bind agent_id then filter to count_q (while leaving
list_query/ list_q binding unchanged), or alternatively switch to named
parameters so count_q and list_q bind the same logical parameters correctly
(modify count_query/count_q and list_query/list_q accordingly to ensure the
status_filter value is bound to the positional placeholder used in that query).

In `@src/conversation/worker_transcript.rs`:
- Around line 45-53: The serialize_transcript function silently swallows
serialization and compression errors; change its signature from pub fn
serialize_transcript(history: &[rig::message::Message]) -> Vec<u8> to return a
Result (e.g. -> Result<Vec<u8>, Box<dyn std::error::Error>> or
anyhow::Result<Vec<u8>>), replace serde_json::to_vec(...).unwrap_or_default()
with let json = serde_json::to_vec(&steps)?;, replace
encoder.write_all(&json).ok() with encoder.write_all(&json)?;, and replace
encoder.finish().unwrap_or_default() with let out = encoder.finish()?; then
return Ok(out); update any callers of serialize_transcript accordingly so errors
are propagated or logged.

In `@src/hooks/spacebot.rs`:
- Around line 195-204: The send on the broadcast channel is silently discarding
the Result via "let _ = self.event_tx.send(event);"; update the send to
explicitly call .ok() on the Result to follow the guideline for channel sends.
Locate the block that constructs ProcessEvent::ToolStarted (uses capped_args
from crate::tools::truncate_output and fields
agent_id/process_id/channel_id/tool_name) and replace the "let _ =
self.event_tx.send(event);" pattern with "self.event_tx.send(event).ok();" so
the Result is explicitly ignored in the approved way.

In `@src/tools/worker_inspect.rs`:
- Around line 137-142: The code truncates with a byte slice (&text[..500]) which
panics on multi-byte UTF-8 boundaries; replace that byte-slice truncation with a
char-safe truncation (e.g., build the preview with
text.chars().take(500).collect::<String>() or compute a char-aware byte index
via char_indices) and use that result when formatting the display variable while
still keeping text.len() (or text.as_bytes().len()) for the total byte count if
desired; update the block that constructs display (the variable named display
using text) to avoid any direct byte-indexing of text.

---

Outside diff comments:
In `@interface/src/routes/ChannelDetail.tsx`:
- Around line 80-101: The CancelButton is currently nested inside the Link (the
<Link ...> block rendering the worker) which is invalid and can cause accidental
navigation; move the <CancelButton ... /> out of the Link so the Link only wraps
the navigational content (the divs showing worker info), render the CancelButton
as a sibling (e.g. immediately after the Link) and keep its onClick using
api.cancelProcess(channelId, "worker", item.id).catch(console.warn); to preserve
behavior, and add an onClick handler that calls event.stopPropagation() (and
ensure it is a real <button> with an accessible aria-label) so clicking cancel
won’t trigger the surrounding navigation.

---

Nitpick comments:
In `@src/agent/channel.rs`:
- Around line 1448-1486: The retrigger fallback logic (trim →
extract_reply_from_tool_syntax → derive source →
normalize_discord_mention_tokens → log bot message → send via response_tx) is
duplicated; refactor by adding a private helper method
send_retrigger_fallback(&self, response: &str) that encapsulates the flow (use
extract_reply_from_tool_syntax,
crate::tools::reply::normalize_discord_mention_tokens,
self.state.conversation_logger.log_bot_message, and self.response_tx.send) and
call it from both the skipped && is_retrigger block and the else if is_retrigger
block to remove duplication while preserving the existing logging and error
handling behavior.

In `@src/tools/worker_inspect.rs`:
- Line 34: The JsonSchema derive on WorkerInspectArgs is redundant because
definition() builds the schema manually; fix by either removing the JsonSchema
derive and any unused schemars imports, or (preferred) use
schemars::schema_for!(WorkerInspectArgs) inside WorkerInspectArgs::definition()
to return the generated schema and remove the handcrafted schema block—ensure
you update imports to include schemars::schema_for and remove now-unused manual
schema construction (references: WorkerInspectArgs, definition(), JsonSchema).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af095f3 and 896acec.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • Cargo.toml is excluded by !**/*.toml
📒 Files selected for processing (28)
  • interface/src/api/client.ts
  • interface/src/components/WebChatPanel.tsx
  • interface/src/hooks/useLiveContext.tsx
  • interface/src/router.tsx
  • interface/src/routes/AgentWorkers.tsx
  • interface/src/routes/ChannelDetail.tsx
  • migrations/20260223000001_worker_transcript.sql
  • migrations/20260224000001_worker_tool_calls.sql
  • prompts/en/channel.md.j2
  • prompts/en/tools/worker_inspect_description.md.j2
  • src/agent/channel.rs
  • src/agent/ingestion.rs
  • src/agent/worker.rs
  • src/api.rs
  • src/api/agents.rs
  • src/api/server.rs
  • src/api/state.rs
  • src/api/workers.rs
  • src/conversation.rs
  • src/conversation/history.rs
  • src/conversation/worker_transcript.rs
  • src/hooks/spacebot.rs
  • src/lib.rs
  • src/main.rs
  • src/prompts/text.rs
  • src/tools.rs
  • src/tools/worker_inspect.rs
  • tests/context_dump.rs

…ndling and deduplication

- Updated WebChatPanel to use useMemo for deduplicating messages from SSE and API.
- Enhanced LiveContextProvider to include agentId in activeWorkers and optimized the retrieval of active workers based on agentId.
- Adjusted AgentWorkers to utilize scopedActiveWorkers for better performance and clarity.
- Modified worker history management in the Rust backend to improve context handling and transcript persistence.
- Improved API endpoints for listing and retrieving worker details to ensure proper agent context is maintained.
@jamiepine jamiepine merged commit 673dbcd into main Feb 24, 2026
3 checks passed
bilawalriaz added a commit to bilawalriaz/spacebot that referenced this pull request Feb 24, 2026
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.

1 participant