@seclai/sdk 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Seclai, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Seclai JavaScript SDK
2
+
3
+ This is the official Seclai JavaScript SDK with TypeScript typings.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @seclai/sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { Seclai } from "@seclai/sdk";
15
+
16
+ const client = new Seclai({ apiKey: process.env.SECLAI_API_KEY });
17
+
18
+ const sources = await client.listSources();
19
+ console.log(sources.pagination, sources.data);
20
+ ```
21
+
22
+ ### Upload a file
23
+
24
+ ```ts
25
+ import { Seclai } from "@seclai/sdk";
26
+
27
+ const client = new Seclai({ apiKey: process.env.SECLAI_API_KEY });
28
+
29
+ const bytes = new TextEncoder().encode("hello");
30
+ const upload = await client.uploadFileToSource("source_connection_id", {
31
+ file: bytes,
32
+ fileName: "hello.txt",
33
+ mimeType: "text/plain",
34
+ title: "Hello",
35
+ });
36
+ console.log(upload);
37
+ ```
38
+
39
+ ## Development
40
+
41
+ ### Base URL
42
+
43
+ Set `SECLAI_API_URL` to point at a different API host (e.g., staging):
44
+
45
+ ```bash
46
+ export SECLAI_API_URL="https://example.invalid"
47
+ ```
48
+
49
+ ### Install dependencies
50
+
51
+ ```bash
52
+ npm install
53
+ ```
54
+
55
+ ### Type checking
56
+
57
+ ```bash
58
+ npm run typecheck
59
+ ```
60
+
61
+ ### Build
62
+
63
+ ```bash
64
+ npm run build
65
+ ```
66
+
67
+ This also regenerates `src/openapi.ts` from `../seclai-python/openapi/seclai.openapi.json`.
package/dist/index.cjs ADDED
@@ -0,0 +1,369 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ SECLAI_API_URL: () => SECLAI_API_URL,
24
+ Seclai: () => Seclai,
25
+ SeclaiAPIStatusError: () => SeclaiAPIStatusError,
26
+ SeclaiAPIValidationError: () => SeclaiAPIValidationError,
27
+ SeclaiConfigurationError: () => SeclaiConfigurationError,
28
+ SeclaiError: () => SeclaiError
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/errors.ts
33
+ var SeclaiError = class extends Error {
34
+ constructor(message) {
35
+ super(message);
36
+ this.name = "SeclaiError";
37
+ }
38
+ };
39
+ var SeclaiConfigurationError = class extends SeclaiError {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "SeclaiConfigurationError";
43
+ }
44
+ };
45
+ var SeclaiAPIStatusError = class extends SeclaiError {
46
+ /** HTTP status code returned by the API. */
47
+ statusCode;
48
+ /** HTTP method used for the request. */
49
+ method;
50
+ /** Full request URL. */
51
+ url;
52
+ /** Best-effort response body text (if available). */
53
+ responseText;
54
+ constructor(opts) {
55
+ super(opts.message);
56
+ this.name = "SeclaiAPIStatusError";
57
+ this.statusCode = opts.statusCode;
58
+ this.method = opts.method;
59
+ this.url = opts.url;
60
+ this.responseText = opts.responseText;
61
+ }
62
+ };
63
+ var SeclaiAPIValidationError = class extends SeclaiAPIStatusError {
64
+ /** Parsed validation error payload (best-effort). */
65
+ validationError;
66
+ constructor(opts) {
67
+ super(opts);
68
+ this.name = "SeclaiAPIValidationError";
69
+ this.validationError = opts.validationError;
70
+ }
71
+ };
72
+
73
+ // src/client.ts
74
+ var SECLAI_API_URL = "https://seclai.com";
75
+ function getEnv(name) {
76
+ const p = globalThis?.process;
77
+ return p?.env?.[name];
78
+ }
79
+ function buildURL(baseUrl, path, query) {
80
+ const url = new URL(path, baseUrl);
81
+ if (query) {
82
+ for (const [key, value] of Object.entries(query)) {
83
+ if (value === void 0 || value === null) continue;
84
+ url.searchParams.set(key, String(value));
85
+ }
86
+ }
87
+ return url;
88
+ }
89
+ async function safeText(response) {
90
+ try {
91
+ return await response.clone().text();
92
+ } catch {
93
+ return void 0;
94
+ }
95
+ }
96
+ async function safeJson(response) {
97
+ try {
98
+ return await response.clone().json();
99
+ } catch {
100
+ return void 0;
101
+ }
102
+ }
103
+ var Seclai = class {
104
+ apiKey;
105
+ baseUrl;
106
+ apiKeyHeader;
107
+ defaultHeaders;
108
+ fetcher;
109
+ /**
110
+ * Create a new Seclai client.
111
+ *
112
+ * @param opts - Client configuration.
113
+ * @throws {@link SeclaiConfigurationError} If no API key is provided (and `SECLAI_API_KEY` is not set).
114
+ * @throws {@link SeclaiConfigurationError} If no `fetch` implementation is available.
115
+ */
116
+ constructor(opts = {}) {
117
+ const apiKey = opts.apiKey ?? getEnv("SECLAI_API_KEY");
118
+ if (!apiKey) {
119
+ throw new SeclaiConfigurationError(
120
+ "Missing API key. Provide apiKey or set SECLAI_API_KEY."
121
+ );
122
+ }
123
+ const fetcher = opts.fetch ?? globalThis.fetch;
124
+ if (!fetcher) {
125
+ throw new SeclaiConfigurationError(
126
+ "No fetch implementation available. Provide opts.fetch or run in an environment with global fetch."
127
+ );
128
+ }
129
+ this.apiKey = apiKey;
130
+ this.baseUrl = opts.baseUrl ?? getEnv("SECLAI_API_URL") ?? SECLAI_API_URL;
131
+ this.apiKeyHeader = opts.apiKeyHeader ?? "x-api-key";
132
+ this.defaultHeaders = { ...opts.defaultHeaders ?? {} };
133
+ this.fetcher = fetcher;
134
+ }
135
+ /**
136
+ * Make a raw HTTP request to the Seclai API.
137
+ *
138
+ * This is a low-level escape hatch. For most operations, prefer the typed convenience methods.
139
+ *
140
+ * @param method - HTTP method (e.g. `"GET"`, `"POST"`).
141
+ * @param path - Request path relative to `baseUrl` (e.g. `"/api/sources/"`).
142
+ * @param opts - Query params, JSON body, and per-request headers.
143
+ * @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.
144
+ * @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).
145
+ * @throws {@link SeclaiAPIStatusError} For other non-success HTTP status codes.
146
+ */
147
+ async request(method, path, opts) {
148
+ const url = buildURL(this.baseUrl, path, opts?.query);
149
+ const headers = {
150
+ ...this.defaultHeaders,
151
+ ...opts?.headers ?? {},
152
+ [this.apiKeyHeader]: this.apiKey
153
+ };
154
+ let body;
155
+ if (opts?.json !== void 0) {
156
+ headers["content-type"] = headers["content-type"] ?? "application/json";
157
+ body = JSON.stringify(opts.json);
158
+ }
159
+ const init = { method, headers };
160
+ if (body !== void 0) {
161
+ init.body = body;
162
+ }
163
+ const response = await this.fetcher(url, init);
164
+ if (response.status === 204) return null;
165
+ const contentType = response.headers.get("content-type") ?? "";
166
+ const isJson = contentType.includes("application/json");
167
+ if (!response.ok) {
168
+ const responseText = await safeText(response);
169
+ if (response.status === 422) {
170
+ const validation = await safeJson(response);
171
+ throw new SeclaiAPIValidationError({
172
+ message: "Validation error",
173
+ statusCode: response.status,
174
+ method,
175
+ url: url.toString(),
176
+ responseText,
177
+ validationError: validation
178
+ });
179
+ }
180
+ throw new SeclaiAPIStatusError({
181
+ message: `Request failed with status ${response.status}`,
182
+ statusCode: response.status,
183
+ method,
184
+ url: url.toString(),
185
+ responseText
186
+ });
187
+ }
188
+ if (!response.body) return null;
189
+ if (isJson) {
190
+ return await response.json();
191
+ }
192
+ return await response.text();
193
+ }
194
+ /**
195
+ * Run an agent.
196
+ *
197
+ * @param agentId - Agent identifier.
198
+ * @param body - Agent run request payload.
199
+ * @returns The created agent run.
200
+ */
201
+ async runAgent(agentId, body) {
202
+ const data = await this.request("POST", `/api/agents/${agentId}/runs`, { json: body });
203
+ return data;
204
+ }
205
+ /**
206
+ * List agent runs for an agent.
207
+ *
208
+ * @param agentId - Agent identifier.
209
+ * @param opts - Pagination options.
210
+ * @returns A paginated list of runs.
211
+ */
212
+ async listAgentRuns(agentId, opts = {}) {
213
+ const data = await this.request("GET", `/api/agents/${agentId}/runs`, {
214
+ query: { page: opts.page ?? 1, limit: opts.limit ?? 50 }
215
+ });
216
+ return data;
217
+ }
218
+ /**
219
+ * Get details of a specific agent run.
220
+ *
221
+ * @param agentId - Agent identifier.
222
+ * @param runId - Run identifier.
223
+ * @returns Agent run details.
224
+ */
225
+ async getAgentRun(agentId, runId) {
226
+ const data = await this.request("GET", `/api/agents/${agentId}/runs/${runId}`);
227
+ return data;
228
+ }
229
+ /**
230
+ * Cancel an agent run.
231
+ *
232
+ * @param agentId - Agent identifier.
233
+ * @param runId - Run identifier.
234
+ * @returns Updated agent run record.
235
+ */
236
+ async deleteAgentRun(agentId, runId) {
237
+ const data = await this.request("DELETE", `/api/agents/${agentId}/runs/${runId}`);
238
+ return data;
239
+ }
240
+ /**
241
+ * Get content detail.
242
+ *
243
+ * Fetches a slice of a content version (use `start`/`end` to page through large content).
244
+ *
245
+ * @param sourceConnectionContentVersion - Content version identifier.
246
+ * @param opts - Range options.
247
+ * @returns Content details for the requested range.
248
+ */
249
+ async getContentDetail(sourceConnectionContentVersion, opts = {}) {
250
+ const data = await this.request(
251
+ "GET",
252
+ `/api/contents/${sourceConnectionContentVersion}`,
253
+ { query: { start: opts.start ?? 0, end: opts.end ?? 5e3 } }
254
+ );
255
+ return data;
256
+ }
257
+ /**
258
+ * Delete a specific content version.
259
+ *
260
+ * @param sourceConnectionContentVersion - Content version identifier.
261
+ */
262
+ async deleteContent(sourceConnectionContentVersion) {
263
+ await this.request("DELETE", `/api/contents/${sourceConnectionContentVersion}`);
264
+ }
265
+ /**
266
+ * List embeddings for a content version.
267
+ *
268
+ * @param sourceConnectionContentVersion - Content version identifier.
269
+ * @param opts - Pagination options.
270
+ * @returns A paginated list of embeddings.
271
+ */
272
+ async listContentEmbeddings(sourceConnectionContentVersion, opts = {}) {
273
+ const data = await this.request(
274
+ "GET",
275
+ `/api/contents/${sourceConnectionContentVersion}/embeddings`,
276
+ { query: { page: opts.page ?? 1, limit: opts.limit ?? 20 } }
277
+ );
278
+ return data;
279
+ }
280
+ /**
281
+ * List sources.
282
+ *
283
+ * @param opts - Pagination and filter options.
284
+ * @returns A paginated list of sources.
285
+ */
286
+ async listSources(opts = {}) {
287
+ const data = await this.request("GET", "/api/sources/", {
288
+ query: {
289
+ page: opts.page ?? 1,
290
+ limit: opts.limit ?? 20,
291
+ sort: opts.sort ?? "created_at",
292
+ order: opts.order ?? "desc",
293
+ account_id: opts.accountId ?? void 0
294
+ }
295
+ });
296
+ return data;
297
+ }
298
+ /**
299
+ * Upload a file to a specific source connection.
300
+ *
301
+ * @param sourceConnectionId - Source connection identifier.
302
+ * @param opts - File payload and optional metadata.
303
+ * @param opts.file - File payload as a `Blob`, `Uint8Array`, or `ArrayBuffer`.
304
+ * @param opts.title - Optional title for the uploaded file.
305
+ * @param opts.fileName - Optional filename to send with the upload.
306
+ * @param opts.mimeType - Optional MIME type to attach to the upload.
307
+ * @returns Upload response details.
308
+ */
309
+ async uploadFileToSource(sourceConnectionId, opts) {
310
+ const url = buildURL(this.baseUrl, `/api/sources/${sourceConnectionId}/upload`);
311
+ const headers = {
312
+ ...this.defaultHeaders,
313
+ [this.apiKeyHeader]: this.apiKey
314
+ };
315
+ const form = new FormData();
316
+ let blob;
317
+ if (opts.file instanceof Blob) {
318
+ blob = opts.file;
319
+ } else if (opts.file instanceof ArrayBuffer) {
320
+ const blobOpts = opts.mimeType ? { type: opts.mimeType } : void 0;
321
+ blob = new Blob([new Uint8Array(opts.file)], blobOpts);
322
+ } else {
323
+ const blobOpts = opts.mimeType ? { type: opts.mimeType } : void 0;
324
+ blob = new Blob([opts.file], blobOpts);
325
+ }
326
+ const fileName = opts.fileName ?? "upload";
327
+ form.set("file", blob, fileName);
328
+ if (opts.title !== void 0) {
329
+ form.set("title", opts.title);
330
+ }
331
+ const response = await this.fetcher(url, {
332
+ method: "POST",
333
+ headers,
334
+ body: form
335
+ });
336
+ if (!response.ok) {
337
+ const responseText = await safeText(response);
338
+ if (response.status === 422) {
339
+ const validation = await safeJson(response);
340
+ throw new SeclaiAPIValidationError({
341
+ message: "Validation error",
342
+ statusCode: response.status,
343
+ method: "POST",
344
+ url: url.toString(),
345
+ responseText,
346
+ validationError: validation
347
+ });
348
+ }
349
+ throw new SeclaiAPIStatusError({
350
+ message: `Request failed with status ${response.status}`,
351
+ statusCode: response.status,
352
+ method: "POST",
353
+ url: url.toString(),
354
+ responseText
355
+ });
356
+ }
357
+ return await response.json();
358
+ }
359
+ };
360
+ // Annotate the CommonJS export names for ESM import in node:
361
+ 0 && (module.exports = {
362
+ SECLAI_API_URL,
363
+ Seclai,
364
+ SeclaiAPIStatusError,
365
+ SeclaiAPIValidationError,
366
+ SeclaiConfigurationError,
367
+ SeclaiError
368
+ });
369
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export {\n Seclai,\n SECLAI_API_URL,\n type SeclaiOptions,\n type FetchLike,\n} from \"./client\";\n\nexport {\n SeclaiError,\n SeclaiConfigurationError,\n SeclaiAPIStatusError,\n SeclaiAPIValidationError,\n} from \"./errors\";\n\nexport type {\n JSONValue,\n AgentRunRequest,\n AgentRunResponse,\n AgentRunListResponse,\n ContentDetailResponse,\n ContentEmbeddingsListResponse,\n SourceListResponse,\n FileUploadResponse,\n HTTPValidationError,\n} from \"./types\";\n","/** Base error class for the Seclai SDK. */\nexport class SeclaiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SeclaiError\";\n }\n}\n\n/** Thrown when the SDK is misconfigured (for example, missing API key). */\nexport class SeclaiConfigurationError extends SeclaiError {\n constructor(message: string) {\n super(message);\n this.name = \"SeclaiConfigurationError\";\n }\n}\n\n/**\n * Thrown when the API returns a non-success status code.\n *\n * @remarks\n * Use {@link SeclaiAPIValidationError} for HTTP 422 validation errors.\n */\nexport class SeclaiAPIStatusError extends SeclaiError {\n /** HTTP status code returned by the API. */\n public readonly statusCode: number;\n /** HTTP method used for the request. */\n public readonly method: string;\n /** Full request URL. */\n public readonly url: string;\n /** Best-effort response body text (if available). */\n public readonly responseText: string | undefined;\n\n constructor(opts: {\n /** Human-readable error message. */\n message: string;\n statusCode: number;\n method: string;\n url: string;\n responseText: string | undefined;\n }) {\n super(opts.message);\n this.name = \"SeclaiAPIStatusError\";\n this.statusCode = opts.statusCode;\n this.method = opts.method;\n this.url = opts.url;\n this.responseText = opts.responseText;\n }\n}\n\n/**\n * Thrown when the API returns a validation error response (typically HTTP 422).\n *\n * The `validationError` field contains the decoded validation payload when available.\n */\nexport class SeclaiAPIValidationError extends SeclaiAPIStatusError {\n /** Parsed validation error payload (best-effort). */\n public readonly validationError: unknown;\n\n constructor(opts: {\n message: string;\n statusCode: number;\n method: string;\n url: string;\n responseText: string | undefined;\n validationError: unknown;\n }) {\n super(opts);\n this.name = \"SeclaiAPIValidationError\";\n this.validationError = opts.validationError;\n }\n}\n","import {\n SeclaiAPIStatusError,\n SeclaiAPIValidationError,\n SeclaiConfigurationError,\n} from \"./errors\";\nimport type {\n AgentRunListResponse,\n AgentRunRequest,\n AgentRunResponse,\n ContentDetailResponse,\n ContentEmbeddingsListResponse,\n FileUploadResponse,\n HTTPValidationError,\n SourceListResponse,\n} from \"./types\";\n\n/** Default API base URL (can be overridden with `baseUrl` or `SECLAI_API_URL`). */\nexport const SECLAI_API_URL = \"https://seclai.com\";\n\n/** A `fetch`-compatible function (e.g. `globalThis.fetch` or `undici.fetch`). */\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\n/** Configuration for the {@link Seclai} client. */\nexport interface SeclaiOptions {\n /** API key used for authentication. Defaults to `process.env.SECLAI_API_KEY` when available. */\n apiKey?: string;\n /** API base URL. Defaults to `process.env.SECLAI_API_URL` when available, else {@link SECLAI_API_URL}. */\n baseUrl?: string;\n /** Header name to use for the API key. Defaults to `x-api-key`. */\n apiKeyHeader?: string;\n /** Extra headers to include on every request. */\n defaultHeaders?: Record<string, string>;\n /** Optional `fetch` implementation for environments without a global `fetch`. */\n fetch?: FetchLike;\n}\n\nfunction getEnv(name: string): string | undefined {\n const p = (globalThis as any)?.process;\n return p?.env?.[name];\n}\n\nfunction buildURL(baseUrl: string, path: string, query?: Record<string, unknown>): URL {\n const url = new URL(path, baseUrl);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) continue;\n url.searchParams.set(key, String(value));\n }\n }\n return url;\n}\n\nasync function safeText(response: Response): Promise<string | undefined> {\n try {\n return await response.clone().text();\n } catch {\n return undefined;\n }\n}\n\nasync function safeJson(response: Response): Promise<unknown | undefined> {\n try {\n return await response.clone().json();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Seclai JavaScript/TypeScript client.\n *\n * @remarks\n * - Uses API key auth via `x-api-key` by default.\n * - Throws SDK exceptions for non-success responses.\n */\nexport class Seclai {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly apiKeyHeader: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly fetcher: FetchLike;\n\n /**\n * Create a new Seclai client.\n *\n * @param opts - Client configuration.\n * @throws {@link SeclaiConfigurationError} If no API key is provided (and `SECLAI_API_KEY` is not set).\n * @throws {@link SeclaiConfigurationError} If no `fetch` implementation is available.\n */\n constructor(opts: SeclaiOptions = {}) {\n const apiKey = opts.apiKey ?? getEnv(\"SECLAI_API_KEY\");\n if (!apiKey) {\n throw new SeclaiConfigurationError(\n \"Missing API key. Provide apiKey or set SECLAI_API_KEY.\"\n );\n }\n\n const fetcher = opts.fetch ?? (globalThis.fetch as FetchLike | undefined);\n if (!fetcher) {\n throw new SeclaiConfigurationError(\n \"No fetch implementation available. Provide opts.fetch or run in an environment with global fetch.\"\n );\n }\n\n this.apiKey = apiKey;\n this.baseUrl = opts.baseUrl ?? getEnv(\"SECLAI_API_URL\") ?? SECLAI_API_URL;\n this.apiKeyHeader = opts.apiKeyHeader ?? \"x-api-key\";\n this.defaultHeaders = { ...(opts.defaultHeaders ?? {}) };\n this.fetcher = fetcher;\n }\n\n /**\n * Make a raw HTTP request to the Seclai API.\n *\n * This is a low-level escape hatch. For most operations, prefer the typed convenience methods.\n *\n * @param method - HTTP method (e.g. `\"GET\"`, `\"POST\"`).\n * @param path - Request path relative to `baseUrl` (e.g. `\"/api/sources/\"`).\n * @param opts - Query params, JSON body, and per-request headers.\n * @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.\n * @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).\n * @throws {@link SeclaiAPIStatusError} For other non-success HTTP status codes.\n */\n async request(\n method: string,\n path: string,\n opts?: {\n query?: Record<string, unknown>;\n json?: unknown;\n headers?: Record<string, string>;\n }\n ): Promise<unknown | string | null> {\n const url = buildURL(this.baseUrl, path, opts?.query);\n\n const headers: Record<string, string> = {\n ...this.defaultHeaders,\n ...(opts?.headers ?? {}),\n [this.apiKeyHeader]: this.apiKey,\n };\n\n let body: BodyInit | undefined;\n if (opts?.json !== undefined) {\n headers[\"content-type\"] = headers[\"content-type\"] ?? \"application/json\";\n body = JSON.stringify(opts.json);\n }\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = body;\n }\n const response = await this.fetcher(url, init);\n\n if (response.status === 204) return null;\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n\n if (!response.ok) {\n const responseText = await safeText(response);\n if (response.status === 422) {\n const validation = (await safeJson(response)) as HTTPValidationError | undefined;\n throw new SeclaiAPIValidationError({\n message: \"Validation error\",\n statusCode: response.status,\n method,\n url: url.toString(),\n responseText,\n validationError: validation,\n });\n }\n throw new SeclaiAPIStatusError({\n message: `Request failed with status ${response.status}`,\n statusCode: response.status,\n method,\n url: url.toString(),\n responseText,\n });\n }\n\n if (!response.body) return null;\n\n if (isJson) {\n return (await response.json()) as unknown;\n }\n return await response.text();\n }\n\n /**\n * Run an agent.\n *\n * @param agentId - Agent identifier.\n * @param body - Agent run request payload.\n * @returns The created agent run.\n */\n async runAgent(agentId: string, body: AgentRunRequest): Promise<AgentRunResponse> {\n const data = await this.request(\"POST\", `/api/agents/${agentId}/runs`, { json: body });\n return data as AgentRunResponse;\n }\n\n /**\n * List agent runs for an agent.\n *\n * @param agentId - Agent identifier.\n * @param opts - Pagination options.\n * @returns A paginated list of runs.\n */\n async listAgentRuns(\n agentId: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<AgentRunListResponse> {\n const data = await this.request(\"GET\", `/api/agents/${agentId}/runs`, {\n query: { page: opts.page ?? 1, limit: opts.limit ?? 50 },\n });\n return data as AgentRunListResponse;\n }\n\n /**\n * Get details of a specific agent run.\n *\n * @param agentId - Agent identifier.\n * @param runId - Run identifier.\n * @returns Agent run details.\n */\n async getAgentRun(agentId: string, runId: string): Promise<AgentRunResponse> {\n const data = await this.request(\"GET\", `/api/agents/${agentId}/runs/${runId}`);\n return data as AgentRunResponse;\n }\n\n /**\n * Cancel an agent run.\n *\n * @param agentId - Agent identifier.\n * @param runId - Run identifier.\n * @returns Updated agent run record.\n */\n async deleteAgentRun(agentId: string, runId: string): Promise<AgentRunResponse> {\n const data = await this.request(\"DELETE\", `/api/agents/${agentId}/runs/${runId}`);\n return data as AgentRunResponse;\n }\n\n /**\n * Get content detail.\n *\n * Fetches a slice of a content version (use `start`/`end` to page through large content).\n *\n * @param sourceConnectionContentVersion - Content version identifier.\n * @param opts - Range options.\n * @returns Content details for the requested range.\n */\n async getContentDetail(\n sourceConnectionContentVersion: string,\n opts: { start?: number; end?: number } = {}\n ): Promise<ContentDetailResponse> {\n const data = await this.request(\n \"GET\",\n `/api/contents/${sourceConnectionContentVersion}`,\n { query: { start: opts.start ?? 0, end: opts.end ?? 5000 } }\n );\n return data as ContentDetailResponse;\n }\n\n /**\n * Delete a specific content version.\n *\n * @param sourceConnectionContentVersion - Content version identifier.\n */\n async deleteContent(sourceConnectionContentVersion: string): Promise<void> {\n await this.request(\"DELETE\", `/api/contents/${sourceConnectionContentVersion}`);\n }\n\n /**\n * List embeddings for a content version.\n *\n * @param sourceConnectionContentVersion - Content version identifier.\n * @param opts - Pagination options.\n * @returns A paginated list of embeddings.\n */\n async listContentEmbeddings(\n sourceConnectionContentVersion: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<ContentEmbeddingsListResponse> {\n const data = await this.request(\n \"GET\",\n `/api/contents/${sourceConnectionContentVersion}/embeddings`,\n { query: { page: opts.page ?? 1, limit: opts.limit ?? 20 } }\n );\n return data as ContentEmbeddingsListResponse;\n }\n\n /**\n * List sources.\n *\n * @param opts - Pagination and filter options.\n * @returns A paginated list of sources.\n */\n async listSources(\n opts: {\n page?: number;\n limit?: number;\n sort?: string;\n order?: \"asc\" | \"desc\";\n accountId?: string | null;\n } = {}\n ): Promise<SourceListResponse> {\n const data = await this.request(\"GET\", \"/api/sources/\", {\n query: {\n page: opts.page ?? 1,\n limit: opts.limit ?? 20,\n sort: opts.sort ?? \"created_at\",\n order: opts.order ?? \"desc\",\n account_id: opts.accountId ?? undefined,\n },\n });\n return data as SourceListResponse;\n }\n\n /**\n * Upload a file to a specific source connection.\n *\n * @param sourceConnectionId - Source connection identifier.\n * @param opts - File payload and optional metadata.\n * @param opts.file - File payload as a `Blob`, `Uint8Array`, or `ArrayBuffer`.\n * @param opts.title - Optional title for the uploaded file.\n * @param opts.fileName - Optional filename to send with the upload.\n * @param opts.mimeType - Optional MIME type to attach to the upload.\n * @returns Upload response details.\n */\n async uploadFileToSource(\n sourceConnectionId: string,\n opts: {\n file: Blob | Uint8Array | ArrayBuffer;\n title?: string;\n fileName?: string;\n mimeType?: string;\n }\n ): Promise<FileUploadResponse> {\n const url = buildURL(this.baseUrl, `/api/sources/${sourceConnectionId}/upload`);\n\n const headers: Record<string, string> = {\n ...this.defaultHeaders,\n [this.apiKeyHeader]: this.apiKey,\n };\n\n const form = new FormData();\n\n let blob: Blob;\n if (opts.file instanceof Blob) {\n blob = opts.file;\n } else if (opts.file instanceof ArrayBuffer) {\n const blobOpts = opts.mimeType ? { type: opts.mimeType } : undefined;\n blob = new Blob([new Uint8Array(opts.file)], blobOpts);\n } else {\n const blobOpts = opts.mimeType ? { type: opts.mimeType } : undefined;\n blob = new Blob([opts.file as unknown as BlobPart], blobOpts);\n }\n\n const fileName = opts.fileName ?? \"upload\";\n form.set(\"file\", blob, fileName);\n\n if (opts.title !== undefined) {\n form.set(\"title\", opts.title);\n }\n\n const response = await this.fetcher(url, {\n method: \"POST\",\n headers,\n body: form,\n });\n\n if (!response.ok) {\n const responseText = await safeText(response);\n if (response.status === 422) {\n const validation = (await safeJson(response)) as HTTPValidationError | undefined;\n throw new SeclaiAPIValidationError({\n message: \"Validation error\",\n statusCode: response.status,\n method: \"POST\",\n url: url.toString(),\n responseText,\n validationError: validation,\n });\n }\n throw new SeclaiAPIStatusError({\n message: `Request failed with status ${response.status}`,\n statusCode: response.status,\n method: \"POST\",\n url: url.toString(),\n responseText,\n });\n }\n\n return (await response.json()) as FileUploadResponse;\n }\n}\n"],"mappings":"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","names":[]}