@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.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,7 +44,36 @@ 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
|
|
@@ -101,10 +130,10 @@ var FileConfigStore = class {
|
|
|
101
130
|
credentialsFile;
|
|
102
131
|
sessionFile;
|
|
103
132
|
constructor(configDir) {
|
|
104
|
-
this.configDir = configDir ?? process.env.ARBI_CONFIG_DIR ??
|
|
105
|
-
this.configFile =
|
|
106
|
-
this.credentialsFile =
|
|
107
|
-
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");
|
|
108
137
|
}
|
|
109
138
|
ensureConfigDir() {
|
|
110
139
|
if (!fs__default.default.existsSync(this.configDir)) {
|
|
@@ -175,6 +204,77 @@ var FileConfigStore = class {
|
|
|
175
204
|
clearChatSession() {
|
|
176
205
|
this.saveChatSession({ ...DEFAULT_SESSION });
|
|
177
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
|
+
}
|
|
178
278
|
};
|
|
179
279
|
function formatWorkspaceChoices(wsList) {
|
|
180
280
|
return wsList.map((ws) => {
|
|
@@ -200,7 +300,11 @@ async function createAuthenticatedClient(config, creds, store) {
|
|
|
200
300
|
});
|
|
201
301
|
store.saveCredentials({
|
|
202
302
|
...creds,
|
|
203
|
-
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
|
|
204
308
|
});
|
|
205
309
|
return { arbi, loginResult };
|
|
206
310
|
}
|
|
@@ -215,7 +319,12 @@ async function performPasswordLogin(config, email, password, store) {
|
|
|
215
319
|
store.saveCredentials({
|
|
216
320
|
email,
|
|
217
321
|
signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),
|
|
218
|
-
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
|
|
219
328
|
});
|
|
220
329
|
return { arbi, loginResult, config };
|
|
221
330
|
}
|
|
@@ -278,6 +387,10 @@ async function resolveAuth(store) {
|
|
|
278
387
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
279
388
|
return { arbi, loginResult, config };
|
|
280
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
|
+
}
|
|
281
394
|
async function resolveWorkspace(store, workspaceOpt) {
|
|
282
395
|
const config = store.requireConfig();
|
|
283
396
|
const creds = store.requireCredentials();
|
|
@@ -285,6 +398,32 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
285
398
|
if (!workspaceId) {
|
|
286
399
|
throw new ArbiError("No workspace selected. Run: arbi workspace select <id>");
|
|
287
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
|
+
}
|
|
288
427
|
const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
|
|
289
428
|
await selectWorkspaceById(
|
|
290
429
|
arbi,
|
|
@@ -297,10 +436,57 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
297
436
|
if (!accessToken || !workspaceKeyHeader) {
|
|
298
437
|
throw new ArbiError("Authentication error \u2014 missing token or workspace key");
|
|
299
438
|
}
|
|
439
|
+
store.saveCredentials({
|
|
440
|
+
...store.requireCredentials(),
|
|
441
|
+
accessToken,
|
|
442
|
+
workspaceKeyHeader,
|
|
443
|
+
workspaceId,
|
|
444
|
+
tokenTimestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
445
|
+
});
|
|
300
446
|
return { arbi, loginResult, config, workspaceId, accessToken, workspaceKeyHeader };
|
|
301
447
|
}
|
|
302
448
|
|
|
303
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
|
+
}
|
|
304
490
|
function parseSSEEvents(chunk, buffer) {
|
|
305
491
|
const combined = buffer + chunk;
|
|
306
492
|
const events = [];
|
|
@@ -328,11 +514,13 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
328
514
|
let text = "";
|
|
329
515
|
let assistantMessageExtId = null;
|
|
330
516
|
const agentSteps = [];
|
|
517
|
+
let toolCallCount = 0;
|
|
331
518
|
const errors = [];
|
|
332
519
|
const artifacts = [];
|
|
333
520
|
let userMessage = null;
|
|
334
521
|
let metadata = null;
|
|
335
522
|
let usage = null;
|
|
523
|
+
let context = null;
|
|
336
524
|
const eventHandlers = {
|
|
337
525
|
// OpenAI Responses API events (dot-separated names from server)
|
|
338
526
|
"response.created": (raw) => {
|
|
@@ -376,6 +564,9 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
376
564
|
metadata = meta;
|
|
377
565
|
callbacks.onMetadata?.(meta);
|
|
378
566
|
}
|
|
567
|
+
if (data.context) {
|
|
568
|
+
context = data.context;
|
|
569
|
+
}
|
|
379
570
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
380
571
|
callbacks.onComplete?.();
|
|
381
572
|
},
|
|
@@ -388,8 +579,12 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
388
579
|
// ARBI-specific events (dot-prefixed from server)
|
|
389
580
|
"arbi.agent_step": (raw) => {
|
|
390
581
|
const data = JSON.parse(raw);
|
|
391
|
-
const
|
|
392
|
-
if (
|
|
582
|
+
const label = formatAgentStepLabel(data);
|
|
583
|
+
if (label) agentSteps.push(label);
|
|
584
|
+
const detail = data.detail;
|
|
585
|
+
if (detail && Array.isArray(detail)) {
|
|
586
|
+
toolCallCount += detail.filter((d) => d.tool).length;
|
|
587
|
+
}
|
|
393
588
|
callbacks.onAgentStep?.(data);
|
|
394
589
|
if (data.t != null) callbacks.onElapsedTime?.(data.t);
|
|
395
590
|
},
|
|
@@ -440,11 +635,13 @@ async function streamSSE(response, callbacks = {}) {
|
|
|
440
635
|
text,
|
|
441
636
|
assistantMessageExtId,
|
|
442
637
|
agentSteps,
|
|
638
|
+
toolCallCount,
|
|
443
639
|
errors,
|
|
444
640
|
userMessage,
|
|
445
641
|
metadata,
|
|
446
642
|
artifacts,
|
|
447
|
-
usage
|
|
643
|
+
usage,
|
|
644
|
+
context
|
|
448
645
|
};
|
|
449
646
|
}
|
|
450
647
|
var consumeSSEStream = streamSSE;
|
|
@@ -643,6 +840,13 @@ function formatWsMessage(msg) {
|
|
|
643
840
|
if (client.isMessageType(msg, "presence_update")) {
|
|
644
841
|
return { text: `${msg.user_id} is ${msg.status}`, level: "info" };
|
|
645
842
|
}
|
|
843
|
+
if (client.isMessageType(msg, "response_complete")) {
|
|
844
|
+
const icon = msg.status === "completed" ? "\u2713" : "\u2717";
|
|
845
|
+
return {
|
|
846
|
+
text: `${icon} Task ${msg.response_id} ${msg.status}`,
|
|
847
|
+
level: msg.status === "completed" ? "success" : "error"
|
|
848
|
+
};
|
|
849
|
+
}
|
|
646
850
|
if (isNotification(msg)) {
|
|
647
851
|
const sender = msg.sender?.email || "someone";
|
|
648
852
|
const content = msg.content ?? msg.type;
|
|
@@ -667,16 +871,34 @@ function formatUserName(user) {
|
|
|
667
871
|
// src/operations/documents.ts
|
|
668
872
|
var documents_exports = {};
|
|
669
873
|
__export(documents_exports, {
|
|
874
|
+
SUPPORTED_EXTENSIONS: () => SUPPORTED_EXTENSIONS,
|
|
670
875
|
deleteDocuments: () => deleteDocuments,
|
|
671
876
|
downloadDocument: () => downloadDocument,
|
|
672
877
|
getDocuments: () => getDocuments,
|
|
673
878
|
getParsedContent: () => getParsedContent,
|
|
674
879
|
listDocuments: () => listDocuments,
|
|
880
|
+
sanitizeFolderPath: () => sanitizeFolderPath,
|
|
675
881
|
updateDocuments: () => updateDocuments,
|
|
676
882
|
uploadFile: () => uploadFile,
|
|
677
|
-
|
|
883
|
+
uploadFiles: () => uploadFiles,
|
|
678
884
|
uploadUrl: () => uploadUrl
|
|
679
885
|
});
|
|
886
|
+
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
887
|
+
".pdf",
|
|
888
|
+
".txt",
|
|
889
|
+
".md",
|
|
890
|
+
".html",
|
|
891
|
+
".doc",
|
|
892
|
+
".docx",
|
|
893
|
+
".rtf",
|
|
894
|
+
".ppt",
|
|
895
|
+
".pptx",
|
|
896
|
+
".xls",
|
|
897
|
+
".xlsx"
|
|
898
|
+
]);
|
|
899
|
+
function sanitizeFolderPath(folderPath) {
|
|
900
|
+
return folderPath.replace(/[^a-zA-Z0-9_\-/]/g, "_").replace(/_{2,}/g, "_");
|
|
901
|
+
}
|
|
680
902
|
async function listDocuments(arbi) {
|
|
681
903
|
return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
|
|
682
904
|
}
|
|
@@ -715,22 +937,31 @@ async function getParsedContent(auth, docId, stage) {
|
|
|
715
937
|
});
|
|
716
938
|
return res.json();
|
|
717
939
|
}
|
|
718
|
-
async function uploadFile(auth, workspaceId, fileData, fileName) {
|
|
940
|
+
async function uploadFile(auth, workspaceId, fileData, fileName, options) {
|
|
719
941
|
const formData = new FormData();
|
|
720
942
|
formData.append("files", fileData, fileName);
|
|
943
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
944
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
721
945
|
const res = await authenticatedFetch({
|
|
722
946
|
...auth,
|
|
723
|
-
path: `/v1/document/upload
|
|
947
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
724
948
|
method: "POST",
|
|
725
949
|
body: formData
|
|
726
950
|
});
|
|
727
951
|
return res.json();
|
|
728
952
|
}
|
|
729
|
-
async function
|
|
730
|
-
const
|
|
731
|
-
const
|
|
732
|
-
const
|
|
733
|
-
|
|
953
|
+
async function uploadFiles(auth, workspaceId, files, options) {
|
|
954
|
+
const formData = new FormData();
|
|
955
|
+
for (const f of files) formData.append("files", f.data, f.name);
|
|
956
|
+
const params = new URLSearchParams({ workspace_ext_id: workspaceId });
|
|
957
|
+
if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
|
|
958
|
+
const res = await authenticatedFetch({
|
|
959
|
+
...auth,
|
|
960
|
+
path: `/v1/document/upload?${params.toString()}`,
|
|
961
|
+
method: "POST",
|
|
962
|
+
body: formData
|
|
963
|
+
});
|
|
964
|
+
return res.json();
|
|
734
965
|
}
|
|
735
966
|
async function downloadDocument(auth, docId) {
|
|
736
967
|
return authenticatedFetch({
|
|
@@ -930,6 +1161,8 @@ async function retrieve(options) {
|
|
|
930
1161
|
input: query,
|
|
931
1162
|
workspace_ext_id: workspaceId,
|
|
932
1163
|
stream: false,
|
|
1164
|
+
background: false,
|
|
1165
|
+
store: true,
|
|
933
1166
|
tools,
|
|
934
1167
|
...model ? { model } : {}
|
|
935
1168
|
};
|
|
@@ -945,6 +1178,8 @@ async function queryAssistant(options) {
|
|
|
945
1178
|
input: question,
|
|
946
1179
|
workspace_ext_id: workspaceId,
|
|
947
1180
|
stream: true,
|
|
1181
|
+
background: false,
|
|
1182
|
+
store: true,
|
|
948
1183
|
tools: {
|
|
949
1184
|
retrieval_chunk: buildRetrievalChunkTool(docIds),
|
|
950
1185
|
retrieval_full_context: buildRetrievalFullContextTool([])
|
|
@@ -1404,11 +1639,12 @@ var Arbi = class {
|
|
|
1404
1639
|
workspaceId ?? this.requireWorkspace(),
|
|
1405
1640
|
shared
|
|
1406
1641
|
),
|
|
1407
|
-
uploadFile: (fileData, fileName,
|
|
1642
|
+
uploadFile: (fileData, fileName, options) => uploadFile(
|
|
1408
1643
|
this.getAuthHeaders(),
|
|
1409
|
-
workspaceId ?? this.requireWorkspace(),
|
|
1644
|
+
options?.workspaceId ?? this.requireWorkspace(),
|
|
1410
1645
|
fileData,
|
|
1411
|
-
fileName
|
|
1646
|
+
fileName,
|
|
1647
|
+
options?.folder ? { folder: options.folder } : void 0
|
|
1412
1648
|
),
|
|
1413
1649
|
download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
|
|
1414
1650
|
getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
|
|
@@ -1550,10 +1786,192 @@ var Arbi = class {
|
|
|
1550
1786
|
}
|
|
1551
1787
|
};
|
|
1552
1788
|
|
|
1789
|
+
// src/operations/documents-node.ts
|
|
1790
|
+
var documents_node_exports = {};
|
|
1791
|
+
__export(documents_node_exports, {
|
|
1792
|
+
uploadDirectory: () => uploadDirectory,
|
|
1793
|
+
uploadLocalFile: () => uploadLocalFile,
|
|
1794
|
+
uploadZip: () => uploadZip
|
|
1795
|
+
});
|
|
1796
|
+
function collectFiles(dirPath, baseDir) {
|
|
1797
|
+
const root = baseDir ?? dirPath;
|
|
1798
|
+
const results = [];
|
|
1799
|
+
for (const entry of fs__default.default.readdirSync(dirPath, { withFileTypes: true })) {
|
|
1800
|
+
const fullPath = path2__default.default.join(dirPath, entry.name);
|
|
1801
|
+
if (entry.isDirectory()) {
|
|
1802
|
+
results.push(...collectFiles(fullPath, root));
|
|
1803
|
+
} else if (entry.isFile()) {
|
|
1804
|
+
const ext = path2__default.default.extname(entry.name).toLowerCase();
|
|
1805
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1806
|
+
results.push({ absolutePath: fullPath, relativePath: path2__default.default.relative(root, fullPath) });
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
return results;
|
|
1811
|
+
}
|
|
1812
|
+
async function uploadLocalFile(auth, workspaceId, filePath, options) {
|
|
1813
|
+
const fileBuffer = fs__default.default.readFileSync(filePath);
|
|
1814
|
+
const fileName = path2__default.default.basename(filePath);
|
|
1815
|
+
const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName, options);
|
|
1816
|
+
return { ...result, fileName };
|
|
1817
|
+
}
|
|
1818
|
+
async function uploadDirectory(auth, workspaceId, dirPath) {
|
|
1819
|
+
const resolvedDir = path2__default.default.resolve(dirPath);
|
|
1820
|
+
const dirName = path2__default.default.basename(resolvedDir);
|
|
1821
|
+
const entries = collectFiles(resolvedDir);
|
|
1822
|
+
if (entries.length === 0) {
|
|
1823
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1824
|
+
}
|
|
1825
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1826
|
+
for (const entry of entries) {
|
|
1827
|
+
const relDir = path2__default.default.dirname(entry.relativePath);
|
|
1828
|
+
const folder = relDir === "." ? dirName : `${dirName}/${relDir}`;
|
|
1829
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1830
|
+
groups.get(folder).push({ absolutePath: entry.absolutePath, name: path2__default.default.basename(entry.relativePath) });
|
|
1831
|
+
}
|
|
1832
|
+
const allDocIds = [];
|
|
1833
|
+
const allDuplicates = [];
|
|
1834
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1835
|
+
for (const [folder, files] of groups) {
|
|
1836
|
+
const blobs = files.map((f) => ({
|
|
1837
|
+
data: new Blob([fs__default.default.readFileSync(f.absolutePath)]),
|
|
1838
|
+
name: f.name
|
|
1839
|
+
}));
|
|
1840
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1841
|
+
const dups = result.duplicates ?? [];
|
|
1842
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1843
|
+
allDuplicates.push(...dups);
|
|
1844
|
+
folders.set(folder, {
|
|
1845
|
+
fileCount: files.length,
|
|
1846
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1847
|
+
duplicates: dups
|
|
1848
|
+
});
|
|
1849
|
+
}
|
|
1850
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1851
|
+
}
|
|
1852
|
+
async function uploadZip(auth, workspaceId, zipPath) {
|
|
1853
|
+
const JSZip = (await import('jszip')).default;
|
|
1854
|
+
const zipBuffer = fs__default.default.readFileSync(zipPath);
|
|
1855
|
+
const zip = await JSZip.loadAsync(zipBuffer);
|
|
1856
|
+
const zipBaseName = path2__default.default.basename(zipPath).replace(/\.zip$/i, "");
|
|
1857
|
+
const entries = [];
|
|
1858
|
+
zip.forEach((relativePath, zipEntry) => {
|
|
1859
|
+
if (zipEntry.dir) return;
|
|
1860
|
+
const ext = path2__default.default.extname(relativePath).toLowerCase();
|
|
1861
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
1862
|
+
entries.push({ zipEntryPath: relativePath, zipEntry });
|
|
1863
|
+
}
|
|
1864
|
+
});
|
|
1865
|
+
if (entries.length === 0) {
|
|
1866
|
+
return { doc_ext_ids: [], duplicates: [], folders: /* @__PURE__ */ new Map() };
|
|
1867
|
+
}
|
|
1868
|
+
const firstParts = new Set(entries.map((e) => e.zipEntryPath.split("/")[0]));
|
|
1869
|
+
const hasSingleRoot = firstParts.size === 1 && entries.every((e) => e.zipEntryPath.includes("/"));
|
|
1870
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1871
|
+
for (const entry of entries) {
|
|
1872
|
+
const data = await entry.zipEntry.async("uint8array");
|
|
1873
|
+
const fileName = path2__default.default.basename(entry.zipEntryPath);
|
|
1874
|
+
const relDir = path2__default.default.dirname(entry.zipEntryPath);
|
|
1875
|
+
let folder;
|
|
1876
|
+
if (hasSingleRoot) {
|
|
1877
|
+
folder = relDir === "." ? zipBaseName : relDir;
|
|
1878
|
+
} else {
|
|
1879
|
+
folder = relDir === "." ? zipBaseName : `${zipBaseName}/${relDir}`;
|
|
1880
|
+
}
|
|
1881
|
+
folder = sanitizeFolderPath(folder);
|
|
1882
|
+
if (!groups.has(folder)) groups.set(folder, []);
|
|
1883
|
+
groups.get(folder).push({ name: fileName, data });
|
|
1884
|
+
}
|
|
1885
|
+
const allDocIds = [];
|
|
1886
|
+
const allDuplicates = [];
|
|
1887
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1888
|
+
for (const [folder, files] of groups) {
|
|
1889
|
+
const blobs = files.map((f) => ({
|
|
1890
|
+
data: new Blob([f.data]),
|
|
1891
|
+
name: f.name
|
|
1892
|
+
}));
|
|
1893
|
+
const result = await uploadFiles(auth, workspaceId, blobs, { folder });
|
|
1894
|
+
const dups = result.duplicates ?? [];
|
|
1895
|
+
allDocIds.push(...result.doc_ext_ids);
|
|
1896
|
+
allDuplicates.push(...dups);
|
|
1897
|
+
folders.set(folder, {
|
|
1898
|
+
fileCount: files.length,
|
|
1899
|
+
doc_ext_ids: result.doc_ext_ids,
|
|
1900
|
+
duplicates: dups
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
return { doc_ext_ids: allDocIds, duplicates: allDuplicates, folders };
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
// src/operations/responses.ts
|
|
1907
|
+
var responses_exports = {};
|
|
1908
|
+
__export(responses_exports, {
|
|
1909
|
+
extractResponseText: () => extractResponseText,
|
|
1910
|
+
getResponse: () => getResponse,
|
|
1911
|
+
submitBackgroundQuery: () => submitBackgroundQuery
|
|
1912
|
+
});
|
|
1913
|
+
async function submitBackgroundQuery(options) {
|
|
1914
|
+
const { workspaceId, question, docIds, previousResponseId, model, ...auth } = options;
|
|
1915
|
+
const tools = {};
|
|
1916
|
+
if (docIds.length > 0) {
|
|
1917
|
+
tools.retrieval_chunk = {
|
|
1918
|
+
name: "retrieval_chunk",
|
|
1919
|
+
description: "retrieval chunk",
|
|
1920
|
+
tool_args: { doc_ext_ids: docIds },
|
|
1921
|
+
tool_responses: {}
|
|
1922
|
+
};
|
|
1923
|
+
tools.retrieval_full_context = {
|
|
1924
|
+
name: "retrieval_full_context",
|
|
1925
|
+
description: "retrieval full context",
|
|
1926
|
+
tool_args: { doc_ext_ids: [] },
|
|
1927
|
+
tool_responses: {}
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
const body = {
|
|
1931
|
+
input: question,
|
|
1932
|
+
workspace_ext_id: workspaceId,
|
|
1933
|
+
stream: false,
|
|
1934
|
+
background: true,
|
|
1935
|
+
store: true,
|
|
1936
|
+
tools,
|
|
1937
|
+
...previousResponseId ? { previous_response_id: previousResponseId } : {},
|
|
1938
|
+
...model ? { model } : {}
|
|
1939
|
+
};
|
|
1940
|
+
const res = await authenticatedFetch({
|
|
1941
|
+
...auth,
|
|
1942
|
+
path: "/v1/responses",
|
|
1943
|
+
method: "POST",
|
|
1944
|
+
body: JSON.stringify(body),
|
|
1945
|
+
headers: { "Content-Type": "application/json" }
|
|
1946
|
+
});
|
|
1947
|
+
return await res.json();
|
|
1948
|
+
}
|
|
1949
|
+
async function getResponse(auth, responseId) {
|
|
1950
|
+
const res = await authenticatedFetch({
|
|
1951
|
+
...auth,
|
|
1952
|
+
path: `/v1/responses/${responseId}`,
|
|
1953
|
+
method: "GET"
|
|
1954
|
+
});
|
|
1955
|
+
return await res.json();
|
|
1956
|
+
}
|
|
1957
|
+
function extractResponseText(response) {
|
|
1958
|
+
const parts = [];
|
|
1959
|
+
for (const msg of response.output) {
|
|
1960
|
+
for (const item of msg.content) {
|
|
1961
|
+
if ("type" in item && item.type === "output_text" && "text" in item) {
|
|
1962
|
+
parts.push(item.text);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
return parts.join("");
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1553
1969
|
exports.Arbi = Arbi;
|
|
1554
1970
|
exports.ArbiApiError = ArbiApiError;
|
|
1555
1971
|
exports.ArbiError = ArbiError;
|
|
1556
1972
|
exports.FileConfigStore = FileConfigStore;
|
|
1973
|
+
exports.LIFECYCLE_LABELS = LIFECYCLE_LABELS;
|
|
1974
|
+
exports.TOOL_LABELS = TOOL_LABELS;
|
|
1557
1975
|
exports.agentconfig = agentconfig_exports;
|
|
1558
1976
|
exports.assistant = assistant_exports;
|
|
1559
1977
|
exports.authenticatedFetch = authenticatedFetch;
|
|
@@ -1570,12 +1988,15 @@ exports.createDocumentWaiter = createDocumentWaiter;
|
|
|
1570
1988
|
exports.dm = dm_exports;
|
|
1571
1989
|
exports.doctags = doctags_exports;
|
|
1572
1990
|
exports.documents = documents_exports;
|
|
1991
|
+
exports.documentsNode = documents_node_exports;
|
|
1573
1992
|
exports.files = files_exports;
|
|
1993
|
+
exports.formatAgentStepLabel = formatAgentStepLabel;
|
|
1574
1994
|
exports.formatFileSize = formatFileSize;
|
|
1575
1995
|
exports.formatUserName = formatUserName;
|
|
1576
1996
|
exports.formatWorkspaceChoices = formatWorkspaceChoices;
|
|
1577
1997
|
exports.formatWsMessage = formatWsMessage;
|
|
1578
1998
|
exports.generateEncryptedWorkspaceKey = generateEncryptedWorkspaceKey;
|
|
1999
|
+
exports.getErrorCode = getErrorCode;
|
|
1579
2000
|
exports.getErrorMessage = getErrorMessage;
|
|
1580
2001
|
exports.health = health_exports;
|
|
1581
2002
|
exports.parseSSEEvents = parseSSEEvents;
|
|
@@ -1584,6 +2005,7 @@ exports.requireData = requireData;
|
|
|
1584
2005
|
exports.requireOk = requireOk;
|
|
1585
2006
|
exports.resolveAuth = resolveAuth;
|
|
1586
2007
|
exports.resolveWorkspace = resolveWorkspace;
|
|
2008
|
+
exports.responses = responses_exports;
|
|
1587
2009
|
exports.selectWorkspace = selectWorkspace;
|
|
1588
2010
|
exports.selectWorkspaceById = selectWorkspaceById;
|
|
1589
2011
|
exports.settings = settings_exports;
|