@arbidocs/sdk 0.3.11 → 0.3.13
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/dist/browser-BszYf6lU.d.cts +3183 -0
- package/dist/browser-BszYf6lU.d.ts +3183 -0
- package/dist/browser.cjs +156 -25
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +154 -21
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +362 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -2973
- package/dist/index.d.ts +40 -2973
- package/dist/index.js +357 -22
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import
|
|
2
|
+
import path2 from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import { createArbiClient, base64ToBytes, deriveEncryptionKeypairFromSigning, sealedBoxDecrypt, createWorkspaceKeyHeader, buildWebSocketUrl, createAuthMessage, parseServerMessage, isMessageType } from '@arbidocs/client';
|
|
5
5
|
|
|
@@ -36,7 +36,36 @@ function requireOk(result, message) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
function getErrorMessage(err) {
|
|
39
|
-
|
|
39
|
+
if (!(err instanceof Error)) return String(err);
|
|
40
|
+
const rootCause = getDeepestCause(err);
|
|
41
|
+
if (rootCause !== err) {
|
|
42
|
+
const rootMsg = rootCause.message || String(rootCause);
|
|
43
|
+
if (err.message && !err.message.includes(rootMsg)) {
|
|
44
|
+
return `${err.message}: ${rootMsg}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return err.message;
|
|
48
|
+
}
|
|
49
|
+
function getDeepestCause(err) {
|
|
50
|
+
let current = err;
|
|
51
|
+
const seen = /* @__PURE__ */ new Set();
|
|
52
|
+
while (current.cause instanceof Error && !seen.has(current.cause)) {
|
|
53
|
+
seen.add(current);
|
|
54
|
+
current = current.cause;
|
|
55
|
+
}
|
|
56
|
+
return current;
|
|
57
|
+
}
|
|
58
|
+
function getErrorCode(err) {
|
|
59
|
+
if (!(err instanceof Error)) return void 0;
|
|
60
|
+
let current = err;
|
|
61
|
+
const seen = /* @__PURE__ */ new Set();
|
|
62
|
+
while (current && !seen.has(current)) {
|
|
63
|
+
seen.add(current);
|
|
64
|
+
const code = current.code;
|
|
65
|
+
if (typeof code === "string") return code;
|
|
66
|
+
current = current.cause instanceof Error ? current.cause : void 0;
|
|
67
|
+
}
|
|
68
|
+
return void 0;
|
|
40
69
|
}
|
|
41
70
|
|
|
42
71
|
// src/fetch.ts
|
|
@@ -93,10 +122,10 @@ var FileConfigStore = class {
|
|
|
93
122
|
credentialsFile;
|
|
94
123
|
sessionFile;
|
|
95
124
|
constructor(configDir) {
|
|
96
|
-
this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ??
|
|
97
|
-
this.configFile =
|
|
98
|
-
this.credentialsFile =
|
|
99
|
-
this.sessionFile =
|
|
125
|
+
this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ?? path2.join(os.homedir(), ".arbi");
|
|
126
|
+
this.configFile = path2.join(this.configDir, "config.json");
|
|
127
|
+
this.credentialsFile = path2.join(this.configDir, "credentials.json");
|
|
128
|
+
this.sessionFile = path2.join(this.configDir, "session.json");
|
|
100
129
|
}
|
|
101
130
|
ensureConfigDir() {
|
|
102
131
|
if (!fs.existsSync(this.configDir)) {
|
|
@@ -167,6 +196,77 @@ var FileConfigStore = class {
|
|
|
167
196
|
clearChatSession() {
|
|
168
197
|
this.saveChatSession({ ...DEFAULT_SESSION });
|
|
169
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Try to resolve config from multiple sources, in priority order:
|
|
201
|
+
*
|
|
202
|
+
* 1. Existing `~/.arbi/config.json` (highest priority)
|
|
203
|
+
* 2. `ARBI_SERVER_URL` environment variable
|
|
204
|
+
* 3. `.env` file in `searchDir` → read `VITE_DEPLOYMENT_DOMAIN`
|
|
205
|
+
* 4. `public/config.json` in `searchDir` → read `deployment.domain`
|
|
206
|
+
* 5. Default to `https://localhost`
|
|
207
|
+
*
|
|
208
|
+
* Returns `{ config, source }` where source describes where the config came from.
|
|
209
|
+
* Saves auto-detected config to disk so subsequent calls use the fast path.
|
|
210
|
+
*/
|
|
211
|
+
resolveConfigWithFallbacks(searchDir) {
|
|
212
|
+
const existing = this.getConfig();
|
|
213
|
+
if (existing?.baseUrl) {
|
|
214
|
+
return { config: existing, source: "config" };
|
|
215
|
+
}
|
|
216
|
+
const envUrl = process.env.ARBI_SERVER_URL;
|
|
217
|
+
if (envUrl) {
|
|
218
|
+
const domain = new URL(envUrl).hostname;
|
|
219
|
+
const config2 = { baseUrl: envUrl.replace(/\/$/, ""), deploymentDomain: domain };
|
|
220
|
+
this.saveConfig(config2);
|
|
221
|
+
return { config: config2, source: "ARBI_SERVER_URL env var" };
|
|
222
|
+
}
|
|
223
|
+
const dir = searchDir || process.cwd();
|
|
224
|
+
const dotenvConfig = this.readDotEnvDomain(path2.join(dir, ".env"));
|
|
225
|
+
if (dotenvConfig) {
|
|
226
|
+
this.saveConfig(dotenvConfig);
|
|
227
|
+
return { config: dotenvConfig, source: ".env file" };
|
|
228
|
+
}
|
|
229
|
+
const publicConfig = this.readPublicConfigDomain(path2.join(dir, "public", "config.json"));
|
|
230
|
+
if (publicConfig) {
|
|
231
|
+
this.saveConfig(publicConfig);
|
|
232
|
+
return { config: publicConfig, source: "public/config.json" };
|
|
233
|
+
}
|
|
234
|
+
const config = { baseUrl: "https://localhost", deploymentDomain: "localhost" };
|
|
235
|
+
this.saveConfig(config);
|
|
236
|
+
return { config, source: "default (https://localhost)" };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Read VITE_DEPLOYMENT_DOMAIN from a .env file.
|
|
240
|
+
*/
|
|
241
|
+
readDotEnvDomain(filePath) {
|
|
242
|
+
try {
|
|
243
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
244
|
+
const match = content.match(/^VITE_DEPLOYMENT_DOMAIN\s*=\s*(.+)$/m);
|
|
245
|
+
if (match) {
|
|
246
|
+
const domain = match[1].trim().replace(/^["']|["']$/g, "");
|
|
247
|
+
if (domain) {
|
|
248
|
+
return { baseUrl: `https://${domain}`, deploymentDomain: domain };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Read deployment.domain from a public/config.json file.
|
|
257
|
+
*/
|
|
258
|
+
readPublicConfigDomain(filePath) {
|
|
259
|
+
try {
|
|
260
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
261
|
+
const json = JSON.parse(content);
|
|
262
|
+
const domain = json?.deployment?.domain;
|
|
263
|
+
if (domain) {
|
|
264
|
+
return { baseUrl: `https://${domain}`, deploymentDomain: domain };
|
|
265
|
+
}
|
|
266
|
+
} catch {
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
170
270
|
};
|
|
171
271
|
function formatWorkspaceChoices(wsList) {
|
|
172
272
|
return wsList.map((ws) => {
|
|
@@ -192,7 +292,11 @@ async function createAuthenticatedClient(config, creds, store) {
|
|
|
192
292
|
});
|
|
193
293
|
store.saveCredentials({
|
|
194
294
|
...creds,
|
|
195
|
-
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
|
|
295
|
+
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
|
|
296
|
+
accessToken: void 0,
|
|
297
|
+
workspaceKeyHeader: void 0,
|
|
298
|
+
workspaceId: void 0,
|
|
299
|
+
tokenTimestamp: void 0
|
|
196
300
|
});
|
|
197
301
|
return { arbi, loginResult };
|
|
198
302
|
}
|
|
@@ -207,7 +311,12 @@ async function performPasswordLogin(config, email, password, store) {
|
|
|
207
311
|
store.saveCredentials({
|
|
208
312
|
email,
|
|
209
313
|
signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),
|
|
210
|
-
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
|
|
314
|
+
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
|
|
315
|
+
// Clear any cached workspace tokens — new session key invalidates them
|
|
316
|
+
accessToken: void 0,
|
|
317
|
+
workspaceKeyHeader: void 0,
|
|
318
|
+
workspaceId: void 0,
|
|
319
|
+
tokenTimestamp: void 0
|
|
211
320
|
});
|
|
212
321
|
return { arbi, loginResult, config };
|
|
213
322
|
}
|
|
@@ -270,6 +379,10 @@ async function resolveAuth(store) {
|
|
|
270
379
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
271
380
|
return { arbi, loginResult, config };
|
|
272
381
|
}
|
|
382
|
+
var TOKEN_MAX_AGE_MS = 50 * 60 * 1e3;
|
|
383
|
+
function isCachedTokenValid(creds, workspaceId) {
|
|
384
|
+
return !!(creds.accessToken && creds.workspaceKeyHeader && creds.workspaceId === workspaceId && creds.tokenTimestamp && Date.now() - new Date(creds.tokenTimestamp).getTime() < TOKEN_MAX_AGE_MS);
|
|
385
|
+
}
|
|
273
386
|
async function resolveWorkspace(store, workspaceOpt) {
|
|
274
387
|
const config = store.requireConfig();
|
|
275
388
|
const creds = store.requireCredentials();
|
|
@@ -277,6 +390,32 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
277
390
|
if (!workspaceId) {
|
|
278
391
|
throw new ArbiError("No workspace selected. Run: arbi workspace select <id>");
|
|
279
392
|
}
|
|
393
|
+
if (isCachedTokenValid(creds, workspaceId)) {
|
|
394
|
+
const arbi2 = createArbiClient({
|
|
395
|
+
baseUrl: config.baseUrl,
|
|
396
|
+
deploymentDomain: config.deploymentDomain,
|
|
397
|
+
credentials: "omit"
|
|
398
|
+
});
|
|
399
|
+
await arbi2.crypto.initSodium();
|
|
400
|
+
arbi2.session.setSelectedWorkspace(workspaceId);
|
|
401
|
+
arbi2.session.setAccessToken(creds.accessToken);
|
|
402
|
+
arbi2.session.setCachedWorkspaceHeader(workspaceId, creds.workspaceKeyHeader);
|
|
403
|
+
const signingPrivateKey = base64ToBytes(creds.signingPrivateKeyBase64);
|
|
404
|
+
const serverSessionKey = base64ToBytes(creds.serverSessionKeyBase64);
|
|
405
|
+
const loginResult2 = {
|
|
406
|
+
accessToken: creds.accessToken,
|
|
407
|
+
signingPrivateKey,
|
|
408
|
+
serverSessionKey
|
|
409
|
+
};
|
|
410
|
+
return {
|
|
411
|
+
arbi: arbi2,
|
|
412
|
+
loginResult: loginResult2,
|
|
413
|
+
config,
|
|
414
|
+
workspaceId,
|
|
415
|
+
accessToken: creds.accessToken,
|
|
416
|
+
workspaceKeyHeader: creds.workspaceKeyHeader
|
|
417
|
+
};
|
|
418
|
+
}
|
|
280
419
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
281
420
|
await selectWorkspaceById(
|
|
282
421
|
arbi,
|
|
@@ -289,10 +428,57 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
289
428
|
if (!accessToken || !workspaceKeyHeader) {
|
|
290
429
|
throw new ArbiError("Authentication error \u2014 missing token or workspace key");
|
|
291
430
|
}
|
|
431
|
+
store.saveCredentials({
|
|
432
|
+
...store.requireCredentials(),
|
|
433
|
+
accessToken,
|
|
434
|
+
workspaceKeyHeader,
|
|
435
|
+
workspaceId,
|
|
436
|
+
tokenTimestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
437
|
+
});
|
|
292
438
|
return { arbi, loginResult, config, workspaceId, accessToken, workspaceKeyHeader };
|
|
293
439
|
}
|
|
294
440
|
|
|
295
441
|
// src/sse.ts
|
|
442
|
+
var TOOL_LABELS = {
|
|
443
|
+
search_documents: "Searching documents",
|
|
444
|
+
get_document_passages: "Reading document",
|
|
445
|
+
get_table_of_contents: "Getting table of contents",
|
|
446
|
+
view_document_pages: "Viewing document pages",
|
|
447
|
+
get_full_document: "Reading full document",
|
|
448
|
+
web_search: "Searching the web",
|
|
449
|
+
read_url: "Reading web pages",
|
|
450
|
+
ask_user: "Asking user",
|
|
451
|
+
compaction: "Compacting conversation",
|
|
452
|
+
personal_agent: "Running agent",
|
|
453
|
+
create_artifact: "Creating artifact",
|
|
454
|
+
create_plan: "Creating plan",
|
|
455
|
+
save_skill: "Saving skill",
|
|
456
|
+
run_code: "Running code"
|
|
457
|
+
};
|
|
458
|
+
var LIFECYCLE_LABELS = {
|
|
459
|
+
evaluation: "Evaluating results",
|
|
460
|
+
answering: "Writing answer",
|
|
461
|
+
reviewing: "Reviewing answer",
|
|
462
|
+
planning: "Planning",
|
|
463
|
+
tool_progress: "Working"
|
|
464
|
+
};
|
|
465
|
+
function formatAgentStepLabel(step) {
|
|
466
|
+
if (step.focus) return step.focus;
|
|
467
|
+
const detail = step.detail;
|
|
468
|
+
if (step.step === "tool_progress" && detail && detail.length > 0) {
|
|
469
|
+
const toolName = detail[0].tool;
|
|
470
|
+
const label = toolName && TOOL_LABELS[toolName] || LIFECYCLE_LABELS.tool_progress;
|
|
471
|
+
const message = detail[0].message;
|
|
472
|
+
return message ? `${label}: ${message}` : label;
|
|
473
|
+
}
|
|
474
|
+
if (step.step) {
|
|
475
|
+
return LIFECYCLE_LABELS[step.step] || step.step;
|
|
476
|
+
}
|
|
477
|
+
if (detail && detail.length > 0 && detail[0].tool) {
|
|
478
|
+
return TOOL_LABELS[detail[0].tool] || detail[0].tool;
|
|
479
|
+
}
|
|
480
|
+
return "";
|
|
481
|
+
}
|
|
296
482
|
function parseSSEEvents(chunk, buffer) {
|
|
297
483
|
const combined = buffer + chunk;
|
|
298
484
|
const events = [];
|
|
@@ -380,8 +566,8 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
380
566
|
// ARBI-specific events (dot-prefixed from server)
|
|
381
567
|
"arbi.agent_step": (raw) => {
|
|
382
568
|
const data = JSON.parse(raw);
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
569
|
+
const label = formatAgentStepLabel(data);
|
|
570
|
+
if (label) agentSteps.push(label);
|
|
385
571
|
callbacks.onAgentStep?.(data);
|
|
386
572
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
387
573
|
},
|
|
@@ -659,16 +845,34 @@ function formatUserName(user) {
|
|
|
659
845
|
// src/operations/documents.ts
|
|
660
846
|
var documents_exports = {};
|
|
661
847
|
__export(documents_exports, {
|
|
848
|
+
SUPPORTED_EXTENSIONS: () => SUPPORTED_EXTENSIONS,
|
|
662
849
|
deleteDocuments: () => deleteDocuments,
|
|
663
850
|
downloadDocument: () => downloadDocument,
|
|
664
851
|
getDocuments: () => getDocuments,
|
|
665
852
|
getParsedContent: () => getParsedContent,
|
|
666
853
|
listDocuments: () => listDocuments,
|
|
854
|
+
sanitizeFolderPath: () => sanitizeFolderPath,
|
|
667
855
|
updateDocuments: () => updateDocuments,
|
|
668
856
|
uploadFile: () => uploadFile,
|
|
669
|
-
|
|
857
|
+
uploadFiles: () => uploadFiles,
|
|
670
858
|
uploadUrl: () => uploadUrl
|
|
671
859
|
});
|
|
860
|
+
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
861
|
+
".pdf",
|
|
862
|
+
".txt",
|
|
863
|
+
".md",
|
|
864
|
+
".html",
|
|
865
|
+
".doc",
|
|
866
|
+
".docx",
|
|
867
|
+
".rtf",
|
|
868
|
+
".ppt",
|
|
869
|
+
".pptx",
|
|
870
|
+
".xls",
|
|
871
|
+
".xlsx"
|
|
872
|
+
]);
|
|
873
|
+
function sanitizeFolderPath(folderPath) {
|
|
874
|
+
return folderPath.replace(/[^a-zA-Z0-9_\-/]/g, "_").replace(/_{2,}/g, "_");
|
|
875
|
+
}
|
|
672
876
|
async function listDocuments(arbi) {
|
|
673
877
|
return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
|
|
674
878
|
}
|
|
@@ -707,22 +911,31 @@ async function getParsedContent(auth, docId, stage) {
|
|
|
707
911
|
});
|
|
708
912
|
return res.json();
|
|
709
913
|
}
|
|
710
|
-
async function uploadFile(auth, workspaceId, fileData, fileName) {
|
|
914
|
+
async function uploadFile(auth, workspaceId, fileData, fileName, options) {
|
|
711
915
|
const formData = new FormData();
|
|
712
916
|
formData.append("files", fileData, fileName);
|
|
917
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
918
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
713
919
|
const res = await authenticatedFetch({
|
|
714
920
|
...auth,
|
|
715
|
-
path: `/v1/document/upload
|
|
921
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
716
922
|
method: "POST",
|
|
717
923
|
body: formData
|
|
718
924
|
});
|
|
719
925
|
return res.json();
|
|
720
926
|
}
|
|
721
|
-
async function
|
|
722
|
-
const
|
|
723
|
-
const
|
|
724
|
-
const
|
|
725
|
-
|
|
927
|
+
async function uploadFiles(auth, workspaceId, files, options) {
|
|
928
|
+
const formData = new FormData();
|
|
929
|
+
for (const f of files) formData.append("files", f.data, f.name);
|
|
930
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
931
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
932
|
+
const res = await authenticatedFetch({
|
|
933
|
+
...auth,
|
|
934
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
935
|
+
method: "POST",
|
|
936
|
+
body: formData
|
|
937
|
+
});
|
|
938
|
+
return res.json();
|
|
726
939
|
}
|
|
727
940
|
async function downloadDocument(auth, docId) {
|
|
728
941
|
return authenticatedFetch({
|
|
@@ -922,6 +1135,8 @@ async function retrieve(options) {
|
|
|
922
1135
|
input: query,
|
|
923
1136
|
workspace_ext_id: workspaceId,
|
|
924
1137
|
stream: false,
|
|
1138
|
+
background: false,
|
|
1139
|
+
store: true,
|
|
925
1140
|
tools,
|
|
926
1141
|
...model ? { model } : {}
|
|
927
1142
|
};
|
|
@@ -937,6 +1152,8 @@ async function queryAssistant(options) {
|
|
|
937
1152
|
input: question,
|
|
938
1153
|
workspace_ext_id: workspaceId,
|
|
939
1154
|
stream: true,
|
|
1155
|
+
background: false,
|
|
1156
|
+
store: true,
|
|
940
1157
|
tools: {
|
|
941
1158
|
retrieval_chunk: buildRetrievalChunkTool(docIds),
|
|
942
1159
|
retrieval_full_context: buildRetrievalFullContextTool([])
|
|
@@ -1396,11 +1613,12 @@ var Arbi = class {
|
|
|
1396
1613
|
workspaceId ?? this.requireWorkspace(),
|
|
1397
1614
|
shared
|
|
1398
1615
|
),
|
|
1399
|
-
uploadFile: (fileData, fileName,
|
|
1616
|
+
uploadFile: (fileData, fileName, options) => uploadFile(
|
|
1400
1617
|
this.getAuthHeaders(),
|
|
1401
|
-
workspaceId ?? this.requireWorkspace(),
|
|
1618
|
+
options?.workspaceId ?? this.requireWorkspace(),
|
|
1402
1619
|
fileData,
|
|
1403
|
-
fileName
|
|
1620
|
+
fileName,
|
|
1621
|
+
options?.folder ? { folder: options.folder } : void 0
|
|
1404
1622
|
),
|
|
1405
1623
|
download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
|
|
1406
1624
|
getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
|
|
@@ -1542,6 +1760,123 @@ var Arbi = class {
|
|
|
1542
1760
|
}
|
|
1543
1761
|
};
|
|
1544
1762
|
|
|
1545
|
-
|
|
1763
|
+
// src/operations/documents-node.ts
|
|
1764
|
+
var documents_node_exports = {};
|
|
1765
|
+
__export(documents_node_exports, {
|
|
1766
|
+
uploadDirectory: () => uploadDirectory,
|
|
1767
|
+
uploadLocalFile: () => uploadLocalFile,
|
|
1768
|
+
uploadZip: () => uploadZip
|
|
1769
|
+
});
|
|
1770
|
+
function collectFiles(dirPath, baseDir) {
|
|
1771
|
+
const root = baseDir ?? dirPath;
|
|
1772
|
+
const results = [];
|
|
1773
|
+
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
|
|
1774
|
+
const fullPath = path2.join(dirPath, entry.name);
|
|
1775
|
+
if (entry.isDirectory()) {
|
|
1776
|
+
results.push(...collectFiles(fullPath, root));
|
|
1777
|
+
} else if (entry.isFile()) {
|
|
1778
|
+
const ext = path2.extname(entry.name).toLowerCase();
|
|
1779
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1780
|
+
results.push({ absolutePath: fullPath, relativePath: path2.relative(root, fullPath) });
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
return results;
|
|
1785
|
+
}
|
|
1786
|
+
async function uploadLocalFile(auth, workspaceId, filePath, options) {
|
|
1787
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
1788
|
+
const fileName = path2.basename(filePath);
|
|
1789
|
+
const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName, options);
|
|
1790
|
+
return { ...result, fileName };
|
|
1791
|
+
}
|
|
1792
|
+
async function uploadDirectory(auth, workspaceId, dirPath) {
|
|
1793
|
+
const resolvedDir = path2.resolve(dirPath);
|
|
1794
|
+
const dirName = path2.basename(resolvedDir);
|
|
1795
|
+
const entries = collectFiles(resolvedDir);
|
|
1796
|
+
if (entries.length === 0) {
|
|
1797
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1798
|
+
}
|
|
1799
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1800
|
+
for (const entry of entries) {
|
|
1801
|
+
const relDir = path2.dirname(entry.relativePath);
|
|
1802
|
+
const folder = relDir === "." ? dirName : `${dirName}/${relDir}`;
|
|
1803
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1804
|
+
groups.get(folder).push({ absolutePath: entry.absolutePath, name: path2.basename(entry.relativePath) });
|
|
1805
|
+
}
|
|
1806
|
+
const allDocIds = [];
|
|
1807
|
+
const allDuplicates = [];
|
|
1808
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1809
|
+
for (const [folder, files] of groups) {
|
|
1810
|
+
const blobs = files.map((f) => ({
|
|
1811
|
+
data: new Blob([fs.readFileSync(f.absolutePath)]),
|
|
1812
|
+
name: f.name
|
|
1813
|
+
}));
|
|
1814
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1815
|
+
const dups = result.duplicates ?? [];
|
|
1816
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1817
|
+
allDuplicates.push(...dups);
|
|
1818
|
+
folders.set(folder, {
|
|
1819
|
+
fileCount: files.length,
|
|
1820
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1821
|
+
duplicates: dups
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1825
|
+
}
|
|
1826
|
+
async function uploadZip(auth, workspaceId, zipPath) {
|
|
1827
|
+
const JSZip = (await import('jszip')).default;
|
|
1828
|
+
const zipBuffer = fs.readFileSync(zipPath);
|
|
1829
|
+
const zip = await JSZip.loadAsync(zipBuffer);
|
|
1830
|
+
const zipBaseName = path2.basename(zipPath).replace(/\.zip$/i, "");
|
|
1831
|
+
const entries = [];
|
|
1832
|
+
zip.forEach((relativePath, zipEntry) => {
|
|
1833
|
+
if (zipEntry.dir) return;
|
|
1834
|
+
const ext = path2.extname(relativePath).toLowerCase();
|
|
1835
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1836
|
+
entries.push({ zipEntryPath: relativePath, zipEntry });
|
|
1837
|
+
}
|
|
1838
|
+
});
|
|
1839
|
+
if (entries.length === 0) {
|
|
1840
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1841
|
+
}
|
|
1842
|
+
const firstParts = new Set(entries.map((e) => e.zipEntryPath.split("/")[0]));
|
|
1843
|
+
const hasSingleRoot = firstParts.size === 1 && entries.every((e) => e.zipEntryPath.includes("/"));
|
|
1844
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1845
|
+
for (const entry of entries) {
|
|
1846
|
+
const data = await entry.zipEntry.async("uint8array");
|
|
1847
|
+
const fileName = path2.basename(entry.zipEntryPath);
|
|
1848
|
+
const relDir = path2.dirname(entry.zipEntryPath);
|
|
1849
|
+
let folder;
|
|
1850
|
+
if (hasSingleRoot) {
|
|
1851
|
+
folder = relDir === "." ? zipBaseName : relDir;
|
|
1852
|
+
} else {
|
|
1853
|
+
folder = relDir === "." ? zipBaseName : `${zipBaseName}/${relDir}`;
|
|
1854
|
+
}
|
|
1855
|
+
folder = sanitizeFolderPath(folder);
|
|
1856
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1857
|
+
groups.get(folder).push({ name: fileName, data });
|
|
1858
|
+
}
|
|
1859
|
+
const allDocIds = [];
|
|
1860
|
+
const allDuplicates = [];
|
|
1861
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1862
|
+
for (const [folder, files] of groups) {
|
|
1863
|
+
const blobs = files.map((f) => ({
|
|
1864
|
+
data: new Blob([f.data]),
|
|
1865
|
+
name: f.name
|
|
1866
|
+
}));
|
|
1867
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1868
|
+
const dups = result.duplicates ?? [];
|
|
1869
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1870
|
+
allDuplicates.push(...dups);
|
|
1871
|
+
folders.set(folder, {
|
|
1872
|
+
fileCount: files.length,
|
|
1873
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1874
|
+
duplicates: dups
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
export { Arbi, ArbiApiError, ArbiError, FileConfigStore, LIFECYCLE_LABELS, TOOL_LABELS, agentconfig_exports as agentconfig, assistant_exports as assistant, authenticatedFetch, buildRetrievalChunkTool, buildRetrievalFullContextTool, buildRetrievalTocTool, connectWebSocket, connectWithReconnect, consumeSSEStream, contacts_exports as contacts, conversations_exports as conversations, createAuthenticatedClient, createDocumentWaiter, dm_exports as dm, doctags_exports as doctags, documents_exports as documents, documents_node_exports as documentsNode, files_exports as files, formatAgentStepLabel, formatFileSize, formatUserName, formatWorkspaceChoices, formatWsMessage, generateEncryptedWorkspaceKey, getErrorCode, getErrorMessage, health_exports as health, parseSSEEvents, performPasswordLogin, requireData, requireOk, resolveAuth, resolveWorkspace, selectWorkspace, selectWorkspaceById, settings_exports as settings, streamSSE, tags_exports as tags, workspaces_exports as workspaces };
|
|
1546
1881
|
//# sourceMappingURL=index.js.map
|
|
1547
1882
|
//# sourceMappingURL=index.js.map
|