Commit graph

140 commits

Author SHA1 Message Date
Yiorgis Gozadinos
e9f6fea598
vb 2026-08-21 13:15:50 +03:00
Yiorgis Gozadinos
2a7c6510d0
vb 2026-08-20 15:48:23 +03:00
Yiorgis Gozadinos
629e1ba4ea
Split the store module by responsibility
engine.py held four unrelated things: what the tables are, how to open a
connection, how to read a database's state, and the Store that coordinates
writes. At 1240 lines the Store's own concerns — locks, migrations, vacuum,
tags — were hard to find among them.

Table records, Arrow schemas, index_specs, ensure_indexes, REQUIRED_TABLES
and query_to_pydantic move to store/schema.py, which imports nothing from
haiku.rag: it describes the tables and never opens or mutates one.

gather_database_info, get_database_stats, DatabaseInfo and its result models
move to store/info.py. Nothing in Store calls them — they are read paths for
the CLI, doctor, inspector and ingester API — so info depends on engine and
not the reverse.

engine.py keeps the Store, ConnectionMode, connect_lancedb, the tag helpers
and the restore-order and retention constants. No re-exports: importers
point at the new modules.

test_app_info_uses_connect_lancedb_for_remote patched
haiku.rag.store.engine.connect_lancedb; gather_database_info now binds that
name in info.py, so the patch targets where the call is looked up.
2026-08-20 12:13:51 +03:00
Yiorgis Gozadinos
e8f00fcff4
Make get_config the only configuration lookup
haiku.rag.config exported two configuration instances: the lazy _config
behind get_config/set_config, and Config, loaded at import time. Nothing
linked them, and eleven signatures captured Config as a default argument,
so set_config could not reach the factories, the client, the store or the
MCP server. reranking/base.py went further and snapshotted the configured
reranker name into a class attribute at import.

Config is removed. Internal defaults are config: AppConfig | None = None,
resolved through get_config() per call. RerankerBase._model is None and
CohereReranker takes its model name as an argument, like every other
reranker.

The suite patched attributes on Config while production read the instance
get_config() returns, a different object, so those patches were no-ops
waiting to happen. They now go through get_config().
2026-08-19 14:43:40 +03:00
Yiorgis Gozadinos
8e93b639bc
Migrate existing databases to the full index set
Adds the 0.75.0 upgrade, which brings a pre-existing database up to the index
set `_init_tables` now creates. It rewrites no table data, so unlike the earlier
data migrations its cost is the index builds alone, each of which reads the
column it indexes.

`ensure_indexes` ensures an index of the declared *type* covers each declared
column, rather than checking that the column is indexed at all. The distinction
is what makes it safe to run against a database of unknown provenance:

- A wrong-typed index no longer satisfies the check. A BTree on `label` covers
  the column while losing the low-cardinality equality lookup the Bitmap is for.
- Nothing is dropped or converted away from. Two index types over one column can
  be deliberate, serving different query shapes, so an index this function did
  not declare survives even on a column it does. The one thing it overwrites is
  an index at LanceDB's default name, `{column}_idx`, which is the name it
  creates itself.
- A column already carrying the declared type is skipped, so a database with the
  full set migrates instantly rather than re-sorting every indexed column.
- Undeclared columns are untouched, so a vector index on `chunks` survives.

It returns the columns it acted on, because a change is not always visible from
outside: adding a Bitmap beside an existing BTree leaves the column indexed
before and after.

The version bump to 0.75.0 is required, not incidental: `_set_initial_version`
stamps a new database with the installed package version, so a migration
numbered above it would be pending the moment the database was created.

`test_client_update_document_replaces_rows_with_bounded_versions` turns
auto_vacuum off. Indexing `documents` means a background vacuum now has an index
to maintain on that table, so `optimize()` writes a version where it previously
had nothing to do, and it landed inside the window the test measures. The
document update itself is still one version, so the bound stays exact.
2026-08-17 16:34:58 +03:00
Yiorgis Gozadinos
d864cf8008
vb 2026-08-13 16:16:35 +03:00
Yiorgis Gozadinos
771ac9c96c
Register the optional capabilities where agents are composed
The README feature list and the overview stopped at the analysis capability.
Both examples and the app backend composed agents without the capabilities the
documentation recommends alongside an evidence capability.

custom_agent.py ran each input as an independent agent run, so it needed a state
dict and a carried history before compaction could mean anything there: without
state the evidence record is empty, and earlier evidence would reduce to
receipts retaining nothing.
2026-08-13 15:04:05 +03:00
Yiorgis Gozadinos
2cd568847e
Move the wire rewrite into the compaction capability
`_compact_old_tool_returns`, `PRIOR_TURN_NOTICE` and `turn_start` leave
`RAGCapabilityBase`, along with its `wrap_model_request` hook. The evidence
capabilities now retrieve and validate, and nothing else. Registering the compaction
capability is what rewrites a request; leaving it out sends the transcript untouched,
which was never a choice a host could make before.

The boundary is the recorded question identity rather than message shape, so a
resumption compacts what lies below the question in progress instead of switching
compaction off for the whole run. The newest earlier evidence return carries the
capsule and every other becomes a receipt, so one capsule exists by construction and
every return stays paired with its call.

Pictures of cited evidence are fetched through the capability that retrieved them and
re-attached beside the capsule with fresh labels. Ownership of a picture on the wire
requires the machine tag we write and an image directly after it, since neither
position nor prose is proof: several tools' results can arrive in one request, and a
user quoting our wording above their own picture had it removed. A picture that cannot
be fetched or decoded is emitted with neither its image nor its label.

The chat TUI and the example backend register the compactor, being multi-turn.
`client.ask`, `client.analyze` and the MCP tools do not: a single-shot question has
nothing earlier to compact.
2026-08-13 13:00:02 +03:00
Yiorgis Gozadinos
d63199d96d
Keep cross-encoder rerank scores apart when they saturate
mxbai-rerank-base-v2 ships a Sigmoid activation and evaluates it in bf16, so
every strongly-relevant candidate rounds to exactly 1.0. Ties then leave the
order to the stable sort, which preserves the incoming hybrid ranking: on 100
t2_finqa retrieval cases the reranker scored MAP 0.661 against 0.659 with no
reranker at all, and 0.742 once the scores separate.

Ask the model for logits and apply the sigmoid here, where it runs in float64.
Scores stay 0-1, matching the cohere, vllm and zeroentropy rerankers.

