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.
55 lines
1.8 KiB
TOML
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>"]
|