@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.
@@ -1,2 +1,2 @@
1
- export { AgentStepEvent, Arbi, ArbiApiError, ArbiError, ArbiOptions, ArtifactEvent, AuthContext, AuthHeaders, AuthenticatedClient, ChatSession, CliConfig, CliCredentials, ConfigStore, ConnectOptions, MessageMetadataPayload, OutputTokensDetails, QueryOptions, ReconnectOptions, ReconnectableWsConnection, ResponseCompletedEvent, ResponseContentPartAddedEvent, ResponseCreatedEvent, ResponseFailedEvent, ResponseOutputItemAddedEvent, ResponseOutputItemDoneEvent, ResponseOutputTextDeltaEvent, ResponseOutputTextDoneEvent, ResponseUsage, SSEEvent, SSEStreamCallbacks, SSEStreamResult, SSEStreamStartData, UserInfo, UserInputRequestEvent, UserMessageEvent, WorkspaceContext, WsConnection, agentconfig, assistant, authenticatedFetch, buildRetrievalChunkTool, buildRetrievalFullContextTool, buildRetrievalTocTool, connectWebSocket, connectWithReconnect, consumeSSEStream, contacts, conversations, createAuthenticatedClient, dm, doctags, documents, files, formatFileSize, formatUserName, formatWorkspaceChoices, getErrorMessage, health, parseSSEEvents, performPasswordLogin, requireData, requireOk, resolveAuth, resolveWorkspace, selectWorkspace, selectWorkspaceById, settings, streamSSE, tags, workspaces } from './index.cjs';
1
+ export { f as AgentStepEvent, g as Arbi, h as ArbiApiError, i as ArbiError, j as ArbiOptions, k as ArtifactEvent, l as AuthContext, A as AuthHeaders, m as AuthenticatedClient, c as ChatSession, a as CliConfig, b as CliCredentials, C as ConfigStore, n as ConnectOptions, L as LIFECYCLE_LABELS, p as MessageMetadataPayload, O as OutputTokensDetails, Q as QueryOptions, R as ReconnectOptions, q as ReconnectableWsConnection, r as ResponseCompletedEvent, s as ResponseContentPartAddedEvent, t as ResponseCreatedEvent, u as ResponseFailedEvent, v as ResponseOutputItemAddedEvent, w as ResponseOutputItemDoneEvent, x as ResponseOutputTextDeltaEvent, y as ResponseOutputTextDoneEvent, z as ResponseUsage, S as SSEEvent, B as SSEStreamCallbacks, E as SSEStreamResult, G as SSEStreamStartData, T as TOOL_LABELS, H as UserInfo, I as UserInputRequestEvent, J as UserMessageEvent, W as WorkspaceContext, K as WsConnection, N as agentconfig, P as assistant, V as authenticatedFetch, X as buildRetrievalChunkTool, Y as buildRetrievalFullContextTool, Z as buildRetrievalTocTool, _ as connectWebSocket, $ as connectWithReconnect, a0 as consumeSSEStream, a1 as contacts, a2 as conversations, a3 as createAuthenticatedClient, a5 as dm, a6 as doctags, a7 as documents, a8 as files, a9 as formatAgentStepLabel, aa as formatFileSize, ab as formatUserName, ac as formatWorkspaceChoices, ag as getErrorMessage, ah as health, ai as parseSSEEvents, aj as performPasswordLogin, ak as requireData, al as requireOk, am as resolveAuth, an as resolveWorkspace, ao as selectWorkspace, ap as selectWorkspaceById, aq as settings, ar as streamSSE, as as tags, at as workspaces } from './browser-BszYf6lU.cjs';
2
2
  import '@arbidocs/client';
