Crew Agent Shows Stale "7 IN FLIGHT" Count #75

Closed
opened 2026-06-02 09:03:31 +00:00 by rawan · 3 comments
Member

The backend crew agent shows WORKING · 7 IN FLIGHT even though the Dashboard shows 0 active jobs. The in-flight counter is stale/not syncing correctly with actual job state.

image

The backend crew agent shows WORKING · 7 IN FLIGHT even though the Dashboard shows 0 active jobs. The in-flight counter is stale/not syncing correctly with actual job state. ![image](/attachments/83e7bc60-9bca-4fef-abf4-c64b5d61a431)
Author
Member

Implementation Spec for Issue #75: Crew Agent Shows Stale "7 IN FLIGHT" Count

Objective

Fix the crew agent status label so the "WORKING · N IN FLIGHT" count reflects the actual number of in-flight asks. The count must drop to 0 (and the agent must read "idle") once its asks have been delivered or failed, matching the Dashboard's 0-active-jobs view.

Root Cause Analysis

The crew agent status label is computed by statusOf() in crates/hero_shrimp_web/ui/src/components/CrewPage.tsx (lines 143-157). It classifies an ask message as "in flight" unless its status is one of:

!["replied", "done", "completed"].includes((m.status || "").toLowerCase())   // line 147

The backend never produces any of those three statuses. The agent-message (mailbox) status lifecycle, set in crates/hero_shrimp_server/src/rpc/methods/crew/mod.rs (crew_tick), is exactly:

pending  ->  dispatched  ->  delivered    (success)
                         ->  failed        (error / timeout)

So every ask ever sent to an agent has status delivered (or failed) once finished — neither of which is in ["replied", "done", "completed"]. Result: statusOf counts every historically-delivered ask as "in flight" forever. After 7 asks to one agent, the card permanently reads "WORKING · 7 IN FLIGHT", even though all jobs are long done and the Dashboard correctly shows 0 active jobs.

This is a vocabulary desync between two sources of truth:

  1. Correct source — the agents.status column (working/idle), maintained by crew_tick. The Dashboard/TopBar crew badge uses this correctly (store.ts, a.status === "working").
  2. Buggy derivation — statusOf re-derives "working/in flight" from the agent_messages history using a status set that can never match a terminal message.

Corroborating evidence that the correct vocabulary is ["delivered", "failed"]: the two other in-flight checks in the SAME file already use it correctly:

  • anyAskInFlight() — CrewPage.tsx lines 99-107 (s === "delivered" || s === "failed" => not in flight)
  • inFlight() in FocusedAgent — CrewPage.tsx lines 609-617 (same)

Only statusOf (line 147) uses the wrong set.

Requirements

  • The in-flight count for an agent must only include asks that are genuinely unfinished (status pending or dispatched).
  • Asks with terminal status (delivered or failed) must NOT be counted.
  • An agent with no unfinished asks must render "idle ...", not "working".
  • The fix must be consistent with the existing delivered/failed vocabulary already used by anyAskInFlight and inFlight in the same file.
  • No backend change is required; the backend status values are already correct.
  • (Optional hardening) Guard against future status-vocabulary drift by deriving "terminal" from a single shared predicate rather than an inline array.

Files to Modify

  • crates/hero_shrimp_web/ui/src/components/CrewPage.tsx — primary and only required change. Fix the terminal-status set in statusOf so delivered/failed asks are excluded from the in-flight filter.

Implementation Plan

Step 1: Fix the in-flight filter vocabulary in statusOf

Files: crates/hero_shrimp_web/ui/src/components/CrewPage.tsx

  • In statusOf (lines 143-157), change the terminal-status exclusion list in the inflight filter (lines 145-147) from the non-existent ["replied", "done", "completed"] to the actual backend terminal statuses ["delivered", "failed"].
  • An ask counts as in-flight iff its lowercased status is NOT delivered and NOT failed (i.e. it is pending, dispatched, or empty/unknown). This matches anyAskInFlight() (line 103) and inFlight() (line 613).
  • Why: the backend only ever emits pending|dispatched|delivered|failed for agent messages; excluding delivered/failed makes the count drop to 0 once all asks finish, fixing the stale "7 IN FLIGHT".
  • Dependencies: none.

