@arbidocs/sdk 0.3.10 → 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 +185 -30
- 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 +183 -26
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +393 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -2971
- package/dist/index.d.ts +40 -2971
- package/dist/index.js +388 -28
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
|
-
var
|
|
4
|
+
var path2 = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
6
|
var client = require('@arbidocs/client');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
10
10
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
11
|
-
var
|
|
11
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
12
12
|
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
13
13
|
|
|
14
14
|
var __defProp = Object.defineProperty;
|
|
@@ -44,14 +44,64 @@ function requireOk(result, message) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function getErrorMessage(err) {
|
|
47
|
-
|
|
47
|
+
if (!(err instanceof Error)) return String(err);
|
|
48
|
+
const rootCause = getDeepestCause(err);
|
|
49
|
+
if (rootCause !== err) {
|
|
50
|
+
const rootMsg = rootCause.message || String(rootCause);
|
|
51
|
+
if (err.message && !err.message.includes(rootMsg)) {
|
|
52
|
+
return `${err.message}: ${rootMsg}`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return err.message;
|
|
56
|
+
}
|
|
57
|
+
function getDeepestCause(err) {
|
|
58
|
+
let current = err;
|
|
59
|
+
const seen = /* @__PURE__ */ new Set();
|
|
60
|
+
while (current.cause instanceof Error && !seen.has(current.cause)) {
|
|
61
|
+
seen.add(current);
|
|
62
|
+
current = current.cause;
|
|
63
|
+
}
|
|
64
|
+
return current;
|
|
65
|
+
}
|
|
66
|
+
function getErrorCode(err) {
|
|
67
|
+
if (!(err instanceof Error)) return void 0;
|
|
68
|
+
let current = err;
|
|
69
|
+
const seen = /* @__PURE__ */ new Set();
|
|
70
|
+
while (current && !seen.has(current)) {
|
|
71
|
+
seen.add(current);
|
|
72
|
+
const code = current.code;
|
|
73
|
+
if (typeof code === "string") return code;
|
|
74
|
+
current = current.cause instanceof Error ? current.cause : void 0;
|
|
75
|
+
}
|
|
76
|
+
return void 0;
|
|
48
77
|
}
|
|
49
78
|
|
|
50
79
|
// src/fetch.ts
|
|
51
|
-
var
|
|
80
|
+
var STATUS_FALLBACKS = {
|
|
52
81
|
401: "Token has expired. Please run: arbi login",
|
|
82
|
+
403: "Access denied. You may not have permission for this workspace.",
|
|
83
|
+
404: "Resource not found.",
|
|
53
84
|
503: "The selected LLM is not responding. Please retry or select another model."
|
|
54
85
|
};
|
|
86
|
+
async function extractErrorMessage(res) {
|
|
87
|
+
let bodyDetail;
|
|
88
|
+
try {
|
|
89
|
+
const text = await res.text();
|
|
90
|
+
if (text) {
|
|
91
|
+
try {
|
|
92
|
+
const json = JSON.parse(text);
|
|
93
|
+
bodyDetail = json.detail || json.message || json.error || void 0;
|
|
94
|
+
} catch {
|
|
95
|
+
if (text.length < 200) bodyDetail = text;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
}
|
|
100
|
+
if (bodyDetail) return `Request failed (${res.status}): ${bodyDetail}`;
|
|
101
|
+
const fallback = STATUS_FALLBACKS[res.status];
|
|
102
|
+
if (fallback) return fallback;
|
|
103
|
+
return `Request failed: ${res.status} ${res.statusText}`;
|
|
104
|
+
}
|
|
55
105
|
async function authenticatedFetch(options) {
|
|
56
106
|
const { baseUrl, accessToken, workspaceKeyHeader, path: path3, method, body, headers } = options;
|
|
57
107
|
const res = await fetch(`${baseUrl}${path3}`, {
|
|
@@ -64,16 +114,15 @@ async function authenticatedFetch(options) {
|
|
|
64
114
|
body
|
|
65
115
|
});
|
|
66
116
|
if (!res.ok) {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
const text = await res.text().catch(() => "");
|
|
70
|
-
throw new Error(`Request failed: ${res.status} ${text}`);
|
|
117
|
+
const message = await extractErrorMessage(res);
|
|
118
|
+
throw new ArbiApiError(message, { status: res.status, statusText: res.statusText });
|
|
71
119
|
}
|
|
72
120
|
return res;
|
|
73
121
|
}
|
|
74
122
|
var DEFAULT_SESSION = {
|
|
75
123
|
lastMessageExtId: null,
|
|
76
|
-
conversationExtId: null
|
|
124
|
+
conversationExtId: null,
|
|
125
|
+
workspaceId: null
|
|
77
126
|
};
|
|
78
127
|
var FileConfigStore = class {
|
|
79
128
|
configDir;
|
|
@@ -81,10 +130,10 @@ var FileConfigStore = class {
|
|
|
81
130
|
credentialsFile;
|
|
82
131
|
sessionFile;
|
|
83
132
|
constructor(configDir) {
|
|
84
|
-
this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ??
|
|
85
|
-
this.configFile =
|
|
86
|
-
this.credentialsFile =
|
|
87
|
-
this.sessionFile =
|
|
133
|
+
this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ?? path2__default.default.join(os__default.default.homedir(), ".arbi");
|
|
134
|
+
this.configFile = path2__default.default.join(this.configDir, "config.json");
|
|
135
|
+
this.credentialsFile = path2__default.default.join(this.configDir, "credentials.json");
|
|
136
|
+
this.sessionFile = path2__default.default.join(this.configDir, "session.json");
|
|
88
137
|
}
|
|
89
138
|
ensureConfigDir() {
|
|
90
139
|
if (!fs__default.default.existsSync(this.configDir)) {
|
|
@@ -155,6 +204,77 @@ var FileConfigStore = class {
|
|
|
155
204
|
clearChatSession() {
|
|
156
205
|
this.saveChatSession({ ...DEFAULT_SESSION });
|
|
157
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Try to resolve config from multiple sources, in priority order:
|
|
209
|
+
*
|
|
210
|
+
* 1. Existing `~/.arbi/config.json` (highest priority)
|
|
211
|
+
* 2. `ARBI_SERVER_URL` environment variable
|
|
212
|
+
* 3. `.env` file in `searchDir` → read `VITE_DEPLOYMENT_DOMAIN`
|
|
213
|
+
* 4. `public/config.json` in `searchDir` → read `deployment.domain`
|
|
214
|
+
* 5. Default to `https://localhost`
|
|
215
|
+
*
|
|
216
|
+
* Returns `{ config, source }` where source describes where the config came from.
|
|
217
|
+
* Saves auto-detected config to disk so subsequent calls use the fast path.
|
|
218
|
+
*/
|
|
219
|
+
resolveConfigWithFallbacks(searchDir) {
|
|
220
|
+
const existing = this.getConfig();
|
|
221
|
+
if (existing?.baseUrl) {
|
|
222
|
+
return { config: existing, source: "config" };
|
|
223
|
+
}
|
|
224
|
+
const envUrl = process.env.ARBI_SERVER_URL;
|
|
225
|
+
if (envUrl) {
|
|
226
|
+
const domain = new URL(envUrl).hostname;
|
|
227
|
+
const config2 = { baseUrl: envUrl.replace(/\/$/, ""), deploymentDomain: domain };
|
|
228
|
+
this.saveConfig(config2);
|
|
229
|
+
return { config: config2, source: "ARBI_SERVER_URL env var" };
|
|
230
|
+
}
|
|
231
|
+
const dir = searchDir || process.cwd();
|
|
232
|
+
const dotenvConfig = this.readDotEnvDomain(path2__default.default.join(dir, ".env"));
|
|
233
|
+
if (dotenvConfig) {
|
|
234
|
+
this.saveConfig(dotenvConfig);
|
|
235
|
+
return { config: dotenvConfig, source: ".env file" };
|
|
236
|
+
}
|
|
237
|
+
const publicConfig = this.readPublicConfigDomain(path2__default.default.join(dir, "public", "config.json"));
|
|
238
|
+
if (publicConfig) {
|
|
239
|
+
this.saveConfig(publicConfig);
|
|
240
|
+
return { config: publicConfig, source: "public/config.json" };
|
|
241
|
+
}
|
|
242
|
+
const config = { baseUrl: "https://localhost", deploymentDomain: "localhost" };
|
|
243
|
+
this.saveConfig(config);
|
|
244
|
+
return { config, source: "default (https://localhost)" };
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Read VITE_DEPLOYMENT_DOMAIN from a .env file.
|
|
248
|
+
*/
|
|
249
|
+
readDotEnvDomain(filePath) {
|
|
250
|
+
try {
|
|
251
|
+
const content = fs__default.default.readFileSync(filePath, "utf-8");
|
|
252
|
+
const match = content.match(/^VITE_DEPLOYMENT_DOMAIN\s*=\s*(.+)$/m);
|
|
253
|
+
if (match) {
|
|
254
|
+
const domain = match[1].trim().replace(/^["']|["']$/g, "");
|
|
255
|
+
if (domain) {
|
|
256
|
+
return { baseUrl: `https://${domain}`, deploymentDomain: domain };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Read deployment.domain from a public/config.json file.
|
|
265
|
+
*/
|
|
266
|
+
readPublicConfigDomain(filePath) {
|
|
267
|
+
try {
|
|
268
|
+
const content = fs__default.default.readFileSync(filePath, "utf-8");
|
|
269
|
+
const json = JSON.parse(content);
|
|
270
|
+
const domain = json?.deployment?.domain;
|
|
271
|
+
if (domain) {
|
|
272
|
+
return { baseUrl: `https://${domain}`, deploymentDomain: domain };
|
|
273
|
+
}
|
|
274
|
+
} catch {
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
158
278
|
};
|
|
159
279
|
function formatWorkspaceChoices(wsList) {
|
|
160
280
|
return wsList.map((ws) => {
|
|
@@ -180,7 +300,11 @@ async function createAuthenticatedClient(config, creds, store) {
|
|
|
180
300
|
});
|
|
181
301
|
store.saveCredentials({
|
|
182
302
|
...creds,
|
|
183
|
-
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
|
|
303
|
+
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
|
|
304
|
+
accessToken: void 0,
|
|
305
|
+
workspaceKeyHeader: void 0,
|
|
306
|
+
workspaceId: void 0,
|
|
307
|
+
tokenTimestamp: void 0
|
|
184
308
|
});
|
|
185
309
|
return { arbi, loginResult };
|
|
186
310
|
}
|
|
@@ -195,7 +319,12 @@ async function performPasswordLogin(config, email, password, store) {
|
|
|
195
319
|
store.saveCredentials({
|
|
196
320
|
email,
|
|
197
321
|
signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),
|
|
198
|
-
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
|
|
322
|
+
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
|
|
323
|
+
// Clear any cached workspace tokens — new session key invalidates them
|
|
324
|
+
accessToken: void 0,
|
|
325
|
+
workspaceKeyHeader: void 0,
|
|
326
|
+
workspaceId: void 0,
|
|
327
|
+
tokenTimestamp: void 0
|
|
199
328
|
});
|
|
200
329
|
return { arbi, loginResult, config };
|
|
201
330
|
}
|
|
@@ -258,6 +387,10 @@ async function resolveAuth(store) {
|
|
|
258
387
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
259
388
|
return { arbi, loginResult, config };
|
|
260
389
|
}
|
|
390
|
+
var TOKEN_MAX_AGE_MS = 50 * 60 * 1e3;
|
|
391
|
+
function isCachedTokenValid(creds, workspaceId) {
|
|
392
|
+
return !!(creds.accessToken && creds.workspaceKeyHeader && creds.workspaceId === workspaceId && creds.tokenTimestamp && Date.now() - new Date(creds.tokenTimestamp).getTime() < TOKEN_MAX_AGE_MS);
|
|
393
|
+
}
|
|
261
394
|
async function resolveWorkspace(store, workspaceOpt) {
|
|
262
395
|
const config = store.requireConfig();
|
|
263
396
|
const creds = store.requireCredentials();
|
|
@@ -265,6 +398,32 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
265
398
|
if (!workspaceId) {
|
|
266
399
|
throw new ArbiError("No workspace selected. Run: arbi workspace select <id>");
|
|
267
400
|
}
|
|
401
|
+
if (isCachedTokenValid(creds, workspaceId)) {
|
|
402
|
+
const arbi2 = client.createArbiClient({
|
|
403
|
+
baseUrl: config.baseUrl,
|
|
404
|
+
deploymentDomain: config.deploymentDomain,
|
|
405
|
+
credentials: "omit"
|
|
406
|
+
});
|
|
407
|
+
await arbi2.crypto.initSodium();
|
|
408
|
+
arbi2.session.setSelectedWorkspace(workspaceId);
|
|
409
|
+
arbi2.session.setAccessToken(creds.accessToken);
|
|
410
|
+
arbi2.session.setCachedWorkspaceHeader(workspaceId, creds.workspaceKeyHeader);
|
|
411
|
+
const signingPrivateKey = client.base64ToBytes(creds.signingPrivateKeyBase64);
|
|
412
|
+
const serverSessionKey = client.base64ToBytes(creds.serverSessionKeyBase64);
|
|
413
|
+
const loginResult2 = {
|
|
414
|
+
accessToken: creds.accessToken,
|
|
415
|
+
signingPrivateKey,
|
|
416
|
+
serverSessionKey
|
|
417
|
+
};
|
|
418
|
+
return {
|
|
419
|
+
arbi: arbi2,
|
|
420
|
+
loginResult: loginResult2,
|
|
421
|
+
config,
|
|
422
|
+
workspaceId,
|
|
423
|
+
accessToken: creds.accessToken,
|
|
424
|
+
workspaceKeyHeader: creds.workspaceKeyHeader
|
|
425
|
+
};
|
|
426
|
+
}
|
|
268
427
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
269
428
|
await selectWorkspaceById(
|
|
270
429
|
arbi,
|
|
@@ -277,10 +436,57 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
277
436
|
if (!accessToken || !workspaceKeyHeader) {
|
|
278
437
|
throw new ArbiError("Authentication error \u2014 missing token or workspace key");
|
|
279
438
|
}
|
|
439
|
+
store.saveCredentials({
|
|
440
|
+
...store.requireCredentials(),
|
|
441
|
+
accessToken,
|
|
442
|
+
workspaceKeyHeader,
|
|
443
|
+
workspaceId,
|
|
444
|
+
tokenTimestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
445
|
+
});
|
|
280
446
|
return { arbi, loginResult, config, workspaceId, accessToken, workspaceKeyHeader };
|
|
281
447
|
}
|
|
282
448
|
|
|
283
449
|
// src/sse.ts
|
|
450
|
+
var TOOL_LABELS = {
|
|
451
|
+
search_documents: "Searching documents",
|
|
452
|
+
get_document_passages: "Reading document",
|
|
453
|
+
get_table_of_contents: "Getting table of contents",
|
|
454
|
+
view_document_pages: "Viewing document pages",
|
|
455
|
+
get_full_document: "Reading full document",
|
|
456
|
+
web_search: "Searching the web",
|
|
457
|
+
read_url: "Reading web pages",
|
|
458
|
+
ask_user: "Asking user",
|
|
459
|
+
compaction: "Compacting conversation",
|
|
460
|
+
personal_agent: "Running agent",
|
|
461
|
+
create_artifact: "Creating artifact",
|
|
462
|
+
create_plan: "Creating plan",
|
|
463
|
+
save_skill: "Saving skill",
|
|
464
|
+
run_code: "Running code"
|
|
465
|
+
};
|
|
466
|
+
var LIFECYCLE_LABELS = {
|
|
467
|
+
evaluation: "Evaluating results",
|
|
468
|
+
answering: "Writing answer",
|
|
469
|
+
reviewing: "Reviewing answer",
|
|
470
|
+
planning: "Planning",
|
|
471
|
+
tool_progress: "Working"
|
|
472
|
+
};
|
|
473
|
+
function formatAgentStepLabel(step) {
|
|
474
|
+
if (step.focus) return step.focus;
|
|
475
|
+
const detail = step.detail;
|
|
476
|
+
if (step.step === "tool_progress" && detail && detail.length > 0) {
|
|
477
|
+
const toolName = detail[0].tool;
|
|
478
|
+
const label = toolName && TOOL_LABELS[toolName] || LIFECYCLE_LABELS.tool_progress;
|
|
479
|
+
const message = detail[0].message;
|
|
480
|
+
return message ? `${label}: ${message}` : label;
|
|
481
|
+
}
|
|
482
|
+
if (step.step) {
|
|
483
|
+
return LIFECYCLE_LABELS[step.step] || step.step;
|
|
484
|
+
}
|
|
485
|
+
if (detail && detail.length > 0 && detail[0].tool) {
|
|
486
|
+
return TOOL_LABELS[detail[0].tool] || detail[0].tool;
|
|
487
|
+
}
|
|
488
|
+
return "";
|
|
489
|
+
}
|
|
284
490
|
function parseSSEEvents(chunk, buffer) {
|
|
285
491
|
const combined = buffer + chunk;
|
|
286
492
|
const events = [];
|
|
@@ -351,6 +557,11 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
351
557
|
usage = data.response.usage;
|
|
352
558
|
callbacks.onUsage?.(data.response.usage);
|
|
353
559
|
}
|
|
560
|
+
if (data.response?.metadata) {
|
|
561
|
+
const meta = data.response.metadata;
|
|
562
|
+
metadata = meta;
|
|
563
|
+
callbacks.onMetadata?.(meta);
|
|
564
|
+
}
|
|
354
565
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
355
566
|
callbacks.onComplete?.();
|
|
356
567
|
},
|
|
@@ -363,8 +574,8 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
363
574
|
// ARBI-specific events (dot-prefixed from server)
|
|
364
575
|
"arbi.agent_step": (raw) => {
|
|
365
576
|
const data = JSON.parse(raw);
|
|
366
|
-
const
|
|
367
|
-
if (
|
|
577
|
+
const label = formatAgentStepLabel(data);
|
|
578
|
+
if (label) agentSteps.push(label);
|
|
368
579
|
callbacks.onAgentStep?.(data);
|
|
369
580
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
370
581
|
},
|
|
@@ -642,16 +853,34 @@ function formatUserName(user) {
|
|
|
642
853
|
// src/operations/documents.ts
|
|
643
854
|
var documents_exports = {};
|
|
644
855
|
__export(documents_exports, {
|
|
856
|
+
SUPPORTED_EXTENSIONS: () => SUPPORTED_EXTENSIONS,
|
|
645
857
|
deleteDocuments: () => deleteDocuments,
|
|
646
858
|
downloadDocument: () => downloadDocument,
|
|
647
859
|
getDocuments: () => getDocuments,
|
|
648
860
|
getParsedContent: () => getParsedContent,
|
|
649
861
|
listDocuments: () => listDocuments,
|
|
862
|
+
sanitizeFolderPath: () => sanitizeFolderPath,
|
|
650
863
|
updateDocuments: () => updateDocuments,
|
|
651
864
|
uploadFile: () => uploadFile,
|
|
652
|
-
|
|
865
|
+
uploadFiles: () => uploadFiles,
|
|
653
866
|
uploadUrl: () => uploadUrl
|
|
654
867
|
});
|
|
868
|
+
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
869
|
+
".pdf",
|
|
870
|
+
".txt",
|
|
871
|
+
".md",
|
|
872
|
+
".html",
|
|
873
|
+
".doc",
|
|
874
|
+
".docx",
|
|
875
|
+
".rtf",
|
|
876
|
+
".ppt",
|
|
877
|
+
".pptx",
|
|
878
|
+
".xls",
|
|
879
|
+
".xlsx"
|
|
880
|
+
]);
|
|
881
|
+
function sanitizeFolderPath(folderPath) {
|
|
882
|
+
return folderPath.replace(/[^a-zA-Z0-9_\-/]/g, "_").replace(/_{2,}/g, "_");
|
|
883
|
+
}
|
|
655
884
|
async function listDocuments(arbi) {
|
|
656
885
|
return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
|
|
657
886
|
}
|
|
@@ -690,22 +919,31 @@ async function getParsedContent(auth, docId, stage) {
|
|
|
690
919
|
});
|
|
691
920
|
return res.json();
|
|
692
921
|
}
|
|
693
|
-
async function uploadFile(auth, workspaceId, fileData, fileName) {
|
|
922
|
+
async function uploadFile(auth, workspaceId, fileData, fileName, options) {
|
|
694
923
|
const formData = new FormData();
|
|
695
924
|
formData.append("files", fileData, fileName);
|
|
925
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
926
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
696
927
|
const res = await authenticatedFetch({
|
|
697
928
|
...auth,
|
|
698
|
-
path: `/v1/document/upload
|
|
929
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
699
930
|
method: "POST",
|
|
700
931
|
body: formData
|
|
701
932
|
});
|
|
702
933
|
return res.json();
|
|
703
934
|
}
|
|
704
|
-
async function
|
|
705
|
-
const
|
|
706
|
-
const
|
|
707
|
-
const
|
|
708
|
-
|
|
935
|
+
async function uploadFiles(auth, workspaceId, files, options) {
|
|
936
|
+
const formData = new FormData();
|
|
937
|
+
for (const f of files) formData.append("files", f.data, f.name);
|
|
938
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
939
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
940
|
+
const res = await authenticatedFetch({
|
|
941
|
+
...auth,
|
|
942
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
943
|
+
method: "POST",
|
|
944
|
+
body: formData
|
|
945
|
+
});
|
|
946
|
+
return res.json();
|
|
709
947
|
}
|
|
710
948
|
async function downloadDocument(auth, docId) {
|
|
711
949
|
return authenticatedFetch({
|
|
@@ -905,6 +1143,8 @@ async function retrieve(options) {
|
|
|
905
1143
|
input: query,
|
|
906
1144
|
workspace_ext_id: workspaceId,
|
|
907
1145
|
stream: false,
|
|
1146
|
+
background: false,
|
|
1147
|
+
store: true,
|
|
908
1148
|
tools,
|
|
909
1149
|
...model ? { model } : {}
|
|
910
1150
|
};
|
|
@@ -920,6 +1160,8 @@ async function queryAssistant(options) {
|
|
|
920
1160
|
input: question,
|
|
921
1161
|
workspace_ext_id: workspaceId,
|
|
922
1162
|
stream: true,
|
|
1163
|
+
background: false,
|
|
1164
|
+
store: true,
|
|
923
1165
|
tools: {
|
|
924
1166
|
retrieval_chunk: buildRetrievalChunkTool(docIds),
|
|
925
1167
|
retrieval_full_context: buildRetrievalFullContextTool([])
|
|
@@ -1379,11 +1621,12 @@ var Arbi = class {
|
|
|
1379
1621
|
workspaceId ?? this.requireWorkspace(),
|
|
1380
1622
|
shared
|
|
1381
1623
|
),
|
|
1382
|
-
uploadFile: (fileData, fileName,
|
|
1624
|
+
uploadFile: (fileData, fileName, options) => uploadFile(
|
|
1383
1625
|
this.getAuthHeaders(),
|
|
1384
|
-
workspaceId ?? this.requireWorkspace(),
|
|
1626
|
+
options?.workspaceId ?? this.requireWorkspace(),
|
|
1385
1627
|
fileData,
|
|
1386
|
-
fileName
|
|
1628
|
+
fileName,
|
|
1629
|
+
options?.folder ? { folder: options.folder } : void 0
|
|
1387
1630
|
),
|
|
1388
1631
|
download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
|
|
1389
1632
|
getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
|
|
@@ -1525,10 +1768,129 @@ var Arbi = class {
|
|
|
1525
1768
|
}
|
|
1526
1769
|
};
|
|
1527
1770
|
|
|
1771
|
+
// src/operations/documents-node.ts
|
|
1772
|
+
var documents_node_exports = {};
|
|
1773
|
+
__export(documents_node_exports, {
|
|
1774
|
+
uploadDirectory: () => uploadDirectory,
|
|
1775
|
+
uploadLocalFile: () => uploadLocalFile,
|
|
1776
|
+
uploadZip: () => uploadZip
|
|
1777
|
+
});
|
|
1778
|
+
function collectFiles(dirPath, baseDir) {
|
|
1779
|
+
const root = baseDir ?? dirPath;
|
|
1780
|
+
const results = [];
|
|
1781
|
+
for (const entry of fs__default.default.readdirSync(dirPath, { withFileTypes: true })) {
|
|
1782
|
+
const fullPath = path2__default.default.join(dirPath, entry.name);
|
|
1783
|
+
if (entry.isDirectory()) {
|
|
1784
|
+
results.push(...collectFiles(fullPath, root));
|
|
1785
|
+
} else if (entry.isFile()) {
|
|
1786
|
+
const ext = path2__default.default.extname(entry.name).toLowerCase();
|
|
1787
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1788
|
+
results.push({ absolutePath: fullPath, relativePath: path2__default.default.relative(root, fullPath) });
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
return results;
|
|
1793
|
+
}
|
|
1794
|
+
async function uploadLocalFile(auth, workspaceId, filePath, options) {
|
|
1795
|
+
const fileBuffer = fs__default.default.readFileSync(filePath);
|
|
1796
|
+
const fileName = path2__default.default.basename(filePath);
|
|
1797
|
+
const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName, options);
|
|
1798
|
+
return { ...result, fileName };
|
|
1799
|
+
}
|
|
1800
|
+
async function uploadDirectory(auth, workspaceId, dirPath) {
|
|
1801
|
+
const resolvedDir = path2__default.default.resolve(dirPath);
|
|
1802
|
+
const dirName = path2__default.default.basename(resolvedDir);
|
|
1803
|
+
const entries = collectFiles(resolvedDir);
|
|
1804
|
+
if (entries.length === 0) {
|
|
1805
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1806
|
+
}
|
|
1807
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1808
|
+
for (const entry of entries) {
|
|
1809
|
+
const relDir = path2__default.default.dirname(entry.relativePath);
|
|
1810
|
+
const folder = relDir === "." ? dirName : `${dirName}/${relDir}`;
|
|
1811
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1812
|
+
groups.get(folder).push({ absolutePath: entry.absolutePath, name: path2__default.default.basename(entry.relativePath) });
|
|
1813
|
+
}
|
|
1814
|
+
const allDocIds = [];
|
|
1815
|
+
const allDuplicates = [];
|
|
1816
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1817
|
+
for (const [folder, files] of groups) {
|
|
1818
|
+
const blobs = files.map((f) => ({
|
|
1819
|
+
data: new Blob([fs__default.default.readFileSync(f.absolutePath)]),
|
|
1820
|
+
name: f.name
|
|
1821
|
+
}));
|
|
1822
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1823
|
+
const dups = result.duplicates ?? [];
|
|
1824
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1825
|
+
allDuplicates.push(...dups);
|
|
1826
|
+
folders.set(folder, {
|
|
1827
|
+
fileCount: files.length,
|
|
1828
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1829
|
+
duplicates: dups
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1833
|
+
}
|
|
1834
|
+
async function uploadZip(auth, workspaceId, zipPath) {
|
|
1835
|
+
const JSZip = (await import('jszip')).default;
|
|
1836
|
+
const zipBuffer = fs__default.default.readFileSync(zipPath);
|
|
1837
|
+
const zip = await JSZip.loadAsync(zipBuffer);
|
|
1838
|
+
const zipBaseName = path2__default.default.basename(zipPath).replace(/\.zip$/i, "");
|
|
1839
|
+
const entries = [];
|
|
1840
|
+
zip.forEach((relativePath, zipEntry) => {
|
|
1841
|
+
if (zipEntry.dir) return;
|
|
1842
|
+
const ext = path2__default.default.extname(relativePath).toLowerCase();
|
|
1843
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1844
|
+
entries.push({ zipEntryPath: relativePath, zipEntry });
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
if (entries.length === 0) {
|
|
1848
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1849
|
+
}
|
|
1850
|
+
const firstParts = new Set(entries.map((e) => e.zipEntryPath.split("/")[0]));
|
|
1851
|
+
const hasSingleRoot = firstParts.size === 1 && entries.every((e) => e.zipEntryPath.includes("/"));
|
|
1852
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1853
|
+
for (const entry of entries) {
|
|
1854
|
+
const data = await entry.zipEntry.async("uint8array");
|
|
1855
|
+
const fileName = path2__default.default.basename(entry.zipEntryPath);
|
|
1856
|
+
const relDir = path2__default.default.dirname(entry.zipEntryPath);
|
|
1857
|
+
let folder;
|
|
1858
|
+
if (hasSingleRoot) {
|
|
1859
|
+
folder = relDir === "." ? zipBaseName : relDir;
|
|
1860
|
+
} else {
|
|
1861
|
+
folder = relDir === "." ? zipBaseName : `${zipBaseName}/${relDir}`;
|
|
1862
|
+
}
|
|
1863
|
+
folder = sanitizeFolderPath(folder);
|
|
1864
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1865
|
+
groups.get(folder).push({ name: fileName, data });
|
|
1866
|
+
}
|
|
1867
|
+
const allDocIds = [];
|
|
1868
|
+
const allDuplicates = [];
|
|
1869
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1870
|
+
for (const [folder, files] of groups) {
|
|
1871
|
+
const blobs = files.map((f) => ({
|
|
1872
|
+
data: new Blob([f.data]),
|
|
1873
|
+
name: f.name
|
|
1874
|
+
}));
|
|
1875
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1876
|
+
const dups = result.duplicates ?? [];
|
|
1877
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1878
|
+
allDuplicates.push(...dups);
|
|
1879
|
+
folders.set(folder, {
|
|
1880
|
+
fileCount: files.length,
|
|
1881
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1882
|
+
duplicates: dups
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1528
1888
|
exports.Arbi = Arbi;
|
|
1529
1889
|
exports.ArbiApiError = ArbiApiError;
|
|
1530
1890
|
exports.ArbiError = ArbiError;
|
|
1531
1891
|
exports.FileConfigStore = FileConfigStore;
|
|
1892
|
+
exports.LIFECYCLE_LABELS = LIFECYCLE_LABELS;
|
|
1893
|
+
exports.TOOL_LABELS = TOOL_LABELS;
|
|
1532
1894
|
exports.agentconfig = agentconfig_exports;
|
|
1533
1895
|
exports.assistant = assistant_exports;
|
|
1534
1896
|
exports.authenticatedFetch = authenticatedFetch;
|
|
@@ -1545,12 +1907,15 @@ exports.createDocumentWaiter = createDocumentWaiter;
|
|
|
1545
1907
|
exports.dm = dm_exports;
|
|
1546
1908
|
exports.doctags = doctags_exports;
|
|
1547
1909
|
exports.documents = documents_exports;
|
|
1910
|
+
exports.documentsNode = documents_node_exports;
|
|
1548
1911
|
exports.files = files_exports;
|
|
1912
|
+
exports.formatAgentStepLabel = formatAgentStepLabel;
|
|
1549
1913
|
exports.formatFileSize = formatFileSize;
|
|
1550
1914
|
exports.formatUserName = formatUserName;
|
|
1551
1915
|
exports.formatWorkspaceChoices = formatWorkspaceChoices;
|
|
1552
1916
|
exports.formatWsMessage = formatWsMessage;
|
|
1553
1917
|
exports.generateEncryptedWorkspaceKey = generateEncryptedWorkspaceKey;
|
|
1918
|
+
exports.getErrorCode = getErrorCode;
|
|
1554
1919
|
exports.getErrorMessage = getErrorMessage;
|
|
1555
1920
|
exports.health = health_exports;
|
|
1556
1921
|
exports.parseSSEEvents = parseSSEEvents;
|