Zenii Process Flows
Table of Contents
- Chat Request Flow
- Startup Sequence
- Default Paths by OS
- Error Handling Flow
- Database Operation Flow
- WebSocket Message Flow
- Identity Loading Flow
- Skill Loading Flow
- User Learning Flow
- Channel Message Flow
- Channel Registration Flow
- Desktop Boot Flow
- Credential Flow
- Provider Management Flow
- Context Injection Flow
- Skill Proposal Flow
- Scheduler Notification Flow
- Embedding Flow
- Reasoning Continuation Flow
- Channel Router Message Pipeline
- Plugin Lifecycle Flow
- Onboarding / First-Run Setup Flow
- Auto-Discovery Flow
- Agent Self-Learning Flow
Chat Request Flow
Startup Sequence
Default Paths by OS
Resolved via directories::ProjectDirs::from("com", "sprklai", "zenii"):
| OS | Config Path | Data Dir / DB Path |
|---|---|---|
| Linux | ~/.config/zenii/config.toml | ~/.local/share/zenii/zenii.db |
| macOS | ~/Library/Application Support/com.sprklai.zenii/config.toml | ~/Library/Application Support/com.sprklai.zenii/zenii.db |
| Windows | %APPDATA%\sprklai\zenii\config\config.toml | %APPDATA%\sprklai\zenii\data\zenii.db |
Override via config.toml:
data_dir = "/custom/data/path" # overrides default data directory
db_path = "/custom/path/zenii.db" # overrides database file directly
Error Handling Flow
Database Operation Flow (async-safe)
WebSocket Message Flow
Identity Loading Flow
Skill Loading Flow
User Learning Flow
Channel Message Flow
Channel Registration Flow
Desktop Boot Flow
The desktop app uses a hybrid gateway model. By default it starts an embedded gateway; if ZENII_GATEWAY_URL is set, it connects to an external daemon instead.
Credential Flow
Provider Management Flow
Context Injection Flow
Skill Proposal Flow
Scheduler Notification Flow
The scheduler tick loop executes payloads via PayloadExecutor (scheduler/payload_executor.rs) and delivers notifications through multiple channels. The TokioScheduler ↔ AppState circular dependency is resolved via OnceCell post-construction wiring.
Embedding Flow
Reasoning Continuation Flow
Channel Router Message Pipeline
The ChannelRouter orchestrates the full message processing flow from inbound channel message to outbound response. It runs as a background task spawned during init_services(), consuming messages from an mpsc channel and using a watch signal for graceful shutdown. Lifecycle hooks (Stage 8.8) are best-effort — failures are logged but do not block the pipeline.
Plugin Lifecycle Flow
Plugins are managed through all three client interfaces, each communicating with the gateway over HTTP:
- CLI:
zenii plugin <cmd>-- direct HTTP calls to gateway plugin endpoints - Web/Desktop:
PluginsSettings.sveltecomponent --pluginsStorefetches/mutates via HTTP - TUI:
PluginListmode --ZeniiClientHTTP calls (keybindings:popen,j/knav,etoggle,dremove,iinstall,rrefresh,Escback)
Onboarding / First-Run Setup Flow
On first launch, all interfaces check GET /setup/status to determine if onboarding is needed. The SetupStatus response includes needs_setup, missing fields, detected_timezone, and has_usable_model. If setup is needed, a multi-step wizard collects AI provider configuration (provider, API key, model), optional channel credentials (Telegram, Slack, Discord), and user profile (name, location, timezone).
Interface Variants
- Desktop: 3-step
OnboardingWizardcomponent (provider setup via embeddedProvidersSettings, optional channels viaChannelsSettings, then profile fields). Next button is in the card header for visibility on long pages. - CLI:
zenii setupcommand -- interactive flow usingdialoguer(Select, Confirm, Password, Input prompts). Channels step uses Confirm prompt (default: skip). - TUI: 5-step overlay modal (ProviderSelect, ApiKey, ModelSelect, Channels, Profile) with j/k navigation. Channels step has Tab to switch between Telegram/Slack/Discord and s to skip.
Config fields: user_name: Option<String>, user_timezone: Option<String> (IANA format), user_location: Option<String> (human-readable)
Key files: onboarding.rs, gateway/handlers/config.rs (setup_status), web/src/lib/components/OnboardingWizard.svelte, crates/zenii-cli/src/commands/onboard.rs, crates/zenii-tui/src/ui/onboard.rs
Auto Fact Extraction Flow
After each chat response, ContextBuilder::extract_facts() optionally calls an LLM to extract structured facts about the user and stores them via UserLearner::observe(). Fire-and-forget -- errors are logged, not propagated.
Output format: category|key|value per line. Categories: preference, knowledge, context, workflow.
Key files: ai/context.rs (ContextBuilder::extract_facts), user/learner.rs (UserLearner::observe)
Auto-Discovery Flow
The context engine uses keyword matching to detect which feature domains are relevant to the user's message, then loads only pertinent agent rules and expanded context sections.
Domain-to-category mapping:
- Channels →
"channel"rules - Scheduler →
"scheduling"rules - Skills/Tools →
"tool_usage"rules - Always included →
"general"rules
Key file: ai/context.rs (ContextDomain, detect_relevant_domains(), domains_to_rule_categories())
Agent Self-Learning Flow
The agent can record behavioral rules during conversations via the agent_notes tool. These rules persist in the database and are automatically injected into future conversations based on domain relevance.
Categories: general, channel, scheduling, user_preference, tool_usage
Control: Gated by self_evolution_enabled config flag (runtime toggle via Arc<AtomicBool>)
Key files: tools/agent_self_tool.rs, ai/context.rs (load_agent_rules())