@seclai/sdk 1.0.1 → 1.0.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/README.md +32 -7
- package/dist/index.cjs +163 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -2
- package/dist/index.d.ts +31 -2
- package/dist/index.js +163 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,13 +12,7 @@ npm install @seclai/sdk
|
|
|
12
12
|
|
|
13
13
|
Online API documentation (latest):
|
|
14
14
|
|
|
15
|
-
https://seclai.github.io/seclai-javascript/1.0.
|
|
16
|
-
|
|
17
|
-
Generate HTML docs into `build/docs/`:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm run docs
|
|
21
|
-
```
|
|
15
|
+
https://seclai.github.io/seclai-javascript/1.0.3/
|
|
22
16
|
|
|
23
17
|
## Usage
|
|
24
18
|
|
|
@@ -31,6 +25,29 @@ const sources = await client.listSources();
|
|
|
31
25
|
console.log(sources.pagination, sources.data);
|
|
32
26
|
```
|
|
33
27
|
|
|
28
|
+
### Run an agent with SSE streaming (wait for final result)
|
|
29
|
+
|
|
30
|
+
Use the SSE streaming endpoint and block until the final `done` event is received.
|
|
31
|
+
|
|
32
|
+
If the stream ends before `done` or the timeout is reached, this method throws.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { Seclai } from "@seclai/sdk";
|
|
36
|
+
|
|
37
|
+
const client = new Seclai({ apiKey: process.env.SECLAI_API_KEY });
|
|
38
|
+
|
|
39
|
+
const run = await client.runStreamingAgentAndWait(
|
|
40
|
+
"agent_id",
|
|
41
|
+
{
|
|
42
|
+
input: "Hello from streaming",
|
|
43
|
+
metadata: { app: "My App" },
|
|
44
|
+
},
|
|
45
|
+
{ timeoutMs: 60_000 }
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
console.log(run);
|
|
49
|
+
```
|
|
50
|
+
|
|
34
51
|
### Upload a file
|
|
35
52
|
|
|
36
53
|
```ts
|
|
@@ -77,3 +94,11 @@ npm run build
|
|
|
77
94
|
```
|
|
78
95
|
|
|
79
96
|
This also regenerates `src/openapi.ts` from `openapi/seclai.openapi.json`.
|
|
97
|
+
|
|
98
|
+
### Generate docs
|
|
99
|
+
|
|
100
|
+
Generate HTML docs into `build/docs/`:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm run docs
|
|
104
|
+
```
|
package/dist/index.cjs
CHANGED
|
@@ -100,6 +100,59 @@ async function safeJson(response) {
|
|
|
100
100
|
return void 0;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
function createSseParser(onMessage) {
|
|
104
|
+
let buffer = "";
|
|
105
|
+
let eventName;
|
|
106
|
+
let dataLines = [];
|
|
107
|
+
function dispatch() {
|
|
108
|
+
if (!eventName && dataLines.length === 0) return;
|
|
109
|
+
const msg = { data: dataLines.join("\n") };
|
|
110
|
+
if (eventName !== void 0) msg.event = eventName;
|
|
111
|
+
onMessage(msg);
|
|
112
|
+
eventName = void 0;
|
|
113
|
+
dataLines = [];
|
|
114
|
+
}
|
|
115
|
+
function feed(textChunk) {
|
|
116
|
+
buffer += textChunk;
|
|
117
|
+
while (true) {
|
|
118
|
+
const newlineIdx = buffer.indexOf("\n");
|
|
119
|
+
if (newlineIdx === -1) return;
|
|
120
|
+
let line = buffer.slice(0, newlineIdx);
|
|
121
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
122
|
+
if (line.endsWith("\r")) line = line.slice(0, -1);
|
|
123
|
+
if (line === "") {
|
|
124
|
+
dispatch();
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (line.startsWith(":")) continue;
|
|
128
|
+
const colon = line.indexOf(":");
|
|
129
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
130
|
+
let value = colon === -1 ? "" : line.slice(colon + 1);
|
|
131
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
132
|
+
if (field === "event") {
|
|
133
|
+
eventName = value;
|
|
134
|
+
} else if (field === "data") {
|
|
135
|
+
dataLines.push(value);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { feed, end: dispatch };
|
|
140
|
+
}
|
|
141
|
+
function anySignal(signals) {
|
|
142
|
+
const present = signals.filter(Boolean);
|
|
143
|
+
if (present.length === 0) return void 0;
|
|
144
|
+
if (present.length === 1) return present[0];
|
|
145
|
+
const controller = new AbortController();
|
|
146
|
+
const onAbort = () => controller.abort();
|
|
147
|
+
for (const s of present) {
|
|
148
|
+
if (s.aborted) {
|
|
149
|
+
controller.abort();
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
s.addEventListener("abort", onAbort, { once: true });
|
|
153
|
+
}
|
|
154
|
+
return controller.signal;
|
|
155
|
+
}
|
|
103
156
|
var Seclai = class {
|
|
104
157
|
apiKey;
|
|
105
158
|
baseUrl;
|
|
@@ -138,7 +191,7 @@ var Seclai = class {
|
|
|
138
191
|
* This is a low-level escape hatch. For most operations, prefer the typed convenience methods.
|
|
139
192
|
*
|
|
140
193
|
* @param method - HTTP method (e.g. `"GET"`, `"POST"`).
|
|
141
|
-
|
|
194
|
+
* @param path - Request path relative to `baseUrl` (e.g. `"/sources/"`).
|
|
142
195
|
* @param opts - Query params, JSON body, and per-request headers.
|
|
143
196
|
* @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.
|
|
144
197
|
* @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).
|
|
@@ -199,9 +252,109 @@ var Seclai = class {
|
|
|
199
252
|
* @returns The created agent run.
|
|
200
253
|
*/
|
|
201
254
|
async runAgent(agentId, body) {
|
|
202
|
-
const data = await this.request("POST", `/
|
|
255
|
+
const data = await this.request("POST", `/agents/${agentId}/runs`, { json: body });
|
|
203
256
|
return data;
|
|
204
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Run an agent in streaming mode (SSE) and block until the final `done` event.
|
|
260
|
+
*
|
|
261
|
+
* @param agentId - Agent identifier.
|
|
262
|
+
* @param body - Streaming agent run request payload.
|
|
263
|
+
* @param opts - Optional timeout + abort signal.
|
|
264
|
+
* @returns Final agent run payload from the `done` event.
|
|
265
|
+
*/
|
|
266
|
+
async runStreamingAgentAndWait(agentId, body, opts) {
|
|
267
|
+
const url = buildURL(this.baseUrl, `/agents/${agentId}/runs/stream`);
|
|
268
|
+
const headers = {
|
|
269
|
+
...this.defaultHeaders,
|
|
270
|
+
[this.apiKeyHeader]: this.apiKey,
|
|
271
|
+
accept: "text/event-stream",
|
|
272
|
+
"content-type": "application/json"
|
|
273
|
+
};
|
|
274
|
+
const timeoutMs = opts?.timeoutMs ?? 6e4;
|
|
275
|
+
const timeoutController = new AbortController();
|
|
276
|
+
let timedOut = false;
|
|
277
|
+
const timeoutId = setTimeout(() => {
|
|
278
|
+
timedOut = true;
|
|
279
|
+
timeoutController.abort();
|
|
280
|
+
}, timeoutMs);
|
|
281
|
+
const signal = anySignal([opts?.signal, timeoutController.signal]);
|
|
282
|
+
try {
|
|
283
|
+
const init = {
|
|
284
|
+
method: "POST",
|
|
285
|
+
headers,
|
|
286
|
+
body: JSON.stringify(body)
|
|
287
|
+
};
|
|
288
|
+
if (signal) init.signal = signal;
|
|
289
|
+
const response = await this.fetcher(url, init);
|
|
290
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
291
|
+
const isJson = contentType.includes("application/json");
|
|
292
|
+
if (!response.ok) {
|
|
293
|
+
const responseText = await safeText(response);
|
|
294
|
+
if (response.status === 422) {
|
|
295
|
+
const validation = await safeJson(response);
|
|
296
|
+
throw new SeclaiAPIValidationError({
|
|
297
|
+
message: "Validation error",
|
|
298
|
+
statusCode: response.status,
|
|
299
|
+
method: "POST",
|
|
300
|
+
url: url.toString(),
|
|
301
|
+
responseText,
|
|
302
|
+
validationError: validation
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
throw new SeclaiAPIStatusError({
|
|
306
|
+
message: `Request failed with status ${response.status}`,
|
|
307
|
+
statusCode: response.status,
|
|
308
|
+
method: "POST",
|
|
309
|
+
url: url.toString(),
|
|
310
|
+
responseText
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
if (isJson) {
|
|
314
|
+
return await response.json();
|
|
315
|
+
}
|
|
316
|
+
if (!response.body) {
|
|
317
|
+
throw new SeclaiConfigurationError(
|
|
318
|
+
"Streaming response body is not available in this environment. Provide a fetch implementation that supports ReadableStream bodies."
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
const reader = response.body.getReader();
|
|
322
|
+
const decoder = new TextDecoder();
|
|
323
|
+
let final;
|
|
324
|
+
let lastSeen;
|
|
325
|
+
const parser = createSseParser((msg) => {
|
|
326
|
+
if (!msg.data) return;
|
|
327
|
+
if (msg.event === "init" || msg.event === "done") {
|
|
328
|
+
try {
|
|
329
|
+
const parsed = JSON.parse(msg.data);
|
|
330
|
+
lastSeen = parsed;
|
|
331
|
+
if (msg.event === "done") {
|
|
332
|
+
final = parsed;
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
while (!final) {
|
|
339
|
+
const { value, done } = await reader.read();
|
|
340
|
+
if (done) break;
|
|
341
|
+
if (value) parser.feed(decoder.decode(value, { stream: true }));
|
|
342
|
+
}
|
|
343
|
+
parser.end();
|
|
344
|
+
if (final) return final;
|
|
345
|
+
if (lastSeen && lastSeen.status && lastSeen.status !== "pending") {
|
|
346
|
+
return lastSeen;
|
|
347
|
+
}
|
|
348
|
+
throw new SeclaiError("Stream ended before receiving a 'done' event.");
|
|
349
|
+
} catch (err) {
|
|
350
|
+
if (timedOut) {
|
|
351
|
+
throw new SeclaiError(`Timed out after ${timeoutMs}ms waiting for streaming agent run to complete.`);
|
|
352
|
+
}
|
|
353
|
+
throw err;
|
|
354
|
+
} finally {
|
|
355
|
+
clearTimeout(timeoutId);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
205
358
|
/**
|
|
206
359
|
* List agent runs for an agent.
|
|
207
360
|
*
|
|
@@ -210,7 +363,7 @@ var Seclai = class {
|
|
|
210
363
|
* @returns A paginated list of runs.
|
|
211
364
|
*/
|
|
212
365
|
async listAgentRuns(agentId, opts = {}) {
|
|
213
|
-
const data = await this.request("GET", `/
|
|
366
|
+
const data = await this.request("GET", `/agents/${agentId}/runs`, {
|
|
214
367
|
query: { page: opts.page ?? 1, limit: opts.limit ?? 50 }
|
|
215
368
|
});
|
|
216
369
|
return data;
|
|
@@ -223,7 +376,7 @@ var Seclai = class {
|
|
|
223
376
|
* @returns Agent run details.
|
|
224
377
|
*/
|
|
225
378
|
async getAgentRun(agentId, runId) {
|
|
226
|
-
const data = await this.request("GET", `/
|
|
379
|
+
const data = await this.request("GET", `/agents/${agentId}/runs/${runId}`);
|
|
227
380
|
return data;
|
|
228
381
|
}
|
|
229
382
|
/**
|
|
@@ -234,7 +387,7 @@ var Seclai = class {
|
|
|
234
387
|
* @returns Updated agent run record.
|
|
235
388
|
*/
|
|
236
389
|
async deleteAgentRun(agentId, runId) {
|
|
237
|
-
const data = await this.request("DELETE", `/
|
|
390
|
+
const data = await this.request("DELETE", `/agents/${agentId}/runs/${runId}`);
|
|
238
391
|
return data;
|
|
239
392
|
}
|
|
240
393
|
/**
|
|
@@ -249,7 +402,7 @@ var Seclai = class {
|
|
|
249
402
|
async getContentDetail(sourceConnectionContentVersion, opts = {}) {
|
|
250
403
|
const data = await this.request(
|
|
251
404
|
"GET",
|
|
252
|
-
`/
|
|
405
|
+
`/contents/${sourceConnectionContentVersion}`,
|
|
253
406
|
{ query: { start: opts.start ?? 0, end: opts.end ?? 5e3 } }
|
|
254
407
|
);
|
|
255
408
|
return data;
|
|
@@ -260,7 +413,7 @@ var Seclai = class {
|
|
|
260
413
|
* @param sourceConnectionContentVersion - Content version identifier.
|
|
261
414
|
*/
|
|
262
415
|
async deleteContent(sourceConnectionContentVersion) {
|
|
263
|
-
await this.request("DELETE", `/
|
|
416
|
+
await this.request("DELETE", `/contents/${sourceConnectionContentVersion}`);
|
|
264
417
|
}
|
|
265
418
|
/**
|
|
266
419
|
* List embeddings for a content version.
|
|
@@ -272,7 +425,7 @@ var Seclai = class {
|
|
|
272
425
|
async listContentEmbeddings(sourceConnectionContentVersion, opts = {}) {
|
|
273
426
|
const data = await this.request(
|
|
274
427
|
"GET",
|
|
275
|
-
`/
|
|
428
|
+
`/contents/${sourceConnectionContentVersion}/embeddings`,
|
|
276
429
|
{ query: { page: opts.page ?? 1, limit: opts.limit ?? 20 } }
|
|
277
430
|
);
|
|
278
431
|
return data;
|
|
@@ -284,7 +437,7 @@ var Seclai = class {
|
|
|
284
437
|
* @returns A paginated list of sources.
|
|
285
438
|
*/
|
|
286
439
|
async listSources(opts = {}) {
|
|
287
|
-
const data = await this.request("GET", "/
|
|
440
|
+
const data = await this.request("GET", "/sources/", {
|
|
288
441
|
query: {
|
|
289
442
|
page: opts.page ?? 1,
|
|
290
443
|
limit: opts.limit ?? 20,
|
|
@@ -307,7 +460,7 @@ var Seclai = class {
|
|
|
307
460
|
* @returns Upload response details.
|
|
308
461
|
*/
|
|
309
462
|
async uploadFileToSource(sourceConnectionId, opts) {
|
|
310
|
-
const url = buildURL(this.baseUrl, `/
|
|
463
|
+
const url = buildURL(this.baseUrl, `/sources/${sourceConnectionId}/upload`);
|
|
311
464
|
const headers = {
|
|
312
465
|
...this.defaultHeaders,
|
|
313
466
|
[this.apiKeyHeader]: this.apiKey
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +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":[]}
|
|
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 AgentRunStreamRequest,\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 SeclaiError,\n} from \"./errors\";\nimport type {\n AgentRunListResponse,\n AgentRunRequest,\n AgentRunResponse,\n AgentRunStreamRequest,\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\ntype SseMessage = { event?: string; data?: string };\n\nfunction createSseParser(onMessage: (msg: SseMessage) => void) {\n let buffer = \"\";\n let eventName: string | undefined;\n let dataLines: string[] = [];\n\n function dispatch() {\n if (!eventName && dataLines.length === 0) return;\n const msg: SseMessage = { data: dataLines.join(\"\\n\") };\n if (eventName !== undefined) msg.event = eventName;\n onMessage(msg);\n eventName = undefined;\n dataLines = [];\n }\n\n function feed(textChunk: string) {\n buffer += textChunk;\n while (true) {\n const newlineIdx = buffer.indexOf(\"\\n\");\n if (newlineIdx === -1) return;\n\n let line = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + 1);\n\n if (line.endsWith(\"\\r\")) line = line.slice(0, -1);\n\n if (line === \"\") {\n dispatch();\n continue;\n }\n\n // Comments/keepalives begin with ':'\n if (line.startsWith(\":\")) continue;\n\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) value = value.slice(1);\n\n if (field === \"event\") {\n eventName = value;\n } else if (field === \"data\") {\n dataLines.push(value);\n }\n }\n }\n\n return { feed, end: dispatch };\n}\n\nfunction anySignal(signals: Array<AbortSignal | undefined>): AbortSignal | undefined {\n const present = signals.filter(Boolean) as AbortSignal[];\n if (present.length === 0) return undefined;\n if (present.length === 1) return present[0];\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n for (const s of present) {\n if (s.aborted) {\n controller.abort();\n break;\n }\n s.addEventListener(\"abort\", onAbort, { once: true });\n }\n return controller.signal;\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. `\"/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\", `/agents/${agentId}/runs`, { json: body });\n return data as AgentRunResponse;\n }\n\n /**\n * Run an agent in streaming mode (SSE) and block until the final `done` event.\n *\n * @param agentId - Agent identifier.\n * @param body - Streaming agent run request payload.\n * @param opts - Optional timeout + abort signal.\n * @returns Final agent run payload from the `done` event.\n */\n async runStreamingAgentAndWait(\n agentId: string,\n body: AgentRunStreamRequest,\n opts?: { timeoutMs?: number; signal?: AbortSignal }\n ): Promise<AgentRunResponse> {\n const url = buildURL(this.baseUrl, `/agents/${agentId}/runs/stream`);\n\n const headers: Record<string, string> = {\n ...this.defaultHeaders,\n [this.apiKeyHeader]: this.apiKey,\n accept: \"text/event-stream\",\n \"content-type\": \"application/json\",\n };\n\n const timeoutMs = opts?.timeoutMs ?? 60_000;\n const timeoutController = new AbortController();\n let timedOut = false;\n const timeoutId = setTimeout(() => {\n timedOut = true;\n timeoutController.abort();\n }, timeoutMs);\n\n const signal = anySignal([opts?.signal, timeoutController.signal]);\n\n try {\n const init: RequestInit = {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n };\n if (signal) init.signal = signal;\n\n const response = await this.fetcher(url, init);\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: \"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 // Some servers may choose to return a JSON response even when we request SSE.\n if (isJson) {\n return (await response.json()) as AgentRunResponse;\n }\n\n if (!response.body) {\n throw new SeclaiConfigurationError(\n \"Streaming response body is not available in this environment. Provide a fetch implementation that supports ReadableStream bodies.\"\n );\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n let final: AgentRunResponse | undefined;\n let lastSeen: AgentRunResponse | undefined;\n\n const parser = createSseParser((msg) => {\n if (!msg.data) return;\n\n // `init` and `done` messages contain JSON payloads in `data:`.\n if (msg.event === \"init\" || msg.event === \"done\") {\n try {\n const parsed = JSON.parse(msg.data) as AgentRunResponse;\n lastSeen = parsed;\n if (msg.event === \"done\") {\n final = parsed;\n }\n } catch {\n // Ignore malformed JSON chunks.\n }\n }\n });\n\n while (!final) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) parser.feed(decoder.decode(value, { stream: true }));\n }\n\n parser.end();\n\n if (final) return final;\n if (lastSeen && (lastSeen as any).status && (lastSeen as any).status !== \"pending\") {\n return lastSeen;\n }\n\n throw new SeclaiError(\"Stream ended before receiving a 'done' event.\");\n } catch (err) {\n if (timedOut) {\n throw new SeclaiError(`Timed out after ${timeoutMs}ms waiting for streaming agent run to complete.`);\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n }\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\", `/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\", `/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\", `/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 `/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\", `/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 `/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\", \"/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, `/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":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -86,6 +86,21 @@ interface components {
|
|
|
86
86
|
/** @description Current status of the agent run. */
|
|
87
87
|
status: components["schemas"]["PendingProcessingCompletedFailedStatus"];
|
|
88
88
|
};
|
|
89
|
+
/** AgentRunStreamRequest */
|
|
90
|
+
AgentRunStreamRequest: {
|
|
91
|
+
/**
|
|
92
|
+
* Input
|
|
93
|
+
* @description Input to provide to the agent upon running for agents with dynamic triggers.
|
|
94
|
+
*/
|
|
95
|
+
input: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Metadata
|
|
98
|
+
* @description Metadata to make available for string substitution expressions in agent tasks.
|
|
99
|
+
*/
|
|
100
|
+
metadata: {
|
|
101
|
+
[key: string]: components["schemas"]["JsonValue"];
|
|
102
|
+
} | null;
|
|
103
|
+
};
|
|
89
104
|
/** Body_upload_file_to_source_api_sources__source_connection_id__upload_post */
|
|
90
105
|
Body_upload_file_to_source_api_sources__source_connection_id__upload_post: {
|
|
91
106
|
/**
|
|
@@ -488,6 +503,8 @@ type JSONValue = {
|
|
|
488
503
|
} | JSONValue[] | string | number | boolean | null;
|
|
489
504
|
/** Request body for starting an agent run. */
|
|
490
505
|
type AgentRunRequest = components["schemas"]["AgentRunRequest"];
|
|
506
|
+
/** Request body for starting an agent run in streaming mode (SSE). */
|
|
507
|
+
type AgentRunStreamRequest = components["schemas"]["AgentRunStreamRequest"];
|
|
491
508
|
/** Response body describing an agent run. */
|
|
492
509
|
type AgentRunResponse = components["schemas"]["AgentRunResponse"];
|
|
493
510
|
/** Paginated list response for agent runs. */
|
|
@@ -547,7 +564,7 @@ declare class Seclai {
|
|
|
547
564
|
* This is a low-level escape hatch. For most operations, prefer the typed convenience methods.
|
|
548
565
|
*
|
|
549
566
|
* @param method - HTTP method (e.g. `"GET"`, `"POST"`).
|
|
550
|
-
|
|
567
|
+
* @param path - Request path relative to `baseUrl` (e.g. `"/sources/"`).
|
|
551
568
|
* @param opts - Query params, JSON body, and per-request headers.
|
|
552
569
|
* @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.
|
|
553
570
|
* @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).
|
|
@@ -566,6 +583,18 @@ declare class Seclai {
|
|
|
566
583
|
* @returns The created agent run.
|
|
567
584
|
*/
|
|
568
585
|
runAgent(agentId: string, body: AgentRunRequest): Promise<AgentRunResponse>;
|
|
586
|
+
/**
|
|
587
|
+
* Run an agent in streaming mode (SSE) and block until the final `done` event.
|
|
588
|
+
*
|
|
589
|
+
* @param agentId - Agent identifier.
|
|
590
|
+
* @param body - Streaming agent run request payload.
|
|
591
|
+
* @param opts - Optional timeout + abort signal.
|
|
592
|
+
* @returns Final agent run payload from the `done` event.
|
|
593
|
+
*/
|
|
594
|
+
runStreamingAgentAndWait(agentId: string, body: AgentRunStreamRequest, opts?: {
|
|
595
|
+
timeoutMs?: number;
|
|
596
|
+
signal?: AbortSignal;
|
|
597
|
+
}): Promise<AgentRunResponse>;
|
|
569
598
|
/**
|
|
570
599
|
* List agent runs for an agent.
|
|
571
600
|
*
|
|
@@ -705,4 +734,4 @@ declare class SeclaiAPIValidationError extends SeclaiAPIStatusError {
|
|
|
705
734
|
});
|
|
706
735
|
}
|
|
707
736
|
|
|
708
|
-
export { type AgentRunListResponse, type AgentRunRequest, type AgentRunResponse, type ContentDetailResponse, type ContentEmbeddingsListResponse, type FetchLike, type FileUploadResponse, type HTTPValidationError, type JSONValue, SECLAI_API_URL, Seclai, SeclaiAPIStatusError, SeclaiAPIValidationError, SeclaiConfigurationError, SeclaiError, type SeclaiOptions, type SourceListResponse };
|
|
737
|
+
export { type AgentRunListResponse, type AgentRunRequest, type AgentRunResponse, type AgentRunStreamRequest, type ContentDetailResponse, type ContentEmbeddingsListResponse, type FetchLike, type FileUploadResponse, type HTTPValidationError, type JSONValue, SECLAI_API_URL, Seclai, SeclaiAPIStatusError, SeclaiAPIValidationError, SeclaiConfigurationError, SeclaiError, type SeclaiOptions, type SourceListResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,21 @@ interface components {
|
|
|
86
86
|
/** @description Current status of the agent run. */
|
|
87
87
|
status: components["schemas"]["PendingProcessingCompletedFailedStatus"];
|
|
88
88
|
};
|
|
89
|
+
/** AgentRunStreamRequest */
|
|
90
|
+
AgentRunStreamRequest: {
|
|
91
|
+
/**
|
|
92
|
+
* Input
|
|
93
|
+
* @description Input to provide to the agent upon running for agents with dynamic triggers.
|
|
94
|
+
*/
|
|
95
|
+
input: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Metadata
|
|
98
|
+
* @description Metadata to make available for string substitution expressions in agent tasks.
|
|
99
|
+
*/
|
|
100
|
+
metadata: {
|
|
101
|
+
[key: string]: components["schemas"]["JsonValue"];
|
|
102
|
+
} | null;
|
|
103
|
+
};
|
|
89
104
|
/** Body_upload_file_to_source_api_sources__source_connection_id__upload_post */
|
|
90
105
|
Body_upload_file_to_source_api_sources__source_connection_id__upload_post: {
|
|
91
106
|
/**
|
|
@@ -488,6 +503,8 @@ type JSONValue = {
|
|
|
488
503
|
} | JSONValue[] | string | number | boolean | null;
|
|
489
504
|
/** Request body for starting an agent run. */
|
|
490
505
|
type AgentRunRequest = components["schemas"]["AgentRunRequest"];
|
|
506
|
+
/** Request body for starting an agent run in streaming mode (SSE). */
|
|
507
|
+
type AgentRunStreamRequest = components["schemas"]["AgentRunStreamRequest"];
|
|
491
508
|
/** Response body describing an agent run. */
|
|
492
509
|
type AgentRunResponse = components["schemas"]["AgentRunResponse"];
|
|
493
510
|
/** Paginated list response for agent runs. */
|
|
@@ -547,7 +564,7 @@ declare class Seclai {
|
|
|
547
564
|
* This is a low-level escape hatch. For most operations, prefer the typed convenience methods.
|
|
548
565
|
*
|
|
549
566
|
* @param method - HTTP method (e.g. `"GET"`, `"POST"`).
|
|
550
|
-
|
|
567
|
+
* @param path - Request path relative to `baseUrl` (e.g. `"/sources/"`).
|
|
551
568
|
* @param opts - Query params, JSON body, and per-request headers.
|
|
552
569
|
* @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.
|
|
553
570
|
* @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).
|
|
@@ -566,6 +583,18 @@ declare class Seclai {
|
|
|
566
583
|
* @returns The created agent run.
|
|
567
584
|
*/
|
|
568
585
|
runAgent(agentId: string, body: AgentRunRequest): Promise<AgentRunResponse>;
|
|
586
|
+
/**
|
|
587
|
+
* Run an agent in streaming mode (SSE) and block until the final `done` event.
|
|
588
|
+
*
|
|
589
|
+
* @param agentId - Agent identifier.
|
|
590
|
+
* @param body - Streaming agent run request payload.
|
|
591
|
+
* @param opts - Optional timeout + abort signal.
|
|
592
|
+
* @returns Final agent run payload from the `done` event.
|
|
593
|
+
*/
|
|
594
|
+
runStreamingAgentAndWait(agentId: string, body: AgentRunStreamRequest, opts?: {
|
|
595
|
+
timeoutMs?: number;
|
|
596
|
+
signal?: AbortSignal;
|
|
597
|
+
}): Promise<AgentRunResponse>;
|
|
569
598
|
/**
|
|
570
599
|
* List agent runs for an agent.
|
|
571
600
|
*
|
|
@@ -705,4 +734,4 @@ declare class SeclaiAPIValidationError extends SeclaiAPIStatusError {
|
|
|
705
734
|
});
|
|
706
735
|
}
|
|
707
736
|
|
|
708
|
-
export { type AgentRunListResponse, type AgentRunRequest, type AgentRunResponse, type ContentDetailResponse, type ContentEmbeddingsListResponse, type FetchLike, type FileUploadResponse, type HTTPValidationError, type JSONValue, SECLAI_API_URL, Seclai, SeclaiAPIStatusError, SeclaiAPIValidationError, SeclaiConfigurationError, SeclaiError, type SeclaiOptions, type SourceListResponse };
|
|
737
|
+
export { type AgentRunListResponse, type AgentRunRequest, type AgentRunResponse, type AgentRunStreamRequest, type ContentDetailResponse, type ContentEmbeddingsListResponse, type FetchLike, type FileUploadResponse, type HTTPValidationError, type JSONValue, SECLAI_API_URL, Seclai, SeclaiAPIStatusError, SeclaiAPIValidationError, SeclaiConfigurationError, SeclaiError, type SeclaiOptions, type SourceListResponse };
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,59 @@ async function safeJson(response) {
|
|
|
69
69
|
return void 0;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
function createSseParser(onMessage) {
|
|
73
|
+
let buffer = "";
|
|
74
|
+
let eventName;
|
|
75
|
+
let dataLines = [];
|
|
76
|
+
function dispatch() {
|
|
77
|
+
if (!eventName && dataLines.length === 0) return;
|
|
78
|
+
const msg = { data: dataLines.join("\n") };
|
|
79
|
+
if (eventName !== void 0) msg.event = eventName;
|
|
80
|
+
onMessage(msg);
|
|
81
|
+
eventName = void 0;
|
|
82
|
+
dataLines = [];
|
|
83
|
+
}
|
|
84
|
+
function feed(textChunk) {
|
|
85
|
+
buffer += textChunk;
|
|
86
|
+
while (true) {
|
|
87
|
+
const newlineIdx = buffer.indexOf("\n");
|
|
88
|
+
if (newlineIdx === -1) return;
|
|
89
|
+
let line = buffer.slice(0, newlineIdx);
|
|
90
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
91
|
+
if (line.endsWith("\r")) line = line.slice(0, -1);
|
|
92
|
+
if (line === "") {
|
|
93
|
+
dispatch();
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (line.startsWith(":")) continue;
|
|
97
|
+
const colon = line.indexOf(":");
|
|
98
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
99
|
+
let value = colon === -1 ? "" : line.slice(colon + 1);
|
|
100
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
101
|
+
if (field === "event") {
|
|
102
|
+
eventName = value;
|
|
103
|
+
} else if (field === "data") {
|
|
104
|
+
dataLines.push(value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { feed, end: dispatch };
|
|
109
|
+
}
|
|
110
|
+
function anySignal(signals) {
|
|
111
|
+
const present = signals.filter(Boolean);
|
|
112
|
+
if (present.length === 0) return void 0;
|
|
113
|
+
if (present.length === 1) return present[0];
|
|
114
|
+
const controller = new AbortController();
|
|
115
|
+
const onAbort = () => controller.abort();
|
|
116
|
+
for (const s of present) {
|
|
117
|
+
if (s.aborted) {
|
|
118
|
+
controller.abort();
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
s.addEventListener("abort", onAbort, { once: true });
|
|
122
|
+
}
|
|
123
|
+
return controller.signal;
|
|
124
|
+
}
|
|
72
125
|
var Seclai = class {
|
|
73
126
|
apiKey;
|
|
74
127
|
baseUrl;
|
|
@@ -107,7 +160,7 @@ var Seclai = class {
|
|
|
107
160
|
* This is a low-level escape hatch. For most operations, prefer the typed convenience methods.
|
|
108
161
|
*
|
|
109
162
|
* @param method - HTTP method (e.g. `"GET"`, `"POST"`).
|
|
110
|
-
|
|
163
|
+
* @param path - Request path relative to `baseUrl` (e.g. `"/sources/"`).
|
|
111
164
|
* @param opts - Query params, JSON body, and per-request headers.
|
|
112
165
|
* @returns Parsed JSON for JSON responses, raw text for non-JSON responses, or `null` for empty bodies.
|
|
113
166
|
* @throws {@link SeclaiAPIValidationError} For validation errors (typically HTTP 422).
|
|
@@ -168,9 +221,109 @@ var Seclai = class {
|
|
|
168
221
|
* @returns The created agent run.
|
|
169
222
|
*/
|
|
170
223
|
async runAgent(agentId, body) {
|
|
171
|
-
const data = await this.request("POST", `/
|
|
224
|
+
const data = await this.request("POST", `/agents/${agentId}/runs`, { json: body });
|
|
172
225
|
return data;
|
|
173
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Run an agent in streaming mode (SSE) and block until the final `done` event.
|
|
229
|
+
*
|
|
230
|
+
* @param agentId - Agent identifier.
|
|
231
|
+
* @param body - Streaming agent run request payload.
|
|
232
|
+
* @param opts - Optional timeout + abort signal.
|
|
233
|
+
* @returns Final agent run payload from the `done` event.
|
|
234
|
+
*/
|
|
235
|
+
async runStreamingAgentAndWait(agentId, body, opts) {
|
|
236
|
+
const url = buildURL(this.baseUrl, `/agents/${agentId}/runs/stream`);
|
|
237
|
+
const headers = {
|
|
238
|
+
...this.defaultHeaders,
|
|
239
|
+
[this.apiKeyHeader]: this.apiKey,
|
|
240
|
+
accept: "text/event-stream",
|
|
241
|
+
"content-type": "application/json"
|
|
242
|
+
};
|
|
243
|
+
const timeoutMs = opts?.timeoutMs ?? 6e4;
|
|
244
|
+
const timeoutController = new AbortController();
|
|
245
|
+
let timedOut = false;
|
|
246
|
+
const timeoutId = setTimeout(() => {
|
|
247
|
+
timedOut = true;
|
|
248
|
+
timeoutController.abort();
|
|
249
|
+
}, timeoutMs);
|
|
250
|
+
const signal = anySignal([opts?.signal, timeoutController.signal]);
|
|
251
|
+
try {
|
|
252
|
+
const init = {
|
|
253
|
+
method: "POST",
|
|
254
|
+
headers,
|
|
255
|
+
body: JSON.stringify(body)
|
|
256
|
+
};
|
|
257
|
+
if (signal) init.signal = signal;
|
|
258
|
+
const response = await this.fetcher(url, init);
|
|
259
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
260
|
+
const isJson = contentType.includes("application/json");
|
|
261
|
+
if (!response.ok) {
|
|
262
|
+
const responseText = await safeText(response);
|
|
263
|
+
if (response.status === 422) {
|
|
264
|
+
const validation = await safeJson(response);
|
|
265
|
+
throw new SeclaiAPIValidationError({
|
|
266
|
+
message: "Validation error",
|
|
267
|
+
statusCode: response.status,
|
|
268
|
+
method: "POST",
|
|
269
|
+
url: url.toString(),
|
|
270
|
+
responseText,
|
|
271
|
+
validationError: validation
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
throw new SeclaiAPIStatusError({
|
|
275
|
+
message: `Request failed with status ${response.status}`,
|
|
276
|
+
statusCode: response.status,
|
|
277
|
+
method: "POST",
|
|
278
|
+
url: url.toString(),
|
|
279
|
+
responseText
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (isJson) {
|
|
283
|
+
return await response.json();
|
|
284
|
+
}
|
|
285
|
+
if (!response.body) {
|
|
286
|
+
throw new SeclaiConfigurationError(
|
|
287
|
+
"Streaming response body is not available in this environment. Provide a fetch implementation that supports ReadableStream bodies."
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
const reader = response.body.getReader();
|
|
291
|
+
const decoder = new TextDecoder();
|
|
292
|
+
let final;
|
|
293
|
+
let lastSeen;
|
|
294
|
+
const parser = createSseParser((msg) => {
|
|
295
|
+
if (!msg.data) return;
|
|
296
|
+
if (msg.event === "init" || msg.event === "done") {
|
|
297
|
+
try {
|
|
298
|
+
const parsed = JSON.parse(msg.data);
|
|
299
|
+
lastSeen = parsed;
|
|
300
|
+
if (msg.event === "done") {
|
|
301
|
+
final = parsed;
|
|
302
|
+
}
|
|
303
|
+
} catch {
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
while (!final) {
|
|
308
|
+
const { value, done } = await reader.read();
|
|
309
|
+
if (done) break;
|
|
310
|
+
if (value) parser.feed(decoder.decode(value, { stream: true }));
|
|
311
|
+
}
|
|
312
|
+
parser.end();
|
|
313
|
+
if (final) return final;
|
|
314
|
+
if (lastSeen && lastSeen.status && lastSeen.status !== "pending") {
|
|
315
|
+
return lastSeen;
|
|
316
|
+
}
|
|
317
|
+
throw new SeclaiError("Stream ended before receiving a 'done' event.");
|
|
318
|
+
} catch (err) {
|
|
319
|
+
if (timedOut) {
|
|
320
|
+
throw new SeclaiError(`Timed out after ${timeoutMs}ms waiting for streaming agent run to complete.`);
|
|
321
|
+
}
|
|
322
|
+
throw err;
|
|
323
|
+
} finally {
|
|
324
|
+
clearTimeout(timeoutId);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
174
327
|
/**
|
|
175
328
|
* List agent runs for an agent.
|
|
176
329
|
*
|
|
@@ -179,7 +332,7 @@ var Seclai = class {
|
|
|
179
332
|
* @returns A paginated list of runs.
|
|
180
333
|
*/
|
|
181
334
|
async listAgentRuns(agentId, opts = {}) {
|
|
182
|
-
const data = await this.request("GET", `/
|
|
335
|
+
const data = await this.request("GET", `/agents/${agentId}/runs`, {
|
|
183
336
|
query: { page: opts.page ?? 1, limit: opts.limit ?? 50 }
|
|
184
337
|
});
|
|
185
338
|
return data;
|
|
@@ -192,7 +345,7 @@ var Seclai = class {
|
|
|
192
345
|
* @returns Agent run details.
|
|
193
346
|
*/
|
|
194
347
|
async getAgentRun(agentId, runId) {
|
|
195
|
-
const data = await this.request("GET", `/
|
|
348
|
+
const data = await this.request("GET", `/agents/${agentId}/runs/${runId}`);
|
|
196
349
|
return data;
|
|
197
350
|
}
|
|
198
351
|
/**
|
|
@@ -203,7 +356,7 @@ var Seclai = class {
|
|
|
203
356
|
* @returns Updated agent run record.
|
|
204
357
|
*/
|
|
205
358
|
async deleteAgentRun(agentId, runId) {
|
|
206
|
-
const data = await this.request("DELETE", `/
|
|
359
|
+
const data = await this.request("DELETE", `/agents/${agentId}/runs/${runId}`);
|
|
207
360
|
return data;
|
|
208
361
|
}
|
|
209
362
|
/**
|
|
@@ -218,7 +371,7 @@ var Seclai = class {
|
|
|
218
371
|
async getContentDetail(sourceConnectionContentVersion, opts = {}) {
|
|
219
372
|
const data = await this.request(
|
|
220
373
|
"GET",
|
|
221
|
-
`/
|
|
374
|
+
`/contents/${sourceConnectionContentVersion}`,
|
|
222
375
|
{ query: { start: opts.start ?? 0, end: opts.end ?? 5e3 } }
|
|
223
376
|
);
|
|
224
377
|
return data;
|
|
@@ -229,7 +382,7 @@ var Seclai = class {
|
|
|
229
382
|
* @param sourceConnectionContentVersion - Content version identifier.
|
|
230
383
|
*/
|
|
231
384
|
async deleteContent(sourceConnectionContentVersion) {
|
|
232
|
-
await this.request("DELETE", `/
|
|
385
|
+
await this.request("DELETE", `/contents/${sourceConnectionContentVersion}`);
|
|
233
386
|
}
|
|
234
387
|
/**
|
|
235
388
|
* List embeddings for a content version.
|
|
@@ -241,7 +394,7 @@ var Seclai = class {
|
|
|
241
394
|
async listContentEmbeddings(sourceConnectionContentVersion, opts = {}) {
|
|
242
395
|
const data = await this.request(
|
|
243
396
|
"GET",
|
|
244
|
-
`/
|
|
397
|
+
`/contents/${sourceConnectionContentVersion}/embeddings`,
|
|
245
398
|
{ query: { page: opts.page ?? 1, limit: opts.limit ?? 20 } }
|
|
246
399
|
);
|
|
247
400
|
return data;
|
|
@@ -253,7 +406,7 @@ var Seclai = class {
|
|
|
253
406
|
* @returns A paginated list of sources.
|
|
254
407
|
*/
|
|
255
408
|
async listSources(opts = {}) {
|
|
256
|
-
const data = await this.request("GET", "/
|
|
409
|
+
const data = await this.request("GET", "/sources/", {
|
|
257
410
|
query: {
|
|
258
411
|
page: opts.page ?? 1,
|
|
259
412
|
limit: opts.limit ?? 20,
|
|
@@ -276,7 +429,7 @@ var Seclai = class {
|
|
|
276
429
|
* @returns Upload response details.
|
|
277
430
|
*/
|
|
278
431
|
async uploadFileToSource(sourceConnectionId, opts) {
|
|
279
|
-
const url = buildURL(this.baseUrl, `/
|
|
432
|
+
const url = buildURL(this.baseUrl, `/sources/${sourceConnectionId}/upload`);
|
|
280
433
|
const headers = {
|
|
281
434
|
...this.defaultHeaders,
|
|
282
435
|
[this.apiKeyHeader]: this.apiKey
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/** 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":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/** 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 SeclaiError,\n} from \"./errors\";\nimport type {\n AgentRunListResponse,\n AgentRunRequest,\n AgentRunResponse,\n AgentRunStreamRequest,\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\ntype SseMessage = { event?: string; data?: string };\n\nfunction createSseParser(onMessage: (msg: SseMessage) => void) {\n let buffer = \"\";\n let eventName: string | undefined;\n let dataLines: string[] = [];\n\n function dispatch() {\n if (!eventName && dataLines.length === 0) return;\n const msg: SseMessage = { data: dataLines.join(\"\\n\") };\n if (eventName !== undefined) msg.event = eventName;\n onMessage(msg);\n eventName = undefined;\n dataLines = [];\n }\n\n function feed(textChunk: string) {\n buffer += textChunk;\n while (true) {\n const newlineIdx = buffer.indexOf(\"\\n\");\n if (newlineIdx === -1) return;\n\n let line = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + 1);\n\n if (line.endsWith(\"\\r\")) line = line.slice(0, -1);\n\n if (line === \"\") {\n dispatch();\n continue;\n }\n\n // Comments/keepalives begin with ':'\n if (line.startsWith(\":\")) continue;\n\n const colon = line.indexOf(\":\");\n const field = colon === -1 ? line : line.slice(0, colon);\n let value = colon === -1 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) value = value.slice(1);\n\n if (field === \"event\") {\n eventName = value;\n } else if (field === \"data\") {\n dataLines.push(value);\n }\n }\n }\n\n return { feed, end: dispatch };\n}\n\nfunction anySignal(signals: Array<AbortSignal | undefined>): AbortSignal | undefined {\n const present = signals.filter(Boolean) as AbortSignal[];\n if (present.length === 0) return undefined;\n if (present.length === 1) return present[0];\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n for (const s of present) {\n if (s.aborted) {\n controller.abort();\n break;\n }\n s.addEventListener(\"abort\", onAbort, { once: true });\n }\n return controller.signal;\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. `\"/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\", `/agents/${agentId}/runs`, { json: body });\n return data as AgentRunResponse;\n }\n\n /**\n * Run an agent in streaming mode (SSE) and block until the final `done` event.\n *\n * @param agentId - Agent identifier.\n * @param body - Streaming agent run request payload.\n * @param opts - Optional timeout + abort signal.\n * @returns Final agent run payload from the `done` event.\n */\n async runStreamingAgentAndWait(\n agentId: string,\n body: AgentRunStreamRequest,\n opts?: { timeoutMs?: number; signal?: AbortSignal }\n ): Promise<AgentRunResponse> {\n const url = buildURL(this.baseUrl, `/agents/${agentId}/runs/stream`);\n\n const headers: Record<string, string> = {\n ...this.defaultHeaders,\n [this.apiKeyHeader]: this.apiKey,\n accept: \"text/event-stream\",\n \"content-type\": \"application/json\",\n };\n\n const timeoutMs = opts?.timeoutMs ?? 60_000;\n const timeoutController = new AbortController();\n let timedOut = false;\n const timeoutId = setTimeout(() => {\n timedOut = true;\n timeoutController.abort();\n }, timeoutMs);\n\n const signal = anySignal([opts?.signal, timeoutController.signal]);\n\n try {\n const init: RequestInit = {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n };\n if (signal) init.signal = signal;\n\n const response = await this.fetcher(url, init);\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: \"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 // Some servers may choose to return a JSON response even when we request SSE.\n if (isJson) {\n return (await response.json()) as AgentRunResponse;\n }\n\n if (!response.body) {\n throw new SeclaiConfigurationError(\n \"Streaming response body is not available in this environment. Provide a fetch implementation that supports ReadableStream bodies.\"\n );\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n let final: AgentRunResponse | undefined;\n let lastSeen: AgentRunResponse | undefined;\n\n const parser = createSseParser((msg) => {\n if (!msg.data) return;\n\n // `init` and `done` messages contain JSON payloads in `data:`.\n if (msg.event === \"init\" || msg.event === \"done\") {\n try {\n const parsed = JSON.parse(msg.data) as AgentRunResponse;\n lastSeen = parsed;\n if (msg.event === \"done\") {\n final = parsed;\n }\n } catch {\n // Ignore malformed JSON chunks.\n }\n }\n });\n\n while (!final) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) parser.feed(decoder.decode(value, { stream: true }));\n }\n\n parser.end();\n\n if (final) return final;\n if (lastSeen && (lastSeen as any).status && (lastSeen as any).status !== \"pending\") {\n return lastSeen;\n }\n\n throw new SeclaiError(\"Stream ended before receiving a 'done' event.\");\n } catch (err) {\n if (timedOut) {\n throw new SeclaiError(`Timed out after ${timeoutMs}ms waiting for streaming agent run to complete.`);\n }\n throw err;\n } finally {\n clearTimeout(timeoutId);\n }\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\", `/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\", `/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\", `/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 `/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\", `/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 `/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\", \"/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, `/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":[]}
|