Skip to main content

Zenii Process Flows

Table of Contents


Chat Request Flow

Startup Sequence

Default Paths by OS

Resolved via directories::ProjectDirs::from("com", "sprklai", "zenii"):

OSConfig PathData 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 TokioSchedulerAppState 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.svelte component -- pluginsStore fetches/mutates via HTTP
  • TUI: PluginList mode -- ZeniiClient HTTP calls (keybindings: p open, j/k nav, e toggle, d remove, i install, r refresh, Esc back)

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 OnboardingWizard component (provider setup via embedded ProvidersSettings, optional channels via ChannelsSettings, then profile fields). Next button is in the card header for visibility on long pages.
  • CLI: zenii setup command -- interactive flow using dialoguer (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())