# abdulsamad/polychat architecture

> Architecture diagram of the GitHub repository abdulsamad/polychat, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/abdulsamad/polychat
- Repository: https://github.com/abdulsamad/polychat

## Overview

PolyChat is a local-first AI chat workspace: a user configures a thread and model, composes text or attachments, submits a queued job, and receives streamed text or generated media rendered in the conversation. Threads, messages, settings, and BYOK secrets stay browser-local; chat, image, and video generation are handled by an authenticated server API and model providers. README capabilities also include model discovery, voice input/playback, message actions, usage details, and local-data management. Several server and route internals are unsampled, so links are limited to documented responsibilities and evidenced calls.

Main entry points: [`apps/client/app/hooks/useHandleChatResponse.tsx`](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useHandleChatResponse.tsx) (Response handling), [`apps/client/app/hooks/useCustomEditor.tsx`](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useCustomEditor.tsx) (Rich composer), [`apps/client/app/hooks/useByokModelAvailability.ts`](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useByokModelAvailability.ts) (Model availability), [`apps/serverless/src/controllers/index.ts`](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/index.ts) (Generation controllers)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_workspace["Chat workspace"]
  node_home["Conversation route<br/>[home.tsx]"]
  node_sidebar["Threads and settings<br/>[index.tsx]"]
  node_composer["Rich composer"]
  node_availability["Model availability"]
  node_submit["Submit and queue"]
  node_response["Response handling"]
  node_threadview["Conversation display<br/>[index.tsx]"]
  node_message["Rich message actions<br/>[index.tsx]"]
  node_speech["Voice features<br/>[useSpeech.tsx]"]
end

subgraph group_clientstate["Local state and keys"]
  node_queue["Chat job state<br/>[index.tsx]"]
  node_store["Conversation state<br/>[index.tsx]"]
  node_indexeddb[("Browser persistence<br/>[lforage.ts]")]
  node_vault[("Encrypted BYOK vault<br/>[byok-vault.ts]")]
end

subgraph group_api["Generation API"]
  node_api_calls["Generation requests<br/>[api-calls.ts]"]
  node_gateway["API entry and auth<br/>[index.ts]"]
  node_controllers["Generation controllers<br/>[index.ts]"]
  node_chat["Text generation<br/>[chat.ts]"]
  node_image["Image generation<br/>[image.ts]"]
  node_video["Video generation<br/>[video.ts]"]
end

subgraph group_models["Model runtime"]
  node_factory["Model factory<br/>[factory.ts]"]
  node_provider{{"AI providers"}}
  node_catalog["Model catalog and schemas<br/>[models.ts]"]
end

node_user(("User"))
node_browser_speech{{"Browser speech services"}}

node_user -->|"opens workspace"| node_home
node_home -->|"shows threads"| node_sidebar
node_home -->|"renders conversation"| node_threadview
node_user -->|"composes prompt"| node_composer
node_composer -->|"checks model"| node_availability
node_composer -->|"submits message"| node_submit
node_submit -->|"enqueues job"| node_queue
node_queue -->|"dispatches job"| node_response
node_response -->|"requests generation"| node_api_calls
node_api_calls -->|"sends request"| node_gateway
node_gateway -->|"dispatches request"| node_controllers
node_controllers -->|"dispatches chat"| node_chat
node_controllers -->|"dispatches image"| node_image
node_controllers -->|"dispatches video"| node_video
node_chat -->|"creates model"| node_factory
node_image -->|"creates model"| node_factory
node_video -->|"creates model"| node_factory
node_factory -->|"uses provider"| node_provider
node_availability -->|"reads catalog"| node_catalog
node_availability -.->|"discovers models"| node_provider
node_response -->|"updates messages"| node_store
node_store -->|"supplies messages"| node_threadview
node_threadview -->|"renders messages"| node_message
node_store -->|"persists threads"| node_indexeddb
node_sidebar -->|"manages threads"| node_store
node_sidebar -->|"manages local data"| node_indexeddb
node_availability -->|"checks keys"| node_vault
node_response -->|"checks provider key"| node_vault
node_response -->|"speaks response"| node_speech
node_speech -.->|"uses playback API"| node_browser_speech
node_composer -.->|"uses recognition API"| node_browser_speech

