Core

Protocols

The dual architecture: the Oracle and Driver protocols.

CADAQUES is agnostic on both sides of the discovery loop:

  • an Oracle is anything that answers queries at a declared price — a simulator, a laboratory instrument, an analytic function;

  • a Driver is anything that decides what to ask next — random search, Bayesian optimization, gradient methods, an LLM agent.

Both sides are metered: the campaign runner charges oracle queries and driver decisions against one budget.

class cadaques.core.protocols.Query(params, fidelity=<factory>, tag='')[source]

A single question to an Oracle.

params are the design/search variables; fidelity are the knobs that trade accuracy for cost (lattice size, mesh density, integration time, …). Keeping fidelity explicit is what makes multi-fidelity, cost-aware campaigns first-class citizens.

Parameters:
class cadaques.core.protocols.Result(query, value, cost, info=<factory>)[source]

An Oracle’s answer, carrying its settled (actual) cost.

Parameters:
class cadaques.core.protocols.Oracle(*args, **kwargs)[source]

Anything that answers queries at a price.

price declares the expected cost ex ante so the runner can check affordability before committing; evaluate performs the query and reports the settled cost inside the Result. Real oracles deviate from their declared price — the ledger records both, and that discrepancy is itself an observable.

class cadaques.core.protocols.Driver(*args, **kwargs)[source]

Anything that decides what to ask next.

propose receives the full history and a read-only view of the budget, enabling budget-aware strategies. observe feeds the settled result back. Drivers that incur their own accountable costs beyond wall time (e.g. LLM tokens) may expose a last_proposal_cost attribute, which the runner will charge.

Cost and budget

Cost primitives: the first-class citizens of CADAQUES.

Every oracle query and every driver decision is priced in a multi-currency Cost and charged against a single Budget. Campaigns end when the budget is exhausted, not when an iteration counter runs out.

cadaques.core.cost.CURRENCIES: tuple[str, ...] = ('seconds', 'cpu_hours', 'euros', 'tokens')

Currencies tracked by the framework. Heterogeneous by design: a DFT relaxation, a beamline measurement and an LLM call are not the same kind of expense.

class cadaques.core.cost.Cost(seconds=0.0, cpu_hours=0.0, euros=0.0, tokens=0.0)[source]

An immutable multi-currency cost vector.

All components default to zero, so Cost(seconds=3.0) prices a 3-second query and Cost() is the free cost.

Parameters:
dominated_by(other)[source]

True if every component of self is <= that of other.

Parameters:

other (Cost)

Return type:

bool

exception cadaques.core.cost.BudgetExceeded[source]

Raised when a charge is attempted beyond the campaign budget.

class cadaques.core.cost.BudgetView(total, spent)[source]

A read-only snapshot of the budget, exposed to Drivers.

Drivers may adapt their strategy to the remaining budget (e.g. explore early, exploit when funds run low) but cannot mutate it.

Parameters:
property fraction_used: float

Largest used fraction across the currencies with a limit.

class cadaques.core.cost.Budget(total, spent=<factory>)[source]

The single budget of a discovery campaign.

Only currencies with a positive total component are limited; the rest are tracked but unbounded. Declared costs are checked with can_afford() before a query is issued; settled costs are charged unconditionally with charge(..., settle=True) — in the real world one discovers an overrun after paying for it, and the ledger keeps the evidence.

Parameters:

Campaign

The Campaign runner: the discovery loop with an accountant inside.

The loop is deliberately small. Its one structural commitment is the framework’s thesis: every query counts. Each iteration prices the oracle query before committing, meters the driver’s decision, and the campaign ends when the budget is exhausted — not when an iteration counter runs out.

exception cadaques.core.campaign.DriverStopped[source]

A Driver may raise this to end a campaign early.

class cadaques.core.campaign.CampaignResult(best: 'Result | None', history: 'list[Result]', ledger: 'Ledger', budget: 'Budget', stop_reason: 'StopReason', _maximize: 'bool' = True)[source]
Parameters:
trace(currency='seconds')[source]

(cumulative settled cost, best-so-far value) — the signature cost-normalized curve of a CADAQUES campaign.

Parameters:

currency (str)

Return type:

list[tuple[float, float]]

class cadaques.core.campaign.Campaign(oracle, driver, budget, *, maximize=True, meter_driver=True)[source]

Couple one Oracle to one Driver under one Budget.

Parameters:

Ledger

The campaign ledger: every transaction, declared and settled.

The ledger is the accounting record of a discovery campaign and, almost for free, its provenance and replay substrate: exporting it to JSONL yields a complete, reproducible trace of what was asked, what it was expected to cost, and what it actually cost.

class cadaques.core.ledger.Transaction(kind: 'TransactionKind', label: 'str', declared: 'Cost', settled: 'Cost', timestamp: 'float' = <factory>, meta: 'Mapping[str, Any]'=<factory>)[source]
Parameters:
property overrun: Cost

the price of optimism.

Type:

Settled minus declared

class cadaques.core.ledger.Ledger(transactions=<factory>)[source]

Append-only record of all campaign transactions.

Parameters:

transactions (list[Transaction])

cumulative(kind=None)[source]

Yield (transaction, running settled total) pairs.

Parameters:

kind (Literal['oracle', 'driver'] | None)

Return type:

Iterator[tuple[Transaction, Cost]]