Files: crates/hero_shrimp_web/ui/src/components/CrewPage.tsx

  • Introduce a single module-level helper, e.g. askInFlight(status?: string): boolean returning !["delivered","failed"].includes((status||"").toLowerCase()), and use it in all three places: statusOf (Step 1), anyAskInFlight (lines 99-107), and inFlight (lines 609-617).
  • Why: removes the duplicated inline arrays that caused the original desync. Directly addresses the class of bug.
  • Dependencies: do Step 1 first (or fold Step 1 into this refactor). Frontend cleanup only; no behavioral change beyond Step 1.

Step 3: Verify the build and the count

Files: none (verification only)

  • Build the web UI (hero_shrimp_web, UI under crates/hero_shrimp_web/ui). Confirm the AgentCard label transitions from "working · N in flight" to "idle · last replied" once all replies land, and the "working in parallel" band disappears.
  • Cross-check the Dashboard "Running now" KPI and TopBar crew badge remain consistent.
  • Dependencies: Steps 1 (and optionally 2).

Acceptance Criteria

  • After an agent's asks complete (status delivered), its CrewPage card shows "idle · last replied" with no "in flight" count.
  • An agent currently processing an ask (status pending or dispatched) shows "working · N in flight" with N = the count of non-terminal asks only.
  • A failed ask does not inflate the in-flight count.
  • The "working in parallel" constellation band only appears when at least one agent has a genuinely non-terminal ask.
  • The CrewPage "working" classification agrees with the TopBar crew badge and the Dashboard "Running now" KPI for the same state.
  • No backend changes; crew.messages status values unchanged.
  • Web UI builds cleanly.

Notes

  • The issue title's uppercase "WORKING · 7 IN FLIGHT" is the lowercase label string working · ${inflight.length} in flight rendered through an uppercase Tailwind class on the AgentCard status pill. No string/case change is needed — only the count logic.
  • Do not "fix" anyAskInFlight or inFlight to match statusOf — they are already correct; statusOf is the outlier.
  • The backend has a dispatch-age backstop (env SHRIMP_AGENT_DISPATCH_MAX_SECS, default 1200s) that transitions a truly-hung dispatched ask to failed. With the fix this also correctly clears such an ask from the in-flight count.
