@arbidocs/blocks 0.4.76 → 0.4.78

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 (123) hide show
  1. package/dist/agents/index.cjs +346 -258
  2. package/dist/agents/index.js +5 -5
  3. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  4. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +15 -4
  5. package/dist/agents/workflows/SchemaForm.d.ts +6 -1
  6. package/dist/agents/workflows/StepBarFrame.d.ts +75 -0
  7. package/dist/agents/workflows/StepParts.d.ts +109 -0
  8. package/dist/agents/workflows/WorkflowRunner.d.ts +15 -2
  9. package/dist/agents/workflows/WorkflowStepBar.d.ts +9 -11
  10. package/dist/agents/workflows/index.d.ts +5 -2
  11. package/dist/agents/workflows/planSteps.d.ts +8 -1
  12. package/dist/agents/workflows/run.d.ts +61 -8
  13. package/dist/agents/workflows/stepWindow.d.ts +59 -0
  14. package/dist/agents/workflows/types.d.ts +133 -4
  15. package/dist/agents/workflows/useWorkflowPreview.d.ts +2 -1
  16. package/dist/agents/workflows/useWorkflowView.d.ts +19 -0
  17. package/dist/chat/ChatPage.d.ts +1 -1
  18. package/dist/chat/WorkflowStepChip.d.ts +24 -0
  19. package/dist/chat/chat-page-types.d.ts +9 -0
  20. package/dist/chat/index.cjs +130 -122
  21. package/dist/chat/index.d.ts +1 -0
  22. package/dist/chat/index.js +2 -2
  23. package/dist/{chunk-TKB7TVMW.js → chunk-5OC5CGYX.js} +168 -100
  24. package/dist/chunk-5OC5CGYX.js.map +1 -0
  25. package/dist/{chunk-ZWA7UUZL.cjs → chunk-7YUFMNFW.cjs} +2 -54
  26. package/dist/chunk-7YUFMNFW.cjs.map +1 -0
  27. package/dist/chunk-A24C6BNA.js +92 -0
  28. package/dist/chunk-A24C6BNA.js.map +1 -0
  29. package/dist/chunk-AINNADMT.cjs +62 -0
  30. package/dist/chunk-AINNADMT.cjs.map +1 -0
  31. package/dist/chunk-CWAZNXC5.js +441 -0
  32. package/dist/chunk-CWAZNXC5.js.map +1 -0
  33. package/dist/{chunk-UIWLDSTF.js → chunk-EWSEQEPL.js} +71 -7
  34. package/dist/chunk-EWSEQEPL.js.map +1 -0
  35. package/dist/chunk-FE4ULGOR.js +151 -0
  36. package/dist/chunk-FE4ULGOR.js.map +1 -0
  37. package/dist/chunk-FT5FFXSJ.js +60 -0
  38. package/dist/chunk-FT5FFXSJ.js.map +1 -0
  39. package/dist/{chunk-WJEKRSPH.js → chunk-ICBAFX5B.js} +3 -3
  40. package/dist/{chunk-WJEKRSPH.js.map → chunk-ICBAFX5B.js.map} +1 -1
  41. package/dist/{chunk-7CVF3DK2.cjs → chunk-IF6VAYIA.cjs} +5 -5
  42. package/dist/{chunk-7CVF3DK2.cjs.map → chunk-IF6VAYIA.cjs.map} +1 -1
  43. package/dist/chunk-MLAHDAN5.cjs +450 -0
  44. package/dist/chunk-MLAHDAN5.cjs.map +1 -0
  45. package/dist/{chunk-IPGKTUF7.cjs → chunk-MP6FK43E.cjs} +71 -5
  46. package/dist/chunk-MP6FK43E.cjs.map +1 -0
  47. package/dist/{chunk-5EBGRG3X.js → chunk-OPA2Y6YZ.js} +3 -54
  48. package/dist/chunk-OPA2Y6YZ.js.map +1 -0
  49. package/dist/{chunk-7FKARMA3.cjs → chunk-SSDISIDW.cjs} +190 -122
  50. package/dist/chunk-SSDISIDW.cjs.map +1 -0
  51. package/dist/chunk-TZR36PPP.cjs +95 -0
  52. package/dist/chunk-TZR36PPP.cjs.map +1 -0
  53. package/dist/chunk-VFIZYSZB.cjs +2783 -0
  54. package/dist/chunk-VFIZYSZB.cjs.map +1 -0
  55. package/dist/chunk-WXRCMIAE.js +2707 -0
  56. package/dist/chunk-WXRCMIAE.js.map +1 -0
  57. package/dist/{chunk-HITAN7JF.cjs → chunk-XMBYDLZQ.cjs} +4 -4
  58. package/dist/{chunk-HITAN7JF.cjs.map → chunk-XMBYDLZQ.cjs.map} +1 -1
  59. package/dist/{chunk-MK6NJQGF.js → chunk-XQDM6T6C.js} +3 -3
  60. package/dist/{chunk-MK6NJQGF.js.map → chunk-XQDM6T6C.js.map} +1 -1
  61. package/dist/chunk-ZVBPRMHJ.cjs +153 -0
  62. package/dist/chunk-ZVBPRMHJ.cjs.map +1 -0
  63. package/dist/connect/docx.cjs +10 -88
  64. package/dist/connect/docx.cjs.map +1 -1
  65. package/dist/connect/docx.js +6 -86
  66. package/dist/connect/docx.js.map +1 -1
  67. package/dist/connect/index.cjs +468 -49
  68. package/dist/connect/index.cjs.map +1 -1
  69. package/dist/connect/index.d.ts +2 -0
  70. package/dist/connect/index.js +454 -37
  71. package/dist/connect/index.js.map +1 -1
  72. package/dist/connection/ConnectedTagMatrix.d.ts +20 -0
  73. package/dist/connection/ConnectedWorkflowRunner.d.ts +28 -2
  74. package/dist/connection/WorkflowRunThread.d.ts +21 -0
  75. package/dist/connection/WorkflowRunnerDialogs.d.ts +37 -0
  76. package/dist/connection/useWorkflowThread.d.ts +12 -0
  77. package/dist/document-tools/index.cjs +7 -143
  78. package/dist/document-tools/index.cjs.map +1 -1
  79. package/dist/document-tools/index.js +5 -144
  80. package/dist/document-tools/index.js.map +1 -1
  81. package/dist/docx/index.cjs +18 -17
  82. package/dist/docx/index.cjs.map +1 -1
  83. package/dist/docx/index.js +3 -2
  84. package/dist/docx/index.js.map +1 -1
  85. package/dist/facts/index.cjs +1 -1
  86. package/dist/facts/index.js +1 -1
  87. package/dist/files/index.cjs +1 -1
  88. package/dist/files/index.js +1 -1
  89. package/dist/home/index.cjs +1 -1
  90. package/dist/home/index.js +1 -1
  91. package/dist/index.cjs +560 -431
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +10 -9
  95. package/dist/index.js.map +1 -1
  96. package/dist/shell/index.cjs +1 -1
  97. package/dist/shell/index.js +1 -1
  98. package/dist/studio/index.cjs +4 -4
  99. package/dist/studio/index.js +3 -3
  100. package/dist/tags/TagMatrix.d.ts +64 -0
  101. package/dist/tags/index.d.ts +3 -0
  102. package/dist/tags/tagMatrixModel.d.ts +39 -0
  103. package/dist/workflow-canvas/StepActionSettings.d.ts +132 -0
  104. package/dist/workflow-canvas/StepInspector.d.ts +25 -2
  105. package/dist/workflow-canvas/WorkflowBuilder.d.ts +11 -3
  106. package/dist/workflow-canvas/WorkflowCanvas.d.ts +27 -2
  107. package/dist/workflow-canvas/edit.d.ts +9 -1
  108. package/dist/workflow-canvas/index.cjs +882 -102
  109. package/dist/workflow-canvas/index.cjs.map +1 -1
  110. package/dist/workflow-canvas/index.js +849 -69
  111. package/dist/workflow-canvas/index.js.map +1 -1
  112. package/package.json +4 -4
  113. package/src/workflow-canvas/canvas.css +9 -0
  114. package/dist/chunk-22P5KNIM.js +0 -1422
  115. package/dist/chunk-22P5KNIM.js.map +0 -1
  116. package/dist/chunk-5EBGRG3X.js.map +0 -1
  117. package/dist/chunk-7FKARMA3.cjs.map +0 -1
  118. package/dist/chunk-IPGKTUF7.cjs.map +0 -1
  119. package/dist/chunk-TKB7TVMW.js.map +0 -1
  120. package/dist/chunk-UIWLDSTF.js.map +0 -1
  121. package/dist/chunk-VYRKO3XU.cjs +0 -1469
  122. package/dist/chunk-VYRKO3XU.cjs.map +0 -1
  123. package/dist/chunk-ZWA7UUZL.cjs.map +0 -1
