@north-light/cli 0.3.550 → 0.3.552

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/api/client.d.ts +11 -0
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/charges.d.ts +122 -0
  6. package/dist/api/dto/charges.js +0 -0
  7. package/dist/api/dto/usage.d.ts +3 -3
  8. package/dist/api/index.d.ts +1 -0
  9. package/dist/api/index.js +1 -1
  10. package/dist/api/routes.d.ts +3 -0
  11. package/dist/api/routes.js +1 -1
  12. package/dist/builtin-memory/crouter-sdk/release-notes.md +10 -0
  13. package/dist/clients/attach/viewer.js +50 -50
  14. package/dist/commands/sys/spend.d.ts +1 -0
  15. package/dist/commands/sys/spend.js +3 -0
  16. package/dist/commands/sys.js +1 -1
  17. package/dist/core/canvas/canvas.js +4 -4
  18. package/dist/core/canvas/export-sqlite.js +2 -2
  19. package/dist/core/canvas/import-sqlite.js +1 -1
  20. package/dist/core/canvas/person.js +7 -16
  21. package/dist/core/canvas/schema-pg.sql +61 -0
  22. package/dist/core/canvas/types.d.ts +4 -0
  23. package/dist/core/config.js +1 -1
  24. package/dist/core/grants/mirror.d.ts +2 -1
  25. package/dist/core/grants/mirror.js +2 -2
  26. package/dist/core/ledger/backfill.d.ts +12 -0
  27. package/dist/core/ledger/backfill.js +22 -0
  28. package/dist/core/ledger/charges.d.ts +18 -0
  29. package/dist/core/ledger/charges.js +1 -0
  30. package/dist/core/ledger/check.d.ts +44 -0
  31. package/dist/core/ledger/check.js +7 -0
  32. package/dist/core/ledger/index.d.ts +9 -0
  33. package/dist/core/ledger/index.js +1 -0
  34. package/dist/core/ledger/limits.d.ts +15 -0
  35. package/dist/core/ledger/limits.js +3 -0
  36. package/dist/core/ledger/months.d.ts +6 -0
  37. package/dist/core/ledger/months.js +1 -0
  38. package/dist/core/ledger/payer.d.ts +34 -0
  39. package/dist/core/ledger/payer.js +1 -0
  40. package/dist/core/ledger/read.d.ts +44 -0
  41. package/dist/core/ledger/read.js +3 -0
  42. package/dist/core/ledger/totals.d.ts +19 -0
  43. package/dist/core/ledger/totals.js +4 -0
  44. package/dist/core/ledger/types.d.ts +66 -0
  45. package/dist/core/ledger/types.js +0 -0
  46. package/dist/core/llm/run.d.ts +17 -5
  47. package/dist/core/llm/run.js +2 -2
  48. package/dist/core/providers/call.d.ts +7 -1
  49. package/dist/core/providers/call.js +1 -1
  50. package/dist/core/providers/errors.js +1 -1
  51. package/dist/core/providers/receipts.d.ts +7 -1
  52. package/dist/core/providers/receipts.js +1 -3
  53. package/dist/core/runs/operations.d.ts +1 -0
  54. package/dist/core/runs/operations.js +7 -7
  55. package/dist/core/runtime/broker/cli-relay.js +1 -1
  56. package/dist/core/runtime/broker/model-adapter.js +2 -2
  57. package/dist/core/runtime/broker/turn-cause.d.ts +7 -0
  58. package/dist/core/runtime/broker/turn-cause.js +1 -0
  59. package/dist/core/runtime/broker.js +1 -1
  60. package/dist/core/runtime/nodes.d.ts +2 -0
  61. package/dist/core/runtime/nodes.js +1 -1
  62. package/dist/core/runtime/recycle.js +1 -1
  63. package/dist/core/runtime/reset.js +1 -1
  64. package/dist/core/runtime/revive.js +2 -2
  65. package/dist/core/runtime/spawn.d.ts +2 -0
  66. package/dist/core/runtime/spawn.js +2 -2
  67. package/dist/core/runtime/start-check.d.ts +15 -0
  68. package/dist/core/runtime/start-check.js +1 -0
  69. package/dist/core/runtime/warm-pool.js +1 -1
  70. package/dist/core/user-settings.d.ts +4 -0
  71. package/dist/core/user-settings.js +1 -1
  72. package/dist/daemon/api/app-listener.js +13 -13
  73. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  74. package/dist/daemon/api/handlers/charges.d.ts +3 -0
  75. package/dist/daemon/api/handlers/charges.js +1 -0
  76. package/dist/daemon/api/handlers/llm.d.ts +9 -5
  77. package/dist/daemon/api/handlers/llm.js +3 -3
  78. package/dist/daemon/api/handlers/messages.js +2 -2
  79. package/dist/daemon/api/handlers/providers.d.ts +2 -0
  80. package/dist/daemon/api/handlers/providers.js +1 -1
  81. package/dist/daemon/api/handlers/run-routes.js +1 -1
  82. package/dist/daemon/api/handlers/runs.d.ts +1 -1
  83. package/dist/daemon/api/handlers/runs.js +1 -1
  84. package/dist/daemon/api/operations.js +1 -1
  85. package/dist/daemon/api/router.d.ts +8 -0
  86. package/dist/daemon/api/router.js +1 -1
  87. package/dist/daemon/api/server.js +1 -1
  88. package/dist/daemon/cron/authority.d.ts +1 -1
  89. package/dist/daemon/cron-run.js +2 -2
  90. package/dist/daemon/crtrd.js +10 -10
  91. package/dist/daemon/fleet.js +4 -4
  92. package/dist/daemon/reconcilers/action-lane.js +1 -1
  93. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +2 -0
  94. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  95. package/dist/doc-editor/editor.css +1 -1
  96. package/dist/doc-editor/editor.js +16 -16
  97. package/dist/types.d.ts +4 -0
  98. package/docs/sdk/release-notes.md +10 -0
  99. package/package.json +2 -2
  100. package/packages/crouter-identity/package.json +1 -1
  101. package/runtime.lock.json +13 -13
  102. package/dist/core/usage/ledger.d.ts +0 -49
  103. package/dist/core/usage/ledger.js +0 -10
