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.cjs +225 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +223 -68
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic/index.cjs +23 -7
- package/dist/providers/anthropic/index.cjs.map +1 -1
- package/dist/providers/anthropic/index.js +23 -7
- package/dist/providers/anthropic/index.js.map +1 -1
- package/dist/providers/openai/index.cjs +23 -6
- package/dist/providers/openai/index.cjs.map +1 -1
- package/dist/providers/openai/index.js +23 -6
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/vercel-ai/index.cjs +27 -9
- package/dist/providers/vercel-ai/index.cjs.map +1 -1
- package/dist/providers/vercel-ai/index.js +27 -9
- package/dist/providers/vercel-ai/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -49,9 +49,11 @@ __export(src_exports, {
|
|
|
49
49
|
getCurrentSpan: () => getCurrentSpan,
|
|
50
50
|
getCurrentSpanId: () => getCurrentSpanId,
|
|
51
51
|
getCurrentTraceId: () => getCurrentTraceId,
|
|
52
|
+
getMetrics: () => getMetrics,
|
|
52
53
|
getSpanById: () => getSpanById,
|
|
54
|
+
getTraceContent: () => getTraceContent,
|
|
53
55
|
getTraceContext: () => getTraceContext,
|
|
54
|
-
getTracer: () =>
|
|
56
|
+
getTracer: () => getTracer2,
|
|
55
57
|
init: () => init,
|
|
56
58
|
injectTraceContext: () => injectTraceContext,
|
|
57
59
|
isEnabled: () => isEnabled,
|
|
@@ -85,6 +87,7 @@ function resolveConfig(config) {
|
|
|
85
87
|
const traceContent = config?.traceContent ?? parseBool(env.RISICARE_TRACE_CONTENT, true);
|
|
86
88
|
const sampleRate = config?.sampleRate ?? parseFloat(env.RISICARE_SAMPLE_RATE ?? "1.0");
|
|
87
89
|
const debug2 = config?.debug ?? parseBool(env.RISICARE_DEBUG, false);
|
|
90
|
+
const compress = config?.compress ?? parseBool(env.RISICARE_COMPRESS, false);
|
|
88
91
|
const batchSize = config?.batchSize ?? 100;
|
|
89
92
|
const batchTimeoutMs = config?.batchTimeoutMs ?? 1e3;
|
|
90
93
|
const maxQueueSize = config?.maxQueueSize ?? 1e4;
|
|
@@ -110,6 +113,7 @@ function resolveConfig(config) {
|
|
|
110
113
|
batchTimeoutMs,
|
|
111
114
|
maxQueueSize,
|
|
112
115
|
debug: debug2,
|
|
116
|
+
compress,
|
|
113
117
|
metadata: config?.metadata ?? {}
|
|
114
118
|
};
|
|
115
119
|
}
|
|
@@ -130,7 +134,7 @@ function generateSpanId() {
|
|
|
130
134
|
return (0, import_node_crypto.randomBytes)(8).toString("hex");
|
|
131
135
|
}
|
|
132
136
|
function generateAgentId(prefix) {
|
|
133
|
-
const suffix = (0, import_node_crypto.randomBytes)(
|
|
137
|
+
const suffix = (0, import_node_crypto.randomBytes)(8).toString("hex");
|
|
134
138
|
return prefix ? `${prefix}-${suffix}` : suffix;
|
|
135
139
|
}
|
|
136
140
|
function validateTraceId(id) {
|
|
@@ -172,6 +176,9 @@ var SemanticPhase = /* @__PURE__ */ ((SemanticPhase2) => {
|
|
|
172
176
|
SemanticPhase2["DECIDE"] = "decide";
|
|
173
177
|
SemanticPhase2["ACT"] = "act";
|
|
174
178
|
SemanticPhase2["OBSERVE"] = "observe";
|
|
179
|
+
SemanticPhase2["REFLECT"] = "reflect";
|
|
180
|
+
SemanticPhase2["COMMUNICATE"] = "communicate";
|
|
181
|
+
SemanticPhase2["COORDINATE"] = "coordinate";
|
|
175
182
|
return SemanticPhase2;
|
|
176
183
|
})(SemanticPhase || {});
|
|
177
184
|
var AgentRole = /* @__PURE__ */ ((AgentRole2) => {
|
|
@@ -447,16 +454,58 @@ function shouldSample(traceId, sampleRate) {
|
|
|
447
454
|
return hash / 4294967295 < sampleRate;
|
|
448
455
|
}
|
|
449
456
|
|
|
450
|
-
// src/
|
|
457
|
+
// src/globals.ts
|
|
451
458
|
var import_node_async_hooks = require("async_hooks");
|
|
452
|
-
var
|
|
459
|
+
var G = globalThis;
|
|
460
|
+
var PREFIX = "__risicare_";
|
|
461
|
+
function getClient() {
|
|
462
|
+
return G[PREFIX + "client"];
|
|
463
|
+
}
|
|
464
|
+
function setClient(client) {
|
|
465
|
+
G[PREFIX + "client"] = client;
|
|
466
|
+
}
|
|
467
|
+
function getTracer() {
|
|
468
|
+
return G[PREFIX + "tracer"];
|
|
469
|
+
}
|
|
470
|
+
function setTracer(tracer) {
|
|
471
|
+
G[PREFIX + "tracer"] = tracer;
|
|
472
|
+
}
|
|
473
|
+
function getContextStorage() {
|
|
474
|
+
if (!G[PREFIX + "ctx"]) {
|
|
475
|
+
G[PREFIX + "ctx"] = new import_node_async_hooks.AsyncLocalStorage();
|
|
476
|
+
}
|
|
477
|
+
return G[PREFIX + "ctx"];
|
|
478
|
+
}
|
|
479
|
+
function getRegistry() {
|
|
480
|
+
if (!G[PREFIX + "registry"]) {
|
|
481
|
+
G[PREFIX + "registry"] = /* @__PURE__ */ new Map();
|
|
482
|
+
}
|
|
483
|
+
return G[PREFIX + "registry"];
|
|
484
|
+
}
|
|
485
|
+
function getOpCount() {
|
|
486
|
+
return G[PREFIX + "opcount"] ?? 0;
|
|
487
|
+
}
|
|
488
|
+
function setOpCount(n) {
|
|
489
|
+
G[PREFIX + "opcount"] = n;
|
|
490
|
+
}
|
|
491
|
+
function getDebug() {
|
|
492
|
+
return G[PREFIX + "debug"] ?? false;
|
|
493
|
+
}
|
|
494
|
+
function setDebugFlag(enabled) {
|
|
495
|
+
G[PREFIX + "debug"] = enabled;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// src/context/storage.ts
|
|
499
|
+
function storage() {
|
|
500
|
+
return getContextStorage();
|
|
501
|
+
}
|
|
453
502
|
function getContext() {
|
|
454
|
-
return
|
|
503
|
+
return storage().getStore() ?? {};
|
|
455
504
|
}
|
|
456
505
|
function runWithContext(overrides, fn) {
|
|
457
506
|
const parent = getContext();
|
|
458
507
|
const merged = { ...parent, ...overrides };
|
|
459
|
-
return
|
|
508
|
+
return storage().run(merged, fn);
|
|
460
509
|
}
|
|
461
510
|
function getCurrentSession() {
|
|
462
511
|
return getContext().session;
|
|
@@ -485,8 +534,22 @@ function getCurrentSpanId() {
|
|
|
485
534
|
function getCurrentContext() {
|
|
486
535
|
const ctx = getContext();
|
|
487
536
|
return {
|
|
488
|
-
session: ctx.session ? {
|
|
489
|
-
|
|
537
|
+
session: ctx.session ? {
|
|
538
|
+
sessionId: ctx.session.sessionId,
|
|
539
|
+
userId: ctx.session.userId,
|
|
540
|
+
...ctx.session.parentSessionId !== void 0 ? { parentSessionId: ctx.session.parentSessionId } : {},
|
|
541
|
+
...ctx.session.turnNumber !== void 0 ? { turnNumber: ctx.session.turnNumber } : {},
|
|
542
|
+
...ctx.session.metadata !== void 0 ? { metadata: ctx.session.metadata } : {}
|
|
543
|
+
} : null,
|
|
544
|
+
agent: ctx.agent ? {
|
|
545
|
+
agentId: ctx.agent.agentId,
|
|
546
|
+
agentName: ctx.agent.agentName,
|
|
547
|
+
agentRole: ctx.agent.agentRole,
|
|
548
|
+
agentType: ctx.agent.agentType,
|
|
549
|
+
...ctx.agent.parentAgentId !== void 0 ? { parentAgentId: ctx.agent.parentAgentId } : {},
|
|
550
|
+
...ctx.agent.version !== void 0 ? { version: ctx.agent.version } : {},
|
|
551
|
+
...ctx.agent.metadata !== void 0 ? { metadata: ctx.agent.metadata } : {}
|
|
552
|
+
} : null,
|
|
490
553
|
span: ctx.span ? { spanId: ctx.span.spanId, traceId: ctx.span.traceId } : null,
|
|
491
554
|
phase: ctx.phase ?? null
|
|
492
555
|
};
|
|
@@ -497,10 +560,12 @@ var Tracer = class {
|
|
|
497
560
|
_onSpanEnd;
|
|
498
561
|
_sampleRate;
|
|
499
562
|
_enabled;
|
|
563
|
+
_traceContent;
|
|
500
564
|
constructor(config) {
|
|
501
565
|
this._onSpanEnd = config.onSpanEnd;
|
|
502
566
|
this._sampleRate = config.sampleRate ?? 1;
|
|
503
567
|
this._enabled = config.enabled ?? true;
|
|
568
|
+
this._traceContent = config.traceContent ?? true;
|
|
504
569
|
}
|
|
505
570
|
get enabled() {
|
|
506
571
|
return this._enabled;
|
|
@@ -508,6 +573,9 @@ var Tracer = class {
|
|
|
508
573
|
set enabled(value) {
|
|
509
574
|
this._enabled = value;
|
|
510
575
|
}
|
|
576
|
+
get traceContent() {
|
|
577
|
+
return this._traceContent;
|
|
578
|
+
}
|
|
511
579
|
/**
|
|
512
580
|
* Start a span, run the callback within its context, and auto-end on completion.
|
|
513
581
|
*
|
|
@@ -541,7 +609,13 @@ var Tracer = class {
|
|
|
541
609
|
kind: opts.kind ?? "internal" /* INTERNAL */,
|
|
542
610
|
traceId,
|
|
543
611
|
parentSpanId,
|
|
544
|
-
attributes:
|
|
612
|
+
attributes: {
|
|
613
|
+
...opts.attributes,
|
|
614
|
+
// Propagate context fields as attributes (matching Python SDK tracer.py:497-511)
|
|
615
|
+
...agent2?.agentRole ? { "agent.role": agent2.agentRole } : {},
|
|
616
|
+
...agent2?.parentAgentId ? { "parent_agent_id": agent2.parentAgentId } : {},
|
|
617
|
+
...session2?.userId ? { "session.user_id": session2.userId } : {}
|
|
618
|
+
},
|
|
545
619
|
sessionId: session2?.sessionId,
|
|
546
620
|
agentId: agent2?.agentId,
|
|
547
621
|
agentName: agent2?.agentName,
|
|
@@ -600,7 +674,13 @@ var Tracer = class {
|
|
|
600
674
|
kind: opts.kind ?? "internal" /* INTERNAL */,
|
|
601
675
|
traceId,
|
|
602
676
|
parentSpanId,
|
|
603
|
-
attributes:
|
|
677
|
+
attributes: {
|
|
678
|
+
...opts.attributes,
|
|
679
|
+
// Propagate context fields as attributes (matching Python SDK tracer.py:497-511)
|
|
680
|
+
...agent2?.agentRole ? { "agent.role": agent2.agentRole } : {},
|
|
681
|
+
...agent2?.parentAgentId ? { "parent_agent_id": agent2.parentAgentId } : {},
|
|
682
|
+
...session2?.userId ? { "session.user_id": session2.userId } : {}
|
|
683
|
+
},
|
|
604
684
|
sessionId: session2?.sessionId,
|
|
605
685
|
agentId: agent2?.agentId,
|
|
606
686
|
agentName: agent2?.agentName,
|
|
@@ -613,12 +693,11 @@ var Tracer = class {
|
|
|
613
693
|
};
|
|
614
694
|
|
|
615
695
|
// src/utils/log.ts
|
|
616
|
-
var _debug = false;
|
|
617
696
|
function setDebug(enabled) {
|
|
618
|
-
|
|
697
|
+
setDebugFlag(enabled);
|
|
619
698
|
}
|
|
620
699
|
function debug(msg) {
|
|
621
|
-
if (
|
|
700
|
+
if (getDebug()) {
|
|
622
701
|
process.stderr.write(`[risicare] ${msg}
|
|
623
702
|
`);
|
|
624
703
|
}
|
|
@@ -629,7 +708,7 @@ function warn(msg) {
|
|
|
629
708
|
}
|
|
630
709
|
|
|
631
710
|
// src/exporters/batch.ts
|
|
632
|
-
var BatchSpanProcessor = class {
|
|
711
|
+
var BatchSpanProcessor = class _BatchSpanProcessor {
|
|
633
712
|
_exporters;
|
|
634
713
|
_batchSize;
|
|
635
714
|
_batchTimeoutMs;
|
|
@@ -639,6 +718,10 @@ var BatchSpanProcessor = class {
|
|
|
639
718
|
_timer = null;
|
|
640
719
|
_started = false;
|
|
641
720
|
_flushing = false;
|
|
721
|
+
_beforeExitHandler = null;
|
|
722
|
+
// Retry tracking for failed batches (Audit #5)
|
|
723
|
+
_retryCounts = /* @__PURE__ */ new Map();
|
|
724
|
+
static MAX_RETRIES = 3;
|
|
642
725
|
// Metrics
|
|
643
726
|
droppedSpans = 0;
|
|
644
727
|
exportedSpans = 0;
|
|
@@ -657,9 +740,10 @@ var BatchSpanProcessor = class {
|
|
|
657
740
|
void this._exportBatch();
|
|
658
741
|
}, this._batchTimeoutMs);
|
|
659
742
|
this._timer.unref();
|
|
660
|
-
|
|
743
|
+
this._beforeExitHandler = () => {
|
|
661
744
|
void this.shutdown();
|
|
662
|
-
}
|
|
745
|
+
};
|
|
746
|
+
process.once("beforeExit", this._beforeExitHandler);
|
|
663
747
|
}
|
|
664
748
|
async shutdown(timeoutMs = 5e3) {
|
|
665
749
|
if (!this._started) return;
|
|
@@ -668,6 +752,10 @@ var BatchSpanProcessor = class {
|
|
|
668
752
|
clearInterval(this._timer);
|
|
669
753
|
this._timer = null;
|
|
670
754
|
}
|
|
755
|
+
if (this._beforeExitHandler) {
|
|
756
|
+
process.removeListener("beforeExit", this._beforeExitHandler);
|
|
757
|
+
this._beforeExitHandler = null;
|
|
758
|
+
}
|
|
671
759
|
const flushPromise = this._exportBatch();
|
|
672
760
|
const timeoutPromise = new Promise((resolve) => setTimeout(resolve, timeoutMs));
|
|
673
761
|
await Promise.race([flushPromise, timeoutPromise]);
|
|
@@ -678,6 +766,7 @@ var BatchSpanProcessor = class {
|
|
|
678
766
|
debug(`Error shutting down ${exporter.name}: ${e}`);
|
|
679
767
|
}
|
|
680
768
|
}
|
|
769
|
+
this._retryCounts.clear();
|
|
681
770
|
debug(
|
|
682
771
|
`BatchSpanProcessor shutdown. Exported: ${this.exportedSpans}, Dropped: ${this.droppedSpans}, Failed: ${this.failedExports}`
|
|
683
772
|
);
|
|
@@ -734,6 +823,9 @@ var BatchSpanProcessor = class {
|
|
|
734
823
|
if (!batchExported) {
|
|
735
824
|
this.exportedSpans += batch.length;
|
|
736
825
|
batchExported = true;
|
|
826
|
+
for (const span of batch) {
|
|
827
|
+
this._retryCounts.delete(span.spanId);
|
|
828
|
+
}
|
|
737
829
|
}
|
|
738
830
|
} else {
|
|
739
831
|
this.failedExports++;
|
|
@@ -743,6 +835,22 @@ var BatchSpanProcessor = class {
|
|
|
743
835
|
debug(`Export to ${exporter.name} failed: ${e}`);
|
|
744
836
|
}
|
|
745
837
|
}
|
|
838
|
+
if (!batchExported) {
|
|
839
|
+
const retryable = batch.filter((span) => {
|
|
840
|
+
const count = (this._retryCounts.get(span.spanId) ?? 0) + 1;
|
|
841
|
+
if (count > _BatchSpanProcessor.MAX_RETRIES) {
|
|
842
|
+
this._retryCounts.delete(span.spanId);
|
|
843
|
+
this.droppedSpans++;
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
this._retryCounts.set(span.spanId, count);
|
|
847
|
+
return true;
|
|
848
|
+
});
|
|
849
|
+
if (retryable.length > 0) {
|
|
850
|
+
this._queue.unshift(...retryable);
|
|
851
|
+
debug(`Re-queued ${retryable.length} spans for retry (${batch.length - retryable.length} dropped after max retries)`);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
746
854
|
} finally {
|
|
747
855
|
this._flushing = false;
|
|
748
856
|
}
|
|
@@ -750,6 +858,7 @@ var BatchSpanProcessor = class {
|
|
|
750
858
|
};
|
|
751
859
|
|
|
752
860
|
// src/exporters/http.ts
|
|
861
|
+
var SDK_VERSION = "0.1.1";
|
|
753
862
|
var HttpExporter = class {
|
|
754
863
|
name = "http";
|
|
755
864
|
_endpoint;
|
|
@@ -776,23 +885,26 @@ var HttpExporter = class {
|
|
|
776
885
|
async export(spans) {
|
|
777
886
|
if (spans.length === 0) return "success" /* SUCCESS */;
|
|
778
887
|
const now = Date.now();
|
|
888
|
+
let isHalfOpen = false;
|
|
779
889
|
if (this._consecutiveFailures >= this._circuitBreakerThreshold) {
|
|
780
890
|
if (now < this._circuitOpenUntil) {
|
|
781
891
|
return "failure" /* FAILURE */;
|
|
782
892
|
}
|
|
893
|
+
isHalfOpen = true;
|
|
783
894
|
}
|
|
784
895
|
const body = {
|
|
785
896
|
spans: spans.map((s) => s.toPayload())
|
|
786
897
|
};
|
|
787
898
|
if (this._projectId) body.projectId = this._projectId;
|
|
788
899
|
if (this._environment) body.environment = this._environment;
|
|
789
|
-
|
|
900
|
+
const maxAttempts = isHalfOpen ? 1 : this._maxRetries;
|
|
901
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
790
902
|
const result = await this._sendRequest(body);
|
|
791
903
|
if (result === "success" /* SUCCESS */) {
|
|
792
904
|
this._consecutiveFailures = 0;
|
|
793
905
|
return result;
|
|
794
906
|
}
|
|
795
|
-
if (attempt <
|
|
907
|
+
if (attempt < maxAttempts - 1) {
|
|
796
908
|
await sleep(100 * Math.pow(2, attempt));
|
|
797
909
|
}
|
|
798
910
|
}
|
|
@@ -808,7 +920,8 @@ var HttpExporter = class {
|
|
|
808
920
|
async _sendRequest(body) {
|
|
809
921
|
const url = `${this._endpoint}/v1/spans`;
|
|
810
922
|
const headers = {
|
|
811
|
-
"Content-Type": "application/json"
|
|
923
|
+
"Content-Type": "application/json",
|
|
924
|
+
"User-Agent": `risicare-js/${SDK_VERSION} node/${process.version}`
|
|
812
925
|
};
|
|
813
926
|
if (this._apiKey) {
|
|
814
927
|
headers["Authorization"] = `Bearer ${this._apiKey}`;
|
|
@@ -819,7 +932,8 @@ var HttpExporter = class {
|
|
|
819
932
|
const { gzipSync } = await import("zlib");
|
|
820
933
|
payload = gzipSync(Buffer.from(payload));
|
|
821
934
|
headers["Content-Encoding"] = "gzip";
|
|
822
|
-
} catch {
|
|
935
|
+
} catch (e) {
|
|
936
|
+
debug(`Gzip compression failed, sending uncompressed: ${e}`);
|
|
823
937
|
}
|
|
824
938
|
}
|
|
825
939
|
try {
|
|
@@ -869,15 +983,17 @@ var ConsoleExporter = class {
|
|
|
869
983
|
};
|
|
870
984
|
|
|
871
985
|
// src/client.ts
|
|
872
|
-
var _client;
|
|
873
|
-
var _tracer;
|
|
874
986
|
var RisicareClient = class {
|
|
875
987
|
config;
|
|
876
988
|
processor;
|
|
877
989
|
tracer;
|
|
878
|
-
|
|
990
|
+
_shutdownPromise;
|
|
991
|
+
_shutdownHandlers = [];
|
|
879
992
|
constructor(config) {
|
|
880
993
|
this.config = resolveConfig(config);
|
|
994
|
+
if (this.config.apiKey && !this.config.apiKey.startsWith("rsk-")) {
|
|
995
|
+
debug('Warning: API key should start with "rsk-". Got: ' + this.config.apiKey.slice(0, 4) + "...");
|
|
996
|
+
}
|
|
881
997
|
let exporter;
|
|
882
998
|
if (this.config.debug && !this.config.apiKey) {
|
|
883
999
|
exporter = new ConsoleExporter();
|
|
@@ -886,7 +1002,8 @@ var RisicareClient = class {
|
|
|
886
1002
|
endpoint: this.config.endpoint,
|
|
887
1003
|
apiKey: this.config.apiKey,
|
|
888
1004
|
projectId: this.config.projectId || void 0,
|
|
889
|
-
environment: this.config.environment || void 0
|
|
1005
|
+
environment: this.config.environment || void 0,
|
|
1006
|
+
compress: this.config.compress
|
|
890
1007
|
});
|
|
891
1008
|
} else {
|
|
892
1009
|
exporter = new ConsoleExporter();
|
|
@@ -901,7 +1018,8 @@ var RisicareClient = class {
|
|
|
901
1018
|
this.tracer = new Tracer({
|
|
902
1019
|
onSpanEnd: (span) => this.processor.onSpanEnd(span),
|
|
903
1020
|
sampleRate: this.config.sampleRate,
|
|
904
|
-
enabled: this.config.enabled
|
|
1021
|
+
enabled: this.config.enabled,
|
|
1022
|
+
traceContent: this.config.traceContent
|
|
905
1023
|
});
|
|
906
1024
|
this.processor.start();
|
|
907
1025
|
this._registerShutdownHooks();
|
|
@@ -914,10 +1032,18 @@ var RisicareClient = class {
|
|
|
914
1032
|
set enabled(value) {
|
|
915
1033
|
this.tracer.enabled = value;
|
|
916
1034
|
}
|
|
1035
|
+
// Audit #6: Promise-based shutdown dedup (fixes TOCTOU race condition)
|
|
917
1036
|
async shutdown() {
|
|
918
|
-
if (this.
|
|
919
|
-
this.
|
|
1037
|
+
if (this._shutdownPromise) return this._shutdownPromise;
|
|
1038
|
+
this._shutdownPromise = this._doShutdown();
|
|
1039
|
+
return this._shutdownPromise;
|
|
1040
|
+
}
|
|
1041
|
+
async _doShutdown() {
|
|
920
1042
|
debug("Shutting down...");
|
|
1043
|
+
for (const { signal, handler } of this._shutdownHandlers) {
|
|
1044
|
+
process.removeListener(signal, handler);
|
|
1045
|
+
}
|
|
1046
|
+
this._shutdownHandlers = [];
|
|
921
1047
|
await this.processor.shutdown();
|
|
922
1048
|
}
|
|
923
1049
|
async flush() {
|
|
@@ -925,43 +1051,68 @@ var RisicareClient = class {
|
|
|
925
1051
|
}
|
|
926
1052
|
_registerShutdownHooks() {
|
|
927
1053
|
const onShutdown = () => {
|
|
1054
|
+
const timeout = setTimeout(() => process.exit(1), 5e3);
|
|
1055
|
+
timeout.unref();
|
|
928
1056
|
this.shutdown().catch(() => {
|
|
929
|
-
});
|
|
1057
|
+
}).finally(() => clearTimeout(timeout));
|
|
930
1058
|
};
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1059
|
+
const signals = ["beforeExit", "SIGTERM", "SIGINT"];
|
|
1060
|
+
for (const signal of signals) {
|
|
1061
|
+
process.once(signal, onShutdown);
|
|
1062
|
+
this._shutdownHandlers.push({ signal, handler: onShutdown });
|
|
1063
|
+
}
|
|
934
1064
|
}
|
|
935
1065
|
};
|
|
936
1066
|
function init(config) {
|
|
937
|
-
if (
|
|
1067
|
+
if (getClient()) {
|
|
938
1068
|
debug("Already initialized. Call shutdown() first to re-initialize.");
|
|
939
1069
|
return;
|
|
940
1070
|
}
|
|
941
|
-
|
|
942
|
-
|
|
1071
|
+
const client = new RisicareClient(config);
|
|
1072
|
+
setClient(client);
|
|
1073
|
+
setTracer(client.tracer);
|
|
943
1074
|
}
|
|
944
1075
|
async function shutdown() {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1076
|
+
const client = getClient();
|
|
1077
|
+
if (!client) return;
|
|
1078
|
+
await client.shutdown();
|
|
1079
|
+
setClient(void 0);
|
|
1080
|
+
setTracer(void 0);
|
|
949
1081
|
}
|
|
950
1082
|
async function flush() {
|
|
951
|
-
|
|
952
|
-
|
|
1083
|
+
const client = getClient();
|
|
1084
|
+
if (!client) return;
|
|
1085
|
+
await client.flush();
|
|
953
1086
|
}
|
|
954
1087
|
function enable() {
|
|
955
|
-
|
|
1088
|
+
const client = getClient();
|
|
1089
|
+
if (client) client.enabled = true;
|
|
956
1090
|
}
|
|
957
1091
|
function disable() {
|
|
958
|
-
|
|
1092
|
+
const client = getClient();
|
|
1093
|
+
if (client) client.enabled = false;
|
|
959
1094
|
}
|
|
960
1095
|
function isEnabled() {
|
|
961
|
-
|
|
1096
|
+
const client = getClient();
|
|
1097
|
+
return client?.enabled ?? false;
|
|
962
1098
|
}
|
|
963
|
-
function
|
|
964
|
-
return
|
|
1099
|
+
function getTracer2() {
|
|
1100
|
+
return getTracer();
|
|
1101
|
+
}
|
|
1102
|
+
function getTraceContent() {
|
|
1103
|
+
const tracer = getTracer();
|
|
1104
|
+
return tracer?.traceContent ?? true;
|
|
1105
|
+
}
|
|
1106
|
+
function getMetrics() {
|
|
1107
|
+
const client = getClient();
|
|
1108
|
+
return client?.processor.getMetrics() ?? {
|
|
1109
|
+
exportedSpans: 0,
|
|
1110
|
+
droppedSpans: 0,
|
|
1111
|
+
failedExports: 0,
|
|
1112
|
+
queueSize: 0,
|
|
1113
|
+
queueCapacity: 0,
|
|
1114
|
+
queueUtilization: 0
|
|
1115
|
+
};
|
|
965
1116
|
}
|
|
966
1117
|
|
|
967
1118
|
// src/context/agent.ts
|
|
@@ -985,7 +1136,7 @@ function withAgent(options, fn) {
|
|
|
985
1136
|
function agent(options, fn) {
|
|
986
1137
|
const spanName = `agent:${options.name ?? "agent"}`;
|
|
987
1138
|
return (...args) => {
|
|
988
|
-
const tracer =
|
|
1139
|
+
const tracer = getTracer2();
|
|
989
1140
|
if (!tracer) {
|
|
990
1141
|
return fn(...args);
|
|
991
1142
|
}
|
|
@@ -1025,28 +1176,28 @@ function withPhase(phase, fn) {
|
|
|
1025
1176
|
}
|
|
1026
1177
|
|
|
1027
1178
|
// src/decorators/phase.ts
|
|
1028
|
-
function phaseWrapper(phase, fn) {
|
|
1179
|
+
function phaseWrapper(phase, kind, fn) {
|
|
1029
1180
|
return (...args) => {
|
|
1030
|
-
const tracer =
|
|
1181
|
+
const tracer = getTracer2();
|
|
1031
1182
|
if (!tracer) {
|
|
1032
1183
|
return fn(...args);
|
|
1033
1184
|
}
|
|
1034
1185
|
return withPhase(phase, () => {
|
|
1035
|
-
return tracer.startSpan({ name: `phase:${phase}
|
|
1186
|
+
return tracer.startSpan({ name: `phase:${phase}`, kind }, () => fn(...args));
|
|
1036
1187
|
});
|
|
1037
1188
|
};
|
|
1038
1189
|
}
|
|
1039
1190
|
function traceThink(fn) {
|
|
1040
|
-
return phaseWrapper("think" /* THINK */, fn);
|
|
1191
|
+
return phaseWrapper("think" /* THINK */, "think" /* THINK */, fn);
|
|
1041
1192
|
}
|
|
1042
1193
|
function traceDecide(fn) {
|
|
1043
|
-
return phaseWrapper("decide" /* DECIDE */, fn);
|
|
1194
|
+
return phaseWrapper("decide" /* DECIDE */, "decide" /* DECIDE */, fn);
|
|
1044
1195
|
}
|
|
1045
1196
|
function traceAct(fn) {
|
|
1046
|
-
return phaseWrapper("act" /* ACT */, fn);
|
|
1197
|
+
return phaseWrapper("act" /* ACT */, "tool_call" /* TOOL_CALL */, fn);
|
|
1047
1198
|
}
|
|
1048
1199
|
function traceObserve(fn) {
|
|
1049
|
-
return phaseWrapper("observe" /* OBSERVE */, fn);
|
|
1200
|
+
return phaseWrapper("observe" /* OBSERVE */, "observe" /* OBSERVE */, fn);
|
|
1050
1201
|
}
|
|
1051
1202
|
|
|
1052
1203
|
// src/decorators/multi-agent.ts
|
|
@@ -1061,7 +1212,7 @@ function namespacedMetadata(metadata) {
|
|
|
1061
1212
|
function traceMessage(options, fn) {
|
|
1062
1213
|
const msgType = options.type ?? "request" /* REQUEST */;
|
|
1063
1214
|
return (...args) => {
|
|
1064
|
-
const tracer =
|
|
1215
|
+
const tracer = getTracer2();
|
|
1065
1216
|
if (!tracer) return fn(...args);
|
|
1066
1217
|
return tracer.startSpan(
|
|
1067
1218
|
{
|
|
@@ -1080,7 +1231,7 @@ function traceMessage(options, fn) {
|
|
|
1080
1231
|
}
|
|
1081
1232
|
function traceDelegate(options, fn) {
|
|
1082
1233
|
return (...args) => {
|
|
1083
|
-
const tracer =
|
|
1234
|
+
const tracer = getTracer2();
|
|
1084
1235
|
if (!tracer) return fn(...args);
|
|
1085
1236
|
return tracer.startSpan(
|
|
1086
1237
|
{
|
|
@@ -1099,7 +1250,7 @@ function traceDelegate(options, fn) {
|
|
|
1099
1250
|
}
|
|
1100
1251
|
function traceCoordinate(options, fn) {
|
|
1101
1252
|
return (...args) => {
|
|
1102
|
-
const tracer =
|
|
1253
|
+
const tracer = getTracer2();
|
|
1103
1254
|
if (!tracer) return fn(...args);
|
|
1104
1255
|
return tracer.startSpan(
|
|
1105
1256
|
{
|
|
@@ -1177,7 +1328,10 @@ function extractTraceContext(headers) {
|
|
|
1177
1328
|
if (eqIdx > 0) {
|
|
1178
1329
|
const key = kv.slice(0, eqIdx).trim();
|
|
1179
1330
|
const value = kv.slice(eqIdx + 1).trim();
|
|
1180
|
-
if (key && value)
|
|
1331
|
+
if (key && value) {
|
|
1332
|
+
const camelKey = key === "session_id" ? "sessionId" : key === "agent_id" ? "agentId" : key;
|
|
1333
|
+
result[camelKey] = value;
|
|
1334
|
+
}
|
|
1181
1335
|
}
|
|
1182
1336
|
}
|
|
1183
1337
|
}
|
|
@@ -1190,36 +1344,37 @@ function extractTraceContext(headers) {
|
|
|
1190
1344
|
var DEFAULT_TTL_MS = 6e4;
|
|
1191
1345
|
var MAX_ENTRIES = 1e4;
|
|
1192
1346
|
var CLEANUP_INTERVAL = 100;
|
|
1193
|
-
|
|
1194
|
-
|
|
1347
|
+
function entries() {
|
|
1348
|
+
return getRegistry();
|
|
1349
|
+
}
|
|
1195
1350
|
function registerSpan(span, ttlMs = DEFAULT_TTL_MS) {
|
|
1196
|
-
entries.set(span.spanId, {
|
|
1351
|
+
entries().set(span.spanId, {
|
|
1197
1352
|
span,
|
|
1198
1353
|
registeredAt: Date.now(),
|
|
1199
1354
|
ttlMs
|
|
1200
1355
|
});
|
|
1201
|
-
|
|
1356
|
+
setOpCount(getOpCount() + 1);
|
|
1202
1357
|
maybeCleanup();
|
|
1203
1358
|
}
|
|
1204
1359
|
function getSpanById(spanId) {
|
|
1205
|
-
const entry = entries.get(spanId);
|
|
1360
|
+
const entry = entries().get(spanId);
|
|
1206
1361
|
if (!entry) return void 0;
|
|
1207
1362
|
if (Date.now() - entry.registeredAt > entry.ttlMs) {
|
|
1208
|
-
entries.delete(spanId);
|
|
1363
|
+
entries().delete(spanId);
|
|
1209
1364
|
return void 0;
|
|
1210
1365
|
}
|
|
1211
1366
|
return entry.span;
|
|
1212
1367
|
}
|
|
1213
1368
|
function unregisterSpan(spanId) {
|
|
1214
|
-
entries.delete(spanId);
|
|
1369
|
+
entries().delete(spanId);
|
|
1215
1370
|
}
|
|
1216
1371
|
function maybeCleanup() {
|
|
1217
|
-
if (
|
|
1218
|
-
if (entries.size <= MAX_ENTRIES) return;
|
|
1372
|
+
if (getOpCount() % CLEANUP_INTERVAL !== 0) return;
|
|
1373
|
+
if (entries().size <= MAX_ENTRIES) return;
|
|
1219
1374
|
const now = Date.now();
|
|
1220
|
-
for (const [id, entry] of entries) {
|
|
1375
|
+
for (const [id, entry] of entries()) {
|
|
1221
1376
|
if (now - entry.registeredAt > entry.ttlMs) {
|
|
1222
|
-
entries.delete(id);
|
|
1377
|
+
entries().delete(id);
|
|
1223
1378
|
}
|
|
1224
1379
|
}
|
|
1225
1380
|
}
|
|
@@ -1244,7 +1399,9 @@ function maybeCleanup() {
|
|
|
1244
1399
|
getCurrentSpan,
|
|
1245
1400
|
getCurrentSpanId,
|
|
1246
1401
|
getCurrentTraceId,
|
|
1402
|
+
getMetrics,
|
|
1247
1403
|
getSpanById,
|
|
1404
|
+
getTraceContent,
|
|
1248
1405
|
getTraceContext,
|
|
1249
1406
|
getTracer,
|
|
1250
1407
|
init,
|