@@ -2,20 +2,24 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkB3WCKBJ7_cjs = require('../chunk-B3WCKBJ7.cjs');
5
- var chunkHITAN7JF_cjs = require('../chunk-HITAN7JF.cjs');
5
+ var chunkXMBYDLZQ_cjs = require('../chunk-XMBYDLZQ.cjs');
6
+ var chunkTZR36PPP_cjs = require('../chunk-TZR36PPP.cjs');
6
7
  var chunkMUMH3Z6K_cjs = require('../chunk-MUMH3Z6K.cjs');
7
- var chunkVYRKO3XU_cjs = require('../chunk-VYRKO3XU.cjs');
8
- require('../chunk-DETZZBG2.cjs');
8
+ var chunkZVBPRMHJ_cjs = require('../chunk-ZVBPRMHJ.cjs');
9
+ require('../chunk-7YUFMNFW.cjs');
10
+ var chunkMLAHDAN5_cjs = require('../chunk-MLAHDAN5.cjs');
11
+ var chunkVFIZYSZB_cjs = require('../chunk-VFIZYSZB.cjs');
9
12
  require('../chunk-7D737FLE.cjs');
13
+ require('../chunk-DETZZBG2.cjs');
10
14
  var chunkQVBZESYQ_cjs = require('../chunk-QVBZESYQ.cjs');
11
15
  require('../chunk-ADOKTJHV.cjs');
12
- var chunkIPGKTUF7_cjs = require('../chunk-IPGKTUF7.cjs');
16
+ var chunkMP6FK43E_cjs = require('../chunk-MP6FK43E.cjs');
13
17
  require('../chunk-VGOFFCMT.cjs');
14
18
  require('../chunk-B4SRYJLM.cjs');
15
19
  require('../chunk-7UTB4PHM.cjs');
16
20
  require('../chunk-PPCATBOY.cjs');
17
21
  var chunkKDG6FER6_cjs = require('../chunk-KDG6FER6.cjs');
18
- require('../chunk-ULWRNGGE.cjs');
22
+ var chunkULWRNGGE_cjs = require('../chunk-ULWRNGGE.cjs');
19
23
  require('../chunk-MHVNT4J3.cjs');