## Implementation Spec for Issue #75: Crew Agent Shows Stale "7 IN FLIGHT" Count ### Objective Fix the crew agent status label so the "WORKING · N IN FLIGHT" count reflects the actual number of in-flight asks. The count must drop to 0 (and the agent must read "idle") once its asks have been delivered or failed, matching the Dashboard's 0-active-jobs view. ### Root Cause Analysis The crew agent status label is computed by `statusOf()` in `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` (lines 143-157). It classifies an `ask` message as "in flight" unless its status is one of: ```ts !["replied", "done", "completed"].includes((m.status || "").toLowerCase()) // line 147 ``` The backend never produces any of those three statuses. The agent-message (mailbox) status lifecycle, set in `crates/hero_shrimp_server/src/rpc/methods/crew/mod.rs` (`crew_tick`), is exactly: ``` pending -> dispatched -> delivered (success) -> failed (error / timeout) ``` So every `ask` ever sent to an agent has status `delivered` (or `failed`) once finished — neither of which is in `["replied", "done", "completed"]`. Result: `statusOf` counts every historically-delivered ask as "in flight" forever. After 7 asks to one agent, the card permanently reads "WORKING · 7 IN FLIGHT", even though all jobs are long done and the Dashboard correctly shows 0 active jobs. This is a vocabulary desync between two sources of truth: 1. Correct source — the `agents.status` column (`working`/`idle`), maintained by `crew_tick`. The Dashboard/TopBar crew badge uses this correctly (`store.ts`, `a.status === "working"`). 2. Buggy derivation — `statusOf` re-derives "working/in flight" from the `agent_messages` history using a status set that can never match a terminal message. Corroborating evidence that the correct vocabulary is `["delivered", "failed"]`: the two other in-flight checks in the SAME file already use it correctly: - `anyAskInFlight()` — CrewPage.tsx lines 99-107 (`s === "delivered" || s === "failed"` => not in flight) - `inFlight()` in `FocusedAgent` — CrewPage.tsx lines 609-617 (same) Only `statusOf` (line 147) uses the wrong set. ### Requirements - The in-flight count for an agent must only include asks that are genuinely unfinished (status `pending` or `dispatched`). - Asks with terminal status (`delivered` or `failed`) must NOT be counted. - An agent with no unfinished asks must render "idle ...", not "working". - The fix must be consistent with the existing `delivered`/`failed` vocabulary already used by `anyAskInFlight` and `inFlight` in the same file. - No backend change is required; the backend status values are already correct. - (Optional hardening) Guard against future status-vocabulary drift by deriving "terminal" from a single shared predicate rather than an inline array. ### Files to Modify - `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` — primary and only required change. Fix the terminal-status set in `statusOf` so delivered/failed asks are excluded from the in-flight filter. ### Implementation Plan #### Step 1: Fix the in-flight filter vocabulary in `statusOf` Files: `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` - In `statusOf` (lines 143-157), change the terminal-status exclusion list in the `inflight` filter (lines 145-147) from the non-existent `["replied", "done", "completed"]` to the actual backend terminal statuses `["delivered", "failed"]`. - An ask counts as in-flight iff its lowercased status is NOT `delivered` and NOT `failed` (i.e. it is `pending`, `dispatched`, or empty/unknown). This matches `anyAskInFlight()` (line 103) and `inFlight()` (line 613). - Why: the backend only ever emits `pending|dispatched|delivered|failed` for agent messages; excluding `delivered`/`failed` makes the count drop to 0 once all asks finish, fixing the stale "7 IN FLIGHT". - Dependencies: none. #### Step 2 (recommended): De-duplicate the terminal-status predicate Files: `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` - Introduce a single module-level helper, e.g. `askInFlight(status?: string): boolean` returning `!["delivered","failed"].includes((status||"").toLowerCase())`, and use it in all three places: `statusOf` (Step 1), `anyAskInFlight` (lines 99-107), and `inFlight` (lines 609-617). - Why: removes the duplicated inline arrays that caused the original desync. Directly addresses the class of bug. - Dependencies: do Step 1 first (or fold Step 1 into this refactor). Frontend cleanup only; no behavioral change beyond Step 1. #### Step 3: Verify the build and the count Files: none (verification only) - Build the web UI (`hero_shrimp_web`, UI under `crates/hero_shrimp_web/ui`). Confirm the AgentCard label transitions from "working · N in flight" to "idle · last replied" once all replies land, and the "working in parallel" band disappears. - Cross-check the Dashboard "Running now" KPI and TopBar crew badge remain consistent. - Dependencies: Steps 1 (and optionally 2). ### Acceptance Criteria - [ ] After an agent's asks complete (status `delivered`), its CrewPage card shows "idle · last replied" with no "in flight" count. - [ ] An agent currently processing an ask (status `pending` or `dispatched`) shows "working · N in flight" with N = the count of non-terminal asks only. - [ ] A `failed` ask does not inflate the in-flight count. - [ ] The "working in parallel" constellation band only appears when at least one agent has a genuinely non-terminal ask. - [ ] The CrewPage "working" classification agrees with the TopBar crew badge and the Dashboard "Running now" KPI for the same state. - [ ] No backend changes; `crew.messages` status values unchanged. - [ ] Web UI builds cleanly. ### Notes - The issue title's uppercase "WORKING · 7 IN FLIGHT" is the lowercase label string `working · ${inflight.length} in flight` rendered through an `uppercase` Tailwind class on the AgentCard status pill. No string/case change is needed — only the count logic. - Do not "fix" `anyAskInFlight` or `inFlight` to match `statusOf` — they are already correct; `statusOf` is the outlier. - The backend has a dispatch-age backstop (env `SHRIMP_AGENT_DISPATCH_MAX_SECS`, default 1200s) that transitions a truly-hung `dispatched` ask to `failed`. With the fix this also correctly clears such an ask from the in-flight count.
Author
Member

Verification Results

The fix is frontend-only (SolidJS UI in crates/hero_shrimp_web/ui). There is no unit-test harness for this component; verification was done via the production build and the embedding crate compile.

  • UI production build (npm run build -> vite): PASS
    • 99 modules transformed, bundle regenerated cleanly, exit 0.
  • Web crate compile (cargo build -p hero_shrimp_web, which embeds the rebuilt static assets): PASS
    • Finished, exit 0.

Change summary

statusOf() now derives "in flight" from the actual backend terminal statuses (delivered/failed) instead of the non-existent set ["replied", "done", "completed"]. A shared module-level helper askInFlight(status) is now the single source of truth, used by all three derivations (statusOf, anyAskInFlight, inFlight) so they can no longer drift apart.

Expected behavior after fix

  • Completed asks (status delivered) no longer counted -> card reads "idle - last replied", count drops to 0.
  • Only pending/dispatched asks are counted as in flight.
  • failed asks do not inflate the count.
  • CrewPage "working" classification now agrees with the TopBar crew badge and Dashboard "Running now" KPI.
