KeiSeiKit-1.0/_primitives/_rust/kei-buddy/Cargo.toml
Parfii-bot fb7c1bf859 feat(kei-buddy): wire kei-chat-store — log every user/bot message with FTS5
After-Ready conversation was going to /dev/null. With this change every
inbound Telegram text + every bot response is persisted to a SQLite +
FTS5 archive via the existing kei-chat-store primitive (no new crate).

Each Telegram chat_id maps 1:1 to a kei-chat-store session
(project="kei-buddy", title="tg-<chat_id>", model="telegram"). Cache
prevents per-message session lookups.

New file:
  * src/chat_log.rs (198 LOC) — ChatLog adapter wrapping
    kei_chat_store::Store + a chat_id→session_id Mutex cache.
    API: from_path / from_memory / ensure_session / log_user /
    log_bot / search(query, chat_id?, limit). Errors map to
    BuddyError::Memory and never propagate from on_event — chat-log
    failure is logged but does not block the conversation.

Modified:
  * Cargo.toml — kei-chat-store path dep added.
  * src/lib.rs — pub mod chat_log + re-export ChatLog.
  * src/serve.rs — BuddyContext gains Arc<ChatLog>;
    process_text calls log_user before handle_step + log_bot after
    send_message; ServeConfig gains chat_log_db_path.
  * src/bin/kei-buddy.rs — KEI_BUDDY_CHAT_LOG_PATH env
    (default ./kei-buddy-chat.db); migrate subcommand applies the
    chat-store schema alongside buddy_state schema.

Tests (3 new in src/chat_log.rs, all pass):
  * log_user_creates_session_and_message
  * log_bot_uses_same_session_as_log_user
  * different_chats_get_different_sessions

Verify-before-commit:
  * cargo check -p kei-buddy (default): PASS
  * cargo check -p kei-buddy --features extractor-openai: PASS
  * cargo test -p kei-buddy --lib: 23 passed / 0 failed
    (was 20 before this commit; 3 new ChatLog tests)

NOT deployed — user is in active conversation with the live bot.
Will roll forward when user signals readiness.
2026-05-12 15:51:24 +08:00

55 lines
1.8 KiB
TOML

[package]
name = "kei-buddy"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
description = "KeiBuddy personal-assistant Telegram bot — onboarding state-machine + skeleton driver. Concept-level scaffold."
authors.workspace = true
license.workspace = true
[[bin]]
name = "kei-buddy"
path = "src/bin/kei-buddy.rs"
[lib]
name = "kei_buddy"
path = "src/lib.rs"
[dependencies]
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "net"] }
tracing = "0.1"
clap = { workspace = true, features = ["derive"] }
async-trait = { workspace = true }
rusqlite = { workspace = true }
reqwest = { workspace = true }
anyhow = { workspace = true }
kei-memory-sqlite = { path = "../kei-memory-sqlite" }
kei-chat-store = { path = "../kei-chat-store" }
chrono = { workspace = true }
# serve feature deps
axum = { version = "0.7", features = ["json", "http1", "tokio"], optional = true }
kei-telegram-webhook = { path = "../kei-telegram-webhook", optional = true }
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
[dev-dependencies]
wiremock = { workspace = true }
tokio = { workspace = true }
[features]
default = ["serve"]
# HTTP server — axum router + webhook handler + Telegram send_message.
serve = ["axum", "kei-telegram-webhook", "tracing-subscriber"]
# Enables OpenAiExtractor — real HTTP to LiteLLM proxy using reqwest.
# Off by default; tests use MockExtractor which has no extra deps.
extractor-openai = []
# future: pulls in kei-notify-telegram for real Telegram transport
telegram = []
[package.metadata.keisei]
maturity = "concept"
description = "KeiBuddy personal-assistant: onboarding FSM + bot driver scaffold"
authors = ["Denis Parfionovich <parfionovich@keilab.io>"]