Skip to content

Repository files navigation

Twinder — Digital Twins for Agent-to-Agent Networking

WeaveHacks 4 | June 2026 | https://github.com/xinyuhwang/Twinder

DEMO: https://www.loom.com/share/37234a31986847f9a90c1a4fd0f812f6

Concept

Your AI digital twin networks on your behalf. Built from your “second brain” (interests, personality, experience), your twin chats with other twins in a virtual room — like a networking event that runs while you sleep. The best conversations surface as matches, ranked by “vibe score.” Then you meet IRL.

Why it matters

  • Networking relies on serendipity; introverts miss connections
  • Your twin can talk to everyone — you only meet the best matches
  • Agents start the conversation; humans can drop in and continue it
  • Works for professional networking, dating, community building

What’s Built (backend)

Tech stack

  • FastAPI + uvicorn (async Python)
  • SQLModel (SQLAlchemy + Pydantic)
  • Redis (Streams, Pub/Sub, Hashes) — sponsor integration
  • LiteLLM (provider-agnostic LLM calls: Claude, GPT-4o, etc.)
  • Google OAuth + JWT auth + dev-login shortcut
  • SQLite for persistence
  • 7 seeded demo users with rich personas (auto-seeded on startup)

Project structure

app/
├── main.py              # FastAPI app, lifespan, CORS, auto-seeds demo users
├── config.py            # Pydantic Settings (.env)
├── deps.py              # Auth dependency (JWT)
├── database.py          # SQLite engine
├── models.py            # User, Room, RoomParticipant
├── schemas.py           # Request/response models (incl. MatchCard, ArenaResponse)
├── redis_client.py      # Async Redis pool (auto RESP2/3)
├── llm.py               # LiteLLM wrapper (swap providers via env)
├── seed.py              # 7 demo users: Alexis, Haley, Leo, Maya, Jordan, Priya, Marcus
├── auth/
│   ├── oauth.py         # Authlib Google OAuth
│   └── router.py        # /auth/google, /auth/callback, /auth/me, /auth/dev-login
├── users/
│   └── router.py        # /users/me, /users/{id}
├── rooms/
│   ├── router.py        # Room CRUD, matchmaking, takeover, completion
│   └── matchmaker.py    # Redis list-based pairing
├── chat/
│   ├── manager.py       # WebSocket ConnectionManager
│   └── router.py        # WS /ws/rooms/{room_id}
├── arena/
│   └── router.py        # Arena batch mode endpoints
└── agents/
    ├── prompts.py        # Twin persona + match card scoring prompts
    ├── engine.py         # Agent conversation loop (chatroom mode)
    ├── arena.py          # Arena batch engine (speed-date all agents)
    └── scorer.py         # Post-conversation vibe scoring

API endpoints

Auth

MethodPathDescription
GET/auth/googleStart Google OAuth flow
GET/auth/callbackOAuth callback -> JWT cookie + redirect
GET/auth/meCurrent user from JWT
POST/auth/dev-loginDev shortcut: create/find user, get JWT
POST/auth/logoutClear cookie

POST /auth/dev-login?name=Alexis — returns JWT for seeded demo user. POST /auth/dev-login?name=NewUser&persona=... — creates a new user.

Users

MethodPathDescription
GET/users/meGet profile
PUT/users/meUpdate name, persona
GET/users/{id}Public profile

Arena (batch mode — primary demo flow)

MethodPathDescription
POST/arena/start?mode=hackathonRun agent against all others, ranked
GET/arena/resultsFetch latest match cards
GET/arena/conversation/{convo_id}Eavesdrop on a specific arena convo

POST /arena/start runs your agent in short (8-turn) parallel conversations with all other users, then scores each and returns ranked match cards with: score, headline, match_type, summary, overlaps, suggested_opener, conversation_highlights, common_interests.

Modes: networking, hackathon, dating, custom.

Rooms (chatroom mode — live conversations)

MethodPathDescription
POST/rooms/matchmakeJoin matchmaking queue
GET/rooms/matchmake/statusPoll match status
GET/roomsList user’s rooms
GET/rooms/{id}Room details + vibe score
GET/rooms/{id}/messagesMessage history (Redis Stream)
POST/rooms/{id}/takeoverHuman replaces agent
POST/rooms/{id}/completeEnd convo, trigger vibe scoring
WS/ws/rooms/{id}?token={jwt}Real-time chat via Redis Pub/Sub

Other

MethodPathDescription
GET/healthSQLite + Redis health
GET/docsSwagger UI (interactive)

Redis data model

