1
0

refactor: centralize config & harden security (#141)

* feat: upgrade primary model from llama3.1:8b to qwen2.5:14b

- Swap OLLAMA_MODEL_PRIMARY to qwen2.5:14b for better reasoning
- llama3.1:8b-instruct becomes fallback
- Update .env default and README quick start
- Fix hardcoded model assertions in tests

qwen2.5:14b provides significantly better multi-step reasoning
and tool calling reliability while still running locally on
modest hardware. The 8B model remains as automatic fallback.

* security: centralize config, harden uploads, fix silent exceptions

- Add 9 pydantic Settings fields (skip_embeddings, disable_csrf,
  rqlite_url, brain_source, brain_db_path, csrf_cookie_secure,
  chat_api_max_body_bytes, timmy_test_mode) to centralize env-var access
- Migrate 8 os.environ.get() calls across 5 source files to use
  `from config import settings` per project convention
- Add path traversal defense-in-depth to file upload endpoint
- Add 1MB request body size limit to chat API
- Make CSRF cookie secure flag configurable via settings
- Replace 2 silent `except: pass` blocks with debug logging in session.py
- Remove unused `import os` from brain/memory.py and csrf.py
- Update 5 CSRF test fixtures to patch settings instead of os.environ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Trip T <trip@local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexander Whitestone
2026-03-07 18:49:37 -05:00
committed by GitHub
parent cdd3e1a90b
commit b615595100
14 changed files with 80 additions and 56 deletions

View File

@@ -27,7 +27,8 @@ class BrainClient:
"""
def __init__(self, rqlite_url: Optional[str] = None, node_id: Optional[str] = None):
self.rqlite_url = rqlite_url or os.environ.get("RQLITE_URL", DEFAULT_RQLITE_URL)
from config import settings
self.rqlite_url = rqlite_url or settings.rqlite_url or DEFAULT_RQLITE_URL
self.node_id = node_id or f"{socket.gethostname()}-{os.getpid()}"
self.source = self._detect_source()
self._client = httpx.AsyncClient(timeout=30)
@@ -36,7 +37,8 @@ class BrainClient:
"""Detect what component is using the brain."""
# Could be 'timmy', 'zeroclaw', 'worker', etc.
# For now, infer from context or env
return os.environ.get("BRAIN_SOURCE", "default")
from config import settings
return settings.brain_source
# ──────────────────────────────────────────────────────────────────────────
# Memory Operations