@arbidocs/sdk 0.3.17 → 0.3.19
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-BtAHbiq_.d.cts → browser-D8aF-wkt.d.cts} +22 -7
- package/dist/{browser-BtAHbiq_.d.ts → browser-D8aF-wkt.d.ts} +22 -7
- package/dist/browser.cjs +11 -25
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +12 -24
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +146 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +145 -24
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -285,6 +285,107 @@ var FileConfigStore = class {
|
|
|
285
285
|
return null;
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
|
+
|
|
289
|
+
// src/device-flow.ts
|
|
290
|
+
var device_flow_exports = {};
|
|
291
|
+
__export(device_flow_exports, {
|
|
292
|
+
DeviceFlowAccessDenied: () => DeviceFlowAccessDenied,
|
|
293
|
+
DeviceFlowError: () => DeviceFlowError,
|
|
294
|
+
DeviceFlowExpired: () => DeviceFlowExpired,
|
|
295
|
+
fetchSsoConfig: () => fetchSsoConfig,
|
|
296
|
+
pollForToken: () => pollForToken,
|
|
297
|
+
requestDeviceCode: () => requestDeviceCode
|
|
298
|
+
});
|
|
299
|
+
var DeviceFlowError = class extends Error {
|
|
300
|
+
constructor(message) {
|
|
301
|
+
super(message);
|
|
302
|
+
this.name = "DeviceFlowError";
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var DeviceFlowExpired = class extends DeviceFlowError {
|
|
306
|
+
constructor() {
|
|
307
|
+
super("Device code expired \u2014 please try again");
|
|
308
|
+
this.name = "DeviceFlowExpired";
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
var DeviceFlowAccessDenied = class extends DeviceFlowError {
|
|
312
|
+
constructor() {
|
|
313
|
+
super("Authorization was denied by the user");
|
|
314
|
+
this.name = "DeviceFlowAccessDenied";
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
async function fetchSsoConfig(baseUrl) {
|
|
318
|
+
const arbi = client.createArbiClient({ baseUrl, deploymentDomain: "", credentials: "omit" });
|
|
319
|
+
const { data, error } = await arbi.fetch.GET("/v1/user/sso-config");
|
|
320
|
+
if (error || !data) {
|
|
321
|
+
throw new DeviceFlowError(`Failed to fetch SSO config`);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
ssoEnabled: data.sso_enabled,
|
|
325
|
+
domain: data.domain,
|
|
326
|
+
clientId: data.cli_client_id || data.client_id,
|
|
327
|
+
audience: data.audience
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
async function requestDeviceCode(domain, clientId, audience, scope = "openid email profile") {
|
|
331
|
+
const body = new URLSearchParams({
|
|
332
|
+
client_id: clientId,
|
|
333
|
+
scope,
|
|
334
|
+
...audience ? { audience } : {}
|
|
335
|
+
});
|
|
336
|
+
const res = await fetch(`https://${domain}/oauth/device/code`, {
|
|
337
|
+
method: "POST",
|
|
338
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
339
|
+
body
|
|
340
|
+
});
|
|
341
|
+
if (!res.ok) {
|
|
342
|
+
const text = await res.text();
|
|
343
|
+
throw new DeviceFlowError(`Device code request failed: ${res.status} ${text}`);
|
|
344
|
+
}
|
|
345
|
+
return await res.json();
|
|
346
|
+
}
|
|
347
|
+
async function pollForToken(domain, clientId, deviceCode, interval, expiresIn, onPoll) {
|
|
348
|
+
const deadline = Date.now() + expiresIn * 1e3;
|
|
349
|
+
let pollInterval = interval * 1e3;
|
|
350
|
+
while (Date.now() < deadline) {
|
|
351
|
+
await sleep(pollInterval);
|
|
352
|
+
onPoll?.(Date.now());
|
|
353
|
+
const res = await fetch(`https://${domain}/oauth/token`, {
|
|
354
|
+
method: "POST",
|
|
355
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
356
|
+
body: new URLSearchParams({
|
|
357
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
358
|
+
client_id: clientId,
|
|
359
|
+
device_code: deviceCode
|
|
360
|
+
})
|
|
361
|
+
});
|
|
362
|
+
if (res.ok) {
|
|
363
|
+
const data = await res.json();
|
|
364
|
+
return data.access_token;
|
|
365
|
+
}
|
|
366
|
+
const errBody = await res.json().catch(() => ({ error: "unknown" }));
|
|
367
|
+
if (errBody.error === "authorization_pending") {
|
|
368
|
+
continue;
|
|
369
|
+
} else if (errBody.error === "slow_down") {
|
|
370
|
+
pollInterval += 5e3;
|
|
371
|
+
continue;
|
|
372
|
+
} else if (errBody.error === "expired_token") {
|
|
373
|
+
throw new DeviceFlowExpired();
|
|
374
|
+
} else if (errBody.error === "access_denied") {
|
|
375
|
+
throw new DeviceFlowAccessDenied();
|
|
376
|
+
} else {
|
|
377
|
+
throw new DeviceFlowError(
|
|
378
|
+
`Token polling error: ${errBody.error} \u2014 ${errBody.error_description ?? ""}`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
throw new DeviceFlowExpired();
|
|
383
|
+
}
|
|
384
|
+
function sleep(ms) {
|
|
385
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/auth.ts
|
|
288
389
|
function formatWorkspaceChoices(wsList) {
|
|
289
390
|
return wsList.map((ws) => {
|
|
290
391
|
const totalDocs = ws.shared_document_count + ws.private_document_count;
|
|
@@ -305,7 +406,8 @@ async function createAuthenticatedClient(config, creds, store) {
|
|
|
305
406
|
const signingPrivateKey = client.base64ToBytes(creds.signingPrivateKeyBase64);
|
|
306
407
|
const loginResult = await arbi.auth.loginWithKey({
|
|
307
408
|
email: creds.email,
|
|
308
|
-
signingPrivateKey
|
|
409
|
+
signingPrivateKey,
|
|
410
|
+
ssoToken: creds.ssoToken
|
|
309
411
|
});
|
|
310
412
|
store.saveCredentials({
|
|
311
413
|
...creds,
|
|
@@ -337,6 +439,40 @@ async function performPasswordLogin(config, email, password, store) {
|
|
|
337
439
|
});
|
|
338
440
|
return { arbi, loginResult, config };
|
|
339
441
|
}
|
|
442
|
+
async function performSsoDeviceFlowLogin(config, email, password, store, callbacks) {
|
|
443
|
+
const ssoConfig = await fetchSsoConfig(config.baseUrl);
|
|
444
|
+
if (!ssoConfig.ssoEnabled) {
|
|
445
|
+
throw new ArbiError("SSO is not enabled on this deployment");
|
|
446
|
+
}
|
|
447
|
+
const dc = await requestDeviceCode(ssoConfig.domain, ssoConfig.clientId, ssoConfig.audience);
|
|
448
|
+
callbacks?.onUserCode?.(dc.user_code, dc.verification_uri_complete);
|
|
449
|
+
const ssoToken = await pollForToken(
|
|
450
|
+
ssoConfig.domain,
|
|
451
|
+
ssoConfig.clientId,
|
|
452
|
+
dc.device_code,
|
|
453
|
+
dc.interval,
|
|
454
|
+
dc.expires_in,
|
|
455
|
+
callbacks?.onPoll
|
|
456
|
+
);
|
|
457
|
+
const arbi = client.createArbiClient({
|
|
458
|
+
baseUrl: config.baseUrl,
|
|
459
|
+
deploymentDomain: config.deploymentDomain,
|
|
460
|
+
credentials: "omit"
|
|
461
|
+
});
|
|
462
|
+
await arbi.crypto.initSodium();
|
|
463
|
+
const loginResult = await arbi.auth.login({ email, password, ssoToken });
|
|
464
|
+
store.saveCredentials({
|
|
465
|
+
email,
|
|
466
|
+
signingPrivateKeyBase64: arbi.crypto.bytesToBase64(loginResult.signingPrivateKey),
|
|
467
|
+
serverSessionKeyBase64: arbi.crypto.bytesToBase64(loginResult.serverSessionKey),
|
|
468
|
+
ssoToken,
|
|
469
|
+
accessToken: void 0,
|
|
470
|
+
workspaceKeyHeader: void 0,
|
|
471
|
+
workspaceId: void 0,
|
|
472
|
+
tokenTimestamp: void 0
|
|
473
|
+
});
|
|
474
|
+
return { arbi, loginResult, config };
|
|
475
|
+
}
|
|
340
476
|
async function selectWorkspace(arbi, workspaceId, wrappedKey, serverSessionKey, signingPrivateKeyBase64) {
|
|
341
477
|
const signingPrivateKey = client.base64ToBytes(signingPrivateKeyBase64);
|
|
342
478
|
const ed25519PublicKey = signingPrivateKey.slice(32, 64);
|
|
@@ -456,23 +592,7 @@ async function resolveWorkspace(store, workspaceOpt) {
|
|
|
456
592
|
}
|
|
457
593
|
|
|
458
594
|
// src/sse.ts
|
|
459
|
-
var
|
|
460
|
-
search_documents: "Searching documents",
|
|
461
|
-
get_document_passages: "Reading document",
|
|
462
|
-
get_table_of_contents: "Getting table of contents",
|
|
463
|
-
view_document_pages: "Viewing document pages",
|
|
464
|
-
get_full_document: "Reading full document",
|
|
465
|
-
web_search: "Searching the web",
|
|
466
|
-
read_url: "Reading web pages",
|
|
467
|
-
ask_user: "Asking user",
|
|
468
|
-
compaction: "Compacting conversation",
|
|
469
|
-
personal_agent: "Running agent",
|
|
470
|
-
create_artifact: "Creating artifact",
|
|
471
|
-
create_plan: "Creating plan",
|
|
472
|
-
save_skill: "Saving skill",
|
|
473
|
-
run_code: "Running code"
|
|
474
|
-
};
|
|
475
|
-
var LIFECYCLE_LABELS = {
|
|
595
|
+
var LIFECYCLE_LABELS_FALLBACK = {
|
|
476
596
|
evaluation: "Evaluating results",
|
|
477
597
|
answering: "Writing answer",
|
|
478
598
|
reviewing: "Reviewing answer",
|
|
@@ -481,18 +601,19 @@ var LIFECYCLE_LABELS = {
|
|
|
481
601
|
};
|
|
482
602
|
function formatAgentStepLabel(step) {
|
|
483
603
|
if (step.focus) return step.focus;
|
|
604
|
+
if (step.label) return step.label;
|
|
484
605
|
const detail = step.detail;
|
|
485
606
|
if (step.step === "tool_progress" && detail && detail.length > 0) {
|
|
486
|
-
const
|
|
487
|
-
const label = toolName && TOOL_LABELS[toolName] || LIFECYCLE_LABELS.tool_progress;
|
|
607
|
+
const label = detail[0].label || LIFECYCLE_LABELS_FALLBACK.tool_progress;
|
|
488
608
|
const message = detail[0].message;
|
|
489
609
|
return message ? `${label}: ${message}` : label;
|
|
490
610
|
}
|
|
491
611
|
if (step.step) {
|
|
492
|
-
return
|
|
612
|
+
return LIFECYCLE_LABELS_FALLBACK[step.step] || step.step;
|
|
493
613
|
}
|
|
494
|
-
if (detail && detail.length > 0
|
|
495
|
-
|
|
614
|
+
if (detail && detail.length > 0) {
|
|
615
|
+
if (detail[0].label) return detail[0].label;
|
|
616
|
+
if (detail[0].tool) return detail[0].tool;
|
|
496
617
|
}
|
|
497
618
|
return "";
|
|
498
619
|
}
|
|
@@ -2081,8 +2202,6 @@ exports.Arbi = Arbi;
|
|
|
2081
2202
|
exports.ArbiApiError = ArbiApiError;
|
|
2082
2203
|
exports.ArbiError = ArbiError;
|
|
2083
2204
|
exports.FileConfigStore = FileConfigStore;
|
|
2084
|
-
exports.LIFECYCLE_LABELS = LIFECYCLE_LABELS;
|
|
2085
|
-
exports.TOOL_LABELS = TOOL_LABELS;
|
|
2086
2205
|
exports.agentconfig = agentconfig_exports;
|
|
2087
2206
|
exports.assistant = assistant_exports;
|
|
2088
2207
|
exports.authenticatedFetch = authenticatedFetch;
|
|
@@ -2097,6 +2216,7 @@ exports.conversations = conversations_exports;
|
|
|
2097
2216
|
exports.countCitations = countCitations;
|
|
2098
2217
|
exports.createAuthenticatedClient = createAuthenticatedClient;
|
|
2099
2218
|
exports.createDocumentWaiter = createDocumentWaiter;
|
|
2219
|
+
exports.deviceFlow = device_flow_exports;
|
|
2100
2220
|
exports.dm = dm_exports;
|
|
2101
2221
|
exports.doctags = doctags_exports;
|
|
2102
2222
|
exports.documents = documents_exports;
|
|
@@ -2114,6 +2234,7 @@ exports.getErrorMessage = getErrorMessage;
|
|
|
2114
2234
|
exports.health = health_exports;
|
|
2115
2235
|
exports.parseSSEEvents = parseSSEEvents;
|
|
2116
2236
|
exports.performPasswordLogin = performPasswordLogin;
|
|
2237
|
+
exports.performSsoDeviceFlowLogin = performSsoDeviceFlowLogin;
|
|
2117
2238
|
exports.requireData = requireData;
|
|
2118
2239
|
exports.requireOk = requireOk;
|
|
2119
2240
|
exports.resolveAuth = resolveAuth;
|