@arbidocs/sdk 0.3.11 → 0.3.14
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-DtwXhEkG.d.cts +3230 -0
- package/dist/browser-DtwXhEkG.d.ts +3230 -0
- package/dist/browser.cjs +232 -26
- 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 +229 -22
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +445 -23
- 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 +439 -23
- 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 = [];
|
|
@@ -320,11 +506,13 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
320
506
|
let text = "";
|
|
321
507
|
let assistantMessageExtId = null;
|
|
322
508
|
const agentSteps = [];
|
|
509
|
+
let toolCallCount = 0;
|
|
323
510
|
const errors = [];
|
|
324
511
|
const artifacts = [];
|
|
325
512
|
let userMessage = null;
|
|
326
513
|
let metadata = null;
|
|
327
514
|
let usage = null;
|
|
515
|
+
let context = null;
|
|
328
516
|
const eventHandlers = {
|
|
329
517
|
// OpenAI Responses API events (dot-separated names from server)
|
|
330
518
|
"response.created": (raw) => {
|
|
@@ -368,6 +556,9 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
368
556
|
metadata = meta;
|
|
369
557
|
callbacks.onMetadata?.(meta);
|
|
370
558
|
}
|
|
559
|
+
if (data.context) {
|
|
560
|
+
context = data.context;
|
|
561
|
+
}
|
|
371
562
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
372
563
|
callbacks.onComplete?.();
|
|
373
564
|
},
|
|
@@ -380,8 +571,12 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
380
571
|
// ARBI-specific events (dot-prefixed from server)
|
|
381
572
|
"arbi.agent_step": (raw) => {
|
|
382
573
|
const data = JSON.parse(raw);
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
574
|
+
const label = formatAgentStepLabel(data);
|
|
575
|
+
if (label) agentSteps.push(label);
|
|
576
|
+
const detail = data.detail;
|
|
577
|
+
if (detail && Array.isArray(detail)) {
|
|
578
|
+
toolCallCount += detail.filter((d) => d.tool).length;
|
|
579
|
+
}
|
|
385
580
|
callbacks.onAgentStep?.(data);
|
|
386
581
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
387
582
|
},
|
|
@@ -432,11 +627,13 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
432
627
|
text,
|
|
433
628
|
assistantMessageExtId,
|
|
434
629
|
agentSteps,
|
|
630
|
+
toolCallCount,
|
|
435
631
|
errors,
|
|
436
632
|
userMessage,
|
|
437
633
|
metadata,
|
|
438
634
|
artifacts,
|
|
439
|
-
usage
|
|
635
|
+
usage,
|
|
636
|
+
context
|
|
440
637
|
};
|
|
441
638
|
}
|
|
442
639
|
var consumeSSEStream = streamSSE;
|
|
@@ -635,6 +832,13 @@ function formatWsMessage(msg) {
|
|
|
635
832
|
if (isMessageType(msg, "presence_update")) {
|
|
636
833
|
return { text: `${msg.user_id} is ${msg.status}`, level: "info" };
|
|
637
834
|
}
|
|
835
|
+
if (isMessageType(msg, "response_complete")) {
|
|
836
|
+
const icon = msg.status === "completed" ? "\u2713" : "\u2717";
|
|
837
|
+
return {
|
|
838
|
+
text: `${icon} Task ${msg.response_id} ${msg.status}`,
|
|
839
|
+
level: msg.status === "completed" ? "success" : "error"
|
|
840
|
+
};
|
|
841
|
+
}
|
|
638
842
|
if (isNotification(msg)) {
|
|
639
843
|
const sender = msg.sender?.email || "someone";
|
|
640
844
|
const content = msg.content ?? msg.type;
|
|
@@ -659,16 +863,34 @@ function formatUserName(user) {
|
|
|
659
863
|
// src/operations/documents.ts
|
|
660
864
|
var documents_exports = {};
|
|
661
865
|
__export(documents_exports, {
|
|
866
|
+
SUPPORTED_EXTENSIONS: () => SUPPORTED_EXTENSIONS,
|
|
662
867
|
deleteDocuments: () => deleteDocuments,
|
|
663
868
|
downloadDocument: () => downloadDocument,
|
|
664
869
|
getDocuments: () => getDocuments,
|
|
665
870
|
getParsedContent: () => getParsedContent,
|
|
666
871
|
listDocuments: () => listDocuments,
|
|
872
|
+
sanitizeFolderPath: () => sanitizeFolderPath,
|
|
667
873
|
updateDocuments: () => updateDocuments,
|
|
668
874
|
uploadFile: () => uploadFile,
|
|
669
|
-
|
|
875
|
+
uploadFiles: () => uploadFiles,
|
|
670
876
|
uploadUrl: () => uploadUrl
|
|
671
877
|
});
|
|
878
|
+
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
879
|
+
".pdf",
|
|
880
|
+
".txt",
|
|
881
|
+
".md",
|
|
882
|
+
".html",
|
|
883
|
+
".doc",
|
|
884
|
+
".docx",
|
|
885
|
+
".rtf",
|
|
886
|
+
".ppt",
|
|
887
|
+
".pptx",
|
|
888
|
+
".xls",
|
|
889
|
+
".xlsx"
|
|
890
|
+
]);
|
|
891
|
+
function sanitizeFolderPath(folderPath) {
|
|
892
|
+
return folderPath.replace(/[^a-zA-Z0-9_\-/]/g, "_").replace(/_{2,}/g, "_");
|
|
893
|
+
}
|
|
672
894
|
async function listDocuments(arbi) {
|
|
673
895
|
return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
|
|
674
896
|
}
|
|
@@ -707,22 +929,31 @@ async function getParsedContent(auth, docId, stage) {
|
|
|
707
929
|
});
|
|
708
930
|
return res.json();
|
|
709
931
|
}
|
|
710
|
-
async function uploadFile(auth, workspaceId, fileData, fileName) {
|
|
932
|
+
async function uploadFile(auth, workspaceId, fileData, fileName, options) {
|
|
711
933
|
const formData = new FormData();
|
|
712
934
|
formData.append("files", fileData, fileName);
|
|
935
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
936
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
713
937
|
const res = await authenticatedFetch({
|
|
714
938
|
...auth,
|
|
715
|
-
path: `/v1/document/upload
|
|
939
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
716
940
|
method: "POST",
|
|
717
941
|
body: formData
|
|
718
942
|
});
|
|
719
943
|
return res.json();
|
|
720
944
|
}
|
|
721
|
-
async function
|
|
722
|
-
const
|
|
723
|
-
const
|
|
724
|
-
const
|
|
725
|
-
|
|
945
|
+
async function uploadFiles(auth, workspaceId, files, options) {
|
|
946
|
+
const formData = new FormData();
|
|
947
|
+
for (const f of files) formData.append("files", f.data, f.name);
|
|
948
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
949
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
950
|
+
const res = await authenticatedFetch({
|
|
951
|
+
...auth,
|
|
952
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
953
|
+
method: "POST",
|
|
954
|
+
body: formData
|
|
955
|
+
});
|
|
956
|
+
return res.json();
|
|
726
957
|
}
|
|
727
958
|
async function downloadDocument(auth, docId) {
|
|
728
959
|
return authenticatedFetch({
|
|
@@ -922,6 +1153,8 @@ async function retrieve(options) {
|
|
|
922
1153
|
input: query,
|
|
923
1154
|
workspace_ext_id: workspaceId,
|
|
924
1155
|
stream: false,
|
|
1156
|
+
background: false,
|
|
1157
|
+
store: true,
|
|
925
1158
|
tools,
|
|
926
1159
|
...model ? { model } : {}
|
|
927
1160
|
};
|
|
@@ -937,6 +1170,8 @@ async function queryAssistant(options) {
|
|
|
937
1170
|
input: question,
|
|
938
1171
|
workspace_ext_id: workspaceId,
|
|
939
1172
|
stream: true,
|
|
1173
|
+
background: false,
|
|
1174
|
+
store: true,
|
|
940
1175
|
tools: {
|
|
941
1176
|
retrieval_chunk: buildRetrievalChunkTool(docIds),
|
|
942
1177
|
retrieval_full_context: buildRetrievalFullContextTool([])
|
|
@@ -1396,11 +1631,12 @@ var Arbi = class {
|
|
|
1396
1631
|
workspaceId ?? this.requireWorkspace(),
|
|
1397
1632
|
shared
|
|
1398
1633
|
),
|
|
1399
|
-
uploadFile: (fileData, fileName,
|
|
1634
|
+
uploadFile: (fileData, fileName, options) => uploadFile(
|
|
1400
1635
|
this.getAuthHeaders(),
|
|
1401
|
-
workspaceId ?? this.requireWorkspace(),
|
|
1636
|
+
options?.workspaceId ?? this.requireWorkspace(),
|
|
1402
1637
|
fileData,
|
|
1403
|
-
fileName
|
|
1638
|
+
fileName,
|
|
1639
|
+
options?.folder ? { folder: options.folder } : void 0
|
|
1404
1640
|
),
|
|
1405
1641
|
download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
|
|
1406
1642
|
getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
|
|
@@ -1542,6 +1778,186 @@ var Arbi = class {
|
|
|
1542
1778
|
}
|
|
1543
1779
|
};
|
|
1544
1780
|
|
|
1545
|
-
|
|
1781
|
+
// src/operations/documents-node.ts
|
|
1782
|
+
var documents_node_exports = {};
|
|
1783
|
+
__export(documents_node_exports, {
|
|
1784
|
+
uploadDirectory: () => uploadDirectory,
|
|
1785
|
+
uploadLocalFile: () => uploadLocalFile,
|
|
1786
|
+
uploadZip: () => uploadZip
|
|
1787
|
+
});
|
|
1788
|
+
function collectFiles(dirPath, baseDir) {
|
|
1789
|
+
const root = baseDir ?? dirPath;
|
|
1790
|
+
const results = [];
|
|
1791
|
+
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
|
|
1792
|
+
const fullPath = path2.join(dirPath, entry.name);
|
|
1793
|
+
if (entry.isDirectory()) {
|
|
1794
|
+
results.push(...collectFiles(fullPath, root));
|
|
1795
|
+
} else if (entry.isFile()) {
|
|
1796
|
+
const ext = path2.extname(entry.name).toLowerCase();
|
|
1797
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1798
|
+
results.push({ absolutePath: fullPath, relativePath: path2.relative(root, fullPath) });
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
return results;
|
|
1803
|
+
}
|
|
1804
|
+
async function uploadLocalFile(auth, workspaceId, filePath, options) {
|
|
1805
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
1806
|
+
const fileName = path2.basename(filePath);
|
|
1807
|
+
const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName, options);
|
|
1808
|
+
return { ...result, fileName };
|
|
1809
|
+
}
|
|
1810
|
+
async function uploadDirectory(auth, workspaceId, dirPath) {
|
|
1811
|
+
const resolvedDir = path2.resolve(dirPath);
|
|
1812
|
+
const dirName = path2.basename(resolvedDir);
|
|
1813
|
+
const entries = collectFiles(resolvedDir);
|
|
1814
|
+
if (entries.length === 0) {
|
|
1815
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1816
|
+
}
|
|
1817
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1818
|
+
for (const entry of entries) {
|
|
1819
|
+
const relDir = path2.dirname(entry.relativePath);
|
|
1820
|
+
const folder = relDir === "." ? dirName : `${dirName}/${relDir}`;
|
|
1821
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1822
|
+
groups.get(folder).push({ absolutePath: entry.absolutePath, name: path2.basename(entry.relativePath) });
|
|
1823
|
+
}
|
|
1824
|
+
const allDocIds = [];
|
|
1825
|
+
const allDuplicates = [];
|
|
1826
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1827
|
+
for (const [folder, files] of groups) {
|
|
1828
|
+
const blobs = files.map((f) => ({
|
|
1829
|
+
data: new Blob([fs.readFileSync(f.absolutePath)]),
|
|
1830
|
+
name: f.name
|
|
1831
|
+
}));
|
|
1832
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1833
|
+
const dups = result.duplicates ?? [];
|
|
1834
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1835
|
+
allDuplicates.push(...dups);
|
|
1836
|
+
folders.set(folder, {
|
|
1837
|
+
fileCount: files.length,
|
|
1838
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1839
|
+
duplicates: dups
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1843
|
+
}
|
|
1844
|
+
async function uploadZip(auth, workspaceId, zipPath) {
|
|
1845
|
+
const JSZip = (await import('jszip')).default;
|
|
1846
|
+
const zipBuffer = fs.readFileSync(zipPath);
|
|
1847
|
+
const zip = await JSZip.loadAsync(zipBuffer);
|
|
1848
|
+
const zipBaseName = path2.basename(zipPath).replace(/\.zip$/i, "");
|
|
1849
|
+
const entries = [];
|
|
1850
|
+
zip.forEach((relativePath, zipEntry) => {
|
|
1851
|
+
if (zipEntry.dir) return;
|
|
1852
|
+
const ext = path2.extname(relativePath).toLowerCase();
|
|
1853
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1854
|
+
entries.push({ zipEntryPath: relativePath, zipEntry });
|
|
1855
|
+
}
|
|
1856
|
+
});
|
|
1857
|
+
if (entries.length === 0) {
|
|
1858
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1859
|
+
}
|
|
1860
|
+
const firstParts = new Set(entries.map((e) => e.zipEntryPath.split("/")[0]));
|
|
1861
|
+
const hasSingleRoot = firstParts.size === 1 && entries.every((e) => e.zipEntryPath.includes("/"));
|
|
1862
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1863
|
+
for (const entry of entries) {
|
|
1864
|
+
const data = await entry.zipEntry.async("uint8array");
|
|
1865
|
+
const fileName = path2.basename(entry.zipEntryPath);
|
|
1866
|
+
const relDir = path2.dirname(entry.zipEntryPath);
|
|
1867
|
+
let folder;
|
|
1868
|
+
if (hasSingleRoot) {
|
|
1869
|
+
folder = relDir === "." ? zipBaseName : relDir;
|
|
1870
|
+
} else {
|
|
1871
|
+
folder = relDir === "." ? zipBaseName : `${zipBaseName}/${relDir}`;
|
|
1872
|
+
}
|
|
1873
|
+
folder = sanitizeFolderPath(folder);
|
|
1874
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1875
|
+
groups.get(folder).push({ name: fileName, data });
|
|
1876
|
+
}
|
|
1877
|
+
const allDocIds = [];
|
|
1878
|
+
const allDuplicates = [];
|
|
1879
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1880
|
+
for (const [folder, files] of groups) {
|
|
1881
|
+
const blobs = files.map((f) => ({
|
|
1882
|
+
data: new Blob([f.data]),
|
|
1883
|
+
name: f.name
|
|
1884
|
+
}));
|
|
1885
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1886
|
+
const dups = result.duplicates ?? [];
|
|
1887
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1888
|
+
allDuplicates.push(...dups);
|
|
1889
|
+
folders.set(folder, {
|
|
1890
|
+
fileCount: files.length,
|
|
1891
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1892
|
+
duplicates: dups
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
// src/operations/responses.ts
|
|
1899
|
+
var responses_exports = {};
|
|
1900
|
+
__export(responses_exports, {
|
|
1901
|
+
extractResponseText: () => extractResponseText,
|
|
1902
|
+
getResponse: () => getResponse,
|
|
1903
|
+
submitBackgroundQuery: () => submitBackgroundQuery
|
|
1904
|
+
});
|
|
1905
|
+
async function submitBackgroundQuery(options) {
|
|
1906
|
+
const { workspaceId, question, docIds, previousResponseId, model, ...auth } = options;
|
|
1907
|
+
const tools = {};
|
|
1908
|
+
if (docIds.length > 0) {
|
|
1909
|
+
tools.retrieval_chunk = {
|
|
1910
|
+
name: "retrieval_chunk",
|
|
1911
|
+
description: "retrieval chunk",
|
|
1912
|
+
tool_args: { doc_ext_ids: docIds },
|
|
1913
|
+
tool_responses: {}
|
|
1914
|
+
};
|
|
1915
|
+
tools.retrieval_full_context = {
|
|
1916
|
+
name: "retrieval_full_context",
|
|
1917
|
+
description: "retrieval full context",
|
|
1918
|
+
tool_args: { doc_ext_ids: [] },
|
|
1919
|
+
tool_responses: {}
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
const body = {
|
|
1923
|
+
input: question,
|
|
1924
|
+
workspace_ext_id: workspaceId,
|
|
1925
|
+
stream: false,
|
|
1926
|
+
background: true,
|
|
1927
|
+
store: true,
|
|
1928
|
+
tools,
|
|
1929
|
+
...previousResponseId ? { previous_response_id: previousResponseId } : {},
|
|
1930
|
+
...model ? { model } : {}
|
|
1931
|
+
};
|
|
1932
|
+
const res = await authenticatedFetch({
|
|
1933
|
+
...auth,
|
|
1934
|
+
path: "/v1/responses",
|
|
1935
|
+
method: "POST",
|
|
1936
|
+
body: JSON.stringify(body),
|
|
1937
|
+
headers: { "Content-Type": "application/json" }
|
|
1938
|
+
});
|
|
1939
|
+
return await res.json();
|
|
1940
|
+
}
|
|
1941
|
+
async function getResponse(auth, responseId) {
|
|
1942
|
+
const res = await authenticatedFetch({
|
|
1943
|
+
...auth,
|
|
1944
|
+
path: `/v1/responses/${responseId}`,
|
|
1945
|
+
method: "GET"
|
|
1946
|
+
});
|
|
1947
|
+
return await res.json();
|
|
1948
|
+
}
|
|
1949
|
+
function extractResponseText(response) {
|
|
1950
|
+
const parts = [];
|
|
1951
|
+
for (const msg of response.output) {
|
|
1952
|
+
for (const item of msg.content) {
|
|
1953
|
+
if ("type" in item && item.type === "output_text" && "text" in item) {
|
|
1954
|
+
parts.push(item.text);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
return parts.join("");
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
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, responses_exports as responses, selectWorkspace, selectWorkspaceById, settings_exports as settings, streamSSE, tags_exports as tags, workspaces_exports as workspaces };
|
|
1546
1962
|
//# sourceMappingURL=index.js.map
|
|
1547
1963
|
//# sourceMappingURL=index.js.map
|