@liveblocks/core 2.25.0-aiprivatebeta10 → 2.25.0-aiprivatebeta12

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.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/version.ts
8
8
  var PKG_NAME = "@liveblocks/core";
9
- var PKG_VERSION = "2.25.0-aiprivatebeta10";
9
+ var PKG_VERSION = "2.25.0-aiprivatebeta12";
10
10
  var PKG_FORMAT = "esm";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -3780,46 +3780,61 @@ var KnowledgeStack = class {
3780
3780
  function now() {
3781
3781
  return (/* @__PURE__ */ new Date()).toISOString();
3782
3782
  }
3783
+ var kWILDCARD = Symbol("*");
3783
3784
  function createStore_forTools() {
3784
- const toolsByChatId\u03A3 = new DefaultMap((_chatId) => {
3785
- return new DefaultMap((_toolName) => {
3786
- return new Signal(void 0);
3785
+ const toolsByChatId\u03A3 = new DefaultMap(
3786
+ (_chatId) => {
3787
+ return new DefaultMap((_name) => {
3788
+ return new Signal(void 0);
3789
+ });
3790
+ }
3791
+ );
3792
+ const globalOrScopedTool\u03A3 = new DefaultMap((nameAndChat) => {
3793
+ const [name, chatId] = tryParseJson(nameAndChat);
3794
+ return DerivedSignal.from(() => {
3795
+ return (
3796
+ // A tool that's registered and scoped to a specific chat ID...
3797
+ (chatId !== void 0 ? toolsByChatId\u03A3.get(chatId)?.get(name) : void 0)?.get() ?? // ...or a globally registered tool
3798
+ toolsByChatId\u03A3.getOrCreate(kWILDCARD).get(name)?.get()
3799
+ );
3787
3800
  });
3788
3801
  });
3789
- function getToolDefinition\u03A3(chatId, toolName) {
3790
- return toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(toolName);
3802
+ function getTool\u03A3(name, chatId) {
3803
+ const key = JSON.stringify(chatId !== void 0 ? [name, chatId] : [name]);
3804
+ return globalOrScopedTool\u03A3.getOrCreate(key);
3791
3805
  }
3792
- function addToolDefinition(chatId, name, definition) {
3793
- if (!definition.execute && !definition.render) {
3806
+ function registerTool(name, tool, chatId) {
3807
+ if (!tool.execute && !tool.render) {
3794
3808
  throw new Error(
3795
- "A tool definition must have an execute() function, a render property, or both."
3809
+ "A tool definition must have an execute() function, a render() function, or both."
3796
3810
  );
3797
3811
  }
3798
- toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(name).set(definition);
3812
+ const key = chatId ?? kWILDCARD;
3813
+ toolsByChatId\u03A3.getOrCreate(key).getOrCreate(name).set(tool);
3814
+ return () => unregisterTool(key, name);
3799
3815
  }
3800
- function removeToolDefinition(chatId, toolName) {
3816
+ function unregisterTool(chatId, name) {
3801
3817
  const tools = toolsByChatId\u03A3.get(chatId);
3802
3818
  if (tools === void 0) return;
3803
- const tool = tools.get(toolName);
3819
+ const tool = tools.get(name);
3804
3820
  if (tool === void 0) return;
3805
3821
  tool.set(void 0);
3806
3822
  }
3807
- function getToolsForChat(chatId) {
3808
- const tools = toolsByChatId\u03A3.get(chatId);
3809
- if (tools === void 0) return [];
3810
- return Array.from(tools.entries()).map(([name, tool]) => {
3811
- if (tool.get() === void 0) return null;
3812
- return {
3813
- name,
3814
- definition: tool.get()
3815
- };
3816
- }).filter((tool) => tool !== null);
3823
+ function getToolDescriptions(chatId) {
3824
+ const globalTools\u03A3 = toolsByChatId\u03A3.get(kWILDCARD);
3825
+ const scopedTools\u03A3 = toolsByChatId\u03A3.get(chatId);
3826
+ return Array.from([
3827
+ ...globalTools\u03A3?.entries() ?? [],
3828
+ ...scopedTools\u03A3?.entries() ?? []
3829
+ ]).flatMap(([name, tool\u03A3]) => {
3830
+ const tool = tool\u03A3.get();
3831
+ return tool ? [{ name, description: tool.description, parameters: tool.parameters }] : [];
3832
+ });
3817
3833
  }
3818
3834
  return {
3819
- getToolDefinition\u03A3,
3820
- getToolsForChat,
3821
- addToolDefinition,
3822
- removeToolDefinition
3835
+ getToolDescriptions,
3836
+ getTool\u03A3,
3837
+ registerTool
3823
3838
  };
3824
3839
  }
3825
3840
  function createStore_forChatMessages(toolsStore, setToolResult) {
@@ -3905,16 +3920,16 @@ function createStore_forChatMessages(toolsStore, setToolResult) {
3905
3920
  for (const toolCall of message.contentSoFar.filter(
3906
3921
  (part) => part.type === "tool-invocation" && part.status === "executing"
3907
3922
  )) {
3908
- if (seenToolCallIds.has(toolCall.toolCallId)) {
3923
+ if (seenToolCallIds.has(toolCall.invocationId)) {
3909
3924
  continue;
3910
3925
  }
3911
- seenToolCallIds.add(toolCall.toolCallId);
3912
- const toolDef = toolsStore.getToolDefinition\u03A3(message.chatId, toolCall.toolName).get();
3926
+ seenToolCallIds.add(toolCall.invocationId);
3927
+ const toolDef = toolsStore.getTool\u03A3(toolCall.name, message.chatId).get();
3913
3928
  const respondSync = (result) => {
3914
3929
  setToolResult(
3915
3930
  message.chatId,
3916
3931
  message.id,
3917
- toolCall.toolCallId,
3932
+ toolCall.invocationId,
3918
3933
  result
3919
3934
  // TODO Pass in AiGenerationOptions here, or make the backend use the same options
3920
3935
  ).catch((err) => {
@@ -3927,8 +3942,8 @@ function createStore_forChatMessages(toolsStore, setToolResult) {
3927
3942
  if (executeFn && autoExecutableMessages.has(message.id)) {
3928
3943
  (async () => {
3929
3944
  const result = await executeFn(toolCall.args, {
3930
- toolName: toolCall.toolName,
3931
- toolCallId: toolCall.toolCallId
3945
+ name: toolCall.name,
3946
+ invocationId: toolCall.invocationId
3932
3947
  });
3933
3948
  respondSync(result);
3934
3949
  })().catch((err) => {
@@ -4091,16 +4106,16 @@ function createStore_forChatMessages(toolsStore, setToolResult) {
4091
4106
  };
4092
4107
  }
4093
4108
  function createStore_forUserAiChats() {
4094
- const mutable\u03A3 = new MutableSignal(
4109
+ const allChatsInclDeleted\u03A3 = new MutableSignal(
4095
4110
  SortedList.with((x, y) => y.createdAt < x.createdAt)
4096
4111
  );
4097
- const chats\u03A3 = DerivedSignal.from(
4098
- () => Array.from(mutable\u03A3.get()).filter((c) => !c.deletedAt)
4112
+ const nonDeletedChats\u03A3 = DerivedSignal.from(
4113
+ () => Array.from(allChatsInclDeleted\u03A3.get()).filter((c) => !c.deletedAt)
4099
4114
  );
4100
4115
  function upsertMany(chats) {
4101
- mutable\u03A3.mutate((list) => {
4116
+ allChatsInclDeleted\u03A3.mutate((list) => {
4102
4117
  for (const chat of chats) {
4103
- remove(chat.id);
4118
+ list.removeBy((c) => c.id === chat.id, 1);
4104
4119
  list.add(chat);
4105
4120
  }
4106
4121
  });
@@ -4108,19 +4123,26 @@ function createStore_forUserAiChats() {
4108
4123
  function upsert(chat) {
4109
4124
  upsertMany([chat]);
4110
4125
  }
4111
- function remove(chatId) {
4112
- mutable\u03A3.mutate((list) => list.removeBy((c) => c.id === chatId, 1));
4126
+ function markDeleted(chatId) {
4127
+ allChatsInclDeleted\u03A3.mutate((list) => {
4128
+ const chat = list.find((c) => c.id === chatId);
4129
+ if (!chat) return false;
4130
+ upsert({ ...chat, deletedAt: now() });
4131
+ return void 0;
4132
+ });
4113
4133
  }
4114
4134
  function getChatById(chatId) {
4115
- return Array.from(mutable\u03A3.get()).find((chat) => chat.id === chatId);
4135
+ return Array.from(allChatsInclDeleted\u03A3.get()).find(
4136
+ (chat) => chat.id === chatId
4137
+ );
4116
4138
  }
4117
4139
  return {
4118
- chats\u03A3,
4140
+ chats\u03A3: nonDeletedChats\u03A3,
4119
4141
  getChatById,
4120
4142
  // Mutations
4121
4143
  upsert,
4122
4144
  upsertMany,
4123
- remove
4145
+ markDeleted
4124
4146
  };
4125
4147
  }
4126
4148
  function createAi(config) {
@@ -4209,7 +4231,11 @@ function createAi(config) {
4209
4231
  context.messagesStore.upsert(msg.message);
4210
4232
  break;
4211
4233
  }
4234
+ case "warning":
4235
+ warn(msg.message);
4236
+ break;
4212
4237
  case "error":
4238
+ error2(msg.error);
4213
4239
  break;
4214
4240
  case "rebooted":
4215
4241
  context.messagesStore.failAllPending();
@@ -4220,7 +4246,7 @@ function createAi(config) {
4220
4246
  context.messagesStore.remove(m.chatId, m.id);
4221
4247
  }
4222
4248
  for (const chatId of msg["-chats"] ?? []) {
4223
- context.chatsStore.remove(chatId);
4249
+ context.chatsStore.markDeleted(chatId);
4224
4250
  context.messagesStore.removeByChatId(chatId);
4225
4251
  }
4226
4252
  for (const chatId of msg.clear ?? []) {
@@ -4246,7 +4272,7 @@ function createAi(config) {
4246
4272
  context.chatsStore.upsert(msg.chat);
4247
4273
  break;
4248
4274
  case "delete-chat":
4249
- context.chatsStore.remove(msg.chatId);
4275
+ context.chatsStore.markDeleted(msg.chatId);
4250
4276
  context.messagesStore.removeByChatId(msg.chatId);
4251
4277
  break;
4252
4278
  case "get-message-tree":
@@ -4344,24 +4370,23 @@ function createAi(config) {
4344
4370
  function updateKnowledge(layerKey, data, key = nanoid()) {
4345
4371
  context.knowledge.updateKnowledge(layerKey, key, data);
4346
4372
  }
4347
- async function setToolResult(chatId, messageId, toolCallId, result, options) {
4373
+ async function setToolResult(chatId, messageId, invocationId, result, options) {
4348
4374
  const knowledge = context.knowledge.get();
4375
+ const tools = context.toolsStore.getToolDescriptions(chatId);
4349
4376
  const resp = await sendClientMsgWithResponse({
4350
4377
  cmd: "set-tool-result",
4351
4378
  chatId,
4352
4379
  messageId,
4353
- toolCallId,
4380
+ invocationId,
4354
4381
  result,
4355
4382
  generationOptions: {
4356
4383
  copilotId: options?.copilotId,
4357
4384
  stream: options?.stream,
4358
4385
  timeout: options?.timeout,
4386
+ // Knowledge and tools aren't coming from the options, but retrieved
4387
+ // from the global context
4359
4388
  knowledge: knowledge.length > 0 ? knowledge : void 0,
4360
- tools: context.toolsStore.getToolsForChat(chatId).map((tool) => ({
4361
- name: tool.name,
4362
- description: tool.definition.description,
4363
- parameters: tool.definition.parameters
4364
- }))
4389
+ tools: tools.length > 0 ? tools : void 0
4365
4390
  }
4366
4391
  });
4367
4392
  if (resp.ok) {
@@ -4387,6 +4412,7 @@ function createAi(config) {
4387
4412
  clearChat: (chatId) => sendClientMsgWithResponse({ cmd: "clear-chat", chatId }),
4388
4413
  askUserMessageInChat: async (chatId, userMessage, targetMessageId, options) => {
4389
4414
  const knowledge = context.knowledge.get();
4415
+ const tools = context.toolsStore.getToolDescriptions(chatId);
4390
4416
  const resp = await sendClientMsgWithResponse({
4391
4417
  cmd: "ask-in-chat",
4392
4418
  chatId,
@@ -4396,12 +4422,10 @@ function createAi(config) {
4396
4422
  copilotId: options?.copilotId,
4397
4423
  stream: options?.stream,
4398
4424
  timeout: options?.timeout,
4425
+ // Knowledge and tools aren't coming from the options, but retrieved
4426
+ // from the global context
4399
4427
  knowledge: knowledge.length > 0 ? knowledge : void 0,
4400
- tools: context.toolsStore.getToolsForChat(chatId).map((tool) => ({
4401
- name: tool.name,
4402
- description: tool.definition.description,
4403
- parameters: tool.definition.parameters
4404
- }))
4428
+ tools: tools.length > 0 ? tools : void 0
4405
4429
  }
4406
4430
  });
4407
4431
  messagesStore.allowAutoExecuteToolCall(resp.targetMessage.id);
@@ -4413,14 +4437,13 @@ function createAi(config) {
4413
4437
  signals: {
4414
4438
  chats\u03A3: context.chatsStore.chats\u03A3,
4415
4439
  getChatMessagesForBranch\u03A3: context.messagesStore.getChatMessagesForBranch\u03A3,
4416
- getToolDefinition\u03A3: context.toolsStore.getToolDefinition\u03A3
4440
+ getTool\u03A3: context.toolsStore.getTool\u03A3
4417
4441
  },
4418
4442
  getChatById: context.chatsStore.getChatById,
4419
4443
  registerKnowledgeLayer,
4420
4444
  deregisterKnowledgeLayer,
4421
4445
  updateKnowledge,
4422
- registerChatTool: context.toolsStore.addToolDefinition,
4423
- unregisterChatTool: context.toolsStore.removeToolDefinition
4446
+ registerTool: context.toolsStore.registerTool
4424
4447
  },
4425
4448
  kInternal,
4426
4449
  { enumerable: false }
@@ -4436,7 +4459,7 @@ function makeCreateSocketDelegateForAi(baseUrl, WebSocketPolyfill) {
4436
4459
  }
4437
4460
  const url2 = new URL(baseUrl);
4438
4461
  url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
4439
- url2.pathname = "/ai/v1";
4462
+ url2.pathname = "/ai/v2";
4440
4463
  if (authValue.type === "secret") {
4441
4464
  url2.searchParams.set("tok", authValue.token.raw);
4442
4465
  } else if (authValue.type === "public") {