feat(cast-agent): boot runtime + gateway status pill#26
Merged
Conversation
PRODUCT + TECH specs for upgrading the existing browser pane (app/src/browser/) into a secure, agent-driven design/UX layer: - Toolbar + tab strip restyle matching the comux reference. - Titlebar toggle button, View menu mirror, command palette, ⌘⌥B keymap. - Global persistence of pane open/closed state and tab list. - Per-app private WebKit data dir, popup interception, gated DevTools, bundled tracker/ad blocklist. - Agent surface (screenshot, evaluate, element picker, console/network capture, navigation API) exposed via warpui actions and an in-process MCP server discoverable through ~/.cast-codes/mcp.json. Builds on prior pane work (390efd4, multi-tab support) without migrating away from the existing wry-direct architecture. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implementation plan for the first of four sequential subprojects: toolbar/tab-strip restyle, ToggleBrowserPane action with ⌘⌥B keymap + titlebar toggle button, persistence of pane state + tabs across restarts. Security hardening, agent surface, and MCP server are deferred to PLAN-02 / PLAN-03 / PLAN-04. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires the Cast Agent backend end-to-end as the agent panel's first live consumer — small enough to validate the runtime + global handle plumbing, intentionally narrow so message-flow and session integration land in later PRs. What's new: - `crates/cast_agent/src/runtime.rs` — owns a dedicated multi-threaded tokio runtime on a background OS thread. `CastAgentRuntime::boot()` builds the runtime, blocks-on `CastAgent::new()`, and spawns a 30s recurring health probe so `is_available()` reflects current state. - `runtime::global()` exposes a `OnceLock<CastAgentRuntime>` so callers get a single shared instance; `runtime::is_available()` is a sync atomic read safe to call on every render frame. - `crates/ai/src/lib.rs` — adds a `cast_agent` module facade (gated by the existing `cast-agent` feature) re-exporting the runtime entry points so `app/src` depends on `ai::cast_agent::*` rather than the cast_agent crate directly. - `app/src/lib.rs` — `run()` eagerly initializes the runtime right after `init_feature_flags()` so the first UI render doesn't pay the `OnceLock` boot cost. Gated by `cfg(feature = "cast-agent")`. - `app/src/ai_assistant/panel.rs` — `render_gateway_status_pill()` draws an 8px brand-colored dot in the agent panel header. Green when the gateway responds to `GET /health`, amber when it doesn't. - `app/src/ai/coven_brand.rs` — `OPENCOVEN_SUCCESS` (#22C55E) and `OPENCOVEN_WARNING` (#F59E0B), matching the brand palette already applied in `castcodes_dark`. Feature wiring: - `app/Cargo.toml` — new `cast-agent = ["ai/cast-agent"]` feature so `app/src` can use `#[cfg(feature = "cast-agent")]` directly. Bundled into `gui` so the OSS graphical build ships with the pill enabled; headless builds skip the tokio runtime + reqwest cost. - `crates/cast_agent/Cargo.toml` — adds `async-trait` workspace dep (the `AgentBackend` trait now uses `#[async_trait]` for object safety, mirroring the rest of the workspace). Verified: - `cargo check -p cast_agent` ✅ - `cargo check -p ai` ✅ - `cargo check -p ai --features cast-agent` ✅ - `cargo check -p warp-app --bin cast-codes --features gui` ✅ (1m 33s) - `cargo check -p warp-app --bin cast-codes --features gui,cast-agent` ✅ - `./script/check_rebrand` ✅ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Introduces the first end-to-end integration slice of the Cast Agent backend into the GUI by booting a dedicated Tokio runtime with a process-wide handle and surfacing gateway reachability via a small status pill in the agent panel header. The PR also adds a set of Browser Panel spec/plan documents under specs/.
Changes:
- Add
cast_agent::runtime(singleton runtime + periodic/healthprobe) and re-export it via anai::cast_agentfacade. - Eagerly boot the runtime at app startup and render a gateway status pill (green/amber) in the AI assistant panel header.
- Add new Browser Panel product/tech specs and an implementation plan under
specs/CASTCODES-BROWSER-PANEL/.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| specs/CASTCODES-BROWSER-PANEL/TECH.md | Adds a technical spec for a future Browser Panel implementation. |
| specs/CASTCODES-BROWSER-PANEL/PRODUCT.md | Adds a product spec defining Browser Panel UX/security/agent goals. |
| specs/CASTCODES-BROWSER-PANEL/PLAN-01-ui-toggle-persistence.md | Adds a detailed step-by-step implementation plan for Browser Panel UI/toggle/persistence. |
| crates/cast_agent/src/runtime.rs | Implements a singleton Tokio runtime + recurring health probe and sync is_available(). |
| crates/cast_agent/src/lib.rs | Exposes the new runtime module and re-exports runtime entry points. |
| crates/cast_agent/src/agent.rs | Adds health_probe() and applies async_trait to the backend impl. |
| crates/cast_agent/Cargo.toml | Adds async-trait dependency to support #[async_trait] usage. |
| crates/ai/src/lib.rs | Adds ai::cast_agent facade gated by the cast-agent feature. |
| CAST-AGENT.md | Updates documentation to reflect runtime boot + status pill wiring. |
| Cargo.lock | Records the new async-trait dependency for cast_agent. |
| app/src/lib.rs | Eagerly boots the Cast Agent runtime during application startup. |
| app/src/ai/coven_brand.rs | Adds brand colors for success/warning used by the status pill. |
| app/src/ai_assistant/panel.rs | Renders a gateway status pill that reads ai::cast_agent::is_available(). |
| app/Cargo.toml | Adds cast-agent feature wiring and bundles it into gui. |
Comments suppressed due to low confidence (1)
crates/cast_agent/src/runtime.rs:39
CastAgentRuntime::boot()’s doc comment says it “spawns a background thread”, but this function currently just builds a multi-thread runtime and continues on the caller thread. If the intent is to offload initialization work from the UI thread, the implementation needs an actual OS thread handoff; otherwise, update the comment to avoid incorrect guarantees.
impl CastAgentRuntime {
/// Build a runtime + agent. Spawns a background thread so the runtime
/// is multi-threaded without taking over the UI thread.
fn boot(config: Option<CastAgentConfig>) -> std::io::Result<Self> {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Member
Author
|
@copilot apply changes based on the comments in this thread |
Copilot stopped work on behalf of
BunsDev due to an error
May 16, 2026 10:11
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First integration slice for the Cast Agent backend that landed in #25 as a skeleton. Picks the smallest end-to-end consumer — a gateway status pill in the agent panel header — to validate the runtime and global-handle plumbing without taking on message-flow, session, or streaming work yet.
crates/cast_agent/src/runtime.rs).CastAgentRuntime::boot()builds a 2-worker multi-thread runtime, blocks-onCastAgent::new(), then spawns a 30s recurringGET /healthprobe sois_available()reflects current state.OnceLock<CastAgentRuntime>so callers share one instance;runtime::is_available()is a sync atomic read safe to call on every render frame.crates/aifacade — newai::cast_agent::*module gated by the existingcast-agentfeature, re-exporting the runtime entry points soapp/srcdepends onai, not directly oncast_agent.run()inapp/src/lib.rsinitializes the runtime right afterinit_feature_flags()so the first render doesn't pay theOnceLockboot cost.render_gateway_status_pill()inapp/src/ai_assistant/panel.rsdraws an 8px brand-colored dot in the agent panel header. Green (#22C55E) when the gateway responds toGET /health, amber (#F59E0B) when it doesn't.Feature wiring
cast-agent = ["ai/cast-agent"]feature onwarp-appsoapp/srccan use#[cfg(feature = "cast-agent")]directly. Bundled intogui(gui = ["voice_input", "cast-agent"]) so the OSS graphical build ships with the pill enabled — headless builds skip the tokio runtime + reqwest cost.crates/cast_agentnow pulls in the workspaceasync-traitdep becauseAgentBackendwas promoted to a#[async_trait]trait in a follow-up commit to PR feat: apply OpenCoven brand + scaffold Cast Agent crate #25.Verification
cargo check -p cast_agentcargo check -p aicargo check -p ai --features cast-agentcargo check -p warp-app --bin cast-codes --features guicargo check -p warp-app --bin cast-codes --features gui,cast-agent./script/check_rebrandDesign choices
handle.spawn(...)on the same runtime.is_available()reads anAtomicBool::Acquire; the background probe writes it. Render-loop friendly.OnceLock+ eager startup hint: the runtime initializes on first access regardless, butrun()warms it eagerly so the cost lands at boot, not in a render frame.appdepends onai::cast_agentrather than thecast_agentcrate so the feature gate remains a single source of truth and future facade work (telemetry wrappers, etc.) has a place to live.Out of scope (next follow-ups)
Documented in
CAST-AGENT.md:tokio-tungstenite.#[cfg(feature = "warp-agent")]gating ofwarp_*deps insidecrates/ai.Test plan
http://localhost:3000answering200 OKonGET /health; within 30 seconds, the pill should flip to green.--no-default-features --features minimaland confirm the cast_agent runtime is not pulled in.