Also drop the remaining pyright references; the project type-checks with ty.
2026-08-07 14:07:53 +03:00
Yiorgis Gozadinos
96475bba8c
vb 2026-08-06 13:55:57 +03:00
Yiorgis Gozadinos
5a023a24ad
vb 2026-07-31 15:25:28 +03:00
Yiorgis Gozadinos
adae9eff2e
vb 2026-07-30 19:37:45 +03:00
Yiorgis Gozadinos
ebd1fc7f3e
vb 2026-07-29 09:06:55 +03:00
Yiorgis Gozadinos
ae345cc39f
Map thinking onto Pydantic AI's unified setting 2026-07-27 18:26:42 +03:00
Yiorgis Gozadinos
94e03d777a
vb 2026-07-25 15:11:54 +03:00
Yiorgis Gozadinos
acbd66afbd
vb 2026-07-24 17:32:20 +03:00
Yiorgis Gozadinos
9e7db72997
Load capabilities eagerly for dedicated single-agent consumers 2026-07-24 15:26:17 +03:00
Yiorgis Gozadinos
9deb1f2bd4
replace haiku.skills with native Pydantic AI capabilities 2026-07-24 15:26:17 +03:00
Yiorgis Gozadinos
ec78641cc4
vb 2026-07-24 15:15:20 +03:00
Yiorgis Gozadinos
9f49bdde6e
vb 2026-07-23 14:28:23 +03:00
Yiorgis Gozadinos
294ced57cd
vb 2026-07-23 10:45:48 +03:00
Yiorgis Gozadinos
4f0fb7322e
vb 2026-07-22 13:27:35 +03:00
Yiorgis Gozadinos
b5c0ea630c
vb 2026-07-16 13:50:40 +03:00
Yiorgis Gozadinos
5dd310a9b7
vb 2026-07-14 16:06:50 +03:00
Yiorgis Gozadinos
5c41f8a0ed
vb 2026-07-10 13:38:24 +03:00
Yiorgis Gozadinos
da79f92af1
Honor OTEL_SERVICE_NAME and set service name/version for all processes 2026-07-10 11:11:46 +03:00
Yiorgis Gozadinos
da0748916b
vb 2026-07-09 15:58:58 +03:00
Yiorgis Gozadinos
995d081aa1
Visualize the exact context the model saw via Citation.doc_item_refs
visualize_chunk re-expanded chunks from scratch to recover their refs,
which could not faithfully reproduce the original merge, scores, and
clip — so a visualization could highlight different pages than the
citation covered. Carry the cited items on Citation.doc_item_refs and
resolve bounding boxes from them directly; re-expansion remains only as
the fallback for callers with no stored context (CLI, inspector). Chat,
inspector, the app endpoint, and the frontend pass the refs through.
2026-07-09 11:51:37 +03:00
Yiorgis Gozadinos
494f774473
Visualize all constituent chunks of a merged citation 2026-07-09 11:05:41 +03:00
Yiorgis Gozadinos
a1cf405cae
Rename document_meta identity column document_id to id 2026-07-08 16:32:55 +03:00
Yiorgis Gozadinos
9a9bea86d3
vb 2026-07-03 13:35:10 +03:00
Yiorgis Gozadinos
9a85632cf3
vb 2026-06-29 12:36:36 +03:00
Yiorgis Gozadinos
b2abdfaffb
vb 2026-06-28 10:57:26 +03:00
Yiorgis Gozadinos
c7c3f75508
vb 2026-06-27 09:59:21 +03:00
Yiorgis Gozadinos
cd1a73b389
vb 2026-06-26 17:13:03 +03:00
Yiorgis Gozadinos
1969c4528e
Fix example app 2026-06-26 13:12:53 +03:00
Yiorgis Gozadinos
197d58a602
vb 2026-06-24 18:41:05 +03:00
Yiorgis Gozadinos
ab1775dbc6
vb 2026-06-24 16:45:19 +03:00
Yiorgis Gozadinos
65f1339aa0
vb 2026-06-23 16:59:00 +03:00
Yiorgis Gozadinos
0fcf91fcf7
vb 2026-06-22 15:18:35 +03:00
Yiorgis Gozadinos
5c4b37df89
vb 2026-06-19 11:12:45 +03:00
Yiorgis Gozadinos
99011755fb
vb 2026-06-16 16:48:36 +03:00
Yiorgis Gozadinos
df8af54298
rebase from main 2026-06-12 10:17:18 +03:00
Yiorgis Gozadinos
88696cc6f1
vb 2026-06-11 09:50:33 +03:00
Yiorgis Gozadinos
bdad908a60
vb 2026-06-09 15:39:14 +03:00
Yiorgis Gozadinos
46b8fa3fef
vb 2026-06-08 12:24:04 +03:00
Yiorgis Gozadinos
916b84bff4
vb 2026-06-05 12:09:57 +03:00
Yiorgis Gozadinos
e70f271ac7
vb 2026-06-04 14:13:55 +03:00
Yiorgis Gozadinos
4eae86225e
vb 2026-06-03 14:26:58 +03:00
Yiorgis Gozadinos
8dbcd4bd7a
vb, changelog 2026-06-01 18:54:22 +03:00