@north-light/api 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.
- package/dist/api/client.d.ts +11 -0
- package/dist/api/client.js +13 -0
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/charges.d.ts +122 -0
- package/dist/api/dto/charges.js +3 -0
- package/dist/api/dto/usage.d.ts +3 -3
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.js +3 -0
- package/dist/core/config.js +5 -1
- package/dist/core/user-settings.d.ts +4 -0
- package/dist/core/user-settings.js +1 -0
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
package/dist/api/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiError } from './errors.js';
|
|
2
|
+
import type { ChargeListDTO, SpendLimitListDTO, SpendLimitRemovedDTO, SpendLimitSetRequest, LimitDTO } from './dto/charges.js';
|
|
2
3
|
import type { AppLimitsChangeDTO, LimitsDTO, SetAppLimitsRequest } from './dto/limits.js';
|
|
3
4
|
import type { DaemonAdmitDTO, DaemonRestartDTO, DueDTO, HealthDTO, ReadyDTO, MigrateStateDTO, MigrateStateRequest, StatusDTO } from './dto/health.js';
|
|
4
5
|
import type { BashJobStatusDTO, BashJobStopResultDTO } from './dto/bash-jobs.js';
|
|
@@ -230,6 +231,16 @@ export declare class CrtrClient {
|
|
|
230
231
|
showLimits(): Promise<LimitsDTO>;
|
|
231
232
|
setAppLimits(app: string, req: SetAppLimitsRequest): Promise<AppLimitsChangeDTO>;
|
|
232
233
|
removeAppLimits(app: string, fields: Array<'memory' | 'disk'>): Promise<AppLimitsChangeDTO>;
|
|
234
|
+
/** One page of this runtime's charge rows for a month, or the rows under a reference, with the month's totals; pass `next` back as `after`. */
|
|
235
|
+
listCharges(query?: {
|
|
236
|
+
month?: string;
|
|
237
|
+
under?: string;
|
|
238
|
+
after?: string;
|
|
239
|
+
limit?: number;
|
|
240
|
+
}): Promise<ChargeListDTO>;
|
|
241
|
+
listSpendLimits(): Promise<SpendLimitListDTO>;
|
|
242
|
+
setSpendLimit(id: string, req: SpendLimitSetRequest): Promise<LimitDTO>;
|
|
243
|
+
removeSpendLimit(id: string): Promise<SpendLimitRemovedDTO>;
|
|
233
244
|
/** Every space on the runtime with its size. */
|
|
234
245
|
listSpaces(): Promise<SpaceListDTO>;
|
|
235
246
|
subscribe(id: string, req: SubscribeRequest): Promise<SubscriptionDTO>;
|
package/dist/api/client.js
CHANGED
|
@@ -402,6 +402,19 @@ export class CrtrClient {
|
|
|
402
402
|
removeAppLimits(app, fields) {
|
|
403
403
|
return this.request('DELETE', withQuery(routes.limitsApp(app), { fields: fields.join(',') }));
|
|
404
404
|
}
|
|
405
|
+
/** One page of this runtime's charge rows for a month, or the rows under a reference, with the month's totals; pass `next` back as `after`. */
|
|
406
|
+
listCharges(query = {}) {
|
|
407
|
+
return this.request('GET', withQuery(routes.charges(), query));
|
|
408
|
+
}
|
|
409
|
+
listSpendLimits() {
|
|
410
|
+
return this.request('GET', routes.spendLimits());
|
|
411
|
+
}
|
|
412
|
+
setSpendLimit(id, req) {
|
|
413
|
+
return this.request('PUT', routes.spendLimit(id), req);
|
|
414
|
+
}
|
|
415
|
+
removeSpendLimit(id) {
|
|
416
|
+
return this.request('DELETE', routes.spendLimit(id));
|
|
417
|
+
}
|
|
405
418
|
/** Every space on the runtime with its size. */
|
|
406
419
|
listSpaces() {
|
|
407
420
|
return this.request('GET', routes.spaces());
|
package/dist/api/contract.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The contract level this build serves and requires. Written by `scripts/contract.mjs release`; never edit by hand. */
|
|
2
|
-
export declare const CONTRACT_LEVEL = "1.
|
|
2
|
+
export declare const CONTRACT_LEVEL = "1.32";
|
|
3
3
|
/** Request header naming the one contract level the caller needs, e.g. `1.3`. Optional: absent means no check. */
|
|
4
4
|
export declare const REQUIRED_CONTRACT_HEADER = "Crouter-Required-Contract";
|
|
5
5
|
/** Response header listing the contract levels the server serves, comma-separated, one per major, e.g. `1.3`. */
|
package/dist/api/contract.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
//
|
|
13
13
|
// PURITY (spec §3.1): Node built-ins + `src/api/*` only.
|
|
14
14
|
/** The contract level this build serves and requires. Written by `scripts/contract.mjs release`; never edit by hand. */
|
|
15
|
-
export const CONTRACT_LEVEL = '1.
|
|
15
|
+
export const CONTRACT_LEVEL = '1.32';
|
|
16
16
|
/** Request header naming the one contract level the caller needs, e.g. `1.3`. Optional: absent means no check. */
|
|
17
17
|
export const REQUIRED_CONTRACT_HEADER = 'Crouter-Required-Contract';
|
|
18
18
|
/** Response header listing the contract levels the server serves, comma-separated, one per major, e.g. `1.3`. */
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export type ChargeKindDTO = 'model' | 'tool' | 'sandbox' | 'job' | 'storage' | 'take';
|
|
2
|
+
export type FundingDTO = 'bill' | 'subscription' | 'key' | 'endpoint' | 'take' | 'legacy';
|
|
3
|
+
export type LimitSourceDTO = 'grant_sync' | 'person' | 'operator';
|
|
4
|
+
/** One charge row. Every field of the ledger's `charges` table. */
|
|
5
|
+
export interface ChargeDTO {
|
|
6
|
+
/** `receipt:<provider>:<receipt id>` for a tool charge; `legacy:…` for a migrated aggregate; otherwise a fresh id. */
|
|
7
|
+
id: string;
|
|
8
|
+
/** The `Request-Id` of the call that spent. Null on legacy rows. */
|
|
9
|
+
request: string | null;
|
|
10
|
+
at: string;
|
|
11
|
+
/** UTC `YYYY-MM`. */
|
|
12
|
+
month: string;
|
|
13
|
+
kind: ChargeKindDTO;
|
|
14
|
+
/** The model that answered, or `<provider id>:<tool path>` for a tool. */
|
|
15
|
+
what: string;
|
|
16
|
+
/** `{input, output, cache_read, cache_write}` tokens, or `{units, unit}` from a receipt; null on a legacy tool row. */
|
|
17
|
+
units: Record<string, unknown> | null;
|
|
18
|
+
/** List-price dollars; null when the model has no list price; 0 on a refused row. */
|
|
19
|
+
usd: number | null;
|
|
20
|
+
/** The principal charged: `user:<id>` or `app:<id>`. */
|
|
21
|
+
payer: string;
|
|
22
|
+
funding: FundingDTO;
|
|
23
|
+
/** The person the work is for. */
|
|
24
|
+
sub: string | null;
|
|
25
|
+
/** The app the charge is attributed to. */
|
|
26
|
+
grantee: string;
|
|
27
|
+
node: string | null;
|
|
28
|
+
run: string | null;
|
|
29
|
+
/** The vendor or provider app the money goes to. */
|
|
30
|
+
provider: string | null;
|
|
31
|
+
/** `message:<id>`, `request:<id>`, `cron_run:<id>`, or null for a root. */
|
|
32
|
+
caused_by: string | null;
|
|
33
|
+
/** The vendor's request id for a model row; the receipt id for a tool row. */
|
|
34
|
+
vendor_ref: string | null;
|
|
35
|
+
/** Set when the check refused this call: the limit id and reason. */
|
|
36
|
+
refused: {
|
|
37
|
+
limit: string;
|
|
38
|
+
reason: string;
|
|
39
|
+
} | null;
|
|
40
|
+
}
|
|
41
|
+
/** One limit row. A null filter means any. */
|
|
42
|
+
export interface LimitDTO {
|
|
43
|
+
id: string;
|
|
44
|
+
payer: string;
|
|
45
|
+
funding: FundingDTO | null;
|
|
46
|
+
grantee: string | null;
|
|
47
|
+
provider: string | null;
|
|
48
|
+
sub: string | null;
|
|
49
|
+
/** 0 is an emergency stop. */
|
|
50
|
+
usd_per_month: number;
|
|
51
|
+
source: LimitSourceDTO;
|
|
52
|
+
updated_at: string;
|
|
53
|
+
}
|
|
54
|
+
/** One month's dollars from the rollup, with the limit rows. */
|
|
55
|
+
export interface ChargeTotalsDTO {
|
|
56
|
+
month: string;
|
|
57
|
+
by_payer: Array<{
|
|
58
|
+
payer: string;
|
|
59
|
+
usd: number;
|
|
60
|
+
}>;
|
|
61
|
+
by_funding: Array<{
|
|
62
|
+
payer: string;
|
|
63
|
+
funding: string;
|
|
64
|
+
usd: number;
|
|
65
|
+
}>;
|
|
66
|
+
limits: LimitDTO[];
|
|
67
|
+
}
|
|
68
|
+
/** `GET /v1/charges?month=&under=&after=&limit=`: this runtime's rows in `(at, id)` order, newest last. An app sees only rows whose grantee it is. */
|
|
69
|
+
export interface ChargeListDTO {
|
|
70
|
+
/** The month the rows are filtered to: the requested one, else the current month. Absent when `under` is given without `month`, because the chain spans months. */
|
|
71
|
+
month?: string;
|
|
72
|
+
/** At most `limit` rows (default 1,000, at most 10,000). */
|
|
73
|
+
charges: ChargeDTO[];
|
|
74
|
+
/** Pass as `after` to read the next page; null when this page is the last. */
|
|
75
|
+
next: string | null;
|
|
76
|
+
/** Month totals by payer and funding with the matching limits, over every row of the month rather than this page. Present for the person and a terminal node; absent for an app and when `under` is given. */
|
|
77
|
+
totals?: ChargeTotalsDTO;
|
|
78
|
+
}
|
|
79
|
+
/** `GET /v1/spend-limits`. */
|
|
80
|
+
export interface SpendLimitListDTO {
|
|
81
|
+
limits: LimitDTO[];
|
|
82
|
+
}
|
|
83
|
+
/** `PUT /v1/spend-limits/:id`: the id must start `person:`. Writes a limit row with source `person`; an existing row of that id is replaced. */
|
|
84
|
+
export interface SpendLimitSetRequest {
|
|
85
|
+
/** `user:<id>` (the person) or `app:<id>`. */
|
|
86
|
+
payer: string;
|
|
87
|
+
usd_per_month: number;
|
|
88
|
+
funding?: FundingDTO | null;
|
|
89
|
+
grantee?: string | null;
|
|
90
|
+
provider?: string | null;
|
|
91
|
+
sub?: string | null;
|
|
92
|
+
}
|
|
93
|
+
/** `DELETE /v1/spend-limits/:id`: clears a person-set limit row. */
|
|
94
|
+
export interface SpendLimitRemovedDTO {
|
|
95
|
+
id: string;
|
|
96
|
+
removed: true;
|
|
97
|
+
}
|
|
98
|
+
/** The `details` of a `402 cap_exhausted` refusal. */
|
|
99
|
+
export interface CapExhaustedDetails {
|
|
100
|
+
limit: {
|
|
101
|
+
id: string;
|
|
102
|
+
payer: string;
|
|
103
|
+
filters: {
|
|
104
|
+
funding: FundingDTO | null;
|
|
105
|
+
grantee: string | null;
|
|
106
|
+
provider: string | null;
|
|
107
|
+
sub: string | null;
|
|
108
|
+
};
|
|
109
|
+
usd_per_month: number;
|
|
110
|
+
source: LimitSourceDTO;
|
|
111
|
+
};
|
|
112
|
+
/** The dollars counted against the limit this month. */
|
|
113
|
+
usd: number;
|
|
114
|
+
/** When the count starts over. */
|
|
115
|
+
reset_at: string;
|
|
116
|
+
/** What the person can do: raise the app's cap, or clear their own limit; absent for an operator limit. */
|
|
117
|
+
user_action?: 'raise_cap' | 'clear_limit';
|
|
118
|
+
/** @deprecated Use `limit.usd_per_month`. */
|
|
119
|
+
spend_cap: number;
|
|
120
|
+
/** @deprecated Use `usd`. */
|
|
121
|
+
usd_equivalent: number;
|
|
122
|
+
}
|
package/dist/api/dto/usage.d.ts
CHANGED
|
@@ -6,12 +6,12 @@ export interface SpendUsageModelRowDTO {
|
|
|
6
6
|
/** List-price cost; null when the served model has no list price (an app-registered endpoint, or an unpriced model). */
|
|
7
7
|
usd_equivalent: number | null;
|
|
8
8
|
}
|
|
9
|
-
/** `usage.get
|
|
9
|
+
/** `usage.get` (deprecated in favour of `charges.list`): the caller's grantee's month-to-date spend (daemon operations, `usage.get`). */
|
|
10
10
|
export interface SpendUsageDTO {
|
|
11
11
|
grantee: string;
|
|
12
12
|
/** UTC calendar month, `YYYY-MM`. */
|
|
13
13
|
month: string;
|
|
14
|
-
/** User-paid spend this month: every model completion and
|
|
14
|
+
/** User-paid spend this month for this grantee: every model completion and every priced tool call. Tool calls have no `by_model` row, so this can exceed the sum of `by_model`. */
|
|
15
15
|
usd_equivalent: number;
|
|
16
16
|
/** User-paid model completions, one row per served model. */
|
|
17
17
|
by_model: SpendUsageModelRowDTO[];
|
|
@@ -20,7 +20,7 @@ export interface SpendUsageDTO {
|
|
|
20
20
|
usd_equivalent: number;
|
|
21
21
|
by_model: SpendUsageModelRowDTO[];
|
|
22
22
|
};
|
|
23
|
-
/** The monthly cap on user-paid spend; once `usd_equivalent` reaches it,
|
|
23
|
+
/** The monthly cap on user-paid spend, which now counts priced tool calls as well as model calls; once `usd_equivalent` reaches it, calls billed to the user answer `cap_exhausted` until `reset_at`. Null when no limit row exists. */
|
|
24
24
|
spend_cap: number | null;
|
|
25
25
|
/** 00:00Z on the first day of the next UTC month, when the count starts over. */
|
|
26
26
|
reset_at: string;
|
package/dist/api/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from './dto/health.js';
|
|
|
17
17
|
export * from './dto/limits.js';
|
|
18
18
|
export * from './dto/grants.js';
|
|
19
19
|
export * from './dto/usage.js';
|
|
20
|
+
export * from './dto/charges.js';
|
|
20
21
|
export * from './dto/nodes.js';
|
|
21
22
|
export * from './dto/node-outcomes.js';
|
|
22
23
|
export * from './dto/node-events.js';
|
package/dist/api/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export * from './dto/health.js';
|
|
|
14
14
|
export * from './dto/limits.js';
|
|
15
15
|
export * from './dto/grants.js';
|
|
16
16
|
export * from './dto/usage.js';
|
|
17
|
+
export * from './dto/charges.js';
|
|
17
18
|
export * from './dto/nodes.js';
|
|
18
19
|
export * from './dto/node-outcomes.js';
|
|
19
20
|
export * from './dto/node-events.js';
|
package/dist/api/routes.d.ts
CHANGED
|
@@ -74,6 +74,9 @@ export declare const routes: {
|
|
|
74
74
|
readonly spaces: () => string;
|
|
75
75
|
readonly limits: () => string;
|
|
76
76
|
readonly limitsApp: (app: string) => string;
|
|
77
|
+
readonly charges: () => string;
|
|
78
|
+
readonly spendLimits: () => string;
|
|
79
|
+
readonly spendLimit: (id: string) => string;
|
|
77
80
|
readonly nodeAttach: (id: string) => string;
|
|
78
81
|
readonly focuses: () => string;
|
|
79
82
|
readonly focusByNode: () => string;
|
package/dist/api/routes.js
CHANGED
|
@@ -92,6 +92,9 @@ export const routes = {
|
|
|
92
92
|
spaces: () => `${V}/spaces`,
|
|
93
93
|
limits: () => `${V}/limits`,
|
|
94
94
|
limitsApp: (app) => `${V}/limits/apps/${encodeURIComponent(app)}`,
|
|
95
|
+
charges: () => `${V}/charges`,
|
|
96
|
+
spendLimits: () => `${V}/spend-limits`,
|
|
97
|
+
spendLimit: (id) => `${V}/spend-limits/${encodeURIComponent(id)}`,
|
|
95
98
|
nodeAttach: (id) => `${V}/nodes/${id}/attach`,
|
|
96
99
|
// Focuses (viewer registry — the canvas.db `focuses` table)
|
|
97
100
|
focuses: () => `${V}/focuses`,
|
package/dist/core/config.js
CHANGED
|
@@ -850,6 +850,10 @@ function mergeConfig(partial) {
|
|
|
850
850
|
if (paths?.user_files !== undefined && (typeof paths.user_files !== 'string' || !paths.user_files.startsWith('/'))) {
|
|
851
851
|
throw new Error('paths.user_files must be an absolute path');
|
|
852
852
|
}
|
|
853
|
+
const ledger = partial.ledger;
|
|
854
|
+
if (ledger?.take_pct !== undefined && (typeof ledger.take_pct !== 'number' || !Number.isFinite(ledger.take_pct) || ledger.take_pct < 0 || ledger.take_pct > 100)) {
|
|
855
|
+
throw new Error('ledger.take_pct must be a number from 0 to 100');
|
|
856
|
+
}
|
|
853
857
|
const store = partial.store;
|
|
854
858
|
const runtime = partial.runtime;
|
|
855
859
|
if (runtime?.person_uids !== undefined && (!Array.isArray(runtime.person_uids)
|
|
@@ -859,7 +863,7 @@ function mergeConfig(partial) {
|
|
|
859
863
|
const spawnEnv = mergeSpawnEnv(partial.spawnEnv, defaults.spawnEnv?.allow);
|
|
860
864
|
const bin = normalizeBin(partial.bin);
|
|
861
865
|
const humanActions = normalizeHumanActions(partial.humanActions);
|
|
862
|
-
return { bin, humanActions, schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, lifecycle, completion_bell, working_gerunds, whip_mode, page_components, page_surface, whip_messages, whip_message_mode, mouse_mode_default, live_cycles, condensed_history, bash_tool_purpose, fold_finished_tools, summarize_tool_calls, detailed_tool_recaps, document_port, consolidate_replies, keybindings, tmux_passthrough, modelLadders, providerOptions, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(Object.keys(routes.legacy).length > 0 ? { legacyModelRoutes: routes.legacy } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, api, ...(paths ? { paths } : {}), ...(store ? { store } : {}), ...(runtime ? { runtime } : {}), spawnEnv };
|
|
866
|
+
return { bin, humanActions, schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, lifecycle, completion_bell, working_gerunds, whip_mode, page_components, page_surface, whip_messages, whip_message_mode, mouse_mode_default, live_cycles, condensed_history, bash_tool_purpose, fold_finished_tools, summarize_tool_calls, detailed_tool_recaps, document_port, consolidate_replies, keybindings, tmux_passthrough, modelLadders, providerOptions, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(Object.keys(routes.legacy).length > 0 ? { legacyModelRoutes: routes.legacy } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, api, ...(paths ? { paths } : {}), ...(ledger ? { ledger } : {}), ...(store ? { store } : {}), ...(runtime ? { runtime } : {}), spawnEnv };
|
|
863
867
|
}
|
|
864
868
|
/** Raw (un-defaulted) partial config for one scope, or null if the scope has
|
|
865
869
|
* no root or no config.json. Used by `readMergedLaunchConfig` to layer
|
|
@@ -469,6 +469,7 @@ export const CONFIG_SETTINGS_COVERAGE = {
|
|
|
469
469
|
remoteCanvas: { surface: 'specialized', owner: 'canvas config commands' },
|
|
470
470
|
api: { surface: 'specialized', owner: 'sys connect' },
|
|
471
471
|
paths: { surface: 'specialized', owner: 'runtime layout' },
|
|
472
|
+
ledger: { surface: 'specialized', owner: 'money ledger (take_pct)' },
|
|
472
473
|
store: { surface: 'specialized', owner: 'daemon conversation store' },
|
|
473
474
|
runtime: { surface: 'specialized', owner: 'app-facing listener' },
|
|
474
475
|
spawnEnv: { surface: 'specialized', owner: 'spawn environment allow-list' },
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/api",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.552",
|
|
4
4
|
"description": "Typed crtrd /v1 API contract — DTOs, route builders, the error contract, the CrtrClient, and the command-plugin manifest format. Zero runtime dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/api/index.js",
|