KeyTypePurpose
room:{id}:messagesStreamMessage history (sender, role, content)
room:{id}:stateHashTurn state, msg count, human overrides
rooms:activeSetActive room IDs
matchmaking:queueListUsers waiting to be paired
matchmaking:result:{uid}StringMatch result (room_id), TTL 5min
room:{id}:eventsPubSubFan-out to WebSockets
arena:{uid}:latestStringLatest arena results JSON, TTL 1hr
arena-convo:{id}StreamArena conversation messages, TTL 1hr

Two interaction modes

Arena (batch) — for the demo

  1. User enters arena
  2. Their agent has short conversations with all other agents (parallel)
  3. Each conversation scored into a rich match card
  4. Results returned ranked by score
  5. Frontend shows swipeable match cards with eavesdrop option

Chatroom (live) — for deeper connection

  1. Two users matched via queue
  2. Agents chat in real-time (20 turns, 3s pacing)
  3. Messages stream via WebSocket + Redis Pub/Sub
  4. Human can take over at any time
  5. On completion, vibe scoring via LLM

Demo users (auto-seeded)

7 users with rich multi-paragraph personas:

NameRole
AlexisAI engineer, climber, builder
HaleySocial/emotional product thinker
LeoBackend/infra builder
MayaProduct designer, UX thinker
JordanGo-to-market, community
PriyaAI researcher, knowledge systems
MarcusIndie hacker, storyteller

LLM provider config

Provider is swappable via LLM_MODEL in .env:

  • anthropic/claude-sonnet-4-20250514 (Claude)
  • gpt-4o (OpenAI)
  • gpt-4o-mini (cheap testing)

Powered by LiteLLM — supports 100+ providers.

Frontend Integration Guide

Quick start for frontend devs

# 1. Get a token for a demo user
TOKEN=$(curl -s -X POST 'http://HOST:8000/auth/dev-login?name=Alexis' | jq -r .token)

# 2. Run arena (takes ~30-60s)
curl -X POST 'http://HOST:8000/arena/start?mode=hackathon' \
  -H "Authorization: Bearer $TOKEN"

# 3. Get match cards
curl 'http://HOST:8000/arena/results' \
  -H "Authorization: Bearer $TOKEN"

# 4. Eavesdrop on a conversation
curl 'http://HOST:8000/arena/conversation/{convo_id}' \
  -H "Authorization: Bearer $TOKEN"

Auth pattern

  • All endpoints except /health, /docs, /auth/google, /auth/callback require auth
  • Pass JWT as Authorization: Bearer {token} header or access_token cookie
  • For WebSocket: pass as query param ?token={jwt}

Key response types

  • MatchCard: score, headline, match_type, summary, strongest_overlap, non_obvious_overlap, complementary_dynamic, suggested_opener, follow_up_questions, conversation_highlights, common_interests, opponent_id, opponent_name
  • ArenaResponse: status, arena_id, match_cards[]
  • MessageRead: id, sender_user_id, sender_name, role (agent/human), content, timestamp
  • UserRead: id, name, email, avatar_url, persona

Full schemas at /docs.

Infrastructure

Redis

  • Dev: local Redis (auto-falls back to RESP2 for older versions)
  • Prod: Redis Cloud 8.x (us-east-1)
  • Switch via REDIS_URL in .env

Running locally

# Start Redis (if using local)
redis-server --daemonize yes

# Install deps
uv venv && source .venv/bin/activate
uv pip install -e .

# Run (auto-seeds 7 demo users)
uvicorn app.main:app --reload
# Docs at http://localhost:8000/docs

Plan / TODO

Project scaffolding + FastAPI skeleton

Google OAuth + JWT auth

Dev login shortcut (bypass OAuth for testing)

User profiles + persona storage

Redis-based matchmaking queue

Agent conversation engine (Claude/GPT via LiteLLM)

WebSocket real-time chat with Redis Pub/Sub

Human takeover flow

Vibe scoring

LLM provider abstraction (LiteLLM)

Arena batch mode with rich match cards

7 demo users with rich personas

End-to-end test (arena + chatroom)

Frontend (Next.js) — other team members

Google OAuth on prod domain

Prompt tuning for better twin personalities

Explore: LangCache for Redis-based LLM caching

Explore: agent memory / context persistence

Deploy frontend

Demo prep + narrative

Team notes

  • Repo: https://github.com/xinyuhwang/Twinder
  • Domain: twindr (setting up)
  • Dev server: DO droplet (backend running)
  • Redis is a hackathon sponsor — bonus points for usage
  • Targeting: compelling live demo + clear narrative
  • Demo flow: enter arena -> agents speed-date -> swipeable match cards -> eavesdrop -> meet

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages