@liveblocks/react-ui 3.8.0 → 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/_private/index.cjs +2 -0
- package/dist/_private/index.cjs.map +1 -1
- package/dist/_private/index.d.cts +7 -1
- package/dist/_private/index.d.ts +7 -1
- package/dist/_private/index.js +1 -0
- package/dist/_private/index.js.map +1 -1
- package/dist/components/AiChat.cjs +19 -4
- package/dist/components/AiChat.cjs.map +1 -1
- package/dist/components/AiChat.js +20 -5
- package/dist/components/AiChat.js.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.cjs +200 -39
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +195 -34
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiComposer.cjs +1 -3
- package/dist/components/internal/AiComposer.cjs.map +1 -1
- package/dist/components/internal/AiComposer.js +1 -3
- package/dist/components/internal/AiComposer.js.map +1 -1
- package/dist/components/internal/Favicon.cjs +26 -0
- package/dist/components/internal/Favicon.cjs.map +1 -0
- package/dist/components/internal/Favicon.js +24 -0
- package/dist/components/internal/Favicon.js.map +1 -0
- package/dist/icon.cjs +2 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +1 -0
- package/dist/icon.js.map +1 -1
- package/dist/icons/Globe.cjs +23 -0
- package/dist/icons/Globe.cjs.map +1 -0
- package/dist/icons/Globe.js +21 -0
- package/dist/icons/Globe.js.map +1 -0
- package/dist/icons/index.cjs +2 -0
- package/dist/icons/index.cjs.map +1 -1
- package/dist/icons/index.js +1 -0
- package/dist/icons/index.js.map +1 -1
- package/dist/index.d.cts +51 -2
- package/dist/index.d.ts +51 -2
- package/dist/overrides.cjs +79 -28
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.js +79 -28
- package/dist/overrides.js.map +1 -1
- package/dist/primitives/AiComposer/index.cjs +6 -2
- package/dist/primitives/AiComposer/index.cjs.map +1 -1
- package/dist/primitives/AiComposer/index.js +6 -2
- package/dist/primitives/AiComposer/index.js.map +1 -1
- package/dist/primitives/AiMessage/index.cjs +16 -2
- package/dist/primitives/AiMessage/index.cjs.map +1 -1
- package/dist/primitives/AiMessage/index.js +16 -2
- package/dist/primitives/AiMessage/index.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/src/styles/index.css +162 -54
- package/styles.css +1 -1
- package/styles.css.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiComposer/index.tsx"],"sourcesContent":["import {\n type AiChatMessage,\n kInternal,\n Signal,\n type WithNavigation,\n} from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect, useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FocusEvent, FormEvent, KeyboardEvent, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport {\n Editable,\n ReactEditor,\n type RenderPlaceholderProps,\n Slate,\n withReact,\n} from \"slate-react\";\n\nimport type { AiComposerBody } from \"../../types\";\nimport { requestSubmit } from \"../../utils/request-submit\";\nimport { useInitial } from \"../../utils/use-initial\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport {\n AiComposerContext,\n AiComposerEditorContext,\n useAiComposer,\n useAiComposerEditorContext,\n} from \"./contexts\";\nimport type {\n AiComposerEditorProps,\n AiComposerFormProps,\n AiComposerSubmitProps,\n} from \"./types\";\n\nconst AI_COMPOSER_SUBMIT_NAME = \"AiComposerSubmit\";\nconst AI_COMPOSER_ABORT_NAME = \"AiComposerAbort\";\nconst AI_COMPOSER_EDITOR_NAME = \"AiComposerEditor\";\nconst AI_COMPOSER_FORM_NAME = \"AiComposerForm\";\n\ntype UiChatMessage = WithNavigation<AiChatMessage>;\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst emptyMessagesΣ = new Signal<UiChatMessage[]>([]);\n\nfunction getLastMessageId(messages: UiChatMessage[]) {\n const lastMessage = messages[messages.length - 1];\n\n if (lastMessage === undefined) {\n return null;\n }\n\n return lastMessage.id;\n}\n\nfunction getAbortableMessageId(messages: UiChatMessage[]) {\n return messages.find(\n (message) =>\n message.role === \"assistant\" &&\n (message.status === \"generating\" || message.status === \"awaiting-tool\")\n )?.id;\n}\n\n/**\n * Surrounds the AI composer's content and handles submissions.\n *\n * @example\n * <AiComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiComposer.Editor />\n * <AiComposer.Submit />\n * </AiComposer.Form>\n */\nexport const AiComposerForm = forwardRef<HTMLFormElement, AiComposerFormProps>(\n (\n {\n onComposerSubmit,\n onSubmit,\n disabled,\n chatId,\n branchId,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const client = useClient();\n const formRef = useRef<HTMLFormElement | null>(null);\n const editor = useInitial(() =>\n withNormalize(withHistory(withReact(createEditor())))\n );\n const [isEditorEmpty, setEditorEmpty] = useState(true);\n const [isSubmitting, setSubmitting] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const messagesΣ = chatId\n ? client[kInternal].ai.signals.getChatMessagesForBranchΣ(chatId, branchId)\n : emptyMessagesΣ;\n const lastMessageId = useSignal(messagesΣ, getLastMessageId);\n const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId);\n\n const isDisabled = isSubmitting || disabled === true;\n const canAbort = abortableMessageId !== undefined;\n const canSubmit = !isEditorEmpty && !canAbort;\n\n const clear = useCallback(() => {\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n }, [editor]);\n\n const select = useCallback(() => {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n }, [editor]);\n\n const focus = useCallback(\n (resetSelection = true) => {\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(\n editor,\n resetSelection || !editor.selection\n ? SlateEditor.end(editor, [])\n : editor.selection\n );\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n },\n [editor]\n );\n\n const blur = useCallback(() => {\n try {\n ReactEditor.blur(editor);\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n }, [editor]);\n\n const onSubmitEnd = useCallback(() => {\n clear();\n setSubmitting(false);\n }, [clear]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled) {\n return;\n }\n\n // In some situations (e.g. pressing Enter while composing diacritics), it's possible\n // for the form to be submitted as empty even though we already checked whether the\n // editor was empty when handling the key press.\n const isEditorEmpty = isEmpty(editor, editor.children);\n\n // We even prevent the user's `onSubmit` handler from being called if the editor is empty.\n if (isEditorEmpty) {\n event.preventDefault();\n\n return;\n }\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n const promise = onComposerSubmit(\n { text: content, lastMessageId },\n event\n );\n\n event.preventDefault();\n\n if (promise) {\n setSubmitting(true);\n promise.then(onSubmitEnd);\n } else {\n onSubmitEnd();\n }\n },\n [disabled, editor, onSubmit, onComposerSubmit, onSubmitEnd, lastMessageId]\n );\n\n useLayoutEffect(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const submit = useCallback(() => {\n if (!canSubmit) {\n return;\n }\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current) {\n requestSubmit(formRef.current);\n }\n });\n }, [canSubmit]);\n\n const abort = useCallback(() => {\n if (!canAbort || !abortableMessageId) {\n return;\n }\n\n client[kInternal].ai.abort(abortableMessageId);\n }, [canAbort, abortableMessageId, client]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiComposerEditorContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n abortableMessageId,\n setFocused,\n }}\n >\n <AiComposerContext.Provider\n value={{\n isDisabled,\n isEmpty: isEditorEmpty,\n isFocused,\n canSubmit,\n canAbort,\n submit,\n abort,\n clear,\n focus,\n blur,\n select,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiComposerContext.Provider>\n </AiComposerEditorContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\nfunction AiComposerEditorPlaceholder({\n attributes,\n children,\n}: RenderPlaceholderProps) {\n const { opacity: _opacity, ...style } = attributes.style;\n\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n}\n\n/**\n * Displays the AI composer's editor.\n *\n * @example\n * <AiComposer.Editor placeholder=\"Write a message…\" />\n */\nconst AiComposerEditor = forwardRef<HTMLDivElement, AiComposerEditorProps>(\n (\n {\n defaultValue = \"\",\n onKeyDown,\n onFocus,\n onBlur,\n disabled,\n autoFocus,\n dir,\n ...props\n },\n forwardedRef\n ) => {\n const { editor, onEditorValueChange, setFocused } =\n useAiComposerEditorContext();\n const {\n submit,\n isDisabled: isComposerDisabled,\n isFocused,\n focus,\n blur,\n select,\n } = useAiComposer();\n const isDisabled = disabled || isComposerDisabled;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n } else if (event.key === \"Escape\") {\n blur();\n }\n },\n [editor, onKeyDown, submit, blur]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus, setFocused]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(false);\n }\n },\n [onBlur, setFocused]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n // Manually focus the editor when `autoFocus` is true\n useLayoutEffect(() => {\n if (autoFocus) {\n focus();\n }\n }, [autoFocus, editor, focus]);\n\n // Manually add a selection in the editor if the selection\n // is still empty after being focused\n useLayoutEffect(() => {\n if (isFocused && editor.selection === null) {\n select();\n }\n }, [editor, select, isFocused]);\n\n const initialValue: AiComposerBody = useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n dir={dir}\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n aria-label=\"Composer editor\"\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-focused={isFocused || undefined}\n data-disabled={isDisabled || undefined}\n {...props}\n readOnly={isDisabled}\n disabled={isDisabled}\n renderPlaceholder={AiComposerEditorPlaceholder}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit the AI composer's content.\n *\n * @example\n * <AiComposer.Submit>Send</AiComposer.Submit>\n */\nexport const AiComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canSubmit } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canSubmit;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n />\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Abort\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to abort a response related to the AI composer.\n *\n * @example\n * <AiComposer.Abort>Cancel</AiComposer.Abort>\n */\nexport const AiComposerAbort = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canAbort, abort } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canAbort;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n abort();\n },\n [abort, onClick]\n );\n\n return (\n <Component\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n onClick={handleClick}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiComposerEditor.displayName = AI_COMPOSER_EDITOR_NAME;\n AiComposerForm.displayName = AI_COMPOSER_FORM_NAME;\n AiComposerSubmit.displayName = AI_COMPOSER_SUBMIT_NAME;\n AiComposerAbort.displayName = AI_COMPOSER_ABORT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiComposer.*\nexport {\n AiComposerAbort as Abort,\n AiComposerEditor as Editor,\n AiComposerForm as Form,\n AiComposerSubmit as Submit,\n};\n"],"names":["Signal","forwardRef","Slot","useClient","useRef","useInitial","withNormalize","withHistory","withReact","createEditor","useState","kInternal","useSignal","useCallback","SlateTransforms","SlateEditor","ReactEditor","isEditorEmpty","isEmpty","useLayoutEffect","requestSubmit","useImperativeHandle","jsx","AiComposerEditorContext","AiComposerContext","useAiComposerEditorContext","useAiComposer","useMemo","Slate","Editable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiComposer/index.tsx"],"sourcesContent":["import {\n type AiChatMessage,\n kInternal,\n Signal,\n type WithNavigation,\n} from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect, useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FocusEvent, FormEvent, KeyboardEvent, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport {\n Editable,\n ReactEditor,\n type RenderPlaceholderProps,\n Slate,\n withReact,\n} from \"slate-react\";\n\nimport type { AiComposerBody } from \"../../types\";\nimport { requestSubmit } from \"../../utils/request-submit\";\nimport { useInitial } from \"../../utils/use-initial\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport {\n AiComposerContext,\n AiComposerEditorContext,\n useAiComposer,\n useAiComposerEditorContext,\n} from \"./contexts\";\nimport type {\n AiComposerEditorProps,\n AiComposerFormProps,\n AiComposerSubmitProps,\n} from \"./types\";\n\nconst AI_COMPOSER_SUBMIT_NAME = \"AiComposerSubmit\";\nconst AI_COMPOSER_ABORT_NAME = \"AiComposerAbort\";\nconst AI_COMPOSER_EDITOR_NAME = \"AiComposerEditor\";\nconst AI_COMPOSER_FORM_NAME = \"AiComposerForm\";\n\ntype UiChatMessage = WithNavigation<AiChatMessage>;\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst emptyMessagesΣ = new Signal<UiChatMessage[]>([]);\n\nfunction getLastMessageId(messages: UiChatMessage[]) {\n const lastMessage = messages[messages.length - 1];\n\n if (lastMessage === undefined) {\n return null;\n }\n\n return lastMessage.id;\n}\n\nfunction getAbortableMessageId(messages: UiChatMessage[]) {\n return messages.find(\n (message) =>\n message.role === \"assistant\" &&\n (message.status === \"generating\" || message.status === \"awaiting-tool\")\n )?.id;\n}\n\n/**\n * Surrounds the AI composer's content and handles submissions.\n *\n * @example\n * <AiComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiComposer.Editor />\n * <AiComposer.Submit />\n * </AiComposer.Form>\n */\nexport const AiComposerForm = forwardRef<HTMLFormElement, AiComposerFormProps>(\n (\n {\n onComposerSubmit,\n onSubmit,\n disabled,\n chatId,\n branchId,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const client = useClient();\n const formRef = useRef<HTMLFormElement | null>(null);\n const editor = useInitial(() =>\n withNormalize(withHistory(withReact(createEditor())))\n );\n const [isEditorEmpty, setEditorEmpty] = useState(true);\n const [isSubmitting, setSubmitting] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const messagesΣ = chatId\n ? client[kInternal].ai.signals.getChatMessagesForBranchΣ(chatId, branchId)\n : emptyMessagesΣ;\n const lastMessageId = useSignal(messagesΣ, getLastMessageId);\n const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId);\n const isAvailable = useSignal(\n // Subscribe to connection status signal\n client[kInternal].ai.signals.statusΣ,\n // \"Disconnected\" means the AI service is not available\n // as it represents a final error status.\n (status) => status !== \"disconnected\"\n );\n\n const isDisabled = isSubmitting || disabled === true;\n\n const canAbort = isAvailable && abortableMessageId !== undefined;\n const canSubmit = isAvailable && !isEditorEmpty && !canAbort;\n\n const clear = useCallback(() => {\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n }, [editor]);\n\n const select = useCallback(() => {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n }, [editor]);\n\n const focus = useCallback(\n (resetSelection = true) => {\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(\n editor,\n resetSelection || !editor.selection\n ? SlateEditor.end(editor, [])\n : editor.selection\n );\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n },\n [editor]\n );\n\n const blur = useCallback(() => {\n try {\n ReactEditor.blur(editor);\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n }, [editor]);\n\n const onSubmitEnd = useCallback(() => {\n clear();\n setSubmitting(false);\n }, [clear]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled) {\n return;\n }\n\n // In some situations (e.g. pressing Enter while composing diacritics), it's possible\n // for the form to be submitted as empty even though we already checked whether the\n // editor was empty when handling the key press.\n const isEditorEmpty = isEmpty(editor, editor.children);\n\n // We even prevent the user's `onSubmit` handler from being called if the editor is empty.\n if (isEditorEmpty) {\n event.preventDefault();\n\n return;\n }\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n const promise = onComposerSubmit(\n { text: content, lastMessageId },\n event\n );\n\n event.preventDefault();\n\n if (promise) {\n setSubmitting(true);\n promise.then(onSubmitEnd);\n } else {\n onSubmitEnd();\n }\n },\n [disabled, editor, onSubmit, onComposerSubmit, onSubmitEnd, lastMessageId]\n );\n\n useLayoutEffect(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const submit = useCallback(() => {\n if (!canSubmit) {\n return;\n }\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current) {\n requestSubmit(formRef.current);\n }\n });\n }, [canSubmit]);\n\n const abort = useCallback(() => {\n if (!canAbort || !abortableMessageId) {\n return;\n }\n\n client[kInternal].ai.abort(abortableMessageId);\n }, [canAbort, abortableMessageId, client]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiComposerEditorContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n abortableMessageId,\n setFocused,\n }}\n >\n <AiComposerContext.Provider\n value={{\n isDisabled,\n isEmpty: isEditorEmpty,\n isFocused,\n canSubmit,\n canAbort,\n submit,\n abort,\n clear,\n focus,\n blur,\n select,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiComposerContext.Provider>\n </AiComposerEditorContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\nfunction AiComposerEditorPlaceholder({\n attributes,\n children,\n}: RenderPlaceholderProps) {\n const { opacity: _opacity, ...style } = attributes.style;\n\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n}\n\n/**\n * Displays the AI composer's editor.\n *\n * @example\n * <AiComposer.Editor placeholder=\"Write a message…\" />\n */\nconst AiComposerEditor = forwardRef<HTMLDivElement, AiComposerEditorProps>(\n (\n {\n defaultValue = \"\",\n onKeyDown,\n onFocus,\n onBlur,\n disabled,\n autoFocus,\n dir,\n ...props\n },\n forwardedRef\n ) => {\n const { editor, onEditorValueChange, setFocused } =\n useAiComposerEditorContext();\n const {\n submit,\n isDisabled: isComposerDisabled,\n isFocused,\n focus,\n blur,\n select,\n } = useAiComposer();\n const isDisabled = disabled || isComposerDisabled;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n } else if (event.key === \"Escape\") {\n blur();\n }\n },\n [editor, onKeyDown, submit, blur]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus, setFocused]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(false);\n }\n },\n [onBlur, setFocused]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n // Manually focus the editor when `autoFocus` is true\n useLayoutEffect(() => {\n if (autoFocus) {\n focus();\n }\n }, [autoFocus, editor, focus]);\n\n // Manually add a selection in the editor if the selection\n // is still empty after being focused\n useLayoutEffect(() => {\n if (isFocused && editor.selection === null) {\n select();\n }\n }, [editor, select, isFocused]);\n\n const initialValue: AiComposerBody = useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n dir={dir}\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n aria-label=\"Composer editor\"\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-focused={isFocused || undefined}\n data-disabled={isDisabled || undefined}\n {...props}\n readOnly={isDisabled}\n disabled={isDisabled}\n renderPlaceholder={AiComposerEditorPlaceholder}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit the AI composer's content.\n *\n * @example\n * <AiComposer.Submit>Send</AiComposer.Submit>\n */\nexport const AiComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canSubmit } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canSubmit;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n />\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Abort\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to abort a response related to the AI composer.\n *\n * @example\n * <AiComposer.Abort>Cancel</AiComposer.Abort>\n */\nexport const AiComposerAbort = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canAbort, abort } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canAbort;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n abort();\n },\n [abort, onClick]\n );\n\n return (\n <Component\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n onClick={handleClick}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiComposerEditor.displayName = AI_COMPOSER_EDITOR_NAME;\n AiComposerForm.displayName = AI_COMPOSER_FORM_NAME;\n AiComposerSubmit.displayName = AI_COMPOSER_SUBMIT_NAME;\n AiComposerAbort.displayName = AI_COMPOSER_ABORT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiComposer.*\nexport {\n AiComposerAbort as Abort,\n AiComposerEditor as Editor,\n AiComposerForm as Form,\n AiComposerSubmit as Submit,\n};\n"],"names":["Signal","forwardRef","Slot","useClient","useRef","useInitial","withNormalize","withHistory","withReact","createEditor","useState","kInternal","useSignal","useCallback","SlateTransforms","SlateEditor","ReactEditor","isEditorEmpty","isEmpty","useLayoutEffect","requestSubmit","useImperativeHandle","jsx","AiComposerEditorContext","AiComposerContext","useAiComposerEditorContext","useAiComposer","useMemo","Slate","Editable"],"mappings":"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"}
|
|
@@ -52,9 +52,13 @@ const AiComposerForm = forwardRef(
|
|
|
52
52
|
const messages\u03A3 = chatId ? client[kInternal].ai.signals.getChatMessagesForBranch\u03A3(chatId, branchId) : emptyMessages\u03A3;
|
|
53
53
|
const lastMessageId = useSignal(messages\u03A3, getLastMessageId);
|
|
54
54
|
const abortableMessageId = useSignal(messages\u03A3, getAbortableMessageId);
|
|
55
|
+
const isAvailable = useSignal(
|
|
56
|
+
client[kInternal].ai.signals.status\u03A3,
|
|
57
|
+
(status) => status !== "disconnected"
|
|
58
|
+
);
|
|
55
59
|
const isDisabled = isSubmitting || disabled === true;
|
|
56
|
-
const canAbort = abortableMessageId !== void 0;
|
|
57
|
-
const canSubmit = !isEditorEmpty && !canAbort;
|
|
60
|
+
const canAbort = isAvailable && abortableMessageId !== void 0;
|
|
61
|
+
const canSubmit = isAvailable && !isEditorEmpty && !canAbort;
|
|
58
62
|
const clear = useCallback(() => {
|
|
59
63
|
Transforms.delete(editor, {
|
|
60
64
|
at: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiComposer/index.tsx"],"sourcesContent":["import {\n type AiChatMessage,\n kInternal,\n Signal,\n type WithNavigation,\n} from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect, useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FocusEvent, FormEvent, KeyboardEvent, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport {\n Editable,\n ReactEditor,\n type RenderPlaceholderProps,\n Slate,\n withReact,\n} from \"slate-react\";\n\nimport type { AiComposerBody } from \"../../types\";\nimport { requestSubmit } from \"../../utils/request-submit\";\nimport { useInitial } from \"../../utils/use-initial\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport {\n AiComposerContext,\n AiComposerEditorContext,\n useAiComposer,\n useAiComposerEditorContext,\n} from \"./contexts\";\nimport type {\n AiComposerEditorProps,\n AiComposerFormProps,\n AiComposerSubmitProps,\n} from \"./types\";\n\nconst AI_COMPOSER_SUBMIT_NAME = \"AiComposerSubmit\";\nconst AI_COMPOSER_ABORT_NAME = \"AiComposerAbort\";\nconst AI_COMPOSER_EDITOR_NAME = \"AiComposerEditor\";\nconst AI_COMPOSER_FORM_NAME = \"AiComposerForm\";\n\ntype UiChatMessage = WithNavigation<AiChatMessage>;\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst emptyMessagesΣ = new Signal<UiChatMessage[]>([]);\n\nfunction getLastMessageId(messages: UiChatMessage[]) {\n const lastMessage = messages[messages.length - 1];\n\n if (lastMessage === undefined) {\n return null;\n }\n\n return lastMessage.id;\n}\n\nfunction getAbortableMessageId(messages: UiChatMessage[]) {\n return messages.find(\n (message) =>\n message.role === \"assistant\" &&\n (message.status === \"generating\" || message.status === \"awaiting-tool\")\n )?.id;\n}\n\n/**\n * Surrounds the AI composer's content and handles submissions.\n *\n * @example\n * <AiComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiComposer.Editor />\n * <AiComposer.Submit />\n * </AiComposer.Form>\n */\nexport const AiComposerForm = forwardRef<HTMLFormElement, AiComposerFormProps>(\n (\n {\n onComposerSubmit,\n onSubmit,\n disabled,\n chatId,\n branchId,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const client = useClient();\n const formRef = useRef<HTMLFormElement | null>(null);\n const editor = useInitial(() =>\n withNormalize(withHistory(withReact(createEditor())))\n );\n const [isEditorEmpty, setEditorEmpty] = useState(true);\n const [isSubmitting, setSubmitting] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const messagesΣ = chatId\n ? client[kInternal].ai.signals.getChatMessagesForBranchΣ(chatId, branchId)\n : emptyMessagesΣ;\n const lastMessageId = useSignal(messagesΣ, getLastMessageId);\n const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId);\n\n const isDisabled = isSubmitting || disabled === true;\n const canAbort = abortableMessageId !== undefined;\n const canSubmit = !isEditorEmpty && !canAbort;\n\n const clear = useCallback(() => {\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n }, [editor]);\n\n const select = useCallback(() => {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n }, [editor]);\n\n const focus = useCallback(\n (resetSelection = true) => {\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(\n editor,\n resetSelection || !editor.selection\n ? SlateEditor.end(editor, [])\n : editor.selection\n );\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n },\n [editor]\n );\n\n const blur = useCallback(() => {\n try {\n ReactEditor.blur(editor);\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n }, [editor]);\n\n const onSubmitEnd = useCallback(() => {\n clear();\n setSubmitting(false);\n }, [clear]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled) {\n return;\n }\n\n // In some situations (e.g. pressing Enter while composing diacritics), it's possible\n // for the form to be submitted as empty even though we already checked whether the\n // editor was empty when handling the key press.\n const isEditorEmpty = isEmpty(editor, editor.children);\n\n // We even prevent the user's `onSubmit` handler from being called if the editor is empty.\n if (isEditorEmpty) {\n event.preventDefault();\n\n return;\n }\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n const promise = onComposerSubmit(\n { text: content, lastMessageId },\n event\n );\n\n event.preventDefault();\n\n if (promise) {\n setSubmitting(true);\n promise.then(onSubmitEnd);\n } else {\n onSubmitEnd();\n }\n },\n [disabled, editor, onSubmit, onComposerSubmit, onSubmitEnd, lastMessageId]\n );\n\n useLayoutEffect(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const submit = useCallback(() => {\n if (!canSubmit) {\n return;\n }\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current) {\n requestSubmit(formRef.current);\n }\n });\n }, [canSubmit]);\n\n const abort = useCallback(() => {\n if (!canAbort || !abortableMessageId) {\n return;\n }\n\n client[kInternal].ai.abort(abortableMessageId);\n }, [canAbort, abortableMessageId, client]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiComposerEditorContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n abortableMessageId,\n setFocused,\n }}\n >\n <AiComposerContext.Provider\n value={{\n isDisabled,\n isEmpty: isEditorEmpty,\n isFocused,\n canSubmit,\n canAbort,\n submit,\n abort,\n clear,\n focus,\n blur,\n select,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiComposerContext.Provider>\n </AiComposerEditorContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\nfunction AiComposerEditorPlaceholder({\n attributes,\n children,\n}: RenderPlaceholderProps) {\n const { opacity: _opacity, ...style } = attributes.style;\n\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n}\n\n/**\n * Displays the AI composer's editor.\n *\n * @example\n * <AiComposer.Editor placeholder=\"Write a message…\" />\n */\nconst AiComposerEditor = forwardRef<HTMLDivElement, AiComposerEditorProps>(\n (\n {\n defaultValue = \"\",\n onKeyDown,\n onFocus,\n onBlur,\n disabled,\n autoFocus,\n dir,\n ...props\n },\n forwardedRef\n ) => {\n const { editor, onEditorValueChange, setFocused } =\n useAiComposerEditorContext();\n const {\n submit,\n isDisabled: isComposerDisabled,\n isFocused,\n focus,\n blur,\n select,\n } = useAiComposer();\n const isDisabled = disabled || isComposerDisabled;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n } else if (event.key === \"Escape\") {\n blur();\n }\n },\n [editor, onKeyDown, submit, blur]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus, setFocused]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(false);\n }\n },\n [onBlur, setFocused]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n // Manually focus the editor when `autoFocus` is true\n useLayoutEffect(() => {\n if (autoFocus) {\n focus();\n }\n }, [autoFocus, editor, focus]);\n\n // Manually add a selection in the editor if the selection\n // is still empty after being focused\n useLayoutEffect(() => {\n if (isFocused && editor.selection === null) {\n select();\n }\n }, [editor, select, isFocused]);\n\n const initialValue: AiComposerBody = useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n dir={dir}\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n aria-label=\"Composer editor\"\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-focused={isFocused || undefined}\n data-disabled={isDisabled || undefined}\n {...props}\n readOnly={isDisabled}\n disabled={isDisabled}\n renderPlaceholder={AiComposerEditorPlaceholder}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit the AI composer's content.\n *\n * @example\n * <AiComposer.Submit>Send</AiComposer.Submit>\n */\nexport const AiComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canSubmit } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canSubmit;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n />\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Abort\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to abort a response related to the AI composer.\n *\n * @example\n * <AiComposer.Abort>Cancel</AiComposer.Abort>\n */\nexport const AiComposerAbort = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canAbort, abort } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canAbort;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n abort();\n },\n [abort, onClick]\n );\n\n return (\n <Component\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n onClick={handleClick}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiComposerEditor.displayName = AI_COMPOSER_EDITOR_NAME;\n AiComposerForm.displayName = AI_COMPOSER_FORM_NAME;\n AiComposerSubmit.displayName = AI_COMPOSER_SUBMIT_NAME;\n AiComposerAbort.displayName = AI_COMPOSER_ABORT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiComposer.*\nexport {\n AiComposerAbort as Abort,\n AiComposerEditor as Editor,\n AiComposerForm as Form,\n AiComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor","isEditorEmpty"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiComposer/index.tsx"],"sourcesContent":["import {\n type AiChatMessage,\n kInternal,\n Signal,\n type WithNavigation,\n} from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect, useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FocusEvent, FormEvent, KeyboardEvent, MouseEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport {\n Editable,\n ReactEditor,\n type RenderPlaceholderProps,\n Slate,\n withReact,\n} from \"slate-react\";\n\nimport type { AiComposerBody } from \"../../types\";\nimport { requestSubmit } from \"../../utils/request-submit\";\nimport { useInitial } from \"../../utils/use-initial\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport {\n AiComposerContext,\n AiComposerEditorContext,\n useAiComposer,\n useAiComposerEditorContext,\n} from \"./contexts\";\nimport type {\n AiComposerEditorProps,\n AiComposerFormProps,\n AiComposerSubmitProps,\n} from \"./types\";\n\nconst AI_COMPOSER_SUBMIT_NAME = \"AiComposerSubmit\";\nconst AI_COMPOSER_ABORT_NAME = \"AiComposerAbort\";\nconst AI_COMPOSER_EDITOR_NAME = \"AiComposerEditor\";\nconst AI_COMPOSER_FORM_NAME = \"AiComposerForm\";\n\ntype UiChatMessage = WithNavigation<AiChatMessage>;\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\nconst emptyMessagesΣ = new Signal<UiChatMessage[]>([]);\n\nfunction getLastMessageId(messages: UiChatMessage[]) {\n const lastMessage = messages[messages.length - 1];\n\n if (lastMessage === undefined) {\n return null;\n }\n\n return lastMessage.id;\n}\n\nfunction getAbortableMessageId(messages: UiChatMessage[]) {\n return messages.find(\n (message) =>\n message.role === \"assistant\" &&\n (message.status === \"generating\" || message.status === \"awaiting-tool\")\n )?.id;\n}\n\n/**\n * Surrounds the AI composer's content and handles submissions.\n *\n * @example\n * <AiComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiComposer.Editor />\n * <AiComposer.Submit />\n * </AiComposer.Form>\n */\nexport const AiComposerForm = forwardRef<HTMLFormElement, AiComposerFormProps>(\n (\n {\n onComposerSubmit,\n onSubmit,\n disabled,\n chatId,\n branchId,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const client = useClient();\n const formRef = useRef<HTMLFormElement | null>(null);\n const editor = useInitial(() =>\n withNormalize(withHistory(withReact(createEditor())))\n );\n const [isEditorEmpty, setEditorEmpty] = useState(true);\n const [isSubmitting, setSubmitting] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const messagesΣ = chatId\n ? client[kInternal].ai.signals.getChatMessagesForBranchΣ(chatId, branchId)\n : emptyMessagesΣ;\n const lastMessageId = useSignal(messagesΣ, getLastMessageId);\n const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId);\n const isAvailable = useSignal(\n // Subscribe to connection status signal\n client[kInternal].ai.signals.statusΣ,\n // \"Disconnected\" means the AI service is not available\n // as it represents a final error status.\n (status) => status !== \"disconnected\"\n );\n\n const isDisabled = isSubmitting || disabled === true;\n\n const canAbort = isAvailable && abortableMessageId !== undefined;\n const canSubmit = isAvailable && !isEditorEmpty && !canAbort;\n\n const clear = useCallback(() => {\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n }, [editor]);\n\n const select = useCallback(() => {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n }, [editor]);\n\n const focus = useCallback(\n (resetSelection = true) => {\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(\n editor,\n resetSelection || !editor.selection\n ? SlateEditor.end(editor, [])\n : editor.selection\n );\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n },\n [editor]\n );\n\n const blur = useCallback(() => {\n try {\n ReactEditor.blur(editor);\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM\n // node no longer exists. This action doesn't make sense on an\n // unmounted editor so we can safely ignore it.\n }\n }, [editor]);\n\n const onSubmitEnd = useCallback(() => {\n clear();\n setSubmitting(false);\n }, [clear]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled) {\n return;\n }\n\n // In some situations (e.g. pressing Enter while composing diacritics), it's possible\n // for the form to be submitted as empty even though we already checked whether the\n // editor was empty when handling the key press.\n const isEditorEmpty = isEmpty(editor, editor.children);\n\n // We even prevent the user's `onSubmit` handler from being called if the editor is empty.\n if (isEditorEmpty) {\n event.preventDefault();\n\n return;\n }\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n const promise = onComposerSubmit(\n { text: content, lastMessageId },\n event\n );\n\n event.preventDefault();\n\n if (promise) {\n setSubmitting(true);\n promise.then(onSubmitEnd);\n } else {\n onSubmitEnd();\n }\n },\n [disabled, editor, onSubmit, onComposerSubmit, onSubmitEnd, lastMessageId]\n );\n\n useLayoutEffect(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const submit = useCallback(() => {\n if (!canSubmit) {\n return;\n }\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current) {\n requestSubmit(formRef.current);\n }\n });\n }, [canSubmit]);\n\n const abort = useCallback(() => {\n if (!canAbort || !abortableMessageId) {\n return;\n }\n\n client[kInternal].ai.abort(abortableMessageId);\n }, [canAbort, abortableMessageId, client]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiComposerEditorContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n abortableMessageId,\n setFocused,\n }}\n >\n <AiComposerContext.Provider\n value={{\n isDisabled,\n isEmpty: isEditorEmpty,\n isFocused,\n canSubmit,\n canAbort,\n submit,\n abort,\n clear,\n focus,\n blur,\n select,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiComposerContext.Provider>\n </AiComposerEditorContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\nfunction AiComposerEditorPlaceholder({\n attributes,\n children,\n}: RenderPlaceholderProps) {\n const { opacity: _opacity, ...style } = attributes.style;\n\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n}\n\n/**\n * Displays the AI composer's editor.\n *\n * @example\n * <AiComposer.Editor placeholder=\"Write a message…\" />\n */\nconst AiComposerEditor = forwardRef<HTMLDivElement, AiComposerEditorProps>(\n (\n {\n defaultValue = \"\",\n onKeyDown,\n onFocus,\n onBlur,\n disabled,\n autoFocus,\n dir,\n ...props\n },\n forwardedRef\n ) => {\n const { editor, onEditorValueChange, setFocused } =\n useAiComposerEditorContext();\n const {\n submit,\n isDisabled: isComposerDisabled,\n isFocused,\n focus,\n blur,\n select,\n } = useAiComposer();\n const isDisabled = disabled || isComposerDisabled;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n } else if (event.key === \"Escape\") {\n blur();\n }\n },\n [editor, onKeyDown, submit, blur]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus, setFocused]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(false);\n }\n },\n [onBlur, setFocused]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n // Manually focus the editor when `autoFocus` is true\n useLayoutEffect(() => {\n if (autoFocus) {\n focus();\n }\n }, [autoFocus, editor, focus]);\n\n // Manually add a selection in the editor if the selection\n // is still empty after being focused\n useLayoutEffect(() => {\n if (isFocused && editor.selection === null) {\n select();\n }\n }, [editor, select, isFocused]);\n\n const initialValue: AiComposerBody = useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n dir={dir}\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n aria-label=\"Composer editor\"\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-focused={isFocused || undefined}\n data-disabled={isDisabled || undefined}\n {...props}\n readOnly={isDisabled}\n disabled={isDisabled}\n renderPlaceholder={AiComposerEditorPlaceholder}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit the AI composer's content.\n *\n * @example\n * <AiComposer.Submit>Send</AiComposer.Submit>\n */\nexport const AiComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canSubmit } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canSubmit;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n />\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Abort\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to abort a response related to the AI composer.\n *\n * @example\n * <AiComposer.Abort>Cancel</AiComposer.Abort>\n */\nexport const AiComposerAbort = forwardRef<\n HTMLButtonElement,\n AiComposerSubmitProps\n>(({ disabled, onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const { isDisabled: isComposerDisabled, canAbort, abort } = useAiComposer();\n const isDisabled = isComposerDisabled || disabled || !canAbort;\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n abort();\n },\n [abort, onClick]\n );\n\n return (\n <Component\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={isDisabled}\n onClick={handleClick}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiComposerEditor.displayName = AI_COMPOSER_EDITOR_NAME;\n AiComposerForm.displayName = AI_COMPOSER_FORM_NAME;\n AiComposerSubmit.displayName = AI_COMPOSER_SUBMIT_NAME;\n AiComposerAbort.displayName = AI_COMPOSER_ABORT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiComposer.*\nexport {\n AiComposerAbort as Abort,\n AiComposerEditor as Editor,\n AiComposerForm as Form,\n AiComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor","isEditorEmpty"],"mappings":"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"}
|
|
@@ -28,12 +28,19 @@ const defaultMessageContentComponents = {
|
|
|
28
28
|
message
|
|
29
29
|
})
|
|
30
30
|
});
|
|
31
|
-
}
|
|
31
|
+
},
|
|
32
|
+
SourcesPart: () => null
|
|
32
33
|
};
|
|
33
34
|
const AiMessageContent = react.forwardRef(
|
|
34
35
|
({ message, components, asChild, ...props }, forwardedRef) => {
|
|
35
36
|
const Component = asChild ? reactSlot.Slot : "div";
|
|
36
|
-
const {
|
|
37
|
+
const {
|
|
38
|
+
ReasoningPart,
|
|
39
|
+
RetrievalPart,
|
|
40
|
+
TextPart,
|
|
41
|
+
ToolInvocationPart,
|
|
42
|
+
SourcesPart
|
|
43
|
+
} = react.useMemo(
|
|
37
44
|
() => ({ ...defaultMessageContentComponents, ...components }),
|
|
38
45
|
[components]
|
|
39
46
|
);
|
|
@@ -68,6 +75,13 @@ const AiMessageContent = react.forwardRef(
|
|
|
68
75
|
...extra,
|
|
69
76
|
message
|
|
70
77
|
}, index);
|
|
78
|
+
case "sources":
|
|
79
|
+
if (message.role === "assistant" && message.status !== "completed" && message.status !== "failed") {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SourcesPart, {
|
|
83
|
+
part
|
|
84
|
+
}, index);
|
|
71
85
|
default:
|
|
72
86
|
return null;
|
|
73
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type { AiAssistantMessage } from \"@liveblocks/core\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n RetrievalPart: () => null,\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const {
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type { AiAssistantMessage } from \"@liveblocks/core\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n RetrievalPart: () => null,\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n SourcesPart: () => null,\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const {\n ReasoningPart,\n RetrievalPart,\n TextPart,\n ToolInvocationPart,\n SourcesPart,\n } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n\n case \"retrieval\":\n return <RetrievalPart key={index} part={part} {...extra} />;\n\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n // For tool invocations, we know for sure it's an AiAssistantMessage\n message={message as AiAssistantMessage}\n />\n );\n\n case \"sources\":\n // Sources are only shown after the message is either completed or failed.\n if (\n message.role === \"assistant\" &&\n message.status !== \"completed\" &&\n message.status !== \"failed\"\n ) {\n return null;\n }\n\n return <SourcesPart key={index} part={part} />;\n\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":["jsx","Markdown","ErrorBoundary","AiMessageToolInvocation","forwardRef","Slot","useMemo"],"mappings":"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"}
|
|
@@ -26,12 +26,19 @@ const defaultMessageContentComponents = {
|
|
|
26
26
|
message
|
|
27
27
|
})
|
|
28
28
|
});
|
|
29
|
-
}
|
|
29
|
+
},
|
|
30
|
+
SourcesPart: () => null
|
|
30
31
|
};
|
|
31
32
|
const AiMessageContent = forwardRef(
|
|
32
33
|
({ message, components, asChild, ...props }, forwardedRef) => {
|
|
33
34
|
const Component = asChild ? Slot : "div";
|
|
34
|
-
const {
|
|
35
|
+
const {
|
|
36
|
+
ReasoningPart,
|
|
37
|
+
RetrievalPart,
|
|
38
|
+
TextPart,
|
|
39
|
+
ToolInvocationPart,
|
|
40
|
+
SourcesPart
|
|
41
|
+
} = useMemo(
|
|
35
42
|
() => ({ ...defaultMessageContentComponents, ...components }),
|
|
36
43
|
[components]
|
|
37
44
|
);
|
|
@@ -66,6 +73,13 @@ const AiMessageContent = forwardRef(
|
|
|
66
73
|
...extra,
|
|
67
74
|
message
|
|
68
75
|
}, index);
|
|
76
|
+
case "sources":
|
|
77
|
+
if (message.role === "assistant" && message.status !== "completed" && message.status !== "failed") {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return /* @__PURE__ */ jsx(SourcesPart, {
|
|
81
|
+
part
|
|
82
|
+
}, index);
|
|
69
83
|
default:
|
|
70
84
|
return null;
|
|
71
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type { AiAssistantMessage } from \"@liveblocks/core\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n RetrievalPart: () => null,\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const {
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type { AiAssistantMessage } from \"@liveblocks/core\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n RetrievalPart: () => null,\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n SourcesPart: () => null,\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const {\n ReasoningPart,\n RetrievalPart,\n TextPart,\n ToolInvocationPart,\n SourcesPart,\n } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n\n case \"retrieval\":\n return <RetrievalPart key={index} part={part} {...extra} />;\n\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n // For tool invocations, we know for sure it's an AiAssistantMessage\n message={message as AiAssistantMessage}\n />\n );\n\n case \"sources\":\n // Sources are only shown after the message is either completed or failed.\n if (\n message.role === \"assistant\" &&\n message.status !== \"completed\" &&\n message.status !== \"failed\"\n ) {\n return null;\n }\n\n return <SourcesPart key={index} part={part} />;\n\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":[],"mappings":"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"}
|
package/dist/version.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PKG_NAME = "@liveblocks/react-ui";
|
|
4
|
-
const PKG_VERSION = typeof "3.
|
|
4
|
+
const PKG_VERSION = typeof "3.9.0" === "string" && "3.9.0";
|
|
5
5
|
const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
|
|
6
6
|
|
|
7
7
|
exports.PKG_FORMAT = PKG_FORMAT;
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const PKG_NAME = "@liveblocks/react-ui";
|
|
2
|
-
const PKG_VERSION = typeof "3.
|
|
2
|
+
const PKG_VERSION = typeof "3.9.0" === "string" && "3.9.0";
|
|
3
3
|
const PKG_FORMAT = typeof "esm" === "string" && "esm";
|
|
4
4
|
|
|
5
5
|
export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@floating-ui/react-dom": "^2.1.2",
|
|
79
|
-
"@liveblocks/client": "3.
|
|
80
|
-
"@liveblocks/core": "3.
|
|
81
|
-
"@liveblocks/react": "3.
|
|
79
|
+
"@liveblocks/client": "3.9.0",
|
|
80
|
+
"@liveblocks/core": "3.9.0",
|
|
81
|
+
"@liveblocks/react": "3.9.0",
|
|
82
82
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
|
83
83
|
"@radix-ui/react-popover": "^1.1.2",
|
|
84
84
|
"@radix-ui/react-slot": "^1.1.0",
|