@assistant-ui/react 0.7.1 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. package/dist/api/ContentPartRuntime.d.ts +5 -1
  2. package/dist/api/ContentPartRuntime.d.ts.map +1 -1
  3. package/dist/api/ContentPartRuntime.js.map +1 -1
  4. package/dist/api/ContentPartRuntime.mjs.map +1 -1
  5. package/dist/api/RuntimePathTypes.d.ts +0 -3
  6. package/dist/api/RuntimePathTypes.d.ts.map +1 -1
  7. package/dist/api/RuntimePathTypes.js.map +1 -1
  8. package/dist/api/ThreadListRuntime.d.ts +0 -5
  9. package/dist/api/ThreadListRuntime.d.ts.map +1 -1
  10. package/dist/api/ThreadListRuntime.js +4 -10
  11. package/dist/api/ThreadListRuntime.js.map +1 -1
  12. package/dist/api/ThreadListRuntime.mjs +4 -10
  13. package/dist/api/ThreadListRuntime.mjs.map +1 -1
  14. package/dist/runtimes/edge/converters/fromCoreMessage.d.ts.map +1 -1
  15. package/dist/runtimes/edge/converters/fromCoreMessage.js +6 -3
  16. package/dist/runtimes/edge/converters/fromCoreMessage.js.map +1 -1
  17. package/dist/runtimes/edge/converters/fromCoreMessage.mjs +6 -3
  18. package/dist/runtimes/edge/converters/fromCoreMessage.mjs.map +1 -1
  19. package/dist/runtimes/edge/converters/fromLanguageModelMessages.d.ts.map +1 -1
  20. package/dist/runtimes/edge/converters/fromLanguageModelMessages.js +3 -2
  21. package/dist/runtimes/edge/converters/fromLanguageModelMessages.js.map +1 -1
  22. package/dist/runtimes/edge/converters/fromLanguageModelMessages.mjs +3 -2
  23. package/dist/runtimes/edge/converters/fromLanguageModelMessages.mjs.map +1 -1
  24. package/dist/runtimes/external-store/ThreadMessageLike.d.ts +5 -1
  25. package/dist/runtimes/external-store/ThreadMessageLike.d.ts.map +1 -1
  26. package/dist/runtimes/external-store/ThreadMessageLike.js +18 -6
  27. package/dist/runtimes/external-store/ThreadMessageLike.js.map +1 -1
  28. package/dist/runtimes/external-store/ThreadMessageLike.mjs +18 -6
  29. package/dist/runtimes/external-store/ThreadMessageLike.mjs.map +1 -1
  30. package/dist/runtimes/local/ChatModelAdapter.d.ts +4 -4
  31. package/dist/runtimes/local/ChatModelAdapter.d.ts.map +1 -1
  32. package/dist/runtimes/local/ChatModelAdapter.js.map +1 -1
  33. package/dist/runtimes/local/LocalThreadRuntimeCore.d.ts.map +1 -1
  34. package/dist/runtimes/local/LocalThreadRuntimeCore.js +1 -0
  35. package/dist/runtimes/local/LocalThreadRuntimeCore.js.map +1 -1
  36. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs +1 -0
  37. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs.map +1 -1
  38. package/dist/types/AssistantTypes.d.ts +60 -51
  39. package/dist/types/AssistantTypes.d.ts.map +1 -1
  40. package/dist/types/AssistantTypes.js.map +1 -1
  41. package/dist/ui/{attachment.d.ts → attachment-ui.d.ts} +3 -3
  42. package/dist/ui/attachment-ui.d.ts.map +1 -0
  43. package/dist/ui/{attachment.js → attachment-ui.js} +9 -9
  44. package/dist/ui/attachment-ui.js.map +1 -0
  45. package/dist/ui/{attachment.mjs → attachment-ui.mjs} +6 -6
  46. package/dist/ui/attachment-ui.mjs.map +1 -0
  47. package/dist/ui/composer.js +2 -2
  48. package/dist/ui/composer.js.map +1 -1
  49. package/dist/ui/composer.mjs +1 -1
  50. package/dist/ui/composer.mjs.map +1 -1
  51. package/dist/ui/index.d.ts +1 -1
  52. package/dist/ui/index.d.ts.map +1 -1
  53. package/dist/ui/index.js +2 -2
  54. package/dist/ui/index.js.map +1 -1
  55. package/dist/ui/index.mjs +1 -1
  56. package/dist/ui/index.mjs.map +1 -1
  57. package/dist/ui/user-message.js +2 -2
  58. package/dist/ui/user-message.js.map +1 -1
  59. package/dist/ui/user-message.mjs +1 -1
  60. package/dist/ui/user-message.mjs.map +1 -1
  61. package/dist/utils/smooth/SmoothContext.d.ts +42 -42
  62. package/package.json +3 -3
  63. package/src/api/ContentPartRuntime.ts +6 -2
  64. package/src/api/RuntimePathTypes.ts +0 -4
  65. package/src/api/ThreadListRuntime.ts +4 -16
  66. package/src/runtimes/edge/converters/fromCoreMessage.ts +4 -0
  67. package/src/runtimes/edge/converters/fromLanguageModelMessages.ts +5 -2
  68. package/src/runtimes/external-store/ThreadMessageLike.tsx +21 -4
  69. package/src/runtimes/local/ChatModelAdapter.tsx +4 -4
  70. package/src/runtimes/local/LocalThreadRuntimeCore.tsx +1 -0
  71. package/src/types/AssistantTypes.ts +65 -52
  72. package/src/ui/{attachment.tsx → attachment-ui.tsx} +3 -3
  73. package/src/ui/composer.tsx +1 -1
  74. package/src/ui/index.ts +1 -1
  75. package/src/ui/user-message.tsx +1 -1
  76. package/dist/ui/attachment.d.ts.map +0 -1
  77. package/dist/ui/attachment.js.map +0 -1
  78. package/dist/ui/attachment.mjs.map +0 -1
