@frugalco/frugal-sdk-node 0.5.0 → 0.6.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.
Files changed (41) hide show
  1. package/README.md +37 -14
  2. package/dist/config.d.ts +19 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +130 -34
  5. package/dist/config.js.map +1 -1
  6. package/dist/instrument.d.ts +2 -0
  7. package/dist/instrument.d.ts.map +1 -1
  8. package/dist/instrument.js +13 -14
  9. package/dist/instrument.js.map +1 -1
  10. package/dist/internal-errors.d.ts +16 -0
  11. package/dist/internal-errors.d.ts.map +1 -0
  12. package/dist/internal-errors.js +54 -0
  13. package/dist/internal-errors.js.map +1 -0
  14. package/dist/otel.d.ts +15 -1
  15. package/dist/otel.d.ts.map +1 -1
  16. package/dist/otel.js +46 -18
  17. package/dist/otel.js.map +1 -1
  18. package/dist/providers.d.ts +2 -1
  19. package/dist/providers.d.ts.map +1 -1
  20. package/dist/providers.js +36 -19
  21. package/dist/providers.js.map +1 -1
  22. package/dist/streams.d.ts.map +1 -1
  23. package/dist/streams.js +6 -5
  24. package/dist/streams.js.map +1 -1
  25. package/dist/track.d.ts +6 -3
  26. package/dist/track.d.ts.map +1 -1
  27. package/dist/track.js +20 -7
  28. package/dist/track.js.map +1 -1
  29. package/dist/wrappers/anthropic.d.ts.map +1 -1
  30. package/dist/wrappers/anthropic.js +11 -31
  31. package/dist/wrappers/anthropic.js.map +1 -1
  32. package/dist/wrappers/batch.d.ts.map +1 -1
  33. package/dist/wrappers/batch.js +14 -34
  34. package/dist/wrappers/batch.js.map +1 -1
  35. package/dist/wrappers/bedrock.d.ts.map +1 -1
  36. package/dist/wrappers/bedrock.js +11 -30
  37. package/dist/wrappers/bedrock.js.map +1 -1
  38. package/dist/wrappers/openai.d.ts.map +1 -1
  39. package/dist/wrappers/openai.js +10 -31
  40. package/dist/wrappers/openai.js.map +1 -1
  41. package/package.json +1 -1
package/README.md CHANGED
@@ -38,7 +38,7 @@ All configuration is via environment variables. No `init()` call, no config obje
38
38
 
39
39
  ### Required
40
40
 
41
- Set both or the wrapper silently returns the client unmodified:
41
+ Set both (or, with `FRUGAL_METRICS_EXPORTER=console`, only `FRUGAL_PROJECT_ID`) or the wrapper silently returns the client unmodified:
42
42
 
43
43
  | Variable | Purpose |
44
44
  | ------------------- | ---------------------------------------------------------- |
@@ -49,26 +49,38 @@ Set both or the wrapper silently returns the client unmodified:
49
49
 
50
50
  | Variable | Purpose |
51
51
  | ---------------------------------------- | --------------------------------------------------------------------------------------- |
52
+ | `FRUGAL_METRICS_PROJECT_ID` / `FRUGAL_METRICS_API_KEY` | Namespaced overrides read before `FRUGAL_PROJECT_ID` / `FRUGAL_API_KEY`; an empty value falls through. Use them when the host app already owns the bare names. |
52
53
  | `FRUGAL_CUSTOMER_ID` | Customer ID issued by Frugal. When unset, the tenant label (auto-injected server-side by VMAuth from the bearer token) identifies the customer and `frugal.customer_id` is omitted. |
53
54
  | `FRUGAL_REPO_ROOT` | Absolute path to the source root; the strip prefix for `caller_file`. Defaults to the process working directory. |