package/dist/types.d.ts CHANGED
@@ -402,6 +402,10 @@ export interface ScopeConfig {
402
402
  paths?: {
403
403
  user_files?: string;
404
404
  };
405
+ /** The money ledger. `take_pct` (0-100, default 0) is Northlight's take on each priced model or tool charge; at 0 no take rows are written. */
406
+ ledger?: {
407
+ take_pct?: number;
408
+ };
405
409
  /** Conversation store configuration for the daemon. */
406
410
  store?: {
407
411
  root?: string;
@@ -7,6 +7,16 @@ description: Behavior changes in @north-light/sdk that an app must act on, newes
7
7
 
8
8
  Changes to `@north-light/sdk` that can change what an existing app sees. Newest first.
9
9
 
10
+ ## 0.3.552
11
+
12
+ One ledger records every charge. Additive, except that the per-app cap now counts more.
13
+
14
+ - **Charges.** `client.charges.list({ month?, under?, after?, limit? })` (`GET /v1/charges`) returns a page of the month's charge rows on this runtime, in time order; while `next` is not null, pass it back as `after` for the rest (`limit` is 1 to 10,000, default 1,000). Each row has: payer, funding, `caused_by`, `request` and the vendor's `vendor_ref`. `under` takes `run:<id>`, `message:<id>`, `request:<id>`, `cron_run:<id>` or a charge id, and lists the rows of every month unless `month` is also given; the answer carries a `month` only when you filtered. An app sees only the rows it is the grantee of. `usage.get` is deprecated in favour of it and keeps its shape.
15
+ - **The per-app cap counts priced tool calls.** The cap a user sets on an app (`spend_cap` in `usage.get`) used to count only model calls on the person's subscription or key. It now counts every charge the app makes on the person, including priced tool calls, so an app can reach its cap sooner than before.
16
+ - **`cap_exhausted` details.** The `402` carries `details.limit` (`id`, `payer`, `filters`, `usd_per_month`, `source`), `details.usd` and `details.reset_at`. `userAction` is `raise_cap` for an app's cap on the person, `clear_limit` for a limit the person set, and absent for an operator limit. `details.spend_cap` and `details.usd_equivalent` are still sent, with the same numbers as `details.limit.usd_per_month` and `details.usd`, but are deprecated: read the new keys. `RateLimitError.capExhausted` returns them typed (`CapExhaustedDetails`). A new run, node or job can now be refused with it too, when a limit covers every charge of its payer, such as a `$0` stop or the app's cap.
17
+ - **Spend limits.** `client.spendLimits.list | set | remove` (`/v1/spend-limits`) reads and writes dollar limits, for the person's own client only; an app is refused `403 owner_only`, and `spendLimits` is not on `AppClient`. These are not `/v1/limits`, which stays the per-app memory and disk cap. `crtr sys spend show | chain | limit` is the command line for all of it.
18
+ - **`Crtr-Caused-By`.** `runs.start({ causedBy })` and the client option `causedBy` send one reference (`message:<id>`, `request:<id>` or `cron_run:<id>`) that the runtime stores on the run's charges. A runtime older than this release ignores it.
19
+
10
20
  ## 0.3.550
11
21
 
12
22
  An app registers a permission schema for its own object types and decides who may read each object with relations. Additive, except that `friends` leaves the privacy levels and nodes move under their profile.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.550",
3
+ "version": "0.3.552",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -140,7 +140,7 @@
140
140
  },
141
141
  "license": "UNLICENSED",
142
142
  "dependencies": {
143
- "@north-light/identity": "0.3.550",
143
+ "@north-light/identity": "0.3.552",
144
144
  "@earendil-works/pi-agent-core": "1.1.0",
145
145
  "@earendil-works/pi-ai": "1.1.0",
146
146
  "@earendil-works/pi-coding-agent": "1.1.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.550",
3
+ "version": "0.3.552",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.550",
3
+ "version": "0.3.552",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.550",
9
+ "version": "0.3.552",
10
10
  "hasInstallScript": true,
11
11
  "license": "UNLICENSED",
12
12
  "workspaces": [
@@ -24,7 +24,7 @@
24
24
  "@milkdown/preset-gfm": "^7.22.3",
25
25
  "@milkdown/prose": "^7.22.3",
26
26
  "@milkdown/utils": "^7.22.3",
27
- "@north-light/identity": "0.3.550",
27
+ "@north-light/identity": "0.3.552",
28
28
  "cron-parser": "^5.6.0",
29
29
  "esbuild": "^0.27.7",
30
30
  "jose": "^6.2.12",
@@ -12455,17 +12455,17 @@
12455
12455
  },
12456
12456
  "packages/crouter-api": {
12457
12457
  "name": "@north-light/api",
12458
- "version": "0.3.550",
12458
+ "version": "0.3.552",
12459
12459
  "license": "UNLICENSED"
12460
12460
  },
12461
12461
  "packages/crouter-env-docker": {
12462
12462
  "name": "@north-light/env-docker",
12463
- "version": "0.3.550",
12463
+ "version": "0.3.552",
12464
12464
  "license": "UNLICENSED"
12465
12465
  },
12466
12466
  "packages/crouter-identity": {
12467
12467
  "name": "@north-light/identity",
12468
- "version": "0.3.550",
12468
+ "version": "0.3.552",
12469
12469
  "license": "UNLICENSED",
12470
12470
  "dependencies": {
12471
12471
  "jose": "^6.2.1"
@@ -12473,21 +12473,21 @@
12473
12473
  },
12474
12474
  "packages/crouter-plugin": {
12475
12475
  "name": "@north-light/plugin",
12476
- "version": "0.3.550",
12476
+ "version": "0.3.552",
12477
12477
  "license": "UNLICENSED",
12478
12478
  "dependencies": {
12479
- "@north-light/api": "0.3.550",
12480
- "@north-light/identity": "0.3.550"
12479
+ "@north-light/api": "0.3.552",
12480
+ "@north-light/identity": "0.3.552"
12481
12481
  }
12482
12482
  },
12483
12483
  "packages/crouter-sdk": {
12484
12484
  "name": "@north-light/sdk",
12485
- "version": "0.3.550",
12485
+ "version": "0.3.552",
12486
12486
  "license": "UNLICENSED",
12487
12487
  "dependencies": {
12488
- "@north-light/api": "0.3.550",
12489
- "@north-light/identity": "0.3.550",
12490
- "@north-light/plugin": "0.3.550",
12488
+ "@north-light/api": "0.3.552",
12489
+ "@north-light/identity": "0.3.552",
12490
+ "@north-light/plugin": "0.3.552",
12491
12491
  "jose": "^6.2.1"
12492
12492
  },
12493
12493
  "bin": {
@@ -1,49 +0,0 @@
1
- import { type CanvasDb } from '../canvas/db.js';
2
- import type { SpendUsageDTO } from '../../api/dto/usage.js';
3
- /** The person's own agent. Its grant carries the directory's default cap, but the
4
- * cap bounds what an app spends of the person's subscription, never the person's
5
- * own work, so `app:terminal` is never stopped. */
6
- export declare const UNCAPPED_GRANTEE = "app:terminal";
7
- export type Payer = 'user' | 'app';
8
- /** The UTC calendar month `YYYY-MM` of `at`. */
9
- export declare function usageMonth(at?: Date): string;
10
- /** 00:00Z on the first day of the UTC month after `month`. */
11
- export declare function resetAt(month: string): string;
12
- export interface UsageRecord {
13
- grantee: string;
14
- payer: Payer;
15
- /** `model` for a completion, `provider:<id>` for a provider receipt. */
16
- source: string;
17
- /** The model that answered; `''` for a provider receipt. */
18
- served_model: string;
19
- input_tokens: number;
20
- output_tokens: number;
21
- cached_tokens: number;
22
- /** List-price cost; null when the served model has no list price (it adds nothing to the total). */
23
- usd_equivalent: number | null;
24
- }
25
- /** Add one completion's or receipt's usage to its grantee's month, inside the caller's write. */
26
- export declare function addUsage(db: CanvasDb, record: UsageRecord, at?: Date): Promise<void>;
27
- /** Record one model completion for `grantee`. */
28
- export declare function recordModelUsage(grantee: string, payer: Payer, servedModel: string, usage: {
29
- input: number;
30
- output: number;
31
- cacheRead: number;
32
- }, usdEquivalent: number | null): Promise<void>;
33
- /** The grantee's user-paid month-to-date model spend; provider receipts are not in it. */
34
- export declare function monthSpend(grantee: string, month?: string): Promise<number>;
35
- /** Who a user-paid call bills, and the cap that bounds it (`null` = uncapped). */
36
- export interface SpendTarget {
37
- grantee: string;
38
- spend_cap: number | null;
39
- }
40
- /** The cap that applies to `target`: none for the person's own agent or a grant with no cap. */
41
- export declare function effectiveCap(target: SpendTarget): number | null;
42
- /** Refuse a user-paid call once the grantee's month spend reached its cap (SPD-2).
43
- * The check runs before the call; one response may overshoot the cap (no
44
- * reserve-then-settle), and the next call is refused. */
45
- export declare function assertUnderCap(target: SpendTarget | undefined, at?: Date): Promise<void>;
46
- /** `usage.get` for one grantee and month. */
47
- export declare function usageFor(grantee: string, spendCap: number | null, month?: string): Promise<SpendUsageDTO>;
48
- /** A `month` query value: `YYYY-MM` with a real month, years 1000-9999; absent means the current month. */
49
- export declare function parseUsageMonth(value: string | null): string;
@@ -1,10 +0,0 @@
1
- var f=Object.defineProperty;var a=(e,t)=>f(e,"name",{value:t,configurable:!0});import{withCanvasWrite as h,openDb as d}from"../canvas/db.js";import{RunError as _}from"../runs/operations.js";const q="app:terminal";function r(e=new Date){return e.toISOString().slice(0,7)}a(r,"usageMonth");function l(e){const[t,n]=e.split("-").map(Number);return new Date(Date.UTC(t,n,1)).toISOString()}a(l,"resetAt");async function w(e,t,n=new Date){const u=r(n);await e.prepare(`INSERT INTO usage (grantee, month, payer, source, served_model, input_tokens, output_tokens, cached_tokens, usd_equivalent)
2
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
3
- ON CONFLICT(grantee, month, payer, source, served_model) DO UPDATE SET
4
- input_tokens = usage.input_tokens + excluded.input_tokens,
5
- output_tokens = usage.output_tokens + excluded.output_tokens,
6
- cached_tokens = usage.cached_tokens + excluded.cached_tokens,
7
- usd_equivalent = CASE WHEN usage.usd_equivalent IS NULL AND excluded.usd_equivalent IS NULL THEN NULL
8
- ELSE COALESCE(usage.usd_equivalent, 0) + COALESCE(excluded.usd_equivalent, 0) END`).run(t.grantee,u,t.payer,t.source,t.served_model,t.input_tokens,t.output_tokens,t.cached_tokens,t.usd_equivalent),t.payer==="user"&&t.source==="model"&&t.usd_equivalent!==null&&t.usd_equivalent>0&&await e.prepare(`INSERT INTO grantee_usage (grantee, month, usd_equivalent) VALUES (?, ?, ?)
9
- ON CONFLICT(grantee, month) DO UPDATE SET usd_equivalent = grantee_usage.usd_equivalent + excluded.usd_equivalent`).run(t.grantee,u,t.usd_equivalent)}a(w,"addUsage");async function y(e,t,n,u,s){await h(async p=>await w(p,{grantee:e,payer:t,source:"model",served_model:n,input_tokens:u.input,output_tokens:u.output,cached_tokens:u.cacheRead,usd_equivalent:s}))}a(y,"recordModelUsage");async function c(e,t=r()){return(await(await d()).prepare("SELECT usd_equivalent FROM grantee_usage WHERE grantee = ? AND month = ?").get(e,t))?.usd_equivalent??0}a(c,"monthSpend");function m(e){return e.grantee===q?null:e.spend_cap}a(m,"effectiveCap");async function x(e,t=new Date){if(!e)return;const n=m(e);if(n===null)return;const u=r(t),s=await c(e.grantee,u);if(!(s<n))throw new _(402,"cap_exhausted",`${e.grantee} reached its monthly usage limit`,void 0,{spend_cap:n,usd_equivalent:s,reset_at:l(u)})}a(x,"assertUnderCap");async function C(e,t,n=r()){const u=await(await d()).prepare(`SELECT payer, source, served_model, input_tokens, output_tokens, usd_equivalent
10
- FROM usage WHERE grantee = ? AND month = ? ORDER BY served_model`).all(e,n),s=a(i=>u.filter(o=>o.payer===i&&o.source==="model").map(({served_model:o,input_tokens:E,output_tokens:v,usd_equivalent:g})=>({served_model:o,input_tokens:E,output_tokens:v,usd_equivalent:g})),"byModel"),p=u.filter(i=>i.payer==="app").reduce((i,o)=>i+(o.usd_equivalent??0),0);return{grantee:e,month:n,usd_equivalent:await c(e,n),by_model:s("user"),app_paid:{usd_equivalent:p,by_model:s("app")},spend_cap:m({grantee:e,spend_cap:t}),reset_at:l(n)}}a(C,"usageFor");function D(e){if(e===null)return r();if(!/^[1-9]\d{3}-(0[1-9]|1[0-2])$/.test(e))throw new _(400,"invalid_request","month must be YYYY-MM","month");return e}a(D,"parseUsageMonth");export{q as UNCAPPED_GRANTEE,w as addUsage,x as assertUnderCap,m as effectiveCap,c as monthSpend,D as parseUsageMonth,y as recordModelUsage,l as resetAt,C as usageFor,r as usageMonth};