20
24
  require('../chunk-DES3K4SD.cjs');
21
25
  var react = require('react');
@@ -25,6 +29,7 @@ var jsxRuntime = require('react/jsx-runtime');
25
29
  var ui = require('@arbidocs/react/ui');
26
30
  var artifacts = require('@arbidocs/react/artifacts');
27
31
  var lucideReact = require('lucide-react');
32
+ var documentTools = require('@arbidocs/react/document-tools');
28
33
  var shell = require('@arbidocs/react/shell');
29
34
 
30
35
  function ConnectionBoundWebSocket({ children }) {
@@ -185,8 +190,15 @@ function StreamedArtifact({
185
190
  }
186
191
  var STARTING = /* @__PURE__ */ new Set(["pending", "running"]);
187
192
  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] ?? ""]));
193
+ const fields = chunkVFIZYSZB_cjs.stepFields(step);
194
+ if (!fields.length) return void 0;
195
+ if (step.kind === "form")
196
+ return Object.fromEntries(fields.map((f) => [f.name, inputs[f.name] ?? ""]));
197
+ const given = fields.flatMap((f) => {
198
+ const v = inputs[f.name];
199
+ return v === void 0 || v === "" ? [] : [[f.name, v]];
200
+ });
201
+ return given.length ? Object.fromEntries(given) : void 0;
190
202
  }
191
203
  var ANSWER_RETRY_CAP = 16;
