-
Notifications
You must be signed in to change notification settings - Fork 163
feat(prompt-input): Add file property to attachment messages for persistent storage #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@chaxus is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Suggestions:
- The
PromptInputMessagetype is not updated to reflect that the files now include thefileproperty. This creates a type mismatch between what's actually passed toonSubmitand what the type signature declares.
View Details
📝 Patch Details
diff --git a/packages/elements/src/prompt-input.tsx b/packages/elements/src/prompt-input.tsx
index f00cbac..62e2874 100644
--- a/packages/elements/src/prompt-input.tsx
+++ b/packages/elements/src/prompt-input.tsx
@@ -415,7 +415,7 @@ export const PromptInputActionAddAttachments = ({
export type PromptInputMessage = {
text: string;
- files: FileUIPart[];
+ files: (FileUIPart & { file: File })[];
};
export type PromptInputProps = Omit<
@@ -708,7 +708,7 @@ export const PromptInput = ({
}
return item;
})
- ).then((convertedFiles: FileUIPart[]) => {
+ ).then((convertedFiles: (FileUIPart & { file: File })[]) => {
try {
const result = onSubmit({ text, files: convertedFiles }, event);
Analysis
Type mismatch: PromptInputMessage doesn't reflect file property passed at runtime
What fails: The PromptInputMessage type declares files: FileUIPart[] but the actual data passed to the onSubmit callback includes (FileUIPart & { file: File })[]. This creates a type-runtime mismatch where the file property is accessible at runtime but TypeScript type-checking rejects access to it.
How to reproduce: Create a PromptInput component with an onSubmit handler that attempts to access the file property:
/>Result: TypeScript compiler error when accessing message.files[0].file - "Property 'file' does not exist on type 'FileUIPart'". However, at runtime the file property IS present because the data transformation in handleSubmit (lines 702-704) preserves it through destructuring and spreading.
Expected behavior: Developers should be able to access the file property on objects in message.files without TypeScript errors, matching the actual runtime behavior. The files stored in the component (line 472) are explicitly typed as (FileUIPart & { id: string; file: File })[], and this property is preserved through the transformation before being passed to onSubmit.
View Details
📝 Patch Details
diff --git a/packages/elements/src/prompt-input.tsx b/packages/elements/src/prompt-input.tsx
index f00cbac..c3cdfb3 100644
--- a/packages/elements/src/prompt-input.tsx
+++ b/packages/elements/src/prompt-input.tsx
@@ -362,7 +362,7 @@ export type PromptInputAttachmentsProps = Omit<
HTMLAttributes<HTMLDivElement>,
"children"
> & {
- children: (attachment: FileUIPart & { id: string }) => ReactNode;
+ children: (attachment: FileUIPart & { id: string; file: File }) => ReactNode;
};
export function PromptInputAttachments({
Analysis
Type mismatch in PromptInputAttachmentsProps children function signature
What fails: The PromptInputAttachmentsProps type's children function is declared to receive (attachment: FileUIPart & { id: string }), but at line 384-385 in PromptInputAttachments(), the component passes attachment objects from attachments.files which are typed as (FileUIPart & { id: string, file: File })[]. This creates a type mismatch where the file property is not included in the children function's type signature.
How to reproduce:
- Open
packages/elements/src/prompt-input.tsx - Notice that
AttachmentsContext.files(line 78) is typed as(FileUIPart & { id: string, file: File })[] - Notice that
PromptInputAttachmentsProps.children(line 365) is typed to acceptFileUIPart & { id: string }- missing thefile: Fileproperty - At line 384,
attachments.files.map((file) => children(file))passes objects with thefileproperty to a function that doesn't expect it
Result: TypeScript would show a type error when attempting to call children(file) because the file object has extra properties not included in the children function's parameter type. Developers cannot access the file property from the attachment without bypassing type safety.
Expected: The children function should accept the full type signature: (attachment: FileUIPart & { id: string; file: File }) => ReactNode, matching what is actually passed to it.
Fix applied: Updated the PromptInputAttachmentsProps type to include file: File in the children function signature to match the actual attachment objects being passed.
View Details
📝 Patch Details
diff --git a/packages/elements/src/prompt-input.tsx b/packages/elements/src/prompt-input.tsx
index f00cbac..774aabe 100644
--- a/packages/elements/src/prompt-input.tsx
+++ b/packages/elements/src/prompt-input.tsx
@@ -263,7 +263,7 @@ export const usePromptInputAttachments = () => {
};
export type PromptInputAttachmentProps = HTMLAttributes<HTMLDivElement> & {
- data: FileUIPart & { id: string };
+ data: FileUIPart & { id: string; file: File };
className?: string;
};
@@ -362,7 +362,7 @@ export type PromptInputAttachmentsProps = Omit<
HTMLAttributes<HTMLDivElement>,
"children"
> & {
- children: (attachment: FileUIPart & { id: string }) => ReactNode;
+ children: (attachment: FileUIPart & { id: string; file: File }) => ReactNode;
};
export function PromptInputAttachments({
Analysis
Missing file property in PromptInputAttachmentProps type
What fails: PromptInputAttachmentProps.data and PromptInputAttachmentsProps.children parameter types don't include the file property that was added to internal attachment state in commit 2ce0bef.
How to reproduce:
// In PromptInputAttachment component
const fileSize = data.file.size; // TypeScript error: Property 'file' does not existWhat happened: TypeScript error when trying to access the file property because the type declaration doesn't include it.
Expected: Since commit 2ce0bef ("feat(prompt-input): add file property to attachment messages for persistent storage") added the file property to AttachmentsContext.files, local state, and both provider and local PromptInput state, the public component prop types should also include it for type consistency and API completeness.
Context: The file property is available at runtime but hidden from the type signature due to TypeScript's width subtyping (allowing wider types to be used where narrower types are expected). However, for type safety and consistency with the internal state types, the component props should accurately reflect what properties are available.
Description
I encountered a use case similar to the one described in #89, where I need to persist chat messages. This requires the ability to upload files attached via the Prompt Input component.
Currently, the component provides file metadata like id, type, url (a local object URL), mediaType, and filename. However, these properties are insufficient for actual file persistence because:
The url is a temporary blob link that becomes invalid after the session.
We lack access to the actual File object, which is required to upload the file data to a server or persistent storage.
Proposed Solution
I would like to suggest exposing the file property from the component. This would allow users to access the File object directly during the onSubmit event.
With access to the file data, we can then handle the file upload and storage independently, fitting it into our own persistence layer.
Benefits
Flexibility: Enables developers to implement custom file upload workflows.
Persistence: Supports use cases where messages (and their associated files) need to be saved permanently.
This is just a suggestion from my perspective, and I believe it would be a helpful addition for others with similar needs. Thank you for considering it!