# arktosum/makonome architecture

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

- Interactive diagram: https://gitdiagram.com/arktosum/makonome
- Repository: https://github.com/arktosum/makonome

## Overview

#### Purpose and Entry Points
Mako is a personal, stateful AI assistant with cross-channel conversation, long-term memory, autonomous check-ins, and tool use. `main.py` starts the local CLI/dashboard or cloud mode; `telegram_bridge.py` is a Telegram door. The HTTP/WebSocket API is hosted by `dashboard/server.py`; Flutter clients enter through `mobile/lib/main.dart`.

#### Session-Centered Agent Runtime
A single shared session preserves one conversation across CLI, dashboard, API, mobile, and Telegram. `agent/session.py` owns buffered, thread-safe interaction; `agent/context.py` assembles prompts from persona, conversation, retrieved memory, and notes; `agent/loop.py` runs model/tool iterations. Runtime activity is emitted as structured events via `agent/events.py` for live clients and prompt inspection.

#### Model Routing and Agent Execution
`config.py` defines the persona seed, per-job model routes, and heartbeat policy. `llm/client.py` selects Groq, OpenAI, Anthropic, or OpenAI-compatible providers per workload and handles native tool calling. For providers lacking it, `llm/react_fallback.py` converts textual ReAct-style requests into the same agent control flow. This boundary keeps chat, curation, wakeups, heartbeat decisions, and reflection independently model-assignable.

#### Memory and Identity Lifecycle
Episodic conversation memory persists and retrieves through Supabase/pgvector in `memory/db.py` and `memory/episodic.py`. A curated notes layer in `memory/notes.py` stores durable user context, open threads, people, and assistant identity. `memory/curator.py` turns meaningful interactions into journal updates; `memory/consolidator.py` supports memory maintenance. These background writes are distinct from synchronous response-time retrieval.

#### Autonomous Life Cycle
The `life/` subsystem lets Mako act without an inbound message. `life/heartbeat.py` schedules hourly, quiet-hour-aware “is there a reason to speak?” decisions; silence is a valid expected output. `life/wakeup.py` produces proactive messages, `life/reflection.py` periodically rewrites the evolving identity from the journal, and `life/push.py` delivers notifications through ntfy and related outbound paths.

#### Interfaces and Delivery Boundaries
`dashboard/server.py` exposes authenticated synchronous chat, memory clearing, health checks, and a WebSocket event stream; `dashboard/static/index.html` and associated JS provide the browser dashboard. `mobile/lib/services/api_service.dart` and `mobile/lib/services/ws_service.dart` consume the same API and live events. `telegram_bridge.py` restricts bot interaction to the configured owner chat and supports replyable heartbeats. Render deployment is defined in `render.yaml`.

#### Tools and External Infrastructure
Tools are registered centrally in `tools/registry.py`, then exposed to the agent loop: search/page access, weather, system/app actions, finance, and note/memory operations (`tools/search.py`, `tools/finance.py`, `tools/notes.py`). Supabase serves both vector memory and BalanceFlow finance integrations; ntfy provides push; LLM providers are external API dependencies. The Python backend is the authoritative runtime, while Flutter is a remote client rather than a separate agent implementation.

