@voltagent/core 1.1.14 → 1.1.15

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/dist/index.d.mts CHANGED
@@ -2010,9 +2010,11 @@ interface VoltAgentStreamTextResult<TOOLS extends Record<string, any> = Record<s
2010
2010
  interface ObservabilityConfig {
2011
2011
  serviceName?: string;
2012
2012
  serviceVersion?: string;
2013
+ instrumentationScopeName?: string;
2013
2014
  storage?: ObservabilityStorageAdapter;
2014
2015
  logger?: Logger;
2015
2016
  resourceAttributes?: Record<string, any>;
2017
+ spanFilters?: SpanFilterConfig;
2016
2018
  voltOpsSync?: {
2017
2019
  sampling?: {
2018
2020
  strategy?: "always" | "never" | "ratio" | "parent";
@@ -2026,6 +2028,23 @@ interface ObservabilityConfig {
2026
2028
  spanProcessors?: SpanProcessor[];
2027
2029
  logProcessors?: LogRecordProcessor[];
2028
2030
  }
2031
+ /**
2032
+ * Span filter configuration
2033
+ */
2034
+ interface SpanFilterConfig {
2035
+ enabled?: boolean;
2036
+ /**
2037
+ * Restrict span processing to spans originating from these tracer
2038
+ * instrumentation scope names. Defaults to the internal VoltAgent tracer
2039
+ * when omitted.
2040
+ */
2041
+ instrumentationScopeNames?: string[];
2042
+ /**
2043
+ * Restrict span processing to the provided `service.name` values. If empty
2044
+ * or undefined, this constraint is ignored.
2045
+ */
2046
+ serviceNames?: string[];
2047
+ }
2029
2048
  /**
2030
2049
  * Unified span format for all observability features
2031
2050
  * Serializable and compatible with OpenTelemetry concepts
@@ -2201,11 +2220,15 @@ declare class VoltAgentObservability {
2201
2220
  private localStorageProcessor?;
2202
2221
  private config;
2203
2222
  private logger;
2223
+ private spanFilterOptions?;
2224
+ private instrumentationScopeName;
2204
2225
  constructor(config?: ObservabilityConfig);
2205
2226
  /**
2206
2227
  * Set up span processors
2207
2228
  */
2208
2229
  private setupProcessors;
2230
+ private applySpanFilter;
2231
+ private resolveSpanFilterOptions;
2209
2232
  /**
2210
2233
  * Try to initialize Pino OpenTelemetry bridge if available
2211
2234
  */
package/dist/index.d.ts CHANGED
@@ -2010,9 +2010,11 @@ interface VoltAgentStreamTextResult<TOOLS extends Record<string, any> = Record<s
2010
2010
  interface ObservabilityConfig {
2011
2011
  serviceName?: string;
2012
2012
  serviceVersion?: string;
2013
+ instrumentationScopeName?: string;
2013
2014
  storage?: ObservabilityStorageAdapter;
2014
2015
  logger?: Logger;
2015
2016
  resourceAttributes?: Record<string, any>;
2017
+ spanFilters?: SpanFilterConfig;
2016
2018
  voltOpsSync?: {
2017
2019
  sampling?: {
2018
2020
  strategy?: "always" | "never" | "ratio" | "parent";
@@ -2026,6 +2028,23 @@ interface ObservabilityConfig {
2026
2028
  spanProcessors?: SpanProcessor[];
2027
2029
  logProcessors?: LogRecordProcessor[];
2028
2030
  }
2031
+ /**
2032
+ * Span filter configuration
2033
+ */
2034
+ interface SpanFilterConfig {
2035
+ enabled?: boolean;
2036
+ /**
2037
+ * Restrict span processing to spans originating from these tracer
2038
+ * instrumentation scope names. Defaults to the internal VoltAgent tracer
2039
+ * when omitted.
2040
+ */
2041
+ instrumentationScopeNames?: string[];
2042
+ /**
2043
+ * Restrict span processing to the provided `service.name` values. If empty
2044
+ * or undefined, this constraint is ignored.
2045
+ */
2046
+ serviceNames?: string[];
2047
+ }
2029
2048
  /**
2030
2049
  * Unified span format for all observability features
2031
2050
  * Serializable and compatible with OpenTelemetry concepts
@@ -2201,11 +2220,15 @@ declare class VoltAgentObservability {
2201
2220
  private localStorageProcessor?;
2202
2221
  private config;
2203
2222
  private logger;
2223
+ private spanFilterOptions?;
2224
+ private instrumentationScopeName;
2204
2225
  constructor(config?: ObservabilityConfig);
2205
2226
  /**
2206
2227
  * Set up span processors
2207
2228
  */
2208
2229
  private setupProcessors;
2230
+ private applySpanFilter;
2231
+ private resolveSpanFilterOptions;
2209
2232
  /**
2210
2233
  * Try to initialize Pino OpenTelemetry bridge if available
2211
2234
  */
package/dist/index.js CHANGED
@@ -2640,7 +2640,7 @@ var import_api_logs3 = require("@opentelemetry/api-logs");
2640
2640
  var import_resources = require("@opentelemetry/resources");
2641
2641
  var import_sdk_logs2 = require("@opentelemetry/sdk-logs");
2642
2642
  var import_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
2643
- var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
2643
+ var import_semantic_conventions2 = require("@opentelemetry/semantic-conventions");
2644
2644
 
2645
2645
  // src/observability/adapters/in-memory-adapter.ts
2646
2646
  var import_internal2 = require("@voltagent/internal");
@@ -3454,6 +3454,69 @@ var SamplingWrapperProcessor = class {
3454
3454
  }
3455
3455
  };
3456
3456
 
3457
+ // src/observability/processors/span-filter-processor.ts
3458
+ var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
3459
+ var SpanFilterProcessor = class {
3460
+ constructor(delegate, options = {}) {
3461
+ this.delegate = delegate;
3462
+ this.options = options;
3463
+ if (options.allowedServiceNames && options.allowedServiceNames.length > 0) {
3464
+ this.allowedServiceNames = new Set(options.allowedServiceNames);
3465
+ }
3466
+ if (options.allowedInstrumentationScopes && options.allowedInstrumentationScopes.length > 0) {
3467
+ this.allowedInstrumentationScopes = new Set(options.allowedInstrumentationScopes);
3468
+ }
3469
+ }
3470
+ static {
3471
+ __name(this, "SpanFilterProcessor");
3472
+ }
3473
+ allowedServiceNames;
3474
+ allowedInstrumentationScopes;
3475
+ onStart(span, parentContext) {
3476
+ if (this.shouldProcess(span)) {
3477
+ this.delegate.onStart(span, parentContext);
3478
+ }
3479
+ }
3480
+ onEnd(span) {
3481
+ if (this.shouldProcess(span)) {
3482
+ this.delegate.onEnd(span);
3483
+ }
3484
+ }
3485
+ async shutdown() {
3486
+ await this.delegate.shutdown();
3487
+ }
3488
+ async forceFlush() {
3489
+ await this.delegate.forceFlush();
3490
+ }
3491
+ shouldProcess(span) {
3492
+ if (this.options.predicate) {
3493
+ return this.options.predicate(span);
3494
+ }
3495
+ if (this.allowedInstrumentationScopes) {
3496
+ const scopeName = this.extractInstrumentationScopeName(span);
3497
+ if (!scopeName || !this.allowedInstrumentationScopes.has(scopeName)) {
3498
+ return false;
3499
+ }
3500
+ }
3501
+ if (!this.allowedServiceNames) {
3502
+ return true;
3503
+ }
3504
+ const serviceName = this.extractServiceName(span);
3505
+ return serviceName !== void 0 && this.allowedServiceNames.has(serviceName);
3506
+ }
3507
+ extractInstrumentationScopeName(span) {
3508
+ const scope = span.instrumentationScope ?? span.instrumentationScope;
3509
+ const value = scope?.name;
3510
+ return typeof value === "string" ? value : void 0;
3511
+ }
3512
+ extractServiceName(span) {
3513
+ const resource = span.resource ?? span.resource;
3514
+ const attributes = resource?.attributes;
3515
+ const value = attributes?.[import_semantic_conventions.ATTR_SERVICE_NAME];
3516
+ return typeof value === "string" ? value : void 0;
3517
+ }
3518
+ };
3519
+
3457
3520
  // src/observability/processors/websocket-span-processor.ts
3458
3521
  var import_node_events3 = require("events");
3459
3522
  var import_api3 = require("@opentelemetry/api");
@@ -3569,9 +3632,29 @@ var VoltAgentObservability = class {
3569
3632
  localStorageProcessor;
3570
3633
  config;
3571
3634
  logger;
3635
+ spanFilterOptions;
3636
+ instrumentationScopeName;
3572
3637
  constructor(config = {}) {
3573
3638
  this.config = config;
3574
3639
  this.logger = getGlobalLogger();
3640
+ this.instrumentationScopeName = config.instrumentationScopeName || "@voltagent/core";
3641
+ this.spanFilterOptions = this.resolveSpanFilterOptions();
3642
+ if (this.spanFilterOptions) {
3643
+ const scopes = this.spanFilterOptions.allowedInstrumentationScopes ?? [];
3644
+ const services = this.spanFilterOptions.allowedServiceNames ?? [];
3645
+ const parts = [];
3646
+ if (scopes.length > 0) {
3647
+ parts.push(`instrumentation scopes [${scopes.join(", ")}]`);
3648
+ }
3649
+ if (services.length > 0) {
3650
+ parts.push(`service.name values [${services.join(", ")}]`);
3651
+ }
3652
+ this.logger.trace(
3653
+ `[VoltAgent] Observability span filtering active for ${parts.join(" and ")}`
3654
+ );
3655
+ } else {
3656
+ this.logger.trace("[VoltAgent] Observability span filtering disabled");
3657
+ }
3575
3658
  this.storage = config.storage || new InMemoryStorageAdapter2({
3576
3659
  maxSpans: 1e4,
3577
3660
  cleanupIntervalMs: 6e4
@@ -3579,8 +3662,8 @@ var VoltAgentObservability = class {
3579
3662
  });
3580
3663
  const resource = (0, import_resources.defaultResource)().merge(
3581
3664
  (0, import_resources.resourceFromAttributes)({
3582
- [import_semantic_conventions.ATTR_SERVICE_NAME]: config.serviceName || "voltagent",
3583
- [import_semantic_conventions.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
3665
+ [import_semantic_conventions2.ATTR_SERVICE_NAME]: config.serviceName || "voltagent",
3666
+ [import_semantic_conventions2.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
3584
3667
  ...config.resourceAttributes
3585
3668
  })
3586
3669
  );
@@ -3590,10 +3673,7 @@ var VoltAgentObservability = class {
3590
3673
  spanProcessors
3591
3674
  });
3592
3675
  this.provider.register();
3593
- this.tracer = import_api4.trace.getTracer(
3594
- config.serviceName || "voltagent",
3595
- config.serviceVersion || "1.0.0"
3596
- );
3676
+ this.tracer = import_api4.trace.getTracer(this.instrumentationScopeName, config.serviceVersion || "1.0.0");
3597
3677
  const logProcessors = this.setupLogProcessors();
3598
3678
  this.loggerProvider = new import_sdk_logs2.LoggerProvider({
3599
3679
  resource,
@@ -3613,9 +3693,9 @@ var VoltAgentObservability = class {
3613
3693
  setupProcessors() {
3614
3694
  const processors = [];
3615
3695
  this.websocketProcessor = new WebSocketSpanProcessor(true);
3616
- processors.push(this.websocketProcessor);
3696
+ processors.push(this.applySpanFilter(this.websocketProcessor));
3617
3697
  this.localStorageProcessor = new LocalStorageSpanProcessor(this.storage);
3618
- processors.push(this.localStorageProcessor);
3698
+ processors.push(this.applySpanFilter(this.localStorageProcessor));
3619
3699
  const samplingStrategy = this.config.voltOpsSync?.sampling?.strategy || "always";
3620
3700
  if (samplingStrategy !== "never") {
3621
3701
  const lazyProcessor = new LazyRemoteExportProcessor({
@@ -3626,7 +3706,7 @@ var VoltAgentObservability = class {
3626
3706
  logger: this.logger
3627
3707
  });
3628
3708
  const finalProcessor = samplingStrategy === "always" ? lazyProcessor : new SamplingWrapperProcessor(lazyProcessor, this.config.voltOpsSync?.sampling);
3629
- processors.push(finalProcessor);
3709
+ processors.push(this.applySpanFilter(finalProcessor));
3630
3710
  this.logger.debug(
3631
3711
  `[VoltAgent] VoltOps sync enabled with ${samplingStrategy} sampling strategy`
3632
3712
  );
@@ -3637,10 +3717,42 @@ var VoltAgentObservability = class {
3637
3717
  }
3638
3718
  }
3639
3719
  if (this.config.spanProcessors) {
3640
- processors.push(...this.config.spanProcessors);
3720
+ processors.push(
3721
+ ...this.config.spanProcessors.map((processor) => this.applySpanFilter(processor))
3722
+ );
3641
3723
  }
3642
3724
  return processors;
3643
3725
  }
3726
+ applySpanFilter(processor) {
3727
+ if (!this.spanFilterOptions) {
3728
+ return processor;
3729
+ }
3730
+ if (processor instanceof SpanFilterProcessor) {
3731
+ return processor;
3732
+ }
3733
+ return new SpanFilterProcessor(processor, this.spanFilterOptions);
3734
+ }
3735
+ resolveSpanFilterOptions() {
3736
+ const filterConfig = this.config.spanFilters;
3737
+ if (filterConfig?.enabled === false) {
3738
+ return void 0;
3739
+ }
3740
+ const instrumentationScopes = filterConfig?.instrumentationScopeNames ?? [
3741
+ this.instrumentationScopeName
3742
+ ];
3743
+ const serviceNames = filterConfig?.serviceNames;
3744
+ const options = {};
3745
+ if (instrumentationScopes && instrumentationScopes.length > 0) {
3746
+ options.allowedInstrumentationScopes = instrumentationScopes;
3747
+ }
3748
+ if (serviceNames && serviceNames.length > 0) {
3749
+ options.allowedServiceNames = serviceNames;
3750
+ }
3751
+ if (!options.allowedInstrumentationScopes && !options.allowedServiceNames) {
3752
+ return void 0;
3753
+ }
3754
+ return options;
3755
+ }
3644
3756
  /**
3645
3757
  * Try to initialize Pino OpenTelemetry bridge if available
3646
3758
  */