@introspection-sdk/introspection-node 0.4.2 → 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/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/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/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/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/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.js +1 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.js +1 -0
- package/dist/version.js.map +1 -0
- package/package.json +81 -24
- 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} +95 -8
- 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 +397 -0
- package/src/otel/index.ts +80 -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/setup.ts +174 -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/ai-sdk-integration.ts +0 -691
- package/src/converters/ai-sdk.ts +0 -323
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Paginated,
|
|
3
|
+
Recipe,
|
|
4
|
+
RunRequest,
|
|
5
|
+
Runtime,
|
|
6
|
+
RuntimeCreate,
|
|
7
|
+
RuntimeListParams,
|
|
8
|
+
RuntimeUpdate,
|
|
9
|
+
RunnerSpec,
|
|
10
|
+
Uuid,
|
|
11
|
+
} from "@introspection-sdk/types";
|
|
12
|
+
import { NotFoundError } from "@introspection-sdk/types";
|
|
13
|
+
import type { HttpClient } from "../http.js";
|
|
14
|
+
import type { IntrospectionClient } from "../client.js";
|
|
15
|
+
import { Runner, type RunnerSource } from "../runner.js";
|
|
16
|
+
|
|
17
|
+
const UUID_RE =
|
|
18
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19
|
+
|
|
20
|
+
export function isUuid(value: string): boolean {
|
|
21
|
+
return UUID_RE.test(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface RuntimeRunRequestBody {
|
|
25
|
+
identity?: {
|
|
26
|
+
user_id?: string;
|
|
27
|
+
anonymous_id?: string;
|
|
28
|
+
conversation_id?: string;
|
|
29
|
+
};
|
|
30
|
+
ttl_seconds?: number;
|
|
31
|
+
recipe_id?: Uuid;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function toRunBody(opts?: RunRequest): RuntimeRunRequestBody | undefined {
|
|
35
|
+
if (!opts) return undefined;
|
|
36
|
+
const out: RuntimeRunRequestBody = {};
|
|
37
|
+
if (opts.identity) out.identity = opts.identity;
|
|
38
|
+
if (opts.ttl_seconds !== undefined) out.ttl_seconds = opts.ttl_seconds;
|
|
39
|
+
if (opts.recipe_id !== undefined) out.recipe_id = opts.recipe_id;
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Programmatic CRUD for `/v1/runtimes` on the CP. Mounted on the
|
|
45
|
+
* IntrospectionClient as a callable hybrid (see `RuntimeHandleFactory`).
|
|
46
|
+
*/
|
|
47
|
+
export class RuntimesApi {
|
|
48
|
+
constructor(
|
|
49
|
+
private readonly http: HttpClient,
|
|
50
|
+
private readonly client: IntrospectionClient,
|
|
51
|
+
) {}
|
|
52
|
+
|
|
53
|
+
list(params: RuntimeListParams): Promise<Paginated<Runtime>> {
|
|
54
|
+
return this.http.request<Paginated<Runtime>>({
|
|
55
|
+
method: "GET",
|
|
56
|
+
path: "/v1/runtimes",
|
|
57
|
+
query: params as unknown as Record<string, unknown>,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async *listAll(params: RuntimeListParams): AsyncIterable<Runtime> {
|
|
62
|
+
let next: string | undefined = params.next;
|
|
63
|
+
do {
|
|
64
|
+
const page = await this.list({ ...params, next });
|
|
65
|
+
for (const r of page.records) yield r;
|
|
66
|
+
next = page.next ?? undefined;
|
|
67
|
+
} while (next);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get(id: Uuid, params: { project_id?: Uuid }): Promise<Runtime> {
|
|
71
|
+
return this.http.request<Runtime>({
|
|
72
|
+
method: "GET",
|
|
73
|
+
path: `/v1/runtimes/${encodeURIComponent(id)}`,
|
|
74
|
+
query: params as Record<string, unknown>,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
create(input: RuntimeCreate): Promise<Runtime> {
|
|
79
|
+
return this.http.request<Runtime>({
|
|
80
|
+
method: "POST",
|
|
81
|
+
path: "/v1/runtimes",
|
|
82
|
+
body: input,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
update(id: Uuid, input: RuntimeUpdate): Promise<Runtime> {
|
|
87
|
+
return this.http.request<Runtime>({
|
|
88
|
+
method: "PATCH",
|
|
89
|
+
path: `/v1/runtimes/${encodeURIComponent(id)}`,
|
|
90
|
+
body: input,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
delete(id: Uuid): Promise<void> {
|
|
95
|
+
return this.http.request<void>({
|
|
96
|
+
method: "DELETE",
|
|
97
|
+
path: `/v1/runtimes/${encodeURIComponent(id)}`,
|
|
98
|
+
expect: "empty",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Resolve a name to a runtime by querying `/v1/runtimes?name=…`. */
|
|
103
|
+
async resolveByName(name: string, projectId?: Uuid): Promise<Runtime> {
|
|
104
|
+
const page = await this.list({ project_id: projectId, name, limit: 2 });
|
|
105
|
+
const match = page.records.find((r) => r.name === name);
|
|
106
|
+
if (!match) {
|
|
107
|
+
throw new NotFoundError({
|
|
108
|
+
message: `Runtime '${name}' not found${projectId ? ` in project ${projectId}` : ""}`,
|
|
109
|
+
status: 404,
|
|
110
|
+
code: "not_found",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return match;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** POST `/v1/runtimes/{id}/run` and wrap the result in a `Runner`. */
|
|
117
|
+
async runById(id: Uuid, opts?: RunRequest): Promise<Runner> {
|
|
118
|
+
const spec = await this.http.request<RunnerSpec>({
|
|
119
|
+
method: "POST",
|
|
120
|
+
path: `/v1/runtimes/${encodeURIComponent(id)}/run`,
|
|
121
|
+
body: toRunBody(opts) ?? {},
|
|
122
|
+
});
|
|
123
|
+
const source: RunnerSource = {
|
|
124
|
+
kind: "runtime",
|
|
125
|
+
id,
|
|
126
|
+
options: opts,
|
|
127
|
+
};
|
|
128
|
+
return new Runner(this.client, source, spec);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async activateById(
|
|
132
|
+
id: Uuid,
|
|
133
|
+
params?: { project_id?: Uuid },
|
|
134
|
+
): Promise<Runtime> {
|
|
135
|
+
return this.http.request<Runtime>({
|
|
136
|
+
method: "POST",
|
|
137
|
+
path: `/v1/runtimes/${encodeURIComponent(id)}/activate`,
|
|
138
|
+
query: params as Record<string, unknown> | undefined,
|
|
139
|
+
body: {},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Handle returned by `client.runtimes(idOrName)`. Resolves the underlying
|
|
146
|
+
* runtime id lazily — if you pass a UUID, no extra lookup happens; if you
|
|
147
|
+
* pass a name, the first call that needs the id will hit
|
|
148
|
+
* `/v1/runtimes?name=…`.
|
|
149
|
+
*/
|
|
150
|
+
export class RuntimeHandle {
|
|
151
|
+
private resolvedId: Uuid | null;
|
|
152
|
+
private readonly pinnedRecipeId: Uuid | null;
|
|
153
|
+
|
|
154
|
+
constructor(
|
|
155
|
+
private readonly api: RuntimesApi,
|
|
156
|
+
private readonly client: IntrospectionClient,
|
|
157
|
+
private readonly idOrName: string,
|
|
158
|
+
pinnedRecipeId: Uuid | null = null,
|
|
159
|
+
) {
|
|
160
|
+
this.resolvedId = isUuid(idOrName) ? idOrName : null;
|
|
161
|
+
this.pinnedRecipeId = pinnedRecipeId;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private async resolveId(): Promise<Uuid> {
|
|
165
|
+
if (this.resolvedId) return this.resolvedId;
|
|
166
|
+
const runtime = await this.api.resolveByName(
|
|
167
|
+
this.idOrName,
|
|
168
|
+
this.client.projectId,
|
|
169
|
+
);
|
|
170
|
+
this.resolvedId = runtime.id;
|
|
171
|
+
return runtime.id;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Pin to a specific recipe — canary a previous version. Subsequent
|
|
176
|
+
* `.run()` calls on the returned handle open a runner against the
|
|
177
|
+
* runtime row in this name whose `recipe_id` matches `recipe.id`
|
|
178
|
+
* (resolved server-side by CP).
|
|
179
|
+
*
|
|
180
|
+
* Returns a new child {@link RuntimeHandle}; the original handle is
|
|
181
|
+
* unaffected. Accepts a {@link Recipe} object (uses `.id`) or a
|
|
182
|
+
* recipe id string.
|
|
183
|
+
*/
|
|
184
|
+
pin(recipe: Recipe | string): RuntimeHandle {
|
|
185
|
+
const recipeId = typeof recipe === "string" ? recipe : recipe.id;
|
|
186
|
+
return new RuntimeHandle(this.api, this.client, this.idOrName, recipeId);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async run(opts?: RunRequest): Promise<Runner> {
|
|
190
|
+
const id = await this.resolveId();
|
|
191
|
+
const merged: RunRequest | undefined =
|
|
192
|
+
this.pinnedRecipeId !== null
|
|
193
|
+
? { ...(opts ?? {}), recipe_id: this.pinnedRecipeId }
|
|
194
|
+
: opts;
|
|
195
|
+
return this.api.runById(id, merged);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async activate(params?: { projectId?: Uuid }): Promise<Runtime> {
|
|
199
|
+
const id = await this.resolveId();
|
|
200
|
+
return this.api.activateById(id, { project_id: params?.projectId });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Callable hybrid: `client.runtimes` exposes the CRUD methods of
|
|
206
|
+
* `RuntimesApi` AND can be invoked as a function returning a
|
|
207
|
+
* `RuntimeHandle`. Realised by `attachRuntimes` below.
|
|
208
|
+
*/
|
|
209
|
+
export type RuntimeHandleFactory = (idOrName: string) => RuntimeHandle;
|
|
210
|
+
|
|
211
|
+
export function attachRuntimes(
|
|
212
|
+
client: IntrospectionClient,
|
|
213
|
+
http: HttpClient,
|
|
214
|
+
): RuntimesApi & RuntimeHandleFactory {
|
|
215
|
+
const api = new RuntimesApi(http, client);
|
|
216
|
+
const factory: RuntimeHandleFactory = (idOrName: string) =>
|
|
217
|
+
new RuntimeHandle(api, client, idOrName);
|
|
218
|
+
// Mount the API methods on the factory function. Using bound copies so
|
|
219
|
+
// the methods can be invoked off the proxy without losing `this`.
|
|
220
|
+
const hybrid = factory as RuntimesApi & RuntimeHandleFactory;
|
|
221
|
+
hybrid.list = api.list.bind(api);
|
|
222
|
+
hybrid.listAll = api.listAll.bind(api);
|
|
223
|
+
hybrid.get = api.get.bind(api);
|
|
224
|
+
hybrid.create = api.create.bind(api);
|
|
225
|
+
hybrid.update = api.update.bind(api);
|
|
226
|
+
hybrid.delete = api.delete.bind(api);
|
|
227
|
+
hybrid.resolveByName = api.resolveByName.bind(api);
|
|
228
|
+
hybrid.runById = api.runById.bind(api);
|
|
229
|
+
hybrid.activateById = api.activateById.bind(api);
|
|
230
|
+
return hybrid;
|
|
231
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
File as FileResource,
|
|
3
|
+
FileCreateTextParams,
|
|
4
|
+
FileListParams,
|
|
5
|
+
FileType,
|
|
6
|
+
FileUpdateParams,
|
|
7
|
+
ListParams,
|
|
8
|
+
Paginated,
|
|
9
|
+
} from "@introspection-sdk/types";
|
|
10
|
+
import { HttpClient } from "../http.js";
|
|
11
|
+
|
|
12
|
+
export type FileUploadBody =
|
|
13
|
+
| { file: Blob; name?: string; file_type?: FileType }
|
|
14
|
+
| {
|
|
15
|
+
file: Uint8Array;
|
|
16
|
+
name: string;
|
|
17
|
+
file_type?: FileType;
|
|
18
|
+
contentType?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export class FileVersionsApi {
|
|
22
|
+
constructor(private readonly http: HttpClient) {}
|
|
23
|
+
|
|
24
|
+
list(fileId: string, params?: ListParams): Promise<Paginated<FileResource>> {
|
|
25
|
+
return this.http.request<Paginated<FileResource>>({
|
|
26
|
+
method: "GET",
|
|
27
|
+
path: `/v1/files/${encodeURIComponent(fileId)}/versions`,
|
|
28
|
+
query: params as Record<string, unknown> | undefined,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async *listAll(
|
|
33
|
+
fileId: string,
|
|
34
|
+
params?: ListParams,
|
|
35
|
+
): AsyncIterable<FileResource> {
|
|
36
|
+
let next: string | undefined = params?.next;
|
|
37
|
+
do {
|
|
38
|
+
const page = await this.list(fileId, { ...params, next });
|
|
39
|
+
for (const f of page.records) yield f;
|
|
40
|
+
next = page.next ?? undefined;
|
|
41
|
+
} while (next);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get(fileId: string, versionId: string): Promise<FileResource> {
|
|
45
|
+
return this.http.request<FileResource>({
|
|
46
|
+
method: "GET",
|
|
47
|
+
path: `/v1/files/${encodeURIComponent(fileId)}/versions/${encodeURIComponent(versionId)}`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
create(fileId: string, body: FileUploadBody): Promise<FileResource> {
|
|
52
|
+
const form = toFormData(body);
|
|
53
|
+
return this.http.request<FileResource>({
|
|
54
|
+
method: "POST",
|
|
55
|
+
path: `/v1/files/${encodeURIComponent(fileId)}/versions`,
|
|
56
|
+
body: form,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class FilesApi {
|
|
62
|
+
readonly versions: FileVersionsApi;
|
|
63
|
+
|
|
64
|
+
constructor(private readonly http: HttpClient) {
|
|
65
|
+
this.versions = new FileVersionsApi(http);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
list(params?: FileListParams): Promise<Paginated<FileResource>> {
|
|
69
|
+
return this.http.request<Paginated<FileResource>>({
|
|
70
|
+
method: "GET",
|
|
71
|
+
path: "/v1/files",
|
|
72
|
+
query: params as Record<string, unknown> | undefined,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async *listAll(params?: FileListParams): AsyncIterable<FileResource> {
|
|
77
|
+
let next: string | undefined = params?.next;
|
|
78
|
+
do {
|
|
79
|
+
const page = await this.list({ ...params, next });
|
|
80
|
+
for (const f of page.records) yield f;
|
|
81
|
+
next = page.next ?? undefined;
|
|
82
|
+
} while (next);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
upload(body: FileUploadBody): Promise<FileResource> {
|
|
86
|
+
const form = toFormData(body);
|
|
87
|
+
return this.http.request<FileResource>({
|
|
88
|
+
method: "POST",
|
|
89
|
+
path: "/v1/files",
|
|
90
|
+
body: form,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
createText(body: FileCreateTextParams): Promise<FileResource> {
|
|
95
|
+
return this.http.request<FileResource>({
|
|
96
|
+
method: "POST",
|
|
97
|
+
path: "/v1/files",
|
|
98
|
+
body,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get(fileId: string): Promise<FileResource> {
|
|
103
|
+
return this.http.request<FileResource>({
|
|
104
|
+
method: "GET",
|
|
105
|
+
path: `/v1/files/${encodeURIComponent(fileId)}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
update(fileId: string, body: FileUpdateParams): Promise<FileResource> {
|
|
110
|
+
return this.http.request<FileResource>({
|
|
111
|
+
method: "PATCH",
|
|
112
|
+
path: `/v1/files/${encodeURIComponent(fileId)}`,
|
|
113
|
+
body,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
delete(fileId: string): Promise<void> {
|
|
118
|
+
return this.http.request<void>({
|
|
119
|
+
method: "DELETE",
|
|
120
|
+
path: `/v1/files/${encodeURIComponent(fileId)}`,
|
|
121
|
+
expect: "empty",
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
download(fileId: string): Promise<Uint8Array> {
|
|
126
|
+
return this.http.request<Uint8Array>({
|
|
127
|
+
method: "GET",
|
|
128
|
+
path: `/v1/files/${encodeURIComponent(fileId)}/content`,
|
|
129
|
+
expect: "bytes",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
downloadStream(fileId: string): Promise<ReadableStream<Uint8Array>> {
|
|
134
|
+
return this.http.request<ReadableStream<Uint8Array>>({
|
|
135
|
+
method: "GET",
|
|
136
|
+
path: `/v1/files/${encodeURIComponent(fileId)}/content`,
|
|
137
|
+
expect: "stream",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function toFormData(body: FileUploadBody): FormData {
|
|
143
|
+
const fd = new FormData();
|
|
144
|
+
if ("file" in body && body.file instanceof Blob) {
|
|
145
|
+
fd.append("file", body.file, body.name);
|
|
146
|
+
} else {
|
|
147
|
+
// Uint8Array branch — copy into a fresh ArrayBuffer so the Blob
|
|
148
|
+
// constructor sees a concrete ArrayBuffer (not ArrayBufferLike,
|
|
149
|
+
// which TS rejects under nodenext lib).
|
|
150
|
+
const u8 = (body as { file: Uint8Array }).file;
|
|
151
|
+
const ct =
|
|
152
|
+
(body as { contentType?: string }).contentType ??
|
|
153
|
+
"application/octet-stream";
|
|
154
|
+
const ab = u8.buffer.slice(
|
|
155
|
+
u8.byteOffset,
|
|
156
|
+
u8.byteOffset + u8.byteLength,
|
|
157
|
+
) as ArrayBuffer;
|
|
158
|
+
fd.append("file", new Blob([ab], { type: ct }), body.name);
|
|
159
|
+
}
|
|
160
|
+
if (body.name) fd.append("name", body.name);
|
|
161
|
+
if (body.file_type) fd.append("file_type", body.file_type);
|
|
162
|
+
return fd;
|
|
163
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Paginated,
|
|
3
|
+
SseEvent,
|
|
4
|
+
Task,
|
|
5
|
+
TaskCancelResponse,
|
|
6
|
+
TaskCreateParams,
|
|
7
|
+
TaskCreateResponse,
|
|
8
|
+
TaskListParams,
|
|
9
|
+
TaskRun,
|
|
10
|
+
TaskRunCreateParams,
|
|
11
|
+
TaskRunResponse,
|
|
12
|
+
TaskUpdateParams,
|
|
13
|
+
} from "@introspection-sdk/types";
|
|
14
|
+
import { HttpClient } from "../http.js";
|
|
15
|
+
import { parseSse } from "../streaming.js";
|
|
16
|
+
|
|
17
|
+
export interface StartParams extends TaskCreateParams {
|
|
18
|
+
prompt: string; // required for the cursor-style sugar
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class RunHandle {
|
|
22
|
+
constructor(
|
|
23
|
+
public readonly task: Task | null,
|
|
24
|
+
public readonly run: TaskRun,
|
|
25
|
+
private readonly runs: TaskRunsApi,
|
|
26
|
+
) {}
|
|
27
|
+
|
|
28
|
+
stream(): AsyncIterable<SseEvent> {
|
|
29
|
+
return this.runs.stream(this.run.task_id, this.run.id);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
cancel(): Promise<TaskCancelResponse> {
|
|
33
|
+
return this.runs.cancel(this.run.task_id, this.run.id);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Convenience: collect `data` from `event: text`-style frames into a string. */
|
|
37
|
+
async text(): Promise<string> {
|
|
38
|
+
let out = "";
|
|
39
|
+
for await (const ev of this.stream()) {
|
|
40
|
+
if (ev.event === "text" || ev.event === "message") out += ev.data;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class TaskRunsApi {
|
|
47
|
+
constructor(private readonly http: HttpClient) {}
|
|
48
|
+
|
|
49
|
+
async create(taskId: string, body: TaskRunCreateParams): Promise<RunHandle> {
|
|
50
|
+
const res = await this.http.request<TaskRunResponse>({
|
|
51
|
+
method: "POST",
|
|
52
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs`,
|
|
53
|
+
body,
|
|
54
|
+
});
|
|
55
|
+
return new RunHandle(null, res.run, this);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get(taskId: string, runId: string): Promise<TaskRun> {
|
|
59
|
+
return this.http.request<TaskRun>({
|
|
60
|
+
method: "GET",
|
|
61
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}`,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
cancel(taskId: string, runId: string): Promise<TaskCancelResponse> {
|
|
66
|
+
return this.http.request<TaskCancelResponse>({
|
|
67
|
+
method: "POST",
|
|
68
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/cancel`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async *stream(taskId: string, runId: string): AsyncIterable<SseEvent> {
|
|
73
|
+
const res = await this.http.stream({
|
|
74
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/runs/${encodeURIComponent(runId)}/stream`,
|
|
75
|
+
});
|
|
76
|
+
yield* parseSse(res);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class TasksApi {
|
|
81
|
+
readonly runs: TaskRunsApi;
|
|
82
|
+
|
|
83
|
+
constructor(private readonly http: HttpClient) {
|
|
84
|
+
this.runs = new TaskRunsApi(http);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
list(params?: TaskListParams): Promise<Paginated<Task>> {
|
|
88
|
+
return this.http.request<Paginated<Task>>({
|
|
89
|
+
method: "GET",
|
|
90
|
+
path: "/v1/tasks",
|
|
91
|
+
query: params as Record<string, unknown> | undefined,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async *listAll(params?: TaskListParams): AsyncIterable<Task> {
|
|
96
|
+
let next: string | undefined = params?.next;
|
|
97
|
+
do {
|
|
98
|
+
const page = await this.list({ ...params, next });
|
|
99
|
+
for (const t of page.records) yield t;
|
|
100
|
+
next = page.next ?? undefined;
|
|
101
|
+
} while (next);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
create(body: TaskCreateParams): Promise<TaskCreateResponse> {
|
|
105
|
+
return this.http.request<TaskCreateResponse>({
|
|
106
|
+
method: "POST",
|
|
107
|
+
path: "/v1/tasks",
|
|
108
|
+
body,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get(taskId: string): Promise<Task> {
|
|
113
|
+
return this.http.request<Task>({
|
|
114
|
+
method: "GET",
|
|
115
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
update(taskId: string, body: TaskUpdateParams): Promise<Task> {
|
|
120
|
+
return this.http.request<Task>({
|
|
121
|
+
method: "PATCH",
|
|
122
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
123
|
+
body,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
delete(taskId: string): Promise<void> {
|
|
128
|
+
return this.http.request<void>({
|
|
129
|
+
method: "DELETE",
|
|
130
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
131
|
+
expect: "empty",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
archive(taskId: string): Promise<void> {
|
|
136
|
+
return this.http.request<void>({
|
|
137
|
+
method: "POST",
|
|
138
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/archive`,
|
|
139
|
+
expect: "empty",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
unarchive(taskId: string): Promise<void> {
|
|
144
|
+
return this.http.request<void>({
|
|
145
|
+
method: "POST",
|
|
146
|
+
path: `/v1/tasks/${encodeURIComponent(taskId)}/unarchive`,
|
|
147
|
+
expect: "empty",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Cursor-style sugar: create a task + return a handle on its initial run. */
|
|
152
|
+
async start(params: StartParams): Promise<RunHandle> {
|
|
153
|
+
const res = await this.create(params);
|
|
154
|
+
return new RunHandle(res.task, res.run, this.runs);
|
|
155
|
+
}
|
|
156
|
+
}
|