KeiSeiKit-1.0/_primitives/_rust/kei-buddy/src
Parfii-bot b61b17ea7b feat(kei-buddy): conversational LLM-driven flow + kei-sage retrieval (graph-RAG)
Replaces the rigid FSM after Intro/AskLanguage with a single LLM call per
turn that sees:
  * persona (what's already known — slots not re-asked)
  * recent 10 chat_log messages (history)
  * top-5 kei-sage atoms relevant to user_text (graph-RAG, not embeddings)
  * raw user_text

LLM returns JSON {slot_updates, response_text, done, focus} which drives
the next state + persona patch + reply. No embeddings, no vector store —
kei-sage's FTS5 + Obsidian-style atom graph is the retrieval layer.

New files:
  * src/retrieval.rs (101 LOC) — retrieve_context(chat_log, topics,
    chat_id, query, history_n, atoms_k) -> RetrievalContext
  * src/conversational.rs (157 LOC) — conversational_step
    (state, persona, context, text, extractor, lang) -> StepOutput

Modified:
  * src/serve.rs::run_fsm — branch on state: Intro/AskLanguage still go
    through legacy handle_step (jump-start); everything else routes to
    conversational_step with retrieval context.
  * src/lib.rs — module declarations.

Tests (5 new, 60 total passing):
  * parses_well_formed_llm_response
  * done_true_transitions_to_ready
  * invalid_json_falls_back_gracefully
  * retrieve_returns_empty_on_empty_stores
  * retrieve_finds_seeded_data

Verify:
  * cargo check -p kei-buddy: PASS
  * cargo test -p kei-buddy --lib: 60/0 (was 55, +5)

Why graph-RAG instead of embeddings: kei-sage already in tree (atoms +
edges + BFS + PageRank + FTS5). Explicit edges (message → topic →
contact) beat opaque cosine similarity for personal-assistant memory
where relationships are typed. No sqlite-vec dep, no embedding cost.

NOT deployed yet — needs server rebuild.
2026-05-12 19:00:27 +08:00
..
bin feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
chat_log.rs feat(kei-buddy): wire kei-chat-store — log every user/bot message with FTS5 2026-05-12 15:51:24 +08:00
command_exec.rs feat(contacts): glue sync + Google pagination + Apple discovery & folding 2026-05-12 17:04:15 +08:00
commands.rs feat(contacts): glue sync + Google pagination + Apple discovery & folding 2026-05-12 17:04:15 +08:00
contacts.rs feat(kei-buddy): wire kei-social-store + kei-sage — contacts + topics + FTS5 2026-05-12 16:05:32 +08:00
contacts_sync.rs feat(contacts): glue sync + Google pagination + Apple discovery & folding 2026-05-12 17:04:15 +08:00
conversational.rs feat(kei-buddy): conversational LLM-driven flow + kei-sage retrieval (graph-RAG) 2026-05-12 19:00:27 +08:00
error.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
extractor.rs feat(kei-buddy): wire OpenAiExtractor + chat_id whitelist + env-configurable LLM 2026-05-12 14:49:43 +08:00
lib.rs feat(kei-buddy): conversational LLM-driven flow + kei-sage retrieval (graph-RAG) 2026-05-12 19:00:27 +08:00
machine.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
machine_helpers.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
machine_lang.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
machine_tests.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
machine_tests_topic_research.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
persona_merge.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
retrieval.rs feat(kei-buddy): conversational LLM-driven flow + kei-sage retrieval (graph-RAG) 2026-05-12 19:00:27 +08:00
schema.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
serve.rs feat(kei-buddy): conversational LLM-driven flow + kei-sage retrieval (graph-RAG) 2026-05-12 19:00:27 +08:00
serve_runner.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
serve_telegram.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
state.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
store.rs feat(kei-buddy fleet): 5 atomics — google/apple contacts + classifier + tick + slash-commands 2026-05-12 16:33:58 +08:00
store_ops.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
strings.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00
tick.rs feat(kei-buddy fleet): 5 atomics — google/apple contacts + classifier + tick + slash-commands 2026-05-12 16:33:58 +08:00
topic_classify.rs feat(kei-buddy fleet): 5 atomics — google/apple contacts + classifier + tick + slash-commands 2026-05-12 16:33:58 +08:00
topics.rs feat(kei-buddy): wire kei-social-store + kei-sage — contacts + topics + FTS5 2026-05-12 16:05:32 +08:00
transition.rs feat(kei-buddy): functional MVP — store + state-machine port + serve binary 2026-05-12 14:21:33 +08:00
voice.rs feat(kei-buddy): AskLanguage i18n + real proposeTopicSources + voice handling 2026-05-12 17:49:06 +08:00