192
204
  function answerRetryDelay(attempt) {
@@ -212,29 +224,40 @@ function useAnswerRetry(missing, refetch) {
212
224
  }
213
225
  function useWorkflowThread(workflow, options = {}) {
214
226
  const arbi = react$1.useArbi();
215
- const { ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
216
- const { wsId } = chunkHITAN7JF_cjs.useWorkspaceDocs();
227
+ const { ensureWorkspaceOpen, status } = chunkMUMH3Z6K_cjs.useConnection();
228
+ const { wsId } = chunkXMBYDLZQ_cjs.useWorkspaceDocs();
217
229
  const [threadId, setThreadId] = react.useState(options.conversationId);
218
230
  const [localInputs, setLocalInputs] = react.useState(
219
- () => chunkVYRKO3XU_cjs.initialRunInputs(workflow, options.initialInputs)
231
+ () => chunkVFIZYSZB_cjs.initialRunInputs(workflow, options.initialInputs)
220
232
  );
221
233
  const [edits, setEdits] = react.useState({});
222
234
  const [localStates, setLocalStates] = react.useState({});
223
235
  const createWork = react$1.useCreateWork();
224
236
  const actOnStep = react$1.useActOnStep();
225
237
  const conversations = react$1.useConversations(wsId, { enabled: !!threadId, live: true });
238
+ const members = react$1.useWorkspaceUsers(wsId, {
239
+ enabled: status === "authenticated" && !!wsId,
240
+ beforeFetch: ensureWorkspaceOpen
241
+ });
242
+ const nameOf = react.useCallback(
243
+ (id) => {
244
+ const u = members.data?.find((m) => m.user.external_id === id)?.user;
245
+ return u ? [u.given_name, u.family_name].filter(Boolean).join(" ") || u.email : void 0;
246
+ },
247
+ [members.data]
248
+ );
226
249
  const conversation = conversations.data?.find((c) => c.external_id === threadId);
227
250
  const steps = react.useMemo(
228
- () => chunkVYRKO3XU_cjs.workflowSteps(workflow).length > 0 ? chunkVYRKO3XU_cjs.workflowSteps(workflow) : chunkVYRKO3XU_cjs.fromPlanSteps(conversation?.plan?.steps ?? []),
251
+ () => chunkVFIZYSZB_cjs.workflowSteps(workflow).length > 0 ? chunkVFIZYSZB_cjs.workflowSteps(workflow) : chunkVFIZYSZB_cjs.fromPlanSteps(conversation?.plan?.steps ?? []),
229
252
  [workflow, conversation?.plan?.steps]
230
253
  );
231
254
  const activity = react$1.useConversationActivity(threadId, { live: !!threadId });
232
255
  const serverStates = react.useMemo(
233
- () => chunkVYRKO3XU_cjs.stepStatesFromActivity(activity.data ?? []),
256
+ () => chunkVFIZYSZB_cjs.stepStatesFromActivity(activity.data ?? []),
234
257
  [activity.data]
235
258
  );
236
259
  const working = steps.some(
237
- (s) => s.kind === "agent" && STARTING.has(serverStates[s.id]?.status ?? "pending")
260
+ (s) => (s.kind === "agent" || s.kind === "action") && STARTING.has(serverStates[s.id]?.status ?? "pending")
238
261
  );
239
262
  const threads = react$1.useConversationThreads(wsId, threadId, { enabled: !!threadId, live: working });
240
263
  const answers = react.useMemo(() => {
@@ -282,7 +305,7 @@ function useWorkflowThread(workflow, options = {}) {
282
305
  if (!id) {
283
306
  await ensureWorkspaceOpen();
284
307
  const created = await createWork.mutateAsync({
285
- title: chunkVYRKO3XU_cjs.runThreadTitle(workflow, values).slice(0, 60),
308
+ title: chunkVFIZYSZB_cjs.runThreadTitle(workflow, values).slice(0, 60),
286
309
  description: workflow.description || null,
287
310
  prompt: null,
288
311
  skill_ref: null,
@@ -294,7 +317,7 @@ function useWorkflowThread(workflow, options = {}) {
294
317
  criteria: [],
295
318
  max_passes: 3,
296
319
  documents: [],
297
- steps: chunkVYRKO3XU_cjs.toPlanSteps(workflow, {
320
+ steps: chunkVFIZYSZB_cjs.toPlanSteps(workflow, {
298
321
  inputs: values,
299
322
  resolveWorkflow: options.resolveWorkflow,
300
323
  compose: options.compose
@@ -306,7 +329,13 @@ function useWorkflowThread(workflow, options = {}) {
306
329
  setLocalStates((s) => ({ ...s, [step.id]: { status: "done" } }));
307
330
  options.onStarted?.(id);
308
331
  }
309
- await act(id, { step: step.id, action: "complete", inputs: formValues(step, values) });
332
+ const documents = step.kind === "upload" ? options.documentsFor?.(step.id) : void 0;
333
+ await act(id, {
334
+ step: step.id,
335
+ action: "complete",
336
+ inputs: formValues(step, values),
337
+ ...documents?.length ? { documents } : {}
338
+ });
310
339
  },
311
340
  [inputs, options, localStates, threadId, ensureWorkspaceOpen, createWork, workflow, act]
312
341
  );
@@ -328,7 +357,22 @@ function useWorkflowThread(workflow, options = {}) {
328
357
  },
329
358
  [arbi, threadId, refresh]
330
359
  );
331
- const view = chunkVYRKO3XU_cjs.useWorkflowView({
360
+ const sendBack = react.useCallback(
361
+ async (stepId, to, note) => {
362
+ if (!threadId) return;
363
+ await act(threadId, { step: stepId, action: "send_back", to, ...note ? { note } : {} });
364
+ },
365
+ [threadId, act]
366
+ );
367
+ const decline = react.useCallback(
368
+ async (stepId, note) => {
369
+ if (!threadId) return;
370
+ await act(threadId, { step: stepId, action: "decline", ...note ? { note } : {} });
371
+ },
372
+ [threadId, act]
373
+ );
374
+ const loaded = !options.conversationId || activity.isSuccess || activity.isError;
375
+ const view = chunkVFIZYSZB_cjs.useWorkflowView({
332
376
  steps,
333
377
  states,
334
378
  inputs,
@@ -336,12 +380,208 @@ function useWorkflowThread(workflow, options = {}) {
336
380
  complete,
337
381
  skip,
338
382
  retry,
383
+ sendBack,
384
+ decline,
385
+ nameOf,
386
+ loaded,
339
387
  isLocked: (id) => states[id]?.status === "done"
340
388
  });
341
- return { view, conversationId: threadId, conversation };
389
+ const people = react.useMemo(
390
+ () => (members.data ?? []).filter((m) => !m.user.external_id.startsWith("agt-")).map((m) => ({
391
+ value: m.user.external_id,
392
+ label: nameOf(m.user.external_id) ?? m.user.external_id
393
+ })),
394
+ [members.data, nameOf]
395
+ );
396
+ return { view, conversationId: threadId, conversation, nameOf, people };
397
+ }
398
+ function WorkflowRunThread({
399
+ conversationId,
400
+ workspaceId,
401
+ aside,
402
+ stepTitle,
403
+ targetMessageId,
404
+ onOpenCitation,
405
+ labels,
406
+ className
407
+ }) {
408
+ const chat = react$1.useArbiChat({ workspaceId });
409
+ const listed = chat.threads.some((t) => t.id === conversationId);
410
+ const { selectThread, activeThreadId } = chat;
411
+ react.useEffect(() => {
412
+ if (listed && activeThreadId !== conversationId) selectThread(conversationId);
413
+ }, [listed, activeThreadId, conversationId, selectThread]);
414
+ return /* @__PURE__ */ jsxRuntime.jsx(
415
+ chunkMP6FK43E_cjs.ChatPage,
416
+ {
417
+ chat: { ...chat, threads: chat.threads.filter((t) => t.id === conversationId) },
418
+ singleThread: true,
419
+ documentsRequired: false,
420
+ aside,
421
+ asideBreakpoint: 52,
422
+ workflowStepTitle: stepTitle,
423
+ targetMessageId,
424
+ onOpenCitation,
425
+ labels,
426
+ className: className ?? "h-[min(78dvh,860px)] min-h-[480px] rounded-xl border border-border"
427
+ }
428
+ );
429
+ }
430
+ var DEFAULT_WORKFLOW_RUNNER_DIALOG_LABELS = {
431
+ loadingDocument: "Opening the document\u2026",
432
+ documentFailed: "The document could not be opened.",
433
+ reviewTitle: "Review",
434
+ reviewDescription: "Each document against each review column.",
435
+ document: "Document",
436
+ empty: "\u2014",
437
+ wordTitle: "Tracked changes"
438
+ };
439
+ function WorkflowSignDialog({
440
+ docRef,
441
+ onClose,
442
+ labels
443
+ }) {
444
+ const arbi = react$1.useArbi();
445
+ const { user, ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
446
+ const tools = documentTools.useOptionalDocumentTools();
447
+ const { id, version } = chunkVFIZYSZB_cjs.splitDocRef(docRef);
448
+ const [pdf, setPdf] = react.useState(null);
449
+ const [failed, setFailed] = react.useState(false);
450
+ react.useEffect(() => {
451
+ let live = true;
452
+ void (async () => {
453
+ try {
454
+ await ensureWorkspaceOpen();
455
+ const res = await arbi.documents.download(id, version);
456
+ if (!res.ok) throw new Error(String(res.status));
457
+ const blob = await res.blob();
458
+ if (live) setPdf(blob);
459
+ } catch {
460
+ if (live) setFailed(true);
461
+ }
462
+ })();
463
+ return () => {
464
+ live = false;
465
+ };
466
+ }, [arbi, id, version, ensureWorkspaceOpen]);
467
+ if (!pdf)
468
+ return /* @__PURE__ */ jsxRuntime.jsx(
469
+ chunkULWRNGGE_cjs.ModalScaffold,
470
+ {
471
+ open: true,
472
+ onOpenChange: (o) => !o && onClose(),
473
+ title: labels.loadingDocument,
474
+ size: "sm",
475
+ testId: "workflow-sign-loading",
476
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkULWRNGGE_cjs.ModalScaffold.Body, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: failed ? labels.documentFailed : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
477
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }),
478
+ " ",
479
+ labels.loadingDocument
480
+ ] }) }) })
481
+ }
482
+ );
483
+ const dialog = /* @__PURE__ */ jsxRuntime.jsx(chunkZVBPRMHJ_cjs.SignDocumentDialog, { open: true, onOpenChange: (o) => !o && onClose(), documentId: id, pdfBlob: pdf });
484
+ return tools ? dialog : /* @__PURE__ */ jsxRuntime.jsx(
485
+ documentTools.DocumentToolsProvider,
486
+ {
487
+ client: arbi.getClient().fetch,
488
+ user: user ? { name: user.name, email: user.email } : null,
489
+ children: dialog
490
+ }
491
+ );
492
+ }
493
+ function WorkflowWordDialog({
494
+ docRef,
495
+ title,
496
+ onClose,
497
+ labels
498
+ }) {
499
+ const { id } = chunkVFIZYSZB_cjs.splitDocRef(docRef);
500
+ return /* @__PURE__ */ jsxRuntime.jsx(
501
+ chunkULWRNGGE_cjs.ModalScaffold,
502
+ {
503
+ open: true,
504
+ onOpenChange: (o) => !o && onClose(),
505
+ title: title ?? labels.wordTitle,
506
+ size: "xl",
507
+ testId: "workflow-word-dialog",
508
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkULWRNGGE_cjs.ModalScaffold.Body, { className: "h-[70dvh] p-0", children: /* @__PURE__ */ jsxRuntime.jsx(chunkTZR36PPP_cjs.ConnectedNativeDocxEditor, { documentId: id, title: title ?? labels.wordTitle }) })
509
+ }
510
+ );
511
+ }
512
+ function WorkflowReviewGridDialog({
513
+ tags,
514
+ documents,
515
+ onClose,
516
+ onOpenDocument,
517
+ labels
518
+ }) {
519
+ const { workspaceId } = chunkMUMH3Z6K_cjs.useConnection();
520
+ const allTags = react$1.useTags(workspaceId ?? void 0);
521
+ const all = react$1.useDocuments(workspaceId ?? void 0);
522
+ const docs = {
523
+ isLoading: all.isLoading,
524
+ data: (all.data ?? []).filter((d) => documents.includes(d.external_id))
525
+ };
526
+ const columns = react.useMemo(
527
+ () => tags.map((id) => ({
528
+ id,
529
+ name: allTags.data?.find((t) => t.external_id === id)?.name ?? id
530
+ })),
531
+ [tags, allTags.data]
532
+ );
533
+ return /* @__PURE__ */ jsxRuntime.jsx(
534
+ chunkULWRNGGE_cjs.ModalScaffold,
535
+ {
536
+ open: true,
537
+ onOpenChange: (o) => !o && onClose(),
538
+ title: labels.reviewTitle,
539
+ description: labels.reviewDescription,
540
+ showDescription: true,
541
+ size: "xl",
542
+ testId: "workflow-review-grid",
543
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkULWRNGGE_cjs.ModalScaffold.Body, { className: "overflow-auto", children: docs.isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
544
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }),
545
+ " ",
546
+ labels.loadingDocument
547
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-sm", children: [
548
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
549
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "sticky left-0 border-b border-border bg-card p-2 text-left font-medium", children: labels.document }),
550
+ columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("th", { className: "border-b border-border p-2 text-left font-medium", children: c.name }, c.id))
551
+ ] }) }),
552
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: (docs.data ?? []).map((d) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { "data-testid": `workflow-review-grid-row-${d.external_id}`, children: [
553
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "sticky left-0 max-w-56 border-b border-border bg-card p-2 align-top", children: /* @__PURE__ */ jsxRuntime.jsx(Cell, { onClick: onOpenDocument && (() => onOpenDocument(d.external_id)), children: d.file_name ?? d.external_id }) }),
554
+ columns.map((c) => {
555
+ const note = d.doctags?.find((t) => t.tag_ext_id === c.id)?.note;
556
+ return /* @__PURE__ */ jsxRuntime.jsx(
557
+ "td",
558
+ {
559
+ className: "max-w-72 border-b border-border p-2 align-top text-muted-foreground",
560
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-4 whitespace-pre-line", children: note || labels.empty })
561
+ },
562
+ c.id
563
+ );
564
+ })
565
+ ] }, d.external_id)) })
566
+ ] }) })
567
+ }
568
+ );
569
+ }
570
+ function Cell({ onClick, children }) {
571
+ return onClick ? /* @__PURE__ */ jsxRuntime.jsx(
572
+ "button",
573
+ {
574
+ type: "button",
575
+ onClick,
576
+ className: "truncate text-left font-medium text-primary hover:underline",
577
+ children
578
+ }
579
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children });
342
580
  }
