@inf-monkeys-tech/monkeys-design 1.0.14 → 1.0.15

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 (60) hide show
  1. package/dist/components/agent-workbench/index.d.mts +41 -168
  2. package/dist/components/agent-workbench/index.d.ts +41 -168
  3. package/dist/components/agent-workbench/index.js +335 -4
  4. package/dist/components/agent-workbench/index.js.map +1 -1
  5. package/dist/components/agent-workbench/index.mjs +336 -6
  6. package/dist/components/agent-workbench/index.mjs.map +1 -1
  7. package/dist/components/base/index.js +32 -1
  8. package/dist/components/base/index.js.map +1 -1
  9. package/dist/components/base/index.mjs +32 -1
  10. package/dist/components/base/index.mjs.map +1 -1
  11. package/dist/components/data-explorer/index.js +32 -1
  12. package/dist/components/data-explorer/index.js.map +1 -1
  13. package/dist/components/data-explorer/index.mjs +32 -1
  14. package/dist/components/data-explorer/index.mjs.map +1 -1
  15. package/dist/components/layout/index.js +32 -1
  16. package/dist/components/layout/index.js.map +1 -1
  17. package/dist/components/layout/index.mjs +32 -1
  18. package/dist/components/layout/index.mjs.map +1 -1
  19. package/dist/components/runtime/index.js +32 -1
  20. package/dist/components/runtime/index.js.map +1 -1
  21. package/dist/components/runtime/index.mjs +32 -1
  22. package/dist/components/runtime/index.mjs.map +1 -1
  23. package/dist/components/toast/index.d.mts +1 -1
  24. package/dist/components/toast/index.d.ts +1 -1
  25. package/dist/components/toast/index.js +32 -1
  26. package/dist/components/toast/index.js.map +1 -1
  27. package/dist/components/toast/index.mjs +32 -1
  28. package/dist/components/toast/index.mjs.map +1 -1
  29. package/dist/components/toolbar/index.js +32 -1
  30. package/dist/components/toolbar/index.js.map +1 -1
  31. package/dist/components/toolbar/index.mjs +32 -1
  32. package/dist/components/toolbar/index.mjs.map +1 -1
  33. package/dist/components/workbench/index.js +32 -1
  34. package/dist/components/workbench/index.js.map +1 -1
  35. package/dist/components/workbench/index.mjs +32 -1
  36. package/dist/components/workbench/index.mjs.map +1 -1
  37. package/dist/details-model-f2034b78b458.d.mts +199 -0
  38. package/dist/details-model-f2034b78b458.d.ts +199 -0
  39. package/dist/index.d.mts +2 -2
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.js +142 -5
  42. package/dist/index.js.map +1 -1
  43. package/dist/index.mjs +142 -5
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/locale/index.d.mts +88 -2
  46. package/dist/locale/index.d.ts +88 -2
  47. package/dist/locale/index.js +72 -2
  48. package/dist/locale/index.js.map +1 -1
  49. package/dist/locale/index.mjs +72 -2
  50. package/dist/locale/index.mjs.map +1 -1
  51. package/dist/provider/index.d.mts +2 -2
  52. package/dist/provider/index.d.ts +2 -2
  53. package/dist/provider/index.js +72 -2
  54. package/dist/provider/index.js.map +1 -1
  55. package/dist/provider/index.mjs +72 -2
  56. package/dist/provider/index.mjs.map +1 -1
  57. package/dist/styles.css +1 -1
  58. package/dist/{types-37967a434f7c.d.mts → types-a81dc2d284e3.d.mts} +37 -0
  59. package/dist/{types-37967a434f7c.d.ts → types-a81dc2d284e3.d.ts} +37 -0
  60. package/package.json +3 -3
@@ -45,7 +45,7 @@ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
45
45
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
46
46
  var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
47
47
 
48
- // src/components/agent-workbench/AgentWorkbenchSidebar.tsx
48
+ // src/components/agent-workbench/AgentWorkbenchComposer.tsx
49
49
 
50
50
  // src/locale/en-US.ts
51
51
  var enUS = {
@@ -146,6 +146,30 @@ var enUS = {
146
146
  reasoning: "Reasoning",
147
147
  plan: "Plan",
148
148
  taskNoDetail: "No additional details",
149
+ modes: { chatbot: "Chatbot", agent: "Agent" },
150
+ composer: {
151
+ send: "Send message",
152
+ stop: "Stop generating",
153
+ queue: "Queue message",
154
+ attach: "Add photos or files",
155
+ voice: "Start voice input",
156
+ webSearch: "Web search",
157
+ model: "Model",
158
+ reasoning: "Reasoning effort",
159
+ permissions: "Permissions",
160
+ removeAttachment: "Remove attachment",
161
+ editQueued: "Edit queued message",
162
+ deleteQueued: "Delete queued message",
163
+ moveUp: "Move message up",
164
+ moveDown: "Move message down",
165
+ queued: "Queued messages",
166
+ uploading: "Uploading",
167
+ noModels: "No models available",
168
+ message: "Message",
169
+ attachmentOnly: "Attachment",
170
+ reasoningOptions: { low: "Low", medium: "Medium", high: "High", xhigh: "Extra high" },
171
+ permissionOptions: { "approval-required": "Approval required", "auto-approve": "Auto approve", "full-access": "Full access" }
172
+ },
149
173
  tool: {
150
174
  input: "Input",
151
175
  output: "Output",
@@ -214,6 +238,10 @@ var enUS = {
214
238
  description: "Summary and workspace activity",
215
239
  duration: "Duration",
216
240
  updated: "Updated",
241
+ model: "Model",
242
+ mode: "Mode",
243
+ permissions: "Permissions",
244
+ tokenUsage: "Token usage",
217
245
  summary: "Summary",
218
246
  summaryEmpty: "No summary is available yet.",
219
247
  summaryFailed: "The summary could not be generated.",
@@ -243,7 +271,10 @@ var enUS = {
243
271
  copySummary: "Copy summary",
244
272
  retry: "Retry",
245
273
  retrySummary: "Retry summary",
246
- resume: "Resume"
274
+ resume: "Resume",
275
+ continueInNewTask: "Continue in new task",
276
+ editAndRerun: "Edit and rerun",
277
+ export: "Export"
247
278
  },
248
279
  workspace: {
249
280
  diffs: "Code changes",
@@ -641,6 +672,238 @@ var SelectSeparator = React2__namespace.forwardRef(
641
672
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Separator, { ref, className: cn("-mx-1 my-1 h-px bg-muted", className), ...props })
642
673
  );
643
674
  SelectSeparator.displayName = "SelectSeparator";
675
+ var iconButtonClass = "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40";
676
+ function modelOptionValue(option) {
677
+ return `${option.mode}:${option.id}`;
678
+ }
679
+ function AgentWorkbenchComposer({
680
+ viewModel,
681
+ className,
682
+ classNames,
683
+ onIntent
684
+ }) {
685
+ const messages = useMonkeysLocaleMessages().agentWorkbench;
686
+ const fileInputRef = React2.useRef(null);
687
+ const surfaceRef = React2.useRef(null);
688
+ const [editingDraftId, setEditingDraftId] = React2.useState();
689
+ const [editingText, setEditingText] = React2.useState("");
690
+ const [isNarrow, setIsNarrow] = React2.useState(false);
691
+ const isBusy = viewModel.status === "loading" || viewModel.status === "streaming" || viewModel.status === "stopping";
692
+ const isStopping = viewModel.status === "stopping";
693
+ const isUploading = viewModel.attachments.some((attachment) => attachment.status === "uploading");
694
+ const canSubmit = !isStopping && !isUploading && (viewModel.value.trim().length > 0 || viewModel.attachments.some((item) => item.status === "ready"));
695
+ const showSubmitButton = !isBusy || canSubmit;
696
+ const selectedModelValue = React2.useMemo(() => {
697
+ const selected = viewModel.model.options.find((option) => option.id === viewModel.model.selectedId);
698
+ return selected ? modelOptionValue(selected) : "";
699
+ }, [viewModel.model.options, viewModel.model.selectedId]);
700
+ React2.useEffect(() => {
701
+ const surface = surfaceRef.current;
702
+ if (!surface) return void 0;
703
+ const updateLayout = () => setIsNarrow(surface.getBoundingClientRect().width <= 704);
704
+ updateLayout();
705
+ window.addEventListener("resize", updateLayout);
706
+ if (typeof ResizeObserver === "undefined") {
707
+ const interval = window.setInterval(updateLayout, 250);
708
+ return () => {
709
+ window.clearInterval(interval);
710
+ window.removeEventListener("resize", updateLayout);
711
+ };
712
+ }
713
+ const observer = new ResizeObserver(updateLayout);
714
+ observer.observe(surface);
715
+ return () => {
716
+ observer.disconnect();
717
+ window.removeEventListener("resize", updateLayout);
718
+ };
719
+ }, []);
720
+ const submit = () => {
721
+ if (canSubmit) onIntent?.({ type: "submit" });
722
+ };
723
+ return /* @__PURE__ */ jsxRuntime.jsxs(
724
+ "form",
725
+ {
726
+ className: cn2("agent-workbench-composer flex min-w-0 w-full flex-col gap-2", className, classNames?.root),
727
+ "aria-label": messages.composer.message,
728
+ onSubmit: (event) => {
729
+ event.preventDefault();
730
+ submit();
731
+ },
732
+ children: [
733
+ viewModel.capabilities.queue && viewModel.queuedDrafts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
734
+ "section",
735
+ {
736
+ "aria-label": messages.composer.queued,
737
+ className: cn2("min-w-0 max-w-full rounded-md border border-border bg-muted/40 p-2", classNames?.queue),
738
+ children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "space-y-1.5", children: viewModel.queuedDrafts.map((draft, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex min-h-9 min-w-0 max-w-full items-center gap-2 overflow-hidden rounded-md bg-background px-2 py-1.5 text-sm", children: [
739
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-5 shrink-0 text-center text-xs text-muted-foreground", children: index + 1 }),
740
+ editingDraftId === draft.id ? /* @__PURE__ */ jsxRuntime.jsx(
741
+ "input",
742
+ {
743
+ autoFocus: true,
744
+ value: editingText,
745
+ "aria-label": messages.composer.editQueued,
746
+ className: "min-w-0 flex-1 rounded border border-input bg-background px-2 py-1 outline-none focus-visible:ring-2 focus-visible:ring-ring",
747
+ onChange: (event) => setEditingText(event.target.value),
748
+ onBlur: () => {
749
+ if (editingText.trim()) onIntent?.({ type: "edit-queued-draft", draftId: draft.id, text: editingText });
750
+ setEditingDraftId(void 0);
751
+ },
752
+ onKeyDown: (event) => {
753
+ if (event.key === "Escape") setEditingDraftId(void 0);
754
+ if (event.key === "Enter" && editingText.trim()) {
755
+ event.preventDefault();
756
+ onIntent?.({ type: "edit-queued-draft", draftId: draft.id, text: editingText });
757
+ setEditingDraftId(void 0);
758
+ }
759
+ }
760
+ }
761
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: draft.text || messages.composer.attachmentOnly }),
762
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [
763
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: iconButtonClass, "aria-label": messages.composer.moveUp, disabled: index === 0, onClick: () => onIntent?.({ type: "move-queued-draft", draftId: draft.id, direction: "up" }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "size-3.5" }) }),
764
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: iconButtonClass, "aria-label": messages.composer.moveDown, disabled: index === viewModel.queuedDrafts.length - 1, onClick: () => onIntent?.({ type: "move-queued-draft", draftId: draft.id, direction: "down" }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "size-3.5" }) }),
765
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: iconButtonClass, "aria-label": messages.composer.editQueued, onClick: () => {
766
+ setEditingDraftId(draft.id);
767
+ setEditingText(draft.text);
768
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "size-3.5" }) }),
769
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cn2(iconButtonClass, "text-destructive-text"), "aria-label": messages.composer.deleteQueued, onClick: () => onIntent?.({ type: "delete-queued-draft", draftId: draft.id }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "size-3.5" }) })
770
+ ] })
771
+ ] }, draft.id)) })
772
+ }
773
+ ) : null,
774
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: surfaceRef, className: "agent-workbench-composer__surface min-w-0 max-w-full rounded-lg border border-input bg-background p-3 shadow-sm focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30", children: [
775
+ viewModel.attachments.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn2("mb-2 flex max-w-full gap-2 overflow-x-auto", classNames?.attachments), children: viewModel.attachments.map((attachment) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex size-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-border bg-muted", children: [
776
+ attachment.previewUrl && attachment.mediaType?.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: attachment.previewUrl, alt: "", className: "size-full object-cover" }) : attachment.mediaType?.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { className: "size-5 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.File, { className: "size-5 text-muted-foreground" }),
777
+ attachment.status === "uploading" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center bg-background/80 text-[10px] font-medium", children: messages.composer.uploading }) : null,
778
+ /* @__PURE__ */ jsxRuntime.jsx(
779
+ "button",
780
+ {
781
+ type: "button",
782
+ className: "absolute right-1 top-1 flex size-5 items-center justify-center rounded-full bg-background/90 text-foreground shadow",
783
+ "aria-label": messages.composer.removeAttachment,
784
+ onClick: () => onIntent?.({ type: "remove-attachment", attachmentId: attachment.id }),
785
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3" })
786
+ }
787
+ ),
788
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-x-0 bottom-0 truncate bg-background/85 px-1 py-0.5 text-[9px]", children: attachment.name })
789
+ ] }, attachment.id)) }) : null,
790
+ /* @__PURE__ */ jsxRuntime.jsx(
791
+ "textarea",
792
+ {
793
+ value: viewModel.value,
794
+ rows: 2,
795
+ "aria-label": messages.composer.message,
796
+ placeholder: viewModel.placeholder,
797
+ className: cn2("max-h-64 min-h-14 min-w-0 w-full resize-none border-0 bg-transparent text-sm leading-relaxed text-foreground outline-none placeholder:text-muted-foreground", classNames?.textarea),
798
+ onChange: (event) => onIntent?.({ type: "change-value", value: event.target.value }),
799
+ onKeyDown: (event) => {
800
+ if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
801
+ event.preventDefault();
802
+ submit();
803
+ }
804
+ }
805
+ }
806
+ ),
807
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn2("agent-workbench-composer__toolbar mt-2 flex min-h-8 min-w-0 max-w-full items-center gap-2", isNarrow ? "flex-wrap" : "flex-nowrap", classNames?.toolbar), children: [
808
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn2("agent-workbench-composer__controls flex min-w-0 max-w-full flex-1 items-center gap-1.5", isNarrow ? "w-full flex-wrap" : "flex-nowrap"), children: [
809
+ viewModel.capabilities.attachments ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
810
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: iconButtonClass, "aria-label": messages.composer.attach, onClick: () => fileInputRef.current?.click(), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { className: "size-4" }) }),
811
+ /* @__PURE__ */ jsxRuntime.jsx(
812
+ "input",
813
+ {
814
+ ref: fileInputRef,
815
+ type: "file",
816
+ className: "hidden",
817
+ multiple: true,
818
+ onChange: (event) => {
819
+ const files = Array.from(event.target.files || []);
820
+ if (files.length > 0) onIntent?.({ type: "request-attachments", files });
821
+ event.target.value = "";
822
+ }
823
+ }
824
+ )
825
+ ] }) : null,
826
+ viewModel.capabilities.voiceInput ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: iconButtonClass, "aria-label": messages.composer.voice, onClick: () => onIntent?.({ type: "request-voice-input" }), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "size-4" }) }) : null,
827
+ viewModel.capabilities.webSearch ? /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex shrink-0 items-center gap-1.5 whitespace-nowrap px-1 text-xs font-medium text-foreground", children: [
828
+ messages.composer.webSearch,
829
+ /* @__PURE__ */ jsxRuntime.jsx(Switch, { checked: viewModel.webSearchEnabled, onCheckedChange: (enabled) => onIntent?.({ type: "toggle-web-search", enabled }) })
830
+ ] }) : null,
831
+ viewModel.capabilities.modelSelection ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: "sr-only", htmlFor: "agent-workbench-model", children: messages.composer.model }) : null,
832
+ viewModel.capabilities.modelSelection ? /* @__PURE__ */ jsxRuntime.jsxs(
833
+ "select",
834
+ {
835
+ id: "agent-workbench-model",
836
+ value: selectedModelValue,
837
+ "aria-label": messages.composer.model,
838
+ className: "h-8 w-48 min-w-36 shrink rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground",
839
+ onChange: (event) => {
840
+ const option = viewModel.model.options.find((item) => modelOptionValue(item) === event.target.value);
841
+ if (option) onIntent?.({ type: "select-model", modelId: option.id, mode: option.mode });
842
+ },
843
+ children: [
844
+ viewModel.model.options.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: messages.composer.noModels }) : null,
845
+ viewModel.model.options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: modelOptionValue(option), disabled: option.disabled, children: [
846
+ option.label,
847
+ " \xB7 ",
848
+ messages.modes[option.mode]
849
+ ] }, modelOptionValue(option)))
850
+ ]
851
+ }
852
+ ) : null,
853
+ viewModel.capabilities.reasoning && viewModel.reasoning ? /* @__PURE__ */ jsxRuntime.jsx(
854
+ "select",
855
+ {
856
+ value: viewModel.reasoning.value,
857
+ "aria-label": messages.composer.reasoning,
858
+ className: "h-8 w-32 min-w-24 shrink rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground",
859
+ onChange: (event) => onIntent?.({ type: "change-reasoning", value: event.target.value }),
860
+ children: viewModel.reasoning.options.map((value) => /* @__PURE__ */ jsxRuntime.jsx("option", { value, children: messages.composer.reasoningOptions[value] }, value))
861
+ }
862
+ ) : null,
863
+ viewModel.capabilities.permissions && viewModel.permissionProfile ? /* @__PURE__ */ jsxRuntime.jsx(
864
+ "select",
865
+ {
866
+ value: viewModel.permissionProfile,
867
+ "aria-label": messages.composer.permissions,
868
+ className: "h-8 w-40 min-w-32 shrink rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground",
869
+ onChange: (event) => onIntent?.({ type: "change-permission", value: event.target.value }),
870
+ children: ["approval-required", "auto-approve", "full-access"].map((value) => /* @__PURE__ */ jsxRuntime.jsx("option", { value, children: messages.composer.permissionOptions[value] }, value))
871
+ }
872
+ ) : null
873
+ ] }),
874
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
875
+ showSubmitButton ? /* @__PURE__ */ jsxRuntime.jsx(
876
+ "button",
877
+ {
878
+ type: "submit",
879
+ className: cn2(
880
+ iconButtonClass,
881
+ "bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground disabled:bg-primary/40 disabled:!opacity-100"
882
+ ),
883
+ "aria-label": isBusy && viewModel.capabilities.queue ? messages.composer.queue : messages.composer.send,
884
+ disabled: !canSubmit,
885
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "size-4" })
886
+ }
887
+ ) : null,
888
+ isBusy && !canSubmit && viewModel.capabilities.stop ? /* @__PURE__ */ jsxRuntime.jsx(
889
+ "button",
890
+ {
891
+ type: "button",
892
+ className: cn2(iconButtonClass, "border border-border"),
893
+ "aria-label": isStopping ? messages.run.stopping : messages.composer.stop,
894
+ disabled: isStopping,
895
+ onClick: () => onIntent?.({ type: "stop" }),
896
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { className: "size-3 fill-current" })
897
+ }
898
+ ) : null
899
+ ] })
900
+ ] })
901
+ ] }),
902
+ viewModel.status === "error" && viewModel.error ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive-text", children: viewModel.error }) : null
903
+ ]
904
+ }
905
+ );
906
+ }
644
907
  function ItemAvatar({ item }) {
645
908
  const [failed, setFailed] = React2.useState(false);
646
909
  if (item.iconUrl && !failed) {
@@ -1475,14 +1738,20 @@ function createAgentWorkbenchDetailsModel(viewModel) {
1475
1738
  );
1476
1739
  return {
1477
1740
  mode: viewModel.snapshot.mode,
1741
+ modelId: viewModel.snapshot.modelId,
1742
+ permissionProfile: viewModel.snapshot.permissionProfile,
1478
1743
  status: viewModel.status,
1479
1744
  sessionId: viewModel.sessionId,
1745
+ capabilities,
1480
1746
  resumable: capabilities.resume === true && viewModel.resumable,
1481
1747
  summary,
1482
1748
  error: [...viewModel.events].reverse().find(
1483
1749
  (event) => event.eventType === "error"
1484
1750
  ),
1485
1751
  run,
1752
+ usage: capabilities.usage ? [...viewModel.events].reverse().find(
1753
+ (event) => event.eventType === "usage"
1754
+ ) : void 0,
1486
1755
  workspace: {
1487
1756
  diffs: latestBy2(workspaceEvents, "diff", (event) => event.payload.path),
1488
1757
  files: latestBy2(
@@ -1593,13 +1862,17 @@ function SummaryPanel({
1593
1862
  model,
1594
1863
  onIntent
1595
1864
  }) {
1596
- const messages = useMonkeysLocaleMessages().agentWorkbench.details;
1865
+ const workbenchMessages = useMonkeysLocaleMessages().agentWorkbench;
1866
+ const messages = workbenchMessages.details;
1597
1867
  const locale = useMonkeysLocale().locale;
1598
1868
  const summary = model.summary;
1599
1869
  const run = model.run?.payload;
1600
1870
  const error = model.error;
1601
1871
  const retryable = model.status === "failed" && error?.payload.retryable;
1602
1872
  const canResume = model.resumable && ["stopped", "completed", "failed"].includes(model.status);
1873
+ const canContinueInNewTask = model.capabilities.threadForking;
1874
+ const canEditAndRerun = model.capabilities.editAndRerun;
1875
+ const tokenUsage = model.usage?.payload.totalTokens ?? (model.usage?.payload.inputTokens !== void 0 || model.usage?.payload.outputTokens !== void 0 ? (model.usage.payload.inputTokens ?? 0) + (model.usage.payload.outputTokens ?? 0) : void 0);
1603
1876
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1604
1877
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-lg border border-border bg-muted/40 p-3", children: [
1605
1878
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -1617,7 +1890,23 @@ function SummaryPanel({
1617
1890
  run?.stoppedAt ?? run?.completedAt ?? run?.failedAt,
1618
1891
  locale
1619
1892
  ) })
1620
- ] })
1893
+ ] }),
1894
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1895
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: messages.model }),
1896
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "mt-0.5 truncate font-medium", children: model.modelId })
1897
+ ] }),
1898
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1899
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: messages.mode }),
1900
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "mt-0.5 font-medium", children: workbenchMessages.modes[model.mode] })
1901
+ ] }),
1902
+ model.permissionProfile ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1903
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: messages.permissions }),
1904
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "mt-0.5 font-medium", children: workbenchMessages.composer.permissionOptions[model.permissionProfile] })
1905
+ ] }) : null,
1906
+ tokenUsage !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1907
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: messages.tokenUsage }),
1908
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "mt-0.5 font-medium", children: new Intl.NumberFormat(locale).format(tokenUsage) })
1909
+ ] }) : null
1621
1910
  ] }),
