Skip to content

Commit

Permalink
feat: Simple Image / Text AttachmentAdapters (#782)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonom authored Sep 9, 2024
1 parent 750fe5f commit d2580d3
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/pink-avocados-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@assistant-ui/react": patch
---

feat: SimpleImageAttachmentAdapter
5 changes: 5 additions & 0 deletions .changeset/shaggy-cars-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@assistant-ui/react": patch
---

feat: SimpleTextAttachmentAdapter
5 changes: 5 additions & 0 deletions .changeset/tall-waves-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@assistant-ui/react": patch
---

feat: ComposedAttachmentAdapter
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
ComposerAttachment,
MessageAttachment,
} from "../../context/stores/Attachment";
import { AttachmentAdapter } from "./AttachmentAdapter";

export class SimpleImageAttachmentAdapter implements AttachmentAdapter {
public accept = "image/*";

public async add(state: { file: File }): Promise<ComposerAttachment> {
return {
id: state.file.name,
type: "image",
name: state.file.name,
file: state.file,
};
}

public async send(
attachment: ComposerAttachment,
): Promise<MessageAttachment> {
return {
...attachment,
content: [
{
type: "image",
image: await getFileDataURL(attachment.file),
},
],
};
}

public async remove() {
// noop
}
}

const getFileDataURL = (file: File) =>
new Promise<string>((resolve, reject) => {
const reader = new FileReader();

reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);

reader.readAsDataURL(file);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
ComposerAttachment,
MessageAttachment,
} from "../../context/stores/Attachment";
import { AttachmentAdapter } from "./AttachmentAdapter";

export class SimpleTextAttachmentAdapter implements AttachmentAdapter {
public accept =
"text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css";

public async add(state: { file: File }): Promise<ComposerAttachment> {
return {
id: state.file.name,
type: "document",
name: state.file.name,
file: state.file,
};
}

public async send(
attachment: ComposerAttachment,
): Promise<MessageAttachment> {
return {
...attachment,
content: [
{
type: "text",
text: `<attachment name=${attachment.name}>\n${await getFileText(attachment.file)}\n</attachment>`,
},
],
};
}

public async remove() {
// noop
}
}

const getFileText = (file: File) =>
new Promise<string>((resolve, reject) => {
const reader = new FileReader();

reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);

reader.readAsText(file);
});
3 changes: 3 additions & 0 deletions packages/react/src/runtimes/attachment/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export type { AttachmentAdapter } from "./AttachmentAdapter";
export { SimpleImageAttachmentAdapter } from "./SimpleImageAttachmentAdapter";
export { SimpleTextAttachmentAdapter } from "./SimpleTextAttachmentAdapter";
export { ComposedAttachmentAdapter } from "./ComposedAttachmentAdapter";

0 comments on commit d2580d3

Please sign in to comment.