@seclai/sdk 1.0.1 → 1.0.2
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 +1 -1
- package/dist/index.cjs +153 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
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;
|
|
@@ -202,6 +255,106 @@ var Seclai = class {
|
|
|
202
255
|
const data = await this.request("POST", `/api/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, `/api/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
|
*
|
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. `\"/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 * 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, `/api/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\", `/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":[]}
|
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. */
|
|
@@ -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. */
|
|
@@ -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;
|
|
@@ -171,6 +224,106 @@ var Seclai = class {
|
|
|
171
224
|
const data = await this.request("POST", `/api/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, `/api/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
|
*
|
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. `\"/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 * 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, `/api/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\", `/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":[]}
|