package/dist/browser.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { AgentStepEvent, Arbi, ArbiApiError, ArbiError, ArbiOptions, ArtifactEvent, AuthContext, AuthHeaders, AuthenticatedClient, ChatSession, CliConfig, CliCredentials, ConfigStore, ConnectOptions, MessageMetadataPayload, OutputTokensDetails, QueryOptions, ReconnectOptions, ReconnectableWsConnection, ResponseCompletedEvent, ResponseContentPartAddedEvent, ResponseCreatedEvent, ResponseFailedEvent, ResponseOutputItemAddedEvent, ResponseOutputItemDoneEvent, ResponseOutputTextDeltaEvent, ResponseOutputTextDoneEvent, ResponseUsage, SSEEvent, SSEStreamCallbacks, SSEStreamResult, SSEStreamStartData, UserInfo, UserInputRequestEvent, UserMessageEvent, WorkspaceContext, WsConnection, agentconfig, assistant, authenticatedFetch, buildRetrievalChunkTool, buildRetrievalFullContextTool, buildRetrievalTocTool, connectWebSocket, connectWithReconnect, consumeSSEStream, contacts, conversations, createAuthenticatedClient, dm, doctags, documents, files, formatFileSize, formatUserName, formatWorkspaceChoices, getErrorMessage, health, parseSSEEvents, performPasswordLogin, requireData, requireOk, resolveAuth, resolveWorkspace, selectWorkspace, selectWorkspaceById, settings, streamSSE, tags, workspaces } from './index.js';
1
+ export { f as AgentStepEvent, g as Arbi, h as ArbiApiError, i as ArbiError, j as ArbiOptions, k as ArtifactEvent, l as AuthContext, A as AuthHeaders, m as AuthenticatedClient, c as ChatSession, a as CliConfig, b as CliCredentials, C as ConfigStore, n as ConnectOptions, L as LIFECYCLE_LABELS, p as MessageMetadataPayload, O as OutputTokensDetails, Q as QueryOptions, R as ReconnectOptions, q as ReconnectableWsConnection, r as ResponseCompletedEvent, s as ResponseContentPartAddedEvent, t as ResponseCreatedEvent, u as ResponseFailedEvent, v as ResponseOutputItemAddedEvent, w as ResponseOutputItemDoneEvent, x as ResponseOutputTextDeltaEvent, y as ResponseOutputTextDoneEvent, z as ResponseUsage, S as SSEEvent, B as SSEStreamCallbacks, E as SSEStreamResult, G as SSEStreamStartData, T as TOOL_LABELS, H as UserInfo, I as UserInputRequestEvent, J as UserMessageEvent, W as WorkspaceContext, K as WsConnection, N as agentconfig, P as assistant, V as authenticatedFetch, X as buildRetrievalChunkTool, Y as buildRetrievalFullContextTool, Z as buildRetrievalTocTool, _ as connectWebSocket, $ as connectWithReconnect, a0 as consumeSSEStream, a1 as contacts, a2 as conversations, a3 as createAuthenticatedClient, a5 as dm, a6 as doctags, a7 as documents, a8 as files, a9 as formatAgentStepLabel, aa as formatFileSize, ab as formatUserName, ac as formatWorkspaceChoices, ag as getErrorMessage, ah as health, ai as parseSSEEvents, aj as performPasswordLogin, ak as requireData, al as requireOk, am as resolveAuth, an as resolveWorkspace, ao as selectWorkspace, ap as selectWorkspaceById, aq as settings, ar as streamSSE, as as tags, at as workspaces } from './browser-BszYf6lU.js';
2
2
  import '@arbidocs/client';
package/dist/browser.js CHANGED
@@ -1,6 +1,4 @@
1
1
  import { createArbiClient, base64ToBytes, deriveEncryptionKeypairFromSigning, sealedBoxDecrypt, createWorkspaceKeyHeader, buildWebSocketUrl, createAuthMessage, parseServerMessage, isMessageType } from '@arbidocs/client';
2
- import fs from 'fs';
3
- import path from 'path';
4
2
 
5
3
  var __defProp = Object.defineProperty;
6
4
  var __export = (target, all) => {
@@ -35,7 +33,24 @@ function requireOk(result, message) {
35
33
  }
36
34
  }
37
35
  function getErrorMessage(err) {
38
- return err instanceof Error ? err.message : String(err);
36
+ if (!(err instanceof Error)) return String(err);
37
+ const rootCause = getDeepestCause(err);
38
+ if (rootCause !== err) {
39
+ const rootMsg = rootCause.message || String(rootCause);
40
+ if (err.message && !err.message.includes(rootMsg)) {
41
+ return `${err.message}: ${rootMsg}`;
42
+ }
43
+ }
44
+ return err.message;
45
+ }
46
+ function getDeepestCause(err) {
47
+ let current = err;
48
+ const seen = /* @__PURE__ */ new Set();
49
+ while (current.cause instanceof Error && !seen.has(current.cause)) {
50
+ seen.add(current);
51
+ current = current.cause;
52
+ }
53
+ return current;
39
54
  }
40
55
 
41
56
  // src/fetch.ts
@@ -65,8 +80,8 @@ async function extractErrorMessage(res) {
65
80
  return `Request failed: ${res.status} ${res.statusText}`;
66
81
  }
