Configuration and paths

axiom.config

core/config.py

Application configuration model for Axiom AI.

Stores user preferences (LLM backend, model names, API keys, Chronicler interval) in a JSON file at ~/.config/AxiomAI/settings.json.

This module is pure Python with no UI dependencies — it can be imported by workers and backend code safely.

class axiom.config.AppConfig(llm_backend='universal', universal_base_url='http://localhost:11434/v1', universal_api_key='', universal_model='llama3.2', gemini_api_key='', gemini_model='gemini-2.0-flash', anthropic_api_key='', anthropic_model='claude-opus-4-8', venice_api_key='', venice_model='zai-org-glm-4.7', fireworks_api_key='', fireworks_model='accounts/fireworks/models/gpt-oss-120b', openai_api_key='', openai_model='gpt-4.1-mini', openrouter_api_key='', openrouter_model='openrouter/auto', extraction_model='llama3.1:8b', time_model='llama3.2:1b', timekeeper_enabled=True, chronicler_interval=50, chronicler_minutes_interval=720, ui_font_size=14, enable_audio=True, doc_tooltips_enabled=True, rag_chunk_count=5, language='en', llm_requests_per_minute=0, gemini_fallback_model='', image_generation_enabled=False, image_backend='mock', image_api_url='http://127.0.0.1:7860', image_width=512, image_height=512, image_steps=20, image_cfg_scale=7.0, image_comfyui_workflow='', image_gemini_model='gemini-2.5-flash-image', image_timeout=180)[source]

User preferences for Axiom AI.

Parameters:
  • llm_backend (str)

  • universal_base_url (str)

  • universal_api_key (str)

  • universal_model (str)

  • gemini_api_key (str)

  • gemini_model (str)

  • anthropic_api_key (str)

  • anthropic_model (str)

  • venice_api_key (str)

  • venice_model (str)

  • fireworks_api_key (str)

  • fireworks_model (str)

  • openai_api_key (str)

  • openai_model (str)

  • openrouter_api_key (str)

  • openrouter_model (str)

  • extraction_model (str)

  • time_model (str)

  • timekeeper_enabled (bool)

  • chronicler_interval (int)

  • chronicler_minutes_interval (int)

  • ui_font_size (int)

  • enable_audio (bool)

  • doc_tooltips_enabled (bool)

  • rag_chunk_count (int)

  • language (str)

  • llm_requests_per_minute (int)

  • gemini_fallback_model (str)

  • image_generation_enabled (bool)

  • image_backend (str)

  • image_api_url (str)

  • image_width (int)

  • image_height (int)

  • image_steps (int)

  • image_cfg_scale (float)

  • image_comfyui_workflow (str)

  • image_gemini_model (str)

  • image_timeout (int)

llm_backend

Active backend — “universal”, “gemini”, or one of the OpenAI-compatible cloud providers: “claude”, “venice”, “fireworks”, “openai”, “openrouter”.

Type:

str

universal_base_url

Base URL for Universal API (e.g. OpenAI-compatible).

Type:

str

universal_api_key

Optional API key for Universal API.

Type:

str

universal_model

Model identifier for Universal API.

Type:

str

gemini_api_key

Google Gemini API key (may be empty).

Type:

str

gemini_model

Gemini model identifier.

Type:

str

anthropic_api_key

Anthropic API key for the “claude” backend.

Type:

str

anthropic_model

Claude model identifier (e.g. claude-opus-4-8).

Type:

str

venice_api_key

Venice AI API key for the “venice” backend.

Type:

str

venice_model

Venice AI model identifier.

Type:

str

fireworks_api_key

Fireworks AI API key for the “fireworks” backend.

Type:

str

fireworks_model

Fireworks AI model identifier.

Type:

str

openai_api_key

OpenAI API key for the “openai” backend.

Type:

str

openai_model

OpenAI model identifier.

Type:

str

openrouter_api_key

OpenRouter API key for the “openrouter” backend.

Type:

str

openrouter_model

OpenRouter model identifier (e.g. openrouter/auto).

Type:

str

extraction_model

Model used specifically for data extraction (Populate).

Type:

str

time_model

Model used by the Timekeeper to deduce elapsed time.

Type:

str

timekeeper_enabled

When True, a dedicated second LLM call (the Timekeeper) deduces the in-game minutes elapsed each turn. When False, that extra call is skipped and the time is estimated from the scene pace alone (cheaper, less precise). See Pilier 5 / TICKET-015.

Type:

bool

chronicler_interval

LEGACY — player turns between Chronicler runs. No longer used for triggering (the Chronicler is now driven by in-game minutes); kept for backward compatibility with older settings files.

Type:

int

chronicler_minutes_interval

In-game minutes between Chronicler runs. The Chronicler fires once whenever the world clock crosses a multiple of this value, so a single long time-skip triggers exactly one off-screen simulation.

Type:

int

ui_font_size

Font size for the chat UI.

Type:

int

enable_audio

Whether background ambiance is enabled.

Type:

bool

doc_tooltips_enabled

Whether the GUI shows the documentation tooltips when hovering interface elements (TICKET-057).

Type:

bool

rag_chunk_count

Number of memory chunks to retrieve for RAG.

Type:

int

llm_requests_per_minute

Soft rate limit applied to Gemini calls (TICKET-031). 0 = unlimited. Free tier example: 10 req/min per model — set 9 to stay under it.