@@ -14,6 +14,7 @@ import {
14
14
  } from "../../types";
15
15
  import {
16
16
  CoreToolCallContentPart,
17
+ ThreadStep,
17
18
  Unstable_AudioContentPart,
18
19
  } from "../../types/AssistantTypes";
19
20
 
@@ -33,7 +34,10 @@ export type ThreadMessageLike = {
33
34
  createdAt?: Date | undefined;
34
35
  status?: MessageStatus | undefined;
35
36
  attachments?: CompleteAttachment[] | undefined;
36
- // TODO metadata
37
+ metadata?: {
38
+ steps?: ThreadStep[] | undefined;
39
+ custom?: Record<string, unknown> | undefined;
40
+ };
37
41
  };
38
42
 
39
43
  export const fromThreadMessageLike = (
@@ -41,7 +45,7 @@ export const fromThreadMessageLike = (
41
45
  fallbackId: string,
42
46
  fallbackStatus: MessageStatus,
43
47
  ): ThreadMessage => {
44
- const { role, id, createdAt, attachments, status } = like;
48
+ const { role, id, createdAt, attachments, status, metadata } = like;
45
49
  const common = {
46
50
  id: id ?? fallbackId,
47
51
  createdAt: createdAt ?? new Date(),
@@ -53,10 +57,13 @@ export const fromThreadMessageLike = (
53
57
  : like.content;
54
58
 
55
59
  if (role !== "user" && attachments)
56
- throw new Error("Attachments are only supported for user messages");
60
+ throw new Error("attachments are only supported for user messages");
57
61
 
58
62
  if (role !== "assistant" && status)
59
- throw new Error("Status is only supported for assistant messages");
63
+ throw new Error("status is only supported for assistant messages");
64
+
65
+ if (role !== "assistant" && metadata?.steps)
66
+ throw new Error("metadata.steps is only supported for assistant messages");
60
67
 
61
68
  switch (role) {
62
69
  case "assistant":
@@ -90,6 +97,10 @@ export const fromThreadMessageLike = (
90
97
  })
91
98
  .filter((c) => !!c),
92
99
  status: status ?? fallbackStatus,
100
+ metadata: {
101
+ custom: metadata?.custom ?? {},
102
+ steps: metadata?.steps ?? [],
103
+ },
93
104
  } satisfies ThreadAssistantMessage;
94
105
 
95
106
  case "user":
@@ -112,6 +123,9 @@ export const fromThreadMessageLike = (
112
123
  }
113
124
  }),
114
125
  attachments: attachments ?? [],
126
+ metadata: {
127
+ custom: metadata?.custom ?? {},
128
+ },
115
129
  } satisfies ThreadUserMessage;
116
130
 
117
131
  case "system":
@@ -124,6 +138,9 @@ export const fromThreadMessageLike = (
124
138
  ...common,
125
139
  role,
126
140
  content: content as [TextContentPart],
141
+ metadata: {
142
+ custom: metadata?.custom ?? {},
143
+ },
127
144
  } satisfies ThreadSystemMessage;
128
145
 
