nw.pricing#
Re-quoting a persisted plan at today’s rates (nw#74).
nw writes cost figures into places that are read back later: a
render-decision payload, a RenderResultBodyV1 body, a job’s cost gate.
Each of those numbers is a falaw.CallPlan.estimated_cost_usd frozen at
plan time. falaw’s rate tables move — 0.0.46 re-quoted every premium LLM call
tenfold upward — so a figure nw stored before a table moves under-quotes the
run it is later used to describe or gate. Under-quoting is the one direction a
spend decision must never err in.
falaw 0.0.49 (falaw#60) supplies the two halves of the fix:
falaw.CostBasis (which pricer, what it priced, the quantity hints,
the rate table and its content digest) and falaw.reprice_plan() (pure
data: no network, no billing API, no cache peek). This module is nw’s single
adoption point for them, and it enforces one rule:
A stored figure is never reported as current. Reading a persisted cost
means calling current_quote() first and reporting
PlanQuote.total_usd with PlanQuote.status beside it. A plan
whose calls carry no basis re-prices to None — unknown, never its stale
number, and never zero.
Two things this module deliberately does not do:
It does not touch cache identity.
cost_basisis descriptive: falaw omits it from the serialized call when unset and keeps it out ofplan_hashand the per-call cache key. So a resumed render still dedups on the same digest, andnw.jobs.enqueue()’s idempotency key is unmoved by anything here —tests/test_pricing.pypins that.It does not re-quote money already spent.
nw.Project.total_spend_usd()sums what was billed, and a receipt isnot a quote: re-pricing it at today’s rates would rewrite history. Its estimate-based fallback is an as-of figure and says so.
>>> from falaw import CallPlan, Plan
>>> stale = CallPlan(tool="text_to_video", application="fal-ai/x",
... arguments={}, output_kind="video",
... estimated_cost_usd=0.25)
>>> quote = current_quote(Plan(calls=(stale,)))
>>> quote.status, quote.total_usd, quote.as_of_total_usd
('unknown', None, 0.25)
Module Attributes
What a re-quote was able to say about a whole plan. |
|
How far a payload's stored total may sit from its calls' sum and still agree. |
|
Why a payload with an internally inconsistent total re-prices as unknown. |
Functions
|
The JSON-able per-call cost rows nw persists in a decision payload. |
|
Re-quote |
|
Rebuild a re-quotable |
|
Today's price for the calls stored in a decision payload. |
|
Today's price for a |
|
A quote for something that could not be re-quoted at all. |
Classes
|
Today's price for a persisted plan, with the stale figure alongside. |
- nw.pricing.DISAGREEING_TOTAL_REASON = "the payload's total_estimated_cost_usd does not match the sum of its calls, so neither figure can be trusted as this render's price"#
Why a payload with an internally inconsistent total re-prices as unknown.
- class nw.pricing.PlanQuote(*, total_usd, status, as_of_total_usd, repriced, reason='')[source]#
Bases:
objectToday’s price for a persisted plan, with the stale figure alongside.
The stale figure is kept — as
as_of_total_usd, explicitly named “as of then” — because an audit surface wants to show the movement. What it must never do is present it as current; that is whattotal_usdandstatusare for.- as_of_total_usd: float | None#
What the persisted plan said,
Noneif it already said unknown.A fact about the moment it was written. Render it labelled as such, or not at all.
- property basis_changed: bool#
True when a rate table moved underneath at least one call.
The audit answer the frozen number could never give: it separates “the price changed because the table changed” from “the price changed because the plan did”. Read it beside
status— achangedwith thisFalseis a caller quoting different quantities, not a repricing event.
- property delta_usd: float | None#
total_usd - as_of_total_usd, orNonewhen either is unknown.Nonerather than0.0: a plan that lost its price did not move by zero.
- property has_unknown_costs: bool#
True when the total cannot be known — the gate’s refusal condition.
The same judgement as
falaw.Plan.has_unknown_costs, made at re-quote time rather than at plan time.
- reason: str#
Why the whole quote is unknown, when that is the situation.
Set by
unquotable()(the thing handed in was not a plan) and byquote_render_decision()(the payload contradicts itself). Empty for an ordinary re-quote, where the per-call reasons live onrepricedinstead.
- repriced: RepricedPlan#
falaw’s per-call diff —
status,basis_changed,reasonper call. Read it for the audit view;total_usdis the headline.
- status: Literal['unchanged', 'changed', 'unknown']#
Which of the three cases this plan fell into — see
QuoteStatus.
- nw.pricing.QuoteStatus#
What a re-quote was able to say about a whole plan.
"unchanged"— every billable call re-quoted, and the total did not move."changed"— re-quoted, and at least one call’s price moved. The total inPlanQuote.total_usdis today’s; the stored one was yesterday’s."unknown"— at least one billable call could not be re-quoted (no basis, no pricer, a model that left the catalogue, a table that moved out from under it).PlanQuote.total_usdisNone: unknown, never free, and never the frozen figure.
alias of
Literal[‘unchanged’, ‘changed’, ‘unknown’]
- nw.pricing.TOTAL_AGREEMENT_ABS_TOL_USD = 1e-09#
How far a payload’s stored total may sit from its calls’ sum and still agree.
Floating-point slack on a sum of a handful of costs, nothing more — far below the smallest sub-cent figure any rate table quotes, so it can never absorb a real disagreement.
- nw.pricing.cost_records(plan)[source]#
The JSON-able per-call cost rows nw persists in a decision payload.
A serialized call cannot be re-quoted from
applicationandargumentsalone — the quantity hints that priced it are estimator-only and never reach the wire arguments. Carryingcost_basisalongside the frozen figure is what makes the row re-quotable later byquote_from_cost_records().cost_basisis omitted when unset, exactly as falaw omits it, so a row written by a caller that records no basis is byte-identical to what nw wrote before nw#74.>>> from falaw import CallPlan, Plan >>> call = CallPlan(tool="t", application="a", arguments={}, ... output_kind="video", estimated_cost_usd=1.0) >>> sorted(cost_records(Plan(calls=(call,)))[0]) ['application', 'cache_status', 'estimated_cost_usd', 'tool']
- nw.pricing.current_quote(plan, *, pricers={'llm_rates': Pricer(quote=<function _quote_from_llm_rates>, table='falaw/data/llm_rates.json', version=<functools._lru_cache_wrapper object>), 'model_catalogue': Pricer(quote = <function _quote_from_catalogue>, table='falaw/data/models.json', version=<functools._lru_cache_wrapper object>)})[source]#
Re-quote
planat today’s rates and report the result honestly.Pure data —
falaw.reprice_plan()reads the committed rate tables and does arithmetic. No network, no billing API, no cache peek, so this is safe to call anywhere aplan()is (nw invariant #1).- Parameters:
plan (
Plan) – The plan to re-quote — typically one just rebuilt from a stored payload withplan_from_cost_records().pricers (
Mapping[str,Pricer]) – Pricing rules byfalaw.CostBasis.pricer. The seam for a caller with reconciled numbers of their own; seefalaw.reprice.Pricer.
- Return type:
>>> from falaw import Plan >>> current_quote(Plan(calls=())).status 'unchanged'
- nw.pricing.plan_from_cost_records(records)[source]#
Rebuild a re-quotable
falaw.Planfromcost_records()rows.The result is a pricing plan, not an executable one:
argumentsis empty andoutput_kindis a placeholder, because a stored cost row does not carry the wire payload and re-pricing does not read it. Never hand one of these tofalaw.execute_plan()— build a fresh plan for that.Rows missing
cost_basiscome back basis-free, which is exactly what makes them re-price as"no_basis"(unknown) rather than as their frozen number.- Return type:
Plan
- nw.pricing.quote_from_cost_records(records, *, pricers={'llm_rates': Pricer(quote=<function _quote_from_llm_rates>, table='falaw/data/llm_rates.json', version=<functools._lru_cache_wrapper object>), 'model_catalogue': Pricer(quote = <function _quote_from_catalogue>, table='falaw/data/models.json', version=<functools._lru_cache_wrapper object>)})[source]#
Today’s price for the calls stored in a decision payload.
The read-back half of
cost_records().Noneor a non-sequence (a payload that recorded no calls at all) yields an empty plan’s quote —total_usd == 0.0,status == "unchanged"— because “no calls” is a known zero, not an unknown.- Return type:
- nw.pricing.quote_render_decision(payload, *, pricers={'llm_rates': Pricer(quote=<function _quote_from_llm_rates>, table='falaw/data/llm_rates.json', version=<functools._lru_cache_wrapper object>), 'model_catalogue': Pricer(quote = <function _quote_from_catalogue>, table='falaw/data/models.json', version=<functools._lru_cache_wrapper object>)})[source]#
Today’s price for a
render_shotdecision payload.The counterpart to what
nw.workflow._record_render_decision()wrote. Read this — neverpayload["total_estimated_cost_usd"]— whenever a stored render cost is about to be shown or gated on as a current figure.A payload written before nw#74 carries no per-call basis, so it re-quotes as
"unknown"withtotal_usdNone. That is the point: nobody can say what it costs today, and saying so is better than repeating a number that has since moved.The stored
total_estimated_cost_usdis the payload’s own headline, so it — not the calls’ sum — is reported asPlanQuote.as_of_total_usd. When the two disagree, the whole payload is unknown: a total of $3 over a payload whose calls sum to $0 is a broken record, and answering “$0, unchanged” would report a stored $3 as a known zero. nw’s own writer never produces such a payload; a hand-edited or truncated one can, and unknown is the only honest reading of it.- Return type:
>>> broken = quote_render_decision( ... {"calls": [], "total_estimated_cost_usd": 3.0}) >>> broken.status, broken.total_usd, broken.as_of_total_usd ('unknown', None, 3.0) >>> stale = quote_render_decision( ... {"calls": [{"tool": "t", "application": "a", ... "estimated_cost_usd": 3.0}], ... "total_estimated_cost_usd": 3.0}) >>> stale.status, stale.total_usd, stale.as_of_total_usd ('unknown', None, 3.0)
- nw.pricing.unquotable(reason)[source]#
A quote for something that could not be re-quoted at all.
For the caller who was handed a plan-shaped thing that turned out not to be a plan — an unparseable payload, an object of the wrong type. The honest answer is
None(unknown), not the frozen figure that came with it, and not0.0.PlanQuote.repricedis an emptyfalaw.RepricedPlan: there were no calls to diff. ReadPlanQuote.reasonfor what went wrong.- Return type:
>>> q = unquotable("params['plan'] is not a falaw Plan") >>> q.status, q.total_usd, q.has_unknown_costs ('unknown', None, True)