@arbidocs/blocks 0.4.72 → 0.4.74

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.
Files changed (109) hide show
  1. package/dist/agents/index.cjs +401 -262
  2. package/dist/agents/index.js +7 -4
  3. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  4. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +58 -0
  5. package/dist/agents/tasks/index.d.ts +1 -0
  6. package/dist/agents/workflows/WorkflowRunner.d.ts +86 -0
  7. package/dist/agents/workflows/WorkflowStepBar.d.ts +23 -0
  8. package/dist/agents/workflows/index.d.ts +7 -1
  9. package/dist/agents/workflows/planSteps.d.ts +28 -0
  10. package/dist/agents/workflows/run.d.ts +98 -0
  11. package/dist/agents/workflows/skillMarkdown.d.ts +15 -0
  12. package/dist/agents/workflows/types.d.ts +111 -0
  13. package/dist/agents/workflows/useWorkflowPreview.d.ts +14 -0
  14. package/dist/agents/workflows/useWorkflowView.d.ts +54 -0
  15. package/dist/agents/workflows/workflow.d.ts +3 -1
  16. package/dist/chat/index.cjs +124 -124
  17. package/dist/chat/index.js +3 -3
  18. package/dist/{chunk-DH7C2UJO.cjs → chunk-5LP54CWR.cjs} +299 -526
  19. package/dist/chunk-5LP54CWR.cjs.map +1 -0
  20. package/dist/{chunk-3SFFTSOI.cjs → chunk-7CVF3DK2.cjs} +5 -5
  21. package/dist/{chunk-3SFFTSOI.cjs.map → chunk-7CVF3DK2.cjs.map} +1 -1
  22. package/dist/chunk-7D737FLE.cjs +43 -0
  23. package/dist/chunk-7D737FLE.cjs.map +1 -0
  24. package/dist/{chunk-V3L5DONY.cjs → chunk-B4SRYJLM.cjs} +31 -2
  25. package/dist/chunk-B4SRYJLM.cjs.map +1 -0
  26. package/dist/{chunk-LFGJAZ5H.js → chunk-DDF5GPIJ.js} +6 -36
  27. package/dist/chunk-DDF5GPIJ.js.map +1 -0
  28. package/dist/chunk-DETZZBG2.cjs +91 -0
  29. package/dist/chunk-DETZZBG2.cjs.map +1 -0
  30. package/dist/chunk-EVUEIBNU.js +89 -0
  31. package/dist/chunk-EVUEIBNU.js.map +1 -0
  32. package/dist/{chunk-G5QTGKDJ.cjs → chunk-HITAN7JF.cjs} +8 -8
  33. package/dist/{chunk-G5QTGKDJ.cjs.map → chunk-HITAN7JF.cjs.map} +1 -1
  34. package/dist/{chunk-3VQYJBOI.js → chunk-HOXKR26S.js} +31 -4
  35. package/dist/chunk-HOXKR26S.js.map +1 -0
  36. package/dist/{chunk-KJ3QEKOJ.cjs → chunk-IPGKTUF7.cjs} +7 -33
  37. package/dist/chunk-IPGKTUF7.cjs.map +1 -0
  38. package/dist/{chunk-IMC2Z32C.js → chunk-KOSGX3UK.js} +269 -485
  39. package/dist/chunk-KOSGX3UK.js.map +1 -0
  40. package/dist/{chunk-KOXUBCLL.js → chunk-MK6NJQGF.js} +4 -4
  41. package/dist/{chunk-KOXUBCLL.js.map → chunk-MK6NJQGF.js.map} +1 -1
  42. package/dist/{chunk-THO7DZNN.cjs → chunk-MUMH3Z6K.cjs} +20 -15
  43. package/dist/chunk-MUMH3Z6K.cjs.map +1 -0
  44. package/dist/{chunk-5HOAOKZL.js → chunk-OYMWV45N.js} +21 -16
  45. package/dist/chunk-OYMWV45N.js.map +1 -0
  46. package/dist/chunk-P2RBE3FD.cjs +1448 -0
  47. package/dist/chunk-P2RBE3FD.cjs.map +1 -0
  48. package/dist/{chunk-G5DP27DU.js → chunk-UIWLDSTF.js} +3 -29
  49. package/dist/chunk-UIWLDSTF.js.map +1 -0
  50. package/dist/{chunk-VRPRAU3J.js → chunk-WJEKRSPH.js} +3 -3
  51. package/dist/{chunk-VRPRAU3J.js.map → chunk-WJEKRSPH.js.map} +1 -1
  52. package/dist/chunk-XD2M6LIG.js +41 -0
  53. package/dist/chunk-XD2M6LIG.js.map +1 -0
  54. package/dist/chunk-YWYVIQ7T.js +1402 -0
  55. package/dist/chunk-YWYVIQ7T.js.map +1 -0
  56. package/dist/{chunk-WBDK4PIA.cjs → chunk-Z5VUZ6YD.cjs} +6 -37
  57. package/dist/chunk-Z5VUZ6YD.cjs.map +1 -0
  58. package/dist/connect/docx.cjs +2 -2
  59. package/dist/connect/docx.js +1 -1
  60. package/dist/connect/index.cjs +379 -27
  61. package/dist/connect/index.cjs.map +1 -1
  62. package/dist/connect/index.d.ts +1 -0
  63. package/dist/connect/index.js +362 -11
  64. package/dist/connect/index.js.map +1 -1
  65. package/dist/connection/ConnectedWorkflowBuilder.d.ts +44 -0
  66. package/dist/connection/ConnectedWorkflowRunner.d.ts +31 -0
  67. package/dist/connection/useWorkflowThread.d.ts +38 -0
  68. package/dist/facts/index.cjs +1 -1
  69. package/dist/facts/index.js +1 -1
  70. package/dist/files/index.cjs +9 -83
  71. package/dist/files/index.cjs.map +1 -1
  72. package/dist/files/index.js +6 -83
  73. package/dist/files/index.js.map +1 -1
  74. package/dist/home/index.cjs +22 -21
  75. package/dist/home/index.cjs.map +1 -1
  76. package/dist/home/index.js +4 -3
  77. package/dist/home/index.js.map +1 -1
  78. package/dist/index.cjs +579 -440
  79. package/dist/index.cjs.map +1 -1
  80. package/dist/index.js +11 -8
  81. package/dist/index.js.map +1 -1
  82. package/dist/shell/index.cjs +1 -1
  83. package/dist/shell/index.js +1 -1
  84. package/dist/studio/index.cjs +7 -7
  85. package/dist/studio/index.js +5 -5
  86. package/dist/workflow-canvas/StepInspector.d.ts +57 -0
  87. package/dist/workflow-canvas/TriggerInspector.d.ts +46 -0
  88. package/dist/workflow-canvas/WorkflowBuilder.d.ts +55 -0
  89. package/dist/workflow-canvas/WorkflowCanvas.d.ts +69 -0
  90. package/dist/workflow-canvas/edit.d.ts +54 -0
  91. package/dist/workflow-canvas/index.cjs +1719 -0
  92. package/dist/workflow-canvas/index.cjs.map +1 -0
  93. package/dist/workflow-canvas/index.d.ts +13 -0
  94. package/dist/workflow-canvas/index.js +1689 -0
  95. package/dist/workflow-canvas/index.js.map +1 -0
  96. package/dist/workflow-canvas/trigger.d.ts +51 -0
  97. package/dist/workflow-canvas/viewport.d.ts +47 -0
  98. package/package.json +25 -14
  99. package/src/workflow-canvas/canvas.css +113 -0
  100. package/dist/chunk-3VQYJBOI.js.map +0 -1
  101. package/dist/chunk-5HOAOKZL.js.map +0 -1
  102. package/dist/chunk-DH7C2UJO.cjs.map +0 -1
  103. package/dist/chunk-G5DP27DU.js.map +0 -1
  104. package/dist/chunk-IMC2Z32C.js.map +0 -1
  105. package/dist/chunk-KJ3QEKOJ.cjs.map +0 -1
  106. package/dist/chunk-LFGJAZ5H.js.map +0 -1
  107. package/dist/chunk-THO7DZNN.cjs.map +0 -1
  108. package/dist/chunk-V3L5DONY.cjs.map +0 -1
  109. package/dist/chunk-WBDK4PIA.cjs.map +0 -1
