configuration-and-data.md 6.0 KB


type: operations title: Configuration and data files description: How src/config.rs loads config.toml, the supported keys and defaults, where the data directory and databases live, and operational and security caveats. tags: [configuration, toml, data-directory, sqlite, security] sources:

  • id: openwiki-source-ea70eb6c04 resource: repo://.gitignore
  • id: openwiki-source-1b05507d70 resource: repo://src/ai.rs
  • id: openwiki-source-2a737474d8 resource: repo://src/config.rs generated: { by: "claude-code", at: "2026-10-19T19:53:56.480Z" } verified:
  • by: openwiki/0.7.2 at: 2026-10-19T19:53:56.480Z ---

Configuration and data files

All runtime settings come from one TOML file loaded by Config::load (src/config.rs:226-230). No environment variable is ever read (src/config.rs:1-20).

Data directory

The data directory is fixed: <platform config dir>/wh, resolved with dirs::config_dir() (src/config.rs:144-148). On Windows this is %APPDATA%\wh. It cannot be changed from the config file. At startup ensure_data_dir creates it if missing (src/config.rs:258-261).

File Purpose Defined by
config.toml Optional settings CONFIG_FILE, src/config.rs:49
session.db WhatsApp session store used by whatsapp-rust (WhatsApp client) session_db_path, src/config.rs:267-269
history.db Local messages, chats, contacts and autoreply flags (History store) history_db_path, src/config.rs:275-277
ai_requests.log Optional AI request log, written only when ai_log = true (AI client) ai_log_path, src/config.rs:283-285

The two databases are separate by design: session.db belongs to the WhatsApp library (linked-device session and keys, schema owned by whatsapp-rust), while history.db belongs to the app (chats, messages, contacts, autoreply flags).

Keys

Key Purpose Default when missing or blank
openai_api_key Bearer token for the AI endpoint (trimmed) none — the AI client cannot be built
openai_base_url Base URL of the OpenAI-compatible endpoint (trimmed, trailing / removed) https://ollama.com/v1
openai_model Model for text replies (trimmed) deepseek-v4.1-flash
openai_vision_model Model for image replies (trimmed) none — image understanding disabled
system_prompt Persona/instructions for autoreplies, kept as written (not trimmed, multiline allowed) none — AI not configured
ai_log Boolean; when true every request sent to the AI model is appended to ai_requests.log false
cooldown_seconds Minimum seconds between autoreplies in a private chat or to a group message addressed to the user; 0 disables it 30
group_cooldown_seconds Same, for group messages not addressed to the user; 0 disables it 300
catch_up_seconds After a restart, the last unanswered message of each private chat is answered once if it is at most this old; 0 disables the catch-up 7200

Mapping and defaults: src/config.rs:236-252, src/config.rs:29-38. The three timing keys are unsigned integers in the file (Option<u32>, src/config.rs:104-111), so a negative value is rejected as an invalid value type; they are stored as i64 in Config. Their use is described in AI autoreply. The binary embeds no prompt text: without system_prompt the AI is not configured and the status line says so (see Application state). Unknown keys are ignored.

Loading rules

  • Missing file → all defaults (src/config.rs:180-190).
  • Unreadable file → cannot read config file <path>.
  • Invalid TOML or wrong value type → invalid config file <path> with the cause invalid TOML syntax or value type at line L, column C; the error never echoes file content (src/config.rs:165-174). This also covers negative or non-integer timing keys and a non-boolean ai_log.
  • A leading UTF-8 BOM (common with Windows editors) and CRLF line endings are tolerated.
  • openai_base_url consisting only of slashes is rejected with openai_base_url in config.toml must not be empty or only slashes (src/config.rs:212-219).

Startup aborts with cannot load configuration on any of these errors (Runtime).

Security and operational notes

  • The API key is never printed: Config's Debug shows *** or <unset> (src/config.rs:114-138), and the raw FileConfig has no Debug impl at all (src/config.rs:90-112). The AI client redacts it too.
  • ai_requests.log never contains the API key and replaces image data with a size placeholder, but it does store the full request (system prompt and chat context) and the reply in clear text, and it is only appended to, never rotated. Enable ai_log only for diagnosis and delete the file afterwards.
  • Keep config.toml in the data directory, outside the repository. .gitignore ignores a root-level /config.toml and .env (.gitignore:4-6), as well as SQLite journal/WAL/SHM files; note that the *.db pattern is commented out (.gitignore:7), so databases copied into the repo would not be ignored.
  • session.db holds the linked-device credentials: deleting it forces a new QR pairing. history.db can be deleted to reset local history and autoreply flags; it is recreated on start.
  • Images downloaded for vision replies are kept in memory only and never written to the data directory.

Tests

src/config.rs:288+ covers defaults, full files, blank values, multiline prompts, trimming, base URL normalisation and errors, Debug masking, vision model, DB and AI log paths, ai_log, cooldown and catch-up defaults, custom values (including 0) and rejection of negatives, unknown keys, BOM/CRLF, non-leaking parse errors, missing, existing, invalid and unreadable files. See Unit tests.