First off the fetch links!
https://asi1.ai/shared-chat/d8faf9a7-ac95-4683-bab1-d37974dd833f
policy-orchestrator: chat entry point that coordinates the whole 6-phase pipeline — https://agentverse.ai/agents/details/agent1qw7y8hck75jalsz2289e60cglpffqs0qy8egqqzxp5s9785taa625w87rdl/profile
use case: to simulate policies [it's a multi-agent orchestrator]
graphrag-agent: extracts entities, relationships, and affected populations from a policy text —
https://agentverse.ai/agents/details/agent1qfn6t48ay75634vaxnzed2c8y3nrpu2ln6lufvdcvqs988cdfww0c8en84v/profile
env-config-agent: looks at the policy and decides which demographic clusters to simulate plus how big to run it — https://agentverse.ai/agents/details/agent1qw6fxrk67cyzwznmd2849u0n92sggw3wtxkzdty5dh6054u7vu7e6eyxaf6/profile
cluster-low_income_renters: simulates how low-income renters react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1q06eycwdnwm9zpyvsuuaxuyppd853xcqhj35y87uvjkw40mre6ksuycv7gj/profile
cluster-homeowners_middle_class: simulates how middle-class homeowners react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1q2dz2knayg24z60vwmcv842cugpssl5ns9f6dz5mjuvppmcm6rwh50axnnf/profile
cluster-small_business_owners: simulates how small business owners react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1qgxm87mldywdvgqa860gxgnqu744phmurz9kpm8yqxv76ydhxx3c5xn4el5/profile
cluster-young_professionals: simulates how young professionals react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1q0gm9w4xwekhuf4wl07suckuv7xhxfjf04cndvkdzptswe25mt2wwvjpxwn/profile
cluster-seniors_retirees: simulates how seniors and retirees react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1qdrmf9tn5lmjkj7rhrcxdgfr2u8tk24kysz4427um6kh8jgxkhjtzynykyl/profile
cluster-families_with_kids: simulates how families with school-age kids react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1q2hxfts0ns24jelnt7nqyuczq6fkj8a9qyrudsataagyc909yakscx9t0tq/profile
cluster-low_income_workers: simulates how low-wage and gig workers react and stays as a chat persona afterward —
https://agentverse.ai/agents/details/agent1qga95hnye8my4ufw8h5r6symj0se8w34jvrswty73e44sa0lzpc05245d6g/profile
report-agent: synthesizes the cluster reports into a markdown decision brief — https://agentverse.ai/agents/details/agent1qgj2pqnwvss47meqclxthzfyz3mv99q2efj9mn5r3rnu6y0t85vnk23838y/profile
social-media-agent: takes $1 via Stripe, then posts your position to Twitter / Reddit / Facebook via Composio —
https://agentverse.ai/agents/details/agent1qtqh3f9f9gmpm8737grm8rq4x30jxwn2y2jyaelw98zvm49ffj2pcka3asd/profile
comparison-agent: classifies real replies on your post and compares them to the simulated predictions —
https://agentverse.ai/agents/details/agent1q0qa0av37ryutmnht38f5xuye990k9lr2x63hj5jj9c34zcmuxf9xjffqh3/profile
the architecture of these agents:
⏺ ┌──────────────────────────────────┐
│ USER (chat or web upload) │
└────────────────┬─────────────────┘
│ chat (mailbox) / POST /api/run (HTTP)
▼
┌──────────────────────────────────┐
│ policy-orchestrator │ ← chat entry on ASI:1
│ (one ~50-line linear handler) │ ← web API on :8000
└────────────────┬─────────────────┘
│ HTTP A2A (httpx → /process)
┌──────────┬───────────┼───────────────┬──────────────┐
▼ ▼ ▼ ▼ ▼
┌───────────┐ ┌──────────┐ ┌──────────────────────────┐ ┌──────────┐ ┌──────────┐
│ Phase 1 │ │ Phase 2 │ │ Phase 3 (parallel) │ │ Phase 4 │ │ Phase 5 │
│ graphrag │ │ env- │ │ asyncio.gather → 7 of: │ │ report │ │ map │
│ │ │ config │ │ ┌────────────────────┐ │ │ │ │ agent │
│ entities, │ │ │ │ │ cluster-low_income │ │ │ markdown │ │ │
│ relations,│ │ pick │ │ │ cluster-homeowners │ │ │ decision │ │ 3D Mapbox│
│ affected │ │ clusters │ │ │ cluster-smallbiz │ │ │ brief │ │ globe │
│ pops │ │ + N pers │ │ │ cluster-young_pro │ │ │ │ │ FastAPI │
│ │ │ + rounds │ │ │ cluster-seniors │ │ │ │ │ /map/│
│ │ │ │ │ │ cluster-families │ │ │ │ │ │
│ │ │ │ │ │ cluster-low_wage │ │ │ │ │ │
│ │ │ │ │ └────────────────────┘ │ │ │ │ │
│ │ │ │ │ each: generate personas, │ │ │ │ │
│ │ │ │ │ run K rounds, aggregate, │ │ │ │ │
│ │ │ │ │ return ClusterReport │ │ │ │ │
└───────────┘ └──────────┘ └──────────────────────────┘ └──────────┘ └──────────┘
│
▼
Phase 6 (orchestrator → sidecar):
generate Twitter / Reddit / Facebook
drafts via ASI:1 → POST /draft on
social-media-agent's :PORT+1 sidecar
│
───── all phases share one envelope ───┴──── (`SharedAgentState` Pydantic model)
───── inter-agent transport: HTTP A2A on localhost via httpx ─────
───── ASI:1 user-facing chat: mailbox (orchestrator + cluster + social + comparison) ─────
┌──────────────────────────────────┐
│ FINAL REPLY TO USER │
│ • markdown decision brief │
│ • 3D map URL │
│ • 7 cluster chat handles │
│ • 3 social drafts pre-loaded │
└────────────────┬─────────────────┘
│
┌────────────────────────┼─────────────────────────┐
▼ ▼ ▼
USER chats a cluster USER chats @social- USER triggers reality-check
directly: media-agent: after replies arrive:
"@cluster-small_ "post on twitter" ┌────────────────┐
business_owners, ┌────────────────┐ │ comparison- │
what would flip you?" │ social-media- │ │ agent │
│ agent │ │ │
Cluster generates │ │ │ classify each │
composite persona │ 1. uses draft │ │ reply → cluster│
+ multi-turn │ 2. Stripe $1 │ │ compute deltas │
in-character chat │ 3. verify pay │ │ return brief: │
with memory. │ 4. Composio → │ │ predicted vs │
│ Twitter / │ │ actual per │
│ Reddit / │ │ cluster │
│ Facebook │ └────────────────┘
└────────────────┘
⏺ ## Inspiration
Local campaigns can't afford pollsters. A Senate race spends $50k+ per polling cycle; a school-board candidate spends zero, announces a position, and finds out what voters actually think only after the
damage is done. We wanted to give first-time candidates the same pre-launch testing, voter listening, and engagement measurement that big-money campaigns get from agencies — for the cost of an LLM API
call.
ChatGPT can roleplay one voter. We wanted to coordinate hundreds across seven demographics, take real actions in the world, and leave each cluster as something the candidate can come back and talk to
later.
## What it does
Upload a policy PDF (or paste text), and Pols 15 spins up an entire campaign workshop around it:
- Simulates reactions across 7 demographic groups — each generating realistic personas who debate the policy across multiple rounds of social-media-style chatter
- Maps the impact onto a 3D Mapbox globe, with each cluster as a colored zone you can click for sample reactions
- Extracts an interactive stakeholder graph — who pushes for the policy, who's squeezed by it, who has to enforce it
- Lets you talk to a constituent — every cluster has a chat agent that maintains an in-character composite persona ("Maria, 34, gig worker") and answers your follow-up questions
- Drafts your position as a tweet, a Reddit post, and a Facebook post, pre-loaded onto the social-media agent
- Posts for real via Composio + Stripe (one $1 payment per platform → live post on your authorized account)
- Compares predictions vs reality — the comparison agent classifies actual replies on your post into clusters and surfaces where you read the room right vs where it diverged
All driven through one chat on ASI:1 or one upload on the website.
## How we built it
Twelve agents on Fetch.ai, all communicating through one shared SharedAgentState envelope (the canonical Fetch hackathon-quickstarter pattern, scaled):
- 1 orchestrator (chat entry point on ASI:1)
- 1 graphrag agent (entity + relationship extraction)
- 1 env-config agent (picks which clusters to simulate + parameters)
- 7 cluster agents (parallel demographic simulations)
- 1 report agent (markdown decision-brief synthesis)
- 1 map agent (3D Mapbox globe, FastAPI service)
- 1 social-media agent (Stripe-gated Composio posting)
- 1 comparison agent (predicted-vs-actual reality check)
Key architectural moves:
- HTTP A2A, not mailbox for inter-agent traffic — the default Agentverse mailbox was 60-90s per hop, fatal for a 6-phase pipeline. We dropped mailbox on workers, added a
/processREST endpoint to
each, and the orchestrator calls them viahttpx. Latency went from minutes to ~1s per hop. Mailbox is reserved for ASI:1 user chat. - Programmatic Agentverse registration via
register_chat_agentfromuagents-core— all 12 agents bind their mailboxes at module load, no manual inspector clicks. - Sidecar FastAPI on the social-media agent — the orchestrator pushes drafts to a separate
/draftport without forcing the chat protocol. - Dual-mode cluster agents — same uagent process serves the orchestrator's pipeline
/processAND a chat protocol where users converse with an in-character persona. Per-sender history kept in memory. - Stripe payment protocol (
payment_protocol_spec, seller role) co-mounted with chat protocol — embedded checkout renders inline in ASI:1, payment verified server-side via
stripe.checkout.Session.retrievebefore any Composio call. - ASI:1 for all LLM work (parsing, persona generation, multi-round simulation, brief synthesis, reply classification, draft generation).
- Web frontend — Vite + React + Tailwind, with a forked MiroFish 3D Mapbox globe and a D3 force-directed knowledge graph.
## Challenges we ran into
- Mailbox latency. Inter-agent messages over Agentverse were taking ~90s round-trip. Our orchestrator's clusters would finish simulating, send their reports, and the orchestrator would never see them —
it had already timed out. We rebuilt the entire inter-agent layer on direct
httpxcalls. - The "Connect Mailbox" dance. Manually clicking the Agentverse inspector for 12 agents was unreliable — proving failed silently on cluster agents past #4. Switching to
register_chat_agent
programmatically (withdangerously_skip_version_checkon Composio) bypassed it entirely. - Stripe deprecated
ui_mode="embedded"toembedded_pagemid-build. Composio added a required toolkit-version pinning we had to escape withdangerously_skip_version_check=True. Both errors surfaced live, mid-demo. - Cluster fan-out under ASI:1 contention. With 7 clusters all making 8 ASI:1 calls each in parallel, individual calls slowed enough that some clusters were finishing past our 180s timeout. Bumped to
300s + added explicit
httpx.Limits(max_connections=50). - OAuth state across agents. Got tangled between per-user Composio user_ids and a shared playground account; eventually consolidated to one shared
COMPOSIO_USER_IDfor all platforms, matching the user_id under which Twitter/Reddit/Facebook were already pre-connected. - Rendering MiroFish-style polish in our timeline. Forked their 1,411-line
index.html, added an?embed=truemode that strips all chrome for clean iframing, and rewired the data path to our orchestrator's payload shape.
## Accomplishments that we're proud of
- Twelve agents, one chat thread. Type one policy on ASI:1 and watch a coordinated multi-agent system fan out, simulate, synthesize, draft, and hand off — in 60-120 seconds, end to end.
- Real money, real posts. A $1 Stripe payment really clears, and the agent really posts to Twitter or Reddit afterward. The whole loop from "draft generated by orchestrator" to "live post on the user's
account" works.
- The reality-check loop. The comparison agent takes actual social-media replies, classifies each into a cluster archetype, and tells you where your simulated voters were right and where the real
public surprised you. That's the feedback loop that no political-tech tool we found does. - Per-cluster persistent personas. Each demographic agent generates a specific composite person on first message and stays in character with conversation memory. The candidate can ask "Maria, what
would flip you?" and get a real answer rooted in concrete daily-life details.
- Pure systems-engineering, not prompt-stuffing. The orchestrator's chat handler is a 50-line linear async function. The complexity hides in the workers.
## What we learned
- Multi-agent orchestration is a systems problem, not a prompting problem. The interesting bugs are about transport, state, latency, and protocol — not about the LLM.
- Pick the right transport per interaction. Agentverse mailbox is great for ASI:1 user chat. It's the wrong choice for inter-agent fan-out.
- One envelope > many typed messages. Replacing 4 typed request/reply pairs with one
SharedAgentStatemodel collapsed the orchestrator from a state machine into a for-loop. - Programmatic > UI clicks for anything you do more than once. Manual Agentverse "Connect Mailbox" was the single biggest source of "this should work, why doesn't it" hours.
- Latency dominates UX. Politicians won't wait 6 minutes for a brief; they'll wait 90 seconds. Every architectural decision was downstream of that constraint.
- The hard part of "agentic" isn't the agents — it's making them coordinate without losing each other's state.
## What's next for Pols 15
- Engagement puller agent — auto-fetch reply data from Composio so the comparison loop runs without the user pasting anything.
- Spectrum visualization — left-right axis with cluster bubbles, sized by sentiment magnitude, colored by stance. Plot individual personas as dots inside their cluster's bubble.
- What-if amendment slider — edit a clause of the policy in-line, watch sentiment per cluster shift in real time, ship the version that flips the most clusters to neutral.
- Town hall practice mode — cluster personas drop into a simulated town hall and grill the candidate. Records audio, transcribes, and generates a debate-prep packet.
- More platforms — LinkedIn, Bluesky, Threads via Composio. Same payment-gated pattern.
- Multi-policy A/B comparison — run two versions of the same policy through the simulator and surface which version flips the most decisive clusters.
- Hosted SaaS — make Pols 15 available to actual local candidates running for school board / city council. Real customers, not hackathon demos.
Built With
- agentverse
- asi
- fetch
Log in or sign up for Devpost to join the conversation.