Adds token limits under launch.limits.tokens (instances, providers, keys, models.P.M). Core (packages/bus/src/limits.mjs) reads the organization file and the per-turn usage records row 124 writes, then asks every switched-on limit-check plug-in; the first refusal wins. A limit no switched-on check reports reads "not enforced". The limit-check kind is interface 2 (mayLaunch, mustStop, report); a v1 check is refused at load. The shipped token-limit check is pure and counts known end records only; unknown turns add nothing and are shown as their own count. The launcher refuses limit-reached through the host's mayLaunch op, or limit-check-failed naming the check. The broker asks mustStop after a usage end and stops the run at its next receive or state. Settings stamps since on a new or changed limit and runs reset; launch.mjs and business.mjs validate the shape. Readers: mosaic limits and mosaic limits reset, the bus limits view, the Console /api/bus/limits route and the Settings token table with Reset. Key limits stay "not enforced" until row 126 names accounts on records. Owner Dewey, design under lead decision 150. Reviewer Filbert: r1 changes (comment 28965), r2 approve (28981), r3 approve (28996) on candidate manifest 8b71c405...fe56 after the rebase onto row 164 (37 of 38 paths with identical +/- lines, TOOLS.md:621 bracket). Decision 123 go on the bus.js hunk from Mos (mos-0814). Sage gate onb6827d19e: 25 steps, all rc 0 (15 packages, 10 script suites), 2295 node tests and 422 script selftests, 0 failed, 20:03:25Z to 20:08:08Z, network sage-r125_default removed. Live stays as pinned. Not part of the8e7ea89a1window. Co-Authored-By: Claude Opus 5.5 <[email protected]>
31 lines
1.6 KiB
Markdown
31 lines
1.6 KiB
Markdown
# Token limit check
|
|
|
|
Row 125 (#1619), REQ-LIMIT-3 and REQ-LIMIT-4, limit-check interface 2. Enable
|
|
with `"plugins": { "limit-check": ["token-limit"] }` in the organization file,
|
|
keeping its other plug-in kinds. Human changes use `mosaic plugins set` and the
|
|
current revision.
|
|
|
|
It enforces `launch.limits.tokens`: per role instance (`instances`), provider
|
|
(`providers`), provider and model (`models.<provider>.<model>`) and key
|
|
(`keys`). Each limit is `{limit, since}`.
|
|
|
|
- A count is `input + output + cacheWrite + cacheRead` summed over the known
|
|
per-turn records whose subject matches and whose `at` is at or after `since`.
|
|
An unknown turn adds nothing; `unknownTurns` counts the distinct unknown
|
|
turns apart, so a count is a floor, not proof.
|
|
- With no usage source switched on, every turn's record is unknown (source
|
|
`@none`), so every limit counts zero.
|
|
- `mayLaunch` and `mustStop` answer the first limit, in the order above, that
|
|
covers the subject and whose count is at or over it. A limit of 0 refuses
|
|
every launch of its subject.
|
|
- A key matches a record's `account`. Until accounts are named (row 126),
|
|
every record's account is null, so a key limit matches nothing and `report`
|
|
shows it as `not enforced: no records name a key` (lead decision 150, Q1).
|
|
- Counts are summed as BigInt; one past `Number.MAX_SAFE_INTEGER` is reported
|
|
as a digit string.
|
|
|
|
The module is pure: it reads no file and no store. A bad `since` or record
|
|
`at` throws `bad-time`, a bad amount `bad-record`, and records that aren't a
|
|
list `bad-records`; core turns any throw into a refusal, a stop, or `check
|
|
failed` (fail closed).
|