@lukeashford/aurelius 3.6.0 → 3.8.0

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/index.d.mts CHANGED
@@ -682,15 +682,15 @@ interface MessageActionsConfig {
682
682
  */
683
683
  showCopy?: boolean;
684
684
  }
685
- interface MessageProps extends React$1.HTMLAttributes<HTMLDivElement> {
685
+ interface MessageProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'content'> {
686
686
  /**
687
687
  * Whether the message is from the user or the assistant
688
688
  */
689
689
  variant?: MessageVariant;
690
690
  /**
691
- * The message content (supports Markdown)
691
+ * The message content (supports Markdown if string)
692
692
  */
693
- content: string;
693
+ content: string | React$1.ReactNode;
694
694
  /**
695
695
  * Whether the message is currently being streamed (shows cursor)
696
696
  */
@@ -823,6 +823,10 @@ interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'o
823
823
  * Called whenever the input value changes, giving the consumer access to the current text
824
824
  */
825
825
  onInputChange?: (value: string) => void;
826
+ /**
827
+ * Initial value for the input, used for state restoration (e.g. from DB or localStorage)
828
+ */
829
+ initialInputValue?: string;
826
830
  /**
827
831
  * Whether to automatically focus the input when it becomes enabled
828
832
  */
@@ -1469,6 +1473,10 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1469
1473
  * Called whenever the chat input value changes, giving the consumer access to the current text.
1470
1474
  */
1471
1475
  onInputChange?: (value: string) => void;
1476
+ /**
1477
+ * Initial value for the input, used for state restoration (e.g. from DB or localStorage)
1478
+ */
1479
+ initialInputValue?: string;
1472
1480
  /**
1473
1481
  * Additional tools to add to the tool sidebars. Each ExternalToolDefinition provides
1474
1482
  * an id, icon, label, group ('top-left' | 'bottom-left' | 'top-right' | 'bottom-right'),
package/dist/index.d.ts CHANGED
@@ -682,15 +682,15 @@ interface MessageActionsConfig {
682
682
  */
683
683
  showCopy?: boolean;
684
684
  }
685
- interface MessageProps extends React$1.HTMLAttributes<HTMLDivElement> {
685
+ interface MessageProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'content'> {
686
686
  /**
687
687
  * Whether the message is from the user or the assistant
688
688
  */
689
689
  variant?: MessageVariant;
690
690
  /**
691
- * The message content (supports Markdown)
691
+ * The message content (supports Markdown if string)
692
692
  */
693
- content: string;
693
+ content: string | React$1.ReactNode;
694
694
  /**
695
695
  * Whether the message is currently being streamed (shows cursor)
696
696
  */
@@ -823,6 +823,10 @@ interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'o
823
823
  * Called whenever the input value changes, giving the consumer access to the current text
824
824
  */
825
825
  onInputChange?: (value: string) => void;
826
+ /**
827
+ * Initial value for the input, used for state restoration (e.g. from DB or localStorage)
828
+ */
829
+ initialInputValue?: string;
826
830
  /**
827
831
  * Whether to automatically focus the input when it becomes enabled
828
832
  */
@@ -1469,6 +1473,10 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1469
1473
  * Called whenever the chat input value changes, giving the consumer access to the current text.
1470
1474
  */
1471
1475
  onInputChange?: (value: string) => void;
1476
+ /**
1477
+ * Initial value for the input, used for state restoration (e.g. from DB or localStorage)
1478
+ */
1479
+ initialInputValue?: string;
1472
1480
  /**
1473
1481
  * Additional tools to add to the tool sidebars. Each ExternalToolDefinition provides
1474
1482
  * an id, icon, label, group ('top-left' | 'bottom-left' | 'top-right' | 'bottom-right'),
package/dist/index.js CHANGED
@@ -4126,7 +4126,7 @@ var Message = import_react55.default.forwardRef(
4126
4126
  const isUser = variant === "user";
4127
4127
  const [copied, setCopied] = (0, import_react55.useState)(false);
4128
4128
  const [isEditing, setIsEditing] = (0, import_react55.useState)(false);
4129
- const [editValue, setEditValue] = (0, import_react55.useState)(content);
4129
+ const [editValue, setEditValue] = (0, import_react55.useState)(typeof content === "string" ? content : "");
4130
4130
  const textareaRef = (0, import_react55.useRef)(null);
4131
4131
  const showBranchNav = branchInfo && branchInfo.total > 1;
4132
4132
  const showActions = actions && !hideActions && !isStreaming;
@@ -4140,6 +4140,9 @@ var Message = import_react55.default.forwardRef(
4140
4140
  }
4141
4141
  }, [isEditing]);
4142
4142
  const handleCopy = async () => {
4143
+ if (typeof content !== "string") {
4144
+ return;
4145
+ }
4143
4146
  try {
4144
4147
  await navigator.clipboard.writeText(content);
4145
4148
  setCopied(true);
@@ -4156,16 +4159,20 @@ var Message = import_react55.default.forwardRef(
4156
4159
  }
4157
4160
  };
4158
4161
  const handleStartEdit = () => {
4159
- setEditValue(content);
4160
- setIsEditing(true);
4162
+ if (typeof content === "string") {
4163
+ setEditValue(content);
4164
+ setIsEditing(true);
4165
+ }
4161
4166
  };
4162
4167
  const handleCancelEdit = () => {
4163
4168
  setIsEditing(false);
4164
- setEditValue(content);
4169
+ if (typeof content === "string") {
4170
+ setEditValue(content);
4171
+ }
4165
4172
  };
4166
4173
  const handleSubmitEdit = () => {
4167
4174
  const trimmed = editValue.trim();
4168
- if (trimmed && trimmed !== content) {
4175
+ if (typeof content === "string" && trimmed && trimmed !== content) {
4169
4176
  actions?.onEdit?.(trimmed);
4170
4177
  }
4171
4178
  setIsEditing(false);
@@ -4232,7 +4239,7 @@ var Message = import_react55.default.forwardRef(
4232
4239
  variantStyles2[variant]
4233
4240
  )
4234
4241
  },
4235
- /* @__PURE__ */ import_react55.default.createElement(
4242
+ typeof content === "string" ? /* @__PURE__ */ import_react55.default.createElement(
4236
4243
  MarkdownContent,
4237
4244
  {
4238
4245
  content,
@@ -4240,7 +4247,7 @@ var Message = import_react55.default.forwardRef(
4240
4247
  isStreaming,
4241
4248
  cursorClassName: "ml-0.5"
4242
4249
  }
4243
- )
4250
+ ) : content
4244
4251
  ),
4245
4252
  showActions && !isEditing && /* @__PURE__ */ import_react55.default.createElement("div", { className: cx(
4246
4253
  "flex items-center gap-0.5 mt-1",
@@ -4252,7 +4259,7 @@ var Message = import_react55.default.forwardRef(
4252
4259
  label: copied ? "Copied!" : "Copy message"
4253
4260
  },
4254
4261
  copied ? /* @__PURE__ */ import_react55.default.createElement(CheckIcon, null) : /* @__PURE__ */ import_react55.default.createElement(CopyIcon, null)
4255
- ), isUser && actions.onEdit && /* @__PURE__ */ import_react55.default.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react55.default.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ import_react55.default.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react55.default.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ import_react55.default.createElement(import_react55.default.Fragment, null, /* @__PURE__ */ import_react55.default.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ import_react55.default.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ import_react55.default.createElement(GitBranchIcon, null), /* @__PURE__ */ import_react55.default.createElement(
4262
+ ), isUser && actions.onEdit && typeof content === "string" && /* @__PURE__ */ import_react55.default.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react55.default.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ import_react55.default.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react55.default.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ import_react55.default.createElement(import_react55.default.Fragment, null, /* @__PURE__ */ import_react55.default.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ import_react55.default.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ import_react55.default.createElement(GitBranchIcon, null), /* @__PURE__ */ import_react55.default.createElement(
4256
4263
  "button",
4257
4264
  {
4258
4265
  type: "button",
@@ -4799,11 +4806,12 @@ var ChatInput = import_react61.default.forwardRef(
4799
4806
  acceptedFileTypes,
4800
4807
  notice,
4801
4808
  onInputChange,
4809
+ initialInputValue = "",
4802
4810
  autoFocus = false,
4803
4811
  className,
4804
4812
  ...rest
4805
4813
  }, ref) => {
4806
- const [value, setValue] = (0, import_react61.useState)("");
4814
+ const [value, setValue] = (0, import_react61.useState)(initialInputValue);
4807
4815
  const [localAttachments, setLocalAttachments] = (0, import_react61.useState)([]);
4808
4816
  const [isDragOver, setIsDragOver] = (0, import_react61.useState)(false);
4809
4817
  const textareaRef = (0, import_react61.useRef)(null);
@@ -6459,15 +6467,13 @@ function sortTasks(tasks) {
6459
6467
  function TaskItem({ task, depth = 0 }) {
6460
6468
  const isTerminal = task.status === "done" || task.status === "cancelled" || task.status === "failed";
6461
6469
  const isSubtle = task.status === "cancelled" || task.status === "failed";
6462
- const showSubtasks = (task.status === "in_progress" || task.status === "done") && task.subtasks && task.subtasks.length > 0;
6470
+ const showSubtasks = task.subtasks && task.subtasks.length > 0;
6463
6471
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
6464
6472
  return /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react74.default.createElement(
6465
6473
  "div",
6466
6474
  {
6467
- className: cx(
6468
- "flex items-center gap-2 py-1",
6469
- depth > 0 && "pl-6"
6470
- )
6475
+ className: "flex items-center gap-2 py-1",
6476
+ style: { paddingLeft: `${depth * 1.5}rem` }
6471
6477
  },
6472
6478
  /* @__PURE__ */ import_react74.default.createElement(TaskIcon, { status: task.status }),
6473
6479
  /* @__PURE__ */ import_react74.default.createElement(
@@ -6489,8 +6495,12 @@ function TaskItem({ task, depth = 0 }) {
6489
6495
  }
6490
6496
  function hasInProgressTask(tasks) {
6491
6497
  return tasks.some((t) => {
6492
- if (t.status === "in_progress") return true;
6493
- if (t.subtasks && t.subtasks.length > 0) return hasInProgressTask(t.subtasks);
6498
+ if (t.status === "in_progress") {
6499
+ return true;
6500
+ }
6501
+ if (t.subtasks && t.subtasks.length > 0) {
6502
+ return hasInProgressTask(t.subtasks);
6503
+ }
6494
6504
  return false;
6495
6505
  });
6496
6506
  }
@@ -6499,7 +6509,9 @@ var TodosList = import_react74.default.forwardRef(
6499
6509
  const sortedTasks = (0, import_react74.useMemo)(() => sortTasks(tasks), [tasks]);
6500
6510
  const [isStopping, setIsStopping] = (0, import_react74.useState)(false);
6501
6511
  const handleStopClick = (0, import_react74.useCallback)(async () => {
6502
- if (!onStopAllTasks || isStopping) return;
6512
+ if (!onStopAllTasks || isStopping) {
6513
+ return;
6514
+ }
6503
6515
  try {
6504
6516
  setIsStopping(true);
6505
6517
  await onStopAllTasks();
@@ -6508,25 +6520,10 @@ var TodosList = import_react74.default.forwardRef(
6508
6520
  }
6509
6521
  }, [onStopAllTasks, isStopping]);
6510
6522
  const countCompleted = (taskList) => {
6511
- let count = 0;
6512
- for (const task of taskList) {
6513
- if (task.status === "done") {
6514
- count++;
6515
- }
6516
- if (task.subtasks) {
6517
- count += countCompleted(task.subtasks);
6518
- }
6519
- }
6520
- return count;
6523
+ return taskList.filter((task) => task.status === "done").length;
6521
6524
  };
6522
6525
  const countTotal = (taskList) => {
6523
- let count = taskList.length;
6524
- for (const task of taskList) {
6525
- if (task.subtasks) {
6526
- count += countTotal(task.subtasks);
6527
- }
6528
- }
6529
- return count;
6526
+ return taskList.length;
6530
6527
  };
6531
6528
  const showStopButton = !!onStopAllTasks && (hasInProgressTask(tasks) || isStopping);
6532
6529
  if (tasks.length === 0) {
@@ -6578,8 +6575,12 @@ TodosList.displayName = "TodosList";
6578
6575
  function areAllTasksSettled(tasks) {
6579
6576
  return tasks.every((t) => {
6580
6577
  const settled = t.status === "done" || t.status === "cancelled" || t.status === "failed";
6581
- if (!settled) return false;
6582
- if (t.subtasks && t.subtasks.length > 0) return areAllTasksSettled(t.subtasks);
6578
+ if (!settled) {
6579
+ return false;
6580
+ }
6581
+ if (t.subtasks && t.subtasks.length > 0) {
6582
+ return areAllTasksSettled(t.subtasks);
6583
+ }
6583
6584
  return true;
6584
6585
  });
6585
6586
  }
@@ -6849,6 +6850,7 @@ var ChatInterface = import_react78.default.forwardRef(
6849
6850
  onStopAllTasks,
6850
6851
  inputNotice,
6851
6852
  onInputChange,
6853
+ initialInputValue = "",
6852
6854
  tools: externalTools = [],
6853
6855
  autoFocus = true,
6854
6856
  className,
@@ -7144,6 +7146,7 @@ var ChatInterface = import_react78.default.forwardRef(
7144
7146
  onAttachmentsChange,
7145
7147
  notice: inputNotice,
7146
7148
  onInputChange,
7149
+ initialInputValue,
7147
7150
  autoFocus
7148
7151
  }
7149
7152
  )), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(