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.
paramsare the design/search variables;fidelityare 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.
- class cadaques.core.protocols.Result(query, value, cost, info=<factory>)[source]¶
An Oracle’s answer, carrying its settled (actual) cost.
- class cadaques.core.protocols.Oracle(*args, **kwargs)[source]¶
Anything that answers queries at a price.
pricedeclares the expected cost ex ante so the runner can check affordability before committing;evaluateperforms 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.
proposereceives the full history and a read-only view of the budget, enabling budget-aware strategies.observefeeds the settled result back. Drivers that incur their own accountable costs beyond wall time (e.g. LLM tokens) may expose alast_proposal_costattribute, 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 andCost()is the free cost.
- 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.
- class cadaques.core.cost.Budget(total, spent=<factory>)[source]¶
The single budget of a discovery campaign.
Only currencies with a positive
totalcomponent are limited; the rest are tracked but unbounded. Declared costs are checked withcan_afford()before a query is issued; settled costs are charged unconditionally withcharge(..., settle=True)— in the real world one discovers an overrun after paying for it, and the ledger keeps the evidence.
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.
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:
- class cadaques.core.ledger.Ledger(transactions=<factory>)[source]¶
Append-only record of all campaign transactions.
- Parameters:
transactions (list[Transaction])