@liveblocks/react 2.25.0-aiprivatebeta9 → 3.0.0

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