@clocknext/sdk 0.12.1 → 0.14.0
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/README.md +20 -5
- package/dist/index.cjs +100 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +234 -28
- package/dist/index.d.ts +234 -28
- package/dist/index.js +100 -11
- package/dist/index.js.map +1 -1
- package/examples/node-basic.ts +5 -3
- package/package.json +1 -1
- package/src/index.ts +9 -0
- package/src/resources/customers.ts +26 -3
- package/src/resources/signals.ts +101 -11
- package/src/types.ts +172 -18
package/examples/node-basic.ts
CHANGED
|
@@ -58,8 +58,9 @@ async function main() {
|
|
|
58
58
|
tokens: { input: 800, output: 5000 },
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
// 4. Outcome run — every step shares a `runId`;
|
|
62
|
-
//
|
|
61
|
+
// 4. Outcome run — every step shares a `runId`; a separate, dedicated call
|
|
62
|
+
// (`completeOutcome`) closes and bills the run — never a flag on a step.
|
|
63
|
+
// `agentKey` is the OutcomeStep's key, which you read off
|
|
63
64
|
// `cnk.outcomes.list()` the same way.
|
|
64
65
|
// `outcomes.list()` returns catalogue rows WITHOUT their steps; the step
|
|
65
66
|
// agent keys — which is what a signal reports against — are on the detail.
|
|
@@ -72,9 +73,10 @@ async function main() {
|
|
|
72
73
|
model: model.modelId,
|
|
73
74
|
agentKey: outcome.steps[0].agentKey,
|
|
74
75
|
runId,
|
|
75
|
-
complete: true, // closes the RUN; a composite still needs its own close
|
|
76
76
|
tokens: { input: 600, output: 150 },
|
|
77
77
|
});
|
|
78
|
+
// Closes the RUN; a composite still needs its own `completeComposite()` close.
|
|
79
|
+
await cnk.signals.completeOutcome({ customerId: customer.id, runId });
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
// 5. Flush the background buffer, then read the signals back. Ingestion is
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -44,6 +44,8 @@ export type {
|
|
|
44
44
|
CreditInput,
|
|
45
45
|
WalletInput,
|
|
46
46
|
OutcomeInput,
|
|
47
|
+
OutcomeCompletionInput,
|
|
48
|
+
OutcomeCompletionResult,
|
|
47
49
|
TrackResult,
|
|
48
50
|
UsageList,
|
|
49
51
|
SerializedUsageLog,
|
|
@@ -57,6 +59,12 @@ export type {
|
|
|
57
59
|
UnitUsageRow,
|
|
58
60
|
UnitUsageList,
|
|
59
61
|
SerializedUnitUsage,
|
|
62
|
+
UsageLogPeriod,
|
|
63
|
+
UsageLogListParams,
|
|
64
|
+
UsageLogAppliedRule,
|
|
65
|
+
UsageLogOutcomeAttribution,
|
|
66
|
+
UsageLogEntry,
|
|
67
|
+
UsageLogPage,
|
|
60
68
|
// workspace
|
|
61
69
|
WorkspaceIdentity,
|
|
62
70
|
Model,
|
|
@@ -87,6 +95,7 @@ export type {
|
|
|
87
95
|
CreditAdjustInput,
|
|
88
96
|
OutcomeAdjustInput,
|
|
89
97
|
UnitAdjustInput,
|
|
98
|
+
CompositeAdjustInput,
|
|
90
99
|
// plans
|
|
91
100
|
Plan,
|
|
92
101
|
PlanDetail,
|
|
@@ -2,6 +2,7 @@ import type { Transport } from "../http.js";
|
|
|
2
2
|
import type {
|
|
3
3
|
AddMemberInput,
|
|
4
4
|
ApiCustomer,
|
|
5
|
+
CompositeAdjustInput,
|
|
5
6
|
CreateCustomerInput,
|
|
6
7
|
CreditAdjustInput,
|
|
7
8
|
CreditBalance,
|
|
@@ -261,13 +262,18 @@ export class Customers {
|
|
|
261
262
|
|
|
262
263
|
// --- Balance adjustments -------------------------------------------------
|
|
263
264
|
|
|
264
|
-
/** Grant or claw back a credit balance.
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
/** Grant or claw back a credit balance. Returns the remaining balance.
|
|
266
|
+
* `POST …/:id/credits/adjust`. */
|
|
267
|
+
async adjustCredit(
|
|
268
|
+
id: string,
|
|
269
|
+
input: CreditAdjustInput,
|
|
270
|
+
): Promise<{ remaining: number }> {
|
|
271
|
+
const res = await this.transport.request<{ remaining: number }>({
|
|
267
272
|
method: "POST",
|
|
268
273
|
path: `/api/v1/customers/${encodeURIComponent(id)}/credits/adjust`,
|
|
269
274
|
body: input,
|
|
270
275
|
});
|
|
276
|
+
return { remaining: res.remaining };
|
|
271
277
|
}
|
|
272
278
|
|
|
273
279
|
/** Grant or claw back an outcome balance. Returns the remaining balance. */
|
|
@@ -295,4 +301,21 @@ export class Customers {
|
|
|
295
301
|
});
|
|
296
302
|
return { remaining: res.remaining };
|
|
297
303
|
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Grant or claw back slots on a customer's ADVANCE composite pool for the
|
|
307
|
+
* current billing cycle. Returns the resulting `remaining` slot count.
|
|
308
|
+
* `POST …/:id/composites/adjust`.
|
|
309
|
+
*/
|
|
310
|
+
async adjustComposite(
|
|
311
|
+
id: string,
|
|
312
|
+
input: CompositeAdjustInput,
|
|
313
|
+
): Promise<{ remaining: number }> {
|
|
314
|
+
const res = await this.transport.request<{ remaining: number }>({
|
|
315
|
+
method: "POST",
|
|
316
|
+
path: `/api/v1/customers/${encodeURIComponent(id)}/composites/adjust`,
|
|
317
|
+
body: input,
|
|
318
|
+
});
|
|
319
|
+
return { remaining: res.remaining };
|
|
320
|
+
}
|
|
298
321
|
}
|
package/src/resources/signals.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
CompositeCompletionInput,
|
|
6
6
|
CompositeCompletionResult,
|
|
7
7
|
CreditInput,
|
|
8
|
+
OutcomeCompletionInput,
|
|
9
|
+
OutcomeCompletionResult,
|
|
8
10
|
OutcomeInput,
|
|
9
11
|
ResolvedConfig,
|
|
10
12
|
SerializedUnitUsage,
|
|
@@ -15,6 +17,8 @@ import type {
|
|
|
15
17
|
UnitTrackResult,
|
|
16
18
|
UnitUsageList,
|
|
17
19
|
UsageList,
|
|
20
|
+
UsageLogListParams,
|
|
21
|
+
UsageLogPage,
|
|
18
22
|
WalletInput,
|
|
19
23
|
} from "../types.js";
|
|
20
24
|
|
|
@@ -37,10 +41,12 @@ const SIGNAL_PATHS: Record<SignalType, string> = {
|
|
|
37
41
|
wallet: "/api/v1/signal/wallet",
|
|
38
42
|
};
|
|
39
43
|
|
|
40
|
-
/** Unit reports and
|
|
41
|
-
*
|
|
44
|
+
/** Unit reports and completion pings are not part of the `Signal` union (no
|
|
45
|
+
* model, no tokens), so they carry their paths separately. */
|
|
42
46
|
const UNIT_PATH = "/api/v1/signal/unit";
|
|
43
47
|
const COMPOSITE_COMPLETE_PATH = "/api/v1/signal/composite/complete";
|
|
48
|
+
const OUTCOME_COMPLETE_PATH = "/api/v1/signal/outcome/complete";
|
|
49
|
+
const USAGE_LOG_PATH = "/api/v1/signal/usage-log";
|
|
44
50
|
|
|
45
51
|
/**
|
|
46
52
|
* Builds the request body for a typed Signal.
|
|
@@ -82,10 +88,12 @@ export function signalToWire(signal: Signal): Record<string, unknown> {
|
|
|
82
88
|
body.agentKey = signal.agentKey;
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
// Outcome runs are grouped by `runId
|
|
91
|
+
// Outcome runs are grouped by `runId`. Ending the run is NOT a flag on this
|
|
92
|
+
// body: `POST /api/v1/signal/outcome` (what this body is sent to) accepts
|
|
93
|
+
// ONLY the step shape and rejects one that also carries `complete` — see
|
|
94
|
+
// `signals.completeOutcome()`, its own dedicated route.
|
|
86
95
|
if (signal.type === "outcome") {
|
|
87
96
|
body.runId = signal.runId;
|
|
88
|
-
if (signal.complete != null) body.complete = signal.complete;
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
// Composite tag, nested under its `refId`. Never set for wallet — the server
|
|
@@ -242,6 +250,56 @@ export class Signals {
|
|
|
242
250
|
return this.track({ ...input, type: "outcome" }, opts);
|
|
243
251
|
}
|
|
244
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Close ONE outcome run — declares the workflow finished and bills it. The
|
|
255
|
+
* outcome mirror of {@link Signals.completeComposite}, on its own dedicated
|
|
256
|
+
* route: `POST /api/v1/signal/outcome/complete`.
|
|
257
|
+
*
|
|
258
|
+
* An outcome bills per COMPLETION, never per step, and `signals.outcome()`
|
|
259
|
+
* never closes one — it accepts only the step shape. Declaring the workflow
|
|
260
|
+
* finished is always this separate, explicit, contentless call.
|
|
261
|
+
*
|
|
262
|
+
* This closes the RUN only. If a step of this run also carried a
|
|
263
|
+
* `composite`, that occurrence stays open and unbilled until you separately
|
|
264
|
+
* call {@link Signals.completeComposite} — the two completions are
|
|
265
|
+
* independent, and neither implies the other.
|
|
266
|
+
*
|
|
267
|
+
* Sent immediately, never buffered. A genuinely second, independent call for
|
|
268
|
+
* an already-closed run is a PERMANENT error (it would bill the run twice),
|
|
269
|
+
* not a safe no-op — see {@link OutcomeCompletionResult}.
|
|
270
|
+
*/
|
|
271
|
+
async completeOutcome(
|
|
272
|
+
input: OutcomeCompletionInput,
|
|
273
|
+
): Promise<OutcomeCompletionResult> {
|
|
274
|
+
const idempotencyKey = input.idempotencyKey ?? newKey();
|
|
275
|
+
const res = await this.transport.request<
|
|
276
|
+
SignalResponse & {
|
|
277
|
+
status?: "COMPLETED" | "ALREADY_COMPLETED";
|
|
278
|
+
usageLog?: OutcomeCompletionResult["usageLog"];
|
|
279
|
+
}
|
|
280
|
+
>({
|
|
281
|
+
method: "POST",
|
|
282
|
+
path: OUTCOME_COMPLETE_PATH,
|
|
283
|
+
idempotencyKey,
|
|
284
|
+
body: {
|
|
285
|
+
customerId: input.customerId,
|
|
286
|
+
runId: input.runId,
|
|
287
|
+
complete: true,
|
|
288
|
+
...(input.member ? { member: input.member } : {}),
|
|
289
|
+
idempotencyKey,
|
|
290
|
+
},
|
|
291
|
+
retry: true,
|
|
292
|
+
});
|
|
293
|
+
const queued = res.queued === true;
|
|
294
|
+
return {
|
|
295
|
+
delivery: queued ? "accepted" : "recorded",
|
|
296
|
+
queued,
|
|
297
|
+
...(res.status != null ? { status: res.status } : {}),
|
|
298
|
+
usageLog: res.usageLog ?? null,
|
|
299
|
+
...handles(res),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
245
303
|
/**
|
|
246
304
|
* Recent usage logs + totals for a customer. `GET /api/v1/usage`.
|
|
247
305
|
*
|
|
@@ -323,13 +381,13 @@ export class Signals {
|
|
|
323
381
|
* arrive in any order and the occurrence stays open and unbilled until you
|
|
324
382
|
* say otherwise. Put it on the line before your own `return`.
|
|
325
383
|
*
|
|
326
|
-
* EVERY composite needs this, outcome-backed ones included.
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
384
|
+
* EVERY composite needs this, outcome-backed ones included. `completeOutcome()`
|
|
385
|
+
* closes its RUN and nothing else — it does not close the composite
|
|
386
|
+
* occurrence the run was tagged into, whatever mix of credits, outcomes and
|
|
387
|
+
* units that composite wraps. (Earlier versions of this SDK documented the
|
|
388
|
+
* opposite. Believing it means the occurrence stays ONGOING forever and is
|
|
389
|
+
* never billed, so if you tag outcome signals with a `composite`, you must
|
|
390
|
+
* still call this.)
|
|
333
391
|
*
|
|
334
392
|
* Closing twice is safe: the second call answers `ALREADY_COMPLETED` and
|
|
335
393
|
* cannot bill again. Calling it EARLY is also safe — before every entitlement
|
|
@@ -390,4 +448,36 @@ export class Signals {
|
|
|
390
448
|
query: { customerId: params.customerId, limit: params.limit },
|
|
391
449
|
});
|
|
392
450
|
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* One customer's usage history, merged from every meter kind — credit,
|
|
454
|
+
* outcome, unit, wallet, and completed composite occurrences — into one
|
|
455
|
+
* feed sorted by time. `GET /api/v1/signal/usage-log`. Exactly the same
|
|
456
|
+
* rows the customer portal's own "Usage logs" table shows, so a caller can
|
|
457
|
+
* build against this instead of the portal UI.
|
|
458
|
+
*
|
|
459
|
+
* Cursor-paginated, NOT page-numbered: `limit` + `cursor` in, `nextCursor`
|
|
460
|
+
* out. Omit `cursor` for the first page; pass the previous page's
|
|
461
|
+
* `nextCursor` back to fetch the next one, and stop once it comes back
|
|
462
|
+
* `null`. Unlike offset pagination, the cost of a page never grows with how
|
|
463
|
+
* deep you've paged — each page only asks for rows strictly before the
|
|
464
|
+
* cursor's position.
|
|
465
|
+
*
|
|
466
|
+
* Read-only; unlike {@link track}/{@link unit}/etc., there is nothing to
|
|
467
|
+
* buffer or retry here.
|
|
468
|
+
*/
|
|
469
|
+
usageLog(params: UsageLogListParams): Promise<UsageLogPage> {
|
|
470
|
+
return this.transport.request<UsageLogPage>({
|
|
471
|
+
method: "GET",
|
|
472
|
+
path: USAGE_LOG_PATH,
|
|
473
|
+
query: {
|
|
474
|
+
customerId: params.customerId,
|
|
475
|
+
limit: params.limit,
|
|
476
|
+
cursor: params.cursor,
|
|
477
|
+
period: params.period,
|
|
478
|
+
from: params.from,
|
|
479
|
+
to: params.to,
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
}
|
|
393
483
|
}
|
package/src/types.ts
CHANGED
|
@@ -140,7 +140,14 @@ export interface WalletSignal extends SignalBase {
|
|
|
140
140
|
/**
|
|
141
141
|
* Records one step of a multi-call outcome run. The `agentKey` identifies the
|
|
142
142
|
* step (and the outcome); `runId` groups every signal of a single run, so a step
|
|
143
|
-
* may repeat freely. The run bills once, when the caller
|
|
143
|
+
* may repeat freely. The run bills once, when the caller closes it with
|
|
144
|
+
* `signals.completeOutcome()` — a SEPARATE, dedicated call, never a flag on a
|
|
145
|
+
* step signal.
|
|
146
|
+
*
|
|
147
|
+
* There is no `complete` field here. `POST /api/v1/signal/outcome` (what this
|
|
148
|
+
* type posts to) now accepts ONLY the step shape and rejects a body that also
|
|
149
|
+
* carries `complete` — see {@link OutcomeCompletionInput} /
|
|
150
|
+
* `signals.completeOutcome()`, its own dedicated route.
|
|
144
151
|
*/
|
|
145
152
|
export interface OutcomeSignal extends SignalBase {
|
|
146
153
|
type: "outcome";
|
|
@@ -152,17 +159,6 @@ export interface OutcomeSignal extends SignalBase {
|
|
|
152
159
|
* outcome). Opaque to ClockNext — any string you can correlate; unique per org.
|
|
153
160
|
*/
|
|
154
161
|
runId: string;
|
|
155
|
-
/**
|
|
156
|
-
* Set `true` on the LAST step signal to declare the run finished — completion
|
|
157
|
-
* is never inferred from step coverage. Sending it twice is a safe no-op and
|
|
158
|
-
* can't bill again.
|
|
159
|
-
*
|
|
160
|
-
* This closes the RUN only. If the signal also carries a `composite`, that
|
|
161
|
-
* occurrence stays open and unbilled until you call
|
|
162
|
-
* `signals.completeComposite()` — the two completions are separate, and
|
|
163
|
-
* neither implies the other.
|
|
164
|
-
*/
|
|
165
|
-
complete?: boolean;
|
|
166
162
|
/** Optional composite this signal belongs to. See {@link CompositeTag}. */
|
|
167
163
|
composite?: CompositeTag;
|
|
168
164
|
}
|
|
@@ -174,6 +170,58 @@ export type CreditInput = Omit<CreditSignal, "type">;
|
|
|
174
170
|
export type WalletInput = Omit<WalletSignal, "type">;
|
|
175
171
|
export type OutcomeInput = Omit<OutcomeSignal, "type">;
|
|
176
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Input for `signals.completeOutcome()` — closes ONE outcome run, the outcome
|
|
175
|
+
* mirror of {@link CompositeCompletionInput}. No `agentKey`, no `usage`: this
|
|
176
|
+
* closes an EXISTING run that an earlier `signals.outcome()` step already
|
|
177
|
+
* opened, so there is no step behind this call and nothing here to price.
|
|
178
|
+
*
|
|
179
|
+
* This closes the RUN only. If a step of this run also carried a `composite`,
|
|
180
|
+
* that occurrence stays open and unbilled until you separately call
|
|
181
|
+
* `signals.completeComposite()` — the two completions are independent, and
|
|
182
|
+
* neither implies the other.
|
|
183
|
+
*/
|
|
184
|
+
export interface OutcomeCompletionInput {
|
|
185
|
+
customerId: string;
|
|
186
|
+
/** The same `runId` the run's step signals were sent with. */
|
|
187
|
+
runId: string;
|
|
188
|
+
/** Optional member (email) this completion is attributed to. */
|
|
189
|
+
member?: string;
|
|
190
|
+
/** Idempotency key, auto-generated if omitted. Sending `complete` twice for
|
|
191
|
+
* the same run is already a safe no-op server-side, so this only collapses
|
|
192
|
+
* a retry into one attempt rather than protecting against a double bill. */
|
|
193
|
+
idempotencyKey?: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* The result of `signals.completeOutcome()`.
|
|
198
|
+
*
|
|
199
|
+
* Unlike {@link CompositeCompletionResult}, `ALREADY_COMPLETED` is NOT what a
|
|
200
|
+
* normal second ping for the same run gets back — that is rejected outright
|
|
201
|
+
* (a permanent error: the run has already been billed, and completing it again
|
|
202
|
+
* would bill it twice). `ALREADY_COMPLETED` is reserved for the much rarer case
|
|
203
|
+
* of two concurrent deliveries of the exact same request (e.g. a client-side
|
|
204
|
+
* retry racing the original), which really is a harmless echo.
|
|
205
|
+
*/
|
|
206
|
+
export interface OutcomeCompletionResult {
|
|
207
|
+
/** How far the ping got. Never `"buffered"` — completions are always sent
|
|
208
|
+
* immediately. See {@link TrackResult.status}. */
|
|
209
|
+
delivery: Extract<SignalDelivery, "accepted" | "recorded">;
|
|
210
|
+
/** True when the ping was accepted but not yet applied (`202`). Prefer
|
|
211
|
+
* {@link OutcomeCompletionResult.delivery}. */
|
|
212
|
+
queued: boolean;
|
|
213
|
+
/** `COMPLETED` on the first close, `ALREADY_COMPLETED` only on the rare
|
|
214
|
+
* concurrent-replay case described above. Absent when the ping was queued. */
|
|
215
|
+
status?: "COMPLETED" | "ALREADY_COMPLETED";
|
|
216
|
+
/** The priced usage log, when the server closed the run inline. `null` on a
|
|
217
|
+
* `202` hand-off. */
|
|
218
|
+
usageLog?: SerializedUsageLog | null;
|
|
219
|
+
/** The durable inbox id — see {@link TrackResult.rawId}. */
|
|
220
|
+
rawId?: string;
|
|
221
|
+
/** The queue message id, present only on a `202` hand-off. */
|
|
222
|
+
messageId?: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
177
225
|
// ---------------------------------------------------------------------------
|
|
178
226
|
// Server response shapes (mirrors src/lib/usage/log.ts)
|
|
179
227
|
// ---------------------------------------------------------------------------
|
|
@@ -337,6 +385,86 @@ export interface UsageList {
|
|
|
337
385
|
logs: SerializedUsageLog[];
|
|
338
386
|
}
|
|
339
387
|
|
|
388
|
+
// ---------------------------------------------------------------------------
|
|
389
|
+
// Usage log (mirrors GET /api/v1/signal/usage-log)
|
|
390
|
+
// ---------------------------------------------------------------------------
|
|
391
|
+
|
|
392
|
+
/** A preset time window, or `"custom"` for an explicit `from`/`to` range. */
|
|
393
|
+
export type UsageLogPeriod = "all" | "today" | "7d" | "30d" | "90d" | "custom";
|
|
394
|
+
|
|
395
|
+
export interface UsageLogListParams {
|
|
396
|
+
customerId: string;
|
|
397
|
+
/** Default 50, max 200. */
|
|
398
|
+
limit?: number;
|
|
399
|
+
/** Pass back a previous page's `nextCursor` to fetch the next page. Omit for
|
|
400
|
+
* the first page. */
|
|
401
|
+
cursor?: string;
|
|
402
|
+
/** Default `"all"`. Pair `"custom"` with `from`/`to`. */
|
|
403
|
+
period?: UsageLogPeriod;
|
|
404
|
+
/** `YYYY-MM-DD`, only used when `period` is `"custom"`. */
|
|
405
|
+
from?: string;
|
|
406
|
+
/** `YYYY-MM-DD`, only used when `period` is `"custom"`. */
|
|
407
|
+
to?: string;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export interface UsageLogAppliedRule {
|
|
411
|
+
ruleId: string | null;
|
|
412
|
+
ruleName: string;
|
|
413
|
+
mode: "MARGIN" | "CREDIT" | null;
|
|
414
|
+
marginPercentApplied: number | null;
|
|
415
|
+
/** Formatted, same as {@link UsageLogEntry.credit}'s `amount`. */
|
|
416
|
+
creditsApplied: string;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface UsageLogOutcomeAttribution {
|
|
420
|
+
/** "2 / 4" — the step this call performed, and the outcome's total step
|
|
421
|
+
* count. Not a progress target: a step may repeat within a run. */
|
|
422
|
+
step: string | null;
|
|
423
|
+
stepName: string | null;
|
|
424
|
+
runId: string | null;
|
|
425
|
+
/** How many signals the run holds. */
|
|
426
|
+
runSignals: number;
|
|
427
|
+
/** True once the run closed (`complete: true` was sent for it). */
|
|
428
|
+
closedRun: boolean;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* One row of a customer's usage history, merged from every meter kind
|
|
433
|
+
* (`UsageLog`, `UnitUsageLog`, completed composite occurrences) into one
|
|
434
|
+
* feed and sorted by time — the same rows the customer portal's own "Usage
|
|
435
|
+
* logs" table shows. `model`, `credit`, `outcome`, `unit` and `composite` are
|
|
436
|
+
* each `null` unless `kind` matches that group.
|
|
437
|
+
*/
|
|
438
|
+
export interface UsageLogEntry {
|
|
439
|
+
id: string;
|
|
440
|
+
createdAt: string;
|
|
441
|
+
kind: "credit" | "outcome" | "unit" | "wallet" | "composite";
|
|
442
|
+
status: SignalStatus;
|
|
443
|
+
typeName: string | null;
|
|
444
|
+
member: string | null;
|
|
445
|
+
model: { name: string | null; provider: string | null } | null;
|
|
446
|
+
usage: { inputTokens: number; outputTokens: number; cacheTokens: number };
|
|
447
|
+
/** Formatted USD strings (e.g. `"$0.0064"`). */
|
|
448
|
+
cost: { providedCost: string; customerCost: string };
|
|
449
|
+
/** Populated only when `kind === "credit"`. `amount` is a formatted credit
|
|
450
|
+
* value, honouring the org's credit-decimals display setting. */
|
|
451
|
+
credit: { amount: string; appliedRules: UsageLogAppliedRule[] } | null;
|
|
452
|
+
/** Populated only when `kind === "outcome"`. */
|
|
453
|
+
outcome: UsageLogOutcomeAttribution | null;
|
|
454
|
+
/** Populated only when `kind === "unit"`. `quantity` is formatted. */
|
|
455
|
+
unit: { quantity: string } | null;
|
|
456
|
+
/** Populated only when `kind === "composite"`. `amount` is a formatted USD
|
|
457
|
+
* price — the composite's flat price, read live, not stored per row. */
|
|
458
|
+
composite: { amount: string } | null;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export interface UsageLogPage {
|
|
462
|
+
usageLogs: UsageLogEntry[];
|
|
463
|
+
/** Pass this back as `cursor` to fetch the next page; `null` on the last
|
|
464
|
+
* page. */
|
|
465
|
+
nextCursor: string | null;
|
|
466
|
+
}
|
|
467
|
+
|
|
340
468
|
// ---------------------------------------------------------------------------
|
|
341
469
|
// Customers (mirrors src/lib/customers/api.ts)
|
|
342
470
|
// ---------------------------------------------------------------------------
|
|
@@ -978,7 +1106,9 @@ export interface WalletEntryInput {
|
|
|
978
1106
|
}
|
|
979
1107
|
|
|
980
1108
|
/** Grant (positive) or claw back (negative) a credit balance. `delta` must be a
|
|
981
|
-
* non-zero whole number. The credit is addressed by its stable `agentKey`.
|
|
1109
|
+
* non-zero whole number. The credit is addressed by its stable `agentKey`. A
|
|
1110
|
+
* reduce is never rejected or floored for going below 0 — the resulting
|
|
1111
|
+
* balance may read negative, same as a real-usage overdraft already can. */
|
|
982
1112
|
export interface CreditAdjustInput {
|
|
983
1113
|
/** The credit's stable agent key (the same key used to record usage). */
|
|
984
1114
|
agentKey: string;
|
|
@@ -986,10 +1116,12 @@ export interface CreditAdjustInput {
|
|
|
986
1116
|
notes?: string;
|
|
987
1117
|
}
|
|
988
1118
|
|
|
989
|
-
/** Grant/claw an outcome balance. `delta` is a non-zero whole number
|
|
990
|
-
*
|
|
1119
|
+
/** Grant/claw an outcome balance. `delta` is a non-zero whole number. The
|
|
1120
|
+
* outcome is addressed here by a STEP's `agentKey`, which resolves to its
|
|
991
1121
|
* parent outcome — NOT by the outcome's own `agentKey` ({@link Outcome.agentKey}),
|
|
992
|
-
* which this endpoint does not accept.
|
|
1122
|
+
* which this endpoint does not accept. A reduce is never rejected or floored
|
|
1123
|
+
* for going below 0 — the resulting balance may read negative, same as a
|
|
1124
|
+
* real-usage overdraft already can. */
|
|
993
1125
|
export interface OutcomeAdjustInput {
|
|
994
1126
|
/** An outcome STEP's stable agent key — identifies the parent outcome. Passing
|
|
995
1127
|
* the outcome's own `agentKey` here fails with `422`. */
|
|
@@ -998,8 +1130,10 @@ export interface OutcomeAdjustInput {
|
|
|
998
1130
|
notes?: string;
|
|
999
1131
|
}
|
|
1000
1132
|
|
|
1001
|
-
/** Grant/claw a unit balance. `delta` is non-zero (fractional allowed)
|
|
1002
|
-
*
|
|
1133
|
+
/** Grant/claw a unit balance. `delta` is non-zero (fractional allowed). The
|
|
1134
|
+
* unit is addressed by its stable `agentKey`. A reduce is never rejected or
|
|
1135
|
+
* floored for going below 0 — the resulting balance may read negative, same
|
|
1136
|
+
* as a real-usage overdraft already can. */
|
|
1003
1137
|
export interface UnitAdjustInput {
|
|
1004
1138
|
/** The unit's stable agent key (the same key used to record usage). */
|
|
1005
1139
|
agentKey: string;
|
|
@@ -1007,6 +1141,26 @@ export interface UnitAdjustInput {
|
|
|
1007
1141
|
notes?: string;
|
|
1008
1142
|
}
|
|
1009
1143
|
|
|
1144
|
+
/**
|
|
1145
|
+
* Grant (positive) or claw back (negative) slots on a customer's ADVANCE
|
|
1146
|
+
* composite (pricing metric) pool for the CURRENT billing cycle. `delta` is a
|
|
1147
|
+
* non-zero whole number. A reduce is never rejected or floored for going below
|
|
1148
|
+
* 0 — same as credit/outcome/unit adjustments; the resulting pool may read
|
|
1149
|
+
* negative. Fails if the customer has no active ADVANCE purchase component
|
|
1150
|
+
* selling this composite.
|
|
1151
|
+
*/
|
|
1152
|
+
export interface CompositeAdjustInput {
|
|
1153
|
+
/**
|
|
1154
|
+
* The composite's stable identifier — its `refId` (see {@link Composite.refId}),
|
|
1155
|
+
* the same value signals tag it with, NOT `agentKey` (a composite has no
|
|
1156
|
+
* `agentKey` column of its own). Named `agentKey` on the wire only so the
|
|
1157
|
+
* four adjust endpoints share one request shape.
|
|
1158
|
+
*/
|
|
1159
|
+
agentKey: string;
|
|
1160
|
+
delta: number;
|
|
1161
|
+
notes?: string;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1010
1164
|
// ---------------------------------------------------------------------------
|
|
1011
1165
|
// Entitlement catalogs: Credits, Outcomes, Units
|
|
1012
1166
|
// ---------------------------------------------------------------------------
|