autotel 3.3.1 → 3.4.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 (39) hide show
  1. package/dist/{chunk-VUYLXWCB.cjs → chunk-6WWXA6IK.cjs} +5 -5
  2. package/dist/{chunk-VUYLXWCB.cjs.map → chunk-6WWXA6IK.cjs.map} +1 -1
  3. package/dist/{chunk-55ALGIAR.js → chunk-AIX6BVNN.js} +41 -6
  4. package/dist/chunk-AIX6BVNN.js.map +1 -0
  5. package/dist/{chunk-DK6VFPVK.cjs → chunk-BGO7TZID.cjs} +7 -7
  6. package/dist/{chunk-DK6VFPVK.cjs.map → chunk-BGO7TZID.cjs.map} +1 -1
  7. package/dist/{chunk-VFU663OM.js → chunk-DMSD5AF3.js} +3 -3
  8. package/dist/{chunk-VFU663OM.js.map → chunk-DMSD5AF3.js.map} +1 -1
  9. package/dist/{chunk-FMTNB27Z.cjs → chunk-FOFBFQES.cjs} +41 -6
  10. package/dist/chunk-FOFBFQES.cjs.map +1 -0
  11. package/dist/{chunk-2GWM2CIT.js → chunk-NMEYVL4L.js} +3 -3
  12. package/dist/{chunk-2GWM2CIT.js.map → chunk-NMEYVL4L.js.map} +1 -1
  13. package/dist/{chunk-4EXFRREO.js → chunk-TEXCI2S6.js} +3 -3
  14. package/dist/{chunk-4EXFRREO.js.map → chunk-TEXCI2S6.js.map} +1 -1
  15. package/dist/{chunk-C4JCSBFO.cjs → chunk-Z3VD3UQZ.cjs} +5 -5
  16. package/dist/{chunk-C4JCSBFO.cjs.map → chunk-Z3VD3UQZ.cjs.map} +1 -1
  17. package/dist/decorators.cjs +1 -1
  18. package/dist/decorators.js +1 -1
  19. package/dist/functional.cjs +9 -9
  20. package/dist/functional.d.cts +13 -0
  21. package/dist/functional.d.ts +13 -0
  22. package/dist/functional.js +1 -1
  23. package/dist/index.cjs +22 -22
  24. package/dist/index.js +5 -5
  25. package/dist/messaging.cjs +5 -5
  26. package/dist/messaging.js +2 -2
  27. package/dist/semantic-helpers.cjs +6 -6
  28. package/dist/semantic-helpers.js +2 -2
  29. package/dist/webhook.cjs +2 -2
  30. package/dist/webhook.js +1 -1
  31. package/dist/workflow-distributed.cjs +3 -3
  32. package/dist/workflow-distributed.js +1 -1
  33. package/dist/workflow.cjs +6 -6
  34. package/dist/workflow.js +2 -2
  35. package/package.json +1 -1
  36. package/src/functional.test.ts +51 -0
  37. package/src/functional.ts +78 -12
  38. package/dist/chunk-55ALGIAR.js.map +0 -1
  39. package/dist/chunk-FMTNB27Z.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -1,19 +1,19 @@
1
1
  export { createDrainPipeline } from './chunk-KFOHQK7X.js';
2
- export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-4EXFRREO.js';
2
+ export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-TEXCI2S6.js';
3
3
  export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-454CH4OV.js';
