# stffns/vstash architecture

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

- Interactive diagram: https://gitdiagram.com/stffns/vstash
- Repository: https://github.com/stffns/vstash

## Overview

vstash is a local-first document memory and hybrid retrieval product. Its main workflow accepts files, URLs, or text; chunks and embeds content into a SQLite-backed store; then serves queries through vector and keyword retrieval, adaptive fusion, and diversity filtering. The product also exposes CLI, SDK, web, and MCP interfaces, plus Q&A, journal memory, monitoring, and self-supervised embedding refinement. Some subsystem links below follow README documentation or SOURCE INDEX references; unsampled implementation details are not inferred as specific calls.

Main entry points: [`vstash/services/search.py`](https://github.com/stffns/vstash/blob/develop/vstash/services/search.py) (Search service), [`vstash/ingest.py`](https://github.com/stffns/vstash/blob/develop/vstash/ingest.py) (Document ingestion), [`vstash/store/__init__.py`](https://github.com/stffns/vstash/blob/develop/vstash/store/__init__.py) (Document store), [`vstash/cli/_app.py`](https://github.com/stffns/vstash/blob/develop/vstash/cli/_app.py) (CLI commands)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["User interfaces"]
  node_cli["CLI commands<br/>[_app.py]"]
  node_sdk["Python SDK<br/>[memory.py]"]
  node_web["Web UI<br/>[web.py]"]
  node_mcp["MCP server<br/>[mcp.py]"]
  node_integrations["Framework adapter<br/>[langchain.py]"]
end

subgraph group_content["Content and memory"]
  node_ingest["Document ingestion<br/>[ingest.py]"]
  node_chunking["Code splitting<br/>[code_split.py]"]
  node_embedding["Embedding engine<br/>[embed.py]"]
  node_memory["Journal memory<br/>[journal.py]"]
  node_store[("Document store<br/>[__init__.py]")]
  node_store_helpers["Store primitives<br/>[_common.py]"]
end

subgraph group_retrieval["Hybrid retrieval"]
  node_validation["Input validation<br/>[validation.py]"]
  node_search_service["Search service<br/>[search.py]"]
  node_answer["Answer and chat<br/>[ask.py]"]
  node_chat["LLM backends<br/>[chat.py]"]
  node_models["Typed data models<br/>[models.py]"]
end

subgraph group_operations["Tuning and operations"]
  node_config["Configuration<br/>[config.py]"]
  node_store_open["Store setup<br/>[_store_open.py]"]
  node_retraining["Embedding retraining<br/>[retrain.py]"]
  node_retrain_batch["Batch retraining<br/>[retrain_batch.py]"]
  node_profiles["Profiles<br/>[profile.py]"]
  node_watch["File watching<br/>[watch.py]"]
  node_metrics["Search metrics<br/>[metrics.py]"]
  node_benchmarks["Retrieval evaluation<br/>[beir_benchmark.py]"]
end

node_user(("User / agent"))
node_database[("SQLite database")]
node_external_llm(("Optional LLM"))

node_user -->|"invokes"| node_cli
node_user -->|"uses"| node_sdk
node_user -->|"uses"| node_web
node_user -->|"connects"| node_mcp
node_user -.->|"uses"| node_integrations
node_cli -->|"dispatches ingestion"| node_ingest
node_cli -->|"dispatches search"| node_search_service
node_cli -->|"dispatches retraining"| node_retraining
node_sdk -->|"adds documents"| node_ingest
node_sdk -->|"queries"| node_search_service
node_sdk -->|"uses journal"| node_memory
node_web -->|"searches through"| node_search_service
node_web -->|"ingests through"| node_ingest
node_mcp -->|"searches through"| node_search_service
node_mcp -->|"ingests through"| node_ingest
node_mcp -->|"uses journal"| node_memory
node_ingest -->|"splits code"| node_chunking
node_ingest -->|"embeds chunks"| node_embedding
node_ingest -->|"writes documents"| node_store
node_search_service -->|"validates query"| node_validation
node_search_service -->|"embeds query"| node_embedding
node_search_service -->|"retrieves candidates"| node_store
node_search_service -->|"records latency"| node_metrics
node_search_service -->|"returns results"| node_models
node_store -->|"uses primitives"| node_store_helpers
node_store -->|"reads and writes"| node_database
node_store -->|"uses typed records"| node_models
node_answer -->|"gets context"| node_search_service
node_answer -->|"generates answer"| node_chat
node_chat -.->|"calls optional backend"| node_external_llm
node_answer -->|"returns answer"| node_models
node_sdk -->|"asks questions"| node_answer
node_config -->|"configures store"| node_store_open
node_store_open -->|"opens"| node_store
node_store_open -->|"resolves path"| node_profiles
node_retraining -->|"refines model"| node_embedding
node_retraining -->|"reads corpus"| node_store
node_retraining -->|"uses batch training"| node_retrain_batch
node_benchmarks -->|"embeds evaluation data"| node_embedding
node_benchmarks -->|"evaluates retrieval"| node_store
node_watch -.->|"auto-ingests changes"| node_ingest
node_cli -->|"starts watching"| node_watch

click node_cli "https://github.com/stffns/vstash/blob/develop/vstash/cli/_app.py"
click node_sdk "https://github.com/stffns/vstash/blob/develop/vstash/memory.py"
click node_web "https://github.com/stffns/vstash/blob/develop/vstash/web.py"
click node_mcp "https://github.com/stffns/vstash/blob/develop/vstash/mcp.py"
click node_integrations "https://github.com/stffns/vstash/blob/develop/vstash/langchain.py"
click node_ingest "https://github.com/stffns/vstash/blob/develop/vstash/ingest.py"
click node_chunking "https://github.com/stffns/vstash/blob/develop/vstash/code_split.py"
click node_embedding "https://github.com/stffns/vstash/blob/develop/vstash/embed.py"
click node_memory "https://github.com/stffns/vstash/blob/develop/vstash/journal.py"
click node_store "https://github.com/stffns/vstash/blob/develop/vstash/store/__init__.py"
click node_store_helpers "https://github.com/stffns/vstash/blob/develop/vstash/store/_common.py"
click node_validation "https://github.com/stffns/vstash/blob/develop/vstash/validation.py"
click node_search_service "https://github.com/stffns/vstash/blob/develop/vstash/services/search.py"
click node_answer "https://github.com/stffns/vstash/blob/develop/vstash/services/ask.py"
click node_chat "https://github.com/stffns/vstash/blob/develop/vstash/chat.py"
click node_models "https://github.com/stffns/vstash/blob/develop/vstash/models.py"
click node_config "https://github.com/stffns/vstash/blob/develop/vstash/config.py"
click node_store_open "https://github.com/stffns/vstash/blob/develop/vstash/_store_open.py"
click node_retraining "https://github.com/stffns/vstash/blob/develop/vstash/retrain.py"
click node_retrain_batch "https://github.com/stffns/vstash/blob/develop/vstash/retrain_batch.py"
click node_profiles "https://github.com/stffns/vstash/blob/develop/vstash/profile.py"
click node_watch "https://github.com/stffns/vstash/blob/develop/vstash/watch.py"
click node_metrics "https://github.com/stffns/vstash/blob/develop/vstash/metrics.py"
click node_benchmarks "https://github.com/stffns/vstash/blob/develop/experiments/beir_benchmark.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_cli,node_sdk,node_web,node_mcp,node_integrations,node_user toneBlue
class node_ingest,node_chunking,node_embedding,node_memory,node_store,node_store_helpers,node_database toneAmber
class node_validation,node_search_service,node_answer,node_chat,node_models toneMint
class node_config,node_store_open,node_retraining,node_retrain_batch,node_profiles,node_watch,node_metrics,node_benchmarks toneRose
class node_external_llm toneIndigo
```

## Components

### User interfaces

- [CLI commands](https://github.com/stffns/vstash/blob/develop/vstash/cli/_app.py): `vstash/cli/_app.py`
- [Python SDK](https://github.com/stffns/vstash/blob/develop/vstash/memory.py): `vstash/memory.py`
- [Web UI](https://github.com/stffns/vstash/blob/develop/vstash/web.py): `vstash/web.py`
- [MCP server](https://github.com/stffns/vstash/blob/develop/vstash/mcp.py): `vstash/mcp.py`
- [Framework adapter](https://github.com/stffns/vstash/blob/develop/vstash/langchain.py): `vstash/langchain.py`

### Content and memory

- [Document ingestion](https://github.com/stffns/vstash/blob/develop/vstash/ingest.py): `vstash/ingest.py`
- [Code splitting](https://github.com/stffns/vstash/blob/develop/vstash/code_split.py): `vstash/code_split.py`
- [Embedding engine](https://github.com/stffns/vstash/blob/develop/vstash/embed.py): `vstash/embed.py`
- [Journal memory](https://github.com/stffns/vstash/blob/develop/vstash/journal.py): `vstash/journal.py`
- [Document store](https://github.com/stffns/vstash/blob/develop/vstash/store/__init__.py): `vstash/store/__init__.py`
- [Store primitives](https://github.com/stffns/vstash/blob/develop/vstash/store/_common.py): `vstash/store/_common.py`

### Hybrid retrieval

- [Input validation](https://github.com/stffns/vstash/blob/develop/vstash/validation.py): `vstash/validation.py`
- [Search service](https://github.com/stffns/vstash/blob/develop/vstash/services/search.py): `vstash/services/search.py`
- [Answer and chat](https://github.com/stffns/vstash/blob/develop/vstash/services/ask.py): `vstash/services/ask.py`
- [LLM backends](https://github.com/stffns/vstash/blob/develop/vstash/chat.py): `vstash/chat.py`
- [Typed data models](https://github.com/stffns/vstash/blob/develop/vstash/models.py): `vstash/models.py`

### Tuning and operations

- [Configuration](https://github.com/stffns/vstash/blob/develop/vstash/config.py): `vstash/config.py`
- [Store setup](https://github.com/stffns/vstash/blob/develop/vstash/_store_open.py): `vstash/_store_open.py`
- [Embedding retraining](https://github.com/stffns/vstash/blob/develop/vstash/retrain.py): `vstash/retrain.py`
- [Batch retraining](https://github.com/stffns/vstash/blob/develop/vstash/retrain_batch.py): `vstash/retrain_batch.py`
- [Profiles](https://github.com/stffns/vstash/blob/develop/vstash/profile.py): `vstash/profile.py`
- [File watching](https://github.com/stffns/vstash/blob/develop/vstash/watch.py): `vstash/watch.py`
- [Search metrics](https://github.com/stffns/vstash/blob/develop/vstash/metrics.py): `vstash/metrics.py`
- [Retrieval evaluation](https://github.com/stffns/vstash/blob/develop/experiments/beir_benchmark.py): `experiments/beir_benchmark.py`

### Other components

- **User / agent**
- **SQLite database**
- **Optional LLM**

## Connections

- User / agent → CLI commands: invokes
- User / agent → Python SDK: uses
- User / agent → Web UI: uses
- User / agent → MCP server: connects
- User / agent → Framework adapter: uses
- CLI commands → Document ingestion: dispatches ingestion (evidence: `vstash/cli/_ingest.py`)
- CLI commands → Search service: dispatches search (evidence: `vstash/cli/_search.py`)
- CLI commands → Embedding retraining: dispatches retraining (evidence: `vstash/cli/_retrain.py`)
- Python SDK → Document ingestion: adds documents (evidence: `vstash/memory.py`)
- Python SDK → Search service: queries (evidence: `vstash/memory.py`)
- Python SDK → Journal memory: uses journal (evidence: `vstash/memory.py`)
- Web UI → Search service: searches through (evidence: `vstash/web.py`)
- Web UI → Document ingestion: ingests through (evidence: `vstash/web.py`)
- MCP server → Search service: searches through (evidence: `vstash/mcp.py`)
- MCP server → Document ingestion: ingests through (evidence: `vstash/mcp.py`)
- MCP server → Journal memory: uses journal (evidence: `vstash/mcp.py`)
- Document ingestion → Code splitting: splits code (evidence: `vstash/ingest.py`)
- Document ingestion → Embedding engine: embeds chunks (evidence: `vstash/ingest.py`)
- Document ingestion → Document store: writes documents (evidence: `vstash/ingest.py`)
- Search service → Input validation: validates query (evidence: `vstash/services/search.py`)
- Search service → Embedding engine: embeds query (evidence: `vstash/services/search.py`)
- Search service → Document store: retrieves candidates (evidence: `vstash/services/search.py`)
- Search service → Search metrics: records latency (evidence: `vstash/services/search.py`)
- Search service → Typed data models: returns results (evidence: `vstash/services/search.py`)
- Document store → Store primitives: uses primitives (evidence: `vstash/store/__init__.py`)
- Document store → SQLite database: reads and writes
- Document store → Typed data models: uses typed records (evidence: `vstash/store/__init__.py`)
- Answer and chat → Search service: gets context (evidence: `vstash/services/ask.py`)
- Answer and chat → LLM backends: generates answer (evidence: `vstash/services/ask.py`)
- LLM backends → Optional LLM: calls optional backend
- Answer and chat → Typed data models: returns answer (evidence: `vstash/services/ask.py`)
- Python SDK → Answer and chat: asks questions (evidence: `vstash/memory.py`)
- Configuration → Store setup: configures store (evidence: `vstash/_store_open.py`)
- Store setup → Document store: opens (evidence: `vstash/_store_open.py`)
- Store setup → Profiles: resolves path (evidence: `vstash/_store_open.py`)
- Embedding retraining → Embedding engine: refines model (evidence: `vstash/retrain.py`)
- Embedding retraining → Document store: reads corpus (evidence: `vstash/retrain.py`)
- Embedding retraining → Batch retraining: uses batch training (evidence: `vstash/retrain.py`)
- Retrieval evaluation → Embedding engine: embeds evaluation data (evidence: `experiments/beir_benchmark.py`)
- Retrieval evaluation → Document store: evaluates retrieval (evidence: `experiments/beir_benchmark.py`)
- File watching → Document ingestion: auto-ingests changes
- CLI commands → File watching: starts watching (evidence: `vstash/cli/_manage.py`)