@@ -1,26 +1,30 @@
1
1
  "use client";
2
2
  import { SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, SettingsCard, SettingsActionRow, PasswordChangeDialog, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-GJV2G4FC.js';
3
- export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-KOXUBCLL.js';
4
- import { ConnectionProvider, useConnection } from '../chunk-5HOAOKZL.js';
5
- export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnection } from '../chunk-5HOAOKZL.js';
6
- import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
3
+ import { useWorkspaceDocs } from '../chunk-MK6NJQGF.js';
4
+ export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-MK6NJQGF.js';
5
+ import { ConnectionProvider, useConnection } from '../chunk-OYMWV45N.js';
6
+ export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnection } from '../chunk-OYMWV45N.js';
7
+ import { WorkflowRunner, initialRunInputs, workflowSteps, fromPlanSteps, stepStatesFromActivity, toPlanSteps, runThreadTitle, useWorkflowView } from '../chunk-YWYVIQ7T.js';
8
+ import '../chunk-EVUEIBNU.js';
9
+ import '../chunk-XD2M6LIG.js';
7
10
  import '../chunk-VILAPTCB.js';
8
- import { ChatPage } from '../chunk-G5DP27DU.js';
11
+ import { StreamedArtifactFrame } from '../chunk-LOJVUGBJ.js';
12
+ import { ChatPage } from '../chunk-UIWLDSTF.js';
9
13
  import '../chunk-KZJAG7T3.js';
