First atom of the kei-buddy phase-1 plan. Pure scaffold — no business
logic; that comes in follow-up commits.
Crate location: _primitives/_rust/kei-buddy/
LOC: 262 across 7 files (largest src/state.rs 85 LOC; all <200).
Contents:
* src/state.rs — OnboardState enum with 11 variants matching the
TS state-machine in keisei-marketplace/src/lib/keibuddy/chat-onboard.ts:
Intro, AskName, AskTone, AskInterests, AskHobbies, TopicSpecifics,
TopicNowLater, TopicResearch, TopicSources, AskSchedule, Ready.
serde(rename_all = "snake_case") matches TS naming.
`next()` is a stub (returns self.clone(); real transitions TBD).
* src/transition.rs — TransitionInput struct (user_text +
extracted_fields json::Value). Struct only, no extraction yet.
* src/error.rs — BuddyError enum via thiserror (StateMachine /
Memory / Transport). No From impls yet.
* src/lib.rs — module declarations + re-exports.
* src/bin/kei-buddy.rs — minimal `kei-buddy serve` clap subcommand,
currently prints "not yet implemented".
* Cargo.toml — workspace member, maturity = "concept".
* README.md — crate-level README, roadmap of 4 follow-up bullets.
Workspace registration: _primitives/_rust/Cargo.toml members list
gains "kei-buddy". Lockfile updated accordingly.
Verify-before-commit (RULE 0.13 §):
* cargo check --offline -p kei-buddy: PASS
* cargo test --offline -p kei-buddy --lib: 1 passed / 0 failed
(state::tests::all_variants_serde_roundtrip)
* cargo check --workspace --offline: PASS
* STATUS-TRUTH MARKER from agent: shipped=scaffolding, stubs=1
(state.rs:50 next() returns self.clone(), expected for scaffold)
Follow-up tasks (tracked in TaskList):
* Port handleStep transition logic from chat-onboard.ts
* LLM extract via kei-cortex
* Memory binding via kei-memory-sqlite
* Telegram webhook driver (new crate kei-telegram-webhook)
* kei-tts trait + 4 backends (ElevenLabs / OpenAI / Google / Piper)
* kei-stt trait + 3 backends (Whisper local / Deepgram / OpenAI API)
37 lines
1.5 KiB
Markdown
37 lines
1.5 KiB
Markdown
# kei-buddy
|
|
|
|
**Maturity:** concept / scaffold — no business logic yet.
|
|
|
|
## Purpose
|
|
|
|
`kei-buddy` is the runtime crate that composes existing KeiSeiKit
|
|
primitives (`kei-pet`, `kei-memory-sqlite`, `kei-cortex`,
|
|
`kei-notify-telegram`) into a personal-assistant Telegram bot called
|
|
KeiBuddy.
|
|
|
|
On first contact the bot walks the user through an 11-state onboarding
|
|
flow: name, tone, interests, hobbies, per-topic decomposition (specifics
|
|
→ now-or-later → research preference → source selection), and digest
|
|
schedule. After onboarding the bot enters ongoing conversation mode,
|
|
drawing on the stored persona and memory.
|
|
|
|
This crate provides the state-machine enum and skeleton driver. The
|
|
onboarding FSM is ported from
|
|
`keisei-marketplace/src/lib/keibuddy/chat-onboard.ts`.
|
|
|
|
## Status
|
|
|
|
Scaffold only. The `OnboardState` enum and `TransitionInput` struct are
|
|
defined. All transition logic is stubbed (`next()` returns `self.clone()`).
|
|
The binary entry point prints a placeholder message and exits 0.
|
|
|
|
## Roadmap
|
|
|
|
- **State-machine transition logic** — port `handleStep` from
|
|
`chat-onboard.ts`; wire per-state LLM-extract calls through kei-cortex.
|
|
- **Memory binding** — persist scratchpad and finalised persona via
|
|
kei-memory-sqlite; implement `getChatState` / `setChatStep` equivalents.
|
|
- **Persona binding** — read persona manifest via `kei-pet`; apply tone
|
|
overlay to outgoing replies.
|
|
- **Transport binding** — wire kei-notify-telegram for outbound messages;
|
|
add a real Telegram webhook server (or kei-gateway adapter) for inbound.
|