margin-meter 0.1.0 → 0.3.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 +353 -8
- package/dist/batching.d.ts +94 -0
- package/dist/batching.d.ts.map +1 -0
- package/dist/batching.js +181 -0
- package/dist/batching.js.map +1 -0
- package/dist/braintrust.d.ts +153 -0
- package/dist/braintrust.d.ts.map +1 -0
- package/dist/braintrust.js +424 -0
- package/dist/braintrust.js.map +1 -0
- package/dist/index.d.ts +428 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +927 -9
- package/dist/index.js.map +1 -1
- package/dist/instrument.d.ts +74 -0
- package/dist/instrument.d.ts.map +1 -0
- package/dist/instrument.js +153 -0
- package/dist/instrument.js.map +1 -0
- package/dist/langsmith.d.ts +150 -0
- package/dist/langsmith.d.ts.map +1 -0
- package/dist/langsmith.js +415 -0
- package/dist/langsmith.js.map +1 -0
- package/dist/promptfoo.d.ts +161 -0
- package/dist/promptfoo.d.ts.map +1 -0
- package/dist/promptfoo.js +446 -0
- package/dist/promptfoo.js.map +1 -0
- package/dist/providers.d.ts +190 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +611 -0
- package/dist/providers.js.map +1 -0
- package/dist/substrate.d.ts +51 -0
- package/dist/substrate.d.ts.map +1 -0
- package/dist/substrate.js +132 -0
- package/dist/substrate.js.map +1 -0
- package/dist/vitest.d.ts +232 -0
- package/dist/vitest.d.ts.map +1 -0
- package/dist/vitest.js +502 -0
- package/dist/vitest.js.map +1 -0
- package/package.json +25 -7
package/dist/index.d.ts
CHANGED
|
@@ -21,11 +21,122 @@
|
|
|
21
21
|
* written `source` is forced server-side to the key's project slug — the
|
|
22
22
|
* client cannot spoof another project's economics.
|
|
23
23
|
*/
|
|
24
|
+
import { type ProviderName } from "./providers.ts";
|
|
25
|
+
import { type Substrate } from "./substrate.ts";
|
|
26
|
+
export * from "./providers.ts";
|
|
27
|
+
export * from "./instrument.ts";
|
|
28
|
+
export * from "./batching.ts";
|
|
29
|
+
export * as substrate from "./substrate.ts";
|
|
30
|
+
export type { Substrate } from "./substrate.ts";
|
|
31
|
+
export * as promptfoo from "./promptfoo.ts";
|
|
32
|
+
export * as braintrust from "./braintrust.ts";
|
|
33
|
+
export * as langsmith from "./langsmith.ts";
|
|
34
|
+
export * as vitest from "./vitest.ts";
|
|
24
35
|
export declare const CALLS_PATH = "/api/ingest/calls";
|
|
25
36
|
export declare const OUTCOMES_PATH = "/api/ingest/outcomes";
|
|
26
37
|
export declare const KEY_HEADER = "X-Margin-Key";
|
|
27
|
-
export declare const DEFAULT_INGEST_URL = "http://127.0.0.1:8000";
|
|
28
38
|
export declare const DEFAULT_TIMEOUT_MS = 10000;
|
|
39
|
+
/** One batched request's byte ceiling, and the retry policy behind it. Full
|
|
40
|
+
* reasoning in `docs/reference/SDK_BATCHING.md`; the short version:
|
|
41
|
+
*
|
|
42
|
+
* - 1 MB is ~7x headroom over a worst-case 1500-byte row at the default 100
|
|
43
|
+
* records, and far under any gateway limit. Vercel accepts 100 MB bodies;
|
|
44
|
+
* that is a ceiling, not a target.
|
|
45
|
+
* - 3 attempts with FULL jitter rather than plain exponential, because every
|
|
46
|
+
* buffered client backs off on the same schedule and un-jittered retries
|
|
47
|
+
* re-synchronise into a herd aimed at the endpoint that just failed.
|
|
48
|
+
* - Duplicates from an at-least-once retry are free: every record carries an
|
|
49
|
+
* `event_id` and the server is idempotent on `(source, event_id)`.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MAX_BATCH_BYTES = 1000000;
|
|
52
|
+
export declare const RETRY_ATTEMPTS = 3;
|
|
53
|
+
export declare const RETRY_BASE_MS = 1000;
|
|
54
|
+
export declare const RETRY_CAP_MS = 30000;
|
|
55
|
+
/** The active step's re-label. Mirrors the Python `_STAGE_OVERRIDE` tuple. */
|
|
56
|
+
interface StageOverride {
|
|
57
|
+
operation?: string;
|
|
58
|
+
sessionId?: string;
|
|
59
|
+
taskClass?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Options for {@link stage}. */
|
|
62
|
+
export interface StageOptions {
|
|
63
|
+
/** The run this step belongs to. Wins over a `sessionId` passed at the call —
|
|
64
|
+
* that is how the steps of one multi-agent run share an id. */
|
|
65
|
+
sessionId?: string;
|
|
66
|
+
/** WHAT KIND of work this step does, in the vocabulary the face-off ledger is
|
|
67
|
+
* keyed on (`signal-check`, `document-extraction`, …). DECLARED, never inferred
|
|
68
|
+
* from the step name (see `RecordCallInput.taskClass`). A call that names its
|
|
69
|
+
* own `taskClass` keeps it; this fills the ones that do not. */
|
|
70
|
+
taskClass?: string;
|
|
71
|
+
/** Attach this step under a parent the async context cannot see — a branch run
|
|
72
|
+
* on a worker (`AsyncLocalStorage` does not cross a worker boundary, exactly as
|
|
73
|
+
* a Python contextvar does not cross a bare thread). Without it such a branch
|
|
74
|
+
* records as a root, which reads as "no chain happened" rather than the missing
|
|
75
|
+
* edge it is, so pass it by hand there. */
|
|
76
|
+
parentSpanId?: string;
|
|
77
|
+
}
|
|
78
|
+
/** Options for {@link span}. */
|
|
79
|
+
export interface SpanOptions {
|
|
80
|
+
/** The orchestration shape THIS block performs. Rides only the calls emitted
|
|
81
|
+
* directly in it — a nested span opens its own node and inherits none of it, so
|
|
82
|
+
* `branchWidth` on a child cannot claim the child did the fanning out. */
|
|
83
|
+
pattern?: "pipeline" | "barrier" | "panel" | "loop_until_dry";
|
|
84
|
+
/** How many branches the orchestration opened. */
|
|
85
|
+
branchWidth?: number;
|
|
86
|
+
/** The rule that ended the orchestration, free text (e.g. "majority of 3"). */
|
|
87
|
+
stoppingRule?: string;
|
|
88
|
+
/** Force this node's id instead of generating one — for a branch resumed in
|
|
89
|
+
* another process that must reuse a known id. */
|
|
90
|
+
spanId?: string;
|
|
91
|
+
/** Attach this node under a parent the async context cannot see (worker/process
|
|
92
|
+
* boundary), the same case as {@link StageOptions.parentSpanId}. */
|
|
93
|
+
parentSpanId?: string;
|
|
94
|
+
}
|
|
95
|
+
/** Mark one STEP of a pipeline — its name, its identity in the chain, and its kind
|
|
96
|
+
* — for the length of `fn`. Every call `fn` makes, however many awaits deep,
|
|
97
|
+
* meters as this operation and records as one node of the chain, nested under any
|
|
98
|
+
* enclosing `stage`/`span`. Returns whatever `fn` returns (a value or a promise).
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { MarginMeter, stage, instrumentGemini } from "margin-meter";
|
|
102
|
+
* await stage("classify", { taskClass: "signal-check", sessionId: runId }, () =>
|
|
103
|
+
* classifier.run(input), // meters as operation="classify"
|
|
104
|
+
* );
|
|
105
|
+
* await stage("implement", { taskClass: "algorithm", sessionId: runId }, () =>
|
|
106
|
+
* implementer.run(plan), // ... and these as operation="implement"
|
|
107
|
+
* );
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* The two steps share `sessionId` but carry DISTINCT operations, so the run reads
|
|
111
|
+
* as a real >=2-step pipeline instead of collapsing onto one node — the exact bug
|
|
112
|
+
* the Python SDK hit before `stage()` opened a span. The step's span id is passed
|
|
113
|
+
* to `fn`, for the worker-boundary case where a child must be attached explicitly
|
|
114
|
+
* via {@link StageOptions.parentSpanId}. This is the TS twin of `margin_meter.stage`. */
|
|
115
|
+
export declare function stage<T>(operation: string, fn: (spanId: string) => T): T;
|
|
116
|
+
export declare function stage<T>(operation: string, opts: StageOptions, fn: (spanId: string) => T): T;
|
|
117
|
+
/** The active `(operation, sessionId, taskClass)` step override, or `undefined`
|
|
118
|
+
* outside any `stage`. */
|
|
119
|
+
export declare function currentStage(): StageOverride | undefined;
|
|
120
|
+
/** Mark every metered call inside `fn` as one node of an agent tree — the tree the
|
|
121
|
+
* Money Map decomposes to ask what a BRANCH cost, which a flat list of calls
|
|
122
|
+
* sharing a `sessionId` cannot answer. Nesting is what builds the tree; returns
|
|
123
|
+
* whatever `fn` returns.
|
|
124
|
+
*
|
|
125
|
+
* ```ts
|
|
126
|
+
* await span({ pattern: "panel", branchWidth: 3, stoppingRule: "majority of 3" }, () =>
|
|
127
|
+
* Promise.all(candidates.map((c) => judge(c))), // each judge nests its own node
|
|
128
|
+
* );
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* `stage()` is the primitive to reach for on a plain pipeline step; `span()` adds
|
|
132
|
+
* the orchestration shape when a block fans out. This is the TS twin of
|
|
133
|
+
* `margin_meter.span`. */
|
|
134
|
+
export declare function span<T>(opts: SpanOptions, fn: (spanId: string) => T): T;
|
|
135
|
+
/** The active `(spanId, parentSpanId)`, or `undefined` outside any span/stage. */
|
|
136
|
+
export declare function currentSpan(): {
|
|
137
|
+
spanId: string;
|
|
138
|
+
parentSpanId?: string;
|
|
139
|
+
} | undefined;
|
|
29
140
|
/** The outcome of one emit. Returned by every record call. */
|
|
30
141
|
export interface IngestResult {
|
|
31
142
|
/** True only on an HTTP 200. */
|
|
@@ -36,6 +147,37 @@ export interface IngestResult {
|
|
|
36
147
|
body?: Record<string, unknown>;
|
|
37
148
|
/** The failure reason, when not ok. */
|
|
38
149
|
error?: string;
|
|
150
|
+
/** The same failure as a stable BUCKET (`no_key`, `transport`, `http_<status>`).
|
|
151
|
+
* `error` is a human sentence and its wording moves, so anything COUNTING
|
|
152
|
+
* failures reads this instead of parsing that. Absent when ok. */
|
|
153
|
+
reason?: string;
|
|
154
|
+
}
|
|
155
|
+
/** What a meter TRIED to deliver against what actually landed.
|
|
156
|
+
*
|
|
157
|
+
* A meter is fail-safe by contract: a dropped row never breaks the host app and
|
|
158
|
+
* never throws. That trade is right — telemetry must not take an agent down —
|
|
159
|
+
* but it makes the failure INVISIBLE, and an invisible loss reads downstream as
|
|
160
|
+
* traffic that never happened. Margin's own 2026-07-25 invoice reconcile found
|
|
161
|
+
* ~65 of ~200 `gpt-4o` calls missing from the ledger with nothing anywhere
|
|
162
|
+
* having recorded a single failure, so the rate could not be told from the cause.
|
|
163
|
+
*
|
|
164
|
+
* `dropRate` is the number that answers "is the ledger short because the agent
|
|
165
|
+
* made fewer calls, or because we failed to deliver them?" — the one question a
|
|
166
|
+
* coverage gap cannot answer about itself.
|
|
167
|
+
*
|
|
168
|
+
* Narrower than the Python SDK's `DeliveryStats` on purpose, not by omission:
|
|
169
|
+
* this client has no file sink and no cross-hook de-dup, so it has no
|
|
170
|
+
* `unmeasured` holes to name and no `deduped` suppressions to keep out of the
|
|
171
|
+
* loss count. Every emit it makes goes through one door and is counted there. */
|
|
172
|
+
export interface DeliveryStats {
|
|
173
|
+
attempted: number;
|
|
174
|
+
delivered: number;
|
|
175
|
+
dropped: number;
|
|
176
|
+
/** Share of attempted emits that never landed. 0 when nothing was tried. */
|
|
177
|
+
dropRate: number;
|
|
178
|
+
droppedByReason: Record<string, number>;
|
|
179
|
+
attemptedByPath: Record<string, number>;
|
|
180
|
+
droppedByPath: Record<string, number>;
|
|
39
181
|
}
|
|
40
182
|
/** The response shape a transport returns (a subset of the `fetch` Response). */
|
|
41
183
|
export interface TransportResponse {
|
|
@@ -84,21 +226,140 @@ export interface RecordCallInput {
|
|
|
84
226
|
inputTokens?: number;
|
|
85
227
|
outputTokens?: number;
|
|
86
228
|
cacheReadTokens?: number;
|
|
229
|
+
cacheCreationTokens?: number;
|
|
230
|
+
/** The 1-hour-TTL portion of cache creation (Anthropic bills it ~2x input, not
|
|
231
|
+
* the 5-minute ~1.25x). Disjoint from cacheCreationTokens; omit/0 when a call
|
|
232
|
+
* uses only the default cache. */
|
|
233
|
+
cacheCreation1hTokens?: number;
|
|
234
|
+
/** The hidden-thinking share of outputTokens (Gemini thoughts, OpenAI
|
|
235
|
+
* reasoning_tokens). A SUBSET of output, already priced at the output rate —
|
|
236
|
+
* never priced separately. Carried only so the reasoning-effort lever can be
|
|
237
|
+
* isolated; omit/0 on a non-reasoning call. */
|
|
238
|
+
reasoningTokens?: number;
|
|
87
239
|
latencyMs?: number;
|
|
88
240
|
status?: string;
|
|
89
241
|
isRetry?: boolean;
|
|
90
242
|
sessionId?: string;
|
|
91
243
|
promptId?: string;
|
|
244
|
+
/** The STEP within a multi-operation workflow this call belongs to (a
|
|
245
|
+
* supply-chain node label the Money Map decomposes by, e.g. "extract"). Omit
|
|
246
|
+
* for a single-call workflow. */
|
|
247
|
+
operation?: string;
|
|
248
|
+
/** WHERE the agent lives — the org-chart rung ABOVE it (MAR-345). `environment`
|
|
249
|
+
* is prod/staging; `team` is who owns it. Two fields rather than one composite
|
|
250
|
+
* because they are two questions: "is this real traffic?" and "whose budget?".
|
|
251
|
+
*
|
|
252
|
+
* ⛔ These are LABELS. They group rows in the estate view and authorise nothing
|
|
253
|
+
* — ownership is still the ingest key's project, forced server-side, which is
|
|
254
|
+
* the part a caller cannot spoof. Omit both and the registry reports the agent
|
|
255
|
+
* under `(unlabelled)`, never a home it did not claim.
|
|
256
|
+
*
|
|
257
|
+
* ⚠️ Omitting them is not free, though: the estate tree collapses from four
|
|
258
|
+
* rungs to two, so "you are running 34 agents across 3 environments" degrades
|
|
259
|
+
* to a flat list. Measured 2026-08-08 — every production row was `(unlabelled)`
|
|
260
|
+
* because this SDK had no way to send them at all. */
|
|
261
|
+
environment?: string;
|
|
262
|
+
team?: string;
|
|
92
263
|
costUsd?: number;
|
|
93
264
|
isSimulated?: boolean;
|
|
265
|
+
/** Idempotency key baked into the emitted payload. Defaults to a fresh uuid
|
|
266
|
+
* per call, so a redelivery of THIS exact emit (a transport retry) collapses
|
|
267
|
+
* to one row server-side instead of double-counting spend. Distinct calls get
|
|
268
|
+
* distinct ids, so real volume is never deduped away. */
|
|
269
|
+
eventId?: string;
|
|
270
|
+
/** The provider billing tier. "standard" (the default) is a normal synchronous
|
|
271
|
+
* call; "batch" is a call routed through the async Batch API, which the server
|
|
272
|
+
* prices at the ~50%-off tier — pricing a real batch call standard would
|
|
273
|
+
* over-state its cost. Omit for standard; the field is sent only when "batch". */
|
|
274
|
+
billingTier?: "standard" | "batch";
|
|
275
|
+
/** This call's own node in an agent tree. A branching run is otherwise a flat
|
|
276
|
+
* list of calls sharing a sessionId — enough to total the run, never enough to
|
|
277
|
+
* ask what one BRANCH cost. Omit for a single-agent call. */
|
|
278
|
+
spanId?: string;
|
|
279
|
+
/** The node that spawned this one; omit at the root. Requires `spanId` (a parent
|
|
280
|
+
* link with no node of its own is an edge to nowhere, and the server rejects
|
|
281
|
+
* it). */
|
|
282
|
+
parentSpanId?: string;
|
|
283
|
+
/** The orchestration shape THIS call performed, on the node that did the
|
|
284
|
+
* orchestrating — not on its branches. The set is closed server-side so shapes
|
|
285
|
+
* stay comparable across runs. */
|
|
286
|
+
orchestrationPattern?: "pipeline" | "barrier" | "panel" | "loop_until_dry";
|
|
287
|
+
/** How many branches the orchestration opened. */
|
|
288
|
+
branchWidth?: number;
|
|
289
|
+
/** The rule that ended the orchestration, free text (e.g. "majority of 3"). */
|
|
290
|
+
stoppingRule?: string;
|
|
291
|
+
/** Which PATH this call took to reach the model — the vendor's own API
|
|
292
|
+
* ("direct"), a router ("openrouter", "litellm"), a cloud reseller ("azure",
|
|
293
|
+
* "bedrock", "vertex"), or an unrecognised proxy ("gateway"). Independent of
|
|
294
|
+
* `provider`, which says who owns the model and bills for it: the same
|
|
295
|
+
* openai/gpt-4o call can arrive over four different paths, and comparing them
|
|
296
|
+
* is something a single-substrate router structurally cannot do. Omit it when
|
|
297
|
+
* the path is not actually known — an unmeasured dimension belongs empty, not
|
|
298
|
+
* defaulted to "direct". The set is closed server-side. */
|
|
299
|
+
substrate?: "direct" | "openrouter" | "litellm" | "azure" | "bedrock" | "vertex" | "gateway";
|
|
300
|
+
/** WHICH UNIT OF WORK this call served, in your own vocabulary — a ticket
|
|
301
|
+
* topic, an intent label, a corpus task id. Margin measures a route's parity
|
|
302
|
+
* on a sample and records what that sample was made of; this is what lets it
|
|
303
|
+
* then say whether the traffic arriving now is still that population, rather
|
|
304
|
+
* than only whether the route got worse. Omit it and that question reads
|
|
305
|
+
* `unknown`, which is the honest answer and a permanent one. Open-ended on
|
|
306
|
+
* purpose: a topic nobody has seen before is how a mix shift announces
|
|
307
|
+
* itself. Never priced. Truncated server-side at 128 characters rather than
|
|
308
|
+
* refused — a long ticket subject costs you the tail of the label, never the
|
|
309
|
+
* call's tokens or cost. */
|
|
310
|
+
taskKey?: string;
|
|
311
|
+
/** WHAT KIND of work this step does (MAR-898), in the vocabulary Margin's face-off
|
|
312
|
+
* ledger is keyed on: `signal-check`, `document-extraction`, `multi-hop-reasoning`,
|
|
313
|
+
* `algorithm`. `taskKey` is WHICH unit of work; this is WHAT KIND, and the
|
|
314
|
+
* difference matters because a hold-rate prior is earned per CLASS — so a step
|
|
315
|
+
* without one can be measured and still not be advisable.
|
|
316
|
+
*
|
|
317
|
+
* ⛔ DECLARE IT; never let it be inferred from a step name. An operation called
|
|
318
|
+
* `summarize` may or may not be the class the ledger calls document-extraction,
|
|
319
|
+
* and mapping by resemblance would attach a real model recommendation to work it
|
|
320
|
+
* may not describe. Omit it and the step reads `not_measured` in a per-stage plan,
|
|
321
|
+
* which is the honest answer. Never priced; truncated server-side at 128. */
|
|
322
|
+
taskClass?: string;
|
|
323
|
+
/** WHICH AGENT SCAFFOLD drove the call (MAR-371) — the orchestration around the
|
|
324
|
+
* model (Claude Code, a LangChain agent, a bespoke loop). The same model on the
|
|
325
|
+
* same tasks costs differently by which harness ran it (Composio measured a 4.7x
|
|
326
|
+
* spread across eight), independent of `model` and `substrate`. Open-ended, never
|
|
327
|
+
* priced, truncated server-side at 64 characters. Omit it when the scaffold is not
|
|
328
|
+
* known — an unmeasured dimension belongs empty. */
|
|
329
|
+
harness?: string;
|
|
330
|
+
/** WHY the provider ended the generation, read verbatim off the response
|
|
331
|
+
* (Anthropic `stop_reason`, OpenAI/Gemini `finish_reason`, Bedrock `stopReason`).
|
|
332
|
+
* A raw signal, NOT a billing verdict: a blocked-and-fell-back call (Fable 5's
|
|
333
|
+
* safety fallback) is often not billed, but that is settled by the invoice, never
|
|
334
|
+
* inferred from this reason alone (MAR-209). Rides only when the provider reported
|
|
335
|
+
* one; absent it stays `unknown`, first-class. Never priced. Truncated
|
|
336
|
+
* server-side (open vocabulary — a novel reason is never a dropped row). */
|
|
337
|
+
finishReason?: string;
|
|
94
338
|
}
|
|
95
339
|
export interface RecordOutcomeInput {
|
|
96
340
|
workflowId: string;
|
|
97
341
|
passed: boolean;
|
|
98
342
|
qualityScore?: number;
|
|
99
343
|
qualityMethod?: string;
|
|
344
|
+
/** WHO/what graded the score: "code" | "judge" | "human". Recorded, never
|
|
345
|
+
* inferred — omit to leave the grader kind unknown on the server. */
|
|
346
|
+
graderKind?: string;
|
|
347
|
+
/** Model id that judged when graderKind is "judge". */
|
|
348
|
+
judgeModelId?: string;
|
|
349
|
+
/** How SURE the grader was of qualityScore, in [0, 1]. Recorded, never inferred —
|
|
350
|
+
* omit to leave it unknown on the server (a missing value is never read as
|
|
351
|
+
* "certain"). */
|
|
352
|
+
graderConfidence?: number;
|
|
100
353
|
link?: string;
|
|
101
354
|
isSimulated?: boolean;
|
|
355
|
+
/** Idempotency key (see RecordCallInput.eventId): a redelivered outcome does
|
|
356
|
+
* not double-count the cost-per-outcome denominator. Defaults to a fresh uuid. */
|
|
357
|
+
eventId?: string;
|
|
358
|
+
/** The WORTH of this outcome in USD — the value-per-outcome NUMERATOR
|
|
359
|
+
* (RA-31 / MAR-634). Supply it when the outcome has a known business value;
|
|
360
|
+
* omit it and the outcome is measured as cost-per-outcome, the honest default.
|
|
361
|
+
* Optional by construction — absent is the normal case, never defaulted to 0. */
|
|
362
|
+
valueUsd?: number;
|
|
102
363
|
}
|
|
103
364
|
/** A per-project client that emits measured economics to a Margin ingest API. */
|
|
104
365
|
export declare class MarginMeter {
|
|
@@ -106,8 +367,84 @@ export declare class MarginMeter {
|
|
|
106
367
|
apiKey?: string;
|
|
107
368
|
raiseOnError: boolean;
|
|
108
369
|
private transport;
|
|
370
|
+
private attempted;
|
|
371
|
+
private delivered;
|
|
372
|
+
private droppedByReason;
|
|
373
|
+
private attemptedByPath;
|
|
374
|
+
private droppedByPath;
|
|
375
|
+
private warnedOnDrop;
|
|
376
|
+
private noUrl;
|
|
377
|
+
private batcher;
|
|
378
|
+
private exitFlush;
|
|
379
|
+
private exitFlushArmed;
|
|
109
380
|
constructor(options?: MarginMeterOptions);
|
|
381
|
+
/** Attach the process-exit flush, once, on the first row that will need it. */
|
|
382
|
+
private armExitFlush;
|
|
383
|
+
/** Record one emit attempt. Called at every exit point that knows its own
|
|
384
|
+
* outcome, BEFORE any `raiseOnError` throw, so a strict-mode failure is
|
|
385
|
+
* counted exactly like the fail-safe one it would otherwise have been. */
|
|
386
|
+
private count;
|
|
387
|
+
/** A snapshot of what this meter delivered against what it tried to.
|
|
388
|
+
* See {@link DeliveryStats}. */
|
|
389
|
+
deliveryStats(): DeliveryStats;
|
|
390
|
+
/**
|
|
391
|
+
* Route one built payload to the wire or the buffer.
|
|
392
|
+
*
|
|
393
|
+
* Buffering is the default and the whole point (`docs/reference/SDK_BATCHING.md`).
|
|
394
|
+
* Two cases deliberately stay immediate, and neither is a knob:
|
|
395
|
+
*
|
|
396
|
+
* - **Strict mode** (`raiseOnError`) means "throw at MY call site when this row
|
|
397
|
+
* is rejected", and a buffered emit has no call site left to throw at by the
|
|
398
|
+
* time the POST happens. The two are incompatible, so strict posts now.
|
|
399
|
+
* - **No key**, because buffering rows that can never be sent would fill the
|
|
400
|
+
* queue and then report `queue_full` — a diagnosis that sends the reader
|
|
401
|
+
* hunting for a network problem when the answer is a missing variable.
|
|
402
|
+
* A missing URL is the same case and is named `no_url`.
|
|
403
|
+
*/
|
|
110
404
|
private emit;
|
|
405
|
+
/** Hand one record to the buffer. Never blocks, never throws.
|
|
406
|
+
*
|
|
407
|
+
* `ok: true` here means ACCEPTED INTO THE BUFFER, not written to the ledger —
|
|
408
|
+
* the body says `queued` so nothing mistakes the two. What actually landed is
|
|
409
|
+
* `deliveryStats()`, which exists for exactly this question. */
|
|
410
|
+
private enqueue;
|
|
411
|
+
/** Resolve once every buffered row has been delivered or counted as dropped.
|
|
412
|
+
*
|
|
413
|
+
* Call it before reading `deliveryStats()` if you need the counts to cover rows
|
|
414
|
+
* you have only just emitted — buffering separates an emit from its delivery
|
|
415
|
+
* in time by design. */
|
|
416
|
+
flush(): Promise<void>;
|
|
417
|
+
/** Drain the buffer and stop the timer. Registered on `beforeExit`.
|
|
418
|
+
*
|
|
419
|
+
* Anything the timeout strands is COUNTED as dropped rather than abandoned: the
|
|
420
|
+
* records are handed back by `Batcher.close` precisely so the number is
|
|
421
|
+
* knowable. */
|
|
422
|
+
close(timeoutMs?: number): Promise<void>;
|
|
423
|
+
private postNow;
|
|
424
|
+
/** POST one buffered batch. Never rejects: it owns its own accounting.
|
|
425
|
+
*
|
|
426
|
+
* ⛔ The blanket `catch` is load-bearing, not defensive habit. `Batcher.flush`
|
|
427
|
+
* swallows a rejection to keep the drain going, so anything escaping here would
|
|
428
|
+
* vanish with the counters reading a clean sheet — an uncounted loss, which
|
|
429
|
+
* makes measured spend read CHEAPER than the bill. Scoped per chunk so records
|
|
430
|
+
* already accounted for in an earlier chunk are not counted twice. */
|
|
431
|
+
private sendBatch;
|
|
432
|
+
/** Split a batch so no request exceeds {@link MAX_BATCH_BYTES}.
|
|
433
|
+
*
|
|
434
|
+
* ⛔ A single record over the cap on its own is DROPPED and counted as
|
|
435
|
+
* `oversize`. No split can send it, and keeping it would wedge the queue behind
|
|
436
|
+
* one poisoned row forever. It is a bug in the caller — every open-vocabulary
|
|
437
|
+
* field is already bounded server-side, so an honest row cannot come near a
|
|
438
|
+
* megabyte.
|
|
439
|
+
*
|
|
440
|
+
* ⛔ A payload that will not serialise is dropped and counted too, and that case
|
|
441
|
+
* is not exotic — a `BigInt` anywhere in the payload makes `JSON.stringify`
|
|
442
|
+
* throw. Unguarded, the throw escaped into the flush and the row vanished with
|
|
443
|
+
* the counters reading a clean sheet. */
|
|
444
|
+
private chunkByBytes;
|
|
445
|
+
private deliverChunk;
|
|
446
|
+
/** POST one batch, retrying the failures that clear with time. */
|
|
447
|
+
private postBatchWithRetry;
|
|
111
448
|
/** Emit one measured LLM call. Cost is computed server-side when `costUsd`
|
|
112
449
|
* is omitted. Never throws unless `raiseOnError`. */
|
|
113
450
|
recordCall(input: RecordCallInput): Promise<IngestResult>;
|
|
@@ -122,17 +459,107 @@ export declare class MarginMeter {
|
|
|
122
459
|
* value `fn` produced; the emit's `IngestResult` is available as `m.result`.
|
|
123
460
|
*/
|
|
124
461
|
measure<T>(input: Omit<RecordCallInput, "latencyMs" | "status">, fn: (m: Measurement) => Promise<T> | T): Promise<T>;
|
|
462
|
+
/**
|
|
463
|
+
* Meter one call by reading tokens straight off its provider `response`
|
|
464
|
+
* (OpenAI / Anthropic / Gemini result). The no-bookkeeping counterpart to
|
|
465
|
+
* `recordCall`: the `(provider, model, tokens)` are recovered by
|
|
466
|
+
* `extractUsage`. `provider` is optional when the shape is unambiguous but the
|
|
467
|
+
* instrumenter always passes it; `model` overrides a response that omits it
|
|
468
|
+
* (Gemini). Numbers are read verbatim. Never throws unless `raiseOnError`.
|
|
469
|
+
*/
|
|
470
|
+
recordResponse(input: RecordResponseInput): Promise<IngestResult>;
|
|
471
|
+
/**
|
|
472
|
+
* Return `fn` wrapped so every call is timed and auto-metered. The core
|
|
473
|
+
* auto-instrumentation primitive: give it any async LLM call
|
|
474
|
+
* (`client.chat.completions.create`, `client.messages.create`,
|
|
475
|
+
* `model.generateContent` …) and it returns a drop-in replacement that times
|
|
476
|
+
* the call, emits its economics from the returned response, and hands the
|
|
477
|
+
* ORIGINAL response back untouched. On a throw the call is metered with
|
|
478
|
+
* `status="error"` and the error re-thrown (never swallowed); a metering
|
|
479
|
+
* failure is fail-safe and never breaks the wrapped call. `provider` is
|
|
480
|
+
* required for a shape the extractor can't disambiguate; `model` supplies a
|
|
481
|
+
* model the response omits (Gemini); `resolveModel(args)` derives it per call
|
|
482
|
+
* (e.g. off a bound Gemini model). Signature-agnostic (`...args`).
|
|
483
|
+
*/
|
|
484
|
+
wrap<F extends (...args: never[]) => Promise<unknown>>(fn: F, opts: WrapOptions): (...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>;
|
|
485
|
+
}
|
|
486
|
+
/** Input to `recordResponse` — meter off a provider response object. */
|
|
487
|
+
export interface RecordResponseInput {
|
|
488
|
+
workflowId: string;
|
|
489
|
+
response: unknown;
|
|
490
|
+
provider?: ProviderName;
|
|
491
|
+
model?: string;
|
|
492
|
+
latencyMs?: number;
|
|
493
|
+
status?: string;
|
|
494
|
+
isRetry?: boolean;
|
|
495
|
+
sessionId?: string;
|
|
496
|
+
promptId?: string;
|
|
497
|
+
operation?: string;
|
|
498
|
+
isSimulated?: boolean;
|
|
499
|
+
/** The delivery path the call took (see `substrate.ts`); omit when unknown. */
|
|
500
|
+
substrate?: Substrate;
|
|
501
|
+
/** The unit of work this call served (see `RecordCallInput.taskKey`). */
|
|
502
|
+
taskKey?: string;
|
|
503
|
+
}
|
|
504
|
+
/** Options for `wrap` — how to meter every call to the wrapped fn. */
|
|
505
|
+
export interface WrapOptions {
|
|
506
|
+
workflowId: string;
|
|
507
|
+
provider?: ProviderName;
|
|
508
|
+
model?: string;
|
|
509
|
+
operation?: string;
|
|
510
|
+
sessionId?: string;
|
|
511
|
+
isRetry?: boolean;
|
|
512
|
+
isSimulated?: boolean;
|
|
513
|
+
/** Derive the model per call (e.g. off a bound Gemini model); a truthy return
|
|
514
|
+
* overrides the static `model`. Receives the wrapped call's args. */
|
|
515
|
+
resolveModel?: (args: unknown[]) => string | undefined;
|
|
516
|
+
/** Derive the unit of work (`task_key`) per call — the WHICH-work axis. Resolved
|
|
517
|
+
* AT CALL TIME on purpose: task identity is per-call, so this is a callable (read
|
|
518
|
+
* a request-scoped store, the current ticket, an async-local), never a constant.
|
|
519
|
+
* A single constant across a whole run would manufacture a one-class distribution
|
|
520
|
+
* the mix gate treats as no signal (the reason the instrument path takes a
|
|
521
|
+
* resolver, not a `taskKey` string — MAR-197 / MAR-46). Undefined return, or no
|
|
522
|
+
* resolver, leaves the row's task_key unset: UNKNOWN, never a fabricated bucket. */
|
|
523
|
+
resolveTaskKey?: () => string | undefined;
|
|
524
|
+
/** OpenAI omits usage from a stream unless asked; when set (only by the OpenAI
|
|
525
|
+
* chat instrumenter), a `stream: true` call gets `stream_options.include_usage`
|
|
526
|
+
* injected so its final chunk carries the count the accumulator meters. */
|
|
527
|
+
streamIncludeUsage?: boolean;
|
|
528
|
+
/** Which DELIVERY PATH this wrapper's calls take (see `substrate.ts`). The JS
|
|
529
|
+
* instrumenters patch a specific client instance, so the endpoint is known at
|
|
530
|
+
* patch time and every call through this wrapper travelled it. Leave unset when
|
|
531
|
+
* the endpoint could not be read — an unmeasured dimension belongs empty, never
|
|
532
|
+
* defaulted to "direct". Never touches the cost math. */
|
|
533
|
+
substrate?: Substrate;
|
|
125
534
|
}
|
|
126
535
|
/** Token accumulator passed into `measure`'s callback. */
|
|
127
536
|
export declare class Measurement {
|
|
128
537
|
inputTokens: number;
|
|
129
538
|
outputTokens: number;
|
|
130
539
|
cacheReadTokens: number;
|
|
540
|
+
cacheCreationTokens: number;
|
|
541
|
+
cacheCreation1hTokens: number;
|
|
131
542
|
result?: IngestResult;
|
|
132
543
|
setTokens(tokens: {
|
|
133
544
|
inputTokens?: number;
|
|
134
545
|
outputTokens?: number;
|
|
135
546
|
cacheReadTokens?: number;
|
|
547
|
+
cacheCreationTokens?: number;
|
|
548
|
+
cacheCreation1hTokens?: number;
|
|
136
549
|
}): void;
|
|
137
550
|
}
|
|
551
|
+
/** The server's own `Retry-After`, in ms, when it sent one.
|
|
552
|
+
*
|
|
553
|
+
* The ingest API computes the real wait from its rolling window rather than
|
|
554
|
+
* sending a round number, so honouring it beats any backoff we could calculate
|
|
555
|
+
* blind — a client that guesses either hammers or overshoots, and overshooting
|
|
556
|
+
* drops exactly the calls the SDK was installed to record. */
|
|
557
|
+
export declare function retryAfterMs_(resp: TransportResponse): number | undefined;
|
|
558
|
+
/** FULL jitter — `random(0, base * 2**attempt)`, capped, or the server's wait.
|
|
559
|
+
*
|
|
560
|
+
* Jittered rather than plain exponential because every buffered client backs off
|
|
561
|
+
* on the same schedule: un-jittered retries re-synchronise into a thundering herd
|
|
562
|
+
* aimed at the endpoint that just failed, which is how a brief blip becomes an
|
|
563
|
+
* outage. */
|
|
564
|
+
export declare function backoffMs(attempt: number, retryAfter?: number): number;
|
|
138
565
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAC9C,eAAO,MAAM,aAAa,yBAAyB,CAAC;AACpD,eAAO,MAAM,UAAU,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|