@seclai/sdk 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +415 -78
- package/dist/index.cjs +1566 -226
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4649 -454
- package/dist/index.d.ts +4649 -454
- package/dist/index.js +1564 -225
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Seclai JavaScript SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official JavaScript/TypeScript SDK for the [Seclai](https://seclai.com) API. Provides full typed coverage of all API endpoints, file uploads, SSE streaming, polling helpers, and automatic pagination.
|
|
4
|
+
|
|
5
|
+
Works in Node.js 18+, Deno, Bun, Cloudflare Workers, and any runtime with a `fetch` implementation.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -8,138 +10,467 @@ This is the official Seclai JavaScript SDK with TypeScript typings.
|
|
|
8
10
|
npm install @seclai/sdk
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Seclai } from "@seclai/sdk";
|
|
17
|
+
|
|
18
|
+
const client = new Seclai({ apiKey: process.env.SECLAI_API_KEY });
|
|
19
|
+
|
|
20
|
+
// List all sources
|
|
21
|
+
const sources = await client.listSources();
|
|
22
|
+
|
|
23
|
+
// Run an agent and stream the result
|
|
24
|
+
const result = await client.runStreamingAgentAndWait(
|
|
25
|
+
"agent_id",
|
|
26
|
+
{ input: "Summarize the latest uploads", metadata: {} },
|
|
27
|
+
{ timeoutMs: 120_000 },
|
|
28
|
+
);
|
|
29
|
+
console.log(result);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
| Option | Environment variable | Default |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `apiKey` | `SECLAI_API_KEY` | *required* |
|
|
37
|
+
| `baseUrl` | `SECLAI_API_URL` | `https://api.seclai.com` |
|
|
38
|
+
| `apiKeyHeader` | — | `x-api-key` |
|
|
39
|
+
| `defaultHeaders` | — | `{}` |
|
|
40
|
+
| `fetch` | — | `globalThis.fetch` |
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const client = new Seclai({
|
|
44
|
+
apiKey: "sk-...",
|
|
45
|
+
baseUrl: "https://staging-api.seclai.com",
|
|
46
|
+
defaultHeaders: { "X-Custom": "value" },
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
11
50
|
## API documentation
|
|
12
51
|
|
|
13
52
|
Online API documentation (latest):
|
|
14
53
|
|
|
15
|
-
https://seclai.github.io/seclai-javascript/1.0
|
|
54
|
+
https://seclai.github.io/seclai-javascript/1.1.0/
|
|
55
|
+
|
|
56
|
+
## Resources
|
|
16
57
|
|
|
17
|
-
|
|
58
|
+
### Agents
|
|
18
59
|
|
|
19
60
|
```ts
|
|
20
|
-
|
|
61
|
+
// CRUD
|
|
62
|
+
const agents = await client.listAgents({ page: 1, limit: 20 });
|
|
63
|
+
const agent = await client.createAgent({ name: "My Agent", description: "..." });
|
|
64
|
+
const fetched = await client.getAgent("agent_id");
|
|
65
|
+
const updated = await client.updateAgent("agent_id", { name: "Renamed" });
|
|
66
|
+
await client.deleteAgent("agent_id");
|
|
67
|
+
|
|
68
|
+
// Definition (step workflow)
|
|
69
|
+
const def = await client.getAgentDefinition("agent_id");
|
|
70
|
+
await client.updateAgentDefinition("agent_id", { steps: [...], change_id: def.change_id });
|
|
71
|
+
```
|
|
21
72
|
|
|
22
|
-
|
|
73
|
+
### Agent runs
|
|
23
74
|
|
|
24
|
-
|
|
25
|
-
|
|
75
|
+
```ts
|
|
76
|
+
// Start a run
|
|
77
|
+
const run = await client.runAgent("agent_id", { input: "Hello" });
|
|
78
|
+
|
|
79
|
+
// List & search runs
|
|
80
|
+
const runs = await client.listAgentRuns("agent_id", { status: "completed" });
|
|
81
|
+
const search = await client.searchAgentRuns({ agent_id: "...", status: ["completed"] });
|
|
82
|
+
|
|
83
|
+
// Fetch run details (optionally with step outputs)
|
|
84
|
+
const detail = await client.getAgentRun("run_id", { includeStepOutputs: true });
|
|
85
|
+
|
|
86
|
+
// Cancel or delete
|
|
87
|
+
await client.cancelAgentRun("run_id");
|
|
88
|
+
await client.deleteAgentRun("run_id");
|
|
26
89
|
```
|
|
27
90
|
|
|
28
|
-
###
|
|
91
|
+
### Streaming
|
|
29
92
|
|
|
30
|
-
|
|
93
|
+
The SDK provides two streaming patterns over the SSE `/runs/stream` endpoint:
|
|
31
94
|
|
|
32
|
-
|
|
95
|
+
**Block until done** — returns the final `done` payload or throws on timeout:
|
|
33
96
|
|
|
34
97
|
```ts
|
|
35
|
-
|
|
98
|
+
const result = await client.runStreamingAgentAndWait(
|
|
99
|
+
"agent_id",
|
|
100
|
+
{ input: "Hello", metadata: {} },
|
|
101
|
+
{ timeoutMs: 60_000 },
|
|
102
|
+
);
|
|
103
|
+
```
|
|
36
104
|
|
|
37
|
-
|
|
105
|
+
**Async iterator** — yields every SSE event as `{ event, data }`:
|
|
38
106
|
|
|
39
|
-
|
|
107
|
+
```ts
|
|
108
|
+
for await (const event of client.runStreamingAgent(
|
|
40
109
|
"agent_id",
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
110
|
+
{ input: "Hello" },
|
|
111
|
+
{ timeoutMs: 120_000 },
|
|
112
|
+
)) {
|
|
113
|
+
console.log(event.event, event.data);
|
|
114
|
+
if (event.event === "done") break;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Polling
|
|
119
|
+
|
|
120
|
+
For environments where SSE is not practical, poll for a completed run:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const result = await client.runAgentAndPoll(
|
|
124
|
+
"agent_id",
|
|
125
|
+
{ input: "Hello" },
|
|
126
|
+
{ pollIntervalMs: 2_000, timeoutMs: 120_000 },
|
|
46
127
|
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Agent input uploads
|
|
47
131
|
|
|
48
|
-
|
|
132
|
+
```ts
|
|
133
|
+
const upload = await client.uploadAgentInput("agent_id", {
|
|
134
|
+
file: new Uint8Array([...]),
|
|
135
|
+
fileName: "input.pdf",
|
|
136
|
+
});
|
|
137
|
+
const status = await client.getAgentInputUploadStatus("agent_id", upload.upload_id);
|
|
49
138
|
```
|
|
50
139
|
|
|
51
|
-
###
|
|
140
|
+
### Agent AI assistant
|
|
52
141
|
|
|
53
|
-
|
|
142
|
+
```ts
|
|
143
|
+
const steps = await client.generateAgentSteps("agent_id", { user_input: "Build a RAG pipeline" });
|
|
144
|
+
const config = await client.generateStepConfig("agent_id", { step_type: "llm", user_input: "..." });
|
|
145
|
+
|
|
146
|
+
// Conversation history
|
|
147
|
+
const history = await client.getAgentAiConversationHistory("agent_id");
|
|
148
|
+
await client.markAgentAiSuggestion("agent_id", "conversation_id", { accepted: true });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Agent evaluations
|
|
54
152
|
|
|
55
153
|
```ts
|
|
56
|
-
|
|
154
|
+
const criteria = await client.listEvaluationCriteria("agent_id");
|
|
155
|
+
const created = await client.createEvaluationCriteria("agent_id", { name: "Accuracy", ... });
|
|
156
|
+
const detail = await client.getEvaluationCriteria("criteria_id");
|
|
157
|
+
await client.updateEvaluationCriteria("criteria_id", { ... });
|
|
158
|
+
await client.deleteEvaluationCriteria("criteria_id");
|
|
57
159
|
|
|
58
|
-
|
|
160
|
+
// Test a draft
|
|
161
|
+
await client.testDraftEvaluation("agent_id", { criteria: { ... }, run_id: "..." });
|
|
59
162
|
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
163
|
+
// Results by criteria
|
|
164
|
+
const results = await client.listEvaluationResults("criteria_id");
|
|
165
|
+
const summary = await client.getEvaluationCriteriaSummary("criteria_id");
|
|
166
|
+
await client.createEvaluationResult("criteria_id", { ... });
|
|
63
167
|
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
168
|
+
// Results by run
|
|
169
|
+
const runResults = await client.listRunEvaluationResults("agent_id", "run_id");
|
|
170
|
+
|
|
171
|
+
// Non-manual evaluation summary
|
|
172
|
+
const nonManual = await client.getNonManualEvaluationSummary("agent_id");
|
|
173
|
+
|
|
174
|
+
// Compatible runs for a criteria
|
|
175
|
+
const compatible = await client.listCompatibleRuns("criteria_id");
|
|
69
176
|
```
|
|
70
177
|
|
|
71
|
-
###
|
|
178
|
+
### Knowledge bases
|
|
72
179
|
|
|
73
|
-
|
|
180
|
+
```ts
|
|
181
|
+
const kbs = await client.listKnowledgeBases();
|
|
182
|
+
const kb = await client.createKnowledgeBase({ name: "Docs KB" });
|
|
183
|
+
const fetched = await client.getKnowledgeBase("kb_id");
|
|
184
|
+
await client.updateKnowledgeBase("kb_id", { name: "Renamed KB" });
|
|
185
|
+
await client.deleteKnowledgeBase("kb_id");
|
|
186
|
+
```
|
|
74
187
|
|
|
75
|
-
|
|
76
|
-
- `application/epub+zip`
|
|
77
|
-
- `application/json`
|
|
78
|
-
- `application/msword`
|
|
79
|
-
- `application/pdf`
|
|
80
|
-
- `application/vnd.ms-excel`
|
|
81
|
-
- `application/vnd.ms-outlook`
|
|
82
|
-
- `application/vnd.ms-powerpoint`
|
|
83
|
-
- `application/vnd.openxmlformats-officedocument.presentationml.presentation`
|
|
84
|
-
- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`
|
|
85
|
-
- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
|
|
86
|
-
- `application/xml`
|
|
87
|
-
- `application/zip`
|
|
88
|
-
- `audio/flac`, `audio/mp4`, `audio/mpeg`, `audio/ogg`, `audio/wav`
|
|
89
|
-
- `image/bmp`, `image/gif`, `image/jpeg`, `image/png`, `image/tiff`, `image/webp`
|
|
90
|
-
- `text/csv`, `text/html`, `text/markdown`, `text/x-markdown`, `text/plain`, `text/xml`
|
|
91
|
-
- `video/mp4`, `video/quicktime`, `video/x-msvideo`
|
|
188
|
+
### Memory banks
|
|
92
189
|
|
|
93
|
-
|
|
190
|
+
```ts
|
|
191
|
+
const banks = await client.listMemoryBanks();
|
|
192
|
+
const bank = await client.createMemoryBank({ name: "Chat Memory", type: "conversation" });
|
|
193
|
+
const fetched = await client.getMemoryBank("mb_id");
|
|
194
|
+
await client.updateMemoryBank("mb_id", { name: "Renamed" });
|
|
195
|
+
await client.deleteMemoryBank("mb_id");
|
|
196
|
+
|
|
197
|
+
// Stats & compaction
|
|
198
|
+
const stats = await client.getMemoryBankStats("mb_id");
|
|
199
|
+
await client.compactMemoryBank("mb_id");
|
|
200
|
+
|
|
201
|
+
// Test compaction
|
|
202
|
+
const test = await client.testMemoryBankCompaction("mb_id", { ... });
|
|
203
|
+
const standalone = await client.testCompactionPromptStandalone({ ... });
|
|
204
|
+
|
|
205
|
+
// Templates & agents
|
|
206
|
+
const templates = await client.listMemoryBankTemplates();
|
|
207
|
+
const agents = await client.getAgentsUsingMemoryBank("mb_id");
|
|
208
|
+
|
|
209
|
+
// AI assistant
|
|
210
|
+
const suggestion = await client.generateMemoryBankConfig({ user_input: "..." });
|
|
211
|
+
const history = await client.getMemoryBankAiLastConversation();
|
|
212
|
+
await client.acceptMemoryBankAiSuggestion("conv_id", { ... });
|
|
213
|
+
|
|
214
|
+
// Source management
|
|
215
|
+
await client.deleteMemoryBankSource("mb_id");
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Sources
|
|
94
219
|
|
|
95
220
|
```ts
|
|
96
|
-
|
|
221
|
+
const sources = await client.listSources({ page: 1, limit: 20, order: "asc" });
|
|
222
|
+
const source = await client.createSource({ name: "My Source", ... });
|
|
223
|
+
const fetched = await client.getSource("source_id");
|
|
224
|
+
await client.updateSource("source_id", { name: "Renamed" });
|
|
225
|
+
await client.deleteSource("source_id");
|
|
226
|
+
```
|
|
97
227
|
|
|
98
|
-
|
|
228
|
+
### File uploads
|
|
99
229
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
230
|
+
Upload a file to a source (max 200 MiB). The SDK infers MIME type from the file extension when `mimeType` is not provided.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { readFile } from "node:fs/promises";
|
|
234
|
+
|
|
235
|
+
await client.uploadFileToSource("source_id", {
|
|
236
|
+
file: await readFile("document.pdf"),
|
|
237
|
+
fileName: "document.pdf",
|
|
238
|
+
title: "Q4 Report",
|
|
239
|
+
metadata: { department: "finance" },
|
|
107
240
|
});
|
|
108
|
-
console.log(upload);
|
|
109
241
|
```
|
|
110
242
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
If you need to correct or update an uploaded document while keeping references stable,
|
|
114
|
-
use `uploadFileToContent` to upload a new file and replace the content behind an existing
|
|
115
|
-
`source_connection_content_version`.
|
|
243
|
+
Upload inline text:
|
|
116
244
|
|
|
117
245
|
```ts
|
|
118
|
-
|
|
246
|
+
await client.uploadInlineTextToSource("source_id", {
|
|
247
|
+
text: "Hello, world!",
|
|
248
|
+
title: "Greeting",
|
|
249
|
+
});
|
|
250
|
+
```
|
|
119
251
|
|
|
120
|
-
|
|
252
|
+
Replace a content version with a new file:
|
|
121
253
|
|
|
122
|
-
|
|
123
|
-
|
|
254
|
+
```ts
|
|
255
|
+
await client.uploadFileToContent("content_version_id", {
|
|
256
|
+
file: await readFile("updated.pdf"),
|
|
124
257
|
fileName: "updated.pdf",
|
|
125
258
|
mimeType: "application/pdf",
|
|
126
|
-
title: "Updated document",
|
|
127
|
-
metadata: { revision: 2 },
|
|
128
259
|
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Source exports
|
|
129
263
|
|
|
130
|
-
|
|
264
|
+
```ts
|
|
265
|
+
const exports = await client.listSourceExports("source_id");
|
|
266
|
+
const exp = await client.createSourceExport("source_id", { format: "json" });
|
|
267
|
+
const status = await client.getSourceExport("source_id", exp.id);
|
|
268
|
+
const estimate = await client.estimateSourceExport("source_id", {});
|
|
269
|
+
const response = await client.downloadSourceExport("source_id", exp.id);
|
|
270
|
+
await client.deleteSourceExport("source_id", exp.id);
|
|
271
|
+
await client.cancelSourceExport("source_id", exp.id);
|
|
131
272
|
```
|
|
132
273
|
|
|
133
|
-
|
|
274
|
+
### Source embedding migrations
|
|
134
275
|
|
|
135
|
-
|
|
276
|
+
```ts
|
|
277
|
+
const migration = await client.getSourceEmbeddingMigration("source_id");
|
|
278
|
+
await client.startSourceEmbeddingMigration("source_id", { target_model: "..." });
|
|
279
|
+
await client.cancelSourceEmbeddingMigration("source_id");
|
|
280
|
+
```
|
|
136
281
|
|
|
137
|
-
|
|
282
|
+
### Content
|
|
138
283
|
|
|
139
|
-
```
|
|
140
|
-
|
|
284
|
+
```ts
|
|
285
|
+
const detail = await client.getContentDetail("content_id", { start: 0, end: 1000 });
|
|
286
|
+
const embeddings = await client.listContentEmbeddings("content_id");
|
|
287
|
+
await client.deleteContent("content_id");
|
|
288
|
+
|
|
289
|
+
// Replace content with inline text
|
|
290
|
+
await client.replaceContentWithInlineText("content_id", { text: "Updated text", title: "Updated" });
|
|
291
|
+
|
|
292
|
+
// Upload a replacement file
|
|
293
|
+
await client.uploadFileToContent("content_id", {
|
|
294
|
+
file: await readFile("updated.pdf"),
|
|
295
|
+
fileName: "updated.pdf",
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Solutions
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
const solutions = await client.listSolutions();
|
|
303
|
+
const sol = await client.createSolution({ name: "My Solution" });
|
|
304
|
+
const fetched = await client.getSolution("solution_id");
|
|
305
|
+
await client.updateSolution("solution_id", { name: "Renamed" });
|
|
306
|
+
await client.deleteSolution("solution_id");
|
|
307
|
+
|
|
308
|
+
// Link / unlink resources
|
|
309
|
+
await client.linkAgentsToSolution("solution_id", { ids: ["agent_id"] });
|
|
310
|
+
await client.unlinkAgentsFromSolution("solution_id", { ids: ["agent_id"] });
|
|
311
|
+
await client.linkKnowledgeBasesToSolution("solution_id", { ids: ["kb_id"] });
|
|
312
|
+
await client.unlinkKnowledgeBasesFromSolution("solution_id", { ids: ["kb_id"] });
|
|
313
|
+
await client.linkSourceConnectionsToSolution("solution_id", { ids: ["source_id"] });
|
|
314
|
+
await client.unlinkSourceConnectionsFromSolution("solution_id", { ids: ["source_id"] });
|
|
315
|
+
|
|
316
|
+
// AI assistant
|
|
317
|
+
const plan = await client.generateSolutionAiPlan("solution_id", { user_input: "Set up a RAG pipeline" });
|
|
318
|
+
await client.acceptSolutionAiPlan("solution_id", "conversation_id", {});
|
|
319
|
+
await client.declineSolutionAiPlan("solution_id", "conversation_id");
|
|
320
|
+
|
|
321
|
+
// AI-generated knowledge base / source within the solution
|
|
322
|
+
await client.generateSolutionAiKnowledgeBase("solution_id", { user_input: "..." });
|
|
323
|
+
await client.generateSolutionAiSource("solution_id", { user_input: "..." });
|
|
324
|
+
|
|
325
|
+
// Conversations
|
|
326
|
+
const convs = await client.listSolutionConversations("solution_id");
|
|
327
|
+
await client.addSolutionConversationTurn("solution_id", { user_input: "..." });
|
|
328
|
+
await client.markSolutionConversationTurn("solution_id", "conversation_id", { ... });
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Governance AI
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
const plan = await client.generateGovernanceAiPlan({ user_input: "Add a toxicity policy" });
|
|
335
|
+
const convs = await client.listGovernanceAiConversations();
|
|
336
|
+
await client.acceptGovernanceAiPlan("conversation_id");
|
|
337
|
+
await client.declineGovernanceAiPlan("conversation_id");
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Alerts
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
const alerts = await client.listAlerts({ status: "active" });
|
|
344
|
+
const alert = await client.getAlert("alert_id");
|
|
345
|
+
await client.changeAlertStatus("alert_id", { status: "resolved" });
|
|
346
|
+
await client.addAlertComment("alert_id", { text: "Investigating" });
|
|
347
|
+
|
|
348
|
+
// Subscriptions
|
|
349
|
+
await client.subscribeToAlert("alert_id");
|
|
350
|
+
await client.unsubscribeFromAlert("alert_id");
|
|
351
|
+
|
|
352
|
+
// Alert configs
|
|
353
|
+
const configs = await client.listAlertConfigs();
|
|
354
|
+
await client.createAlertConfig({ ... });
|
|
355
|
+
await client.getAlertConfig("config_id");
|
|
356
|
+
await client.updateAlertConfig("config_id", { ... });
|
|
357
|
+
await client.deleteAlertConfig("config_id");
|
|
358
|
+
|
|
359
|
+
// Organization preferences
|
|
360
|
+
const prefs = await client.listOrganizationAlertPreferences();
|
|
361
|
+
await client.updateOrganizationAlertPreference("org_id", "alert_type", { ... });
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Models
|
|
365
|
+
|
|
366
|
+
```ts
|
|
367
|
+
const alerts = await client.listModelAlerts();
|
|
368
|
+
await client.markModelAlertRead("alert_id");
|
|
369
|
+
await client.markAllModelAlertsRead();
|
|
370
|
+
const unread = await client.getUnreadModelAlertCount();
|
|
371
|
+
const recs = await client.getModelRecommendations("model_id");
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Search
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
const results = await client.search({ query: "quarterly report" });
|
|
378
|
+
const filtered = await client.search({ query: "my agent", entityType: "agent", limit: 5 });
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Top-level AI assistant
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
// Generate plans for different resource types
|
|
385
|
+
const kb = await client.aiAssistantKnowledgeBase({ user_input: "Create a docs KB" });
|
|
386
|
+
const src = await client.aiAssistantSource({ user_input: "Add a web source" });
|
|
387
|
+
const sol = await client.aiAssistantSolution({ user_input: "Set up monitoring" });
|
|
388
|
+
const mb = await client.aiAssistantMemoryBank({ user_input: "Create a chat memory" });
|
|
389
|
+
|
|
390
|
+
// Accept or decline the generated plan
|
|
391
|
+
await client.acceptAiAssistantPlan("conversation_id", { confirm_deletions: true });
|
|
392
|
+
await client.declineAiAssistantPlan("conversation_id");
|
|
393
|
+
|
|
394
|
+
// Memory bank conversation history
|
|
395
|
+
const history = await client.getAiAssistantMemoryBankHistory();
|
|
396
|
+
await client.acceptAiMemoryBankSuggestion("conversation_id", { ... });
|
|
397
|
+
|
|
398
|
+
// Feedback
|
|
399
|
+
await client.submitAiFeedback({ ... });
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Pagination helper
|
|
403
|
+
|
|
404
|
+
Automatically iterate through all pages:
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
for await (const source of client.paginate(
|
|
408
|
+
(opts) => client.listSources(opts),
|
|
409
|
+
{ limit: 50 },
|
|
410
|
+
)) {
|
|
411
|
+
console.log(source.name);
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Error handling
|
|
416
|
+
|
|
417
|
+
All errors extend `SeclaiError`:
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
import {
|
|
421
|
+
SeclaiError,
|
|
422
|
+
SeclaiConfigurationError,
|
|
423
|
+
SeclaiAPIStatusError,
|
|
424
|
+
SeclaiAPIValidationError,
|
|
425
|
+
SeclaiStreamingError,
|
|
426
|
+
} from "@seclai/sdk";
|
|
427
|
+
|
|
428
|
+
try {
|
|
429
|
+
await client.getAgent("bad_id");
|
|
430
|
+
} catch (err) {
|
|
431
|
+
if (err instanceof SeclaiAPIValidationError) {
|
|
432
|
+
console.error("Validation:", err.validationError);
|
|
433
|
+
} else if (err instanceof SeclaiAPIStatusError) {
|
|
434
|
+
console.error(`HTTP ${err.statusCode}:`, err.responseText);
|
|
435
|
+
} else if (err instanceof SeclaiStreamingError) {
|
|
436
|
+
console.error("Stream failed for run:", err.runId);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Cancellation (AbortSignal)
|
|
442
|
+
|
|
443
|
+
All low-level methods support an `AbortSignal` for request cancellation:
|
|
444
|
+
|
|
445
|
+
```ts
|
|
446
|
+
const controller = new AbortController();
|
|
447
|
+
|
|
448
|
+
// Cancel after 5 seconds
|
|
449
|
+
setTimeout(() => controller.abort(), 5_000);
|
|
450
|
+
|
|
451
|
+
const data = await client.request("GET", "/agents", {
|
|
452
|
+
signal: controller.signal,
|
|
453
|
+
});
|
|
141
454
|
```
|
|
142
455
|
|
|
456
|
+
## Low-level access
|
|
457
|
+
|
|
458
|
+
For endpoints not yet covered by a convenience method, use `request` or `requestRaw`:
|
|
459
|
+
|
|
460
|
+
```ts
|
|
461
|
+
// JSON request/response
|
|
462
|
+
const data = await client.request("POST", "/custom/endpoint", {
|
|
463
|
+
json: { key: "value" },
|
|
464
|
+
query: { filter: "active" },
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// Raw Response (e.g. binary downloads)
|
|
468
|
+
const response = await client.requestRaw("GET", "/files/download/123");
|
|
469
|
+
const blob = await response.blob();
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Development
|
|
473
|
+
|
|
143
474
|
### Install dependencies
|
|
144
475
|
|
|
145
476
|
```bash
|
|
@@ -160,6 +491,12 @@ npm run build
|
|
|
160
491
|
|
|
161
492
|
This also regenerates `src/openapi.ts` from `openapi/seclai.openapi.json`.
|
|
162
493
|
|
|
494
|
+
### Run tests
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
npm test
|
|
498
|
+
```
|
|
499
|
+
|
|
163
500
|
### Generate docs
|
|
164
501
|
|
|
165
502
|
Generate HTML docs into `build/docs/`:
|