343
581
  var DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS = {
344
582
  notify: "Ask to approve",
583
+ showInThread: "Show in the thread",
584
+ currentStep: "Current step",
345
585
  notified: "Notified.",
346
586
  openThread: "Open the thread",
347
587
  loadingAnswer: "Fetching the answer\u2026"
@@ -352,17 +592,56 @@ function ConnectedWorkflowRunner({
352
592
  onOpenConversation,
353
593
  emptyHint,
354
594
  connectedLabels,
595
+ onOpenDocument,
596
+ onOpenDraft,
597
+ onOpenMessage,
598
+ actions: hostActions,
599
+ dialogLabels,
600
+ layout = "thread",
355
601
  testIdPrefix = "workflow-run",
356
602
  ...runnerProps
357
603
  }) {
358
604
  const l = { ...DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, ...connectedLabels };
605
+ const dl = { ...DEFAULT_WORKFLOW_RUNNER_DIALOG_LABELS, ...dialogLabels };
359
606
  const arbi = react$1.useArbi();
360
- const { ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
361
- const { wsId } = chunkHITAN7JF_cjs.useWorkspaceDocs();
607
+ const { ensureWorkspaceOpen, user } = chunkMUMH3Z6K_cjs.useConnection();
608
+ const { wsId } = chunkXMBYDLZQ_cjs.useWorkspaceDocs();
362
609
  const { data: docs = [], refetch } = react$1.useDocuments(wsId);
363
610
  const [uploading, setUploading] = react.useState(false);
364
- const { view, conversationId } = useWorkflowThread(workflow, options);
365
611
  const [added, setAdded] = react.useState({});
612
+ const addedRef = react.useRef(added);
613
+ addedRef.current = added;
614
+ const { view, conversationId, people } = useWorkflowThread(workflow, {
615
+ ...options,
616
+ // An upload step records exactly the files added on it (else the server's guess).
617
+ documentsFor: options?.documentsFor ?? ((stepId) => Object.entries(addedRef.current).flatMap(([doc, step]) => step === stepId ? [doc] : []))
618
+ });
619
+ const [dialog, setDialog] = react.useState(null);
620
+ const inThread = layout === "thread" && !!conversationId;
621
+ const [target, setTarget] = react.useState(void 0);
622
+ const nameOfDoc = react.useCallback(
623
+ (id) => docs.find((d) => d.external_id === id)?.file_name ?? void 0,
624
+ [docs]
625
+ );
626
+ const actions = react.useMemo(
627
+ () => ({
628
+ me: user?.externalId,
629
+ openDocument: onOpenDocument && ((ref) => {
630
+ const { id, version } = chunkVFIZYSZB_cjs.splitDocRef(ref);
631
+ onOpenDocument(id, version);
632
+ }),
633
+ openDraft: onOpenDraft && ((draftId) => onOpenDraft(draftId)),
634
+ // In the thread layout an answer is right there: scroll to it.
635
+ openMessage: inThread ? setTarget : onOpenMessage,
636
+ sign: hostActions?.sign ?? ((_step, state) => {
637
+ const w = state.waiting;
638
+ if (w?.doc_ext_id) setDialog({ kind: "sign", docRef: w.doc_ext_id });
639
+ }),
640
+ openRedline: hostActions?.openRedline ?? ((ref) => setDialog({ kind: "word", docRef: ref, title: nameOfDoc(chunkVFIZYSZB_cjs.splitDocRef(ref).id) ?? "" })),
641
+ openReview: hostActions?.openReview ?? ((tags, documents) => setDialog({ kind: "review", tags, documents }))
642
+ }),
643
+ [user?.externalId, onOpenDocument, onOpenDraft, onOpenMessage, hostActions, nameOfDoc, inThread]
644
+ );
366
645
  const onUpload = react.useCallback(
367
646
  async (files2, step) => {
368
647
  if (!files2.length) return;
@@ -394,6 +673,23 @@ function ConnectedWorkflowRunner({
394
673
  }, [reading, refetch]);
395
674
  const renderAgentOutput = (step, state) => {
396
675
  const status = state?.status;
676
+ if (inThread) {
677
+ const id = state?.responseId;
678
+ return id && status === "done" ? /* @__PURE__ */ jsxRuntime.jsxs(
679
+ ui.Button,
680
+ {
681
+ variant: "outline",
682
+ size: "sm",
683
+ onClick: () => setTarget(id),
684
+ "data-testid": `${testIdPrefix}-${step.id}-show-in-thread`,
685
+ children: [
686
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-4" }),
687
+ " ",
688
+ l.showInThread
689
+ ]
690
+ }
691
+ ) : null;
692
+ }
397
693
  if (!state?.text && status !== "done") return null;
398
694
  if (!state?.text && state?.responseId) {
399
695
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -419,6 +715,34 @@ function ConnectedWorkflowRunner({
419
715
  }
420
716
  );
421
717
  };
718
+ const runner = (compact) => /* @__PURE__ */ jsxRuntime.jsx(
719
+ chunkVFIZYSZB_cjs.WorkflowRunner,
720
+ {
721
+ people,
722
+ ...runnerProps,
723
+ workflow,
724
+ run: view,
725
+ renderAgentOutput,
726
+ renderReview: (step) => conversationId ? /* @__PURE__ */ jsxRuntime.jsx(
727
+ ReviewNotify,
728
+ {
729
+ conversationId,
730
+ workspaceId: wsId,
731
+ labels: l,
732
+ testId: `${testIdPrefix}-${step.id}`
733
+ }
734
+ ) : null,
735
+ onUpload,
736
+ uploading,
737
+ files,
738
+ actions,
739
+ nameOfDoc,
740
+ testIdPrefix,
741
+ hideStepBar: compact,
742
+ compact,
743
+ className: compact ? void 0 : runnerProps.className
744
+ }
745
+ );
422
746
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
423
747
  conversationId && onOpenConversation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
424
748
  ui.Button,
@@ -434,26 +758,47 @@ function ConnectedWorkflowRunner({
434
758
  ]
435
759
  }
436
760
  ) }),
437
- /* @__PURE__ */ jsxRuntime.jsx(
438
- chunkVYRKO3XU_cjs.WorkflowRunner,
761
+ inThread && conversationId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
762
+ /* @__PURE__ */ jsxRuntime.jsx(
763
+ chunkVFIZYSZB_cjs.WorkflowStepBar,
764
+ {
765
+ run: view,
766
+ levels: chunkVFIZYSZB_cjs.stepLevels(view.steps),
767
+ doneTitle: (workflow.run.kind === "steps" ? workflow.run.completion?.title : void 0) ?? runnerProps.labels?.complete ?? "Done",
768
+ icon: (key) => key && runnerProps.renderIcon ? runnerProps.renderIcon(key) : void 0,
769
+ tid: (suffix) => `${testIdPrefix}-${suffix}`
770
+ }
771
+ ),
772
+ /* @__PURE__ */ jsxRuntime.jsx(
773
+ WorkflowRunThread,
774
+ {
775
+ conversationId,
776
+ workspaceId: wsId,
777
+ stepTitle: (id) => view.steps.find((s) => s.id === id)?.title,
778
+ targetMessageId: target,
779
+ labels: { workflows: l.currentStep },
780
+ aside: runner(true)
781
+ }
782
+ )
783
+ ] }) : runner(false),
784
+ dialog?.kind === "sign" && /* @__PURE__ */ jsxRuntime.jsx(WorkflowSignDialog, { docRef: dialog.docRef, onClose: () => setDialog(null), labels: dl }),
785
+ dialog?.kind === "word" && /* @__PURE__ */ jsxRuntime.jsx(
786
+ WorkflowWordDialog,
439
787
  {
440
- ...runnerProps,
441
- workflow,
442
- run: view,
443
- renderAgentOutput,
444
- renderReview: (step) => conversationId ? /* @__PURE__ */ jsxRuntime.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
788
+ docRef: dialog.docRef,
789
+ title: dialog.title || void 0,
790
+ onClose: () => setDialog(null),
791
+ labels: dl
792
+ }
793
+ ),
794
+ dialog?.kind === "review" && /* @__PURE__ */ jsxRuntime.jsx(
795
+ WorkflowReviewGridDialog,
796
+ {
797
+ tags: dialog.tags,
798
+ documents: dialog.documents,
799
+ onClose: () => setDialog(null),
800
+ onOpenDocument: onOpenDocument && ((id) => onOpenDocument(id)),
801
+ labels: dl
457
802
  }
458
803
  )
459
804
  ] });
@@ -530,6 +875,78 @@ function ReviewNotify({
530
875
  ] })
531
876
  ] });
532
877
  }
878
+ function ConnectedTagMatrix({
879
+ parentId,
880
+ linksLimit = 3,
881
+ exportTitle,
882
+ onExported,
883
+ readOnly,
884
+ ...props
885
+ }) {
886
+ const arbi = react$1.useArbi();
887
+ const { workspaceId, status, ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
888
+ const matrix = react$1.useTagMatrix({ parentId }, { linksLimit });
889
+ const update = react$1.useUpdateTagFields();
890
+ const invalidate = react$1.useInvalidateTagData();
891
+ const members = react$1.useWorkspaceUsers(workspaceId ?? void 0, {
892
+ enabled: status === "authenticated" && !!workspaceId,
893
+ beforeFetch: ensureWorkspaceOpen
894
+ });
895
+ const [error, setError] = react.useState(null);
896
+ const people = (members.data ?? []).map((m) => ({
897
+ value: m.user.external_id,
898
+ label: [m.user.given_name, m.user.family_name].filter(Boolean).join(" ") || m.user.email
899
+ }));
900
+ const fail = (e) => setError(e instanceof Error ? e.message : String(e));
901
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
902
+ /* @__PURE__ */ jsxRuntime.jsx(
903
+ chunkMLAHDAN5_cjs.TagMatrix,
904
+ {
905
+ ...props,
906
+ matrix: matrix.data,
907
+ isLoading: matrix.isLoading,
908
+ people,
909
+ onChangeValue: readOnly ? void 0 : async (tagId, fieldId, value) => {
910
+ setError(null);
911
+ await update.mutateAsync({ tagId, values: { [fieldId]: value } }).catch(fail);
912
+ },
913
+ onAddRow: readOnly ? void 0 : async (name) => {
914
+ setError(null);
915
+ try {
916
+ await ensureWorkspaceOpen();
917
+ await arbi.tags.create({ name, parentId });
918
+ await invalidate();
919
+ } catch (e) {
920
+ fail(e);
921
+ }
922
+ },
923
+ onExport: onExported && matrix.data ? async () => {
924
+ setError(null);
925
+ try {
926
+ const data = matrix.data;
927
+ if (!data) return;
928
+ const title = exportTitle ?? data.parent?.name ?? "Matrix";
929
+ const markdown = chunkMLAHDAN5_cjs.tagMatrixMarkdown(data, {
930
+ title,
931
+ nameOf: (id2) => people.find((p) => p.value === id2)?.label
932
+ });
933
+ await ensureWorkspaceOpen();
934
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
935
+ const uploaded = await arbi.documents.uploadFile(
936
+ new Blob([markdown], { type: "text/markdown" }),
937
+ `${title} (${stamp}).md`
938
+ );
939
+ const id = uploaded?.doc_ext_ids?.[0];
940
+ if (id) onExported(id);
941
+ } catch (e) {
942
+ fail(e);
943
+ }
944
+ } : void 0
945
+ }
946
+ ),
947
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: error })
948
+ ] });
949
+ }
533
950
  function useConnectedShellWorkspaces(options = {}) {
534
951
  const { workspaceId, setWorkspace } = chunkMUMH3Z6K_cjs.useConnection();
535
952
  const query = react$1.useWorkspaces();
@@ -1068,7 +1485,7 @@ function mapWorkNotification(note) {
1068
1485
  function ActiveChat({ agentId, workspaceId }) {
1069
1486
  const chat = react$1.useArbiChat({ agentId, workspaceId });
1070
1487
  return /* @__PURE__ */ jsxRuntime.jsx(
1071
- chunkIPGKTUF7_cjs.ChatPage,
1488
+ chunkMP6FK43E_cjs.ChatPage,
1072
1489
  {
1073
1490
  chat: { ...chat, assistantMode: void 0, setAssistantMode: void 0 },
1074
1491
  documentsRequired: false,
@@ -1130,35 +1547,35 @@ function ConnectedAgentChatPanel({
1130
1547
 
1131
1548
  Object.defineProperty(exports, "ConnectedAssistantDock", {
1132
1549
  enumerable: true,
1133
- get: function () { return chunkHITAN7JF_cjs.ConnectedAssistantDock; }
1550
+ get: function () { return chunkXMBYDLZQ_cjs.ConnectedAssistantDock; }
1134
1551
  });
1135
1552
  Object.defineProperty(exports, "redlineStats", {
1136
1553
  enumerable: true,
1137
- get: function () { return chunkHITAN7JF_cjs.redlineStats; }
1554
+ get: function () { return chunkXMBYDLZQ_cjs.redlineStats; }
1138
1555
  });
1139
1556
  Object.defineProperty(exports, "textToArtifact", {
1140
1557
  enumerable: true,
1141
- get: function () { return chunkHITAN7JF_cjs.textToArtifact; }
1558
+ get: function () { return chunkXMBYDLZQ_cjs.textToArtifact; }
1142
1559
  });
1143
1560
  Object.defineProperty(exports, "toRedlineMarkdown", {
1144
1561
  enumerable: true,
1145
- get: function () { return chunkHITAN7JF_cjs.toRedlineMarkdown; }
1562
+ get: function () { return chunkXMBYDLZQ_cjs.toRedlineMarkdown; }
1146
1563
  });
1147
1564
  Object.defineProperty(exports, "useConnectedAiTask", {
1148
1565
  enumerable: true,
1149
- get: function () { return chunkHITAN7JF_cjs.useConnectedAiTask; }
1566
+ get: function () { return chunkXMBYDLZQ_cjs.useConnectedAiTask; }
1150
1567
  });
1151
1568
  Object.defineProperty(exports, "useConnectedChat", {
1152
1569
  enumerable: true,
1153
- get: function () { return chunkHITAN7JF_cjs.useConnectedChat; }
1570
+ get: function () { return chunkXMBYDLZQ_cjs.useConnectedChat; }
1154
1571
  });
1155
1572
  Object.defineProperty(exports, "useSemanticSearch", {
1156
1573
  enumerable: true,
1157
- get: function () { return chunkHITAN7JF_cjs.useSemanticSearch; }
1574
+ get: function () { return chunkXMBYDLZQ_cjs.useSemanticSearch; }
1158
1575
  });
1159
1576
  Object.defineProperty(exports, "useWorkspaceDocs", {
1160
1577
  enumerable: true,
1161
- get: function () { return chunkHITAN7JF_cjs.useWorkspaceDocs; }
1578
+ get: function () { return chunkXMBYDLZQ_cjs.useWorkspaceDocs; }
1162
1579
  });
1163
1580
  Object.defineProperty(exports, "ConnectionProvider", {
1164
1581
  enumerable: true,
@@ -1187,10 +1604,12 @@ exports.ConnectedRequireVerified = ConnectedRequireVerified;
1187
1604
  exports.ConnectedSecuritySection = ConnectedSecuritySection;
1188
1605
  exports.ConnectedSessionsRow = ConnectedSessionsRow;
1189
1606
  exports.ConnectedSkillUpload = ConnectedSkillUpload;
1607
+ exports.ConnectedTagMatrix = ConnectedTagMatrix;
1190
1608
  exports.ConnectedTaskAccessRequest = ConnectedTaskAccessRequest;
1191
1609
  exports.ConnectedWorkflowRunner = ConnectedWorkflowRunner;
1192
1610
  exports.DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS = DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS;
1193
1611
  exports.StreamedArtifact = StreamedArtifact;
1612
+ exports.WorkflowRunThread = WorkflowRunThread;
1194
1613
  exports.defaultUnmetPasswordRequirement = defaultUnmetPasswordRequirement;
1195
1614
  exports.useConnectedDocxNotifications = useConnectedDocxNotifications;
1196
1615
  exports.useConnectedShellWorkspaces = useConnectedShellWorkspaces;