Main entry points: [`dashboard/server.py`](https://github.com/arktosum/makonome/blob/main/dashboard/server.py) (Dashboard API), [`agent/loop.py`](https://github.com/arktosum/makonome/blob/main/agent/loop.py) (Agent loop), [`agent/session.py`](https://github.com/arktosum/makonome/blob/main/agent/session.py) (Shared session), [`llm/client.py`](https://github.com/arktosum/makonome/blob/main/llm/client.py) (LLM router)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Entry &amp; Clients"]
  node_main["Application entry<br/>Python entrypoint<br/>[main.py]"]
  node_telegram["Telegram bridge<br/>Bot gateway<br/>[telegram_bridge.py]"]
  node_api["Dashboard API<br/>HTTP/WebSocket server<br/>[server.py]"]
  node_browser["Browser dashboard<br/>Web client<br/>[index.html]"]
  node_mobile_app["Flutter client<br/>Mobile client<br/>[main.dart]"]
  node_mobile_api["Mobile API service<br/>API client<br/>[api_service.dart]"]
  node_mobile_ws["Mobile WebSocket service<br/>Event client<br/>[ws_service.dart]"]
end

subgraph group_runtime["Agent Runtime"]
  node_session[("Shared session<br/>Conversation state<br/>[session.py]")]
  node_context["Prompt context<br/>Context assembler<br/>[context.py]"]
  node_agent_loop["Agent loop<br/>Model/tool executor<br/>[loop.py]"]
  node_events["Runtime events<br/>Structured event stream<br/>[events.py]"]
  node_config["Persona &amp; routes<br/>Runtime policy<br/>[config.py]"]
  node_llm["LLM router<br/>Provider client<br/>[client.py]"]
  node_react["ReAct fallback<br/>Tool-call adapter<br/>[react_fallback.py]"]
end

subgraph group_memory["Memory &amp; Autonomy"]
  node_episodic[("Episodic memory<br/>Conversation retrieval<br/>[episodic.py]")]
  node_notes[("Curated notes<br/>Durable identity store<br/>[notes.py]")]
  node_curator["Memory curation<br/>Background writer<br/>[curator.py]"]
  node_consolidator["Memory consolidation<br/>Maintenance job<br/>[consolidator.py]"]
  node_heartbeat["Heartbeat scheduler<br/>Autonomy scheduler<br/>[heartbeat.py]"]
  node_wakeup["Proactive wakeup<br/>Message generator<br/>[wakeup.py]"]
  node_reflection["Identity reflection<br/>Periodic identity writer<br/>[reflection.py]"]
  node_push["Push delivery<br/>Notification gateway<br/>[push.py]"]
end

subgraph group_integrations["Tools &amp; Infrastructure"]
  node_tools["Tool registry<br/>Tool boundary<br/>[registry.py]"]
  node_memory_db[("Supabase pgvector<br/>Memory database<br/>[db.py]")]
  node_providers{{"LLM providers<br/>External APIs"}}
  node_ntfy{{"ntfy<br/>Push service"}}
  node_render["Render deployment<br/>Deployment definition<br/>[render.yaml]"]
end

node_main -->|"starts"| node_api
node_main -->|"initializes"| node_session
node_telegram -->|"owner messages"| node_session
node_api -->|"chat requests"| node_session
node_browser -->|"HTTP and events"| node_api
node_mobile_app -->|"uses"| node_mobile_api
node_mobile_app -->|"uses"| node_mobile_ws
node_mobile_api -->|"HTTP"| node_api
node_mobile_ws -->|"WebSocket"| node_api
node_session -->|"conversation"| node_context
node_context -->|"assembled prompt"| node_agent_loop
node_episodic -->|"retrieved memories"| node_context
node_notes -->|"durable context"| node_context
node_agent_loop -->|"model iterations"| node_llm
node_config -->|"workload routes"| node_llm
node_llm -->|"provider calls"| node_providers
node_llm -.->|"unsupported tool calls"| node_react
node_agent_loop -->|"tool execution"| node_tools
node_agent_loop -->|"emits activity"| node_events
node_events -->|"live stream"| node_api
node_episodic -->|"persist and retrieve"| node_memory_db
node_session -.->|"meaningful interactions"| node_curator
node_curator -->|"journal updates"| node_notes
node_consolidator -.->|"maintains"| node_episodic
node_heartbeat -->|"reason to speak"| node_wakeup
node_wakeup -->|"proactive prompt"| node_agent_loop
node_reflection -->|"identity rewrite"| node_notes
node_wakeup -->|"outbound message"| node_push
node_push -->|"notification"| node_ntfy
node_render -.->|"deploys"| node_main

click node_main "https://github.com/arktosum/makonome/blob/main/main.py"
click node_telegram "https://github.com/arktosum/makonome/blob/main/telegram_bridge.py"
click node_api "https://github.com/arktosum/makonome/blob/main/dashboard/server.py"
click node_browser "https://github.com/arktosum/makonome/blob/main/dashboard/static/index.html"
click node_mobile_app "https://github.com/arktosum/makonome/blob/main/mobile/lib/main.dart"
click node_mobile_api "https://github.com/arktosum/makonome/blob/main/mobile/lib/services/api_service.dart"
click node_mobile_ws "https://github.com/arktosum/makonome/blob/main/mobile/lib/services/ws_service.dart"
click node_session "https://github.com/arktosum/makonome/blob/main/agent/session.py"
click node_context "https://github.com/arktosum/makonome/blob/main/agent/context.py"
click node_agent_loop "https://github.com/arktosum/makonome/blob/main/agent/loop.py"
click node_events "https://github.com/arktosum/makonome/blob/main/agent/events.py"
click node_config "https://github.com/arktosum/makonome/blob/main/config.py"
click node_llm "https://github.com/arktosum/makonome/blob/main/llm/client.py"
click node_react "https://github.com/arktosum/makonome/blob/main/llm/react_fallback.py"
click node_episodic "https://github.com/arktosum/makonome/blob/main/memory/episodic.py"
click node_notes "https://github.com/arktosum/makonome/blob/main/memory/notes.py"
click node_curator "https://github.com/arktosum/makonome/blob/main/memory/curator.py"
click node_consolidator "https://github.com/arktosum/makonome/blob/main/memory/consolidator.py"
click node_heartbeat "https://github.com/arktosum/makonome/blob/main/life/heartbeat.py"
click node_wakeup "https://github.com/arktosum/makonome/blob/main/life/wakeup.py"
click node_reflection "https://github.com/arktosum/makonome/blob/main/life/reflection.py"
click node_push "https://github.com/arktosum/makonome/blob/main/life/push.py"
click node_tools "https://github.com/arktosum/makonome/blob/main/tools/registry.py"
click node_memory_db "https://github.com/arktosum/makonome/blob/main/memory/db.py"
click node_render "https://github.com/arktosum/makonome/blob/main/render.yaml"

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_main,node_telegram,node_api,node_browser,node_mobile_app,node_mobile_api,node_mobile_ws toneBlue
class node_session,node_context,node_agent_loop,node_events,node_config,node_llm,node_react toneAmber
class node_episodic,node_notes,node_curator,node_consolidator,node_heartbeat,node_wakeup,node_reflection,node_push toneMint
class node_tools,node_memory_db,node_providers,node_ntfy,node_render toneRose
```

## Components

### Entry & Clients

- [Application entry](https://github.com/arktosum/makonome/blob/main/main.py): Python entrypoint · Starts local dashboard/CLI or cloud mode. · `main.py`
- [Telegram bridge](https://github.com/arktosum/makonome/blob/main/telegram_bridge.py): Bot gateway · Restricts interaction to the configured owner chat. · `telegram_bridge.py`
- [Dashboard API](https://github.com/arktosum/makonome/blob/main/dashboard/server.py): HTTP/WebSocket server · Authenticated chat, health, memory control, and event streaming. · `dashboard/server.py`
- [Browser dashboard](https://github.com/arktosum/makonome/blob/main/dashboard/static/index.html): Web client · `dashboard/static/index.html`
- [Flutter client](https://github.com/arktosum/makonome/blob/main/mobile/lib/main.dart): Mobile client · `mobile/lib/main.dart`
- [Mobile API service](https://github.com/arktosum/makonome/blob/main/mobile/lib/services/api_service.dart): API client · `mobile/lib/services/api_service.dart`
- [Mobile WebSocket service](https://github.com/arktosum/makonome/blob/main/mobile/lib/services/ws_service.dart): Event client · `mobile/lib/services/ws_service.dart`

### Agent Runtime

- [Shared session](https://github.com/arktosum/makonome/blob/main/agent/session.py): Conversation state · Thread-safe buffered session shared by every channel. · `agent/session.py`
- [Prompt context](https://github.com/arktosum/makonome/blob/main/agent/context.py): Context assembler · Combines persona, conversation, retrieved memory, and notes. · `agent/context.py`
- [Agent loop](https://github.com/arktosum/makonome/blob/main/agent/loop.py): Model/tool executor · Runs iterative model and tool control flow. · `agent/loop.py`
- [Runtime events](https://github.com/arktosum/makonome/blob/main/agent/events.py): Structured event stream · Feeds live clients and prompt inspection. · `agent/events.py`
- [Persona & routes](https://github.com/arktosum/makonome/blob/main/config.py): Runtime policy · Defines persona seed, workload model routes, and heartbeat policy. · `config.py`
- [LLM router](https://github.com/arktosum/makonome/blob/main/llm/client.py): Provider client · Selects provider and handles native tool calling per workload. · `llm/client.py`
- [ReAct fallback](https://github.com/arktosum/makonome/blob/main/llm/react_fallback.py): Tool-call adapter · Normalizes textual tool requests into agent control flow. · `llm/react_fallback.py`

### Memory & Autonomy

- [Episodic memory](https://github.com/arktosum/makonome/blob/main/memory/episodic.py): Conversation retrieval · `memory/episodic.py`
- [Curated notes](https://github.com/arktosum/makonome/blob/main/memory/notes.py): Durable identity store · Stores user context, open threads, people, and identity. · `memory/notes.py`
- [Memory curation](https://github.com/arktosum/makonome/blob/main/memory/curator.py): Background writer · Turns meaningful interactions into journal updates. · `memory/curator.py`
- [Memory consolidation](https://github.com/arktosum/makonome/blob/main/memory/consolidator.py): Maintenance job · `memory/consolidator.py`
- [Heartbeat scheduler](https://github.com/arktosum/makonome/blob/main/life/heartbeat.py): Autonomy scheduler · Makes quiet-hour-aware decisions; silence is valid. · `life/heartbeat.py`
- [Proactive wakeup](https://github.com/arktosum/makonome/blob/main/life/wakeup.py): Message generator · `life/wakeup.py`
- [Identity reflection](https://github.com/arktosum/makonome/blob/main/life/reflection.py): Periodic identity writer · Rewrites evolving identity from the journal. · `life/reflection.py`
- [Push delivery](https://github.com/arktosum/makonome/blob/main/life/push.py): Notification gateway · `life/push.py`

### Tools & Infrastructure

- [Tool registry](https://github.com/arktosum/makonome/blob/main/tools/registry.py): Tool boundary · Registers search, finance, system, weather, and memory tools. · `tools/registry.py`
- [Supabase pgvector](https://github.com/arktosum/makonome/blob/main/memory/db.py): Memory database · Persists episodic vectors and supports finance integration. · `memory/db.py`
- **LLM providers**: External APIs · Groq, OpenAI, Anthropic, and compatible endpoints.
- **ntfy**: Push service
- [Render deployment](https://github.com/arktosum/makonome/blob/main/render.yaml): Deployment definition · `render.yaml`

## Connections

- Application entry → Dashboard API: starts
- Application entry → Shared session: initializes
- Telegram bridge → Shared session: owner messages
- Dashboard API → Shared session: chat requests
- Browser dashboard → Dashboard API: HTTP and events
- Flutter client → Mobile API service: uses
- Flutter client → Mobile WebSocket service: uses
- Mobile API service → Dashboard API: HTTP
- Mobile WebSocket service → Dashboard API: WebSocket
- Shared session → Prompt context: conversation
- Prompt context → Agent loop: assembled prompt
- Episodic memory → Prompt context: retrieved memories
- Curated notes → Prompt context: durable context
- Agent loop → LLM router: model iterations
- Persona & routes → LLM router: workload routes
- LLM router → LLM providers: provider calls
- LLM router → ReAct fallback: unsupported tool calls
- Agent loop → Tool registry: tool execution
- Agent loop → Runtime events: emits activity
- Runtime events → Dashboard API: live stream
- Episodic memory → Supabase pgvector: persist and retrieve
- Shared session → Memory curation: meaningful interactions
- Memory curation → Curated notes: journal updates
- Memory consolidation → Episodic memory: maintains
- Heartbeat scheduler → Proactive wakeup: reason to speak
- Proactive wakeup → Agent loop: proactive prompt
- Identity reflection → Curated notes: identity rewrite
- Proactive wakeup → Push delivery: outbound message
- Push delivery → ntfy: notification
- Render deployment → Application entry: deploys
