@ingram-cloud/sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/dist/client.js +460 -0
- package/dist/events.js +108 -0
- package/dist/index.js +19 -0
- package/dist/responses.js +12 -0
- package/dist/schemas.js +4 -0
- package/dist/zod/_page.js +17 -0
- package/dist/zod/agents.js +176 -0
- package/dist/zod/approvals.js +38 -0
- package/dist/zod/budgets.js +62 -0
- package/dist/zod/catalog.js +49 -0
- package/dist/zod/connections.js +75 -0
- package/dist/zod/conversations.js +91 -0
- package/dist/zod/customers.js +53 -0
- package/dist/zod/deployments.js +81 -0
- package/dist/zod/discord.js +32 -0
- package/dist/zod/email.js +45 -0
- package/dist/zod/files.js +55 -0
- package/dist/zod/index.js +35 -0
- package/dist/zod/mcp.js +107 -0
- package/dist/zod/memories.js +43 -0
- package/dist/zod/observability.js +133 -0
- package/dist/zod/projects.js +58 -0
- package/dist/zod/runs.js +119 -0
- package/dist/zod/schedules.js +71 -0
- package/dist/zod/slack.js +69 -0
- package/dist/zod/smith-revisions.js +42 -0
- package/dist/zod/smiths.js +108 -0
- package/dist/zod/telegram.js +36 -0
- package/dist/zod/tenant.js +219 -0
- package/dist/zod/vector-stores.js +251 -0
- package/dist/zod/whatsapp.js +47 -0
- package/package.json +56 -0
- package/ts/client.ts +1187 -0
- package/ts/events.ts +119 -0
- package/ts/index.ts +20 -0
- package/ts/responses.ts +83 -0
- package/ts/schemas.ts +4 -0
- package/ts/zod/_page.ts +18 -0
- package/ts/zod/agents.ts +202 -0
- package/ts/zod/approvals.ts +44 -0
- package/ts/zod/budgets.ts +75 -0
- package/ts/zod/catalog.ts +57 -0
- package/ts/zod/connections.ts +87 -0
- package/ts/zod/conversations.ts +103 -0
- package/ts/zod/customers.ts +62 -0
- package/ts/zod/deployments.ts +93 -0
- package/ts/zod/discord.ts +39 -0
- package/ts/zod/email.ts +52 -0
- package/ts/zod/files.ts +62 -0
- package/ts/zod/index.ts +35 -0
- package/ts/zod/mcp.ts +123 -0
- package/ts/zod/memories.ts +53 -0
- package/ts/zod/observability.ts +155 -0
- package/ts/zod/projects.ts +68 -0
- package/ts/zod/runs.ts +135 -0
- package/ts/zod/schedules.ts +82 -0
- package/ts/zod/slack.ts +79 -0
- package/ts/zod/smith-revisions.ts +50 -0
- package/ts/zod/smiths.ts +118 -0
- package/ts/zod/telegram.ts +43 -0
- package/ts/zod/tenant.ts +267 -0
- package/ts/zod/vector-stores.ts +296 -0
- package/ts/zod/whatsapp.ts +54 -0
package/ts/client.ts
ADDED
|
@@ -0,0 +1,1187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Ingram Cloud management-plane client: typed CRUD over the `/v1` REST
|
|
3
|
+
* surface (smiths, agents, runs, deployments, tenant config, organization).
|
|
4
|
+
*
|
|
5
|
+
* The data plane is not here on purpose. Chat rides the OpenAI-compatible
|
|
6
|
+
* surface via `@ingram-cloud/ai-sdk`; the native run stream returns the
|
|
7
|
+
* raw SSE `Response` for the caller to pump (`smiths.runs.stream`).
|
|
8
|
+
*
|
|
9
|
+
* Method inputs are `z.input`-inferred from the same Zod schemas the API
|
|
10
|
+
* validates requests with (`./zod/*`), and outputs are the `IC*` response
|
|
11
|
+
* types — every import here is type-only, so the client pulls no Zod (or
|
|
12
|
+
* anything else) in at runtime. Transport is the global `fetch`.
|
|
13
|
+
*
|
|
14
|
+
* Auth is a pluggable token seam: pass a static bearer, or a function that
|
|
15
|
+
* mints one per request (e.g. a short-lived tenant-admin token). Smith-scoped
|
|
16
|
+
* calls made with a tenant token name the acting smith per call via
|
|
17
|
+
* `{ smith: "smt_…" }`, which rides the `IC-Smith-Id` header.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { IngramCloud } from "@ingram-cloud/sdk/client";
|
|
21
|
+
*
|
|
22
|
+
* const ic = new IngramCloud({ token: process.env.INGRAM_CLOUD_TOKEN! });
|
|
23
|
+
* const smith = await ic.smiths.create({ external_id: "user-42" });
|
|
24
|
+
* const page = await ic.smiths.list({ limit: 50 });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import type { z } from "zod";
|
|
28
|
+
import type {
|
|
29
|
+
ICAgent,
|
|
30
|
+
ICAgentVersion,
|
|
31
|
+
ICApproval,
|
|
32
|
+
ICBudget,
|
|
33
|
+
ICBudgetStatus,
|
|
34
|
+
ICCatalogEntry,
|
|
35
|
+
ICConnection,
|
|
36
|
+
ICConversation,
|
|
37
|
+
ICConversationItem,
|
|
38
|
+
ICCustomer,
|
|
39
|
+
ICDeployment,
|
|
40
|
+
ICDeploymentCreated,
|
|
41
|
+
ICDiscordApp,
|
|
42
|
+
ICEmailConfig,
|
|
43
|
+
ICEvent,
|
|
44
|
+
ICFile,
|
|
45
|
+
ICFileList,
|
|
46
|
+
ICMcpServer,
|
|
47
|
+
ICMintedToken,
|
|
48
|
+
ICModelCatalog,
|
|
49
|
+
ICModelKey,
|
|
50
|
+
ICProject,
|
|
51
|
+
ICProvider,
|
|
52
|
+
ICRecallHit,
|
|
53
|
+
ICRun,
|
|
54
|
+
ICRunEvent,
|
|
55
|
+
ICSchedule,
|
|
56
|
+
ICSlackApp,
|
|
57
|
+
ICSmith,
|
|
58
|
+
ICSmithRevision,
|
|
59
|
+
ICTelegramBot,
|
|
60
|
+
ICToken,
|
|
61
|
+
ICTrace,
|
|
62
|
+
ICTraceDetail,
|
|
63
|
+
ICUiResource,
|
|
64
|
+
ICUsage,
|
|
65
|
+
ICUsageBreakdown,
|
|
66
|
+
ICVectorStore,
|
|
67
|
+
ICVectorStoreFile,
|
|
68
|
+
ICVectorStoreFileBatch,
|
|
69
|
+
ICVectorStoreSearchPage,
|
|
70
|
+
ICWebhook,
|
|
71
|
+
ICWhatsAppConfig,
|
|
72
|
+
ICWorkingMemory,
|
|
73
|
+
} from "./responses.js";
|
|
74
|
+
import type {
|
|
75
|
+
AgentIn,
|
|
76
|
+
AgentPatch,
|
|
77
|
+
AttachIn,
|
|
78
|
+
ImportIn,
|
|
79
|
+
PublishIn,
|
|
80
|
+
RolloutIn,
|
|
81
|
+
UiResourceIn,
|
|
82
|
+
} from "./zod/agents.js";
|
|
83
|
+
import type { BudgetIn, BudgetPatch } from "./zod/budgets.js";
|
|
84
|
+
import type {
|
|
85
|
+
AuthorizeIn,
|
|
86
|
+
AuthorizeOut,
|
|
87
|
+
ConnectionIn,
|
|
88
|
+
ConnectionPatch,
|
|
89
|
+
} from "./zod/connections.js";
|
|
90
|
+
import type { ConversationCreate, ConversationUpdate } from "./zod/conversations.js";
|
|
91
|
+
import type { CustomerCreate, CustomerPatch } from "./zod/customers.js";
|
|
92
|
+
import type { DeploymentIn, DeploymentPatch } from "./zod/deployments.js";
|
|
93
|
+
import type { DiscordAppIn } from "./zod/discord.js";
|
|
94
|
+
import type { EmailConfigIn } from "./zod/email.js";
|
|
95
|
+
import type { McpServerIn, McpServerWriteOut } from "./zod/mcp.js";
|
|
96
|
+
import type { RecallBody, WorkingMemorySet } from "./zod/memories.js";
|
|
97
|
+
import type { ProjectIn, ProjectTokenIn, ProjectTokenOut } from "./zod/projects.js";
|
|
98
|
+
import type { RunIn, Submit } from "./zod/runs.js";
|
|
99
|
+
import type {
|
|
100
|
+
VectorStoreFileBatchIn,
|
|
101
|
+
VectorStoreFileIn,
|
|
102
|
+
VectorStoreFileUpdate,
|
|
103
|
+
VectorStoreIn,
|
|
104
|
+
VectorStorePatch,
|
|
105
|
+
VectorStoreSearchIn,
|
|
106
|
+
} from "./zod/vector-stores.js";
|
|
107
|
+
import type { ScheduleIn, SchedulePatch, ScheduleRunNowOut } from "./zod/schedules.js";
|
|
108
|
+
import type { SlackAppIn } from "./zod/slack.js";
|
|
109
|
+
import type { RestoreIn } from "./zod/smith-revisions.js";
|
|
110
|
+
import type { SmithCreate, SmithPatch } from "./zod/smiths.js";
|
|
111
|
+
import type { TelegramBotIn } from "./zod/telegram.js";
|
|
112
|
+
import type {
|
|
113
|
+
HostedToolOut,
|
|
114
|
+
ModelKeyConfiguredOut,
|
|
115
|
+
ModelKeyIn,
|
|
116
|
+
ProviderConfiguredOut,
|
|
117
|
+
ProviderIn,
|
|
118
|
+
TokenIn,
|
|
119
|
+
WebhookCreateOut,
|
|
120
|
+
WebhookIn,
|
|
121
|
+
WebhookPatch,
|
|
122
|
+
} from "./zod/tenant.js";
|
|
123
|
+
import type { WhatsAppConfigIn } from "./zod/whatsapp.js";
|
|
124
|
+
|
|
125
|
+
export const DEFAULT_BASE_URL = "https://api.cloud.ingram.tech";
|
|
126
|
+
|
|
127
|
+
/** The `/v1` API version this client pins (`IC-Api-Version`). */
|
|
128
|
+
export const DEFAULT_API_VERSION = "2026-05-01";
|
|
129
|
+
|
|
130
|
+
/** A cursor-paginated `/v1` list page, normalized so a missing cursor reads as
|
|
131
|
+
* a terminal page. Pass `next_cursor` straight back as `cursor`. */
|
|
132
|
+
export interface ICPage<T> {
|
|
133
|
+
data: T[];
|
|
134
|
+
next_cursor: string | null;
|
|
135
|
+
has_more: boolean;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** A non-2xx `/v1` response: HTTP status + the error envelope's `code`.
|
|
139
|
+
* `message` carries the full context (method, path, status); `detail` is the
|
|
140
|
+
* envelope's bare `error.message`, suitable for user-facing copy. */
|
|
141
|
+
export class ICError extends Error {
|
|
142
|
+
constructor(
|
|
143
|
+
public readonly status: number,
|
|
144
|
+
public readonly code: string,
|
|
145
|
+
message: string,
|
|
146
|
+
public readonly requestId?: string,
|
|
147
|
+
public readonly detail?: string,
|
|
148
|
+
) {
|
|
149
|
+
super(message);
|
|
150
|
+
this.name = "ICError";
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface IngramCloudOptions {
|
|
155
|
+
/** Bearer token, or a function minting one per request (e.g. a short-lived
|
|
156
|
+
* tenant-admin token). */
|
|
157
|
+
token: string | (() => string | Promise<string>);
|
|
158
|
+
/** API origin. Default {@link DEFAULT_BASE_URL}. */
|
|
159
|
+
baseURL?: string;
|
|
160
|
+
/** Override the pinned `IC-Api-Version`. */
|
|
161
|
+
apiVersion?: string;
|
|
162
|
+
/** Custom transport (tests, in-process apps). Default: global `fetch`. */
|
|
163
|
+
fetch?: (url: string, init: RequestInit) => Response | Promise<Response>;
|
|
164
|
+
/** Extra `RequestInit` merged into every request (e.g. Next's
|
|
165
|
+
* `{ cache: "no-store" }`). */
|
|
166
|
+
requestInit?: RequestInit;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Per-call options accepted by every method. */
|
|
170
|
+
export interface RequestOptions {
|
|
171
|
+
/** Acting smith for smith-scoped calls made with a tenant token
|
|
172
|
+
* (`IC-Smith-Id` header). */
|
|
173
|
+
smith?: string;
|
|
174
|
+
/** Per-call bearer override (e.g. a minted per-principal token). */
|
|
175
|
+
token?: string;
|
|
176
|
+
headers?: Record<string, string>;
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Query params: skipped when `undefined`/`null`/`""`. Typed as `object` so
|
|
181
|
+
* the concrete per-endpoint option interfaces assign without index
|
|
182
|
+
* signatures; values are stringified. */
|
|
183
|
+
type Query = object;
|
|
184
|
+
|
|
185
|
+
interface FullRequestOptions extends RequestOptions {
|
|
186
|
+
query?: Query;
|
|
187
|
+
body?: unknown;
|
|
188
|
+
/** Pass-through body (multipart uploads); no JSON content-type is set. */
|
|
189
|
+
rawBody?: RequestInit["body"];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Common cursor-pagination query params. */
|
|
193
|
+
export interface PageOpts {
|
|
194
|
+
cursor?: string;
|
|
195
|
+
limit?: number;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const enc = encodeURIComponent;
|
|
199
|
+
|
|
200
|
+
function qs(query: Query | undefined): string {
|
|
201
|
+
if (!query) return "";
|
|
202
|
+
const p = new URLSearchParams();
|
|
203
|
+
for (const [k, v] of Object.entries(query) as [string, unknown][]) {
|
|
204
|
+
if (v === undefined || v === null || v === "") continue;
|
|
205
|
+
p.set(k, String(v));
|
|
206
|
+
}
|
|
207
|
+
const s = p.toString();
|
|
208
|
+
return s ? `?${s}` : "";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export class IngramCloud {
|
|
212
|
+
private readonly token: IngramCloudOptions["token"];
|
|
213
|
+
private readonly base: string;
|
|
214
|
+
private readonly apiVersion: string;
|
|
215
|
+
private readonly transport: (
|
|
216
|
+
url: string,
|
|
217
|
+
init: RequestInit,
|
|
218
|
+
) => Response | Promise<Response>;
|
|
219
|
+
private readonly requestInit: RequestInit;
|
|
220
|
+
|
|
221
|
+
constructor(opts: IngramCloudOptions) {
|
|
222
|
+
this.token = opts.token;
|
|
223
|
+
this.base = (opts.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
224
|
+
this.apiVersion = opts.apiVersion ?? DEFAULT_API_VERSION;
|
|
225
|
+
this.transport = opts.fetch ?? ((url, init) => fetch(url, init));
|
|
226
|
+
this.requestInit = opts.requestInit ?? {};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Low-level escape hatch: an authenticated `/v1` call (path without the
|
|
230
|
+
* `/v1` prefix). Throws {@link ICError} on a non-2xx. */
|
|
231
|
+
async request(
|
|
232
|
+
method: string,
|
|
233
|
+
path: string,
|
|
234
|
+
opts: FullRequestOptions = {},
|
|
235
|
+
): Promise<Response> {
|
|
236
|
+
const token =
|
|
237
|
+
opts.token ??
|
|
238
|
+
(typeof this.token === "function" ? await this.token() : this.token);
|
|
239
|
+
const headers: Record<string, string> = {
|
|
240
|
+
accept: "application/json",
|
|
241
|
+
"ic-api-version": this.apiVersion,
|
|
242
|
+
authorization: `Bearer ${token}`,
|
|
243
|
+
...(opts.body !== undefined && opts.rawBody === undefined
|
|
244
|
+
? { "content-type": "application/json" }
|
|
245
|
+
: {}),
|
|
246
|
+
...(opts.smith ? { "ic-smith-id": opts.smith } : {}),
|
|
247
|
+
...opts.headers,
|
|
248
|
+
};
|
|
249
|
+
const res = await this.transport(`${this.base}/v1${path}${qs(opts.query)}`, {
|
|
250
|
+
...this.requestInit,
|
|
251
|
+
method,
|
|
252
|
+
headers,
|
|
253
|
+
body:
|
|
254
|
+
opts.rawBody ??
|
|
255
|
+
(opts.body !== undefined ? JSON.stringify(opts.body) : undefined),
|
|
256
|
+
signal: opts.signal,
|
|
257
|
+
});
|
|
258
|
+
if (!res.ok) {
|
|
259
|
+
const body = await res.text().catch(() => "");
|
|
260
|
+
let code = `http_${res.status}`;
|
|
261
|
+
let detail: string | undefined;
|
|
262
|
+
try {
|
|
263
|
+
const parsed = JSON.parse(body) as {
|
|
264
|
+
error?: { code?: string; message?: string };
|
|
265
|
+
};
|
|
266
|
+
code = parsed.error?.code ?? code;
|
|
267
|
+
detail = parsed.error?.message;
|
|
268
|
+
} catch {}
|
|
269
|
+
const requestId = res.headers.get("x-request-id") ?? undefined;
|
|
270
|
+
throw new ICError(
|
|
271
|
+
res.status,
|
|
272
|
+
code,
|
|
273
|
+
`IC ${method} ${path} → ${res.status} ${code}: ${detail ?? body.slice(0, 300)}${requestId ? ` [${requestId}]` : ""}`,
|
|
274
|
+
requestId,
|
|
275
|
+
detail,
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
return res;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** {@link request}, parsed as JSON. */
|
|
282
|
+
async json<T>(
|
|
283
|
+
method: string,
|
|
284
|
+
path: string,
|
|
285
|
+
opts: FullRequestOptions = {},
|
|
286
|
+
): Promise<T> {
|
|
287
|
+
const res = await this.request(method, path, opts);
|
|
288
|
+
return res.json() as Promise<T>;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private async page<T>(
|
|
292
|
+
path: string,
|
|
293
|
+
query: Query | undefined,
|
|
294
|
+
opts?: RequestOptions,
|
|
295
|
+
): Promise<ICPage<T>> {
|
|
296
|
+
const r = await this.json<Partial<ICPage<T>>>("GET", path, { ...opts, query });
|
|
297
|
+
return {
|
|
298
|
+
data: r.data ?? [],
|
|
299
|
+
next_cursor: r.next_cursor ?? null,
|
|
300
|
+
has_more: r.has_more ?? false,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private async data<T>(
|
|
305
|
+
method: string,
|
|
306
|
+
path: string,
|
|
307
|
+
opts: FullRequestOptions = {},
|
|
308
|
+
): Promise<T[]> {
|
|
309
|
+
const r = await this.json<{ data?: T[] }>(method, path, opts);
|
|
310
|
+
return r.data ?? [];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private async empty(
|
|
314
|
+
method: string,
|
|
315
|
+
path: string,
|
|
316
|
+
opts: FullRequestOptions = {},
|
|
317
|
+
): Promise<void> {
|
|
318
|
+
await this.request(method, path, opts);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ── Smiths ──────────────────────────────────────────────────────────────
|
|
322
|
+
|
|
323
|
+
readonly smiths = {
|
|
324
|
+
list: (
|
|
325
|
+
query?: PageOpts & {
|
|
326
|
+
agent_id?: string;
|
|
327
|
+
customer_id?: string;
|
|
328
|
+
external_id?: string;
|
|
329
|
+
external_id_prefix?: string;
|
|
330
|
+
},
|
|
331
|
+
opts?: RequestOptions,
|
|
332
|
+
) => this.page<ICSmith>("/smiths", query, opts),
|
|
333
|
+
create: (body: z.input<typeof SmithCreate>, opts?: RequestOptions) =>
|
|
334
|
+
this.json<ICSmith>("POST", "/smiths", { ...opts, body }),
|
|
335
|
+
get: (pid: string, opts?: RequestOptions) =>
|
|
336
|
+
this.json<ICSmith>("GET", `/smiths/${enc(pid)}`, opts),
|
|
337
|
+
update: (
|
|
338
|
+
pid: string,
|
|
339
|
+
body: z.input<typeof SmithPatch>,
|
|
340
|
+
opts?: RequestOptions,
|
|
341
|
+
) => this.json<ICSmith>("PATCH", `/smiths/${enc(pid)}`, { ...opts, body }),
|
|
342
|
+
delete: (pid: string, opts?: RequestOptions) =>
|
|
343
|
+
this.empty("DELETE", `/smiths/${enc(pid)}`, opts),
|
|
344
|
+
|
|
345
|
+
memory: {
|
|
346
|
+
get: (pid: string, opts?: RequestOptions) =>
|
|
347
|
+
this.json<ICWorkingMemory>("GET", `/smiths/${enc(pid)}/memory`, opts),
|
|
348
|
+
set: (
|
|
349
|
+
pid: string,
|
|
350
|
+
body: z.input<typeof WorkingMemorySet>,
|
|
351
|
+
opts?: RequestOptions,
|
|
352
|
+
) =>
|
|
353
|
+
this.json<ICWorkingMemory>("PUT", `/smiths/${enc(pid)}/memory`, {
|
|
354
|
+
...opts,
|
|
355
|
+
body,
|
|
356
|
+
}),
|
|
357
|
+
recall: (
|
|
358
|
+
pid: string,
|
|
359
|
+
body: z.input<typeof RecallBody>,
|
|
360
|
+
opts?: RequestOptions,
|
|
361
|
+
) =>
|
|
362
|
+
this.data<ICRecallHit>("POST", `/smiths/${enc(pid)}/memory/recall`, {
|
|
363
|
+
...opts,
|
|
364
|
+
body,
|
|
365
|
+
}),
|
|
366
|
+
},
|
|
367
|
+
|
|
368
|
+
revisions: {
|
|
369
|
+
list: (pid: string, opts?: RequestOptions) =>
|
|
370
|
+
this.data<ICSmithRevision>(
|
|
371
|
+
"GET",
|
|
372
|
+
`/smiths/${enc(pid)}/revisions`,
|
|
373
|
+
opts,
|
|
374
|
+
),
|
|
375
|
+
restore: (
|
|
376
|
+
pid: string,
|
|
377
|
+
version: number,
|
|
378
|
+
body: z.input<typeof RestoreIn> = {},
|
|
379
|
+
opts?: RequestOptions,
|
|
380
|
+
) =>
|
|
381
|
+
this.json<ICSmithRevision>(
|
|
382
|
+
"POST",
|
|
383
|
+
`/smiths/${enc(pid)}/revisions/${version}/restore`,
|
|
384
|
+
{
|
|
385
|
+
...opts,
|
|
386
|
+
body,
|
|
387
|
+
},
|
|
388
|
+
),
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
connections: {
|
|
392
|
+
list: (pid: string, opts?: RequestOptions) =>
|
|
393
|
+
this.data<ICConnection>("GET", `/smiths/${enc(pid)}/connections`, opts),
|
|
394
|
+
get: (pid: string, cid: string, opts?: RequestOptions) =>
|
|
395
|
+
this.json<ICConnection>(
|
|
396
|
+
"GET",
|
|
397
|
+
`/smiths/${enc(pid)}/connections/${enc(cid)}`,
|
|
398
|
+
opts,
|
|
399
|
+
),
|
|
400
|
+
create: (
|
|
401
|
+
pid: string,
|
|
402
|
+
body: z.input<typeof ConnectionIn>,
|
|
403
|
+
opts?: RequestOptions,
|
|
404
|
+
) =>
|
|
405
|
+
this.json<ICConnection>("POST", `/smiths/${enc(pid)}/connections`, {
|
|
406
|
+
...opts,
|
|
407
|
+
body,
|
|
408
|
+
}),
|
|
409
|
+
update: (
|
|
410
|
+
pid: string,
|
|
411
|
+
cid: string,
|
|
412
|
+
body: z.input<typeof ConnectionPatch>,
|
|
413
|
+
opts?: RequestOptions,
|
|
414
|
+
) =>
|
|
415
|
+
this.json<ICConnection>(
|
|
416
|
+
"PATCH",
|
|
417
|
+
`/smiths/${enc(pid)}/connections/${enc(cid)}`,
|
|
418
|
+
{ ...opts, body },
|
|
419
|
+
),
|
|
420
|
+
delete: (pid: string, cid: string, opts?: RequestOptions) =>
|
|
421
|
+
this.empty(
|
|
422
|
+
"DELETE",
|
|
423
|
+
`/smiths/${enc(pid)}/connections/${enc(cid)}`,
|
|
424
|
+
opts,
|
|
425
|
+
),
|
|
426
|
+
refresh: (pid: string, cid: string, opts?: RequestOptions) =>
|
|
427
|
+
this.json<ICConnection>(
|
|
428
|
+
"POST",
|
|
429
|
+
`/smiths/${enc(pid)}/connections/${enc(cid)}/refresh`,
|
|
430
|
+
opts,
|
|
431
|
+
),
|
|
432
|
+
/** Mint a hosted-consent authorize URL the end user is sent to. */
|
|
433
|
+
authorize: (
|
|
434
|
+
pid: string,
|
|
435
|
+
body: z.input<typeof AuthorizeIn>,
|
|
436
|
+
opts?: RequestOptions,
|
|
437
|
+
) =>
|
|
438
|
+
this.json<z.infer<typeof AuthorizeOut>>(
|
|
439
|
+
"POST",
|
|
440
|
+
`/smiths/${enc(pid)}/connections/authorize`,
|
|
441
|
+
{
|
|
442
|
+
...opts,
|
|
443
|
+
body,
|
|
444
|
+
},
|
|
445
|
+
),
|
|
446
|
+
},
|
|
447
|
+
|
|
448
|
+
schedules: {
|
|
449
|
+
list: (pid: string, opts?: RequestOptions) =>
|
|
450
|
+
this.data<ICSchedule>("GET", `/smiths/${enc(pid)}/schedules`, opts),
|
|
451
|
+
create: (
|
|
452
|
+
pid: string,
|
|
453
|
+
body: z.input<typeof ScheduleIn>,
|
|
454
|
+
opts?: RequestOptions,
|
|
455
|
+
) =>
|
|
456
|
+
this.json<ICSchedule>("POST", `/smiths/${enc(pid)}/schedules`, {
|
|
457
|
+
...opts,
|
|
458
|
+
body,
|
|
459
|
+
}),
|
|
460
|
+
update: (
|
|
461
|
+
pid: string,
|
|
462
|
+
sid: string,
|
|
463
|
+
body: z.input<typeof SchedulePatch>,
|
|
464
|
+
opts?: RequestOptions,
|
|
465
|
+
) =>
|
|
466
|
+
this.json<ICSchedule>(
|
|
467
|
+
"PATCH",
|
|
468
|
+
`/smiths/${enc(pid)}/schedules/${enc(sid)}`,
|
|
469
|
+
{ ...opts, body },
|
|
470
|
+
),
|
|
471
|
+
delete: (pid: string, sid: string, opts?: RequestOptions) =>
|
|
472
|
+
this.empty("DELETE", `/smiths/${enc(pid)}/schedules/${enc(sid)}`, opts),
|
|
473
|
+
runNow: (pid: string, sid: string, opts?: RequestOptions) =>
|
|
474
|
+
this.json<z.infer<typeof ScheduleRunNowOut>>(
|
|
475
|
+
"POST",
|
|
476
|
+
`/smiths/${enc(pid)}/schedules/${enc(sid)}/run_now`,
|
|
477
|
+
opts,
|
|
478
|
+
),
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
runs: {
|
|
482
|
+
list: (
|
|
483
|
+
pid: string,
|
|
484
|
+
query?: PageOpts & { status?: string },
|
|
485
|
+
opts?: RequestOptions,
|
|
486
|
+
) => this.page<ICRun>(`/smiths/${enc(pid)}/runs`, query, opts),
|
|
487
|
+
/** Non-streaming run: returns the completed (or paused) run record. */
|
|
488
|
+
create: (
|
|
489
|
+
pid: string,
|
|
490
|
+
body: Omit<z.input<typeof RunIn>, "stream">,
|
|
491
|
+
opts?: RequestOptions,
|
|
492
|
+
) =>
|
|
493
|
+
this.json<ICRun>("POST", `/smiths/${enc(pid)}/runs`, {
|
|
494
|
+
...opts,
|
|
495
|
+
body: { ...body, stream: false },
|
|
496
|
+
}),
|
|
497
|
+
/** Streaming run: returns the raw SSE `Response`, body unconsumed. */
|
|
498
|
+
stream: (
|
|
499
|
+
pid: string,
|
|
500
|
+
body: Omit<z.input<typeof RunIn>, "stream">,
|
|
501
|
+
opts?: RequestOptions,
|
|
502
|
+
) =>
|
|
503
|
+
this.request("POST", `/smiths/${enc(pid)}/runs`, {
|
|
504
|
+
...opts,
|
|
505
|
+
body: { ...body, stream: true },
|
|
506
|
+
}),
|
|
507
|
+
get: (pid: string, rid: string, opts?: RequestOptions) =>
|
|
508
|
+
this.json<ICRun>("GET", `/smiths/${enc(pid)}/runs/${enc(rid)}`, opts),
|
|
509
|
+
/** Resume a paused run (approval decision, tool result, cancel). */
|
|
510
|
+
submit: (
|
|
511
|
+
pid: string,
|
|
512
|
+
rid: string,
|
|
513
|
+
body: z.input<typeof Submit>,
|
|
514
|
+
opts?: RequestOptions,
|
|
515
|
+
) =>
|
|
516
|
+
this.json<ICRun>(
|
|
517
|
+
"POST",
|
|
518
|
+
`/smiths/${enc(pid)}/runs/${enc(rid)}/submit`,
|
|
519
|
+
{ ...opts, body },
|
|
520
|
+
),
|
|
521
|
+
/** Re-run a recorded run's input as a fresh run. */
|
|
522
|
+
replay: (pid: string, rid: string, opts?: RequestOptions) =>
|
|
523
|
+
this.json<ICRun>(
|
|
524
|
+
"POST",
|
|
525
|
+
`/smiths/${enc(pid)}/runs/${enc(rid)}/replay`,
|
|
526
|
+
{ ...opts, body: {} },
|
|
527
|
+
),
|
|
528
|
+
/** The recorded run events (the SSE replay endpoint, parsed). */
|
|
529
|
+
events: async (
|
|
530
|
+
pid: string,
|
|
531
|
+
rid: string,
|
|
532
|
+
opts?: RequestOptions,
|
|
533
|
+
): Promise<ICRunEvent[]> => {
|
|
534
|
+
const res = await this.request(
|
|
535
|
+
"GET",
|
|
536
|
+
`/smiths/${enc(pid)}/runs/${enc(rid)}/events`,
|
|
537
|
+
opts,
|
|
538
|
+
);
|
|
539
|
+
const text = await res.text();
|
|
540
|
+
const out: ICRunEvent[] = [];
|
|
541
|
+
for (const block of text.split(/\r?\n\r?\n/)) {
|
|
542
|
+
let seq = 0;
|
|
543
|
+
let type = "";
|
|
544
|
+
let data = "";
|
|
545
|
+
for (const line of block.split(/\r?\n/)) {
|
|
546
|
+
if (line.startsWith("id:")) seq = Number(line.slice(3).trim());
|
|
547
|
+
else if (line.startsWith("event:")) type = line.slice(6).trim();
|
|
548
|
+
else if (line.startsWith("data:")) data += line.slice(5).trim();
|
|
549
|
+
}
|
|
550
|
+
if (!data) continue;
|
|
551
|
+
try {
|
|
552
|
+
out.push({
|
|
553
|
+
seq,
|
|
554
|
+
type,
|
|
555
|
+
data: JSON.parse(data),
|
|
556
|
+
created_at: null,
|
|
557
|
+
});
|
|
558
|
+
} catch {}
|
|
559
|
+
}
|
|
560
|
+
return out;
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
// ── Runs (tenant-wide feed) ─────────────────────────────────────────────
|
|
566
|
+
|
|
567
|
+
readonly runs = {
|
|
568
|
+
list: (
|
|
569
|
+
query?: PageOpts & {
|
|
570
|
+
smith_id?: string;
|
|
571
|
+
agent_id?: string;
|
|
572
|
+
status?: string;
|
|
573
|
+
},
|
|
574
|
+
opts?: RequestOptions,
|
|
575
|
+
) => this.page<ICRun>("/runs", query, opts),
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
// ── Agents ──────────────────────────────────────────────────────────────
|
|
579
|
+
|
|
580
|
+
readonly agents = {
|
|
581
|
+
list: (query?: PageOpts, opts?: RequestOptions) =>
|
|
582
|
+
this.page<ICAgent>("/agents", query, opts),
|
|
583
|
+
create: (body: z.input<typeof AgentIn>, opts?: RequestOptions) =>
|
|
584
|
+
this.json<ICAgent>("POST", "/agents", { ...opts, body }),
|
|
585
|
+
get: (aid: string, opts?: RequestOptions) =>
|
|
586
|
+
this.json<ICAgent>("GET", `/agents/${enc(aid)}`, opts),
|
|
587
|
+
update: (
|
|
588
|
+
aid: string,
|
|
589
|
+
body: z.input<typeof AgentPatch>,
|
|
590
|
+
opts?: RequestOptions,
|
|
591
|
+
) => this.json<ICAgent>("PATCH", `/agents/${enc(aid)}`, { ...opts, body }),
|
|
592
|
+
delete: (aid: string, opts?: RequestOptions) =>
|
|
593
|
+
this.empty("DELETE", `/agents/${enc(aid)}`, opts),
|
|
594
|
+
|
|
595
|
+
versions: {
|
|
596
|
+
list: (aid: string, opts?: RequestOptions) =>
|
|
597
|
+
this.data<ICAgentVersion>("GET", `/agents/${enc(aid)}/versions`, opts),
|
|
598
|
+
/** Snapshot the draft as the next immutable version. */
|
|
599
|
+
publish: (
|
|
600
|
+
aid: string,
|
|
601
|
+
body: z.input<typeof PublishIn> = {},
|
|
602
|
+
opts?: RequestOptions,
|
|
603
|
+
) =>
|
|
604
|
+
this.json<ICAgentVersion>("POST", `/agents/${enc(aid)}/versions`, {
|
|
605
|
+
...opts,
|
|
606
|
+
body,
|
|
607
|
+
}),
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
/** Point smiths at a version (`percent < 100` stages a sticky rollout). */
|
|
611
|
+
rollout: (
|
|
612
|
+
aid: string,
|
|
613
|
+
body: z.input<typeof RolloutIn>,
|
|
614
|
+
opts?: RequestOptions,
|
|
615
|
+
) =>
|
|
616
|
+
this.json<ICAgent>("POST", `/agents/${enc(aid)}/rollout`, {
|
|
617
|
+
...opts,
|
|
618
|
+
body,
|
|
619
|
+
}),
|
|
620
|
+
/** Seed a new agent from an existing smith's effective config. */
|
|
621
|
+
import: (body: z.input<typeof ImportIn>, opts?: RequestOptions) =>
|
|
622
|
+
this.json<ICAgent>("POST", "/agents/import", { ...opts, body }),
|
|
623
|
+
/** Adopt existing smiths onto this agent. */
|
|
624
|
+
attach: (aid: string, body: z.input<typeof AttachIn>, opts?: RequestOptions) =>
|
|
625
|
+
this.json<{
|
|
626
|
+
attached: { smith_id: string; override_keys: string[] }[];
|
|
627
|
+
count: number;
|
|
628
|
+
}>("POST", `/agents/${enc(aid)}/attach`, { ...opts, body }),
|
|
629
|
+
|
|
630
|
+
/** MCP Apps UI templates (SEP-1865) attached to the agent's draft. */
|
|
631
|
+
ui: {
|
|
632
|
+
list: (aid: string, opts?: RequestOptions) =>
|
|
633
|
+
this.data<ICUiResource>("GET", `/agents/${enc(aid)}/ui`, opts),
|
|
634
|
+
get: (aid: string, name: string, opts?: RequestOptions) =>
|
|
635
|
+
this.json<ICUiResource>("GET", `/agents/${enc(aid)}/ui/${enc(name)}`, opts),
|
|
636
|
+
/** Upload/replace a template — `html` is the bundle, `meta` its
|
|
637
|
+
* `{ name, csp?, permissions?, tool? }` sidecar. Replaces by name. */
|
|
638
|
+
put: (
|
|
639
|
+
aid: string,
|
|
640
|
+
html: string | Blob,
|
|
641
|
+
meta: z.input<typeof UiResourceIn>,
|
|
642
|
+
opts?: RequestOptions,
|
|
643
|
+
) => {
|
|
644
|
+
const form = new FormData();
|
|
645
|
+
form.append(
|
|
646
|
+
"file",
|
|
647
|
+
html instanceof Blob ? html : new Blob([html], { type: "text/html" }),
|
|
648
|
+
`${meta.name}.html`,
|
|
649
|
+
);
|
|
650
|
+
form.append("metadata", JSON.stringify(meta));
|
|
651
|
+
return this.json<ICUiResource>("POST", `/agents/${enc(aid)}/ui`, {
|
|
652
|
+
...opts,
|
|
653
|
+
rawBody: form,
|
|
654
|
+
});
|
|
655
|
+
},
|
|
656
|
+
delete: (aid: string, name: string, opts?: RequestOptions) =>
|
|
657
|
+
this.json<{ name: string; deleted: boolean }>(
|
|
658
|
+
"DELETE",
|
|
659
|
+
`/agents/${enc(aid)}/ui/${enc(name)}`,
|
|
660
|
+
opts,
|
|
661
|
+
),
|
|
662
|
+
},
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// ── Conversations (smith-scoped: pass `{ smith }` with a tenant token) ──
|
|
666
|
+
|
|
667
|
+
readonly conversations = {
|
|
668
|
+
list: (query?: PageOpts, opts?: RequestOptions) =>
|
|
669
|
+
this.page<ICConversation>("/conversations", query, opts),
|
|
670
|
+
create: (
|
|
671
|
+
body: z.input<typeof ConversationCreate> = {},
|
|
672
|
+
opts?: RequestOptions,
|
|
673
|
+
) => this.json<ICConversation>("POST", "/conversations", { ...opts, body }),
|
|
674
|
+
get: (cnvId: string, opts?: RequestOptions) =>
|
|
675
|
+
this.json<ICConversation>("GET", `/conversations/${enc(cnvId)}`, opts),
|
|
676
|
+
/** OpenAI-style modify — a POST, not a PATCH. */
|
|
677
|
+
update: (
|
|
678
|
+
cnvId: string,
|
|
679
|
+
body: z.input<typeof ConversationUpdate>,
|
|
680
|
+
opts?: RequestOptions,
|
|
681
|
+
) =>
|
|
682
|
+
this.json<ICConversation>("POST", `/conversations/${enc(cnvId)}`, {
|
|
683
|
+
...opts,
|
|
684
|
+
body,
|
|
685
|
+
}),
|
|
686
|
+
delete: (cnvId: string, opts?: RequestOptions) =>
|
|
687
|
+
this.empty("DELETE", `/conversations/${enc(cnvId)}`, opts),
|
|
688
|
+
/** The faithful transcript (message / function_call / mcp_call items). */
|
|
689
|
+
items: (
|
|
690
|
+
cnvId: string,
|
|
691
|
+
query?: { order?: "asc" | "desc"; limit?: number },
|
|
692
|
+
opts?: RequestOptions,
|
|
693
|
+
) =>
|
|
694
|
+
this.data<ICConversationItem>("GET", `/conversations/${enc(cnvId)}/items`, {
|
|
695
|
+
...opts,
|
|
696
|
+
query,
|
|
697
|
+
}),
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
// ── Approvals / events ──────────────────────────────────────────────────
|
|
701
|
+
|
|
702
|
+
readonly approvals = {
|
|
703
|
+
list: (query?: PageOpts & { status?: string }, opts?: RequestOptions) =>
|
|
704
|
+
this.page<ICApproval>("/approvals", query, opts),
|
|
705
|
+
get: (aprId: string, opts?: RequestOptions) =>
|
|
706
|
+
this.json<ICApproval>("GET", `/approvals/${enc(aprId)}`, opts),
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
readonly events = {
|
|
710
|
+
list: (
|
|
711
|
+
query?: PageOpts & { type?: string; smith_id?: string },
|
|
712
|
+
opts?: RequestOptions,
|
|
713
|
+
) => this.page<ICEvent>("/events", query, opts),
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
// ── Customers / budgets ─────────────────────────────────────────────────
|
|
717
|
+
|
|
718
|
+
readonly customers = {
|
|
719
|
+
list: (query?: PageOpts, opts?: RequestOptions) =>
|
|
720
|
+
this.page<ICCustomer>("/customers", query, opts),
|
|
721
|
+
create: (body: z.input<typeof CustomerCreate>, opts?: RequestOptions) =>
|
|
722
|
+
this.json<ICCustomer>("POST", "/customers", { ...opts, body }),
|
|
723
|
+
get: (cid: string, opts?: RequestOptions) =>
|
|
724
|
+
this.json<ICCustomer>("GET", `/customers/${enc(cid)}`, opts),
|
|
725
|
+
update: (
|
|
726
|
+
cid: string,
|
|
727
|
+
body: z.input<typeof CustomerPatch>,
|
|
728
|
+
opts?: RequestOptions,
|
|
729
|
+
) =>
|
|
730
|
+
this.json<ICCustomer>("PATCH", `/customers/${enc(cid)}`, { ...opts, body }),
|
|
731
|
+
delete: (cid: string, opts?: RequestOptions) =>
|
|
732
|
+
this.empty("DELETE", `/customers/${enc(cid)}`, opts),
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
readonly budgets = {
|
|
736
|
+
list: (opts?: RequestOptions) => this.data<ICBudget>("GET", "/budgets", opts),
|
|
737
|
+
create: (body: z.input<typeof BudgetIn>, opts?: RequestOptions) =>
|
|
738
|
+
this.json<ICBudget>("POST", "/budgets", { ...opts, body }),
|
|
739
|
+
get: (bid: string, opts?: RequestOptions) =>
|
|
740
|
+
this.json<ICBudget>("GET", `/budgets/${enc(bid)}`, opts),
|
|
741
|
+
update: (
|
|
742
|
+
bid: string,
|
|
743
|
+
body: z.input<typeof BudgetPatch>,
|
|
744
|
+
opts?: RequestOptions,
|
|
745
|
+
) => this.json<ICBudget>("PATCH", `/budgets/${enc(bid)}`, { ...opts, body }),
|
|
746
|
+
delete: (bid: string, opts?: RequestOptions) =>
|
|
747
|
+
this.empty("DELETE", `/budgets/${enc(bid)}`, opts),
|
|
748
|
+
status: (bid: string, opts?: RequestOptions) =>
|
|
749
|
+
this.json<ICBudgetStatus>("GET", `/budgets/${enc(bid)}/status`, opts),
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
// ── Deployments (smith/agent bound to a messaging surface) ──────────────
|
|
753
|
+
|
|
754
|
+
readonly deployments = {
|
|
755
|
+
list: (
|
|
756
|
+
query?: PageOpts & { target_type?: "smith" | "agent"; target_id?: string },
|
|
757
|
+
opts?: RequestOptions,
|
|
758
|
+
) => this.page<ICDeployment>("/deployments", query, opts),
|
|
759
|
+
create: (body: z.input<typeof DeploymentIn>, opts?: RequestOptions) =>
|
|
760
|
+
this.json<ICDeploymentCreated>("POST", "/deployments", { ...opts, body }),
|
|
761
|
+
get: (depId: string, opts?: RequestOptions) =>
|
|
762
|
+
this.json<ICDeployment>("GET", `/deployments/${enc(depId)}`, opts),
|
|
763
|
+
update: (
|
|
764
|
+
depId: string,
|
|
765
|
+
body: z.input<typeof DeploymentPatch>,
|
|
766
|
+
opts?: RequestOptions,
|
|
767
|
+
) =>
|
|
768
|
+
this.json<ICDeployment>("PATCH", `/deployments/${enc(depId)}`, {
|
|
769
|
+
...opts,
|
|
770
|
+
body,
|
|
771
|
+
}),
|
|
772
|
+
delete: (depId: string, opts?: RequestOptions) =>
|
|
773
|
+
this.empty("DELETE", `/deployments/${enc(depId)}`, opts),
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
// ── Catalog (Ingram-curated MCP integration presets) ────────────────────
|
|
777
|
+
|
|
778
|
+
readonly catalog = {
|
|
779
|
+
list: (opts?: RequestOptions) =>
|
|
780
|
+
this.data<ICCatalogEntry>("GET", "/catalog", opts),
|
|
781
|
+
get: (slug: string, opts?: RequestOptions) =>
|
|
782
|
+
this.json<ICCatalogEntry>("GET", `/catalog/${enc(slug)}`, opts),
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
// ── Observability ───────────────────────────────────────────────────────
|
|
786
|
+
|
|
787
|
+
readonly traces = {
|
|
788
|
+
list: (
|
|
789
|
+
query?: PageOpts & {
|
|
790
|
+
smith_id?: string;
|
|
791
|
+
app_id?: string;
|
|
792
|
+
status?: string;
|
|
793
|
+
since?: string;
|
|
794
|
+
},
|
|
795
|
+
opts?: RequestOptions,
|
|
796
|
+
) => this.page<ICTrace>("/traces", query, opts),
|
|
797
|
+
get: (traceId: string, opts?: RequestOptions) =>
|
|
798
|
+
this.json<ICTraceDetail>("GET", `/traces/${enc(traceId)}`, opts),
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
readonly usage = {
|
|
802
|
+
/** Token/cost/run totals grouped by app, smith, model, or customer. */
|
|
803
|
+
breakdown: (
|
|
804
|
+
query?: {
|
|
805
|
+
group_by?: "app" | "smith" | "model" | "customer";
|
|
806
|
+
from?: string;
|
|
807
|
+
to?: string;
|
|
808
|
+
period?: string;
|
|
809
|
+
smith_id?: string;
|
|
810
|
+
customer_id?: string;
|
|
811
|
+
},
|
|
812
|
+
opts?: RequestOptions,
|
|
813
|
+
) => this.json<ICUsageBreakdown>("GET", "/usage", { ...opts, query }),
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
// ── Files (the OpenAI Files API) ─────────────────────────────────────────
|
|
817
|
+
|
|
818
|
+
readonly files = {
|
|
819
|
+
/** Multipart upload. `file` is a `File`/`Blob`; `purpose` defaults to
|
|
820
|
+
* `assistants` (the vector-store source purpose). */
|
|
821
|
+
upload: (
|
|
822
|
+
file: Blob,
|
|
823
|
+
opts?: { filename?: string; purpose?: string } & RequestOptions,
|
|
824
|
+
) => {
|
|
825
|
+
const form = new FormData();
|
|
826
|
+
form.set(
|
|
827
|
+
"file",
|
|
828
|
+
file,
|
|
829
|
+
opts?.filename ?? (file instanceof File ? file.name : "file"),
|
|
830
|
+
);
|
|
831
|
+
form.set("purpose", opts?.purpose ?? "assistants");
|
|
832
|
+
return this.json<ICFile>("POST", "/files", { ...opts, rawBody: form });
|
|
833
|
+
},
|
|
834
|
+
/** Uploads only (OpenAI `list` envelope); inline files stay unlisted. */
|
|
835
|
+
list: (
|
|
836
|
+
query?: { purpose?: string; after?: string; limit?: number; order?: "asc" | "desc" },
|
|
837
|
+
opts?: RequestOptions,
|
|
838
|
+
) => this.json<ICFileList>("GET", "/files", { ...opts, query }),
|
|
839
|
+
get: (id: string, opts?: RequestOptions) =>
|
|
840
|
+
this.json<ICFile>("GET", `/files/${enc(id)}`, opts),
|
|
841
|
+
/** The raw bytes `Response` (follows the presigned-URL redirect). */
|
|
842
|
+
content: (id: string, opts?: RequestOptions) =>
|
|
843
|
+
this.request("GET", `/files/${enc(id)}/content`, opts),
|
|
844
|
+
delete: (id: string, opts?: RequestOptions) =>
|
|
845
|
+
this.json<{ id: string; deleted: true }>("DELETE", `/files/${enc(id)}`, opts),
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
// ── Vector stores (the OpenAI Vector Stores API) ─────────────────────────
|
|
849
|
+
|
|
850
|
+
readonly vectorStores = {
|
|
851
|
+
create: (body: z.input<typeof VectorStoreIn>, opts?: RequestOptions) =>
|
|
852
|
+
this.json<ICVectorStore>("POST", "/vector_stores", { ...opts, body }),
|
|
853
|
+
list: (
|
|
854
|
+
query?: { limit?: number; order?: "asc" | "desc"; after?: string; before?: string },
|
|
855
|
+
opts?: RequestOptions,
|
|
856
|
+
) =>
|
|
857
|
+
this.json<{ data: ICVectorStore[]; first_id: string | null; last_id: string | null; has_more: boolean }>(
|
|
858
|
+
"GET",
|
|
859
|
+
"/vector_stores",
|
|
860
|
+
{ ...opts, query },
|
|
861
|
+
),
|
|
862
|
+
get: (vsId: string, opts?: RequestOptions) =>
|
|
863
|
+
this.json<ICVectorStore>("GET", `/vector_stores/${enc(vsId)}`, opts),
|
|
864
|
+
/** Modify (OpenAI uses `POST`, not `PATCH`). */
|
|
865
|
+
update: (
|
|
866
|
+
vsId: string,
|
|
867
|
+
body: z.input<typeof VectorStorePatch>,
|
|
868
|
+
opts?: RequestOptions,
|
|
869
|
+
) => this.json<ICVectorStore>("POST", `/vector_stores/${enc(vsId)}`, { ...opts, body }),
|
|
870
|
+
delete: (vsId: string, opts?: RequestOptions) =>
|
|
871
|
+
this.json<{ id: string; deleted: true }>(
|
|
872
|
+
"DELETE",
|
|
873
|
+
`/vector_stores/${enc(vsId)}`,
|
|
874
|
+
opts,
|
|
875
|
+
),
|
|
876
|
+
search: (
|
|
877
|
+
vsId: string,
|
|
878
|
+
body: z.input<typeof VectorStoreSearchIn>,
|
|
879
|
+
opts?: RequestOptions,
|
|
880
|
+
) =>
|
|
881
|
+
this.json<ICVectorStoreSearchPage>("POST", `/vector_stores/${enc(vsId)}/search`, {
|
|
882
|
+
...opts,
|
|
883
|
+
body,
|
|
884
|
+
}),
|
|
885
|
+
|
|
886
|
+
files: {
|
|
887
|
+
create: (
|
|
888
|
+
vsId: string,
|
|
889
|
+
body: z.input<typeof VectorStoreFileIn>,
|
|
890
|
+
opts?: RequestOptions,
|
|
891
|
+
) =>
|
|
892
|
+
this.json<ICVectorStoreFile>("POST", `/vector_stores/${enc(vsId)}/files`, {
|
|
893
|
+
...opts,
|
|
894
|
+
body,
|
|
895
|
+
}),
|
|
896
|
+
list: (
|
|
897
|
+
vsId: string,
|
|
898
|
+
query?: {
|
|
899
|
+
limit?: number;
|
|
900
|
+
order?: "asc" | "desc";
|
|
901
|
+
after?: string;
|
|
902
|
+
before?: string;
|
|
903
|
+
filter?: string;
|
|
904
|
+
},
|
|
905
|
+
opts?: RequestOptions,
|
|
906
|
+
) =>
|
|
907
|
+
this.json<{ data: ICVectorStoreFile[]; first_id: string | null; last_id: string | null; has_more: boolean }>(
|
|
908
|
+
"GET",
|
|
909
|
+
`/vector_stores/${enc(vsId)}/files`,
|
|
910
|
+
{ ...opts, query },
|
|
911
|
+
),
|
|
912
|
+
get: (vsId: string, fileId: string, opts?: RequestOptions) =>
|
|
913
|
+
this.json<ICVectorStoreFile>(
|
|
914
|
+
"GET",
|
|
915
|
+
`/vector_stores/${enc(vsId)}/files/${enc(fileId)}`,
|
|
916
|
+
opts,
|
|
917
|
+
),
|
|
918
|
+
update: (
|
|
919
|
+
vsId: string,
|
|
920
|
+
fileId: string,
|
|
921
|
+
body: z.input<typeof VectorStoreFileUpdate>,
|
|
922
|
+
opts?: RequestOptions,
|
|
923
|
+
) =>
|
|
924
|
+
this.json<ICVectorStoreFile>(
|
|
925
|
+
"POST",
|
|
926
|
+
`/vector_stores/${enc(vsId)}/files/${enc(fileId)}`,
|
|
927
|
+
{ ...opts, body },
|
|
928
|
+
),
|
|
929
|
+
delete: (vsId: string, fileId: string, opts?: RequestOptions) =>
|
|
930
|
+
this.json<{ id: string; deleted: true }>(
|
|
931
|
+
"DELETE",
|
|
932
|
+
`/vector_stores/${enc(vsId)}/files/${enc(fileId)}`,
|
|
933
|
+
opts,
|
|
934
|
+
),
|
|
935
|
+
},
|
|
936
|
+
|
|
937
|
+
fileBatches: {
|
|
938
|
+
create: (
|
|
939
|
+
vsId: string,
|
|
940
|
+
body: z.input<typeof VectorStoreFileBatchIn>,
|
|
941
|
+
opts?: RequestOptions,
|
|
942
|
+
) =>
|
|
943
|
+
this.json<ICVectorStoreFileBatch>(
|
|
944
|
+
"POST",
|
|
945
|
+
`/vector_stores/${enc(vsId)}/file_batches`,
|
|
946
|
+
{ ...opts, body },
|
|
947
|
+
),
|
|
948
|
+
get: (vsId: string, batchId: string, opts?: RequestOptions) =>
|
|
949
|
+
this.json<ICVectorStoreFileBatch>(
|
|
950
|
+
"GET",
|
|
951
|
+
`/vector_stores/${enc(vsId)}/file_batches/${enc(batchId)}`,
|
|
952
|
+
opts,
|
|
953
|
+
),
|
|
954
|
+
cancel: (vsId: string, batchId: string, opts?: RequestOptions) =>
|
|
955
|
+
this.json<ICVectorStoreFileBatch>(
|
|
956
|
+
"POST",
|
|
957
|
+
`/vector_stores/${enc(vsId)}/file_batches/${enc(batchId)}/cancel`,
|
|
958
|
+
opts,
|
|
959
|
+
),
|
|
960
|
+
files: (
|
|
961
|
+
vsId: string,
|
|
962
|
+
batchId: string,
|
|
963
|
+
query?: { limit?: number; order?: "asc" | "desc"; after?: string; filter?: string },
|
|
964
|
+
opts?: RequestOptions,
|
|
965
|
+
) =>
|
|
966
|
+
this.json<{ data: ICVectorStoreFile[]; has_more: boolean }>(
|
|
967
|
+
"GET",
|
|
968
|
+
`/vector_stores/${enc(vsId)}/file_batches/${enc(batchId)}/files`,
|
|
969
|
+
{ ...opts, query },
|
|
970
|
+
),
|
|
971
|
+
},
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
// ── Tenant config ───────────────────────────────────────────────────────
|
|
975
|
+
|
|
976
|
+
readonly tenant = {
|
|
977
|
+
usage: (opts?: RequestOptions) =>
|
|
978
|
+
this.json<ICUsage>("GET", "/tenant/usage", opts),
|
|
979
|
+
models: (opts?: RequestOptions) =>
|
|
980
|
+
this.json<ICModelCatalog>("GET", "/tenant/models", opts),
|
|
981
|
+
hostedTools: (opts?: RequestOptions) =>
|
|
982
|
+
this.data<z.infer<typeof HostedToolOut>>(
|
|
983
|
+
"GET",
|
|
984
|
+
"/tenant/hosted_tools",
|
|
985
|
+
opts,
|
|
986
|
+
),
|
|
987
|
+
|
|
988
|
+
tokens: {
|
|
989
|
+
list: (query?: PageOpts, opts?: RequestOptions) =>
|
|
990
|
+
this.page<ICToken>("/tenant/tokens", query, opts),
|
|
991
|
+
/** Mint a tenant-admin or smith token (secret shown once). */
|
|
992
|
+
create: (body: z.input<typeof TokenIn>, opts?: RequestOptions) =>
|
|
993
|
+
this.json<ICMintedToken>("POST", "/tenant/tokens", { ...opts, body }),
|
|
994
|
+
revoke: (tid: string, opts?: RequestOptions) =>
|
|
995
|
+
this.empty("DELETE", `/tenant/tokens/${enc(tid)}`, opts),
|
|
996
|
+
},
|
|
997
|
+
|
|
998
|
+
webhooks: {
|
|
999
|
+
list: (query?: PageOpts, opts?: RequestOptions) =>
|
|
1000
|
+
this.page<ICWebhook>("/tenant/webhooks", query, opts),
|
|
1001
|
+
/** Returns the signing `secret` exactly once. */
|
|
1002
|
+
create: (body: z.input<typeof WebhookIn>, opts?: RequestOptions) =>
|
|
1003
|
+
this.json<z.infer<typeof WebhookCreateOut>>(
|
|
1004
|
+
"POST",
|
|
1005
|
+
"/tenant/webhooks",
|
|
1006
|
+
{ ...opts, body },
|
|
1007
|
+
),
|
|
1008
|
+
update: (
|
|
1009
|
+
wid: string,
|
|
1010
|
+
body: z.input<typeof WebhookPatch>,
|
|
1011
|
+
opts?: RequestOptions,
|
|
1012
|
+
) =>
|
|
1013
|
+
this.json<{ id: string }>("PATCH", `/tenant/webhooks/${enc(wid)}`, {
|
|
1014
|
+
...opts,
|
|
1015
|
+
body,
|
|
1016
|
+
}),
|
|
1017
|
+
delete: (wid: string, opts?: RequestOptions) =>
|
|
1018
|
+
this.empty("DELETE", `/tenant/webhooks/${enc(wid)}`, opts),
|
|
1019
|
+
test: (wid: string, opts?: RequestOptions) =>
|
|
1020
|
+
this.json<{ delivered: boolean }>(
|
|
1021
|
+
"POST",
|
|
1022
|
+
`/tenant/webhooks/${enc(wid)}/test`,
|
|
1023
|
+
opts,
|
|
1024
|
+
),
|
|
1025
|
+
},
|
|
1026
|
+
|
|
1027
|
+
providers: {
|
|
1028
|
+
list: (opts?: RequestOptions) =>
|
|
1029
|
+
this.data<ICProvider>("GET", "/tenant/providers", opts),
|
|
1030
|
+
get: (provider: string, opts?: RequestOptions) =>
|
|
1031
|
+
this.json<ICProvider>(
|
|
1032
|
+
"GET",
|
|
1033
|
+
`/tenant/providers/${enc(provider)}`,
|
|
1034
|
+
opts,
|
|
1035
|
+
),
|
|
1036
|
+
put: (
|
|
1037
|
+
provider: string,
|
|
1038
|
+
body: z.input<typeof ProviderIn>,
|
|
1039
|
+
opts?: RequestOptions,
|
|
1040
|
+
) =>
|
|
1041
|
+
this.json<z.infer<typeof ProviderConfiguredOut>>(
|
|
1042
|
+
"PUT",
|
|
1043
|
+
`/tenant/providers/${enc(provider)}`,
|
|
1044
|
+
{
|
|
1045
|
+
...opts,
|
|
1046
|
+
body,
|
|
1047
|
+
},
|
|
1048
|
+
),
|
|
1049
|
+
delete: (provider: string, opts?: RequestOptions) =>
|
|
1050
|
+
this.empty("DELETE", `/tenant/providers/${enc(provider)}`, opts),
|
|
1051
|
+
},
|
|
1052
|
+
|
|
1053
|
+
modelKeys: {
|
|
1054
|
+
list: (opts?: RequestOptions) =>
|
|
1055
|
+
this.data<ICModelKey>("GET", "/tenant/model_keys", opts),
|
|
1056
|
+
/** Store a BYOK model-provider key (never read back). */
|
|
1057
|
+
put: (
|
|
1058
|
+
provider: string,
|
|
1059
|
+
body: z.input<typeof ModelKeyIn>,
|
|
1060
|
+
opts?: RequestOptions,
|
|
1061
|
+
) =>
|
|
1062
|
+
this.json<z.infer<typeof ModelKeyConfiguredOut>>(
|
|
1063
|
+
"PUT",
|
|
1064
|
+
`/tenant/model_keys/${enc(provider)}`,
|
|
1065
|
+
{
|
|
1066
|
+
...opts,
|
|
1067
|
+
body,
|
|
1068
|
+
},
|
|
1069
|
+
),
|
|
1070
|
+
delete: (provider: string, opts?: RequestOptions) =>
|
|
1071
|
+
this.empty("DELETE", `/tenant/model_keys/${enc(provider)}`, opts),
|
|
1072
|
+
},
|
|
1073
|
+
|
|
1074
|
+
mcp: {
|
|
1075
|
+
list: (opts?: RequestOptions) =>
|
|
1076
|
+
this.data<ICMcpServer>("GET", "/tenant/mcp", opts),
|
|
1077
|
+
get: (name: string, opts?: RequestOptions) =>
|
|
1078
|
+
this.json<ICMcpServer>("GET", `/tenant/mcp/${enc(name)}`, opts),
|
|
1079
|
+
/** Register or replace a server (full replace; probes `tools/list`). */
|
|
1080
|
+
put: (
|
|
1081
|
+
name: string,
|
|
1082
|
+
body: z.input<typeof McpServerIn>,
|
|
1083
|
+
opts?: RequestOptions,
|
|
1084
|
+
) =>
|
|
1085
|
+
this.json<z.infer<typeof McpServerWriteOut>>(
|
|
1086
|
+
"PUT",
|
|
1087
|
+
`/tenant/mcp/${enc(name)}`,
|
|
1088
|
+
{ ...opts, body },
|
|
1089
|
+
),
|
|
1090
|
+
refresh: (name: string, opts?: RequestOptions) =>
|
|
1091
|
+
this.json<z.infer<typeof McpServerWriteOut>>(
|
|
1092
|
+
"POST",
|
|
1093
|
+
`/tenant/mcp/${enc(name)}/refresh`,
|
|
1094
|
+
opts,
|
|
1095
|
+
),
|
|
1096
|
+
delete: (name: string, opts?: RequestOptions) =>
|
|
1097
|
+
this.empty("DELETE", `/tenant/mcp/${enc(name)}`, opts),
|
|
1098
|
+
},
|
|
1099
|
+
|
|
1100
|
+
telegram: {
|
|
1101
|
+
get: (opts?: RequestOptions) =>
|
|
1102
|
+
this.json<ICTelegramBot>("GET", "/tenant/telegram", opts),
|
|
1103
|
+
put: (body: z.input<typeof TelegramBotIn>, opts?: RequestOptions) =>
|
|
1104
|
+
this.json<ICTelegramBot>("PUT", "/tenant/telegram", { ...opts, body }),
|
|
1105
|
+
delete: (opts?: RequestOptions) =>
|
|
1106
|
+
this.empty("DELETE", "/tenant/telegram", opts),
|
|
1107
|
+
},
|
|
1108
|
+
|
|
1109
|
+
slack: {
|
|
1110
|
+
get: (opts?: RequestOptions) =>
|
|
1111
|
+
this.json<ICSlackApp>("GET", "/tenant/slack", opts),
|
|
1112
|
+
put: (body: z.input<typeof SlackAppIn>, opts?: RequestOptions) =>
|
|
1113
|
+
this.json<ICSlackApp>("PUT", "/tenant/slack", { ...opts, body }),
|
|
1114
|
+
delete: (opts?: RequestOptions) =>
|
|
1115
|
+
this.empty("DELETE", "/tenant/slack", opts),
|
|
1116
|
+
},
|
|
1117
|
+
|
|
1118
|
+
discord: {
|
|
1119
|
+
get: (opts?: RequestOptions) =>
|
|
1120
|
+
this.json<ICDiscordApp>("GET", "/tenant/discord", opts),
|
|
1121
|
+
put: (body: z.input<typeof DiscordAppIn>, opts?: RequestOptions) =>
|
|
1122
|
+
this.json<ICDiscordApp>("PUT", "/tenant/discord", { ...opts, body }),
|
|
1123
|
+
delete: (opts?: RequestOptions) =>
|
|
1124
|
+
this.empty("DELETE", "/tenant/discord", opts),
|
|
1125
|
+
},
|
|
1126
|
+
|
|
1127
|
+
whatsapp: {
|
|
1128
|
+
get: (opts?: RequestOptions) =>
|
|
1129
|
+
this.json<ICWhatsAppConfig>("GET", "/tenant/whatsapp", opts),
|
|
1130
|
+
put: (body: z.input<typeof WhatsAppConfigIn>, opts?: RequestOptions) =>
|
|
1131
|
+
this.json<ICWhatsAppConfig>("PUT", "/tenant/whatsapp", {
|
|
1132
|
+
...opts,
|
|
1133
|
+
body,
|
|
1134
|
+
}),
|
|
1135
|
+
delete: (opts?: RequestOptions) =>
|
|
1136
|
+
this.empty("DELETE", "/tenant/whatsapp", opts),
|
|
1137
|
+
},
|
|
1138
|
+
|
|
1139
|
+
email: {
|
|
1140
|
+
get: (opts?: RequestOptions) =>
|
|
1141
|
+
this.json<ICEmailConfig>("GET", "/tenant/email", opts),
|
|
1142
|
+
put: (body: z.input<typeof EmailConfigIn>, opts?: RequestOptions) =>
|
|
1143
|
+
this.json<ICEmailConfig>("PUT", "/tenant/email", { ...opts, body }),
|
|
1144
|
+
delete: (opts?: RequestOptions) =>
|
|
1145
|
+
this.empty("DELETE", "/tenant/email", opts),
|
|
1146
|
+
},
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
// ── Organization (org token: projects + billing) ────────────────────────
|
|
1150
|
+
|
|
1151
|
+
readonly organization = {
|
|
1152
|
+
projects: {
|
|
1153
|
+
list: (opts?: RequestOptions) =>
|
|
1154
|
+
this.data<ICProject>("GET", "/organization/projects", opts),
|
|
1155
|
+
create: (body: z.input<typeof ProjectIn>, opts?: RequestOptions) =>
|
|
1156
|
+
this.json<ICProject>("POST", "/organization/projects", {
|
|
1157
|
+
...opts,
|
|
1158
|
+
body,
|
|
1159
|
+
}),
|
|
1160
|
+
get: (pid: string, opts?: RequestOptions) =>
|
|
1161
|
+
this.json<ICProject>("GET", `/organization/projects/${enc(pid)}`, opts),
|
|
1162
|
+
delete: (pid: string, opts?: RequestOptions) =>
|
|
1163
|
+
this.empty("DELETE", `/organization/projects/${enc(pid)}`, opts),
|
|
1164
|
+
tokens: {
|
|
1165
|
+
create: (
|
|
1166
|
+
pid: string,
|
|
1167
|
+
body: z.input<typeof ProjectTokenIn>,
|
|
1168
|
+
opts?: RequestOptions,
|
|
1169
|
+
) =>
|
|
1170
|
+
this.json<z.infer<typeof ProjectTokenOut>>(
|
|
1171
|
+
"POST",
|
|
1172
|
+
`/organization/projects/${enc(pid)}/tokens`,
|
|
1173
|
+
{
|
|
1174
|
+
...opts,
|
|
1175
|
+
body,
|
|
1176
|
+
},
|
|
1177
|
+
),
|
|
1178
|
+
delete: (pid: string, tid: string, opts?: RequestOptions) =>
|
|
1179
|
+
this.empty(
|
|
1180
|
+
"DELETE",
|
|
1181
|
+
`/organization/projects/${enc(pid)}/tokens/${enc(tid)}`,
|
|
1182
|
+
opts,
|
|
1183
|
+
),
|
|
1184
|
+
},
|
|
1185
|
+
},
|
|
1186
|
+
};
|
|
1187
|
+
}
|