click node_home "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/routes/home.tsx"
click node_sidebar "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/AppSidebar/index.tsx"
click node_composer "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useCustomEditor.tsx"
click node_availability "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useByokModelAvailability.ts"
click node_submit "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useSubmitMessage.tsx"
click node_queue "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/store/index.tsx"
click node_response "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useHandleChatResponse.tsx"
click node_threadview "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/Thread/index.tsx"
click node_message "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/Message/index.tsx"
click node_speech "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useSpeech.tsx"
click node_store "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/store/index.tsx"
click node_indexeddb "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/lforage.ts"
click node_vault "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/byok-vault.ts"
click node_api_calls "https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/api-calls.ts"
click node_gateway "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/index.ts"
click node_controllers "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/index.ts"
click node_chat "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/chat.ts"
click node_image "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/image.ts"
click node_video "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/video.ts"
click node_factory "https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/models/factory.ts"
click node_catalog "https://github.com/abdulsamad/polychat/blob/main/packages/utils/src/models.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_home,node_sidebar,node_composer,node_availability,node_submit,node_response,node_threadview,node_message,node_speech,node_user,node_browser_speech toneBlue
class node_queue,node_store,node_indexeddb,node_vault toneAmber
class node_api_calls,node_gateway,node_controllers,node_chat,node_image,node_video toneMint
class node_factory,node_provider,node_catalog toneRose
```

## Components

### Chat workspace

- [Conversation route](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/routes/home.tsx): `apps/client/app/routes/home.tsx`
- [Threads and settings](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/AppSidebar/index.tsx): `apps/client/app/components/AppSidebar/index.tsx`
- [Rich composer](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useCustomEditor.tsx): `apps/client/app/hooks/useCustomEditor.tsx`
- [Model availability](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useByokModelAvailability.ts): `apps/client/app/hooks/useByokModelAvailability.ts`
- [Submit and queue](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useSubmitMessage.tsx): `apps/client/app/hooks/useSubmitMessage.tsx`
- [Response handling](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useHandleChatResponse.tsx): `apps/client/app/hooks/useHandleChatResponse.tsx`
- [Conversation display](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/Thread/index.tsx): `apps/client/app/components/Thread/index.tsx`
- [Rich message actions](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/components/Message/index.tsx): `apps/client/app/components/Message/index.tsx`
- [Voice features](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/hooks/useSpeech.tsx): `apps/client/app/hooks/useSpeech.tsx`

### Local state and keys

- [Chat job state](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/store/index.tsx): `apps/client/app/store/index.tsx`
- [Conversation state](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/store/index.tsx): `apps/client/app/store/index.tsx`
- [Browser persistence](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/lforage.ts): `apps/client/app/utils/lforage.ts`
- [Encrypted BYOK vault](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/byok-vault.ts): `apps/client/app/utils/byok-vault.ts`

### Generation API

- [Generation requests](https://github.com/abdulsamad/polychat/blob/main/apps/client/app/utils/api-calls.ts): `apps/client/app/utils/api-calls.ts`
- [API entry and auth](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/index.ts): `apps/serverless/src/index.ts`
- [Generation controllers](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/index.ts): `apps/serverless/src/controllers/index.ts`
- [Text generation](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/chat.ts): `apps/serverless/src/controllers/chat.ts`
- [Image generation](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/image.ts): `apps/serverless/src/controllers/image.ts`
- [Video generation](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/controllers/video.ts): `apps/serverless/src/controllers/video.ts`

### Model runtime

- [Model factory](https://github.com/abdulsamad/polychat/blob/main/apps/serverless/src/models/factory.ts): `apps/serverless/src/models/factory.ts`
- **AI providers**
- [Model catalog and schemas](https://github.com/abdulsamad/polychat/blob/main/packages/utils/src/models.ts): `packages/utils/src/models.ts`

### Other components

- **User**
- **Browser speech services**

## Connections

- User → Conversation route: opens workspace
- Conversation route → Threads and settings: shows threads
- Conversation route → Conversation display: renders conversation
- User → Rich composer: composes prompt
- Rich composer → Model availability: checks model
- Rich composer → Submit and queue: submits message
- Submit and queue → Chat job state: enqueues job
- Chat job state → Response handling: dispatches job
- Response handling → Generation requests: requests generation
- Generation requests → API entry and auth: sends request
- API entry and auth → Generation controllers: dispatches request
- Generation controllers → Text generation: dispatches chat
- Generation controllers → Image generation: dispatches image
- Generation controllers → Video generation: dispatches video
- Text generation → Model factory: creates model
- Image generation → Model factory: creates model
- Video generation → Model factory: creates model
- Model factory → AI providers: uses provider
- Model availability → Model catalog and schemas: reads catalog
- Model availability → AI providers: discovers models
- Response handling → Conversation state: updates messages
- Conversation state → Conversation display: supplies messages
- Conversation display → Rich message actions: renders messages
- Conversation state → Browser persistence: persists threads
- Threads and settings → Conversation state: manages threads
- Threads and settings → Browser persistence: manages local data
- Model availability → Encrypted BYOK vault: checks keys
- Response handling → Encrypted BYOK vault: checks provider key
- Response handling → Voice features: speaks response
- Voice features → Browser speech services: uses playback API
- Rich composer → Browser speech services: uses recognition API
