@layerum-team/rag-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/LICENSE +178 -0
- package/README.md +116 -0
- package/dist/index.cjs +447 -0
- package/dist/index.d.cts +282 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.js +419 -0
- package/package.json +41 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
LayerumApiError: () => LayerumApiError,
|
|
24
|
+
LayerumClient: () => LayerumClient
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/error.ts
|
|
29
|
+
var LayerumApiError = class extends Error {
|
|
30
|
+
status;
|
|
31
|
+
details;
|
|
32
|
+
path;
|
|
33
|
+
method;
|
|
34
|
+
constructor(message, status, details, method, path) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = "LayerumApiError";
|
|
37
|
+
this.status = status;
|
|
38
|
+
this.details = details;
|
|
39
|
+
this.method = method;
|
|
40
|
+
this.path = path;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/http.ts
|
|
45
|
+
function normalizeErrorMessage(payload, status) {
|
|
46
|
+
const fallback = `Request failed (${status})`;
|
|
47
|
+
if (!payload || typeof payload !== "object") return fallback;
|
|
48
|
+
const message = payload.message;
|
|
49
|
+
if (Array.isArray(message)) {
|
|
50
|
+
return message.map((item) => typeof item === "string" ? item : JSON.stringify(item)).join(", ");
|
|
51
|
+
}
|
|
52
|
+
if (typeof message === "string") return message;
|
|
53
|
+
if (message && typeof message === "object") {
|
|
54
|
+
const nested = message.message;
|
|
55
|
+
if (typeof nested === "string") return nested;
|
|
56
|
+
}
|
|
57
|
+
return fallback;
|
|
58
|
+
}
|
|
59
|
+
function shouldRetry(status, method, attempt, maxRetries) {
|
|
60
|
+
if (attempt >= maxRetries) return false;
|
|
61
|
+
if (method === "POST" || method === "PATCH" || method === "DELETE") return false;
|
|
62
|
+
return status === 429 || status >= 500;
|
|
63
|
+
}
|
|
64
|
+
function sleep(ms) {
|
|
65
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
66
|
+
}
|
|
67
|
+
var HttpClient = class {
|
|
68
|
+
baseUrl;
|
|
69
|
+
apiKey;
|
|
70
|
+
timeoutMs;
|
|
71
|
+
maxRetries;
|
|
72
|
+
constructor(options) {
|
|
73
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
74
|
+
this.apiKey = options.apiKey;
|
|
75
|
+
this.timeoutMs = options.timeoutMs;
|
|
76
|
+
this.maxRetries = options.maxRetries;
|
|
77
|
+
}
|
|
78
|
+
async request(path, options = {}) {
|
|
79
|
+
const method = options.method ?? "GET";
|
|
80
|
+
let attempt = 0;
|
|
81
|
+
while (true) {
|
|
82
|
+
const controller = new AbortController();
|
|
83
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
86
|
+
method,
|
|
87
|
+
headers: options.isFormData ? { Authorization: `Bearer ${this.apiKey}` } : {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
90
|
+
},
|
|
91
|
+
body: options.body === void 0 ? void 0 : options.isFormData ? options.body : JSON.stringify(options.body),
|
|
92
|
+
signal: controller.signal
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
const payload = await response.json().catch(() => null);
|
|
96
|
+
const message = normalizeErrorMessage(payload, response.status);
|
|
97
|
+
if (shouldRetry(response.status, method, attempt, this.maxRetries)) {
|
|
98
|
+
attempt += 1;
|
|
99
|
+
await sleep(250 * attempt);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
throw new LayerumApiError(
|
|
103
|
+
message,
|
|
104
|
+
response.status,
|
|
105
|
+
payload?.details,
|
|
106
|
+
method,
|
|
107
|
+
path
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
if (response.status === 204) return void 0;
|
|
111
|
+
return await response.json();
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error instanceof LayerumApiError) throw error;
|
|
114
|
+
const message = error instanceof Error ? error.message : "Unknown network error";
|
|
115
|
+
throw new LayerumApiError(
|
|
116
|
+
`Network error while ${method} ${path}: ${message}`,
|
|
117
|
+
0,
|
|
118
|
+
error,
|
|
119
|
+
method,
|
|
120
|
+
path
|
|
121
|
+
);
|
|
122
|
+
} finally {
|
|
123
|
+
clearTimeout(timeout);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// src/client.ts
|
|
130
|
+
function sleep2(ms) {
|
|
131
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
132
|
+
}
|
|
133
|
+
function toBlob(file) {
|
|
134
|
+
if (typeof Blob !== "undefined" && file instanceof Blob) return file;
|
|
135
|
+
if (file instanceof ArrayBuffer) return new Blob([file]);
|
|
136
|
+
if (file instanceof Uint8Array) {
|
|
137
|
+
return new Blob([file]);
|
|
138
|
+
}
|
|
139
|
+
return new Blob([file]);
|
|
140
|
+
}
|
|
141
|
+
function unwrapItems(payload) {
|
|
142
|
+
if (!payload) return [];
|
|
143
|
+
if (Array.isArray(payload)) return payload;
|
|
144
|
+
return payload.items ?? [];
|
|
145
|
+
}
|
|
146
|
+
var EntitiesApi = class {
|
|
147
|
+
constructor(http) {
|
|
148
|
+
this.http = http;
|
|
149
|
+
}
|
|
150
|
+
async list(parentId) {
|
|
151
|
+
const payload = await this.http.request("/v1/entities");
|
|
152
|
+
const items = unwrapItems(payload);
|
|
153
|
+
if (!parentId) return items;
|
|
154
|
+
return items.filter(
|
|
155
|
+
(item) => (item.parentId ?? item.parent_id ?? null) === parentId
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
async tree() {
|
|
159
|
+
const payload = await this.http.request("/v1/entities/tree");
|
|
160
|
+
return unwrapItems(payload);
|
|
161
|
+
}
|
|
162
|
+
create(input) {
|
|
163
|
+
return this.http.request("/v1/entities", {
|
|
164
|
+
method: "POST",
|
|
165
|
+
body: {
|
|
166
|
+
entity_type_id: input.entityTypeId,
|
|
167
|
+
name: input.name,
|
|
168
|
+
description: input.description,
|
|
169
|
+
parent_id: input.parentId,
|
|
170
|
+
metadata: input.metadata
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
remove(entityId) {
|
|
175
|
+
return this.http.request(`/v1/entities/${entityId}`, {
|
|
176
|
+
method: "DELETE"
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
var EntityTypesApi = class {
|
|
181
|
+
constructor(http) {
|
|
182
|
+
this.http = http;
|
|
183
|
+
}
|
|
184
|
+
async list() {
|
|
185
|
+
const payload = await this.http.request(
|
|
186
|
+
"/v1/entity-types"
|
|
187
|
+
);
|
|
188
|
+
return unwrapItems(payload);
|
|
189
|
+
}
|
|
190
|
+
get(entityTypeId) {
|
|
191
|
+
return this.http.request(`/v1/entity-types/${entityTypeId}`);
|
|
192
|
+
}
|
|
193
|
+
create(input) {
|
|
194
|
+
return this.http.request("/v1/entity-types", {
|
|
195
|
+
method: "POST",
|
|
196
|
+
body: {
|
|
197
|
+
name: input.name,
|
|
198
|
+
label: input.label
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
remove(entityTypeId) {
|
|
203
|
+
return this.http.request(
|
|
204
|
+
`/v1/entity-types/${entityTypeId}`,
|
|
205
|
+
{
|
|
206
|
+
method: "DELETE"
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
var DocumentsApi = class {
|
|
212
|
+
constructor(http) {
|
|
213
|
+
this.http = http;
|
|
214
|
+
}
|
|
215
|
+
async list(input) {
|
|
216
|
+
const path = input.allInWorkspace ? "/v1/documents" : `/v1/entities/${input.entityId}/documents`;
|
|
217
|
+
const payload = await this.http.request(path);
|
|
218
|
+
return unwrapItems(payload);
|
|
219
|
+
}
|
|
220
|
+
get(entityId, sourceId) {
|
|
221
|
+
return this.http.request(
|
|
222
|
+
`/v1/entities/${entityId}/documents/${sourceId}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
upload(input) {
|
|
226
|
+
const form = new FormData();
|
|
227
|
+
form.set("file", toBlob(input.file), input.fileName);
|
|
228
|
+
if (input.visibility) form.set("visibility", input.visibility);
|
|
229
|
+
if (input.modelConfigId) form.set("model_config_id", input.modelConfigId);
|
|
230
|
+
return this.http.request(
|
|
231
|
+
`/v1/entities/${input.entityId}/documents/upload`,
|
|
232
|
+
{
|
|
233
|
+
method: "POST",
|
|
234
|
+
body: form,
|
|
235
|
+
isFormData: true
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
uploadInit(input) {
|
|
240
|
+
return this.http.request(
|
|
241
|
+
`/v1/entities/${input.entityId}/documents/upload/init`,
|
|
242
|
+
{
|
|
243
|
+
method: "POST",
|
|
244
|
+
body: {
|
|
245
|
+
file_name: input.fileName,
|
|
246
|
+
file_size_bytes: input.fileSizeBytes,
|
|
247
|
+
content_type: input.contentType,
|
|
248
|
+
visibility: input.visibility,
|
|
249
|
+
model_config_id: input.modelConfigId
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
uploadComplete(input) {
|
|
255
|
+
return this.http.request(
|
|
256
|
+
`/v1/entities/${input.entityId}/documents/upload/complete`,
|
|
257
|
+
{
|
|
258
|
+
method: "POST",
|
|
259
|
+
body: {
|
|
260
|
+
upload_id: input.uploadId,
|
|
261
|
+
display_name: input.displayName,
|
|
262
|
+
visibility: input.visibility,
|
|
263
|
+
model_config_id: input.modelConfigId,
|
|
264
|
+
checksum: input.checksum
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
async uploadDirect(input) {
|
|
270
|
+
const blob = toBlob(input.file);
|
|
271
|
+
const contentType = input.contentType || blob.type || "application/octet-stream";
|
|
272
|
+
const initialized = await this.uploadInit({
|
|
273
|
+
entityId: input.entityId,
|
|
274
|
+
fileName: input.fileName,
|
|
275
|
+
fileSizeBytes: blob.size,
|
|
276
|
+
contentType,
|
|
277
|
+
visibility: input.visibility,
|
|
278
|
+
modelConfigId: input.modelConfigId
|
|
279
|
+
});
|
|
280
|
+
const form = new FormData();
|
|
281
|
+
for (const [key, value] of Object.entries(initialized.fields ?? {})) {
|
|
282
|
+
form.set(key, value);
|
|
283
|
+
}
|
|
284
|
+
form.set("file", blob, input.fileName);
|
|
285
|
+
const uploadRes = await fetch(initialized.uploadUrl, {
|
|
286
|
+
method: initialized.method ?? "POST",
|
|
287
|
+
body: form
|
|
288
|
+
});
|
|
289
|
+
if (!uploadRes.ok) {
|
|
290
|
+
throw new Error(`Direct upload failed with status ${uploadRes.status}`);
|
|
291
|
+
}
|
|
292
|
+
return this.uploadComplete({
|
|
293
|
+
entityId: input.entityId,
|
|
294
|
+
uploadId: initialized.uploadId,
|
|
295
|
+
displayName: input.fileName,
|
|
296
|
+
visibility: input.visibility,
|
|
297
|
+
modelConfigId: input.modelConfigId
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
createText(input) {
|
|
301
|
+
return this.http.request(`/v1/entities/${input.entityId}/documents`, {
|
|
302
|
+
method: "POST",
|
|
303
|
+
body: {
|
|
304
|
+
source_type: "text",
|
|
305
|
+
display_name: input.displayName,
|
|
306
|
+
raw_text: input.rawText,
|
|
307
|
+
visibility: input.visibility ?? "self_and_descendants",
|
|
308
|
+
model_config_id: input.modelConfigId
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
createUrl(input) {
|
|
313
|
+
return this.http.request(`/v1/entities/${input.entityId}/documents`, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
body: {
|
|
316
|
+
source_type: "url",
|
|
317
|
+
display_name: input.displayName,
|
|
318
|
+
source_url: input.sourceUrl,
|
|
319
|
+
visibility: input.visibility ?? "self_and_descendants",
|
|
320
|
+
model_config_id: input.modelConfigId
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
remove(input) {
|
|
325
|
+
return this.http.request(
|
|
326
|
+
`/v1/entities/${input.entityId}/documents/${input.sourceId}`,
|
|
327
|
+
{
|
|
328
|
+
method: "DELETE"
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
var IngestionApi = class {
|
|
334
|
+
constructor(http, documentsApi) {
|
|
335
|
+
this.http = http;
|
|
336
|
+
this.documentsApi = documentsApi;
|
|
337
|
+
}
|
|
338
|
+
retry(input) {
|
|
339
|
+
return this.http.request(
|
|
340
|
+
`/v1/entities/${input.entityId}/documents/${input.sourceId}/retry`,
|
|
341
|
+
{
|
|
342
|
+
method: "POST"
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
error(input) {
|
|
347
|
+
return this.http.request(
|
|
348
|
+
`/v1/entities/${input.entityId}/documents/${input.sourceId}/error`
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
async waitUntilReady(input) {
|
|
352
|
+
const timeoutMs = input.timeoutMs ?? 12e4;
|
|
353
|
+
const intervalMs = input.intervalMs ?? 2e3;
|
|
354
|
+
const start = Date.now();
|
|
355
|
+
while (true) {
|
|
356
|
+
const source = await this.documentsApi.get(input.entityId, input.sourceId);
|
|
357
|
+
if (source.status === "completed") return source;
|
|
358
|
+
if (source.status === "failed") {
|
|
359
|
+
const details = await this.error({
|
|
360
|
+
entityId: input.entityId,
|
|
361
|
+
sourceId: input.sourceId
|
|
362
|
+
}).catch(() => null);
|
|
363
|
+
throw new Error(
|
|
364
|
+
`Ingestion failed for source ${input.sourceId}${details?.latestJob?.error_message ? `: ${details.latestJob.error_message}` : ""}`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
if (Date.now() - start >= timeoutMs) {
|
|
368
|
+
throw new Error(
|
|
369
|
+
`Timed out waiting for source ${input.sourceId} to complete ingestion`
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
await sleep2(intervalMs);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
var QueryApi = class {
|
|
377
|
+
constructor(http) {
|
|
378
|
+
this.http = http;
|
|
379
|
+
}
|
|
380
|
+
run(input) {
|
|
381
|
+
return this.http.request("/v1/query", {
|
|
382
|
+
method: "POST",
|
|
383
|
+
body: {
|
|
384
|
+
entityId: input.entityId,
|
|
385
|
+
modelConfigId: input.modelConfigId,
|
|
386
|
+
query: input.query,
|
|
387
|
+
topK: input.topK,
|
|
388
|
+
includeParentScopes: input.includeParentScopes
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
runDebug(input) {
|
|
393
|
+
return this.http.request("/v1/query/debug", {
|
|
394
|
+
method: "POST",
|
|
395
|
+
body: {
|
|
396
|
+
entityId: input.entityId,
|
|
397
|
+
modelConfigId: input.modelConfigId,
|
|
398
|
+
query: input.query,
|
|
399
|
+
topK: input.topK,
|
|
400
|
+
includeParentScopes: input.includeParentScopes
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
var ModelsApi = class {
|
|
406
|
+
constructor(http) {
|
|
407
|
+
this.http = http;
|
|
408
|
+
}
|
|
409
|
+
async listConfigs() {
|
|
410
|
+
const payload = await this.http.request("/v1/models");
|
|
411
|
+
return unwrapItems(payload);
|
|
412
|
+
}
|
|
413
|
+
async listDefinitions(input) {
|
|
414
|
+
const query = input?.type ? `?type=${encodeURIComponent(input.type)}` : "";
|
|
415
|
+
const payload = await this.http.request(
|
|
416
|
+
`/v1/model-definitions${query}`
|
|
417
|
+
);
|
|
418
|
+
return unwrapItems(payload);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
var LayerumClient = class {
|
|
422
|
+
entities;
|
|
423
|
+
entityTypes;
|
|
424
|
+
documents;
|
|
425
|
+
ingestion;
|
|
426
|
+
query;
|
|
427
|
+
models;
|
|
428
|
+
constructor(options) {
|
|
429
|
+
const http = new HttpClient({
|
|
430
|
+
apiKey: options.apiKey,
|
|
431
|
+
baseUrl: options.baseUrl ?? "http://localhost:4000",
|
|
432
|
+
timeoutMs: options.timeoutMs ?? 3e4,
|
|
433
|
+
maxRetries: options.maxRetries ?? 2
|
|
434
|
+
});
|
|
435
|
+
this.entities = new EntitiesApi(http);
|
|
436
|
+
this.entityTypes = new EntityTypesApi(http);
|
|
437
|
+
this.documents = new DocumentsApi(http);
|
|
438
|
+
this.ingestion = new IngestionApi(http, this.documents);
|
|
439
|
+
this.query = new QueryApi(http);
|
|
440
|
+
this.models = new ModelsApi(http);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
444
|
+
0 && (module.exports = {
|
|
445
|
+
LayerumApiError,
|
|
446
|
+
LayerumClient
|
|
447
|
+
});
|