# xpzero/demo-agent architecture

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

- Interactive diagram: https://gitdiagram.com/xpzero/demo-agent
- Repository: https://github.com/xpzero/demo-agent

## Overview

demo-agent is a learning project implementing a tool-using, streaming LLM agent with both CLI and browser chat. A user message enters either interface, reaches the agent loop, and may trigger locally executed tools before the model returns a final response. Conversations preserve Responses items across turns and sessions; permission checks and approval handling govern sensitive tool calls. The README documents the HTTP streaming boundary and major tool capabilities, but sampled source does not show the API, loop, or approval wiring in detail, so uncertain call edges are omitted.

Main entry points: [`server/tools/__init__.py`](https://github.com/xpzero/demo-agent/blob/main/server/tools/__init__.py) (Tool registry), [`server/agent/loop.py`](https://github.com/xpzero/demo-agent/blob/main/server/agent/loop.py) (Agent loop), [`server/cli/chat.py`](https://github.com/xpzero/demo-agent/blob/main/server/cli/chat.py) (CLI chat), [`server/api.py`](https://github.com/xpzero/demo-agent/blob/main/server/api.py) (HTTP API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["Chat interfaces"]
  node_web["Browser chat<br/>[App.tsx]"]
  node_adapter["Chat adapter<br/>[adapter.ts]"]
  node_cli["CLI chat<br/>[chat.py]"]
  node_api["HTTP API<br/>[api.py]"]
end

subgraph group_agent["Agent runtime"]
  node_loop["Agent loop<br/>[loop.py]"]
  node_client["OpenAI client<br/>[client.py]"]
  node_container["Service container<br/>[container.py]"]
end

subgraph group_tools["Tools and permissions"]
  node_dispatcher["Tool registry<br/>[__init__.py]"]
  node_calculate["Calculation<br/>[calculate.py]"]
  node_weather["Weather<br/>[get_weather.py]"]
  node_file_read["File reading<br/>[read.py]"]
  node_file_write["File writing<br/>[write.py]"]
  node_paths["Path checks<br/>[paths.py]"]
  node_search["Web search<br/>[search.py]"]
  node_fetch["URL fetch<br/>[fetch.py]"]
  node_permissions["Permission service<br/>[service.py]"]
  node_rules["Permission rules<br/>[rules.py]"]
  node_approval["Approval handling<br/>[approval.py]"]
end

subgraph group_sessions["Conversation state"]
  node_manager["Session manager<br/>[manager.py]"]
  node_session["Session model<br/>[session.py]"]
  node_store[("Session files<br/>[manager.py]")]
end

node_user(("User"))
node_tavily["Tavily"]
node_responses["Responses API"]

node_user -->|"sends message"| node_web
node_web -->|"submits chat"| node_adapter
node_adapter -->|"streams requests"| node_api
node_api -->|"runs agent"| node_loop
node_user -->|"enters prompt"| node_cli
node_cli -->|"runs agent"| node_loop
node_cli -->|"manages sessions"| node_manager
node_loop -->|"requests response"| node_client
node_client -->|"calls API"| node_responses
node_loop -->|"dispatches tools"| node_dispatcher
node_dispatcher -->|"dispatches"| node_calculate
node_dispatcher -->|"dispatches"| node_weather
node_dispatcher -->|"dispatches"| node_file_read
node_dispatcher -->|"dispatches"| node_file_write
node_dispatcher -->|"dispatches"| node_search
node_dispatcher -->|"dispatches"| node_fetch
node_file_read -->|"validates paths"| node_paths
node_file_write -->|"validates paths"| node_paths
node_search -->|"searches"| node_tavily
node_fetch -->|"fetches pages"| node_tavily
node_loop -->|"checks access"| node_permissions
node_permissions -->|"evaluates rules"| node_rules
node_loop -->|"handles approvals"| node_approval
node_container -->|"provides service"| node_permissions
node_manager -->|"loads and saves"| node_session
node_manager -->|"reads and writes"| node_store
node_api -->|"streams events"| node_adapter

click node_web "https://github.com/xpzero/demo-agent/blob/main/web/src/App.tsx"
click node_adapter "https://github.com/xpzero/demo-agent/blob/main/web/src/adapter.ts"
click node_cli "https://github.com/xpzero/demo-agent/blob/main/server/cli/chat.py"
click node_api "https://github.com/xpzero/demo-agent/blob/main/server/api.py"
click node_loop "https://github.com/xpzero/demo-agent/blob/main/server/agent/loop.py"
click node_client "https://github.com/xpzero/demo-agent/blob/main/server/agent/client.py"
click node_dispatcher "https://github.com/xpzero/demo-agent/blob/main/server/tools/__init__.py"
click node_calculate "https://github.com/xpzero/demo-agent/blob/main/server/tools/calculate.py"
click node_weather "https://github.com/xpzero/demo-agent/blob/main/server/tools/get_weather.py"
click node_file_read "https://github.com/xpzero/demo-agent/blob/main/server/tools/files/read.py"
click node_file_write "https://github.com/xpzero/demo-agent/blob/main/server/tools/files/write.py"
click node_paths "https://github.com/xpzero/demo-agent/blob/main/server/tools/files/paths.py"
click node_search "https://github.com/xpzero/demo-agent/blob/main/server/tools/web/search.py"
click node_fetch "https://github.com/xpzero/demo-agent/blob/main/server/tools/web/fetch.py"
click node_permissions "https://github.com/xpzero/demo-agent/blob/main/server/services/permission/service.py"
click node_rules "https://github.com/xpzero/demo-agent/blob/main/server/services/permission/rules.py"
click node_approval "https://github.com/xpzero/demo-agent/blob/main/server/agent/approval.py"
click node_container "https://github.com/xpzero/demo-agent/blob/main/server/services/container.py"
click node_manager "https://github.com/xpzero/demo-agent/blob/main/server/sessions/manager.py"
click node_session "https://github.com/xpzero/demo-agent/blob/main/server/sessions/session.py"
click node_store "https://github.com/xpzero/demo-agent/blob/main/server/sessions/manager.py"

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_web,node_adapter,node_cli,node_api,node_user toneBlue
class node_loop,node_client,node_container toneAmber
class node_dispatcher,node_calculate,node_weather,node_file_read,node_file_write,node_paths,node_search,node_fetch,node_permissions,node_rules,node_approval,node_responses toneMint
class node_manager,node_session,node_store toneRose
class node_tavily toneIndigo
```

## Components

### Chat interfaces

- [Browser chat](https://github.com/xpzero/demo-agent/blob/main/web/src/App.tsx): `web/src/App.tsx`
- [Chat adapter](https://github.com/xpzero/demo-agent/blob/main/web/src/adapter.ts): `web/src/adapter.ts`
- [CLI chat](https://github.com/xpzero/demo-agent/blob/main/server/cli/chat.py): `server/cli/chat.py`
- [HTTP API](https://github.com/xpzero/demo-agent/blob/main/server/api.py): `server/api.py`

### Agent runtime

- [Agent loop](https://github.com/xpzero/demo-agent/blob/main/server/agent/loop.py): `server/agent/loop.py`
- [OpenAI client](https://github.com/xpzero/demo-agent/blob/main/server/agent/client.py): `server/agent/client.py`
- [Service container](https://github.com/xpzero/demo-agent/blob/main/server/services/container.py): `server/services/container.py`

### Tools and permissions

- [Tool registry](https://github.com/xpzero/demo-agent/blob/main/server/tools/__init__.py): `server/tools/__init__.py`
- [Calculation](https://github.com/xpzero/demo-agent/blob/main/server/tools/calculate.py): `server/tools/calculate.py`
- [Weather](https://github.com/xpzero/demo-agent/blob/main/server/tools/get_weather.py): `server/tools/get_weather.py`
- [File reading](https://github.com/xpzero/demo-agent/blob/main/server/tools/files/read.py): `server/tools/files/read.py`
- [File writing](https://github.com/xpzero/demo-agent/blob/main/server/tools/files/write.py): `server/tools/files/write.py`
- [Path checks](https://github.com/xpzero/demo-agent/blob/main/server/tools/files/paths.py): `server/tools/files/paths.py`
- [Web search](https://github.com/xpzero/demo-agent/blob/main/server/tools/web/search.py): `server/tools/web/search.py`
- [URL fetch](https://github.com/xpzero/demo-agent/blob/main/server/tools/web/fetch.py): `server/tools/web/fetch.py`
- [Permission service](https://github.com/xpzero/demo-agent/blob/main/server/services/permission/service.py): `server/services/permission/service.py`
- [Permission rules](https://github.com/xpzero/demo-agent/blob/main/server/services/permission/rules.py): `server/services/permission/rules.py`
- [Approval handling](https://github.com/xpzero/demo-agent/blob/main/server/agent/approval.py): `server/agent/approval.py`

### Conversation state

- [Session manager](https://github.com/xpzero/demo-agent/blob/main/server/sessions/manager.py): `server/sessions/manager.py`
- [Session model](https://github.com/xpzero/demo-agent/blob/main/server/sessions/session.py): `server/sessions/session.py`
- [Session files](https://github.com/xpzero/demo-agent/blob/main/server/sessions/manager.py): `server/sessions/manager.py`

### Other components

- **User**
- **Tavily**
- **Responses API**

## Connections

- User → Browser chat: sends message
- Browser chat → Chat adapter: submits chat
- Chat adapter → HTTP API: streams requests
- HTTP API → Agent loop: runs agent
- User → CLI chat: enters prompt
- CLI chat → Agent loop: runs agent
- CLI chat → Session manager: manages sessions
- Agent loop → OpenAI client: requests response
- OpenAI client → Responses API: calls API
- Agent loop → Tool registry: dispatches tools
- Tool registry → Calculation: dispatches
- Tool registry → Weather: dispatches
- Tool registry → File reading: dispatches
- Tool registry → File writing: dispatches
- Tool registry → Web search: dispatches
- Tool registry → URL fetch: dispatches
- File reading → Path checks: validates paths
- File writing → Path checks: validates paths
- Web search → Tavily: searches
- URL fetch → Tavily: fetches pages
- Agent loop → Permission service: checks access
- Permission service → Permission rules: evaluates rules
- Agent loop → Approval handling: handles approvals
- Service container → Permission service: provides service
- Session manager → Session model: loads and saves
- Session manager → Session files: reads and writes
- HTTP API → Chat adapter: streams events
