feat(llm): duckdb_replica / valuation_years / code_cited_per_code config (refs P48)

This commit is contained in:
kert
2026-09-08 22:38:58 -04:00
parent 25756f658b
commit 6d85ffcff0
3 changed files with 22 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ Env contract:
LLM_PG_HOST beats [llm].pg_host (containers set this to "postgres") LLM_PG_HOST beats [llm].pg_host (containers set this to "postgres")
LLM_DB_PASSWORD required for pg_url(); lives in .env, never stack.toml LLM_DB_PASSWORD required for pg_url(); lives in .env, never stack.toml
LLM_BUILD_ANN_INDEX beats [llm].build_ann_index ("1"/"true"/"yes" = True) LLM_BUILD_ANN_INDEX beats [llm].build_ann_index ("1"/"true"/"yes" = True)
LLM_DUCKDB_REPLICA beats [llm].duckdb_replica (containers set /app/data/aco.ro.duckdb)
Ollama has no GPU-size API, so VRAM is *declared* per host; liveness is Ollama has no GPU-size API, so VRAM is *declared* per host; liveness is
probed at request time (``HostPool.check``). Together they implement probed at request time (``HostPool.check``). Together they implement
@@ -43,6 +44,9 @@ class LlmConfig:
default_factory=lambda: dict(_DEFAULT_K_PER_KIND) default_factory=lambda: dict(_DEFAULT_K_PER_KIND)
) )
top_n: int = 8 top_n: int = 8
duckdb_replica: str = "data/aco.ro.duckdb"
valuation_years: int = 4
code_cited_per_code: int = 3
def parse_hosts(spec: str) -> tuple[tuple[str, float], ...]: def parse_hosts(spec: str) -> tuple[tuple[str, float], ...]:
@@ -97,6 +101,10 @@ def load() -> LlmConfig:
recency_weight=float(_opt(section, "recency_weight", 0.3)), recency_weight=float(_opt(section, "recency_weight", 0.3)),
k_per_kind=k_per_kind, k_per_kind=k_per_kind,
top_n=int(_opt(section, "top_n", 8)), top_n=int(_opt(section, "top_n", 8)),
duckdb_replica=os.environ.get("LLM_DUCKDB_REPLICA")
or str(_opt(section, "duckdb_replica", "data/aco.ro.duckdb")),
valuation_years=int(_opt(section, "valuation_years", 4)),
code_cited_per_code=int(_opt(section, "code_cited_per_code", 3)),
embed_dim=int(section.embed_dim), embed_dim=int(section.embed_dim),
build_ann_index=build_ann_index, build_ann_index=build_ann_index,
pg_host=os.environ.get("LLM_PG_HOST", str(section.pg_host)), pg_host=os.environ.get("LLM_PG_HOST", str(section.pg_host)),

View File

@@ -124,6 +124,9 @@ pg_user = "llm"
recency_half_life_days = 365 recency_half_life_days = 365
recency_weight = 0.3 recency_weight = 0.3
top_n = 8 top_n = 8
duckdb_replica = "data/aco.ro.duckdb" # read-only DuckDB replica the chat reads valuations from
valuation_years = 4 # final-rule vintages shown per code (plus the newest NPRM)
code_cited_per_code = 3 # rule paragraphs literally citing each detected code
[llm.k_per_kind] # over-fetched ×3 per kind, then re-ranked [llm.k_per_kind] # over-fetched ×3 per kind, then re-ranked
comment = 8 comment = 8

View File

@@ -87,3 +87,14 @@ class TestNewKnobs:
cfg = llm_config.load() cfg = llm_config.load()
assert cfg.ollama_hosts == ("http://rig:11434", "http://laptop:11434") assert cfg.ollama_hosts == ("http://rig:11434", "http://laptop:11434")
assert cfg.host_vram == {"http://rig:11434": 24.0, "http://laptop:11434": 12.0} assert cfg.host_vram == {"http://rig:11434": 24.0, "http://laptop:11434": 12.0}
def test_valuation_knobs_defaults(self, monkeypatch):
monkeypatch.delenv("LLM_DUCKDB_REPLICA", raising=False)
cfg = llm_config.load()
assert cfg.duckdb_replica == "data/aco.ro.duckdb"
assert cfg.valuation_years == 4
assert cfg.code_cited_per_code == 3
def test_duckdb_replica_env_override(self, monkeypatch):
monkeypatch.setenv("LLM_DUCKDB_REPLICA", "/app/data/aco.ro.duckdb")
assert llm_config.load().duckdb_replica == "/app/data/aco.ro.duckdb"