# ezzuldinst/askme-bot architecture

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

- Interactive diagram: https://gitdiagram.com/ezzuldinst/askme-bot
- Repository: https://github.com/ezzuldinst/askme-bot

## Overview

#### Purpose and Entry Points
AskMe is a Rust long-running bot for the Things social network. It detects @AskMe mentions, gathers thread/media context, asks Gemini for a response, and posts a threaded reply. The production entry point is `src/main.rs`; a developer dry-run path accepts `--test-post <id>` and can optionally publish with `--post`.

#### Runtime Orchestration
`src/main.rs` owns startup: loads environment credentials, initializes Things, Gemini, and optional Qdrant clients, then drives post handling. The bot requires Things and Gemini credentials; Qdrant initialization is non-fatal so processing continues without persistent memory. Domain structures passed across stages are defined in `src/models.rs` and `src/entities.rs`.

#### Things Network Boundary
`src/things_client.rs` encapsulates authentication to Things (email/password with OTP) and network operations needed to read posts, replies, and attached media, as well as publish the bot’s threaded response. This isolates the social-network API and its post/thread identifiers from orchestration and AI logic.

#### Context Construction and Conversation Semantics
The bot treats the mentioned post and its reply ancestry as conversational context. It limits included thread history through `CONTEXT_DEPTH_LIMIT`, enabling follow-up questions to retain prior discussion. `src/entities.rs` represents Things-side content/entities and supports output-oriented entity handling, while `src/models.rs` provides application-level message/request data structures.

#### Gemini Generation and Multimodal AI
`src/gemini_client.rs` is the boundary for Gemini chat and embedding APIs. It receives constructed conversation context plus available image/video material and returns the raw model response used for the Things reply. Gemini also supplies embeddings for semantic memory; its API key and model choices are configured by `GEMINI_API_KEY`, `EMBEDDING_MODEL`, and embedding dimension/batch settings.

#### Persistent Memory and Idempotency
`src/qdrant_client.rs` manages optional Qdrant-backed storage and retrieval. It supports semantic recall of prior thread content and persistent “already handled” state, preventing duplicate replies across restarts or network retries. `src/qdrant_models.rs` defines the Qdrant collection payload/vector representations. If Qdrant is unavailable, the bot degrades to stateless processing: no cross-restart deduplication and no recalled context.

#### Infrastructure and Operational Dependencies
The executable runs as a Cargo/Rust process (`Cargo.toml`) and calls external Things, Gemini, and Qdrant services. Qdrant is expected over local gRPC at port 6334 by default and can be started through `scripts/start_qdrant.sh`. Runtime secrets and endpoint/model tuning are supplied through environment variables, with example values in `.env.example`.

