@introspection-sdk/introspection-node 0.4.2 → 0.4.4
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/dist/client.d.ts +42 -132
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +67 -366
- package/dist/client.js.map +1 -0
- package/dist/converters/claude.d.ts +4 -0
- 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/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/{anthropic.d.ts → otel/anthropic.d.ts} +23 -13
- package/dist/otel/anthropic.d.ts.map +1 -0
- package/dist/{anthropic.js → otel/anthropic.js} +132 -40
- package/dist/otel/anthropic.js.map +1 -0
- package/dist/{claude-hooks.d.ts → otel/claude-hooks.d.ts} +19 -1
- package/dist/otel/claude-hooks.d.ts.map +1 -0
- package/dist/{claude-hooks.js → otel/claude-hooks.js} +94 -20
- package/dist/otel/claude-hooks.js.map +1 -0
- package/dist/otel/claude-wrapper.d.ts.map +1 -0
- package/dist/{claude-wrapper.js → otel/claude-wrapper.js} +2 -1
- package/dist/otel/claude-wrapper.js.map +1 -0
- package/dist/otel/gemini.d.ts +56 -0
- package/dist/otel/gemini.d.ts.map +1 -0
- package/dist/otel/gemini.js +348 -0
- package/dist/otel/gemini.js.map +1 -0
- package/dist/otel/index.d.ts +32 -0
- package/dist/otel/index.d.ts.map +1 -0
- package/dist/otel/index.js +41 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/otel/init.d.ts +126 -0
- package/dist/otel/init.d.ts.map +1 -0
- package/dist/otel/init.js +259 -0
- package/dist/otel/init.js.map +1 -0
- package/dist/otel/integrations/anthropic.d.ts +10 -0
- package/dist/otel/integrations/anthropic.d.ts.map +1 -0
- package/dist/otel/integrations/anthropic.js +22 -0
- package/dist/otel/integrations/anthropic.js.map +1 -0
- package/dist/otel/integrations/base.d.ts +83 -0
- package/dist/otel/integrations/base.d.ts.map +1 -0
- package/dist/otel/integrations/base.js +23 -0
- package/dist/otel/integrations/base.js.map +1 -0
- package/dist/otel/integrations/claude-agent.d.ts +13 -0
- package/dist/otel/integrations/claude-agent.d.ts.map +1 -0
- package/dist/otel/integrations/claude-agent.js +27 -0
- package/dist/otel/integrations/claude-agent.js.map +1 -0
- package/dist/otel/integrations/gemini.d.ts +11 -0
- package/dist/otel/integrations/gemini.d.ts.map +1 -0
- package/dist/otel/integrations/gemini.js +21 -0
- package/dist/otel/integrations/gemini.js.map +1 -0
- package/dist/otel/integrations/index.d.ts +39 -0
- package/dist/otel/integrations/index.d.ts.map +1 -0
- package/dist/otel/integrations/index.js +131 -0
- package/dist/otel/integrations/index.js.map +1 -0
- package/dist/otel/integrations/langchain.d.ts +16 -0
- package/dist/otel/integrations/langchain.d.ts.map +1 -0
- package/dist/otel/integrations/langchain.js +41 -0
- package/dist/otel/integrations/langchain.js.map +1 -0
- package/dist/otel/integrations/mastra.d.ts +14 -0
- package/dist/otel/integrations/mastra.d.ts.map +1 -0
- package/dist/otel/integrations/mastra.js +27 -0
- package/dist/otel/integrations/mastra.js.map +1 -0
- package/dist/otel/integrations/openai-agents.d.ts +11 -0
- package/dist/otel/integrations/openai-agents.d.ts.map +1 -0
- package/dist/otel/integrations/openai-agents.js +25 -0
- package/dist/otel/integrations/openai-agents.js.map +1 -0
- package/dist/otel/integrations/pi.d.ts +12 -0
- package/dist/otel/integrations/pi.d.ts.map +1 -0
- package/dist/otel/integrations/pi.js +20 -0
- package/dist/otel/integrations/pi.js.map +1 -0
- package/dist/otel/integrations/vercel.d.ts +15 -0
- package/dist/otel/integrations/vercel.d.ts.map +1 -0
- package/dist/otel/integrations/vercel.js +20 -0
- package/dist/otel/integrations/vercel.js.map +1 -0
- package/dist/{langchain-handler.d.ts → otel/langchain-handler.d.ts} +10 -1
- package/dist/otel/langchain-handler.d.ts.map +1 -0
- package/dist/{langchain-handler.js → otel/langchain-handler.js} +43 -6
- 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/{mastra-exporter.d.ts → otel/mastra-exporter.d.ts} +3 -1
- package/dist/otel/mastra-exporter.d.ts.map +1 -0
- package/dist/{mastra-exporter.js → otel/mastra-exporter.js} +71 -17
- 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/register.d.ts +8 -0
- package/dist/otel/register.d.ts.map +1 -0
- package/dist/otel/register.js +48 -0
- package/dist/otel/register.js.map +1 -0
- package/dist/otel/setup.d.ts +52 -0
- package/dist/otel/setup.d.ts.map +1 -0
- package/dist/otel/setup.js +146 -0
- package/dist/otel/setup.js.map +1 -0
- package/dist/{span-processor.d.ts → otel/span-processor.d.ts} +1 -1
- package/dist/otel/span-processor.d.ts.map +1 -0
- package/dist/{span-processor.js → otel/span-processor.js} +11 -5
- package/dist/otel/span-processor.js.map +1 -0
- package/dist/{tracing-processor.d.ts → otel/tracing-processor.d.ts} +4 -1
- package/dist/otel/tracing-processor.d.ts.map +1 -0
- package/dist/{tracing-processor.js → otel/tracing-processor.js} +64 -14
- 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/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/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +13 -4
- package/dist/utils.js.map +1 -0
- package/dist/version.js +1 -0
- package/dist/version.js.map +1 -0
- package/package.json +91 -22
- package/src/client.ts +76 -473
- package/src/converters/claude.ts +10 -0
- 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} +206 -54
- package/src/{claude-hooks.ts → otel/claude-hooks.ts} +119 -20
- package/src/{claude-wrapper.ts → otel/claude-wrapper.ts} +1 -1
- package/src/otel/gemini.ts +491 -0
- package/src/otel/index.ts +121 -0
- package/src/otel/init.ts +411 -0
- package/src/otel/integrations/anthropic.ts +26 -0
- package/src/otel/integrations/base.ts +95 -0
- package/src/otel/integrations/claude-agent.ts +32 -0
- package/src/otel/integrations/gemini.ts +25 -0
- package/src/otel/integrations/index.ts +151 -0
- package/src/otel/integrations/langchain.ts +45 -0
- package/src/otel/integrations/mastra.ts +30 -0
- package/src/otel/integrations/openai-agents.ts +31 -0
- package/src/otel/integrations/pi.ts +24 -0
- package/src/otel/integrations/vercel.ts +24 -0
- package/src/{langchain-handler.ts → otel/langchain-handler.ts} +53 -6
- package/src/otel/logs.ts +394 -0
- package/src/{mastra-exporter.ts → otel/mastra-exporter.ts} +83 -22
- package/src/otel/pi.ts +88 -0
- package/src/otel/register.ts +50 -0
- package/src/otel/setup.ts +215 -0
- package/src/{span-processor.ts → otel/span-processor.ts} +11 -6
- package/src/{tracing-processor.ts → otel/tracing-processor.ts} +94 -19
- 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 +12 -5
- package/dist/ai-sdk-integration.d.ts +0 -123
- package/dist/ai-sdk-integration.d.ts.map +0 -1
- package/dist/ai-sdk-integration.js +0 -475
- package/dist/anthropic.d.ts.map +0 -1
- package/dist/claude-hooks.d.ts.map +0 -1
- package/dist/claude-wrapper.d.ts.map +0 -1
- package/dist/converters/ai-sdk.d.ts +0 -65
- package/dist/converters/ai-sdk.d.ts.map +0 -1
- package/dist/converters/ai-sdk.js +0 -261
- package/dist/langchain-handler.d.ts.map +0 -1
- package/dist/mastra-exporter.d.ts.map +0 -1
- package/dist/span-processor.d.ts.map +0 -1
- package/dist/tracing-processor.d.ts.map +0 -1
- package/src/ai-sdk-integration.ts +0 -691
- package/src/converters/ai-sdk.ts +0 -323
- /package/dist/{claude-wrapper.d.ts → otel/claude-wrapper.d.ts} +0 -0
package/src/runner.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RunnerExpiredError,
|
|
3
|
+
type RunnerContext,
|
|
4
|
+
type RunnerDeployment,
|
|
5
|
+
type RunnerSpec,
|
|
6
|
+
type RunRequest,
|
|
7
|
+
type Uuid,
|
|
8
|
+
} from "@introspection-sdk/types";
|
|
9
|
+
import { HttpClient } from "./http.js";
|
|
10
|
+
import { TasksApi } from "./runner-resources/tasks.js";
|
|
11
|
+
import { FilesApi } from "./runner-resources/files.js";
|
|
12
|
+
import type { IntrospectionClient } from "./client.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Where this Runner came from, so `refresh()` can call CP again with the
|
|
16
|
+
* same arguments to obtain a fresh `RunnerSpec` (manual escape hatch only;
|
|
17
|
+
* not auto-scheduled).
|
|
18
|
+
*/
|
|
19
|
+
export type RunnerSource =
|
|
20
|
+
| { kind: "runtime"; id: Uuid; options?: RunRequest }
|
|
21
|
+
| { kind: "experiment"; id: Uuid; options?: RunRequest };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Live handle to a Data Plane sandbox. Holds the bearer JWT, the DP
|
|
25
|
+
* endpoint URL, and the runtime/experiment context, and exposes the
|
|
26
|
+
* runner-bound `tasks` and `files` namespaces.
|
|
27
|
+
*
|
|
28
|
+
* In v1 of the agent-session-based design, token refresh is handled
|
|
29
|
+
* server-side by the DP materializer attached to the agent session — the
|
|
30
|
+
* SDK does NOT auto-refresh and does NOT install a 401 safety-net. The
|
|
31
|
+
* `refresh()` method is kept as a manual escape hatch that re-calls the
|
|
32
|
+
* CP `/run` route to mint a brand-new spec.
|
|
33
|
+
*/
|
|
34
|
+
export class Runner {
|
|
35
|
+
private spec: RunnerSpec;
|
|
36
|
+
private http: HttpClient;
|
|
37
|
+
private closed = false;
|
|
38
|
+
|
|
39
|
+
// Public API surfaces.
|
|
40
|
+
readonly tasks: TasksApi;
|
|
41
|
+
readonly files: FilesApi;
|
|
42
|
+
|
|
43
|
+
constructor(
|
|
44
|
+
private readonly client: IntrospectionClient,
|
|
45
|
+
private readonly source: RunnerSource,
|
|
46
|
+
spec: RunnerSpec,
|
|
47
|
+
) {
|
|
48
|
+
this.spec = spec;
|
|
49
|
+
this.http = this.buildHttp();
|
|
50
|
+
this.tasks = new TasksApi(this.guardedHttp(this.http));
|
|
51
|
+
this.files = new FilesApi(this.guardedHttp(this.http));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// --- public accessors ---
|
|
55
|
+
|
|
56
|
+
/** DP REST base URL the runner is bound to. */
|
|
57
|
+
get dpEndpoint(): string {
|
|
58
|
+
return this.spec.deployment.endpoint;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Routing target — DP endpoint / slug / region. */
|
|
62
|
+
get deployment(): Readonly<RunnerDeployment> {
|
|
63
|
+
return Object.freeze({ ...this.spec.deployment });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Session lifetime (ISO-8601 string). */
|
|
67
|
+
get expires_at(): string {
|
|
68
|
+
return this.spec.expires_at;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Session ID assigned by CP. */
|
|
72
|
+
get session_id(): string {
|
|
73
|
+
return this.spec.session_id;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Resolved runtime / arm / recipe / identity / caller context. */
|
|
77
|
+
get context(): Readonly<RunnerContext> {
|
|
78
|
+
return Object.freeze({ ...this.spec.runtime_context });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** True once `close()` has been called. */
|
|
82
|
+
get isClosed(): boolean {
|
|
83
|
+
return this.closed;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// --- lifecycle ---
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Manual escape hatch: re-call CP `/v1/runtimes/{id}/run` or
|
|
90
|
+
* `/v1/experiments/{id}/run` with the original `RunRequest` and replace
|
|
91
|
+
* this runner's in-memory spec with a fresh one.
|
|
92
|
+
*
|
|
93
|
+
* Not auto-scheduled — in v1 the DP materializer refreshes the
|
|
94
|
+
* underlying access token transparently for the agent-session-backed
|
|
95
|
+
* runner. Call this only if you have an explicit reason to mint a new
|
|
96
|
+
* session (e.g. you held a runner across a very long pause).
|
|
97
|
+
*/
|
|
98
|
+
async refresh(): Promise<void> {
|
|
99
|
+
if (this.closed) {
|
|
100
|
+
throw new RunnerExpiredError({
|
|
101
|
+
message: "Runner has been closed",
|
|
102
|
+
status: 401,
|
|
103
|
+
code: "runner_expired",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const fresh = await this.requestFreshSpec();
|
|
107
|
+
this.spec = fresh;
|
|
108
|
+
// Note: we intentionally don't swap the underlying `http` here — the
|
|
109
|
+
// constructor-time bindings stay stable for the lifetime of the Runner.
|
|
110
|
+
// Callers wanting a freshly-bound Runner should call
|
|
111
|
+
// `client.runtimes(id).run(...)` again.
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Best-effort close — flips a local `isClosed` flag so subsequent
|
|
116
|
+
* `runner.tasks` / `runner.files` calls throw a friendly error. No
|
|
117
|
+
* server-side revoke is performed; future work will route a revoke via
|
|
118
|
+
* the CP locator-token path.
|
|
119
|
+
*/
|
|
120
|
+
async close(): Promise<void> {
|
|
121
|
+
this.closed = true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// --- internals ---
|
|
125
|
+
|
|
126
|
+
private buildHttp(): HttpClient {
|
|
127
|
+
const advanced = this.client.advancedOptions;
|
|
128
|
+
return new HttpClient({
|
|
129
|
+
apiUrl: this.spec.deployment.endpoint,
|
|
130
|
+
token: this.spec.session_token,
|
|
131
|
+
additionalHeaders: advanced.additionalHeaders,
|
|
132
|
+
fetch: advanced.fetch,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Wrap an HttpClient so that calls after `close()` fail with a clear
|
|
138
|
+
* `RunnerExpiredError` instead of hitting the network with a stale
|
|
139
|
+
* bearer. No 401 retry / refresh logic — that is the DP materializer's
|
|
140
|
+
* job in v1.
|
|
141
|
+
*/
|
|
142
|
+
private guardedHttp(http: HttpClient): HttpClient {
|
|
143
|
+
const proxy: HttpClient = Object.create(http);
|
|
144
|
+
proxy.request = async <T>(
|
|
145
|
+
opts: Parameters<HttpClient["request"]>[0],
|
|
146
|
+
): Promise<T> => {
|
|
147
|
+
this.assertOpen();
|
|
148
|
+
return http.request<T>(opts);
|
|
149
|
+
};
|
|
150
|
+
proxy.stream = async (
|
|
151
|
+
opts: Parameters<HttpClient["stream"]>[0],
|
|
152
|
+
): Promise<Response> => {
|
|
153
|
+
this.assertOpen();
|
|
154
|
+
return http.stream(opts);
|
|
155
|
+
};
|
|
156
|
+
return proxy;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private assertOpen(): void {
|
|
160
|
+
if (this.closed) {
|
|
161
|
+
throw new RunnerExpiredError({
|
|
162
|
+
message: "Runner has been closed",
|
|
163
|
+
status: 401,
|
|
164
|
+
code: "runner_expired",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private async requestFreshSpec(): Promise<RunnerSpec> {
|
|
170
|
+
const http = this.client.cpHttp;
|
|
171
|
+
const body = toRunBody(this.source.options);
|
|
172
|
+
if (this.source.kind === "runtime") {
|
|
173
|
+
return await http.request<RunnerSpec>({
|
|
174
|
+
method: "POST",
|
|
175
|
+
path: `/v1/runtimes/${encodeURIComponent(this.source.id)}/run`,
|
|
176
|
+
body,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return await http.request<RunnerSpec>({
|
|
180
|
+
method: "POST",
|
|
181
|
+
path: `/v1/experiments/${encodeURIComponent(this.source.id)}/run`,
|
|
182
|
+
body,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function toRunBody(opts?: RunRequest): Record<string, unknown> {
|
|
188
|
+
if (!opts) return {};
|
|
189
|
+
const out: Record<string, unknown> = {};
|
|
190
|
+
if (opts.identity) out.identity = opts.identity;
|
|
191
|
+
if (opts.caller) out.caller = opts.caller;
|
|
192
|
+
if (opts.ttl_seconds !== undefined) out.ttl_seconds = opts.ttl_seconds;
|
|
193
|
+
return out;
|
|
194
|
+
}
|
package/src/streaming.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { SseEvent } from "@introspection-sdk/types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parse a `text/event-stream` Response into an async-iterable of SSE
|
|
5
|
+
* events. Minimal parser: handles `event:`, `data:` (multi-line),
|
|
6
|
+
* `id:`, `retry:`; ignores comments and unknown fields.
|
|
7
|
+
*/
|
|
8
|
+
export async function* parseSse(res: Response): AsyncIterable<SseEvent> {
|
|
9
|
+
if (!res.body) return;
|
|
10
|
+
const reader = res.body.getReader();
|
|
11
|
+
const decoder = new TextDecoder();
|
|
12
|
+
let buf = "";
|
|
13
|
+
let event = "message";
|
|
14
|
+
let data: string[] = [];
|
|
15
|
+
let id: string | undefined;
|
|
16
|
+
let retry: number | undefined;
|
|
17
|
+
const flush = (): SseEvent | null => {
|
|
18
|
+
if (data.length === 0 && event === "message" && id === undefined)
|
|
19
|
+
return null;
|
|
20
|
+
const ev: SseEvent = { event, data: data.join("\n") };
|
|
21
|
+
if (id !== undefined) ev.id = id;
|
|
22
|
+
if (retry !== undefined) ev.retry = retry;
|
|
23
|
+
event = "message";
|
|
24
|
+
data = [];
|
|
25
|
+
id = undefined;
|
|
26
|
+
retry = undefined;
|
|
27
|
+
return ev;
|
|
28
|
+
};
|
|
29
|
+
while (true) {
|
|
30
|
+
const { value, done } = await reader.read();
|
|
31
|
+
if (done) break;
|
|
32
|
+
buf += decoder.decode(value, { stream: true });
|
|
33
|
+
let nl: number;
|
|
34
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
35
|
+
const line = buf.slice(0, nl).replace(/\r$/, "");
|
|
36
|
+
buf = buf.slice(nl + 1);
|
|
37
|
+
if (line === "") {
|
|
38
|
+
const ev = flush();
|
|
39
|
+
if (ev) yield ev;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (line.startsWith(":")) continue;
|
|
43
|
+
const colon = line.indexOf(":");
|
|
44
|
+
const field = colon < 0 ? line : line.slice(0, colon);
|
|
45
|
+
const valueRaw = colon < 0 ? "" : line.slice(colon + 1).replace(/^ /, "");
|
|
46
|
+
if (field === "event") event = valueRaw;
|
|
47
|
+
else if (field === "data") data.push(valueRaw);
|
|
48
|
+
else if (field === "id") id = valueRaw;
|
|
49
|
+
else if (field === "retry") {
|
|
50
|
+
const n = Number(valueRaw);
|
|
51
|
+
if (Number.isFinite(n)) retry = n;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const ev = flush();
|
|
56
|
+
if (ev) yield ev;
|
|
57
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { DiagLogLevel, DiagLogger } from "@opentelemetry/api";
|
|
2
2
|
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
3
|
+
import { resolveForwardProxyUrl } from "@introspection-sdk/introspection-proxy";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Attach a forward-proxy agent to OTLP exporter options when a proxy is
|
|
7
|
+
* configured in the environment.
|
|
8
|
+
*
|
|
9
|
+
* Note: the OTLP proto exporters use Node's `http`/`https` stack, so this uses
|
|
10
|
+
* `HttpsProxyAgent` (an `http.Agent`) rather than the undici dispatcher from
|
|
11
|
+
* `./proxy.js` — a dispatcher only applies to `fetch`. The proxy *URL* is
|
|
12
|
+
* resolved by the shared {@link resolveForwardProxyUrl} so fetch and OTLP
|
|
13
|
+
* traffic agree on which proxy to use.
|
|
14
|
+
*/
|
|
8
15
|
export function withOtlpHttpsProxy<T extends object>(options: T): T {
|
|
9
|
-
const proxyUrl =
|
|
16
|
+
const proxyUrl = resolveForwardProxyUrl();
|
|
10
17
|
if (!proxyUrl) return options;
|
|
11
18
|
|
|
12
19
|
return {
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI SDK TelemetryIntegration for Introspection.
|
|
3
|
-
*
|
|
4
|
-
* Implements the Vercel AI SDK's TelemetryIntegration interface to capture
|
|
5
|
-
* LLM interactions and export them as OpenTelemetry spans with gen_ai.*
|
|
6
|
-
* semantic convention attributes to the Introspection backend.
|
|
7
|
-
*
|
|
8
|
-
* Similar to IntrospectionTracingProcessor for OpenAI Agents SDK and
|
|
9
|
-
* IntrospectionClaudeHooks for Claude Agent SDK.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* import { IntrospectionAISDKIntegration } from "@introspection-sdk/introspection-node";
|
|
14
|
-
* import { generateText } from "ai";
|
|
15
|
-
* import { openai } from "@ai-sdk/openai";
|
|
16
|
-
*
|
|
17
|
-
* const introspection = new IntrospectionAISDKIntegration({
|
|
18
|
-
* token: "sk-intro-...",
|
|
19
|
-
* serviceName: "my-app",
|
|
20
|
-
* });
|
|
21
|
-
*
|
|
22
|
-
* const { text } = await generateText({
|
|
23
|
-
* model: openai("gpt-4o"),
|
|
24
|
-
* prompt: "Hello!",
|
|
25
|
-
* experimental_telemetry: {
|
|
26
|
-
* isEnabled: true,
|
|
27
|
-
* integrations: [introspection],
|
|
28
|
-
* },
|
|
29
|
-
* });
|
|
30
|
-
*
|
|
31
|
-
* await introspection.shutdown();
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
import { type SpanExporter, type IdGenerator } from "@opentelemetry/sdk-trace-base";
|
|
35
|
-
/** Advanced options for testing and customization. */
|
|
36
|
-
export interface AISDKIntegrationAdvancedOptions {
|
|
37
|
-
/** Custom span exporter (for testing — use InMemorySpanExporter). */
|
|
38
|
-
spanExporter?: SpanExporter;
|
|
39
|
-
/** Custom ID generator (for testing). */
|
|
40
|
-
idGenerator?: IdGenerator;
|
|
41
|
-
/** Use SimpleSpanProcessor instead of BatchSpanProcessor (for testing). */
|
|
42
|
-
useSimpleSpanProcessor?: boolean;
|
|
43
|
-
/** Maximum batch size for span export. */
|
|
44
|
-
maxExportBatchSize?: number;
|
|
45
|
-
/** Delay between batch exports in milliseconds. */
|
|
46
|
-
scheduledDelayMillis?: number;
|
|
47
|
-
}
|
|
48
|
-
/** Configuration for {@link IntrospectionAISDKIntegration}. */
|
|
49
|
-
export interface IntrospectionAISDKIntegrationOptions {
|
|
50
|
-
/** Authentication token (env: INTROSPECTION_TOKEN). */
|
|
51
|
-
token?: string;
|
|
52
|
-
/** Base URL for the API (env: INTROSPECTION_BASE_URL, default: "https://otel.introspection.dev"). */
|
|
53
|
-
baseUrl?: string;
|
|
54
|
-
/** Service name for telemetry (env: INTROSPECTION_SERVICE_NAME). */
|
|
55
|
-
serviceName?: string;
|
|
56
|
-
/** Additional headers to include in requests. */
|
|
57
|
-
additionalHeaders?: Record<string, string>;
|
|
58
|
-
/** Advanced options for testing and customization. */
|
|
59
|
-
advanced?: AISDKIntegrationAdvancedOptions;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* AI SDK {@link TelemetryIntegration} that captures LLM interactions and
|
|
63
|
-
* exports them as OpenTelemetry spans with `gen_ai.*` semantic convention
|
|
64
|
-
* attributes to the Introspection backend.
|
|
65
|
-
*
|
|
66
|
-
* Creates its own {@link BasicTracerProvider} — no external OTel setup required.
|
|
67
|
-
* Each generation (generateText/streamText call) produces:
|
|
68
|
-
* - A root span grouping the entire operation
|
|
69
|
-
* - Step spans (one per LLM call) with full gen_ai attributes
|
|
70
|
-
* - Tool call spans nested under their parent step
|
|
71
|
-
*/
|
|
72
|
-
export declare class IntrospectionAISDKIntegration {
|
|
73
|
-
private _tracerProvider;
|
|
74
|
-
private _tracer;
|
|
75
|
-
private _generation;
|
|
76
|
-
constructor(options?: IntrospectionAISDKIntegrationOptions);
|
|
77
|
-
/**
|
|
78
|
-
* Called when a generation operation begins (before any LLM calls).
|
|
79
|
-
* Creates a root span to group all steps in this generation.
|
|
80
|
-
*/
|
|
81
|
-
onStart: (event: unknown) => void;
|
|
82
|
-
/**
|
|
83
|
-
* Called when a step (individual LLM call) begins.
|
|
84
|
-
* Creates a child span under the root span and captures input messages.
|
|
85
|
-
*/
|
|
86
|
-
onStepStart: (event: unknown) => void;
|
|
87
|
-
/**
|
|
88
|
-
* Called when a tool execution begins.
|
|
89
|
-
* Creates a child span under the current step span.
|
|
90
|
-
*/
|
|
91
|
-
onToolCallStart: (event: unknown) => void;
|
|
92
|
-
/**
|
|
93
|
-
* Called when a tool execution completes.
|
|
94
|
-
* Sets output/error attributes and ends the tool span.
|
|
95
|
-
*/
|
|
96
|
-
onToolCallFinish: (event: unknown) => void;
|
|
97
|
-
/**
|
|
98
|
-
* Called when a step (LLM call) completes.
|
|
99
|
-
* Sets gen_ai attributes (input/output messages, usage, model) and ends
|
|
100
|
-
* the step span.
|
|
101
|
-
*/
|
|
102
|
-
onStepFinish: (event: unknown) => void;
|
|
103
|
-
/**
|
|
104
|
-
* Called when the entire generation completes (all steps finished).
|
|
105
|
-
* Sets total usage on the root span and ends it.
|
|
106
|
-
*/
|
|
107
|
-
onFinish: (event: unknown) => void;
|
|
108
|
-
/**
|
|
109
|
-
* Shut down the tracer provider, flushing all pending spans.
|
|
110
|
-
*
|
|
111
|
-
* @returns A promise that resolves once shutdown is complete.
|
|
112
|
-
*/
|
|
113
|
-
shutdown(): Promise<void>;
|
|
114
|
-
/**
|
|
115
|
-
* Force-flush any buffered spans to the Introspection backend.
|
|
116
|
-
*
|
|
117
|
-
* @returns A promise that resolves once the flush completes.
|
|
118
|
-
*/
|
|
119
|
-
forceFlush(): Promise<void>;
|
|
120
|
-
/** Cleanly end any active generation, closing all open spans. */
|
|
121
|
-
private _endGeneration;
|
|
122
|
-
}
|
|
123
|
-
//# sourceMappingURL=ai-sdk-integration.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai-sdk-integration.d.ts","sourceRoot":"","sources":["../src/ai-sdk-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAOH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAoBvC,sDAAsD;AACtD,MAAM,WAAW,+BAA+B;IAC9C,qEAAqE;IACrE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yCAAyC;IACzC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,2EAA2E;IAC3E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,0CAA0C;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mDAAmD;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,+DAA+D;AAC/D,MAAM,WAAW,oCAAoC;IACnD,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qGAAqG;IACrG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,sDAAsD;IACtD,QAAQ,CAAC,EAAE,+BAA+B,CAAC;CAC5C;AAoBD;;;;;;;;;;GAUG;AACH,qBAAa,6BAA6B;IACxC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,OAAO,CAA+C;IAC9D,OAAO,CAAC,WAAW,CAAgC;gBAEvC,OAAO,GAAE,oCAAyC;IA8F9D;;;OAGG;IACH,OAAO,GAAI,OAAO,OAAO,KAAG,IAAI,CA2D9B;IAEF;;;OAGG;IACH,WAAW,GAAI,OAAO,OAAO,KAAG,IAAI,CAgFlC;IAEF;;;OAGG;IACH,eAAe,GAAI,OAAO,OAAO,KAAG,IAAI,CA0CtC;IAEF;;;OAGG;IACH,gBAAgB,GAAI,OAAO,OAAO,KAAG,IAAI,CAgDvC;IAEF;;;;OAIG;IACH,YAAY,GAAI,OAAO,OAAO,KAAG,IAAI,CAuHnC;IAEF;;;OAGG;IACH,QAAQ,GAAI,OAAO,OAAO,KAAG,IAAI,CA+C/B;IAMF;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC,iEAAiE;IACjE,OAAO,CAAC,cAAc;CASvB"}
|