@telemetry-dev/sdk 0.1.5 → 0.1.6

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 CHANGED
@@ -90,12 +90,19 @@ The SDK installs the [session sampling wrapper](../otel/README.md#correlation-at
90
90
  context.
91
91
  - `extractW3cContext(carrier, options?)` / `injectW3cContext(context, carrier, options?)` — extract
92
92
  or inject W3C trace context. Baggage is omitted unless `includeBaggage` is true.
93
+ - `captureEnabled("input" | "output")` — report whether the active initialized client permits that
94
+ capture direction. Returns `false` when no client is initialized.
95
+ - `boundedCapture(value, options?)` — copy a JSON-compatible value within bounded work and retained
96
+ size. Defaults to 48 KiB, depth 32, and 1,000 traversal items. Returns `{ value, truncated }`;
97
+ `value` can be partial or `undefined` when a limit, cycle, getter, or skip rule prevents capture.
93
98
  - `flush()` / `shutdown()` — export pending data; required before serverless freeze/exit.
94
99
 
95
100
  Span types: `span` (default) | `generation` | `tool` | `agent` | `embedding` — mapped to
96
101
  `gen_ai.operation.name` `function` / `chat` / `execute_tool` / `invoke_agent` / `embeddings`.
97
102
  Generation fields (`model`, `provider`, `usage`, `costUsd`, sampling params, …) map to the OTel
98
- GenAI semantic conventions; cost is computed server-side from usage unless `costUsd` is set.
103
+ GenAI semantic conventions. An explicit `costUsd` takes precedence; otherwise, the server estimates
104
+ standard token cost when reported usage and matching model pricing are available. Missing pricing leaves cost
105
+ unavailable, not zero, and does not prevent tracing or token accounting.
99
106
 
100
107
  Duration and token-usage histograms (`gen_ai.client.operation.duration`,
101
108
  `gen_ai.client.token.usage`) are recorded automatically for generation/agent/embedding/tool spans.
package/dist/index.d.mts CHANGED
@@ -59,6 +59,24 @@ interface TelemetryOptions {
59
59
  sdkName?: string;
60
60
  }
61
61
  //#endregion
62
+ //#region src/capture.d.ts
63
+ interface BoundedCaptureOptions {
64
+ maxBytes?: number;
65
+ maxDepth?: number;
66
+ maxItems?: number;
67
+ skip?: (key: string, value: unknown, parent: unknown, path: readonly string[]) => boolean;
68
+ }
69
+ interface BoundedCaptureResult {
70
+ value: unknown;
71
+ truncated: boolean;
72
+ }
73
+ interface BoundedCaptureDetails extends BoundedCaptureResult {
74
+ bytes: number;
75
+ items: number;
76
+ }
77
+ declare function boundedCaptureDetails(input: unknown, options?: BoundedCaptureOptions): BoundedCaptureDetails;
78
+ declare function boundedCapture(input: unknown, options?: BoundedCaptureOptions): BoundedCaptureResult;
79
+ //#endregion
62
80
  //#region src/attrs.d.ts
63
81
  type SpanType = "span" | "generation" | "tool" | "agent" | "embedding";
64
82
  interface TokenUsage {
@@ -68,6 +86,15 @@ interface TokenUsage {
68
86
  cacheReadInputTokens?: number;
69
87
  cacheCreationInputTokens?: number;
70
88
  reasoningOutputTokens?: number;
89
+ textInputTokens?: number;
90
+ textOutputTokens?: number;
91
+ textCacheReadInputTokens?: number;
92
+ imageInputTokens?: number;
93
+ imageOutputTokens?: number;
94
+ imageCacheReadInputTokens?: number;
95
+ audioInputTokens?: number;
96
+ audioOutputTokens?: number;
97
+ audioCacheReadInputTokens?: number;
71
98
  }
72
99
  interface GenerationFields {
73
100
  model?: string;
@@ -126,6 +153,7 @@ interface TelemetryClient {
126
153
  /** Flush + teardown + unregister globals; the client becomes a no-op afterwards. */
127
154
  shutdown(): Promise<void>;
128
155
  }
156
+ declare function captureEnabled(kind: "input" | "output"): boolean;
129
157
  declare function flush(): Promise<void>;
130
158
  declare function shutdown(): Promise<void>;
131
159
  declare function init(options?: TelemetryOptions, overrides?: ClientOverrides): TelemetryClient;
@@ -207,4 +235,4 @@ interface ObserveOptions extends StartSpanOptions {
207
235
  */
208
236
  declare function observe<TThis, TArgs extends unknown[], TReturn>(fn: (this: TThis, ...args: TArgs) => TReturn, options?: ObserveOptions): (...args: TArgs) => TReturn;
209
237
  //#endregion
210
- export { type AgentFields, type BatchOptions, type ClientOverrides, type ExportMode, type GenerationFields, type LogLevel, type LogOptions, type MaskFn, type ObserveOptions, type ParentRef, type PropagatedAttributes, SCOPE_NAME, type SdkLogLevel, type SpanFields, type SpanHandle, type SpanType, type StartSpanOptions, type TelemetryClient, type TelemetryOptions, TelemetrySpanProcessor, type TelemetrySpanProcessorOptions, type TokenUsage, type ToolFields, activeContext, extractW3cContext, flush, getTraceparent, init, injectW3cContext, log, observe, propagateAttributes, shutdown, startActiveSpan, startSpan, updateActiveSpan, withContext };
238
+ export { type AgentFields, type BatchOptions, type BoundedCaptureDetails, type BoundedCaptureOptions, type BoundedCaptureResult, type ClientOverrides, type ExportMode, type GenerationFields, type LogLevel, type LogOptions, type MaskFn, type ObserveOptions, type ParentRef, type PropagatedAttributes, SCOPE_NAME, type SdkLogLevel, type SpanFields, type SpanHandle, type SpanType, type StartSpanOptions, type TelemetryClient, type TelemetryOptions, TelemetrySpanProcessor, type TelemetrySpanProcessorOptions, type TokenUsage, type ToolFields, activeContext, boundedCapture, boundedCaptureDetails, captureEnabled, extractW3cContext, flush, getTraceparent, init, injectW3cContext, log, observe, propagateAttributes, shutdown, startActiveSpan, startSpan, updateActiveSpan, withContext };
package/dist/index.mjs CHANGED
@@ -48,6 +48,10 @@ let activeClient;
48
48
  function currentClient() {
49
49
  return activeClient ?? NOOP_CLIENT;
50
50
  }
51
+ function captureEnabled(kind) {
52
+ const config = currentClient().core?.config;
53
+ return kind === "input" ? config?.captureInput ?? false : config?.captureOutput ?? false;
54
+ }
51
55
  function flush() {
52
56
  return currentClient().flush();
53
57
  }
@@ -186,6 +190,137 @@ function initInner(options, overrides) {
186
190
  //#endregion
187
191
  //#region src/capture.ts
188
192
  const TRUNCATION_MARKER = "...[truncated]";
193
+ const jsonStringByteLength = (value, limit) => {
194
+ let bytes = 2;
195
+ for (let index = 0; index < value.length && bytes <= limit; index += 1) {
196
+ const code = value.charCodeAt(index);
197
+ if (code === 34 || code === 92 || code === 8 || code === 9 || code === 10 || code === 12 || code === 13) bytes += 2;
198
+ else if (code < 32) bytes += 6;
199
+ else if (code < 128) bytes += 1;
200
+ else if (code < 2048) bytes += 2;
201
+ else if (code >= 55296 && code <= 56319) {
202
+ const next = value.charCodeAt(index + 1);
203
+ if (next >= 56320 && next <= 57343) {
204
+ bytes += 4;
205
+ index += 1;
206
+ } else bytes += 6;
207
+ } else if (code >= 56320 && code <= 57343) bytes += 6;
208
+ else bytes += 3;
209
+ }
210
+ return bytes;
211
+ };
212
+ const captureLimit = (name, value, fallback) => {
213
+ if (value === void 0) return fallback;
214
+ if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name} must be a non-negative safe integer`);
215
+ return value;
216
+ };
217
+ function boundedCaptureDetails(input, options = {}) {
218
+ const maxBytes = captureLimit("maxBytes", options.maxBytes, 48 * 1024);
219
+ const maxDepth = captureLimit("maxDepth", options.maxDepth, 32);
220
+ const maxItems = captureLimit("maxItems", options.maxItems, 1e3);
221
+ const ancestors = /* @__PURE__ */ new WeakSet();
222
+ let bytes = 0;
223
+ let items = 0;
224
+ let truncated = false;
225
+ const visit = (value, depth, path) => {
226
+ if (items >= maxItems) {
227
+ truncated = true;
228
+ return;
229
+ }
230
+ items += 1;
231
+ if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
232
+ const length = typeof value === "string" ? jsonStringByteLength(value, maxBytes - bytes) : JSON.stringify(value)?.length ?? 0;
233
+ if (bytes + length > maxBytes) {
234
+ truncated = true;
235
+ return;
236
+ }
237
+ bytes += length;
238
+ return value;
239
+ }
240
+ if (typeof value !== "object") return void 0;
241
+ if (depth >= maxDepth || ancestors.has(value) || bytes + 2 > maxBytes) {
242
+ truncated = true;
243
+ return;
244
+ }
245
+ ancestors.add(value);
246
+ bytes += 2;
247
+ try {
248
+ if (Array.isArray(value)) {
249
+ const result = [];
250
+ for (const item of value) {
251
+ if (items >= maxItems) {
252
+ truncated = true;
253
+ break;
254
+ }
255
+ const previousBytes = bytes;
256
+ if (result.length > 0) bytes += 1;
257
+ const converted = visit(item, depth + 1, path);
258
+ if (converted === void 0) bytes = previousBytes;
259
+ else result.push(converted);
260
+ }
261
+ return result;
262
+ }
263
+ const result = {};
264
+ let emitted = false;
265
+ for (const key in value) {
266
+ if (items >= maxItems) {
267
+ truncated = true;
268
+ break;
269
+ }
270
+ if (!Object.hasOwn(value, key)) {
271
+ items += 1;
272
+ continue;
273
+ }
274
+ const keyBytes = jsonStringByteLength(key, maxBytes - bytes) + 1 + (emitted ? 1 : 0);
275
+ if (bytes + keyBytes > maxBytes) {
276
+ items += 1;
277
+ truncated = true;
278
+ continue;
279
+ }
280
+ let item;
281
+ try {
282
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
283
+ item = descriptor?.get ? descriptor.get.call(value) : descriptor?.value;
284
+ if (options.skip?.(key, item, value, path)) {
285
+ items += 1;
286
+ continue;
287
+ }
288
+ } catch {
289
+ items += 1;
290
+ truncated = true;
291
+ continue;
292
+ }
293
+ const previousBytes = bytes;
294
+ bytes += keyBytes;
295
+ const converted = visit(item, depth + 1, [...path, key]);
296
+ if (converted === void 0) bytes = previousBytes;
297
+ else {
298
+ result[key] = converted;
299
+ emitted = true;
300
+ }
301
+ }
302
+ return result;
303
+ } catch {
304
+ truncated = true;
305
+ return;
306
+ } finally {
307
+ ancestors.delete(value);
308
+ }
309
+ };
310
+ return {
311
+ value: visit(input, 0, []),
312
+ truncated,
313
+ bytes,
314
+ items
315
+ };
316
+ }
317
+ function boundedCapture(input, options = {}) {
318
+ const { value, truncated } = boundedCaptureDetails(input, options);
319
+ return {
320
+ value,
321
+ truncated
322
+ };
323
+ }
189
324
  function truncate(value, maxLength) {
190
325
  if (value.length <= maxLength) return value;
191
326
  return value.slice(0, Math.max(maxLength - 14, 0)) + TRUNCATION_MARKER;
@@ -308,6 +443,15 @@ function fieldsToAttributes(fields, type, cfg) {
308
443
  "gen_ai.usage.cache_read.input_tokens": fields.usage?.cacheReadInputTokens,
309
444
  "gen_ai.usage.cache_creation.input_tokens": fields.usage?.cacheCreationInputTokens,
310
445
  "gen_ai.usage.reasoning.output_tokens": fields.usage?.reasoningOutputTokens,
446
+ "gen_ai.usage.text.input_tokens": fields.usage?.textInputTokens,
447
+ "gen_ai.usage.text.output_tokens": fields.usage?.textOutputTokens,
448
+ "gen_ai.usage.text.cache_read.input_tokens": fields.usage?.textCacheReadInputTokens,
449
+ "gen_ai.usage.image.input_tokens": fields.usage?.imageInputTokens,
450
+ "gen_ai.usage.image.output_tokens": fields.usage?.imageOutputTokens,
451
+ "gen_ai.usage.image.cache_read.input_tokens": fields.usage?.imageCacheReadInputTokens,
452
+ "gen_ai.usage.audio.input_tokens": fields.usage?.audioInputTokens,
453
+ "gen_ai.usage.audio.output_tokens": fields.usage?.audioOutputTokens,
454
+ "gen_ai.usage.audio.cache_read.input_tokens": fields.usage?.audioCacheReadInputTokens,
311
455
  "gen_ai.usage.cost": fields.costUsd,
312
456
  "gen_ai.response.finish_reasons": fields.finishReason ? [fields.finishReason] : void 0,
313
457
  "gen_ai.output.type": fields.outputType,
@@ -625,4 +769,4 @@ function observe(fn, options) {
625
769
  return wrapped;
626
770
  }
627
771
  //#endregion
628
- export { SCOPE_NAME, TelemetrySpanProcessor, activeContext, extractW3cContext, flush, getTraceparent, init, injectW3cContext, log, observe, propagateAttributes, shutdown, startActiveSpan, startSpan, updateActiveSpan, withContext };
772
+ export { SCOPE_NAME, TelemetrySpanProcessor, activeContext, boundedCapture, boundedCaptureDetails, captureEnabled, extractW3cContext, flush, getTraceparent, init, injectW3cContext, log, observe, propagateAttributes, shutdown, startActiveSpan, startSpan, updateActiveSpan, withContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telemetry-dev/sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Pure TypeScript SDK for telemetry.dev: LLM traces, logs, and GenAI metrics on OpenTelemetry, for Node and edge runtimes.",
5
5
  "keywords": [
6
6
  "genai",
package/src/attrs.ts CHANGED
@@ -32,6 +32,15 @@ export interface TokenUsage {
32
32
  cacheReadInputTokens?: number;
33
33
  cacheCreationInputTokens?: number;
34
34
  reasoningOutputTokens?: number;
35
+ textInputTokens?: number;
36
+ textOutputTokens?: number;
37
+ textCacheReadInputTokens?: number;
38
+ imageInputTokens?: number;
39
+ imageOutputTokens?: number;
40
+ imageCacheReadInputTokens?: number;
41
+ audioInputTokens?: number;
42
+ audioOutputTokens?: number;
43
+ audioCacheReadInputTokens?: number;
35
44
  }
36
45
 
37
46
  export interface GenerationFields {
@@ -103,6 +112,15 @@ export function fieldsToAttributes(
103
112
  "gen_ai.usage.cache_read.input_tokens": fields.usage?.cacheReadInputTokens,
104
113
  "gen_ai.usage.cache_creation.input_tokens": fields.usage?.cacheCreationInputTokens,
105
114
  "gen_ai.usage.reasoning.output_tokens": fields.usage?.reasoningOutputTokens,
115
+ "gen_ai.usage.text.input_tokens": fields.usage?.textInputTokens,
116
+ "gen_ai.usage.text.output_tokens": fields.usage?.textOutputTokens,
117
+ "gen_ai.usage.text.cache_read.input_tokens": fields.usage?.textCacheReadInputTokens,
118
+ "gen_ai.usage.image.input_tokens": fields.usage?.imageInputTokens,
119
+ "gen_ai.usage.image.output_tokens": fields.usage?.imageOutputTokens,
120
+ "gen_ai.usage.image.cache_read.input_tokens": fields.usage?.imageCacheReadInputTokens,
121
+ "gen_ai.usage.audio.input_tokens": fields.usage?.audioInputTokens,
122
+ "gen_ai.usage.audio.output_tokens": fields.usage?.audioOutputTokens,
123
+ "gen_ai.usage.audio.cache_read.input_tokens": fields.usage?.audioCacheReadInputTokens,
106
124
  "gen_ai.usage.cost": fields.costUsd,
107
125
  "gen_ai.response.finish_reasons": fields.finishReason ? [fields.finishReason] : undefined,
108
126
  "gen_ai.output.type": fields.outputType,
package/src/capture.ts CHANGED
@@ -11,6 +11,235 @@ export interface CaptureConfig {
11
11
  onError?: (cause: Error) => void;
12
12
  }
13
13
 
14
+ export interface BoundedCaptureOptions {
15
+ maxBytes?: number;
16
+ maxDepth?: number;
17
+ maxItems?: number;
18
+ skip?: (key: string, value: unknown, parent: unknown, path: readonly string[]) => boolean;
19
+ }
20
+
21
+ export interface BoundedCaptureResult {
22
+ value: unknown;
23
+ truncated: boolean;
24
+ }
25
+
26
+ export interface BoundedCaptureDetails extends BoundedCaptureResult {
27
+ bytes: number;
28
+ items: number;
29
+ }
30
+
31
+ interface CapturedObject {
32
+ [key: string]: CapturedValue;
33
+ }
34
+
35
+ type CapturedValue = null | boolean | number | string | CapturedValue[] | CapturedObject;
36
+
37
+ const jsonStringByteLength = (value: string, limit: number) => {
38
+ let bytes = 2;
39
+
40
+ for (let index = 0; index < value.length && bytes <= limit; index += 1) {
41
+ const code = value.charCodeAt(index);
42
+
43
+ if (
44
+ code === 0x22 ||
45
+ code === 0x5c ||
46
+ code === 0x08 ||
47
+ code === 0x09 ||
48
+ code === 0x0a ||
49
+ code === 0x0c ||
50
+ code === 0x0d
51
+ ) {
52
+ bytes += 2;
53
+ } else if (code < 0x20) {
54
+ bytes += 6;
55
+ } else if (code < 0x80) {
56
+ bytes += 1;
57
+ } else if (code < 0x800) {
58
+ bytes += 2;
59
+ } else if (code >= 0xd800 && code <= 0xdbff) {
60
+ const next = value.charCodeAt(index + 1);
61
+
62
+ if (next >= 0xdc00 && next <= 0xdfff) {
63
+ bytes += 4;
64
+ index += 1;
65
+ } else {
66
+ bytes += 6;
67
+ }
68
+ } else if (code >= 0xdc00 && code <= 0xdfff) {
69
+ bytes += 6;
70
+ } else {
71
+ bytes += 3;
72
+ }
73
+ }
74
+
75
+ return bytes;
76
+ };
77
+
78
+ const captureLimit = (name: string, value: number | undefined, fallback: number) => {
79
+ if (value === undefined) return fallback;
80
+
81
+ if (!Number.isSafeInteger(value) || value < 0) {
82
+ throw new RangeError(`${name} must be a non-negative safe integer`);
83
+ }
84
+
85
+ return value;
86
+ };
87
+
88
+ export function boundedCaptureDetails(
89
+ input: unknown,
90
+ options: BoundedCaptureOptions = {},
91
+ ): BoundedCaptureDetails {
92
+ const maxBytes = captureLimit("maxBytes", options.maxBytes, 48 * 1024);
93
+ const maxDepth = captureLimit("maxDepth", options.maxDepth, 32);
94
+ const maxItems = captureLimit("maxItems", options.maxItems, 1_000);
95
+ const ancestors = new WeakSet<object>();
96
+ let bytes = 0;
97
+ let items = 0;
98
+ let truncated = false;
99
+
100
+ const visit = (
101
+ value: unknown,
102
+ depth: number,
103
+ path: readonly string[],
104
+ ): CapturedValue | undefined => {
105
+ if (items >= maxItems) {
106
+ truncated = true;
107
+
108
+ return undefined;
109
+ }
110
+
111
+ items += 1;
112
+
113
+ if (
114
+ value === null ||
115
+ typeof value === "boolean" ||
116
+ typeof value === "number" ||
117
+ typeof value === "string"
118
+ ) {
119
+ const length =
120
+ typeof value === "string"
121
+ ? jsonStringByteLength(value, maxBytes - bytes)
122
+ : (JSON.stringify(value)?.length ?? 0);
123
+
124
+ if (bytes + length > maxBytes) {
125
+ truncated = true;
126
+
127
+ return undefined;
128
+ }
129
+
130
+ bytes += length;
131
+
132
+ return value;
133
+ }
134
+
135
+ if (typeof value !== "object") return undefined;
136
+
137
+ if (depth >= maxDepth || ancestors.has(value) || bytes + 2 > maxBytes) {
138
+ truncated = true;
139
+
140
+ return undefined;
141
+ }
142
+
143
+ ancestors.add(value);
144
+ bytes += 2;
145
+
146
+ try {
147
+ if (Array.isArray(value)) {
148
+ const result: CapturedValue[] = [];
149
+
150
+ for (const item of value) {
151
+ if (items >= maxItems) {
152
+ truncated = true;
153
+ break;
154
+ }
155
+
156
+ const previousBytes = bytes;
157
+
158
+ if (result.length > 0) bytes += 1;
159
+ const converted = visit(item, depth + 1, path);
160
+
161
+ if (converted === undefined) {
162
+ bytes = previousBytes;
163
+ } else {
164
+ result.push(converted);
165
+ }
166
+ }
167
+
168
+ return result;
169
+ }
170
+
171
+ const result: CapturedObject = {};
172
+ let emitted = false;
173
+
174
+ for (const key in value) {
175
+ if (items >= maxItems) {
176
+ truncated = true;
177
+ break;
178
+ }
179
+
180
+ if (!Object.hasOwn(value, key)) {
181
+ items += 1;
182
+ continue;
183
+ }
184
+
185
+ const keyBytes = jsonStringByteLength(key, maxBytes - bytes) + 1 + (emitted ? 1 : 0);
186
+
187
+ if (bytes + keyBytes > maxBytes) {
188
+ items += 1;
189
+ truncated = true;
190
+ continue;
191
+ }
192
+
193
+ let item: unknown;
194
+
195
+ try {
196
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
197
+ item = descriptor?.get ? descriptor.get.call(value) : descriptor?.value;
198
+
199
+ if (options.skip?.(key, item, value, path)) {
200
+ items += 1;
201
+ continue;
202
+ }
203
+ } catch {
204
+ items += 1;
205
+ truncated = true;
206
+ continue;
207
+ }
208
+
209
+ const previousBytes = bytes;
210
+ bytes += keyBytes;
211
+ const converted = visit(item, depth + 1, [...path, key]);
212
+
213
+ if (converted === undefined) {
214
+ bytes = previousBytes;
215
+ } else {
216
+ result[key] = converted;
217
+ emitted = true;
218
+ }
219
+ }
220
+
221
+ return result;
222
+ } catch {
223
+ truncated = true;
224
+
225
+ return undefined;
226
+ } finally {
227
+ ancestors.delete(value);
228
+ }
229
+ };
230
+
231
+ return { value: visit(input, 0, []), truncated, bytes, items };
232
+ }
233
+
234
+ export function boundedCapture(
235
+ input: unknown,
236
+ options: BoundedCaptureOptions = {},
237
+ ): BoundedCaptureResult {
238
+ const { value, truncated } = boundedCaptureDetails(input, options);
239
+
240
+ return { value, truncated };
241
+ }
242
+
14
243
  export function truncate(value: string, maxLength: number): string {
15
244
  if (value.length <= maxLength) return value;
16
245
 
package/src/client.ts CHANGED
@@ -75,6 +75,12 @@ export function currentClient(): ClientHandle {
75
75
  return activeClient ?? NOOP_CLIENT;
76
76
  }
77
77
 
78
+ export function captureEnabled(kind: "input" | "output"): boolean {
79
+ const config = currentClient().core?.config;
80
+
81
+ return kind === "input" ? (config?.captureInput ?? false) : (config?.captureOutput ?? false);
82
+ }
83
+
78
84
  export function flush(): Promise<void> {
79
85
  return currentClient().flush();
80
86
  }
package/src/index.ts CHANGED
@@ -7,7 +7,14 @@ export type {
7
7
  ToolFields,
8
8
  } from "./attrs.ts";
9
9
 
10
- export { type ClientOverrides, flush, init, shutdown, type TelemetryClient } from "./client.ts";
10
+ export {
11
+ captureEnabled,
12
+ type ClientOverrides,
13
+ flush,
14
+ init,
15
+ shutdown,
16
+ type TelemetryClient,
17
+ } from "./client.ts";
11
18
 
12
19
  export type {
13
20
  BatchOptions,
@@ -18,6 +25,14 @@ export type {
18
25
  TelemetryOptions,
19
26
  } from "./config.ts";
20
27
 
28
+ export {
29
+ boundedCapture,
30
+ boundedCaptureDetails,
31
+ type BoundedCaptureDetails,
32
+ type BoundedCaptureOptions,
33
+ type BoundedCaptureResult,
34
+ } from "./capture.ts";
35
+
21
36
  export {
22
37
  propagateAttributes,
23
38
  type PropagatedAttributes,