Skip to content

PranAD-dev/pols-15

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stump — The Campaign Toolbox

A Fetch.ai multi-agent system for anyone running for office (school board, city council, state house, federal). Upload a policy → simulate how every demographic actually reacts → talk to constituents in character → draft and post your position → measure real engagement against the simulated predictions.

Twelve discoverable agents on Agentverse, one chat entry point on ASI:1, two transports (mailbox + HTTP A2A), one shared envelope (SharedAgentState).


🎯 Try it live

The whole flow is driven through one ASI:1 chat — the orchestrator dispatches everything else.

Try the live demo on ASI:1

Type something like:

"simulate a 5% minimum wage increase in San Jose, 5 personas per cluster and 2 rounds"

You'll get back, in one reply: a markdown decision brief with verdicts and quotes per cluster, a 3D Mapbox impact globe URL, chat handles for each cluster persona to drill into, and pre-loaded social-media drafts ready to post via Stripe-gated Composio.


🤖 The agents

Multi-agent orchestration pipeline

The orchestrator chains six phases through these agents — each with its own discoverable Agentverse profile:

# Agent Role Profile
0 policy-orchestrator Chat entry point. Coordinates all phases. Profile →
1 graphrag-agent Extracts entities / relationships / affected populations from policy text Profile →
2 env-config-agent Picks which clusters to simulate + persona/round counts Profile →
3a cluster-low_income_renters Demographic simulator + in-character chat persona Profile →
3b cluster-homeowners_middle_class Demographic simulator + in-character chat persona Profile →
3c cluster-small_business_owners Demographic simulator + in-character chat persona Profile →
3d cluster-young_professionals Demographic simulator + in-character chat persona Profile →
3e cluster-seniors_retirees Demographic simulator + in-character chat persona Profile →
3f cluster-families_with_kids Demographic simulator + in-character chat persona Profile →
3g cluster-low_income_workers Demographic simulator + in-character chat persona Profile →
4 report-agent Synthesizes the markdown decision brief Profile →
5 map-agent Builds the 3D Mapbox impact globe (FastAPI service — local-only, not on Agentverse) local FastAPI on :8888
6 drafts pushed Orchestrator pushes platform drafts to social-media-agent's /draft sidecar

Companion agents (post-orchestration workflow)

These aren't part of the simulation pipeline itself — they're the act and measure half of the campaign workflow:

Agent Role Profile
social-media-agent Pay-to-post via Stripe + Composio. Posts to Twitter / Reddit / Facebook on the user's authorized accounts after $1 payment confirmation. Pre-loaded with drafts from the orchestrator. Profile →
comparison-agent Reality-check agent. Takes simulated cluster reports + actual replies on a published post, classifies each reply into its closest cluster, and produces a "predicted vs actual" delta brief. Profile →

🗺️ The pipeline

USER (chat or web)
  │
  ▼  Phase 1: graphrag-agent             extract entities + relationships + populations
  ▼  Phase 2: env-config-agent           pick clusters + persona/round counts
  ▼  Phase 3: 7 cluster-* agents         parallel sentiment simulations (asyncio.gather)
  ▼  Phase 4: report-agent               markdown decision brief
  ▼  Phase 5: map-agent                  3D Mapbox impact globe
  ▼  Phase 6: drafts pushed              tweet / reddit / facebook drafts pre-loaded
  │                                      onto social-media-agent's sidecar
  ▼
RESULT: brief + map URL + 7 cluster chat handles + social drafts ready

THEN — separately, after the politician posts a position:

USER → social-media-agent → Stripe checkout → Composio post (Twitter / Reddit / Facebook)

THEN — once replies accumulate on the post:

USER / dashboard → comparison-agent → predicted-vs-actual reality-check brief

🏗️ Architecture

The system is built around a few deliberate engineering choices:

Canonical SharedAgentState envelope

Instead of typed request/reply pairs per agent (which would mean 10+ message classes), every inter-agent message uses the same Pydantic model. Each sub-agent reads what it needs, fills its slice, and returns the whole envelope. The orchestrator's chat handler is one ~50-line linear async function — no event machine, no state DB.

HTTP A2A, not Agentverse mailbox

Default Fetch transport (mailbox websocket polling) was 60-90s per hop in our tests — fatal for a 6-phase pipeline. Workers expose /process REST endpoints; orchestrator calls them via httpx.post. Latency drops from minutes to ~1s per hop. Mailbox is reserved for ASI:1 user-facing chat — orchestrator + cluster agents + social-media-agent + comparison-agent all keep mailbox=True for that.

Programmatic Agentverse registration

We use register_chat_agent from uagents_core.utils.registration with the AGENTVERSE_API_KEY to register every agent at module load — before agent.run(). Bypasses the manual "Connect Mailbox" inspector click. Mailbox client finds the bound mailbox on first connect.