54
- | `FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector URL for Frugal metrics. Defaults to `https://metrics.frugal.co/opentelemetry/v1/metrics`. Falls back to `OTEL_EXPORTER_OTLP_ENDPOINT`. |
55
- | `FRUGAL_OTEL_EXPORTER_OTLP_HEADERS` | Export auth headers (e.g. `Authorization=Bearer ...`). Overrides the header built from `FRUGAL_API_KEY`. Falls back to `OTEL_EXPORTER_OTLP_HEADERS`. |
55
+ | `FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector URL for Frugal metrics. Defaults to `https://metrics.frugal.co/opentelemetry/v1/metrics`; an empty value falls through to the default. |
56
+ | `FRUGAL_METRICS_EXPORTER` | `otlp` (default) or `console`. `console` prints metrics to stdout through the console exporter for local verification; console mode needs only `FRUGAL_PROJECT_ID`; the API key, endpoint and header variables are ignored. Value is trimmed and case-insensitive; anything else warns once and uses `otlp`. |
57
+ | `FRUGAL_OTEL_EXPORTER_OTLP_HEADERS` | Export auth headers (e.g. `Authorization=Bearer ...`). Overrides the header built from `FRUGAL_METRICS_API_KEY` / `FRUGAL_API_KEY`; an empty or blank (whitespace-only) value is treated as unset and falls through to it. A non-blank value with no `key=value` pairs (e.g. `Authorization: Bearer x`) counts as missing auth, even when an API key is set — it never falls back to the key. Values are percent-decoded (`Bearer%20tok` → `Bearer tok`); a value that fails to decode is kept as-is. |
56
58
  | `FRUGAL_COMPONENTS` | Comma-separated logical components (e.g. `ai-handler,reco`). When set, each metric is ALSO emitted once per component (tagged `frugal.component`) on top of the base project series, so usage can be viewed for the whole project or split by component. Only the **first 10** distinct entries are honored (a fixed cap, not configurable — each component multiplies every instrument's series count); the rest are dropped with one warning. |
57
59
  | `FRUGAL_CUSTOM_PROVIDERS` | Comma-separated allowlist of provider names beyond the built-in registry (e.g. `together_ai,fireworks`) that should pass through verbatim on `gen_ai.system` / `gen_ai.provider.name` instead of being coerced to `custom`. Capped at 10 (extras are coerced) to keep label cardinality bounded. |
58
- | `FRUGAL_CUSTOM_LABEL` | Comma-separated allowlist for the `frugal.custom_label` label on manual track calls (e.g. `billing,search,recs`). A `customLabel` passed to `trackAICall`/`startAICall` outside the first 20 entries (a hard, non-configurable cap) is coerced to `other` with a warn-once diagnostic. `other` is reserved and ignored as an entry. See [Custom call sites](#custom-call-sites). |
60
+ | `FRUGAL_CUSTOM_LABEL` | Comma-separated allowlist for the `frugal.custom_label` label on manual track calls (e.g. `billing,search,recs`). A `customLabel` passed to `trackAICall`/`startAICall` outside the first 20 entries (a hard, non-configurable cap) is coerced to `other` with a warn-once diagnostic. A warning fires only when non-empty entries past the 20th are dropped (a trailing comma does not warn). `other` is reserved and ignored as an entry. See [Custom call sites](#custom-call-sites). |
59
61
  | `FRUGAL_PATH_BLOCK_LIST` | Comma-separated repo-relative paths to skip for caller attribution (see below). |
60
- | `FRUGAL_METRIC_EXPORT_INTERVAL_MS` | Export cadence in milliseconds. Default `60000`. |
62
+ | `FRUGAL_METRIC_EXPORT_INTERVAL_MS` | Export cadence in milliseconds, `1`-`2147483647`. Default `60000`; a larger value warns once and uses the default. |
61
63
  | `FRUGAL_MAX_CALL_SITES` | Cardinality cap — max distinct `(caller_file, caller_function)` pairs to attribute. Default `500`. Set to `0` to disable. |
62
64
  | `FRUGAL_MAX_MODELS` | Cardinality cap — max distinct model strings (`gen_ai.request.model` and `gen_ai.response.model` share one registry) before further models collapse to `<overflow>`. Default `100`, which is ~50 logical models: a request alias (`gpt-4o`) and the dated snapshot the response reports (`gpt-4o-2024-08-06`) are two strings in the one shared registry. Set to `0` to disable. |
63
65
  | `FRUGAL_MAX_SERIES_PER_INSTRUMENT` | OpenTelemetry's per-instrument limit on distinct label **combinations**. Default `50000` (OTel's own default is 2000, far too low for this SDK's label set); `0` means effectively unlimited (a 1,000,000 ceiling). |
64
- | `FRUGAL_PROMPT_ANALYSIS_SAMPLE_RATE` | Fraction of calls (0..1) that run the lightweight prompt analyzer. Default `0.1`. Set to `0` to disable, `1` for every call. |
66
+ | `FRUGAL_PROMPT_ANALYSIS_SAMPLE_RATE` | Fraction of calls (0..1) that run the lightweight prompt analyzer. Default `0.1`. Set to `0` to disable, `1` for every call. A decimal in [0, 1], plain or scientific notation (e.g. `0.25`, `1e-1`); anything else warns once and uses `0.1`. |
65
67
  | `FRUGAL_DUPLICATE_REQUEST_DETECTION` | Duplicate-request detection (default **on**): every chat request is canonicalized and hashed in-process to classify `first_seen`/`repeat_seen` — only the 2-value state is exported, never content. Set to `0`/`false`/`no`/`off` to disable the hashing and the `frugal.gen_ai.duplicate_requests` metric entirely. |
66
68
  | `FRUGAL_DUPLICATE_WINDOW_SECONDS` | How long a request signature is remembered. Default `3600`, max `86400` (retention is 30–60 min at defaults — see [docs/metrics-reference.md](docs/metrics-reference.md)). |
67
69
  | `FRUGAL_DUPLICATE_CAPACITY` | Expected distinct requests per window (Bloom filter sizing). Default `10000`, max `1000000`. Raise if the saturation warning fires. |
68
- | `FRUGAL_DUPLICATE_FP_RATE` | Target false-positive rate for the duplicate filter. Default `0.01`, max `0.5`. |
70
+ | `FRUGAL_DUPLICATE_FP_RATE` | Target false-positive rate for the duplicate filter. Default `0.01`; clamped to `[1e-6, 0.5]` with a warning. |
69
71
  | `FRUGAL_DUPLICATE_GENERATIONS` | Rotating-Bloom generation count. Default `2`, max `16`. |
70
72
  | `FRUGAL_DISABLED` | Set to `1` to disable all instrumentation without uninstalling. |
71
73
 
74
+ The export endpoint and headers come only from `FRUGAL_`-prefixed variables.
75
+ The SDK never reads `OTEL_EXPORTER_OTLP_ENDPOINT` or
76
+ `OTEL_EXPORTER_OTLP_HEADERS`, and it hides `OTEL_EXPORTER_OTLP_HEADERS` and
77
+ `OTEL_EXPORTER_OTLP_METRICS_HEADERS` from the OTel exporter library while
78
+ constructing its exporter (the library would otherwise merge them into every
79
+ request), so the host's own OpenTelemetry headers never reach Frugal and the
80
+ Frugal bearer never reaches the host's collector. The exporter library still
81
+ reads its other standard variables (TLS, compression, timeout, temporality) on
82
+ its own.
83
+
72
84
  ## What gets captured
73
85
 
74
86
  Every wrapped call emits OTel metrics tagged with the caller's source file and function, the provider, and the model:
@@ -83,7 +95,7 @@ Every wrapped call emits OTel metrics tagged with the caller's source file and f
83
95
  | `frugal.gen_ai.reasoning_tokens` | histogram | OpenAI reasoning tokens (o-series), Anthropic thinking tokens| — |
84
96
  | `frugal.gen_ai.agent.turns` | histogram | Model-response turns in a successful agent invocation | — |
85
97
  | `frugal.gen_ai.errors` | counter | Errors by exception type | `frugal.error.type` |
86
- | `frugal.gen_ai.internal_errors` | counter | frugal-metrics internal failures (cardinality caps, bugs) | `frugal.internal_error.stage`, `frugal.instrument` (on `otel_cardinality_overflow` only) |
98
+ | `frugal.gen_ai.internal_errors` | counter | frugal-metrics internal failures (cardinality caps, bugs) | `frugal.internal_error.stage`, `frugal.internal_error.type`, `frugal.instrument` (on `otel_cardinality_overflow` only) |
87
99
  | `frugal.gen_ai.output_cap_utilization` | histogram | `output_tokens / max_tokens` ratio when `max_tokens` is set | `frugal.structured_output_mode` |
88
100
  | `frugal.gen_ai.history_depth` | histogram | `messages.length` — every chat call, success or error (100%, not sampled) | — |
89
101
  | `frugal.gen_ai.duplicate_requests` | counter | Request-duplication state from a windowed signature filter — every chat call (100%, not sampled; see `FRUGAL_DUPLICATE_*` vars) | `frugal.dup_state` (`first_seen` \| `repeat_seen`) |
@@ -106,7 +118,7 @@ Every metric carries this base attribute set:
106
118
  - `gen_ai.system` + `gen_ai.provider.name` — the provider, dual-emitted under both the legacy and current OTel attribute (`openai`, `anthropic`, `aws.bedrock`, `vertex_ai`/`gcp.vertex_ai`, …, or `custom`). Override via the `provider` field; an unrecognized value is coerced to `custom` with a one-time warning. See [`docs/metrics-reference.md`](docs/metrics-reference.md#attributes).
107
119
  - `gen_ai.request.model`, `gen_ai.response.model` — the model used. Both draw on one shared registry capped by `FRUGAL_MAX_MODELS`; past the cap the value reads `<overflow>` (the same sentinel the caller labels use). `<unknown>` when the wrapper could not read a model off the request
108
120
  - `gen_ai.operation.name` — `chat`, `text_completion`, `embeddings`, `generate_content`, `execute_tool`, `create_agent`, `invoke_agent`, or `other` (the sentinel an unrecognized operation coerces to)
109
- - `frugal.batched` — `true` for batch-API paths (OpenAI Batch API submissions; Anthropic Message Batches submissions and results), `false` otherwise
121
+ - `frugal.batched` — `true` for batch-API paths (OpenAI Batch API submissions; Anthropic Message Batches submissions and results), `false` otherwise; on every metric of the call except the `frugal.gen_ai.internal_errors` points
110
122
 
111
123
  The "Additional attributes" column above lists what each metric carries on top of the base set. See [`docs/metrics-reference.md`](docs/metrics-reference.md) for the values each attribute takes, sentinel values for caller fields, and the full internal-error-stage list.
112
124
 
@@ -222,7 +234,7 @@ report({
222
234
  });
223
235
  ```
224
236
 
225
- **Metadata** — `info` (all optional): `provider` (→ `gen_ai.system`, default `"custom"`), `operation` (default `"chat"`), `model` (→ `gen_ai.request.model`, default `"<unknown>"`), `customLabel` (→ `frugal.custom_label` on **every** metric of the call; the value must be one of the first 20 comma-separated entries of `FRUGAL_CUSTOM_LABEL` or it is coerced to `"other"` — the label is exclusive to this manual API, wrapper calls never carry it). To also run the sampled prompt analyzer, pass any of `messages` / `system` / `tools` / `responseFormat` / `maxTokens`.
237
+ **Metadata** — `info` (all optional): `provider` (→ `gen_ai.system`, default `"custom"`), `operation` (default `"chat"`), `model` (→ `gen_ai.request.model`, default `"<unknown>"`), `customLabel` (→ `frugal.custom_label` on every metric of the call except the `frugal.gen_ai.internal_errors` `setup_failed` / `emission` points; the value must be one of the first 20 comma-separated entries of `FRUGAL_CUSTOM_LABEL` or it is coerced to `"other"` — the label is exclusive to this manual API, wrapper calls never carry it). To also run the sampled prompt analyzer, pass any of `messages` / `system` / `tools` / `responseFormat` / `maxTokens`.
226
238
 
227
239
  **Usage** — `report(...)` / `end(...)` fields (all optional): `inputTokens`, `outputTokens`, `cacheReadTokens`, `cacheWriteTokens`, `reasoningTokens`, `responseModel`, `agentTurns`.
228
240
 
@@ -320,17 +332,28 @@ It is **opt-in** because installing signal handlers is intrusive. If you run you
320
332
 
321
333
  ## Verifying the setup
322
334
 
323
- Set the OTLP endpoint to empty to print metrics to the console instead of exporting them:
335
+ Set `FRUGAL_METRICS_EXPORTER=console` to print the metrics to stdout instead
336
+ of exporting them (console mode needs only `FRUGAL_PROJECT_ID`; the API key, endpoint and header variables are ignored):
337
+
338
+ ```bash
339
+ export FRUGAL_PROJECT_ID=my-project
340
+ export FRUGAL_METRICS_EXPORTER=console
341
+ export FRUGAL_METRIC_EXPORT_INTERVAL_MS=5000
342
+ node my_script.js
343
+ ```
344
+
345
+ Or point the library at a local OTLP/HTTP collector. An empty endpoint is not a
346
+ console switch: it falls through to the default Frugal endpoint.
324
347
 
325
348
  ```bash
326
- export FRUGAL_API_KEY=local
349
+ export FRUGAL_API_KEY=my-key
327
350
  export FRUGAL_PROJECT_ID=my-project
328
- export FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT= # empty → ConsoleMetricExporter
351
+ export FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/metrics
329
352
  export FRUGAL_METRIC_EXPORT_INTERVAL_MS=5000
330
353
  node my_script.js
331
354
  ```
332
355
 
333
- You should see JSON metric records with `gen_ai.*` and `frugal.*` attributes every 5 seconds.
356
+ The collector should receive metric records with `gen_ai.*` and `frugal.*` attributes every 5 seconds.
334
357
 
335
358
  ## License
336
359
 
package/dist/config.d.ts CHANGED
@@ -19,8 +19,18 @@ export interface Config {
19
19
  customLabels: readonly string[];
20
20
  repoRoot: string;
21
21
  pathBlockList: readonly string[];
22
+ /** Metric exporter: `otlp` (default) or `console` (prints to stdout; endpoint/headers ignored). */
23
+ exporter: "otlp" | "console";
22
24
  otlpEndpoint: string;
25
+ /** Resolved header string (display/compat). Only an explicit FRUGAL_OTEL_EXPORTER_OTLP_HEADERS value is parsed and percent-decoded for export. */
23
26
  otlpHeaders: string;
27
+ /**
28
+ * The raw API key when the export header comes from it (no explicit
29
+ * FRUGAL_OTEL_EXPORTER_OTLP_HEADERS), else null. The exporter builds
30
+ * `Authorization: Bearer <key>` from it directly, so a key containing `%` or
31
+ * `,` is never decoded or split.
32
+ */
33
+ otlpApiKey: string | null;
24
34
  exportIntervalMs: number;
25
35
  /** Max distinct (file, function) combinations to attribute before overflow. 0 = unlimited. */
26
36
  maxCallSites: number;
@@ -55,6 +65,15 @@ export interface Config {
55
65
  * taking the process with it.
56
66
  */
57
67
  export declare function loadConfig(): Config | null;
68
+ /**
69
+ * Parse an OTLP `key=value,key=value` header string. Values are
70
+ * percent-decoded like OTel's own env parser (`Bearer%20tok` → `Bearer tok`);
71
+ * keys are kept literal, and a value that fails to decode is kept raw. Parts
72
+ * without `=` or with an empty key are dropped; a string with no pairs at all
73
+ * returns undefined.
74
+ * Same rule in the Python and Go SDKs.
75
+ */
76
+ export declare function parseHeaders(raw: string | null): Record<string, string> | undefined;
58
77
  /** Test-only hook to re-arm the one-shot warning. */
59
78
  export declare function resetWarningStateForTests(): void;
60
79
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,MAAM;IACrB,mGAAmG;IACnG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;OAIG;IACH,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,wBAAwB,EAAE,MAAM,CAAC;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAoMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAW1C;AAsQD,qDAAqD;AACrD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,MAAM;IACrB,mGAAmG;IACnG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;OAIG;IACH,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,mGAAmG;IACnG,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kJAAkJ;IAClJ,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,wBAAwB,EAAE,MAAM,CAAC;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAmMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAW1C;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAoBnF;AAwUD,qDAAqD;AACrD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
package/dist/config.js CHANGED
@@ -23,9 +23,14 @@
23
23
  // viewed for the whole project (component absent) or split by component.
24
24
  //
25
25
  // The older env vars (FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT,
26
- // FRUGAL_OTEL_EXPORTER_OTLP_HEADERS, FRUGAL_REPO_ROOT, FRUGAL_CUSTOMER_ID,
27
- // plus the standard OTel ones) all still work — explicit values override
28
- // the defaults so existing customers don't need to change anything.
26
+ // FRUGAL_OTEL_EXPORTER_OTLP_HEADERS, FRUGAL_REPO_ROOT, FRUGAL_CUSTOMER_ID)
27
+ // all still work — explicit values override the defaults. The export endpoint
28
+ // and headers come only from FRUGAL_-prefixed variables: the SDK never reads
29
+ // OTEL_EXPORTER_OTLP_ENDPOINT / _HEADERS, and buildReader hides
30
+ // OTEL_EXPORTER_OTLP_HEADERS / OTEL_EXPORTER_OTLP_METRICS_HEADERS from the
31
+ // exporter library while constructing it, so the host's own OTel pipeline
32
+ // never crosses wires with Frugal's. (The exporter library still reads its
33
+ // other standard variables, such as TLS, compression and timeout.)
29
34
  import { realpathSync } from "node:fs";
30
35
  import { resolve } from "node:path";
31
36
  import { emitLog, emitLogOnce } from "./debug.js";
@@ -47,8 +52,7 @@ const ENV = {
47
52
  API_KEY: "FRUGAL_API_KEY",
48
53
  FRUGAL_OTLP_ENDPOINT: "FRUGAL_OTEL_EXPORTER_OTLP_ENDPOINT",
49
54
  FRUGAL_OTLP_HEADERS: "FRUGAL_OTEL_EXPORTER_OTLP_HEADERS",
50
- OTLP_ENDPOINT: "OTEL_EXPORTER_OTLP_ENDPOINT",
51
- OTLP_HEADERS: "OTEL_EXPORTER_OTLP_HEADERS",
55
+ METRICS_EXPORTER: "FRUGAL_METRICS_EXPORTER",
52
56
  EXPORT_INTERVAL_MS: "FRUGAL_METRIC_EXPORT_INTERVAL_MS",
53
57
  MAX_CALL_SITES: "FRUGAL_MAX_CALL_SITES",
54
58
  MAX_SERIES_PER_INSTRUMENT: "FRUGAL_MAX_SERIES_PER_INSTRUMENT",
@@ -73,6 +77,7 @@ const DEFAULT_MAX_SERIES_PER_INSTRUMENT = 50_000;
73
77
  // deployment using 50 logical models needs ~100 strings.
74
78
  const DEFAULT_MAX_MODELS = 100;
75
79
  const DEFAULT_EXPORT_INTERVAL_MS = 60_000;
80
+ const MAX_EXPORT_INTERVAL_MS = 2_147_483_647;
76
81
  const DEFAULT_PROMPT_ANALYSIS_SAMPLE_RATE = 0.1;
77
82
  const DEFAULT_DUPLICATE_WINDOW_SECONDS = 3600;
78
83
  const DEFAULT_DUPLICATE_CAPACITY = 10_000;
@@ -96,6 +101,11 @@ const MAX_DUPLICATE_WINDOW_SECONDS = 86_400;
96
101
  // filter degenerates); values in [0.5, 1) must warn HERE, not silently differ
97
102
  // from what the filter actually uses.
98
103
  const MAX_DUPLICATE_FP_RATE = 0.5;
104
+ // The floor bloomParams also clamps to; clamping HERE (with a warning) keeps
105
+ // the configured value equal to what the filter uses, as in the Python SDK.
106
+ const MIN_DUPLICATE_FP_RATE = 1e-6;
107
+ // Plain or scientific-notation decimal, no sign, no NaN/Infinity, no "_".
108
+ const DECIMAL = /^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$/;
99
109
  /** Upper bound on customer-registered provider names — keeps label cardinality bounded. */
100
110
  const MAX_CUSTOM_PROVIDERS = 10;
101
111
  // Hard bound on the FRUGAL_COMPONENTS fan-out list. Every component multiplies
@@ -120,8 +130,8 @@ function explicitlyOff(value) {
120
130
  const v = value.trim().toLowerCase();
121
131
  return v === "0" || v === "false" || v === "no" || v === "off";
122
132
  }
123
- // Number(raw) validates the FULL string (unlike parseInt/parseFloat, whose
124
- // prefix parsing turns "1e6" into 1 and "10,000" into 10 — a capacity of 1
133
+ // Number(raw) validates the FULL string (unlike the Number.parse* helpers,
134
+ // whose prefix parsing turns "1e6" into 1 and "10,000" into 10 — a capacity of 1
125
135
  // means a 10-bit filter that saturates instantly). Warnings are de-duped per
126
136
  // var: loadConfig() runs on every call, so a bad value must not flood the
127
137
  // bounded debug ring buffer.
@@ -162,14 +172,15 @@ const DIGITS_ONLY = /^\d+$/;
162
172
  * one warning — and every representable value, however large, is honored
163
173
  * verbatim.
164
174
  */
165
- function parseDigitsInt(raw, name, fallback, minimum) {
175
+ function parseDigitsInt(raw, name, fallback, minimum, maximum = Number.MAX_SAFE_INTEGER) {
166
176
  if (!raw || !raw.trim())
167
177
  return fallback;
168
178
  const trimmed = raw.trim();
169
179
  if (DIGITS_ONLY.test(trimmed)) {
170
180
  const parsed = Number(trimmed);
171
- if (Number.isSafeInteger(parsed) && parsed >= minimum)
181
+ if (Number.isSafeInteger(parsed) && parsed >= minimum && parsed <= maximum) {
172
182
  return parsed;
183
+ }
173
184
  }
174
185
  emitLogOnce(`bad_env_${name}`, "warn", `could not parse ${name}=${raw}; using default ${fallback}`);
175
186
  return fallback;
@@ -178,10 +189,6 @@ function parseDigitsInt(raw, name, fallback, minimum) {
178
189
  function parseNonNegativeInt(raw, name, fallback) {
179
190
  return parseDigitsInt(raw, name, fallback, 0);
180
191
  }
181
- /** Knobs where 0 is meaningless (or fatal downstream) rather than "off". */
182
- function parsePositiveInt(raw, name, fallback) {
183
- return parseDigitsInt(raw, name, fallback, 1);
184
- }
185
192
  function warnOnce(message) {
186
193
  if (warnedOnce)
187
194
  return;
@@ -208,6 +215,40 @@ export function loadConfig() {
208
215
  return null;
209
216
  }
210
217
  }
218
+ /**
219
+ * Parse an OTLP `key=value,key=value` header string. Values are
220
+ * percent-decoded like OTel's own env parser (`Bearer%20tok` → `Bearer tok`);
221
+ * keys are kept literal, and a value that fails to decode is kept raw. Parts
222
+ * without `=` or with an empty key are dropped; a string with no pairs at all
223
+ * returns undefined.
224
+ * Same rule in the Python and Go SDKs.
225
+ */
226
+ export function parseHeaders(raw) {
227
+ if (!raw)
228
+ return undefined;
229
+ const out = {};
230
+ for (const part of raw.split(",")) {
231
+ const trimmed = part.trim();
232
+ if (!trimmed)
233
+ continue;
234
+ const eq = trimmed.indexOf("=");
235
+ if (eq < 0)
236
+ continue;
237
+ const key = trimmed.slice(0, eq).trim();
238
+ if (!key)
239
+ continue;
240
+ const value = trimmed.slice(eq + 1).trim();
241
+ let decoded = value;
242
+ try {
243
+ decoded = decodeURIComponent(value);
244
+ }
245
+ catch {
246
+ // URIError (e.g. `%zz`): keep the raw value.
247
+ }
248
+ out[key] = decoded;
249
+ }
250
+ return Object.keys(out).length > 0 ? out : undefined;
251
+ }
211
252
  function loadConfigUnguarded() {
212
253
  if (truthy(process.env[ENV.DISABLED]))
213
254
  return null;
@@ -217,23 +258,55 @@ function loadConfigUnguarded() {
217
258
  // override falls through to the bare name rather than blanking the value.
218
259
  const projectId = process.env[ENV.METRICS_PROJECT_ID] || process.env[ENV.PROJECT_ID];
219
260
  const repoRootEnv = process.env[ENV.REPO_ROOT];
220
- const apiKey = process.env[ENV.METRICS_API_KEY] || process.env[ENV.API_KEY];
221
- // Explicit headers override anything we'd build from the API key — keeps
222
- // existing deployments that set FRUGAL_OTEL_EXPORTER_OTLP_HEADERS directly
223
- // working unchanged.
224
- const explicitHeaders = process.env[ENV.FRUGAL_OTLP_HEADERS] ?? process.env[ENV.OTLP_HEADERS];
225
- const otlpHeaders = explicitHeaders
226
- ? explicitHeaders
227
- : apiKey
228
- ? `Authorization=Bearer ${apiKey}`
229
- : null;
230
- // Required for any useful run: PROJECT_ID (the attribution key) and SOME auth
231
- // (either FRUGAL_API_KEY or an explicit OTLP_HEADERS containing the bearer).
261
+ // Trimmed: a secret mounted with a trailing newline would otherwise put a
262
+ // CR/LF in the Authorization header, which Node's http rejects on every
263
+ // export. `%` and `,` inside the key stay verbatim. A whitespace-only value
264
+ // falls through like an empty one.
265
+ const apiKey = process.env[ENV.METRICS_API_KEY]?.trim() || process.env[ENV.API_KEY]?.trim();
266
+ // Header rule, identical across the Node, Python and Go SDKs:
267
+ // FRUGAL_OTEL_EXPORTER_OTLP_HEADERS, else the bearer built from the API key,
268
+ // else none. Endpoint and auth come only from FRUGAL_-prefixed variables: the
269
+ // generic OTEL_EXPORTER_OTLP_HEADERS / _ENDPOINT belong to the host's own OTel
270
+ // pipeline, so honoring them could send another vendor's header to Frugal or
271
+ // the Frugal bearer to another vendor (buildReader also hides the generic
272
+ // header variables from the exporter library, which would otherwise merge
273
+ // them in). `||`, not `??`: an empty value falls through to the next source.
274
+ // An explicit headers value always wins, even when it parses to no pairs:
275
+ // that is treated as missing auth below, never as a fallback to the key.
276
+ // Decided on the trimmed value: a blank (whitespace-only) value counts as
277
+ // unset and falls through to the API key, like a blank key does.
278
+ const explicitHeaders = process.env[ENV.FRUGAL_OTLP_HEADERS]?.trim() || null;
279
+ const explicitHeadersUnparseable = explicitHeaders !== null && parseHeaders(explicitHeaders) === undefined;
280
+ const otlpApiKey = !explicitHeaders && apiKey ? apiKey : null;
281
+ const otlpHeaders = explicitHeaders || (otlpApiKey ? `Authorization=Bearer ${otlpApiKey}` : null);
282
+ // Explicit opt-in for the console exporter (local verification). Anything but
283
+ // `otlp` / `console` warns once and keeps the default. Endpoint and headers
284
+ // are simply not consulted in console mode.
285
+ let exporter = "otlp";
286
+ const exporterRaw = process.env[ENV.METRICS_EXPORTER];
287
+ if (exporterRaw && exporterRaw.trim()) {
288
+ const mode = exporterRaw.trim().toLowerCase();
289
+ if (mode === "console") {
290
+ exporter = "console";
291
+ }
292
+ else if (mode !== "otlp") {
293
+ emitLogOnce(`bad_env_${ENV.METRICS_EXPORTER}`, "warn", `could not parse ${ENV.METRICS_EXPORTER}=${exporterRaw}; using default otlp`);
294
+ }
295
+ }
296
+ // Required for any useful run. OTLP mode: PROJECT_ID (the attribution key)
297
+ // and SOME auth (either FRUGAL_API_KEY or an explicit OTLP_HEADERS containing
298
+ // the bearer; an explicit headers value with no key=value pairs counts as
299
+ // missing). Console mode prints locally and sends nothing, so only the
300
+ // project id is required; the API key, endpoint and headers are ignored.
232
301
  const missing = [];
233
302
  if (!projectId)
234
303
  missing.push(ENV.PROJECT_ID);
235
- if (!otlpHeaders)
304
+ if (exporter !== "console" && explicitHeadersUnparseable) {
305
+ missing.push(`${ENV.FRUGAL_OTLP_HEADERS} (set but has no key=value pairs)`);
306
+ }
307
+ else if (exporter !== "console" && !otlpHeaders) {
236
308
  missing.push(`${ENV.API_KEY} or ${ENV.FRUGAL_OTLP_HEADERS}`);
309
+ }
237
310
  if (missing.length > 0) {
238
311
  warnOnce(`missing required env vars: ${missing.join(", ")}`);
239
312
  return null;
@@ -310,25 +383,42 @@ function loadConfigUnguarded() {
310
383
  if (customLabels.length < customLabelsParsed.length) {
311
384
  emitLogOnce("custom_labels_reserved", "warn", `${ENV.CUSTOM_LABEL} contains the reserved value "${CUSTOM_LABEL_OTHER}" (the coercion sentinel); it is ignored — rename that label to keep it distinguishable from coerced values.`);
312
385
  }
313
- if (customLabelEntries.length > MAX_CUSTOM_LABELS && customLabelsRaw.trim()) {
314
- emitLogOnce("custom_labels_truncated", "warn", `${ENV.CUSTOM_LABEL} lists ${customLabelEntries.length} entries; only the first ${MAX_CUSTOM_LABELS} are honored, values outside them are coerced to "${CUSTOM_LABEL_OTHER}".`);
386
+ // Warn only when a real entry is actually dropped: blank positions past the
387
+ // 20th (a trailing comma, ", , ") cost nothing and must not warn. The text
388
+ // is shared verbatim with the Python and Go SDKs.
389
+ const dropped = customLabelEntries
390
+ .slice(MAX_CUSTOM_LABELS)
391
+ .map((e) => e.trim())
392
+ .filter((e) => e.length > 0);
393
+ if (dropped.length > 0) {
394
+ emitLogOnce("custom_labels_truncated", "warn", `${ENV.CUSTOM_LABEL} has ${dropped.length} non-empty entries past the first ${MAX_CUSTOM_LABELS}; they are ignored and values matching them are coerced to "${CUSTOM_LABEL_OTHER}".`);
315
395
  }
316
- const otlpEndpoint = process.env[ENV.FRUGAL_OTLP_ENDPOINT] ??
317
- process.env[ENV.OTLP_ENDPOINT] ??
318
- DEFAULT_OTLP_ENDPOINT;
396
+ // `||`, not `??`: an empty value falls through to the default. The generic
397
+ // OTEL_EXPORTER_OTLP_ENDPOINT is never read (see the header comment above).
398
+ // The console exporter is chosen only via FRUGAL_METRICS_EXPORTER=console,
399
+ // never by an empty endpoint.
400
+ const otlpEndpoint = process.env[ENV.FRUGAL_OTLP_ENDPOINT] || DEFAULT_OTLP_ENDPOINT;
319
401
  // Strictly positive: PeriodicExportingMetricReader THROWS on an interval of
320
402
  // 0 or less, and that throw propagates out of getInstruments on the
321
403
  // customer's first call. Every wrapper catches it, so the SDK degrades to a
322
404
  // no-op rather than breaking the host — but a typo silently costing all
323
405
  // metrics is worse than a typo that warns and uses the default.
324
- const exportIntervalMs = parsePositiveInt(process.env[ENV.EXPORT_INTERVAL_MS], ENV.EXPORT_INTERVAL_MS, DEFAULT_EXPORT_INTERVAL_MS);
406
+ //
407
+ // Capped at 2^31-1 ms: setInterval clamps a larger delay to 1 ms, which would
408
+ // turn the export loop into a hot spin inside the customer's process. A value
409
+ // above the cap is treated as malformed (warn once, use the default).
410
+ const exportIntervalMs = parseDigitsInt(process.env[ENV.EXPORT_INTERVAL_MS], ENV.EXPORT_INTERVAL_MS, DEFAULT_EXPORT_INTERVAL_MS, 1, MAX_EXPORT_INTERVAL_MS);
325
411
  const maxCallSites = parseNonNegativeInt(process.env[ENV.MAX_CALL_SITES], ENV.MAX_CALL_SITES, DEFAULT_MAX_CALL_SITES);
326
412
  const maxSeriesPerInstrument = parseNonNegativeInt(process.env[ENV.MAX_SERIES_PER_INSTRUMENT], ENV.MAX_SERIES_PER_INSTRUMENT, DEFAULT_MAX_SERIES_PER_INSTRUMENT);
327
413
  const maxModels = parseNonNegativeInt(process.env[ENV.MAX_MODELS], ENV.MAX_MODELS, DEFAULT_MAX_MODELS);
414
+ // Strict decimal grammar (shared with the Python SDK): the WHOLE trimmed
415
+ // value must be a plain or scientific-notation decimal, so "0.5abc", "+0.5",
416
+ // "nan", "Infinity" and "1_0" are rejected rather than prefix-parsed.
328
417
  const sampleRateRaw = process.env[ENV.PROMPT_ANALYSIS_SAMPLE_RATE];
329
418
  let promptAnalysisSampleRate = DEFAULT_PROMPT_ANALYSIS_SAMPLE_RATE;
330
419
  if (sampleRateRaw && sampleRateRaw.trim()) {
331
- const parsed = Number.parseFloat(sampleRateRaw);
420
+ const trimmed = sampleRateRaw.trim();
421
+ const parsed = DECIMAL.test(trimmed) ? Number(trimmed) : Number.NaN;
332
422
  if (Number.isFinite(parsed) && parsed >= 0 && parsed <= 1) {
333
423
  promptAnalysisSampleRate = parsed;
334
424
  }
@@ -346,6 +436,10 @@ function loadConfigUnguarded() {
346
436
  emitLogOnce(`clamped_env_${ENV.DUPLICATE_FP_RATE}`, "warn", `${ENV.DUPLICATE_FP_RATE}=${fpRate} exceeds the maximum ${MAX_DUPLICATE_FP_RATE}; clamping to ${MAX_DUPLICATE_FP_RATE}`);
347
437
  duplicateFpRate = MAX_DUPLICATE_FP_RATE;
348
438
  }
439
+ else if (fpRate < MIN_DUPLICATE_FP_RATE) {
440
+ emitLogOnce(`clamped_env_${ENV.DUPLICATE_FP_RATE}`, "warn", `${ENV.DUPLICATE_FP_RATE}=${fpRate} is below the minimum ${MIN_DUPLICATE_FP_RATE}; clamping to ${MIN_DUPLICATE_FP_RATE}`);
441
+ duplicateFpRate = MIN_DUPLICATE_FP_RATE;
442
+ }
349
443
  // The kill switch disables only on an explicit off value. Operators reach
350
444
  // for this knob on privacy/overhead grounds, so a value we don't recognize
351
445
  // ("disabled", "n", …) must not silently leave full-payload hashing on.
@@ -364,8 +458,10 @@ function loadConfigUnguarded() {
364
458
  customLabels,
365
459
  repoRoot: repoRootAbs,
366
460
  pathBlockList,
461
+ exporter,
367
462
  otlpEndpoint,
368
- otlpHeaders: otlpHeaders,
463
+ otlpHeaders: otlpHeaders ?? "",
464
+ otlpApiKey,
369
465
  exportIntervalMs,
370
466
  maxCallSites,
371
467
  maxSeriesPerInstrument,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,8 @@ export declare class CallEmitter {
50
50
  private readonly operation;
51
51
  private finalized;
52
52
  constructor(config: Config, ctx: CallContext, caller: CallerInfo, instruments: Instruments, startSec: number, provider: ProviderEntry, operation: string);
53
+ /** Count and log an emission failure caught off the wrapper's own path. */
54
+ recordEmissionFailure(err: unknown): void;
53
55
  success(usage: UsageReport): void;
54
56
  private recordCallShape;
55
57
  private recordInternalError;
@@ -1 +1 @@
1
- {"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,11 @@
7
7
  // the wrapper frame and resolveCaller, or the caller attribution will be wrong.
8
8
  import { consumeCapHitEvent, resolveCaller, } from "./caller.js";
9
9
  import { emitLogOnce } from "./debug.js";
10
+ import { errorName, recordEmissionFailure } from "./internal-errors.js";
10
11
  import { applyModelCap, consumeModelCapHitEvent } from "./model-cap.js";
11
12
  import { getInstruments } from "./otel.js";
12
13
  import { getSharedBlockHashLRU } from "./block-hash-lru.js";
13
- import { normalizeOperation, normalizeProvider, warnInvalidOnce, } from "./providers.js";
14
+ import { normalizeOperation, normalizeProvider, warnCustomLabelOnce, } from "./providers.js";
14
15
  import { analyzeRequest, historyBucket, historyDepth, requestSignature, shouldSample, structuredOutputMode, } from "./prompt-analyzer.js";
15
16
  import { getSharedDuplicateFilter } from "./duplicate-filter.js";
16
17
  import { BLOCK_SCHEMA, BLOCK_SYSTEM, BLOCK_TOOLS, BLOCK_USER, CUSTOM_LABEL_OTHER, FRUGAL_BATCHED, FRUGAL_BLOCK, FRUGAL_CALLER_FILE, FRUGAL_CALLER_FUNCTION, FRUGAL_CUSTOMER_ID, FRUGAL_CUSTOM_LABEL, FRUGAL_DUP_STATE, FRUGAL_ERROR_TYPE, FRUGAL_HISTORY_BUCKET, FRUGAL_PROJECT_ID, FRUGAL_STABLE, FRUGAL_STRUCTURED_OUTPUT_MODE, GEN_AI_OPERATION_NAME, GEN_AI_PROVIDER_NAME, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_SYSTEM, GEN_AI_TOKEN_TYPE, TOKEN_INPUT, TOKEN_OUTPUT, } from "./semconv.js";
@@ -70,6 +71,10 @@ export class CallEmitter {
70
71
  this.provider = provider;
71
72
  this.operation = operation;
72
73
  }
74
+ /** Count and log an emission failure caught off the wrapper's own path. */
75
+ recordEmissionFailure(err) {
76
+ recordEmissionFailure(this.config, err);
77
+ }
73
78
  success(usage) {
74
79
  if (this.finalized)
75
80
  return;
@@ -293,9 +298,11 @@ export class CallEmitter {
293
298
  this.recordDuplicate(attrs);
294
299
  }
295
300
  baseAttrs() {
296
- // In baseAttrs (not stamped per-instrument) because the contract is "every
297
- // metric of the call, without exception" — new instruments added later
298
- // inherit it automatically instead of each needing a stamp.
301
+ // In baseAttrs (not stamped per-instrument) because the contract is every
302
+ // metric this emitter records for the call — new instruments added later
303
+ // inherit it automatically instead of each needing a stamp. The only
304
+ // carve-out, the internal_errors setup_failed / emission points, is
305
+ // recorded outside the emitter by internal-errors.ts.
299
306
  const customLabel = resolveCustomLabel(this.ctx, this.config);
300
307
  const requestModel = applyModelCap(this.ctx.requestModel, this.config.maxModels);
301
308
  noteModelCapHit(this.instruments, this.config, customLabel);
@@ -434,13 +441,13 @@ function resolveCustomLabel(ctx, config) {
434
441
  if (raw === undefined || raw === null)
435
442
  return null;
436
443
  if (typeof raw !== "string") {
437
- warnInvalidOnce(`custom_label:<${typeof raw}>`, `customLabel must be a string (got ${typeof raw}) — coerced to "${CUSTOM_LABEL_OTHER}".`);
444
+ warnCustomLabelOnce(`custom_label:<${typeof raw}>`, `customLabel must be a string (got ${typeof raw}) — coerced to "${CUSTOM_LABEL_OTHER}".`);
438
445
  return CUSTOM_LABEL_OTHER;
439
446
  }
440
447
  const value = raw.trim();
441
448
  if (config.customLabels.includes(value))
442
449
  return value;
443
- warnInvalidOnce(`custom_label:${value}`, `customLabel "${value}" is not in the FRUGAL_CUSTOM_LABEL allowlist — coerced to "${CUSTOM_LABEL_OTHER}". Add it to the env var (first 20 entries are honored) to attribute it.`);
450
+ warnCustomLabelOnce(`custom_label:${value}`, `customLabel "${value}" is not in the FRUGAL_CUSTOM_LABEL allowlist — coerced to "${CUSTOM_LABEL_OTHER}". Add it to the env var (first 20 entries are honored) to attribute it.`);
444
451
  return CUSTOM_LABEL_OTHER;
445
452
  }
446
453
  // history_depth and duplicate_requests are documented without an error-type
@@ -454,12 +461,4 @@ function stripErrorType(attrs) {
454
461
  const { [FRUGAL_ERROR_TYPE]: _ignored, ...rest } = attrs;
455
462
  return rest;
456
463
  }
457
- function errorName(err) {
458
- if (err && typeof err === "object" && "name" in err && typeof err.name === "string") {
459
- return err.name;
460
- }
461
- if (err instanceof Error)
462
- return err.constructor.name;
463
- return "UnknownError";
464
- }
465
464
  //# sourceMappingURL=instrument.js.map