Interface: SqlSpendMeterOptions
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:184
Properties
db
db:
StorageAdapter
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:185
ensureSchema?
optionalensureSchema:boolean
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:234
Create the tables when they are missing, and on tables that exist the indexes they lack (see SqlSpendMeter.ensureSchema). Default true. With false the meter runs no DDL: the product's own migrations make the tables and their indexes.
leaseMs?
optionalleaseMs:number
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:202
How long a reservation lives without a heartbeat. Default 45 seconds.
maxAttemptsPerOperation?
optionalmaxAttemptsPerOperation:number
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:204
Reservations an operation may take in all, its retries after a release included. Default 3.
requireShared?
optionalrequireShared:boolean
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:228
Refuse a store that several processes cannot share (no transactions, no persistence or no concurrent access): a SQLite file per process would give every instance an allowance of its own. Default true; tests pass false.
retry?
optionalretry:SpendRetryPolicy
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:205
tablePrefix?
optionaltablePrefix:string
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:247
The start of the two tables' names: <prefix>_meter and <prefix>_reservations, their indexes named after them
(idx_<prefix>_reservations_*). Default agentos_spend, the names SPEND_METER_DDL makes, whose indexes
are idx_spend_reservations_*. Meters with different rules share one database each under a prefix of its own, so
one's count and one's purge never reach another's rows; meters under one prefix share its tables.
A lower-case letter, then at most 37 lower-case letters, digits or underscores, and not spend, whose index names
are the default prefix's. At 38 characters the longest names the meter gives, idx_<prefix>_reservations_account
and idx_<prefix>_reservations_settled, take the 63 bytes Postgres keeps of an identifier. The constructor checks
the prefix before any statement is built and throws on any other value, so nothing unchecked reaches the SQL text.
spendMeterDdl makes the tables for a prefix.
unknownAfterLease?
optionalunknownAfterLease:"release"|"consume"
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:223
How an expired reservation settles when the product cannot tell. Default release: the person is not charged for a turn nobody saw finish.
windowMs?
optionalwindowMs:number
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:200
A rolling window in milliseconds. The allowance then holds the units consumed in the windowMs before each
reservation and every unit still reserved, counted from the reservations themselves under the account's row lock,
and every row of the account carries the period window. A consumed unit has left the window once more than
windowMs have passed since its reservation; one still reserved counts whatever its age, until it settles; a
released one never counts.
Methods
allowanceFor()
allowanceFor(
accountId,period):number|Promise<number>
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:187
The account's allowance for a period, in units. Read at every reservation, so a plan change applies at the next turn.
Parameters
accountId
string
period
string
Returns
number | Promise<number>
onWarning()?
optionalonWarning(warning):void
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:256
Told of each statement that failed while SqlSpendMeter.ensureSchema brought tables that exist up to the
meter's indexes, with the statement and the error the store threw: the CREATE INDEX of an index the tables lack
(refused, for example, to a role that does not own them, or stopped by a lock or statement timeout), or the read of
the catalogue before them. Such a failure is not fatal: the indexes speed the meter's reads and change none of its
answers, so the meter uses the tables as they are. An error the callback throws is dropped. Without a callback,
nothing is reported.
Parameters
warning
error
unknown
statement
string
Returns
void
periodOf()?
optionalperiodOf(now,accountId):string|Promise<string>
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:192
The period a moment falls in for an account, e.g. its calendar month in its own time zone ("2026-10"). Required
unless windowMs is set; with a window it is not read.
Parameters
now
number
accountId
string
Returns
string | Promise<string>
resolveExpired()?
optionalresolveExpired(reservation):SpendExpiryDecision|Promise<SpendExpiryDecision>
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:221
Asked by SqlSpendMeter.reconcile for each expired reservation, in place of resolveUnknown and
unknownAfterLease: consumed, released, or deferred until retryAt with its evidence, which stays reserved and
counted. A resolver that throws defers the reservation for one lease; it never falls through to a default outcome.
An answer is written only to the attempt it was asked about and only while that attempt's lease is still out at the
pass's now, so an operation released and retried while it is asked keeps the retry reserved under its own lease,
and a lease a heartbeat renewed, or a deferral another pass made to a next check after now, stands meanwhile.
Parameters
reservation
Returns
SpendExpiryDecision | Promise<SpendExpiryDecision>
resolveUnknown()?
optionalresolveUnknown(reservation):SpendUnknownResolution|Promise<SpendUnknownResolution>
Defined in: packages/agentos/src/safety/runtime/SqlSpendMeter.ts:212
Asked by SqlSpendMeter.reconcile for each expired reservation on a meter without resolveExpired, except
one made with requireFence or deferred before, which such a meter leaves reserved. Its answer settles the
reservation only if, when the pass writes it, the reservation is still the attempt asked about, still past its
lease and still unfenced: one an opted-in pass defers, or a heartbeat renews, while it is asked stays reserved.
Parameters
reservation
accountId
string
operationId
string
period
string
units
number
Returns
SpendUnknownResolution | Promise<SpendUnknownResolution>