Describe any incident β a haunting on the venue floor or a real outage at 3 AM. A CrewAI swarm with partial knowledge deliberates, the live web verifies it, and Parasail streams a bespoke, operable command station into existence, component by component. One button and the room's Discord lights up.
CrewAI Β· Parasail Β· You.com Β· One Β· Python 3.10β3.13 Β· React 19 Β· MIT Β· Hack with YOU, Halloween 2026Watch a recorded run Β· Quickstart Β· How it works Β· Architecture Β· Every partner is load-bearing Β· Deck Β· Video script
When something goes wrong β a breach on the venue floor, a cloud region falling over, smoke drifting over the Bay β the people in charge get a static dashboard that was designed months ago for a different crisis, plus a wall of unverified chatter. Every incident is different. Every dashboard is the same.
Don't build a dashboard. Compile one.
WRAITH treats the interface as the output of an agent swarm, not a template it fills in:
- A CrewAI Flow routes the incident (
hauntingΒ·real_worldΒ·control) and plans what to check. - Three specialist agents, each seeing only its own slice of the world, gather intel in parallel β instruments, a vector-indexed grimoire of countermeasures and playbooks, and the live web via You.com.
- A Commander who sees only their briefs resolves their disagreements and decides:
contain,evacuateorobserve. - Parasail streams a JSON-schema-locked UI manifest, token by token, over a WebSocket. The browser parses partial JSON and materialises each component the instant its props arrive β while the model is still thinking.
- The station is operable: isolate sectors on the floor plan, arm countermeasures, move civilians, tick the protocol. The dispatch payload rebuilds live from what you did, and One posts it to the venue's Discord
#loft-incidentand hands back a receipt.
The same engine plays the venue's Track 1 scenario feed on autopilot β and refuses to escalate the harmless control tick.
1 Β· The swarm deliberates in the open. The router's headline, the CrewAI branch it took, and three agents β each seeing only part of the picture β typing their briefs and votes.
2 Β· The commander decides β and you see what the live web changed. Wildfire smoke over the Bay: without You.com the commander would have moved 300 people; with today's air quality it says observe. How the fork is computed: the same Commander gets the same three briefs again, in parallel, with the Verifier's evidence replaced by "the live web did not answer" (counterfactual() in wraith/swarm.py).
3 Β· Then the station writes itself. Every section was chosen, ordered and filled by Parasail for this incident. The verdict docks on top; Dispatch is one click away.
4 Β· A different incident, a different station. "Is it us or AWS?" β a PagerDuty alert with real telemetry gets an SRE console, not a ghost radar.
| Moment | What happens | Partner on stage |
|---|---|---|
| Read | the incident appears; the router names it and takes a branch β haunting, real world or control |
CrewAI Flow @router on Parasail |
| Gather | each agent's tools run in parallel; the Verifier's You.com queries print as they go | You.com, Parasail BGE-M3, the venue oracle |
| Deliberate | three columns type their briefs as sentences; votes appear β contain, evacuate, observe | CrewAI agents on Parasail |
| Decide | the verdict lands in 76 px serif; carried votes are highlighted, overruled ones struck through; the counterfactual shows what the live web changed | Parasail (thinking on), You.com |
| Compose | the station writes itself section by section while the camera follows the pen, then pulls back | Parasail streaming json_schema |
| Act | isolate sectors, arm countermeasures, move people; the alert rewrites itself; Dispatch walks One's three tools step by step | One |
| Escalate | Next tick β feeds tick 143 (EMF 98 β 131 mG) and the station rebuilds | the scenario feed |
git clone https://github.com/vnmoorthy/wraith && cd wraith
cp .env.example .env # add your keys (below)
./run.sh # installs, builds the UI, checks every partner, serves http://localhost:8666./run.sh is the only command you need. It picks a Python between 3.10 and 3.13 (CrewAI does not support 3.14), creates .venv, installs pinned dependencies, installs the One CLI if it is missing, builds the React UI into wraith/static, runs a live health check against every partner and serves the app.
| Key | What it powers | Get it |
|---|---|---|
PARASAIL_API_KEY |
router, 4 agents, the streaming interface compiler, BGE-M3 embeddings | saas.parasail.io/keys |
YDC_API_KEY |
live web search (highlights) + page contents for the Verifier | you.com |
ONE_SECRET |
the Dispatch action (connect Discord with write access in One) | app.withone.ai |
TEAM_HANDLE |
Track 1 autopilot submissions to the venue feed | your welcome card |
make check # live health check: β parasail β youcom β one β scenario β crewai
make dev # backend + Vite hot reload on :5173No keys? Open Replays β recorded runs re-stream their exact event log (agent tokens, partner calls, manifest deltas) with original timing. They are always labelled REPLAY, and they work fully offline.
sequenceDiagram
autonumber
participant UI as Browser (React)
participant WS as FastAPI WebSocket
participant F as CrewAI Flow
participant P as Parasail
participant Y as You.com
participant S as Scenario MCP
participant O as One β Discord
UI->>WS: summon {incident, ablations}
WS->>F: kickoff_async()
F->>P: @start intake (json_schema Route)
F-->>UI: route + @router branch
par each agent's tools, in parallel
F->>Y: /v1/search (highlights) Γ2 β /v1/contents
F->>P: /v1/embeddings (BGE-M3) β grimoire top-k
F->>S: hack26-ask-oracle (doctrine)
end
par partial-knowledge crew
F->>P: Sentinel.kickoff_async(SentinelBrief)
F->>P: Archivist.kickoff_async(ArchivistBrief)
F->>P: Verifier.kickoff_async(VerifierBrief)
end
F-->>UI: agent tokens (CrewAI LLMStreamChunkEvent)
F->>P: Commander.kickoff_async(CommanderDecision)
F->>P: compile: stream=true, json_schema manifest
P-->>UI: manifest deltas β components materialise
UI->>WS: POST /api/dispatch (payload from operator state)
WS->>O: list_one_integrations β find_one_actions β execute_one_action
O-->>UI: receipt (message id, latency)
WraithFlow.intake makes one schema-locked Parasail call (gpt-oss-120b-fast) (response_format: json_schema) that classifies the incident, extracts checkable claims, writes the web-search plan and the grimoire query. @router then branches deterministically:
| Branch | Agents | Behaviour |
|---|---|---|
haunting |
Sentinel Β· Archivist (+ oracle) Β· Verifier Β· Commander | Verifier tries to rule out mundane causes (real weather, real outages near 525 Market St) |
real_world |
Sentinel Β· Archivist (real playbooks) Β· Verifier Β· Commander | Verifier confirms the incident from news and status pages |
control |
Sentinel Β· Archivist Β· Commander | Fast path. escalate is forced false β a harmless control tick is never a false alarm |
| Agent | Tool | Partner |
|---|---|---|
| Sentinel | z-scores of EMF / temperature / motion against the venue baseline. EMF + cold together is a signature; motion alone is people. | β (pure math) |
| Archivist | cosine search over a 31-entry grimoire (countermeasures, entity profiles, doctrine, real-world playbooks), embedded once with parasail-bge-m3 and cached; plus hack26-ask-oracle doctrine |
Parasail embeddings Β· Scenario MCP |
| Verifier | POST /v1/search with extraction: {extraction_mode: "highlights"} for each planned query (passages arrive in contents.highlights), then POST /v1/contents on the top URLs for full markdown |
You.com |
Each agent is a real crewai.Agent invoked with kickoff_async(..., response_format=<Pydantic brief>) on a Parasail model. Its prompt contains only its slice: the Sentinel never sees a sighting, the Verifier never sees the lore, the Archivist never sees raw sensor numbers. Their tokens stream live into the swarm panel via CrewAI's LLMStreamChunkEvent, with the agent's knows / blind-to chips visible.
deepseek-v41-flash fuses three briefs under doctrine β evacuate when civilians are in the contact zone or the threat is mobile; contain when localised; observe when non-hostile, unknown, or a control event β and must explain its dissent resolution.
The final Flow step streams a manifest from Parasail with stream: true and a server-enforced json_schema that is an anyOf over 14 component variants, each with its own typed props. The model chooses, orders and fills the components for this incident and tags each with the source agent whose intel built it. If a server rejects the schema, WRAITH falls back to streamed json_object mode and validates per component β one malformed fragment never blanks the screen.
The browser re-parses the growing JSON with partial-json on every structural delta. A component renders the instant its component name and a props object exist, with a materialise animation and a scan-line "compilingβ¦" state for the one still streaming. X-ray shows the raw manifest growing token by token next to the live partner-call trace; Provenance colours every panel by the agent that produced it.
The Dispatch Console builds its payload from runtime state β the commander's call, the sector, the countermeasures you armed, the sectors you isolated, civilians you moved, checklist progress and two You.com citation URLs:
team-04 Β· [catering_coffee_bar] Β· EVACUATE Β· 4 civilians pinned in the contact zone; EMF rising 98β131 mG
deploying salt_line_deployer, uv_lanterns Β· civilians: 4 pinned; catering coffee bar β evacuating Β· isolated: main_stage Β· confidence 91% Β· threat 5/5
evidence: <https://β¦> <https://β¦>
β WRAITH FLASH Β· run 191502-a1b2c3 Β· CrewAI swarm on Parasail, grounded by You.com, sent by One
It then runs One's three-tool loop through the One CLI β list_one_integrations (find the Discord connection) β find_one_actions("send a message to a channel") (resolve the action id at run time, never hardcoded) β execute_one_action with channelId in path variables β and shows the message id and latency back on the station. Arm/confirm is a two-step control, and a dry-run toggle lets One build the request without sending.
wraith/
βββ server.py FastAPI: one WebSocket (summon / autopilot), REST for dispatch, health, runs, scoreboard
βββ swarm.py WraithFlow (CrewAI Flow), the partial-knowledge agents, the streaming interface compiler, run recorder
βββ schemas.py Route, the agent briefs, CommanderDecision, and the 14-variant manifest JSON schema
βββ grimoire.py 31 countermeasures / entities / doctrine / playbooks, BGE-M3-embedded once and cached
βββ sensors.py Sentinel's instrument scoring (z-scores vs venue baseline)
βββ youcom.py You.com Search (highlights) + Contents, Retry-After aware
βββ parasail.py OpenAI-compatible client: chat, json_schema, streaming, embeddings, 429 backoff
βββ one.py One CLI driver: init β list β find β execute, receipts, secret redaction
βββ scenario.py The venue scenario feed as a real MCP client (streamable HTTP), fixtures + submission queue fallback
βββ fixtures/ the official tick and incident fixtures (same contract as the live feed)
web/src/
βββ lib/run.ts event-sourced run state: one reducer turns the WebSocket stream into UI state
βββ components/station/ the 14 renderable components + the streaming Station renderer
βββ components/ Header (partner health + ablation), Intake, Swarm lanes, X-ray, Timeline
βββ views/ Autopilot (Track 1) and Replays
Every run is a stream of typed events, recorded to .wraith/runs/<id>.json for replay:
| Event | Payload |
|---|---|
run.start |
incident, ablations, model routing |
route |
the router's Route and the branch taken |
agent.tools Β· agent.start Β· agent.token Β· agent.done |
per-agent lifecycle, knows/blind slices, streamed tokens, the typed brief |
intel |
tool results per agent (evidence, grimoire hits, sensor scores) |
trace |
every partner call: partner, op, latency, ok |
decision |
the Commander's CommanderDecision |
manifest.start Β· manifest.delta Β· manifest.done |
the compiler's token stream and the validated manifest (+ time to first token) |
run.done |
partner call counts, total time |
autopilot.* |
Track 1: tick, judgment (score, false alarm), dispatch receipt, done |
Click a partner in the header to ablate it for the next run. Each one visibly breaks the product β which is the point.
| Partner | What it does in WRAITH | Switch it off and⦠|
|---|---|---|
| Parasail | router Β· 4 agents Β· streaming schema-locked compiler Β· BGE-M3 embeddings Β· model routing (gpt-oss-120b-fast / DeepSeek V4.1 flash / BGE-M3) | there is no brain and no interface: the station never assembles |
| CrewAI | Flow with @start / @router / @listen, partial-knowledge Agents, live token events |
one generic layout from raw text β no routing, no verification, no decision |
| You.com | search with highlights + page contents; every claim gets a clickable source | the evidence rail goes empty and severity becomes "unverified" |
| One | list_one_integrations β find_one_actions β execute_one_action on Discord |
the station sees the threat and cannot act on it |
| Scenario MCP | ticks, the oracle's doctrine, containment judgments, the scoreboard | autopilot queues submissions and replays them when the feed returns |
The Autopilot tab runs the same swarm against the venue scenario feed over MCP (hack26-get-tick β swarm β hack26-submit-containment β hack26-get-scoreboard):
- Practice mode uses the official fixtures and a local referee that follows the published doctrine β nothing is submitted.
- Live mode pulls real ticks for your
TEAM_HANDLE, submits each decision once (the feed accepts one answer per tick), shows the judgment and false-alarm flag, optionally auto-dispatches real threats to#loft-incident, and highlights your row on the live scoreboard. - If the feed is unreachable, decisions are queued and replayed later β the tick matters, not the wall clock.
| Tick | What the swarm sees | Decision |
|---|---|---|
| 142 | catering breached Β· 4 pinned Β· EMF 98 mG Β· β4 Β°C Β· level-5 phantom 82 % | EVACUATE β civilians in the contact zone |
| 143 | EMF climbing to 131 mG Β· β7 Β°C Β· entrance shows a residual echo | EVACUATE β threat escalating, the echo is non-hostile |
| 900 | main stage Β· 41 motion events Β· EMF 3 mG Β· 21 Β°C Β· "human-crowd" 97 % | OBSERVE β people, not ghosts. No escalation, no false alarm |
The haunting is the demo; incidents are the market. Type anything:
- "Our checkout API is failing with 5xx errors from AWS us-east-1 β is AWS having an incident?" β an abyssal-blue SRE war room with status-page evidence, a failover runbook and a drafted customer update.
- "Power just failed across the 2nd floor during demos, two people stuck in the stairwell." β the venue floor plan, civilian tracker and a single dispatch channel.
- "Heavy wildfire smoke over the Bay β should we move 300 people indoors?" β live air-quality evidence, a shelter-in-place playbook and a comms draft.
Same engine, different incident, different interface.
Verbatim from the recorded live runs shipped in wraith/recordings/ (open them in Replays):
| Incident | Branch Β· theme | Commander | Without the live web | Why β in its own words |
|---|---|---|---|---|
Venue fixture spooky-2026-9912 |
haunting Β· spectral goth dark | EVACUATE 86% | evacuate 90% | "Operator reports 4 engineers pinned by hostile mobile Level-5 Phantom; life safety overrides web silence." |
| Tick 142 | haunting Β· spectral goth dark | EVACUATE 82% | evacuate 90% | "Operator reports 4 civilians pinned; first-hand life-safety report is authoritative regardless of web verification." |
| Tick 900 (control) | control Β· ectoplasm green | OBSERVE 95% | β | "Motion +2.07z with normal EMF (3 mG) and temp 21C: crowd, not entity. No civilians at risk." |
| "Power fails at the Loft during demos" | real world Β· daylight ops | EVACUATE 82% | evacuate 82% | "Operator reports ~120 civilians trapped in a dark, unlit SE stairwell; life safety overrides zero-signature instrument feeds." |
| "Is it us or AWS?" (PagerDuty P1 with telemetry) | real world Β· abyssal blue | CONTAIN 72% | contain 72% | "Verifier confirms real AWS US-EAST-1 thermal outage; 78x 5xx and payment failures are live, not a control tick." |
| "Wildfire smoke over the Bay" | real world Β· daylight ops | OBSERVE 72% | evacuate 60% β changed by You.com | "Live AQI 20-56 Good/Moderate contradicts heavy smoke; non-hostile drifting hazard, no sensor feed, no injuries reported." |
The Verifier's job on a haunting is to rule out mundane causes: "Outdoor weather is mild (50β67 Β°F), so weather cannot explain indoor β4 Β°C." On a real incident, it refuses to panic on stale news.
| Stage | Model | Typical latency |
|---|---|---|
Intake router (json_schema) |
parasail-gpt-oss-120b-fast Β· reasoning low |
1.0β1.9 s |
| Grimoire retrieval | parasail-bge-m3 (1024-d) |
0.15β0.3 s |
| You.com search Γ2 (highlights) + contents | β | 0.3β1.0 s + 0.2β2.8 s |
| Sentinel / Archivist / Verifier, in parallel | parasail-deepseek-v41-flash Β· thinking off |
0.5β1.5 s each |
| Commander | parasail-deepseek-v41-flash Β· thinking on |
0.9β3.3 s |
| Interface compiler (streamed) | parasail-deepseek-v41-flash Β· thinking off |
first token 0.4β5 s, 7β13 s total |
| End to end | 12β22 s |
We benchmarked before choosing: qwen3-235b produced broken JSON after 112 s, glm-53-flash spent its budget thinking and returned nothing, kimi-k3-fast reasoned past 3 000 tokens, and gpt-oss under guided decoding sometimes pads a missing field with whitespace forever β so it only does the small-schema router.
Before writing code, we generated 10 ideas and ran a workflow of 100 independent persona judges β sponsor engineers from You.com, Parasail, CrewAI and One, UpScaleX partners, AWS architects, veteran hackathon judges, UX leads, pre-mortem skeptics and a clone of the organizers' automated reviewer, each with a different temperament β scoring every idea on the official rubric plus feasibility and wow. Five investigators then stress-tested the leaders (rubric math, competitive landscape, pre-mortem, sponsor removal test, demo theatre).
| Rank | Idea | Borda | 1st-place votes | Rubric /100 | Wow /10 |
|---|---|---|---|---|---|
| 1 | WRAITH β the war room that builds itself | 1000 | 100 / 100 | 82.3 | 9.63 |
| 2 | Hallucination Exorcist | 852 | 0 | 67.9 | 6.72 |
| 3 | Graveyard Shift (3 AM SRE swarm) | 703 | 0 | 66.9 | 5.53 |
| 4 | SΓ©ance (generative UI for the live web) | 660 | 0 | 66.8 | 6.96 |
| 5 | Poltergeist (red-team arena for swarms) | 630 | 0 | 66.7 | 6.36 |
| 6 | Exorcism Protocol 3D digital twin | 566 | 0 | 64.1 | 8.38 |
| 7 | Necropolis (zombie-code exorcist) | 449 | 0 | 60.1 | 6.18 |
| 8 | Banshee (disaster early warning) | 289 | 0 | 62.6 | 5.51 |
| 9 | Haunted Mansion (Discord game) | 195 | 0 | 51.1 | 6.21 |
| 10 | Frankenstein (agent that builds agents) | 156 | 0 | 64.9 | 7.57 |
Every must-have the investigators named is in the build: component-by-component streaming with per-component validation, the manifest X-ray, provenance, citations that change the interface, a dispatch built from runtime state with a receipt, a reality mode a judge can type into, a Track 1 autopilot, live partner ablation, a rate-aware client, and an honest REPLAY mode.
| Variable | Default | |
|---|---|---|
WRAITH_MODEL_ROUTER |
parasail-gpt-oss-120b-fast |
the Flow's intake router |
WRAITH_MODEL_SWARM |
parasail-deepseek-v41-flash |
Sentinel and Archivist |
WRAITH_MODEL_VERIFIER |
parasail-deepseek-v41-flash |
Verifier |
WRAITH_MODEL_COMMANDER |
parasail-deepseek-v41-flash |
the Commander (try parasail-kimi-k3-fast) |
WRAITH_MODEL_COMPILER |
parasail-deepseek-v41-flash |
the streaming interface compiler |
WRAITH_MODEL_EMBED |
parasail-bge-m3 |
grimoire embeddings |
WRAITH_DISPATCH_LIVE |
1 |
0 makes every dispatch a One dry run |
DISCORD_CHANNEL_ID |
1564842098740695100 |
#loft-incident |
SCENARIO_MCP |
https://api.you.com/mcp/halloween-hack-26 |
the venue feed |
WRAITH_PORT |
8666 |
tests/fake_parasail.py is an OpenAI-compatible test double (schema-valid placeholder output, deterministic embeddings) used to integration-test the Flow, the streaming compiler, the WebSocket and the renderer without keys. It is never used by the app itself.
.venv/bin/python tests/fake_parasail.py & # :8777
PARASAIL_BASE_URL=http://127.0.0.1:8777/v1 PARASAIL_API_KEY=test WRAITH_PORT=8667 .venv/bin/python -m wraith &
WRAITH_PORT=8667 .venv/bin/python tests/ws_smoke.py fixture # also: tick, control, reality, autopilotIs the interface really generated, or is it a template? The model picks which of 14 components to show, in what order, with what props β a control tick gets a calm, minimal station; an AWS outage gets no EMF radar and a generic zone map; a phantom gets the floor plan. Turn on X-ray and watch the JSON arrive.
What if the model emits something broken? The schema is enforced server-side; on top of that every component is validated on its own, and the renderer only mounts a component once its props object exists.
Is anything faked? No. Live runs call the partners live; replays are recordings of live runs and are labelled REPLAY. The local test double exists only under tests/.
Why Python + React? CrewAI lives in Python; the generative UI needs a real component runtime. One process serves both.
- One Connect so each operator brings their own Slack / PagerDuty / Linear grant
- Multi-incident board with live re-compilation as new ticks arrive
- Voice intake; a judge can speak the incident
- Bedrock AgentCore deployment template
Built in one day at Hack with YOU: Halloween Edition (AWS Builder Loft, San Francisco, Oct 28 2026) with You.com, Parasail, CrewAI and One. MIT licensed.