Sidecar FastAPI for cross-pipeline pushes

social-media-agent runs a uagent on its main port (chat + payment protocols) AND a FastAPI server on port+1 for the orchestrator's draft push. Daemon thread, same process. Avoids forcing the orchestrator into the chat protocol just to send context.

Dual-mode cluster agents

Each cluster-* agent serves both: (a) the orchestrator's /process REST for full simulations, and (b) AgentChatProtocol/0.3.0 for direct user chat. In chat mode, the agent generates a single composite persona on first message and stays in character with per-sender history.

Stripe payment protocol

social-media-agent includes both chat_protocol_spec and payment_protocol_spec (seller role). On chat, it creates a Stripe Checkout session and ships the client_secret in RequestPayment.metadata["stripe"]. ASI:1's chat UI renders the embedded checkout. On CommitPayment, the agent verifies via stripe.checkout.Session.retrieve and only then dispatches to Composio.


🛠️ Stack

Layer Tech
Agent framework Fetch.ai uagents 0.24.2, uagents-core 0.4.4
LLM ASI:1 (OpenAI-compatible, Fetch-hosted)
Inter-agent transport HTTP A2A via httpx (workers) + Agentverse mailbox (user-chat)
Discovery Programmatic Almanac registration via register_chat_agent
Payments Stripe Checkout (embedded_page) wrapped in payment_protocol_spec
Tool integrations Composio (Twitter / Reddit / Facebook) with dangerously_skip_version_check
Visualization Mapbox GL JS 3D globe + D3.js force-directed knowledge graph
Geocoding Nominatim (free, no API key)
Web frontend Vite + React 19 + TypeScript + Tailwind

📂 Repository layout

.
├── policy_simulator/
│   ├── orchestrator.py           # chat-protocol entry; pipeline coordinator + web API on :8000
│   ├── graphrag_agent.py         # Phase 1
│   ├── env_config_agent.py       # Phase 2
│   ├── cluster_agent.py          # Phase 3 — generic, picked per `CLUSTER` env
│   ├── report_agent.py           # Phase 4
│   ├── map_agent.py              # Phase 5 — pure FastAPI, serves /map/<id> + 3D globe
│   ├── social_media_agent.py     # post-pipeline action — Stripe + Composio
│   ├── comparison_agent.py       # post-pipeline measurement — predicted-vs-actual
│   ├── composio_socials.py       # Composio wrappers (Twitter/Reddit/Facebook)
│   ├── personas.py / simulation.py / clusters/definitions.py
│   └── static/map.html           # forked MiroFish 3D globe UI
├── shared/
│   ├── models.py                 # SharedAgentState + ClusterReport + ComparisonRequest etc.
│   ├── chat_proto.py             # AgentChatProtocol/0.3.0 helpers
│   ├── registration.py           # programmatic Agentverse registration
│   └── asi_one.py                # ASI:1 client
├── twitter_agent/                # standalone Twitter assistant (legacy, separate use)
├── website/                      # Vite + React frontend (Stump)
└── scripts/run_swarm.py          # spawns all sub-agents

▶️ Running locally

# 0. setup
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env  # then fill in ASI_ONE_API_KEY, AGENTVERSE_API_KEY, COMPOSIO_API_KEY,
                     # STRIPE_SECRET_KEY/STRIPE_PUBLISHABLE_KEY, MAPBOX_TOKEN

# 1. spawn all sub-agents (graphrag + env_config + report + map + social_media +
#    comparison + 7 cluster agents)
.venv/bin/python scripts/run_swarm.py

# 2. spawn the orchestrator (chat on :8002, web API on :8000)
.venv/bin/python -m policy_simulator.orchestrator

# 3. (optional) spawn the website
cd website && npm install && npm run dev    # http://localhost:5173

Once everything's up, all twelve agents auto-register on Agentverse via API key — they show up under your "My Agents" dashboard within a few seconds. From there you can chat the orchestrator (or any sub-agent) directly via ASI:1.


🎓 Why this isn't "just a wrapper around ChatGPT"

ChatGPT can roleplay one voter. This system coordinates 140 across seven demographics, runs six rounds of opinion drift between them, takes real actions in the world (Stripe payments + OAuth-authorized social posts), and leaves each cluster as a discoverable agent you can drill into. Each agent is its own process with isolated state. Each posts a manifest on Agentverse. Each is callable programmatically by other agents.

"One prompt is a tool. An agent system is a product."


📝 License

MIT — built on Fetch.ai for the campaign toolbox demo.

About

The campaign toolbox for anyone running for office — twelve Fetch.ai agents that simulate voter reaction, talk to constituents in character, post via Stripe-gated Composio, and compare predictions to real engagement.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors