Files
Memoh/AGENTS.md
T
BBQ bc374fe8cd refactor: content-addressed assets, cross-channel multimodal, infra simplification (#63)
* refactor(attachment): multimodal attachment refactor with snapshot schema and storage layer

- Add snapshot schema migration (0008) and update init/versions/snapshots
- Add internal/attachment and internal/channel normalize for unified attachment handling
- Move containerfs provider from internal/media to internal/storage
- Update agent types, channel adapters (Telegram/Feishu), inbound and handlers
- Add containerd snapshot lineage and local_channel tests
- Regenerate sqlc, swagger and SDK

* refactor(media): content-addressed asset system with unified naming

- Replace asset_id foreign key with content_hash as sole identifier
  for bot_history_message_assets (pure soft-link model)
- Remove mime, size_bytes, storage_key from DB; derive at read time
  via media.Resolve from actual storage
- Merge migrations 0008/0009 into single 0008; keep 0001 as canonical schema
- Add Docker initdb script for deterministic migration execution order
- Fix cross-channel real-time image display (Telegram → WebUI SSE)
- Fix message disappearing on refresh (null assets fallback)
- Fix file icon instead of image preview (mime derivation from storage)
- Unify AssetID → ContentHash naming across Go, Agent, and Frontend
- Change storage key prefix from 4-char to 2-char for directory sharding
- Add server-entrypoint.sh for Docker deployment migration handling

* refactor(infra): embedded migrations, Docker simplification, and config consolidation

- Embed SQL migrations into Go binary, removing shell-based migration scripts
- Consolidate config files into conf/ directory (app.example.toml, app.docker.toml, app.dev.toml)
- Simplify Docker setup: remove initdb.d scripts, streamline nginx config and entrypoint
- Remove legacy CLI, feishu-echo commands, and obsolete incremental migration files
- Update install script and docs to require sudo for one-click install
- Add mise tasks for dev environment orchestration

* chore: recover migrations

---------

Co-authored-by: Acbox <acbox0328@gmail.com>
2026-02-19 00:20:27 +08:00

9.3 KiB

AGENTS.md

Project Overview

Memoh is a multi-member, structured long-memory, containerized AI agent system platform. Users can create AI bots and chat with them via Telegram, Discord, Lark (Feishu), and more. Every bot has an independent container and memory system, allowing it to edit files, execute commands, and build itself — providing a secure, flexible, and scalable solution for multi-bot management.

Architecture Overview

The system consists of three core services:

Service Tech Stack Port Description
Server (Backend) Go + Echo 8080 Main service: REST API, auth, database, container management
Agent Gateway Bun + Elysia 8081 AI chat gateway: handles chat requests and tool execution
Web (Frontend) Vue 3 + Vite 8082 Management UI: visual configuration for Bots, Models, Channels, etc.

Infrastructure dependencies:

  • PostgreSQL — Relational data storage
  • Qdrant — Vector database for memory semantic search
  • Containerd — Container runtime providing isolated environments per bot

Tech Stack

Backend (Go)

  • Framework: Echo (HTTP)
  • Dependency Injection: Uber FX
  • Database Driver: pgx/v5
  • Code Generation: sqlc (SQL → Go)
  • API Docs: Swagger/OpenAPI (swaggo)
  • Containers: containerd v2

Agent Gateway (TypeScript)

  • Runtime: Bun
  • Framework: Elysia

Frontend (TypeScript)

  • Framework: Vue 3 (Composition API)
  • Build Tool: Vite
  • State Management: Pinia + Pinia Colada
  • UI: Tailwind CSS + custom component library (@memoh/ui) + Reka UI
  • Package Manager: pnpm monorepo

Tooling

  • Task Runner: mise
  • Package Managers: pnpm (frontend monorepo), Go modules (backend)

Project Structure

Memoh/
├── cmd/                        # Go application entry points
│   ├── agent/                  #   Main backend server (main.go)
│   ├── mcp/                    #   MCP server binary
│   └── cli/                    #   CLI tool
├── internal/                   # Go backend core code
│   ├── handlers/               #   HTTP handlers (REST API)
│   ├── services/               #   Business logic services
│   ├── db/                     #   Database layer
│   │   └── sqlc/               #   ⚠️ Auto-generated by sqlc — DO NOT modify manually
│   ├── channel/                #   Channel adapters (Telegram, Feishu, Local)
│   ├── memory/                 #   Memory / embedding system
│   ├── mcp/                    #   MCP protocol implementation
│   ├── conversation/           #   Conversation flow management
│   ├── bots/                   #   Bot management
│   └── containerd/             #   Container management
├── agent/                      # Agent Gateway (Bun/Elysia)
│   └── src/
├── packages/                   # Frontend monorepo
│   ├── web/                    #   Main web app (Vue 3)
│   ├── ui/                     #   Shared UI component library
│   ├── sdk/                    #   TypeScript SDK (auto-generated from OpenAPI)
│   ├── cli/                    #   TypeScript CLI
│   └── config/                 #   Shared configuration utilities
├── db/                         # Database
│   ├── migrations/             #   SQL migration files
│   └── queries/                #   SQL query files (sqlc input)
├── conf/                       # Configuration templates (app.example.toml, app.dev.toml, app.docker.toml)
├── devenv/                     # Development environment (docker-compose for local infra)
├── docker/                     # Docker build & runtime (Dockerfiles, entrypoints, nginx.conf)
├── docs/                       # Documentation site
├── scripts/                    # Utility scripts
├── docker-compose.yml          # Docker Compose orchestration (production)
├── mise.toml                   # mise tasks and tool version definitions
└── sqlc.yaml                   # sqlc code generation config

Development Guide

Prerequisites

  1. Install mise
  2. Install toolchains and dependencies: mise install
  3. Initialize the project: mise run setup
  4. Start the dev environment: mise run dev

Common Commands

Command Description
mise run dev Start the full dev environment (backend + agent gateway + frontend)
mise run setup Initialize dev environment (sqlc gen + DB migration + dependency install)
mise run sqlc-generate Regenerate Go code after modifying SQL files
mise run swagger-generate Generate Swagger documentation
mise run sdk-generate Generate TypeScript SDK (depends on swagger-generate)
mise run db-up Initialize and migrate the database
mise run db-down Drop the database
mise run //agent:dev Start Agent Gateway only
mise run //cmd/agent:start Start the backend server only
mise run //packages/web:dev Start the frontend dev server only

Docker Deployment

docker compose up -d        # Start all services
# Visit http://localhost:8082

Key Development Rules

Database, sqlc & Migrations

  1. SQL queries are defined in db/queries/*.sql.
  2. All Go files under internal/db/sqlc/ are auto-generated by sqlc. DO NOT modify them manually.
  3. After modifying any SQL files (migrations or queries), run mise run sqlc-generate to update the generated Go code.

Migration Rules

Migrations live in db/migrations/ and follow a dual-update convention:

  • 0001_init.up.sql is the canonical full schema. It always contains the complete, up-to-date database definition (all tables, indexes, constraints, etc.). When adding schema changes, you must also update 0001_init.up.sql to reflect the final state.
  • Incremental migration files (0002_, 0003_, ...) contain only the diff needed to upgrade an existing database. They exist for environments that already have the schema and need to apply only the delta.
  • Both must be kept in sync: every schema change requires updating 0001_init.up.sql AND creating a new incremental migration file.
  • Naming: {NNNN}_{description}.up.sql and {NNNN}_{description}.down.sql, where {NNNN} is a zero-padded sequential number (e.g., 0005). Always use the next available number.
  • Paired files: Every incremental migration must have both an .up.sql (apply) and a .down.sql (rollback) file.
  • Header comment: Each file should start with a comment indicating the migration name and a brief description:
    -- 0005_add_feature_x
    -- Add feature_x column to bots table for ...
    
  • Idempotent DDL: Use IF NOT EXISTS / IF EXISTS guards (e.g., CREATE TABLE IF NOT EXISTS, ADD COLUMN IF NOT EXISTS, DROP TABLE IF EXISTS) so migrations are safe to re-run.
  • Down migration must fully reverse up: The .down.sql must cleanly undo everything its .up.sql does, in reverse order.
  • After creating or modifying migrations, run mise run sqlc-generate to regenerate the Go code, then mise run db-up to apply.

API Development Workflow

  1. Write handlers in internal/handlers/ with swaggo annotations.
  2. Run mise run swagger-generate to update the OpenAPI docs.
  3. Run mise run sdk-generate to update the frontend TypeScript SDK (packages/sdk/).
  4. The frontend calls APIs via the auto-generated @memoh/sdk.

Frontend Development

  • Use Vue 3 Composition API with <script setup> style.
  • Shared components belong in packages/ui/.
  • API calls use the auto-generated @memoh/sdk.
  • State management uses Pinia; data fetching uses Pinia Colada.

Container Management

  • In Docker deployment, containerd runs inside the server container.
  • Each bot has its own isolated container instance.

Database Tables

Table Description
users User accounts (admin/member roles)
channel_identities Unified identity system (cross-platform)
bots Bot definitions with model references
bot_members Bot membership (owner/admin/member)
bot_channel_configs Per-bot channel configurations
bot_channel_routes Conversation route mapping
bot_history_messages Unified message history
llm_providers LLM provider configurations
models Model definitions (chat/embedding types)
mcp_connections MCP connection configurations
containers Bot container instances
snapshots Container snapshots
schedule Scheduled tasks (cron)
subagents Sub-agent definitions
search_providers Search engine provider configurations

Configuration

The main configuration file is config.toml (copied from conf/app.example.toml or conf/app.dev.toml for development), containing:

  • [server] — HTTP listen address
  • [admin] — Admin account credentials
  • [auth] — JWT authentication settings
  • [containerd] — Container runtime socket path
  • [mcp] — MCP image and data configuration
  • [postgres] — PostgreSQL connection
  • [qdrant] — Qdrant vector database connection
  • [agent_gateway] — Agent Gateway address
  • [web] — Web frontend address
  • [brave] — Brave Search API configuration