Type:

int

gemini_fallback_model

Model tried when the primary Gemini model is still quota-exhausted (429) after retries. Google quotas are per-model, so a different model usually still has budget. Empty = no fallback.

Type:

str

image_generation_enabled

Whether narrative image generation is enabled.

Type:

bool

image_backend

Image generation backend (“mock”, “stable_diffusion”, or “comfyui”).

Type:

str

image_api_url

API base URL for the local image generator.

Type:

str

image_width

Generated image width in pixels.

Type:

int

image_height

Generated image height in pixels.

Type:

int

image_steps

Denoising steps for the image generation.

Type:

int

image_cfg_scale

Classifier Free Guidance scale.

Type:

float

image_comfyui_workflow

Optional path to a ComfyUI workflow JSON file or a serialized workflow JSON string.

Type:

str

image_gemini_model

Gemini image model used by the “gemini” image backend.

Type:

str

image_timeout

Max seconds to wait for a local image backend (SD WebUI request / ComfyUI polling) per image.

Type:

int

axiom.config.register_builtin_keys(provider, keys)[source]

Register shared fallback keys for an OpenAI-compatible provider.

Parameters:
  • provider (str) – One of OPENAI_COMPAT_PROVIDERS (e.g. “fireworks”).

  • keys (list[str]) – Ordered key pool; empty entries are dropped. An empty list unregisters the provider.

Return type:

None

axiom.config.get_builtin_keys(provider)[source]

Return the registered key pool for a provider ([] when none).

Parameters:

provider (str)

Return type:

list[str]

axiom.config.uses_builtin_keys(config)[source]

True when the active backend will run on the registered shared keys (provider with a registered pool and no user key configured).

Parameters:

config (AppConfig)

Return type:

bool

axiom.config.load_config()[source]

Load configuration from the settings file.

Returns sensible defaults if the file does not exist or is malformed. Never raises. The result is cached as long as the file’s mtime does not change (save_config goes through the file: automatic invalidation).

Returns:

AppConfig populated from disk, or a default AppConfig on any error.

Return type:

AppConfig

axiom.config.save_config(config)[source]

Persist an AppConfig to the settings file.

Creates the config directory if it does not exist.

Parameters:

config (AppConfig) – The configuration to save.

Raises:

OSError – If the file cannot be written (propagated to the caller).

Return type:

None

axiom.config.resolve_extraction_model(config)[source]

Pick the model name for auxiliary LLM calls (hero decision, extraction).

extraction_model is an Ollama-style local model name; it only makes sense for the universal/Ollama backend. On a cloud backend (Gemini, Claude, Venice, Fireworks, OpenAI) there is no separate local model, so sending extraction_model (“llama3.1:8b”) to the provider yields a 404. Fall back to the provider’s main model in that case.

Parameters:

config (AppConfig)

Return type:

str

axiom.config.resolve_time_model(config)[source]

Return the correct time model identifier based on the active backend.

On a cloud backend the local time_model identifier cannot be used, so we fall back to the provider’s main model.

Parameters:

config (AppConfig)

Return type:

str

axiom.config.build_llm_from_config(config, model_override=None)[source]

Instantiate and return the correct LLMBackend for the given config.

Parameters:
  • config (AppConfig) – The current AppConfig.

  • model_override (str | None) – Optional model identifier to use instead of the default.

Returns:

A concrete LLMBackend instance ready for use.

Raises:

ValueError – If config.llm_backend is not “universal”, “gemini”, or one of the OpenAI-compatible cloud providers (claude, venice, fireworks, openai, openrouter).

Return type:

LLMBackend

axiom.paths

core/paths.py

Centralised path management for Axiom AI. Ensures cross-platform compatibility by using OS-specific standard directories.

axiom.paths.get_app_config_dir()[source]

Return the standard directory for application configuration files.

Return type:

Path

axiom.paths.get_app_cache_dir()[source]

Return the standard directory for non-essential data (logs, etc).

Return type:

Path

axiom.paths.get_app_data_dir()[source]

Return the standard directory for user-created content (universes, saves).

Return type:

Path

axiom.paths.configure(*, data_dir=None, config_dir=None)[source]

Inject path roots. Only the arguments provided are changed.

Parameters:
  • data_dir (str | PathLike | None) – Root for per-game data (vector, logs). None leaves it.

  • config_dir (str | PathLike | None) – Root for cross-cutting config (settings.json, global.db).

Return type:

None

axiom.paths.reset()[source]

Clear all injected overrides (back to defaults / env). Used by tests.

Return type:

None

axiom.paths.has_config_override()[source]

True if a config root was injected (via configure or env var).

Return type:

bool

axiom.paths.get_vector_dir()[source]

Vector store root, honouring an injected/env data_dir.

Return type:

Path

axiom.paths.get_saves_dir()[source]

Root of the separate saves, honours injected/env data_dir.

Return type:

Path

axiom.paths.get_assets_dir()[source]

Root of the generated images (assets/<save_id>/turn_<n>.png), honours injected/env data_dir.

Return type:

Path

axiom.paths.get_log_dir()[source]

Log directory. Defaults to the machine-global cache root (legacy location); under an injected/env data_dir, logs move to <data_dir>/logs.

Return type:

Path

axiom.paths.get_config_dir()[source]

Config directory, honouring an injected/env config_dir.

Return type:

Path