@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/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,4 +1,19 @@
|
|
|
1
1
|
import { DiagLogLevel, DiagLogger } from "@opentelemetry/api";
|
|
2
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
3
|
+
|
|
4
|
+
function getHttpsProxyUrl(): string | undefined {
|
|
5
|
+
return process.env.HTTPS_PROXY || undefined;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function withOtlpHttpsProxy<T extends object>(options: T): T {
|
|
9
|
+
const proxyUrl = getHttpsProxyUrl();
|
|
10
|
+
if (!proxyUrl) return options;
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
...options,
|
|
14
|
+
httpAgentOptions: () => new HttpsProxyAgent(proxyUrl),
|
|
15
|
+
} as T;
|
|
16
|
+
}
|
|
2
17
|
|
|
3
18
|
/**
|
|
4
19
|
* Logger for introspection-sdk package.
|