@liveblocks/react 2.25.0-aiprivatebeta0 → 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.
@@ -1,5 +1,13 @@
1
1
  // src/contexts.ts
2
+ import { raise } from "@liveblocks/core";
2
3
  import { createContext, useContext } from "react";
4
+ var ClientContext = createContext(null);
5
+ function useClientOrNull() {
6
+ return useContext(ClientContext);
7
+ }
8
+ function useClient() {
9
+ return useClientOrNull() ?? raise("LiveblocksProvider is missing from the React tree.");
10
+ }
3
11
  var RoomContext = createContext(null);
4
12
  function useRoomOrNull() {
5
13
  return useContext(RoomContext);
@@ -9,10 +17,42 @@ function useIsInsideRoom() {
9
17
  return room !== null;
10
18
  }
11
19
 
20
+ // src/ai.tsx
21
+ import { kInternal, nanoid } from "@liveblocks/core";
22
+ import { memo, useEffect, useId, useState } from "react";
23
+ function useAi() {
24
+ return useClient()[kInternal].ai;
25
+ }
26
+ function useRandom() {
27
+ return useState(nanoid)[0];
28
+ }
29
+ var RegisterAiKnowledge = memo(function RegisterAiKnowledge2(props) {
30
+ const layerId = useId();
31
+ const ai = useAi();
32
+ const { description, value } = props;
33
+ const [layerKey, setLayerKey] = useState();
34
+ useEffect(() => {
35
+ const layerKey2 = ai.registerKnowledgeLayer(layerId);
36
+ setLayerKey(layerKey2);
37
+ return () => {
38
+ ai.deregisterKnowledgeLayer(layerKey2);
39
+ setLayerKey(void 0);
40
+ };
41
+ }, [ai, layerId]);
42
+ const randomKey = useRandom();
43
+ const knowledgeKey = props.id ?? randomKey;
44
+ useEffect(() => {
45
+ if (layerKey !== void 0) {
46
+ ai.updateKnowledge(layerKey, { description, value }, knowledgeKey);
47
+ }
48
+ }, [ai, layerKey, knowledgeKey, description, value]);
49
+ return null;
50
+ });
51
+
12
52
  // src/use-sync-external-store-with-selector.ts
13
53
  import {
14
54
  useDebugValue,
15
- useEffect,
55
+ useEffect as useEffect2,
16
56
  useMemo,
17
57
  useRef,
18
58
  useSyncExternalStore
@@ -77,7 +117,7 @@ function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnaps
77
117
  getSelection,
78
118
  getServerSelection
79
119
  );
80
- useEffect(() => {
120
+ useEffect2(() => {
81
121
  inst.hasValue = true;
82
122
  inst.value = value;
83
123
  }, [value]);
@@ -104,24 +144,20 @@ function useSignal(signal, selector, isEqual) {
104
144
  }
105
145
 
106
146
  // src/liveblocks.tsx
107
- import {
108
- HttpError
109
- } from "@liveblocks/core";
110
147
  import {
111
148
  assert,
112
149
  createClient,
113
- kInternal as kInternal2,
150
+ HttpError,
151
+ kInternal as kInternal3,
114
152
  makePoller,
115
- raise,
153
+ raise as raise2,
116
154
  shallow as shallow3
117
155
  } from "@liveblocks/core";
118
156
  import {
119
- createContext as createContext2,
120
157
  useCallback as useCallback2,
121
- useContext as useContext2,
122
- useEffect as useEffect3,
158
+ useEffect as useEffect4,
123
159
  useMemo as useMemo2,
124
- useState,
160
+ useState as useState2,
125
161
  useSyncExternalStore as useSyncExternalStore2
126
162
  } from "react";
127
163
 
@@ -183,10 +219,10 @@ function ensureNotServerSide() {
183
219
  import { useCallback, useReducer } from "react";
184
220
 
185
221
  // src/lib/use-latest.ts
186
- import { useEffect as useEffect2, useRef as useRef2 } from "react";
222
+ import { useEffect as useEffect3, useRef as useRef2 } from "react";
187
223
  function useLatest(value) {
188
224
  const ref = useRef2(value);
189
- useEffect2(() => {
225
+ useEffect3(() => {
190
226
  ref.current = value;
191
227
  }, [value]);
192
228
  return ref;
@@ -248,9 +284,9 @@ import {
248
284
  DerivedSignal,
249
285
  getMentionedIdsFromCommentBody,
250
286
  getSubscriptionKey,
251
- kInternal,
287
+ kInternal as kInternal2,
252
288
  MutableSignal as MutableSignal3,
253
- nanoid,
289
+ nanoid as nanoid2,
254
290
  nn,
255
291
  patchNotificationSettings,
256
292
  shallow,
@@ -746,21 +782,26 @@ function createStore_forHistoryVersions() {
746
782
  };
747
783
  }
748
784
  function createStore_forPermissionHints() {
749
- const signal = new MutableSignal3(
750
- new DefaultMap(() => /* @__PURE__ */ new Set())
785
+ const permissionsByRoomId = new DefaultMap(
786
+ () => new Signal(/* @__PURE__ */ new Set())
751
787
  );
752
788
  function update(newHints) {
753
- signal.mutate((lut) => {
754
- for (const [roomId, newPermissions] of Object.entries(newHints)) {
755
- const existing = lut.getOrCreate(roomId);
756
- for (const permission of newPermissions) {
757
- existing.add(permission);
789
+ batch2(() => {
790
+ for (const [roomId, permissions] of Object.entries(newHints)) {
791
+ const signal = permissionsByRoomId.getOrCreate(roomId);
792
+ const existingPermissions = new Set(signal.get());
793
+ for (const permission of permissions) {
794
+ existingPermissions.add(permission);
758
795
  }
796
+ signal.set(existingPermissions);
759
797
  }
760
798
  });
761
799
  }
800
+ function getPermissionForRoom\u03A3(roomId) {
801
+ return permissionsByRoomId.getOrCreate(roomId);
802
+ }
762
803
  return {
763
- signal: signal.asReadonly(),
804
+ getPermissionForRoom\u03A3,
764
805
  // Mutations
765
806
  update
766
807
  };
@@ -784,14 +825,14 @@ function createStore_forNotificationSettings(updates) {
784
825
  }
785
826
  function createStore_forOptimistic(client) {
786
827
  const signal = new Signal([]);
787
- const syncSource = client[kInternal].createSyncSource();
828
+ const syncSource = client[kInternal2].createSyncSource();
788
829
  signal.subscribe(
789
830
  () => syncSource.setSyncStatus(
790
831
  signal.get().length > 0 ? "synchronizing" : "synchronized"
791
832
  )
792
833
  );
793
834
  function add(optimisticUpdate) {
794
- const id = nanoid();
835
+ const id = nanoid2();
795
836
  const newUpdate = { ...optimisticUpdate, id };
796
837
  signal.set((state) => [...state, newUpdate]);
797
838
  return id;
@@ -875,7 +916,7 @@ var UmbrellaStore = class {
875
916
  // Copilot chats
876
917
  #aiChats;
877
918
  constructor(client) {
878
- this.#client = client[kInternal].as();
919
+ this.#client = client[kInternal2].as();
879
920
  this.optimisticUpdates = createStore_forOptimistic(this.#client);
880
921
  this.permissionHints = createStore_forPermissionHints();
881
922
  this.#notificationsPaginationState = new PaginatedResource(
@@ -904,7 +945,7 @@ var UmbrellaStore = class {
904
945
  notificationSettingsFetcher
905
946
  );
906
947
  this.#aiChats = new PaginatedResource(async (cursor) => {
907
- const result = await this.#client[kInternal].ai.getChats({
948
+ const result = await this.#client[kInternal2].ai.getChats({
908
949
  cursor
909
950
  });
910
951
  return result.nextCursor;
@@ -946,7 +987,7 @@ var UmbrellaStore = class {
946
987
  (queryKey) => {
947
988
  const query = JSON.parse(queryKey);
948
989
  const resource = new PaginatedResource(async (cursor) => {
949
- const result = await this.#client[kInternal].httpClient.getUserThreads_experimental({
990
+ const result = await this.#client[kInternal2].httpClient.getUserThreads_experimental({
950
991
  cursor,
951
992
  query
952
993
  });
@@ -989,7 +1030,7 @@ var UmbrellaStore = class {
989
1030
  (queryKey) => {
990
1031
  const [roomId, query] = JSON.parse(queryKey);
991
1032
  const resource = new PaginatedResource(async (cursor) => {
992
- const result = await this.#client[kInternal].httpClient.getThreads({
1033
+ const result = await this.#client[kInternal2].httpClient.getThreads({
993
1034
  roomId,
994
1035
  cursor,
995
1036
  query
@@ -1078,7 +1119,7 @@ var UmbrellaStore = class {
1078
1119
  if (room === null) {
1079
1120
  throw new Error(`Room '${roomId}' is not available on client`);
1080
1121
  }
1081
- const result = await room[kInternal].listTextVersions();
1122
+ const result = await room[kInternal2].listTextVersions();
1082
1123
  this.historyVersions.update(roomId, result.versions);
1083
1124
  const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1084
1125
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
@@ -1123,7 +1164,7 @@ var UmbrellaStore = class {
1123
1164
  }
1124
1165
  return {
1125
1166
  isLoading: false,
1126
- chats: this.#client[kInternal].ai.signals.chats\u03A3.get(),
1167
+ chats: this.#client[kInternal2].ai.signals.chats\u03A3.get(),
1127
1168
  hasFetchedAll: result.data.hasFetchedAll,
1128
1169
  isFetchingMore: result.data.isFetchingMore,
1129
1170
  fetchMore: result.data.fetchMore,
@@ -1134,7 +1175,7 @@ var UmbrellaStore = class {
1134
1175
  };
1135
1176
  const messagesByChatId = new DefaultMap((chatId) => {
1136
1177
  const resource\u03A3 = new SinglePageResource(async () => {
1137
- await this.#client[kInternal].ai.getMessageTree(chatId);
1178
+ await this.#client[kInternal2].ai.getMessageTree(chatId);
1138
1179
  });
1139
1180
  return new DefaultMap(
1140
1181
  (branch) => {
@@ -1145,13 +1186,38 @@ var UmbrellaStore = class {
1145
1186
  }
1146
1187
  return ASYNC_OK(
1147
1188
  "messages",
1148
- this.#client[kInternal].ai.signals.getChatMessagesForBranch\u03A3(chatId, branch ?? void 0).get()
1189
+ this.#client[kInternal2].ai.signals.getChatMessagesForBranch\u03A3(chatId, branch ?? void 0).get()
1149
1190
  );
1150
1191
  });
1151
1192
  return { signal, waitUntilLoaded: resource\u03A3.waitUntilLoaded };
1152
1193
  }
1153
1194
  );
1154
1195
  });
1196
+ const aiChatById = new DefaultMap((chatId) => {
1197
+ const resource = new SinglePageResource(async () => {
1198
+ await this.#client[kInternal2].ai.getOrCreateChat(chatId);
1199
+ });
1200
+ const signal = DerivedSignal.from(() => {
1201
+ const chat = this.#client[kInternal2].ai.getChatById(chatId);
1202
+ if (chat === void 0) {
1203
+ const result = resource.get();
1204
+ if (result.isLoading || result.error) {
1205
+ return result;
1206
+ } else {
1207
+ return ASYNC_OK(
1208
+ "chat",
1209
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1210
+ );
1211
+ }
1212
+ } else {
1213
+ return ASYNC_OK(
1214
+ "chat",
1215
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1216
+ );
1217
+ }
1218
+ }, shallow);
1219
+ return { signal, waitUntilLoaded: resource.waitUntilLoaded };
1220
+ });
1155
1221
  this.outputs = {
1156
1222
  threadifications,
1157
1223
  threads,
@@ -1164,7 +1230,8 @@ var UmbrellaStore = class {
1164
1230
  notificationSettings,
1165
1231
  threadSubscriptions,
1166
1232
  aiChats,
1167
- messagesByChatId
1233
+ messagesByChatId,
1234
+ aiChatById
1168
1235
  };
1169
1236
  autobind(this);
1170
1237
  }
@@ -1370,7 +1437,7 @@ var UmbrellaStore = class {
1370
1437
  if (lastRequestedAt === void 0) {
1371
1438
  return;
1372
1439
  }
1373
- const updates = await this.#client[kInternal].httpClient.getThreadsSince({
1440
+ const updates = await this.#client[kInternal2].httpClient.getThreadsSince({
1374
1441
  roomId,
1375
1442
  since: lastRequestedAt,
1376
1443
  signal
@@ -1393,7 +1460,7 @@ var UmbrellaStore = class {
1393
1460
  if (lastRequestedAt === null) {
1394
1461
  return;
1395
1462
  }
1396
- const result = await this.#client[kInternal].httpClient.getUserThreadsSince_experimental({
1463
+ const result = await this.#client[kInternal2].httpClient.getUserThreadsSince_experimental({
1397
1464
  since: lastRequestedAt,
1398
1465
  signal
1399
1466
  });
@@ -1419,7 +1486,7 @@ var UmbrellaStore = class {
1419
1486
  this.#client.getRoom(roomId),
1420
1487
  `Room with id ${roomId} is not available on client`
1421
1488
  );
1422
- const updates = await room[kInternal].listTextVersionsSince({
1489
+ const updates = await room[kInternal2].listTextVersionsSince({
1423
1490
  since: lastRequestedAt,
1424
1491
  signal
1425
1492
  });
@@ -1885,7 +1952,6 @@ function isThreadParticipant(thread, userId) {
1885
1952
 
1886
1953
  // src/liveblocks.tsx
1887
1954
  import { jsx } from "react/jsx-runtime";
1888
- var ClientContext = createContext2(null);
1889
1955
  function missingUserError(userId) {
1890
1956
  return new Error(`resolveUsers didn't return anything for user '${userId}'`);
1891
1957
  }
@@ -2044,9 +2110,11 @@ function makeLiveblocksContextBundle(client) {
2044
2110
  useInboxNotificationThread: useInboxNotificationThread2,
2045
2111
  useUserThreads_experimental,
2046
2112
  useAiChats,
2113
+ useAiChat,
2047
2114
  useAiChatMessages,
2048
2115
  useCreateAiChat,
2049
2116
  useDeleteAiChat,
2117
+ useSendAiMessage,
2050
2118
  ...shared.classic,
2051
2119
  suspense: {
2052
2120
  LiveblocksProvider: LiveblocksProvider2,
@@ -2061,9 +2129,11 @@ function makeLiveblocksContextBundle(client) {
2061
2129
  useUpdateNotificationSettings: useUpdateNotificationSettings2,
2062
2130
  useUserThreads_experimental: useUserThreadsSuspense_experimental,
2063
2131
  useAiChats: useAiChatsSuspense,
2132
+ useAiChat: useAiChatSuspense,
2064
2133
  useAiChatMessages: useAiChatMessagesSuspense,
2065
2134
  useCreateAiChat,
2066
2135
  useDeleteAiChat,
2136
+ useSendAiMessage,
2067
2137
  ...shared.suspense
2068
2138
  }
2069
2139
  };
@@ -2071,7 +2141,7 @@ function makeLiveblocksContextBundle(client) {
2071
2141
  }
2072
2142
  function useInboxNotifications_withClient(client, selector, isEqual) {
2073
2143
  const { store, notificationsPoller: poller } = getLiveblocksExtrasForClient(client);
2074
- useEffect3(
2144
+ useEffect4(
2075
2145
  () => void store.outputs.loadingNotifications.waitUntilLoaded()
2076
2146
  // NOTE: Deliberately *not* using a dependency array here!
2077
2147
  //
@@ -2082,7 +2152,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
2082
2152
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2083
2153
  // *next* render after that, a *new* fetch/promise will get created.
2084
2154
  );
2085
- useEffect3(() => {
2155
+ useEffect4(() => {
2086
2156
  poller.inc();
2087
2157
  poller.pollNowIfStale();
2088
2158
  return () => {
@@ -2140,7 +2210,7 @@ function useMarkInboxNotificationAsRead_withClient(client) {
2140
2210
  },
2141
2211
  (err) => {
2142
2212
  store.optimisticUpdates.remove(optimisticId);
2143
- client[kInternal2].emitError(
2213
+ client[kInternal3].emitError(
2144
2214
  {
2145
2215
  type: "MARK_INBOX_NOTIFICATION_AS_READ_ERROR",
2146
2216
  inboxNotificationId
@@ -2167,7 +2237,7 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
2167
2237
  },
2168
2238
  (err) => {
2169
2239
  store.optimisticUpdates.remove(optimisticId);
2170
- client[kInternal2].emitError(
2240
+ client[kInternal3].emitError(
2171
2241
  // No roomId, threadId, commentId to include for this error
2172
2242
  { type: "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR" },
2173
2243
  err
@@ -2192,7 +2262,7 @@ function useDeleteInboxNotification_withClient(client) {
2192
2262
  },
2193
2263
  (err) => {
2194
2264
  store.optimisticUpdates.remove(optimisticId);
2195
- client[kInternal2].emitError(
2265
+ client[kInternal3].emitError(
2196
2266
  { type: "DELETE_INBOX_NOTIFICATION_ERROR", inboxNotificationId },
2197
2267
  err
2198
2268
  );
@@ -2216,7 +2286,7 @@ function useDeleteAllInboxNotifications_withClient(client) {
2216
2286
  },
2217
2287
  (err) => {
2218
2288
  store.optimisticUpdates.remove(optimisticId);
2219
- client[kInternal2].emitError(
2289
+ client[kInternal3].emitError(
2220
2290
  { type: "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR" },
2221
2291
  err
2222
2292
  );
@@ -2230,15 +2300,15 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
2230
2300
  store.outputs.threadifications,
2231
2301
  useCallback2(
2232
2302
  (state) => {
2233
- const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise(
2303
+ const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise2(
2234
2304
  `Inbox notification with ID "${inboxNotificationId}" not found`
2235
2305
  );
2236
2306
  if (inboxNotification.kind !== "thread") {
2237
- raise(
2307
+ raise2(
2238
2308
  `Inbox notification with ID "${inboxNotificationId}" is not of kind "thread"`
2239
2309
  );
2240
2310
  }
2241
- const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise(
2311
+ const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise2(
2242
2312
  `Thread with ID "${inboxNotification.threadId}" not found, this inbox notification might not be of kind "thread"`
2243
2313
  );
2244
2314
  return thread;
@@ -2269,7 +2339,7 @@ function useUpdateNotificationSettings_withClient(client) {
2269
2339
  const msg = [err.details?.error, err.details?.reason].filter(Boolean).join("\n");
2270
2340
  console.error(msg);
2271
2341
  }
2272
- client[kInternal2].emitError(
2342
+ client[kInternal3].emitError(
2273
2343
  {
2274
2344
  type: "UPDATE_USER_NOTIFICATION_SETTINGS_ERROR"
2275
2345
  },
@@ -2287,10 +2357,10 @@ function useUpdateNotificationSettings_withClient(client) {
2287
2357
  function useNotificationSettings_withClient(client) {
2288
2358
  const updateNotificationSettings = useUpdateNotificationSettings_withClient(client);
2289
2359
  const { store, notificationSettingsPoller: poller } = getLiveblocksExtrasForClient(client);
2290
- useEffect3(() => {
2360
+ useEffect4(() => {
2291
2361
  void store.outputs.notificationSettings.waitUntilLoaded();
2292
2362
  });
2293
- useEffect3(() => {
2363
+ useEffect4(() => {
2294
2364
  poller.inc();
2295
2365
  poller.pollNowIfStale();
2296
2366
  return () => {
@@ -2314,7 +2384,7 @@ function useNotificationSettingsSuspense_withClient(client) {
2314
2384
  }, [result, updateNotificationSettings]);
2315
2385
  }
2316
2386
  function useUser_withClient(client, userId) {
2317
- const usersStore = client[kInternal2].usersStore;
2387
+ const usersStore = client[kInternal3].usersStore;
2318
2388
  const getUserState = useCallback2(
2319
2389
  () => usersStore.getItemState(userId),
2320
2390
  [usersStore, userId]
@@ -2330,7 +2400,7 @@ function useUser_withClient(client, userId) {
2330
2400
  selector,
2331
2401
  shallow3
2332
2402
  );
2333
- useEffect3(
2403
+ useEffect4(
2334
2404
  () => void usersStore.enqueue(userId)
2335
2405
  // NOTE: Deliberately *not* using a dependency array here!
2336
2406
  //
@@ -2345,7 +2415,7 @@ function useUser_withClient(client, userId) {
2345
2415
  return result;
2346
2416
  }
2347
2417
  function useUserSuspense_withClient(client, userId) {
2348
- const usersStore = client[kInternal2].usersStore;
2418
+ const usersStore = client[kInternal3].usersStore;
2349
2419
  const getUserState = useCallback2(
2350
2420
  () => usersStore.getItemState(userId),
2351
2421
  [usersStore, userId]
@@ -2375,7 +2445,7 @@ function useUserSuspense_withClient(client, userId) {
2375
2445
  };
2376
2446
  }
2377
2447
  function useRoomInfo_withClient(client, roomId) {
2378
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2448
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2379
2449
  const getRoomInfoState = useCallback2(
2380
2450
  () => roomsInfoStore.getItemState(roomId),
2381
2451
  [roomsInfoStore, roomId]
@@ -2391,7 +2461,7 @@ function useRoomInfo_withClient(client, roomId) {
2391
2461
  selector,
2392
2462
  shallow3
2393
2463
  );
2394
- useEffect3(
2464
+ useEffect4(
2395
2465
  () => void roomsInfoStore.enqueue(roomId)
2396
2466
  // NOTE: Deliberately *not* using a dependency array here!
2397
2467
  //
@@ -2406,7 +2476,7 @@ function useRoomInfo_withClient(client, roomId) {
2406
2476
  return result;
2407
2477
  }
2408
2478
  function useRoomInfoSuspense_withClient(client, roomId) {
2409
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2479
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2410
2480
  const getRoomInfoState = useCallback2(
2411
2481
  () => roomsInfoStore.getItemState(roomId),
2412
2482
  [roomsInfoStore, roomId]
@@ -2439,7 +2509,7 @@ function useRoomInfoSuspense_withClient(client, roomId) {
2439
2509
  function useAiChats() {
2440
2510
  const client = useClient();
2441
2511
  const store = getUmbrellaStoreForClient(client);
2442
- useEffect3(
2512
+ useEffect4(
2443
2513
  () => void store.outputs.aiChats.waitUntilLoaded()
2444
2514
  // NOTE: Deliberately *not* using a dependency array here!
2445
2515
  //
@@ -2462,11 +2532,11 @@ function useAiChatsSuspense() {
2462
2532
  assert(!result.isLoading, "Did not expect loading");
2463
2533
  return result;
2464
2534
  }
2465
- function useAiChatMessages(chatId, branch) {
2535
+ function useAiChatMessages(chatId, options) {
2466
2536
  const client = useClient();
2467
2537
  const store = getUmbrellaStoreForClient(client);
2468
- useEffect3(
2469
- () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2538
+ useEffect4(
2539
+ () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2470
2540
  // NOTE: Deliberately *not* using a dependency array here!
2471
2541
  //
2472
2542
  // It is important to call waitUntil on *every* render.
@@ -2477,17 +2547,43 @@ function useAiChatMessages(chatId, branch) {
2477
2547
  // *next* render after that, a *new* fetch/promise will get created.
2478
2548
  );
2479
2549
  return useSignal(
2480
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).signal
2550
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).signal
2481
2551
  );
2482
2552
  }
2483
- function useAiChatMessagesSuspense(chatId, branch) {
2553
+ function useAiChatMessagesSuspense(chatId, options) {
2484
2554
  ensureNotServerSide();
2485
2555
  const client = useClient();
2486
2556
  const store = getUmbrellaStoreForClient(client);
2487
2557
  use(
2488
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2558
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2559
+ );
2560
+ const result = useAiChatMessages(chatId, options);
2561
+ assert(!result.error, "Did not expect error");
2562
+ assert(!result.isLoading, "Did not expect loading");
2563
+ return result;
2564
+ }
2565
+ function useAiChat(chatId) {
2566
+ const client = useClient();
2567
+ const store = getUmbrellaStoreForClient(client);
2568
+ useEffect4(
2569
+ () => void store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded()
2570
+ // NOTE: Deliberately *not* using a dependency array here!
2571
+ //
2572
+ // It is important to call waitUntil on *every* render.
2573
+ // This is harmless though, on most renders, except:
2574
+ // 1. The very first render, in which case we'll want to trigger the initial page fetch.
2575
+ // 2. All other subsequent renders now "just" return the same promise (a quick operation).
2576
+ // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2577
+ // *next* render after that, a *new* fetch/promise will get created.
2489
2578
  );
2490
- const result = useAiChatMessages(chatId, branch);
2579
+ return useSignal(store.outputs.aiChatById.getOrCreate(chatId).signal);
2580
+ }
2581
+ function useAiChatSuspense(chatId) {
2582
+ ensureNotServerSide();
2583
+ const client = useClient();
2584
+ const store = getUmbrellaStoreForClient(client);
2585
+ use(store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded());
2586
+ const result = useAiChat(chatId);
2491
2587
  assert(!result.error, "Did not expect error");
2492
2588
  assert(!result.isLoading, "Did not expect loading");
2493
2589
  return result;
@@ -2496,7 +2592,7 @@ function useCreateAiChat() {
2496
2592
  const client = useClient();
2497
2593
  return useCallback2(
2498
2594
  (options) => {
2499
- client[kInternal2].ai.createChat(options.id).catch((err) => {
2595
+ client[kInternal3].ai.getOrCreateChat(options.id, options).catch((err) => {
2500
2596
  console.error(
2501
2597
  `Failed to create chat with ID "${options.id}": ${String(err)}`
2502
2598
  );
@@ -2509,7 +2605,7 @@ function useDeleteAiChat() {
2509
2605
  const client = useClient();
2510
2606
  return useCallback2(
2511
2607
  (chatId) => {
2512
- client[kInternal2].ai.deleteChat(chatId).catch((err) => {
2608
+ client[kInternal3].ai.deleteChat(chatId).catch((err) => {
2513
2609
  console.error(
2514
2610
  `Failed to delete chat with ID "${chatId}": ${String(err)}`
2515
2611
  );
@@ -2518,6 +2614,38 @@ function useDeleteAiChat() {
2518
2614
  [client]
2519
2615
  );
2520
2616
  }
2617
+ function useSendAiMessage(chatId, options) {
2618
+ const client = useClient();
2619
+ const copilotId = options?.copilotId;
2620
+ return useCallback2(
2621
+ (message) => {
2622
+ const messages = client[kInternal3].ai.signals.getChatMessagesForBranch\u03A3(chatId).get();
2623
+ const lastMessageId = messages[messages.length - 1]?.id ?? null;
2624
+ const content = [{ type: "text", text: message }];
2625
+ const newMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2626
+ chatId,
2627
+ "user",
2628
+ lastMessageId,
2629
+ content
2630
+ );
2631
+ const targetMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2632
+ chatId,
2633
+ "assistant",
2634
+ newMessageId
2635
+ );
2636
+ void client[kInternal3].ai.askUserMessageInChat(
2637
+ chatId,
2638
+ { id: newMessageId, parentMessageId: lastMessageId, content },
2639
+ targetMessageId,
2640
+ {
2641
+ stream: false,
2642
+ copilotId
2643
+ }
2644
+ );
2645
+ },
2646
+ [client, chatId, copilotId]
2647
+ );
2648
+ }
2521
2649
  function createSharedContext(client) {
2522
2650
  const useClient2 = () => client;
2523
2651
  function useSyncStatus2(options) {
@@ -2530,7 +2658,8 @@ function createSharedContext(client) {
2530
2658
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
2531
2659
  useIsInsideRoom,
2532
2660
  useErrorListener,
2533
- useSyncStatus: useSyncStatus2
2661
+ useSyncStatus: useSyncStatus2,
2662
+ RegisterAiKnowledge
2534
2663
  },
2535
2664
  suspense: {
2536
2665
  useClient: useClient2,
@@ -2538,7 +2667,8 @@ function createSharedContext(client) {
2538
2667
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
2539
2668
  useIsInsideRoom,
2540
2669
  useErrorListener,
2541
- useSyncStatus: useSyncStatus2
2670
+ useSyncStatus: useSyncStatus2,
2671
+ RegisterAiKnowledge
2542
2672
  }
2543
2673
  };
2544
2674
  }
@@ -2550,12 +2680,6 @@ function useEnsureNoLiveblocksProvider(options) {
2550
2680
  );
2551
2681
  }
2552
2682
  }
2553
- function useClientOrNull() {
2554
- return useContext2(ClientContext);
2555
- }
2556
- function useClient() {
2557
- return useClientOrNull() ?? raise("LiveblocksProvider is missing from the React tree.");
2558
- }
2559
2683
  function LiveblocksProviderWithClient(props) {
2560
2684
  useEnsureNoLiveblocksProvider(props);
2561
2685
  return /* @__PURE__ */ jsx(ClientContext.Provider, { value: props.client, children: props.children });
@@ -2588,10 +2712,10 @@ function LiveblocksProvider(props) {
2588
2712
  )
2589
2713
  };
2590
2714
  const client = useMemo2(() => createClient(options), []);
2591
- useEffect3(() => {
2592
- client[kInternal2].ai.connect();
2715
+ useEffect4(() => {
2716
+ client[kInternal3].ai.connect();
2593
2717
  return () => {
2594
- client[kInternal2].ai.disconnect();
2718
+ client[kInternal3].ai.disconnect();
2595
2719
  };
2596
2720
  }, [client]);
2597
2721
  return /* @__PURE__ */ jsx(LiveblocksProviderWithClient, { client, children });
@@ -2603,7 +2727,7 @@ function useUserThreads_experimental(options = {}) {
2603
2727
  const client = useClient();
2604
2728
  const { store, userThreadsPoller: poller } = getLiveblocksExtrasForClient(client);
2605
2729
  const queryKey = makeUserThreadsQueryKey(options.query);
2606
- useEffect3(
2730
+ useEffect4(
2607
2731
  () => void store.outputs.loadingUserThreads.getOrCreate(queryKey).waitUntilLoaded()
2608
2732
  // NOTE: Deliberately *not* using a dependency array here!
2609
2733
  //
@@ -2614,7 +2738,7 @@ function useUserThreads_experimental(options = {}) {
2614
2738
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2615
2739
  // *next* render after that, a *new* fetch/promise will get created.
2616
2740
  );
2617
- useEffect3(() => {
2741
+ useEffect4(() => {
2618
2742
  poller.inc();
2619
2743
  poller.pollNowIfStale();
2620
2744
  return () => {
@@ -2696,6 +2820,8 @@ var _useUserThreads_experimental = useUserThreads_experimental;
2696
2820
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
2697
2821
  var _useAiChats = useAiChats;
2698
2822
  var _useAiChatsSuspense = useAiChatsSuspense;
2823
+ var _useAiChat = useAiChat;
2824
+ var _useAiChatSuspense = useAiChatSuspense;
2699
2825
  var _useAiChatMessages = useAiChatMessages;
2700
2826
  var _useAiChatMessagesSuspense = useAiChatMessagesSuspense;
2701
2827
  function useSyncStatus_withClient(client, options) {
@@ -2715,9 +2841,9 @@ function useSyncStatusImmediate_withClient(client) {
2715
2841
  }
2716
2842
  function useSyncStatusSmooth_withClient(client) {
2717
2843
  const getter = client.getSyncStatus;
2718
- const [status, setStatus] = useState(getter);
2844
+ const [status, setStatus] = useState2(getter);
2719
2845
  const oldStatus = useLatest(getter());
2720
- useEffect3(() => {
2846
+ useEffect4(() => {
2721
2847
  let timeoutId;
2722
2848
  const unsub = client.events.syncStatus.subscribe(() => {
2723
2849
  const newStatus = getter();
@@ -2741,7 +2867,7 @@ function useSyncStatus(options) {
2741
2867
  function useErrorListener(callback) {
2742
2868
  const client = useClient();
2743
2869
  const savedCallback = useLatest(callback);
2744
- useEffect3(
2870
+ useEffect4(
2745
2871
  () => client.events.error.subscribe((e) => savedCallback.current(e)),
2746
2872
  [client, savedCallback]
2747
2873
  );
@@ -2758,22 +2884,22 @@ import {
2758
2884
  errorIf,
2759
2885
  getSubscriptionKey as getSubscriptionKey2,
2760
2886
  HttpError as HttpError2,
2761
- kInternal as kInternal3,
2887
+ kInternal as kInternal4,
2762
2888
  makePoller as makePoller2,
2763
2889
  ServerMsgCode
2764
2890
  } from "@liveblocks/core";
2765
2891
  import {
2766
2892
  useCallback as useCallback3,
2767
- useEffect as useEffect5,
2893
+ useEffect as useEffect6,
2768
2894
  useMemo as useMemo3,
2769
2895
  useRef as useRef3,
2770
- useState as useState2,
2896
+ useState as useState3,
2771
2897
  useSyncExternalStore as useSyncExternalStore3,
2772
2898
  version as reactVersion
2773
2899
  } from "react";
2774
2900
 
2775
2901
  // src/use-scroll-to-comment-on-load-effect.ts
2776
- import { useEffect as useEffect4 } from "react";
2902
+ import { useEffect as useEffect5 } from "react";
2777
2903
  function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2778
2904
  if (shouldScrollOnLoad === false) return;
2779
2905
  if (!state.threads) return;
@@ -2792,7 +2918,7 @@ function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2792
2918
  comment.scrollIntoView();
2793
2919
  }
2794
2920
  function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
2795
- useEffect4(
2921
+ useEffect5(
2796
2922
  () => {
2797
2923
  handleScrollToCommentOnLoad(shouldScrollOnLoad, state);
2798
2924
  },
@@ -2846,7 +2972,7 @@ function makeMutationContext(room) {
2846
2972
  };
2847
2973
  }
2848
2974
  function getCurrentUserId(client) {
2849
- const userId = client[kInternal3].currentUserId.get();
2975
+ const userId = client[kInternal4].currentUserId.get();
2850
2976
  if (userId === void 0) {
2851
2977
  return "anonymous";
2852
2978
  }
@@ -2883,7 +3009,7 @@ function makeRoomExtrasForClient(client) {
2883
3009
  ].filter(Boolean).join("\n");
2884
3010
  console3.error(detailedMessage);
2885
3011
  }
2886
- client[kInternal3].emitError(context, innerError);
3012
+ client[kInternal4].emitError(context, innerError);
2887
3013
  } else {
2888
3014
  throw innerError;
2889
3015
  }
@@ -3054,13 +3180,13 @@ function makeRoomContextBundle(client) {
3054
3180
  ...shared.suspense
3055
3181
  }
3056
3182
  };
3057
- return Object.defineProperty(bundle, kInternal3, {
3183
+ return Object.defineProperty(bundle, kInternal4, {
3058
3184
  enumerable: false
3059
3185
  });
3060
3186
  }
3061
3187
  function RoomProvider(props) {
3062
3188
  const client = useClient();
3063
- const [cache] = useState2(
3189
+ const [cache] = useState3(
3064
3190
  () => /* @__PURE__ */ new Map()
3065
3191
  );
3066
3192
  const stableEnterRoom = useCallback3(
@@ -3110,14 +3236,14 @@ function RoomProviderInner(props) {
3110
3236
  initialStorage: props.initialStorage,
3111
3237
  autoConnect: props.autoConnect ?? typeof window !== "undefined"
3112
3238
  });
3113
- const [{ room }, setRoomLeavePair] = useState2(
3239
+ const [{ room }, setRoomLeavePair] = useState3(
3114
3240
  () => stableEnterRoom(roomId, {
3115
3241
  ...frozenProps,
3116
3242
  autoConnect: false
3117
3243
  // Deliberately using false here on the first render, see below
3118
3244
  })
3119
3245
  );
3120
- useEffect5(() => {
3246
+ useEffect6(() => {
3121
3247
  const { store } = getRoomExtrasForClient(client);
3122
3248
  async function handleCommentEvent(message) {
3123
3249
  if (message.type === ServerMsgCode.THREAD_DELETED) {
@@ -3164,7 +3290,7 @@ function RoomProviderInner(props) {
3164
3290
  (message) => void handleCommentEvent(message)
3165
3291
  );
3166
3292
  }, [client, room]);
3167
- useEffect5(() => {
3293
+ useEffect6(() => {
3168
3294
  const pair = stableEnterRoom(roomId, frozenProps);
3169
3295
  setRoomLeavePair(pair);
3170
3296
  const { room: room2, leave } = pair;
@@ -3194,14 +3320,14 @@ function useStatus() {
3194
3320
  function useReportTextEditor(editor, rootKey) {
3195
3321
  const isReported = useRef3(false);
3196
3322
  const room = useRoom();
3197
- useEffect5(() => {
3323
+ useEffect6(() => {
3198
3324
  if (isReported.current) {
3199
3325
  return;
3200
3326
  }
3201
3327
  const unsubscribe = room.events.status.subscribe((status) => {
3202
3328
  if (status === "connected" && !isReported.current) {
3203
3329
  isReported.current = true;
3204
- void room[kInternal3].reportTextEditor(editor, rootKey);
3330
+ void room[kInternal4].reportTextEditor(editor, rootKey);
3205
3331
  }
3206
3332
  });
3207
3333
  return unsubscribe;
@@ -3211,12 +3337,12 @@ function useYjsProvider() {
3211
3337
  const room = useRoom();
3212
3338
  const subscribe = useCallback3(
3213
3339
  (onStoreChange) => {
3214
- return room[kInternal3].yjsProviderDidChange.subscribe(onStoreChange);
3340
+ return room[kInternal4].yjsProviderDidChange.subscribe(onStoreChange);
3215
3341
  },
3216
3342
  [room]
3217
3343
  );
3218
3344
  const getSnapshot = useCallback3(() => {
3219
- return room[kInternal3].getYjsProvider();
3345
+ return room[kInternal4].getYjsProvider();
3220
3346
  }, [room]);
3221
3347
  return useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
3222
3348
  }
@@ -3224,7 +3350,7 @@ function useCreateTextMention() {
3224
3350
  const room = useRoom();
3225
3351
  return useCallback3(
3226
3352
  (userId, mentionId) => {
3227
- room[kInternal3].createTextMention(userId, mentionId).catch((err) => {
3353
+ room[kInternal4].createTextMention(userId, mentionId).catch((err) => {
3228
3354
  console3.error(
3229
3355
  `Cannot create text mention for user '${userId}' and mention '${mentionId}'`,
3230
3356
  err
@@ -3238,7 +3364,7 @@ function useDeleteTextMention() {
3238
3364
  const room = useRoom();
3239
3365
  return useCallback3(
3240
3366
  (mentionId) => {
3241
- room[kInternal3].deleteTextMention(mentionId).catch((err) => {
3367
+ room[kInternal4].deleteTextMention(mentionId).catch((err) => {
3242
3368
  console3.error(`Cannot delete text mention '${mentionId}'`, err);
3243
3369
  });
3244
3370
  },
@@ -3247,11 +3373,11 @@ function useDeleteTextMention() {
3247
3373
  }
3248
3374
  function useResolveMentionSuggestions() {
3249
3375
  const client = useClient();
3250
- return client[kInternal3].resolveMentionSuggestions;
3376
+ return client[kInternal4].resolveMentionSuggestions;
3251
3377
  }
3252
3378
  function useMentionSuggestionsCache() {
3253
3379
  const client = useClient();
3254
- return client[kInternal3].mentionSuggestionsCache;
3380
+ return client[kInternal4].mentionSuggestionsCache;
3255
3381
  }
3256
3382
  function useStorageStatus(options) {
3257
3383
  const smooth = useInitial(options?.smooth ?? false);
@@ -3270,9 +3396,9 @@ function useStorageStatusImmediate() {
3270
3396
  }
3271
3397
  function useStorageStatusSmooth() {
3272
3398
  const room = useRoom();
3273
- const [status, setStatus] = useState2(room.getStorageStatus);
3399
+ const [status, setStatus] = useState3(room.getStorageStatus);
3274
3400
  const oldStatus = useLatest(room.getStorageStatus());
3275
- useEffect5(() => {
3401
+ useEffect6(() => {
3276
3402
  let timeoutId;
3277
3403
  const unsub = room.events.storageStatus.subscribe((newStatus) => {
3278
3404
  if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
@@ -3304,7 +3430,7 @@ function useBroadcastEvent() {
3304
3430
  function useOthersListener(callback) {
3305
3431
  const room = useRoom();
3306
3432
  const savedCallback = useLatest(callback);
3307
- useEffect5(
3433
+ useEffect6(
3308
3434
  () => room.events.others.subscribe((event) => savedCallback.current(event)),
3309
3435
  [room, savedCallback]
3310
3436
  );
@@ -3312,7 +3438,7 @@ function useOthersListener(callback) {
3312
3438
  function useLostConnectionListener(callback) {
3313
3439
  const room = useRoom();
3314
3440
  const savedCallback = useLatest(callback);
3315
- useEffect5(
3441
+ useEffect6(
3316
3442
  () => room.events.lostConnection.subscribe(
3317
3443
  (event) => savedCallback.current(event)
3318
3444
  ),
@@ -3322,7 +3448,7 @@ function useLostConnectionListener(callback) {
3322
3448
  function useEventListener(callback) {
3323
3449
  const room = useRoom();
3324
3450
  const savedCallback = useLatest(callback);
3325
- useEffect5(() => {
3451
+ useEffect6(() => {
3326
3452
  const listener = (eventData) => {
3327
3453
  savedCallback.current(eventData);
3328
3454
  };
@@ -3506,7 +3632,7 @@ function useThreads(options = {}) {
3506
3632
  const { store, getOrCreateThreadsPollerForRoomId } = getRoomExtrasForClient(client);
3507
3633
  const queryKey = makeRoomThreadsQueryKey(room.id, options.query);
3508
3634
  const poller = getOrCreateThreadsPollerForRoomId(room.id);
3509
- useEffect5(
3635
+ useEffect6(
3510
3636
  () => void store.outputs.loadingRoomThreads.getOrCreate(queryKey).waitUntilLoaded()
3511
3637
  // NOTE: Deliberately *not* using a dependency array here!
3512
3638
  //
@@ -3517,7 +3643,7 @@ function useThreads(options = {}) {
3517
3643
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
3518
3644
  // *next* render after that, a *new* fetch/promise will get created.
3519
3645
  );
3520
- useEffect5(() => {
3646
+ useEffect6(() => {
3521
3647
  poller.inc();
3522
3648
  poller.pollNowIfStale();
3523
3649
  return () => poller.dec();
@@ -3569,7 +3695,7 @@ function useCreateRoomThread(roomId) {
3569
3695
  roomId
3570
3696
  });
3571
3697
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3572
- client[kInternal3].httpClient.createThread({
3698
+ client[kInternal4].httpClient.createThread({
3573
3699
  roomId,
3574
3700
  threadId,
3575
3701
  commentId,
@@ -3617,7 +3743,7 @@ function useDeleteRoomThread(roomId) {
3617
3743
  threadId,
3618
3744
  deletedAt: /* @__PURE__ */ new Date()
3619
3745
  });
3620
- client[kInternal3].httpClient.deleteThread({ roomId, threadId }).then(
3746
+ client[kInternal4].httpClient.deleteThread({ roomId, threadId }).then(
3621
3747
  () => {
3622
3748
  store.deleteThread(threadId, optimisticId);
3623
3749
  },
@@ -3651,7 +3777,7 @@ function useEditRoomThreadMetadata(roomId) {
3651
3777
  threadId,
3652
3778
  updatedAt
3653
3779
  });
3654
- client[kInternal3].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3780
+ client[kInternal4].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3655
3781
  (metadata2) => (
3656
3782
  // Replace the optimistic update by the real thing
3657
3783
  store.patchThread(threadId, optimisticId, { metadata: metadata2 }, updatedAt)
@@ -3697,7 +3823,7 @@ function useCreateRoomComment(roomId) {
3697
3823
  comment
3698
3824
  });
3699
3825
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3700
- client[kInternal3].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3826
+ client[kInternal4].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3701
3827
  (newComment) => {
3702
3828
  store.createComment(newComment, optimisticId);
3703
3829
  },
@@ -3753,7 +3879,7 @@ function useEditRoomComment(roomId) {
3753
3879
  }
3754
3880
  });
3755
3881
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3756
- client[kInternal3].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3882
+ client[kInternal4].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3757
3883
  (editedComment) => {
3758
3884
  store.editComment(threadId, optimisticId, editedComment);
3759
3885
  },
@@ -3783,7 +3909,7 @@ function useDeleteRoomComment(roomId) {
3783
3909
  deletedAt,
3784
3910
  roomId
3785
3911
  });
3786
- client[kInternal3].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3912
+ client[kInternal4].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3787
3913
  () => {
3788
3914
  store.deleteComment(threadId, optimisticId, commentId, deletedAt);
3789
3915
  },
@@ -3817,7 +3943,7 @@ function useAddRoomCommentReaction(roomId) {
3817
3943
  createdAt
3818
3944
  }
3819
3945
  });
3820
- client[kInternal3].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3946
+ client[kInternal4].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3821
3947
  (addedReaction) => {
3822
3948
  store.addReaction(
3823
3949
  threadId,
@@ -3861,7 +3987,7 @@ function useRemoveRoomCommentReaction(roomId) {
3861
3987
  userId,
3862
3988
  removedAt
3863
3989
  });
3864
- client[kInternal3].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
3990
+ client[kInternal4].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
3865
3991
  () => {
3866
3992
  store.removeReaction(
3867
3993
  threadId,
@@ -3908,7 +4034,7 @@ function useMarkRoomThreadAsRead(roomId) {
3908
4034
  inboxNotificationId: inboxNotification.id,
3909
4035
  readAt: now
3910
4036
  });
3911
- client[kInternal3].httpClient.markRoomInboxNotificationAsRead({
4037
+ client[kInternal4].httpClient.markRoomInboxNotificationAsRead({
3912
4038
  roomId,
3913
4039
  inboxNotificationId: inboxNotification.id
3914
4040
  }).then(
@@ -3950,7 +4076,7 @@ function useMarkRoomThreadAsResolved(roomId) {
3950
4076
  threadId,
3951
4077
  updatedAt
3952
4078
  });
3953
- client[kInternal3].httpClient.markThreadAsResolved({ roomId, threadId }).then(
4079
+ client[kInternal4].httpClient.markThreadAsResolved({ roomId, threadId }).then(
3954
4080
  () => {
3955
4081
  store.patchThread(
3956
4082
  threadId,
@@ -3983,7 +4109,7 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3983
4109
  threadId,
3984
4110
  updatedAt
3985
4111
  });
3986
- client[kInternal3].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
4112
+ client[kInternal4].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
3987
4113
  () => {
3988
4114
  store.patchThread(
3989
4115
  threadId,
@@ -4016,7 +4142,7 @@ function useSubscribeToRoomThread(roomId) {
4016
4142
  threadId,
4017
4143
  subscribedAt
4018
4144
  });
4019
- client[kInternal3].httpClient.subscribeToThread({ roomId, threadId }).then(
4145
+ client[kInternal4].httpClient.subscribeToThread({ roomId, threadId }).then(
4020
4146
  (subscription) => {
4021
4147
  store.createSubscription(subscription, optimisticId);
4022
4148
  },
@@ -4044,7 +4170,7 @@ function useUnsubscribeFromRoomThread(roomId) {
4044
4170
  threadId,
4045
4171
  unsubscribedAt
4046
4172
  });
4047
- client[kInternal3].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4173
+ client[kInternal4].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4048
4174
  () => {
4049
4175
  store.deleteSubscription(
4050
4176
  getSubscriptionKey2("thread", threadId),
@@ -4108,7 +4234,7 @@ function useRoomNotificationSettings() {
4108
4234
  const room = useRoom();
4109
4235
  const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4110
4236
  const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4111
- useEffect5(
4237
+ useEffect6(
4112
4238
  () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4113
4239
  // NOTE: Deliberately *not* using a dependency array here!
4114
4240
  //
@@ -4119,7 +4245,7 @@ function useRoomNotificationSettings() {
4119
4245
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4120
4246
  // *next* render after that, a *new* fetch/promise will get created.
4121
4247
  );
4122
- useEffect5(() => {
4248
+ useEffect6(() => {
4123
4249
  poller.inc();
4124
4250
  poller.pollNowIfStale();
4125
4251
  return () => {
@@ -4139,7 +4265,7 @@ function useRoomSubscriptionSettings() {
4139
4265
  const room = useRoom();
4140
4266
  const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4141
4267
  const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4142
- useEffect5(
4268
+ useEffect6(
4143
4269
  () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4144
4270
  // NOTE: Deliberately *not* using a dependency array here!
4145
4271
  //
@@ -4150,7 +4276,7 @@ function useRoomSubscriptionSettings() {
4150
4276
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4151
4277
  // *next* render after that, a *new* fetch/promise will get created.
4152
4278
  );
4153
- useEffect5(() => {
4279
+ useEffect6(() => {
4154
4280
  poller.inc();
4155
4281
  poller.pollNowIfStale();
4156
4282
  return () => {
@@ -4195,15 +4321,15 @@ function useRoomSubscriptionSettingsSuspense() {
4195
4321
  }, [settings, updateRoomSubscriptionSettings]);
4196
4322
  }
4197
4323
  function useHistoryVersionData(versionId) {
4198
- const [state, setState] = useState2({
4324
+ const [state, setState] = useState3({
4199
4325
  isLoading: true
4200
4326
  });
4201
4327
  const room = useRoom();
4202
- useEffect5(() => {
4328
+ useEffect6(() => {
4203
4329
  setState({ isLoading: true });
4204
4330
  const load = async () => {
4205
4331
  try {
4206
- const response = await room[kInternal3].getTextVersion(versionId);
4332
+ const response = await room[kInternal4].getTextVersion(versionId);
4207
4333
  const buffer = await response.arrayBuffer();
4208
4334
  const data = new Uint8Array(buffer);
4209
4335
  setState({
@@ -4228,12 +4354,12 @@ function useHistoryVersions() {
4228
4354
  const room = useRoom();
4229
4355
  const { store, getOrCreateVersionsPollerForRoomId } = getRoomExtrasForClient(client);
4230
4356
  const poller = getOrCreateVersionsPollerForRoomId(room.id);
4231
- useEffect5(() => {
4357
+ useEffect6(() => {
4232
4358
  poller.inc();
4233
4359
  poller.pollNowIfStale();
4234
4360
  return () => poller.dec();
4235
4361
  }, [poller]);
4236
- useEffect5(
4362
+ useEffect6(
4237
4363
  () => void store.outputs.versionsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4238
4364
  // NOTE: Deliberately *not* using a dependency array here!
4239
4365
  //
@@ -4406,12 +4532,12 @@ function useAttachmentUrl(attachmentId) {
4406
4532
  }
4407
4533
  function useRoomAttachmentUrl(attachmentId, roomId) {
4408
4534
  const client = useClient();
4409
- const store = client[kInternal3].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4535
+ const store = client[kInternal4].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4410
4536
  const getAttachmentUrlState = useCallback3(
4411
4537
  () => store.getItemState(attachmentId),
4412
4538
  [store, attachmentId]
4413
4539
  );
4414
- useEffect5(() => {
4540
+ useEffect6(() => {
4415
4541
  void store.enqueue(attachmentId);
4416
4542
  }, [store, attachmentId]);
4417
4543
  return useSyncExternalStoreWithSelector(
@@ -4424,7 +4550,7 @@ function useRoomAttachmentUrl(attachmentId, roomId) {
4424
4550
  }
4425
4551
  function useAttachmentUrlSuspense(attachmentId) {
4426
4552
  const room = useRoom();
4427
- const { attachmentUrlsStore } = room[kInternal3];
4553
+ const { attachmentUrlsStore } = room[kInternal4];
4428
4554
  const getAttachmentUrlState = useCallback3(
4429
4555
  () => attachmentUrlsStore.getItemState(attachmentId),
4430
4556
  [attachmentUrlsStore, attachmentId]
@@ -4450,14 +4576,10 @@ function useAttachmentUrlSuspense(attachmentId) {
4450
4576
  error: void 0
4451
4577
  };
4452
4578
  }
4453
- var NO_PERMISSIONS = /* @__PURE__ */ new Set();
4454
4579
  function useRoomPermissions(roomId) {
4455
4580
  const client = useClient();
4456
4581
  const store = getRoomExtrasForClient(client).store;
4457
- return useSignal(
4458
- store.permissionHints.signal,
4459
- (hints) => hints.get(roomId) ?? NO_PERMISSIONS
4460
- );
4582
+ return useSignal(store.permissionHints.getPermissionForRoom\u03A3(roomId));
4461
4583
  }
4462
4584
  function createRoomContext(client) {
4463
4585
  return getOrCreateRoomContextBundle(client);
@@ -4504,15 +4626,17 @@ var _useStorageRoot = useStorageRoot;
4504
4626
  var _useUpdateMyPresence = useUpdateMyPresence;
4505
4627
 
4506
4628
  export {
4629
+ ClientContext,
4630
+ useClientOrNull,
4631
+ useClient,
4507
4632
  RoomContext,
4633
+ RegisterAiKnowledge,
4508
4634
  useSyncExternalStoreWithSelector,
4509
4635
  useSignal,
4510
- ClientContext,
4511
4636
  getUmbrellaStoreForClient,
4512
4637
  useCreateAiChat,
4513
4638
  useDeleteAiChat,
4514
- useClientOrNull,
4515
- useClient,
4639
+ useSendAiMessage,
4516
4640
  LiveblocksProvider,
4517
4641
  createLiveblocksContext,
4518
4642
  useInboxNotifications,
@@ -4535,6 +4659,8 @@ export {
4535
4659
  _useUserThreadsSuspense_experimental,
4536
4660
  _useAiChats,
4537
4661
  _useAiChatsSuspense,
4662
+ _useAiChat,
4663
+ _useAiChatSuspense,
4538
4664
  _useAiChatMessages,
4539
4665
  _useAiChatMessagesSuspense,
4540
4666
  useSyncStatus,
@@ -4620,4 +4746,4 @@ export {
4620
4746
  _useStorageRoot,
4621
4747
  _useUpdateMyPresence
4622
4748
  };
4623
- //# sourceMappingURL=chunk-E6PCFJWE.js.map
4749
+ //# sourceMappingURL=chunk-Y7BGHNHH.js.map