diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 2779b3e36a..78d216bdba 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -64,8 +64,8 @@ "test:e2e:update-snapshots": "npm run build && WLR_BACKENDS=headless WLR_NO_HARDWARE_CURSORS=1 cage -- npx playwright test e2e/ --reporter=list --update-snapshots" }, "dependencies": { - "@assistant-ui/react": "0.15.1", - "@assistant-ui/react-streamdown": "0.3.8", + "@assistant-ui/react": "0.14.24", + "@assistant-ui/react-streamdown": "0.3.5", "@audiowave/react": "0.6.2", "@chenglou/pretext": "0.0.6", "@codemirror/commands": "6.10.4", diff --git a/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.test.tsx b/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.test.tsx index 50ea8d09ec..7707c8ae75 100644 --- a/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.test.tsx +++ b/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.test.tsx @@ -10,11 +10,15 @@ import { type ComposerScope, ComposerScopeProvider, MAIN_COMPOSER_SCOPE } from ' import { useComposerDraft } from './use-composer-draft' -const mockComposerApi = { setText: vi.fn(), getState: () => ({ text: '' }) } +const mockComposerApi = { setText: vi.fn() } vi.mock('@assistant-ui/react', () => ({ - useAui: () => ({ composer: () => mockComposerApi, subscribe: () => () => undefined }), - useAuiState: (selector: (state: { composer: { text: string } }) => unknown) => selector({ composer: { text: '' } }) + useAui: () => ({ composer: () => mockComposerApi }), + useAuiState: (selector: (state: { composer: { text: string } }) => unknown) => selector({ composer: { text: '' } }), + useComposerRuntime: () => ({ + getState: () => ({ text: '' }), + subscribe: () => () => undefined + }) })) interface ProbeHarnessProps { diff --git a/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.ts b/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.ts index 034f180c42..b5bf87dc46 100644 --- a/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.ts +++ b/apps/desktop/src/app/chat/composer/hooks/use-composer-draft.ts @@ -1,4 +1,4 @@ -import { useAui, useAuiState } from '@assistant-ui/react' +import { useAui, useAuiState, useComposerRuntime } from '@assistant-ui/react' import { type RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react' import { SLASH_COMMAND_RE } from '@/lib/chat-runtime' @@ -58,6 +58,7 @@ export function useComposerDraft({ sessionId }: UseComposerDraftArgs) { const aui = useAui() + const composerRuntime = useComposerRuntime() // Which composer this is on the focus bus + which attachment set it owns. const { attachments: attachmentScope, target } = useComposerScope() @@ -78,7 +79,7 @@ export function useComposerDraft({ const setComposerText = useCallback( (value: string) => { try { - aui.composer.setText(value) + aui.composer().setText(value) } catch { // Composer core not bound yet — DOM/draftRef carry the text. } @@ -271,7 +272,7 @@ export function useComposerDraft({ // eslint-disable-next-line no-restricted-syntax -- legitimate non-atom ref write (see eslint rule comment) useEffect(() => { const sync = () => { - const text = aui.composer.getState().text + const text = composerRuntime.getState().text draftRef.current = text const editor = editorRef.current @@ -303,13 +304,13 @@ export function useComposerDraft({ }, DRAFT_PERSIST_DEBOUNCE_MS) } - const unsubscribe = aui.subscribe(sync) + const unsubscribe = composerRuntime.subscribe(sync) return () => { unsubscribe() window.clearTimeout(draftPersistTimerRef.current) } - }, [aui, queueEditRef]) + }, [composerRuntime, queueEditRef]) const insertText = (text: string) => { const base = draftRef.current diff --git a/apps/desktop/src/components/assistant-ui/thread/use-message-reactions.ts b/apps/desktop/src/components/assistant-ui/thread/use-message-reactions.ts index 9120dbb491..75b011c555 100644 --- a/apps/desktop/src/components/assistant-ui/thread/use-message-reactions.ts +++ b/apps/desktop/src/components/assistant-ui/thread/use-message-reactions.ts @@ -1,4 +1,4 @@ -import { useAui, useAuiState } from '@assistant-ui/react' +import { useAuiState, useMessageRuntime } from '@assistant-ui/react' import { useStore } from '@nanostores/react' import { type MouseEvent, useCallback } from 'react' @@ -106,7 +106,7 @@ export function useTapbackDoubleClick( role: ChatMessage['role'] ): ((event: MouseEvent) => void) | undefined { const enabled = useStore($reactionsEnabled) - const messageRuntime = useAui().message + const messageRuntime = useMessageRuntime() const onDoubleClick = useCallback( (event: MouseEvent) => { diff --git a/package-lock.json b/package-lock.json index 73bc3d9b15..fbb1d07182 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,8 @@ "typescript-eslint": "8.64.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=20.0.0", + "npm": "<11.10.0 || >=12.0.0" } }, "apps/bootstrap-installer": { @@ -70,8 +71,8 @@ "name": "hermes", "version": "0.17.0", "dependencies": { - "@assistant-ui/react": "0.15.1", - "@assistant-ui/react-streamdown": "0.3.8", + "@assistant-ui/react": "0.14.24", + "@assistant-ui/react-streamdown": "0.3.5", "@audiowave/react": "0.6.2", "@chenglou/pretext": "0.0.6", "@codemirror/commands": "6.10.4", @@ -169,6 +170,186 @@ "node": "^20.19.0 || >=22.12.0" } }, + "apps/desktop/node_modules/@assistant-ui/react": { + "version": "0.14.24", + "resolved": "https://registry.npmjs.org/@assistant-ui/react/-/react-0.14.24.tgz", + "integrity": "sha512-DHUEbJfn3EeApiLXJp6pZfwzGUwQ7aAoGeUfs8bmo1G9uAkRlxF1RKr7MwM/oVSUt+ixSsfWey+OuHJi5gtKCQ==", + "license": "MIT", + "dependencies": { + "@assistant-ui/core": "^0.2.19", + "@assistant-ui/store": "^0.2.19", + "@assistant-ui/tap": "^0.9.3", + "@radix-ui/primitive": "^1.1.4", + "@radix-ui/react-compose-refs": "^1.1.3", + "@radix-ui/react-context": "^1.1.4", + "@radix-ui/react-primitive": "^2.1.6", + "@radix-ui/react-use-callback-ref": "^1.1.2", + "@radix-ui/react-use-escape-keydown": "^1.1.2", + "assistant-cloud": "^0.1.34", + "assistant-stream": "^0.3.24", + "nanoid": "^5.1.15", + "radix-ui": "^1.6.0", + "react-textarea-autosize": "^8.5.9", + "safe-content-frame": "^0.0.21", + "zod": "^4.4.3", + "zustand": "^5.0.14" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "apps/desktop/node_modules/@assistant-ui/react-streamdown": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@assistant-ui/react-streamdown/-/react-streamdown-0.3.5.tgz", + "integrity": "sha512-xl4UoFGtCfeUk6T/F9d94djE4Vc2KPQ8I3vy7cV0fb8IGN63yHt/rVzehxMSX4XT81Qrpsa0KUQhJOo/8zxdkw==", + "license": "MIT", + "dependencies": { + "rehype-harden": "^1.1.8", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "remend": "^1.3.0", + "streamdown": "^2.5.0" + }, + "peerDependencies": { + "@assistant-ui/react": "^0.14.18", + "@streamdown/cjk": "^1.0.0", + "@streamdown/code": "^1.0.0", + "@streamdown/math": "^1.0.0", + "@streamdown/mermaid": "^1.0.0", + "@types/react": "*", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@streamdown/cjk": { + "optional": true + }, + "@streamdown/code": { + "optional": true + }, + "@streamdown/math": { + "optional": true + }, + "@streamdown/mermaid": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "apps/desktop/node_modules/@assistant-ui/react/node_modules/@assistant-ui/core": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@assistant-ui/core/-/core-0.2.23.tgz", + "integrity": "sha512-mD/sWrdH4SF1POxWE0Wn8jrxOSnuGOJfj8j5coDuEtdtoevQT3Z8LzD5mkd2UdyXHIkwFsMb3/vIL1kH8XKyGg==", + "license": "MIT", + "dependencies": { + "assistant-stream": "^0.3.28", + "nanoid": "^6.0.0" + }, + "peerDependencies": { + "@assistant-ui/store": "^0.2.13", + "@assistant-ui/tap": "^0.9.0", + "@types/react": "*", + "assistant-cloud": "^0.1.31", + "react": "^18 || ^19", + "zustand": "^5.0.11" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "assistant-cloud": { + "optional": true + }, + "react": { + "optional": true + }, + "zustand": { + "optional": true + } + } + }, + "apps/desktop/node_modules/@assistant-ui/react/node_modules/@assistant-ui/core/node_modules/nanoid": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-6.0.0.tgz", + "integrity": "sha512-mkUH+rPkwU2qPadJ0oJZOjeZ5Mxn8Q1UhevwkTRWNuUZzyia3h4rhzK39hxaHTk0o2OxB8W2SQ6A8k23ZDi1pQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^22 || ^24 || >=26" + } + }, + "apps/desktop/node_modules/@assistant-ui/react/node_modules/@assistant-ui/store": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@assistant-ui/store/-/store-0.2.22.tgz", + "integrity": "sha512-RdUFLOFJ3ZwIoOZYrRvps3OAODwnWoUAuNfqbROKrj5qtlQsIJRqxUNdLTjcf4AimhkjCwOaFacGHHm9lE4qBw==", + "license": "MIT", + "dependencies": { + "use-effect-event": "^2.0.3" + }, + "peerDependencies": { + "@assistant-ui/tap": "^0.9.0", + "@types/react": "*", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "apps/desktop/node_modules/@assistant-ui/react/node_modules/@assistant-ui/store/node_modules/use-effect-event": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/use-effect-event/-/use-effect-event-2.0.3.tgz", + "integrity": "sha512-fz1en+z3fYXCXx3nMB8hXDMuygBltifNKZq29zDx+xNJ+1vEs6oJlYd9sK31vxJ0YI534VUsHEBY0k2BATsmBQ==", + "license": "MIT", + "peerDependencies": { + "react": "^18.3 || ^19.0.0-0" + } + }, + "apps/desktop/node_modules/@assistant-ui/react/node_modules/nanoid": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz", + "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "apps/desktop/node_modules/safe-content-frame": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/safe-content-frame/-/safe-content-frame-0.0.21.tgz", + "integrity": "sha512-4LgYcX0lESOg9zVi6QCcqHaNGjZuc86w0IGRJij7lA4YG/6QHBblL2Jwh5OJBtkVSnhDOeARRpD3jvFNGiIWiw==", + "license": "MIT" + }, "apps/shared": { "name": "@hermes/shared", "version": "0.0.0", @@ -253,134 +434,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@assistant-ui/core": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@assistant-ui/core/-/core-0.3.2.tgz", - "integrity": "sha512-OXLoym/icUVPfgE3OrfNYkkL6sgscqZrQSoA/ru0ThIXPK69Yf6devhXzY6LAEcHFL4q/5TtZ/yI7YEy/W2D0w==", - "license": "MIT", - "dependencies": { - "assistant-stream": "^0.3.31", - "nanoid": "^6.0.0" - }, - "peerDependencies": { - "@assistant-ui/store": "^0.3.0", - "@assistant-ui/tap": "^0.9.0", - "@types/react": "*", - "assistant-cloud": "^0.1.31", - "react": "^18 || ^19", - "zustand": "^5.0.11" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "assistant-cloud": { - "optional": true - }, - "react": { - "optional": true - }, - "zustand": { - "optional": true - } - } - }, - "node_modules/@assistant-ui/react": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@assistant-ui/react/-/react-0.15.1.tgz", - "integrity": "sha512-SZdhTCL7HdfsOs3K9pqDLpUPrsigvKjt2TawGaY0bU/Wt//U/dbNN9bRdTYYZ5wbAOPfpm8TNvZoLSXjZSkm8g==", - "license": "MIT", - "dependencies": { - "@assistant-ui/core": "^0.3.1", - "@assistant-ui/store": "^0.3.1", - "@assistant-ui/tap": "^0.9.7", - "@radix-ui/primitive": "^1.1.7", - "@radix-ui/react-collection": "^1.1.15", - "@radix-ui/react-compose-refs": "^1.1.5", - "@radix-ui/react-context": "^1.2.2", - "@radix-ui/react-primitive": "^2.1.10", - "@radix-ui/react-use-callback-ref": "^1.1.4", - "@radix-ui/react-use-controllable-state": "^1.2.6", - "@radix-ui/react-use-escape-keydown": "^1.1.5", - "assistant-cloud": "^0.1.37", - "assistant-stream": "^0.3.30", - "nanoid": "^6.0.0", - "radix-ui": "^1.6.7", - "react-textarea-autosize": "^8.5.9", - "safe-content-frame": "^0.0.25", - "zod": "^4.4.3", - "zustand": "^5.0.14" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^18 || ^19", - "react-dom": "^18 || ^19" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@assistant-ui/react-streamdown": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@assistant-ui/react-streamdown/-/react-streamdown-0.3.8.tgz", - "integrity": "sha512-/wLO1wIrBWosmyliw2R1tN0XuMtaMLacLIIys3XRZ7X9F+5sBA9TxZOVx/lXRZeNWumI2jO8e+NdUFDUSOGmOQ==", - "license": "MIT", - "dependencies": { - "rehype-harden": "^1.1.8", - "rehype-raw": "^7.0.0", - "rehype-sanitize": "^6.0.0", - "remend": "^1.3.0", - "streamdown": "^2.5.0" - }, - "peerDependencies": { - "@assistant-ui/react": "^0.15.0", - "@streamdown/cjk": "^1.0.0", - "@streamdown/code": "^1.0.0", - "@streamdown/math": "^1.0.0", - "@streamdown/mermaid": "^1.0.0", - "@types/react": "*", - "react": "^18 || ^19" - }, - "peerDependenciesMeta": { - "@streamdown/cjk": { - "optional": true - }, - "@streamdown/code": { - "optional": true - }, - "@streamdown/math": { - "optional": true - }, - "@streamdown/mermaid": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@assistant-ui/store": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@assistant-ui/store/-/store-0.3.2.tgz", - "integrity": "sha512-D6NgnYEifDcusQd6CbokNutqfHA2OEr1sz0/+ds+Bc7xsm8ghRxkvBubtttIYQKaajALPPJbWcr/zcvGv21g0g==", - "license": "MIT", - "peerDependencies": { - "@assistant-ui/tap": "^0.9.0", - "@types/react": "*", - "react": "^18 || ^19" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@assistant-ui/tap": { "version": "0.9.8", "resolved": "https://registry.npmjs.org/@assistant-ui/tap/-/tap-0.9.8.tgz", @@ -4489,9 +4542,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4508,9 +4558,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4527,9 +4574,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4546,9 +4590,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4565,9 +4606,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4584,9 +4622,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5075,9 +5110,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5094,9 +5126,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5113,9 +5142,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5132,9 +5158,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5383,9 +5406,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 OR MIT", "optional": true, "os": [ @@ -5403,9 +5423,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0 OR MIT", "optional": true, "os": [ @@ -5423,9 +5440,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 OR MIT", "optional": true, "os": [ @@ -5443,9 +5457,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0 OR MIT", "optional": true, "os": [ @@ -5463,9 +5474,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0 OR MIT", "optional": true, "os": [ @@ -11974,9 +11982,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11997,9 +12002,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -12020,9 +12022,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -12043,9 +12042,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -16499,12 +16495,6 @@ "dev": true, "license": "MIT" }, - "node_modules/safe-content-frame": { - "version": "0.0.25", - "resolved": "https://registry.npmjs.org/safe-content-frame/-/safe-content-frame-0.0.25.tgz", - "integrity": "sha512-Oztqn3kWTbNzMlWSr6SQiUBPtLJLbjzaJUYtO7PN5SfC5PxtOrBnEfnVy0IMT7do1SGqUkd/o1KTSXMRS+FBMw==", - "license": "MIT" - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",