From efdf5dc562d3a821be9d8b2047e259a6b2381232 Mon Sep 17 00:00:00 2001 From: Nimesh Nayaju Date: Fri, 8 Aug 2025 10:17:00 -0400 Subject: [PATCH 1/6] Add query options to `useAiChats` and `useAiChatsSuspense` (#2576) --- CHANGELOG.md | 8 + packages/liveblocks-core/src/AiChatDB.ts | 87 +++++++ packages/liveblocks-core/src/ai.ts | 52 ++-- packages/liveblocks-core/src/index.ts | 1 + .../src/lib/__tests__/AiChatDB.test.ts | 239 ++++++++++++++++++ packages/liveblocks-core/src/types/ai.ts | 30 ++- packages/liveblocks-react/src/liveblocks.tsx | 23 +- packages/liveblocks-react/src/types/index.ts | 13 +- .../liveblocks-react/src/umbrella-store.ts | 72 ++++-- 9 files changed, 456 insertions(+), 69 deletions(-) create mode 100644 packages/liveblocks-core/src/AiChatDB.ts create mode 100644 packages/liveblocks-core/src/lib/__tests__/AiChatDB.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f355b664573..12b006f8751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ - Knowledge passed as a prop to `AiChat` no longer leaks that knowledge to other instances of `AiChat` that are currently mounted on screen. +### `@liveblocks/react` + +- Add `query` option to `useAiChats` to filter the current user’s AI chats by + metadata. Supports exact matches for string values, "contains all" for + string arrays, and filtering by absence using `null` (e.g. + `{ metadata: { archived: null } }`). + + ## v3.2.1 ### `@liveblocks/react-ui` diff --git a/packages/liveblocks-core/src/AiChatDB.ts b/packages/liveblocks-core/src/AiChatDB.ts new file mode 100644 index 00000000000..7cb02800e03 --- /dev/null +++ b/packages/liveblocks-core/src/AiChatDB.ts @@ -0,0 +1,87 @@ +import { MutableSignal } from "./lib/signals"; +import { SortedList } from "./lib/SortedList"; +import type { AiChat, AiChatsQuery, ISODateString } from "./types/ai"; + +export class AiChatDB { + #byId: Map; // A map of chat id to chat details + #chats: SortedList>; // Sorted list of non-deleted chats, most recent first + + public readonly signal: MutableSignal; + + constructor() { + this.#byId = new Map(); + this.#chats = SortedList.from>([], (c1, c2) => { + // Sort by 'lastMessageAt' if available, otherwise 'createdAt' (most recent first) + const d2 = c2.lastMessageAt ?? c2.createdAt; + const d1 = c1.lastMessageAt ?? c1.createdAt; + return d2 < d1 ? true : d2 === d1 ? c2.id < c1.id : false; + }); + + this.signal = new MutableSignal(this); + } + + public getEvenIfDeleted(chatId: string): AiChat | undefined { + return this.#byId.get(chatId); + } + + public markDeleted(chatId: string): void { + const chat = this.#byId.get(chatId); + if (chat === undefined || chat.deletedAt !== undefined) return; + this.upsert({ + ...chat, + deletedAt: new Date().toISOString() as ISODateString, + }); + } + + public upsert(chat: AiChat): void { + this.signal.mutate(() => { + // If the chat already exists, remove it before deciding whether to add the incoming one + const existingThread = this.#byId.get(chat.id); + if (existingThread !== undefined) { + if (existingThread.deletedAt !== undefined) return false; + + this.#chats.remove(existingThread); + this.#byId.delete(existingThread.id); + } + + // We only add non-deleted chats to the chat list + if (chat.deletedAt === undefined) { + this.#chats.add(chat); + } + this.#byId.set(chat.id, chat); + return true; + }); + } + + public findMany(query: AiChatsQuery): Omit[] { + return Array.from( + this.#chats.filter((chat) => { + // If metadata query is not provided, include all chats + if (query.metadata === undefined) return true; + + for (const [key, value] of Object.entries(query.metadata)) { + // If the value is null, check that the key does not exist in the chat's metadata + if (value === null) { + if (key in chat.metadata) return false; + } + // If the metadata key is a string, check for an exact match against the chat's metadata + else if (typeof value === "string") { + if (chat.metadata[key] !== value) return false; + } + // If the metadata key is an array, ensure all values are present in the chat's metadata array + else { + const chatValue = chat.metadata[key]; + if ( + !Array.isArray(chatValue) || + !value.every((v) => chatValue.includes(v)) + ) { + return false; + } + } + } + + return true; + }) + ); + } +} diff --git a/packages/liveblocks-core/src/ai.ts b/packages/liveblocks-core/src/ai.ts index fec3a42525d..43205ef11d4 100644 --- a/packages/liveblocks-core/src/ai.ts +++ b/packages/liveblocks-core/src/ai.ts @@ -1,3 +1,4 @@ +import { AiChatDB } from "./AiChatDB"; import { getBearerTokenFromAuthValue } from "./api-client"; import type { AuthValue } from "./auth-manager"; import type { Delegates, Status } from "./connection"; @@ -13,7 +14,6 @@ import { nanoid } from "./lib/nanoid"; import type { Resolve } from "./lib/Resolve"; import { shallow, shallow2 } from "./lib/shallow"; import { batch, DerivedSignal, MutableSignal, Signal } from "./lib/signals"; -import { SortedList } from "./lib/SortedList"; import { TreePool } from "./lib/TreePool"; import type { Brand, DistributiveOmit } from "./lib/utils"; import { raise, tryParseJson } from "./lib/utils"; @@ -30,6 +30,7 @@ import type { AiAssistantDeltaUpdate, AiChat, AiChatMessage, + AiChatsQuery, AiFailedAssistantMessage, AiGeneratingAssistantMessage, AiGenerationOptions, @@ -43,9 +44,9 @@ import type { ClientAiMsg, CmdId, CreateChatOptions, - Cursor, DeleteChatResponse, DeleteMessageResponse, + GetChatsOptions, GetChatsResponse, GetMessageTreeResponse, GetOrCreateChatResponse, @@ -767,28 +768,18 @@ function createStore_forChatMessages( } function createStore_forUserAiChats() { - // The foundation is the mutable signal, which is a simple Map (easy to make - // one-off updates to). But externally we expose a derived signal that - // produces a new lazy "object" copy of this map any time it changes. This - // plays better with React APIs. - const allChatsInclDeletedΣ = new MutableSignal( - SortedList.with((x, y) => y.createdAt < x.createdAt) - ); - const nonDeletedChatsΣ = DerivedSignal.from(() => - Array.from(allChatsInclDeletedΣ.get()).filter((c) => !c.deletedAt) - ); + const chatsDB = new AiChatDB(); function upsertMany(chats: AiChat[]) { - allChatsInclDeletedΣ.mutate((list) => { + batch(() => { for (const chat of chats) { - list.removeBy((c) => c.id === chat.id, 1); - list.add(chat); + chatsDB.upsert(chat); } }); } function upsert(chat: AiChat) { - upsertMany([chat]); + chatsDB.upsert(chat); } /** @@ -797,25 +788,22 @@ function createStore_forUserAiChats() { * we'll re-render those so they can display the chat is deleted. */ function markDeleted(chatId: string) { - allChatsInclDeletedΣ.mutate((list) => { - const chat = list.find((c) => c.id === chatId); - if (!chat) return false; - - upsert({ ...chat, deletedAt: now() }); - return undefined; - }); + chatsDB.markDeleted(chatId); } function getChatById(chatId: string) { - return Array.from(allChatsInclDeletedΣ.get()).find( - (chat) => chat.id === chatId - ); + return chatsDB.getEvenIfDeleted(chatId); + } + + function findMany(query: AiChatsQuery): AiChat[] { + return chatsDB.signal.get().findMany(query); } return { - chatsΣ: nonDeletedChatsΣ, getChatById, + findMany, + // Mutations upsert, upsertMany, @@ -835,7 +823,7 @@ export type Ai = { getStatus: () => Status; /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ - getChats: (options?: { cursor?: Cursor }) => Promise; + getChats: (options?: GetChatsOptions) => Promise; /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ getOrCreateChat: ( /** A unique identifier for the chat. */ @@ -878,7 +866,6 @@ export type Ai = { ) => Promise; /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ signals: { - chatsΣ: DerivedSignal; getChatMessagesForBranchΣ( chatId: string, branch?: MessageId @@ -891,6 +878,8 @@ export type Ai = { /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ getChatById: (chatId: string) => AiChat | undefined; /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ + queryChats: (query: AiChatsQuery) => AiChat[]; + /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ registerKnowledgeLayer: (uniqueLayerId: string) => LayerKey; /** @private This API will change, and is not considered stable. DO NOT RELY on it. */ deregisterKnowledgeLayer: (layerKey: LayerKey) => void; @@ -1192,10 +1181,11 @@ export function createAi(config: AiConfig): Ai { ); } - function getChats(options: { cursor?: Cursor } = {}) { + function getChats(options: GetChatsOptions = {}) { return sendClientMsgWithResponse({ cmd: "get-chats", cursor: options.cursor, + query: options.query, }); } @@ -1331,13 +1321,13 @@ export function createAi(config: AiConfig): Ai { getStatus: () => managedSocket.getStatus(), signals: { - chatsΣ: context.chatsStore.chatsΣ, getChatMessagesForBranchΣ: context.messagesStore.getChatMessagesForBranchΣ, getToolΣ: context.toolsStore.getToolΣ, }, getChatById: context.chatsStore.getChatById, + queryChats: context.chatsStore.findMany, registerKnowledgeLayer, deregisterKnowledgeLayer, updateKnowledge, diff --git a/packages/liveblocks-core/src/index.ts b/packages/liveblocks-core/src/index.ts index da11f7d8f8e..25b60000c9f 100644 --- a/packages/liveblocks-core/src/index.ts +++ b/packages/liveblocks-core/src/index.ts @@ -323,6 +323,7 @@ export type { AiAssistantMessage, AiChat, AiChatMessage, + AiChatsQuery, AiKnowledgeSource, AiReasoningPart, AiTextPart, diff --git a/packages/liveblocks-core/src/lib/__tests__/AiChatDB.test.ts b/packages/liveblocks-core/src/lib/__tests__/AiChatDB.test.ts new file mode 100644 index 00000000000..e3aafdae69c --- /dev/null +++ b/packages/liveblocks-core/src/lib/__tests__/AiChatDB.test.ts @@ -0,0 +1,239 @@ +import { AiChatDB } from "../../AiChatDB"; +import type { AiChat, ISODateString } from "../../types/ai"; + +function iso(s: string): ISODateString { + return new Date(s).toISOString() as ISODateString; +} + +function dummyAiChatData( + partial: Partial & Pick +): AiChat { + return { + id: partial.id, + title: partial.title ?? `title-${partial.id}`, + metadata: partial.metadata ?? {}, + createdAt: partial.createdAt ?? iso("2024-01-01T00:00:00Z"), + lastMessageAt: partial.lastMessageAt, + deletedAt: partial.deletedAt, + } as AiChat; +} + +describe("AiChatDB", () => { + test("upsert adds and sorts by lastMessageAt then createdAt (most recent first)", () => { + const db = new AiChatDB(); + + const a = dummyAiChatData({ + id: "a", + createdAt: iso("2024-01-01T00:00:00Z"), + }); + const b = dummyAiChatData({ + id: "b", + createdAt: iso("2024-01-02T00:00:00Z"), + }); + const c = dummyAiChatData({ + id: "c", + createdAt: iso("2024-01-01T00:00:00Z"), + lastMessageAt: iso("2024-01-03T00:00:00Z"), + }); + + db.upsert(a); + db.upsert(b); + db.upsert(c); + + const ids = db.findMany({}).map((ch) => ch.id); + expect(ids).toEqual(["c", "b", "a"]); + }); + + test("tie-breaker: same timestamps are ordered by id (descending)", () => { + const db = new AiChatDB(); + + const a = dummyAiChatData({ + id: "a", + createdAt: iso("2024-01-01T00:00:00Z"), + }); + const b = dummyAiChatData({ + id: "b", + createdAt: iso("2024-01-01T00:00:00Z"), + }); + db.upsert(a); + db.upsert(b); + + const ids = db.findMany({}).map((ch) => ch.id); + // With equal createdAt, comparator places higher id first + expect(ids).toEqual(["b", "a"]); + }); + + test("markDeleted removes from sorted list but keeps in map (getEvenIfDeleted)", () => { + const db = new AiChatDB(); + const x = dummyAiChatData({ id: "x" }); + db.upsert(x); + + expect(db.findMany({}).map((c) => c.id)).toEqual(["x"]); + + db.markDeleted("x"); + + expect(db.findMany({})).toEqual([]); + const stored = db.getEvenIfDeleted("x"); + expect(stored?.id).toBe("x"); + expect(stored?.deletedAt).toBeDefined(); + + // Re-marking a deleted chat is a no-op + const deletedAt = stored!.deletedAt; + db.markDeleted("x"); + expect(db.getEvenIfDeleted("x")?.deletedAt).toBe(deletedAt); + }); + + test("upsert of a previously deleted chat id is ignored", () => { + const db = new AiChatDB(); + const y = dummyAiChatData({ + id: "y", + createdAt: iso("2024-01-01T00:00:00Z"), + }); + db.upsert(y); + db.markDeleted("y"); + + // Attempt to resurrect with newer timestamps should be ignored + db.upsert( + dummyAiChatData({ id: "y", createdAt: iso("2025-01-01T00:00:00Z") }) + ); + + expect(db.findMany({})).toEqual([]); // still excluded from list + const stored = db.getEvenIfDeleted("y"); + expect(stored?.deletedAt).toBeDefined(); + expect(stored?.createdAt).toBe(iso("2024-01-01T00:00:00Z")); + }); + + test("upserting a chat already deleted (incoming deletedAt) stores in map but not in list", () => { + const db = new AiChatDB(); + const z = dummyAiChatData({ + id: "z", + deletedAt: iso("2024-01-10T00:00:00Z"), + }); + db.upsert(z); + + expect(db.findMany({})).toEqual([]); + expect(db.getEvenIfDeleted("z")?.deletedAt).toBeDefined(); + }); + + describe("metadata filtering", () => { + test("no metadata query returns all non-deleted chats", () => { + const db = new AiChatDB(); + db.upsert(dummyAiChatData({ id: "m1", metadata: { a: "1" } })); + db.upsert(dummyAiChatData({ id: "m2", metadata: { b: ["x", "y"] } })); + db.upsert(dummyAiChatData({ id: "m3", metadata: {} })); + db.upsert( + dummyAiChatData({ + id: "m4", + metadata: { a: "2" }, + deletedAt: iso("2024-01-01T00:00:00Z"), + }) + ); + + const ids = db.findMany({}).map((c) => c.id); + expect(ids.sort()).toEqual(["m1", "m2", "m3"].sort()); + }); + + test("string exact match for single metadata key", () => { + const db = new AiChatDB(); + db.upsert(dummyAiChatData({ id: "s1", metadata: { tag: "urgent" } })); + db.upsert(dummyAiChatData({ id: "s2", metadata: { tag: "normal" } })); + db.upsert(dummyAiChatData({ id: "s3", metadata: {} })); + db.upsert( + dummyAiChatData({ id: "s4", metadata: { tag: ["urgent"] } as any }) + ); + + const ids = db.findMany({ metadata: { tag: "urgent" } }).map((c) => c.id); + // Only s1 matches exactly; s4 has array and should NOT match string + expect(ids).toEqual(["s1"]); + }); + + test("array requires all values present and metadata value must be an array", () => { + const db = new AiChatDB(); + db.upsert( + dummyAiChatData({ + id: "a1", + metadata: { tag: ["urgent", "p1", "work"] }, + }) + ); + db.upsert(dummyAiChatData({ id: "a2", metadata: { tag: ["urgent"] } })); + db.upsert( + dummyAiChatData({ id: "a3", metadata: { tag: "urgent" } as any }) + ); + db.upsert(dummyAiChatData({ id: "a4", metadata: { tag: ["p1"] } })); + + const ids = db + .findMany({ metadata: { tag: ["urgent", "p1"] } }) + .map((c) => c.id) + .sort(); + expect(ids).toEqual(["a1"].sort()); + }); + + test("null means key must be absent", () => { + const db = new AiChatDB(); + db.upsert(dummyAiChatData({ id: "n1", metadata: {} })); + db.upsert(dummyAiChatData({ id: "n2", metadata: { archived: "yes" } })); + db.upsert(dummyAiChatData({ id: "n3", metadata: { archived: "" } })); + + const ids = db + .findMany({ metadata: { archived: null } }) + .map((c) => c.id); + expect(ids.sort()).toEqual(["n1"].sort()); + }); + + test("multiple metadata keys are AND-ed", () => { + const db = new AiChatDB(); + db.upsert( + dummyAiChatData({ + id: "m1", + metadata: { team: "alpha", tag: ["urgent", "p1"] }, + }) + ); + db.upsert( + dummyAiChatData({ id: "m2", metadata: { team: "alpha", tag: ["p1"] } }) + ); + db.upsert( + dummyAiChatData({ + id: "m3", + metadata: { team: "beta", tag: ["urgent", "p1"] }, + }) + ); + db.upsert( + dummyAiChatData({ id: "m4", metadata: { tag: ["urgent", "p1"] } }) + ); + + const ids = db + .findMany({ metadata: { team: "alpha", tag: ["urgent", "p1"] } }) + .map((c) => c.id); + expect(ids).toEqual(["m1"]); + }); + + test("filter respects sorting order of results", () => { + const db = new AiChatDB(); + db.upsert( + dummyAiChatData({ + id: "r1", + metadata: { tag: ["x"] }, + createdAt: iso("2024-01-01T00:00:00Z"), + }) + ); + db.upsert( + dummyAiChatData({ + id: "r2", + metadata: { tag: ["x"] }, + lastMessageAt: iso("2024-02-01T00:00:00Z"), + }) + ); + db.upsert( + dummyAiChatData({ + id: "r3", + metadata: { tag: ["x"] }, + createdAt: iso("2024-01-15T00:00:00Z"), + }) + ); + db.upsert(dummyAiChatData({ id: "r4", metadata: { tag: ["y"] } })); + + const ids = db.findMany({ metadata: { tag: ["x"] } }).map((c) => c.id); + expect(ids).toEqual(["r2", "r3", "r1"]); + }); + }); +}); diff --git a/packages/liveblocks-core/src/types/ai.ts b/packages/liveblocks-core/src/types/ai.ts index 553413e5b28..a0c86246b2e 100644 --- a/packages/liveblocks-core/src/types/ai.ts +++ b/packages/liveblocks-core/src/types/ai.ts @@ -76,7 +76,11 @@ export type SetToolResultResponse = ServerCmdResponse; type GetChatsPair = DefineCmd< "get-chats", - { cursor?: Cursor; pageSize?: number }, + { + cursor?: Cursor; + pageSize?: number; + query?: { metadata?: Record }; + }, { chats: AiChat[]; nextCursor: Cursor | null } >; @@ -87,6 +91,30 @@ export type CreateChatOptions = { metadata?: Record; }; +export type AiChatsQuery = { + metadata?: Record; +}; + +export type GetChatsOptions = { + /** + * The cursor to use for pagination. + */ + cursor?: Cursor; + /** + * The query (including metadata) to filter chats by. If provided, only chats + * that match the query will be returned. If not provided, all chats will be returned. + * @example + * ``` + * // Filter by presence of metadata values + * { metadata: { tag: ["urgent"] } } + * + * // Filter by absence of metadata key (key must not exist) + * { metadata: { archived: null } } + * ``` + */ + query?: AiChatsQuery; +}; + type GetOrCreateChatPair = DefineCmd< "get-or-create-chat", { diff --git a/packages/liveblocks-react/src/liveblocks.tsx b/packages/liveblocks-react/src/liveblocks.tsx index 91f4bd9c96a..ead0d10607c 100644 --- a/packages/liveblocks-react/src/liveblocks.tsx +++ b/packages/liveblocks-react/src/liveblocks.tsx @@ -66,13 +66,18 @@ import type { ThreadsAsyncResult, ThreadsAsyncSuccess, UnreadInboxNotificationsCountAsyncResult, + UseAiChatsOptions, UserAsyncResult, UserAsyncSuccess, UseSendAiMessageOptions, UseSyncStatusOptions, UseUserThreadsOptions, } from "./types"; -import { makeUserThreadsQueryKey, UmbrellaStore } from "./umbrella-store"; +import { + makeAiChatsQueryKey, + makeUserThreadsQueryKey, + UmbrellaStore, +} from "./umbrella-store"; import { useSignal } from "./use-signal"; import { useSyncExternalStoreWithSelector } from "./use-sync-external-store-with-selector"; @@ -960,14 +965,16 @@ function useRoomInfoSuspense_withClient(client: OpaqueClient, roomId: string) { * @example * const { chats } = useAiChats(); */ -function useAiChats(): AiChatsAsyncResult { +function useAiChats(options?: UseAiChatsOptions): AiChatsAsyncResult { const client = useClient(); const store = getUmbrellaStoreForClient(client); + const queryKey = makeAiChatsQueryKey(options?.query); + useEnsureAiConnection(client); useEffect( - () => void store.outputs.aiChats.waitUntilLoaded() + () => void store.outputs.aiChats.getOrCreate(queryKey).waitUntilLoaded() // NOTE: Deliberately *not* using a dependency array here! // @@ -979,10 +986,10 @@ function useAiChats(): AiChatsAsyncResult { // *next* render after that, a *new* fetch/promise will get created. ); - return useSignal(store.outputs.aiChats.signal, identity, shallow); + return useSignal(store.outputs.aiChats.getOrCreate(queryKey).signal, identity, shallow); } -function useAiChatsSuspense(): AiChatsAsyncSuccess { +function useAiChatsSuspense(options?: UseAiChatsOptions): AiChatsAsyncSuccess { // Throw error if we're calling this hook server side ensureNotServerSide(); @@ -991,9 +998,11 @@ function useAiChatsSuspense(): AiChatsAsyncSuccess { useEnsureAiConnection(client); - use(store.outputs.aiChats.waitUntilLoaded()); + const queryKey = makeAiChatsQueryKey(options?.query); + + use(store.outputs.aiChats.getOrCreate(queryKey).waitUntilLoaded()); - const result = useAiChats(); + const result = useAiChats(options); assert(!result.error, "Did not expect error"); assert(!result.isLoading, "Did not expect loading"); return result; diff --git a/packages/liveblocks-react/src/types/index.ts b/packages/liveblocks-react/src/types/index.ts index 69b157a8309..e7220787769 100644 --- a/packages/liveblocks-react/src/types/index.ts +++ b/packages/liveblocks-react/src/types/index.ts @@ -16,6 +16,7 @@ import type { import type { AiChat, AiChatMessage, + AiChatsQuery, AsyncError, AsyncLoading, AsyncResult, @@ -76,6 +77,14 @@ export type UseSendAiMessageOptions = { timeout?: number; }; +export type UseAiChatsOptions = { + /** + * The query (including metadata) to filter the chats by. If provided, only chats + * that match the query will be returned. If not provided, all chats will be returned. + */ + query?: AiChatsQuery; +}; + export type ThreadsQuery = { /** * Whether to only return threads marked as resolved or unresolved. If not provided, @@ -1320,7 +1329,7 @@ export type LiveblocksContextBundle< * @example * const { chats, error, isLoading } = useAiChats(); */ - useAiChats(): AiChatsAsyncResult; + useAiChats(options?: UseAiChatsOptions): AiChatsAsyncResult; /** * (Private beta) Returns the messages in the given chat. @@ -1384,7 +1393,7 @@ export type LiveblocksContextBundle< * @example * const { chats } = useAiChats(); */ - useAiChats(): AiChatsAsyncSuccess; + useAiChats(options?: UseAiChatsOptions): AiChatsAsyncSuccess; /** * (Private beta) Returns the messages in the given chat. diff --git a/packages/liveblocks-react/src/umbrella-store.ts b/packages/liveblocks-react/src/umbrella-store.ts index 20c27736eda..0eb8e4340c4 100644 --- a/packages/liveblocks-react/src/umbrella-store.ts +++ b/packages/liveblocks-react/src/umbrella-store.ts @@ -1,4 +1,5 @@ import type { + AiChatsQuery, AsyncResult, BaseMetadata, BaseUserMeta, @@ -255,6 +256,12 @@ export function makeUserThreadsQueryKey( return stableStringify(query ?? {}); } +export function makeAiChatsQueryKey( + query: AiChatsQuery | undefined +): AiChatsQueryKey { + return stableStringify(query ?? {}); +} + /** * Like Promise, except it will have a synchronously readable `status` * field, indicating the status of the promise. @@ -550,6 +557,8 @@ type RoomId = string; type UserQueryKey = string; type RoomQueryKey = string; +type AiChatsQueryKey = string; + /** * A lookup table (LUT) for all the history versions. */ @@ -1015,7 +1024,10 @@ export class UmbrellaStore { LoadableResource >; readonly notificationSettings: LoadableResource; - readonly aiChats: LoadableResource; + readonly aiChats: DefaultMap< + AiChatsQueryKey, + LoadableResource + >; readonly messagesByChatId: DefaultMap< string, DefaultMap> @@ -1042,9 +1054,6 @@ export class UmbrellaStore { // Notification Settings #notificationSettings: SinglePageResource; - // Copilot chats - #aiChats: PaginatedResource; - constructor(client: OpaqueClient) { this.#client = client[kInternal].as(); @@ -1084,13 +1093,6 @@ export class UmbrellaStore { notificationSettingsFetcher ); - this.#aiChats = new PaginatedResource(async (cursor?: string) => { - const result = await this.#client[kInternal].ai.getChats({ - cursor: cursor as Cursor, - }); - return result.nextCursor; - }); - this.threads = new ThreadDB(); this.subscriptions = createStore_forSubscriptions( @@ -1363,24 +1365,38 @@ export class UmbrellaStore { waitUntilLoaded: this.#notificationSettings.waitUntilLoaded, }; - const aiChats: LoadableResource = { - signal: DerivedSignal.from((): AiChatsAsyncResult => { - const result = this.#aiChats.get(); - if (result.isLoading || result.error) { - return result; - } + const aiChats = new DefaultMap( + (queryKey: AiChatsQueryKey): LoadableResource => { + const query = JSON.parse(queryKey) as AiChatsQuery; + const resource = new PaginatedResource(async (cursor?: string) => { + const result = await this.#client[kInternal].ai.getChats({ + cursor: cursor as Cursor, + query, + }); + return result.nextCursor; + }); - return { - isLoading: false, - chats: this.#client[kInternal].ai.signals.chatsΣ.get(), - hasFetchedAll: result.data.hasFetchedAll, - isFetchingMore: result.data.isFetchingMore, - fetchMore: result.data.fetchMore, - fetchMoreError: result.data.fetchMoreError, - }; - }, shallow), - waitUntilLoaded: this.#aiChats.waitUntilLoaded, - }; + const signal = DerivedSignal.from((): AiChatsAsyncResult => { + const result = resource.get(); + if (result.isLoading || result.error) { + return result; + } + + const chats = this.#client[kInternal].ai.queryChats(query); + + return { + isLoading: false, + chats, + hasFetchedAll: result.data.hasFetchedAll, + isFetchingMore: result.data.isFetchingMore, + fetchMore: result.data.fetchMore, + fetchMoreError: result.data.fetchMoreError, + }; + }, shallow); + + return { signal, waitUntilLoaded: resource.waitUntilLoaded }; + } + ); const messagesByChatId = new DefaultMap((chatId: string) => { const resourceΣ = new SinglePageResource(async () => { From e8cca7a2dbc46161e4712982fad8717d6ba32aec Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 8 Aug 2025 10:18:40 -0400 Subject: [PATCH 2/6] Add account deletion documentation (#2573) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: adrien.gaudon@liveblocks.io Co-authored-by: Nimesh Nayaju --- assets/account-management/delete-account.png | Bin 0 -> 252337 bytes docs/pages/platform/account-management.mdx | 1 + .../account-management/delete-an-account.mdx | 33 ++++++++++++++++++ docs/routes.json | 4 +++ 4 files changed, 38 insertions(+) create mode 100644 assets/account-management/delete-account.png create mode 100644 docs/pages/platform/account-management/delete-an-account.mdx diff --git a/assets/account-management/delete-account.png b/assets/account-management/delete-account.png new file mode 100644 index 0000000000000000000000000000000000000000..506f85dab0f8050d9f68774f634e560ac2abe0f7 GIT binary patch literal 252337 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 literal 0 HcmV?d00001 diff --git a/docs/pages/platform/account-management.mdx b/docs/pages/platform/account-management.mdx index 7711e5861fb..9677ddc86f1 100644 --- a/docs/pages/platform/account-management.mdx +++ b/docs/pages/platform/account-management.mdx @@ -12,3 +12,4 @@ accounts and teams. - [Manage team members](/docs/platform/account-management/manage-team-members) - [Configure SSO](/docs/platform/account-management/saml) - [Configure Directory sync](/docs/platform/account-management/directory-sync) +- [Delete an account](/docs/platform/account-management/delete-an-account) diff --git a/docs/pages/platform/account-management/delete-an-account.mdx b/docs/pages/platform/account-management/delete-an-account.mdx new file mode 100644 index 00000000000..35f1d5d5b1f --- /dev/null +++ b/docs/pages/platform/account-management/delete-an-account.mdx @@ -0,0 +1,33 @@ +--- +meta: + title: "Delete an account" + parentTitle: "Platform" + description: "Learn how to delete your Liveblocks account and data." +--- + + + +Please note that this action is **irreversible**. All data associated with your +account will be permanently deleted, and any applications running on Liveblocks +will stop working. + + + +To delete your account, click on the user dropdown in the Liveblocks dashboard +and go to **Personal settings**. Once there, click **Delete account** and follow +the on-screen instructions to confirm deletion. + +
+ Delete your Liveblocks account +
+ +## Getting help + +If you need further assistance with account deletion or have questions about +what data will be removed, contact us at +[support@liveblocks.io](mailto:support@liveblocks.io). diff --git a/docs/routes.json b/docs/routes.json index 9f4ea32d320..7bfa1ae323e 100644 --- a/docs/routes.json +++ b/docs/routes.json @@ -662,6 +662,10 @@ { "title": "Directory sync", "path": "/platform/account-management/directory-sync" + }, + { + "title": "Delete an account", + "path": "/platform/account-management/delete-an-account" } ] }, From 5fd4f71ec4a98b33372088c9000793fd4f6d57fa Mon Sep 17 00:00:00 2001 From: Marc Bouchenoire Date: Fri, 8 Aug 2025 16:42:36 +0200 Subject: [PATCH 3/6] Release: 3.3 (#2554) Co-authored-by: Chris Nicholas Co-authored-by: Vincent Driessen Co-authored-by: Nimesh Nayaju --- CHANGELOG.md | 33 +- .../liveblocks-react-lexical.mdx | 102 ++++ .../api-reference/liveblocks-react-tiptap.mdx | 108 ++++ .../api-reference/liveblocks-react-ui.mdx | 41 ++ docs/pages/api-reference/liveblocks-react.mdx | 82 ++- .../app/chats/[chatId]/chat-composer.tsx | 12 +- .../app/chats/[chatId]/user-message.tsx | 12 +- e2e/next-ai-kitchen-sink/app/styles/page.tsx | 2 +- .../test/knowledge-isolation.test.ts | 20 +- .../test/knowledge-simple.test.ts | 6 +- .../test/knowledge.test.ts | 12 +- .../test/simple-chat.test.ts | 6 +- .../test/tool-calling.test.ts | 19 +- packages/liveblocks-core/src/index.ts | 7 +- packages/liveblocks-core/src/lib/utils.ts | 6 + .../src/comments/floating-composer.tsx | 59 +- .../src/comments/floating-threads.tsx | 4 +- .../liveblocks-react-lexical/src/index.ts | 1 + .../src/comments/AnchoredThreads.tsx | 3 +- .../src/comments/FloatingComposer.tsx | 54 +- .../src/comments/FloatingThreads.tsx | 6 +- .../liveblocks-react-ui/src/_private/index.ts | 11 +- .../src/components/AiChat.tsx | 22 +- .../src/components/Thread.tsx | 136 +++++ .../components/internal/AiChatComposer.tsx | 262 --------- .../src/components/internal/AiComposer.tsx | 228 ++++++++ .../src/components/internal/Button.tsx | 1 + packages/liveblocks-react-ui/src/index.ts | 5 +- .../liveblocks-react-ui/src/overrides.tsx | 19 +- .../src/primitives/AiChatComposer/index.tsx | 317 ----------- .../src/primitives/AiChatComposer/types.ts | 45 -- .../src/primitives/AiComposer/contexts.ts | 94 ++++ .../src/primitives/AiComposer/index.tsx | 522 ++++++++++++++++++ .../src/primitives/AiComposer/types.ts | 72 +++ .../src/primitives/index.ts | 1 + .../liveblocks-react-ui/src/styles/index.css | 46 +- .../liveblocks-react/scripts/check-exports.ts | 2 + packages/liveblocks-react/src/index.ts | 1 + .../liveblocks-react/src/lib/use-polyfill.ts | 20 +- packages/liveblocks-react/src/liveblocks.tsx | 142 ++++- packages/liveblocks-react/src/suspense.ts | 1 + packages/liveblocks-react/src/types/index.ts | 118 +++- 42 files changed, 1879 insertions(+), 781 deletions(-) delete mode 100644 packages/liveblocks-react-ui/src/components/internal/AiChatComposer.tsx create mode 100644 packages/liveblocks-react-ui/src/components/internal/AiComposer.tsx delete mode 100644 packages/liveblocks-react-ui/src/primitives/AiChatComposer/index.tsx delete mode 100644 packages/liveblocks-react-ui/src/primitives/AiChatComposer/types.ts create mode 100644 packages/liveblocks-react-ui/src/primitives/AiComposer/contexts.ts create mode 100644 packages/liveblocks-react-ui/src/primitives/AiComposer/index.tsx create mode 100644 packages/liveblocks-react-ui/src/primitives/AiComposer/types.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 12b006f8751..1b4e7c45473 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,42 @@ ## vNEXT (not yet published) +## v3.3.0 + ### `@liveblocks/react-ui` -- Knowledge passed as a prop to `AiChat` no longer leaks that knowledge to other - instances of `AiChat` that are currently mounted on screen. +- Add `maxVisibleComments` prop to `Thread` to control the maximum number of + comments to show. When comments are hidden, a "Show more replies" button is + shown to allow users to expand the thread. +- Add `onComposerSubmit` callback to `AiChat` triggered when a new message is + sent. It can also be used to customize message submission by calling + `useSendAiMessage` yourself. +- Overrides and CSS classes for `AiChat`'s composer have been renamed: + - Overrides: `AI_CHAT_COMPOSER_SEND` → `AI_COMPOSER_PLACEHOLDER` + - CSS classes: `.lb-ai-chat-composer-form` → `.lb-ai-composer-form` +- Fix: knowledge passed as a prop to `AiChat` no longer leaks that knowledge to + other instances of `AiChat` that are currently mounted on screen. ### `@liveblocks/react` - Add `query` option to `useAiChats` to filter the current user’s AI chats by - metadata. Supports exact matches for string values, "contains all" for - string arrays, and filtering by absence using `null` (e.g. + metadata. Supports exact matches for string values, "contains all" for string + arrays, and filtering by absence using `null` (e.g. `{ metadata: { archived: null } }`). +- `useSendAiMessage` now accepts passing the chat ID and/or options to the + function rather than the hook. This can be useful in dynamic scenarios where + the chat ID might not be known when calling the hook for example. +- `useCreateAiChat` now accepts a chat ID as a string instead of + `{ id: "chat-id" }`. + +### `@liveblocks/react-tiptap` and `@liveblocks/react-lexical` + +- Allow using custom composers in `FloatingComposer` via the + `components={{ Composer }}` prop. + +### `@liveblocks/react-lexical` +- Add `ATTACH_THREAD_COMMAND` command to manually create a thread attached to + the current selection. ## v3.2.1 diff --git a/docs/pages/api-reference/liveblocks-react-lexical.mdx b/docs/pages/api-reference/liveblocks-react-lexical.mdx index 8b00fc1ea45..d816ce40c7a 100644 --- a/docs/pages/api-reference/liveblocks-react-lexical.mdx +++ b/docs/pages/api-reference/liveblocks-react-lexical.mdx @@ -1018,6 +1018,95 @@ function Toolbar() { } ``` +#### Customization [#FloatingComposer-customization] + +The `FloatingComposer` components acts as a wrapper around a [`Composer`][], +near the current selection. You can treat the component like you would a `form`, +using classes, listeners, and more. + +```tsx + +``` + +To apply styling to the composer, you can pass a custom `Composer` property to +`components` and modify this in any way. + +```tsx +import { Composer } from "@liveblocks/react-ui"; + + ( + + ), + }} + // +++ +/>; +``` + +You can return any custom `ReactNode` here, including anything from a simple +wrapper around `Composer`, up to a full custom `Composer` component built using +our +[Composer primitives](/docs/api-reference/liveblocks-react-ui#primitives-Composer). + +```tsx +import { Composer } from "@liveblocks/react-ui/primitives"; + + ( + + + Send + + ), + // +++ + }} +/>; +``` + +You can also customize submission behavior by passing a custom +`onComposerSubmit` function to the `Composer.Form` component. + +```tsx +import { Composer } from "@liveblocks/react-ui/primitives"; + + ( + { + event.preventDefault(); + + const thread = createThread({ + body: comment.body, + attachments: comment.attachments, + metadata: ..., + }); + + editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id); + }} + // +++ + > + + Send + + ) + }} +/>; +``` + #### Props [#FloatingComposer-props] @@ -1061,6 +1150,19 @@ function Toolbar() { > Override the component’s strings. + + Override the component’s components. + + + Override the [`Composer`](/docs/api-reference/liveblocks-react-ui#Composer) + component. + ### FloatingThreads diff --git a/docs/pages/api-reference/liveblocks-react-tiptap.mdx b/docs/pages/api-reference/liveblocks-react-tiptap.mdx index ef57fa42db4..54246a0023a 100644 --- a/docs/pages/api-reference/liveblocks-react-tiptap.mdx +++ b/docs/pages/api-reference/liveblocks-react-tiptap.mdx @@ -936,6 +936,101 @@ function Toolbar({ editor }: { editor: Editor | null }) { } ``` +#### Customization [#FloatingComposer-customization] + +The `FloatingComposer` components acts as a wrapper around a [`Composer`][], +near the current selection. You can treat the component like you would a `form`, +using classes, listeners, and more. + +```tsx + +``` + +To apply styling to the composer, you can pass a custom `Composer` property to +`components` and modify this in any way. + +```tsx +import { Composer } from "@liveblocks/react-ui"; + + ( + + ), + }} + // +++ +/>; +``` + +You can return any custom `ReactNode` here, including anything from a simple +wrapper around `Composer`, up to a full custom `Composer` component built using +our +[Composer primitives](/docs/api-reference/liveblocks-react-ui#primitives-Composer). + +```tsx +import { Composer } from "@liveblocks/react-ui/primitives"; + + ( + // +++ + + + Send + + // +++ + ), + }} +/>; +``` + +You can also customize submission behavior by passing a custom +`onComposerSubmit` function to the `Composer.Form` component. + +```tsx +import { Composer } from "@liveblocks/react-ui/primitives"; + + ( + { + event.preventDefault(); + + const thread = createThread({ + body: comment.body, + attachments: comment.attachments, + metadata: ..., + }); + + editor.commands.addComment(thread.id); + }} + // +++ + > + + Send + + ), + }} +/>; +``` + #### Props [#FloatingComposer-props] @@ -979,6 +1074,19 @@ function Toolbar({ editor }: { editor: Editor | null }) { > Override the component’s strings. + + Override the component’s components. + + + Override the [`Composer`](/docs/api-reference/liveblocks-react-ui#Composer) + component. + ### FloatingThreads diff --git a/docs/pages/api-reference/liveblocks-react-ui.mdx b/docs/pages/api-reference/liveblocks-react-ui.mdx index 8d142368ed7..0be802a4427 100644 --- a/docs/pages/api-reference/liveblocks-react-ui.mdx +++ b/docs/pages/api-reference/liveblocks-react-ui.mdx @@ -437,6 +437,13 @@ the `components` prop. A full list is [available here](#AiChat-components). Object mapping tool names to tool definitions that should be available in this chat. + + The event handler called when the composer is submitted. + The layout mode for the chat. Use `'inset'` (default) for standalone chats, or `'compact'` for embedded scenarios like pop-up windows. @@ -893,6 +900,32 @@ and [`useMarkThreadAsUnresolved`](/docs/api-reference/liveblocks-react#useMarkThreadAsUnresolved) to update the property. +##### Collapsed threads + +You can collapse threads by setting the `maxVisibleComments` prop. If a thread +contains more comments than the limit set, some of the comments will be hidden +and a "Show more replies" button will be displayed instead. Clicking on it will +expand the thread to show all comments. + +```tsx + +``` + +The first and last comments are always visible, and by default the oldest +comments are more likely to be hidden. You can customize this behavior by +setting `maxVisibleComments` to an object. + +```tsx +// This is the default behavior, the same as `maxVisibleComments={5}`. + + +// Only show the last comment, and all the older ones to fit the limit. + + +// Show as many old comments as new ones to fit the limit. + +``` + ##### Props [#Thread-props] @@ -940,6 +973,14 @@ to update the property. > Whether to show the action to resolve the thread. + + The maximum number of comments to show. +
-
{abortableMessageId === null ? ( - event.preventDefault()} aria-label="Send" className="inline-flex size-7.5 rounded-full items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed bg-neutral-900 text-white hover:bg-neutral-800 dark:bg-neutral-100 dark:text-neutral-900 dark:hover:bg-neutral-200" > - + ) : (
- + ); } diff --git a/e2e/next-ai-kitchen-sink/app/chats/[chatId]/user-message.tsx b/e2e/next-ai-kitchen-sink/app/chats/[chatId]/user-message.tsx index bf5b68e88e2..bf3058d2342 100644 --- a/e2e/next-ai-kitchen-sink/app/chats/[chatId]/user-message.tsx +++ b/e2e/next-ai-kitchen-sink/app/chats/[chatId]/user-message.tsx @@ -9,7 +9,7 @@ import { MessageId, WithNavigation, } from "@liveblocks/core"; -import { AiChatComposer } from "@liveblocks/react-ui/_private"; +import { AiComposer } from "@liveblocks/react-ui/_private"; import { useClient } from "@liveblocks/react"; import { ChevronLeftIcon } from "../../icons/chevron-left-icon"; import { ChevronRightIcon } from "../../icons/chevron-right-icon"; @@ -93,13 +93,13 @@ export const UserMessage = memo(function UserMessage({ if (isEditing) { return (
-
- - event.preventDefault()} aria-label="Send" className="inline-flex rounded-lg items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed text-sm py-2 px-3 font-medium bg-neutral-900 text-white hover:bg-neutral-800 dark:bg-neutral-100 dark:text-neutral-950 dark:hover:bg-neutral-200" > Send - +
- + ); } diff --git a/e2e/next-ai-kitchen-sink/app/styles/page.tsx b/e2e/next-ai-kitchen-sink/app/styles/page.tsx index c88b27cf8c2..365a3d17a56 100644 --- a/e2e/next-ai-kitchen-sink/app/styles/page.tsx +++ b/e2e/next-ai-kitchen-sink/app/styles/page.tsx @@ -591,7 +591,7 @@ export default function Home() {
-
+
{/* Debug panel */}
{ // Wait for the AiChat components to be fully loaded await expect( - page.locator('[data-testid="chat-a"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-a"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); await expect( - page.locator('[data-testid="chat-b"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-b"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); @@ -172,12 +172,12 @@ test.describe("AiChat Knowledge Isolation", () => { // Wait for components to load await expect( - page.locator('[data-testid="chat-a"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-a"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); await expect( - page.locator('[data-testid="chat-b"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-b"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); @@ -230,12 +230,12 @@ test.describe("AiChat Knowledge Isolation", () => { // Wait for the AiChat components to be fully loaded await expect( - page.locator('[data-testid="chat-a"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-a"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); await expect( - page.locator('[data-testid="chat-b"] .lb-ai-chat-composer') + page.locator('[data-testid="chat-b"] .lb-ai-composer') ).toBeVisible({ timeout: 10000, }); diff --git a/e2e/next-ai-kitchen-sink/test/knowledge-simple.test.ts b/e2e/next-ai-kitchen-sink/test/knowledge-simple.test.ts index 00065a0d069..f3bf3b82f91 100644 --- a/e2e/next-ai-kitchen-sink/test/knowledge-simple.test.ts +++ b/e2e/next-ai-kitchen-sink/test/knowledge-simple.test.ts @@ -42,13 +42,13 @@ test.describe("Knowledge Registration - Simple", () => { } // Wait for the AI chat popover to be visible - await expect(page.locator(".lb-ai-chat-composer")).toBeVisible({ + await expect(page.locator(".lb-ai-composer")).toBeVisible({ timeout: 10000, }); // Find the text input and send button - const textInput = page.locator(".lb-ai-chat-composer-editor"); - const sendButton = page.locator(".lb-ai-chat-composer-action"); + const textInput = page.locator(".lb-ai-composer-editor"); + const sendButton = page.locator(".lb-ai-composer-action"); // If there's an ongoing operation (abort button is enabled), click it first to clear state const buttonVariant = await sendButton.getAttribute("data-variant"); diff --git a/e2e/next-ai-kitchen-sink/test/knowledge.test.ts b/e2e/next-ai-kitchen-sink/test/knowledge.test.ts index 002d741aa90..906a575d791 100644 --- a/e2e/next-ai-kitchen-sink/test/knowledge.test.ts +++ b/e2e/next-ai-kitchen-sink/test/knowledge.test.ts @@ -12,19 +12,19 @@ async function setupAiChat(page: Page) { } // Wait for the AI chat popover to be visible - await expect(page.locator(".lb-ai-chat-composer")).toBeVisible({ + await expect(page.locator(".lb-ai-composer")).toBeVisible({ timeout: 10000, }); // Find the text input and send button - const textInput = page.locator(".lb-ai-chat-composer-editor"); - const sendButton = page.locator(".lb-ai-chat-composer-action"); + const textInput = page.locator(".lb-ai-composer-editor"); + const sendButton = page.locator(".lb-ai-composer-action"); // Wait for the send button to be present and ready await expect(sendButton).toBeVisible({ timeout: 10000 }); // Wait for the composer form to not be disabled - const composerForm = page.locator(".lb-ai-chat-composer-form"); + const composerForm = page.locator(".lb-ai-composer-form"); await expect(composerForm).not.toHaveAttribute("disabled", { timeout: 10000, }); @@ -56,7 +56,9 @@ async function sendAiMessage(page: Page, message: string) { // Verify the message was sent (appears in the chat) // Use a user message selector to be more specific and avoid duplicates - await expect(page.locator(".lb-ai-chat-user-message").last()).toContainText(message); + await expect(page.locator(".lb-ai-chat-user-message").last()).toContainText( + message + ); } test.describe("Knowledge Registration", () => { diff --git a/e2e/next-ai-kitchen-sink/test/simple-chat.test.ts b/e2e/next-ai-kitchen-sink/test/simple-chat.test.ts index c54d739bfda..c0ddb214695 100644 --- a/e2e/next-ai-kitchen-sink/test/simple-chat.test.ts +++ b/e2e/next-ai-kitchen-sink/test/simple-chat.test.ts @@ -5,11 +5,11 @@ async function setupSimpleChat(page: Page) { await page.goto("/simple"); // Wait for the chat interface to load - await expect(page.locator(".lb-ai-chat-composer")).toBeVisible(); + await expect(page.locator(".lb-ai-composer")).toBeVisible(); // Find the text input and send button - const textInput = page.locator(".lb-ai-chat-composer-editor"); - const sendButton = page.locator(".lb-ai-chat-composer-action"); + const textInput = page.locator(".lb-ai-composer-editor"); + const sendButton = page.locator(".lb-ai-composer-action"); // If there's an ongoing operation (abort button is enabled), click it first to clear state if ( diff --git a/e2e/next-ai-kitchen-sink/test/tool-calling.test.ts b/e2e/next-ai-kitchen-sink/test/tool-calling.test.ts index 0f0a48bba97..8dd4793a7fc 100644 --- a/e2e/next-ai-kitchen-sink/test/tool-calling.test.ts +++ b/e2e/next-ai-kitchen-sink/test/tool-calling.test.ts @@ -3,13 +3,13 @@ import type { Page } from "@playwright/test"; async function setupAiChat(page: Page) { // Wait for the AI chat popover to be visible - await expect(page.locator(".lb-ai-chat-composer")).toBeVisible({ + await expect(page.locator(".lb-ai-composer")).toBeVisible({ timeout: 10000, }); // Find the text input and send button in the AI chat - const textInput = page.locator(".lb-ai-chat-composer-editor"); - const sendButton = page.locator(".lb-ai-chat-composer-action"); + const textInput = page.locator(".lb-ai-composer-editor"); + const sendButton = page.locator(".lb-ai-composer-action"); // If there's an ongoing operation (abort button is enabled), click it first to clear state if ((await sendButton.getAttribute("aria-label")) === "Abort response") { @@ -34,7 +34,9 @@ async function sendAiMessage(page: Page, message: string) { await sendButton.click(); // Verify the message was sent (appears in the chat) - await expect(page.locator(".lb-ai-chat-user-message").last()).toContainText(message); + await expect(page.locator(".lb-ai-chat-user-message").last()).toContainText( + message + ); } test.describe("Tool Calling", () => { @@ -222,8 +224,11 @@ test.describe("Tool Calling", () => { ).toBeVisible(); // Verify the AI shows the request was denied - await expect(page.locator(".lb-ai-chat-messages")).toContainText(/denied|cancelled/i, { - timeout: 10000 - }); + await expect(page.locator(".lb-ai-chat-messages")).toContainText( + /denied|cancelled/i, + { + timeout: 10000, + } + ); }); }); diff --git a/packages/liveblocks-core/src/index.ts b/packages/liveblocks-core/src/index.ts index 25b60000c9f..ea977050565 100644 --- a/packages/liveblocks-core/src/index.ts +++ b/packages/liveblocks-core/src/index.ts @@ -158,7 +158,12 @@ export { SortedList } from "./lib/SortedList"; export { stableStringify } from "./lib/stringify"; export type { QueryParams, URLSafeString } from "./lib/url"; export { generateUrl, sanitizeUrl, url, urljoin } from "./lib/url"; -export type { Brand, DistributiveOmit } from "./lib/utils"; +export type { + Brand, + DistributiveOmit, + WithOptional, + WithRequired, +} from "./lib/utils"; export { b64decode, compactObject, diff --git a/packages/liveblocks-core/src/lib/utils.ts b/packages/liveblocks-core/src/lib/utils.ts index e7c0007a5bc..e8558953fdf 100644 --- a/packages/liveblocks-core/src/lib/utils.ts +++ b/packages/liveblocks-core/src/lib/utils.ts @@ -11,6 +11,12 @@ export type DistributiveOmit = T extends any // ? Pick // : never; +export type WithRequired = T & { [P in K]-?: T[P] }; + +export type WithOptional = Omit & { + [P in K]?: T[P]; +}; + /** * Throw an error, but as an expression instead of a statement. */ diff --git a/packages/liveblocks-react-lexical/src/comments/floating-composer.tsx b/packages/liveblocks-react-lexical/src/comments/floating-composer.tsx index c1562a8ebe4..ec79ff694a2 100644 --- a/packages/liveblocks-react-lexical/src/comments/floating-composer.tsx +++ b/packages/liveblocks-react-lexical/src/comments/floating-composer.tsx @@ -18,7 +18,7 @@ import type { ComposerProps, ComposerSubmitComment, } from "@liveblocks/react-ui"; -import { Composer } from "@liveblocks/react-ui"; +import { Composer as DefaultComposer } from "@liveblocks/react-ui"; import type { LexicalCommand } from "lexical"; import { $getSelection, @@ -27,7 +27,7 @@ import { COMMAND_PRIORITY_EDITOR, createCommand, } from "lexical"; -import type { ComponentRef, FormEvent, KeyboardEvent, ReactNode } from "react"; +import type { ComponentType, FormEvent, KeyboardEvent, ReactNode } from "react"; import { forwardRef, useCallback, useEffect, useState } from "react"; import { createPortal } from "react-dom"; @@ -35,6 +35,10 @@ import { createDOMRange } from "../create-dom-range"; import { createRectsFromDOMRange } from "../create-rects-from-dom-range"; import $wrapSelectionInThreadMarkNode from "./wrap-selection-in-thread-mark-node"; +type FloatingComposerComponents = { + Composer: ComponentType>; +}; + /** * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer * @@ -59,12 +63,22 @@ import $wrapSelectionInThreadMarkNode from "./wrap-selection-in-thread-mark-node export const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand = createCommand("OPEN_FLOATING_COMPOSER_COMMAND"); -type ComposerElement = ComponentRef; +/** + * Dispatching ATTACH_THREAD_COMMAND will attach a comment to the current selection. + */ +export const ATTACH_THREAD_COMMAND: LexicalCommand = createCommand( + "ATTACH_THREAD_COMMAND" +); export type FloatingComposerProps = Omit< ComposerProps, "threadId" | "commentId" ->; +> & { + /** + * Override the component's components. + */ + components?: Partial; +}; /** * Displays a `Composer` near the current lexical selection. @@ -75,7 +89,7 @@ export type FloatingComposerProps = Omit< * Should be nested inside `LiveblocksPlugin`. */ export const FloatingComposer = forwardRef< - ComposerElement, + HTMLFormElement, FloatingComposerProps >(function FloatingComposer(props, forwardedRef) { const [range, setRange] = useState(null); @@ -126,7 +140,7 @@ interface FloatingComposerImplProps extends FloatingComposerProps { } const FloatingComposerImpl = forwardRef< - ComposerElement, + HTMLFormElement, FloatingComposerImplProps >(function FloatingComposer(props, forwardedRef) { const { @@ -134,9 +148,10 @@ const FloatingComposerImpl = forwardRef< onRangeChange, onKeyDown, onComposerSubmit, + components, ...composerProps } = props; - + const Composer = components?.Composer ?? DefaultComposer; const [editor] = useLexicalComposerContext(); const createThread = useCreateThread(); @@ -173,18 +188,16 @@ const FloatingComposerImpl = forwardRef< }); }, [editor, range, onRangeChange, $onStateRead]); - /** - * Create a new ThreadMarkNode and wrap the selected content in it. - * @param threadId The id of the thread to associate with the selected content - */ - const onThreadCreate = useCallback( - (threadId: string) => { - editor.update(() => { + // Create a new ThreadMarkNode from a thread ID and wrap the selected content in it. + useEffect(() => { + return editor.registerCommand( + ATTACH_THREAD_COMMAND, + (threadId: string) => { const selection = $getSelection(); - if (!$isRangeSelection(selection)) return; + if (!$isRangeSelection(selection)) return false; // If the selection is collapsed, we do not create a new thread node in the editor. - if (selection.isCollapsed()) return; + if (selection.isCollapsed()) return false; const isBackward = selection.isBackward(); // Wrap content in a ThreadMarkNode @@ -192,10 +205,12 @@ const FloatingComposerImpl = forwardRef< // Clear the selection after wrapping $setSelection(null); - }); - }, - [editor] - ); + + return true; + }, + COMMAND_PRIORITY_EDITOR + ); + }, [editor]); const handleComposerSubmit = useCallback( (comment: ComposerSubmitComment, event: FormEvent) => { @@ -210,9 +225,9 @@ const FloatingComposerImpl = forwardRef< metadata: props.metadata ?? {}, }); - onThreadCreate(thread.id); + editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id); }, - [onThreadCreate, onComposerSubmit, props.metadata, createThread] + [onComposerSubmit, props.metadata, createThread, editor] ); function handleKeyDown(event: KeyboardEvent) { diff --git a/packages/liveblocks-react-lexical/src/comments/floating-threads.tsx b/packages/liveblocks-react-lexical/src/comments/floating-threads.tsx index e9a136718cd..fb50279b115 100644 --- a/packages/liveblocks-react-lexical/src/comments/floating-threads.tsx +++ b/packages/liveblocks-react-lexical/src/comments/floating-threads.tsx @@ -42,7 +42,7 @@ import { } from "./comment-plugin-provider"; import { ThreadToNodesContext } from "./comment-plugin-provider"; -type ThreadPanelComponents = { +type FloatingThreadsComponents = { Thread: ComponentType; }; @@ -56,7 +56,7 @@ export interface FloatingThreadsProps /** * Override the component's components. */ - components?: Partial; + components?: Partial; } export function FloatingThreads({ diff --git a/packages/liveblocks-react-lexical/src/index.ts b/packages/liveblocks-react-lexical/src/index.ts index 6eb3c4263c6..33a98d9cab6 100644 --- a/packages/liveblocks-react-lexical/src/index.ts +++ b/packages/liveblocks-react-lexical/src/index.ts @@ -9,6 +9,7 @@ export { AnchoredThreads } from "./comments/anchored-threads"; export { useIsThreadActive } from "./comments/comment-plugin-provider"; export type { FloatingComposerProps } from "./comments/floating-composer"; export { + ATTACH_THREAD_COMMAND, FloatingComposer, OPEN_FLOATING_COMPOSER_COMMAND, } from "./comments/floating-composer"; diff --git a/packages/liveblocks-react-tiptap/src/comments/AnchoredThreads.tsx b/packages/liveblocks-react-tiptap/src/comments/AnchoredThreads.tsx index 3f4bb83a92e..499668434eb 100644 --- a/packages/liveblocks-react-tiptap/src/comments/AnchoredThreads.tsx +++ b/packages/liveblocks-react-tiptap/src/comments/AnchoredThreads.tsx @@ -34,8 +34,9 @@ export interface AnchoredThreadsProps * Override the component's components. */ components?: Partial; + /** - * The tiptap editor + * The Tiptap editor. */ editor: Editor | null; } diff --git a/packages/liveblocks-react-tiptap/src/comments/FloatingComposer.tsx b/packages/liveblocks-react-tiptap/src/comments/FloatingComposer.tsx index 1fe5e692a73..c6ee7996844 100644 --- a/packages/liveblocks-react-tiptap/src/comments/FloatingComposer.tsx +++ b/packages/liveblocks-react-tiptap/src/comments/FloatingComposer.tsx @@ -17,9 +17,14 @@ import type { ComposerProps, ComposerSubmitComment, } from "@liveblocks/react-ui"; -import { Composer } from "@liveblocks/react-ui"; +import { Composer as DefaultComposer } from "@liveblocks/react-ui"; import { type Editor, useEditorState } from "@tiptap/react"; -import type { ComponentRef, FormEvent, KeyboardEvent } from "react"; +import type { + ComponentType, + FormEvent, + KeyboardEvent, + MouseEvent, +} from "react"; import { forwardRef, useCallback } from "react"; import { createPortal } from "react-dom"; @@ -29,23 +34,36 @@ import type { } from "../types"; import { compareSelections, getDomRangeFromSelection } from "../utils"; +type FloatingComposerComponents = { + Composer: ComponentType>; +}; + export type FloatingComposerProps = Omit< ComposerProps, "threadId" | "commentId" > & { + /** + * Override the component's components. + */ + components?: Partial; + + /** + * The Tiptap editor. + */ editor: Editor | null; }; -type ComposerElement = ComponentRef; - export const FLOATING_COMPOSER_COLLISION_PADDING = 10; export const FloatingComposer = forwardRef< - ComposerElement, + HTMLFormElement, FloatingComposerProps ->(function FloatingComposer(props, forwardedRef) { +>(function FloatingComposer( + { editor, onComposerSubmit, onKeyDown, onClick, components, ...props }, + forwardedRef +) { + const Composer = components?.Composer ?? DefaultComposer; const createThread = useCreateThread(); - const { editor, onComposerSubmit, onKeyDown } = props; const pendingCommentSelection = useEditorState({ editor, @@ -115,6 +133,7 @@ export const FloatingComposer = forwardRef< if (!editor) { return; } + event.preventDefault(); const thread = createThread({ @@ -144,6 +163,20 @@ export const FloatingComposer = forwardRef< [editor, onKeyDown] ); + const handleClick = useCallback( + (event: MouseEvent) => { + onClick?.(event); + + if (event.defaultPrevented) { + return; + } + + // Don't send up a click event from emoji picker and close the composer. + event.stopPropagation(); + }, + [onClick] + ); + if (!isOpen || !editor) { return null; } @@ -162,14 +195,11 @@ export const FloatingComposer = forwardRef< > { - // Don't send up a click event from emoji popout and close the composer - e.stopPropagation(); - }} - autoFocus={true} + onClick={handleClick} />
, document.body diff --git a/packages/liveblocks-react-tiptap/src/comments/FloatingThreads.tsx b/packages/liveblocks-react-tiptap/src/comments/FloatingThreads.tsx index 06ae6bf85f6..a2a66cf18b0 100644 --- a/packages/liveblocks-react-tiptap/src/comments/FloatingThreads.tsx +++ b/packages/liveblocks-react-tiptap/src/comments/FloatingThreads.tsx @@ -29,7 +29,7 @@ import { createPortal } from "react-dom"; import { THREADS_PLUGIN_KEY } from "../types"; -type ThreadPanelComponents = { +type FloatingThreadsComponents = { Thread: ComponentType; }; @@ -43,10 +43,10 @@ export interface FloatingThreadsProps /** * Override the component's components. */ - components?: Partial; + components?: Partial; /** - * The tiptap editor + * The Tiptap editor. */ editor: Editor | null; } diff --git a/packages/liveblocks-react-ui/src/_private/index.ts b/packages/liveblocks-react-ui/src/_private/index.ts index 4c61d5742fd..d265622800f 100644 --- a/packages/liveblocks-react-ui/src/_private/index.ts +++ b/packages/liveblocks-react-ui/src/_private/index.ts @@ -18,12 +18,13 @@ export { useRefs } from "../utils/use-refs"; // Private primitives (which will be exported from @liveblocks/react-ui/primitives when/if made public) -export * as AiChatComposer from "../primitives/AiChatComposer"; +export * as AiComposer from "../primitives/AiComposer"; +export { useAiComposer } from "../primitives/AiComposer/contexts"; export type { - AiChatComposerEditorProps, - AiChatComposerFormProps, - AiChatComposerSubmitProps, -} from "../primitives/AiChatComposer/types"; + AiComposerEditorProps, + AiComposerFormProps, + AiComposerSubmitProps, +} from "../primitives/AiComposer/types"; export * as AiMessage from "../primitives/AiMessage"; export type { AiMessageContentComponents, diff --git a/packages/liveblocks-react-ui/src/components/AiChat.tsx b/packages/liveblocks-react-ui/src/components/AiChat.tsx index 17a7349bda4..ea683fe5d50 100644 --- a/packages/liveblocks-react-ui/src/components/AiChat.tsx +++ b/packages/liveblocks-react-ui/src/components/AiChat.tsx @@ -21,9 +21,9 @@ import type { GlobalComponents } from "../components"; import { ArrowDownIcon } from "../icons/ArrowDown"; import { SpinnerIcon } from "../icons/Spinner"; import { - type AiChatComposerOverrides, type AiChatMessageOverrides, type AiChatOverrides, + type AiComposerOverrides, type GlobalOverrides, useOverrides, } from "../overrides"; @@ -31,8 +31,8 @@ import type { MarkdownComponents } from "../primitives/Markdown"; import { cn } from "../utils/cn"; import { useIntersectionCallback } from "../utils/use-visible"; import { AiChatAssistantMessage } from "./internal/AiChatAssistantMessage"; -import { AiChatComposer } from "./internal/AiChatComposer"; import { AiChatUserMessage } from "./internal/AiChatUserMessage"; +import { AiComposer, type AiComposerProps } from "./internal/AiComposer"; /** * The minimum number of pixels from the bottom of the scrollable area @@ -100,6 +100,11 @@ export interface AiChatProps extends ComponentProps<"div"> { */ tools?: Record; + /** + * The event handler called when the composer is submitted. + */ + onComposerSubmit?: AiComposerProps["onComposerSubmit"]; + /** * The layout of the chat and its composer. */ @@ -110,8 +115,8 @@ export interface AiChatProps extends ComponentProps<"div"> { */ overrides?: Partial< GlobalOverrides & + AiComposerOverrides & AiChatMessageOverrides & - AiChatComposerOverrides & AiChatOverrides >; @@ -418,6 +423,7 @@ export const AiChat = forwardRef( overrides, knowledge: localKnowledge, tools = {}, + onComposerSubmit, layout = "inset", components, className, @@ -554,19 +560,21 @@ export const AiChat = forwardRef(
- setLastSentMessageId(id)} - className={ + onComposerSubmit={onComposerSubmit} + onComposerSubmitted={({ id }) => setLastSentMessageId(id)} + className={cn( + "lb-ai-chat-composer", layout === "inset" ? "lb-elevation lb-elevation-moderate" : undefined - } + )} />
diff --git a/packages/liveblocks-react-ui/src/components/Thread.tsx b/packages/liveblocks-react-ui/src/components/Thread.tsx index a66ec849f0f..f3788fe2cfc 100644 --- a/packages/liveblocks-react-ui/src/components/Thread.tsx +++ b/packages/liveblocks-react-ui/src/components/Thread.tsx @@ -84,6 +84,27 @@ export interface ThreadProps */ showComposerFormattingControls?: ComposerProps["showFormattingControls"]; + /** + * The maximum number of comments to show. + * + * The first and last comments are always shown and by default if some comments + * are hidden, only the first comment will be shown before the "show more" button + * and after it will be shown all the newest comments to fit the limit set. + * + * It's possible to customize this by setting `maxVisibleComments` to an object: + * + * @example + * // Only show the last comment, and all the older ones to fit the limit. + * + * + * @example + * // Show as many old comments as new ones to fit the limit. + * + */ + maxVisibleComments?: + | number + | { max: number; show: "oldest" | "both" | "newest" }; + /** * Whether to blur the composer editor when the composer is submitted. */ @@ -181,6 +202,7 @@ export const Thread = forwardRef( showComposer = "collapsed", showAttachments = true, showComposerFormattingControls = true, + maxVisibleComments, onResolvedChange, onCommentEdit, onCommentDelete, @@ -200,6 +222,7 @@ export const Thread = forwardRef( const markThreadAsResolved = useMarkRoomThreadAsResolved(thread.roomId); const markThreadAsUnresolved = useMarkRoomThreadAsUnresolved(thread.roomId); const $ = useOverrides(overrides); + const [showAllComments, setShowAllComments] = useState(false); const firstCommentIndex = useMemo(() => { return showDeletedComments ? 0 @@ -210,6 +233,92 @@ export const Thread = forwardRef( ? thread.comments.length - 1 : findLastIndex(thread.comments, (comment) => comment.body); }, [showDeletedComments, thread.comments]); + const hiddenComments = useMemo(() => { + const maxVisibleCommentsCount = + typeof maxVisibleComments === "number" + ? maxVisibleComments + : maxVisibleComments?.max; + const visibleCommentsShow = + (typeof maxVisibleComments === "object" + ? maxVisibleComments?.show + : undefined) ?? "newest"; + + // If we explicitly want to show all comments or there's no limit set, + // no need to hide any comments. + if (showAllComments || maxVisibleCommentsCount === undefined) { + return; + } + + const comments = thread.comments + .map((comment, index) => ({ comment, index })) + .filter(({ comment }) => showDeletedComments || comment.body); + + // There aren't enough comments so no need to hide any. + if (comments.length <= Math.max(maxVisibleCommentsCount, 2)) { + return; + } + + const firstVisibleComment = comments[0]!; + const lastVisibleComment = comments[comments.length - 1]!; + + // Always show the first and last comments even if the limit is set to lower than 2. + if (maxVisibleCommentsCount <= 2) { + const firstHiddenCommentIndex = + comments[1]?.index ?? firstVisibleComment.index; + const lastHiddenCommentIndex = + comments[comments.length - 2]?.index ?? lastVisibleComment.index; + + return { + firstIndex: firstHiddenCommentIndex, + lastIndex: lastHiddenCommentIndex, + count: comments.slice(1, comments.length - 1).length, + }; + } + + const remainingVisibleCommentsCount = maxVisibleCommentsCount - 2; + + // Split the remaining visible comments before, after, or equally. + const beforeVisibleCommentsCount = + visibleCommentsShow === "oldest" + ? remainingVisibleCommentsCount + : visibleCommentsShow === "newest" + ? 0 + : Math.floor(remainingVisibleCommentsCount / 2); + const afterVisibleCommentsCount = + visibleCommentsShow === "oldest" + ? 0 + : visibleCommentsShow === "newest" + ? remainingVisibleCommentsCount + : Math.ceil(remainingVisibleCommentsCount / 2); + + // The first comment is always visible so `+ 1` to skip it. + const firstHiddenComment = comments[1 + beforeVisibleCommentsCount]; + // The last comment is always visible so `- 2` to skip it. + const lastHiddenComment = + comments[comments.length - 2 - afterVisibleCommentsCount]; + + // There aren't any comments to hide besides the first and last ones. + if ( + !firstHiddenComment || + !lastHiddenComment || + firstHiddenComment.index > lastHiddenComment.index + ) { + return; + } + + return { + firstIndex: firstHiddenComment.index, + lastIndex: lastHiddenComment.index, + count: thread.comments + .slice(firstHiddenComment.index, lastHiddenComment.index + 1) + .filter((comment) => showDeletedComments || comment.body).length, + }; + }, [ + maxVisibleComments, + showAllComments, + showDeletedComments, + thread.comments, + ]); const { status: subscriptionStatus, unreadSince, @@ -327,6 +436,33 @@ export const Thread = forwardRef( const isFirstComment = index === firstCommentIndex; const isUnread = unreadIndex !== undefined && index >= unreadIndex; + const isHidden = + hiddenComments && + index >= hiddenComments.firstIndex && + index <= hiddenComments.lastIndex; + const isFirstHiddenComment = + isHidden && index === hiddenComments.firstIndex; + + if (isFirstHiddenComment) { + return ( +
+ +
+ ); + } + + if (isHidden) { + return null; + } const children = ( ; - -/* ------------------------------------------------------------------------------------------------- - * AiChatComposer - * -----------------------------------------------------------------------------------------------*/ -export interface AiChatComposerProps extends ComponentProps<"form"> { - /** - * The composer's initial value. - */ - defaultValue?: string; - /** - * The event handler called when a chat message is submitted. - */ - onComposerSubmit?: ( - message: { - /** - * The submitted message text. - */ - text: string; - }, - event: FormEvent - ) => void; - - /** - * @internal - * The event handler called when a user chat message is created optimistically. - */ - onUserMessageCreate?: (message: { - /** - * The created user message id. - */ - id: MessageId; - }) => void; - /** - * Whether the composer is disabled. - */ - disabled?: boolean; - /** - * Whether to focus the editor on mount. - */ - autoFocus?: boolean; - /** - * Override the component's strings. - */ - overrides?: Partial; - /** - * The id of the chat the composer belongs to. - */ - chatId: string; - /** - * The id of the copilot to use to send the message. - */ - copilotId?: CopilotId; - /** - * The contextual knowledge to include in the chat. May be used by the - * assistant when generating responses. In addition to the knowledge passed - * in via this prop, the AiChat instance will also have access to any - * globally registered knowledge via . - */ - knowledge?: AiKnowledgeSource[]; - /** - * @internal - */ - branchId?: MessageId; - /** - * @internal - */ - stream?: boolean; -} - -export const AiChatComposer = forwardRef( - ( - { - defaultValue, - onComposerSubmit, - disabled, - autoFocus, - overrides, - className, - chatId, - branchId, - copilotId, - knowledge: localKnowledge, - stream = true, - onUserMessageCreate, - ...props - }, - forwardedRef - ) => { - const $ = useOverrides(overrides); - const client = useClient(); - - const getLastMessageId = useCallback((messages: UiChatMessage[]) => { - const lastMessage = messages[messages.length - 1]; - if (lastMessage === undefined) return null; - return lastMessage.id; - }, []); - - const getAbortableMessageId = useCallback((messages: UiChatMessage[]) => { - return messages.find( - (m) => - m.role === "assistant" && - (m.status === "generating" || m.status === "awaiting-tool") - )?.id; - }, []); - - const messagesΣ = client[kInternal].ai.signals.getChatMessagesForBranchΣ( - chatId, - branchId - ); - - const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId); - const lastMessageId = useSignal(messagesΣ, getLastMessageId); - - const handleComposerSubmit = useCallback( - (message: { text: string }, event: FormEvent) => { - if (abortableMessageId !== undefined) { - event.preventDefault(); - return; - } - - onComposerSubmit?.(message, event); - if (event.isDefaultPrevented()) return; - - const content = [{ type: "text" as const, text: message.text }]; - const newMessageId = client[kInternal].ai[ - kInternal - ].context.messagesStore.createOptimistically( - chatId, - "user", - lastMessageId, - content - ); - onUserMessageCreate?.({ id: newMessageId }); - - const targetMessageId = client[kInternal].ai[ - kInternal - ].context.messagesStore.createOptimistically( - chatId, - "assistant", - newMessageId - ); - - client[kInternal].ai.askUserMessageInChat( - chatId, - { id: newMessageId, parentMessageId: lastMessageId, content }, - targetMessageId, - { - stream, - copilotId, - knowledge: localKnowledge, - } - ); - }, - [ - onComposerSubmit, - onUserMessageCreate, - client, - chatId, - lastMessageId, - abortableMessageId, - stream, - copilotId, - localKnowledge, - ] - ); - - return ( - - -
- - -
-
- {/* No actions for now but it makes sense to keep the DOM structure */} -
- -
- {abortableMessageId === undefined ? ( - - -
-
-
-
-
- ); - } -); diff --git a/packages/liveblocks-react-ui/src/components/internal/AiComposer.tsx b/packages/liveblocks-react-ui/src/components/internal/AiComposer.tsx new file mode 100644 index 00000000000..156cb601ace --- /dev/null +++ b/packages/liveblocks-react-ui/src/components/internal/AiComposer.tsx @@ -0,0 +1,228 @@ +import { + type AiChatMessage, + type AiKnowledgeSource, + type CopilotId, + type MessageId, +} from "@liveblocks/core"; +import { + useSendAiMessage, + type UseSendAiMessageOptions, +} from "@liveblocks/react"; +import { + type ComponentProps, + type FormEvent, + forwardRef, + type SyntheticEvent, + useCallback, +} from "react"; + +import { SendIcon } from "../../icons/Send"; +import { StopIcon } from "../../icons/Stop"; +import { + type AiComposerOverrides, + type GlobalOverrides, + useOverrides, +} from "../../overrides"; +import * as AiComposerPrimitive from "../../primitives/AiComposer"; +import { useAiComposer } from "../../primitives/AiComposer/contexts"; +import type { + AiComposerEditorProps, + AiComposerFormProps, + AiComposerSubmitMessage, +} from "../../primitives/AiComposer/types"; +import { cn } from "../../utils/cn"; +import { Button } from "./Button"; +import { ShortcutTooltip, TooltipProvider } from "./Tooltip"; + +/* ------------------------------------------------------------------------------------------------- + * AiComposer + * -----------------------------------------------------------------------------------------------*/ +export interface AiComposerProps + extends Omit, "defaultValue"> { + /** + * The composer's initial value. + */ + defaultValue?: string; + + /** + * The event handler called when the composer is submitted. + */ + onComposerSubmit?: ( + message: AiComposerSubmitMessage, + event: FormEvent + ) => void; + + /** + * The event handler called after the composer is submitted. + * + * @internal This API will change, and is not considered stable. DO NOT RELY on it. + */ + onComposerSubmitted?: (message: AiChatMessage) => void; + + /** + * Whether the composer is disabled. + */ + disabled?: AiComposerFormProps["disabled"]; + + /** + * Whether to focus the composer on mount. + */ + autoFocus?: AiComposerEditorProps["autoFocus"]; + + /** + * Override the component's strings. + */ + overrides?: Partial; + + /** + * The ID of the chat the composer belongs to. + */ + chatId: string; + + /** + * The ID of the copilot to use to send the message. + */ + copilotId?: CopilotId; + + /** + * @internal + */ + knowledge?: AiKnowledgeSource[]; + + /** + * @internal + */ + branchId?: MessageId; + + /** + * @internal + */ + stream?: boolean; +} + +function AiComposerAction({ + overrides, +}: { + overrides?: AiComposerProps["overrides"]; +}) { + const { canAbort } = useAiComposer(); + const $ = useOverrides(overrides); + + const preventDefault = useCallback((event: SyntheticEvent) => { + event.preventDefault(); + }, []); + + const stopPropagation = useCallback((event: SyntheticEvent) => { + event.stopPropagation(); + }, []); + + return canAbort ? ( + + +