10
- import '../chunk-3VQYJBOI.js';
14
+ import '../chunk-HOXKR26S.js';
11
15
  import '../chunk-AA3PT6KR.js';
12
16
  import '../chunk-NPLYHR2E.js';
13
17
  import { initials } from '../chunk-OXF2IFXG.js';
14
18
  import '../chunk-TX2ZICS7.js';
15
19
  import '../chunk-7F6CBP3Z.js';
16
20
  import '../chunk-VUNV25KB.js';
17
- import { lazy, useState, Suspense, useMemo, useEffect } from 'react';
21
+ import { lazy, useState, Suspense, useCallback, useEffect, useMemo, useRef } from 'react';
18
22
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
19
- import { ArbiProvider, useConversations, useRunConversation, useUploadSkillFiles, ArtifactCanvas, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useLogoutAllSessions, useDeleteAccount, useDeleteAccountFlow, useArbi, useArbiWebSocket, notify, useWorkNotifications, useAgentSession, useStartAgentSession, useCloseAgentSession, ArbiWebSocketProvider, useArbiChat } from '@arbidocs/react';
23
+ import { ArbiProvider, useConversations, useRunConversation, useUploadSkillFiles, ArtifactCanvas, useArbi, useDocuments, useWorkspaceUsers, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useLogoutAllSessions, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, notify, useWorkNotifications, useAgentSession, useStartAgentSession, useCloseAgentSession, AiAnswer, ArbiWebSocketProvider, useCreateWork, useActOnStep, useConversationActivity, useConversationThreads, useArbiChat } from '@arbidocs/react';
20
24
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
21
- import { Button, Label, Input } from '@arbidocs/react/ui';
25
+ import { Button, Label, Input, cn } from '@arbidocs/react/ui';
22
26
  import { useStreamedArtifact } from '@arbidocs/react/artifacts';