Main entry points: [`src/main.rs`](https://github.com/ezzuldinst/askme-bot/blob/master/src/main.rs) (Startup & orchestration), [`src/gemini_client.rs`](https://github.com/ezzuldinst/askme-bot/blob/master/src/gemini_client.rs) (Gemini client), [`src/things_client.rs`](https://github.com/ezzuldinst/askme-bot/blob/master/src/things_client.rs) (Things client), [`src/qdrant_client.rs`](https://github.com/ezzuldinst/askme-bot/blob/master/src/qdrant_client.rs) (Qdrant client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Bot Runtime"]
  node_cargo{{"Cargo process<br/>Rust executable<br/>[Cargo.toml]"}}
  node_main["Startup &amp; orchestration<br/>Rust entry point<br/>[main.rs]"]
  node_models["Application models<br/>domain data<br/>[models.rs]"]
  node_things_client["Things client<br/>API adapter<br/>[things_client.rs]"]
  node_env_example["Environment settings<br/>runtime configuration<br/>[.env.example]"]
end

subgraph group_context["Context &amp; AI"]
  node_entities["Things entities<br/>content entities<br/>[entities.rs]"]
  node_thread_context["Thread context<br/>conversation builder"]
  node_media_context["Media context<br/>multimodal input"]
  node_gemini_client["Gemini client<br/>AI API adapter<br/>[gemini_client.rs]"]
  node_raw_response["Model response<br/>generated reply"]
end

subgraph group_memory["Persistent Memory"]
  node_qdrant_client["Qdrant client<br/>memory adapter<br/>[qdrant_client.rs]"]
  node_qdrant_models["Qdrant models<br/>storage schema<br/>[qdrant_models.rs]"]
end

subgraph group_external["External Services"]
  node_things_service(("Things<br/>social network"))
  node_gemini_service(("Gemini<br/>AI service"))
  node_qdrant_service[("Qdrant<br/>vector database")]
  node_qdrant_script["Qdrant launcher<br/>operations script<br/>[start_qdrant.sh]"]
end

node_cargo -->|"runs"| node_main
node_env_example -.->|"documents env"| node_main
node_main -->|"initializes"| node_things_client
node_main -->|"initializes"| node_gemini_client
node_main -.->|"optionally initializes"| node_qdrant_client
node_main -->|"uses"| node_models
node_main -->|"uses"| node_entities
node_things_client -->|"authenticates and calls"| node_things_service
node_things_client -->|"post and ancestry"| node_thread_context
node_things_client -->|"attached media"| node_media_context
node_thread_context -->|"conversation context"| node_gemini_client
node_media_context -->|"image/video context"| node_gemini_client
node_qdrant_client -.->|"recalled context"| node_thread_context
node_gemini_client -->|"chat and embeddings"| node_gemini_service
node_gemini_client -->|"generates"| node_raw_response
node_raw_response -->|"threaded reply"| node_things_client
node_gemini_client -.->|"embeddings"| node_qdrant_client
node_qdrant_client -->|"stores"| node_qdrant_models
node_qdrant_client -.->|"recall and deduplicate"| node_qdrant_service
node_qdrant_script -->|"starts"| node_qdrant_service

click node_cargo "https://github.com/ezzuldinst/askme-bot/blob/master/Cargo.toml"
click node_main "https://github.com/ezzuldinst/askme-bot/blob/master/src/main.rs"
click node_models "https://github.com/ezzuldinst/askme-bot/blob/master/src/models.rs"
click node_entities "https://github.com/ezzuldinst/askme-bot/blob/master/src/entities.rs"
click node_things_client "https://github.com/ezzuldinst/askme-bot/blob/master/src/things_client.rs"
click node_gemini_client "https://github.com/ezzuldinst/askme-bot/blob/master/src/gemini_client.rs"
click node_qdrant_client "https://github.com/ezzuldinst/askme-bot/blob/master/src/qdrant_client.rs"
click node_qdrant_models "https://github.com/ezzuldinst/askme-bot/blob/master/src/qdrant_models.rs"
click node_qdrant_script "https://github.com/ezzuldinst/askme-bot/blob/master/scripts/start_qdrant.sh"
click node_env_example "https://github.com/ezzuldinst/askme-bot/blob/master/.env.example"

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_cargo,node_main,node_models,node_things_client,node_env_example toneBlue
class node_entities,node_thread_context,node_media_context,node_gemini_client,node_raw_response toneAmber
class node_qdrant_client,node_qdrant_models toneMint
class node_things_service,node_gemini_service,node_qdrant_service,node_qdrant_script toneRose
```

## Components

### Bot Runtime

- [Cargo process](https://github.com/ezzuldinst/askme-bot/blob/master/Cargo.toml): Rust executable · `Cargo.toml`
- [Startup & orchestration](https://github.com/ezzuldinst/askme-bot/blob/master/src/main.rs): Rust entry point · Initializes clients and drives normal or dry-run post handling. · `src/main.rs`
- [Application models](https://github.com/ezzuldinst/askme-bot/blob/master/src/models.rs): domain data · `src/models.rs`
- [Things client](https://github.com/ezzuldinst/askme-bot/blob/master/src/things_client.rs): API adapter · Authenticates, reads threads/media, and publishes replies. · `src/things_client.rs`
- [Environment settings](https://github.com/ezzuldinst/askme-bot/blob/master/.env.example): runtime configuration · Documents credentials, endpoint, and model tuning variables. · `.env.example`

### Context & AI

- [Things entities](https://github.com/ezzuldinst/askme-bot/blob/master/src/entities.rs): content entities · Represents Things content and output-oriented entities. · `src/entities.rs`
- **Thread context**: conversation builder · Builds bounded reply ancestry using CONTEXT_DEPTH_LIMIT.
- **Media context**: multimodal input · Collects available images and videos for generation.
- [Gemini client](https://github.com/ezzuldinst/askme-bot/blob/master/src/gemini_client.rs): AI API adapter · Generates replies and embeddings. · `src/gemini_client.rs`
- **Model response**: generated reply

### Persistent Memory

- [Qdrant client](https://github.com/ezzuldinst/askme-bot/blob/master/src/qdrant_client.rs): memory adapter · Optional semantic recall and handled-state persistence. · `src/qdrant_client.rs`
- [Qdrant models](https://github.com/ezzuldinst/askme-bot/blob/master/src/qdrant_models.rs): storage schema · `src/qdrant_models.rs`

### External Services

- **Things**: social network
- **Gemini**: AI service
- **Qdrant**: vector database · Optional local gRPC service on port 6334 by default.
- [Qdrant launcher](https://github.com/ezzuldinst/askme-bot/blob/master/scripts/start_qdrant.sh): operations script · `scripts/start_qdrant.sh`

## Connections

- Cargo process → Startup & orchestration: runs
- Environment settings → Startup & orchestration: documents env
- Startup & orchestration → Things client: initializes
- Startup & orchestration → Gemini client: initializes
- Startup & orchestration → Qdrant client: optionally initializes
- Startup & orchestration → Application models: uses
- Startup & orchestration → Things entities: uses
- Things client → Things: authenticates and calls
- Things client → Thread context: post and ancestry
- Things client → Media context: attached media
- Thread context → Gemini client: conversation context
- Media context → Gemini client: image/video context
- Qdrant client → Thread context: recalled context
- Gemini client → Gemini: chat and embeddings
- Gemini client → Model response: generates
- Model response → Things client: threaded reply
- Gemini client → Qdrant client: embeddings
- Qdrant client → Qdrant models: stores
- Qdrant client → Qdrant: recall and deduplicate
- Qdrant launcher → Qdrant: starts
