Skip to content

fix: batch of P3 fixes (scipy dep, prompt token budget, style-profile lookup, embedder cold start, local dev docs) - #129

Merged
Davisuco28 merged 5 commits into
mainfrom
fix/p3-batch-105-90-108-104-101
Jul 29, 2026
Merged

fix: batch of P3 fixes (scipy dep, prompt token budget, style-profile lookup, embedder cold start, local dev docs)#129
Davisuco28 merged 5 commits into
mainfrom
fix/p3-batch-105-90-108-104-101

Conversation

@PabloVc-77

@PabloVc-77 PabloVc-77 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

What

Batch of 5 P3 technical-debt fixes identified while triaging open issues: an undeclared dependency, an unbounded prompt token budget, duplicated "current style profile" query logic, an eager model load causing slow cold starts, and missing local-dev documentation.

Why

Closes #105
Closes #90
Closes #108
Closes #104
Closes #101

How IBM Bob helped

  • Custom Mode used: none
  • Bob session export: n/a

Screenshots / output

No UI changes. Backend/pipeline behavior changes:

  • ai_pipeline/pyproject.toml now declares scipy>=1.11 explicitly (previously only transitive via scikit-learn).
  • conditioner.build_system_prompt now measures the real tiktoken (cl100k_base) token count and truncates the last RAG chunk at a sentence/word boundary instead of relying on a chunk-count heuristic that could produce ~2,590-token prompts against a ~1,200-token budget.
  • GET style-profile lookups in authors.py and generate.py now go through a single app.db.get_current_style_profile() helper (order by computed_at desc limit 1) instead of two independent copies of the same query.
  • embedder.py no longer constructs the 418MB SentenceTransformer at import time; it's a lazy singleton (ensure_model_loaded()), and railway.toml pre-fetches the model at build time so cold starts read from local disk.
  • New docs/LOCAL_DEV.md documents the local setup flow and known local/deploy divergences (referenced from README.md and docs/DEPLOYMENT.md).

Checklist

  • Tests pass locally (make test) — ai_pipeline: 162 passed / 4 skipped; backend: 118 passed (plus new tests for each fix)
  • Lint passes (make lint) — ruff check . and black --check . clean
  • If schema changed (StyleProfile / Passport) → bumped version + updated docs/ (no schema change — [ml] style_profiles no deduplica: la puerta 'count(*) = 3' de #86 se rompe al sembrar dos veces #108 is a query/documentation fix, not a schema change)
  • If new env var → added to .env.example (no new env vars)
  • If new/changed endpoint → updated docs/api_contract.yaml (no endpoint contract change)
  • Documentation in the relevant README.md updated
  • At least one teammate reviewed

scipy was only pulled in transitively via scikit-learn even though
fit_scorer.py imports it directly (#105) - declare it explicitly.

Also stop constructing the 418MB SentenceTransformer at module import
time: any transitive import of embedder.py (e.g. via backend/db.py) paid
the cold-start cost. Use a lazy singleton (ensure_model_loaded) instead,
and pre-fetch the model into the HuggingFace cache during the Railway
build step so cold starts read from local disk rather than the network (#104).

Closes #105
Closes #104
Capping the system prompt at 5 RAG chunks does not bound the token count:
5 passages of ~500 tokens each blow past the ~1200 token budget (PR #125
measured ~2,590 real tokens). Pack chunks against an actual tiktoken
(cl100k_base) count instead, truncating the last chunk that does not fit
at the nearest sentence/word boundary rather than mid-word.

Adds 6 tests reproducing the over-budget scenario and covering truncation
edge cases (mid-word safety, short chunks, empty input).

Closes #90
style_profiles keeps history by design (erd.md, migration comments already
say so) - recompute appends a row, "current" is the one with the latest
computed_at. The actual bug was that the `order by computed_at desc limit 1`
query was duplicated between authors.py and generate.py instead of living
in one place.

Extract get_current_style_profile() to app/db.py and use it from both
routes. Add a dedicated regression test file asserting the helper picks
the latest row and calls order/limit with the exact expected shape.

Closes #108
Add docs/LOCAL_DEV.md covering the make install-py / install-front flow,
why sentence-transformers/spaCy are lazy-loaded and cached, and the
divergences between local dev and the Railway/Linux deploy target
(CUDA-less wheel resolution on Windows/macOS vs. uv pip compile,
editable-install absolute paths breaking under git worktrees, ruff/black
version drift from CI). Link it from README.md and docs/DEPLOYMENT.md,
and record the decision not to pursue full container parity in
docs/decision_log.md.

Closes #101
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
author-ai Ready Ready Preview, Comment Jul 29, 2026 8:45am

@Davisuco28
Davisuco28 merged commit ae95eb6 into main Jul 29, 2026
8 checks passed
@Davisuco28
Davisuco28 deleted the fix/p3-batch-105-90-108-104-101 branch July 29, 2026 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment