Pagepiper (and possibly other products copying its pattern) imported
dispatch_task(caller, args) -> task_id / get_task_status(task_id) -> dict
from circuitforge_core.tasks, expecting a "product/task_name" + kwargs-dict
interface. Neither function existed, so every call silently hit an
except-Exception fallback with no visible error.
This is a new module, not a TaskScheduler wrapper — TaskScheduler is keyed
by task_id/job_id/params against a specific SQLite background_tasks table
(VRAM-budgeted LLM queue), a different shape from the generic named-runnable
dispatch pagepiper actually needed.
Scope: free-tier, in-process, single-node only. Routing through the
circuitforge-orch coordinator would need a new generic task-dispatch
endpoint on that separate BSL package (CFOrchClient only exposes model/
service allocation today) — tracked as follow-up, not attempted here.
Consuming products additionally need to call register_task_runner() at
startup to benefit; that's product-side work in a separate repo.
Bump to 0.22.0.
Closes: #67
- LLMRouter.__init__ now accepts a Path | dict; pagepiper ingest scripts
pass a runtime-constructed config dict instead of a temp file
- _check_ollama_model_pulled() preflight on embed(): checks /api/tags once
per backend URL and raises RuntimeError("...Fix: ollama pull <model>")
when the configured embedding model is not pulled; silently skips for
non-Ollama backends (vLLM, etc.) that don't expose /api/tags
- 6 new tests: dict init paths (x2) + preflight scenarios (x4)
- Existing embed tests updated to mock requests.get to avoid live Ollama calls
Five backends: BGE (FlagEmbedding), Qwen3 (generative yes/no logit scorer,
batched forward pass), CrossEncoder (sentence-transformers, covers mxbai-rerank
/ ms-marco / jina), Cohere (BYOK cloud), Remote (HTTP delegate to cf-reranker
service). Mock adapter for tests. 54 tests.
cf-reranker FastAPI service app (port 8011) — cf-orch manages as a process,
defaults to Qwen3-Reranker-0.6B.
make_reranker() auto-detects CF_ORCH_URL and routes to cf-orch cf-reranker
when set — cloud apps (Kiwi, Peregrine, Snipe) get remote Qwen3 reranking
with zero code changes. Local dev falls back to local BGE.
pyproject extras: reranker-bge, reranker-qwen3, reranker-cross-encoder,
reranker-cohere, reranker-service.
Adds circuitforge_core.preferences.currency with get/set_currency_code()
and format_currency(). Priority chain: store → CURRENCY_DEFAULT env → USD.
Formatting uses babel when available; falls back to a 30-currency symbol
table with correct ISO 4217 minor-unit decimal places (0 for JPY, KRW, etc.).
Consumed by Snipe, Kiwi, Peregrine, Crossbill. Bumps to v0.13.0.
12 signal functions covering staleness, repost patterns, salary transparency,
ATS blackhole detection, and enrichment signals. All pure functions — no LLM,
no network, no I/O. trust_score = 1 - sum(triggered weights), clamped to [0,1].
confidence reflects fraction of signals with available evidence.
Salary transparency enforced for CO/CA/NY/WA/IL/MA. ATS blackhole patterns:
Lever, Greenhouse, Workday, iCIMS, Taleo.
83 tests (models, all 12 signals individually, scorer). Bumps to v0.12.0.