@naturali/sdk 0.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 +90 -0
- package/dist/index.cjs +1796 -0
- package/dist/index.d.cts +5706 -0
- package/dist/index.d.mts +5706 -0
- package/dist/index.mjs +1780 -0
- package/package.json +49 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1796 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/generated/core/bodySerializer.gen.ts
|
|
3
|
+
const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/generated/core/serverSentEvents.gen.ts
|
|
6
|
+
function createSseClient({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) {
|
|
7
|
+
let lastEventId;
|
|
8
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
9
|
+
const createStream = async function* () {
|
|
10
|
+
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
11
|
+
let attempt = 0;
|
|
12
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
13
|
+
while (true) {
|
|
14
|
+
if (signal.aborted) break;
|
|
15
|
+
attempt++;
|
|
16
|
+
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
17
|
+
if (lastEventId !== void 0) headers.set("Last-Event-ID", lastEventId);
|
|
18
|
+
try {
|
|
19
|
+
const requestInit = {
|
|
20
|
+
redirect: "follow",
|
|
21
|
+
...options,
|
|
22
|
+
body: options.serializedBody,
|
|
23
|
+
headers,
|
|
24
|
+
signal
|
|
25
|
+
};
|
|
26
|
+
let request = new Request(url, requestInit);
|
|
27
|
+
if (onRequest) request = await onRequest(url, requestInit);
|
|
28
|
+
const response = await (options.fetch ?? globalThis.fetch)(request);
|
|
29
|
+
if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
|
|
30
|
+
if (!response.body) throw new Error("No body in SSE response");
|
|
31
|
+
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
32
|
+
let buffer = "";
|
|
33
|
+
const abortHandler = () => {
|
|
34
|
+
try {
|
|
35
|
+
reader.cancel();
|
|
36
|
+
} catch {}
|
|
37
|
+
};
|
|
38
|
+
signal.addEventListener("abort", abortHandler);
|
|
39
|
+
try {
|
|
40
|
+
while (true) {
|
|
41
|
+
const { done, value } = await reader.read();
|
|
42
|
+
if (done) break;
|
|
43
|
+
buffer += value;
|
|
44
|
+
buffer = buffer.replace(/\r\n?/g, "\n");
|
|
45
|
+
const chunks = buffer.split("\n\n");
|
|
46
|
+
buffer = chunks.pop() ?? "";
|
|
47
|
+
for (const chunk of chunks) {
|
|
48
|
+
const lines = chunk.split("\n");
|
|
49
|
+
const dataLines = [];
|
|
50
|
+
let eventName;
|
|
51
|
+
for (const line of lines) if (line.startsWith("data:")) dataLines.push(line.replace(/^data:\s*/, ""));
|
|
52
|
+
else if (line.startsWith("event:")) eventName = line.replace(/^event:\s*/, "");
|
|
53
|
+
else if (line.startsWith("id:")) lastEventId = line.replace(/^id:\s*/, "");
|
|
54
|
+
else if (line.startsWith("retry:")) {
|
|
55
|
+
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
|
|
56
|
+
if (!Number.isNaN(parsed)) retryDelay = parsed;
|
|
57
|
+
}
|
|
58
|
+
let data;
|
|
59
|
+
let parsedJson = false;
|
|
60
|
+
if (dataLines.length) {
|
|
61
|
+
const rawData = dataLines.join("\n");
|
|
62
|
+
try {
|
|
63
|
+
data = JSON.parse(rawData);
|
|
64
|
+
parsedJson = true;
|
|
65
|
+
} catch {
|
|
66
|
+
data = rawData;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (parsedJson) {
|
|
70
|
+
if (responseValidator) await responseValidator(data);
|
|
71
|
+
if (responseTransformer) data = await responseTransformer(data);
|
|
72
|
+
}
|
|
73
|
+
onSseEvent?.({
|
|
74
|
+
data,
|
|
75
|
+
event: eventName,
|
|
76
|
+
id: lastEventId,
|
|
77
|
+
retry: retryDelay
|
|
78
|
+
});
|
|
79
|
+
if (dataLines.length) yield data;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} finally {
|
|
83
|
+
signal.removeEventListener("abort", abortHandler);
|
|
84
|
+
reader.releaseLock();
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
onSseError?.(error);
|
|
89
|
+
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) break;
|
|
90
|
+
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
|
|
91
|
+
await sleep(backoff);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return { stream: createStream() };
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/generated/core/pathSerializer.gen.ts
|
|
99
|
+
const separatorArrayExplode = (style) => {
|
|
100
|
+
switch (style) {
|
|
101
|
+
case "label": return ".";
|
|
102
|
+
case "matrix": return ";";
|
|
103
|
+
case "simple": return ",";
|
|
104
|
+
default: return "&";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const separatorArrayNoExplode = (style) => {
|
|
108
|
+
switch (style) {
|
|
109
|
+
case "form": return ",";
|
|
110
|
+
case "pipeDelimited": return "|";
|
|
111
|
+
case "spaceDelimited": return "%20";
|
|
112
|
+
default: return ",";
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const separatorObjectExplode = (style) => {
|
|
116
|
+
switch (style) {
|
|
117
|
+
case "label": return ".";
|
|
118
|
+
case "matrix": return ";";
|
|
119
|
+
case "simple": return ",";
|
|
120
|
+
default: return "&";
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const serializeArrayParam = ({ allowReserved, explode, name, style, value }) => {
|
|
124
|
+
if (!explode) {
|
|
125
|
+
const joinedValues = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
126
|
+
switch (style) {
|
|
127
|
+
case "label": return `.${joinedValues}`;
|
|
128
|
+
case "matrix": return `;${name}=${joinedValues}`;
|
|
129
|
+
case "simple": return joinedValues;
|
|
130
|
+
default: return `${name}=${joinedValues}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const separator = separatorArrayExplode(style);
|
|
134
|
+
const joinedValues = value.map((v) => {
|
|
135
|
+
if (style === "label" || style === "simple") return allowReserved ? v : encodeURIComponent(v);
|
|
136
|
+
return serializePrimitiveParam({
|
|
137
|
+
allowReserved,
|
|
138
|
+
name,
|
|
139
|
+
value: v
|
|
140
|
+
});
|
|
141
|
+
}).join(separator);
|
|
142
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
143
|
+
};
|
|
144
|
+
const serializePrimitiveParam = ({ allowReserved, name, value }) => {
|
|
145
|
+
if (value === void 0 || value === null) return "";
|
|
146
|
+
if (typeof value === "object") throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");
|
|
147
|
+
return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
148
|
+
};
|
|
149
|
+
const serializeObjectParam = ({ allowReserved, explode, name, style, value, valueOnly }) => {
|
|
150
|
+
if (value instanceof Date) return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
|
|
151
|
+
if (style !== "deepObject" && !explode) {
|
|
152
|
+
let values = [];
|
|
153
|
+
Object.entries(value).forEach(([key, v]) => {
|
|
154
|
+
values = [
|
|
155
|
+
...values,
|
|
156
|
+
key,
|
|
157
|
+
allowReserved ? v : encodeURIComponent(v)
|
|
158
|
+
];
|
|
159
|
+
});
|
|
160
|
+
const joinedValues = values.join(",");
|
|
161
|
+
switch (style) {
|
|
162
|
+
case "form": return `${name}=${joinedValues}`;
|
|
163
|
+
case "label": return `.${joinedValues}`;
|
|
164
|
+
case "matrix": return `;${name}=${joinedValues}`;
|
|
165
|
+
default: return joinedValues;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const separator = separatorObjectExplode(style);
|
|
169
|
+
const joinedValues = Object.entries(value).map(([key, v]) => serializePrimitiveParam({
|
|
170
|
+
allowReserved,
|
|
171
|
+
name: style === "deepObject" ? `${name}[${key}]` : key,
|
|
172
|
+
value: v
|
|
173
|
+
})).join(separator);
|
|
174
|
+
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
175
|
+
};
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/generated/core/utils.gen.ts
|
|
178
|
+
const PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
179
|
+
const defaultPathSerializer = ({ path, url: _url }) => {
|
|
180
|
+
let url = _url;
|
|
181
|
+
const matches = _url.match(PATH_PARAM_RE);
|
|
182
|
+
if (matches) for (const match of matches) {
|
|
183
|
+
let explode = false;
|
|
184
|
+
let name = match.substring(1, match.length - 1);
|
|
185
|
+
let style = "simple";
|
|
186
|
+
if (name.endsWith("*")) {
|
|
187
|
+
explode = true;
|
|
188
|
+
name = name.substring(0, name.length - 1);
|
|
189
|
+
}
|
|
190
|
+
if (name.startsWith(".")) {
|
|
191
|
+
name = name.substring(1);
|
|
192
|
+
style = "label";
|
|
193
|
+
} else if (name.startsWith(";")) {
|
|
194
|
+
name = name.substring(1);
|
|
195
|
+
style = "matrix";
|
|
196
|
+
}
|
|
197
|
+
const value = path[name];
|
|
198
|
+
if (value === void 0 || value === null) continue;
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
url = url.replace(match, serializeArrayParam({
|
|
201
|
+
explode,
|
|
202
|
+
name,
|
|
203
|
+
style,
|
|
204
|
+
value
|
|
205
|
+
}));
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (typeof value === "object") {
|
|
209
|
+
url = url.replace(match, serializeObjectParam({
|
|
210
|
+
explode,
|
|
211
|
+
name,
|
|
212
|
+
style,
|
|
213
|
+
value,
|
|
214
|
+
valueOnly: true
|
|
215
|
+
}));
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (style === "matrix") {
|
|
219
|
+
url = url.replace(match, `;${serializePrimitiveParam({
|
|
220
|
+
name,
|
|
221
|
+
value
|
|
222
|
+
})}`);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const replaceValue = encodeURIComponent(style === "label" ? `.${value}` : value);
|
|
226
|
+
url = url.replace(match, replaceValue);
|
|
227
|
+
}
|
|
228
|
+
return url;
|
|
229
|
+
};
|
|
230
|
+
const getUrl = ({ baseUrl, path, query, querySerializer, url: _url }) => {
|
|
231
|
+
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
232
|
+
let url = (baseUrl ?? "") + pathUrl;
|
|
233
|
+
if (path) url = defaultPathSerializer({
|
|
234
|
+
path,
|
|
235
|
+
url
|
|
236
|
+
});
|
|
237
|
+
let search = query ? querySerializer(query) : "";
|
|
238
|
+
if (search.startsWith("?")) search = search.substring(1);
|
|
239
|
+
if (search) url += `?${search}`;
|
|
240
|
+
return url;
|
|
241
|
+
};
|
|
242
|
+
function getValidRequestBody(options) {
|
|
243
|
+
const hasBody = options.body !== void 0;
|
|
244
|
+
if (hasBody && options.bodySerializer) {
|
|
245
|
+
if ("serializedBody" in options) return options.serializedBody !== void 0 && options.serializedBody !== "" ? options.serializedBody : null;
|
|
246
|
+
return options.body !== "" ? options.body : null;
|
|
247
|
+
}
|
|
248
|
+
if (hasBody) return options.body;
|
|
249
|
+
}
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/generated/core/auth.gen.ts
|
|
252
|
+
const getAuthToken = async (auth, callback) => {
|
|
253
|
+
const token = typeof callback === "function" ? await callback(auth) : callback;
|
|
254
|
+
if (!token) return;
|
|
255
|
+
if (auth.scheme === "bearer") return `Bearer ${token}`;
|
|
256
|
+
if (auth.scheme === "basic") return `Basic ${btoa(token)}`;
|
|
257
|
+
return token;
|
|
258
|
+
};
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/generated/client/utils.gen.ts
|
|
261
|
+
const createQuerySerializer = ({ parameters = {}, ...args } = {}) => {
|
|
262
|
+
const querySerializer = (queryParams) => {
|
|
263
|
+
const search = [];
|
|
264
|
+
if (queryParams && typeof queryParams === "object") for (const name in queryParams) {
|
|
265
|
+
const value = queryParams[name];
|
|
266
|
+
if (value === void 0 || value === null) continue;
|
|
267
|
+
const options = parameters[name] || args;
|
|
268
|
+
if (Array.isArray(value)) {
|
|
269
|
+
const serializedArray = serializeArrayParam({
|
|
270
|
+
allowReserved: options.allowReserved,
|
|
271
|
+
explode: true,
|
|
272
|
+
name,
|
|
273
|
+
style: "form",
|
|
274
|
+
value,
|
|
275
|
+
...options.array
|
|
276
|
+
});
|
|
277
|
+
if (serializedArray) search.push(serializedArray);
|
|
278
|
+
} else if (typeof value === "object") {
|
|
279
|
+
const serializedObject = serializeObjectParam({
|
|
280
|
+
allowReserved: options.allowReserved,
|
|
281
|
+
explode: true,
|
|
282
|
+
name,
|
|
283
|
+
style: "deepObject",
|
|
284
|
+
value,
|
|
285
|
+
...options.object
|
|
286
|
+
});
|
|
287
|
+
if (serializedObject) search.push(serializedObject);
|
|
288
|
+
} else {
|
|
289
|
+
const serializedPrimitive = serializePrimitiveParam({
|
|
290
|
+
allowReserved: options.allowReserved,
|
|
291
|
+
name,
|
|
292
|
+
value
|
|
293
|
+
});
|
|
294
|
+
if (serializedPrimitive) search.push(serializedPrimitive);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return search.join("&");
|
|
298
|
+
};
|
|
299
|
+
return querySerializer;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Infers parseAs value from provided Content-Type header.
|
|
303
|
+
*/
|
|
304
|
+
const getParseAs = (contentType) => {
|
|
305
|
+
if (!contentType) return "stream";
|
|
306
|
+
const cleanContent = contentType.split(";")[0]?.trim();
|
|
307
|
+
if (!cleanContent) return;
|
|
308
|
+
if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) return "json";
|
|
309
|
+
if (cleanContent === "multipart/form-data") return "formData";
|
|
310
|
+
if ([
|
|
311
|
+
"application/",
|
|
312
|
+
"audio/",
|
|
313
|
+
"image/",
|
|
314
|
+
"video/"
|
|
315
|
+
].some((type) => cleanContent.startsWith(type))) return "blob";
|
|
316
|
+
if (cleanContent.startsWith("text/")) return "text";
|
|
317
|
+
};
|
|
318
|
+
const checkForExistence = (options, name) => {
|
|
319
|
+
if (!name) return false;
|
|
320
|
+
if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) return true;
|
|
321
|
+
return false;
|
|
322
|
+
};
|
|
323
|
+
async function setAuthParams(options) {
|
|
324
|
+
for (const auth of options.security ?? []) {
|
|
325
|
+
if (checkForExistence(options, auth.name)) continue;
|
|
326
|
+
const token = await getAuthToken(auth, options.auth);
|
|
327
|
+
if (!token) continue;
|
|
328
|
+
const name = auth.name ?? "Authorization";
|
|
329
|
+
switch (auth.in) {
|
|
330
|
+
case "query":
|
|
331
|
+
if (!options.query) options.query = {};
|
|
332
|
+
options.query[name] = token;
|
|
333
|
+
break;
|
|
334
|
+
case "cookie":
|
|
335
|
+
options.headers.append("Cookie", `${name}=${token}`);
|
|
336
|
+
break;
|
|
337
|
+
default:
|
|
338
|
+
options.headers.set(name, token);
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
const buildUrl = (options) => getUrl({
|
|
344
|
+
baseUrl: options.baseUrl,
|
|
345
|
+
path: options.path,
|
|
346
|
+
query: options.query,
|
|
347
|
+
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
|
|
348
|
+
url: options.url
|
|
349
|
+
});
|
|
350
|
+
const mergeConfigs = (a, b) => {
|
|
351
|
+
const config = {
|
|
352
|
+
...a,
|
|
353
|
+
...b
|
|
354
|
+
};
|
|
355
|
+
if (config.baseUrl?.endsWith("/")) config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
356
|
+
config.headers = mergeHeaders(a.headers, b.headers);
|
|
357
|
+
return config;
|
|
358
|
+
};
|
|
359
|
+
const headersEntries = (headers) => {
|
|
360
|
+
const entries = [];
|
|
361
|
+
headers.forEach((value, key) => {
|
|
362
|
+
entries.push([key, value]);
|
|
363
|
+
});
|
|
364
|
+
return entries;
|
|
365
|
+
};
|
|
366
|
+
const mergeHeaders = (...headers) => {
|
|
367
|
+
const mergedHeaders = new Headers();
|
|
368
|
+
for (const header of headers) {
|
|
369
|
+
if (!header) continue;
|
|
370
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
371
|
+
for (const [key, value] of iterator) if (value === null) mergedHeaders.delete(key);
|
|
372
|
+
else if (Array.isArray(value)) for (const v of value) mergedHeaders.append(key, v);
|
|
373
|
+
else if (value !== void 0) mergedHeaders.set(key, typeof value === "object" ? JSON.stringify(value) : value);
|
|
374
|
+
}
|
|
375
|
+
return mergedHeaders;
|
|
376
|
+
};
|
|
377
|
+
var Interceptors = class {
|
|
378
|
+
fns = [];
|
|
379
|
+
clear() {
|
|
380
|
+
this.fns = [];
|
|
381
|
+
}
|
|
382
|
+
eject(id) {
|
|
383
|
+
const index = this.getInterceptorIndex(id);
|
|
384
|
+
if (this.fns[index]) this.fns[index] = null;
|
|
385
|
+
}
|
|
386
|
+
exists(id) {
|
|
387
|
+
const index = this.getInterceptorIndex(id);
|
|
388
|
+
return Boolean(this.fns[index]);
|
|
389
|
+
}
|
|
390
|
+
getInterceptorIndex(id) {
|
|
391
|
+
if (typeof id === "number") return this.fns[id] ? id : -1;
|
|
392
|
+
return this.fns.indexOf(id);
|
|
393
|
+
}
|
|
394
|
+
update(id, fn) {
|
|
395
|
+
const index = this.getInterceptorIndex(id);
|
|
396
|
+
if (this.fns[index]) {
|
|
397
|
+
this.fns[index] = fn;
|
|
398
|
+
return id;
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
use(fn) {
|
|
403
|
+
this.fns.push(fn);
|
|
404
|
+
return this.fns.length - 1;
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const createInterceptors = () => ({
|
|
408
|
+
error: new Interceptors(),
|
|
409
|
+
request: new Interceptors(),
|
|
410
|
+
response: new Interceptors()
|
|
411
|
+
});
|
|
412
|
+
const defaultQuerySerializer = createQuerySerializer({
|
|
413
|
+
allowReserved: false,
|
|
414
|
+
array: {
|
|
415
|
+
explode: true,
|
|
416
|
+
style: "form"
|
|
417
|
+
},
|
|
418
|
+
object: {
|
|
419
|
+
explode: true,
|
|
420
|
+
style: "deepObject"
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
const defaultHeaders = { "Content-Type": "application/json" };
|
|
424
|
+
const createConfig = (override = {}) => ({
|
|
425
|
+
...jsonBodySerializer,
|
|
426
|
+
headers: defaultHeaders,
|
|
427
|
+
parseAs: "auto",
|
|
428
|
+
querySerializer: defaultQuerySerializer,
|
|
429
|
+
...override
|
|
430
|
+
});
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/generated/client/client.gen.ts
|
|
433
|
+
const createClient = (config = {}) => {
|
|
434
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
435
|
+
const getConfig = () => ({ ..._config });
|
|
436
|
+
const setConfig = (config) => {
|
|
437
|
+
_config = mergeConfigs(_config, config);
|
|
438
|
+
return getConfig();
|
|
439
|
+
};
|
|
440
|
+
const interceptors = createInterceptors();
|
|
441
|
+
const beforeRequest = async (options) => {
|
|
442
|
+
const opts = {
|
|
443
|
+
..._config,
|
|
444
|
+
...options,
|
|
445
|
+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
446
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
447
|
+
serializedBody: void 0
|
|
448
|
+
};
|
|
449
|
+
if (opts.security) await setAuthParams(opts);
|
|
450
|
+
if (opts.requestValidator) await opts.requestValidator(opts);
|
|
451
|
+
if (opts.body !== void 0 && opts.bodySerializer) opts.serializedBody = opts.bodySerializer(opts.body);
|
|
452
|
+
if (opts.body === void 0 || opts.serializedBody === "") opts.headers.delete("Content-Type");
|
|
453
|
+
const resolvedOpts = opts;
|
|
454
|
+
return {
|
|
455
|
+
opts: resolvedOpts,
|
|
456
|
+
url: buildUrl(resolvedOpts)
|
|
457
|
+
};
|
|
458
|
+
};
|
|
459
|
+
const request = async (options) => {
|
|
460
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
461
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
462
|
+
let request;
|
|
463
|
+
let response;
|
|
464
|
+
try {
|
|
465
|
+
const { opts, url } = await beforeRequest(options);
|
|
466
|
+
const requestInit = {
|
|
467
|
+
redirect: "follow",
|
|
468
|
+
...opts,
|
|
469
|
+
body: getValidRequestBody(opts)
|
|
470
|
+
};
|
|
471
|
+
request = new Request(url, requestInit);
|
|
472
|
+
for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
|
|
473
|
+
const _fetch = opts.fetch;
|
|
474
|
+
response = await _fetch(request);
|
|
475
|
+
for (const fn of interceptors.response.fns) if (fn) response = await fn(response, request, opts);
|
|
476
|
+
const result = {
|
|
477
|
+
request,
|
|
478
|
+
response
|
|
479
|
+
};
|
|
480
|
+
if (response.ok) {
|
|
481
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
482
|
+
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
483
|
+
let emptyData;
|
|
484
|
+
switch (parseAs) {
|
|
485
|
+
case "arrayBuffer":
|
|
486
|
+
case "blob":
|
|
487
|
+
case "text":
|
|
488
|
+
emptyData = await response[parseAs]();
|
|
489
|
+
break;
|
|
490
|
+
case "formData":
|
|
491
|
+
emptyData = new FormData();
|
|
492
|
+
break;
|
|
493
|
+
case "stream":
|
|
494
|
+
emptyData = response.body;
|
|
495
|
+
break;
|
|
496
|
+
default:
|
|
497
|
+
emptyData = {};
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
return opts.responseStyle === "data" ? emptyData : {
|
|
501
|
+
data: emptyData,
|
|
502
|
+
...result
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
let data;
|
|
506
|
+
switch (parseAs) {
|
|
507
|
+
case "arrayBuffer":
|
|
508
|
+
case "blob":
|
|
509
|
+
case "formData":
|
|
510
|
+
case "text":
|
|
511
|
+
data = await response[parseAs]();
|
|
512
|
+
break;
|
|
513
|
+
case "json": {
|
|
514
|
+
const text = await response.text();
|
|
515
|
+
data = text ? JSON.parse(text) : {};
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
case "stream": return opts.responseStyle === "data" ? response.body : {
|
|
519
|
+
data: response.body,
|
|
520
|
+
...result
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (parseAs === "json") {
|
|
524
|
+
if (opts.responseValidator) await opts.responseValidator(data);
|
|
525
|
+
if (opts.responseTransformer) data = await opts.responseTransformer(data);
|
|
526
|
+
}
|
|
527
|
+
return opts.responseStyle === "data" ? data : {
|
|
528
|
+
data,
|
|
529
|
+
...result
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const textError = await response.text();
|
|
533
|
+
let jsonError;
|
|
534
|
+
try {
|
|
535
|
+
jsonError = JSON.parse(textError);
|
|
536
|
+
} catch {}
|
|
537
|
+
throw jsonError ?? textError;
|
|
538
|
+
} catch (error) {
|
|
539
|
+
let finalError = error;
|
|
540
|
+
for (const fn of interceptors.error.fns) if (fn) finalError = await fn(finalError, response, request, options);
|
|
541
|
+
finalError = finalError || {};
|
|
542
|
+
if (throwOnError) throw finalError;
|
|
543
|
+
return responseStyle === "data" ? void 0 : {
|
|
544
|
+
error: finalError,
|
|
545
|
+
request,
|
|
546
|
+
response
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
const makeMethodFn = (method) => (options) => request({
|
|
551
|
+
...options,
|
|
552
|
+
method
|
|
553
|
+
});
|
|
554
|
+
const makeSseFn = (method) => async (options) => {
|
|
555
|
+
const { opts, url } = await beforeRequest(options);
|
|
556
|
+
return createSseClient({
|
|
557
|
+
...opts,
|
|
558
|
+
body: opts.body,
|
|
559
|
+
method,
|
|
560
|
+
onRequest: async (url, init) => {
|
|
561
|
+
let request = new Request(url, init);
|
|
562
|
+
for (const fn of interceptors.request.fns) if (fn) request = await fn(request, opts);
|
|
563
|
+
return request;
|
|
564
|
+
},
|
|
565
|
+
serializedBody: getValidRequestBody(opts),
|
|
566
|
+
url
|
|
567
|
+
});
|
|
568
|
+
};
|
|
569
|
+
const _buildUrl = (options) => buildUrl({
|
|
570
|
+
..._config,
|
|
571
|
+
...options
|
|
572
|
+
});
|
|
573
|
+
return {
|
|
574
|
+
buildUrl: _buildUrl,
|
|
575
|
+
connect: makeMethodFn("CONNECT"),
|
|
576
|
+
delete: makeMethodFn("DELETE"),
|
|
577
|
+
get: makeMethodFn("GET"),
|
|
578
|
+
getConfig,
|
|
579
|
+
head: makeMethodFn("HEAD"),
|
|
580
|
+
interceptors,
|
|
581
|
+
options: makeMethodFn("OPTIONS"),
|
|
582
|
+
patch: makeMethodFn("PATCH"),
|
|
583
|
+
post: makeMethodFn("POST"),
|
|
584
|
+
put: makeMethodFn("PUT"),
|
|
585
|
+
request,
|
|
586
|
+
setConfig,
|
|
587
|
+
sse: {
|
|
588
|
+
connect: makeSseFn("CONNECT"),
|
|
589
|
+
delete: makeSseFn("DELETE"),
|
|
590
|
+
get: makeSseFn("GET"),
|
|
591
|
+
head: makeSseFn("HEAD"),
|
|
592
|
+
options: makeSseFn("OPTIONS"),
|
|
593
|
+
patch: makeSseFn("PATCH"),
|
|
594
|
+
post: makeSseFn("POST"),
|
|
595
|
+
put: makeSseFn("PUT"),
|
|
596
|
+
trace: makeSseFn("TRACE")
|
|
597
|
+
},
|
|
598
|
+
trace: makeMethodFn("TRACE")
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
//#endregion
|
|
602
|
+
//#region src/generated/client.gen.ts
|
|
603
|
+
const client = createClient(createConfig());
|
|
604
|
+
//#endregion
|
|
605
|
+
//#region src/generated/sdk.gen.ts
|
|
606
|
+
var Agents = class {
|
|
607
|
+
/**
|
|
608
|
+
* List agents
|
|
609
|
+
*
|
|
610
|
+
* Lists the agents in the project.
|
|
611
|
+
*/
|
|
612
|
+
static listAgents(options) {
|
|
613
|
+
return (options.client ?? client).get({
|
|
614
|
+
url: "/v1/projects/{project_id}/agents",
|
|
615
|
+
...options
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Create an agent
|
|
620
|
+
*
|
|
621
|
+
* Create an agent bound to one of the project's providers (provider_id), optionally attaching tools (tool_ids). See AgentCreate for the runtime config fields.
|
|
622
|
+
*
|
|
623
|
+
*/
|
|
624
|
+
static createAgent(options) {
|
|
625
|
+
return (options.client ?? client).post({
|
|
626
|
+
url: "/v1/projects/{project_id}/agents",
|
|
627
|
+
...options,
|
|
628
|
+
headers: {
|
|
629
|
+
"Content-Type": "application/json",
|
|
630
|
+
...options.headers
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Delete an agent
|
|
636
|
+
*
|
|
637
|
+
* Deletes the backing SOAT agent. Returns 409 if the agent still has dependent generations or traces — pass `force=true` to delete those along with the agent (destructive and irreversible).
|
|
638
|
+
*
|
|
639
|
+
*/
|
|
640
|
+
static deleteAgent(options) {
|
|
641
|
+
return (options.client ?? client).delete({
|
|
642
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}",
|
|
643
|
+
...options
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Get an agent
|
|
648
|
+
*/
|
|
649
|
+
static getAgent(options) {
|
|
650
|
+
return (options.client ?? client).get({
|
|
651
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}",
|
|
652
|
+
...options
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Update an agent
|
|
657
|
+
*
|
|
658
|
+
* Change the bound provider, name, model, instructions, sampling/step config, attached tools (tool_ids/tool_choice), or the naturali-side status. At least one field is required.
|
|
659
|
+
*
|
|
660
|
+
*/
|
|
661
|
+
static updateAgent(options) {
|
|
662
|
+
return (options.client ?? client).patch({
|
|
663
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}",
|
|
664
|
+
...options,
|
|
665
|
+
headers: {
|
|
666
|
+
"Content-Type": "application/json",
|
|
667
|
+
...options.headers
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
var ApiKeys = class {
|
|
673
|
+
/**
|
|
674
|
+
* List API keys
|
|
675
|
+
*
|
|
676
|
+
* Lists API keys accessible to the caller. A project-scoped credential sees only keys in its project; an account-scoped credential sees all keys in the account. Raw secrets are never returned.
|
|
677
|
+
*
|
|
678
|
+
*/
|
|
679
|
+
static listApiKeys(options) {
|
|
680
|
+
return (options?.client ?? client).get({
|
|
681
|
+
url: "/v1/api-keys",
|
|
682
|
+
...options
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Create an API key
|
|
687
|
+
*
|
|
688
|
+
* Creates an API key. When `project_id` is set the key is scoped to that project (the default and recommended stance); omit it for an account-scoped key. `capabilities` narrows what the key may do; when omitted the key inherits the creator's capabilities. The raw `key` (nat_sk_…) is returned only in this response.
|
|
689
|
+
*
|
|
690
|
+
*/
|
|
691
|
+
static createApiKey(options) {
|
|
692
|
+
return (options.client ?? client).post({
|
|
693
|
+
url: "/v1/api-keys",
|
|
694
|
+
...options,
|
|
695
|
+
headers: {
|
|
696
|
+
"Content-Type": "application/json",
|
|
697
|
+
...options.headers
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Revoke an API key
|
|
703
|
+
*
|
|
704
|
+
* Revokes an API key immediately. Subsequent use returns 401.
|
|
705
|
+
*/
|
|
706
|
+
static deleteApiKey(options) {
|
|
707
|
+
return (options.client ?? client).delete({
|
|
708
|
+
url: "/v1/api-keys/{api_key_id}",
|
|
709
|
+
...options
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Get an API key
|
|
714
|
+
*
|
|
715
|
+
* Returns metadata for an API key. The raw secret is never returned after creation.
|
|
716
|
+
*/
|
|
717
|
+
static getApiKey(options) {
|
|
718
|
+
return (options.client ?? client).get({
|
|
719
|
+
url: "/v1/api-keys/{api_key_id}",
|
|
720
|
+
...options
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Update an API key
|
|
725
|
+
*
|
|
726
|
+
* Rename an API key or replace its capability set. The scope (project vs account) is immutable.
|
|
727
|
+
*/
|
|
728
|
+
static updateApiKey(options) {
|
|
729
|
+
return (options.client ?? client).patch({
|
|
730
|
+
url: "/v1/api-keys/{api_key_id}",
|
|
731
|
+
...options,
|
|
732
|
+
headers: {
|
|
733
|
+
"Content-Type": "application/json",
|
|
734
|
+
...options.headers
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Rotate an API key
|
|
740
|
+
*
|
|
741
|
+
* Issues a new secret for the same key record (same id, scope and capabilities) and invalidates the previous secret. The new raw `key` is returned only in this response.
|
|
742
|
+
*
|
|
743
|
+
*/
|
|
744
|
+
static rotateApiKey(options) {
|
|
745
|
+
return (options.client ?? client).post({
|
|
746
|
+
url: "/v1/api-keys/{api_key_id}:rotate",
|
|
747
|
+
...options
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
var Auth = class {
|
|
752
|
+
/**
|
|
753
|
+
* Create an account
|
|
754
|
+
*
|
|
755
|
+
* Creates a user and opens a session. A verification email is sent separately; unverified accounts may be limited until verified.
|
|
756
|
+
*
|
|
757
|
+
*/
|
|
758
|
+
static signup(options) {
|
|
759
|
+
return (options.client ?? client).post({
|
|
760
|
+
url: "/v1/auth/signup",
|
|
761
|
+
...options,
|
|
762
|
+
headers: {
|
|
763
|
+
"Content-Type": "application/json",
|
|
764
|
+
...options.headers
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Log in
|
|
770
|
+
*
|
|
771
|
+
* Exchanges email + password for an access JWT and a refresh token.
|
|
772
|
+
*/
|
|
773
|
+
static login(options) {
|
|
774
|
+
return (options.client ?? client).post({
|
|
775
|
+
url: "/v1/auth/login",
|
|
776
|
+
...options,
|
|
777
|
+
headers: {
|
|
778
|
+
"Content-Type": "application/json",
|
|
779
|
+
...options.headers
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Refresh a session
|
|
785
|
+
*
|
|
786
|
+
* Exchanges a valid refresh token for a new access JWT and a rotated refresh token. Refresh tokens are single-use; presenting a previously-rotated token is treated as reuse and revokes the whole session family (createRefreshRotation reuse detection).
|
|
787
|
+
*
|
|
788
|
+
*/
|
|
789
|
+
static refreshSession(options) {
|
|
790
|
+
return (options.client ?? client).post({
|
|
791
|
+
url: "/v1/auth/refresh",
|
|
792
|
+
...options,
|
|
793
|
+
headers: {
|
|
794
|
+
"Content-Type": "application/json",
|
|
795
|
+
...options.headers
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Log out
|
|
801
|
+
*
|
|
802
|
+
* Revokes the current refresh token (and its rotation family). Pass `all: true` to revoke every active session for the user.
|
|
803
|
+
*
|
|
804
|
+
*/
|
|
805
|
+
static logout(options) {
|
|
806
|
+
return (options?.client ?? client).post({
|
|
807
|
+
url: "/v1/auth/logout",
|
|
808
|
+
...options,
|
|
809
|
+
headers: {
|
|
810
|
+
"Content-Type": "application/json",
|
|
811
|
+
...options?.headers
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Request a password reset
|
|
817
|
+
*
|
|
818
|
+
* Sends a password-reset email if the address has an account. Always responds 202 so account existence is never leaked.
|
|
819
|
+
*
|
|
820
|
+
*/
|
|
821
|
+
static requestPasswordReset(options) {
|
|
822
|
+
return (options.client ?? client).post({
|
|
823
|
+
url: "/v1/auth/password/reset-request",
|
|
824
|
+
...options,
|
|
825
|
+
headers: {
|
|
826
|
+
"Content-Type": "application/json",
|
|
827
|
+
...options.headers
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Complete a password reset
|
|
833
|
+
*
|
|
834
|
+
* Sets a new password using a valid one-time reset token, then revokes existing sessions.
|
|
835
|
+
*/
|
|
836
|
+
static confirmPasswordReset(options) {
|
|
837
|
+
return (options.client ?? client).post({
|
|
838
|
+
url: "/v1/auth/password/reset",
|
|
839
|
+
...options,
|
|
840
|
+
headers: {
|
|
841
|
+
"Content-Type": "application/json",
|
|
842
|
+
...options.headers
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Verify an email address
|
|
848
|
+
*
|
|
849
|
+
* Confirms an email address using a one-time verification token.
|
|
850
|
+
*/
|
|
851
|
+
static verifyEmail(options) {
|
|
852
|
+
return (options.client ?? client).post({
|
|
853
|
+
url: "/v1/auth/verify-email",
|
|
854
|
+
...options,
|
|
855
|
+
headers: {
|
|
856
|
+
"Content-Type": "application/json",
|
|
857
|
+
...options.headers
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Get the current identity
|
|
863
|
+
*
|
|
864
|
+
* Returns the user behind the presented access token.
|
|
865
|
+
*/
|
|
866
|
+
static getCurrentUser(options) {
|
|
867
|
+
return (options?.client ?? client).get({
|
|
868
|
+
url: "/v1/auth/me",
|
|
869
|
+
...options
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
var Channels = class {
|
|
874
|
+
/**
|
|
875
|
+
* List channels
|
|
876
|
+
*
|
|
877
|
+
* Lists the channels connected in the project.
|
|
878
|
+
*/
|
|
879
|
+
static listChannels(options) {
|
|
880
|
+
return (options.client ?? client).get({
|
|
881
|
+
url: "/v1/projects/{project_id}/channels",
|
|
882
|
+
...options
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Connect a channel
|
|
887
|
+
*
|
|
888
|
+
* Connect a channel. The required fields depend on `channel`; no credential is ever returned.
|
|
889
|
+
* **Discord** (`channel: discord`) — supply `application_id` and `bot_token`, plus the `modes` selecting which Gateway flows to serve (direct messages, and/or @mention-opens-a-thread). Returns `501` when the deployment has no `CHANNEL_TOKEN_KEY` configured.
|
|
890
|
+
* **WhatsApp** (default) — one of two credential paths, both filling the same write-only secret:
|
|
891
|
+
* * **BYOT** (`credential_source: byot`, default) — supply
|
|
892
|
+
* `phone_number_id` and `access_token` from your own Meta app.
|
|
893
|
+
*
|
|
894
|
+
* * **Embedded signup** (`credential_source: embedded_signup`) — supply
|
|
895
|
+
* `code` and `waba_id` (and optionally `pin`) from the Meta popup;
|
|
896
|
+
* naturali exchanges the `code` for the token and subscribes its app to
|
|
897
|
+
* the WABA, so the customer never hands over a token. Returns `501` on
|
|
898
|
+
* deployments where Meta App credentials are not configured.
|
|
899
|
+
*
|
|
900
|
+
*/
|
|
901
|
+
static createChannel(options) {
|
|
902
|
+
return (options.client ?? client).post({
|
|
903
|
+
url: "/v1/projects/{project_id}/channels",
|
|
904
|
+
...options,
|
|
905
|
+
headers: {
|
|
906
|
+
"Content-Type": "application/json",
|
|
907
|
+
...options.headers
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Delete a channel
|
|
913
|
+
*
|
|
914
|
+
* Deletes the channel and whatever it provisioned — the WhatsApp send tool and write-only credential secret, or the Discord channel's sealed bot token (dropped with the row, closing its gateway connection).
|
|
915
|
+
*
|
|
916
|
+
*/
|
|
917
|
+
static deleteChannel(options) {
|
|
918
|
+
return (options.client ?? client).delete({
|
|
919
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}",
|
|
920
|
+
...options
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Get a channel
|
|
925
|
+
*/
|
|
926
|
+
static getChannel(options) {
|
|
927
|
+
return (options.client ?? client).get({
|
|
928
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}",
|
|
929
|
+
...options
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Update a channel
|
|
934
|
+
*
|
|
935
|
+
* Rotate the credential, update the kind's config (`waba_id` / `credential_source` for WhatsApp, `modes` for Discord), or flip the naturali-side status. At least one field is required. Rotating a WhatsApp token stores a new write-only secret, repoints the send tool and deletes the old secret; rotating a Discord bot token reseals it and the gateway worker reconnects with it.
|
|
936
|
+
*
|
|
937
|
+
*/
|
|
938
|
+
static updateChannel(options) {
|
|
939
|
+
return (options.client ?? client).patch({
|
|
940
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}",
|
|
941
|
+
...options,
|
|
942
|
+
headers: {
|
|
943
|
+
"Content-Type": "application/json",
|
|
944
|
+
...options.headers
|
|
945
|
+
}
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Unbind the channel
|
|
950
|
+
*/
|
|
951
|
+
static deleteChannelBinding(options) {
|
|
952
|
+
return (options.client ?? client).delete({
|
|
953
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/binding",
|
|
954
|
+
...options
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Get the channel's binding
|
|
959
|
+
*/
|
|
960
|
+
static getChannelBinding(options) {
|
|
961
|
+
return (options.client ?? client).get({
|
|
962
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/binding",
|
|
963
|
+
...options
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Set the channel's binding
|
|
968
|
+
*
|
|
969
|
+
* Create or replace the channel's agent binding (a channel has one binding in v1). `agent_id` is required and must be an agent owned in the project; `language` / `config` / `status` default to null / null / active when absent (full replace).
|
|
970
|
+
*
|
|
971
|
+
*/
|
|
972
|
+
static setChannelBinding(options) {
|
|
973
|
+
return (options.client ?? client).put({
|
|
974
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/binding",
|
|
975
|
+
...options,
|
|
976
|
+
headers: {
|
|
977
|
+
"Content-Type": "application/json",
|
|
978
|
+
...options.headers
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* List the channel's conversations
|
|
984
|
+
*
|
|
985
|
+
* A cursor page of the channel's conversations, newest first. A conversation is one contact's dialogue on the channel — the continuity anchor that resumes the same SOAT session instead of starting fresh per message — so this is the read path for who has talked to the channel and which actor/session their dialogue resolved to.
|
|
986
|
+
* Conversations are created by the inbound path (the WhatsApp webhook, the Discord gateway worker) when a real message arrives; there is no way to create one directly.
|
|
987
|
+
*
|
|
988
|
+
*/
|
|
989
|
+
static listChannelConversations(options) {
|
|
990
|
+
return (options.client ?? client).get({
|
|
991
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/conversations",
|
|
992
|
+
...options
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Get a conversation
|
|
997
|
+
*/
|
|
998
|
+
static getChannelConversation(options) {
|
|
999
|
+
return (options.client ?? client).get({
|
|
1000
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/conversations/{conversation_id}",
|
|
1001
|
+
...options
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Read a conversation's transcript
|
|
1006
|
+
*
|
|
1007
|
+
* The conversation's messages, oldest first. naturali stores no message bodies — the dialogue lives in the SOAT session the conversation maps to, so this reads through to SOAT. Pagination is `limit`/`offset` rather than an opaque cursor because the upstream is offset-based over a stable `position` ordering.
|
|
1008
|
+
*
|
|
1009
|
+
*/
|
|
1010
|
+
static listChannelConversationMessages(options) {
|
|
1011
|
+
return (options.client ?? client).get({
|
|
1012
|
+
url: "/v1/projects/{project_id}/channels/{channel_id}/conversations/{conversation_id}/messages",
|
|
1013
|
+
...options
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
var Contacts = class {
|
|
1018
|
+
/**
|
|
1019
|
+
* List contacts
|
|
1020
|
+
*
|
|
1021
|
+
* A cursor page of the project's contacts, newest first.
|
|
1022
|
+
* `channel` + `identifier` (supplied together) is the identity lookup — "who is this phone number?" — and returns at most one contact, following the merge pointer to whoever holds the identifier today. `external_id` asks the same question from the customer's side of the mapping. Contacts merged away are omitted unless `include_merged` asks for them.
|
|
1023
|
+
*
|
|
1024
|
+
*/
|
|
1025
|
+
static listContacts(options) {
|
|
1026
|
+
return (options.client ?? client).get({
|
|
1027
|
+
url: "/v1/projects/{project_id}/contacts",
|
|
1028
|
+
...options
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Create a contact
|
|
1033
|
+
*
|
|
1034
|
+
* Record a contact the customer already knows about, optionally with the identifiers it is expected to arrive at.
|
|
1035
|
+
* Optional by design — the inbound path creates contacts on its own. This is for the embedder who has a user in their own system and wants naturali to agree about who that is before the first message, which is what makes `external_id` (and, through it, a session's `tool_context`) useful. No SOAT actor is created here; the contact gets one on first need.
|
|
1036
|
+
*
|
|
1037
|
+
*/
|
|
1038
|
+
static createContact(options) {
|
|
1039
|
+
return (options.client ?? client).post({
|
|
1040
|
+
url: "/v1/projects/{project_id}/contacts",
|
|
1041
|
+
...options,
|
|
1042
|
+
headers: {
|
|
1043
|
+
"Content-Type": "application/json",
|
|
1044
|
+
...options.headers
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Erase a contact
|
|
1050
|
+
*
|
|
1051
|
+
* **Erasure (C4/LGPD).** Not a soft delete and not reversible: the contact's sessions — with their messages and media — its SOAT actor, its memory container and every identifier it was reachable at are removed, along with the merge records that reference it.
|
|
1052
|
+
* The upstream deletes happen first, so a failure there aborts before the local pointers are dropped and a retry can still find what is left. A contact that was merged into another cannot be erased directly: its data lives with the survivor, so erase that one.
|
|
1053
|
+
*
|
|
1054
|
+
*/
|
|
1055
|
+
static deleteContact(options) {
|
|
1056
|
+
return (options.client ?? client).delete({
|
|
1057
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}",
|
|
1058
|
+
...options
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Get a contact
|
|
1063
|
+
*/
|
|
1064
|
+
static getContact(options) {
|
|
1065
|
+
return (options.client ?? client).get({
|
|
1066
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}",
|
|
1067
|
+
...options
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Update a contact
|
|
1072
|
+
*
|
|
1073
|
+
* Retune the customer-owned fields. At least one is required. Identities are attached and detached through their own sub-resource, because each one is a claim about reachability rather than a property of the record.
|
|
1074
|
+
*
|
|
1075
|
+
*/
|
|
1076
|
+
static updateContact(options) {
|
|
1077
|
+
return (options.client ?? client).patch({
|
|
1078
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}",
|
|
1079
|
+
...options,
|
|
1080
|
+
headers: {
|
|
1081
|
+
"Content-Type": "application/json",
|
|
1082
|
+
...options.headers
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Attach an identity
|
|
1088
|
+
*
|
|
1089
|
+
* Attach a `(channel, identifier)` pair — the manual half of what the inbound path does automatically, and the way a customer tells naturali that a number it has never seen belongs to a user it already knows. The identifier must be free (C3).
|
|
1090
|
+
*
|
|
1091
|
+
*/
|
|
1092
|
+
static createContactIdentity(options) {
|
|
1093
|
+
return (options.client ?? client).post({
|
|
1094
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}/identities",
|
|
1095
|
+
...options,
|
|
1096
|
+
headers: {
|
|
1097
|
+
"Content-Type": "application/json",
|
|
1098
|
+
...options.headers
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Detach an identity
|
|
1104
|
+
*
|
|
1105
|
+
* Detach an identifier attached in error. Refused with `identity_in_use` once a dialogue hangs off it: dropping an identifier with history is erasure wearing a smaller name, and erasure has its own route that actually removes the messages instead of orphaning them.
|
|
1106
|
+
*
|
|
1107
|
+
*/
|
|
1108
|
+
static deleteContactIdentity(options) {
|
|
1109
|
+
return (options.client ?? client).delete({
|
|
1110
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}/identities/{identity_id}",
|
|
1111
|
+
...options
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* List the contact's conversations
|
|
1116
|
+
*
|
|
1117
|
+
* Every dialogue the contact has, across channels, newest first. The channel-scoped list answers "who has talked to this number?"; this one answers "where has this human talked to us?" — the read that makes a merge visible, since both channels' rows then appear under one contact.
|
|
1118
|
+
*
|
|
1119
|
+
*/
|
|
1120
|
+
static listContactConversations(options) {
|
|
1121
|
+
return (options.client ?? client).get({
|
|
1122
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}/conversations",
|
|
1123
|
+
...options
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Merge another contact into this one
|
|
1128
|
+
*
|
|
1129
|
+
* Fold `source_contact_id` into this contact — "same human, two identifiers" (C4).
|
|
1130
|
+
* What moves: every identity and every conversation, so the survivor's history is the union of both. What is *shared* rather than moved: agent memory — SOAT hangs it off the actor, so the source's actor is re-pointed at the survivor's memory container and both keep answering with one recollection. Existing sessions keep working, which is the point of not rewriting them.
|
|
1131
|
+
* The source is not deleted: it stays as a tombstone pointing at the survivor, and the returned merge record lists exactly what moved, so the merge can be audited and reverted.
|
|
1132
|
+
*
|
|
1133
|
+
*/
|
|
1134
|
+
static mergeContact(options) {
|
|
1135
|
+
return (options.client ?? client).post({
|
|
1136
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}:merge",
|
|
1137
|
+
...options,
|
|
1138
|
+
headers: {
|
|
1139
|
+
"Content-Type": "application/json",
|
|
1140
|
+
...options.headers
|
|
1141
|
+
}
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* List the contact's merges
|
|
1146
|
+
*
|
|
1147
|
+
* The contact's merge history, newest first, from both sides: the merges it absorbed and the one that absorbed it. The audit half of C4.
|
|
1148
|
+
*
|
|
1149
|
+
*/
|
|
1150
|
+
static listContactMerges(options) {
|
|
1151
|
+
return (options.client ?? client).get({
|
|
1152
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}/merges",
|
|
1153
|
+
...options
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Revert a merge
|
|
1158
|
+
*
|
|
1159
|
+
* Undo a merge (C4). Replays the record backwards: the identities and conversations it lists go back to the source, the source's actor is re-pointed at the memory it had before, and the tombstone becomes a contact again. Anything that arrived *after* the merge stays with the survivor — it was never the source's.
|
|
1160
|
+
* Only the merge still in force can be reverted; a source that has since been merged somewhere else has to be unwound from the top (`merge_superseded`).
|
|
1161
|
+
*
|
|
1162
|
+
*/
|
|
1163
|
+
static revertContactMerge(options) {
|
|
1164
|
+
return (options.client ?? client).post({
|
|
1165
|
+
url: "/v1/projects/{project_id}/contacts/{contact_id}/merges/{merge_id}:revert",
|
|
1166
|
+
...options
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
};
|
|
1170
|
+
var Generations = class {
|
|
1171
|
+
/**
|
|
1172
|
+
* List an agent's generations
|
|
1173
|
+
*
|
|
1174
|
+
* Lists the generation records the agent has produced, newest first. Filter by lifecycle `status` to find the failures without paging everything the agent has ever run.
|
|
1175
|
+
*
|
|
1176
|
+
*/
|
|
1177
|
+
static listAgentGenerations(options) {
|
|
1178
|
+
return (options.client ?? client).get({
|
|
1179
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/generations",
|
|
1180
|
+
...options
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Run an agent generation
|
|
1185
|
+
*
|
|
1186
|
+
* Sends messages to the agent, resolves its tools, and runs the model loop. Returns the final text when `status` is `completed` (plus `object` when the agent has an output schema), or the pending `tool_calls` when `status` is `requires_action`. With `stream: true` the response is a Server-Sent Events stream (Content-Type text/event-stream) proxied from SOAT instead of a single JSON body.
|
|
1187
|
+
*
|
|
1188
|
+
*/
|
|
1189
|
+
static createGeneration(options) {
|
|
1190
|
+
return (options.client ?? client).post({
|
|
1191
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/generations",
|
|
1192
|
+
...options,
|
|
1193
|
+
headers: {
|
|
1194
|
+
"Content-Type": "application/json",
|
|
1195
|
+
...options.headers
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Get a generation
|
|
1201
|
+
*
|
|
1202
|
+
* Returns one generation record. Flat rather than nested under the agent, because the ids that need resolving arrive on their own — a session reply carries a `generation_id` with no agent in hand.
|
|
1203
|
+
* A generation belonging to another project responds `404`, not `403` — the API never confirms that an id exists elsewhere.
|
|
1204
|
+
*
|
|
1205
|
+
*/
|
|
1206
|
+
static getGeneration(options) {
|
|
1207
|
+
return (options.client ?? client).get({
|
|
1208
|
+
url: "/v1/projects/{project_id}/generations/{generation_id}",
|
|
1209
|
+
...options
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
var Knowledge = class {
|
|
1214
|
+
/**
|
|
1215
|
+
* List collections
|
|
1216
|
+
*
|
|
1217
|
+
* Lists the knowledge collections in the project.
|
|
1218
|
+
*/
|
|
1219
|
+
static listKnowledgeCollections(options) {
|
|
1220
|
+
return (options.client ?? client).get({
|
|
1221
|
+
url: "/v1/projects/{project_id}/knowledge/collections",
|
|
1222
|
+
...options
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
/**
|
|
1226
|
+
* Create a collection
|
|
1227
|
+
*
|
|
1228
|
+
* Create a knowledge collection. The name is the key manifests reference (an agent's `knowledge:` block) and must be unique within the project.
|
|
1229
|
+
*
|
|
1230
|
+
*/
|
|
1231
|
+
static createKnowledgeCollection(options) {
|
|
1232
|
+
return (options.client ?? client).post({
|
|
1233
|
+
url: "/v1/projects/{project_id}/knowledge/collections",
|
|
1234
|
+
...options,
|
|
1235
|
+
headers: {
|
|
1236
|
+
"Content-Type": "application/json",
|
|
1237
|
+
...options.headers
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Delete a collection
|
|
1243
|
+
*
|
|
1244
|
+
* Deletes an empty collection. Returns 409 if the collection still has documents (delete them first).
|
|
1245
|
+
*
|
|
1246
|
+
*/
|
|
1247
|
+
static deleteKnowledgeCollection(options) {
|
|
1248
|
+
return (options.client ?? client).delete({
|
|
1249
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1250
|
+
...options
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Get a collection
|
|
1255
|
+
*/
|
|
1256
|
+
static getKnowledgeCollection(options) {
|
|
1257
|
+
return (options.client ?? client).get({
|
|
1258
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1259
|
+
...options
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Update a collection
|
|
1264
|
+
*
|
|
1265
|
+
* Rename the collection or edit its description. At least one field is required.
|
|
1266
|
+
*/
|
|
1267
|
+
static updateKnowledgeCollection(options) {
|
|
1268
|
+
return (options.client ?? client).patch({
|
|
1269
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1270
|
+
...options,
|
|
1271
|
+
headers: {
|
|
1272
|
+
"Content-Type": "application/json",
|
|
1273
|
+
...options.headers
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Query a collection (retrieval preview)
|
|
1279
|
+
*
|
|
1280
|
+
* Retrieval preview (API.md §4, K5): returns the chunks the collection would surface for a question — debuggable standalone, before any agent is bound to it. This is the `…:query` action; the path segment is `{collection_id}:query`.
|
|
1281
|
+
*
|
|
1282
|
+
*/
|
|
1283
|
+
static queryKnowledgeCollection(options) {
|
|
1284
|
+
return (options.client ?? client).post({
|
|
1285
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1286
|
+
...options,
|
|
1287
|
+
headers: {
|
|
1288
|
+
"Content-Type": "application/json",
|
|
1289
|
+
...options.headers
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* List documents
|
|
1295
|
+
*
|
|
1296
|
+
* Lists the documents in the collection, with their ingestion status.
|
|
1297
|
+
*/
|
|
1298
|
+
static listKnowledgeDocuments(options) {
|
|
1299
|
+
return (options.client ?? client).get({
|
|
1300
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents",
|
|
1301
|
+
...options
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Create a document
|
|
1306
|
+
*
|
|
1307
|
+
* Add an inline-text document to the collection. The platform ingests the content (chunk + embed) and records the document's ingestion status. File upload (PDF/binary) is a deliberate follow-up.
|
|
1308
|
+
*
|
|
1309
|
+
*/
|
|
1310
|
+
static createKnowledgeDocument(options) {
|
|
1311
|
+
return (options.client ?? client).post({
|
|
1312
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents",
|
|
1313
|
+
...options,
|
|
1314
|
+
headers: {
|
|
1315
|
+
"Content-Type": "application/json",
|
|
1316
|
+
...options.headers
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* Delete a document
|
|
1322
|
+
*/
|
|
1323
|
+
static deleteKnowledgeDocument(options) {
|
|
1324
|
+
return (options.client ?? client).delete({
|
|
1325
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}",
|
|
1326
|
+
...options
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Get a document
|
|
1331
|
+
*
|
|
1332
|
+
* Returns the document, including its text content when ingestion is complete.
|
|
1333
|
+
*/
|
|
1334
|
+
static getKnowledgeDocument(options) {
|
|
1335
|
+
return (options.client ?? client).get({
|
|
1336
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}",
|
|
1337
|
+
...options
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Re-ingest a document
|
|
1342
|
+
*
|
|
1343
|
+
* Re-run ingestion for a document against its stored source, resetting it to `pending` before re-processing — the recovery path for a `failed` ingest (API.md §4, K1). This is the `…:reingest` action; the path segment is `{document_id}:reingest`.
|
|
1344
|
+
*
|
|
1345
|
+
*/
|
|
1346
|
+
static reingestKnowledgeDocument(options) {
|
|
1347
|
+
return (options.client ?? client).post({
|
|
1348
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}",
|
|
1349
|
+
...options
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
var Models = class {
|
|
1354
|
+
/**
|
|
1355
|
+
* List models
|
|
1356
|
+
*
|
|
1357
|
+
* Lists catalog models, newest sources merged and sorted by id. Filter by vendor, provider, output/input modality or status.
|
|
1358
|
+
*
|
|
1359
|
+
*/
|
|
1360
|
+
static listModels(options) {
|
|
1361
|
+
return (options?.client ?? client).get({
|
|
1362
|
+
url: "/v1/models",
|
|
1363
|
+
...options
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Get a model
|
|
1368
|
+
*/
|
|
1369
|
+
static getModel(options) {
|
|
1370
|
+
return (options.client ?? client).get({
|
|
1371
|
+
url: "/v1/models/{model_id}",
|
|
1372
|
+
...options
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
var Projects = class {
|
|
1377
|
+
/**
|
|
1378
|
+
* List projects
|
|
1379
|
+
*
|
|
1380
|
+
* Lists projects accessible to the caller.
|
|
1381
|
+
*/
|
|
1382
|
+
static listProjects(options) {
|
|
1383
|
+
return (options?.client ?? client).get({
|
|
1384
|
+
url: "/v1/projects",
|
|
1385
|
+
...options
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Create a project
|
|
1390
|
+
*
|
|
1391
|
+
* Creates a project (one per client or per environment).
|
|
1392
|
+
*/
|
|
1393
|
+
static createProject(options) {
|
|
1394
|
+
return (options.client ?? client).post({
|
|
1395
|
+
url: "/v1/projects",
|
|
1396
|
+
...options,
|
|
1397
|
+
headers: {
|
|
1398
|
+
"Content-Type": "application/json",
|
|
1399
|
+
...options.headers
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Delete a project
|
|
1405
|
+
*
|
|
1406
|
+
* Permanently deletes the project and its backing SOAT project. Fails with 409 if the SOAT project still has dependent resources — remove them first, or pass `force=true` to delete the project and all its dependents (agents, providers, tools, sessions, generations, traces). Forcing is destructive and irreversible.
|
|
1407
|
+
*
|
|
1408
|
+
*/
|
|
1409
|
+
static deleteProject(options) {
|
|
1410
|
+
return (options.client ?? client).delete({
|
|
1411
|
+
url: "/v1/projects/{project_id}",
|
|
1412
|
+
...options
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Get a project
|
|
1417
|
+
*/
|
|
1418
|
+
static getProject(options) {
|
|
1419
|
+
return (options.client ?? client).get({
|
|
1420
|
+
url: "/v1/projects/{project_id}",
|
|
1421
|
+
...options
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Update a project
|
|
1426
|
+
*
|
|
1427
|
+
* Rename or archive a project. Archiving is reversible; resources are retained.
|
|
1428
|
+
*/
|
|
1429
|
+
static updateProject(options) {
|
|
1430
|
+
return (options.client ?? client).patch({
|
|
1431
|
+
url: "/v1/projects/{project_id}",
|
|
1432
|
+
...options,
|
|
1433
|
+
headers: {
|
|
1434
|
+
"Content-Type": "application/json",
|
|
1435
|
+
...options.headers
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Get per-project usage
|
|
1441
|
+
*
|
|
1442
|
+
* The per-project meter — the re-billing view (A11/C12/P3). Aggregates the project's usage over an optional [from, to] window, bucketed by a single dimension. Costs are the billing-grade cost_usd SOAT freezes at write time; null means nothing in the bucket was priced (never that it was free). Only managed providers are priced (on SOAT), so cost reflects managed usage; BYOK usage carries no LLM cost.
|
|
1443
|
+
*
|
|
1444
|
+
*/
|
|
1445
|
+
static getProjectUsage(options) {
|
|
1446
|
+
return (options.client ?? client).get({
|
|
1447
|
+
url: "/v1/projects/{project_id}/usage",
|
|
1448
|
+
...options
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
};
|
|
1452
|
+
var Providers = class {
|
|
1453
|
+
/**
|
|
1454
|
+
* List providers
|
|
1455
|
+
*
|
|
1456
|
+
* Lists the AI providers registered in the project.
|
|
1457
|
+
*/
|
|
1458
|
+
static listProviders(options) {
|
|
1459
|
+
return (options.client ?? client).get({
|
|
1460
|
+
url: "/v1/projects/{project_id}/providers",
|
|
1461
|
+
...options
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Register a provider (managed or BYOK)
|
|
1466
|
+
*
|
|
1467
|
+
* Register a managed provider (naturali-keyed, priced on SOAT) or a BYOK provider (your credentials, stored write-only and never priced). See ProviderCreate for the fields each mode takes.
|
|
1468
|
+
*
|
|
1469
|
+
*/
|
|
1470
|
+
static createProvider(options) {
|
|
1471
|
+
return (options.client ?? client).post({
|
|
1472
|
+
url: "/v1/projects/{project_id}/providers",
|
|
1473
|
+
...options,
|
|
1474
|
+
headers: {
|
|
1475
|
+
"Content-Type": "application/json",
|
|
1476
|
+
...options.headers
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Delete a provider
|
|
1482
|
+
*
|
|
1483
|
+
* Deletes the backing SOAT ai_provider and its secret. Returns 409 if the provider is still referenced by live resources (agents) — detach those first. `force=true` clears only soft dependents (price overrides, usage history); live references always block deletion.
|
|
1484
|
+
*
|
|
1485
|
+
*/
|
|
1486
|
+
static deleteProvider(options) {
|
|
1487
|
+
return (options.client ?? client).delete({
|
|
1488
|
+
url: "/v1/projects/{project_id}/providers/{provider_id}",
|
|
1489
|
+
...options
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Get a provider
|
|
1494
|
+
*/
|
|
1495
|
+
static getProvider(options) {
|
|
1496
|
+
return (options.client ?? client).get({
|
|
1497
|
+
url: "/v1/projects/{project_id}/providers/{provider_id}",
|
|
1498
|
+
...options
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Update a provider
|
|
1503
|
+
*
|
|
1504
|
+
* Change the model, name or base URL, rotate the credentials (api_key), or set the naturali-side status. At least one field is required.
|
|
1505
|
+
*
|
|
1506
|
+
*/
|
|
1507
|
+
static updateProvider(options) {
|
|
1508
|
+
return (options.client ?? client).patch({
|
|
1509
|
+
url: "/v1/projects/{project_id}/providers/{provider_id}",
|
|
1510
|
+
...options,
|
|
1511
|
+
headers: {
|
|
1512
|
+
"Content-Type": "application/json",
|
|
1513
|
+
...options.headers
|
|
1514
|
+
}
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
var Sessions = class {
|
|
1519
|
+
/**
|
|
1520
|
+
* Open a session
|
|
1521
|
+
*
|
|
1522
|
+
* Opens a durable session against the agent. The session accumulates messages and is resumable by id; its lifecycle (open / closed / expired) and configuration live in the backing SOAT session.
|
|
1523
|
+
*
|
|
1524
|
+
*/
|
|
1525
|
+
static createSession(options) {
|
|
1526
|
+
return (options.client ?? client).post({
|
|
1527
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/sessions",
|
|
1528
|
+
...options,
|
|
1529
|
+
headers: {
|
|
1530
|
+
"Content-Type": "application/json",
|
|
1531
|
+
...options.headers
|
|
1532
|
+
}
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Get a session
|
|
1537
|
+
*
|
|
1538
|
+
* Returns the session's current state — status, activity timestamps and configuration — read live from the backing SOAT session, so a resumed session reflects everything that has happened since it was opened.
|
|
1539
|
+
*
|
|
1540
|
+
*/
|
|
1541
|
+
static getSession(options) {
|
|
1542
|
+
return (options.client ?? client).get({
|
|
1543
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/sessions/{session_id}",
|
|
1544
|
+
...options
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Add a message
|
|
1549
|
+
*
|
|
1550
|
+
* Appends a user message to the session — plain `message` text or a `document_id`, exactly one of the two. `idempotency_key` makes the append safe to retry: a repeat with the same key returns the original message (HTTP 200) and triggers no new work. When the session has `auto_generate` on, the response is the agent's reply (a Generation shape) instead of the saved message.
|
|
1551
|
+
*
|
|
1552
|
+
*/
|
|
1553
|
+
static addSessionMessage(options) {
|
|
1554
|
+
return (options.client ?? client).post({
|
|
1555
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/sessions/{session_id}/messages",
|
|
1556
|
+
...options,
|
|
1557
|
+
headers: {
|
|
1558
|
+
"Content-Type": "application/json",
|
|
1559
|
+
...options.headers
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Generate a response
|
|
1565
|
+
*
|
|
1566
|
+
* Runs the agent over the session's accumulated messages and returns its reply. `status` is `completed` with the assistant `message`, or `requires_action` with the pending `required_action` tool calls. `model` overrides the agent's default model for this turn only.
|
|
1567
|
+
*
|
|
1568
|
+
*/
|
|
1569
|
+
static generateSessionResponse(options) {
|
|
1570
|
+
return (options.client ?? client).post({
|
|
1571
|
+
url: "/v1/projects/{project_id}/agents/{agent_id}/sessions/{session_id}/generate",
|
|
1572
|
+
...options,
|
|
1573
|
+
headers: {
|
|
1574
|
+
"Content-Type": "application/json",
|
|
1575
|
+
...options.headers
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
var Tools = class {
|
|
1581
|
+
/**
|
|
1582
|
+
* List tools
|
|
1583
|
+
*
|
|
1584
|
+
* Lists the tools registered in the project.
|
|
1585
|
+
*/
|
|
1586
|
+
static listTools(options) {
|
|
1587
|
+
return (options.client ?? client).get({
|
|
1588
|
+
url: "/v1/projects/{project_id}/tools",
|
|
1589
|
+
...options
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Create a tool
|
|
1594
|
+
*
|
|
1595
|
+
* Create an http or mcp tool in the project. See ToolCreate for the fields each type takes. Any auth headers are stored write-only and never returned.
|
|
1596
|
+
*
|
|
1597
|
+
*/
|
|
1598
|
+
static createTool(options) {
|
|
1599
|
+
return (options.client ?? client).post({
|
|
1600
|
+
url: "/v1/projects/{project_id}/tools",
|
|
1601
|
+
...options,
|
|
1602
|
+
headers: {
|
|
1603
|
+
"Content-Type": "application/json",
|
|
1604
|
+
...options.headers
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Delete a tool
|
|
1610
|
+
*
|
|
1611
|
+
* Deletes the backing SOAT tool. Returns 409 if the tool is still attached to an agent (detach it first).
|
|
1612
|
+
*
|
|
1613
|
+
*/
|
|
1614
|
+
static deleteTool(options) {
|
|
1615
|
+
return (options.client ?? client).delete({
|
|
1616
|
+
url: "/v1/projects/{project_id}/tools/{tool_id}",
|
|
1617
|
+
...options
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Get a tool
|
|
1622
|
+
*/
|
|
1623
|
+
static getTool(options) {
|
|
1624
|
+
return (options.client ?? client).get({
|
|
1625
|
+
url: "/v1/projects/{project_id}/tools/{tool_id}",
|
|
1626
|
+
...options
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Update a tool
|
|
1631
|
+
*
|
|
1632
|
+
* Change the name, description, parameters, type-specific config (incl. rotating auth headers), or the naturali-side status. The tool `type` is immutable. At least one field is required.
|
|
1633
|
+
*
|
|
1634
|
+
*/
|
|
1635
|
+
static updateTool(options) {
|
|
1636
|
+
return (options.client ?? client).patch({
|
|
1637
|
+
url: "/v1/projects/{project_id}/tools/{tool_id}",
|
|
1638
|
+
...options,
|
|
1639
|
+
headers: {
|
|
1640
|
+
"Content-Type": "application/json",
|
|
1641
|
+
...options.headers
|
|
1642
|
+
}
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
var Traces = class {
|
|
1647
|
+
/**
|
|
1648
|
+
* List traces
|
|
1649
|
+
*
|
|
1650
|
+
* Lists the project's execution traces, newest first.
|
|
1651
|
+
*/
|
|
1652
|
+
static listTraces(options) {
|
|
1653
|
+
return (options.client ?? client).get({
|
|
1654
|
+
url: "/v1/projects/{project_id}/traces",
|
|
1655
|
+
...options
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* Get a trace
|
|
1660
|
+
*
|
|
1661
|
+
* Returns one trace. A trace belonging to another project responds `404`, not `403` — the API never confirms that an id exists elsewhere.
|
|
1662
|
+
*
|
|
1663
|
+
*/
|
|
1664
|
+
static getTrace(options) {
|
|
1665
|
+
return (options.client ?? client).get({
|
|
1666
|
+
url: "/v1/projects/{project_id}/traces/{trace_id}",
|
|
1667
|
+
...options
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Get a trace tree
|
|
1672
|
+
*
|
|
1673
|
+
* Returns the whole execution tree. Each node is one agent's execution; `children` are the traces its sub-agent tool calls started.
|
|
1674
|
+
* Asking for a child returns the tree from its root, so the response is the full execution either way — pass `include=generations` and one call is enough to render a finished run.
|
|
1675
|
+
*
|
|
1676
|
+
*/
|
|
1677
|
+
static getTraceTree(options) {
|
|
1678
|
+
return (options.client ?? client).get({
|
|
1679
|
+
url: "/v1/projects/{project_id}/traces/{trace_id}/tree",
|
|
1680
|
+
...options
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* List a trace's generations
|
|
1685
|
+
*
|
|
1686
|
+
* Lists the generations recorded under this trace — the model loops the execution ran, including sub-agent generations linked by `initiator_generation_id`.
|
|
1687
|
+
*
|
|
1688
|
+
*/
|
|
1689
|
+
static listTraceGenerations(options) {
|
|
1690
|
+
return (options.client ?? client).get({
|
|
1691
|
+
url: "/v1/projects/{project_id}/traces/{trace_id}/generations",
|
|
1692
|
+
...options
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
1696
|
+
//#endregion
|
|
1697
|
+
//#region src/naturaliClient.ts
|
|
1698
|
+
/**
|
|
1699
|
+
* Wraps a generated static SDK class so every method is callable without
|
|
1700
|
+
* passing `client` — the configured client is injected into each call.
|
|
1701
|
+
*
|
|
1702
|
+
* The return type stays `T` (= `typeof <StaticClass>`), so callers keep full
|
|
1703
|
+
* auto-complete and type checking on arguments and results.
|
|
1704
|
+
*/
|
|
1705
|
+
const bindResource = (SdkClass, client) => {
|
|
1706
|
+
return new Proxy(SdkClass, { get: (target, prop) => {
|
|
1707
|
+
const value = target[prop];
|
|
1708
|
+
if (typeof value === "function") return (options) => {
|
|
1709
|
+
return value({
|
|
1710
|
+
...options,
|
|
1711
|
+
client
|
|
1712
|
+
});
|
|
1713
|
+
};
|
|
1714
|
+
return value;
|
|
1715
|
+
} });
|
|
1716
|
+
};
|
|
1717
|
+
/**
|
|
1718
|
+
* The naturali.ai API client.
|
|
1719
|
+
*
|
|
1720
|
+
* Create one and reuse it; each property is a resource whose methods mirror
|
|
1721
|
+
* the generated SDK exactly, with the configured HTTP client already bound.
|
|
1722
|
+
*
|
|
1723
|
+
* ```ts
|
|
1724
|
+
* import { NaturaliClient } from '@naturali/sdk';
|
|
1725
|
+
*
|
|
1726
|
+
* const naturali = new NaturaliClient({
|
|
1727
|
+
* baseUrl: 'https://api.naturali.ai',
|
|
1728
|
+
* token: process.env.NATURALI_TOKEN,
|
|
1729
|
+
* });
|
|
1730
|
+
*
|
|
1731
|
+
* const { data, error } = await naturali.sessions.addSessionMessage({
|
|
1732
|
+
* path: { project_id: PROJECT_ID, agent_id: AGENT_ID, session_id: SESSION_ID },
|
|
1733
|
+
* body: { role: 'user', content: 'What is the capital of France?' },
|
|
1734
|
+
* });
|
|
1735
|
+
* ```
|
|
1736
|
+
*
|
|
1737
|
+
* Every method resolves to `{ data, error }` rather than throwing on a non-2xx
|
|
1738
|
+
* response, so the platform's error envelope (`{ error: { code, message } }`)
|
|
1739
|
+
* is available as typed data.
|
|
1740
|
+
*/
|
|
1741
|
+
var NaturaliClient = class {
|
|
1742
|
+
agents;
|
|
1743
|
+
apiKeys;
|
|
1744
|
+
auth;
|
|
1745
|
+
channels;
|
|
1746
|
+
contacts;
|
|
1747
|
+
generations;
|
|
1748
|
+
knowledge;
|
|
1749
|
+
models;
|
|
1750
|
+
projects;
|
|
1751
|
+
providers;
|
|
1752
|
+
sessions;
|
|
1753
|
+
tools;
|
|
1754
|
+
traces;
|
|
1755
|
+
/** The underlying HTTP client, for interceptors or one-off requests. */
|
|
1756
|
+
http;
|
|
1757
|
+
constructor({ baseUrl, token, headers } = {}) {
|
|
1758
|
+
this.http = createClient(createConfig({
|
|
1759
|
+
baseUrl: baseUrl ?? "",
|
|
1760
|
+
headers: {
|
|
1761
|
+
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
1762
|
+
...headers
|
|
1763
|
+
}
|
|
1764
|
+
}));
|
|
1765
|
+
this.agents = bindResource(Agents, this.http);
|
|
1766
|
+
this.apiKeys = bindResource(ApiKeys, this.http);
|
|
1767
|
+
this.auth = bindResource(Auth, this.http);
|
|
1768
|
+
this.channels = bindResource(Channels, this.http);
|
|
1769
|
+
this.contacts = bindResource(Contacts, this.http);
|
|
1770
|
+
this.generations = bindResource(Generations, this.http);
|
|
1771
|
+
this.knowledge = bindResource(Knowledge, this.http);
|
|
1772
|
+
this.models = bindResource(Models, this.http);
|
|
1773
|
+
this.projects = bindResource(Projects, this.http);
|
|
1774
|
+
this.providers = bindResource(Providers, this.http);
|
|
1775
|
+
this.sessions = bindResource(Sessions, this.http);
|
|
1776
|
+
this.tools = bindResource(Tools, this.http);
|
|
1777
|
+
this.traces = bindResource(Traces, this.http);
|
|
1778
|
+
}
|
|
1779
|
+
};
|
|
1780
|
+
//#endregion
|
|
1781
|
+
exports.Agents = Agents;
|
|
1782
|
+
exports.ApiKeys = ApiKeys;
|
|
1783
|
+
exports.Auth = Auth;
|
|
1784
|
+
exports.Channels = Channels;
|
|
1785
|
+
exports.Contacts = Contacts;
|
|
1786
|
+
exports.Generations = Generations;
|
|
1787
|
+
exports.Knowledge = Knowledge;
|
|
1788
|
+
exports.Models = Models;
|
|
1789
|
+
exports.NaturaliClient = NaturaliClient;
|
|
1790
|
+
exports.Projects = Projects;
|
|
1791
|
+
exports.Providers = Providers;
|
|
1792
|
+
exports.Sessions = Sessions;
|
|
1793
|
+
exports.Tools = Tools;
|
|
1794
|
+
exports.Traces = Traces;
|
|
1795
|
+
exports.createClient = createClient;
|
|
1796
|
+
exports.createConfig = createConfig;
|