@iqai/adk 0.6.4 → 0.6.5

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.mjs CHANGED
@@ -2098,6 +2098,9 @@ import {
2098
2098
  import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
2099
2099
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
2100
2100
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
2101
+ import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
2102
+ import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
2103
+ import { NestInstrumentation } from "@opentelemetry/instrumentation-nestjs-core";
2101
2104
  import {
2102
2105
  detectResources,
2103
2106
  envDetector,
@@ -2112,6 +2115,7 @@ import { NodeSDK } from "@opentelemetry/sdk-node";
2112
2115
  import {
2113
2116
  BatchSpanProcessor,
2114
2117
  NodeTracerProvider,
2118
+ SimpleSpanProcessor,
2115
2119
  TraceIdRatioBasedSampler
2116
2120
  } from "@opentelemetry/sdk-trace-node";
2117
2121
  import {
@@ -2119,6 +2123,124 @@ import {
2119
2123
  ATTR_SERVICE_VERSION
2120
2124
  } from "@opentelemetry/semantic-conventions";
2121
2125
 
2126
+ // src/telemetry/in-memory-exporter.ts
2127
+ import { ExportResultCode } from "@opentelemetry/core";
2128
+ var CustomInMemorySpanExporter = class {
2129
+ spansByTraceId = /* @__PURE__ */ new Map();
2130
+ traceDict = /* @__PURE__ */ new Map();
2131
+ export(spans, resultCallback) {
2132
+ for (const span of spans) {
2133
+ const traceId = span.spanContext().traceId;
2134
+ const existingSpans = this.spansByTraceId.get(traceId);
2135
+ if (existingSpans) {
2136
+ existingSpans.push(span);
2137
+ } else {
2138
+ this.spansByTraceId.set(traceId, [span]);
2139
+ }
2140
+ const sessionId = span.attributes[ADK_ATTRS.SESSION_ID];
2141
+ if (sessionId) {
2142
+ const existingTraces = this.traceDict.get(sessionId);
2143
+ if (existingTraces) {
2144
+ if (!existingTraces.includes(traceId)) {
2145
+ existingTraces.push(traceId);
2146
+ }
2147
+ } else {
2148
+ this.traceDict.set(sessionId, [traceId]);
2149
+ }
2150
+ }
2151
+ }
2152
+ resultCallback({ code: ExportResultCode.SUCCESS });
2153
+ }
2154
+ /**
2155
+ * Get all finished spans
2156
+ */
2157
+ getFinishedSpans() {
2158
+ const allSpans = [];
2159
+ for (const spans of this.spansByTraceId.values()) {
2160
+ allSpans.push(...spans);
2161
+ }
2162
+ return allSpans;
2163
+ }
2164
+ /**
2165
+ * Get spans for a specific session (efficient)
2166
+ */
2167
+ getFinishedSpansForSession(sessionId) {
2168
+ const traceIds = this.traceDict.get(sessionId);
2169
+ if (!traceIds || traceIds.length === 0) {
2170
+ return [];
2171
+ }
2172
+ const result = [];
2173
+ for (const traceId of traceIds) {
2174
+ const spans = this.spansByTraceId.get(traceId);
2175
+ if (spans) {
2176
+ result.push(...spans);
2177
+ }
2178
+ }
2179
+ return result;
2180
+ }
2181
+ /**
2182
+ * Get all session IDs
2183
+ */
2184
+ getSessionIds() {
2185
+ return Array.from(this.traceDict.keys());
2186
+ }
2187
+ /**
2188
+ * Get trace IDs for a specific session
2189
+ */
2190
+ getTraceIdsForSession(sessionId) {
2191
+ return this.traceDict.get(sessionId) || [];
2192
+ }
2193
+ /**
2194
+ * Force flush (no-op)
2195
+ */
2196
+ async forceFlush() {
2197
+ return;
2198
+ }
2199
+ /**
2200
+ * Shutdown exporter
2201
+ */
2202
+ async shutdown() {
2203
+ this.clear();
2204
+ }
2205
+ /**
2206
+ * Clear all stored data
2207
+ */
2208
+ clear() {
2209
+ this.spansByTraceId.clear();
2210
+ this.traceDict.clear();
2211
+ }
2212
+ /**
2213
+ * Get statistics about stored data
2214
+ */
2215
+ getStats() {
2216
+ let totalSpans = 0;
2217
+ for (const spans of this.spansByTraceId.values()) {
2218
+ totalSpans += spans.length;
2219
+ }
2220
+ const sessionStats = Array.from(this.traceDict.entries()).map(
2221
+ ([sessionId, traceIds]) => {
2222
+ let spanCount = 0;
2223
+ for (const traceId of traceIds) {
2224
+ const spans = this.spansByTraceId.get(traceId);
2225
+ if (spans) {
2226
+ spanCount += spans.length;
2227
+ }
2228
+ }
2229
+ return {
2230
+ sessionId,
2231
+ traceCount: traceIds.length,
2232
+ spanCount
2233
+ };
2234
+ }
2235
+ );
2236
+ return {
2237
+ totalSpans,
2238
+ totalSessions: this.traceDict.size,
2239
+ sessionStats
2240
+ };
2241
+ }
2242
+ };
2243
+
2122
2244
  // src/telemetry/utils.ts
2123
2245
  function shouldCaptureContent() {
2124
2246
  const value = process.env[ENV_VARS.CAPTURE_MESSAGE_CONTENT];
@@ -2293,9 +2415,6 @@ function validateConfig(config) {
2293
2415
  if (!config.appName) {
2294
2416
  errors.push("appName is required");
2295
2417
  }
2296
- if (!config.otlpEndpoint) {
2297
- errors.push("otlpEndpoint is required");
2298
- }
2299
2418
  if (config.samplingRatio !== void 0 && (config.samplingRatio < 0 || config.samplingRatio > 1)) {
2300
2419
  errors.push("samplingRatio must be between 0.0 and 1.0");
2301
2420
  }
@@ -2312,6 +2431,7 @@ var SetupService = class {
2312
2431
  tracerProvider = null;
2313
2432
  isInitialized = false;
2314
2433
  config = null;
2434
+ inMemoryExporter = null;
2315
2435
  /**
2316
2436
  * Initialize OpenTelemetry with comprehensive configuration
2317
2437
  */
@@ -2325,6 +2445,7 @@ var SetupService = class {
2325
2445
  throw new Error(`Invalid telemetry configuration: ${errors.join(", ")}`);
2326
2446
  }
2327
2447
  this.config = config;
2448
+ this.inMemoryExporter = new CustomInMemorySpanExporter();
2328
2449
  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
2329
2450
  const resource = this.createResource(config);
2330
2451
  const enableTracing = config.enableTracing ?? DEFAULTS.ENABLE_TRACING;
@@ -2383,16 +2504,23 @@ var SetupService = class {
2383
2504
  * Initialize tracing provider
2384
2505
  */
2385
2506
  initializeTracing(config, resource) {
2386
- const traceExporter = new OTLPTraceExporter({
2387
- url: config.otlpEndpoint,
2388
- headers: config.otlpHeaders
2389
- });
2390
- const spanProcessor = new BatchSpanProcessor(traceExporter);
2507
+ const spanProcessors = [];
2508
+ if (config.otlpEndpoint) {
2509
+ const traceExporter = new OTLPTraceExporter({
2510
+ url: config.otlpEndpoint,
2511
+ headers: config.otlpHeaders
2512
+ });
2513
+ spanProcessors.push(new BatchSpanProcessor(traceExporter));
2514
+ }
2515
+ if (config.debug) {
2516
+ const inMemoryProcessor = new SimpleSpanProcessor(this.inMemoryExporter);
2517
+ spanProcessors.push(inMemoryProcessor);
2518
+ }
2391
2519
  const sampler = config.samplingRatio !== void 0 ? new TraceIdRatioBasedSampler(config.samplingRatio) : void 0;
2392
2520
  this.tracerProvider = new NodeTracerProvider({
2393
2521
  resource,
2394
2522
  sampler,
2395
- spanProcessors: [spanProcessor]
2523
+ spanProcessors
2396
2524
  });
2397
2525
  this.tracerProvider.register();
2398
2526
  diag.debug("Tracing provider initialized");
@@ -2401,6 +2529,10 @@ var SetupService = class {
2401
2529
  * Initialize metrics provider
2402
2530
  */
2403
2531
  initializeMetrics(config, resource) {
2532
+ if (!config.otlpEndpoint) {
2533
+ diag.debug("Skipping metrics initialization: No otlpEndpoint provided");
2534
+ return;
2535
+ }
2404
2536
  const metricsEndpoint = config.otlpEndpoint.replace(
2405
2537
  "/v1/traces",
2406
2538
  "/v1/metrics"
@@ -2431,37 +2563,51 @@ var SetupService = class {
2431
2563
  async initializeAutoInstrumentation(config, resource) {
2432
2564
  const enableTracing = config.enableTracing ?? DEFAULTS.ENABLE_TRACING;
2433
2565
  const enableMetrics = config.enableMetrics ?? DEFAULTS.ENABLE_METRICS;
2434
- const traceExporter = enableTracing ? new OTLPTraceExporter({
2566
+ const traceExporter = enableTracing && config.otlpEndpoint ? new OTLPTraceExporter({
2435
2567
  url: config.otlpEndpoint,
2436
2568
  headers: config.otlpHeaders
2437
2569
  }) : void 0;
2438
- const metricsEndpoint = config.otlpEndpoint.replace(
2439
- "/v1/traces",
2440
- "/v1/metrics"
2441
- );
2442
- const metricReader = enableMetrics ? new PeriodicExportingMetricReader({
2443
- exporter: new OTLPMetricExporter({
2444
- url: metricsEndpoint,
2445
- headers: config.otlpHeaders
2446
- }),
2447
- exportIntervalMillis: config.metricExportIntervalMs ?? DEFAULTS.METRIC_EXPORT_INTERVAL_MS
2448
- }) : void 0;
2570
+ let metricReader;
2571
+ if (enableMetrics && config.otlpEndpoint) {
2572
+ const metricsEndpoint = config.otlpEndpoint.replace(
2573
+ "/v1/traces",
2574
+ "/v1/metrics"
2575
+ );
2576
+ metricReader = new PeriodicExportingMetricReader({
2577
+ exporter: new OTLPMetricExporter({
2578
+ url: metricsEndpoint,
2579
+ headers: config.otlpHeaders
2580
+ }),
2581
+ exportIntervalMillis: config.metricExportIntervalMs ?? DEFAULTS.METRIC_EXPORT_INTERVAL_MS
2582
+ });
2583
+ }
2449
2584
  const sampler = config.samplingRatio !== void 0 ? new TraceIdRatioBasedSampler(config.samplingRatio) : void 0;
2585
+ const spanProcessors = [];
2586
+ if (enableTracing && traceExporter) {
2587
+ spanProcessors.push(new BatchSpanProcessor(traceExporter));
2588
+ }
2589
+ if (config.debug) {
2590
+ spanProcessors.push(new SimpleSpanProcessor(this.inMemoryExporter));
2591
+ }
2450
2592
  this.sdk = new NodeSDK({
2451
2593
  resource,
2452
- traceExporter,
2594
+ spanProcessors: spanProcessors.length > 0 ? spanProcessors : void 0,
2453
2595
  metricReader,
2454
2596
  sampler,
2455
2597
  instrumentations: [
2456
- getNodeAutoInstrumentations({
2457
- // Ignore incoming HTTP requests (we're usually making outgoing calls)
2598
+ new ExpressInstrumentation(),
2599
+ new NestInstrumentation(),
2600
+ new HttpInstrumentation(),
2601
+ // Only enable auto-instrumentations when NOT in debug
2602
+ ...!config.debug ? getNodeAutoInstrumentations({
2458
2603
  "@opentelemetry/instrumentation-http": {
2604
+ // Ignore incoming HTTP requests (we're usually making outgoing calls)
2459
2605
  ignoreIncomingRequestHook: () => true
2460
2606
  }
2461
- })
2607
+ }) : []
2462
2608
  ]
2463
2609
  });
2464
- await this.sdk.start();
2610
+ this.sdk.start();
2465
2611
  diag.debug("Auto-instrumentation initialized with NodeSDK");
2466
2612
  }
2467
2613
  /**
@@ -2536,6 +2682,12 @@ var SetupService = class {
2536
2682
  });
2537
2683
  await Promise.race([Promise.all(flushPromises), timeoutPromise]);
2538
2684
  }
2685
+ getInMemoryExporter() {
2686
+ if (!this.inMemoryExporter) {
2687
+ throw new Error("Telemetry not initialized - call initialize() first");
2688
+ }
2689
+ return this.inMemoryExporter;
2690
+ }
2539
2691
  };
2540
2692
  var setupService = new SetupService();
2541
2693
 
@@ -3267,11 +3419,21 @@ var TelemetryService = class {
3267
3419
  async shutdown(timeoutMs) {
3268
3420
  await setupService.shutdown(timeoutMs);
3269
3421
  }
3422
+ /**
3423
+ * Get traces for a specific session (Debug/Visualization)
3424
+ */
3425
+ getTraces() {
3426
+ return setupService.getInMemoryExporter().getFinishedSpans();
3427
+ }
3428
+ getTracesForSession(sessionId) {
3429
+ return setupService.getInMemoryExporter().getFinishedSpansForSession(sessionId);
3430
+ }
3270
3431
  };
3271
3432
  var telemetryService = new TelemetryService();
3272
3433
  var tracer = telemetryService.getTracer();
3273
3434
  var initializeTelemetry = (config) => telemetryService.initialize(config);
3274
3435
  var shutdownTelemetry = (timeoutMs) => telemetryService.shutdown(timeoutMs);
3436
+ var getTraces = () => telemetryService.getTraces();
3275
3437
  var traceAgentInvocation = (agent, invocationContext, input, output) => telemetryService.traceAgentInvocation(
3276
3438
  agent,
3277
3439
  invocationContext,
@@ -14583,6 +14745,12 @@ var Runner = class {
14583
14745
  newMessage,
14584
14746
  runConfig
14585
14747
  });
14748
+ span.setAttribute(ADK_ATTRS.SESSION_ID, session.id);
14749
+ span.setAttribute(ADK_ATTRS.USER_ID, userId);
14750
+ span.setAttribute(
14751
+ ADK_ATTRS.INVOCATION_ID,
14752
+ invocationContext.invocationId
14753
+ );
14586
14754
  if (newMessage) {
14587
14755
  await context3.with(
14588
14756
  spanContext,
@@ -19672,6 +19840,7 @@ export {
19672
19840
  getEnvironment,
19673
19841
  getLongRunningFunctionCalls,
19674
19842
  getMcpTools,
19843
+ getTraces,
19675
19844
  handleFunctionCallsAsync,
19676
19845
  handleFunctionCallsLive,
19677
19846
  requestProcessor7 as identityRequestProcessor,
package/package.json CHANGED
@@ -1,9 +1,31 @@
1
1
  {
2
2
  "name": "@iqai/adk",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Agent Development Kit for TypeScript with multi-provider LLM support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": {
10
+ "types": "./dist/index.d.mts",
11
+ "default": "./dist/index.mjs"
12
+ },
13
+ "require": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "./constants": {
19
+ "import": {
20
+ "types": "./dist/constants.d.mts",
21
+ "default": "./dist/constants.mjs"
22
+ },
23
+ "require": {
24
+ "types": "./dist/constants.d.ts",
25
+ "default": "./dist/constants.js"
26
+ }
27
+ }
28
+ },
7
29
  "bin": {
8
30
  "adk": "./dist/cli/index.js"
9
31
  },
@@ -32,8 +54,11 @@
32
54
  "@modelcontextprotocol/sdk": "1.25.1",
33
55
  "@opentelemetry/api": "^1.9.0",
34
56
  "@opentelemetry/auto-instrumentations-node": "^0.67.3",
57
+ "@opentelemetry/core": "^2.3.0",
35
58
  "@opentelemetry/exporter-metrics-otlp-http": "^0.208.0",
36
59
  "@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
60
+ "@opentelemetry/instrumentation": "^0.209.0",
61
+ "@opentelemetry/instrumentation-openai": "^0.7.1",
37
62
  "@opentelemetry/resources": "^2.2.0",
38
63
  "@opentelemetry/sdk-metrics": "^2.2.0",
39
64
  "@opentelemetry/sdk-node": "^0.208.0",
@@ -58,12 +83,24 @@
58
83
  "zod": "^4.1.5"
59
84
  },
60
85
  "peerDependencies": {
86
+ "@opentelemetry/instrumentation-express": "^0.58.0",
87
+ "@opentelemetry/instrumentation-http": "^0.210.0",
88
+ "@opentelemetry/instrumentation-nestjs-core": "^0.55.0",
61
89
  "better-sqlite3": "^11.10.0",
62
90
  "langfuse": "^3.38.6",
63
91
  "mysql2": "^3.14.1",
64
92
  "pg": "^8.16.0"
65
93
  },
66
94
  "peerDependenciesMeta": {
95
+ "@opentelemetry/instrumentation-express": {
96
+ "optional": true
97
+ },
98
+ "@opentelemetry/instrumentation-http": {
99
+ "optional": true
100
+ },
101
+ "@opentelemetry/instrumentation-nestjs-core": {
102
+ "optional": true
103
+ },
67
104
  "better-sqlite3": {
68
105
  "optional": true
69
106
  },