@introspection-sdk/introspection-node 0.4.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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-check-types.log +5 -0
- package/.turbo/turbo-lint.log +5 -0
- package/dist/ai-sdk-integration.d.ts +123 -0
- package/dist/ai-sdk-integration.d.ts.map +1 -0
- package/dist/ai-sdk-integration.js +475 -0
- package/dist/anthropic.d.ts +54 -0
- package/dist/anthropic.d.ts.map +1 -0
- package/dist/anthropic.js +375 -0
- package/dist/claude-hooks.d.ts +328 -0
- package/dist/claude-hooks.d.ts.map +1 -0
- package/dist/claude-hooks.js +571 -0
- package/dist/claude-wrapper.d.ts +93 -0
- package/dist/claude-wrapper.d.ts.map +1 -0
- package/dist/claude-wrapper.js +154 -0
- package/dist/client.d.ts +157 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +394 -0
- package/dist/converters/ai-sdk.d.ts +65 -0
- package/dist/converters/ai-sdk.d.ts.map +1 -0
- package/dist/converters/ai-sdk.js +238 -0
- package/dist/converters/claude.d.ts +146 -0
- package/dist/converters/claude.d.ts.map +1 -0
- package/dist/converters/claude.js +202 -0
- package/dist/converters/index.d.ts +9 -0
- package/dist/converters/index.d.ts.map +1 -0
- package/dist/converters/index.js +8 -0
- package/dist/converters/openai.d.ts +51 -0
- package/dist/converters/openai.d.ts.map +1 -0
- package/dist/converters/openai.js +268 -0
- package/dist/converters/openclaw.d.ts +16 -0
- package/dist/converters/openclaw.d.ts.map +1 -0
- package/dist/converters/openclaw.js +49 -0
- package/dist/converters/openinference.d.ts +107 -0
- package/dist/converters/openinference.d.ts.map +1 -0
- package/dist/converters/openinference.js +552 -0
- package/dist/converters/vercel.d.ts +21 -0
- package/dist/converters/vercel.d.ts.map +1 -0
- package/dist/converters/vercel.js +208 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/langchain-handler.d.ts +101 -0
- package/dist/langchain-handler.d.ts.map +1 -0
- package/dist/langchain-handler.js +489 -0
- package/dist/mastra-exporter.d.ts +85 -0
- package/dist/mastra-exporter.d.ts.map +1 -0
- package/dist/mastra-exporter.js +471 -0
- package/dist/span-processor.d.ts +62 -0
- package/dist/span-processor.d.ts.map +1 -0
- package/dist/span-processor.js +310 -0
- package/dist/tracing-processor.d.ts +136 -0
- package/dist/tracing-processor.d.ts.map +1 -0
- package/dist/tracing-processor.js +368 -0
- package/dist/types/genai.d.ts +165 -0
- package/dist/types/genai.d.ts.map +1 -0
- package/dist/types/genai.js +82 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +57 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/eslint.config.mjs +4 -0
- package/package.json +78 -0
- package/src/ai-sdk-integration.ts +689 -0
- package/src/anthropic.ts +465 -0
- package/src/claude-hooks.ts +1010 -0
- package/src/claude-wrapper.ts +240 -0
- package/src/client.ts +513 -0
- package/src/converters/ai-sdk.ts +298 -0
- package/src/converters/claude.ts +334 -0
- package/src/converters/index.ts +44 -0
- package/src/converters/openai.ts +302 -0
- package/src/converters/openinference.ts +673 -0
- package/src/converters/vercel.ts +264 -0
- package/src/index.ts +121 -0
- package/src/langchain-handler.ts +722 -0
- package/src/mastra-exporter.ts +650 -0
- package/src/span-processor.ts +418 -0
- package/src/tracing-processor.ts +548 -0
- package/src/types/genai.ts +264 -0
- package/src/types.ts +13 -0
- package/src/utils.ts +69 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converter for Vercel AI SDK telemetry spans → Gen AI semantic conventions.
|
|
3
|
+
*
|
|
4
|
+
* The Vercel AI SDK emits spans with `ai.*` attributes when
|
|
5
|
+
* `experimental_telemetry: { isEnabled: true }` is set on streamText/generateText.
|
|
6
|
+
* This converter translates those to `gen_ai.*` so the Introspection frontend
|
|
7
|
+
* can render them in the conversation view.
|
|
8
|
+
*/
|
|
9
|
+
/** Check if a span is a Vercel AI SDK span worth converting.
|
|
10
|
+
* Only converts child "do*" spans (doStream, doGenerate) which have
|
|
11
|
+
* the actual prompt/response data with proper message windows.
|
|
12
|
+
* Parent wrapper spans (ai.streamText, ai.generateText) are skipped
|
|
13
|
+
* to avoid duplicate conversation steps without user messages. */
|
|
14
|
+
export function isVercelAISpan(attrs) {
|
|
15
|
+
const operationId = attrs["ai.operationId"];
|
|
16
|
+
return typeof operationId === "string" && operationId.includes(".do");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Convert Vercel AI SDK `ai.*` attributes to `gen_ai.*` semconv attributes.
|
|
20
|
+
* Returns only the gen_ai attributes to merge — does NOT remove originals.
|
|
21
|
+
*/
|
|
22
|
+
export function convertVercelAIToGenAI(attrs) {
|
|
23
|
+
const result = {};
|
|
24
|
+
// gen_ai.operation.name
|
|
25
|
+
result["gen_ai.operation.name"] = "chat";
|
|
26
|
+
// gen_ai.usage.cache_read.input_tokens from ai.usage.cachedInputTokens
|
|
27
|
+
const cachedInput = attrs["ai.usage.cachedInputTokens"];
|
|
28
|
+
if (typeof cachedInput === "number") {
|
|
29
|
+
result["gen_ai.usage.cache_read.input_tokens"] = cachedInput;
|
|
30
|
+
}
|
|
31
|
+
// gen_ai.conversation.id from telemetry metadata (set by app)
|
|
32
|
+
const metadataConvId = attrs["ai.telemetry.metadata.gen_ai.conversation.id"];
|
|
33
|
+
if (typeof metadataConvId === "string") {
|
|
34
|
+
result["gen_ai.conversation.id"] = metadataConvId;
|
|
35
|
+
}
|
|
36
|
+
// gen_ai.request.model and gen_ai.system from ai.model.*
|
|
37
|
+
const modelId = attrs["ai.model.id"];
|
|
38
|
+
if (typeof modelId === "string" && !attrs["gen_ai.request.model"]) {
|
|
39
|
+
result["gen_ai.request.model"] = modelId;
|
|
40
|
+
}
|
|
41
|
+
const modelProvider = attrs["ai.model.provider"];
|
|
42
|
+
if (typeof modelProvider === "string" && !attrs["gen_ai.system"]) {
|
|
43
|
+
result["gen_ai.system"] = modelProvider;
|
|
44
|
+
}
|
|
45
|
+
// Vercel AI SDK stores prompt data in two formats:
|
|
46
|
+
// - Child spans (doStream): flat keys like ai.prompt.messages, ai.prompt.toolChoice
|
|
47
|
+
// - Parent spans (streamText): single JSON string in ai.prompt
|
|
48
|
+
const promptMessages = attrs["ai.prompt.messages"];
|
|
49
|
+
const promptRaw = attrs["ai.prompt"];
|
|
50
|
+
let parsedMessages = null;
|
|
51
|
+
let parsedSystem = null;
|
|
52
|
+
if (typeof promptMessages === "string") {
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(promptMessages);
|
|
55
|
+
if (Array.isArray(parsed))
|
|
56
|
+
parsedMessages = parsed;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
/* ignore */
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (typeof promptRaw === "string") {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(promptRaw);
|
|
65
|
+
if (Array.isArray(parsed?.messages))
|
|
66
|
+
parsedMessages = parsed.messages;
|
|
67
|
+
if (typeof parsed?.system === "string")
|
|
68
|
+
parsedSystem = parsed.system;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
/* ignore */
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// gen_ai.input.messages — excluding system messages
|
|
75
|
+
const nonSystemMessages = parsedMessages
|
|
76
|
+
? parsedMessages.filter((m) => m.role !== "system")
|
|
77
|
+
: null;
|
|
78
|
+
if (nonSystemMessages && nonSystemMessages.length > 0) {
|
|
79
|
+
const converted = nonSystemMessages.map(convertVercelMessageToGenAI);
|
|
80
|
+
result["gen_ai.input.messages"] = JSON.stringify(converted);
|
|
81
|
+
}
|
|
82
|
+
// gen_ai.output.messages — build from ai.response.text + ai.response.reasoning
|
|
83
|
+
const responseText = attrs["ai.response.text"];
|
|
84
|
+
const responseReasoning = attrs["ai.response.reasoning"];
|
|
85
|
+
if (typeof responseText === "string" && responseText) {
|
|
86
|
+
const parts = [];
|
|
87
|
+
if (typeof responseReasoning === "string" && responseReasoning) {
|
|
88
|
+
parts.push({ type: "thinking", content: responseReasoning });
|
|
89
|
+
}
|
|
90
|
+
parts.push({ type: "text", content: responseText });
|
|
91
|
+
result["gen_ai.output.messages"] = JSON.stringify([
|
|
92
|
+
{ role: "assistant", parts },
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
// gen_ai.tool.definitions — parse ai.prompt.tools JSON strings
|
|
96
|
+
const promptTools = attrs["ai.prompt.tools"];
|
|
97
|
+
if (typeof promptTools === "string") {
|
|
98
|
+
try {
|
|
99
|
+
const parsed = JSON.parse(promptTools);
|
|
100
|
+
if (Array.isArray(parsed)) {
|
|
101
|
+
result["gen_ai.tool.definitions"] = JSON.stringify(parsed
|
|
102
|
+
.map((t) => {
|
|
103
|
+
if (typeof t === "string") {
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(t);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return { name: t };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return t;
|
|
112
|
+
})
|
|
113
|
+
.map((t) => ({
|
|
114
|
+
type: t.type || "function",
|
|
115
|
+
name: t.name || "",
|
|
116
|
+
description: t.description || "",
|
|
117
|
+
parameters: t.inputSchema || t.parameters || undefined,
|
|
118
|
+
})));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// ignore
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (Array.isArray(promptTools)) {
|
|
126
|
+
const tools = promptTools.map((t) => {
|
|
127
|
+
const parsed = (typeof t === "string" ? JSON.parse(t) : t);
|
|
128
|
+
return {
|
|
129
|
+
type: parsed.type || "function",
|
|
130
|
+
name: parsed.name || "",
|
|
131
|
+
description: parsed.description || "",
|
|
132
|
+
parameters: parsed.inputSchema || parsed.parameters || undefined,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
result["gen_ai.tool.definitions"] = JSON.stringify(tools);
|
|
136
|
+
}
|
|
137
|
+
// gen_ai.agent.name — from telemetry functionId or operation
|
|
138
|
+
const functionId = attrs["ai.telemetry.functionId"];
|
|
139
|
+
if (typeof functionId === "string" && functionId) {
|
|
140
|
+
result["gen_ai.agent.name"] = functionId;
|
|
141
|
+
}
|
|
142
|
+
// gen_ai.system_instructions — from parsed system prompt or system role messages
|
|
143
|
+
if (parsedSystem) {
|
|
144
|
+
result["gen_ai.system_instructions"] = JSON.stringify([
|
|
145
|
+
{ type: "text", content: parsedSystem },
|
|
146
|
+
]);
|
|
147
|
+
}
|
|
148
|
+
else if (parsedMessages) {
|
|
149
|
+
const systemMsgs = parsedMessages.filter((m) => m.role === "system");
|
|
150
|
+
if (systemMsgs.length > 0) {
|
|
151
|
+
result["gen_ai.system_instructions"] = JSON.stringify(systemMsgs.map((m) => ({
|
|
152
|
+
type: "text",
|
|
153
|
+
content: typeof m.content === "string"
|
|
154
|
+
? m.content
|
|
155
|
+
: JSON.stringify(m.content),
|
|
156
|
+
})));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
function convertVercelMessageToGenAI(msg) {
|
|
162
|
+
const role = msg.role || "user";
|
|
163
|
+
if (role === "system") {
|
|
164
|
+
return {
|
|
165
|
+
role,
|
|
166
|
+
parts: [{ type: "text", content: extractTextContent(msg.content) }],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
role,
|
|
171
|
+
parts: extractParts(msg.content),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function extractTextContent(content) {
|
|
175
|
+
if (typeof content === "string")
|
|
176
|
+
return content;
|
|
177
|
+
if (Array.isArray(content)) {
|
|
178
|
+
return content
|
|
179
|
+
.filter((p) => p.type === "text")
|
|
180
|
+
.map((p) => p.text || p.content || "")
|
|
181
|
+
.join("");
|
|
182
|
+
}
|
|
183
|
+
return String(content || "");
|
|
184
|
+
}
|
|
185
|
+
function extractParts(content) {
|
|
186
|
+
if (typeof content === "string") {
|
|
187
|
+
return [{ type: "text", content }];
|
|
188
|
+
}
|
|
189
|
+
if (Array.isArray(content)) {
|
|
190
|
+
return content.map((part) => {
|
|
191
|
+
if (part.type === "text") {
|
|
192
|
+
return { type: "text", content: part.text || part.content || "" };
|
|
193
|
+
}
|
|
194
|
+
if (part.type === "tool-call" || part.type === "tool_call") {
|
|
195
|
+
return {
|
|
196
|
+
type: "tool_call",
|
|
197
|
+
name: part.toolName || part.name || "",
|
|
198
|
+
id: part.toolCallId || part.id || "",
|
|
199
|
+
arguments: typeof part.args === "string"
|
|
200
|
+
? part.args
|
|
201
|
+
: JSON.stringify(part.args),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return { type: "text", content: JSON.stringify(part) };
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return [{ type: "text", content: String(content || "") }];
|
|
208
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
2
|
+
import type { IntrospectionSpanProcessorOptions } from "./span-processor.js";
|
|
3
|
+
/**
|
|
4
|
+
* Factory that creates an {@link IntrospectionSpanProcessor}.
|
|
5
|
+
*
|
|
6
|
+
* Provided as the default export for convenient use with logfire's
|
|
7
|
+
* `additionalSpanProcessors` option.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Optional processor configuration (token, serviceName, etc.).
|
|
10
|
+
* @returns A ready-to-use {@link IntrospectionSpanProcessor}.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import introspectionSpanProcessor from "@introspection-sdk/introspection-node";
|
|
15
|
+
*
|
|
16
|
+
* logfire.configure({ additionalSpanProcessors: [introspectionSpanProcessor()] });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export default function introspectionSpanProcessor(options?: IntrospectionSpanProcessorOptions): IntrospectionSpanProcessor;
|
|
20
|
+
export { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
21
|
+
export type { IntrospectionSpanProcessorOptions } from "./span-processor.js";
|
|
22
|
+
export { IntrospectionClient } from "./client.js";
|
|
23
|
+
export type { AdvancedOptions, IntrospectionClientOptions, FeedbackOptions, UserTraits, } from "./types.js";
|
|
24
|
+
export { IntrospectionTracingProcessor } from "./tracing-processor.js";
|
|
25
|
+
export type { IntrospectionTracingProcessorOptions, TracingProcessorAdvancedOptions, } from "./tracing-processor.js";
|
|
26
|
+
export { IntrospectionClaudeHooks } from "./claude-hooks.js";
|
|
27
|
+
export type { IntrospectionClaudeHooksOptions, ClaudeHooksAdvancedOptions, ClaudeHooksConfig, ClaudeHookCallbackMatcher, ClaudeHookEvent, ClaudeHookInput, ClaudeHookOutput, ClaudeHookCallback, ClaudeUsage, ClaudeModelUsage, ClaudeResultMessage, ClaudeAssistantMessage, ClaudeSDKMessage, } from "./claude-hooks.js";
|
|
28
|
+
export { withIntrospection } from "./claude-wrapper.js";
|
|
29
|
+
export type { WithIntrospectionOptions, InstrumentedClaudeAgentSDK, ClaudeAgentSDKModule, } from "./claude-wrapper.js";
|
|
30
|
+
export type { GenAiAttributes, InputMessage, OutputMessage, SystemInstruction, ToolDefinition, TextPart, ToolCallRequestPart, ToolCallResponsePart, MessagePart, } from "./types/genai.js";
|
|
31
|
+
export { toAttributes } from "./types/genai.js";
|
|
32
|
+
export { convertResponsesInputsToSemconv, convertResponsesOutputsToSemconv, convertResponsesToolsToSemconv, convertResponsesInstructionsToSemconv, } from "./converters/openai.js";
|
|
33
|
+
export type { ResponseInputItem, ResponseOutputItem, ResponseTool, ResponseUsage, Response as OpenAIResponse, } from "./converters/openai.js";
|
|
34
|
+
export { IntrospectionAISDKIntegration } from "./ai-sdk-integration.js";
|
|
35
|
+
export type { IntrospectionAISDKIntegrationOptions, AISDKIntegrationAdvancedOptions, } from "./ai-sdk-integration.js";
|
|
36
|
+
export { addOpenInferenceAttributes, OpenInferenceSpanExporter, } from "./converters/openinference.js";
|
|
37
|
+
export { AnthropicInstrumentor, tracedMessagesCreate, REDACTED_THINKING_CONTENT, } from "./anthropic.js";
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,qBAAqB,CAAC;AAE7E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,OAAO,CAAC,EAAE,iCAAiC,GAC1C,0BAA0B,CAE5B;AAGD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EAAE,iCAAiC,EAAE,MAAM,qBAAqB,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,YAAY,EACV,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,YAAY,EACV,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EACV,+BAA+B,EAC/B,0BAA0B,EAC1B,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,EAChC,8BAA8B,EAC9B,qCAAqC,GACtC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,QAAQ,IAAI,cAAc,GAC3B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,YAAY,EACV,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
2
|
+
/**
|
|
3
|
+
* Factory that creates an {@link IntrospectionSpanProcessor}.
|
|
4
|
+
*
|
|
5
|
+
* Provided as the default export for convenient use with logfire's
|
|
6
|
+
* `additionalSpanProcessors` option.
|
|
7
|
+
*
|
|
8
|
+
* @param options - Optional processor configuration (token, serviceName, etc.).
|
|
9
|
+
* @returns A ready-to-use {@link IntrospectionSpanProcessor}.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import introspectionSpanProcessor from "@introspection-sdk/introspection-node";
|
|
14
|
+
*
|
|
15
|
+
* logfire.configure({ additionalSpanProcessors: [introspectionSpanProcessor()] });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export default function introspectionSpanProcessor(options) {
|
|
19
|
+
return new IntrospectionSpanProcessor(options);
|
|
20
|
+
}
|
|
21
|
+
// Span processor exports (for OpenTelemetry integration)
|
|
22
|
+
export { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
23
|
+
// Client exports
|
|
24
|
+
export { IntrospectionClient } from "./client.js";
|
|
25
|
+
// Tracing processor exports (for OpenAI Agents SDK integration)
|
|
26
|
+
export { IntrospectionTracingProcessor } from "./tracing-processor.js";
|
|
27
|
+
// Claude Agent SDK hooks exports
|
|
28
|
+
export { IntrospectionClaudeHooks } from "./claude-hooks.js";
|
|
29
|
+
// Claude Agent SDK wrapper exports
|
|
30
|
+
export { withIntrospection } from "./claude-wrapper.js";
|
|
31
|
+
export { toAttributes } from "./types/genai.js";
|
|
32
|
+
// OpenAI converter exports
|
|
33
|
+
export { convertResponsesInputsToSemconv, convertResponsesOutputsToSemconv, convertResponsesToolsToSemconv, convertResponsesInstructionsToSemconv, } from "./converters/openai.js";
|
|
34
|
+
// AI SDK integration exports (for Vercel AI SDK)
|
|
35
|
+
export { IntrospectionAISDKIntegration } from "./ai-sdk-integration.js";
|
|
36
|
+
// OpenInference converter exports
|
|
37
|
+
export { addOpenInferenceAttributes, OpenInferenceSpanExporter, } from "./converters/openinference.js";
|
|
38
|
+
// Anthropic instrumentor exports
|
|
39
|
+
export { AnthropicInstrumentor, tracedMessagesCreate, REDACTED_THINKING_CONTENT, } from "./anthropic.js";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain/LangGraph Callback Handler for Introspection.
|
|
3
|
+
*
|
|
4
|
+
* Hooks into LangChain's native callback system to capture LLM, tool, and
|
|
5
|
+
* chain interactions as gen_ai.* OTel spans for the Introspection backend.
|
|
6
|
+
*
|
|
7
|
+
* Similar to IntrospectionTracingProcessor for OpenAI Agents SDK and
|
|
8
|
+
* IntrospectionClaudeHooks for Claude Agent SDK.
|
|
9
|
+
*
|
|
10
|
+
* **Important:** This module requires `@langchain/core` at runtime.
|
|
11
|
+
* Import via the subpath: `@introspection-sdk/introspection-node/langchain`
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { IntrospectionCallbackHandler } from "@introspection-sdk/introspection-node/langchain";
|
|
16
|
+
* import { ChatOpenAI } from "@langchain/openai";
|
|
17
|
+
*
|
|
18
|
+
* const handler = new IntrospectionCallbackHandler({
|
|
19
|
+
* serviceName: "my-langchain-app",
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* const model = new ChatOpenAI({ modelName: "gpt-4o" });
|
|
23
|
+
* const response = await model.invoke("Hello!", { callbacks: [handler] });
|
|
24
|
+
*
|
|
25
|
+
* await handler.shutdown();
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
29
|
+
import type { Serialized } from "@langchain/core/load/serializable";
|
|
30
|
+
import type { LLMResult } from "@langchain/core/outputs";
|
|
31
|
+
import type { BaseMessage } from "@langchain/core/messages";
|
|
32
|
+
import type { ChainValues } from "@langchain/core/utils/types";
|
|
33
|
+
import { type SpanExporter, type IdGenerator } from "@opentelemetry/sdk-trace-base";
|
|
34
|
+
/** Advanced options for testing and customization. */
|
|
35
|
+
export interface LangChainHandlerAdvancedOptions {
|
|
36
|
+
/** Custom span exporter for testing. */
|
|
37
|
+
spanExporter?: SpanExporter;
|
|
38
|
+
/** Custom ID generator for testing. */
|
|
39
|
+
idGenerator?: IdGenerator;
|
|
40
|
+
/** Use SimpleSpanProcessor instead of BatchSpanProcessor. */
|
|
41
|
+
useSimpleSpanProcessor?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Configuration for {@link IntrospectionCallbackHandler}. */
|
|
44
|
+
export interface IntrospectionCallbackHandlerOptions {
|
|
45
|
+
/** Authentication token (env: INTROSPECTION_TOKEN). */
|
|
46
|
+
token?: string;
|
|
47
|
+
/** Base URL for the API (env: INTROSPECTION_BASE_URL). */
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
/** Service name for telemetry (env: INTROSPECTION_SERVICE_NAME). */
|
|
50
|
+
serviceName?: string;
|
|
51
|
+
/** Additional headers to include in requests. */
|
|
52
|
+
additionalHeaders?: Record<string, string>;
|
|
53
|
+
/** Advanced options for testing. */
|
|
54
|
+
advanced?: LangChainHandlerAdvancedOptions;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* LangChain callback handler that captures LLM, tool, and chain events
|
|
58
|
+
* as gen_ai.* OTel spans and exports them to the Introspection backend.
|
|
59
|
+
*
|
|
60
|
+
* Pass as a callback to any LangChain invoke call, or set globally via
|
|
61
|
+
* `setGlobalHandler()`.
|
|
62
|
+
*/
|
|
63
|
+
export declare class IntrospectionCallbackHandler extends BaseCallbackHandler {
|
|
64
|
+
name: string;
|
|
65
|
+
private _tracerProvider;
|
|
66
|
+
private _tracer;
|
|
67
|
+
private _spans;
|
|
68
|
+
private _rootSpan;
|
|
69
|
+
private _conversationId;
|
|
70
|
+
private _spanNames;
|
|
71
|
+
private _spanParents;
|
|
72
|
+
private static _wrapperNames;
|
|
73
|
+
private _llmInputs;
|
|
74
|
+
constructor(options?: IntrospectionCallbackHandlerOptions);
|
|
75
|
+
/** Get or create a root span so all callbacks share the same traceId. */
|
|
76
|
+
private _ensureRoot;
|
|
77
|
+
/** Create a child span under the root (or under a parent if provided).
|
|
78
|
+
* Sets gen_ai.agent.name to the parent span's name for hierarchy. */
|
|
79
|
+
private _createChildSpan;
|
|
80
|
+
handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, _tags?: string[], metadata?: Record<string, unknown>, runName?: string): void;
|
|
81
|
+
handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, _tags?: string[], metadata?: Record<string, unknown>, runName?: string): void;
|
|
82
|
+
handleLLMEnd(output: LLMResult, runId: string): void;
|
|
83
|
+
handleLLMError(err: Error, runId: string): void;
|
|
84
|
+
handleChainStart(chain: Serialized, _inputs: ChainValues, runId: string, _runType?: string, _tags?: string[], metadata?: Record<string, unknown>, runName?: string, parentRunId?: string): void;
|
|
85
|
+
handleChainEnd(_outputs: ChainValues, runId: string): void;
|
|
86
|
+
handleChainError(err: Error, runId: string): void;
|
|
87
|
+
handleToolStart(tool: Serialized, input: string, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record<string, unknown>, runName?: string): void;
|
|
88
|
+
handleToolEnd(output: unknown, runId: string): void;
|
|
89
|
+
handleToolError(err: Error, runId: string): void;
|
|
90
|
+
shutdown(): Promise<void>;
|
|
91
|
+
forceFlush(): Promise<void>;
|
|
92
|
+
private _extractModelName;
|
|
93
|
+
private _extractProvider;
|
|
94
|
+
/** Walk up the span tree to find the first non-wrapper span name. */
|
|
95
|
+
private _findAgentName;
|
|
96
|
+
private _getConversationId;
|
|
97
|
+
private _convertMessages;
|
|
98
|
+
private _mapRole;
|
|
99
|
+
private _extractContent;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=langchain-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain-handler.d.ts","sourceRoot":"","sources":["../src/langchain-handler.ts"],"names":[],"mappings":"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"}
|