@liveblocks/react 2.25.0-aiprivatebeta1 → 2.25.0-aiprivatebeta11

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;
@@ -248,9 +296,9 @@ import {
248
296
  DerivedSignal,
249
297
  getMentionedIdsFromCommentBody,
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,
@@ -746,21 +794,26 @@ function createStore_forHistoryVersions() {
746
794
  };
747
795
  }
748
796
  function createStore_forPermissionHints() {
749
- const signal = new MutableSignal3(
750
- new DefaultMap(() => /* @__PURE__ */ new Set())
797
+ const permissionsByRoomId = new DefaultMap(
798
+ () => new Signal(/* @__PURE__ */ new Set())
751
799
  );
752
800
  function update(newHints) {
753
- signal.mutate((lut) => {
754
- for (const [roomId, newPermissions] of Object.entries(newHints)) {
755
- const existing = lut.getOrCreate(roomId);
756
- for (const permission of newPermissions) {
757
- existing.add(permission);
801
+ batch2(() => {
802
+ for (const [roomId, permissions] of Object.entries(newHints)) {
803
+ const signal = permissionsByRoomId.getOrCreate(roomId);
804
+ const existingPermissions = new Set(signal.get());
805
+ for (const permission of permissions) {
806
+ existingPermissions.add(permission);
758
807
  }
808
+ signal.set(existingPermissions);
759
809
  }
760
810
  });
761
811
  }
812
+ function getPermissionForRoom\u03A3(roomId) {
813
+ return permissionsByRoomId.getOrCreate(roomId);
814
+ }
762
815
  return {
763
- signal: signal.asReadonly(),
816
+ getPermissionForRoom\u03A3,
764
817
  // Mutations
765
818
  update
766
819
  };
@@ -784,14 +837,14 @@ function createStore_forNotificationSettings(updates) {
784
837
  }
785
838
  function createStore_forOptimistic(client) {
786
839
  const signal = new Signal([]);
787
- const syncSource = client[kInternal].createSyncSource();
840
+ const syncSource = client[kInternal2].createSyncSource();
788
841
  signal.subscribe(
789
842
  () => syncSource.setSyncStatus(
790
843
  signal.get().length > 0 ? "synchronizing" : "synchronized"
791
844
  )
792
845
  );
793
846
  function add(optimisticUpdate) {
794
- const id = nanoid();
847
+ const id = nanoid2();
795
848
  const newUpdate = { ...optimisticUpdate, id };
796
849
  signal.set((state) => [...state, newUpdate]);
797
850
  return id;
@@ -875,7 +928,7 @@ var UmbrellaStore = class {
875
928
  // Copilot chats
876
929
  #aiChats;
877
930
  constructor(client) {
878
- this.#client = client[kInternal].as();
931
+ this.#client = client[kInternal2].as();
879
932
  this.optimisticUpdates = createStore_forOptimistic(this.#client);
880
933
  this.permissionHints = createStore_forPermissionHints();
881
934
  this.#notificationsPaginationState = new PaginatedResource(
@@ -904,7 +957,7 @@ var UmbrellaStore = class {
904
957
  notificationSettingsFetcher
905
958
  );
906
959
  this.#aiChats = new PaginatedResource(async (cursor) => {
907
- const result = await this.#client[kInternal].ai.getChats({
960
+ const result = await this.#client[kInternal2].ai.getChats({
908
961
  cursor
909
962
  });
910
963
  return result.nextCursor;
@@ -946,7 +999,7 @@ var UmbrellaStore = class {
946
999
  (queryKey) => {
947
1000
  const query = JSON.parse(queryKey);
948
1001
  const resource = new PaginatedResource(async (cursor) => {
949
- const result = await this.#client[kInternal].httpClient.getUserThreads_experimental({
1002
+ const result = await this.#client[kInternal2].httpClient.getUserThreads_experimental({
950
1003
  cursor,
951
1004
  query
952
1005
  });
@@ -989,7 +1042,7 @@ var UmbrellaStore = class {
989
1042
  (queryKey) => {
990
1043
  const [roomId, query] = JSON.parse(queryKey);
991
1044
  const resource = new PaginatedResource(async (cursor) => {
992
- const result = await this.#client[kInternal].httpClient.getThreads({
1045
+ const result = await this.#client[kInternal2].httpClient.getThreads({
993
1046
  roomId,
994
1047
  cursor,
995
1048
  query
@@ -1078,7 +1131,7 @@ var UmbrellaStore = class {
1078
1131
  if (room === null) {
1079
1132
  throw new Error(`Room '${roomId}' is not available on client`);
1080
1133
  }
1081
- const result = await room[kInternal].listTextVersions();
1134
+ const result = await room[kInternal2].listTextVersions();
1082
1135
  this.historyVersions.update(roomId, result.versions);
1083
1136
  const lastRequestedAt = this.#roomVersionsLastRequestedAtByRoom.get(roomId);
1084
1137
  if (lastRequestedAt === void 0 || lastRequestedAt > result.requestedAt) {
@@ -1123,7 +1176,7 @@ var UmbrellaStore = class {
1123
1176
  }
1124
1177
  return {
1125
1178
  isLoading: false,
1126
- chats: this.#client[kInternal].ai.signals.chats\u03A3.get(),
1179
+ chats: this.#client[kInternal2].ai.signals.chats\u03A3.get(),
1127
1180
  hasFetchedAll: result.data.hasFetchedAll,
1128
1181
  isFetchingMore: result.data.isFetchingMore,
1129
1182
  fetchMore: result.data.fetchMore,
@@ -1134,7 +1187,7 @@ var UmbrellaStore = class {
1134
1187
  };
1135
1188
  const messagesByChatId = new DefaultMap((chatId) => {
1136
1189
  const resource\u03A3 = new SinglePageResource(async () => {
1137
- await this.#client[kInternal].ai.getMessageTree(chatId);
1190
+ await this.#client[kInternal2].ai.getMessageTree(chatId);
1138
1191
  });
1139
1192
  return new DefaultMap(
1140
1193
  (branch) => {
@@ -1145,13 +1198,38 @@ var UmbrellaStore = class {
1145
1198
  }
1146
1199
  return ASYNC_OK(
1147
1200
  "messages",
1148
- 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()
1149
1202
  );
1150
1203
  });
1151
1204
  return { signal, waitUntilLoaded: resource\u03A3.waitUntilLoaded };
1152
1205
  }
1153
1206
  );
1154
1207
  });
1208
+ const aiChatById = new DefaultMap((chatId) => {
1209
+ const resource = new SinglePageResource(async () => {
1210
+ await this.#client[kInternal2].ai.getOrCreateChat(chatId);
1211
+ });
1212
+ const signal = DerivedSignal.from(() => {
1213
+ const chat = this.#client[kInternal2].ai.getChatById(chatId);
1214
+ if (chat === void 0) {
1215
+ const result = resource.get();
1216
+ if (result.isLoading || result.error) {
1217
+ return result;
1218
+ } else {
1219
+ return ASYNC_OK(
1220
+ "chat",
1221
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1222
+ );
1223
+ }
1224
+ } else {
1225
+ return ASYNC_OK(
1226
+ "chat",
1227
+ nn(this.#client[kInternal2].ai.getChatById(chatId))
1228
+ );
1229
+ }
1230
+ }, shallow);
1231
+ return { signal, waitUntilLoaded: resource.waitUntilLoaded };
1232
+ });
1155
1233
  this.outputs = {
1156
1234
  threadifications,
1157
1235
  threads,
@@ -1164,7 +1242,8 @@ var UmbrellaStore = class {
1164
1242
  notificationSettings,
1165
1243
  threadSubscriptions,
1166
1244
  aiChats,
1167
- messagesByChatId
1245
+ messagesByChatId,
1246
+ aiChatById
1168
1247
  };
1169
1248
  autobind(this);
1170
1249
  }
@@ -1370,7 +1449,7 @@ var UmbrellaStore = class {
1370
1449
  if (lastRequestedAt === void 0) {
1371
1450
  return;
1372
1451
  }
1373
- const updates = await this.#client[kInternal].httpClient.getThreadsSince({
1452
+ const updates = await this.#client[kInternal2].httpClient.getThreadsSince({
1374
1453
  roomId,
1375
1454
  since: lastRequestedAt,
1376
1455
  signal
@@ -1393,7 +1472,7 @@ var UmbrellaStore = class {
1393
1472
  if (lastRequestedAt === null) {
1394
1473
  return;
1395
1474
  }
1396
- const result = await this.#client[kInternal].httpClient.getUserThreadsSince_experimental({
1475
+ const result = await this.#client[kInternal2].httpClient.getUserThreadsSince_experimental({
1397
1476
  since: lastRequestedAt,
1398
1477
  signal
1399
1478
  });
@@ -1419,7 +1498,7 @@ var UmbrellaStore = class {
1419
1498
  this.#client.getRoom(roomId),
1420
1499
  `Room with id ${roomId} is not available on client`
1421
1500
  );
1422
- const updates = await room[kInternal].listTextVersionsSince({
1501
+ const updates = await room[kInternal2].listTextVersionsSince({
1423
1502
  since: lastRequestedAt,
1424
1503
  signal
1425
1504
  });
@@ -1885,7 +1964,6 @@ function isThreadParticipant(thread, userId) {
1885
1964
 
1886
1965
  // src/liveblocks.tsx
1887
1966
  import { jsx } from "react/jsx-runtime";
1888
- var ClientContext = createContext2(null);
1889
1967
  function missingUserError(userId) {
1890
1968
  return new Error(`resolveUsers didn't return anything for user '${userId}'`);
1891
1969
  }
@@ -2044,9 +2122,11 @@ function makeLiveblocksContextBundle(client) {
2044
2122
  useInboxNotificationThread: useInboxNotificationThread2,
2045
2123
  useUserThreads_experimental,
2046
2124
  useAiChats,
2125
+ useAiChat,
2047
2126
  useAiChatMessages,
2048
2127
  useCreateAiChat,
2049
2128
  useDeleteAiChat,
2129
+ useSendAiMessage,
2050
2130
  ...shared.classic,
2051
2131
  suspense: {
2052
2132
  LiveblocksProvider: LiveblocksProvider2,
@@ -2061,9 +2141,11 @@ function makeLiveblocksContextBundle(client) {
2061
2141
  useUpdateNotificationSettings: useUpdateNotificationSettings2,
2062
2142
  useUserThreads_experimental: useUserThreadsSuspense_experimental,
2063
2143
  useAiChats: useAiChatsSuspense,
2144
+ useAiChat: useAiChatSuspense,
2064
2145
  useAiChatMessages: useAiChatMessagesSuspense,
2065
2146
  useCreateAiChat,
2066
2147
  useDeleteAiChat,
2148
+ useSendAiMessage,
2067
2149
  ...shared.suspense
2068
2150
  }
2069
2151
  };
@@ -2071,7 +2153,7 @@ function makeLiveblocksContextBundle(client) {
2071
2153
  }
2072
2154
  function useInboxNotifications_withClient(client, selector, isEqual) {
2073
2155
  const { store, notificationsPoller: poller } = getLiveblocksExtrasForClient(client);
2074
- useEffect3(
2156
+ useEffect4(
2075
2157
  () => void store.outputs.loadingNotifications.waitUntilLoaded()
2076
2158
  // NOTE: Deliberately *not* using a dependency array here!
2077
2159
  //
@@ -2082,7 +2164,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
2082
2164
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2083
2165
  // *next* render after that, a *new* fetch/promise will get created.
2084
2166
  );
2085
- useEffect3(() => {
2167
+ useEffect4(() => {
2086
2168
  poller.inc();
2087
2169
  poller.pollNowIfStale();
2088
2170
  return () => {
@@ -2140,7 +2222,7 @@ function useMarkInboxNotificationAsRead_withClient(client) {
2140
2222
  },
2141
2223
  (err) => {
2142
2224
  store.optimisticUpdates.remove(optimisticId);
2143
- client[kInternal2].emitError(
2225
+ client[kInternal3].emitError(
2144
2226
  {
2145
2227
  type: "MARK_INBOX_NOTIFICATION_AS_READ_ERROR",
2146
2228
  inboxNotificationId
@@ -2167,7 +2249,7 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
2167
2249
  },
2168
2250
  (err) => {
2169
2251
  store.optimisticUpdates.remove(optimisticId);
2170
- client[kInternal2].emitError(
2252
+ client[kInternal3].emitError(
2171
2253
  // No roomId, threadId, commentId to include for this error
2172
2254
  { type: "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR" },
2173
2255
  err
@@ -2192,7 +2274,7 @@ function useDeleteInboxNotification_withClient(client) {
2192
2274
  },
2193
2275
  (err) => {
2194
2276
  store.optimisticUpdates.remove(optimisticId);
2195
- client[kInternal2].emitError(
2277
+ client[kInternal3].emitError(
2196
2278
  { type: "DELETE_INBOX_NOTIFICATION_ERROR", inboxNotificationId },
2197
2279
  err
2198
2280
  );
@@ -2216,7 +2298,7 @@ function useDeleteAllInboxNotifications_withClient(client) {
2216
2298
  },
2217
2299
  (err) => {
2218
2300
  store.optimisticUpdates.remove(optimisticId);
2219
- client[kInternal2].emitError(
2301
+ client[kInternal3].emitError(
2220
2302
  { type: "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR" },
2221
2303
  err
2222
2304
  );
@@ -2230,15 +2312,15 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
2230
2312
  store.outputs.threadifications,
2231
2313
  useCallback2(
2232
2314
  (state) => {
2233
- const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise(
2315
+ const inboxNotification = state.notificationsById[inboxNotificationId] ?? raise2(
2234
2316
  `Inbox notification with ID "${inboxNotificationId}" not found`
2235
2317
  );
2236
2318
  if (inboxNotification.kind !== "thread") {
2237
- raise(
2319
+ raise2(
2238
2320
  `Inbox notification with ID "${inboxNotificationId}" is not of kind "thread"`
2239
2321
  );
2240
2322
  }
2241
- const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise(
2323
+ const thread = state.threadsDB.get(inboxNotification.threadId) ?? raise2(
2242
2324
  `Thread with ID "${inboxNotification.threadId}" not found, this inbox notification might not be of kind "thread"`
2243
2325
  );
2244
2326
  return thread;
@@ -2269,7 +2351,7 @@ function useUpdateNotificationSettings_withClient(client) {
2269
2351
  const msg = [err.details?.error, err.details?.reason].filter(Boolean).join("\n");
2270
2352
  console.error(msg);
2271
2353
  }
2272
- client[kInternal2].emitError(
2354
+ client[kInternal3].emitError(
2273
2355
  {
2274
2356
  type: "UPDATE_USER_NOTIFICATION_SETTINGS_ERROR"
2275
2357
  },
@@ -2287,10 +2369,10 @@ function useUpdateNotificationSettings_withClient(client) {
2287
2369
  function useNotificationSettings_withClient(client) {
2288
2370
  const updateNotificationSettings = useUpdateNotificationSettings_withClient(client);
2289
2371
  const { store, notificationSettingsPoller: poller } = getLiveblocksExtrasForClient(client);
2290
- useEffect3(() => {
2372
+ useEffect4(() => {
2291
2373
  void store.outputs.notificationSettings.waitUntilLoaded();
2292
2374
  });
2293
- useEffect3(() => {
2375
+ useEffect4(() => {
2294
2376
  poller.inc();
2295
2377
  poller.pollNowIfStale();
2296
2378
  return () => {
@@ -2314,7 +2396,7 @@ function useNotificationSettingsSuspense_withClient(client) {
2314
2396
  }, [result, updateNotificationSettings]);
2315
2397
  }
2316
2398
  function useUser_withClient(client, userId) {
2317
- const usersStore = client[kInternal2].usersStore;
2399
+ const usersStore = client[kInternal3].usersStore;
2318
2400
  const getUserState = useCallback2(
2319
2401
  () => usersStore.getItemState(userId),
2320
2402
  [usersStore, userId]
@@ -2330,7 +2412,7 @@ function useUser_withClient(client, userId) {
2330
2412
  selector,
2331
2413
  shallow3
2332
2414
  );
2333
- useEffect3(
2415
+ useEffect4(
2334
2416
  () => void usersStore.enqueue(userId)
2335
2417
  // NOTE: Deliberately *not* using a dependency array here!
2336
2418
  //
@@ -2345,7 +2427,7 @@ function useUser_withClient(client, userId) {
2345
2427
  return result;
2346
2428
  }
2347
2429
  function useUserSuspense_withClient(client, userId) {
2348
- const usersStore = client[kInternal2].usersStore;
2430
+ const usersStore = client[kInternal3].usersStore;
2349
2431
  const getUserState = useCallback2(
2350
2432
  () => usersStore.getItemState(userId),
2351
2433
  [usersStore, userId]
@@ -2375,7 +2457,7 @@ function useUserSuspense_withClient(client, userId) {
2375
2457
  };
2376
2458
  }
2377
2459
  function useRoomInfo_withClient(client, roomId) {
2378
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2460
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2379
2461
  const getRoomInfoState = useCallback2(
2380
2462
  () => roomsInfoStore.getItemState(roomId),
2381
2463
  [roomsInfoStore, roomId]
@@ -2391,7 +2473,7 @@ function useRoomInfo_withClient(client, roomId) {
2391
2473
  selector,
2392
2474
  shallow3
2393
2475
  );
2394
- useEffect3(
2476
+ useEffect4(
2395
2477
  () => void roomsInfoStore.enqueue(roomId)
2396
2478
  // NOTE: Deliberately *not* using a dependency array here!
2397
2479
  //
@@ -2406,7 +2488,7 @@ function useRoomInfo_withClient(client, roomId) {
2406
2488
  return result;
2407
2489
  }
2408
2490
  function useRoomInfoSuspense_withClient(client, roomId) {
2409
- const roomsInfoStore = client[kInternal2].roomsInfoStore;
2491
+ const roomsInfoStore = client[kInternal3].roomsInfoStore;
2410
2492
  const getRoomInfoState = useCallback2(
2411
2493
  () => roomsInfoStore.getItemState(roomId),
2412
2494
  [roomsInfoStore, roomId]
@@ -2439,7 +2521,7 @@ function useRoomInfoSuspense_withClient(client, roomId) {
2439
2521
  function useAiChats() {
2440
2522
  const client = useClient();
2441
2523
  const store = getUmbrellaStoreForClient(client);
2442
- useEffect3(
2524
+ useEffect4(
2443
2525
  () => void store.outputs.aiChats.waitUntilLoaded()
2444
2526
  // NOTE: Deliberately *not* using a dependency array here!
2445
2527
  //
@@ -2462,11 +2544,11 @@ function useAiChatsSuspense() {
2462
2544
  assert(!result.isLoading, "Did not expect loading");
2463
2545
  return result;
2464
2546
  }
2465
- function useAiChatMessages(chatId, branch) {
2547
+ function useAiChatMessages(chatId, options) {
2466
2548
  const client = useClient();
2467
2549
  const store = getUmbrellaStoreForClient(client);
2468
- useEffect3(
2469
- () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2550
+ useEffect4(
2551
+ () => void store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2470
2552
  // NOTE: Deliberately *not* using a dependency array here!
2471
2553
  //
2472
2554
  // It is important to call waitUntil on *every* render.
@@ -2477,17 +2559,43 @@ function useAiChatMessages(chatId, branch) {
2477
2559
  // *next* render after that, a *new* fetch/promise will get created.
2478
2560
  );
2479
2561
  return useSignal(
2480
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).signal
2562
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).signal
2481
2563
  );
2482
2564
  }
2483
- function useAiChatMessagesSuspense(chatId, branch) {
2565
+ function useAiChatMessagesSuspense(chatId, options) {
2484
2566
  ensureNotServerSide();
2485
2567
  const client = useClient();
2486
2568
  const store = getUmbrellaStoreForClient(client);
2487
2569
  use(
2488
- store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(branch ?? null).waitUntilLoaded()
2570
+ store.outputs.messagesByChatId.getOrCreate(chatId).getOrCreate(options?.branchId ?? null).waitUntilLoaded()
2489
2571
  );
2490
- const result = useAiChatMessages(chatId, branch);
2572
+ const result = useAiChatMessages(chatId, options);
2573
+ assert(!result.error, "Did not expect error");
2574
+ assert(!result.isLoading, "Did not expect loading");
2575
+ return result;
2576
+ }
2577
+ function useAiChat(chatId) {
2578
+ const client = useClient();
2579
+ const store = getUmbrellaStoreForClient(client);
2580
+ useEffect4(
2581
+ () => void store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded()
2582
+ // NOTE: Deliberately *not* using a dependency array here!
2583
+ //
2584
+ // It is important to call waitUntil on *every* render.
2585
+ // This is harmless though, on most renders, except:
2586
+ // 1. The very first render, in which case we'll want to trigger the initial page fetch.
2587
+ // 2. All other subsequent renders now "just" return the same promise (a quick operation).
2588
+ // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2589
+ // *next* render after that, a *new* fetch/promise will get created.
2590
+ );
2591
+ return useSignal(store.outputs.aiChatById.getOrCreate(chatId).signal);
2592
+ }
2593
+ function useAiChatSuspense(chatId) {
2594
+ ensureNotServerSide();
2595
+ const client = useClient();
2596
+ const store = getUmbrellaStoreForClient(client);
2597
+ use(store.outputs.aiChatById.getOrCreate(chatId).waitUntilLoaded());
2598
+ const result = useAiChat(chatId);
2491
2599
  assert(!result.error, "Did not expect error");
2492
2600
  assert(!result.isLoading, "Did not expect loading");
2493
2601
  return result;
@@ -2496,7 +2604,10 @@ function useCreateAiChat() {
2496
2604
  const client = useClient();
2497
2605
  return useCallback2(
2498
2606
  (options) => {
2499
- client[kInternal2].ai.createChat(options.id).catch((err) => {
2607
+ client[kInternal3].ai.getOrCreateChat(options.id, {
2608
+ title: options.title,
2609
+ metadata: options.metadata
2610
+ }).catch((err) => {
2500
2611
  console.error(
2501
2612
  `Failed to create chat with ID "${options.id}": ${String(err)}`
2502
2613
  );
@@ -2509,7 +2620,7 @@ function useDeleteAiChat() {
2509
2620
  const client = useClient();
2510
2621
  return useCallback2(
2511
2622
  (chatId) => {
2512
- client[kInternal2].ai.deleteChat(chatId).catch((err) => {
2623
+ client[kInternal3].ai.deleteChat(chatId).catch((err) => {
2513
2624
  console.error(
2514
2625
  `Failed to delete chat with ID "${chatId}": ${String(err)}`
2515
2626
  );
@@ -2518,6 +2629,38 @@ function useDeleteAiChat() {
2518
2629
  [client]
2519
2630
  );
2520
2631
  }
2632
+ function useSendAiMessage(chatId, options) {
2633
+ const client = useClient();
2634
+ const copilotId = options?.copilotId;
2635
+ return useCallback2(
2636
+ (message) => {
2637
+ const messages = client[kInternal3].ai.signals.getChatMessagesForBranch\u03A3(chatId).get();
2638
+ const lastMessageId = messages[messages.length - 1]?.id ?? null;
2639
+ const content = [{ type: "text", text: message }];
2640
+ const newMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2641
+ chatId,
2642
+ "user",
2643
+ lastMessageId,
2644
+ content
2645
+ );
2646
+ const targetMessageId = client[kInternal3].ai[kInternal3].context.messagesStore.createOptimistically(
2647
+ chatId,
2648
+ "assistant",
2649
+ newMessageId
2650
+ );
2651
+ void client[kInternal3].ai.askUserMessageInChat(
2652
+ chatId,
2653
+ { id: newMessageId, parentMessageId: lastMessageId, content },
2654
+ targetMessageId,
2655
+ {
2656
+ stream: false,
2657
+ copilotId
2658
+ }
2659
+ );
2660
+ },
2661
+ [client, chatId, copilotId]
2662
+ );
2663
+ }
2521
2664
  function createSharedContext(client) {
2522
2665
  const useClient2 = () => client;
2523
2666
  function useSyncStatus2(options) {
@@ -2530,7 +2673,9 @@ function createSharedContext(client) {
2530
2673
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
2531
2674
  useIsInsideRoom,
2532
2675
  useErrorListener,
2533
- useSyncStatus: useSyncStatus2
2676
+ useSyncStatus: useSyncStatus2,
2677
+ RegisterAiKnowledge,
2678
+ RegisterAiTool
2534
2679
  },
2535
2680
  suspense: {
2536
2681
  useClient: useClient2,
@@ -2538,7 +2683,9 @@ function createSharedContext(client) {
2538
2683
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
2539
2684
  useIsInsideRoom,
2540
2685
  useErrorListener,
2541
- useSyncStatus: useSyncStatus2
2686
+ useSyncStatus: useSyncStatus2,
2687
+ RegisterAiKnowledge,
2688
+ RegisterAiTool
2542
2689
  }
2543
2690
  };
2544
2691
  }
@@ -2550,12 +2697,6 @@ function useEnsureNoLiveblocksProvider(options) {
2550
2697
  );
2551
2698
  }
2552
2699
  }
2553
- function useClientOrNull() {
2554
- return useContext2(ClientContext);
2555
- }
2556
- function useClient() {
2557
- return useClientOrNull() ?? raise("LiveblocksProvider is missing from the React tree.");
2558
- }
2559
2700
  function LiveblocksProviderWithClient(props) {
2560
2701
  useEnsureNoLiveblocksProvider(props);
2561
2702
  return /* @__PURE__ */ jsx(ClientContext.Provider, { value: props.client, children: props.children });
@@ -2588,10 +2729,10 @@ function LiveblocksProvider(props) {
2588
2729
  )
2589
2730
  };
2590
2731
  const client = useMemo2(() => createClient(options), []);
2591
- useEffect3(() => {
2592
- client[kInternal2].ai.connect();
2732
+ useEffect4(() => {
2733
+ client[kInternal3].ai.connect();
2593
2734
  return () => {
2594
- client[kInternal2].ai.disconnect();
2735
+ client[kInternal3].ai.disconnect();
2595
2736
  };
2596
2737
  }, [client]);
2597
2738
  return /* @__PURE__ */ jsx(LiveblocksProviderWithClient, { client, children });
@@ -2603,7 +2744,7 @@ function useUserThreads_experimental(options = {}) {
2603
2744
  const client = useClient();
2604
2745
  const { store, userThreadsPoller: poller } = getLiveblocksExtrasForClient(client);
2605
2746
  const queryKey = makeUserThreadsQueryKey(options.query);
2606
- useEffect3(
2747
+ useEffect4(
2607
2748
  () => void store.outputs.loadingUserThreads.getOrCreate(queryKey).waitUntilLoaded()
2608
2749
  // NOTE: Deliberately *not* using a dependency array here!
2609
2750
  //
@@ -2614,7 +2755,7 @@ function useUserThreads_experimental(options = {}) {
2614
2755
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
2615
2756
  // *next* render after that, a *new* fetch/promise will get created.
2616
2757
  );
2617
- useEffect3(() => {
2758
+ useEffect4(() => {
2618
2759
  poller.inc();
2619
2760
  poller.pollNowIfStale();
2620
2761
  return () => {
@@ -2696,6 +2837,8 @@ var _useUserThreads_experimental = useUserThreads_experimental;
2696
2837
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
2697
2838
  var _useAiChats = useAiChats;
2698
2839
  var _useAiChatsSuspense = useAiChatsSuspense;
2840
+ var _useAiChat = useAiChat;
2841
+ var _useAiChatSuspense = useAiChatSuspense;
2699
2842
  var _useAiChatMessages = useAiChatMessages;
2700
2843
  var _useAiChatMessagesSuspense = useAiChatMessagesSuspense;
2701
2844
  function useSyncStatus_withClient(client, options) {
@@ -2715,9 +2858,9 @@ function useSyncStatusImmediate_withClient(client) {
2715
2858
  }
2716
2859
  function useSyncStatusSmooth_withClient(client) {
2717
2860
  const getter = client.getSyncStatus;
2718
- const [status, setStatus] = useState(getter);
2861
+ const [status, setStatus] = useState2(getter);
2719
2862
  const oldStatus = useLatest(getter());
2720
- useEffect3(() => {
2863
+ useEffect4(() => {
2721
2864
  let timeoutId;
2722
2865
  const unsub = client.events.syncStatus.subscribe(() => {
2723
2866
  const newStatus = getter();
@@ -2741,7 +2884,7 @@ function useSyncStatus(options) {
2741
2884
  function useErrorListener(callback) {
2742
2885
  const client = useClient();
2743
2886
  const savedCallback = useLatest(callback);
2744
- useEffect3(
2887
+ useEffect4(
2745
2888
  () => client.events.error.subscribe((e) => savedCallback.current(e)),
2746
2889
  [client, savedCallback]
2747
2890
  );
@@ -2758,22 +2901,22 @@ import {
2758
2901
  errorIf,
2759
2902
  getSubscriptionKey as getSubscriptionKey2,
2760
2903
  HttpError as HttpError2,
2761
- kInternal as kInternal3,
2904
+ kInternal as kInternal4,
2762
2905
  makePoller as makePoller2,
2763
2906
  ServerMsgCode
2764
2907
  } from "@liveblocks/core";
2765
2908
  import {
2766
2909
  useCallback as useCallback3,
2767
- useEffect as useEffect5,
2910
+ useEffect as useEffect6,
2768
2911
  useMemo as useMemo3,
2769
2912
  useRef as useRef3,
2770
- useState as useState2,
2913
+ useState as useState3,
2771
2914
  useSyncExternalStore as useSyncExternalStore3,
2772
2915
  version as reactVersion
2773
2916
  } from "react";
2774
2917
 
2775
2918
  // src/use-scroll-to-comment-on-load-effect.ts
2776
- import { useEffect as useEffect4 } from "react";
2919
+ import { useEffect as useEffect5 } from "react";
2777
2920
  function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2778
2921
  if (shouldScrollOnLoad === false) return;
2779
2922
  if (!state.threads) return;
@@ -2792,7 +2935,7 @@ function handleScrollToCommentOnLoad(shouldScrollOnLoad, state) {
2792
2935
  comment.scrollIntoView();
2793
2936
  }
2794
2937
  function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
2795
- useEffect4(
2938
+ useEffect5(
2796
2939
  () => {
2797
2940
  handleScrollToCommentOnLoad(shouldScrollOnLoad, state);
2798
2941
  },
@@ -2846,7 +2989,7 @@ function makeMutationContext(room) {
2846
2989
  };
2847
2990
  }
2848
2991
  function getCurrentUserId(client) {
2849
- const userId = client[kInternal3].currentUserId.get();
2992
+ const userId = client[kInternal4].currentUserId.get();
2850
2993
  if (userId === void 0) {
2851
2994
  return "anonymous";
2852
2995
  }
@@ -2883,7 +3026,7 @@ function makeRoomExtrasForClient(client) {
2883
3026
  ].filter(Boolean).join("\n");
2884
3027
  console3.error(detailedMessage);
2885
3028
  }
2886
- client[kInternal3].emitError(context, innerError);
3029
+ client[kInternal4].emitError(context, innerError);
2887
3030
  } else {
2888
3031
  throw innerError;
2889
3032
  }
@@ -3054,13 +3197,13 @@ function makeRoomContextBundle(client) {
3054
3197
  ...shared.suspense
3055
3198
  }
3056
3199
  };
3057
- return Object.defineProperty(bundle, kInternal3, {
3200
+ return Object.defineProperty(bundle, kInternal4, {
3058
3201
  enumerable: false
3059
3202
  });
3060
3203
  }
3061
3204
  function RoomProvider(props) {
3062
3205
  const client = useClient();
3063
- const [cache] = useState2(
3206
+ const [cache] = useState3(
3064
3207
  () => /* @__PURE__ */ new Map()
3065
3208
  );
3066
3209
  const stableEnterRoom = useCallback3(
@@ -3110,14 +3253,14 @@ function RoomProviderInner(props) {
3110
3253
  initialStorage: props.initialStorage,
3111
3254
  autoConnect: props.autoConnect ?? typeof window !== "undefined"
3112
3255
  });
3113
- const [{ room }, setRoomLeavePair] = useState2(
3256
+ const [{ room }, setRoomLeavePair] = useState3(
3114
3257
  () => stableEnterRoom(roomId, {
3115
3258
  ...frozenProps,
3116
3259
  autoConnect: false
3117
3260
  // Deliberately using false here on the first render, see below
3118
3261
  })
3119
3262
  );
3120
- useEffect5(() => {
3263
+ useEffect6(() => {
3121
3264
  const { store } = getRoomExtrasForClient(client);
3122
3265
  async function handleCommentEvent(message) {
3123
3266
  if (message.type === ServerMsgCode.THREAD_DELETED) {
@@ -3164,7 +3307,7 @@ function RoomProviderInner(props) {
3164
3307
  (message) => void handleCommentEvent(message)
3165
3308
  );
3166
3309
  }, [client, room]);
3167
- useEffect5(() => {
3310
+ useEffect6(() => {
3168
3311
  const pair = stableEnterRoom(roomId, frozenProps);
3169
3312
  setRoomLeavePair(pair);
3170
3313
  const { room: room2, leave } = pair;
@@ -3194,14 +3337,14 @@ function useStatus() {
3194
3337
  function useReportTextEditor(editor, rootKey) {
3195
3338
  const isReported = useRef3(false);
3196
3339
  const room = useRoom();
3197
- useEffect5(() => {
3340
+ useEffect6(() => {
3198
3341
  if (isReported.current) {
3199
3342
  return;
3200
3343
  }
3201
3344
  const unsubscribe = room.events.status.subscribe((status) => {
3202
3345
  if (status === "connected" && !isReported.current) {
3203
3346
  isReported.current = true;
3204
- void room[kInternal3].reportTextEditor(editor, rootKey);
3347
+ void room[kInternal4].reportTextEditor(editor, rootKey);
3205
3348
  }
3206
3349
  });
3207
3350
  return unsubscribe;
@@ -3211,12 +3354,12 @@ function useYjsProvider() {
3211
3354
  const room = useRoom();
3212
3355
  const subscribe = useCallback3(
3213
3356
  (onStoreChange) => {
3214
- return room[kInternal3].yjsProviderDidChange.subscribe(onStoreChange);
3357
+ return room[kInternal4].yjsProviderDidChange.subscribe(onStoreChange);
3215
3358
  },
3216
3359
  [room]
3217
3360
  );
3218
3361
  const getSnapshot = useCallback3(() => {
3219
- return room[kInternal3].getYjsProvider();
3362
+ return room[kInternal4].getYjsProvider();
3220
3363
  }, [room]);
3221
3364
  return useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
3222
3365
  }
@@ -3224,7 +3367,7 @@ function useCreateTextMention() {
3224
3367
  const room = useRoom();
3225
3368
  return useCallback3(
3226
3369
  (userId, mentionId) => {
3227
- room[kInternal3].createTextMention(userId, mentionId).catch((err) => {
3370
+ room[kInternal4].createTextMention(userId, mentionId).catch((err) => {
3228
3371
  console3.error(
3229
3372
  `Cannot create text mention for user '${userId}' and mention '${mentionId}'`,
3230
3373
  err
@@ -3238,7 +3381,7 @@ function useDeleteTextMention() {
3238
3381
  const room = useRoom();
3239
3382
  return useCallback3(
3240
3383
  (mentionId) => {
3241
- room[kInternal3].deleteTextMention(mentionId).catch((err) => {
3384
+ room[kInternal4].deleteTextMention(mentionId).catch((err) => {
3242
3385
  console3.error(`Cannot delete text mention '${mentionId}'`, err);
3243
3386
  });
3244
3387
  },
@@ -3247,11 +3390,11 @@ function useDeleteTextMention() {
3247
3390
  }
3248
3391
  function useResolveMentionSuggestions() {
3249
3392
  const client = useClient();
3250
- return client[kInternal3].resolveMentionSuggestions;
3393
+ return client[kInternal4].resolveMentionSuggestions;
3251
3394
  }
3252
3395
  function useMentionSuggestionsCache() {
3253
3396
  const client = useClient();
3254
- return client[kInternal3].mentionSuggestionsCache;
3397
+ return client[kInternal4].mentionSuggestionsCache;
3255
3398
  }
3256
3399
  function useStorageStatus(options) {
3257
3400
  const smooth = useInitial(options?.smooth ?? false);
@@ -3270,9 +3413,9 @@ function useStorageStatusImmediate() {
3270
3413
  }
3271
3414
  function useStorageStatusSmooth() {
3272
3415
  const room = useRoom();
3273
- const [status, setStatus] = useState2(room.getStorageStatus);
3416
+ const [status, setStatus] = useState3(room.getStorageStatus);
3274
3417
  const oldStatus = useLatest(room.getStorageStatus());
3275
- useEffect5(() => {
3418
+ useEffect6(() => {
3276
3419
  let timeoutId;
3277
3420
  const unsub = room.events.storageStatus.subscribe((newStatus) => {
3278
3421
  if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
@@ -3304,7 +3447,7 @@ function useBroadcastEvent() {
3304
3447
  function useOthersListener(callback) {
3305
3448
  const room = useRoom();
3306
3449
  const savedCallback = useLatest(callback);
3307
- useEffect5(
3450
+ useEffect6(
3308
3451
  () => room.events.others.subscribe((event) => savedCallback.current(event)),
3309
3452
  [room, savedCallback]
3310
3453
  );
@@ -3312,7 +3455,7 @@ function useOthersListener(callback) {
3312
3455
  function useLostConnectionListener(callback) {
3313
3456
  const room = useRoom();
3314
3457
  const savedCallback = useLatest(callback);
3315
- useEffect5(
3458
+ useEffect6(
3316
3459
  () => room.events.lostConnection.subscribe(
3317
3460
  (event) => savedCallback.current(event)
3318
3461
  ),
@@ -3322,7 +3465,7 @@ function useLostConnectionListener(callback) {
3322
3465
  function useEventListener(callback) {
3323
3466
  const room = useRoom();
3324
3467
  const savedCallback = useLatest(callback);
3325
- useEffect5(() => {
3468
+ useEffect6(() => {
3326
3469
  const listener = (eventData) => {
3327
3470
  savedCallback.current(eventData);
3328
3471
  };
@@ -3506,7 +3649,7 @@ function useThreads(options = {}) {
3506
3649
  const { store, getOrCreateThreadsPollerForRoomId } = getRoomExtrasForClient(client);
3507
3650
  const queryKey = makeRoomThreadsQueryKey(room.id, options.query);
3508
3651
  const poller = getOrCreateThreadsPollerForRoomId(room.id);
3509
- useEffect5(
3652
+ useEffect6(
3510
3653
  () => void store.outputs.loadingRoomThreads.getOrCreate(queryKey).waitUntilLoaded()
3511
3654
  // NOTE: Deliberately *not* using a dependency array here!
3512
3655
  //
@@ -3517,7 +3660,7 @@ function useThreads(options = {}) {
3517
3660
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
3518
3661
  // *next* render after that, a *new* fetch/promise will get created.
3519
3662
  );
3520
- useEffect5(() => {
3663
+ useEffect6(() => {
3521
3664
  poller.inc();
3522
3665
  poller.pollNowIfStale();
3523
3666
  return () => poller.dec();
@@ -3569,7 +3712,7 @@ function useCreateRoomThread(roomId) {
3569
3712
  roomId
3570
3713
  });
3571
3714
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3572
- client[kInternal3].httpClient.createThread({
3715
+ client[kInternal4].httpClient.createThread({
3573
3716
  roomId,
3574
3717
  threadId,
3575
3718
  commentId,
@@ -3617,7 +3760,7 @@ function useDeleteRoomThread(roomId) {
3617
3760
  threadId,
3618
3761
  deletedAt: /* @__PURE__ */ new Date()
3619
3762
  });
3620
- client[kInternal3].httpClient.deleteThread({ roomId, threadId }).then(
3763
+ client[kInternal4].httpClient.deleteThread({ roomId, threadId }).then(
3621
3764
  () => {
3622
3765
  store.deleteThread(threadId, optimisticId);
3623
3766
  },
@@ -3651,7 +3794,7 @@ function useEditRoomThreadMetadata(roomId) {
3651
3794
  threadId,
3652
3795
  updatedAt
3653
3796
  });
3654
- client[kInternal3].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3797
+ client[kInternal4].httpClient.editThreadMetadata({ roomId, threadId, metadata }).then(
3655
3798
  (metadata2) => (
3656
3799
  // Replace the optimistic update by the real thing
3657
3800
  store.patchThread(threadId, optimisticId, { metadata: metadata2 }, updatedAt)
@@ -3697,7 +3840,7 @@ function useCreateRoomComment(roomId) {
3697
3840
  comment
3698
3841
  });
3699
3842
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3700
- client[kInternal3].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3843
+ client[kInternal4].httpClient.createComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3701
3844
  (newComment) => {
3702
3845
  store.createComment(newComment, optimisticId);
3703
3846
  },
@@ -3753,7 +3896,7 @@ function useEditRoomComment(roomId) {
3753
3896
  }
3754
3897
  });
3755
3898
  const attachmentIds = attachments?.map((attachment) => attachment.id);
3756
- client[kInternal3].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3899
+ client[kInternal4].httpClient.editComment({ roomId, threadId, commentId, body, attachmentIds }).then(
3757
3900
  (editedComment) => {
3758
3901
  store.editComment(threadId, optimisticId, editedComment);
3759
3902
  },
@@ -3783,7 +3926,7 @@ function useDeleteRoomComment(roomId) {
3783
3926
  deletedAt,
3784
3927
  roomId
3785
3928
  });
3786
- client[kInternal3].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3929
+ client[kInternal4].httpClient.deleteComment({ roomId, threadId, commentId }).then(
3787
3930
  () => {
3788
3931
  store.deleteComment(threadId, optimisticId, commentId, deletedAt);
3789
3932
  },
@@ -3817,7 +3960,7 @@ function useAddRoomCommentReaction(roomId) {
3817
3960
  createdAt
3818
3961
  }
3819
3962
  });
3820
- client[kInternal3].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3963
+ client[kInternal4].httpClient.addReaction({ roomId, threadId, commentId, emoji }).then(
3821
3964
  (addedReaction) => {
3822
3965
  store.addReaction(
3823
3966
  threadId,
@@ -3861,7 +4004,7 @@ function useRemoveRoomCommentReaction(roomId) {
3861
4004
  userId,
3862
4005
  removedAt
3863
4006
  });
3864
- client[kInternal3].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
4007
+ client[kInternal4].httpClient.removeReaction({ roomId, threadId, commentId, emoji }).then(
3865
4008
  () => {
3866
4009
  store.removeReaction(
3867
4010
  threadId,
@@ -3908,7 +4051,7 @@ function useMarkRoomThreadAsRead(roomId) {
3908
4051
  inboxNotificationId: inboxNotification.id,
3909
4052
  readAt: now
3910
4053
  });
3911
- client[kInternal3].httpClient.markRoomInboxNotificationAsRead({
4054
+ client[kInternal4].httpClient.markRoomInboxNotificationAsRead({
3912
4055
  roomId,
3913
4056
  inboxNotificationId: inboxNotification.id
3914
4057
  }).then(
@@ -3950,7 +4093,7 @@ function useMarkRoomThreadAsResolved(roomId) {
3950
4093
  threadId,
3951
4094
  updatedAt
3952
4095
  });
3953
- client[kInternal3].httpClient.markThreadAsResolved({ roomId, threadId }).then(
4096
+ client[kInternal4].httpClient.markThreadAsResolved({ roomId, threadId }).then(
3954
4097
  () => {
3955
4098
  store.patchThread(
3956
4099
  threadId,
@@ -3983,7 +4126,7 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3983
4126
  threadId,
3984
4127
  updatedAt
3985
4128
  });
3986
- client[kInternal3].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
4129
+ client[kInternal4].httpClient.markThreadAsUnresolved({ roomId, threadId }).then(
3987
4130
  () => {
3988
4131
  store.patchThread(
3989
4132
  threadId,
@@ -4016,7 +4159,7 @@ function useSubscribeToRoomThread(roomId) {
4016
4159
  threadId,
4017
4160
  subscribedAt
4018
4161
  });
4019
- client[kInternal3].httpClient.subscribeToThread({ roomId, threadId }).then(
4162
+ client[kInternal4].httpClient.subscribeToThread({ roomId, threadId }).then(
4020
4163
  (subscription) => {
4021
4164
  store.createSubscription(subscription, optimisticId);
4022
4165
  },
@@ -4044,7 +4187,7 @@ function useUnsubscribeFromRoomThread(roomId) {
4044
4187
  threadId,
4045
4188
  unsubscribedAt
4046
4189
  });
4047
- client[kInternal3].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4190
+ client[kInternal4].httpClient.unsubscribeFromThread({ roomId, threadId }).then(
4048
4191
  () => {
4049
4192
  store.deleteSubscription(
4050
4193
  getSubscriptionKey2("thread", threadId),
@@ -4108,7 +4251,7 @@ function useRoomNotificationSettings() {
4108
4251
  const room = useRoom();
4109
4252
  const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4110
4253
  const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4111
- useEffect5(
4254
+ useEffect6(
4112
4255
  () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4113
4256
  // NOTE: Deliberately *not* using a dependency array here!
4114
4257
  //
@@ -4119,7 +4262,7 @@ function useRoomNotificationSettings() {
4119
4262
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4120
4263
  // *next* render after that, a *new* fetch/promise will get created.
4121
4264
  );
4122
- useEffect5(() => {
4265
+ useEffect6(() => {
4123
4266
  poller.inc();
4124
4267
  poller.pollNowIfStale();
4125
4268
  return () => {
@@ -4139,7 +4282,7 @@ function useRoomSubscriptionSettings() {
4139
4282
  const room = useRoom();
4140
4283
  const { store, getOrCreateSubscriptionSettingsPollerForRoomId } = getRoomExtrasForClient(client);
4141
4284
  const poller = getOrCreateSubscriptionSettingsPollerForRoomId(room.id);
4142
- useEffect5(
4285
+ useEffect6(
4143
4286
  () => void store.outputs.roomSubscriptionSettingsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4144
4287
  // NOTE: Deliberately *not* using a dependency array here!
4145
4288
  //
@@ -4150,7 +4293,7 @@ function useRoomSubscriptionSettings() {
4150
4293
  // 3. If ever the promise would fail, then after 5 seconds it would reset, and on the very
4151
4294
  // *next* render after that, a *new* fetch/promise will get created.
4152
4295
  );
4153
- useEffect5(() => {
4296
+ useEffect6(() => {
4154
4297
  poller.inc();
4155
4298
  poller.pollNowIfStale();
4156
4299
  return () => {
@@ -4195,15 +4338,15 @@ function useRoomSubscriptionSettingsSuspense() {
4195
4338
  }, [settings, updateRoomSubscriptionSettings]);
4196
4339
  }
4197
4340
  function useHistoryVersionData(versionId) {
4198
- const [state, setState] = useState2({
4341
+ const [state, setState] = useState3({
4199
4342
  isLoading: true
4200
4343
  });
4201
4344
  const room = useRoom();
4202
- useEffect5(() => {
4345
+ useEffect6(() => {
4203
4346
  setState({ isLoading: true });
4204
4347
  const load = async () => {
4205
4348
  try {
4206
- const response = await room[kInternal3].getTextVersion(versionId);
4349
+ const response = await room[kInternal4].getTextVersion(versionId);
4207
4350
  const buffer = await response.arrayBuffer();
4208
4351
  const data = new Uint8Array(buffer);
4209
4352
  setState({
@@ -4228,12 +4371,12 @@ function useHistoryVersions() {
4228
4371
  const room = useRoom();
4229
4372
  const { store, getOrCreateVersionsPollerForRoomId } = getRoomExtrasForClient(client);
4230
4373
  const poller = getOrCreateVersionsPollerForRoomId(room.id);
4231
- useEffect5(() => {
4374
+ useEffect6(() => {
4232
4375
  poller.inc();
4233
4376
  poller.pollNowIfStale();
4234
4377
  return () => poller.dec();
4235
4378
  }, [poller]);
4236
- useEffect5(
4379
+ useEffect6(
4237
4380
  () => void store.outputs.versionsByRoomId.getOrCreate(room.id).waitUntilLoaded()
4238
4381
  // NOTE: Deliberately *not* using a dependency array here!
4239
4382
  //
@@ -4406,12 +4549,12 @@ function useAttachmentUrl(attachmentId) {
4406
4549
  }
4407
4550
  function useRoomAttachmentUrl(attachmentId, roomId) {
4408
4551
  const client = useClient();
4409
- const store = client[kInternal3].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4552
+ const store = client[kInternal4].httpClient.getOrCreateAttachmentUrlsStore(roomId);
4410
4553
  const getAttachmentUrlState = useCallback3(
4411
4554
  () => store.getItemState(attachmentId),
4412
4555
  [store, attachmentId]
4413
4556
  );
4414
- useEffect5(() => {
4557
+ useEffect6(() => {
4415
4558
  void store.enqueue(attachmentId);
4416
4559
  }, [store, attachmentId]);
4417
4560
  return useSyncExternalStoreWithSelector(
@@ -4424,7 +4567,7 @@ function useRoomAttachmentUrl(attachmentId, roomId) {
4424
4567
  }
4425
4568
  function useAttachmentUrlSuspense(attachmentId) {
4426
4569
  const room = useRoom();
4427
- const { attachmentUrlsStore } = room[kInternal3];
4570
+ const { attachmentUrlsStore } = room[kInternal4];
4428
4571
  const getAttachmentUrlState = useCallback3(
4429
4572
  () => attachmentUrlsStore.getItemState(attachmentId),
4430
4573
  [attachmentUrlsStore, attachmentId]
@@ -4450,14 +4593,10 @@ function useAttachmentUrlSuspense(attachmentId) {
4450
4593
  error: void 0
4451
4594
  };
4452
4595
  }
4453
- var NO_PERMISSIONS = /* @__PURE__ */ new Set();
4454
4596
  function useRoomPermissions(roomId) {
4455
4597
  const client = useClient();
4456
4598
  const store = getRoomExtrasForClient(client).store;
4457
- return useSignal(
4458
- store.permissionHints.signal,
4459
- (hints) => hints.get(roomId) ?? NO_PERMISSIONS
4460
- );
4599
+ return useSignal(store.permissionHints.getPermissionForRoom\u03A3(roomId));
4461
4600
  }
4462
4601
  function createRoomContext(client) {
4463
4602
  return getOrCreateRoomContextBundle(client);
@@ -4504,15 +4643,18 @@ var _useStorageRoot = useStorageRoot;
4504
4643
  var _useUpdateMyPresence = useUpdateMyPresence;
4505
4644
 
4506
4645
  export {
4646
+ ClientContext,
4647
+ useClientOrNull,
4648
+ useClient,
4507
4649
  RoomContext,
4650
+ RegisterAiKnowledge,
4651
+ RegisterAiTool,
4508
4652
  useSyncExternalStoreWithSelector,
4509
4653
  useSignal,
4510
- ClientContext,
4511
4654
  getUmbrellaStoreForClient,
4512
4655
  useCreateAiChat,
4513
4656
  useDeleteAiChat,
4514
- useClientOrNull,
4515
- useClient,
4657
+ useSendAiMessage,
4516
4658
  LiveblocksProvider,
4517
4659
  createLiveblocksContext,
4518
4660
  useInboxNotifications,
@@ -4535,6 +4677,8 @@ export {
4535
4677
  _useUserThreadsSuspense_experimental,
4536
4678
  _useAiChats,
4537
4679
  _useAiChatsSuspense,
4680
+ _useAiChat,
4681
+ _useAiChatSuspense,
4538
4682
  _useAiChatMessages,
4539
4683
  _useAiChatMessagesSuspense,
4540
4684
  useSyncStatus,
@@ -4620,4 +4764,4 @@ export {
4620
4764
  _useStorageRoot,
4621
4765
  _useUpdateMyPresence
4622
4766
  };
4623
- //# sourceMappingURL=chunk-E6PCFJWE.js.map
4767
+ //# sourceMappingURL=chunk-X7TWWGKZ.js.map