Search¶
chronicle.search runs Vertex-backed semantic search across your research docs, experiment metadata, and arxiv assets, filtered to what you're allowed to read.
query is the primitive: it hits POST /search, returns one page of SearchResult hits ranked by relevance, and takes filters, an experiment-context boost, and a hard scope. history is a thin alias for searching your internal corpus; iter walks every page for you.
ACL- and namespace-filtered server-side
The server applies RBAC and storage-prefix isolation before ranking — you only ever see hits you can read, so you never filter for them yourself. SearchFilters layers on top of those server filters. POST /search is Vertex-backed and returns 503 where Vertex isn't configured (local dev, CI without credentials) — catch methodic.errors.ServerError and check status_code == 503 to gate against that.
query¶
resp = chronicle.search.query(
"shock formation in 2D compressible Euler",
filters={"asset_types": ["research_report"], "created_after": "2026-01-01"},
)
for hit in resp.results:
print(hit.relevance_score, hit.title, hit.document_id)
print(resp.total_size, resp.next_page_token)
Parameters:
| Param | Type | Effect |
|---|---|---|
query |
str |
The semantic query string. |
filters |
SearchFilters \| dict \| None |
Narrowing filters (table below). |
experiment_context |
list[str] \| None |
Experiment ids that boost lineage-related hits — does not exclude others. |
scope |
SearchScope \| dict \| None |
Hard filter to a union of collections + experiments (see below). |
page_size |
int \| None |
Hits per page. |
page_token |
str \| None |
Cursor from a prior next_page_token. |
SearchFilters fields:
| Field | Matches on |
|---|---|
asset_types |
restrict to listed asset types (e.g. ["research_report"]) |
created_by |
author principal |
created_after / created_before |
creation-time window |
source_type |
source of the indexed doc |
tags |
hits carrying any listed tag (human-facing label names) |
organization_id / team_id |
owning scope |
Boost vs. scope¶
experiment_context and scope both name experiments but do opposite things. experiment_context boosts lineage-related hits while leaving the rest of the corpus in play. scope is a hard filter — results are restricted to the resolved union of the named collections and experiments, ANDed with the server's ACL filter:
from methodic import SearchScope
resp = chronicle.search.query(
"spectral loss instabilities",
scope=SearchScope(collections=["col_pde"], experiments=["exp_7Qk"]),
)
To scope to your current experiment, pass an empty SearchScope() together with experiment_context — the empty scope flips those anchors from boost to hard-scope.
history — your internal corpus¶
history searches Chronicle's internal corpus: your experiment history and internal research documents (hypotheses, takeaways, research reports, experiment metadata). It's a semantic alias for query with the common narrowing knobs lifted into keyword args (created_by, created_after, created_before, asset_types) and assembled into a SearchFilters — same POST /search endpoint, same ACL scoping.
resp = chronicle.search.history(
"did increasing viscosity stabilize the rollout?",
asset_types=["research_report"],
created_after="2026-03-01",
)
asset_types defaults to None; Chronicle already excludes session assets server-side, so the unfiltered corpus is the right default. history takes no scope or source_type — reach for query when you need those.
No external literature
history does not search arxiv or external papers — that's served by a separate external MCP, not by this API.
iter — paginate¶
iter yields every hit across all pages, fetching the next page server-side as it goes. Same query/filters/experiment_context/scope/page_size parameters as query; no page_token (it manages the cursor):
for hit in chronicle.search.iter(
"neural operator generalization across Reynolds numbers",
filters=SearchFilters(asset_types=["research_report"]),
page_size=50,
):
print(hit.title, hit.relevance_score)
Result fields¶
Each SearchResult carries document_id, source_type, relevance_score, and lineage_boost always, plus optional asset_type, title, snippet, experiment_ids, and created_at. A SearchResponse wraps results, total_size, and next_page_token (None on the last page). Full field list: reference/client.md.