risicare 0.1.4 → 0.2.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.
- package/dist/frameworks/instructor.cjs +178 -0
- package/dist/frameworks/instructor.cjs.map +1 -0
- package/dist/frameworks/instructor.d.cts +28 -0
- package/dist/frameworks/instructor.d.ts +28 -0
- package/dist/frameworks/instructor.js +151 -0
- package/dist/frameworks/instructor.js.map +1 -0
- package/dist/frameworks/langchain.cjs +262 -0
- package/dist/frameworks/langchain.cjs.map +1 -0
- package/dist/frameworks/langchain.d.cts +45 -0
- package/dist/frameworks/langchain.d.ts +45 -0
- package/dist/frameworks/langchain.js +235 -0
- package/dist/frameworks/langchain.js.map +1 -0
- package/dist/frameworks/langgraph.cjs +296 -0
- package/dist/frameworks/langgraph.cjs.map +1 -0
- package/dist/frameworks/langgraph.d.cts +28 -0
- package/dist/frameworks/langgraph.d.ts +28 -0
- package/dist/frameworks/langgraph.js +269 -0
- package/dist/frameworks/langgraph.js.map +1 -0
- package/dist/frameworks/llamaindex.cjs +239 -0
- package/dist/frameworks/llamaindex.cjs.map +1 -0
- package/dist/frameworks/llamaindex.d.cts +55 -0
- package/dist/frameworks/llamaindex.d.ts +55 -0
- package/dist/frameworks/llamaindex.js +212 -0
- package/dist/frameworks/llamaindex.js.map +1 -0
- package/dist/index.cjs +468 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -6
- package/dist/index.d.ts +124 -6
- package/dist/index.js +459 -7
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic/index.cjs +22 -0
- package/dist/providers/anthropic/index.cjs.map +1 -1
- package/dist/providers/anthropic/index.js +22 -0
- package/dist/providers/anthropic/index.js.map +1 -1
- package/dist/providers/bedrock/index.cjs +334 -0
- package/dist/providers/bedrock/index.cjs.map +1 -0
- package/dist/providers/bedrock/index.d.cts +37 -0
- package/dist/providers/bedrock/index.d.ts +37 -0
- package/dist/providers/bedrock/index.js +307 -0
- package/dist/providers/bedrock/index.js.map +1 -0
- package/dist/providers/cerebras/index.cjs +282 -0
- package/dist/providers/cerebras/index.cjs.map +1 -0
- package/dist/providers/cerebras/index.d.cts +24 -0
- package/dist/providers/cerebras/index.d.ts +24 -0
- package/dist/providers/cerebras/index.js +255 -0
- package/dist/providers/cerebras/index.js.map +1 -0
- package/dist/providers/cohere/index.cjs +347 -0
- package/dist/providers/cohere/index.cjs.map +1 -0
- package/dist/providers/cohere/index.d.cts +24 -0
- package/dist/providers/cohere/index.d.ts +24 -0
- package/dist/providers/cohere/index.js +320 -0
- package/dist/providers/cohere/index.js.map +1 -0
- package/dist/providers/google/index.cjs +337 -0
- package/dist/providers/google/index.cjs.map +1 -0
- package/dist/providers/google/index.d.cts +25 -0
- package/dist/providers/google/index.d.ts +25 -0
- package/dist/providers/google/index.js +310 -0
- package/dist/providers/google/index.js.map +1 -0
- package/dist/providers/groq/index.cjs +282 -0
- package/dist/providers/groq/index.cjs.map +1 -0
- package/dist/providers/groq/index.d.cts +23 -0
- package/dist/providers/groq/index.d.ts +23 -0
- package/dist/providers/groq/index.js +255 -0
- package/dist/providers/groq/index.js.map +1 -0
- package/dist/providers/huggingface/index.cjs +289 -0
- package/dist/providers/huggingface/index.cjs.map +1 -0
- package/dist/providers/huggingface/index.d.cts +24 -0
- package/dist/providers/huggingface/index.d.ts +24 -0
- package/dist/providers/huggingface/index.js +262 -0
- package/dist/providers/huggingface/index.js.map +1 -0
- package/dist/providers/mistral/index.cjs +336 -0
- package/dist/providers/mistral/index.cjs.map +1 -0
- package/dist/providers/mistral/index.d.cts +24 -0
- package/dist/providers/mistral/index.d.ts +24 -0
- package/dist/providers/mistral/index.js +309 -0
- package/dist/providers/mistral/index.js.map +1 -0
- package/dist/providers/ollama/index.cjs +376 -0
- package/dist/providers/ollama/index.cjs.map +1 -0
- package/dist/providers/ollama/index.d.cts +28 -0
- package/dist/providers/ollama/index.d.ts +28 -0
- package/dist/providers/ollama/index.js +349 -0
- package/dist/providers/ollama/index.js.map +1 -0
- package/dist/providers/openai/index.cjs +31 -1
- package/dist/providers/openai/index.cjs.map +1 -1
- package/dist/providers/openai/index.js +31 -1
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/together/index.cjs +275 -0
- package/dist/providers/together/index.cjs.map +1 -0
- package/dist/providers/together/index.d.cts +24 -0
- package/dist/providers/together/index.d.ts +24 -0
- package/dist/providers/together/index.js +248 -0
- package/dist/providers/together/index.js.map +1 -0
- package/dist/providers/vercel-ai/index.cjs.map +1 -1
- package/dist/providers/vercel-ai/index.js.map +1 -1
- package/package.json +124 -2
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// src/ids.ts
|
|
2
|
+
import { randomBytes } from "crypto";
|
|
3
|
+
|
|
4
|
+
// src/noop.ts
|
|
5
|
+
var NOOP_SPAN = Object.freeze({
|
|
6
|
+
traceId: "00000000000000000000000000000000",
|
|
7
|
+
spanId: "0000000000000000",
|
|
8
|
+
parentSpanId: void 0,
|
|
9
|
+
name: "noop",
|
|
10
|
+
kind: "internal" /* INTERNAL */,
|
|
11
|
+
startTime: "",
|
|
12
|
+
startHrtime: 0,
|
|
13
|
+
endTime: void 0,
|
|
14
|
+
status: "unset" /* UNSET */,
|
|
15
|
+
statusMessage: void 0,
|
|
16
|
+
attributes: Object.freeze({}),
|
|
17
|
+
events: Object.freeze([]),
|
|
18
|
+
links: Object.freeze([]),
|
|
19
|
+
sessionId: void 0,
|
|
20
|
+
agentId: void 0,
|
|
21
|
+
agentName: void 0,
|
|
22
|
+
semanticPhase: void 0,
|
|
23
|
+
llmProvider: void 0,
|
|
24
|
+
llmModel: void 0,
|
|
25
|
+
llmPromptTokens: void 0,
|
|
26
|
+
llmCompletionTokens: void 0,
|
|
27
|
+
llmTotalTokens: void 0,
|
|
28
|
+
llmCostUsd: void 0,
|
|
29
|
+
toolName: void 0,
|
|
30
|
+
toolSuccess: void 0,
|
|
31
|
+
isEnded: true,
|
|
32
|
+
durationMs: 0,
|
|
33
|
+
setAttribute() {
|
|
34
|
+
return this;
|
|
35
|
+
},
|
|
36
|
+
setAttributes() {
|
|
37
|
+
return this;
|
|
38
|
+
},
|
|
39
|
+
setStatus() {
|
|
40
|
+
return this;
|
|
41
|
+
},
|
|
42
|
+
addEvent() {
|
|
43
|
+
return this;
|
|
44
|
+
},
|
|
45
|
+
addLink() {
|
|
46
|
+
return this;
|
|
47
|
+
},
|
|
48
|
+
recordException() {
|
|
49
|
+
return this;
|
|
50
|
+
},
|
|
51
|
+
setLlmFields() {
|
|
52
|
+
return this;
|
|
53
|
+
},
|
|
54
|
+
setToolFields() {
|
|
55
|
+
return this;
|
|
56
|
+
},
|
|
57
|
+
end() {
|
|
58
|
+
},
|
|
59
|
+
toPayload() {
|
|
60
|
+
return {
|
|
61
|
+
traceId: this.traceId,
|
|
62
|
+
spanId: this.spanId,
|
|
63
|
+
name: this.name,
|
|
64
|
+
kind: this.kind,
|
|
65
|
+
startTime: this.startTime,
|
|
66
|
+
status: this.status,
|
|
67
|
+
attributes: {},
|
|
68
|
+
events: [],
|
|
69
|
+
links: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// src/globals.ts
|
|
75
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
76
|
+
var G = globalThis;
|
|
77
|
+
var PREFIX = "__risicare_";
|
|
78
|
+
function getTracer() {
|
|
79
|
+
return G[PREFIX + "tracer"];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/client.ts
|
|
83
|
+
function getTracer2() {
|
|
84
|
+
return getTracer();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/frameworks/langchain.ts
|
|
88
|
+
var RisicareCallbackHandler = class {
|
|
89
|
+
name = "RisicareCallbackHandler";
|
|
90
|
+
_spans = /* @__PURE__ */ new Map();
|
|
91
|
+
// ── Chain lifecycle ────────────────────────────────────────────────────────
|
|
92
|
+
handleChainStart(chain, _inputs, runId, parentRunId) {
|
|
93
|
+
const tracer = getTracer2();
|
|
94
|
+
if (!tracer?.enabled) return;
|
|
95
|
+
const parentEntry = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
96
|
+
const span = tracer.createSpan({
|
|
97
|
+
name: chain.name || chain._type || "chain",
|
|
98
|
+
kind: "internal" /* INTERNAL */,
|
|
99
|
+
parentSpanId: parentEntry?.span.spanId,
|
|
100
|
+
traceId: parentEntry?.span.traceId,
|
|
101
|
+
attributes: {
|
|
102
|
+
"framework": "langchain",
|
|
103
|
+
"langchain.run_id": runId,
|
|
104
|
+
...parentRunId ? { "langchain.parent_run_id": parentRunId } : {},
|
|
105
|
+
...chain._type ? { "langchain.chain_type": chain._type } : {}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
this._spans.set(runId, { span, startTime: Date.now() });
|
|
109
|
+
}
|
|
110
|
+
handleChainEnd(_outputs, runId) {
|
|
111
|
+
const entry = this._spans.get(runId);
|
|
112
|
+
if (!entry) return;
|
|
113
|
+
entry.span.setAttribute("gen_ai.latency_ms", Date.now() - entry.startTime);
|
|
114
|
+
entry.span.end();
|
|
115
|
+
this._spans.delete(runId);
|
|
116
|
+
}
|
|
117
|
+
handleChainError(error, runId) {
|
|
118
|
+
const entry = this._spans.get(runId);
|
|
119
|
+
if (!entry) return;
|
|
120
|
+
entry.span.recordException(error);
|
|
121
|
+
entry.span.end();
|
|
122
|
+
this._spans.delete(runId);
|
|
123
|
+
}
|
|
124
|
+
// ── LLM lifecycle ─────────────────────────────────────────────────────────
|
|
125
|
+
handleLLMStart(llm, _prompts, runId, parentRunId) {
|
|
126
|
+
const tracer = getTracer2();
|
|
127
|
+
if (!tracer?.enabled) return;
|
|
128
|
+
const parentEntry = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
129
|
+
const span = tracer.createSpan({
|
|
130
|
+
name: llm.name || llm._type || "llm",
|
|
131
|
+
kind: "llm_call" /* LLM_CALL */,
|
|
132
|
+
parentSpanId: parentEntry?.span.spanId,
|
|
133
|
+
traceId: parentEntry?.span.traceId,
|
|
134
|
+
attributes: {
|
|
135
|
+
"framework": "langchain",
|
|
136
|
+
"langchain.run_id": runId,
|
|
137
|
+
"gen_ai.system": "langchain",
|
|
138
|
+
"gen_ai.prompt.count": _prompts.length
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
this._spans.set(runId, { span, startTime: Date.now() });
|
|
142
|
+
}
|
|
143
|
+
handleLLMEnd(output, runId) {
|
|
144
|
+
const entry = this._spans.get(runId);
|
|
145
|
+
if (!entry) return;
|
|
146
|
+
const usage = output.llmOutput?.tokenUsage;
|
|
147
|
+
if (usage) {
|
|
148
|
+
entry.span.setLlmFields({
|
|
149
|
+
promptTokens: usage.promptTokens ?? usage.prompt_tokens,
|
|
150
|
+
completionTokens: usage.completionTokens ?? usage.completion_tokens,
|
|
151
|
+
totalTokens: usage.totalTokens ?? usage.total_tokens
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
const model = output.llmOutput?.model ?? output.llmOutput?.modelName;
|
|
155
|
+
if (model) {
|
|
156
|
+
entry.span.setLlmFields({ model });
|
|
157
|
+
}
|
|
158
|
+
entry.span.setAttribute("gen_ai.latency_ms", Date.now() - entry.startTime);
|
|
159
|
+
entry.span.end();
|
|
160
|
+
this._spans.delete(runId);
|
|
161
|
+
}
|
|
162
|
+
handleLLMError(error, runId) {
|
|
163
|
+
const entry = this._spans.get(runId);
|
|
164
|
+
if (!entry) return;
|
|
165
|
+
entry.span.recordException(error);
|
|
166
|
+
entry.span.end();
|
|
167
|
+
this._spans.delete(runId);
|
|
168
|
+
}
|
|
169
|
+
// ── Tool lifecycle ────────────────────────────────────────────────────────
|
|
170
|
+
handleToolStart(tool, input, runId, parentRunId) {
|
|
171
|
+
const tracer = getTracer2();
|
|
172
|
+
if (!tracer?.enabled) return;
|
|
173
|
+
const parentEntry = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
174
|
+
const span = tracer.createSpan({
|
|
175
|
+
name: tool.name || "tool",
|
|
176
|
+
kind: "tool_call" /* TOOL_CALL */,
|
|
177
|
+
parentSpanId: parentEntry?.span.spanId,
|
|
178
|
+
traceId: parentEntry?.span.traceId,
|
|
179
|
+
attributes: {
|
|
180
|
+
"framework": "langchain",
|
|
181
|
+
"langchain.run_id": runId,
|
|
182
|
+
"tool.name": tool.name || "unknown",
|
|
183
|
+
"tool.input_length": input?.length ?? 0
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
this._spans.set(runId, { span, startTime: Date.now() });
|
|
187
|
+
}
|
|
188
|
+
handleToolEnd(output, runId) {
|
|
189
|
+
const entry = this._spans.get(runId);
|
|
190
|
+
if (!entry) return;
|
|
191
|
+
entry.span.setAttribute("tool.output_length", output?.length ?? 0);
|
|
192
|
+
entry.span.setAttribute("gen_ai.latency_ms", Date.now() - entry.startTime);
|
|
193
|
+
entry.span.end();
|
|
194
|
+
this._spans.delete(runId);
|
|
195
|
+
}
|
|
196
|
+
handleToolError(error, runId) {
|
|
197
|
+
const entry = this._spans.get(runId);
|
|
198
|
+
if (!entry) return;
|
|
199
|
+
entry.span.recordException(error);
|
|
200
|
+
entry.span.end();
|
|
201
|
+
this._spans.delete(runId);
|
|
202
|
+
}
|
|
203
|
+
// ── Retriever lifecycle ───────────────────────────────────────────────────
|
|
204
|
+
handleRetrieverStart(retriever, _query, runId, parentRunId) {
|
|
205
|
+
const tracer = getTracer2();
|
|
206
|
+
if (!tracer?.enabled) return;
|
|
207
|
+
const parentEntry = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
208
|
+
const span = tracer.createSpan({
|
|
209
|
+
name: retriever.name || "retriever",
|
|
210
|
+
kind: "retrieval" /* RETRIEVAL */,
|
|
211
|
+
parentSpanId: parentEntry?.span.spanId,
|
|
212
|
+
traceId: parentEntry?.span.traceId,
|
|
213
|
+
attributes: {
|
|
214
|
+
"framework": "langchain",
|
|
215
|
+
"langchain.run_id": runId
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
this._spans.set(runId, { span, startTime: Date.now() });
|
|
219
|
+
}
|
|
220
|
+
handleRetrieverEnd(documents, runId) {
|
|
221
|
+
const entry = this._spans.get(runId);
|
|
222
|
+
if (!entry) return;
|
|
223
|
+
entry.span.setAttribute(
|
|
224
|
+
"retriever.document_count",
|
|
225
|
+
documents?.length ?? 0
|
|
226
|
+
);
|
|
227
|
+
entry.span.setAttribute("gen_ai.latency_ms", Date.now() - entry.startTime);
|
|
228
|
+
entry.span.end();
|
|
229
|
+
this._spans.delete(runId);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/frameworks/langgraph.ts
|
|
234
|
+
function instrumentLangGraph(graph) {
|
|
235
|
+
return new Proxy(graph, {
|
|
236
|
+
get(target, prop, receiver) {
|
|
237
|
+
const value = Reflect.get(target, prop, receiver);
|
|
238
|
+
if ((prop === "invoke" || prop === "stream") && typeof value === "function") {
|
|
239
|
+
return function patchedMethod(...args) {
|
|
240
|
+
const tracer = getTracer2();
|
|
241
|
+
if (!tracer?.enabled) return value.apply(this, args);
|
|
242
|
+
return tracer.startSpan(
|
|
243
|
+
{
|
|
244
|
+
name: `langgraph.${String(prop)}`,
|
|
245
|
+
kind: "agent" /* AGENT */,
|
|
246
|
+
attributes: { framework: "langgraph" }
|
|
247
|
+
},
|
|
248
|
+
(_span) => {
|
|
249
|
+
const config = args[1] ?? {};
|
|
250
|
+
const callbacks = config.callbacks ?? [];
|
|
251
|
+
callbacks.push(new RisicareCallbackHandler());
|
|
252
|
+
args[1] = { ...config, callbacks };
|
|
253
|
+
const result = value.apply(this, args);
|
|
254
|
+
if (result && typeof result.then === "function") {
|
|
255
|
+
return result.then((r) => r);
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
export {
|
|
267
|
+
instrumentLangGraph
|
|
268
|
+
};
|
|
269
|
+
//# sourceMappingURL=langgraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ids.ts","../../src/noop.ts","../../src/globals.ts","../../src/client.ts","../../src/frameworks/langchain.ts","../../src/frameworks/langgraph.ts"],"sourcesContent":["/**\n * ID generation for traces and spans.\n *\n * Trace IDs: 32 lowercase hex characters (16 random bytes)\n * Span IDs: 16 lowercase hex characters (8 random bytes)\n *\n * Uses crypto.randomBytes for cryptographically secure randomness.\n */\n\nimport { randomBytes } from 'node:crypto';\n\nconst HEX_REGEX_32 = /^[0-9a-f]{32}$/;\nconst HEX_REGEX_16 = /^[0-9a-f]{16}$/;\n\nexport function generateTraceId(): string {\n return randomBytes(16).toString('hex');\n}\n\nexport function generateSpanId(): string {\n return randomBytes(8).toString('hex');\n}\n\nexport function generateAgentId(prefix?: string): string {\n const suffix = randomBytes(8).toString('hex');\n return prefix ? `${prefix}-${suffix}` : suffix;\n}\n\nexport function validateTraceId(id: string): boolean {\n return HEX_REGEX_32.test(id);\n}\n\nexport function validateSpanId(id: string): boolean {\n return HEX_REGEX_16.test(id);\n}\n","/**\n * No-op implementations for the disabled path.\n *\n * When tracing is disabled, all operations return these no-op objects\n * to maintain zero overhead. No allocations, no side effects.\n */\n\nimport { SpanKind, SpanStatus, type SpanPayload } from './types.js';\n\n/**\n * A frozen no-op span that silently ignores all operations.\n * Used when SDK is disabled to avoid overhead.\n */\nexport const NOOP_SPAN = Object.freeze({\n traceId: '00000000000000000000000000000000',\n spanId: '0000000000000000',\n parentSpanId: undefined,\n name: 'noop',\n kind: SpanKind.INTERNAL,\n startTime: '',\n startHrtime: 0,\n endTime: undefined,\n status: SpanStatus.UNSET,\n statusMessage: undefined,\n attributes: Object.freeze({}) as Record<string, unknown>,\n events: Object.freeze([]) as readonly [],\n links: Object.freeze([]) as readonly [],\n sessionId: undefined,\n agentId: undefined,\n agentName: undefined,\n semanticPhase: undefined,\n llmProvider: undefined,\n llmModel: undefined,\n llmPromptTokens: undefined,\n llmCompletionTokens: undefined,\n llmTotalTokens: undefined,\n llmCostUsd: undefined,\n toolName: undefined,\n toolSuccess: undefined,\n isEnded: true,\n durationMs: 0,\n\n setAttribute() { return this; },\n setAttributes() { return this; },\n setStatus() { return this; },\n addEvent() { return this; },\n addLink() { return this; },\n recordException() { return this; },\n setLlmFields() { return this; },\n setToolFields() { return this; },\n end() {},\n toPayload(): SpanPayload {\n return {\n traceId: this.traceId,\n spanId: this.spanId,\n name: this.name,\n kind: this.kind,\n startTime: this.startTime,\n status: this.status,\n attributes: {},\n events: [],\n links: [],\n };\n },\n});\n\nexport type NoopSpan = typeof NOOP_SPAN;\n","/**\n * Shared state via globalThis — ensures all entry point bundles share\n * the same singleton instances.\n *\n * Problem: tsup with `splitting: false` gives each entry point (index,\n * openai, anthropic, vercel-ai) its own copy of module-level variables.\n * This means `init()` from 'risicare' sets a tracer that 'risicare/openai'\n * can't see — breaking all provider instrumentation silently.\n *\n * Solution: Store all mutable singletons on globalThis with a namespaced\n * prefix. Every bundle reads/writes the same global slots.\n *\n * This pattern is used by React, OpenTelemetry, and other SDKs that must\n * share state across independently bundled entry points.\n *\n * @internal\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst G = globalThis as any;\nconst PREFIX = '__risicare_';\n\n// ─── Client & Tracer ────────────────────────────────────────────────────────\n\nexport function getClient(): unknown {\n return G[PREFIX + 'client'];\n}\n\nexport function setClient(client: unknown): void {\n G[PREFIX + 'client'] = client;\n}\n\nexport function getTracer(): unknown {\n return G[PREFIX + 'tracer'];\n}\n\nexport function setTracer(tracer: unknown): void {\n G[PREFIX + 'tracer'] = tracer;\n}\n\n// ─── Context Storage ────────────────────────────────────────────────────────\n\nexport function getContextStorage(): AsyncLocalStorage<unknown> {\n if (!G[PREFIX + 'ctx']) {\n G[PREFIX + 'ctx'] = new AsyncLocalStorage();\n }\n return G[PREFIX + 'ctx'];\n}\n\n// ─── Span Registry ──────────────────────────────────────────────────────────\n\nexport function getRegistry(): Map<string, unknown> {\n if (!G[PREFIX + 'registry']) {\n G[PREFIX + 'registry'] = new Map();\n }\n return G[PREFIX + 'registry'];\n}\n\nexport function getOpCount(): number {\n return G[PREFIX + 'opcount'] ?? 0;\n}\n\nexport function setOpCount(n: number): void {\n G[PREFIX + 'opcount'] = n;\n}\n\n// ─── Debug Flag ─────────────────────────────────────────────────────────────\n\nexport function getDebug(): boolean {\n return G[PREFIX + 'debug'] ?? false;\n}\n\nexport function setDebugFlag(enabled: boolean): void {\n G[PREFIX + 'debug'] = enabled;\n}\n","/**\n * RisicareClient — singleton client managing SDK lifecycle.\n *\n * Handles initialization, shutdown, and the connection between\n * the Tracer and the export pipeline (batch processor + HTTP exporter).\n *\n * Usage:\n * import { init, shutdown } from 'risicare';\n * init({ apiKey: 'rsk-...' }); // API key determines project\n * // ... instrument code ...\n * await shutdown(); // flush remaining spans\n */\n\nimport { type RisicareConfig, resolveConfig } from './config.js';\nimport { Tracer } from './tracer.js';\nimport { BatchSpanProcessor } from './exporters/batch.js';\nimport { HttpExporter } from './exporters/http.js';\nimport { ConsoleExporter } from './exporters/console.js';\nimport { SpanKind, SpanStatus } from './types.js';\nimport type { SpanExporter } from './exporters/base.js';\nimport { setDebug, debug } from './utils/log.js';\nimport {\n getClient as getGlobalClient,\n setClient as setGlobalClient,\n getTracer as getGlobalTracer,\n setTracer as setGlobalTracer,\n} from './globals.js';\n\n// ─── Client Class ───────────────────────────────────────────────────────────\n\nclass RisicareClient {\n readonly config: ReturnType<typeof resolveConfig>;\n readonly processor: BatchSpanProcessor;\n readonly tracer: Tracer;\n private _shutdownPromise: Promise<void> | undefined;\n private _shutdownHandlers: { signal: string; handler: () => void }[] = [];\n\n constructor(config?: Partial<RisicareConfig>) {\n this.config = resolveConfig(config);\n\n // API key format validation\n if (this.config.apiKey && !this.config.apiKey.startsWith('rsk-')) {\n debug('Warning: API key should start with \"rsk-\". Got: ' + this.config.apiKey.slice(0, 4) + '...');\n }\n\n // Build exporter chain\n let exporter: SpanExporter;\n if (this.config.debug && !this.config.apiKey) {\n exporter = new ConsoleExporter();\n } else if (this.config.apiKey) {\n exporter = new HttpExporter({\n endpoint: this.config.endpoint,\n apiKey: this.config.apiKey,\n projectId: this.config.projectId || undefined,\n environment: this.config.environment || undefined,\n compress: this.config.compress,\n });\n } else {\n // No API key and not debug — use console as fallback\n exporter = new ConsoleExporter();\n }\n\n this.processor = new BatchSpanProcessor({\n exporters: [exporter],\n batchSize: this.config.batchSize,\n batchTimeoutMs: this.config.batchTimeoutMs,\n maxQueueSize: this.config.maxQueueSize,\n debug: this.config.debug,\n });\n\n this.tracer = new Tracer({\n onSpanEnd: (span) => this.processor.onSpanEnd(span),\n sampleRate: this.config.sampleRate,\n enabled: this.config.enabled,\n traceContent: this.config.traceContent,\n });\n\n // Start the batch processor (enables span queuing and periodic flushing)\n this.processor.start();\n\n // Register shutdown hooks\n this._registerShutdownHooks();\n\n // Enable internal debug logging if configured\n setDebug(this.config.debug);\n debug(`Initialized: enabled=${this.config.enabled}, endpoint=${this.config.endpoint}`);\n }\n\n get enabled(): boolean {\n return this.tracer.enabled;\n }\n\n set enabled(value: boolean) {\n this.tracer.enabled = value;\n }\n\n // Audit #6: Promise-based shutdown dedup (fixes TOCTOU race condition)\n async shutdown(): Promise<void> {\n if (this._shutdownPromise) return this._shutdownPromise;\n this._shutdownPromise = this._doShutdown();\n return this._shutdownPromise;\n }\n\n private async _doShutdown(): Promise<void> {\n debug('Shutting down...');\n\n // Audit #3: Remove process listeners to prevent leak\n for (const { signal, handler } of this._shutdownHandlers) {\n process.removeListener(signal, handler);\n }\n this._shutdownHandlers = [];\n\n await this.processor.shutdown();\n }\n\n async flush(): Promise<void> {\n await this.processor.flush();\n }\n\n private _registerShutdownHooks(): void {\n const onShutdown = () => {\n // Audit #3: Add 5s timeout to prevent hanging on signal\n const timeout = setTimeout(() => process.exit(1), 5000);\n timeout.unref();\n this.shutdown().catch(() => {}).finally(() => clearTimeout(timeout));\n };\n\n const signals = ['beforeExit', 'SIGTERM', 'SIGINT'];\n for (const signal of signals) {\n process.once(signal, onShutdown);\n this._shutdownHandlers.push({ signal, handler: onShutdown });\n }\n }\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\n/**\n * Initialize the Risicare SDK. Call once at application startup.\n *\n * @example\n * import { init } from 'risicare';\n * init({ apiKey: 'rsk-...', serviceName: 'my-agent', environment: 'production' });\n */\nexport function init(config?: Partial<RisicareConfig>): void {\n if (getGlobalClient()) {\n debug('Already initialized. Call shutdown() first to re-initialize.');\n return;\n }\n\n const client = new RisicareClient(config);\n setGlobalClient(client);\n setGlobalTracer(client.tracer);\n}\n\n/**\n * Gracefully shut down the SDK. Flushes pending spans before resolving.\n */\nexport async function shutdown(): Promise<void> {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client) return;\n await client.shutdown();\n setGlobalClient(undefined);\n setGlobalTracer(undefined);\n}\n\n/**\n * Flush all pending spans without shutting down.\n */\nexport async function flush(): Promise<void> {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client) return;\n await client.flush();\n}\n\n/**\n * Enable tracing at runtime.\n */\nexport function enable(): void {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (client) client.enabled = true;\n}\n\n/**\n * Disable tracing at runtime. Spans will not be created or exported.\n */\nexport function disable(): void {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (client) client.enabled = false;\n}\n\n/**\n * Check whether tracing is currently enabled.\n */\nexport function isEnabled(): boolean {\n const client = getGlobalClient() as RisicareClient | undefined;\n return client?.enabled ?? false;\n}\n\n/**\n * Get the global tracer instance. Returns undefined if not initialized.\n */\nexport function getTracer(): Tracer | undefined {\n return getGlobalTracer() as Tracer | undefined;\n}\n\n/**\n * Get the global tracer, or throw if not initialized.\n * @internal Used by decorators and providers that require an active tracer.\n */\nexport function requireTracer(): Tracer {\n const tracer = getGlobalTracer() as Tracer | undefined;\n if (!tracer) {\n throw new Error(\n 'Risicare SDK not initialized. Call init() before using tracing features.',\n );\n }\n return tracer;\n}\n\n/**\n * Check whether content tracing (prompt/completion capture) is enabled.\n */\nexport function getTraceContent(): boolean {\n const tracer = getGlobalTracer() as Tracer | undefined;\n return tracer?.traceContent ?? true;\n}\n\n/**\n * Get SDK metrics: exported spans, dropped spans, failed exports, queue stats.\n * Returns zero-valued metrics if SDK is not initialized.\n */\nexport function getMetrics() {\n const client = getGlobalClient() as RisicareClient | undefined;\n return client?.processor.getMetrics() ?? {\n exportedSpans: 0,\n droppedSpans: 0,\n failedExports: 0,\n queueSize: 0,\n queueCapacity: 0,\n queueUtilization: 0,\n };\n}\n\n// ─── reportError ──────────────────────────────────────────────────────────\n\n/**\n * Report a caught exception to the self-healing pipeline.\n *\n * Creates an error span that triggers diagnosis and fix generation.\n * This function never throws and is non-blocking.\n *\n * @param error - The caught exception (Error object or string)\n * @param options - Optional attributes and context overrides\n */\nexport function reportError(\n error: unknown,\n options?: { name?: string; attributes?: Record<string, unknown> },\n): void {\n try {\n const tracer = getTracer();\n if (!tracer) return;\n\n const err = error instanceof Error ? error : new Error(String(error));\n const spanName = options?.name ?? `error:${err.constructor.name}`;\n\n tracer.startSpan({ name: spanName, kind: SpanKind.INTERNAL }, (span) => {\n span.setStatus(SpanStatus.ERROR, err.message);\n span.setAttribute('error', true);\n span.setAttribute('error.type', err.constructor.name);\n span.setAttribute('error.message', err.message.slice(0, 2000));\n if (err.stack) span.setAttribute('error.stack', err.stack.slice(0, 4000));\n span.setAttribute('risicare.reported_error', true);\n if (options?.attributes) {\n for (const [k, v] of Object.entries(options.attributes)) {\n span.setAttribute(k, v);\n }\n }\n });\n } catch {\n // Never crash the host application\n debug('reportError failed');\n }\n}\n\n// ─── score ─────────────────────────────────────────────────────────────────\n\n/**\n * Record a custom evaluation score on a trace.\n *\n * Sends the score to the server in a fire-and-forget fashion.\n * This function never throws and is non-blocking.\n *\n * @param traceId - The trace to score\n * @param name - Score name (e.g., \"accuracy\", \"user_satisfaction\")\n * @param value - Score value between 0.0 and 1.0 inclusive\n * @param options - Optional span_id and comment\n */\nexport function score(\n traceId: string,\n name: string,\n value: number,\n options?: { spanId?: string; comment?: string },\n): void {\n try {\n if (typeof value !== 'number' || value < 0.0 || value > 1.0) {\n debug(`score: value must be in [0.0, 1.0], got ${value}. Score not sent.`);\n return;\n }\n if (!traceId || !name) {\n debug('score: traceId and name are required');\n return;\n }\n\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client?.enabled || !client.config.apiKey) return;\n\n const endpoint = client.config.endpoint.replace(/\\/$/, '');\n const url = `${endpoint}/api/v1/scores`;\n const body = JSON.stringify({\n trace_id: traceId,\n name,\n score: value,\n source: 'sdk',\n ...(options?.spanId && { span_id: options.spanId }),\n ...(options?.comment && { comment: options.comment }),\n });\n\n // Fire-and-forget — never blocks caller\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${client.config.apiKey}`,\n },\n body,\n }).catch((err) => debug(`score: send failed: ${err}`));\n } catch {\n // Never crash the host application\n debug('score failed');\n }\n}\n","/**\n * LangChain.js integration via callback handler.\n *\n * LangChain.js uses BaseCallbackHandler from @langchain/core/callbacks/base.\n * This handler receives lifecycle events (handleChainStart, handleLLMEnd, etc.)\n * with a runId (UUID string) for parent-child correlation.\n *\n * Usage:\n * import { RisicareCallbackHandler } from 'risicare/frameworks/langchain';\n * const handler = new RisicareCallbackHandler();\n * const result = await chain.invoke(input, { callbacks: [handler] });\n *\n * Does NOT suppress provider instrumentation -- LangChain callbacks are\n * supplementary to the underlying LLM provider spans.\n */\n\nimport { getTracer } from '../client.js';\nimport { SpanKind } from '../types.js';\nimport type { Span } from '../span.js';\n\ninterface SpanEntry {\n span: Span;\n startTime: number;\n}\n\nexport class RisicareCallbackHandler {\n name = 'RisicareCallbackHandler';\n\n private _spans = new Map<string, SpanEntry>();\n\n // ── Chain lifecycle ────────────────────────────────────────────────────────\n\n handleChainStart(\n chain: { name?: string; _type?: string },\n _inputs: Record<string, unknown>,\n runId: string,\n parentRunId?: string,\n ): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n const parentEntry = parentRunId ? this._spans.get(parentRunId) : undefined;\n const span = tracer.createSpan({\n name: chain.name || chain._type || 'chain',\n kind: SpanKind.INTERNAL,\n parentSpanId: parentEntry?.span.spanId,\n traceId: parentEntry?.span.traceId,\n attributes: {\n 'framework': 'langchain',\n 'langchain.run_id': runId,\n ...(parentRunId ? { 'langchain.parent_run_id': parentRunId } : {}),\n ...(chain._type ? { 'langchain.chain_type': chain._type } : {}),\n },\n });\n\n this._spans.set(runId, { span, startTime: Date.now() });\n }\n\n handleChainEnd(_outputs: Record<string, unknown>, runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.setAttribute('gen_ai.latency_ms', Date.now() - entry.startTime);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n handleChainError(error: Error, runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.recordException(error);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n // ── LLM lifecycle ─────────────────────────────────────────────────────────\n\n handleLLMStart(\n llm: { name?: string; _type?: string },\n _prompts: string[],\n runId: string,\n parentRunId?: string,\n ): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n const parentEntry = parentRunId ? this._spans.get(parentRunId) : undefined;\n const span = tracer.createSpan({\n name: llm.name || llm._type || 'llm',\n kind: SpanKind.LLM_CALL,\n parentSpanId: parentEntry?.span.spanId,\n traceId: parentEntry?.span.traceId,\n attributes: {\n 'framework': 'langchain',\n 'langchain.run_id': runId,\n 'gen_ai.system': 'langchain',\n 'gen_ai.prompt.count': _prompts.length,\n },\n });\n\n this._spans.set(runId, { span, startTime: Date.now() });\n }\n\n handleLLMEnd(\n output: {\n generations?: unknown[][];\n llmOutput?: Record<string, unknown>;\n },\n runId: string,\n ): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n\n // Extract token usage from llmOutput\n const usage = output.llmOutput?.tokenUsage as\n | Record<string, number>\n | undefined;\n if (usage) {\n entry.span.setLlmFields({\n promptTokens: usage.promptTokens ?? usage.prompt_tokens,\n completionTokens: usage.completionTokens ?? usage.completion_tokens,\n totalTokens: usage.totalTokens ?? usage.total_tokens,\n });\n }\n\n const model = (output.llmOutput?.model ??\n output.llmOutput?.modelName) as string | undefined;\n if (model) {\n entry.span.setLlmFields({ model });\n }\n\n entry.span.setAttribute('gen_ai.latency_ms', Date.now() - entry.startTime);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n handleLLMError(error: Error, runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.recordException(error);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n // ── Tool lifecycle ────────────────────────────────────────────────────────\n\n handleToolStart(\n tool: { name?: string },\n input: string,\n runId: string,\n parentRunId?: string,\n ): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n const parentEntry = parentRunId ? this._spans.get(parentRunId) : undefined;\n const span = tracer.createSpan({\n name: tool.name || 'tool',\n kind: SpanKind.TOOL_CALL,\n parentSpanId: parentEntry?.span.spanId,\n traceId: parentEntry?.span.traceId,\n attributes: {\n 'framework': 'langchain',\n 'langchain.run_id': runId,\n 'tool.name': tool.name || 'unknown',\n 'tool.input_length': input?.length ?? 0,\n },\n });\n\n this._spans.set(runId, { span, startTime: Date.now() });\n }\n\n handleToolEnd(output: string, runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.setAttribute('tool.output_length', output?.length ?? 0);\n entry.span.setAttribute('gen_ai.latency_ms', Date.now() - entry.startTime);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n handleToolError(error: Error, runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.recordException(error);\n entry.span.end();\n this._spans.delete(runId);\n }\n\n // ── Retriever lifecycle ───────────────────────────────────────────────────\n\n handleRetrieverStart(\n retriever: { name?: string },\n _query: string,\n runId: string,\n parentRunId?: string,\n ): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n const parentEntry = parentRunId ? this._spans.get(parentRunId) : undefined;\n const span = tracer.createSpan({\n name: retriever.name || 'retriever',\n kind: SpanKind.RETRIEVAL,\n parentSpanId: parentEntry?.span.spanId,\n traceId: parentEntry?.span.traceId,\n attributes: {\n 'framework': 'langchain',\n 'langchain.run_id': runId,\n },\n });\n\n this._spans.set(runId, { span, startTime: Date.now() });\n }\n\n handleRetrieverEnd(documents: unknown[], runId: string): void {\n const entry = this._spans.get(runId);\n if (!entry) return;\n entry.span.setAttribute(\n 'retriever.document_count',\n documents?.length ?? 0,\n );\n entry.span.setAttribute('gen_ai.latency_ms', Date.now() - entry.startTime);\n entry.span.end();\n this._spans.delete(runId);\n }\n}\n","/**\n * LangGraph.js integration via Proxy wrapping.\n *\n * LangGraph uses LangChain callbacks under the hood. This integration wraps\n * a compiled graph's invoke/stream methods to:\n * 1. Create a parent \"langgraph.invoke\" or \"langgraph.stream\" span\n * 2. Inject a RisicareCallbackHandler into the config so all internal\n * chain/LLM/tool calls are also traced\n *\n * Usage:\n * import { instrumentLangGraph } from 'risicare/frameworks/langgraph';\n * const graph = instrumentLangGraph(compiledGraph);\n * const result = await graph.invoke(input);\n *\n * Does NOT suppress provider instrumentation.\n */\n\nimport { getTracer } from '../client.js';\nimport { SpanKind } from '../types.js';\nimport { RisicareCallbackHandler } from './langchain.js';\n\n/**\n * Wrap a compiled LangGraph graph with Risicare tracing.\n *\n * Returns a Proxy that intercepts `invoke` and `stream` calls to create\n * a parent span and inject the LangChain callback handler.\n *\n * @param graph - A compiled LangGraph graph object with invoke/stream methods\n * @returns A proxied graph with tracing enabled\n */\nexport function instrumentLangGraph<T extends object>(graph: T): T {\n return new Proxy(graph, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n\n if (\n (prop === 'invoke' || prop === 'stream') &&\n typeof value === 'function'\n ) {\n return function patchedMethod(\n this: unknown,\n ...args: unknown[]\n ): unknown {\n const tracer = getTracer();\n if (!tracer?.enabled) return value.apply(this, args);\n\n return tracer.startSpan(\n {\n name: `langgraph.${String(prop)}`,\n kind: SpanKind.AGENT,\n attributes: { framework: 'langgraph' },\n },\n (_span) => {\n // Inject RisicareCallbackHandler into config (second argument)\n const config = (args[1] ?? {}) as Record<string, unknown>;\n const callbacks = (config.callbacks ?? []) as unknown[];\n callbacks.push(new RisicareCallbackHandler());\n args[1] = { ...config, callbacks };\n\n const result = value.apply(this, args);\n\n // Handle async results (Promises)\n if (\n result &&\n typeof (result as Promise<unknown>).then === 'function'\n ) {\n return (result as Promise<unknown>).then((r) => r);\n }\n return result;\n },\n );\n };\n }\n\n return value;\n },\n });\n}\n"],"mappings":"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","names":["getTracer","getTracer","getTracer"]}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/frameworks/llamaindex.ts
|
|
21
|
+
var llamaindex_exports = {};
|
|
22
|
+
__export(llamaindex_exports, {
|
|
23
|
+
RisicareLlamaIndexHandler: () => RisicareLlamaIndexHandler
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(llamaindex_exports);
|
|
26
|
+
|
|
27
|
+
// src/ids.ts
|
|
28
|
+
var import_node_crypto = require("crypto");
|
|
29
|
+
|
|
30
|
+
// src/noop.ts
|
|
31
|
+
var NOOP_SPAN = Object.freeze({
|
|
32
|
+
traceId: "00000000000000000000000000000000",
|
|
33
|
+
spanId: "0000000000000000",
|
|
34
|
+
parentSpanId: void 0,
|
|
35
|
+
name: "noop",
|
|
36
|
+
kind: "internal" /* INTERNAL */,
|
|
37
|
+
startTime: "",
|
|
38
|
+
startHrtime: 0,
|
|
39
|
+
endTime: void 0,
|
|
40
|
+
status: "unset" /* UNSET */,
|
|
41
|
+
statusMessage: void 0,
|
|
42
|
+
attributes: Object.freeze({}),
|
|
43
|
+
events: Object.freeze([]),
|
|
44
|
+
links: Object.freeze([]),
|
|
45
|
+
sessionId: void 0,
|
|
46
|
+
agentId: void 0,
|
|
47
|
+
agentName: void 0,
|
|
48
|
+
semanticPhase: void 0,
|
|
49
|
+
llmProvider: void 0,
|
|
50
|
+
llmModel: void 0,
|
|
51
|
+
llmPromptTokens: void 0,
|
|
52
|
+
llmCompletionTokens: void 0,
|
|
53
|
+
llmTotalTokens: void 0,
|
|
54
|
+
llmCostUsd: void 0,
|
|
55
|
+
toolName: void 0,
|
|
56
|
+
toolSuccess: void 0,
|
|
57
|
+
isEnded: true,
|
|
58
|
+
durationMs: 0,
|
|
59
|
+
setAttribute() {
|
|
60
|
+
return this;
|
|
61
|
+
},
|
|
62
|
+
setAttributes() {
|
|
63
|
+
return this;
|
|
64
|
+
},
|
|
65
|
+
setStatus() {
|
|
66
|
+
return this;
|
|
67
|
+
},
|
|
68
|
+
addEvent() {
|
|
69
|
+
return this;
|
|
70
|
+
},
|
|
71
|
+
addLink() {
|
|
72
|
+
return this;
|
|
73
|
+
},
|
|
74
|
+
recordException() {
|
|
75
|
+
return this;
|
|
76
|
+
},
|
|
77
|
+
setLlmFields() {
|
|
78
|
+
return this;
|
|
79
|
+
},
|
|
80
|
+
setToolFields() {
|
|
81
|
+
return this;
|
|
82
|
+
},
|
|
83
|
+
end() {
|
|
84
|
+
},
|
|
85
|
+
toPayload() {
|
|
86
|
+
return {
|
|
87
|
+
traceId: this.traceId,
|
|
88
|
+
spanId: this.spanId,
|
|
89
|
+
name: this.name,
|
|
90
|
+
kind: this.kind,
|
|
91
|
+
startTime: this.startTime,
|
|
92
|
+
status: this.status,
|
|
93
|
+
attributes: {},
|
|
94
|
+
events: [],
|
|
95
|
+
links: []
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// src/globals.ts
|
|
101
|
+
var import_node_async_hooks = require("async_hooks");
|
|
102
|
+
var G = globalThis;
|
|
103
|
+
var PREFIX = "__risicare_";
|
|
104
|
+
function getTracer() {
|
|
105
|
+
return G[PREFIX + "tracer"];
|
|
106
|
+
}
|
|
107
|
+
function getContextStorage() {
|
|
108
|
+
if (!G[PREFIX + "ctx"]) {
|
|
109
|
+
G[PREFIX + "ctx"] = new import_node_async_hooks.AsyncLocalStorage();
|
|
110
|
+
}
|
|
111
|
+
return G[PREFIX + "ctx"];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/context/storage.ts
|
|
115
|
+
function storage() {
|
|
116
|
+
return getContextStorage();
|
|
117
|
+
}
|
|
118
|
+
function getContext() {
|
|
119
|
+
return storage().getStore() ?? {};
|
|
120
|
+
}
|
|
121
|
+
function runWithContext(overrides, fn) {
|
|
122
|
+
const parent = getContext();
|
|
123
|
+
const merged = { ...parent, ...overrides };
|
|
124
|
+
return storage().run(merged, fn);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/client.ts
|
|
128
|
+
function getTracer2() {
|
|
129
|
+
return getTracer();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/context/dedup.ts
|
|
133
|
+
function suppressProviderInstrumentation(fn) {
|
|
134
|
+
return runWithContext({ _suppressProviderInstrumentation: true }, fn);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/frameworks/llamaindex.ts
|
|
138
|
+
var RisicareLlamaIndexHandler = class {
|
|
139
|
+
_spans = /* @__PURE__ */ new Map();
|
|
140
|
+
/**
|
|
141
|
+
* Handle a LlamaIndex lifecycle event.
|
|
142
|
+
*
|
|
143
|
+
* Events follow the convention:
|
|
144
|
+
* - `*.start` / `*.begin` -- component starts
|
|
145
|
+
* - `*.end` / `*.complete` -- component finishes
|
|
146
|
+
* - `*.error` -- component failed
|
|
147
|
+
*/
|
|
148
|
+
onEvent(event) {
|
|
149
|
+
const tracer = getTracer2();
|
|
150
|
+
if (!tracer?.enabled) return;
|
|
151
|
+
if (event.type.endsWith(".start") || event.type.endsWith(".begin")) {
|
|
152
|
+
this._handleStart(event);
|
|
153
|
+
} else if (event.type.endsWith(".end") || event.type.endsWith(".complete")) {
|
|
154
|
+
this._handleEnd(event);
|
|
155
|
+
} else if (event.type.endsWith(".error")) {
|
|
156
|
+
this._handleError(event);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Run a function with provider instrumentation suppressed.
|
|
161
|
+
*
|
|
162
|
+
* LlamaIndex handler creates its own LLM spans, so provider spans
|
|
163
|
+
* (patchOpenAI, patchAnthropic, etc.) should be suppressed to avoid
|
|
164
|
+
* double-tracing.
|
|
165
|
+
*/
|
|
166
|
+
withSuppression(fn) {
|
|
167
|
+
return suppressProviderInstrumentation(fn);
|
|
168
|
+
}
|
|
169
|
+
// ── Internal event handlers ───────────────────────────────────────────────
|
|
170
|
+
_handleStart(event) {
|
|
171
|
+
const tracer = getTracer2();
|
|
172
|
+
if (!tracer?.enabled) return;
|
|
173
|
+
const componentKind = this._classifyComponent(event.type);
|
|
174
|
+
const parentEntry = event.parentId ? this._spans.get(event.parentId) : void 0;
|
|
175
|
+
const spanKind = componentKind === "llm" ? "llm_call" /* LLM_CALL */ : componentKind === "retrieval" ? "retrieval" /* RETRIEVAL */ : componentKind === "embedding" ? "llm_call" /* LLM_CALL */ : "internal" /* INTERNAL */;
|
|
176
|
+
const span = tracer.createSpan({
|
|
177
|
+
name: event.type.replace(/\.(start|begin)$/, ""),
|
|
178
|
+
kind: spanKind,
|
|
179
|
+
parentSpanId: parentEntry?.span.spanId,
|
|
180
|
+
traceId: parentEntry?.span.traceId,
|
|
181
|
+
attributes: {
|
|
182
|
+
framework: "llamaindex",
|
|
183
|
+
"framework.span_kind": componentKind,
|
|
184
|
+
...event.data?.model ? { "gen_ai.request.model": event.data.model } : {}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
this._spans.set(event.id, { span, startTime: Date.now(), componentKind });
|
|
188
|
+
}
|
|
189
|
+
_handleEnd(event) {
|
|
190
|
+
const entry = this._spans.get(event.id);
|
|
191
|
+
if (!entry) return;
|
|
192
|
+
entry.span.setAttribute(
|
|
193
|
+
"gen_ai.latency_ms",
|
|
194
|
+
Date.now() - entry.startTime
|
|
195
|
+
);
|
|
196
|
+
const usage = event.data?.usage;
|
|
197
|
+
if (usage) {
|
|
198
|
+
entry.span.setLlmFields({
|
|
199
|
+
promptTokens: usage.promptTokens ?? usage.prompt_tokens,
|
|
200
|
+
completionTokens: usage.completionTokens ?? usage.completion_tokens
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (event.data?.documentCount != null) {
|
|
204
|
+
entry.span.setAttribute(
|
|
205
|
+
"retriever.document_count",
|
|
206
|
+
event.data.documentCount
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
entry.span.end();
|
|
210
|
+
this._spans.delete(event.id);
|
|
211
|
+
}
|
|
212
|
+
_handleError(event) {
|
|
213
|
+
const entry = this._spans.get(event.id);
|
|
214
|
+
if (!entry) return;
|
|
215
|
+
const error = event.data?.error;
|
|
216
|
+
entry.span.recordException(
|
|
217
|
+
error instanceof Error ? error : String(error ?? "Unknown error")
|
|
218
|
+
);
|
|
219
|
+
entry.span.end();
|
|
220
|
+
this._spans.delete(event.id);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Classify a LlamaIndex event type into a component kind.
|
|
224
|
+
*/
|
|
225
|
+
_classifyComponent(eventType) {
|
|
226
|
+
const lower = eventType.toLowerCase();
|
|
227
|
+
if (lower.includes("llm") || lower.includes("chat")) return "llm";
|
|
228
|
+
if (lower.includes("embed")) return "embedding";
|
|
229
|
+
if (lower.includes("retriev") || lower.includes("vector")) return "retrieval";
|
|
230
|
+
if (lower.includes("synth") || lower.includes("response")) return "synthesis";
|
|
231
|
+
if (lower.includes("query")) return "query";
|
|
232
|
+
return "component";
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
236
|
+
0 && (module.exports = {
|
|
237
|
+
RisicareLlamaIndexHandler
|
|
238
|
+
});
|
|
239
|
+
//# sourceMappingURL=llamaindex.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frameworks/llamaindex.ts","../../src/ids.ts","../../src/noop.ts","../../src/globals.ts","../../src/context/storage.ts","../../src/client.ts","../../src/context/dedup.ts"],"sourcesContent":["/**\n * LlamaIndex.TS integration via event handler.\n *\n * LlamaIndex uses a span handler / callback event pattern. This handler\n * receives events with { type, id, parentId, data } and manages the\n * span lifecycle accordingly.\n *\n * Usage:\n * import { RisicareLlamaIndexHandler } from 'risicare/frameworks/llamaindex';\n * const handler = new RisicareLlamaIndexHandler();\n *\n * // Register with LlamaIndex's event system\n * Settings.callbackManager.on('*', (event) => handler.onEvent(event));\n *\n * // For LLM/embedding calls, suppress provider instrumentation:\n * const result = handler.withSuppression(() => query(...));\n *\n * SUPPRESSES provider instrumentation -- LlamaIndex creates its own LLM spans,\n * so provider-level spans (patchOpenAI, etc.) would duplicate.\n */\n\nimport { getTracer } from '../client.js';\nimport { SpanKind } from '../types.js';\nimport { suppressProviderInstrumentation } from '../context/dedup.js';\nimport type { Span } from '../span.js';\n\ninterface SpanEntry {\n span: Span;\n startTime: number;\n componentKind: string;\n}\n\nexport interface LlamaIndexEvent {\n type: string;\n id: string;\n parentId?: string;\n data?: Record<string, unknown>;\n}\n\nexport class RisicareLlamaIndexHandler {\n private _spans = new Map<string, SpanEntry>();\n\n /**\n * Handle a LlamaIndex lifecycle event.\n *\n * Events follow the convention:\n * - `*.start` / `*.begin` -- component starts\n * - `*.end` / `*.complete` -- component finishes\n * - `*.error` -- component failed\n */\n onEvent(event: LlamaIndexEvent): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n if (event.type.endsWith('.start') || event.type.endsWith('.begin')) {\n this._handleStart(event);\n } else if (\n event.type.endsWith('.end') ||\n event.type.endsWith('.complete')\n ) {\n this._handleEnd(event);\n } else if (event.type.endsWith('.error')) {\n this._handleError(event);\n }\n }\n\n /**\n * Run a function with provider instrumentation suppressed.\n *\n * LlamaIndex handler creates its own LLM spans, so provider spans\n * (patchOpenAI, patchAnthropic, etc.) should be suppressed to avoid\n * double-tracing.\n */\n withSuppression<T>(fn: () => T): T {\n return suppressProviderInstrumentation(fn);\n }\n\n // ── Internal event handlers ───────────────────────────────────────────────\n\n private _handleStart(event: LlamaIndexEvent): void {\n const tracer = getTracer();\n if (!tracer?.enabled) return;\n\n const componentKind = this._classifyComponent(event.type);\n const parentEntry = event.parentId\n ? this._spans.get(event.parentId)\n : undefined;\n\n const spanKind =\n componentKind === 'llm'\n ? SpanKind.LLM_CALL\n : componentKind === 'retrieval'\n ? SpanKind.RETRIEVAL\n : componentKind === 'embedding'\n ? SpanKind.LLM_CALL\n : SpanKind.INTERNAL;\n\n const span = tracer.createSpan({\n name: event.type.replace(/\\.(start|begin)$/, ''),\n kind: spanKind,\n parentSpanId: parentEntry?.span.spanId,\n traceId: parentEntry?.span.traceId,\n attributes: {\n framework: 'llamaindex',\n 'framework.span_kind': componentKind,\n ...(event.data?.model\n ? { 'gen_ai.request.model': event.data.model }\n : {}),\n },\n });\n\n this._spans.set(event.id, { span, startTime: Date.now(), componentKind });\n }\n\n private _handleEnd(event: LlamaIndexEvent): void {\n const entry = this._spans.get(event.id);\n if (!entry) return;\n\n entry.span.setAttribute(\n 'gen_ai.latency_ms',\n Date.now() - entry.startTime,\n );\n\n // Extract token usage if available\n const usage = event.data?.usage as Record<string, number> | undefined;\n if (usage) {\n entry.span.setLlmFields({\n promptTokens: usage.promptTokens ?? usage.prompt_tokens,\n completionTokens: usage.completionTokens ?? usage.completion_tokens,\n });\n }\n\n if (event.data?.documentCount != null) {\n entry.span.setAttribute(\n 'retriever.document_count',\n event.data.documentCount,\n );\n }\n\n entry.span.end();\n this._spans.delete(event.id);\n }\n\n private _handleError(event: LlamaIndexEvent): void {\n const entry = this._spans.get(event.id);\n if (!entry) return;\n\n const error = event.data?.error;\n entry.span.recordException(\n error instanceof Error ? error : String(error ?? 'Unknown error'),\n );\n entry.span.end();\n this._spans.delete(event.id);\n }\n\n /**\n * Classify a LlamaIndex event type into a component kind.\n */\n private _classifyComponent(eventType: string): string {\n const lower = eventType.toLowerCase();\n if (lower.includes('llm') || lower.includes('chat')) return 'llm';\n if (lower.includes('embed')) return 'embedding';\n if (lower.includes('retriev') || lower.includes('vector')) return 'retrieval';\n if (lower.includes('synth') || lower.includes('response')) return 'synthesis';\n if (lower.includes('query')) return 'query';\n return 'component';\n }\n}\n","/**\n * ID generation for traces and spans.\n *\n * Trace IDs: 32 lowercase hex characters (16 random bytes)\n * Span IDs: 16 lowercase hex characters (8 random bytes)\n *\n * Uses crypto.randomBytes for cryptographically secure randomness.\n */\n\nimport { randomBytes } from 'node:crypto';\n\nconst HEX_REGEX_32 = /^[0-9a-f]{32}$/;\nconst HEX_REGEX_16 = /^[0-9a-f]{16}$/;\n\nexport function generateTraceId(): string {\n return randomBytes(16).toString('hex');\n}\n\nexport function generateSpanId(): string {\n return randomBytes(8).toString('hex');\n}\n\nexport function generateAgentId(prefix?: string): string {\n const suffix = randomBytes(8).toString('hex');\n return prefix ? `${prefix}-${suffix}` : suffix;\n}\n\nexport function validateTraceId(id: string): boolean {\n return HEX_REGEX_32.test(id);\n}\n\nexport function validateSpanId(id: string): boolean {\n return HEX_REGEX_16.test(id);\n}\n","/**\n * No-op implementations for the disabled path.\n *\n * When tracing is disabled, all operations return these no-op objects\n * to maintain zero overhead. No allocations, no side effects.\n */\n\nimport { SpanKind, SpanStatus, type SpanPayload } from './types.js';\n\n/**\n * A frozen no-op span that silently ignores all operations.\n * Used when SDK is disabled to avoid overhead.\n */\nexport const NOOP_SPAN = Object.freeze({\n traceId: '00000000000000000000000000000000',\n spanId: '0000000000000000',\n parentSpanId: undefined,\n name: 'noop',\n kind: SpanKind.INTERNAL,\n startTime: '',\n startHrtime: 0,\n endTime: undefined,\n status: SpanStatus.UNSET,\n statusMessage: undefined,\n attributes: Object.freeze({}) as Record<string, unknown>,\n events: Object.freeze([]) as readonly [],\n links: Object.freeze([]) as readonly [],\n sessionId: undefined,\n agentId: undefined,\n agentName: undefined,\n semanticPhase: undefined,\n llmProvider: undefined,\n llmModel: undefined,\n llmPromptTokens: undefined,\n llmCompletionTokens: undefined,\n llmTotalTokens: undefined,\n llmCostUsd: undefined,\n toolName: undefined,\n toolSuccess: undefined,\n isEnded: true,\n durationMs: 0,\n\n setAttribute() { return this; },\n setAttributes() { return this; },\n setStatus() { return this; },\n addEvent() { return this; },\n addLink() { return this; },\n recordException() { return this; },\n setLlmFields() { return this; },\n setToolFields() { return this; },\n end() {},\n toPayload(): SpanPayload {\n return {\n traceId: this.traceId,\n spanId: this.spanId,\n name: this.name,\n kind: this.kind,\n startTime: this.startTime,\n status: this.status,\n attributes: {},\n events: [],\n links: [],\n };\n },\n});\n\nexport type NoopSpan = typeof NOOP_SPAN;\n","/**\n * Shared state via globalThis — ensures all entry point bundles share\n * the same singleton instances.\n *\n * Problem: tsup with `splitting: false` gives each entry point (index,\n * openai, anthropic, vercel-ai) its own copy of module-level variables.\n * This means `init()` from 'risicare' sets a tracer that 'risicare/openai'\n * can't see — breaking all provider instrumentation silently.\n *\n * Solution: Store all mutable singletons on globalThis with a namespaced\n * prefix. Every bundle reads/writes the same global slots.\n *\n * This pattern is used by React, OpenTelemetry, and other SDKs that must\n * share state across independently bundled entry points.\n *\n * @internal\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst G = globalThis as any;\nconst PREFIX = '__risicare_';\n\n// ─── Client & Tracer ────────────────────────────────────────────────────────\n\nexport function getClient(): unknown {\n return G[PREFIX + 'client'];\n}\n\nexport function setClient(client: unknown): void {\n G[PREFIX + 'client'] = client;\n}\n\nexport function getTracer(): unknown {\n return G[PREFIX + 'tracer'];\n}\n\nexport function setTracer(tracer: unknown): void {\n G[PREFIX + 'tracer'] = tracer;\n}\n\n// ─── Context Storage ────────────────────────────────────────────────────────\n\nexport function getContextStorage(): AsyncLocalStorage<unknown> {\n if (!G[PREFIX + 'ctx']) {\n G[PREFIX + 'ctx'] = new AsyncLocalStorage();\n }\n return G[PREFIX + 'ctx'];\n}\n\n// ─── Span Registry ──────────────────────────────────────────────────────────\n\nexport function getRegistry(): Map<string, unknown> {\n if (!G[PREFIX + 'registry']) {\n G[PREFIX + 'registry'] = new Map();\n }\n return G[PREFIX + 'registry'];\n}\n\nexport function getOpCount(): number {\n return G[PREFIX + 'opcount'] ?? 0;\n}\n\nexport function setOpCount(n: number): void {\n G[PREFIX + 'opcount'] = n;\n}\n\n// ─── Debug Flag ─────────────────────────────────────────────────────────────\n\nexport function getDebug(): boolean {\n return G[PREFIX + 'debug'] ?? false;\n}\n\nexport function setDebugFlag(enabled: boolean): void {\n G[PREFIX + 'debug'] = enabled;\n}\n","/**\n * AsyncLocalStorage-based context propagation.\n *\n * Uses a single AsyncLocalStorage instance with a composite state object.\n * This is simpler and more performant than multiple separate stores.\n *\n * Node.js AsyncLocalStorage automatically propagates through:\n * - Promise / async-await\n * - setTimeout / setImmediate\n * - EventEmitter callbacks\n * - process.nextTick\n * - async generators (unlike Python's contextvars!)\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { Span } from '../span.js';\nimport type { SemanticPhase } from '../types.js';\nimport { getContextStorage } from '../globals.js';\n\n// ─── Context Types ───────────────────────────────────────────────────────────\n\nexport interface SessionContext {\n sessionId: string;\n userId?: string;\n metadata?: Record<string, unknown>;\n parentSessionId?: string;\n turnNumber?: number;\n}\n\nexport interface AgentContext {\n agentId: string;\n agentName?: string;\n agentRole?: string;\n agentType?: string;\n parentAgentId?: string;\n version?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ContextState {\n session?: SessionContext;\n agent?: AgentContext;\n span?: Span;\n phase?: SemanticPhase;\n /** When true, provider instrumentors skip span creation (framework is handling it). */\n _suppressProviderInstrumentation?: boolean;\n}\n\n// ─── Storage Accessor ────────────────────────────────────────────────────────\n\nfunction storage(): AsyncLocalStorage<ContextState> {\n return getContextStorage() as AsyncLocalStorage<ContextState>;\n}\n\n// ─── Core Operations ─────────────────────────────────────────────────────────\n\n/**\n * Get the current context state, or empty object if outside any context.\n */\nexport function getContext(): ContextState {\n return storage().getStore() ?? {};\n}\n\n/**\n * Run a callback within a new context scope.\n * The new scope inherits from the parent, with overrides applied.\n */\nexport function runWithContext<T>(overrides: Partial<ContextState>, fn: () => T): T {\n const parent = getContext();\n const merged: ContextState = { ...parent, ...overrides };\n return storage().run(merged, fn);\n}\n\n/**\n * Run an async callback within a new context scope.\n */\nexport function runWithContextAsync<T>(overrides: Partial<ContextState>, fn: () => Promise<T>): Promise<T> {\n const parent = getContext();\n const merged: ContextState = { ...parent, ...overrides };\n return storage().run(merged, fn);\n}\n\n// ─── Context Accessors ───────────────────────────────────────────────────────\n\nexport function getCurrentSession(): SessionContext | undefined {\n return getContext().session;\n}\n\nexport function getCurrentAgent(): AgentContext | undefined {\n return getContext().agent;\n}\n\nexport function getCurrentSpan(): Span | undefined {\n return getContext().span;\n}\n\nexport function getCurrentPhase(): SemanticPhase | undefined {\n return getContext().phase;\n}\n\nexport function getCurrentSessionId(): string | undefined {\n return getContext().session?.sessionId;\n}\n\nexport function getCurrentAgentId(): string | undefined {\n return getContext().agent?.agentId;\n}\n\nexport function getCurrentTraceId(): string | undefined {\n return getContext().span?.traceId;\n}\n\nexport function getCurrentSpanId(): string | undefined {\n return getContext().span?.spanId;\n}\n\nexport function getCurrentParentSpanId(): string | undefined {\n return getContext().span?.parentSpanId;\n}\n\n/**\n * Get all current context as a plain object (for debugging/serialization).\n */\nexport function getCurrentContext(): Record<string, unknown> {\n const ctx = getContext();\n return {\n session: ctx.session ? {\n sessionId: ctx.session.sessionId,\n userId: ctx.session.userId,\n ...(ctx.session.parentSessionId !== undefined ? { parentSessionId: ctx.session.parentSessionId } : {}),\n ...(ctx.session.turnNumber !== undefined ? { turnNumber: ctx.session.turnNumber } : {}),\n ...(ctx.session.metadata !== undefined ? { metadata: ctx.session.metadata } : {}),\n } : null,\n agent: ctx.agent ? {\n agentId: ctx.agent.agentId,\n agentName: ctx.agent.agentName,\n agentRole: ctx.agent.agentRole,\n agentType: ctx.agent.agentType,\n ...(ctx.agent.parentAgentId !== undefined ? { parentAgentId: ctx.agent.parentAgentId } : {}),\n ...(ctx.agent.version !== undefined ? { version: ctx.agent.version } : {}),\n ...(ctx.agent.metadata !== undefined ? { metadata: ctx.agent.metadata } : {}),\n } : null,\n span: ctx.span ? { spanId: ctx.span.spanId, traceId: ctx.span.traceId } : null,\n phase: ctx.phase ?? null,\n };\n}\n","/**\n * RisicareClient — singleton client managing SDK lifecycle.\n *\n * Handles initialization, shutdown, and the connection between\n * the Tracer and the export pipeline (batch processor + HTTP exporter).\n *\n * Usage:\n * import { init, shutdown } from 'risicare';\n * init({ apiKey: 'rsk-...' }); // API key determines project\n * // ... instrument code ...\n * await shutdown(); // flush remaining spans\n */\n\nimport { type RisicareConfig, resolveConfig } from './config.js';\nimport { Tracer } from './tracer.js';\nimport { BatchSpanProcessor } from './exporters/batch.js';\nimport { HttpExporter } from './exporters/http.js';\nimport { ConsoleExporter } from './exporters/console.js';\nimport { SpanKind, SpanStatus } from './types.js';\nimport type { SpanExporter } from './exporters/base.js';\nimport { setDebug, debug } from './utils/log.js';\nimport {\n getClient as getGlobalClient,\n setClient as setGlobalClient,\n getTracer as getGlobalTracer,\n setTracer as setGlobalTracer,\n} from './globals.js';\n\n// ─── Client Class ───────────────────────────────────────────────────────────\n\nclass RisicareClient {\n readonly config: ReturnType<typeof resolveConfig>;\n readonly processor: BatchSpanProcessor;\n readonly tracer: Tracer;\n private _shutdownPromise: Promise<void> | undefined;\n private _shutdownHandlers: { signal: string; handler: () => void }[] = [];\n\n constructor(config?: Partial<RisicareConfig>) {\n this.config = resolveConfig(config);\n\n // API key format validation\n if (this.config.apiKey && !this.config.apiKey.startsWith('rsk-')) {\n debug('Warning: API key should start with \"rsk-\". Got: ' + this.config.apiKey.slice(0, 4) + '...');\n }\n\n // Build exporter chain\n let exporter: SpanExporter;\n if (this.config.debug && !this.config.apiKey) {\n exporter = new ConsoleExporter();\n } else if (this.config.apiKey) {\n exporter = new HttpExporter({\n endpoint: this.config.endpoint,\n apiKey: this.config.apiKey,\n projectId: this.config.projectId || undefined,\n environment: this.config.environment || undefined,\n compress: this.config.compress,\n });\n } else {\n // No API key and not debug — use console as fallback\n exporter = new ConsoleExporter();\n }\n\n this.processor = new BatchSpanProcessor({\n exporters: [exporter],\n batchSize: this.config.batchSize,\n batchTimeoutMs: this.config.batchTimeoutMs,\n maxQueueSize: this.config.maxQueueSize,\n debug: this.config.debug,\n });\n\n this.tracer = new Tracer({\n onSpanEnd: (span) => this.processor.onSpanEnd(span),\n sampleRate: this.config.sampleRate,\n enabled: this.config.enabled,\n traceContent: this.config.traceContent,\n });\n\n // Start the batch processor (enables span queuing and periodic flushing)\n this.processor.start();\n\n // Register shutdown hooks\n this._registerShutdownHooks();\n\n // Enable internal debug logging if configured\n setDebug(this.config.debug);\n debug(`Initialized: enabled=${this.config.enabled}, endpoint=${this.config.endpoint}`);\n }\n\n get enabled(): boolean {\n return this.tracer.enabled;\n }\n\n set enabled(value: boolean) {\n this.tracer.enabled = value;\n }\n\n // Audit #6: Promise-based shutdown dedup (fixes TOCTOU race condition)\n async shutdown(): Promise<void> {\n if (this._shutdownPromise) return this._shutdownPromise;\n this._shutdownPromise = this._doShutdown();\n return this._shutdownPromise;\n }\n\n private async _doShutdown(): Promise<void> {\n debug('Shutting down...');\n\n // Audit #3: Remove process listeners to prevent leak\n for (const { signal, handler } of this._shutdownHandlers) {\n process.removeListener(signal, handler);\n }\n this._shutdownHandlers = [];\n\n await this.processor.shutdown();\n }\n\n async flush(): Promise<void> {\n await this.processor.flush();\n }\n\n private _registerShutdownHooks(): void {\n const onShutdown = () => {\n // Audit #3: Add 5s timeout to prevent hanging on signal\n const timeout = setTimeout(() => process.exit(1), 5000);\n timeout.unref();\n this.shutdown().catch(() => {}).finally(() => clearTimeout(timeout));\n };\n\n const signals = ['beforeExit', 'SIGTERM', 'SIGINT'];\n for (const signal of signals) {\n process.once(signal, onShutdown);\n this._shutdownHandlers.push({ signal, handler: onShutdown });\n }\n }\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\n/**\n * Initialize the Risicare SDK. Call once at application startup.\n *\n * @example\n * import { init } from 'risicare';\n * init({ apiKey: 'rsk-...', serviceName: 'my-agent', environment: 'production' });\n */\nexport function init(config?: Partial<RisicareConfig>): void {\n if (getGlobalClient()) {\n debug('Already initialized. Call shutdown() first to re-initialize.');\n return;\n }\n\n const client = new RisicareClient(config);\n setGlobalClient(client);\n setGlobalTracer(client.tracer);\n}\n\n/**\n * Gracefully shut down the SDK. Flushes pending spans before resolving.\n */\nexport async function shutdown(): Promise<void> {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client) return;\n await client.shutdown();\n setGlobalClient(undefined);\n setGlobalTracer(undefined);\n}\n\n/**\n * Flush all pending spans without shutting down.\n */\nexport async function flush(): Promise<void> {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client) return;\n await client.flush();\n}\n\n/**\n * Enable tracing at runtime.\n */\nexport function enable(): void {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (client) client.enabled = true;\n}\n\n/**\n * Disable tracing at runtime. Spans will not be created or exported.\n */\nexport function disable(): void {\n const client = getGlobalClient() as RisicareClient | undefined;\n if (client) client.enabled = false;\n}\n\n/**\n * Check whether tracing is currently enabled.\n */\nexport function isEnabled(): boolean {\n const client = getGlobalClient() as RisicareClient | undefined;\n return client?.enabled ?? false;\n}\n\n/**\n * Get the global tracer instance. Returns undefined if not initialized.\n */\nexport function getTracer(): Tracer | undefined {\n return getGlobalTracer() as Tracer | undefined;\n}\n\n/**\n * Get the global tracer, or throw if not initialized.\n * @internal Used by decorators and providers that require an active tracer.\n */\nexport function requireTracer(): Tracer {\n const tracer = getGlobalTracer() as Tracer | undefined;\n if (!tracer) {\n throw new Error(\n 'Risicare SDK not initialized. Call init() before using tracing features.',\n );\n }\n return tracer;\n}\n\n/**\n * Check whether content tracing (prompt/completion capture) is enabled.\n */\nexport function getTraceContent(): boolean {\n const tracer = getGlobalTracer() as Tracer | undefined;\n return tracer?.traceContent ?? true;\n}\n\n/**\n * Get SDK metrics: exported spans, dropped spans, failed exports, queue stats.\n * Returns zero-valued metrics if SDK is not initialized.\n */\nexport function getMetrics() {\n const client = getGlobalClient() as RisicareClient | undefined;\n return client?.processor.getMetrics() ?? {\n exportedSpans: 0,\n droppedSpans: 0,\n failedExports: 0,\n queueSize: 0,\n queueCapacity: 0,\n queueUtilization: 0,\n };\n}\n\n// ─── reportError ──────────────────────────────────────────────────────────\n\n/**\n * Report a caught exception to the self-healing pipeline.\n *\n * Creates an error span that triggers diagnosis and fix generation.\n * This function never throws and is non-blocking.\n *\n * @param error - The caught exception (Error object or string)\n * @param options - Optional attributes and context overrides\n */\nexport function reportError(\n error: unknown,\n options?: { name?: string; attributes?: Record<string, unknown> },\n): void {\n try {\n const tracer = getTracer();\n if (!tracer) return;\n\n const err = error instanceof Error ? error : new Error(String(error));\n const spanName = options?.name ?? `error:${err.constructor.name}`;\n\n tracer.startSpan({ name: spanName, kind: SpanKind.INTERNAL }, (span) => {\n span.setStatus(SpanStatus.ERROR, err.message);\n span.setAttribute('error', true);\n span.setAttribute('error.type', err.constructor.name);\n span.setAttribute('error.message', err.message.slice(0, 2000));\n if (err.stack) span.setAttribute('error.stack', err.stack.slice(0, 4000));\n span.setAttribute('risicare.reported_error', true);\n if (options?.attributes) {\n for (const [k, v] of Object.entries(options.attributes)) {\n span.setAttribute(k, v);\n }\n }\n });\n } catch {\n // Never crash the host application\n debug('reportError failed');\n }\n}\n\n// ─── score ─────────────────────────────────────────────────────────────────\n\n/**\n * Record a custom evaluation score on a trace.\n *\n * Sends the score to the server in a fire-and-forget fashion.\n * This function never throws and is non-blocking.\n *\n * @param traceId - The trace to score\n * @param name - Score name (e.g., \"accuracy\", \"user_satisfaction\")\n * @param value - Score value between 0.0 and 1.0 inclusive\n * @param options - Optional span_id and comment\n */\nexport function score(\n traceId: string,\n name: string,\n value: number,\n options?: { spanId?: string; comment?: string },\n): void {\n try {\n if (typeof value !== 'number' || value < 0.0 || value > 1.0) {\n debug(`score: value must be in [0.0, 1.0], got ${value}. Score not sent.`);\n return;\n }\n if (!traceId || !name) {\n debug('score: traceId and name are required');\n return;\n }\n\n const client = getGlobalClient() as RisicareClient | undefined;\n if (!client?.enabled || !client.config.apiKey) return;\n\n const endpoint = client.config.endpoint.replace(/\\/$/, '');\n const url = `${endpoint}/api/v1/scores`;\n const body = JSON.stringify({\n trace_id: traceId,\n name,\n score: value,\n source: 'sdk',\n ...(options?.spanId && { span_id: options.spanId }),\n ...(options?.comment && { comment: options.comment }),\n });\n\n // Fire-and-forget — never blocks caller\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${client.config.apiKey}`,\n },\n body,\n }).catch((err) => debug(`score: send failed: ${err}`));\n } catch {\n // Never crash the host application\n debug('score failed');\n }\n}\n","/**\n * Double-tracing prevention for framework integrations.\n *\n * When a framework integration (e.g., LlamaIndex handler) creates its own\n * LLM span, the underlying provider proxy (e.g., patchOpenAI) would also\n * create a duplicate span. This module provides suppression:\n *\n * - Framework integrations SET suppression via suppressProviderInstrumentation()\n * - Provider proxies CHECK via isProviderInstrumentationSuppressed() and skip\n *\n * Scoped to AsyncLocalStorage — concurrent calls are independent.\n */\n\nimport { getContext, runWithContext } from './storage.js';\n\n/**\n * Run a callback with provider instrumentation suppressed.\n *\n * During this callback, all provider instrumentors (patchOpenAI, etc.) will\n * skip span creation. The framework is responsible for creating the span.\n *\n * @param fn - The function to run with suppression active\n * @returns The function's return value\n */\nexport function suppressProviderInstrumentation<T>(fn: () => T): T {\n return runWithContext({ _suppressProviderInstrumentation: true }, fn);\n}\n\n/**\n * Check if provider instrumentation should be suppressed.\n *\n * Called by provider instrumentors as an early-exit guard. When true,\n * the provider calls the original method directly without creating a span.\n */\nexport function isProviderInstrumentationSuppressed(): boolean {\n return getContext()._suppressProviderInstrumentation === true;\n}\n"],"mappings":"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","names":["getTracer","getTracer"]}
|