Development¶
This page documents the development, validation, documentation, and deployment workflow for Loca. It is intended for maintainers who update the Streamlit application, modify the local model registry, add document workflows, adjust SQLite persistence, or maintain the MkDocs documentation site.
π§ Purpose¶
The development workflow protects Loca from regressions while keeping the documentation source-driven and MkDocs-compatible.
Development work should preserve:
- local model runtime behavior;
- Streamlit session-state keys;
- model and mode registry contracts;
- SQLite schema compatibility;
- document extraction and retrieval behavior;
- prompt engineering persistence;
- exception logging through
boogr.py; - MkDocs API rendering through Google-style docstrings.
π§± Project Structure¶
A typical Loca project structure should resemble:
Loca/
βββ app.py
βββ config.py
βββ boogr.py
βββ mkdocs.yml
βββ requirements.txt
βββ resources/
β βββ images/
β βββ favicon.ico
β βββ loca-llama_logo.png
βββ stores/
β βββ sqlite/
β βββ loca.db
βββ logging/
β βββ Exceptions.db
βββ docs/
βββ index.md
βββ architecture.md
βββ development.md
βββ images/
β βββ loca-architecture-dark.png
βββ user-guide/
β βββ index.md
β βββ text-generation.md
β βββ document-qna.md
β βββ semantic-search.md
β βββ prompt-engineering.md
β βββ data-management.md
βββ api/
β βββ index.md
β βββ app.md
β βββ config.md
β βββ boogr.md
βββ assets/
βββ css/
β βββ loca.css
βββ js/
βββ loca.js
The Python source files are the source of truth for API documentation. The Markdown pages explain workflows, architecture, usage, and maintenance.
βοΈ Environment Setup¶
Create and activate a virtual environment before installing dependencies.
Install the application and documentation dependencies.
pip install streamlit pandas numpy plotly mkdocs mkdocs-material mkdocstrings[python] pymdown-extensions
Install optional document and local model dependencies as needed.
Use llama-cpp-python only when local GGUF inference is required in the active environment.
π§ Model Registry Development¶
Model configuration is centralized in config.py.
When adding or modifying a model, update the model registry entry with:
| Field | Purpose |
|---|---|
path |
GGUF model path, usually from an environment variable. |
logo |
Logo path used by Streamlit branding. |
modes |
Supported application modes. |
family |
Model family label. |
model_name |
User-facing model name. |
size |
Model size label. |
base_model |
Base model identifier used for capability checks. |
chat_template |
Prompt template style. |
description |
Short user-facing description. |
Use environment variables for model paths. Do not hard-code local machine paths into config.py.
Example:
π Mode Contract Development¶
The mode contract is defined through constants in config.py.
TEXT_MODE = 'Text Generation'
IMAGE_MODE = 'Images API'
AUDIO_MODE = 'Audio API'
DOCQNA_MODE = 'Document Q&A'
SEMANTIC_MODE = 'Semantic Search'
PROMPT_MODE = 'Prompt Engineering'
DATA_MODE = 'Data Management'
When adding a new mode:
- Add a mode constant.
- Add the mode to the appropriate model registry entries.
- Initialize required session-state keys before the UI reads them.
- Add the mode panel in
app.py. - Add user-guide documentation.
- Add or update API documentation if new functions are introduced.
- Run the full validation workflow.
Do not reuse existing session-state keys for unrelated data. Each workflow should have a clear state contract.
ποΈ Session-State Development Rules¶
Streamlit reruns the script frequently. Session-state keys must be initialized before they are read.
Required practices:
| Rule | Reason |
|---|---|
| Initialize keys early | Prevents missing-key failures during reruns. |
| Use workflow-specific prefixes | Prevents accidental state collisions. |
| Preserve widget-owned keys | Avoids Streamlit widget state errors. |
| Do not clear upstream state unexpectedly | Prevents unrelated workflows from losing data. |
| Keep model-derived state separate from user-owned state | Prevents model changes from overwriting user inputs. |
Examples of useful prefixes:
| Prefix | Workflow |
|---|---|
docqna_ |
Document Q&A |
semantic_ |
Semantic Search |
pe_ |
Prompt Engineering |
dm_ |
Data Management |
image_ |
Image workflow |
audio_ |
Audio workflow |
web_browse_ |
Web context workflow |
π Document Workflow Development¶
Document-related development should preserve safe fallback behavior.
When changing document extraction or retrieval:
- Confirm optional dependency checks remain intact.
- Confirm unsupported file types fail safely.
- Confirm extracted text is not silently discarded.
- Confirm chunk size and overlap controls are respected.
- Confirm document fingerprints remain stable.
- Confirm retrieval diagnostics still show useful state.
- Confirm Document Q&A and Semantic Search do not overwrite each otherβs state.
Optional dependency behavior should be explicit. If python-docx or PyMuPDF is missing, the
application should report the unavailable capability rather than crash.
π Retrieval Development¶
Retrieval development affects Document Q&A, Semantic Search, and Text Generation context injection.
Preserve these behaviors:
| Behavior | Development Rule |
|---|---|
| Chunking | Validate chunk size and overlap before use. |
| Embedding | Confirm vector dimensions before comparing vectors. |
| Similarity | Avoid comparing incompatible vector shapes. |
| Fallback retrieval | Keep fallback behavior explicit and diagnostic. |
| Context injection | Keep retrieved context bounded. |
| Small model support | Use compact retrieval profiles where appropriate. |
When changing retrieval defaults, test with both short and long documents.
π§° Prompt Engineering Development¶
Prompt Engineering uses SQLite-backed prompt records and shared system-instruction state.
When modifying prompt features:
- Preserve the
Promptstable contract. - Preserve prompt selector behavior.
- Preserve template application to shared system instructions.
- Preserve XML-to-Markdown conversion behavior.
- Preserve prompt metadata synchronization.
- Avoid overwriting user-edited prompt text during reruns.
- Confirm saved prompts reappear after app restart.
Prompt text can be long and user-authored. Do not write prompt text into exception method strings or diagnostic identifiers.
ποΈ SQLite Development¶
Loca uses SQLite for local persistence. Database initialization should be idempotent.
Core development rules:
| Rule | Reason |
|---|---|
Use CREATE TABLE IF NOT EXISTS |
Prevents startup failures when tables already exist. |
| Keep schema changes backward-aware | Protects existing local databases. |
| Use parameterized SQL | Prevents malformed queries and unsafe interpolation. |
| Keep connections bounded | Avoids long-lived database locks. |
| Commit write operations | Ensures records persist. |
| Do not store secrets in diagnostic tables | Protects local configuration data. |
Before changing schema, inspect dependent functions and user-guide pages.
π¨ Exception Logging Development¶
Loca uses boogr.py for structured exception logging.
Use this pattern in operational exception handlers:
except Exception as e:
exception = Error( e )
exception.module = 'app'
exception.cause = 'WorkflowName'
exception.method = 'function_name( arg: type ) -> return_type'
Logger( ).write( exception )
raise exception
For failure-safe helpers that intentionally return a default value, log only when diagnostics are valuable. Do not turn every small fallback into a raised exception.
Never include the following in exception.method:
- prompt text;
- user input;
- uploaded document text;
- dataframe contents;
- embedding vectors;
- file contents;
- API keys;
- tokens;
- full local paths;
- object memory addresses.
The method string should be a stable signature only.
π§Ύ Documentation Comment Standard¶
All public Python modules, classes, functions, methods, and properties should use Google-style docstrings compatible with MkDocs, mkdocstrings, and griffe.
Use these section names only when applicable:
Do not use underline-style sections:
Do not document self or cls.
Do not add Returns: sections to __init__.
Do not add Returns: sections to functions that return no meaningful value.
Correct:
def get_model_path( model_name: str ) -> str:
"""Return the GGUF path for a selected local model.
Purpose:
Resolves the configured model path from the central model registry so model loading,
UI diagnostics, and selected-model session state use one authoritative path source.
Args:
model_name: Selected local model name.
Returns:
str: Resolved GGUF model path.
"""
Incorrect:
def get_model_path( model_name: str ) -> str:
"""
Purpose:
--------
Gets model path.
Parameters:
-----------
model_name : str
Returns:
--------
str
"""
π§ͺ Source Validation¶
Run source validation after editing Python files.
Then run a project-wide compile check.
Optional import checks:
Be careful importing app.py directly because Streamlit applications may execute top-level UI code
during import.
π§© MkDocs API Pages¶
API pages should be source-driven and minimal.
docs/api/app.md:
docs/api/config.md:
docs/api/boogr.md:
Manual prose belongs in architecture and user-guide pages. API pages should let mkdocstrings render the source docstrings.
ποΈ MkDocs Build¶
Build the documentation site from the project root.
Serve the site locally.
Then open the local server URL shown in the terminal.
π¬ MkDocs Warning Triage¶
Treat griffe and MkDocs warnings as defects.
| Warning | Likely Cause | Fix |
|---|---|---|
Page exists but is not in nav |
Markdown file not listed in mkdocs.yml |
Add the page to nav or remove the unused file. |
| Nav page not found | mkdocs.yml references a missing file |
Create the file or remove the nav entry. |
Failed to get name: description pair |
Malformed Args: or Attributes: entry |
Rewrite entries as name: Description. |
| No type or annotation for returned value | Return section lacks explicit type or function lacks annotation | Add a return annotation or explicit return type in Returns:. |
| Import failure during API build | mkdocstrings cannot import the module | Run direct import checks and fix missing dependencies or top-level runtime errors. |
| Broken image link | Image path does not exist under docs/ |
Move the image or correct the Markdown link. |
Do not hide API pages to suppress warnings. Repair the source docstrings or import issue.
π¨ CSS and JavaScript Development¶
The documentation site uses custom assets:
The CSS provides:
- dark-mode theme overrides;
- dark blue header and tab bar;
- wider documentation content;
- styled tables;
- styled API reference blocks;
- code block styling;
- image and diagram styling;
- print styling;
- responsive layout adjustments.
The JavaScript provides:
- API search/filter tools;
- expand/collapse controls;
- heading copy links;
- page copy and print buttons;
- table filters;
- code labels;
- long-code expand/collapse;
- reading progress;
- scroll-to-top control.
After changing CSS or JavaScript, run:
Then hard-refresh the browser to avoid stale cached assets.
πΌοΈ Diagram Assets¶
Architecture and class-map diagrams should be stored under:
Recommended files:
Reference the architecture diagram from architecture.md:
Use relative paths from the Markdown file location.
For docs/architecture.md, use:
For a page under docs/user-guide/, use:
β Development Checklist¶
Before committing changes, confirm:
| Check | Status |
|---|---|
| Python files compile | Required |
| Public docstrings are Google-style | Required |
| No underline-style docstring sections remain | Required |
No Returns: None sections exist for procedures |
Required |
| Logging pattern uses stable method signatures | Required |
| No prompt text or file content is logged as method metadata | Required |
| Session-state keys are initialized before use | Required |
| Model registry entries use environment-based paths | Required |
| API pages exist for documented modules | Required |
Every docs page is listed in mkdocs.yml |
Required |
Images referenced by Markdown exist under docs/ |
Required |
| CSS and JavaScript paths exist | Required |
mkdocs build succeeds |
Required |
π GitHub Pages Deployment¶
After the documentation builds locally, deploy with:
This publishes the generated site to the repositoryβs gh-pages branch.
In GitHub repository settings:
- Open Settings.
- Open Pages.
- Set the source to Deploy from a branch.
- Select the
gh-pagesbranch. - Select
/ (root). - Save the setting.
The repository README can link to the published documentation site after GitHub Pages is active.
π οΈ Common Development Problems¶
| Problem | Likely Cause | Fix |
|---|---|---|
| Streamlit widget state error | Widget-owned key modified after widget creation | Move state mutation before widget creation. |
| Model mode resets unexpectedly | Derived model state overwrites user-owned selection | Separate selected state from derived state. |
| API page fails to render | Module import fails during mkdocstrings build | Fix import dependency or top-level runtime execution. |
| Logo does not appear | Path is outside docs/ for MkDocs or missing at runtime for Streamlit |
Use correct path for the target environment. |
| Griffe warnings persist | Docstring section is still malformed | Repair the exact function named in the warning. |
| Document Q&A loses files | Session-state key was cleared during rerun | Preserve upload state unless user explicitly clears it. |
| Semantic Search returns stale results | Old index was appended instead of cleared | Clear or rebuild the semantic index. |
| Prompt selector is empty | Prompts table is empty or captions are missing |
Save a prompt with a valid caption. |
| Exception log is empty | No exceptions have been logged or path/table differs | Confirm LOG_PATH and LOG_FILE. |