@liveblocks/react-ui 2.25.0-aiprivatebeta1 → 2.25.0-aiprivatebeta10
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 +18 -10
- package/dist/_private/index.cjs.map +1 -1
- package/dist/_private/index.d.cts +204 -172
- package/dist/_private/index.d.ts +204 -172
- package/dist/_private/index.js +12 -5
- package/dist/_private/index.js.map +1 -1
- package/dist/components/AiChat.cjs +185 -0
- package/dist/components/AiChat.cjs.map +1 -0
- package/dist/components/AiChat.js +183 -0
- package/dist/components/AiChat.js.map +1 -0
- package/dist/components/AiTool.cjs +164 -0
- package/dist/components/AiTool.cjs.map +1 -0
- package/dist/components/AiTool.js +162 -0
- package/dist/components/AiTool.js.map +1 -0
- package/dist/components/Comment.cjs +7 -5
- package/dist/components/Comment.cjs.map +1 -1
- package/dist/components/Comment.js +7 -5
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/Composer.cjs +1 -2
- package/dist/components/Composer.cjs.map +1 -1
- package/dist/components/Composer.js +1 -2
- package/dist/components/Composer.js.map +1 -1
- package/dist/components/InboxNotificationList.cjs +11 -3
- package/dist/components/InboxNotificationList.cjs.map +1 -1
- package/dist/components/InboxNotificationList.js +12 -4
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/Thread.cjs +3 -3
- package/dist/components/Thread.cjs.map +1 -1
- package/dist/components/Thread.js +3 -3
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.cjs +74 -291
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +76 -293
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiChatComposer.cjs +58 -282
- package/dist/components/internal/AiChatComposer.cjs.map +1 -1
- package/dist/components/internal/AiChatComposer.js +63 -283
- package/dist/components/internal/AiChatComposer.js.map +1 -1
- package/dist/components/internal/AiChatUserMessage.cjs +26 -169
- package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatUserMessage.js +28 -171
- package/dist/components/internal/AiChatUserMessage.js.map +1 -1
- package/dist/components/internal/Button.cjs.map +1 -1
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/CodeBlock.cjs +72 -0
- package/dist/components/internal/CodeBlock.cjs.map +1 -0
- package/dist/components/internal/CodeBlock.js +70 -0
- package/dist/components/internal/CodeBlock.js.map +1 -0
- package/dist/components/internal/Emoji.cjs +12 -4
- package/dist/components/internal/Emoji.cjs.map +1 -1
- package/dist/components/internal/Emoji.js +12 -4
- package/dist/components/internal/Emoji.js.map +1 -1
- package/dist/components/internal/Prose.cjs +37 -0
- package/dist/components/internal/Prose.cjs.map +1 -0
- package/dist/components/internal/Prose.js +35 -0
- package/dist/components/internal/Prose.js.map +1 -0
- package/dist/constants.cjs +2 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/icon.cjs +6 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +3 -0
- package/dist/icon.js.map +1 -1
- package/dist/icons/{Resolve.cjs → CheckCircle.cjs} +3 -3
- package/dist/icons/CheckCircle.cjs.map +1 -0
- package/dist/icons/{Resolve.js → CheckCircle.js} +3 -3
- package/dist/icons/CheckCircle.js.map +1 -0
- package/dist/icons/{Resolved.cjs → CheckCircleFill.cjs} +3 -3
- package/dist/icons/CheckCircleFill.cjs.map +1 -0
- package/dist/icons/{Resolved.js → CheckCircleFill.js} +3 -3
- package/dist/icons/CheckCircleFill.js.map +1 -0
- package/dist/icons/Copy.cjs +8 -9
- package/dist/icons/Copy.cjs.map +1 -1
- package/dist/icons/Copy.js +8 -9
- package/dist/icons/Copy.js.map +1 -1
- package/dist/icons/Retry.cjs +21 -0
- package/dist/icons/Retry.cjs.map +1 -0
- package/dist/icons/Retry.js +19 -0
- package/dist/icons/Retry.js.map +1 -0
- package/dist/icons/index.cjs +8 -4
- package/dist/icons/index.cjs.map +1 -1
- package/dist/icons/index.js +4 -2
- package/dist/icons/index.js.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -43
- package/dist/index.d.ts +102 -43
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/overrides.cjs +6 -12
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.js +6 -12
- package/dist/overrides.js.map +1 -1
- package/dist/primitives/AiChatComposer/index.cjs +202 -0
- package/dist/primitives/AiChatComposer/index.cjs.map +1 -0
- package/dist/primitives/AiChatComposer/index.js +195 -0
- package/dist/primitives/AiChatComposer/index.js.map +1 -0
- package/dist/primitives/AiMessage/contexts.cjs +18 -0
- package/dist/primitives/AiMessage/contexts.cjs.map +1 -0
- package/dist/primitives/AiMessage/contexts.js +15 -0
- package/dist/primitives/AiMessage/contexts.js.map +1 -0
- package/dist/primitives/AiMessage/index.cjs +134 -0
- package/dist/primitives/AiMessage/index.cjs.map +1 -0
- package/dist/primitives/AiMessage/index.js +132 -0
- package/dist/primitives/AiMessage/index.js.map +1 -0
- package/dist/primitives/Collapsible/index.cjs +127 -0
- package/dist/primitives/Collapsible/index.cjs.map +1 -0
- package/dist/primitives/Collapsible/index.js +123 -0
- package/dist/primitives/Collapsible/index.js.map +1 -0
- package/dist/primitives/Comment/index.cjs +2 -2
- package/dist/primitives/Comment/index.cjs.map +1 -1
- package/dist/primitives/Comment/index.js +1 -1
- package/dist/primitives/Comment/index.js.map +1 -1
- package/dist/primitives/Composer/index.cjs +19 -14
- package/dist/primitives/Composer/index.cjs.map +1 -1
- package/dist/primitives/Composer/index.js +18 -13
- package/dist/primitives/Composer/index.js.map +1 -1
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-formatting.cjs +3 -3
- package/dist/primitives/Composer/slate/plugins/auto-formatting.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-formatting.js +3 -3
- package/dist/primitives/Composer/slate/plugins/auto-formatting.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-links.cjs +7 -2
- package/dist/primitives/Composer/slate/plugins/auto-links.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-links.js +8 -3
- package/dist/primitives/Composer/slate/plugins/auto-links.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/custom-links.cjs +8 -3
- package/dist/primitives/Composer/slate/plugins/custom-links.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/custom-links.js +9 -4
- package/dist/primitives/Composer/slate/plugins/custom-links.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/mentions.cjs +9 -10
- package/dist/primitives/Composer/slate/plugins/mentions.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/mentions.js +6 -6
- package/dist/primitives/Composer/slate/plugins/mentions.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/paste.cjs +1 -1
- package/dist/primitives/Composer/slate/plugins/paste.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/paste.js +1 -1
- package/dist/primitives/Composer/slate/plugins/paste.js.map +1 -0
- package/dist/primitives/Composer/utils.cjs +4 -4
- package/dist/primitives/Composer/utils.cjs.map +1 -1
- package/dist/primitives/Composer/utils.js +4 -4
- package/dist/primitives/Composer/utils.js.map +1 -1
- package/dist/primitives/{internal/Markdown.cjs → Markdown.cjs} +150 -83
- package/dist/primitives/Markdown.cjs.map +1 -0
- package/dist/primitives/{internal/Markdown.js → Markdown.js} +151 -83
- package/dist/primitives/Markdown.js.map +1 -0
- package/dist/primitives/index.cjs +4 -9
- package/dist/primitives/index.cjs.map +1 -1
- package/dist/primitives/index.d.cts +4 -110
- package/dist/primitives/index.d.ts +4 -110
- package/dist/primitives/index.js +0 -1
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/slate/plugins/empty-clear-formatting.cjs.map +1 -0
- package/dist/primitives/slate/plugins/empty-clear-formatting.js.map +1 -0
- package/dist/{slate → primitives/slate}/plugins/normalize.cjs +0 -5
- package/dist/primitives/slate/plugins/normalize.cjs.map +1 -0
- package/dist/{slate → primitives/slate}/plugins/normalize.js +0 -5
- package/dist/primitives/slate/plugins/normalize.js.map +1 -0
- package/dist/primitives/slate/utils/get-character.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-character.js.map +1 -0
- package/dist/primitives/slate/utils/get-dom-range.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-dom-range.js.map +1 -0
- package/dist/primitives/slate/utils/get-match-range.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-match-range.js.map +1 -0
- package/dist/primitives/slate/utils/is-empty-string.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-empty-string.js.map +1 -0
- package/dist/primitives/slate/utils/is-empty.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-empty.js.map +1 -0
- package/dist/primitives/slate/utils/is-text.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-text.js.map +1 -0
- package/dist/primitives/slate/utils/is-whitespace-character.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-whitespace-character.js.map +1 -0
- package/dist/{slate → primitives/slate}/utils/marks.cjs +9 -9
- package/dist/primitives/slate/utils/marks.cjs.map +1 -0
- package/dist/{slate → primitives/slate}/utils/marks.js +9 -9
- package/dist/primitives/slate/utils/marks.js.map +1 -0
- package/dist/primitives/slate/utils/selection-contains-inlines.cjs.map +1 -0
- package/dist/primitives/slate/utils/selection-contains-inlines.js.map +1 -0
- package/dist/utils/ErrorBoundary.cjs +48 -0
- package/dist/utils/ErrorBoundary.cjs.map +1 -0
- package/dist/utils/ErrorBoundary.js +45 -0
- package/dist/utils/ErrorBoundary.js.map +1 -0
- package/dist/utils/use-visible.cjs +63 -45
- package/dist/utils/use-visible.cjs.map +1 -1
- package/dist/utils/use-visible.js +64 -46
- package/dist/utils/use-visible.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +18 -6
- package/src/styles/constants.css +1 -1
- package/src/styles/dark/index.css +7 -3
- package/src/styles/index.css +640 -307
- package/src/styles/utils.css +8 -3
- package/styles/dark/attributes.css +1 -1
- package/styles/dark/attributes.css.map +1 -1
- package/styles/dark/media-query.css +1 -1
- package/styles/dark/media-query.css.map +1 -1
- package/styles.css +1 -1
- package/styles.css.map +1 -1
- package/dist/components/AiChat/AiChat.cjs +0 -211
- package/dist/components/AiChat/AiChat.cjs.map +0 -1
- package/dist/components/AiChat/AiChat.js +0 -209
- package/dist/components/AiChat/AiChat.js.map +0 -1
- package/dist/icons/Resolve.cjs.map +0 -1
- package/dist/icons/Resolve.js.map +0 -1
- package/dist/icons/Resolved.cjs.map +0 -1
- package/dist/icons/Resolved.js.map +0 -1
- package/dist/primitives/Chat/Composer/index.cjs +0 -323
- package/dist/primitives/Chat/Composer/index.cjs.map +0 -1
- package/dist/primitives/Chat/Composer/index.js +0 -315
- package/dist/primitives/Chat/Composer/index.js.map +0 -1
- package/dist/primitives/internal/Collapsible.cjs +0 -99
- package/dist/primitives/internal/Collapsible.cjs.map +0 -1
- package/dist/primitives/internal/Collapsible.js +0 -95
- package/dist/primitives/internal/Collapsible.js.map +0 -1
- package/dist/primitives/internal/Emoji.cjs +0 -32
- package/dist/primitives/internal/Emoji.cjs.map +0 -1
- package/dist/primitives/internal/Emoji.js +0 -30
- package/dist/primitives/internal/Emoji.js.map +0 -1
- package/dist/primitives/internal/Markdown.cjs.map +0 -1
- package/dist/primitives/internal/Markdown.js.map +0 -1
- package/dist/slate/plugins/auto-formatting.cjs.map +0 -1
- package/dist/slate/plugins/auto-formatting.js.map +0 -1
- package/dist/slate/plugins/auto-links.cjs.map +0 -1
- package/dist/slate/plugins/auto-links.js.map +0 -1
- package/dist/slate/plugins/custom-links.cjs.map +0 -1
- package/dist/slate/plugins/custom-links.js.map +0 -1
- package/dist/slate/plugins/empty-clear-formatting.cjs.map +0 -1
- package/dist/slate/plugins/empty-clear-formatting.js.map +0 -1
- package/dist/slate/plugins/mentions.cjs.map +0 -1
- package/dist/slate/plugins/mentions.js.map +0 -1
- package/dist/slate/plugins/normalize.cjs.map +0 -1
- package/dist/slate/plugins/normalize.js.map +0 -1
- package/dist/slate/plugins/paste.cjs.map +0 -1
- package/dist/slate/plugins/paste.js.map +0 -1
- package/dist/slate/utils/get-character.cjs.map +0 -1
- package/dist/slate/utils/get-character.js.map +0 -1
- package/dist/slate/utils/get-dom-range.cjs.map +0 -1
- package/dist/slate/utils/get-dom-range.js.map +0 -1
- package/dist/slate/utils/get-match-range.cjs.map +0 -1
- package/dist/slate/utils/get-match-range.js.map +0 -1
- package/dist/slate/utils/is-empty-string.cjs.map +0 -1
- package/dist/slate/utils/is-empty-string.js.map +0 -1
- package/dist/slate/utils/is-empty.cjs.map +0 -1
- package/dist/slate/utils/is-empty.js.map +0 -1
- package/dist/slate/utils/is-text.cjs.map +0 -1
- package/dist/slate/utils/is-text.js.map +0 -1
- package/dist/slate/utils/is-whitespace-character.cjs.map +0 -1
- package/dist/slate/utils/is-whitespace-character.js.map +0 -1
- package/dist/slate/utils/marks.cjs.map +0 -1
- package/dist/slate/utils/marks.js.map +0 -1
- package/dist/slate/utils/selection-contains-inlines.cjs.map +0 -1
- package/dist/slate/utils/selection-contains-inlines.js.map +0 -1
- /package/dist/{slate → primitives/slate}/plugins/empty-clear-formatting.cjs +0 -0
- /package/dist/{slate → primitives/slate}/plugins/empty-clear-formatting.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-character.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-character.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-dom-range.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-dom-range.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-match-range.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-match-range.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty-string.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty-string.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-text.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-text.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-whitespace-character.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-whitespace-character.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/selection-contains-inlines.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/selection-contains-inlines.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\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 onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\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 === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\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 requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n 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 enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
const AiToolInvocationContext = react.createContext(null);
|
|
6
|
+
function useAiToolInvocationContext() {
|
|
7
|
+
const context = react.useContext(AiToolInvocationContext);
|
|
8
|
+
if (context === null) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"This component must be used within a tool's render method."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.AiToolInvocationContext = AiToolInvocationContext;
|
|
17
|
+
exports.useAiToolInvocationContext = useAiToolInvocationContext;
|
|
18
|
+
//# sourceMappingURL=contexts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contexts.cjs","sources":["../../../src/primitives/AiMessage/contexts.ts"],"sourcesContent":["import type { AiOpaqueToolInvocationProps } from \"@liveblocks/core\";\nimport { createContext, useContext } from \"react\";\n\nexport const AiToolInvocationContext =\n createContext<AiOpaqueToolInvocationProps | null>(null);\n\nexport function useAiToolInvocationContext() {\n const context = useContext(AiToolInvocationContext);\n\n if (context === null) {\n throw new Error(\n \"This component must be used within a tool's render method.\"\n );\n }\n\n return context;\n}\n"],"names":["createContext","useContext"],"mappings":";;;;AAGa,MAAA,uBAAA,GACXA,oBAAkD,IAAI,EAAA;AAEjD,SAAS,0BAA6B,GAAA;AAC3C,EAAM,MAAA,OAAA,GAAUC,iBAAW,uBAAuB,CAAA,CAAA;AAElD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,4DAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
const AiToolInvocationContext = createContext(null);
|
|
4
|
+
function useAiToolInvocationContext() {
|
|
5
|
+
const context = useContext(AiToolInvocationContext);
|
|
6
|
+
if (context === null) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"This component must be used within a tool's render method."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
return context;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { AiToolInvocationContext, useAiToolInvocationContext };
|
|
15
|
+
//# sourceMappingURL=contexts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contexts.js","sources":["../../../src/primitives/AiMessage/contexts.ts"],"sourcesContent":["import type { AiOpaqueToolInvocationProps } from \"@liveblocks/core\";\nimport { createContext, useContext } from \"react\";\n\nexport const AiToolInvocationContext =\n createContext<AiOpaqueToolInvocationProps | null>(null);\n\nexport function useAiToolInvocationContext() {\n const context = useContext(AiToolInvocationContext);\n\n if (context === null) {\n throw new Error(\n \"This component must be used within a tool's render method.\"\n );\n }\n\n return context;\n}\n"],"names":[],"mappings":";;AAGa,MAAA,uBAAA,GACX,cAAkD,IAAI,EAAA;AAEjD,SAAS,0BAA6B,GAAA;AAC3C,EAAM,MAAA,OAAA,GAAU,WAAW,uBAAuB,CAAA,CAAA;AAElD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,4DAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var core = require('@liveblocks/core');
|
|
5
|
+
var react = require('@liveblocks/react');
|
|
6
|
+
var _private = require('@liveblocks/react/_private');
|
|
7
|
+
var reactSlot = require('@radix-ui/react-slot');
|
|
8
|
+
var react$1 = require('react');
|
|
9
|
+
var ErrorBoundary = require('../../utils/ErrorBoundary.cjs');
|
|
10
|
+
var Markdown = require('../Markdown.cjs');
|
|
11
|
+
var contexts = require('./contexts.cjs');
|
|
12
|
+
|
|
13
|
+
const AI_MESSAGE_CONTENT_NAME = "AiMessageContent";
|
|
14
|
+
const defaultMessageContentComponents = {
|
|
15
|
+
TextPart: ({ part }) => {
|
|
16
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Markdown.Markdown, {
|
|
17
|
+
content: part.text
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
ReasoningPart: ({ part }) => {
|
|
21
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Markdown.Markdown, {
|
|
22
|
+
content: part.text
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
ToolInvocationPart: ({ children }) => children
|
|
26
|
+
};
|
|
27
|
+
function ToolInvocation({
|
|
28
|
+
chatId,
|
|
29
|
+
messageId,
|
|
30
|
+
part
|
|
31
|
+
}) {
|
|
32
|
+
const client = react.useClient();
|
|
33
|
+
const ai = client[core.kInternal].ai;
|
|
34
|
+
const tool = _private.useSignal(ai.signals.getToolDefinition\u03A3(chatId, part.toolName));
|
|
35
|
+
const respond = react$1.useCallback(
|
|
36
|
+
(result) => {
|
|
37
|
+
if (part.status === "receiving") {
|
|
38
|
+
console.log(
|
|
39
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`
|
|
40
|
+
);
|
|
41
|
+
} else if (part.status === "executed") {
|
|
42
|
+
console.log(
|
|
43
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`
|
|
44
|
+
);
|
|
45
|
+
} else {
|
|
46
|
+
ai.setToolResult(
|
|
47
|
+
chatId,
|
|
48
|
+
messageId,
|
|
49
|
+
part.toolCallId,
|
|
50
|
+
result
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
[ai, chatId, messageId, part.status, part.toolName, part.toolCallId]
|
|
55
|
+
);
|
|
56
|
+
if (tool === void 0 || tool.render === void 0)
|
|
57
|
+
return null;
|
|
58
|
+
const RenderFn = tool.render;
|
|
59
|
+
const { type: _, ...rest } = part;
|
|
60
|
+
const props = {
|
|
61
|
+
...rest,
|
|
62
|
+
respond,
|
|
63
|
+
types: void 0,
|
|
64
|
+
[core.kInternal]: {
|
|
65
|
+
execute: tool.execute
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.ErrorBoundary, {
|
|
69
|
+
fallback: /* @__PURE__ */ jsxRuntime.jsxs("p", {
|
|
70
|
+
style: { color: "red" },
|
|
71
|
+
children: [
|
|
72
|
+
"Failed to render tool call result for \u2018",
|
|
73
|
+
part.toolName,
|
|
74
|
+
"\u2019. See console for details."
|
|
75
|
+
]
|
|
76
|
+
}),
|
|
77
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(contexts.AiToolInvocationContext.Provider, {
|
|
78
|
+
value: props,
|
|
79
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(RenderFn, {
|
|
80
|
+
...props
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const AiMessageContent = react$1.forwardRef(
|
|
86
|
+
({ message, components, asChild, ...props }, forwardedRef) => {
|
|
87
|
+
const Component = asChild ? reactSlot.Slot : "div";
|
|
88
|
+
const { TextPart, ReasoningPart, ToolInvocationPart } = react$1.useMemo(
|
|
89
|
+
() => ({ ...defaultMessageContentComponents, ...components }),
|
|
90
|
+
[components]
|
|
91
|
+
);
|
|
92
|
+
const content = message.content ?? message.contentSoFar;
|
|
93
|
+
const numParts = content.length;
|
|
94
|
+
const isGenerating = message.role === "assistant" && message.status === "generating";
|
|
95
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
96
|
+
...props,
|
|
97
|
+
ref: forwardedRef,
|
|
98
|
+
children: content.map((part, index) => {
|
|
99
|
+
const isStreaming = isGenerating && index === numParts - 1;
|
|
100
|
+
const extra = { index, isStreaming };
|
|
101
|
+
switch (part.type) {
|
|
102
|
+
case "text":
|
|
103
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextPart, {
|
|
104
|
+
part,
|
|
105
|
+
...extra
|
|
106
|
+
}, index);
|
|
107
|
+
case "reasoning":
|
|
108
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ReasoningPart, {
|
|
109
|
+
part,
|
|
110
|
+
...extra
|
|
111
|
+
}, index);
|
|
112
|
+
case "tool-invocation":
|
|
113
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToolInvocationPart, {
|
|
114
|
+
part,
|
|
115
|
+
...extra,
|
|
116
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ToolInvocation, {
|
|
117
|
+
part,
|
|
118
|
+
chatId: message.chatId,
|
|
119
|
+
messageId: message.id
|
|
120
|
+
}, index)
|
|
121
|
+
}, index);
|
|
122
|
+
default:
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
if (process.env.NODE_ENV !== "production") {
|
|
130
|
+
AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
exports.Content = AiMessageContent;
|
|
134
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type {\n AiToolInvocationPart,\n AiToolInvocationProps,\n JsonObject,\n MessageId,\n ToolResultData,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ComponentType } from \"react\";\nimport { forwardRef, useCallback, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiToolInvocationContext } from \"./contexts\";\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 ToolInvocationPart: ({ children }) => children,\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\n\nfunction ToolInvocation({\n chatId,\n messageId,\n part,\n}: {\n chatId: string;\n messageId: MessageId;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolDefinitionΣ(chatId, part.toolName));\n\n const respond = useCallback(\n (result: ToolResultData) => {\n if (part.status === \"receiving\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`\n );\n } else if (part.status === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`\n );\n } else {\n ai.setToolResult(\n chatId,\n messageId,\n part.toolCallId,\n result\n // TODO Pass in AiGenerationOptions here?\n );\n }\n },\n [ai, chatId, messageId, part.status, part.toolName, part.toolCallId]\n );\n\n if (tool === undefined || tool.render === undefined) return null;\n const RenderFn = tool.render as ComponentType<\n AiToolInvocationProps<JsonObject, ToolResultData>\n >;\n\n const { type: _, ...rest } = part;\n const props = {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool.execute,\n },\n };\n return (\n <ErrorBoundary\n fallback={\n <p style={{ color: \"red\" }}>\n Failed to render tool call result for ‘{part.toolName}’. See console\n for details.\n </p>\n }\n >\n <AiToolInvocationContext.Provider value={props}>\n <RenderFn {...props} />\n </AiToolInvocationContext.Provider>\n </ErrorBoundary>\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 { TextPart, ReasoningPart, ToolInvocationPart } = 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 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 case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n // TODO: If the render() method doesn't exist, we should not render the ToolInvocationPart\n // or pass it no children so that it can decide to not render?\n return (\n <ToolInvocationPart key={index} part={part} {...extra}>\n <ToolInvocation\n key={index}\n part={part}\n chatId={message.chatId}\n messageId={message.id}\n />\n </ToolInvocationPart>\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","useClient","kInternal","useSignal","useCallback","ErrorBoundary","jsxs","AiToolInvocationContext","forwardRef","Slot","useMemo"],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { kInternal } from '@liveblocks/core';
|
|
3
|
+
import { useClient } from '@liveblocks/react';
|
|
4
|
+
import { useSignal } from '@liveblocks/react/_private';
|
|
5
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
6
|
+
import { useCallback, forwardRef, useMemo } from 'react';
|
|
7
|
+
import { ErrorBoundary } from '../../utils/ErrorBoundary.js';
|
|
8
|
+
import { Markdown } from '../Markdown.js';
|
|
9
|
+
import { AiToolInvocationContext } from './contexts.js';
|
|
10
|
+
|
|
11
|
+
const AI_MESSAGE_CONTENT_NAME = "AiMessageContent";
|
|
12
|
+
const defaultMessageContentComponents = {
|
|
13
|
+
TextPart: ({ part }) => {
|
|
14
|
+
return /* @__PURE__ */ jsx(Markdown, {
|
|
15
|
+
content: part.text
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
ReasoningPart: ({ part }) => {
|
|
19
|
+
return /* @__PURE__ */ jsx(Markdown, {
|
|
20
|
+
content: part.text
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
ToolInvocationPart: ({ children }) => children
|
|
24
|
+
};
|
|
25
|
+
function ToolInvocation({
|
|
26
|
+
chatId,
|
|
27
|
+
messageId,
|
|
28
|
+
part
|
|
29
|
+
}) {
|
|
30
|
+
const client = useClient();
|
|
31
|
+
const ai = client[kInternal].ai;
|
|
32
|
+
const tool = useSignal(ai.signals.getToolDefinition\u03A3(chatId, part.toolName));
|
|
33
|
+
const respond = useCallback(
|
|
34
|
+
(result) => {
|
|
35
|
+
if (part.status === "receiving") {
|
|
36
|
+
console.log(
|
|
37
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`
|
|
38
|
+
);
|
|
39
|
+
} else if (part.status === "executed") {
|
|
40
|
+
console.log(
|
|
41
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`
|
|
42
|
+
);
|
|
43
|
+
} else {
|
|
44
|
+
ai.setToolResult(
|
|
45
|
+
chatId,
|
|
46
|
+
messageId,
|
|
47
|
+
part.toolCallId,
|
|
48
|
+
result
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
[ai, chatId, messageId, part.status, part.toolName, part.toolCallId]
|
|
53
|
+
);
|
|
54
|
+
if (tool === void 0 || tool.render === void 0)
|
|
55
|
+
return null;
|
|
56
|
+
const RenderFn = tool.render;
|
|
57
|
+
const { type: _, ...rest } = part;
|
|
58
|
+
const props = {
|
|
59
|
+
...rest,
|
|
60
|
+
respond,
|
|
61
|
+
types: void 0,
|
|
62
|
+
[kInternal]: {
|
|
63
|
+
execute: tool.execute
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
return /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
67
|
+
fallback: /* @__PURE__ */ jsxs("p", {
|
|
68
|
+
style: { color: "red" },
|
|
69
|
+
children: [
|
|
70
|
+
"Failed to render tool call result for \u2018",
|
|
71
|
+
part.toolName,
|
|
72
|
+
"\u2019. See console for details."
|
|
73
|
+
]
|
|
74
|
+
}),
|
|
75
|
+
children: /* @__PURE__ */ jsx(AiToolInvocationContext.Provider, {
|
|
76
|
+
value: props,
|
|
77
|
+
children: /* @__PURE__ */ jsx(RenderFn, {
|
|
78
|
+
...props
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const AiMessageContent = forwardRef(
|
|
84
|
+
({ message, components, asChild, ...props }, forwardedRef) => {
|
|
85
|
+
const Component = asChild ? Slot : "div";
|
|
86
|
+
const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(
|
|
87
|
+
() => ({ ...defaultMessageContentComponents, ...components }),
|
|
88
|
+
[components]
|
|
89
|
+
);
|
|
90
|
+
const content = message.content ?? message.contentSoFar;
|
|
91
|
+
const numParts = content.length;
|
|
92
|
+
const isGenerating = message.role === "assistant" && message.status === "generating";
|
|
93
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
94
|
+
...props,
|
|
95
|
+
ref: forwardedRef,
|
|
96
|
+
children: content.map((part, index) => {
|
|
97
|
+
const isStreaming = isGenerating && index === numParts - 1;
|
|
98
|
+
const extra = { index, isStreaming };
|
|
99
|
+
switch (part.type) {
|
|
100
|
+
case "text":
|
|
101
|
+
return /* @__PURE__ */ jsx(TextPart, {
|
|
102
|
+
part,
|
|
103
|
+
...extra
|
|
104
|
+
}, index);
|
|
105
|
+
case "reasoning":
|
|
106
|
+
return /* @__PURE__ */ jsx(ReasoningPart, {
|
|
107
|
+
part,
|
|
108
|
+
...extra
|
|
109
|
+
}, index);
|
|
110
|
+
case "tool-invocation":
|
|
111
|
+
return /* @__PURE__ */ jsx(ToolInvocationPart, {
|
|
112
|
+
part,
|
|
113
|
+
...extra,
|
|
114
|
+
children: /* @__PURE__ */ jsx(ToolInvocation, {
|
|
115
|
+
part,
|
|
116
|
+
chatId: message.chatId,
|
|
117
|
+
messageId: message.id
|
|
118
|
+
}, index)
|
|
119
|
+
}, index);
|
|
120
|
+
default:
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
if (process.env.NODE_ENV !== "production") {
|
|
128
|
+
AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { AiMessageContent as Content };
|
|
132
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type {\n AiToolInvocationPart,\n AiToolInvocationProps,\n JsonObject,\n MessageId,\n ToolResultData,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ComponentType } from \"react\";\nimport { forwardRef, useCallback, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiToolInvocationContext } from \"./contexts\";\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 ToolInvocationPart: ({ children }) => children,\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\n\nfunction ToolInvocation({\n chatId,\n messageId,\n part,\n}: {\n chatId: string;\n messageId: MessageId;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolDefinitionΣ(chatId, part.toolName));\n\n const respond = useCallback(\n (result: ToolResultData) => {\n if (part.status === \"receiving\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`\n );\n } else if (part.status === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`\n );\n } else {\n ai.setToolResult(\n chatId,\n messageId,\n part.toolCallId,\n result\n // TODO Pass in AiGenerationOptions here?\n );\n }\n },\n [ai, chatId, messageId, part.status, part.toolName, part.toolCallId]\n );\n\n if (tool === undefined || tool.render === undefined) return null;\n const RenderFn = tool.render as ComponentType<\n AiToolInvocationProps<JsonObject, ToolResultData>\n >;\n\n const { type: _, ...rest } = part;\n const props = {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool.execute,\n },\n };\n return (\n <ErrorBoundary\n fallback={\n <p style={{ color: \"red\" }}>\n Failed to render tool call result for ‘{part.toolName}’. See console\n for details.\n </p>\n }\n >\n <AiToolInvocationContext.Provider value={props}>\n <RenderFn {...props} />\n </AiToolInvocationContext.Provider>\n </ErrorBoundary>\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 { TextPart, ReasoningPart, ToolInvocationPart } = 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 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 case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n // TODO: If the render() method doesn't exist, we should not render the ToolInvocationPart\n // or pass it no children so that it can decide to not render?\n return (\n <ToolInvocationPart key={index} part={part} {...extra}>\n <ToolInvocation\n key={index}\n part={part}\n chatId={message.chatId}\n messageId={message.id}\n />\n </ToolInvocationPart>\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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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var reactSlot = require('@radix-ui/react-slot');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var useControllableState = require('../../utils/use-controllable-state.cjs');
|
|
7
|
+
|
|
8
|
+
const COLLAPSIBLE_ROOT_NAME = "CollapsibleRoot";
|
|
9
|
+
const COLLAPSIBLE_TRIGGER_NAME = "CollapsibleTrigger";
|
|
10
|
+
const COLLAPSIBLE_CONTENT_NAME = "CollapsibleContent";
|
|
11
|
+
const CollapsibleContext = react.createContext(null);
|
|
12
|
+
const CollapsibleRoot = react.forwardRef(
|
|
13
|
+
({
|
|
14
|
+
open: controlledOpen,
|
|
15
|
+
onOpenChange: controlledOnOpenChange,
|
|
16
|
+
defaultOpen,
|
|
17
|
+
disabled = false,
|
|
18
|
+
asChild,
|
|
19
|
+
...props
|
|
20
|
+
}, forwardedRef) => {
|
|
21
|
+
const [isOpen, onOpenChange] = useControllableState.useControllableState(
|
|
22
|
+
controlledOpen === void 0 && defaultOpen === void 0 ? true : controlledOpen,
|
|
23
|
+
controlledOnOpenChange,
|
|
24
|
+
defaultOpen
|
|
25
|
+
);
|
|
26
|
+
const Component = asChild ? reactSlot.Slot : "div";
|
|
27
|
+
const id = react.useId();
|
|
28
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, {
|
|
29
|
+
value: { open: isOpen, onOpenChange, disabled, contentId: id },
|
|
30
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
31
|
+
...props,
|
|
32
|
+
ref: forwardedRef,
|
|
33
|
+
"data-state": isOpen ? "open" : "closed",
|
|
34
|
+
"data-disabled": disabled ? "" : void 0
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
const CollapsibleTrigger = react.forwardRef(
|
|
40
|
+
({ onClick, asChild, ...props }, forwardedRef) => {
|
|
41
|
+
const Component = asChild ? reactSlot.Slot : "button";
|
|
42
|
+
const context = react.useContext(CollapsibleContext);
|
|
43
|
+
if (!context) {
|
|
44
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
45
|
+
}
|
|
46
|
+
const { open, disabled, contentId, onOpenChange } = context;
|
|
47
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
48
|
+
...props,
|
|
49
|
+
ref: forwardedRef,
|
|
50
|
+
type: "button",
|
|
51
|
+
"aria-controls": contentId,
|
|
52
|
+
"aria-expanded": open || false,
|
|
53
|
+
"data-state": open ? "open" : "closed",
|
|
54
|
+
"data-disabled": disabled ? "" : void 0,
|
|
55
|
+
disabled,
|
|
56
|
+
onClick: (event) => {
|
|
57
|
+
onClick?.(event);
|
|
58
|
+
if (event.defaultPrevented)
|
|
59
|
+
return;
|
|
60
|
+
if (disabled)
|
|
61
|
+
return;
|
|
62
|
+
onOpenChange(!open);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
const CollapsibleContent = react.forwardRef(
|
|
68
|
+
({ asChild, ...props }, forwardedRef) => {
|
|
69
|
+
const Component = asChild ? reactSlot.Slot : "div";
|
|
70
|
+
const context = react.useContext(CollapsibleContext);
|
|
71
|
+
const divRef = react.useRef(null);
|
|
72
|
+
if (!context) {
|
|
73
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
74
|
+
}
|
|
75
|
+
const { open, onOpenChange, disabled, contentId } = context;
|
|
76
|
+
react.useEffect(() => {
|
|
77
|
+
const element = divRef.current;
|
|
78
|
+
if (element === null)
|
|
79
|
+
return;
|
|
80
|
+
const isHiddenUntilFoundSupported = "onbeforematch" in document.body;
|
|
81
|
+
if (!isHiddenUntilFoundSupported)
|
|
82
|
+
return;
|
|
83
|
+
function handleBeforeMatch() {
|
|
84
|
+
onOpenChange(true);
|
|
85
|
+
}
|
|
86
|
+
element.addEventListener("beforematch", handleBeforeMatch);
|
|
87
|
+
return () => {
|
|
88
|
+
element.removeEventListener("beforematch", handleBeforeMatch);
|
|
89
|
+
};
|
|
90
|
+
}, [onOpenChange]);
|
|
91
|
+
react.useEffect(() => {
|
|
92
|
+
const element = divRef.current;
|
|
93
|
+
if (element === null)
|
|
94
|
+
return;
|
|
95
|
+
if (open)
|
|
96
|
+
return;
|
|
97
|
+
const isHiddenUntilFoundSupported = "onbeforematch" in document.body;
|
|
98
|
+
if (!isHiddenUntilFoundSupported)
|
|
99
|
+
return;
|
|
100
|
+
element.setAttribute("hidden", "until-found");
|
|
101
|
+
return () => {
|
|
102
|
+
element.removeAttribute("hidden");
|
|
103
|
+
};
|
|
104
|
+
}, [open]);
|
|
105
|
+
react.useImperativeHandle(forwardedRef, () => {
|
|
106
|
+
return divRef.current;
|
|
107
|
+
}, []);
|
|
108
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
109
|
+
...props,
|
|
110
|
+
ref: divRef,
|
|
111
|
+
"data-state": open ? "open" : "closed",
|
|
112
|
+
"data-disabled": disabled ? "" : void 0,
|
|
113
|
+
id: contentId,
|
|
114
|
+
hidden: !open
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
if (process.env.NODE_ENV !== "production") {
|
|
119
|
+
CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;
|
|
120
|
+
CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;
|
|
121
|
+
CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
exports.Content = CollapsibleContent;
|
|
125
|
+
exports.Root = CollapsibleRoot;
|
|
126
|
+
exports.Trigger = CollapsibleTrigger;
|
|
127
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/Collapsible/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\n\nimport { useControllableState } from \"../../utils/use-controllable-state\";\nimport type { ContentProps, RootProps, TriggerProps } from \"./types\";\n\nconst COLLAPSIBLE_ROOT_NAME = \"CollapsibleRoot\";\nconst COLLAPSIBLE_TRIGGER_NAME = \"CollapsibleTrigger\";\nconst COLLAPSIBLE_CONTENT_NAME = \"CollapsibleContent\";\n\nconst CollapsibleContext = createContext<{\n open?: boolean;\n onOpenChange: (open: boolean) => void;\n disabled: boolean;\n contentId: string;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleRoot = forwardRef<HTMLDivElement, RootProps>(\n (\n {\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n defaultOpen,\n disabled = false,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const [isOpen, onOpenChange] = useControllableState(\n // If the collapsible is neither controlled nor uncontrolled, it defaults to controlled as open.\n controlledOpen === undefined && defaultOpen === undefined\n ? true\n : controlledOpen,\n controlledOnOpenChange,\n defaultOpen\n );\n const Component = asChild ? Slot : \"div\";\n const id = useId();\n\n return (\n <CollapsibleContext.Provider\n value={{ open: isOpen, onOpenChange, disabled, contentId: id }}\n >\n <Component\n {...props}\n ref={forwardedRef}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n />\n </CollapsibleContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleTrigger = forwardRef<HTMLButtonElement, TriggerProps>(\n ({ onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(CollapsibleContext);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, disabled, contentId, onOpenChange } = context;\n\n return (\n <Component\n {...props}\n ref={forwardedRef}\n type=\"button\"\n aria-controls={contentId}\n aria-expanded={open || false}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n disabled={disabled}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (disabled) return;\n onOpenChange(!open);\n }}\n />\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleContent = forwardRef<HTMLDivElement, ContentProps>(\n ({ asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const context = useContext(CollapsibleContext);\n const divRef = useRef<HTMLDivElement>(null);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, onOpenChange, disabled, contentId } = context;\n\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n function handleBeforeMatch() {\n onOpenChange(true);\n }\n\n // https://developer.chrome.com/articles/hidden-until-found/\n element.addEventListener(\"beforematch\", handleBeforeMatch);\n return () => {\n element.removeEventListener(\"beforematch\", handleBeforeMatch);\n };\n }, [onOpenChange]);\n\n // Passing `string` to `hidden` in JSX is not currently supported: https://github.com/facebook/react/issues/24740\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n if (open) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n element.setAttribute(\"hidden\", \"until-found\");\n return () => {\n element.removeAttribute(\"hidden\");\n };\n }, [open]);\n\n useImperativeHandle<\n HTMLDivElement | null,\n HTMLDivElement | null\n >(forwardedRef, () => {\n return divRef.current;\n }, []);\n\n return (\n <Component\n {...props}\n ref={divRef}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n id={contentId}\n hidden={!open}\n />\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;\n CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;\n CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as Collapsible.*\nexport {\n CollapsibleContent as Content,\n CollapsibleRoot as Root,\n CollapsibleTrigger as Trigger,\n};\n"],"names":["createContext","forwardRef","useControllableState","Slot","useId","jsx","useContext","useRef","useEffect","useImperativeHandle"],"mappings":"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"}
|