@lukeashford/aurelius 3.8.1 → 3.9.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
@@ -737,6 +737,158 @@ interface MarkdownContentProps extends React$1.HTMLAttributes<HTMLDivElement> {
737
737
  }
738
738
  declare const MarkdownContent: React$1.ForwardRefExoticComponent<MarkdownContentProps & React$1.RefAttributes<HTMLDivElement>>;
739
739
 
740
+ /**
741
+ * Conversation Tree Types
742
+ *
743
+ * These types support branching conversations where users can:
744
+ * - Edit their messages (creating a new branch)
745
+ * - Retry assistant responses (creating a new branch)
746
+ * - Navigate between different conversation branches
747
+ */
748
+
749
+ /**
750
+ * A node in the conversation tree
751
+ */
752
+ interface MessageNode {
753
+ /**
754
+ * Unique identifier for this message
755
+ */
756
+ id: string;
757
+ /**
758
+ * The role of the message author
759
+ */
760
+ role: 'user' | 'assistant';
761
+ /**
762
+ * The message content (may include HTML/markdown or React components)
763
+ */
764
+ content: ReactNode;
765
+ /**
766
+ * ID of the parent message (null for root messages)
767
+ */
768
+ parentId: string | null;
769
+ /**
770
+ * IDs of child messages (branches/continuations)
771
+ */
772
+ children: string[];
773
+ /**
774
+ * Which sibling branch this message is (0, 1, 2...)
775
+ * Used for UI display like "1/3"
776
+ */
777
+ branchIndex?: number;
778
+ /**
779
+ * Whether this message is currently being streamed
780
+ */
781
+ isStreaming?: boolean;
782
+ /**
783
+ * Timestamp when the message was created
784
+ */
785
+ createdAt?: number;
786
+ }
787
+ /**
788
+ * The full conversation tree structure
789
+ */
790
+ interface ConversationTree {
791
+ /**
792
+ * All nodes indexed by their ID
793
+ */
794
+ nodes: Record<string, MessageNode>;
795
+ /**
796
+ * IDs of root-level messages (messages with no parent)
797
+ */
798
+ rootIds: string[];
799
+ /**
800
+ * The current "head" of the viewed branch
801
+ * This is the leaf node that determines which path we're viewing
802
+ */
803
+ activeLeafId: string | null;
804
+ }
805
+ /**
806
+ * Attachment types for file uploads
807
+ */
808
+ type AttachmentStatus = 'pending' | 'uploading' | 'complete' | 'error';
809
+ interface Attachment {
810
+ /**
811
+ * Unique identifier for the attachment
812
+ */
813
+ id: string;
814
+ /**
815
+ * The File object
816
+ */
817
+ file: File;
818
+ /**
819
+ * Blob URL for image previews
820
+ */
821
+ previewUrl?: string;
822
+ /**
823
+ * Current upload status
824
+ */
825
+ status: AttachmentStatus;
826
+ /**
827
+ * Error message if status is 'error'
828
+ */
829
+ error?: string;
830
+ /**
831
+ * Upload progress (0-100)
832
+ */
833
+ progress?: number;
834
+ }
835
+ /**
836
+ * Helper to check if a file is an image
837
+ */
838
+ declare function isImageFile(file: File): boolean;
839
+ /**
840
+ * Helper to create a preview URL for an image file
841
+ */
842
+ declare function createPreviewUrl(file: File): string | undefined;
843
+ /**
844
+ * Helper to revoke a preview URL when no longer needed
845
+ */
846
+ declare function revokePreviewUrl(url: string | undefined): void;
847
+ /**
848
+ * Generate a unique ID
849
+ */
850
+ declare function generateId(): string;
851
+ /**
852
+ * Create an empty conversation tree
853
+ */
854
+ declare function createEmptyTree(): ConversationTree;
855
+ /**
856
+ * Add a message to the tree
857
+ */
858
+ declare function addMessageToTree(tree: ConversationTree, message: Omit<MessageNode, 'children' | 'branchIndex'>, parentId?: string | null): ConversationTree;
859
+ /**
860
+ * Get the linear path from root to the active leaf
861
+ */
862
+ declare function getActivePathMessages(tree: ConversationTree): MessageNode[];
863
+ /**
864
+ * Get sibling count and current index for a node
865
+ */
866
+ declare function getSiblingInfo(tree: ConversationTree, nodeId: string): {
867
+ total: number;
868
+ current: number;
869
+ };
870
+ /**
871
+ * Switch to a different branch at a given node
872
+ */
873
+ declare function switchBranch(tree: ConversationTree, nodeId: string, direction: 'prev' | 'next'): ConversationTree;
874
+ /**
875
+ * Update a node's content (e.g., during streaming)
876
+ */
877
+ declare function updateNodeContent(tree: ConversationTree, nodeId: string, content: ReactNode, isStreaming?: boolean): ConversationTree;
878
+ /**
879
+ * Convert a flat message array to a conversation tree
880
+ */
881
+ declare function messagesToTree(messages: Array<{
882
+ id: string;
883
+ role: 'user' | 'assistant';
884
+ content: ReactNode;
885
+ isStreaming?: boolean;
886
+ }>): ConversationTree;
887
+ /**
888
+ * Check if a node has multiple children (is a branch point)
889
+ */
890
+ declare function isBranchPoint(tree: ConversationTree, nodeId: string): boolean;
891
+
740
892
  interface ChatInputNotice {
741
893
  /**
742
894
  * Visual severity: 'warning' shows a dismissible amber notice, 'error' shows a persistent red
@@ -757,15 +909,6 @@ interface ChatInputNotice {
757
909
  onDismiss?: () => void;
758
910
  }
759
911
  type ChatInputPosition = 'centered' | 'bottom';
760
- type AttachmentStatus = 'pending' | 'uploading' | 'complete' | 'error';
761
- interface Attachment {
762
- id: string;
763
- file: File;
764
- previewUrl?: string;
765
- status: AttachmentStatus;
766
- error?: string;
767
- progress?: number;
768
- }
769
912
  interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'onSubmit'> {
770
913
  /**
771
914
  * Position of the input: 'centered' for empty state, 'bottom' for conversation mode
@@ -807,6 +950,10 @@ interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'o
807
950
  * Called when attachments change (controlled mode)
808
951
  */
809
952
  onAttachmentsChange?: (attachments: Attachment[]) => void;
953
+ /**
954
+ * Called when an attachment is removed by the user (clicking the "x")
955
+ */
956
+ onAttachmentRemove?: (attachment: Attachment) => void;
810
957
  /**
811
958
  * Whether to show the attachment button
812
959
  */
@@ -1177,128 +1324,6 @@ interface ArtifactNode {
1177
1324
  children: ArtifactNode[];
1178
1325
  }
1179
1326
 
1180
- /**
1181
- * Conversation Tree Types
1182
- *
1183
- * These types support branching conversations where users can:
1184
- * - Edit their messages (creating a new branch)
1185
- * - Retry assistant responses (creating a new branch)
1186
- * - Navigate between different conversation branches
1187
- */
1188
-
1189
- /**
1190
- * A node in the conversation tree
1191
- */
1192
- interface MessageNode {
1193
- /**
1194
- * Unique identifier for this message
1195
- */
1196
- id: string;
1197
- /**
1198
- * The role of the message author
1199
- */
1200
- role: 'user' | 'assistant';
1201
- /**
1202
- * The message content (may include HTML/markdown or React components)
1203
- */
1204
- content: ReactNode;
1205
- /**
1206
- * ID of the parent message (null for root messages)
1207
- */
1208
- parentId: string | null;
1209
- /**
1210
- * IDs of child messages (branches/continuations)
1211
- */
1212
- children: string[];
1213
- /**
1214
- * Which sibling branch this message is (0, 1, 2...)
1215
- * Used for UI display like "1/3"
1216
- */
1217
- branchIndex?: number;
1218
- /**
1219
- * Whether this message is currently being streamed
1220
- */
1221
- isStreaming?: boolean;
1222
- /**
1223
- * Timestamp when the message was created
1224
- */
1225
- createdAt?: number;
1226
- }
1227
- /**
1228
- * The full conversation tree structure
1229
- */
1230
- interface ConversationTree {
1231
- /**
1232
- * All nodes indexed by their ID
1233
- */
1234
- nodes: Record<string, MessageNode>;
1235
- /**
1236
- * IDs of root-level messages (messages with no parent)
1237
- */
1238
- rootIds: string[];
1239
- /**
1240
- * The current "head" of the viewed branch
1241
- * This is the leaf node that determines which path we're viewing
1242
- */
1243
- activeLeafId: string | null;
1244
- }
1245
- /**
1246
- * Helper to check if a file is an image
1247
- */
1248
- declare function isImageFile(file: File): boolean;
1249
- /**
1250
- * Helper to create a preview URL for an image file
1251
- */
1252
- declare function createPreviewUrl(file: File): string | undefined;
1253
- /**
1254
- * Helper to revoke a preview URL when no longer needed
1255
- */
1256
- declare function revokePreviewUrl(url: string | undefined): void;
1257
- /**
1258
- * Generate a unique ID
1259
- */
1260
- declare function generateId(): string;
1261
- /**
1262
- * Create an empty conversation tree
1263
- */
1264
- declare function createEmptyTree(): ConversationTree;
1265
- /**
1266
- * Add a message to the tree
1267
- */
1268
- declare function addMessageToTree(tree: ConversationTree, message: Omit<MessageNode, 'children' | 'branchIndex'>, parentId?: string | null): ConversationTree;
1269
- /**
1270
- * Get the linear path from root to the active leaf
1271
- */
1272
- declare function getActivePathMessages(tree: ConversationTree): MessageNode[];
1273
- /**
1274
- * Get sibling count and current index for a node
1275
- */
1276
- declare function getSiblingInfo(tree: ConversationTree, nodeId: string): {
1277
- total: number;
1278
- current: number;
1279
- };
1280
- /**
1281
- * Switch to a different branch at a given node
1282
- */
1283
- declare function switchBranch(tree: ConversationTree, nodeId: string, direction: 'prev' | 'next'): ConversationTree;
1284
- /**
1285
- * Update a node's content (e.g., during streaming)
1286
- */
1287
- declare function updateNodeContent(tree: ConversationTree, nodeId: string, content: ReactNode, isStreaming?: boolean): ConversationTree;
1288
- /**
1289
- * Convert a flat message array to a conversation tree
1290
- */
1291
- declare function messagesToTree(messages: Array<{
1292
- id: string;
1293
- role: 'user' | 'assistant';
1294
- content: ReactNode;
1295
- isStreaming?: boolean;
1296
- }>): ConversationTree;
1297
- /**
1298
- * Check if a node has multiple children (is a branch point)
1299
- */
1300
- declare function isBranchPoint(tree: ConversationTree, nodeId: string): boolean;
1301
-
1302
1327
  interface Conversation {
1303
1328
  /**
1304
1329
  * Unique identifier for the conversation
@@ -1413,6 +1438,10 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1413
1438
  * Called when attachments are added or removed in the chat input.
1414
1439
  */
1415
1440
  onAttachmentsChange?: (attachments: Attachment[]) => void;
1441
+ /**
1442
+ * Called when an attachment is removed by the user (clicking the "x")
1443
+ */
1444
+ onAttachmentRemove?: (attachment: Attachment) => void;
1416
1445
  /**
1417
1446
  * Top-level artifact tree nodes for the artifacts panel.
1418
1447
  */
package/dist/index.d.ts CHANGED
@@ -737,6 +737,158 @@ interface MarkdownContentProps extends React$1.HTMLAttributes<HTMLDivElement> {
737
737
  }
738
738
  declare const MarkdownContent: React$1.ForwardRefExoticComponent<MarkdownContentProps & React$1.RefAttributes<HTMLDivElement>>;
739
739
 
740
+ /**
741
+ * Conversation Tree Types
742
+ *
743
+ * These types support branching conversations where users can:
744
+ * - Edit their messages (creating a new branch)
745
+ * - Retry assistant responses (creating a new branch)
746
+ * - Navigate between different conversation branches
747
+ */
748
+
749
+ /**
750
+ * A node in the conversation tree
751
+ */
752
+ interface MessageNode {
753
+ /**
754
+ * Unique identifier for this message
755
+ */
756
+ id: string;
757
+ /**
758
+ * The role of the message author
759
+ */
760
+ role: 'user' | 'assistant';
761
+ /**
762
+ * The message content (may include HTML/markdown or React components)
763
+ */
764
+ content: ReactNode;
765
+ /**
766
+ * ID of the parent message (null for root messages)
767
+ */
768
+ parentId: string | null;
769
+ /**
770
+ * IDs of child messages (branches/continuations)
771
+ */
772
+ children: string[];
773
+ /**
774
+ * Which sibling branch this message is (0, 1, 2...)
775
+ * Used for UI display like "1/3"
776
+ */
777
+ branchIndex?: number;
778
+ /**
779
+ * Whether this message is currently being streamed
780
+ */
781
+ isStreaming?: boolean;
782
+ /**
783
+ * Timestamp when the message was created
784
+ */
785
+ createdAt?: number;
786
+ }
787
+ /**
788
+ * The full conversation tree structure
789
+ */
790
+ interface ConversationTree {
791
+ /**
792
+ * All nodes indexed by their ID
793
+ */
794
+ nodes: Record<string, MessageNode>;
795
+ /**
796
+ * IDs of root-level messages (messages with no parent)
797
+ */
798
+ rootIds: string[];
799
+ /**
800
+ * The current "head" of the viewed branch
801
+ * This is the leaf node that determines which path we're viewing
802
+ */
803
+ activeLeafId: string | null;
804
+ }
805
+ /**
806
+ * Attachment types for file uploads
807
+ */
808
+ type AttachmentStatus = 'pending' | 'uploading' | 'complete' | 'error';
809
+ interface Attachment {
810
+ /**
811
+ * Unique identifier for the attachment
812
+ */
813
+ id: string;
814
+ /**
815
+ * The File object
816
+ */
817
+ file: File;
818
+ /**
819
+ * Blob URL for image previews
820
+ */
821
+ previewUrl?: string;
822
+ /**
823
+ * Current upload status
824
+ */
825
+ status: AttachmentStatus;
826
+ /**
827
+ * Error message if status is 'error'
828
+ */
829
+ error?: string;
830
+ /**
831
+ * Upload progress (0-100)
832
+ */
833
+ progress?: number;
834
+ }
835
+ /**
836
+ * Helper to check if a file is an image
837
+ */
838
+ declare function isImageFile(file: File): boolean;
839
+ /**
840
+ * Helper to create a preview URL for an image file
841
+ */
842
+ declare function createPreviewUrl(file: File): string | undefined;
843
+ /**
844
+ * Helper to revoke a preview URL when no longer needed
845
+ */
846
+ declare function revokePreviewUrl(url: string | undefined): void;
847
+ /**
848
+ * Generate a unique ID
849
+ */
850
+ declare function generateId(): string;
851
+ /**
852
+ * Create an empty conversation tree
853
+ */
854
+ declare function createEmptyTree(): ConversationTree;
855
+ /**
856
+ * Add a message to the tree
857
+ */
858
+ declare function addMessageToTree(tree: ConversationTree, message: Omit<MessageNode, 'children' | 'branchIndex'>, parentId?: string | null): ConversationTree;
859
+ /**
860
+ * Get the linear path from root to the active leaf
861
+ */
862
+ declare function getActivePathMessages(tree: ConversationTree): MessageNode[];
863
+ /**
864
+ * Get sibling count and current index for a node
865
+ */
866
+ declare function getSiblingInfo(tree: ConversationTree, nodeId: string): {
867
+ total: number;
868
+ current: number;
869
+ };
870
+ /**
871
+ * Switch to a different branch at a given node
872
+ */
873
+ declare function switchBranch(tree: ConversationTree, nodeId: string, direction: 'prev' | 'next'): ConversationTree;
874
+ /**
875
+ * Update a node's content (e.g., during streaming)
876
+ */
877
+ declare function updateNodeContent(tree: ConversationTree, nodeId: string, content: ReactNode, isStreaming?: boolean): ConversationTree;
878
+ /**
879
+ * Convert a flat message array to a conversation tree
880
+ */
881
+ declare function messagesToTree(messages: Array<{
882
+ id: string;
883
+ role: 'user' | 'assistant';
884
+ content: ReactNode;
885
+ isStreaming?: boolean;
886
+ }>): ConversationTree;
887
+ /**
888
+ * Check if a node has multiple children (is a branch point)
889
+ */
890
+ declare function isBranchPoint(tree: ConversationTree, nodeId: string): boolean;
891
+
740
892
  interface ChatInputNotice {
741
893
  /**
742
894
  * Visual severity: 'warning' shows a dismissible amber notice, 'error' shows a persistent red
@@ -757,15 +909,6 @@ interface ChatInputNotice {
757
909
  onDismiss?: () => void;
758
910
  }
759
911
  type ChatInputPosition = 'centered' | 'bottom';
760
- type AttachmentStatus = 'pending' | 'uploading' | 'complete' | 'error';
761
- interface Attachment {
762
- id: string;
763
- file: File;
764
- previewUrl?: string;
765
- status: AttachmentStatus;
766
- error?: string;
767
- progress?: number;
768
- }
769
912
  interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'onSubmit'> {
770
913
  /**
771
914
  * Position of the input: 'centered' for empty state, 'bottom' for conversation mode
@@ -807,6 +950,10 @@ interface ChatInputProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'o
807
950
  * Called when attachments change (controlled mode)
808
951
  */
809
952
  onAttachmentsChange?: (attachments: Attachment[]) => void;
953
+ /**
954
+ * Called when an attachment is removed by the user (clicking the "x")
955
+ */
956
+ onAttachmentRemove?: (attachment: Attachment) => void;
810
957
  /**
811
958
  * Whether to show the attachment button
812
959
  */
@@ -1177,128 +1324,6 @@ interface ArtifactNode {
1177
1324
  children: ArtifactNode[];
1178
1325
  }
1179
1326
 
1180
- /**
1181
- * Conversation Tree Types
1182
- *
1183
- * These types support branching conversations where users can:
1184
- * - Edit their messages (creating a new branch)
1185
- * - Retry assistant responses (creating a new branch)
1186
- * - Navigate between different conversation branches
1187
- */
1188
-
1189
- /**
1190
- * A node in the conversation tree
1191
- */
1192
- interface MessageNode {
1193
- /**
1194
- * Unique identifier for this message
1195
- */
1196
- id: string;
1197
- /**
1198
- * The role of the message author
1199
- */
1200
- role: 'user' | 'assistant';
1201
- /**
1202
- * The message content (may include HTML/markdown or React components)
1203
- */
1204
- content: ReactNode;
1205
- /**
1206
- * ID of the parent message (null for root messages)
1207
- */
1208
- parentId: string | null;
1209
- /**
1210
- * IDs of child messages (branches/continuations)
1211
- */
1212
- children: string[];
1213
- /**
1214
- * Which sibling branch this message is (0, 1, 2...)
1215
- * Used for UI display like "1/3"
1216
- */
1217
- branchIndex?: number;
1218
- /**
1219
- * Whether this message is currently being streamed
1220
- */
1221
- isStreaming?: boolean;
1222
- /**
1223
- * Timestamp when the message was created
1224
- */
1225
- createdAt?: number;
1226
- }
1227
- /**
1228
- * The full conversation tree structure
1229
- */
1230
- interface ConversationTree {
1231
- /**
1232
- * All nodes indexed by their ID
1233
- */
1234
- nodes: Record<string, MessageNode>;
1235
- /**
1236
- * IDs of root-level messages (messages with no parent)
1237
- */
1238
- rootIds: string[];
1239
- /**
1240
- * The current "head" of the viewed branch
1241
- * This is the leaf node that determines which path we're viewing
1242
- */
1243
- activeLeafId: string | null;
1244
- }
1245
- /**
1246
- * Helper to check if a file is an image
1247
- */
1248
- declare function isImageFile(file: File): boolean;
1249
- /**
1250
- * Helper to create a preview URL for an image file
1251
- */
1252
- declare function createPreviewUrl(file: File): string | undefined;
1253
- /**
1254
- * Helper to revoke a preview URL when no longer needed
1255
- */
1256
- declare function revokePreviewUrl(url: string | undefined): void;
1257
- /**
1258
- * Generate a unique ID
1259
- */
1260
- declare function generateId(): string;
1261
- /**
1262
- * Create an empty conversation tree
1263
- */
1264
- declare function createEmptyTree(): ConversationTree;
1265
- /**
1266
- * Add a message to the tree
1267
- */
1268
- declare function addMessageToTree(tree: ConversationTree, message: Omit<MessageNode, 'children' | 'branchIndex'>, parentId?: string | null): ConversationTree;
1269
- /**
1270
- * Get the linear path from root to the active leaf
1271
- */
1272
- declare function getActivePathMessages(tree: ConversationTree): MessageNode[];
1273
- /**
1274
- * Get sibling count and current index for a node
1275
- */
1276
- declare function getSiblingInfo(tree: ConversationTree, nodeId: string): {
1277
- total: number;
1278
- current: number;
1279
- };
1280
- /**
1281
- * Switch to a different branch at a given node
1282
- */
1283
- declare function switchBranch(tree: ConversationTree, nodeId: string, direction: 'prev' | 'next'): ConversationTree;
1284
- /**
1285
- * Update a node's content (e.g., during streaming)
1286
- */
1287
- declare function updateNodeContent(tree: ConversationTree, nodeId: string, content: ReactNode, isStreaming?: boolean): ConversationTree;
1288
- /**
1289
- * Convert a flat message array to a conversation tree
1290
- */
1291
- declare function messagesToTree(messages: Array<{
1292
- id: string;
1293
- role: 'user' | 'assistant';
1294
- content: ReactNode;
1295
- isStreaming?: boolean;
1296
- }>): ConversationTree;
1297
- /**
1298
- * Check if a node has multiple children (is a branch point)
1299
- */
1300
- declare function isBranchPoint(tree: ConversationTree, nodeId: string): boolean;
1301
-
1302
1327
  interface Conversation {
1303
1328
  /**
1304
1329
  * Unique identifier for the conversation
@@ -1413,6 +1438,10 @@ interface ChatInterfaceProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>
1413
1438
  * Called when attachments are added or removed in the chat input.
1414
1439
  */
1415
1440
  onAttachmentsChange?: (attachments: Attachment[]) => void;
1441
+ /**
1442
+ * Called when an attachment is removed by the user (clicking the "x")
1443
+ */
1444
+ onAttachmentRemove?: (attachment: Attachment) => void;
1416
1445
  /**
1417
1446
  * Top-level artifact tree nodes for the artifacts panel.
1418
1447
  */
package/dist/index.js CHANGED
@@ -4800,6 +4800,7 @@ var ChatInput = import_react61.default.forwardRef(
4800
4800
  onStop,
4801
4801
  attachments: controlledAttachments,
4802
4802
  onAttachmentsChange,
4803
+ onAttachmentRemove,
4803
4804
  showAttachmentButton = true,
4804
4805
  acceptedFileTypes,
4805
4806
  notice,
@@ -4886,15 +4887,19 @@ var ChatInput = import_react61.default.forwardRef(
4886
4887
  );
4887
4888
  const handleRemoveAttachment = (0, import_react61.useCallback)(
4888
4889
  (id) => {
4890
+ const attachment = attachments.find((a) => a.id === id);
4891
+ if (attachment && onAttachmentRemove) {
4892
+ onAttachmentRemove(attachment);
4893
+ }
4889
4894
  setAttachments((prev) => {
4890
- const attachment = prev.find((a) => a.id === id);
4891
- if (attachment?.previewUrl) {
4892
- URL.revokeObjectURL(attachment.previewUrl);
4895
+ const attachmentToRemove = prev.find((a) => a.id === id);
4896
+ if (attachmentToRemove?.previewUrl) {
4897
+ URL.revokeObjectURL(attachmentToRemove.previewUrl);
4893
4898
  }
4894
4899
  return prev.filter((a) => a.id !== id);
4895
4900
  });
4896
4901
  },
4897
- [setAttachments]
4902
+ [attachments, onAttachmentRemove, setAttachments]
4898
4903
  );
4899
4904
  const handleDragEnter = (0, import_react61.useCallback)((e) => {
4900
4905
  e.preventDefault();
@@ -4926,7 +4931,8 @@ var ChatInput = import_react61.default.forwardRef(
4926
4931
  );
4927
4932
  const isCentered = position === "centered";
4928
4933
  const hasAttachments = attachments.length > 0;
4929
- const canSubmit = value.trim() && !disabled && !isStreaming;
4934
+ const isUploading = attachments.some((a) => a.status === "uploading");
4935
+ const canSubmit = value.trim() && !disabled && !isStreaming && !isUploading;
4930
4936
  return /* @__PURE__ */ import_react61.default.createElement(
4931
4937
  "div",
4932
4938
  {
@@ -6840,6 +6846,7 @@ var ChatInterface = import_react78.default.forwardRef(
6840
6846
  enableMessageActions = true,
6841
6847
  attachments: propsAttachments,
6842
6848
  onAttachmentsChange,
6849
+ onAttachmentRemove,
6843
6850
  artifactNodes,
6844
6851
  isArtifactsPanelOpen,
6845
6852
  onArtifactsPanelOpenChange,
@@ -7149,6 +7156,7 @@ var ChatInterface = import_react78.default.forwardRef(
7149
7156
  showAttachmentButton,
7150
7157
  attachments: propsAttachments,
7151
7158
  onAttachmentsChange,
7159
+ onAttachmentRemove,
7152
7160
  notice: inputNotice,
7153
7161
  onInputChange,
7154
7162
  initialInputValue,