23
- import { UserCircle, KeyRound, Radio } from 'lucide-react';
27
+ import { ExternalLink, UserCircle, KeyRound, Radio, Loader2 } from 'lucide-react';
24
28
  import { useNotify } from '@arbidocs/react/shell';
25
29
 
26
30
  function ConnectionBoundWebSocket({ children }) {
@@ -179,6 +183,353 @@ function StreamedArtifact({
179
183
  }
180
184
  );
181
185
  }
186
+ var STARTING = /* @__PURE__ */ new Set(["pending", "running"]);
187
+ function formValues(step, inputs) {
188
+ if (step.kind !== "form") return void 0;
189
+ return Object.fromEntries(step.inputs.map((f) => [f.name, inputs[f.name] ?? ""]));
190
+ }
191
+ var ANSWER_RETRY_CAP = 16;
192
+ function answerRetryDelay(attempt) {
193
+ return attempt === 0 ? 0 : Math.min(1e3 * 2 ** (attempt - 1), 15e3);
194
+ }
195
+ function useAnswerRetry(missing, refetch) {
196
+ const [attempt, setAttempt] = useState(0);
197
+ const [prev, setPrev] = useState(missing);
198
+ if (prev !== missing) {
199
+ setPrev(missing);
200
+ setAttempt(0);
201
+ }
202
+ const refetchRef = useRef(refetch);
203
+ refetchRef.current = refetch;
204
+ useEffect(() => {
205
+ if (!missing || attempt >= ANSWER_RETRY_CAP) return;
206
+ const t = setTimeout(() => {
207
+ void refetchRef.current();
208
+ setAttempt((a) => a + 1);
209
+ }, answerRetryDelay(attempt));
210
+ return () => clearTimeout(t);
211
+ }, [missing, attempt]);
212
+ }
213
+ function useWorkflowThread(workflow, options = {}) {
214
+ const arbi = useArbi();
215
+ const { ensureWorkspaceOpen } = useConnection();
216
+ const { wsId } = useWorkspaceDocs();
217
+ const [threadId, setThreadId] = useState(options.conversationId);
218
+ const [localInputs, setLocalInputs] = useState(
219
+ () => initialRunInputs(workflow, options.initialInputs)
220
+ );
221
+ const [edits, setEdits] = useState({});
222
+ const [localStates, setLocalStates] = useState({});
223
+ const createWork = useCreateWork();
224
+ const actOnStep = useActOnStep();
225
+ const conversations = useConversations(wsId, { enabled: !!threadId, live: true });
226
+ const conversation = conversations.data?.find((c) => c.external_id === threadId);
227
+ const steps = useMemo(
228
+ () => workflowSteps(workflow).length > 0 ? workflowSteps(workflow) : fromPlanSteps(conversation?.plan?.steps ?? []),
229
+ [workflow, conversation?.plan?.steps]
230
+ );
231
+ const activity = useConversationActivity(threadId, { live: !!threadId });
232
+ const serverStates = useMemo(
233
+ () => stepStatesFromActivity(activity.data ?? []),
234
+ [activity.data]
235
+ );
236
+ const working = steps.some(
237
+ (s) => s.kind === "agent" && STARTING.has(serverStates[s.id]?.status ?? "pending")
238
+ );
239
+ const threads = useConversationThreads(wsId, threadId, { enabled: !!threadId, live: working });
240
+ const answers = useMemo(() => {
241
+ const byId = /* @__PURE__ */ new Map();
242
+ for (const t of threads.data?.threads ?? [])
243
+ for (const m of t.history)
244
+ if (m.role === "assistant" && m.content?.trim()) byId.set(m.external_id, m.content);
245
+ return byId;
246
+ }, [threads.data]);
247
+ const missing = Object.values(serverStates).flatMap(
248
+ (st) => st.status === "done" && st.responseId && !answers.has(st.responseId) ? [st.responseId] : []
249
+ ).sort().join(" ");
250
+ useAnswerRetry(missing, threads.refetch);
251
+ const states = useMemo(() => {
252
+ if (!threadId) return localStates;
253
+ const out = {};
254
+ for (const [id, s] of Object.entries(serverStates))
255
+ out[id] = { ...s, text: s.responseId ? answers.get(s.responseId) : void 0 };
256
+ return out;
257
+ }, [threadId, localStates, serverStates, answers]);
258
+ const inputs = useMemo(
259
+ () => threadId ? { ...localInputs, ...conversation?.skill_inputs ?? {}, ...edits } : { ...localInputs, ...edits },
260
+ [threadId, localInputs, conversation?.skill_inputs, edits]
261
+ );
262
+ const refresh = useCallback(async () => {
263
+ await Promise.all([activity.refetch(), conversations.refetch()]);
264
+ }, [activity, conversations]);
265
+ const act = useCallback(
266
+ async (id, body) => {
267
+ await actOnStep.mutateAsync({ conversationId: id, body });
268
+ await refresh();
269
+ },
270
+ [actOnStep, refresh]
271
+ );
272
+ const complete = useCallback(
273
+ async (step) => {
274
+ let values = inputs;
275
+ const commit = step.commit ? options.commit?.[step.id] : void 0;
276
+ if (commit && localStates[step.id]?.status !== "done") {
277
+ values = { ...values, ...await commit(values) ?? {} };
278
+ setLocalInputs(values);
279
+ setEdits({});
280
+ }
281
+ let id = threadId;
282
+ if (!id) {
283
+ await ensureWorkspaceOpen();
284
+ const created = await createWork.mutateAsync({
285
+ title: runThreadTitle(workflow, values).slice(0, 60),
286
+ description: workflow.description || null,
287
+ prompt: null,
288
+ skill_ref: null,
289
+ skill_inputs: values,
290
+ agent_ext_id: options.agentId ?? null,
291
+ auth_mode: "run_now_temp",
292
+ plan: {
293
+ goal: "",
294
+ criteria: [],
295
+ max_passes: 3,
296
+ documents: [],
297
+ steps: toPlanSteps(workflow, {
298
+ inputs: values,
299
+ resolveWorkflow: options.resolveWorkflow,
300
+ compose: options.compose
301
+ })
302
+ }
303
+ });
304
+ id = created.external_id;
305
+ setThreadId(id);
306
+ setLocalStates((s) => ({ ...s, [step.id]: { status: "done" } }));
307
+ options.onStarted?.(id);
308
+ }
309
+ await act(id, { step: step.id, action: "complete", inputs: formValues(step, values) });
310
+ },
311
+ [inputs, options, localStates, threadId, ensureWorkspaceOpen, createWork, workflow, act]
312
+ );
313
+ const skip = useCallback(
314
+ async (stepId) => {
315
+ if (!threadId) {
316
+ setLocalStates((s) => ({ ...s, [stepId]: { status: "skipped" } }));
317
+ return;
318
+ }
319
+ await act(threadId, { step: stepId, action: "skip" });
320
+ },
321
+ [threadId, act]
322
+ );
323
+ const retry = useCallback(
324
+ async (_stepId) => {
325
+ if (!threadId) return;
326
+ await arbi.conversations.runWithAuth(threadId);
327
+ await refresh();
328
+ },
329
+ [arbi, threadId, refresh]
330
+ );
331
+ const view = useWorkflowView({
332
+ steps,
333
+ states,
334
+ inputs,
335
+ setInput: (name, value) => setEdits((i) => ({ ...i, [name]: value })),
336
+ complete,
337
+ skip,
338
+ retry,
339
+ isLocked: (id) => states[id]?.status === "done"
340
+ });
341
+ return { view, conversationId: threadId, conversation };
342
+ }
343
+ var DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS = {
344
+ notify: "Ask to approve",
345
+ notified: "Notified.",
346
+ openThread: "Open the thread",
347
+ loadingAnswer: "Fetching the answer\u2026"
348
+ };
349
+ function ConnectedWorkflowRunner({
350
+ workflow,
351
+ options,
352
+ onOpenConversation,
353
+ emptyHint,
354
+ connectedLabels,
355
+ testIdPrefix = "workflow-run",
356
+ ...runnerProps
357
+ }) {
358
+ const l = { ...DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, ...connectedLabels };
359
+ const arbi = useArbi();
360
+ const { ensureWorkspaceOpen } = useConnection();
361
+ const { wsId } = useWorkspaceDocs();
362
+ const { data: docs = [], refetch } = useDocuments(wsId);
363
+ const [uploading, setUploading] = useState(false);
364
+ const { view, conversationId } = useWorkflowThread(workflow, options);
365
+ const [added, setAdded] = useState({});
366
+ const onUpload = useCallback(
367
+ async (files2, step) => {
368
+ if (!files2.length) return;
369
+ setUploading(true);
370
+ try {
371
+ await ensureWorkspaceOpen();
372
+ for (const f of files2) {
373
+ const { doc_ext_ids = [] } = await arbi.documents.uploadFile(f, f.name) ?? {};
374
+ setAdded((a) => ({ ...a, ...Object.fromEntries(doc_ext_ids.map((id) => [id, step.id])) }));
375
+ }
376
+ await refetch();
377
+ } finally {
378
+ setUploading(false);
379
+ }
380
+ },
381
+ [arbi, ensureWorkspaceOpen, refetch]
382
+ );
383
+ const files = docs.map((d) => ({
384
+ id: d.external_id,
385
+ name: d.file_name ?? d.external_id,
386
+ status: fileStatus(d.status),
387
+ addedFor: added[d.external_id]
388
+ }));
389
+ const reading = files.some((f) => f.addedFor && f.status === "processing");
390
+ useEffect(() => {
391
+ if (!reading) return;
392
+ const t = setInterval(() => void refetch(), READ_POLL_MS);
393
+ return () => clearInterval(t);
394
+ }, [reading, refetch]);
395
+ const renderAgentOutput = (step, state) => {
396
+ const status = state?.status;
397
+ if (!state?.text && status !== "done") return null;
398
+ if (!state?.text && state?.responseId) {
399
+ return /* @__PURE__ */ jsxs(
400
+ "p",
401
+ {
402
+ className: "flex items-center gap-2 text-sm text-muted-foreground",
403
+ "data-testid": `${testIdPrefix}-${step.id}-answer-loading`,
404
+ children: [
405
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
406
+ " ",
407
+ l.loadingAnswer
408
+ ]
409
+ }
410
+ );
411
+ }
412
+ return /* @__PURE__ */ jsx(
413
+ AiAnswer,
414
+ {
415
+ status: status === "running" ? "running" : "done",
416
+ text: state?.text ?? "",
417
+ emptyHint: emptyHint?.(step),
418
+ testId: `${testIdPrefix}-${step.id}-answer`
419
+ }
420
+ );
421
+ };
422
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
423
+ conversationId && onOpenConversation && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
424
+ Button,
425
+ {
426
+ variant: "ghost",
427
+ size: "sm",
428
+ onClick: () => onOpenConversation(conversationId),
429
+ "data-testid": `${testIdPrefix}-open-thread`,
430
+ children: [
431
+ /* @__PURE__ */ jsx(ExternalLink, { className: "size-4" }),
432
+ " ",
433
+ l.openThread
434
+ ]
435
+ }
436
+ ) }),
437
+ /* @__PURE__ */ jsx(
438
+ WorkflowRunner,
439
+ {
440
+ ...runnerProps,
441
+ workflow,
442
+ run: view,
443
+ renderAgentOutput,
444
+ renderReview: (step) => conversationId ? /* @__PURE__ */ jsx(
445
+ ReviewNotify,
446
+ {
447
+ conversationId,
448
+ workspaceId: wsId,
449
+ labels: l,
450
+ testId: `${testIdPrefix}-${step.id}`
451
+ }
452
+ ) : null,
453
+ onUpload,
454
+ uploading,
455
+ files,
456
+ testIdPrefix
457
+ }
458
+ )
459
+ ] });
460
+ }
461
+ var READ_POLL_MS = 3e3;
462
+ function fileStatus(status) {
463
+ const s = status?.toLowerCase();
464
+ if (!s) return void 0;
465
+ if (s === "failed") return "failed";
466
+ if (s === "completed" || s === "empty" || s === "low-content") return "ready";
467
+ return "processing";
468
+ }
469
+ function ReviewNotify({
470
+ conversationId,
471
+ workspaceId,
472
+ labels,
473
+ testId
474
+ }) {
475
+ const arbi = useArbi();
476
+ const { status, user, ensureWorkspaceOpen } = useConnection();
477
+ const { data: members = [] } = useWorkspaceUsers(workspaceId, {
478
+ enabled: status === "authenticated" && !!workspaceId,
479
+ beforeFetch: ensureWorkspaceOpen
480
+ });
481
+ const people = members.filter(
482
+ (m) => !m.agent_ext_id && !m.user.external_id.startsWith("agt-") && m.user.external_id !== user?.externalId
483
+ );
484
+ const [picked, setPicked] = useState([]);
485
+ const [sent, setSent] = useState(false);
486
+ const [busy, setBusy] = useState(false);
487
+ if (people.length === 0) return null;
488
+ const toggle = (id) => setPicked((p) => p.includes(id) ? p.filter((x) => x !== id) : [...p, id]);
489
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", "data-testid": `${testId}-notify`, children: [
490
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: people.map((m) => {
491
+ const name = [m.user.given_name, m.user.family_name].filter(Boolean).join(" ") || m.user.email;
492
+ const on = picked.includes(m.user.external_id);
493
+ return /* @__PURE__ */ jsx(
494
+ "button",
495
+ {
496
+ type: "button",
497
+ onClick: () => toggle(m.user.external_id),
498
+ "aria-pressed": on,
499
+ className: cn(
500
+ "rounded-full border px-2.5 py-1 text-xs",
501
+ on ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground"
502
+ ),
503
+ "data-testid": `${testId}-person-${m.user.external_id}`,
504
+ children: name
505
+ },
506
+ m.user.external_id
507
+ );
508
+ }) }),
509
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
510
+ /* @__PURE__ */ jsx(
511
+ Button,
512
+ {
513
+ variant: "outline",
514
+ size: "sm",
515
+ disabled: !picked.length || busy,
516
+ onClick: async () => {
517
+ setBusy(true);
518
+ try {
519
+ await arbi.conversations.notify(conversationId, picked);
520
+ setSent(true);
521
+ } finally {
522
+ setBusy(false);
523
+ }
524
+ },
525
+ "data-testid": `${testId}-notify-send`,
526
+ children: labels.notify
527
+ }
528
+ ),
529
+ sent && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: labels.notified })
530
+ ] })
531
+ ] });
532
+ }
182
533
  function useConnectedShellWorkspaces(options = {}) {
183
534
  const { workspaceId, setWorkspace } = useConnection();
184
535
  const query = useWorkspaces();
@@ -777,6 +1128,6 @@ function ConnectedAgentChatPanel({
777
1128
  ] });
778
1129
  }
779
1130
 
780
- export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedNotificationPreferences, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTaskAccessRequest, StreamedArtifact, defaultUnmetPasswordRequirement, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications };
1131
+ export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedNotificationPreferences, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTaskAccessRequest, ConnectedWorkflowRunner, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, defaultUnmetPasswordRequirement, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications };
781
1132
  //# sourceMappingURL=index.js.map
782
1133
  //# sourceMappingURL=index.js.map