@apteva/apteva-kit 0.1.72 → 0.1.77

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
@@ -606,6 +606,14 @@ function findMatchingBracket(text, startIndex) {
606
606
  }
607
607
  return -1;
608
608
  }
609
+ function findOpeningBracket(text) {
610
+ const squareIndex = text.indexOf("[");
611
+ const curlyIndex = text.indexOf("{");
612
+ if (squareIndex === -1 && curlyIndex === -1) return null;
613
+ if (squareIndex === -1) return { index: curlyIndex, char: "{" };
614
+ if (curlyIndex === -1) return { index: squareIndex, char: "[" };
615
+ return squareIndex < curlyIndex ? { index: squareIndex, char: "[" } : { index: curlyIndex, char: "{" };
616
+ }
609
617
  function parseWidgetsFromText(text) {
610
618
  const segments = [];
611
619
  let hasWidgets = false;
@@ -619,13 +627,14 @@ function parseWidgetsFromText(text) {
619
627
  const typeMatch = afterStart.match(/^@ui:(\w+)/);
620
628
  if (typeMatch) {
621
629
  const widgetType = typeMatch[1];
622
- const bracketOpenIndex = afterStart.indexOf("[");
623
- if (bracketOpenIndex === -1) {
630
+ const afterType = afterStart.slice(typeMatch[0].length);
631
+ const bracketInfo = findOpeningBracket(afterType);
632
+ if (!bracketInfo) {
624
633
  processText = text.slice(0, lastWidgetStart);
625
634
  pendingWidgetType = widgetType;
626
635
  hasPendingWidget = true;
627
636
  } else {
628
- const fullBracketStart = lastWidgetStart + bracketOpenIndex;
637
+ const fullBracketStart = lastWidgetStart + typeMatch[0].length + bracketInfo.index;
629
638
  const bracketEnd = findMatchingBracket(text, fullBracketStart);
630
639
  if (bracketEnd === -1) {
631
640
  if (STREAMABLE_WIDGET_TYPES.includes(widgetType)) {
@@ -667,16 +676,22 @@ function parseWidgetsFromText(text) {
667
676
  if (hasPendingWidget) {
668
677
  processText = processText.replace(/[\s:;\-–—\.]+$/g, "");
669
678
  }
670
- const startPattern = /@ui:(\w+)\[/g;
679
+ const startPattern = /@ui:(\w+)([\[{])/g;
671
680
  let match;
672
681
  while ((match = startPattern.exec(processText)) !== null) {
673
682
  const widgetType = match[1];
683
+ const openingBracket = match[2];
674
684
  const bracketStart = match.index + match[0].length - 1;
675
685
  const bracketEnd = findMatchingBracket(processText, bracketStart);
676
686
  if (bracketEnd === -1) {
677
687
  continue;
678
688
  }
679
- const jsonContent = processText.slice(bracketStart + 1, bracketEnd);
689
+ let jsonContent;
690
+ if (openingBracket === "[") {
691
+ jsonContent = processText.slice(bracketStart + 1, bracketEnd);
692
+ } else {
693
+ jsonContent = processText.slice(bracketStart, bracketEnd + 1);
694
+ }
680
695
  if (match.index > currentIndex) {
681
696
  const textContent = processText.slice(currentIndex, match.index).trim();
682
697
  if (textContent) {
@@ -1520,19 +1535,14 @@ function MarkdownContent({ content, className = "" }) {
1520
1535
 
1521
1536
  function ToolCall({ name, status, isReceiving = false, inputLength = 0 }) {
1522
1537
  if (status === "preparing") {
1523
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `apteva-tool-card apteva-tool-card-preparing ${isReceiving ? "apteva-tool-receiving" : ""}`, children: [
1538
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "apteva-tool-card apteva-tool-card-preparing", children: [
1524
1539
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { className: "apteva-tool-icon apteva-tool-icon-spin", fill: "none", viewBox: "0 0 24 24", children: [
1525
1540
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { className: "apteva-tool-spinner-track", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1526
1541
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { className: "apteva-tool-spinner-fill", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
1527
1542
  ] }),
1528
1543
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "apteva-tool-label", children: [
1529
1544
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: name }),
1530
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-status-text", children: " preparing" }),
1531
- inputLength > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "apteva-tool-char-count", children: [
1532
- " (",
1533
- inputLength,
1534
- " chars)"
1535
- ] })
1545
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-status-text", children: " preparing..." })
1536
1546
  ] })
1537
1547
  ] });
1538
1548
  }
@@ -2871,8 +2881,8 @@ ${widgetContext}` : widgetContext;
2871
2881
  let currentTextBuffer = "";
2872
2882
  let accumulatedWidgets = [];
2873
2883
  let responseThreadId = currentThreadId;
2874
- let toolInputBuffer = "";
2875
- let receivingTimeout = null;
2884
+ const toolInputBuffers = {};
2885
+ const receivingTimeouts = {};
2876
2886
  const streamingMessageId = `msg-${Date.now()}`;
2877
2887
  const updateMessage = () => {
2878
2888
  const segments = [...contentSegments];
@@ -2950,7 +2960,7 @@ ${widgetContext}` : widgetContext;
2950
2960
  currentTextBuffer = "";
2951
2961
  }
2952
2962
  contentSegments.push({ type: "tool", id: chunk.tool_id, name: displayName, status: "preparing" });
2953
- toolInputBuffer = "";
2963
+ toolInputBuffers[chunk.tool_id] = "";
2954
2964
  setChatToolName(displayName);
2955
2965
  _optionalChain([onToolCall, 'optionalCall', _72 => _72(chunk.tool_name, chunk.tool_id)]);
2956
2966
  updateMessage();
@@ -2958,14 +2968,18 @@ ${widgetContext}` : widgetContext;
2958
2968
  break;
2959
2969
  case "tool_input_delta":
2960
2970
  if (chunk.tool_id && chunk.content) {
2961
- toolInputBuffer += chunk.content;
2962
- const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
2971
+ const toolId = chunk.tool_id;
2972
+ if (toolInputBuffers[toolId] === void 0) {
2973
+ toolInputBuffers[toolId] = "";
2974
+ }
2975
+ toolInputBuffers[toolId] += chunk.content;
2976
+ const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === toolId);
2963
2977
  if (toolSegment) {
2964
2978
  toolSegment.isReceiving = true;
2965
- toolSegment.inputLength = toolInputBuffer.length;
2979
+ toolSegment.inputLength = toolInputBuffers[toolId].length;
2966
2980
  updateMessage();
2967
- if (receivingTimeout) clearTimeout(receivingTimeout);
2968
- receivingTimeout = setTimeout(() => {
2981
+ if (receivingTimeouts[toolId]) clearTimeout(receivingTimeouts[toolId]);
2982
+ receivingTimeouts[toolId] = setTimeout(() => {
2969
2983
  if (toolSegment.status === "preparing") {
2970
2984
  toolSegment.isReceiving = false;
2971
2985
  updateMessage();