Files
sol/CLAUDE.md

3.7 KiB

Sol — Developer Context

Build & Test

cargo build --release                              # debug: cargo build
cargo test                                         # 102 unit tests, no external services needed
cargo build --release --target x86_64-unknown-linux-gnu  # cross-compile for production

Docker (multi-stage, vendored deps):

docker build -t sol .

Production build + deploy via sunbeam CLI:

sunbeam build sol --push --deploy

Private Cargo Registry

mistralai-client is published to Sunbeam's private Gitea cargo registry at src.sunbeam.pt. The crate is vendored into vendor/ for Docker builds. Registry config lives in .cargo/config.toml (not checked in — generated by Dockerfile and locally via cargo vendor vendor/).

Vendor Workflow

After adding/updating deps:

cargo vendor vendor/

This updates the vendored sources. Commit vendor/ changes alongside Cargo.lock.

Key Architecture Notes

  • chat_blocking() workaround: The Mistral client's chat_async holds a std::sync::MutexGuard across .await, making the future !Send. All chat calls use chat_blocking() which runs client.chat() via tokio::task::spawn_blocking.
  • Two response paths: Controlled by agents.use_conversations_api config toggle.
    • Legacy: manual Vec<ChatMessage> assembly, chat completions, tool iteration loop.
    • Conversations API: ConversationRegistry with persistent state (SQLite-backed), agents, function call loop.
  • deno_core sandbox: run_script tool spins up a fresh V8 isolate per invocation with sol.* host API bindings. Timeout via V8 isolate termination. Output truncated to 4096 chars.

K8s Context

  • Namespace: matrix
  • Deployment: sol (Recreate strategy — single replica, SQLite can't share)
  • PVC: sol-data (1Gi RWO) mounted at /data — holds sol.db + matrix-state/
  • ConfigMap: sol-configsol.toml + system_prompt.md (subPath mounts)
  • Secrets: sol-secrets via VaultStaticSecret from OpenBao secret/sol (5 keys: matrix-access-token, matrix-device-id, mistral-api-key, gitea-admin-username, gitea-admin-password)
  • Vault auth: Sol authenticates to OpenBao via K8s auth (role sol-agent, policy sol-agent) for storing user impersonation tokens at secret/sol-tokens/{localpart}/{service}
  • Build target: x86_64-unknown-linux-gnu (Scaleway amd64 server)
  • Base image: gcr.io/distroless/cc-debian12:nonroot

Source Layout

  • src/main.rs — startup, component wiring, backfill, agent recreation + sneeze
  • src/sync.rs — Matrix event handlers, context hint injection for new conversations
  • src/config.rs — TOML config with serde defaults (6 sections: matrix, opensearch, mistral, behavior, agents, services, vault)
  • src/context.rsResponseContext, derive_user_id, localpart
  • src/conversations.rsConversationRegistry (room→conversation mapping, SQLite-backed, reset_all)
  • src/persistence.rs — SQLite store (WAL mode, 3 tables: conversations, agents, service_users)
  • src/agent_ux.rsAgentProgress (reaction lifecycle + thread posting)
  • src/matrix_utils.rs — message extraction, image download, reactions
  • src/brain/ — evaluator (full system prompt context), responder (per-message context headers + memory), personality, conversation manager
  • src/agents/ — registry (instructions hash + automatic recreation), definitions (dynamic delegation)
  • src/sdk/ — vault client (K8s auth), token store (Vault-backed), gitea client (PAT auto-provisioning)
  • src/memory/ — schema, store, extractor
  • src/tools/ — registry (12 tools), search, room_history, room_info, script, devtools (gitea), bridge
  • src/archive/ — schema, indexer