@introspection-sdk/introspection-node 0.4.1 → 0.4.3
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 +1 -1
- package/.turbo/turbo-check-types.log +4 -0
- package/.turbo/turbo-lint.log +5 -0
- package/dist/ai-sdk-integration.d.ts.map +1 -1
- package/dist/ai-sdk-integration.js +2 -2
- package/dist/claude-hooks.d.ts.map +1 -1
- package/dist/claude-hooks.js +3 -3
- package/dist/client.d.ts +42 -132
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +66 -365
- package/dist/client.js.map +1 -0
- package/dist/converters/claude.d.ts +5 -1
- package/dist/converters/claude.d.ts.map +1 -1
- package/dist/converters/claude.js +7 -0
- package/dist/converters/claude.js.map +1 -0
- package/dist/converters/gemini.d.ts +90 -0
- package/dist/converters/gemini.d.ts.map +1 -0
- package/dist/converters/gemini.js +171 -0
- package/dist/converters/gemini.js.map +1 -0
- package/dist/converters/index.d.ts +1 -1
- package/dist/converters/index.d.ts.map +1 -1
- package/dist/converters/index.js +2 -1
- package/dist/converters/index.js.map +1 -0
- package/dist/converters/openai.js +1 -0
- package/dist/converters/openai.js.map +1 -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.js +1 -0
- package/dist/converters/openinference.js.map +1 -0
- package/dist/converters/vercel.d.ts.map +1 -1
- package/dist/converters/vercel.js +31 -3
- package/dist/converters/vercel.js.map +1 -0
- package/dist/http.d.ts +36 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +145 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +24 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -32
- package/dist/index.js.map +1 -0
- package/dist/langchain-handler.d.ts.map +1 -1
- package/dist/langchain-handler.js +2 -2
- package/dist/mastra-exporter.d.ts.map +1 -1
- package/dist/mastra-exporter.js +2 -2
- package/dist/otel/anthropic.d.ts +62 -0
- package/dist/otel/anthropic.d.ts.map +1 -0
- package/dist/otel/anthropic.js +425 -0
- package/dist/otel/anthropic.js.map +1 -0
- package/dist/otel/claude-hooks.d.ts +346 -0
- package/dist/otel/claude-hooks.d.ts.map +1 -0
- package/dist/otel/claude-hooks.js +645 -0
- package/dist/otel/claude-hooks.js.map +1 -0
- package/dist/otel/claude-wrapper.d.ts +93 -0
- package/dist/otel/claude-wrapper.d.ts.map +1 -0
- package/dist/otel/claude-wrapper.js +155 -0
- package/dist/otel/claude-wrapper.js.map +1 -0
- package/dist/otel/gemini.d.ts +48 -0
- package/dist/otel/gemini.d.ts.map +1 -0
- package/dist/otel/gemini.js +297 -0
- package/dist/otel/gemini.js.map +1 -0
- package/dist/otel/index.d.ts +27 -0
- package/dist/otel/index.d.ts.map +1 -0
- package/dist/otel/index.js +33 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/otel/langchain-handler.d.ts +112 -0
- package/dist/otel/langchain-handler.d.ts.map +1 -0
- package/dist/otel/langchain-handler.js +555 -0
- package/dist/otel/langchain-handler.js.map +1 -0
- package/dist/otel/logs.d.ts +82 -0
- package/dist/otel/logs.d.ts.map +1 -0
- package/dist/otel/logs.js +271 -0
- package/dist/otel/logs.js.map +1 -0
- package/dist/otel/mastra-exporter.d.ts +87 -0
- package/dist/otel/mastra-exporter.d.ts.map +1 -0
- package/dist/otel/mastra-exporter.js +525 -0
- package/dist/otel/mastra-exporter.js.map +1 -0
- package/dist/otel/pi.d.ts +59 -0
- package/dist/otel/pi.d.ts.map +1 -0
- package/dist/otel/pi.js +67 -0
- package/dist/otel/pi.js.map +1 -0
- package/dist/otel/setup.d.ts +23 -0
- package/dist/otel/setup.d.ts.map +1 -0
- package/dist/otel/setup.js +127 -0
- package/dist/otel/setup.js.map +1 -0
- package/dist/otel/span-processor.d.ts +62 -0
- package/dist/otel/span-processor.d.ts.map +1 -0
- package/dist/otel/span-processor.js +319 -0
- package/dist/otel/span-processor.js.map +1 -0
- package/dist/otel/tracing-processor.d.ts +139 -0
- package/dist/otel/tracing-processor.d.ts.map +1 -0
- package/dist/otel/tracing-processor.js +418 -0
- package/dist/otel/tracing-processor.js.map +1 -0
- package/dist/resources/experiments.d.ts +31 -0
- package/dist/resources/experiments.d.ts.map +1 -0
- package/dist/resources/experiments.js +133 -0
- package/dist/resources/experiments.js.map +1 -0
- package/dist/resources/recipes.d.ts +22 -0
- package/dist/resources/recipes.d.ts.map +1 -0
- package/dist/resources/recipes.js +61 -0
- package/dist/resources/recipes.js.map +1 -0
- package/dist/resources/runtimes.d.ts +76 -0
- package/dist/resources/runtimes.d.ts.map +1 -0
- package/dist/resources/runtimes.js +179 -0
- package/dist/resources/runtimes.js.map +1 -0
- package/dist/runner-resources/files.d.ts +35 -0
- package/dist/runner-resources/files.d.ts.map +1 -0
- package/dist/runner-resources/files.js +131 -0
- package/dist/runner-resources/files.js.map +1 -0
- package/dist/runner-resources/tasks.d.ts +39 -0
- package/dist/runner-resources/tasks.d.ts.map +1 -0
- package/dist/runner-resources/tasks.js +129 -0
- package/dist/runner-resources/tasks.js.map +1 -0
- package/dist/runner.d.ts +80 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +159 -0
- package/dist/runner.js.map +1 -0
- package/dist/span-processor.d.ts.map +1 -1
- package/dist/span-processor.js +3 -3
- package/dist/streaming.d.ts +8 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +67 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tracing-processor.d.ts.map +1 -1
- package/dist/tracing-processor.js +3 -3
- 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.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.js +1 -0
- package/dist/version.js.map +1 -0
- package/package.json +83 -25
- package/src/client.ts +76 -471
- package/src/converters/claude.ts +11 -1
- package/src/converters/gemini.ts +243 -0
- package/src/converters/index.ts +13 -7
- package/src/converters/vercel.ts +41 -3
- package/src/http.ts +163 -0
- package/src/index.ts +110 -75
- package/src/{anthropic.ts → otel/anthropic.ts} +95 -8
- package/src/{claude-hooks.ts → otel/claude-hooks.ts} +125 -24
- package/src/{claude-wrapper.ts → otel/claude-wrapper.ts} +1 -1
- package/src/otel/gemini.ts +397 -0
- package/src/otel/index.ts +80 -0
- package/src/{langchain-handler.ts → otel/langchain-handler.ts} +56 -7
- package/src/otel/logs.ts +394 -0
- package/src/{mastra-exporter.ts → otel/mastra-exporter.ts} +86 -23
- package/src/otel/pi.ts +88 -0
- package/src/otel/setup.ts +174 -0
- package/src/{span-processor.ts → otel/span-processor.ts} +17 -10
- package/src/{tracing-processor.ts → otel/tracing-processor.ts} +100 -23
- package/src/resources/experiments.ts +170 -0
- package/src/resources/recipes.ts +73 -0
- package/src/resources/runtimes.ts +231 -0
- package/src/runner-resources/files.ts +163 -0
- package/src/runner-resources/tasks.ts +156 -0
- package/src/runner.ts +194 -0
- package/src/streaming.ts +57 -0
- package/src/utils.ts +15 -0
- package/src/ai-sdk-integration.ts +0 -689
- package/src/converters/ai-sdk.ts +0 -323
package/src/index.ts
CHANGED
|
@@ -1,36 +1,18 @@
|
|
|
1
|
-
import { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
2
|
-
import type { IntrospectionSpanProcessorOptions } from "./span-processor.js";
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Provided as the default export for convenient use with logfire's
|
|
8
|
-
* `additionalSpanProcessors` option.
|
|
2
|
+
* Root entry point — REST-only surface.
|
|
9
3
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
4
|
+
* Exports `IntrospectionClient` (REST), Runner / RuntimeHandle /
|
|
5
|
+
* ExperimentHandle, REST wire types, and HTTP helpers. None of these
|
|
6
|
+
* touch the OpenTelemetry SDK.
|
|
12
7
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* import introspectionSpanProcessor from "@introspection-sdk/introspection-node";
|
|
16
|
-
*
|
|
17
|
-
* logfire.configure({ additionalSpanProcessors: [introspectionSpanProcessor()] });
|
|
18
|
-
* ```
|
|
8
|
+
* For the OTel surface (logs, span processors, instrumentors) import
|
|
9
|
+
* from `@introspection-sdk/introspection-node/otel`.
|
|
19
10
|
*/
|
|
20
|
-
export default function introspectionSpanProcessor(
|
|
21
|
-
options?: IntrospectionSpanProcessorOptions,
|
|
22
|
-
): IntrospectionSpanProcessor {
|
|
23
|
-
return new IntrospectionSpanProcessor(options);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Span processor exports (for OpenTelemetry integration)
|
|
27
|
-
export { IntrospectionSpanProcessor } from "./span-processor.js";
|
|
28
|
-
export type { IntrospectionSpanProcessorOptions } from "./span-processor.js";
|
|
29
11
|
|
|
30
|
-
//
|
|
12
|
+
// REST client.
|
|
31
13
|
export { IntrospectionClient } from "./client.js";
|
|
32
14
|
|
|
33
|
-
//
|
|
15
|
+
// Configuration / event types shared with the OTel surface.
|
|
34
16
|
export type {
|
|
35
17
|
AdvancedOptions,
|
|
36
18
|
IntrospectionClientOptions,
|
|
@@ -38,40 +20,98 @@ export type {
|
|
|
38
20
|
UserTraits,
|
|
39
21
|
} from "./types.js";
|
|
40
22
|
|
|
41
|
-
//
|
|
42
|
-
export {
|
|
43
|
-
export type {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
} from "./
|
|
23
|
+
// Runner-bound REST namespaces (runner.tasks, runner.files) + HTTP/SSE.
|
|
24
|
+
export { TasksApi, TaskRunsApi, RunHandle } from "./runner-resources/tasks.js";
|
|
25
|
+
export type { StartParams } from "./runner-resources/tasks.js";
|
|
26
|
+
export { FilesApi, FileVersionsApi } from "./runner-resources/files.js";
|
|
27
|
+
export type { FileUploadBody } from "./runner-resources/files.js";
|
|
28
|
+
export { HttpClient } from "./http.js";
|
|
29
|
+
export type { ResolvedApiConfig } from "./http.js";
|
|
30
|
+
export { parseSse } from "./streaming.js";
|
|
47
31
|
|
|
48
|
-
//
|
|
49
|
-
export {
|
|
50
|
-
export type {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} from "./
|
|
32
|
+
// Runner + CP resources.
|
|
33
|
+
export { Runner } from "./runner.js";
|
|
34
|
+
export type { RunnerSource } from "./runner.js";
|
|
35
|
+
export {
|
|
36
|
+
RuntimesApi,
|
|
37
|
+
RuntimeHandle,
|
|
38
|
+
attachRuntimes,
|
|
39
|
+
isUuid,
|
|
40
|
+
} from "./resources/runtimes.js";
|
|
41
|
+
export type { RuntimeHandleFactory } from "./resources/runtimes.js";
|
|
42
|
+
export {
|
|
43
|
+
ExperimentsApi,
|
|
44
|
+
ExperimentHandle,
|
|
45
|
+
attachExperiments,
|
|
46
|
+
} from "./resources/experiments.js";
|
|
47
|
+
export type { ExperimentHandleFactory } from "./resources/experiments.js";
|
|
48
|
+
export { RecipesApi, attachRecipes } from "./resources/recipes.js";
|
|
65
49
|
|
|
66
|
-
//
|
|
67
|
-
export { withIntrospection } from "./claude-wrapper.js";
|
|
50
|
+
// REST API wire types
|
|
68
51
|
export type {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
52
|
+
Paginated,
|
|
53
|
+
ListParams,
|
|
54
|
+
Task,
|
|
55
|
+
TaskCreateParams,
|
|
56
|
+
TaskUpdateParams,
|
|
57
|
+
TaskListParams,
|
|
58
|
+
TaskMode,
|
|
59
|
+
TaskStatus,
|
|
60
|
+
TaskPrompt,
|
|
61
|
+
TaskRun,
|
|
62
|
+
TaskRunCreateParams,
|
|
63
|
+
TaskRunResponse,
|
|
64
|
+
TaskCreateResponse,
|
|
65
|
+
TaskCancelResponse,
|
|
66
|
+
AgentInfo,
|
|
67
|
+
File,
|
|
68
|
+
FileType,
|
|
69
|
+
FileListParams,
|
|
70
|
+
FileUpdateParams,
|
|
71
|
+
FileCreateTextParams,
|
|
72
|
+
SseEvent,
|
|
73
|
+
Runtime,
|
|
74
|
+
RuntimeCreate,
|
|
75
|
+
RuntimeUpdate,
|
|
76
|
+
RuntimeListParams,
|
|
77
|
+
Experiment,
|
|
78
|
+
ExperimentCreate,
|
|
79
|
+
ExperimentUpdate,
|
|
80
|
+
ExperimentListParams,
|
|
81
|
+
ExperimentStatus,
|
|
82
|
+
ExperimentEndParams,
|
|
83
|
+
Arm,
|
|
84
|
+
Recipe,
|
|
85
|
+
RecipeCreate,
|
|
86
|
+
RecipeUpdate,
|
|
87
|
+
RecipeListParams,
|
|
88
|
+
RunnerSpec,
|
|
89
|
+
RunnerDeployment,
|
|
90
|
+
RunnerContext,
|
|
91
|
+
RunnerRecipeSummary,
|
|
92
|
+
RunnerIdentity,
|
|
93
|
+
RunRequest,
|
|
94
|
+
RunCaller,
|
|
95
|
+
RunCallerLibrary,
|
|
96
|
+
RunCallerPage,
|
|
97
|
+
RunIdentityInput,
|
|
98
|
+
} from "@introspection-sdk/types";
|
|
99
|
+
export {
|
|
100
|
+
IntrospectionAPIError,
|
|
101
|
+
AuthenticationError,
|
|
102
|
+
InsufficientScopeError,
|
|
103
|
+
RunnerExpiredError,
|
|
104
|
+
NotFoundError,
|
|
105
|
+
ConflictError,
|
|
106
|
+
ValidationError,
|
|
107
|
+
RateLimitError,
|
|
108
|
+
SandboxUnavailableError,
|
|
109
|
+
StreamError,
|
|
110
|
+
NetworkError,
|
|
111
|
+
apiErrorFromResponse,
|
|
112
|
+
} from "@introspection-sdk/types";
|
|
73
113
|
|
|
74
|
-
// GenAI types
|
|
114
|
+
// GenAI types (shared, no OTel SDK imports).
|
|
75
115
|
export type {
|
|
76
116
|
GenAiAttributes,
|
|
77
117
|
InputMessage,
|
|
@@ -85,7 +125,7 @@ export type {
|
|
|
85
125
|
} from "@introspection-sdk/types";
|
|
86
126
|
export { toAttributes } from "@introspection-sdk/types";
|
|
87
127
|
|
|
88
|
-
// OpenAI converter exports
|
|
128
|
+
// OpenAI converter exports (pure functions, no OTel SDK imports).
|
|
89
129
|
export {
|
|
90
130
|
convertResponsesInputsToSemconv,
|
|
91
131
|
convertResponsesOutputsToSemconv,
|
|
@@ -100,22 +140,17 @@ export type {
|
|
|
100
140
|
Response as OpenAIResponse,
|
|
101
141
|
} from "./converters/openai.js";
|
|
102
142
|
|
|
103
|
-
//
|
|
104
|
-
export { IntrospectionAISDKIntegration } from "./ai-sdk-integration.js";
|
|
105
|
-
export type {
|
|
106
|
-
IntrospectionAISDKIntegrationOptions,
|
|
107
|
-
AISDKIntegrationAdvancedOptions,
|
|
108
|
-
} from "./ai-sdk-integration.js";
|
|
109
|
-
|
|
110
|
-
// OpenInference converter exports
|
|
111
|
-
export {
|
|
112
|
-
addOpenInferenceAttributes,
|
|
113
|
-
OpenInferenceSpanExporter,
|
|
114
|
-
} from "./converters/openinference.js";
|
|
115
|
-
|
|
116
|
-
// Anthropic instrumentor exports
|
|
143
|
+
// Gemini converters (pure functions, no OTel SDK imports).
|
|
117
144
|
export {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
convertGeminiContentsToInputMessages,
|
|
146
|
+
convertGeminiCandidatesToOutputMessages,
|
|
147
|
+
convertGeminiSystemInstructionToSemconv,
|
|
148
|
+
convertGeminiToolsToToolDefinitions,
|
|
149
|
+
} from "./converters/gemini.js";
|
|
150
|
+
export type {
|
|
151
|
+
GeminiCandidate,
|
|
152
|
+
GeminiContent,
|
|
153
|
+
GeminiFunctionDeclaration,
|
|
154
|
+
GeminiPart,
|
|
155
|
+
GeminiTool,
|
|
156
|
+
} from "./converters/gemini.js";
|
|
@@ -24,7 +24,13 @@ import type {
|
|
|
24
24
|
ReasoningPart,
|
|
25
25
|
} from "@introspection-sdk/types";
|
|
26
26
|
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
trace,
|
|
29
|
+
context as otelContext,
|
|
30
|
+
propagation,
|
|
31
|
+
SpanKind,
|
|
32
|
+
SpanStatusCode,
|
|
33
|
+
} from "@opentelemetry/api";
|
|
28
34
|
import type { Tracer, Span } from "@opentelemetry/api";
|
|
29
35
|
import type { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
|
|
30
36
|
|
|
@@ -154,7 +160,11 @@ function serializeMessages(msgs: InputMessage[] | OutputMessage[]): string {
|
|
|
154
160
|
);
|
|
155
161
|
}
|
|
156
162
|
|
|
157
|
-
function startSpan(
|
|
163
|
+
function startSpan(
|
|
164
|
+
tracer: Tracer,
|
|
165
|
+
model: string,
|
|
166
|
+
conversationId?: string,
|
|
167
|
+
): { span: Span; token: null } {
|
|
158
168
|
const span = tracer.startSpan("chat", {
|
|
159
169
|
kind: SpanKind.CLIENT,
|
|
160
170
|
attributes: {
|
|
@@ -163,6 +173,9 @@ function startSpan(tracer: Tracer, model: string): { span: Span; token: null } {
|
|
|
163
173
|
"gen_ai.operation.name": "chat",
|
|
164
174
|
"gen_ai.request.model": model,
|
|
165
175
|
"openinference.span.kind": "LLM",
|
|
176
|
+
...(conversationId
|
|
177
|
+
? { "gen_ai.conversation.id": conversationId }
|
|
178
|
+
: undefined),
|
|
166
179
|
},
|
|
167
180
|
});
|
|
168
181
|
return { span, token: null };
|
|
@@ -177,10 +190,26 @@ function setRequestAttrs(span: Span, kwargs: Record<string, unknown>): void {
|
|
|
177
190
|
|
|
178
191
|
const system = kwargs.system;
|
|
179
192
|
if (system) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
let sysVal: string;
|
|
194
|
+
if (typeof system === "string") {
|
|
195
|
+
sysVal = JSON.stringify([{ type: "text", content: system }]);
|
|
196
|
+
} else if (Array.isArray(system)) {
|
|
197
|
+
// Anthropic block format: [{type:"text", text:"...", cache_control:{...}}]
|
|
198
|
+
// Normalize to gen_ai format: [{type:"text", content:"..."}]
|
|
199
|
+
sysVal = JSON.stringify(
|
|
200
|
+
(system as Array<Record<string, unknown>>).map((block) => ({
|
|
201
|
+
type: "text",
|
|
202
|
+
content:
|
|
203
|
+
typeof block.text === "string"
|
|
204
|
+
? block.text
|
|
205
|
+
: typeof block.content === "string"
|
|
206
|
+
? block.content
|
|
207
|
+
: "",
|
|
208
|
+
})),
|
|
209
|
+
);
|
|
210
|
+
} else {
|
|
211
|
+
sysVal = JSON.stringify(system);
|
|
212
|
+
}
|
|
184
213
|
span.setAttribute("gen_ai.system_instructions", sysVal);
|
|
185
214
|
}
|
|
186
215
|
|
|
@@ -219,6 +248,16 @@ function setResponseAttrs(span: Span, response: Record<string, unknown>): void {
|
|
|
219
248
|
span.setAttribute("gen_ai.usage.input_tokens", usage.input_tokens);
|
|
220
249
|
if (usage.output_tokens != null)
|
|
221
250
|
span.setAttribute("gen_ai.usage.output_tokens", usage.output_tokens);
|
|
251
|
+
if (usage.cache_read_input_tokens != null)
|
|
252
|
+
span.setAttribute(
|
|
253
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
254
|
+
usage.cache_read_input_tokens,
|
|
255
|
+
);
|
|
256
|
+
if (usage.cache_creation_input_tokens != null)
|
|
257
|
+
span.setAttribute(
|
|
258
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
259
|
+
usage.cache_creation_input_tokens,
|
|
260
|
+
);
|
|
222
261
|
}
|
|
223
262
|
|
|
224
263
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -245,6 +284,8 @@ class TracedStream {
|
|
|
245
284
|
private responseModel: string | null = null;
|
|
246
285
|
private inputTokens = 0;
|
|
247
286
|
private outputTokens = 0;
|
|
287
|
+
private cacheReadInputTokens = 0;
|
|
288
|
+
private cacheCreationInputTokens = 0;
|
|
248
289
|
private finalized = false;
|
|
249
290
|
|
|
250
291
|
constructor(inner: AsyncIterable<StreamEvent>, span: Span) {
|
|
@@ -268,7 +309,11 @@ class TracedStream {
|
|
|
268
309
|
this.responseId = (event.message.id as string) || null;
|
|
269
310
|
this.responseModel = (event.message.model as string) || null;
|
|
270
311
|
const usage = event.message.usage as Record<string, number> | undefined;
|
|
271
|
-
if (usage)
|
|
312
|
+
if (usage) {
|
|
313
|
+
this.inputTokens = usage.input_tokens || 0;
|
|
314
|
+
this.cacheReadInputTokens = usage.cache_read_input_tokens || 0;
|
|
315
|
+
this.cacheCreationInputTokens = usage.cache_creation_input_tokens || 0;
|
|
316
|
+
}
|
|
272
317
|
} else if (event.type === "content_block_start" && event.content_block) {
|
|
273
318
|
const bt = (event.content_block.type as string) || "";
|
|
274
319
|
this.currentBlock = { type: bt };
|
|
@@ -328,6 +373,16 @@ class TracedStream {
|
|
|
328
373
|
this.span.setAttribute("gen_ai.usage.input_tokens", this.inputTokens);
|
|
329
374
|
if (this.outputTokens)
|
|
330
375
|
this.span.setAttribute("gen_ai.usage.output_tokens", this.outputTokens);
|
|
376
|
+
if (this.cacheReadInputTokens)
|
|
377
|
+
this.span.setAttribute(
|
|
378
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
379
|
+
this.cacheReadInputTokens,
|
|
380
|
+
);
|
|
381
|
+
if (this.cacheCreationInputTokens)
|
|
382
|
+
this.span.setAttribute(
|
|
383
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
384
|
+
this.cacheCreationInputTokens,
|
|
385
|
+
);
|
|
331
386
|
this.span.setStatus({ code: SpanStatusCode.OK });
|
|
332
387
|
this.span.end();
|
|
333
388
|
}
|
|
@@ -345,8 +400,13 @@ export async function tracedMessagesCreate(
|
|
|
345
400
|
tracer: Tracer,
|
|
346
401
|
client: { messages: { create: (...args: unknown[]) => Promise<unknown> } },
|
|
347
402
|
kwargs: Record<string, unknown>,
|
|
403
|
+
conversationId?: string,
|
|
348
404
|
): Promise<unknown> {
|
|
349
|
-
const { span } = startSpan(
|
|
405
|
+
const { span } = startSpan(
|
|
406
|
+
tracer,
|
|
407
|
+
(kwargs.model as string) || "unknown",
|
|
408
|
+
conversationId,
|
|
409
|
+
);
|
|
350
410
|
try {
|
|
351
411
|
setRequestAttrs(span, kwargs);
|
|
352
412
|
const response = (await client.messages.create(kwargs)) as Record<
|
|
@@ -382,12 +442,20 @@ export class AnthropicInstrumentor {
|
|
|
382
442
|
private tracer: Tracer | null = null;
|
|
383
443
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
384
444
|
private patchedClients: Array<{ client: any; originalCreate: any }> = [];
|
|
445
|
+
private conversationId: string | undefined;
|
|
385
446
|
|
|
386
447
|
instrument(opts: {
|
|
387
448
|
tracerProvider?: BasicTracerProvider;
|
|
388
449
|
/** The Anthropic client instance to instrument. */
|
|
389
450
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
390
451
|
client: any;
|
|
452
|
+
/**
|
|
453
|
+
* Conversation ID shared across all spans produced by this instrumentor.
|
|
454
|
+
* Enables the Introspection processor to reliably link multi-turn API calls
|
|
455
|
+
* into a single conversation without relying on history-hash matching.
|
|
456
|
+
* Defaults to a random UUID generated at instrument() time.
|
|
457
|
+
*/
|
|
458
|
+
conversationId?: string;
|
|
391
459
|
}): void {
|
|
392
460
|
const { client } = opts;
|
|
393
461
|
if (!client?.messages?.create) {
|
|
@@ -396,6 +464,8 @@ export class AnthropicInstrumentor {
|
|
|
396
464
|
);
|
|
397
465
|
}
|
|
398
466
|
|
|
467
|
+
this.conversationId = opts.conversationId ?? crypto.randomUUID();
|
|
468
|
+
|
|
399
469
|
const provider = opts.tracerProvider ?? trace.getTracerProvider();
|
|
400
470
|
this.tracer = (provider as BasicTracerProvider).getTracer(
|
|
401
471
|
"introspection-anthropic",
|
|
@@ -404,16 +474,33 @@ export class AnthropicInstrumentor {
|
|
|
404
474
|
const origCreate = client.messages.create.bind(client.messages);
|
|
405
475
|
this.patchedClients.push({ client, originalCreate: origCreate });
|
|
406
476
|
const tracer = this.tracer!;
|
|
477
|
+
const defaultConversationId = this.conversationId;
|
|
407
478
|
|
|
408
479
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
409
480
|
client.messages.create = function (...args: any[]) {
|
|
410
481
|
const kwargs = args[0] as Record<string, unknown>;
|
|
411
482
|
const isStream = kwargs?.stream === true;
|
|
412
483
|
|
|
484
|
+
// Baggage on the active context overrides the conversation ID bound
|
|
485
|
+
// at instrument() time, so callers can wrap a request in
|
|
486
|
+
// IntrospectionClient.withConversation() to scope a single call to a
|
|
487
|
+
// distinct conversation without re-instrumenting the client.
|
|
488
|
+
const baggage = propagation.getBaggage(otelContext.active());
|
|
489
|
+
const baggageConvId = baggage?.getEntry("gen_ai.conversation.id")?.value;
|
|
490
|
+
const baggageAgentName = baggage?.getEntry("gen_ai.agent.name")?.value;
|
|
491
|
+
const baggageAgentId = baggage?.getEntry("gen_ai.agent.id")?.value;
|
|
492
|
+
|
|
413
493
|
const { span } = startSpan(
|
|
414
494
|
tracer,
|
|
415
495
|
(kwargs?.model as string) || "unknown",
|
|
496
|
+
baggageConvId ?? defaultConversationId,
|
|
416
497
|
);
|
|
498
|
+
if (baggageAgentName) {
|
|
499
|
+
span.setAttribute("gen_ai.agent.name", baggageAgentName);
|
|
500
|
+
}
|
|
501
|
+
if (baggageAgentId) {
|
|
502
|
+
span.setAttribute("gen_ai.agent.id", baggageAgentId);
|
|
503
|
+
}
|
|
417
504
|
setRequestAttrs(span, kwargs || {});
|
|
418
505
|
|
|
419
506
|
if (isStream) {
|