@liveblocks/react 2.25.0-aiprivatebeta9 → 3.1.0-alpha1

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,56 @@ 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
+ var RegisterAiTool = memo(function RegisterAiTool2({
52
+ chatId,
53
+ name,
54
+ tool,
55
+ enabled
56
+ }) {
57
+ const client = useClient();
58
+ const ai = client[kInternal].ai;
59
+ useEffect(() => {
60
+ const toolWithEnabled = enabled !== void 0 ? { ...tool, enabled } : tool;
61
+ return ai.registerTool(name, toolWithEnabled, chatId);
62
+ }, [ai, chatId, name, tool, enabled]);
63
+ return null;
64
+ });
65
+
12
66
  // src/use-sync-external-store-with-selector.ts
13
67
  import {
14
68
  useDebugValue,
15
- useEffect,
69
+ useEffect as useEffect2,
16
70
  useMemo,
17
71
  useRef,
18
72
  useSyncExternalStore
@@ -77,7 +131,7 @@ function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnaps
77
131
  getSelection,
78
132
  getServerSelection
79
133
  );
80
- useEffect(() => {
134
+ useEffect2(() => {
81
135
  inst.hasValue = true;
82
136
  inst.value = value;
83
137
  }, [value]);
@@ -104,24 +158,20 @@ function useSignal(signal, selector, isEqual) {
104
158
  }
105
159
 
106
160
  // src/liveblocks.tsx
107
- import {
108
- HttpError
109
- } from "@liveblocks/core";
110
161
  import {
111
162
  assert,
112
163
  createClient,
113
- kInternal as kInternal2,
164
+ HttpError,
165
+ kInternal as kInternal3,
114
166
  makePoller,
115
- raise,
167
+ raise as raise2,
116
168
  shallow as shallow3
117
169
  } from "@liveblocks/core";
118
170
  import {
119
- createContext as createContext2,
120
171
  useCallback as useCallback2,
121
- useContext as useContext2,
122
- useEffect as useEffect3,
172
+ useEffect as useEffect4,
123
173
  useMemo as useMemo2,
124
- useState,
174
+ useState as useState2,
125
175
  useSyncExternalStore as useSyncExternalStore2
126
176
  } from "react";
127
177
 
@@ -183,10 +233,10 @@ function ensureNotServerSide() {
183
233
  import { useCallback, useReducer } from "react";
184
234
 
185
235
  // src/lib/use-latest.ts
186
- import { useEffect as useEffect2, useRef as useRef2 } from "react";
236
+ import { useEffect as useEffect3, useRef as useRef2 } from "react";
187
237
  function useLatest(value) {
188
238
  const ref = useRef2(value);
189
- useEffect2(() => {
239
+ useEffect3(() => {
190
240
  ref.current = value;
191
241
  }, [value]);
192
242
  return ref;
@@ -246,11 +296,11 @@ import {
246
296
  createNotificationSettings,
247
297
  DefaultMap,
248
298
  DerivedSignal,
249
- getMentionedIdsFromCommentBody,
299
+ getMentionsFromCommentBody,
250
300
  getSubscriptionKey,
251
- kInternal,
301
+ kInternal as kInternal2,
252
302
  MutableSignal as MutableSignal3,
253
- nanoid,
303
+ nanoid as nanoid2,
254
304
  nn,
255
305
  patchNotificationSettings,
256
306
  shallow,
@@ -789,14 +839,14 @@ function createStore_forNotificationSettings(updates) {
789
839
  }
790
840
  function createStore_forOptimistic(client) {
791
841
  const signal = new Signal([]);
792
- const syncSource = client[kInternal].createSyncSource();
842
+ const syncSource = client[kInternal2].createSyncSource();
793
843
  signal.subscribe(
794
844
  () => syncSource.setSyncStatus(
795
845
  signal.get().length > 0 ? "synchronizing" : "synchronized"
796
846
  )
797
847
  );
798
848
  function add(optimisticUpdate) {
799
- const id = nanoid();
849
+ const id = nanoid2();
800
850
  const newUpdate = { ...optimisticUpdate, id };
801
851
  signal.set((state) => [...state, newUpdate]);
802
852
  return id;
@@ -880,7 +930,7 @@ var UmbrellaStore = class {
880
930
  // Copilot chats
881
931
  #aiChats;
882
932
  constructor(client) {
883
- this.#client = client[kInternal].as();
933
+ this.#client = client[kInternal2].as();
884
934
  this.optimisticUpdates = createStore_forOptimistic(this.#client);
885
935
  this.permissionHints = createStore_forPermissionHints();
886
936
  this.#notificationsPaginationState = new PaginatedResource(
@@ -909,7 +959,7 @@ var UmbrellaStore = class {
909
959
  notificationSettingsFetcher
910
960
  );
911
961
  this.#aiChats = new PaginatedResource(async (cursor) => {
912
- const result = await this.#client[kInternal].ai.getChats({
962
+ const result = await this.#client[kInternal2].ai.getChats({
913
963
  cursor
914
964
  });
915
965
  return result.nextCursor;
@@ -951,7 +1001,7 @@ var UmbrellaStore = class {
951
1001
  (queryKey) => {
952
1002
  const query = JSON.parse(queryKey);
953
1003
  const resource = new PaginatedResource(async (cursor) => {
954
- const result = await this.#client[kInternal].httpClient.getUserThreads_experimental({
1004
+ const result = await this.#client[kInternal2].httpClient.getUserThreads_experimental({
955
1005
  cursor,
956
1006
  query
957
1007
  });
@@ -994,7 +1044,7 @@ var UmbrellaStore = class {
994
1044
  (queryKey) => {
995
1045
  const [roomId, query] = JSON.parse(queryKey);
996
1046
  const resource = new PaginatedResource(async (cursor) => {
997
- const result = await this.#client[kInternal].httpClient.getThreads({
1047
+ const result = await this.#client[kInternal2].httpClient.getThreads({
998
1048
  roomId,
999
1049
  cursor,
1000
1050
  query
@@ -1083,7 +1133,7 @@ var UmbrellaStore = class {
1083
1133
  if (room === null) {
1084
1134
  throw new Error(`Room '${roomId}' is not available on client`);
1085
1135
  }
1086
- const result = await room[kInternal].listTextVersions();
1136
+ const result = await room[kInternal2].listTextVersions();
1087
1137
  this.historyVersions.update(roomId, result.versions);
1088
1138
  const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1089
1139
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
@@ -1128,7 +1178,7 @@ var UmbrellaStore = class {
1128
1178
  }
1129
1179
  return {
1130
1180
  isLoading: false,
1131
- chats: this.#client[kInternal].ai.signals.chats\u03A3.get(),
1181
+ chats: this.#client[kInternal2].ai.signals.chats\u03A3.get(),
1132
1182
  hasFetchedAll: result.data.hasFetchedAll,
1133
1183
  isFetchingMore: result.data.isFetchingMore,
1134
1184
  fetchMore: result.data.fetchMore,
@@ -1139,7 +1189,7 @@ var UmbrellaStore = class {
1139
1189
  };
1140
1190
  const messagesByChatId = new DefaultMap((chatId) => {
1141
1191
  const resource\u03A3 = new SinglePageResource(async () => {
1142
- await this.#client[kInternal].ai.getMessageTree(chatId);
1192
+ await this.#client[kInternal2].ai.getMessageTree(chatId);
1143
1193
  });
1144
1194
  return new DefaultMap(
1145
1195
  (branch) => {
@@ -1150,7 +1200,7 @@ var UmbrellaStore = class {
1150
1200
  }
1151
1201
  return ASYNC_OK(
1152
1202
  "messages",
1153
- this.#client[kInternal].ai.signals.getChatMessagesForBranch\u03A3(chatId, branch ?? void 0).get()
1203
+ this.#client[kInternal2].ai.signals.getChatMessagesForBranch\u03A3(chatId, branch ?? void 0).get()
1154
1204
  );
1155
1205
  });
1156
1206
  return { signal, waitUntilLoaded: resource\u03A3.waitUntilLoaded };
@@ -1159,10 +1209,10 @@ var UmbrellaStore = class {
1159
1209
  });
1160
1210
  const aiChatById = new DefaultMap((chatId) => {
1161
1211
  const resource = new SinglePageResource(async () => {
1162
- await this.#client[kInternal].ai.getOrCreateChat(chatId);
1212
+ await this.#client[kInternal2].ai.getOrCreateChat(chatId);
1163
1213
  });
1164
1214
  const signal = DerivedSignal.from(() => {
1165
- const chat = this.#client[kInternal].ai.getChatById(chatId);
1215
+ const chat = this.#client[kInternal2].ai.getChatById(chatId);
1166
1216
  if (chat === void 0) {
1167
1217
  const result = resource.get();
1168
1218
  if (result.isLoading || result.error) {
@@ -1170,13 +1220,13 @@ var UmbrellaStore = class {
1170
1220
  } else {
1171
1221
  return ASYNC_OK(
1172
1222
  "chat",
1173
- nn(this.#client[kInternal].ai.getChatById(chatId))
1223
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1174
1224
  );
1175
1225
  }
1176
1226
  } else {
1177
1227
  return ASYNC_OK(
1178
1228
  "chat",
1179
- nn(this.#client[kInternal].ai.getChatById(chatId))
1229
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1180
1230
  );
1181
1231
  }
1182
1232
  }, shallow);
@@ -1401,7 +1451,7 @@ var UmbrellaStore = class {
1401
1451
  if (lastRequestedAt === void 0) {
1402
1452
  return;
1403
1453
  }
1404
- const updates = await this.#client[kInternal].httpClient.getThreadsSince({
1454
+ const updates = await this.#client[kInternal2].httpClient.getThreadsSince({
1405
1455
  roomId,
1406
1456
  since: lastRequestedAt,
1407
1457
  signal
@@ -1424,7 +1474,7 @@ var UmbrellaStore = class {
1424
1474
  if (lastRequestedAt === null) {
1425
1475
  return;
1426
1476
  }
1427
- const result = await this.#client[kInternal].httpClient.getUserThreadsSince_experimental({
1477
+ const result = await this.#client[kInternal2].httpClient.getUserThreadsSince_experimental({
1428
1478
  since: lastRequestedAt,
1429
1479
  signal
1430
1480
  });
@@ -1450,7 +1500,7 @@ var UmbrellaStore = class {
1450
1500
  this.#client.getRoom(roomId),
1451
1501
  `Room with id ${roomId} is not available on client`
1452
1502
  );
1453
- const updates = await room[kInternal].listTextVersionsSince({
1503
+ const updates = await room[kInternal2].listTextVersionsSince({
1454
1504
  since: lastRequestedAt,
1455
1505
  signal
1456
1506
  });
@@ -1905,8 +1955,11 @@ function isThreadParticipant(thread, userId) {
1905
1955
  isParticipant = true;
1906
1956
  break;
1907
1957
  }
1908
- const mentionedIds = getMentionedIdsFromCommentBody(comment.body);
1909
- if (mentionedIds.includes(userId)) {
1958
+ const mentions = getMentionsFromCommentBody(
1959
+ comment.body,
1960
+ (mention) => mention.kind === "user" && mention.id === userId
1961
+ );
1962
+ if (mentions.length > 0) {
1910
1963
  isParticipant = true;
1911
1964
  break;
1912
1965
  }
@@ -1916,7 +1969,6 @@ function isThreadParticipant(thread, userId) {
1916
1969
 
1917
1970
  // src/liveblocks.tsx
1918
1971
  import { jsx } from "react/jsx-runtime";
1919
- var ClientContext = createContext2(null);
1920
1972
  function missingUserError(userId) {
1921
1973
  return new Error(`resolveUsers didn't return anything for user '${userId}'`);
1922
1974
  }
@@ -2003,6 +2055,11 @@ function getLiveblocksExtrasForClient(client) {
2003
2055
  }
2004
2056
  return extras;
2005
2057
  }
2058
+ function useEnsureAiConnection(client) {
2059
+ useEffect4(() => {
2060
+ client[kInternal3].ai.connectInitially();
2061
+ }, [client]);
2062
+ }
2006
2063
  function makeLiveblocksExtrasForClient(client) {
2007
2064
  const store = getUmbrellaStoreForClient(client);
2008
2065
  const notificationsPoller = makePoller(
@@ -2079,6 +2136,7 @@ function makeLiveblocksContextBundle(client) {
2079
2136
  useAiChatMessages,
2080
2137
  useCreateAiChat,
2081
2138
  useDeleteAiChat,
2139
+ useSendAiMessage,
2082
2140
  ...shared.classic,
2083
2141
  suspense: {
2084
2142
  LiveblocksProvider: LiveblocksProvider2,
@@ -2097,6 +2155,7 @@ function makeLiveblocksContextBundle(client) {
2097
2155
  useAiChatMessages: useAiChatMessagesSuspense,
2098
2156
  useCreateAiChat,
2099
2157
  useDeleteAiChat,
2158
+ useSendAiMessage,
2100
2159
  ...shared.suspense
2101
2160
  }
2102
2161
  };
@@ -2104,7 +2163,7 @@ function makeLiveblocksContextBundle(client) {
2104
2163
  }
2105
2164
  function useInboxNotifications_withClient(client, selector, isEqual) {
2106
2165
  const { store, notificationsPoller: poller } = getLiveblocksExtrasForClient(client);
2107
- useEffect3(
2166
+ useEffect4(
2108
2167
  () => void store.outputs.loadingNotifications.waitUntilLoaded()
2109
2168
  // NOTE: Deliberately *not* using a dependency array here!
2110
2169
  //
@@ -2115,7 +2174,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
2115
2174
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2116
2175
  // *next* render after that, a *new* fetch/promise will get created.
2117
2176
  );
2118
- useEffect3(() => {
2177
+ useEffect4(() => {
2119
2178
  poller.inc();
2120
2179
  poller.pollNowIfStale();
2121
2180
  return () => {
@@ -2173,7 +2232,7 @@ function useMarkInboxNotificationAsRead_withClient(client) {
2173
2232
  },
2174
2233
  (err) => {
2175
2234
  store.optimisticUpdates.remove(optimisticId);
2176
- client[kInternal2].emitError(
2235
+ client[kInternal3].emitError(
2177
2236
  {
2178
2237
  type: "MARK_INBOX_NOTIFICATION_AS_READ_ERROR",
2179
2238
  inboxNotificationId
@@ -2200,7 +2259,7 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
2200
2259
  },
2201
2260
  (err) => {
2202
2261
  store.optimisticUpdates.remove(optimisticId);
2203
- client[kInternal2].emitError(
2262
+ client[kInternal3].emitError(
2204
2263
  // No roomId, threadId, commentId to include for this error
2205
2264
  { type: "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR" },
2206
2265
  err
@@ -2225,7 +2284,7 @@ function useDeleteInboxNotification_withClient(client) {
2225
2284
  },
2226
2285
  (err) => {
2227
2286
  store.optimisticUpdates.remove(optimisticId);
2228
- client[kInternal2].emitError(
2287
+ client[kInternal3].emitError(
2229
2288
  { type: "DELETE_INBOX_NOTIFICATION_ERROR", inboxNotificationId },
2230
2289
  err
2231
2290
  );
@@ -2249,7 +2308,7 @@ function useDeleteAllInboxNotifications_withClient(client) {
2249
2308
  },
2250
2309
  (err) => {
2251
2310
  store.optimisticUpdates.remove(optimisticId);
2252
- client[kInternal2].emitError(
2311
+ client[kInternal3].emitError(
2253
2312
  { type: "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR" },
2254
2313
  err
2255
2314
  );
@@ -2263,15 +2322,15 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
2263
2322
  store.outputs.threadifications,
2264
2323
  useCallback2(
2265
2324
  (state) => {
2266
- const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise(
2325
+ const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise2(
2267
2326
  `Inbox notification with ID "${inboxNotificationId}" not found`
2268
2327
  );
2269
2328
  if (inboxNotification.kind !== "thread") {
2270
- raise(
2329
+ raise2(
2271
2330
  `Inbox notification with ID "${inboxNotificationId}" is not of kind "thread"`
2272
2331
  );
2273
2332
  }
2274
- const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise(
2333
+ const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise2(
2275
2334
  `Thread with ID "${inboxNotification.threadId}" not found, this inbox notification might not be of kind "thread"`
2276
2335
  );
2277
2336
  return thread;
@@ -2302,9 +2361,9 @@ function useUpdateNotificationSettings_withClient(client) {
2302
2361
  const msg = [err.details?.error, err.details?.reason].filter(Boolean).join("\n");
2303
2362
  console.error(msg);
2304
2363
  }
2305
- client[kInternal2].emitError(
2364
+ client[kInternal3].emitError(
2306
2365
  {
2307
- type: "UPDATE_USER_NOTIFICATION_SETTINGS_ERROR"
2366
+ type: "UPDATE_NOTIFICATION_SETTINGS_ERROR"
2308
2367
  },
2309
2368
  err
2310
2369
  );
@@ -2320,10 +2379,10 @@ function useUpdateNotificationSettings_withClient(client) {
2320
2379
  function useNotificationSettings_withClient(client) {
2321
2380
  const updateNotificationSettings = useUpdateNotificationSettings_withClient(client);
2322
2381
  const { store, notificationSettingsPoller: poller } = getLiveblocksExtrasForClient(client);
2323
- useEffect3(() => {
2382
+ useEffect4(() => {
2324
2383
  void store.outputs.notificationSettings.waitUntilLoaded();
2325
2384
  });
2326
- useEffect3(() => {
2385
+ useEffect4(() => {
2327
2386
  poller.inc();
2328
2387
  poller.pollNowIfStale();
2329
2388
  return () => {
@@ -2347,7 +2406,7 @@ function useNotificationSettingsSuspense_withClient(client) {
2347
2406
  }, [result, updateNotificationSettings]);
2348
2407
  }
2349
2408
  function useUser_withClient(client, userId) {
2350
- const usersStore = client[kInternal2].usersStore;
2409
+ const usersStore = client[kInternal3].usersStore;
2351
2410
  const getUserState = useCallback2(
2352
2411
  () => usersStore.getItemState(userId),
2353
2412
  [usersStore, userId]
@@ -2363,7 +2422,7 @@ function useUser_withClient(client, userId) {
2363
2422
  selector,
2364
2423
  shallow3
2365
2424
  );
2366
- useEffect3(
2425
+ useEffect4(
2367
2426
  () => void usersStore.enqueue(userId)
2368
2427
  // NOTE: Deliberately *not* using a dependency array here!
2369
2428
  //
@@ -2378,7 +2437,7 @@ function useUser_withClient(client, userId) {
2378
2437
  return result;
2379
2438
  }
2380
2439
  function useUserSuspense_withClient(client, userId) {
2381
- const usersStore = client[kInternal2].usersStore;
2440
+ const usersStore = client[kInternal3].usersStore;
2382
2441
  const getUserState = useCallback2(
2383
2442
  () => usersStore.getItemState(userId),
2384
2443
  [usersStore, userId]
@@ -2408,7 +2467,7 @@ function useUserSuspense_withClient(client, userId) {
2408
2467
  };
2409
2468
  }
2410
2469
  function useRoomInfo_withClient(client, roomId) {
2411
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2470
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2412
2471
  const getRoomInfoState = useCallback2(
2413
2472
  () => roomsInfoStore.getItemState(roomId),
2414
2473
  [roomsInfoStore, roomId]
@@ -2424,7 +2483,7 @@ function useRoomInfo_withClient(client, roomId) {
2424
2483
  selector,
2425
2484
  shallow3
2426
2485
  );
2427
- useEffect3(
2486
+ useEffect4(
2428
2487
  () => void roomsInfoStore.enqueue(roomId)
2429
2488
  // NOTE: Deliberately *not* using a dependency array here!
2430
2489
  //
@@ -2439,7 +2498,7 @@ function useRoomInfo_withClient(client, roomId) {
2439
2498
  return result;
2440
2499
  }
2441
2500
  function useRoomInfoSuspense_withClient(client, roomId) {
2442
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2501
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2443
2502
  const getRoomInfoState = useCallback2(
2444
2503
  () => roomsInfoStore.getItemState(roomId),
2445
2504
  [roomsInfoStore, roomId]
@@ -2472,7 +2531,8 @@ function useRoomInfoSuspense_withClient(client, roomId) {
2472
2531
  function useAiChats() {
2473
2532
  const client = useClient();
2474
2533
  const store = getUmbrellaStoreForClient(client);
2475
- useEffect3(
2534
+ useEnsureAiConnection(client);
2535
+ useEffect4(
2476
2536
  () => void store.outputs.aiChats.waitUntilLoaded()
2477
2537
  // NOTE: Deliberately *not* using a dependency array here!
2478
2538
  //
@@ -2489,17 +2549,19 @@ function useAiChatsSuspense() {
2489
2549
  ensureNotServerSide();
2490
2550
  const client = useClient();
2491
2551
  const store = getUmbrellaStoreForClient(client);
2552
+ useEnsureAiConnection(client);
2492
2553
  use(store.outputs.aiChats.waitUntilLoaded());
2493
2554
  const result = useAiChats();
2494
2555
  assert(!result.error, "Did not expect error");
2495
2556
  assert(!result.isLoading, "Did not expect loading");
2496
2557
  return result;
2497
2558
  }
2498
- function useAiChatMessages(chatId, branch) {
2559
+ function useAiChatMessages(chatId, options) {
2499
2560
  const client = useClient();
2500
2561
  const store = getUmbrellaStoreForClient(client);
2501
- useEffect3(
2502
- () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2562
+ useEnsureAiConnection(client);
2563
+ useEffect4(
2564
+ () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2503
2565
  // NOTE: Deliberately *not* using a dependency array here!
2504
2566
  //
2505
2567
  // It is important to call waitUntil on *every* render.
@@ -2510,17 +2572,18 @@ function useAiChatMessages(chatId, branch) {
2510
2572
  // *next* render after that, a *new* fetch/promise will get created.
2511
2573
  );
2512
2574
  return useSignal(
2513
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).signal
2575
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).signal
2514
2576
  );
2515
2577
  }
2516
- function useAiChatMessagesSuspense(chatId, branch) {
2578
+ function useAiChatMessagesSuspense(chatId, options) {
2517
2579
  ensureNotServerSide();
2518
2580
  const client = useClient();
2519
2581
  const store = getUmbrellaStoreForClient(client);
2582
+ useEnsureAiConnection(client);
2520
2583
  use(
2521
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2584
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2522
2585
  );
2523
- const result = useAiChatMessages(chatId, branch);
2586
+ const result = useAiChatMessages(chatId, options);
2524
2587
  assert(!result.error, "Did not expect error");
2525
2588
  assert(!result.isLoading, "Did not expect loading");
2526
2589
  return result;
@@ -2528,7 +2591,8 @@ function useAiChatMessagesSuspense(chatId, branch) {
2528
2591
  function useAiChat(chatId) {
2529
2592
  const client = useClient();
2530
2593
  const store = getUmbrellaStoreForClient(client);
2531
- useEffect3(
2594
+ useEnsureAiConnection(client);
2595
+ useEffect4(
2532
2596
  () => void store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded()
2533
2597
  // NOTE: Deliberately *not* using a dependency array here!
2534
2598
  //
@@ -2545,6 +2609,7 @@ function useAiChatSuspense(chatId) {
2545
2609
  ensureNotServerSide();
2546
2610
  const client = useClient();
2547
2611
  const store = getUmbrellaStoreForClient(client);
2612
+ useEnsureAiConnection(client);
2548
2613
  use(store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded());
2549
2614
  const result = useAiChat(chatId);
2550
2615
  assert(!result.error, "Did not expect error");
@@ -2555,7 +2620,10 @@ function useCreateAiChat() {
2555
2620
  const client = useClient();
2556
2621
  return useCallback2(
2557
2622
  (options) => {
2558
- client[kInternal2].ai.getOrCreateChat(options.id, options).catch((err) => {
2623
+ client[kInternal3].ai.getOrCreateChat(options.id, {
2624
+ title: options.title,
2625
+ metadata: options.metadata
2626
+ }).catch((err) => {
2559
2627
  console.error(
2560
2628
  `Failed to create chat with ID "${options.id}": ${String(err)}`
2561
2629
  );
@@ -2568,7 +2636,7 @@ function useDeleteAiChat() {
2568
2636
  const client = useClient();
2569
2637
  return useCallback2(
2570
2638
  (chatId) => {
2571
- client[kInternal2].ai.deleteChat(chatId).catch((err) => {
2639
+ client[kInternal3].ai.deleteChat(chatId).catch((err) => {
2572
2640
  console.error(
2573
2641
  `Failed to delete chat with ID "${chatId}": ${String(err)}`
2574
2642
  );
@@ -2577,6 +2645,39 @@ function useDeleteAiChat() {
2577
2645
  [client]
2578
2646
  );
2579
2647
  }
2648
+ function useSendAiMessage(chatId, options) {
2649
+ const client = useClient();
2650
+ const copilotId = options?.copilotId;
2651
+ return useCallback2(
2652
+ (message) => {
2653
+ const messages = client[kInternal3].ai.signals.getChatMessagesForBranch\u03A3(chatId).get();
2654
+ const lastMessageId = messages[messages.length - 1]?.id ?? null;
2655
+ const content = [{ type: "text", text: message }];
2656
+ const newMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2657
+ chatId,
2658
+ "user",
2659
+ lastMessageId,
2660
+ content
2661
+ );
2662
+ const targetMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2663
+ chatId,
2664
+ "assistant",
2665
+ newMessageId
2666
+ );
2667
+ void client[kInternal3].ai.askUserMessageInChat(
2668
+ chatId,
2669
+ { id: newMessageId, parentMessageId: lastMessageId, content },
2670
+ targetMessageId,
2671
+ {
2672
+ stream: options?.stream,
2673
+ copilotId,
2674
+ timeout: options?.timeout
2675
+ }
2676
+ );
2677
+ },
2678
+ [client, chatId, copilotId, options?.stream, options?.timeout]
2679
+ );
2680
+ }
2580
2681
  function createSharedContext(client) {
2581
2682
  const useClient2 = () => client;
2582
2683
  function useSyncStatus2(options) {
@@ -2589,7 +2690,9 @@ function createSharedContext(client) {
2589
2690
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
2590
2691
  useIsInsideRoom,
2591
2692
  useErrorListener,
2592
- useSyncStatus: useSyncStatus2
2693
+ useSyncStatus: useSyncStatus2,
2694
+ RegisterAiKnowledge,
2695
+ RegisterAiTool
2593
2696
  },
2594
2697
  suspense: {
2595
2698
  useClient: useClient2,
@@ -2597,7 +2700,9 @@ function createSharedContext(client) {
2597
2700
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
2598
2701
  useIsInsideRoom,
2599
2702
  useErrorListener,
2600
- useSyncStatus: useSyncStatus2
2703
+ useSyncStatus: useSyncStatus2,
2704
+ RegisterAiKnowledge,
2705
+ RegisterAiTool
2601
2706
  }
2602
2707
  };
2603
2708
  }
@@ -2609,12 +2714,6 @@ function useEnsureNoLiveblocksProvider(options) {
2609
2714
  );
2610
2715
  }
2611
2716
  }
2612
- function useClientOrNull() {
2613
- return useContext2(ClientContext);
2614
- }
2615
- function useClient() {
2616
- return useClientOrNull() ?? raise("LiveblocksProvider is missing from the React tree.");
2617
- }
2618
2717
  function LiveblocksProviderWithClient(props) {
2619
2718
  useEnsureNoLiveblocksProvider(props);
2620
2719
  return /* @__PURE__ */ jsx(ClientContext.Provider, { value: props.client, children: props.children });
@@ -2628,7 +2727,6 @@ function LiveblocksProvider(props) {
2628
2727
  backgroundKeepAliveTimeout: useInitial(o.backgroundKeepAliveTimeout),
2629
2728
  polyfills: useInitial(o.polyfills),
2630
2729
  largeMessageStrategy: useInitial(o.largeMessageStrategy),
2631
- unstable_fallbackToHTTP: useInitial(o.unstable_fallbackToHTTP),
2632
2730
  unstable_streamData: useInitial(o.unstable_streamData),
2633
2731
  preventUnsavedChanges: useInitial(o.preventUnsavedChanges),
2634
2732
  authEndpoint: useInitialUnlessFunction(o.authEndpoint),
@@ -2647,10 +2745,9 @@ function LiveblocksProvider(props) {
2647
2745
  )
2648
2746
  };
2649
2747
  const client = useMemo2(() => createClient(options), []);
2650
- useEffect3(() => {
2651
- client[kInternal2].ai.connect();
2748
+ useEffect4(() => {
2652
2749
  return () => {
2653
- client[kInternal2].ai.disconnect();
2750
+ client[kInternal3].ai.disconnect();
2654
2751
  };
2655
2752
  }, [client]);
2656
2753
  return /* @__PURE__ */ jsx(LiveblocksProviderWithClient, { client, children });
@@ -2662,7 +2759,7 @@ function useUserThreads_experimental(options = {}) {
2662
2759
  const client = useClient();
2663
2760
  const { store, userThreadsPoller: poller } = getLiveblocksExtrasForClient(client);
2664
2761
  const queryKey = makeUserThreadsQueryKey(options.query);
2665
- useEffect3(
2762
+ useEffect4(
2666
2763
  () => void store.outputs.loadingUserThreads.getOrCreate(queryKey).waitUntilLoaded()
2667
2764
  // NOTE: Deliberately *not* using a dependency array here!
2668
2765
  //
@@ -2673,7 +2770,7 @@ function useUserThreads_experimental(options = {}) {
2673
2770
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2674
2771
  // *next* render after that, a *new* fetch/promise will get created.
2675
2772
  );
2676
- useEffect3(() => {
2773
+ useEffect4(() => {
2677
2774
  poller.inc();
2678
2775
  poller.pollNowIfStale();
2679
2776
  return () => {
@@ -2755,6 +2852,7 @@ var _useUserThreads_experimental = useUserThreads_experimental;
2755
2852
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
2756
2853
  var _useAiChats = useAiChats;
2757
2854
  var _useAiChatsSuspense = useAiChatsSuspense;
2855
+ var _useAiChat = useAiChat;
2758
2856
  var _useAiChatSuspense = useAiChatSuspense;
2759
2857
  var _useAiChatMessages = useAiChatMessages;
2760
2858
  var _useAiChatMessagesSuspense = useAiChatMessagesSuspense;
@@ -2775,9 +2873,9 @@ function useSyncStatusImmediate_withClient(client) {
2775
2873
  }
2776
2874
  function useSyncStatusSmooth_withClient(client) {
2777
2875
  const getter = client.getSyncStatus;
2778
- const [status, setStatus] = useState(getter);
2876
+ const [status, setStatus] = useState2(getter);
2779
2877
  const oldStatus = useLatest(getter());
2780
- useEffect3(() => {
2878
+ useEffect4(() => {
2781
2879
  let timeoutId;
2782
2880
  const unsub = client.events.syncStatus.subscribe(() => {
2783
2881
  const newStatus = getter();
@@ -2801,7 +2899,7 @@ function useSyncStatus(options) {
2801
2899
  function useErrorListener(callback) {
2802
2900
  const client = useClient();
2803
2901
  const savedCallback = useLatest(callback);
2804
- useEffect3(
2902
+ useEffect4(
2805
2903
  () => client.events.error.subscribe((e) => savedCallback.current(e)),
2806
2904
  [client, savedCallback]
2807
2905
  );
@@ -2818,22 +2916,22 @@ import {
2818
2916
  errorIf,
2819
2917
  getSubscriptionKey as getSubscriptionKey2,
2820
2918
  HttpError as HttpError2,
2821
- kInternal as kInternal3,
2919
+ kInternal as kInternal4,
2822
2920
  makePoller as makePoller2,
2823
2921
  ServerMsgCode
2824
2922
  } from "@liveblocks/core";
2825
2923
  import {
2826
2924
  useCallback as useCallback3,
2827
- useEffect as useEffect5,
2925
+ useEffect as useEffect6,
2828
2926
  useMemo as useMemo3,
2829
2927
  useRef as useRef3,
2830
- useState as useState2,
2928
+ useState as useState3,
2831
2929
  useSyncExternalStore as useSyncExternalStore3,
2832
2930
  version as reactVersion
2833
2931
  } from "react";
2834
2932
 
2835
2933
  // src/use-scroll-to-comment-on-load-effect.ts
2836
- import { useEffect as useEffect4 } from "react";
2934
+ import { useEffect as useEffect5 } from "react";
2837
2935
  function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2838
2936
  if (shouldScrollOnLoad === false) return;
2839
2937
  if (!state.threads) return;
@@ -2852,7 +2950,7 @@ function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2852
2950
  comment.scrollIntoView();
2853
2951
  }
2854
2952
  function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
2855
- useEffect4(
2953
+ useEffect5(
2856
2954
  () => {
2857
2955
  handleScrollToCommentOnLoad(shouldScrollOnLoad, state);
2858
2956
  },
@@ -2906,7 +3004,7 @@ function makeMutationContext(room) {
2906
3004
  };
2907
3005
  }
2908
3006
  function getCurrentUserId(client) {
2909
- const userId = client[kInternal3].currentUserId.get();
3007
+ const userId = client[kInternal4].currentUserId.get();
2910
3008
  if (userId === void 0) {
2911
3009
  return "anonymous";
2912
3010
  }
@@ -2943,7 +3041,7 @@ function makeRoomExtrasForClient(client) {
2943
3041
  ].filter(Boolean).join("\n");
2944
3042
  console3.error(detailedMessage);
2945
3043
  }
2946
- client[kInternal3].emitError(context, innerError);
3044
+ client[kInternal4].emitError(context, innerError);
2947
3045
  } else {
2948
3046
  throw innerError;
2949
3047
  }
@@ -3019,8 +3117,6 @@ function makeRoomContextBundle(client) {
3019
3117
  RoomProvider: RoomProvider_withImplicitLiveblocksProvider,
3020
3118
  useRoom,
3021
3119
  useStatus,
3022
- useStorageStatus,
3023
- useBatch,
3024
3120
  useBroadcastEvent,
3025
3121
  useOthersListener,
3026
3122
  useLostConnectionListener,
@@ -3058,9 +3154,7 @@ function makeRoomContextBundle(client) {
3058
3154
  useAttachmentUrl,
3059
3155
  useHistoryVersions,
3060
3156
  useHistoryVersionData,
3061
- useRoomNotificationSettings,
3062
3157
  useRoomSubscriptionSettings,
3063
- useUpdateRoomNotificationSettings,
3064
3158
  useUpdateRoomSubscriptionSettings,
3065
3159
  ...shared.classic,
3066
3160
  suspense: {
@@ -3068,8 +3162,6 @@ function makeRoomContextBundle(client) {
3068
3162
  RoomProvider: RoomProvider_withImplicitLiveblocksProvider,
3069
3163
  useRoom,
3070
3164
  useStatus,
3071
- useStorageStatus: useStorageStatusSuspense,
3072
- useBatch,
3073
3165
  useBroadcastEvent,
3074
3166
  useOthersListener,
3075
3167
  useLostConnectionListener,
@@ -3107,20 +3199,18 @@ function makeRoomContextBundle(client) {
3107
3199
  useAttachmentUrl: useAttachmentUrlSuspense,
3108
3200
  // TODO: useHistoryVersionData: useHistoryVersionDataSuspense,
3109
3201
  useHistoryVersions: useHistoryVersionsSuspense,
3110
- useRoomNotificationSettings: useRoomNotificationSettingsSuspense,
3111
3202
  useRoomSubscriptionSettings: useRoomSubscriptionSettingsSuspense,
3112
- useUpdateRoomNotificationSettings,
3113
3203
  useUpdateRoomSubscriptionSettings,
3114
3204
  ...shared.suspense
3115
3205
  }
3116
3206
  };
3117
- return Object.defineProperty(bundle, kInternal3, {
3207
+ return Object.defineProperty(bundle, kInternal4, {
3118
3208
  enumerable: false
3119
3209
  });
3120
3210
  }
3121
3211
  function RoomProvider(props) {
3122
3212
  const client = useClient();
3123
- const [cache] = useState2(
3213
+ const [cache] = useState3(
3124
3214
  () => /* @__PURE__ */ new Map()
3125
3215
  );
3126
3216
  const stableEnterRoom = useCallback3(
@@ -3170,14 +3260,14 @@ function RoomProviderInner(props) {
3170
3260
  initialStorage: props.initialStorage,
3171
3261
  autoConnect: props.autoConnect ?? typeof window !== "undefined"
3172
3262
  });
3173
- const [{ room }, setRoomLeavePair] = useState2(
3263
+ const [{ room }, setRoomLeavePair] = useState3(
3174
3264
  () => stableEnterRoom(roomId, {
3175
3265
  ...frozenProps,
3176
3266
  autoConnect: false
3177
3267
  // Deliberately using false here on the first render, see below
3178
3268
  })
3179
3269
  );
3180
- useEffect5(() => {
3270
+ useEffect6(() => {
3181
3271
  const { store } = getRoomExtrasForClient(client);
3182
3272
  async function handleCommentEvent(message) {
3183
3273
  if (message.type === ServerMsgCode.THREAD_DELETED) {
@@ -3224,7 +3314,7 @@ function RoomProviderInner(props) {
3224
3314
  (message) => void handleCommentEvent(message)
3225
3315
  );
3226
3316
  }, [client, room]);
3227
- useEffect5(() => {
3317
+ useEffect6(() => {
3228
3318
  const pair = stableEnterRoom(roomId, frozenProps);
3229
3319
  setRoomLeavePair(pair);
3230
3320
  const { room: room2, leave } = pair;
@@ -3254,14 +3344,14 @@ function useStatus() {
3254
3344
  function useReportTextEditor(editor, rootKey) {
3255
3345
  const isReported = useRef3(false);
3256
3346
  const room = useRoom();
3257
- useEffect5(() => {
3347
+ useEffect6(() => {
3258
3348
  if (isReported.current) {
3259
3349
  return;
3260
3350
  }
3261
3351
  const unsubscribe = room.events.status.subscribe((status) => {
3262
3352
  if (status === "connected" && !isReported.current) {
3263
3353
  isReported.current = true;
3264
- void room[kInternal3].reportTextEditor(editor, rootKey);
3354
+ void room[kInternal4].reportTextEditor(editor, rootKey);
3265
3355
  }
3266
3356
  });
3267
3357
  return unsubscribe;
@@ -3271,12 +3361,12 @@ function useYjsProvider() {
3271
3361
  const room = useRoom();
3272
3362
  const subscribe = useCallback3(
3273
3363
  (onStoreChange) => {
3274
- return room[kInternal3].yjsProviderDidChange.subscribe(onStoreChange);
3364
+ return room[kInternal4].yjsProviderDidChange.subscribe(onStoreChange);
3275
3365
  },
3276
3366
  [room]
3277
3367
  );
3278
3368
  const getSnapshot = useCallback3(() => {
3279
- return room[kInternal3].getYjsProvider();
3369
+ return room[kInternal4].getYjsProvider();
3280
3370
  }, [room]);
3281
3371
  return useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
3282
3372
  }
@@ -3284,7 +3374,7 @@ function useCreateTextMention() {
3284
3374
  const room = useRoom();
3285
3375
  return useCallback3(
3286
3376
  (userId, mentionId) => {
3287
- room[kInternal3].createTextMention(userId, mentionId).catch((err) => {
3377
+ room[kInternal4].createTextMention(userId, mentionId).catch((err) => {
3288
3378
  console3.error(
3289
3379
  `Cannot create text mention for user '${userId}' and mention '${mentionId}'`,
3290
3380
  err
@@ -3298,7 +3388,7 @@ function useDeleteTextMention() {
3298
3388
  const room = useRoom();
3299
3389
  return useCallback3(
3300
3390
  (mentionId) => {
3301
- room[kInternal3].deleteTextMention(mentionId).catch((err) => {
3391
+ room[kInternal4].deleteTextMention(mentionId).catch((err) => {
3302
3392
  console3.error(`Cannot delete text mention '${mentionId}'`, err);
3303
3393
  });
3304
3394
  },
@@ -3307,50 +3397,11 @@ function useDeleteTextMention() {
3307
3397
  }
3308
3398
  function useResolveMentionSuggestions() {
3309
3399
  const client = useClient();
3310
- return client[kInternal3].resolveMentionSuggestions;
3400
+ return client[kInternal4].resolveMentionSuggestions;
3311
3401
  }
3312
3402
  function useMentionSuggestionsCache() {
3313
3403
  const client = useClient();
3314
- return client[kInternal3].mentionSuggestionsCache;
3315
- }
3316
- function useStorageStatus(options) {
3317
- const smooth = useInitial(options?.smooth ?? false);
3318
- if (smooth) {
3319
- return useStorageStatusSmooth();
3320
- } else {
3321
- return useStorageStatusImmediate();
3322
- }
3323
- }
3324
- function useStorageStatusImmediate() {
3325
- const room = useRoom();
3326
- const subscribe = room.events.storageStatus.subscribe;
3327
- const getSnapshot = room.getStorageStatus;
3328
- const getServerSnapshot = room.getStorageStatus;
3329
- return useSyncExternalStore3(subscribe, getSnapshot, getServerSnapshot);
3330
- }
3331
- function useStorageStatusSmooth() {
3332
- const room = useRoom();
3333
- const [status, setStatus] = useState2(room.getStorageStatus);
3334
- const oldStatus = useLatest(room.getStorageStatus());
3335
- useEffect5(() => {
3336
- let timeoutId;
3337
- const unsub = room.events.storageStatus.subscribe((newStatus) => {
3338
- if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
3339
- timeoutId = setTimeout(() => setStatus(newStatus), config.SMOOTH_DELAY);
3340
- } else {
3341
- clearTimeout(timeoutId);
3342
- setStatus(newStatus);
3343
- }
3344
- });
3345
- return () => {
3346
- clearTimeout(timeoutId);
3347
- unsub();
3348
- };
3349
- }, [room, oldStatus]);
3350
- return status;
3351
- }
3352
- function useBatch() {
3353
- return useRoom().batch;
3404
+ return client[kInternal4].mentionSuggestionsCache;
3354
3405
  }
3355
3406
  function useBroadcastEvent() {
3356
3407
  const room = useRoom();
@@ -3364,7 +3415,7 @@ function useBroadcastEvent() {
3364
3415
  function useOthersListener(callback) {
3365
3416
  const room = useRoom();
3366
3417
  const savedCallback = useLatest(callback);
3367
- useEffect5(
3418
+ useEffect6(
3368
3419
  () => room.events.others.subscribe((event) => savedCallback.current(event)),
3369
3420
  [room, savedCallback]
3370
3421
  );
@@ -3372,7 +3423,7 @@ function useOthersListener(callback) {
3372
3423
  function useLostConnectionListener(callback) {
3373
3424
  const room = useRoom();
3374
3425
  const savedCallback = useLatest(callback);
3375
- useEffect5(
3426
+ useEffect6(
3376
3427
  () => room.events.lostConnection.subscribe(
3377
3428
  (event) => savedCallback.current(event)
3378
3429
  ),
@@ -3382,7 +3433,7 @@ function useLostConnectionListener(callback) {
3382
3433
  function useEventListener(callback) {
3383
3434
  const room = useRoom();
3384
3435
  const savedCallback = useLatest(callback);
3385
- useEffect5(() => {
3436
+ useEffect6(() => {
3386
3437
  const listener = (eventData) => {
3387
3438
  savedCallback.current(eventData);
3388
3439
  };
@@ -3566,7 +3617,7 @@ function useThreads(options = {}) {
3566
3617
  const { store, getOrCreateThreadsPollerForRoomId } = getRoomExtrasForClient(client);
3567
3618
  const queryKey = makeRoomThreadsQueryKey(room.id, options.query);
3568
3619
  const poller = getOrCreateThreadsPollerForRoomId(room.id);
3569
- useEffect5(
3620
+ useEffect6(
3570
3621
  () => void store.outputs.loadingRoomThreads.getOrCreate(queryKey).waitUntilLoaded()
3571
3622
  // NOTE: Deliberately *not* using a dependency array here!
3572
3623
  //
@@ -3577,7 +3628,7 @@ function useThreads(options = {}) {
3577
3628
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
3578
3629
  // *next* render after that, a *new* fetch/promise will get created.
3579
3630
  );
3580
- useEffect5(() => {
3631
+ useEffect6(() => {
3581
3632
  poller.inc();
3582
3633
  poller.pollNowIfStale();
3583
3634
  return () => poller.dec();
@@ -3629,7 +3680,7 @@ function useCreateRoomThread(roomId) {
3629
3680
  roomId
3630
3681
  });
3631
3682
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3632
- client[kInternal3].httpClient.createThread({
3683
+ client[kInternal4].httpClient.createThread({
3633
3684
  roomId,
3634
3685
  threadId,
3635
3686
  commentId,
@@ -3677,7 +3728,7 @@ function useDeleteRoomThread(roomId) {
3677
3728
  threadId,
3678
3729
  deletedAt: /* @__PURE__ */ new Date()
3679
3730
  });
3680
- client[kInternal3].httpClient.deleteThread({ roomId, threadId }).then(
3731
+ client[kInternal4].httpClient.deleteThread({ roomId, threadId }).then(
3681
3732
  () => {
3682
3733
  store.deleteThread(threadId, optimisticId);
3683
3734
  },
@@ -3711,7 +3762,7 @@ function useEditRoomThreadMetadata(roomId) {
3711
3762
  threadId,
3712
3763
  updatedAt
3713
3764
  });
3714
- client[kInternal3].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3765
+ client[kInternal4].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3715
3766
  (metadata2) => (
3716
3767
  // Replace the optimistic update by the real thing
3717
3768
  store.patchThread(threadId, optimisticId, { metadata: metadata2 }, updatedAt)
@@ -3757,7 +3808,7 @@ function useCreateRoomComment(roomId) {
3757
3808
  comment
3758
3809
  });
3759
3810
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3760
- client[kInternal3].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3811
+ client[kInternal4].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3761
3812
  (newComment) => {
3762
3813
  store.createComment(newComment, optimisticId);
3763
3814
  },
@@ -3813,7 +3864,7 @@ function useEditRoomComment(roomId) {
3813
3864
  }
3814
3865
  });
3815
3866
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3816
- client[kInternal3].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3867
+ client[kInternal4].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3817
3868
  (editedComment) => {
3818
3869
  store.editComment(threadId, optimisticId, editedComment);
3819
3870
  },
@@ -3843,7 +3894,7 @@ function useDeleteRoomComment(roomId) {
3843
3894
  deletedAt,
3844
3895
  roomId
3845
3896
  });
3846
- client[kInternal3].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3897
+ client[kInternal4].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3847
3898
  () => {
3848
3899
  store.deleteComment(threadId, optimisticId, commentId, deletedAt);
3849
3900
  },
@@ -3877,7 +3928,7 @@ function useAddRoomCommentReaction(roomId) {
3877
3928
  createdAt
3878
3929
  }
3879
3930
  });
3880
- client[kInternal3].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3931
+ client[kInternal4].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3881
3932
  (addedReaction) => {
3882
3933
  store.addReaction(
3883
3934
  threadId,
@@ -3921,7 +3972,7 @@ function useRemoveRoomCommentReaction(roomId) {
3921
3972
  userId,
3922
3973
  removedAt
3923
3974
  });
3924
- client[kInternal3].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
3975
+ client[kInternal4].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
3925
3976
  () => {
3926
3977
  store.removeReaction(
3927
3978
  threadId,
@@ -3968,7 +4019,7 @@ function useMarkRoomThreadAsRead(roomId) {
3968
4019
  inboxNotificationId: inboxNotification.id,
3969
4020
  readAt: now
3970
4021
  });
3971
- client[kInternal3].httpClient.markRoomInboxNotificationAsRead({
4022
+ client[kInternal4].httpClient.markRoomInboxNotificationAsRead({
3972
4023
  roomId,
3973
4024
  inboxNotificationId: inboxNotification.id
3974
4025
  }).then(
@@ -4010,7 +4061,7 @@ function useMarkRoomThreadAsResolved(roomId) {
4010
4061
  threadId,
4011
4062
  updatedAt
4012
4063
  });
4013
- client[kInternal3].httpClient.markThreadAsResolved({ roomId, threadId }).then(
4064
+ client[kInternal4].httpClient.markThreadAsResolved({ roomId, threadId }).then(
4014
4065
  () => {
4015
4066
  store.patchThread(
4016
4067
  threadId,
@@ -4043,7 +4094,7 @@ function useMarkRoomThreadAsUnresolved(roomId) {
4043
4094
  threadId,
4044
4095
  updatedAt
4045
4096
  });
4046
- client[kInternal3].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
4097
+ client[kInternal4].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
4047
4098
  () => {
4048
4099
  store.patchThread(
4049
4100
  threadId,
@@ -4076,7 +4127,7 @@ function useSubscribeToRoomThread(roomId) {
4076
4127
  threadId,
4077
4128
  subscribedAt
4078
4129
  });
4079
- client[kInternal3].httpClient.subscribeToThread({ roomId, threadId }).then(
4130
+ client[kInternal4].httpClient.subscribeToThread({ roomId, threadId }).then(
4080
4131
  (subscription) => {
4081
4132
  store.createSubscription(subscription, optimisticId);
4082
4133
  },
@@ -4104,7 +4155,7 @@ function useUnsubscribeFromRoomThread(roomId) {
4104
4155
  threadId,
4105
4156
  unsubscribedAt
4106
4157
  });
4107
- client[kInternal3].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4158
+ client[kInternal4].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4108
4159
  () => {
4109
4160
  store.deleteSubscription(
4110
4161
  getSubscriptionKey2("thread", threadId),
@@ -4162,44 +4213,13 @@ function useRoomThreadSubscription(roomId, threadId) {
4162
4213
  );
4163
4214
  return useSignal(signal, selector, shallow4);
4164
4215
  }
4165
- function useRoomNotificationSettings() {
4166
- const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
4167
- const client = useClient();
4168
- const room = useRoom();
4169
- const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4170
- const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4171
- useEffect5(
4172
- () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4173
- // NOTE: Deliberately *not* using a dependency array here!
4174
- //
4175
- // It is important to call waitUntil on *every* render.
4176
- // This is harmless though, on most renders, except:
4177
- // 1. The very first render, in which case we'll want to trigger the initial page fetch.
4178
- // 2. All other subsequent renders now "just" return the same promise (a quick operation).
4179
- // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4180
- // *next* render after that, a *new* fetch/promise will get created.
4181
- );
4182
- useEffect5(() => {
4183
- poller.inc();
4184
- poller.pollNowIfStale();
4185
- return () => {
4186
- poller.dec();
4187
- };
4188
- }, [poller]);
4189
- const settings = useSignal(
4190
- store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).signal
4191
- );
4192
- return useMemo3(() => {
4193
- return [settings, updateRoomNotificationSettings];
4194
- }, [settings, updateRoomNotificationSettings]);
4195
- }
4196
4216
  function useRoomSubscriptionSettings() {
4197
4217
  const updateRoomSubscriptionSettings = useUpdateRoomSubscriptionSettings();
4198
4218
  const client = useClient();
4199
4219
  const room = useRoom();
4200
4220
  const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4201
4221
  const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4202
- useEffect5(
4222
+ useEffect6(
4203
4223
  () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4204
4224
  // NOTE: Deliberately *not* using a dependency array here!
4205
4225
  //
@@ -4210,7 +4230,7 @@ function useRoomSubscriptionSettings() {
4210
4230
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4211
4231
  // *next* render after that, a *new* fetch/promise will get created.
4212
4232
  );
4213
- useEffect5(() => {
4233
+ useEffect6(() => {
4214
4234
  poller.inc();
4215
4235
  poller.pollNowIfStale();
4216
4236
  return () => {
@@ -4224,21 +4244,6 @@ function useRoomSubscriptionSettings() {
4224
4244
  return [settings, updateRoomSubscriptionSettings];
4225
4245
  }, [settings, updateRoomSubscriptionSettings]);
4226
4246
  }
4227
- function useRoomNotificationSettingsSuspense() {
4228
- ensureNotServerSide();
4229
- const client = useClient();
4230
- const store = getRoomExtrasForClient(client).store;
4231
- const room = useRoom();
4232
- use(
4233
- store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4234
- );
4235
- const [settings, updateRoomNotificationSettings] = useRoomNotificationSettings();
4236
- assert2(!settings.error, "Did not expect error");
4237
- assert2(!settings.isLoading, "Did not expect loading");
4238
- return useMemo3(() => {
4239
- return [settings, updateRoomNotificationSettings];
4240
- }, [settings, updateRoomNotificationSettings]);
4241
- }
4242
4247
  function useRoomSubscriptionSettingsSuspense() {
4243
4248
  ensureNotServerSide();
4244
4249
  const client = useClient();
@@ -4255,15 +4260,15 @@ function useRoomSubscriptionSettingsSuspense() {
4255
4260
  }, [settings, updateRoomSubscriptionSettings]);
4256
4261
  }
4257
4262
  function useHistoryVersionData(versionId) {
4258
- const [state, setState] = useState2({
4263
+ const [state, setState] = useState3({
4259
4264
  isLoading: true
4260
4265
  });
4261
4266
  const room = useRoom();
4262
- useEffect5(() => {
4267
+ useEffect6(() => {
4263
4268
  setState({ isLoading: true });
4264
4269
  const load = async () => {
4265
4270
  try {
4266
- const response = await room[kInternal3].getTextVersion(versionId);
4271
+ const response = await room[kInternal4].getTextVersion(versionId);
4267
4272
  const buffer = await response.arrayBuffer();
4268
4273
  const data = new Uint8Array(buffer);
4269
4274
  setState({
@@ -4288,12 +4293,12 @@ function useHistoryVersions() {
4288
4293
  const room = useRoom();
4289
4294
  const { store, getOrCreateVersionsPollerForRoomId } = getRoomExtrasForClient(client);
4290
4295
  const poller = getOrCreateVersionsPollerForRoomId(room.id);
4291
- useEffect5(() => {
4296
+ useEffect6(() => {
4292
4297
  poller.inc();
4293
4298
  poller.pollNowIfStale();
4294
4299
  return () => poller.dec();
4295
4300
  }, [poller]);
4296
- useEffect5(
4301
+ useEffect6(
4297
4302
  () => void store.outputs.versionsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4298
4303
  // NOTE: Deliberately *not* using a dependency array here!
4299
4304
  //
@@ -4317,40 +4322,6 @@ function useHistoryVersionsSuspense() {
4317
4322
  assert2(!result.isLoading, "Did not expect loading");
4318
4323
  return result;
4319
4324
  }
4320
- function useUpdateRoomNotificationSettings() {
4321
- const client = useClient();
4322
- const room = useRoom();
4323
- return useCallback3(
4324
- (settings) => {
4325
- const { store, onMutationFailure, pollThreadsForRoomId } = getRoomExtrasForClient(client);
4326
- const userId = getCurrentUserId(client);
4327
- const optimisticId = store.optimisticUpdates.add({
4328
- type: "update-room-subscription-settings",
4329
- roomId: room.id,
4330
- userId,
4331
- settings
4332
- });
4333
- room.updateSubscriptionSettings(settings).then(
4334
- (updatedSettings) => {
4335
- store.updateRoomSubscriptionSettings(
4336
- room.id,
4337
- optimisticId,
4338
- updatedSettings
4339
- );
4340
- if (settings.threads) {
4341
- pollThreadsForRoomId(room.id);
4342
- }
4343
- },
4344
- (err) => onMutationFailure(
4345
- optimisticId,
4346
- { type: "UPDATE_NOTIFICATION_SETTINGS_ERROR", roomId: room.id },
4347
- err
4348
- )
4349
- );
4350
- },
4351
- [client, room]
4352
- );
4353
- }
4354
4325
  function useUpdateRoomSubscriptionSettings() {
4355
4326
  const client = useClient();
4356
4327
  const room = useRoom();
@@ -4431,10 +4402,6 @@ function useStorageSuspense(selector, isEqual) {
4431
4402
  isEqual
4432
4403
  );
4433
4404
  }
4434
- function useStorageStatusSuspense(options) {
4435
- useSuspendUntilStorageReady();
4436
- return useStorageStatus(options);
4437
- }
4438
4405
  function useThreadsSuspense(options = {}) {
4439
4406
  ensureNotServerSide();
4440
4407
  const client = useClient();
@@ -4466,12 +4433,12 @@ function useAttachmentUrl(attachmentId) {
4466
4433
  }
4467
4434
  function useRoomAttachmentUrl(attachmentId, roomId) {
4468
4435
  const client = useClient();
4469
- const store = client[kInternal3].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4436
+ const store = client[kInternal4].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4470
4437
  const getAttachmentUrlState = useCallback3(
4471
4438
  () => store.getItemState(attachmentId),
4472
4439
  [store, attachmentId]
4473
4440
  );
4474
- useEffect5(() => {
4441
+ useEffect6(() => {
4475
4442
  void store.enqueue(attachmentId);
4476
4443
  }, [store, attachmentId]);
4477
4444
  return useSyncExternalStoreWithSelector(
@@ -4484,7 +4451,7 @@ function useRoomAttachmentUrl(attachmentId, roomId) {
4484
4451
  }
4485
4452
  function useAttachmentUrlSuspense(attachmentId) {
4486
4453
  const room = useRoom();
4487
- const { attachmentUrlsStore } = room[kInternal3];
4454
+ const { attachmentUrlsStore } = room[kInternal4];
4488
4455
  const getAttachmentUrlState = useCallback3(
4489
4456
  () => attachmentUrlsStore.getItemState(attachmentId),
4490
4457
  [attachmentUrlsStore, attachmentId]
@@ -4534,9 +4501,7 @@ var _useOthersMapped = useOthersMapped;
4534
4501
  var _useOthersMappedSuspense = useOthersMappedSuspense;
4535
4502
  var _useThreads = useThreads;
4536
4503
  var _useThreadsSuspense = useThreadsSuspense;
4537
- var _useRoomNotificationSettings = useRoomNotificationSettings;
4538
4504
  var _useRoomSubscriptionSettings = useRoomSubscriptionSettings;
4539
- var _useRoomNotificationSettingsSuspense = useRoomNotificationSettingsSuspense;
4540
4505
  var _useRoomSubscriptionSettingsSuspense = useRoomSubscriptionSettingsSuspense;
4541
4506
  var _useHistoryVersions = useHistoryVersions;
4542
4507
  var _useHistoryVersionsSuspense = useHistoryVersionsSuspense;
@@ -4560,15 +4525,18 @@ var _useStorageRoot = useStorageRoot;
4560
4525
  var _useUpdateMyPresence = useUpdateMyPresence;
4561
4526
 
4562
4527
  export {
4528
+ ClientContext,
4529
+ useClientOrNull,
4530
+ useClient,
4563
4531
  RoomContext,
4532
+ RegisterAiKnowledge,
4533
+ RegisterAiTool,
4564
4534
  useSyncExternalStoreWithSelector,
4565
4535
  useSignal,
4566
- ClientContext,
4567
4536
  getUmbrellaStoreForClient,
4568
4537
  useCreateAiChat,
4569
4538
  useDeleteAiChat,
4570
- useClientOrNull,
4571
- useClient,
4539
+ useSendAiMessage,
4572
4540
  LiveblocksProvider,
4573
4541
  createLiveblocksContext,
4574
4542
  useInboxNotifications,
@@ -4591,6 +4559,7 @@ export {
4591
4559
  _useUserThreadsSuspense_experimental,
4592
4560
  _useAiChats,
4593
4561
  _useAiChatsSuspense,
4562
+ _useAiChat,
4594
4563
  _useAiChatSuspense,
4595
4564
  _useAiChatMessages,
4596
4565
  _useAiChatMessagesSuspense,
@@ -4603,8 +4572,6 @@ export {
4603
4572
  useDeleteTextMention,
4604
4573
  useResolveMentionSuggestions,
4605
4574
  useMentionSuggestionsCache,
4606
- useStorageStatus,
4607
- useBatch,
4608
4575
  useLostConnectionListener,
4609
4576
  useHistory,
4610
4577
  useUndo,
@@ -4635,10 +4602,8 @@ export {
4635
4602
  useThreadSubscription,
4636
4603
  useRoomThreadSubscription,
4637
4604
  useHistoryVersionData,
4638
- useUpdateRoomNotificationSettings,
4639
4605
  useUpdateRoomSubscriptionSettings,
4640
4606
  useOthersConnectionIdsSuspense,
4641
- useStorageStatusSuspense,
4642
4607
  useAttachmentUrl,
4643
4608
  useRoomAttachmentUrl,
4644
4609
  useAttachmentUrlSuspense,
@@ -4660,9 +4625,7 @@ export {
4660
4625
  _useOthersMappedSuspense,
4661
4626
  _useThreads,
4662
4627
  _useThreadsSuspense,
4663
- _useRoomNotificationSettings,
4664
4628
  _useRoomSubscriptionSettings,
4665
- _useRoomNotificationSettingsSuspense,
4666
4629
  _useRoomSubscriptionSettingsSuspense,
4667
4630
  _useHistoryVersions,
4668
4631
  _useHistoryVersionsSuspense,
@@ -4677,4 +4640,4 @@ export {
4677
4640
  _useStorageRoot,
4678
4641
  _useUpdateMyPresence
4679
4642
  };
4680
- //# sourceMappingURL=chunk-TMKZ6U2Y.js.map
4643
+ //# sourceMappingURL=chunk-MXMOBMOL.js.map