129
146
  default: {
@@ -14,11 +14,11 @@ export type ChatModelRunUpdate = {
14
14
  };
15
15
 
16
16
  export type ChatModelRunResult = {
17
- content?: ThreadAssistantContentPart[];
18
- status?: MessageStatus;
17
+ content?: ThreadAssistantContentPart[] | undefined;
18
+ status?: MessageStatus | undefined;
19
19
  metadata?: {
20
- steps?: ThreadStep[];
21
- custom?: Record<string, unknown>;
20
+ steps?: ThreadStep[] | undefined;
21
+ custom?: Record<string, unknown> | undefined;
22
22
  };
23
23
  };
24
24
 
@@ -118,6 +118,7 @@ export class LocalThreadRuntimeCore
118
118
  role: "assistant",
119
119
  status: { type: "running" },
120
120
  content: [],
121
+ metadata: { steps: [], custom: {} },
121
122
  createdAt: new Date(),
122
123
  };
123
124
 
@@ -4,45 +4,45 @@ import { CompleteAttachment } from "./AttachmentTypes";
4
4
  export type MessageRole = "user" | "assistant" | "system";
5
5
 
6
6
  export type TextContentPart = {
7
- type: "text";
8
- text: string;
7
+ readonly type: "text";
8
+ readonly text: string;
9
9
  };
10
10
 
11
11
  export type ImageContentPart = {
12
- type: "image";
13
- image: string;
12
+ readonly type: "image";
13
+ readonly image: string;
14
14
  };
15
15
 
