risicare 0.1.0 → 0.1.2

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.ts CHANGED
@@ -31,6 +31,8 @@ interface RisicareConfig {
31
31
  maxQueueSize?: number;
32
32
  /** Enable debug logging (default: false) */
33
33
  debug?: boolean;
34
+ /** Enable gzip compression for HTTP exports (default: false) */
35
+ compress?: boolean;
34
36
  /** Custom metadata attached to all spans */
35
37
  metadata?: Record<string, unknown>;
36
38
  }
@@ -69,7 +71,10 @@ declare enum SemanticPhase {
69
71
  THINK = "think",
70
72
  DECIDE = "decide",
71
73
  ACT = "act",
72
- OBSERVE = "observe"
74
+ OBSERVE = "observe",
75
+ REFLECT = "reflect",
76
+ COMMUNICATE = "communicate",
77
+ COORDINATE = "coordinate"
73
78
  }
74
79
  declare enum AgentRole {
75
80
  ORCHESTRATOR = "orchestrator",
@@ -241,14 +246,18 @@ interface TracerConfig {
241
246
  sampleRate?: number;
242
247
  /** Whether tracing is enabled */
243
248
  enabled?: boolean;
249
+ /** Whether to capture prompt/completion content (default: true) */
250
+ traceContent?: boolean;
244
251
  }
245
252
  declare class Tracer {
246
253
  private _onSpanEnd;
247
254
  private _sampleRate;
248
255
  private _enabled;
256
+ private _traceContent;
249
257
  constructor(config: TracerConfig);
250
258
  get enabled(): boolean;
251
259
  set enabled(value: boolean);
260
+ get traceContent(): boolean;
252
261
  /**
253
262
  * Start a span, run the callback within its context, and auto-end on completion.
254
263
  *
@@ -316,6 +325,22 @@ declare function isEnabled(): boolean;
316
325
  * Get the global tracer instance. Returns undefined if not initialized.
317
326
  */
318
327
  declare function getTracer(): Tracer | undefined;
328
+ /**
329
+ * Check whether content tracing (prompt/completion capture) is enabled.
330
+ */
331
+ declare function getTraceContent(): boolean;
332
+ /**
333
+ * Get SDK metrics: exported spans, dropped spans, failed exports, queue stats.
334
+ * Returns zero-valued metrics if SDK is not initialized.
335
+ */
336
+ declare function getMetrics(): {
337
+ exportedSpans: number;
338
+ droppedSpans: number;
339
+ failedExports: number;
340
+ queueSize: number;
341
+ queueCapacity: number;
342
+ queueUtilization: number;
343
+ };
319
344
 
320
345
  /**
321
346
  * Agent context — identifies which agent is executing.
@@ -561,4 +586,4 @@ declare function registerSpan(span: Span, ttlMs?: number): void;
561
586
  declare function getSpanById(spanId: string): Span | undefined;
562
587
  declare function unregisterSpan(spanId: string): void;
563
588
 
564
- export { type AgentContext, type AgentOptions, AgentRole, MessageType, type RisicareConfig, SemanticPhase, type SessionContext, type SessionOptions, Span, SpanKind, type SpanOptions, SpanStatus, type StartSpanOptions, type TraceContext, Tracer, agent, disable, enable, extractTraceContext, flush, getCurrentAgent, getCurrentAgentId, getCurrentContext, getCurrentPhase, getCurrentSession, getCurrentSessionId, getCurrentSpan, getCurrentSpanId, getCurrentTraceId, getSpanById, getTraceContext, getTracer, init, injectTraceContext, isEnabled, registerSpan, session, shutdown, traceAct, traceCoordinate, traceDecide, traceDelegate, traceMessage, traceObserve, traceThink, unregisterSpan, withAgent, withPhase, withSession };
589
+ export { type AgentContext, type AgentOptions, AgentRole, MessageType, type RisicareConfig, SemanticPhase, type SessionContext, type SessionOptions, Span, SpanKind, type SpanOptions, SpanStatus, type StartSpanOptions, type TraceContext, Tracer, agent, disable, enable, extractTraceContext, flush, getCurrentAgent, getCurrentAgentId, getCurrentContext, getCurrentPhase, getCurrentSession, getCurrentSessionId, getCurrentSpan, getCurrentSpanId, getCurrentTraceId, getMetrics, getSpanById, getTraceContent, getTraceContext, getTracer, init, injectTraceContext, isEnabled, registerSpan, session, shutdown, traceAct, traceCoordinate, traceDecide, traceDelegate, traceMessage, traceObserve, traceThink, unregisterSpan, withAgent, withPhase, withSession };
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ function resolveConfig(config) {
11
11
  const traceContent = config?.traceContent ?? parseBool(env.RISICARE_TRACE_CONTENT, true);
12
12
  const sampleRate = config?.sampleRate ?? parseFloat(env.RISICARE_SAMPLE_RATE ?? "1.0");
13
13
  const debug2 = config?.debug ?? parseBool(env.RISICARE_DEBUG, false);
14
+ const compress = config?.compress ?? parseBool(env.RISICARE_COMPRESS, false);
14
15
  const batchSize = config?.batchSize ?? 100;
15
16
  const batchTimeoutMs = config?.batchTimeoutMs ?? 1e3;
16
17
  const maxQueueSize = config?.maxQueueSize ?? 1e4;
@@ -36,6 +37,7 @@ function resolveConfig(config) {
36
37
  batchTimeoutMs,
37
38
  maxQueueSize,
38
39
  debug: debug2,
40
+ compress,
39
41
  metadata: config?.metadata ?? {}
40
42
  };
41
43
  }
@@ -56,7 +58,7 @@ function generateSpanId() {
56
58
  return randomBytes(8).toString("hex");
57
59
  }
58
60
  function generateAgentId(prefix) {
59
- const suffix = randomBytes(6).toString("hex");
61
+ const suffix = randomBytes(8).toString("hex");
60
62
  return prefix ? `${prefix}-${suffix}` : suffix;
61
63
  }
62
64
  function validateTraceId(id) {
@@ -98,6 +100,9 @@ var SemanticPhase = /* @__PURE__ */ ((SemanticPhase2) => {
98
100
  SemanticPhase2["DECIDE"] = "decide";
99
101
  SemanticPhase2["ACT"] = "act";
100
102
  SemanticPhase2["OBSERVE"] = "observe";
103
+ SemanticPhase2["REFLECT"] = "reflect";
104
+ SemanticPhase2["COMMUNICATE"] = "communicate";
105
+ SemanticPhase2["COORDINATE"] = "coordinate";
101
106
  return SemanticPhase2;
102
107
  })(SemanticPhase || {});
103
108
  var AgentRole = /* @__PURE__ */ ((AgentRole2) => {
@@ -373,16 +378,58 @@ function shouldSample(traceId, sampleRate) {
373
378
  return hash / 4294967295 < sampleRate;
374
379
  }
375
380
 
376
- // src/context/storage.ts
381
+ // src/globals.ts
377
382
  import { AsyncLocalStorage } from "async_hooks";
378
- var contextStorage = new AsyncLocalStorage();
383
+ var G = globalThis;
384
+ var PREFIX = "__risicare_";
385
+ function getClient() {
386
+ return G[PREFIX + "client"];
387
+ }
388
+ function setClient(client) {
389
+ G[PREFIX + "client"] = client;
390
+ }
391
+ function getTracer() {
392
+ return G[PREFIX + "tracer"];
393
+ }
394
+ function setTracer(tracer) {
395
+ G[PREFIX + "tracer"] = tracer;
396
+ }
397
+ function getContextStorage() {
398
+ if (!G[PREFIX + "ctx"]) {
399
+ G[PREFIX + "ctx"] = new AsyncLocalStorage();
400
+ }
401
+ return G[PREFIX + "ctx"];
402
+ }
403
+ function getRegistry() {
404
+ if (!G[PREFIX + "registry"]) {
405
+ G[PREFIX + "registry"] = /* @__PURE__ */ new Map();
406
+ }
407
+ return G[PREFIX + "registry"];
408
+ }
409
+ function getOpCount() {
410
+ return G[PREFIX + "opcount"] ?? 0;
411
+ }
412
+ function setOpCount(n) {
413
+ G[PREFIX + "opcount"] = n;
414
+ }
415
+ function getDebug() {
416
+ return G[PREFIX + "debug"] ?? false;
417
+ }
418
+ function setDebugFlag(enabled) {
419
+ G[PREFIX + "debug"] = enabled;
420
+ }
421
+
422
+ // src/context/storage.ts
423
+ function storage() {
424
+ return getContextStorage();
425
+ }
379
426
  function getContext() {
380
- return contextStorage.getStore() ?? {};
427
+ return storage().getStore() ?? {};
381
428
  }
382
429
  function runWithContext(overrides, fn) {
383
430
  const parent = getContext();
384
431
  const merged = { ...parent, ...overrides };
385
- return contextStorage.run(merged, fn);
432
+ return storage().run(merged, fn);
386
433
  }
387
434
  function getCurrentSession() {
388
435
  return getContext().session;
@@ -411,8 +458,22 @@ function getCurrentSpanId() {
411
458
  function getCurrentContext() {
412
459
  const ctx = getContext();
413
460
  return {
414
- session: ctx.session ? { sessionId: ctx.session.sessionId, userId: ctx.session.userId } : null,
415
- agent: ctx.agent ? { agentId: ctx.agent.agentId, agentName: ctx.agent.agentName, agentRole: ctx.agent.agentRole } : null,
461
+ session: ctx.session ? {
462
+ sessionId: ctx.session.sessionId,
463
+ userId: ctx.session.userId,
464
+ ...ctx.session.parentSessionId !== void 0 ? { parentSessionId: ctx.session.parentSessionId } : {},
465
+ ...ctx.session.turnNumber !== void 0 ? { turnNumber: ctx.session.turnNumber } : {},
466
+ ...ctx.session.metadata !== void 0 ? { metadata: ctx.session.metadata } : {}
467
+ } : null,
468
+ agent: ctx.agent ? {
469
+ agentId: ctx.agent.agentId,
470
+ agentName: ctx.agent.agentName,
471
+ agentRole: ctx.agent.agentRole,
472
+ agentType: ctx.agent.agentType,
473
+ ...ctx.agent.parentAgentId !== void 0 ? { parentAgentId: ctx.agent.parentAgentId } : {},
474
+ ...ctx.agent.version !== void 0 ? { version: ctx.agent.version } : {},
475
+ ...ctx.agent.metadata !== void 0 ? { metadata: ctx.agent.metadata } : {}
476
+ } : null,
416
477
  span: ctx.span ? { spanId: ctx.span.spanId, traceId: ctx.span.traceId } : null,
417
478
  phase: ctx.phase ?? null
418
479
  };
@@ -423,10 +484,12 @@ var Tracer = class {
423
484
  _onSpanEnd;
424
485
  _sampleRate;
425
486
  _enabled;
487
+ _traceContent;
426
488
  constructor(config) {
427
489
  this._onSpanEnd = config.onSpanEnd;
428
490
  this._sampleRate = config.sampleRate ?? 1;
429
491
  this._enabled = config.enabled ?? true;
492
+ this._traceContent = config.traceContent ?? true;
430
493
  }
431
494
  get enabled() {
432
495
  return this._enabled;
@@ -434,6 +497,9 @@ var Tracer = class {
434
497
  set enabled(value) {
435
498
  this._enabled = value;
436
499
  }
500
+ get traceContent() {
501
+ return this._traceContent;
502
+ }
437
503
  /**
438
504
  * Start a span, run the callback within its context, and auto-end on completion.
439
505
  *
@@ -467,7 +533,13 @@ var Tracer = class {
467
533
  kind: opts.kind ?? "internal" /* INTERNAL */,
468
534
  traceId,
469
535
  parentSpanId,
470
- attributes: opts.attributes,
536
+ attributes: {
537
+ ...opts.attributes,
538
+ // Propagate context fields as attributes (matching Python SDK tracer.py:497-511)
539
+ ...agent2?.agentRole ? { "agent.role": agent2.agentRole } : {},
540
+ ...agent2?.parentAgentId ? { "parent_agent_id": agent2.parentAgentId } : {},
541
+ ...session2?.userId ? { "session.user_id": session2.userId } : {}
542
+ },
471
543
  sessionId: session2?.sessionId,
472
544
  agentId: agent2?.agentId,
473
545
  agentName: agent2?.agentName,
@@ -526,7 +598,13 @@ var Tracer = class {
526
598
  kind: opts.kind ?? "internal" /* INTERNAL */,
527
599
  traceId,
528
600
  parentSpanId,
529
- attributes: opts.attributes,
601
+ attributes: {
602
+ ...opts.attributes,
603
+ // Propagate context fields as attributes (matching Python SDK tracer.py:497-511)
604
+ ...agent2?.agentRole ? { "agent.role": agent2.agentRole } : {},
605
+ ...agent2?.parentAgentId ? { "parent_agent_id": agent2.parentAgentId } : {},
606
+ ...session2?.userId ? { "session.user_id": session2.userId } : {}
607
+ },
530
608
  sessionId: session2?.sessionId,
531
609
  agentId: agent2?.agentId,
532
610
  agentName: agent2?.agentName,
@@ -539,12 +617,11 @@ var Tracer = class {
539
617
  };
540
618
 
541
619
  // src/utils/log.ts
542
- var _debug = false;
543
620
  function setDebug(enabled) {
544
- _debug = enabled;
621
+ setDebugFlag(enabled);
545
622
  }
546
623
  function debug(msg) {
547
- if (_debug) {
624
+ if (getDebug()) {
548
625
  process.stderr.write(`[risicare] ${msg}
549
626
  `);
550
627
  }
@@ -555,7 +632,7 @@ function warn(msg) {
555
632
  }
556
633
 
557
634
  // src/exporters/batch.ts
558
- var BatchSpanProcessor = class {
635
+ var BatchSpanProcessor = class _BatchSpanProcessor {
559
636
  _exporters;
560
637
  _batchSize;
561
638
  _batchTimeoutMs;
@@ -565,6 +642,10 @@ var BatchSpanProcessor = class {
565
642
  _timer = null;
566
643
  _started = false;
567
644
  _flushing = false;
645
+ _beforeExitHandler = null;
646
+ // Retry tracking for failed batches (Audit #5)
647
+ _retryCounts = /* @__PURE__ */ new Map();
648
+ static MAX_RETRIES = 3;
568
649
  // Metrics
569
650
  droppedSpans = 0;
570
651
  exportedSpans = 0;
@@ -583,9 +664,10 @@ var BatchSpanProcessor = class {
583
664
  void this._exportBatch();
584
665
  }, this._batchTimeoutMs);
585
666
  this._timer.unref();
586
- process.on("beforeExit", () => {
667
+ this._beforeExitHandler = () => {
587
668
  void this.shutdown();
588
- });
669
+ };
670
+ process.once("beforeExit", this._beforeExitHandler);
589
671
  }
590
672
  async shutdown(timeoutMs = 5e3) {
591
673
  if (!this._started) return;
@@ -594,6 +676,10 @@ var BatchSpanProcessor = class {
594
676
  clearInterval(this._timer);
595
677
  this._timer = null;
596
678
  }
679
+ if (this._beforeExitHandler) {
680
+ process.removeListener("beforeExit", this._beforeExitHandler);
681
+ this._beforeExitHandler = null;
682
+ }
597
683
  const flushPromise = this._exportBatch();
598
684
  const timeoutPromise = new Promise((resolve) => setTimeout(resolve, timeoutMs));
599
685
  await Promise.race([flushPromise, timeoutPromise]);
@@ -604,6 +690,7 @@ var BatchSpanProcessor = class {
604
690
  debug(`Error shutting down ${exporter.name}: ${e}`);
605
691
  }
606
692
  }
693
+ this._retryCounts.clear();
607
694
  debug(
608
695
  `BatchSpanProcessor shutdown. Exported: ${this.exportedSpans}, Dropped: ${this.droppedSpans}, Failed: ${this.failedExports}`
609
696
  );
@@ -660,6 +747,9 @@ var BatchSpanProcessor = class {
660
747
  if (!batchExported) {
661
748
  this.exportedSpans += batch.length;
662
749
  batchExported = true;
750
+ for (const span of batch) {
751
+ this._retryCounts.delete(span.spanId);
752
+ }
663
753
  }
664
754
  } else {
665
755
  this.failedExports++;
@@ -669,6 +759,22 @@ var BatchSpanProcessor = class {
669
759
  debug(`Export to ${exporter.name} failed: ${e}`);
670
760
  }
671
761
  }
762
+ if (!batchExported) {
763
+ const retryable = batch.filter((span) => {
764
+ const count = (this._retryCounts.get(span.spanId) ?? 0) + 1;
765
+ if (count > _BatchSpanProcessor.MAX_RETRIES) {
766
+ this._retryCounts.delete(span.spanId);
767
+ this.droppedSpans++;
768
+ return false;
769
+ }
770
+ this._retryCounts.set(span.spanId, count);
771
+ return true;
772
+ });
773
+ if (retryable.length > 0) {
774
+ this._queue.unshift(...retryable);
775
+ debug(`Re-queued ${retryable.length} spans for retry (${batch.length - retryable.length} dropped after max retries)`);
776
+ }
777
+ }
672
778
  } finally {
673
779
  this._flushing = false;
674
780
  }
@@ -676,6 +782,7 @@ var BatchSpanProcessor = class {
676
782
  };
677
783
 
678
784
  // src/exporters/http.ts
785
+ var SDK_VERSION = "0.1.1";
679
786
  var HttpExporter = class {
680
787
  name = "http";
681
788
  _endpoint;
@@ -702,23 +809,26 @@ var HttpExporter = class {
702
809
  async export(spans) {
703
810
  if (spans.length === 0) return "success" /* SUCCESS */;
704
811
  const now = Date.now();
812
+ let isHalfOpen = false;
705
813
  if (this._consecutiveFailures >= this._circuitBreakerThreshold) {
706
814
  if (now < this._circuitOpenUntil) {
707
815
  return "failure" /* FAILURE */;
708
816
  }
817
+ isHalfOpen = true;
709
818
  }
710
819
  const body = {
711
820
  spans: spans.map((s) => s.toPayload())
712
821
  };
713
822
  if (this._projectId) body.projectId = this._projectId;
714
823
  if (this._environment) body.environment = this._environment;
715
- for (let attempt = 0; attempt < this._maxRetries; attempt++) {
824
+ const maxAttempts = isHalfOpen ? 1 : this._maxRetries;
825
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
716
826
  const result = await this._sendRequest(body);
717
827
  if (result === "success" /* SUCCESS */) {
718
828
  this._consecutiveFailures = 0;
719
829
  return result;
720
830
  }
721
- if (attempt < this._maxRetries - 1) {
831
+ if (attempt < maxAttempts - 1) {
722
832
  await sleep(100 * Math.pow(2, attempt));
723
833
  }
724
834
  }
@@ -734,7 +844,8 @@ var HttpExporter = class {
734
844
  async _sendRequest(body) {
735
845
  const url = `${this._endpoint}/v1/spans`;
736
846
  const headers = {
737
- "Content-Type": "application/json"
847
+ "Content-Type": "application/json",
848
+ "User-Agent": `risicare-js/${SDK_VERSION} node/${process.version}`
738
849
  };
739
850
  if (this._apiKey) {
740
851
  headers["Authorization"] = `Bearer ${this._apiKey}`;
@@ -745,7 +856,8 @@ var HttpExporter = class {
745
856
  const { gzipSync } = await import("zlib");
746
857
  payload = gzipSync(Buffer.from(payload));
747
858
  headers["Content-Encoding"] = "gzip";
748
- } catch {
859
+ } catch (e) {
860
+ debug(`Gzip compression failed, sending uncompressed: ${e}`);
749
861
  }
750
862
  }
751
863
  try {
@@ -795,15 +907,17 @@ var ConsoleExporter = class {
795
907
  };
796
908
 
797
909
  // src/client.ts
798
- var _client;
799
- var _tracer;
800
910
  var RisicareClient = class {
801
911
  config;
802
912
  processor;
803
913
  tracer;
804
- _shutdownCalled = false;
914
+ _shutdownPromise;
915
+ _shutdownHandlers = [];
805
916
  constructor(config) {
806
917
  this.config = resolveConfig(config);
918
+ if (this.config.apiKey && !this.config.apiKey.startsWith("rsk-")) {
919
+ debug('Warning: API key should start with "rsk-". Got: ' + this.config.apiKey.slice(0, 4) + "...");
920
+ }
807
921
  let exporter;
808
922
  if (this.config.debug && !this.config.apiKey) {
809
923
  exporter = new ConsoleExporter();
@@ -812,7 +926,8 @@ var RisicareClient = class {
812
926
  endpoint: this.config.endpoint,
813
927
  apiKey: this.config.apiKey,
814
928
  projectId: this.config.projectId || void 0,
815
- environment: this.config.environment || void 0
929
+ environment: this.config.environment || void 0,
930
+ compress: this.config.compress
816
931
  });
817
932
  } else {
818
933
  exporter = new ConsoleExporter();
@@ -827,7 +942,8 @@ var RisicareClient = class {
827
942
  this.tracer = new Tracer({
828
943
  onSpanEnd: (span) => this.processor.onSpanEnd(span),
829
944
  sampleRate: this.config.sampleRate,
830
- enabled: this.config.enabled
945
+ enabled: this.config.enabled,
946
+ traceContent: this.config.traceContent
831
947
  });
832
948
  this.processor.start();
833
949
  this._registerShutdownHooks();
@@ -840,10 +956,18 @@ var RisicareClient = class {
840
956
  set enabled(value) {
841
957
  this.tracer.enabled = value;
842
958
  }
959
+ // Audit #6: Promise-based shutdown dedup (fixes TOCTOU race condition)
843
960
  async shutdown() {
844
- if (this._shutdownCalled) return;
845
- this._shutdownCalled = true;
961
+ if (this._shutdownPromise) return this._shutdownPromise;
962
+ this._shutdownPromise = this._doShutdown();
963
+ return this._shutdownPromise;
964
+ }
965
+ async _doShutdown() {
846
966
  debug("Shutting down...");
967
+ for (const { signal, handler } of this._shutdownHandlers) {
968
+ process.removeListener(signal, handler);
969
+ }
970
+ this._shutdownHandlers = [];
847
971
  await this.processor.shutdown();
848
972
  }
849
973
  async flush() {
@@ -851,43 +975,68 @@ var RisicareClient = class {
851
975
  }
852
976
  _registerShutdownHooks() {
853
977
  const onShutdown = () => {
978
+ const timeout = setTimeout(() => process.exit(1), 5e3);
979
+ timeout.unref();
854
980
  this.shutdown().catch(() => {
855
- });
981
+ }).finally(() => clearTimeout(timeout));
856
982
  };
857
- process.once("beforeExit", onShutdown);
858
- process.once("SIGTERM", onShutdown);
859
- process.once("SIGINT", onShutdown);
983
+ const signals = ["beforeExit", "SIGTERM", "SIGINT"];
984
+ for (const signal of signals) {
985
+ process.once(signal, onShutdown);
986
+ this._shutdownHandlers.push({ signal, handler: onShutdown });
987
+ }
860
988
  }
861
989
  };
862
990
  function init(config) {
863
- if (_client) {
991
+ if (getClient()) {
864
992
  debug("Already initialized. Call shutdown() first to re-initialize.");
865
993
  return;
866
994
  }
867
- _client = new RisicareClient(config);
868
- _tracer = _client.tracer;
995
+ const client = new RisicareClient(config);
996
+ setClient(client);
997
+ setTracer(client.tracer);
869
998
  }
870
999
  async function shutdown() {
871
- if (!_client) return;
872
- await _client.shutdown();
873
- _client = void 0;
874
- _tracer = void 0;
1000
+ const client = getClient();
1001
+ if (!client) return;
1002
+ await client.shutdown();
1003
+ setClient(void 0);
1004
+ setTracer(void 0);
875
1005
  }
876
1006
  async function flush() {
877
- if (!_client) return;
878
- await _client.flush();
1007
+ const client = getClient();
1008
+ if (!client) return;
1009
+ await client.flush();
879
1010
  }
880
1011
  function enable() {
881
- if (_client) _client.enabled = true;
1012
+ const client = getClient();
1013
+ if (client) client.enabled = true;
882
1014
  }
883
1015
  function disable() {
884
- if (_client) _client.enabled = false;
1016
+ const client = getClient();
1017
+ if (client) client.enabled = false;
885
1018
  }
886
1019
  function isEnabled() {
887
- return _client?.enabled ?? false;
1020
+ const client = getClient();
1021
+ return client?.enabled ?? false;
888
1022
  }
889
- function getTracer() {
890
- return _tracer;
1023
+ function getTracer2() {
1024
+ return getTracer();
1025
+ }
1026
+ function getTraceContent() {
1027
+ const tracer = getTracer();
1028
+ return tracer?.traceContent ?? true;
1029
+ }
1030
+ function getMetrics() {
1031
+ const client = getClient();
1032
+ return client?.processor.getMetrics() ?? {
1033
+ exportedSpans: 0,
1034
+ droppedSpans: 0,
1035
+ failedExports: 0,
1036
+ queueSize: 0,
1037
+ queueCapacity: 0,
1038
+ queueUtilization: 0
1039
+ };
891
1040
  }
892
1041
 
893
1042
  // src/context/agent.ts
@@ -911,7 +1060,7 @@ function withAgent(options, fn) {
911
1060
  function agent(options, fn) {
912
1061
  const spanName = `agent:${options.name ?? "agent"}`;
913
1062
  return (...args) => {
914
- const tracer = getTracer();
1063
+ const tracer = getTracer2();
915
1064
  if (!tracer) {
916
1065
  return fn(...args);
917
1066
  }
@@ -951,28 +1100,28 @@ function withPhase(phase, fn) {
951
1100
  }
952
1101
 
953
1102
  // src/decorators/phase.ts
954
- function phaseWrapper(phase, fn) {
1103
+ function phaseWrapper(phase, kind, fn) {
955
1104
  return (...args) => {
956
- const tracer = getTracer();
1105
+ const tracer = getTracer2();
957
1106
  if (!tracer) {
958
1107
  return fn(...args);
959
1108
  }
960
1109
  return withPhase(phase, () => {
961
- return tracer.startSpan({ name: `phase:${phase}` }, () => fn(...args));
1110
+ return tracer.startSpan({ name: `phase:${phase}`, kind }, () => fn(...args));
962
1111
  });
963
1112
  };
964
1113
  }
965
1114
  function traceThink(fn) {
966
- return phaseWrapper("think" /* THINK */, fn);
1115
+ return phaseWrapper("think" /* THINK */, "think" /* THINK */, fn);
967
1116
  }
968
1117
  function traceDecide(fn) {
969
- return phaseWrapper("decide" /* DECIDE */, fn);
1118
+ return phaseWrapper("decide" /* DECIDE */, "decide" /* DECIDE */, fn);
970
1119
  }
971
1120
  function traceAct(fn) {
972
- return phaseWrapper("act" /* ACT */, fn);
1121
+ return phaseWrapper("act" /* ACT */, "tool_call" /* TOOL_CALL */, fn);
973
1122
  }
974
1123
  function traceObserve(fn) {
975
- return phaseWrapper("observe" /* OBSERVE */, fn);
1124
+ return phaseWrapper("observe" /* OBSERVE */, "observe" /* OBSERVE */, fn);
976
1125
  }
977
1126
 
978
1127
  // src/decorators/multi-agent.ts
@@ -987,7 +1136,7 @@ function namespacedMetadata(metadata) {
987
1136
  function traceMessage(options, fn) {
988
1137
  const msgType = options.type ?? "request" /* REQUEST */;
989
1138
  return (...args) => {
990
- const tracer = getTracer();
1139
+ const tracer = getTracer2();
991
1140
  if (!tracer) return fn(...args);
992
1141
  return tracer.startSpan(
993
1142
  {
@@ -1006,7 +1155,7 @@ function traceMessage(options, fn) {
1006
1155
  }
1007
1156
  function traceDelegate(options, fn) {
1008
1157
  return (...args) => {
1009
- const tracer = getTracer();
1158
+ const tracer = getTracer2();
1010
1159
  if (!tracer) return fn(...args);
1011
1160
  return tracer.startSpan(
1012
1161
  {
@@ -1025,7 +1174,7 @@ function traceDelegate(options, fn) {
1025
1174
  }
1026
1175
  function traceCoordinate(options, fn) {
1027
1176
  return (...args) => {
1028
- const tracer = getTracer();
1177
+ const tracer = getTracer2();
1029
1178
  if (!tracer) return fn(...args);
1030
1179
  return tracer.startSpan(
1031
1180
  {
@@ -1103,7 +1252,10 @@ function extractTraceContext(headers) {
1103
1252
  if (eqIdx > 0) {
1104
1253
  const key = kv.slice(0, eqIdx).trim();
1105
1254
  const value = kv.slice(eqIdx + 1).trim();
1106
- if (key && value) result[key] = value;
1255
+ if (key && value) {
1256
+ const camelKey = key === "session_id" ? "sessionId" : key === "agent_id" ? "agentId" : key;
1257
+ result[camelKey] = value;
1258
+ }
1107
1259
  }
1108
1260
  }
1109
1261
  }
@@ -1116,36 +1268,37 @@ function extractTraceContext(headers) {
1116
1268
  var DEFAULT_TTL_MS = 6e4;
1117
1269
  var MAX_ENTRIES = 1e4;
1118
1270
  var CLEANUP_INTERVAL = 100;
1119
- var entries = /* @__PURE__ */ new Map();
1120
- var operationCount = 0;
1271
+ function entries() {
1272
+ return getRegistry();
1273
+ }
1121
1274
  function registerSpan(span, ttlMs = DEFAULT_TTL_MS) {
1122
- entries.set(span.spanId, {
1275
+ entries().set(span.spanId, {
1123
1276
  span,
1124
1277
  registeredAt: Date.now(),
1125
1278
  ttlMs
1126
1279
  });
1127
- operationCount++;
1280
+ setOpCount(getOpCount() + 1);
1128
1281
  maybeCleanup();
1129
1282
  }
1130
1283
  function getSpanById(spanId) {
1131
- const entry = entries.get(spanId);
1284
+ const entry = entries().get(spanId);
1132
1285
  if (!entry) return void 0;
1133
1286
  if (Date.now() - entry.registeredAt > entry.ttlMs) {
1134
- entries.delete(spanId);
1287
+ entries().delete(spanId);
1135
1288
  return void 0;
1136
1289
  }
1137
1290
  return entry.span;
1138
1291
  }
1139
1292
  function unregisterSpan(spanId) {
1140
- entries.delete(spanId);
1293
+ entries().delete(spanId);
1141
1294
  }
1142
1295
  function maybeCleanup() {
1143
- if (operationCount % CLEANUP_INTERVAL !== 0) return;
1144
- if (entries.size <= MAX_ENTRIES) return;
1296
+ if (getOpCount() % CLEANUP_INTERVAL !== 0) return;
1297
+ if (entries().size <= MAX_ENTRIES) return;
1145
1298
  const now = Date.now();
1146
- for (const [id, entry] of entries) {
1299
+ for (const [id, entry] of entries()) {
1147
1300
  if (now - entry.registeredAt > entry.ttlMs) {
1148
- entries.delete(id);
1301
+ entries().delete(id);
1149
1302
  }
1150
1303
  }
1151
1304
  }
@@ -1169,9 +1322,11 @@ export {
1169
1322
  getCurrentSpan,
1170
1323
  getCurrentSpanId,
1171
1324
  getCurrentTraceId,
1325
+ getMetrics,
1172
1326
  getSpanById,
1327
+ getTraceContent,
1173
1328
  getTraceContext,
1174
- getTracer,
1329
+ getTracer2 as getTracer,
1175
1330
  init,
1176
1331
  injectTraceContext,
1177
1332
  isEnabled,