@stigg/agent-sdk-js 0.7.9 → 0.7.10

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.
@@ -26,12 +26,11 @@ const meter_stream_1 = require("../../../shared/meter-stream");
26
26
  const base_url_1 = require("../../../shared/base-url");
27
27
  const openai_recipe_1 = require("../../providers/openai/openai-recipe");
28
28
  const token_usage_1 = require("../../../shared/token-usage");
29
+ const cost_units_1 = require("../../../shared/cost-units");
29
30
  /** The cost LiteLLM charged for this call, in USD. Non-streaming responses only. */
30
31
  const COST_HEADER = 'x-litellm-response-cost';
31
32
  /** The proxy's own id for the call: stable across its retries, which a local step counter is not. */
32
33
  const CALL_ID_HEADER = 'x-litellm-call-id';
33
- /** Float noise: 0.00108 * 1e6 is 1080.0000000000002, and ceil would bill the extra unit. */
34
- const toUnits = (cost, unitsPerDollar) => Math.max(1, Math.ceil(Number((cost * unitsPerDollar).toPrecision(12))));
35
34
  /** The header is a string on the wire, and absent on every streamed response. */
36
35
  function costOf(response) {
37
36
  const raw = response?.headers?.get(COST_HEADER);
@@ -50,7 +49,7 @@ function measure(usage, parse, keys, model, id, response, options) {
50
49
  const cost = costOf(response);
51
50
  const metrics = (0, token_usage_1.pickMetrics)(usage, keys);
52
51
  if (cost !== undefined && cost > 0)
53
- metrics.cost = toUnits(cost, options.unitsPerDollar);
52
+ metrics.cost = (0, cost_units_1.toUnits)(cost, options.unitsPerDollar);
54
53
  return {
55
54
  metrics,
56
55
  usage: parse(usage),
@@ -77,7 +76,7 @@ function measure(usage, parse, keys, model, id, response, options) {
77
76
  function litellmRecipe(options = {}) {
78
77
  const resolved = {
79
78
  estimate: options.estimate ?? (() => 1),
80
- unitsPerDollar: positiveDenomination(options.unitsPerDollar, 'unitsPerDollar'),
79
+ unitsPerDollar: (0, cost_units_1.positiveDenomination)(options.unitsPerDollar, 'unitsPerDollar'),
81
80
  modelDimension: options.modelDimension ?? 'model',
82
81
  };
83
82
  return {
@@ -141,18 +140,3 @@ function isLiteLLM(client, baseUrl) {
141
140
  return (0, base_url_1.withinBaseUrl)(baseUrl, clientBase);
142
141
  return clientBase.toLowerCase().includes('litellm');
143
142
  }
144
- /**
145
- * The denomination, refused when it cannot divide a price.
146
- *
147
- * `NaN` and `Infinity` make `toUnits` produce a value the ingest rejects a call later, and zero or
148
- * a negative clamps every cost to the floor of 1 - a bill that looks plausible and is not. Both
149
- * are configuration mistakes worth naming where they were made.
150
- */
151
- function positiveDenomination(value, name) {
152
- if (value === undefined)
153
- return 1_000_000;
154
- if (!Number.isFinite(value) || value <= 0) {
155
- throw new Error(`${name} must be a finite positive number - got ${value}, which prices every call wrongly.`);
156
- }
157
- return value;
158
- }
@@ -25,9 +25,8 @@ const openai_recipe_1 = require("../../providers/openai/openai-recipe");
25
25
  const token_usage_1 = require("../../../shared/token-usage");
26
26
  const registry_1 = require("../../core/registry");
27
27
  const base_url_1 = require("../../../shared/base-url");
28
+ const cost_units_1 = require("../../../shared/cost-units");
28
29
  const sdk_usage_1 = require("./sdk-usage");
29
- /** Float noise: 0.00108 * 1e6 is 1080.0000000000002, and ceil would bill the extra unit. */
30
- const toUnits = (cost, unitsPerCredit) => Math.max(1, Math.ceil(Number((cost * unitsPerCredit).toPrecision(12))));
31
30
  /**
32
31
  * Tokens and cost, from one response.
33
32
  *
@@ -57,7 +56,7 @@ stated) {
57
56
  const metrics = (0, token_usage_1.pickMetrics)(usage, keys);
58
57
  // `cost` is the gateway's own field name, so it obeys the same rule as every other metric.
59
58
  if (typeof cost === 'number' && cost > 0)
60
- metrics.cost = toUnits(cost, options.unitsPerCredit);
59
+ metrics.cost = (0, cost_units_1.toUnits)(cost, options.unitsPerCredit);
61
60
  return {
62
61
  metrics,
63
62
  usage: parse(usage),
@@ -137,7 +136,7 @@ function sdkSurfaces(resolved) {
137
136
  function openrouterRecipe(options = {}) {
138
137
  const resolved = {
139
138
  estimate: options.estimate ?? (() => 1),
140
- unitsPerCredit: positiveDenomination(options.unitsPerCredit, 'unitsPerCredit'),
139
+ unitsPerCredit: (0, cost_units_1.positiveDenomination)(options.unitsPerCredit, 'unitsPerCredit'),
141
140
  modelDimension: options.modelDimension ?? 'model',
142
141
  };
143
142
  return {
@@ -216,18 +215,3 @@ function isOpenRouterSdk(client) {
216
215
  return false;
217
216
  return 'credits' in client && 'generations' in client;
218
217
  }
219
- /**
220
- * The denomination, refused when it cannot divide a price.
221
- *
222
- * `NaN` and `Infinity` make `toUnits` produce a value the ingest rejects a call later, and zero or
223
- * a negative clamps every cost to the floor of 1 - a bill that looks plausible and is not. Both
224
- * are configuration mistakes worth naming where they were made.
225
- */
226
- function positiveDenomination(value, name) {
227
- if (value === undefined)
228
- return 1_000_000;
229
- if (!Number.isFinite(value) || value <= 0) {
230
- throw new Error(`${name} must be a finite positive number - got ${value}, which prices every call wrongly.`);
231
- }
232
- return value;
233
- }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * A price a gateway states, in whole units of the denomination the caller configured.
3
+ *
4
+ * Shared by every recipe that reports a `cost` metric, so the rounding and the configuration check
5
+ * are one decision rather than a copy per gateway.
6
+ */
7
+ /** The denomination used when none is configured: micro-units of the gateway's currency. */
8
+ export declare const DEFAULT_UNITS = 1000000;
9
+ /**
10
+ * Rounded up, with a floor of 1 so a call that cost something never reports zero.
11
+ *
12
+ * The product is cut to 12 significant digits first, because float noise would otherwise round a
13
+ * whole number up by one: 0.000123 * 1e6 is 123.00000000000001, and `ceil` would report 124.
14
+ */
15
+ export declare const toUnits: (cost: number, unitsPer: number) => number;
16
+ /**
17
+ * The denomination, refused when it cannot divide a price.
18
+ *
19
+ * `NaN` and `Infinity` make `toUnits` produce a value the ingest rejects a call later, and zero or
20
+ * a negative clamps every cost to the floor of 1 - a figure that looks plausible and is not. Both
21
+ * are configuration mistakes worth naming where they were made.
22
+ */
23
+ export declare function positiveDenomination(value: number | undefined, name: string): number;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /**
3
+ * A price a gateway states, in whole units of the denomination the caller configured.
4
+ *
5
+ * Shared by every recipe that reports a `cost` metric, so the rounding and the configuration check
6
+ * are one decision rather than a copy per gateway.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.toUnits = exports.DEFAULT_UNITS = void 0;
10
+ exports.positiveDenomination = positiveDenomination;
11
+ /** The denomination used when none is configured: micro-units of the gateway's currency. */
12
+ exports.DEFAULT_UNITS = 1_000_000;
13
+ /**
14
+ * Rounded up, with a floor of 1 so a call that cost something never reports zero.
15
+ *
16
+ * The product is cut to 12 significant digits first, because float noise would otherwise round a
17
+ * whole number up by one: 0.000123 * 1e6 is 123.00000000000001, and `ceil` would report 124.
18
+ */
19
+ const toUnits = (cost, unitsPer) => Math.max(1, Math.ceil(Number((cost * unitsPer).toPrecision(12))));
20
+ exports.toUnits = toUnits;
21
+ /**
22
+ * The denomination, refused when it cannot divide a price.
23
+ *
24
+ * `NaN` and `Infinity` make `toUnits` produce a value the ingest rejects a call later, and zero or
25
+ * a negative clamps every cost to the floor of 1 - a figure that looks plausible and is not. Both
26
+ * are configuration mistakes worth naming where they were made.
27
+ */
28
+ function positiveDenomination(value, name) {
29
+ if (value === undefined)
30
+ return exports.DEFAULT_UNITS;
31
+ if (!Number.isFinite(value) || value <= 0) {
32
+ throw new Error(`${name} must be a finite positive number - got ${value}, which prices every call wrongly.`);
33
+ }
34
+ return value;
35
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigg/agent-sdk-js",
3
- "version": "0.7.9",
3
+ "version": "0.7.10",
4
4
  "description": "Stigg agent SDK (JS) - run-lifecycle governance for agentic stacks, with examples per layer",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -83,7 +83,7 @@
83
83
  "node": ">=22"
84
84
  },
85
85
  "dependencies": {
86
- "@stigg/node-server-sdk": "6.2.0",
86
+ "@stigg/node-server-sdk": "6.3.0",
87
87
  "@stigg/typescript": "0.1.0-beta.55",
88
88
  "zod": "^4.6.1"
89
89
  },