67
82
  async function authenticatedFetch(options) {
68
- const { baseUrl, accessToken, workspaceKeyHeader, path: path2, method, body, headers } = options;
69
- const res = await fetch(`${baseUrl}${path2}`, {
83
+ const { baseUrl, accessToken, workspaceKeyHeader, path, method, body, headers } = options;
84
+ const res = await fetch(`${baseUrl}${path}`, {
70
85
  method: method ?? (body ? "POST" : "GET"),
71
86
  headers: {
72
87
  Authorization: `Bearer ${accessToken}`,
@@ -105,7 +120,11 @@ async function createAuthenticatedClient(config, creds, store) {
105
120
  });
106
121
  store.saveCredentials({
107
122
  ...creds,
108
- serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
123
+ serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
124
+ accessToken: void 0,
125
+ workspaceKeyHeader: void 0,
126
+ workspaceId: void 0,
127
+ tokenTimestamp: void 0
109
128
  });
110
129
  return { arbi, loginResult };
111
130
  }
@@ -120,7 +139,12 @@ async function performPasswordLogin(config, email, password, store) {
120
139
  store.saveCredentials({
121
140
  email,
122
141
  signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),
123
- serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey)
142
+ serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
143
+ // Clear any cached workspace tokens — new session key invalidates them
144
+ accessToken: void 0,
145
+ workspaceKeyHeader: void 0,
146
+ workspaceId: void 0,
147
+ tokenTimestamp: void 0
124
148
  });
125
149
  return { arbi, loginResult, config };
126
150
  }
@@ -173,6 +197,10 @@ async function resolveAuth(store) {
173
197
  const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
174
198
  return { arbi, loginResult, config };
175
199
  }
200
+ var TOKEN_MAX_AGE_MS = 50 * 60 * 1e3;
201
+ function isCachedTokenValid(creds, workspaceId) {
202
+ return !!(creds.accessToken && creds.workspaceKeyHeader && creds.workspaceId === workspaceId && creds.tokenTimestamp && Date.now() - new Date(creds.tokenTimestamp).getTime() < TOKEN_MAX_AGE_MS);
203
+ }
176
204
  async function resolveWorkspace(store, workspaceOpt) {
177
205
  const config = store.requireConfig();
178
206
  const creds = store.requireCredentials();
@@ -180,6 +208,32 @@ async function resolveWorkspace(store, workspaceOpt) {
180
208
  if (!workspaceId) {
181
209
  throw new ArbiError("No workspace selected. Run: arbi workspace select <id>");
182
210
  }
211
+ if (isCachedTokenValid(creds, workspaceId)) {
212
+ const arbi2 = createArbiClient({
213
+ baseUrl: config.baseUrl,
214
+ deploymentDomain: config.deploymentDomain,
215
+ credentials: "omit"
216
+ });
217
+ await arbi2.crypto.initSodium();
218
+ arbi2.session.setSelectedWorkspace(workspaceId);
219
+ arbi2.session.setAccessToken(creds.accessToken);
220
+ arbi2.session.setCachedWorkspaceHeader(workspaceId, creds.workspaceKeyHeader);
221
+ const signingPrivateKey = base64ToBytes(creds.signingPrivateKeyBase64);
222
+ const serverSessionKey = base64ToBytes(creds.serverSessionKeyBase64);
223
+ const loginResult2 = {
224
+ accessToken: creds.accessToken,
225
+ signingPrivateKey,
226
+ serverSessionKey
227
+ };
228
+ return {
229
+ arbi: arbi2,
230
+ loginResult: loginResult2,
231
+ config,
232
+ workspaceId,
233
+ accessToken: creds.accessToken,
234
+ workspaceKeyHeader: creds.workspaceKeyHeader
235
+ };
236
+ }
183
237
  const { arbi, loginResult } = await createAuthenticatedClient(config, creds, store);
184
238
  await selectWorkspaceById(
185
239
  arbi,
@@ -192,10 +246,57 @@ async function resolveWorkspace(store, workspaceOpt) {
192
246
  if (!accessToken || !workspaceKeyHeader) {
193
247
  throw new ArbiError("Authentication error \u2014 missing token or workspace key");
194
248
  }
249
+ store.saveCredentials({
250
+ ...store.requireCredentials(),
251
+ accessToken,
252
+ workspaceKeyHeader,
253
+ workspaceId,
254
+ tokenTimestamp: (/* @__PURE__ */ new Date()).toISOString()
255
+ });
195
256
  return { arbi, loginResult, config, workspaceId, accessToken, workspaceKeyHeader };
196
257
  }
197
258
 
198
259
  // src/sse.ts
260
+ var TOOL_LABELS = {
261
+ search_documents: "Searching documents",
262
+ get_document_passages: "Reading document",
263
+ get_table_of_contents: "Getting table of contents",
264
+ view_document_pages: "Viewing document pages",
265
+ get_full_document: "Reading full document",
266
+ web_search: "Searching the web",
267
+ read_url: "Reading web pages",
268
+ ask_user: "Asking user",
269
+ compaction: "Compacting conversation",
270
+ personal_agent: "Running agent",
271
+ create_artifact: "Creating artifact",
272
+ create_plan: "Creating plan",
273
+ save_skill: "Saving skill",
274
+ run_code: "Running code"
275
+ };
276
+ var LIFECYCLE_LABELS = {
277
+ evaluation: "Evaluating results",
278
+ answering: "Writing answer",
279
+ reviewing: "Reviewing answer",
280
+ planning: "Planning",
281
+ tool_progress: "Working"
282
+ };
283
+ function formatAgentStepLabel(step) {
284
+ if (step.focus) return step.focus;
285
+ const detail = step.detail;
286
+ if (step.step === "tool_progress" && detail && detail.length > 0) {
287
+ const toolName = detail[0].tool;
288
+ const label = toolName && TOOL_LABELS[toolName] || LIFECYCLE_LABELS.tool_progress;
289
+ const message = detail[0].message;
290
+ return message ? `${label}: ${message}` : label;
291
+ }
292
+ if (step.step) {
293
+ return LIFECYCLE_LABELS[step.step] || step.step;
294
+ }
295
+ if (detail && detail.length > 0 && detail[0].tool) {
296
+ return TOOL_LABELS[detail[0].tool] || detail[0].tool;
297
+ }
298
+ return "";
299
+ }
199
300
  function parseSSEEvents(chunk, buffer) {
200
301
  const combined = buffer + chunk;
201
302
  const events = [];
@@ -283,8 +384,8 @@ async function streamSSE(response, callbacks = {}) {
283
384
  // ARBI-specific events (dot-prefixed from server)
284
385
  "arbi.agent_step": (raw) => {
285
386
  const data = JSON.parse(raw);
286
- const focus = data.focus || data.step || "";
287
- if (focus) agentSteps.push(focus);
387
+ const label = formatAgentStepLabel(data);
388
+ if (label) agentSteps.push(label);
288
389
  callbacks.onAgentStep?.(data);
289
390
  if (data.t != null) callbacks.onElapsedTime?.(data.t);
290
391
  },
@@ -463,16 +564,34 @@ function formatUserName(user) {
463
564
  // src/operations/documents.ts
464
565
  var documents_exports = {};
465
566
  __export(documents_exports, {
567
+ SUPPORTED_EXTENSIONS: () => SUPPORTED_EXTENSIONS,
466
568
  deleteDocuments: () => deleteDocuments,
467
569
  downloadDocument: () => downloadDocument,
468
570
  getDocuments: () => getDocuments,
469
571
  getParsedContent: () => getParsedContent,
470
572
  listDocuments: () => listDocuments,
573
+ sanitizeFolderPath: () => sanitizeFolderPath,
471
574
  updateDocuments: () => updateDocuments,
472
575
  uploadFile: () => uploadFile,
473
- uploadLocalFile: () => uploadLocalFile,
576
+ uploadFiles: () => uploadFiles,
474
577
  uploadUrl: () => uploadUrl
475
578
  });
579
+ var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
580
+ ".pdf",
581
+ ".txt",
582
+ ".md",
583
+ ".html",
584
+ ".doc",
585
+ ".docx",
586
+ ".rtf",
587
+ ".ppt",
588
+ ".pptx",
589
+ ".xls",
590
+ ".xlsx"
591
+ ]);
592
+ function sanitizeFolderPath(folderPath) {
593
+ return folderPath.replace(/[^a-zA-Z0-9_\-/]/g, "_").replace(/_{2,}/g, "_");
594
+ }
476
595
  async function listDocuments(arbi) {
477
596
  return requireData(await arbi.fetch.GET("/v1/document/list"), "Failed to fetch documents");
478
597
  }
@@ -511,22 +630,31 @@ async function getParsedContent(auth, docId, stage) {
511
630
  });
512
631
  return res.json();
513
632
  }
514
- async function uploadFile(auth, workspaceId, fileData, fileName) {
633
+ async function uploadFile(auth, workspaceId, fileData, fileName, options) {
515
634
  const formData = new FormData();
516
635
  formData.append("files", fileData, fileName);
636
+ const params = new URLSearchParams({ workspace_ext_id: workspaceId });
637
+ if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
517
638
  const res = await authenticatedFetch({
518
639
  ...auth,
519
- path: `/v1/document/upload?workspace_ext_id=${workspaceId}`,
640
+ path: `/v1/document/upload?${params.toString()}`,
520
641
  method: "POST",
521
642
  body: formData
522
643
  });
523
644
  return res.json();
524
645
  }
525
- async function uploadLocalFile(auth, workspaceId, filePath) {
526
- const fileBuffer = fs.readFileSync(filePath);
527
- const fileName = path.basename(filePath);
528
- const result = await uploadFile(auth, workspaceId, new Blob([fileBuffer]), fileName);
529
- return { ...result, fileName };
646
+ async function uploadFiles(auth, workspaceId, files, options) {
647
+ const formData = new FormData();
648
+ for (const f of files) formData.append("files", f.data, f.name);
649
+ const params = new URLSearchParams({ workspace_ext_id: workspaceId });
650
+ if (options?.folder) params.set("folder", sanitizeFolderPath(options.folder));
651
+ const res = await authenticatedFetch({
652
+ ...auth,
653
+ path: `/v1/document/upload?${params.toString()}`,
654
+ method: "POST",
655
+ body: formData
656
+ });
657
+ return res.json();
530
658
  }
531
659
  async function downloadDocument(auth, docId) {
532
660
  return authenticatedFetch({
@@ -726,6 +854,8 @@ async function retrieve(options) {
726
854
  input: query,
727
855
  workspace_ext_id: workspaceId,
728
856
  stream: false,
857
+ background: false,
858
+ store: true,
729
859
  tools,
730
860
  ...model ? { model } : {}
731
861
  };
@@ -741,6 +871,8 @@ async function queryAssistant(options) {
741
871
  input: question,
742
872
  workspace_ext_id: workspaceId,
743
873
  stream: true,
874
+ background: false,
875
+ store: true,
744
876
  tools: {
745
877
  retrieval_chunk: buildRetrievalChunkTool(docIds),
746
878
  retrieval_full_context: buildRetrievalFullContextTool([])
@@ -1200,11 +1332,12 @@ var Arbi = class {
1200
1332
  workspaceId ?? this.requireWorkspace(),
1201
1333
  shared
1202
1334
  ),
1203
- uploadFile: (fileData, fileName, workspaceId) => uploadFile(
1335
+ uploadFile: (fileData, fileName, options) => uploadFile(
1204
1336
  this.getAuthHeaders(),
1205
- workspaceId ?? this.requireWorkspace(),
1337
+ options?.workspaceId ?? this.requireWorkspace(),
1206
1338
  fileData,
1207
- fileName
1339
+ fileName,
1340
+ options?.folder ? { folder: options.folder } : void 0
1208
1341
  ),
1209
1342
  download: (docId) => downloadDocument(this.getAuthHeaders(), docId),
1210
1343
  getParsedContent: (docId, stage) => getParsedContent(this.getAuthHeaders(), docId, stage)
@@ -1346,6 +1479,6 @@ var Arbi = class {
1346
1479
  }
1347
1480
  };
1348
1481
 
1349
- export { Arbi, ArbiApiError, ArbiError, agentconfig_exports as agentconfig, assistant_exports as assistant, authenticatedFetch, buildRetrievalChunkTool, buildRetrievalFullContextTool, buildRetrievalTocTool, connectWebSocket, connectWithReconnect, consumeSSEStream, contacts_exports as contacts, conversations_exports as conversations, createAuthenticatedClient, dm_exports as dm, doctags_exports as doctags, documents_exports as documents, files_exports as files, formatFileSize, formatUserName, formatWorkspaceChoices, 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 };
1482
+ export { Arbi, ArbiApiError, ArbiError, 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, dm_exports as dm, doctags_exports as doctags, documents_exports as documents, files_exports as files, formatAgentStepLabel, formatFileSize, formatUserName, formatWorkspaceChoices, 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 };
1350
1483
  //# sourceMappingURL=browser.js.map
1351
1484
  //# sourceMappingURL=browser.js.map