1622
1911
  error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 rounded-md border border-destructive/30 bg-destructive/5 p-2.5 text-sm text-destructive-text", role: "alert", children: error.payload.message }) : null,
1623
1912
  retryable || canResume ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [
@@ -1643,6 +1932,47 @@ function SummaryPanel({
1643
1932
  ) : null
1644
1933
  ] }) : null
1645
1934
  ] }),
1935
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-wrap gap-2 rounded-lg border border-border bg-card p-3 text-card-foreground", children: [
1936
+ canContinueInNewTask ? /* @__PURE__ */ jsxRuntime.jsxs(
1937
+ "button",
1938
+ {
1939
+ type: "button",
1940
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring",
1941
+ disabled: !onIntent,
1942
+ onClick: () => onIntent?.({ type: "continue-in-new-task", sessionId: model.sessionId }),
1943
+ children: [
1944
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitFork, { className: "size-3.5", "aria-hidden": "true" }),
1945
+ messages.actions.continueInNewTask
1946
+ ]
1947
+ }
1948
+ ) : null,
1949
+ canEditAndRerun ? /* @__PURE__ */ jsxRuntime.jsxs(
1950
+ "button",
1951
+ {
1952
+ type: "button",
1953
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring",
1954
+ disabled: !onIntent,
1955
+ onClick: () => onIntent?.({ type: "edit-and-rerun", sessionId: model.sessionId }),
1956
+ children: [
1957
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PencilLine, { className: "size-3.5", "aria-hidden": "true" }),
1958
+ messages.actions.editAndRerun
1959
+ ]
1960
+ }
1961
+ ) : null,
1962
+ /* @__PURE__ */ jsxRuntime.jsxs(
1963
+ "button",
1964
+ {
1965
+ type: "button",
1966
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring",
1967
+ disabled: !onIntent,
1968
+ onClick: () => onIntent?.({ type: "export", sessionId: model.sessionId }),
1969
+ children: [
1970
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "size-3.5", "aria-hidden": "true" }),
1971
+ messages.actions.export
1972
+ ]
1973
+ }
1974
+ )
1975
+ ] }),
1646
1976
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-lg border border-border bg-card p-3 text-card-foreground", children: [
1647
1977
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1648
1978
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold", children: messages.summary }),
@@ -1887,6 +2217,7 @@ function AgentWorkbenchTaskDetails({
1887
2217
  }
1888
2218
 
1889
2219
  exports.AgentWorkbenchActivity = AgentWorkbenchActivity;
2220
+ exports.AgentWorkbenchComposer = AgentWorkbenchComposer;
1890
2221
  exports.AgentWorkbenchSidebar = AgentWorkbenchSidebar;
1891
2222
  exports.AgentWorkbenchTaskDetails = AgentWorkbenchTaskDetails;
1892
2223
  exports.AgentWorkbenchTool = AgentWorkbenchTool;