## Verification Results The fix is frontend-only (SolidJS UI in `crates/hero_shrimp_web/ui`). There is no unit-test harness for this component; verification was done via the production build and the embedding crate compile. - UI production build (`npm run build` -> vite): PASS - 99 modules transformed, bundle regenerated cleanly, exit 0. - Web crate compile (`cargo build -p hero_shrimp_web`, which embeds the rebuilt static assets): PASS - Finished, exit 0. ### Change summary `statusOf()` now derives "in flight" from the actual backend terminal statuses (`delivered`/`failed`) instead of the non-existent set `["replied", "done", "completed"]`. A shared module-level helper `askInFlight(status)` is now the single source of truth, used by all three derivations (`statusOf`, `anyAskInFlight`, `inFlight`) so they can no longer drift apart. ### Expected behavior after fix - Completed asks (status `delivered`) no longer counted -> card reads "idle - last replied", count drops to 0. - Only `pending`/`dispatched` asks are counted as in flight. - `failed` asks do not inflate the count. - CrewPage "working" classification now agrees with the TopBar crew badge and Dashboard "Running now" KPI.
Author
Member

Implementation Summary

Fixed the stale "WORKING - N IN FLIGHT" count on the crew agent cards.

Root cause

statusOf() in crates/hero_shrimp_web/ui/src/components/CrewPage.tsx filtered out finished asks using ["replied", "done", "completed"] — statuses the backend never emits. The backend mailbox lifecycle is pending -> dispatched -> delivered/failed, so every completed ask kept being counted as "in flight" forever. After 7 asks to an agent, the card permanently showed "7 IN FLIGHT" while the Dashboard correctly showed 0 active jobs.

Changes

Files modified:

  • crates/hero_shrimp_web/ui/src/components/CrewPage.tsx
    • Added a shared module-level helper askInFlight(status) — the single source of truth for whether an ask is unfinished (lowercased status not delivered and not failed).
    • statusOf() now uses askInFlight() instead of the bogus ["replied","done","completed"] set, so the in-flight count only includes pending/dispatched asks.
    • Refactored anyAskInFlight() and inFlight() (FocusedAgent) to use the same helper, removing the duplicated inline checks that allowed the original drift.
  • crates/hero_shrimp_web/static/index.html and crates/hero_shrimp_web/static/assets/* — regenerated production bundle.

No backend changes — the backend status values were already correct.

Verification

  • UI production build (vite): PASS
  • Web crate compile (cargo build -p hero_shrimp_web, embeds the rebuilt assets): PASS

Notes

  • The count now drops to 0 and the card reads "idle - last replied" once all asks are delivered.
  • failed asks no longer inflate the count.
  • CrewPage "working" classification now agrees with the TopBar crew badge and Dashboard "Running now" KPI.
## Implementation Summary Fixed the stale "WORKING - N IN FLIGHT" count on the crew agent cards. ### Root cause `statusOf()` in `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` filtered out finished asks using `["replied", "done", "completed"]` — statuses the backend never emits. The backend mailbox lifecycle is `pending -> dispatched -> delivered/failed`, so every completed ask kept being counted as "in flight" forever. After 7 asks to an agent, the card permanently showed "7 IN FLIGHT" while the Dashboard correctly showed 0 active jobs. ### Changes Files modified: - `crates/hero_shrimp_web/ui/src/components/CrewPage.tsx` - Added a shared module-level helper `askInFlight(status)` — the single source of truth for whether an ask is unfinished (lowercased status not `delivered` and not `failed`). - `statusOf()` now uses `askInFlight()` instead of the bogus `["replied","done","completed"]` set, so the in-flight count only includes `pending`/`dispatched` asks. - Refactored `anyAskInFlight()` and `inFlight()` (FocusedAgent) to use the same helper, removing the duplicated inline checks that allowed the original drift. - `crates/hero_shrimp_web/static/index.html` and `crates/hero_shrimp_web/static/assets/*` — regenerated production bundle. No backend changes — the backend status values were already correct. ### Verification - UI production build (vite): PASS - Web crate compile (cargo build -p hero_shrimp_web, embeds the rebuilt assets): PASS ### Notes - The count now drops to 0 and the card reads "idle - last replied" once all asks are delivered. - `failed` asks no longer inflate the count. - CrewPage "working" classification now agrees with the TopBar crew badge and Dashboard "Running now" KPI.
rawan closed this issue 2026-06-03 10:48:42 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_shrimp#75
No description provided.