4
4
  export { httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './chunk-7552UTQW.js';
5
5
  export { HTTPAttributes, ServiceAttributes, URLAttributes } from './chunk-4A53YIAX.js';
6
6
  export { parseError } from './chunk-J7VGRIAJ.js';
7
- export { traceConsumer, traceProducer } from './chunk-VFU663OM.js';
7
+ export { traceConsumer, traceProducer } from './chunk-DMSD5AF3.js';
8
8
  import { emitCorrelatedEvent } from './chunk-KIL5CUN6.js';
9
9
  export { BusinessBaggage, createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
10
10
  import { resetMetrics } from './chunk-7SAWIN74.js';
11
11
  export { Metric, getMetrics, resetMetrics } from './chunk-7SAWIN74.js';
12
12
  import './chunk-5ZN622AO.js';
13
13
  export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './chunk-TQ5UWA7S.js';
14
- export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-2GWM2CIT.js';
15
- import { trace as trace$1 } from './chunk-55ALGIAR.js';
16
- export { ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './chunk-55ALGIAR.js';
14
+ export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-NMEYVL4L.js';
15
+ import { trace as trace$1 } from './chunk-AIX6BVNN.js';
16
+ export { ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './chunk-AIX6BVNN.js';
17
17
  export { createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan } from './chunk-HLZ7H3VZ.js';
18
18
  import { resetEvents } from './chunk-LKASEUWE.js';
19
19
  export { Event, getEvents, resetEvents } from './chunk-LKASEUWE.js';
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkVUYLXWCB_cjs = require('./chunk-VUYLXWCB.cjs');
3
+ var chunk6WWXA6IK_cjs = require('./chunk-6WWXA6IK.cjs');
4
4
  require('./chunk-4P6ZOARG.cjs');
5
- require('./chunk-FMTNB27Z.cjs');
5
+ require('./chunk-FOFBFQES.cjs');
6
6
  require('./chunk-2GIBANLB.cjs');
7
7
  require('./chunk-VQTCQKHQ.cjs');
8
8
  require('./chunk-JAX4LFGG.cjs');
@@ -24,15 +24,15 @@ require('./chunk-YREV3LGG.cjs');
24
24
 
25
25
  Object.defineProperty(exports, "clearOrderingState", {
26
26
  enumerable: true,
27
- get: function () { return chunkVUYLXWCB_cjs.clearOrderingState; }
27
+ get: function () { return chunk6WWXA6IK_cjs.clearOrderingState; }
28
28
  });
29
29
  Object.defineProperty(exports, "traceConsumer", {
30
30
  enumerable: true,
31
- get: function () { return chunkVUYLXWCB_cjs.traceConsumer; }
31
+ get: function () { return chunk6WWXA6IK_cjs.traceConsumer; }
32
32
  });
33
33
  Object.defineProperty(exports, "traceProducer", {
34
34
  enumerable: true,
35
- get: function () { return chunkVUYLXWCB_cjs.traceProducer; }
35
+ get: function () { return chunk6WWXA6IK_cjs.traceProducer; }
36
36
  });
37
37
  //# sourceMappingURL=messaging.cjs.map
38
38
  //# sourceMappingURL=messaging.cjs.map
package/dist/messaging.js CHANGED
@@ -1,6 +1,6 @@
1
- export { clearOrderingState, traceConsumer, traceProducer } from './chunk-VFU663OM.js';
1
+ export { clearOrderingState, traceConsumer, traceProducer } from './chunk-DMSD5AF3.js';
2
2
  import './chunk-KIL5CUN6.js';
3
- import './chunk-55ALGIAR.js';
3
+ import './chunk-AIX6BVNN.js';
4
4
  import './chunk-HLZ7H3VZ.js';
5
5
  import './chunk-SEO6NAQT.js';
6
6
  import './chunk-LCXOOJIP.js';
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkDK6VFPVK_cjs = require('./chunk-DK6VFPVK.cjs');
4
- require('./chunk-FMTNB27Z.cjs');
3
+ var chunkBGO7TZID_cjs = require('./chunk-BGO7TZID.cjs');
4
+ require('./chunk-FOFBFQES.cjs');
5
5
  require('./chunk-2GIBANLB.cjs');
6
6
  require('./chunk-VQTCQKHQ.cjs');
7
7
  require('./chunk-JAX4LFGG.cjs');
@@ -23,19 +23,19 @@ require('./chunk-YREV3LGG.cjs');
23
23
 
24
24
  Object.defineProperty(exports, "traceDB", {
25
25
  enumerable: true,
26
- get: function () { return chunkDK6VFPVK_cjs.traceDB; }
26
+ get: function () { return chunkBGO7TZID_cjs.traceDB; }
27
27
  });
28
28
  Object.defineProperty(exports, "traceHTTP", {
29
29
  enumerable: true,
30
- get: function () { return chunkDK6VFPVK_cjs.traceHTTP; }
30
+ get: function () { return chunkBGO7TZID_cjs.traceHTTP; }
31
31
  });
32
32
  Object.defineProperty(exports, "traceLLM", {
33
33
  enumerable: true,
34
- get: function () { return chunkDK6VFPVK_cjs.traceLLM; }
34
+ get: function () { return chunkBGO7TZID_cjs.traceLLM; }
35
35
  });
36
36
  Object.defineProperty(exports, "traceMessaging", {
37
37
  enumerable: true,
38
- get: function () { return chunkDK6VFPVK_cjs.traceMessaging; }
38
+ get: function () { return chunkBGO7TZID_cjs.traceMessaging; }
39
39
  });
40
40
  //# sourceMappingURL=semantic-helpers.cjs.map
41
41
  //# sourceMappingURL=semantic-helpers.cjs.map
@@ -1,5 +1,5 @@
1
- export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-2GWM2CIT.js';
2
- import './chunk-55ALGIAR.js';
1
+ export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-NMEYVL4L.js';
2
+ import './chunk-AIX6BVNN.js';
3
3
  import './chunk-HLZ7H3VZ.js';
4
4
  import './chunk-SEO6NAQT.js';
5
5
  import './chunk-LCXOOJIP.js';
package/dist/webhook.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk4P6ZOARG_cjs = require('./chunk-4P6ZOARG.cjs');
4
- var chunkFMTNB27Z_cjs = require('./chunk-FMTNB27Z.cjs');
4
+ var chunkFOFBFQES_cjs = require('./chunk-FOFBFQES.cjs');
5
5
  require('./chunk-2GIBANLB.cjs');
6
6
  require('./chunk-VQTCQKHQ.cjs');
7
7
  var chunkJAX4LFGG_cjs = require('./chunk-JAX4LFGG.cjs');
@@ -157,7 +157,7 @@ function createParkingLot(config) {
157
157
  },
158
158
  traceCallback(callbackConfig) {
159
159
  return (fnFactory) => {
160
- return chunkFMTNB27Z_cjs.trace(
160
+ return chunkFOFBFQES_cjs.trace(
161
161
  {
162
162
  name: callbackConfig.name,
163
163
  spanKind: api.SpanKind.SERVER
package/dist/webhook.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { emitCorrelatedEvent } from './chunk-KIL5CUN6.js';
2
- import { trace } from './chunk-55ALGIAR.js';
2
+ import { trace } from './chunk-AIX6BVNN.js';
3
3
  import './chunk-HLZ7H3VZ.js';
4
4
  import './chunk-SEO6NAQT.js';
5
5
  import { recordStructuredError } from './chunk-LCXOOJIP.js';
@@ -2,7 +2,7 @@
2
2
 
3
3
  var chunk4P6ZOARG_cjs = require('./chunk-4P6ZOARG.cjs');
4
4
  var chunkINJD3G4K_cjs = require('./chunk-INJD3G4K.cjs');
5
- var chunkFMTNB27Z_cjs = require('./chunk-FMTNB27Z.cjs');
5
+ var chunkFOFBFQES_cjs = require('./chunk-FOFBFQES.cjs');
6
6
  require('./chunk-2GIBANLB.cjs');
7
7
  require('./chunk-VQTCQKHQ.cjs');
8
8
  require('./chunk-JAX4LFGG.cjs');
@@ -58,7 +58,7 @@ var WorkflowBaggage = chunkINJD3G4K_cjs.createSafeBaggageSchema(workflowBaggageF
58
58
  function traceDistributedWorkflow(config) {
59
59
  const spanName = `workflow.${config.name}`;
60
60
  return (fnFactory) => {
61
- return chunkFMTNB27Z_cjs.trace(
61
+ return chunkFOFBFQES_cjs.trace(
62
62
  { name: spanName, spanKind: api.SpanKind.INTERNAL },
63
63
  (baseCtx) => {
64
64
  return async (...args) => {
@@ -157,7 +157,7 @@ function traceDistributedWorkflow(config) {
157
157
  function traceDistributedStep(config) {
158
158
  const spanName = `workflow.step.${config.name}`;
159
159
  return (fnFactory) => {
160
- return chunkFMTNB27Z_cjs.trace(
160
+ return chunkFOFBFQES_cjs.trace(
161
161
  { name: spanName, spanKind: api.SpanKind.INTERNAL },
162
162
  (baseCtx) => {
163
163
  return async (...args) => {
@@ -1,6 +1,6 @@
1
1
  import { emitCorrelatedEvent } from './chunk-KIL5CUN6.js';
2
2
  import { createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
3
- import { trace } from './chunk-55ALGIAR.js';
3
+ import { trace } from './chunk-AIX6BVNN.js';
4
4
  import './chunk-HLZ7H3VZ.js';
5
5
  import './chunk-SEO6NAQT.js';
6
6
  import './chunk-LCXOOJIP.js';
package/dist/workflow.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkC4JCSBFO_cjs = require('./chunk-C4JCSBFO.cjs');
3
+ var chunkZ3VD3UQZ_cjs = require('./chunk-Z3VD3UQZ.cjs');
4
4
  require('./chunk-4P6ZOARG.cjs');
5
- require('./chunk-FMTNB27Z.cjs');
5
+ require('./chunk-FOFBFQES.cjs');
6
6
  require('./chunk-2GIBANLB.cjs');
7
7
  require('./chunk-VQTCQKHQ.cjs');
8
8
  require('./chunk-JAX4LFGG.cjs');
@@ -24,19 +24,19 @@ require('./chunk-YREV3LGG.cjs');
24
24
 
25
25
  Object.defineProperty(exports, "getCurrentWorkflowContext", {
26
26
  enumerable: true,
27
- get: function () { return chunkC4JCSBFO_cjs.getCurrentWorkflowContext; }
27
+ get: function () { return chunkZ3VD3UQZ_cjs.getCurrentWorkflowContext; }
28
28
  });
29
29
  Object.defineProperty(exports, "isInWorkflow", {
30
30
  enumerable: true,
31
- get: function () { return chunkC4JCSBFO_cjs.isInWorkflow; }
31
+ get: function () { return chunkZ3VD3UQZ_cjs.isInWorkflow; }
32
32
  });
33
33
  Object.defineProperty(exports, "traceStep", {
34
34
  enumerable: true,
35
- get: function () { return chunkC4JCSBFO_cjs.traceStep; }
35
+ get: function () { return chunkZ3VD3UQZ_cjs.traceStep; }
36
36
  });
37
37
  Object.defineProperty(exports, "traceWorkflow", {
38
38
  enumerable: true,
39
- get: function () { return chunkC4JCSBFO_cjs.traceWorkflow; }
39
+ get: function () { return chunkZ3VD3UQZ_cjs.traceWorkflow; }
40
40
  });
41
41
  //# sourceMappingURL=workflow.cjs.map
42
42
  //# sourceMappingURL=workflow.cjs.map
package/dist/workflow.js CHANGED
@@ -1,6 +1,6 @@
1
- export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-4EXFRREO.js';
1
+ export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-TEXCI2S6.js';
2
2
  import './chunk-KIL5CUN6.js';
3
- import './chunk-55ALGIAR.js';
3
+ import './chunk-AIX6BVNN.js';
4
4
  import './chunk-HLZ7H3VZ.js';
5
5
  import './chunk-SEO6NAQT.js';
6
6
  import './chunk-LCXOOJIP.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "description": "Write Once, Observe Anywhere",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -337,6 +337,57 @@ describe('Functional API', () => {
337
337
  expect(spans[0]!.attributes['userId']).toBe('456');
338
338
  });
339
339
 
340
+ it('captures input/output as autotel.input/output when opted in', async () => {
341
+ const collector = createTraceCollector();
342
+
343
+ const calc = traceOptionsFactory(
344
+ { name: 'calc', captureInput: true, captureOutput: true },
345
+ (_ctx: TraceContext) => async (a: number, b: number) => a + b,
346
+ );
347
+
348
+ await calc(2, 3);
349
+
350
+ const span = collector.getSpans()[0]!;
351
+ // Multiple args captured as an array; single value would be captured directly.
352
+ expect(span.attributes['autotel.input']).toBe('[2,3]');
353
+ expect(span.attributes['autotel.output']).toBe('5');
354
+ });
355
+
356
+ it('does not capture input/output by default', async () => {
357
+ const collector = createTraceCollector();
358
+
359
+ const calc = traceOptionsFactory(
360
+ { name: 'calc-default' },
361
+ (_ctx: TraceContext) => async (a: number, b: number) => a + b,
362
+ );
363
+
364
+ await calc(2, 3);
365
+
366
+ const span = collector.getSpans()[0]!;
367
+ expect(span.attributes['autotel.input']).toBeUndefined();
368
+ expect(span.attributes['autotel.output']).toBeUndefined();
369
+ });
370
+
371
+ it('captures a single argument directly (not wrapped in an array)', async () => {
372
+ const collector = createTraceCollector();
373
+
374
+ const load = traceOptionsFactory(
375
+ { name: 'load', captureInput: true, captureOutput: true },
376
+ (_ctx: TraceContext) => async (req: { userId: string }) => ({
377
+ holdings: 3,
378
+ userId: req.userId,
379
+ }),
380
+ );
381
+
382
+ await load({ userId: 'anon' });
383
+
384
+ const span = collector.getSpans()[0]!;
385
+ expect(span.attributes['autotel.input']).toBe('{"userId":"anon"}');
386
+ expect(span.attributes['autotel.output']).toBe(
387
+ '{"holdings":3,"userId":"anon"}',
388
+ );
389
+ });
390
+
340
391
  it('should respect NeverSampler', async () => {
341
392
  const collector = createTraceCollector();
342
393
 
package/src/functional.ts CHANGED
@@ -415,6 +415,21 @@ export interface TracingOptions<
415
415
  */
416
416
  attributesFromResult?: (result: TReturn) => Record<string, unknown>;
417
417
 
418
+ /**
419
+ * Capture the function arguments onto the span as `autotel.input`
420
+ * (JSON, truncated). One arg is captured directly; multiple are captured as
421
+ * an array. Off by default — opt in per call. Tools (visualizers, devtools)
422
+ * read this alongside `ai.toolCall.args` to show function I/O uniformly.
423
+ * Avoid on args with secrets/PII, or pair with a redacting processor.
424
+ */
425
+ captureInput?: boolean;
426
+
427
+ /**
428
+ * Capture the function return value onto the span as `autotel.output`
429
+ * (JSON, truncated). Off by default. Same caveats as {@link captureInput}.
430
+ */
431
+ captureOutput?: boolean;
432
+
418
433
  /**
419
434
  * Start a new root span instead of creating a child
420
435
  * Useful for serverless entry points
@@ -494,6 +509,45 @@ function createDummyCtx<
494
509
  } as unknown as TraceContext<TBaggage>;
495
510
  }
496
511
 
512
+ /** Attribute keys for opt-in function I/O capture (see TracingOptions). */
513
+ const AUTOTEL_INPUT_ATTR = 'autotel.input';
514
+ const AUTOTEL_OUTPUT_ATTR = 'autotel.output';
515
+ const CAPTURE_MAX_CHARS = 4096;
516
+
517
+ /** JSON-serialize a captured value, defensively (truncate, swallow cycles). */
518
+ function serializeCapture(value: unknown): string | undefined {
519
+ if (value === undefined) return undefined;
520
+ try {
521
+ const json = typeof value === 'string' ? value : JSON.stringify(value);
522
+ if (json === undefined) return undefined;
523
+ return json.length > CAPTURE_MAX_CHARS
524
+ ? `${json.slice(0, CAPTURE_MAX_CHARS)}…[truncated]`
525
+ : json;
526
+ } catch {
527
+ return undefined;
528
+ }
529
+ }
530
+
531
+ /** `autotel.input` from args (single arg captured directly, else the array). */
532
+ function captureInputAttrs(
533
+ args: unknown[],
534
+ enabled?: boolean,
535
+ ): Record<string, unknown> {
536
+ if (!enabled) return {};
537
+ const s = serializeCapture(args.length === 1 ? args[0] : args);
538
+ return s === undefined ? {} : { [AUTOTEL_INPUT_ATTR]: s };
539
+ }
540
+
541
+ /** `autotel.output` from the return value. */
542
+ function captureOutputAttrs(
543
+ result: unknown,
544
+ enabled?: boolean,
545
+ ): Record<string, unknown> {
546
+ if (!enabled) return {};
547
+ const s = serializeCapture(result);
548
+ return s === undefined ? {} : { [AUTOTEL_OUTPUT_ATTR]: s };
549
+ }
550
+
497
551
  function isAsyncFunction(fn: unknown): boolean {
498
552
  return typeof fn === 'function' && fn.constructor?.name === 'AsyncFunction';
499
553
  }
@@ -842,9 +896,12 @@ function wrapWithTracing<TArgs extends unknown[], TReturn>(
842
896
 
843
897
  const ctxValue = createTraceContext(span);
844
898
  const fn = fnFactory(ctxValue);
845
- const argsAttributes = options.attributesFromArgs
846
- ? options.attributesFromArgs(args)
847
- : {};
899
+ const argsAttributes = {
900
+ ...captureInputAttrs(args, options.captureInput),
901
+ ...(options.attributesFromArgs
902
+ ? options.attributesFromArgs(args)
903
+ : {}),
904
+ };
848
905
 
849
906
  const handleTailSampling = (
850
907
  success: boolean,
@@ -879,9 +936,12 @@ function wrapWithTracing<TArgs extends unknown[], TReturn>(
879
936
  status: 'success',
880
937
  });
881
938
 
882
- const resultAttributes = options.attributesFromResult
883
- ? options.attributesFromResult(result)
884
- : {};
939
+ const resultAttributes = {
940
+ ...captureOutputAttrs(result, options.captureOutput),
941
+ ...(options.attributesFromResult
942
+ ? options.attributesFromResult(result)
943
+ : {}),
944
+ };
885
945
 
886
946
  span.setStatus({ code: SpanStatusCode.OK });
887
947
  span.setAttributes({
@@ -1155,9 +1215,12 @@ function wrapWithTracingSync<TArgs extends unknown[], TReturn>(
1155
1215
 
1156
1216
  // Extract attributes only when actually tracing
1157
1217
  // This avoids expensive preprocessing when sampling rejects the trace
1158
- const argsAttributes = options.attributesFromArgs
1159
- ? options.attributesFromArgs(args)
1160
- : {};
1218
+ const argsAttributes = {
1219
+ ...captureInputAttrs(args, options.captureInput),
1220
+ ...(options.attributesFromArgs
1221
+ ? options.attributesFromArgs(args)
1222
+ : {}),
1223
+ };
1161
1224
 
1162
1225
  const handleTailSampling = (
1163
1226
  success: boolean,
@@ -1192,9 +1255,12 @@ function wrapWithTracingSync<TArgs extends unknown[], TReturn>(
1192
1255
  status: 'success',
1193
1256
  });
1194
1257
 
1195
- const resultAttributes = options.attributesFromResult
1196
- ? options.attributesFromResult(result)
1197
- : {};
1258
+ const resultAttributes = {
1259
+ ...captureOutputAttrs(result, options.captureOutput),
1260
+ ...(options.attributesFromResult
1261
+ ? options.attributesFromResult(result)
1262
+ : {}),
1263
+ };
1198
1264
 
1199
1265
  span.setStatus({ code: SpanStatusCode.OK });
1200
1266
  span.setAttributes({