16
16
  export type Unstable_AudioContentPart = {
17
- type: "audio";
18
- audio: {
19
- data: string;
20
- format: "mp3" | "wav";
17
+ readonly type: "audio";
18
+ readonly audio: {
19
+ readonly data: string;
20
+ readonly format: "mp3" | "wav";
21
21
  };
22
22
  };
23
23
 
24
24
  export type UIContentPart = {
25
- type: "ui";
26
- display: ReactNode;
25
+ readonly type: "ui";
26
+ readonly display: ReactNode;
27
27
  };
28
28
 
29
29
  export type CoreToolCallContentPart<
30
30
  TArgs extends Record<string, unknown> = Record<string | number, unknown>,
31
31
  TResult = unknown,
32
32
  > = {
33
- type: "tool-call";
34
- toolCallId: string;
35
- toolName: string;
36
- args: TArgs;
37
- result?: TResult | undefined;
38
- isError?: boolean | undefined;
33
+ readonly type: "tool-call";
34
+ readonly toolCallId: string;
35
+ readonly toolName: string;
36
+ readonly args: TArgs;
37
+ readonly result?: TResult | undefined;
38
+ readonly isError?: boolean | undefined;
39
39
  };
40
40
 
41
41
  export type ToolCallContentPart<
42
42
  TArgs extends Record<string, unknown> = Record<string | number, unknown>,
43
43
  TResult = unknown,
44
44
  > = CoreToolCallContentPart<TArgs, TResult> & {
45
- argsText: string;
45
+ readonly argsText: string;
46
46
  };
47
47
 
48
48
  export type ThreadUserContentPart =
@@ -57,82 +57,92 @@ export type ThreadAssistantContentPart =
57
57
  | UIContentPart;
58
58
 
59
59
  type MessageCommonProps = {
60
- id: string;
61
- createdAt: Date;
60
+ readonly id: string;
61
+ readonly createdAt: Date;
62
62
  };
63
63
 
64
64
  export type ThreadStep = {
65
- usage?:
65
+ readonly usage?:
66
66
  | {
67
- promptTokens: number;
68
- completionTokens: number;
67
+ readonly promptTokens: number;
68
+ readonly completionTokens: number;
69
69
  }
70
70
  | undefined;
71
71
  };
72
72
 
73
73
  export type ContentPartStatus =
74
74
  | {
75
- type: "running";
75
+ readonly type: "running";
76
76
  }
77
77
  | {
78
- type: "complete";
78
+ readonly type: "complete";
79
79
  }
80
80
  | {
81
- type: "incomplete";
82
- reason: "cancelled" | "length" | "content-filter" | "other" | "error";
83
- error?: unknown;
81
+ readonly type: "incomplete";
82
+ readonly reason:
83
+ | "cancelled"
84
+ | "length"
85
+ | "content-filter"
86
+ | "other"
87
+ | "error";
88
+ readonly error?: unknown;
84
89
  };
85
90
 
86
91
  export type ToolCallContentPartStatus =
87
92
  | {
88
- type: "requires-action";
89
- reason: "tool-calls";
93
+ readonly type: "requires-action";
94
+ readonly reason: "tool-calls";
90
95
  }
91
96
  | ContentPartStatus;
92
97
 
93
98
  export type MessageStatus =
94
99
  | {
95
- type: "running";
100
+ readonly type: "running";
96
101
  }
97
102
  | {
98
- type: "requires-action";
99
- reason: "tool-calls";
103
+ readonly type: "requires-action";
104
+ readonly reason: "tool-calls";
100
105
  }
101
106
  | {
102
- type: "complete";
103
- reason: "stop" | "unknown";
107
+ readonly type: "complete";
108
+ readonly reason: "stop" | "unknown";
104
109
  }
105
110
  | {
106
- type: "incomplete";
107
- reason:
111
+ readonly type: "incomplete";
112
+ readonly reason:
108
113
  | "cancelled"
109
114
  | "tool-calls"
110
115
  | "length"
111
116
  | "content-filter"
112
117
  | "other"
113
118
  | "error";
114
- error?: unknown;
119
+ readonly error?: unknown;
115
120
  };
116
121
 
117
122
  export type ThreadSystemMessage = MessageCommonProps & {
118
- role: "system";
119
- content: [TextContentPart];
123
+ readonly role: "system";
124
+ readonly content: [TextContentPart];
125
+ readonly metadata: {
126
+ readonly custom: Record<string, unknown>;
127
+ };
120
128
  };
121
129
 
122
130
  export type ThreadUserMessage = MessageCommonProps & {
123
- role: "user";
124
- content: ThreadUserContentPart[];
125
- attachments: readonly CompleteAttachment[];
126
- // TODO metadata
131
+ readonly role: "user";
132
+ readonly content: ThreadUserContentPart[];
133
+ readonly attachments: readonly CompleteAttachment[];
134
+ readonly metadata: {
135
+ readonly custom: Record<string, unknown>;
136
+ };
127
137
  };
128
138
 
129
139
  export type ThreadAssistantMessage = MessageCommonProps & {
130
- role: "assistant";
131
- content: ThreadAssistantContentPart[];
132
- status: MessageStatus;
133
- metadata?: {
134
- steps?: ThreadStep[] | undefined;
135
- custom?: Record<string, unknown> | undefined;
140
+ readonly role: "assistant";
141
+ readonly content: ThreadAssistantContentPart[];
142
+ readonly status: MessageStatus;
143
+ readonly metadata: {
144
+ readonly steps: ThreadStep[];
145
+ readonly custom: Record<string, unknown>;
136
146
  };
137
147
  };
138
148
 
@@ -143,9 +153,12 @@ export type AppendMessage = CoreMessage & {
143
153
  };
144
154
 
145
155
  type BaseThreadMessage = {
146
- status?: ThreadAssistantMessage["status"];
147
- metadata?: ThreadAssistantMessage["metadata"];
148
- attachments?: ThreadUserMessage["attachments"];
156
+ readonly status?: ThreadAssistantMessage["status"];
157
+ readonly metadata: {
158
+ readonly steps?: ThreadStep[];
159
+ readonly custom: Record<string, unknown>;
160
+ };
161
+ readonly attachments?: ThreadUserMessage["attachments"];
149
162
  };
150
163
 
151
164
  export type ThreadMessage = BaseThreadMessage &
@@ -126,7 +126,7 @@ const AttachmentThumb: FC = () => {
126
126
  );
127
127
  };
128
128
 
129
- const Attachment: FC = () => {
129
+ const AttachmentUI: FC = () => {
130
130
  const canRemove = useAttachment((a) => a.source !== "message");
131
131
  const typeLabel = useAttachment((a) => {
132
132
  const type = a.type;
@@ -165,7 +165,7 @@ const Attachment: FC = () => {
165
165
  );
166
166
  };
167
167
 
168
- Attachment.displayName = "Attachment";
168
+ AttachmentUI.displayName = "Attachment";
169
169
 
170
170
  namespace AttachmentRemove {
171
171
  export type Element = HTMLButtonElement;
@@ -204,5 +204,5 @@ const exports = {
204
204
  Remove: AttachmentRemove,
205
205
  };
206
206
 
207
- export default Object.assign(Attachment, exports) as typeof Attachment &
207
+ export default Object.assign(AttachmentUI, exports) as typeof AttachmentUI &
208
208
  typeof exports;
@@ -12,7 +12,7 @@ import {
12
12
  import { CircleStopIcon } from "./base/CircleStopIcon";
13
13
  import { ComposerPrimitive, ThreadPrimitive } from "../primitives";
14
14
  import { useThread } from "../context/react/ThreadContext";
15
- import Attachment from "./attachment";
15
+ import Attachment from "./attachment-ui";
16
16
 
17
17
  const useAllowAttachments = (ensureCapability = false) => {
18
18
  const { composer: { allowAttachments = true } = {} } = useThreadConfig();
package/src/ui/index.ts CHANGED
@@ -22,7 +22,7 @@ export { default as Composer } from "./composer";
22
22
 
23
23
  export {
24
24
  default as AttachmentUI, // TODO name collision with Attachment
25
- } from "./attachment";
25
+ } from "./attachment-ui";
26
26
 
27
27
  export { default as EditComposer } from "./edit-composer";
28
28
 
@@ -7,7 +7,7 @@ import { withDefaults } from "./utils/withDefaults";
7
7
  import UserActionBar from "./user-action-bar";
8
8
  import ContentPart from "./content-part";
9
9
  import { MessagePrimitive } from "../primitives";
10
- import Attachment from "./attachment";
10
+ import Attachment from "./attachment-ui";
11
11
 
12
12
  const UserMessage: FC = () => {
13
13
  return (
@@ -1 +0,0 @@
1
- {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../src/ui/attachment.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,EAAE,EACR,MAAM,OAAO,CAAC;AAIf,OAAO,EAEL,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AAiHpC,QAAA,MAAM,UAAU,EAAE,EAqCjB,CAAC;AAoCF,QAAA,MAAM,OAAO;;;;;;;CAGZ,CAAC;wBAEmD,OAAO,UAAU,GACpE,OAAO,OAAO;AADhB,wBACiB"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/ui/attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n PropsWithChildren,\n useEffect,\n useState,\n type FC,\n} from \"react\";\nimport { CircleXIcon, FileIcon } from \"lucide-react\";\nimport { withDefaults } from \"./utils/withDefaults\";\nimport { useThreadConfig } from \"./thread-config\";\nimport {\n TooltipIconButton,\n TooltipIconButtonProps,\n} from \"./base/tooltip-icon-button\";\nimport { AttachmentPrimitive } from \"../primitives\";\nimport { useAttachment } from \"../context/react/AttachmentContext\";\nimport {\n AvatarImage,\n AvatarRoot,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./base\";\nimport { Dialog, DialogTrigger, DialogContent } from \"./base/dialog\";\nimport { AvatarFallback } from \"@radix-ui/react-avatar\";\nimport { useShallow } from \"zustand/shallow\";\nimport { DialogTitle } from \"@radix-ui/react-dialog\";\n\nconst AttachmentRoot = withDefaults(AttachmentPrimitive.Root, {\n className: \"aui-attachment-root\",\n});\n\nAttachmentRoot.displayName = \"AttachmentRoot\";\n\nconst useFileSrc = (file: File | undefined) => {\n const [src, setSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!file) {\n setSrc(undefined);\n return;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [file]);\n\n return src;\n};\n\nconst useAttachmentSrc = () => {\n const { file, src } = useAttachment(\n useShallow((a): { file?: File; src?: string } => {\n if (a.type !== \"image\") return {};\n if (a.file) return { file: a.file };\n const src = a.content?.filter((c) => c.type === \"image\")[0]?.image;\n if (!src) return {};\n return { src };\n }),\n );\n\n return useFileSrc(file) ?? src;\n};\n\ntype AttachmentPreviewProps = {\n src: string;\n};\n\nconst AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {\n const [isLoaded, setIsLoaded] = useState(false);\n\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={src}\n style={{\n width: \"auto\",\n height: \"auto\",\n maxWidth: \"75dvh\",\n maxHeight: \"75dvh\",\n display: isLoaded ? \"block\" : \"none\",\n overflow: \"clip\",\n }}\n onLoad={() => setIsLoaded(true)}\n alt=\"Image Preview\"\n />\n );\n};\n\nconst AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {\n const src = useAttachmentSrc();\n\n if (!src) return children;\n\n return (\n <Dialog>\n <DialogTrigger className=\"aui-attachment-preview-trigger\" asChild>\n {children}\n </DialogTrigger>\n <DialogContent>\n <DialogTitle className=\"aui-sr-only\">\n Image Attachment Preview\n </DialogTitle>\n <AttachmentPreview src={src} />\n </DialogContent>\n </Dialog>\n );\n};\n\nconst AttachmentThumb: FC = () => {\n const isImage = useAttachment((a) => a.type === \"image\");\n const src = useAttachmentSrc();\n return (\n <AvatarRoot className=\"aui-attachment-thumb\">\n <AvatarFallback delayMs={isImage ? 200 : 0}>\n <FileIcon />\n </AvatarFallback>\n <AvatarImage src={src}></AvatarImage>\n </AvatarRoot>\n );\n};\n\nconst Attachment: FC = () => {\n const canRemove = useAttachment((a) => a.source !== \"message\");\n const typeLabel = useAttachment((a) => {\n const type = a.type;\n switch (type) {\n case \"image\":\n return \"Image\";\n case \"document\":\n return \"Document\";\n case \"file\":\n return \"File\";\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);\n }\n });\n return (\n <Tooltip>\n <AttachmentPreviewDialog>\n <TooltipTrigger asChild>\n <AttachmentRoot>\n <AttachmentThumb />\n <div className=\"aui-attachment-text\">\n <p className=\"aui-attachment-name\">\n <AttachmentPrimitive.Name />\n </p>\n <p className=\"aui-attachment-type\">{typeLabel}</p>\n </div>\n {canRemove && <AttachmentRemove />}\n </AttachmentRoot>\n </TooltipTrigger>\n </AttachmentPreviewDialog>\n <TooltipContent side=\"top\">\n <AttachmentPrimitive.Name />\n </TooltipContent>\n </Tooltip>\n );\n};\n\nAttachment.displayName = \"Attachment\";\n\nnamespace AttachmentRemove {\n export type Element = HTMLButtonElement;\n export type Props = Partial<TooltipIconButtonProps>;\n}\n\nconst AttachmentRemove = forwardRef<\n AttachmentRemove.Element,\n AttachmentRemove.Props\n>((props, ref) => {\n const {\n strings: {\n composer: { removeAttachment: { tooltip = \"Remove file\" } = {} } = {},\n } = {},\n } = useThreadConfig();\n\n return (\n <AttachmentPrimitive.Remove asChild>\n <TooltipIconButton\n tooltip={tooltip}\n className=\"aui-attachment-remove\"\n side=\"top\"\n {...props}\n ref={ref}\n >\n {props.children ?? <CircleXIcon />}\n </TooltipIconButton>\n </AttachmentPrimitive.Remove>\n );\n});\n\nAttachmentRemove.displayName = \"AttachmentRemove\";\n\nconst exports = {\n Root: AttachmentRoot,\n Remove: AttachmentRemove,\n};\n\nexport default Object.assign(Attachment, exports) as typeof Attachment &\n typeof exports;\n"],"mappings":"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","names":["src","exports"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/ui/attachment.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n PropsWithChildren,\n useEffect,\n useState,\n type FC,\n} from \"react\";\nimport { CircleXIcon, FileIcon } from \"lucide-react\";\nimport { withDefaults } from \"./utils/withDefaults\";\nimport { useThreadConfig } from \"./thread-config\";\nimport {\n TooltipIconButton,\n TooltipIconButtonProps,\n} from \"./base/tooltip-icon-button\";\nimport { AttachmentPrimitive } from \"../primitives\";\nimport { useAttachment } from \"../context/react/AttachmentContext\";\nimport {\n AvatarImage,\n AvatarRoot,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"./base\";\nimport { Dialog, DialogTrigger, DialogContent } from \"./base/dialog\";\nimport { AvatarFallback } from \"@radix-ui/react-avatar\";\nimport { useShallow } from \"zustand/shallow\";\nimport { DialogTitle } from \"@radix-ui/react-dialog\";\n\nconst AttachmentRoot = withDefaults(AttachmentPrimitive.Root, {\n className: \"aui-attachment-root\",\n});\n\nAttachmentRoot.displayName = \"AttachmentRoot\";\n\nconst useFileSrc = (file: File | undefined) => {\n const [src, setSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n if (!file) {\n setSrc(undefined);\n return;\n }\n\n const objectUrl = URL.createObjectURL(file);\n setSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [file]);\n\n return src;\n};\n\nconst useAttachmentSrc = () => {\n const { file, src } = useAttachment(\n useShallow((a): { file?: File; src?: string } => {\n if (a.type !== \"image\") return {};\n if (a.file) return { file: a.file };\n const src = a.content?.filter((c) => c.type === \"image\")[0]?.image;\n if (!src) return {};\n return { src };\n }),\n );\n\n return useFileSrc(file) ?? src;\n};\n\ntype AttachmentPreviewProps = {\n src: string;\n};\n\nconst AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {\n const [isLoaded, setIsLoaded] = useState(false);\n\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={src}\n style={{\n width: \"auto\",\n height: \"auto\",\n maxWidth: \"75dvh\",\n maxHeight: \"75dvh\",\n display: isLoaded ? \"block\" : \"none\",\n overflow: \"clip\",\n }}\n onLoad={() => setIsLoaded(true)}\n alt=\"Image Preview\"\n />\n );\n};\n\nconst AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {\n const src = useAttachmentSrc();\n\n if (!src) return children;\n\n return (\n <Dialog>\n <DialogTrigger className=\"aui-attachment-preview-trigger\" asChild>\n {children}\n </DialogTrigger>\n <DialogContent>\n <DialogTitle className=\"aui-sr-only\">\n Image Attachment Preview\n </DialogTitle>\n <AttachmentPreview src={src} />\n </DialogContent>\n </Dialog>\n );\n};\n\nconst AttachmentThumb: FC = () => {\n const isImage = useAttachment((a) => a.type === \"image\");\n const src = useAttachmentSrc();\n return (\n <AvatarRoot className=\"aui-attachment-thumb\">\n <AvatarFallback delayMs={isImage ? 200 : 0}>\n <FileIcon />\n </AvatarFallback>\n <AvatarImage src={src}></AvatarImage>\n </AvatarRoot>\n );\n};\n\nconst Attachment: FC = () => {\n const canRemove = useAttachment((a) => a.source !== \"message\");\n const typeLabel = useAttachment((a) => {\n const type = a.type;\n switch (type) {\n case \"image\":\n return \"Image\";\n case \"document\":\n return \"Document\";\n case \"file\":\n return \"File\";\n default:\n const _exhaustiveCheck: never = type;\n throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);\n }\n });\n return (\n <Tooltip>\n <AttachmentPreviewDialog>\n <TooltipTrigger asChild>\n <AttachmentRoot>\n <AttachmentThumb />\n <div className=\"aui-attachment-text\">\n <p className=\"aui-attachment-name\">\n <AttachmentPrimitive.Name />\n </p>\n <p className=\"aui-attachment-type\">{typeLabel}</p>\n </div>\n {canRemove && <AttachmentRemove />}\n </AttachmentRoot>\n </TooltipTrigger>\n </AttachmentPreviewDialog>\n <TooltipContent side=\"top\">\n <AttachmentPrimitive.Name />\n </TooltipContent>\n </Tooltip>\n );\n};\n\nAttachment.displayName = \"Attachment\";\n\nnamespace AttachmentRemove {\n export type Element = HTMLButtonElement;\n export type Props = Partial<TooltipIconButtonProps>;\n}\n\nconst AttachmentRemove = forwardRef<\n AttachmentRemove.Element,\n AttachmentRemove.Props\n>((props, ref) => {\n const {\n strings: {\n composer: { removeAttachment: { tooltip = \"Remove file\" } = {} } = {},\n } = {},\n } = useThreadConfig();\n\n return (\n <AttachmentPrimitive.Remove asChild>\n <TooltipIconButton\n tooltip={tooltip}\n className=\"aui-attachment-remove\"\n side=\"top\"\n {...props}\n ref={ref}\n >\n {props.children ?? <CircleXIcon />}\n </TooltipIconButton>\n </AttachmentPrimitive.Remove>\n );\n});\n\nAttachmentRemove.displayName = \"AttachmentRemove\";\n\nconst exports = {\n Root: AttachmentRoot,\n Remove: AttachmentRemove,\n};\n\nexport default Object.assign(Attachment, exports) as typeof Attachment &\n typeof exports;\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,aAAa,gBAAgB;AACtC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,OAEK;AACP,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,QAAQ,eAAe,qBAAqB;AACrD,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAmDxB,cA0BE,YA1BF;AAjDJ,IAAM,iBAAiB,aAAa,oBAAoB,MAAM;AAAA,EAC5D,WAAW;AACb,CAAC;AAED,eAAe,cAAc;AAE7B,IAAM,aAAa,CAAC,SAA2B;AAC7C,QAAM,CAAC,KAAK,MAAM,IAAI,SAA6B,MAAS;AAE5D,YAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,aAAO,MAAS;AAChB;AAAA,IACF;AAEA,UAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,WAAO,SAAS;AAEhB,WAAO,MAAM;AACX,UAAI,gBAAgB,SAAS;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,SAAO;AACT;AAEA,IAAM,mBAAmB,MAAM;AAC7B,QAAM,EAAE,MAAM,IAAI,IAAI;AAAA,IACpB,WAAW,CAAC,MAAqC;AAC/C,UAAI,EAAE,SAAS,QAAS,QAAO,CAAC;AAChC,UAAI,EAAE,KAAM,QAAO,EAAE,MAAM,EAAE,KAAK;AAClC,YAAMA,OAAM,EAAE,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC,GAAG;AAC7D,UAAI,CAACA,KAAK,QAAO,CAAC;AAClB,aAAO,EAAE,KAAAA,KAAI;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO,WAAW,IAAI,KAAK;AAC7B;AAMA,IAAM,oBAAgD,CAAC,EAAE,IAAI,MAAM;AACjE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C;AAAA;AAAA,IAEE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,WAAW;AAAA,UACX,SAAS,WAAW,UAAU;AAAA,UAC9B,UAAU;AAAA,QACZ;AAAA,QACA,QAAQ,MAAM,YAAY,IAAI;AAAA,QAC9B,KAAI;AAAA;AAAA,IACN;AAAA;AAEJ;AAEA,IAAM,0BAAiD,CAAC,EAAE,SAAS,MAAM;AACvE,QAAM,MAAM,iBAAiB;AAE7B,MAAI,CAAC,IAAK,QAAO;AAEjB,SACE,qBAAC,UACC;AAAA,wBAAC,iBAAc,WAAU,kCAAiC,SAAO,MAC9D,UACH;AAAA,IACA,qBAAC,iBACC;AAAA,0BAAC,eAAY,WAAU,eAAc,sCAErC;AAAA,MACA,oBAAC,qBAAkB,KAAU;AAAA,OAC/B;AAAA,KACF;AAEJ;AAEA,IAAM,kBAAsB,MAAM;AAChC,QAAM,UAAU,cAAc,CAAC,MAAM,EAAE,SAAS,OAAO;AACvD,QAAM,MAAM,iBAAiB;AAC7B,SACE,qBAAC,cAAW,WAAU,wBACpB;AAAA,wBAAC,kBAAe,SAAS,UAAU,MAAM,GACvC,8BAAC,YAAS,GACZ;AAAA,IACA,oBAAC,eAAY,KAAU;AAAA,KACzB;AAEJ;AAEA,IAAM,aAAiB,MAAM;AAC3B,QAAM,YAAY,cAAc,CAAC,MAAM,EAAE,WAAW,SAAS;AAC7D,QAAM,YAAY,cAAc,CAAC,MAAM;AACrC,UAAM,OAAO,EAAE;AACf,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,cAAM,mBAA0B;AAChC,cAAM,IAAI,MAAM,4BAA4B,gBAAgB,EAAE;AAAA,IAClE;AAAA,EACF,CAAC;AACD,SACE,qBAAC,WACC;AAAA,wBAAC,2BACC,8BAAC,kBAAe,SAAO,MACrB,+BAAC,kBACC;AAAA,0BAAC,mBAAgB;AAAA,MACjB,qBAAC,SAAI,WAAU,uBACb;AAAA,4BAAC,OAAE,WAAU,uBACX,8BAAC,oBAAoB,MAApB,EAAyB,GAC5B;AAAA,QACA,oBAAC,OAAE,WAAU,uBAAuB,qBAAU;AAAA,SAChD;AAAA,MACC,aAAa,oBAAC,oBAAiB;AAAA,OAClC,GACF,GACF;AAAA,IACA,oBAAC,kBAAe,MAAK,OACnB,8BAAC,oBAAoB,MAApB,EAAyB,GAC5B;AAAA,KACF;AAEJ;AAEA,WAAW,cAAc;AAOzB,IAAM,mBAAmB,WAGvB,CAAC,OAAO,QAAQ;AAChB,QAAM;AAAA,IACJ,SAAS;AAAA,MACP,UAAU,EAAE,kBAAkB,EAAE,UAAU,cAAc,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,IACtE,IAAI,CAAC;AAAA,EACP,IAAI,gBAAgB;AAEpB,SACE,oBAAC,oBAAoB,QAApB,EAA2B,SAAO,MACjC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACJ,GAAG;AAAA,MACJ;AAAA,MAEC,gBAAM,YAAY,oBAAC,eAAY;AAAA;AAAA,EAClC,GACF;AAEJ,CAAC;AAED,iBAAiB,cAAc;AAE/B,IAAM,UAAU;AAAA,EACd,MAAM;AAAA,EACN,QAAQ;AACV;AAEA,IAAO,qBAAQ,OAAO,OAAO,YAAY,OAAO;","names":["src"]}