@meetsmore-oss/use-ai-client 1.14.1 → 1.16.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.
package/dist/index.js CHANGED
@@ -56,7 +56,9 @@ var defaultStrings = {
56
56
  /** File size error (use {filename} and {maxSize} placeholders) */
57
57
  fileSizeError: 'File "{filename}" exceeds {maxSize}MB limit',
58
58
  /** File type error (use {type} placeholder) */
59
- fileTypeError: 'File type "{type}" is not accepted'
59
+ fileTypeError: 'File type "{type}" is not accepted',
60
+ /** Error when too many files are attached (use {max} placeholder) */
61
+ maxAttachmentsError: "You can attach at most {max} files per message"
60
62
  },
61
63
  // Floating button
62
64
  floatingButton: {
@@ -374,6 +376,12 @@ function shouldSubmitOnEnter(e, mode) {
374
376
  return e.metaKey || e.ctrlKey;
375
377
  }
376
378
 
379
+ // src/types.ts
380
+ import { EventType, ErrorCode, TOOL_APPROVAL_REQUEST } from "@meetsmore-oss/use-ai-core";
381
+ var DEFAULT_ENABLED_FEATURES = {
382
+ slashCommands: true
383
+ };
384
+
377
385
  // src/components/MarkdownContent.tsx
378
386
  import ReactMarkdown from "react-markdown";
379
387
  import remarkGfm from "remark-gfm";
@@ -1399,6 +1407,9 @@ async function getTransformedContent(files, transformer, context, onProgress) {
1399
1407
  transformationCache.set(cacheKey, results);
1400
1408
  return results;
1401
1409
  }
1410
+ function normalizeUploadResult(result) {
1411
+ return typeof result === "string" ? { url: result } : result;
1412
+ }
1402
1413
  async function toContentPart(attachment, backend) {
1403
1414
  if (attachment.transformedContent !== void 0) {
1404
1415
  return {
@@ -1411,16 +1422,12 @@ async function toContentPart(attachment, backend) {
1411
1422
  }
1412
1423
  };
1413
1424
  }
1414
- const url = await backend.prepareForSend(attachment.file);
1415
- if (attachment.file.type.startsWith("image/")) {
1416
- return { type: "image", url };
1425
+ const result = normalizeUploadResult(await backend.prepareForSend(attachment.file));
1426
+ const isImage = attachment.file.type.startsWith("image/");
1427
+ if ("ref" in result) {
1428
+ return isImage ? { type: "image_ref", ref: result.ref } : { type: "file_ref", ref: result.ref, mimeType: attachment.file.type, name: attachment.file.name };
1417
1429
  }
1418
- return {
1419
- type: "file",
1420
- url,
1421
- mimeType: attachment.file.type,
1422
- name: attachment.file.name
1423
- };
1430
+ return isImage ? { type: "image_url", url: result.url } : { type: "file_url", url: result.url, mimeType: attachment.file.type, name: attachment.file.name };
1424
1431
  }
1425
1432
  async function processAttachments(attachments, config) {
1426
1433
  const { getCurrentChat, backend = new EmbedFileUploadBackend(), transformers = {}, onFileProgress } = config;
@@ -1523,7 +1530,12 @@ function useFileUpload({
1523
1530
  const enabled = config !== void 0;
1524
1531
  const maxFileSize = config?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
1525
1532
  const acceptedTypes = config?.acceptedTypes;
1533
+ const maxAttachments = config?.maxAttachments;
1526
1534
  const transformers = config?.transformers;
1535
+ const attachmentsRef = useRef3(attachments);
1536
+ useEffect3(() => {
1537
+ attachmentsRef.current = attachments;
1538
+ }, [attachments]);
1527
1539
  useEffect3(() => {
1528
1540
  if (fileError) {
1529
1541
  const timer = setTimeout(() => setFileError(null), 3e3);
@@ -1559,7 +1571,13 @@ function useFileUpload({
1559
1571
  }, [getCurrentChat, transformers]);
1560
1572
  const handleFiles = useCallback2(async (files) => {
1561
1573
  const fileArray = Array.from(files);
1574
+ let currentCount = attachmentsRef.current.length;
1562
1575
  for (const file of fileArray) {
1576
+ if (maxAttachments !== void 0 && currentCount >= maxAttachments) {
1577
+ const errorMsg = strings.fileUpload.maxAttachmentsError.replace("{max}", String(maxAttachments));
1578
+ setFileError(errorMsg);
1579
+ break;
1580
+ }
1563
1581
  if (file.size > maxFileSize) {
1564
1582
  const errorMsg = strings.fileUpload.fileSizeError.replace("{filename}", file.name).replace("{maxSize}", String(Math.round(maxFileSize / (1024 * 1024))));
1565
1583
  setFileError(errorMsg);
@@ -1578,14 +1596,17 @@ function useFileUpload({
1578
1596
  preview
1579
1597
  };
1580
1598
  setAttachments((prev) => [...prev, attachment]);
1599
+ attachmentsRef.current = [...attachmentsRef.current, attachment];
1600
+ currentCount++;
1581
1601
  const transformerKey = findTransformerPattern(file.type, transformers);
1582
1602
  if (transformerKey) {
1583
1603
  runTransformer(attachmentId, file, transformerKey);
1584
1604
  }
1585
1605
  }
1586
- }, [maxFileSize, acceptedTypes, strings, transformers, runTransformer]);
1606
+ }, [maxFileSize, acceptedTypes, maxAttachments, strings, transformers, runTransformer]);
1587
1607
  const removeAttachment = useCallback2((id) => {
1588
1608
  setAttachments((prev) => prev.filter((a) => a.id !== id));
1609
+ attachmentsRef.current = attachmentsRef.current.filter((a) => a.id !== id);
1589
1610
  setProcessingState((prev) => {
1590
1611
  const next = new Map(prev);
1591
1612
  next.delete(id);
@@ -1594,6 +1615,7 @@ function useFileUpload({
1594
1615
  }, []);
1595
1616
  const clearAttachments = useCallback2(() => {
1596
1617
  setAttachments([]);
1618
+ attachmentsRef.current = [];
1597
1619
  setProcessingState(/* @__PURE__ */ new Map());
1598
1620
  }, []);
1599
1621
  const openFilePicker = useCallback2(() => {
@@ -2164,7 +2186,16 @@ function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedCo
2164
2186
  );
2165
2187
  }
2166
2188
  function hasFileContent(content) {
2167
- return Array.isArray(content) && content.some((part) => part.type === "file");
2189
+ return Array.isArray(content) && content.some((part) => part.type === "file" || part.type === "attachment_ref");
2190
+ }
2191
+ function fileChipInfo(part) {
2192
+ if (part.type === "file") {
2193
+ return { name: part.file.name, size: part.file.size };
2194
+ }
2195
+ if (part.type === "attachment_ref") {
2196
+ return { name: part.name, size: part.size };
2197
+ }
2198
+ return null;
2168
2199
  }
2169
2200
  function UseAIChatPanel({
2170
2201
  onSendMessage,
@@ -2189,6 +2220,7 @@ function UseAIChatPanel({
2189
2220
  fileProcessing,
2190
2221
  commands = [],
2191
2222
  onSaveCommand,
2223
+ enabledFeatures,
2192
2224
  onRenameCommand,
2193
2225
  onDeleteCommand,
2194
2226
  closeButton,
@@ -2202,6 +2234,8 @@ function UseAIChatPanel({
2202
2234
  }) {
2203
2235
  const strings = useStrings();
2204
2236
  const theme = useTheme();
2237
+ const features = { ...DEFAULT_ENABLED_FEATURES, ...enabledFeatures };
2238
+ const slashCommandsEnabled = features.slashCommands;
2205
2239
  const displayMessages = mergeAssistantMessagesForDisplay(messages);
2206
2240
  const [input, setInput] = useState6("");
2207
2241
  const chatHistoryDropdown = useDropdownState();
@@ -2776,7 +2810,7 @@ function UseAIChatPanel({
2776
2810
  maxWidth: "80%"
2777
2811
  },
2778
2812
  children: [
2779
- message.role === "user" && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */ jsx12(
2813
+ message.role === "user" && slashCommandsEnabled && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */ jsx12(
2780
2814
  "button",
2781
2815
  {
2782
2816
  "data-testid": "save-command-button",
@@ -2834,14 +2868,10 @@ function UseAIChatPanel({
2834
2868
  wordWrap: "break-word"
2835
2869
  },
2836
2870
  children: [
2837
- message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.filter((part) => part.type === "file").map((part, idx) => /* @__PURE__ */ jsx12(
2838
- FilePlaceholder,
2839
- {
2840
- name: part.file.name,
2841
- size: part.file.size
2842
- },
2843
- idx
2844
- )) }),
2871
+ message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.flatMap((part, idx) => {
2872
+ const info = fileChipInfo(part);
2873
+ return info ? [/* @__PURE__ */ jsx12(FilePlaceholder, { name: info.name, size: info.size }, idx)] : [];
2874
+ }) }),
2845
2875
  message.role === "assistant" ? /* @__PURE__ */ jsxs9(Fragment, { children: [
2846
2876
  message.reasoningParts && message.reasoningParts.length > 0 && /* @__PURE__ */ jsx12(
2847
2877
  Reasoning,
@@ -3380,6 +3410,7 @@ function UseAIChat({ floating = false, submitMode }) {
3380
3410
  fileProcessing: ctx.fileProcessing,
3381
3411
  commands: ctx.commands.list,
3382
3412
  onSaveCommand: ctx.commands.save,
3413
+ enabledFeatures: ctx.enabledFeatures,
3383
3414
  onRenameCommand: ctx.commands.rename,
3384
3415
  onDeleteCommand: ctx.commands.delete,
3385
3416
  executingTool: ctx.tools.executing,
@@ -3411,7 +3442,7 @@ function UseAIChat({ floating = false, submitMode }) {
3411
3442
 
3412
3443
  // src/client.ts
3413
3444
  import { io } from "socket.io-client";
3414
- import { EventType } from "@meetsmore-oss/use-ai-core";
3445
+ import { EventType as EventType2 } from "@meetsmore-oss/use-ai-core";
3415
3446
  import { v4 as uuidv42 } from "uuid";
3416
3447
  var UseAIClient = class {
3417
3448
  /**
@@ -3517,7 +3548,7 @@ var UseAIClient = class {
3517
3548
  });
3518
3549
  }
3519
3550
  handleEvent(event) {
3520
- if (event.type === EventType.RUN_STARTED) {
3551
+ if (event.type === EventType2.RUN_STARTED) {
3521
3552
  this._currentAssistantMessage = {
3522
3553
  id: uuidv42(),
3523
3554
  role: "assistant",
@@ -3529,31 +3560,31 @@ var UseAIClient = class {
3529
3560
  this._currentReasoningBlockText = "";
3530
3561
  this._currentMessageContent = "";
3531
3562
  }
3532
- if (event.type === EventType.TEXT_MESSAGE_START) {
3563
+ if (event.type === EventType2.TEXT_MESSAGE_START) {
3533
3564
  const e = event;
3534
3565
  this._currentMessageId = e.messageId;
3535
3566
  this._currentMessageContent = "";
3536
- } else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {
3567
+ } else if (event.type === EventType2.TEXT_MESSAGE_CONTENT) {
3537
3568
  const e = event;
3538
3569
  this._currentMessageContent += e.delta;
3539
- } else if (event.type === EventType.TEXT_MESSAGE_END) {
3570
+ } else if (event.type === EventType2.TEXT_MESSAGE_END) {
3540
3571
  if (this._currentAssistantMessage) {
3541
3572
  this._currentAssistantMessage.content = this._currentMessageContent;
3542
3573
  }
3543
3574
  this._currentMessageId = null;
3544
- } else if (event.type === EventType.TOOL_CALL_START) {
3575
+ } else if (event.type === EventType2.TOOL_CALL_START) {
3545
3576
  const e = event;
3546
3577
  this.currentToolCalls.set(e.toolCallId, {
3547
3578
  name: e.toolCallName,
3548
3579
  args: ""
3549
3580
  });
3550
- } else if (event.type === EventType.TOOL_CALL_ARGS) {
3581
+ } else if (event.type === EventType2.TOOL_CALL_ARGS) {
3551
3582
  const e = event;
3552
3583
  const toolCall = this.currentToolCalls.get(e.toolCallId);
3553
3584
  if (toolCall) {
3554
3585
  toolCall.args += e.delta;
3555
3586
  }
3556
- } else if (event.type === EventType.TOOL_CALL_END) {
3587
+ } else if (event.type === EventType2.TOOL_CALL_END) {
3557
3588
  const e = event;
3558
3589
  const toolCall = this.currentToolCalls.get(e.toolCallId);
3559
3590
  if (toolCall) {
@@ -3566,17 +3597,17 @@ var UseAIClient = class {
3566
3597
  }
3567
3598
  });
3568
3599
  }
3569
- } else if (event.type === EventType.REASONING_MESSAGE_START) {
3600
+ } else if (event.type === EventType2.REASONING_MESSAGE_START) {
3570
3601
  this._currentReasoningBlockText = "";
3571
- } else if (event.type === EventType.REASONING_MESSAGE_CONTENT) {
3602
+ } else if (event.type === EventType2.REASONING_MESSAGE_CONTENT) {
3572
3603
  const e = event;
3573
3604
  this._currentReasoningBlockText += e.delta;
3574
- } else if (event.type === EventType.REASONING_MESSAGE_END) {
3605
+ } else if (event.type === EventType2.REASONING_MESSAGE_END) {
3575
3606
  this._currentReasoningBlocks.push({
3576
3607
  text: this._currentReasoningBlockText
3577
3608
  });
3578
3609
  this._currentReasoningBlockText = "";
3579
- } else if (event.type === EventType.REASONING_ENCRYPTED_VALUE) {
3610
+ } else if (event.type === EventType2.REASONING_ENCRYPTED_VALUE) {
3580
3611
  const e = event;
3581
3612
  if (e.subtype === "message" && this._currentReasoningBlocks.length > 0) {
3582
3613
  const lastBlock = this._currentReasoningBlocks[this._currentReasoningBlocks.length - 1];
@@ -3587,7 +3618,7 @@ var UseAIClient = class {
3587
3618
  tc.encryptedValue = e.encryptedValue;
3588
3619
  }
3589
3620
  }
3590
- } else if (event.type === EventType.TOOL_CALL_RESULT) {
3621
+ } else if (event.type === EventType2.TOOL_CALL_RESULT) {
3591
3622
  const e = event;
3592
3623
  const alreadyTracked = this._pendingToolResults.some(
3593
3624
  (r) => "toolCallId" in r && r.toolCallId === e.toolCallId
@@ -3600,7 +3631,7 @@ var UseAIClient = class {
3600
3631
  toolCallId: e.toolCallId
3601
3632
  });
3602
3633
  }
3603
- } else if (event.type === EventType.STEP_FINISHED) {
3634
+ } else if (event.type === EventType2.STEP_FINISHED) {
3604
3635
  if (this._currentAssistantToolCalls.length > 0 && this._currentAssistantMessage) {
3605
3636
  const reasoningParts = this._currentReasoningBlocks.length > 0 ? [...this._currentReasoningBlocks] : void 0;
3606
3637
  const assistantMsg = {
@@ -3618,10 +3649,10 @@ var UseAIClient = class {
3618
3649
  this._currentReasoningBlocks = [];
3619
3650
  this._currentMessageContent = "";
3620
3651
  }
3621
- } else if (event.type === EventType.RUN_FINISHED) {
3652
+ } else if (event.type === EventType2.RUN_FINISHED) {
3622
3653
  this.finalizeRun({ aborted: false });
3623
3654
  }
3624
- if (event.type === EventType.RUN_FINISHED || event.type === EventType.RUN_ERROR) {
3655
+ if (event.type === EventType2.RUN_FINISHED || event.type === EventType2.RUN_ERROR) {
3625
3656
  this._currentRunId = null;
3626
3657
  }
3627
3658
  this.eventHandlers.forEach((handler) => handler(event));
@@ -3659,31 +3690,13 @@ var UseAIClient = class {
3659
3690
  async sendPrompt(prompt, multimodalContent, forwardedProps) {
3660
3691
  let messageContent = prompt;
3661
3692
  if (multimodalContent && multimodalContent.length > 0) {
3662
- messageContent = multimodalContent.map((part) => {
3663
- if (part.type === "text") {
3664
- return { type: "text", text: part.text };
3665
- } else if (part.type === "image") {
3666
- return { type: "image", url: part.url };
3667
- } else if (part.type === "file") {
3668
- return {
3669
- type: "file",
3670
- url: part.url,
3671
- mimeType: part.mimeType
3672
- };
3673
- } else {
3674
- return {
3675
- type: "transformed_file",
3676
- text: part.text,
3677
- originalFile: part.originalFile
3678
- };
3679
- }
3680
- });
3693
+ messageContent = multimodalContent;
3681
3694
  }
3682
3695
  const userMessage = {
3683
3696
  id: uuidv42(),
3684
3697
  role: "user",
3698
+ // @ag-ui/core declares Message.content as `string`; the wire also carries MultimodalContent[].
3685
3699
  content: messageContent
3686
- // Type cast needed for Message type compatibility
3687
3700
  };
3688
3701
  this._messages.push(userMessage);
3689
3702
  const runId = uuidv42();
@@ -3914,7 +3927,7 @@ var UseAIClient = class {
3914
3927
  */
3915
3928
  onTextMessage(handler) {
3916
3929
  return this.onEvent("text-message-handler", (event) => {
3917
- if (event.type === EventType.TEXT_MESSAGE_END && this._currentMessageContent) {
3930
+ if (event.type === EventType2.TEXT_MESSAGE_END && this._currentMessageContent) {
3918
3931
  handler(this._currentMessageContent);
3919
3932
  }
3920
3933
  });
@@ -3928,7 +3941,7 @@ var UseAIClient = class {
3928
3941
  */
3929
3942
  onToolCall(handler) {
3930
3943
  return this.onEvent("tool-call-handler", (event) => {
3931
- if (event.type === EventType.TOOL_CALL_END) {
3944
+ if (event.type === EventType2.TOOL_CALL_END) {
3932
3945
  const e = event;
3933
3946
  const toolCall = this.currentToolCalls.get(e.toolCallId);
3934
3947
  if (toolCall) {
@@ -4381,6 +4394,7 @@ function buildPersistedParts(message, attachments, fileContent) {
4381
4394
  parts.push({ type: "text", text: message });
4382
4395
  }
4383
4396
  const transformedByKey = /* @__PURE__ */ new Map();
4397
+ const nonTransformedParts = [];
4384
4398
  for (const part of fileContent) {
4385
4399
  if (part.type === "transformed_file") {
4386
4400
  const key = `${part.originalFile.name}:${part.originalFile.size}:${part.originalFile.mimeType}`;
@@ -4390,6 +4404,8 @@ function buildPersistedParts(message, attachments, fileContent) {
4390
4404
  } else {
4391
4405
  transformedByKey.set(key, [part]);
4392
4406
  }
4407
+ } else {
4408
+ nonTransformedParts.push(part);
4393
4409
  }
4394
4410
  }
4395
4411
  for (const attachment of attachments) {
@@ -4401,6 +4417,18 @@ function buildPersistedParts(message, attachments, fileContent) {
4401
4417
  text: transformed.text,
4402
4418
  originalFile: transformed.originalFile
4403
4419
  });
4420
+ continue;
4421
+ }
4422
+ const part = nonTransformedParts.shift();
4423
+ const ref = part && (part.type === "image_ref" || part.type === "file_ref") ? part.ref : void 0;
4424
+ if (ref) {
4425
+ parts.push({
4426
+ type: "attachment_ref",
4427
+ ref,
4428
+ name: attachment.file.name,
4429
+ mimeType: attachment.file.type,
4430
+ size: attachment.file.size
4431
+ });
4404
4432
  } else {
4405
4433
  parts.push({
4406
4434
  type: "file",
@@ -4453,9 +4481,18 @@ function transformMessagesToClientFormat(persistedMessages) {
4453
4481
  ${p.text}`
4454
4482
  }];
4455
4483
  }
4484
+ if (p.type === "attachment_ref") {
4485
+ return [
4486
+ p.mimeType.startsWith("image/") ? { type: "image_ref", ref: p.ref } : { type: "file_ref", ref: p.ref, mimeType: p.mimeType, name: p.name }
4487
+ ];
4488
+ }
4456
4489
  return [];
4457
4490
  });
4458
- return { id: msg.id, role: "user", content: parts };
4491
+ return {
4492
+ id: msg.id,
4493
+ role: "user",
4494
+ content: parts
4495
+ };
4459
4496
  }
4460
4497
  }
4461
4498
  });
@@ -5381,11 +5418,6 @@ function useFeedback({
5381
5418
 
5382
5419
  // src/hooks/useServerEvents.ts
5383
5420
  import { useState as useState13, useCallback as useCallback11, useRef as useRef10 } from "react";
5384
-
5385
- // src/types.ts
5386
- import { EventType as EventType2, ErrorCode, TOOL_APPROVAL_REQUEST } from "@meetsmore-oss/use-ai-core";
5387
-
5388
- // src/hooks/useServerEvents.ts
5389
5421
  function useServerEvents({
5390
5422
  toolSystem,
5391
5423
  saveAIResponse,
@@ -5439,21 +5471,21 @@ function useServerEvents({
5439
5471
  const handleServerEvent = useCallback11(async (client, event) => {
5440
5472
  const ts = toolSystemRef.current;
5441
5473
  const strs = stringsRef.current;
5442
- if (event.type === EventType2.RUN_STARTED) {
5474
+ if (event.type === EventType.RUN_STARTED) {
5443
5475
  messageCountAtRunStartRef.current = client.messages.length;
5444
5476
  runIdAtRunStartRef.current = client.currentRunId ?? void 0;
5445
5477
  hasTextFromPriorStepRef.current = false;
5446
5478
  setStreamingReasoning("");
5447
- } else if (event.type === EventType2.REASONING_MESSAGE_START) {
5479
+ } else if (event.type === EventType.REASONING_MESSAGE_START) {
5448
5480
  setStreamingReasoning((prev) => prev ? prev + "\n\n" : prev);
5449
- } else if (event.type === EventType2.REASONING_MESSAGE_CONTENT) {
5481
+ } else if (event.type === EventType.REASONING_MESSAGE_CONTENT) {
5450
5482
  const reasoningEvent = event;
5451
5483
  setStreamingReasoning((prev) => prev + reasoningEvent.delta);
5452
- } else if (event.type === EventType2.TEXT_MESSAGE_START) {
5484
+ } else if (event.type === EventType.TEXT_MESSAGE_START) {
5453
5485
  if (hasTextFromPriorStepRef.current) {
5454
5486
  setStreamingText((prev) => prev + "\n\n");
5455
5487
  }
5456
- } else if (event.type === EventType2.TOOL_CALL_START) {
5488
+ } else if (event.type === EventType.TOOL_CALL_START) {
5457
5489
  const e = event;
5458
5490
  const tool = ts.aggregatedToolsRef.current[e.toolCallName];
5459
5491
  const title = e.annotations?.title ?? tool?._options?.annotations?.title ?? null;
@@ -5462,7 +5494,7 @@ function useServerEvents({
5462
5494
  executingToolFallbackRef.current = fallbacks[Math.floor(Math.random() * fallbacks.length)];
5463
5495
  }
5464
5496
  setExecutingTool({ toolCallId: e.toolCallId, title });
5465
- } else if (event.type === EventType2.TOOL_CALL_END) {
5497
+ } else if (event.type === EventType.TOOL_CALL_END) {
5466
5498
  const toolCallEnd = event;
5467
5499
  const toolCallId = toolCallEnd.toolCallId;
5468
5500
  setExecutingTool((prev) => prev?.toolCallId === toolCallId ? null : prev);
@@ -5487,16 +5519,16 @@ function useServerEvents({
5487
5519
  } else if (event.type === TOOL_APPROVAL_REQUEST) {
5488
5520
  const e = event;
5489
5521
  ts.handleApprovalRequest(e);
5490
- } else if (event.type === EventType2.TEXT_MESSAGE_CONTENT) {
5522
+ } else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {
5491
5523
  const contentEvent = event;
5492
5524
  hasTextFromPriorStepRef.current = true;
5493
5525
  setStreamingText((prev) => prev + contentEvent.delta);
5494
- } else if (event.type === EventType2.TEXT_MESSAGE_END) {
5495
- } else if (event.type === EventType2.RUN_FINISHED) {
5526
+ } else if (event.type === EventType.TEXT_MESSAGE_END) {
5527
+ } else if (event.type === EventType.RUN_FINISHED) {
5496
5528
  const finishedEvent = event;
5497
5529
  await persistFinalResponse(client, { aborted: false, traceId: finishedEvent.runId });
5498
5530
  resetRunUiState();
5499
- } else if (event.type === EventType2.RUN_ERROR) {
5531
+ } else if (event.type === EventType.RUN_ERROR) {
5500
5532
  const errorEvent = event;
5501
5533
  const errorCode = errorEvent.message;
5502
5534
  if (errorCode === ErrorCode.ABORTED) {
@@ -5697,6 +5729,7 @@ function UseAIProvider({
5697
5729
  forwardedPropsProvider,
5698
5730
  fileUploadConfig: fileUploadConfigProp,
5699
5731
  commandRepository,
5732
+ enabledFeatures,
5700
5733
  renderChat = true,
5701
5734
  theme: customTheme,
5702
5735
  strings: customStrings,
@@ -5949,6 +5982,7 @@ function UseAIProvider({
5949
5982
  rename: renameCommand,
5950
5983
  delete: deleteCommand
5951
5984
  },
5985
+ enabledFeatures,
5952
5986
  ui: {
5953
5987
  isOpen: isChatOpen,
5954
5988
  setOpen: handleSetChatOpen
@@ -5992,6 +6026,7 @@ function UseAIProvider({
5992
6026
  fileProcessing: fileProcessingState,
5993
6027
  commands,
5994
6028
  onSaveCommand: saveCommand,
6029
+ enabledFeatures,
5995
6030
  onRenameCommand: renameCommand,
5996
6031
  onDeleteCommand: deleteCommand,
5997
6032
  executingTool: serverEvents.executingTool,
@@ -6225,7 +6260,7 @@ function useAI(options = {}) {
6225
6260
  }, [enabled, client]);
6226
6261
  const handleAGUIEvent = useCallback14(async (event) => {
6227
6262
  switch (event.type) {
6228
- case EventType2.TEXT_MESSAGE_END: {
6263
+ case EventType.TEXT_MESSAGE_END: {
6229
6264
  const content = client?.currentMessageContent;
6230
6265
  if (content) {
6231
6266
  setResponse(content);
@@ -6233,7 +6268,7 @@ function useAI(options = {}) {
6233
6268
  }
6234
6269
  break;
6235
6270
  }
6236
- case EventType2.RUN_ERROR: {
6271
+ case EventType.RUN_ERROR: {
6237
6272
  const errorEvent = event;
6238
6273
  const error2 = new Error(errorEvent.message);
6239
6274
  setError(error2);