Files
zeekay 45338077fd hanzo-research 0.3.0: measure what the org does not already hold
key(run) is the sha256 the cloud derives as a run's key: benchmark,
split, system, version, k, temperature, max_tokens, embedder, reader and
the four digests, each as text and NUL-terminated.  tests/test_measure.py
holds the vectors hanzo-inc/cloud's apps/research TestKeyVector does.
Run keeps the crate's fields; the key is computed, not carried.

Research.measure(identity, fn, force=False) asks for a complete run under
that key and returns the latest to end without calling fn.  A miss, a
partial run or force calls fn, records the run and returns it as read
back.  fn may not change an identity field.

Arena.post_run follows the arena: it answers the latest run held per
benchmark, or that nothing was queued, and spends nothing, so confirm,
endpoint and attempts go.  Admission becomes Measurements.

Claude-Session: https://claude.ai/code/session_01M8RoubcPN71KgJuZ8LdBUL
2026-10-15 14:53:44 -07:00

202 lines
5.2 KiB
Python

"""Hanzo Research: file measurements to `/v1/research` and `/v1/benchmark` with their provenance.
from hanzo_research import Research, Run, capture, now
r = Research() # HANZO_API_KEY, else `hanzo auth token`
p = capture(model="kai-1.3", weights="/models/kai-1.3", device="cpu", dtype="f32")
run = Run(id="demo.latency-dev-cpu-kai", benchmark="demo.latency", split="dev",
questions=200, answered=200, when=p.date)
run.put("all", "p50_ms", 38.3, n=200, of=200)
run.ended = now()
p.apply(run) # commit, system, version, by, notes
r.record(runs=[run])
r.grant(run.id, visibility="public", publishable=True)
r.get_run(run.id, org="hanzo") # the public read, no credential
The Rust peer is the `hanzo-research` crate (hanzoai/ml): the same wire records, the same
RFC 8785 digests, the same lineage and WAL records.
"""
from . import wal, wire, lineage, benchmark, canonical, provenance
from .wal import ResearchWal
from .wire import (
IDENTITY,
Ack,
Gap,
Run,
Batch,
Delta,
Paper,
Split,
Study,
Census,
Record,
Stored,
Totals,
Listing,
Measure,
Summary,
Artifact,
Benchmark,
KindTotal,
Comparison,
Difference,
key,
now,
left,
scope,
token,
claimed,
completion,
)
from .client import DEFAULT_LIBS, Research, Experiment
from .errors import Error, Denied, Invalid, Limited, Missing, Unavailable
from .benchmark import Arena
from .canonical import digest, canonicalize
from .transport import VERSION
from .provenance import Provenance, capture
__version__ = VERSION
__all__ = [
"Research",
"Experiment",
"Arena",
"DEFAULT_LIBS",
"Split",
"Benchmark",
"Measure",
"Run",
"Study",
"Paper",
"Difference",
"Delta",
"Comparison",
"Census",
"Gap",
"Listing",
"Batch",
"Stored",
"Artifact",
"Record",
"Ack",
"KindTotal",
"Totals",
"Summary",
"completion",
"IDENTITY",
"key",
"token",
"claimed",
"left",
"scope",
"now",
"canonicalize",
"digest",
"Provenance",
"capture",
"ResearchWal",
"Error",
"Denied",
"Missing",
"Invalid",
"Limited",
"Unavailable",
"benchmark",
"canonical",
"lineage",
"provenance",
"wal",
"wire",
"configure",
"client",
"experiment",
"query",
"totals",
"record",
"benchmarks",
"runs",
"studies",
"papers",
"compare",
"measure",
]
_default: Research | None = None
def configure(**kwargs) -> Research: # type: ignore[no-untyped-def]
"""Set the process-wide default client (base, api_key, project, repo, libs, timeout, org)."""
global _default
_default = Research(**kwargs)
return _default
def client() -> Research:
"""The process-wide default client, built from the environment on first use."""
global _default
if _default is None:
_default = Research()
return _default
def experiment(
kind: str,
subject: str,
task: str,
metric: str = "accuracy",
n_total: int = 0,
note: str = "",
hypothesis: str = "",
predict: str = "",
) -> Experiment:
"""An experiment handle on the default client (see `Experiment`)."""
return client().experiment(
kind, subject, task, metric=metric, n_total=n_total, note=note, hypothesis=hypothesis, predict=predict
)
def query(project: str | None = None, kind: str | None = None) -> list[Record]:
"""Canonical experiments on the default client."""
return client().query(project=project, kind=kind)
def totals(project: str | None = None) -> Totals:
"""The headline totals on the default client."""
return client().totals(project=project)
def record(benchmarks=(), runs=(), studies=(), papers=()) -> dict[str, Batch]: # type: ignore[no-untyped-def]
"""File benchmarks, studies, runs and papers on the default client (see `Research.record`)."""
return client().record(benchmarks=benchmarks, runs=runs, studies=studies, papers=papers)
def benchmarks(**filters) -> list[Benchmark]: # type: ignore[no-untyped-def]
"""Canonical benchmark definitions on the default client."""
return client().benchmarks(**filters)
def runs(**filters) -> Listing: # type: ignore[no-untyped-def]
"""Canonical runs on the default client; `org=` reads another org's public runs."""
return client().runs(**filters)
def studies(**filters) -> list[Study]: # type: ignore[no-untyped-def]
"""Canonical studies on the default client."""
return client().studies(**filters)
def papers(**filters) -> list[Paper]: # type: ignore[no-untyped-def]
"""Canonical papers on the default client."""
return client().papers(**filters)
def compare(a: str, b: str) -> Comparison:
"""Two runs side by side on the default client."""
return client().compare(a, b)
def measure(identity, fn, force: bool = False) -> Run: # type: ignore[no-untyped-def]
"""The org's complete run under `key(identity)`, else `fn`'s results recorded (see `Research.measure`)."""
return client().measure(identity, fn, force=force)