@ash-ai/ui 0.0.2 → 0.0.3

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.cjs CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  SessionHistory: () => SessionHistory,
34
34
  StatusIndicator: () => StatusIndicator,
35
35
  Terminal: () => Terminal2,
36
+ ThinkingBlock: () => ThinkingBlock,
36
37
  ToolCallBlock: () => ToolCallBlock,
37
38
  buildFileTree: () => buildFileTree,
38
39
  cn: () => cn,
@@ -112,6 +113,16 @@ function buildFileTree(files) {
112
113
  sortNodes(root);
113
114
  return root;
114
115
  }
116
+ function unwrapMessageObject(obj) {
117
+ if (obj.message && typeof obj.message === "object") {
118
+ const msg = obj.message;
119
+ if (Array.isArray(msg.content)) return msg.content;
120
+ }
121
+ if (Array.isArray(obj.content)) return obj.content;
122
+ if (typeof obj.content === "string") return obj.content;
123
+ if (typeof obj.result === "string") return obj.result;
124
+ return "";
125
+ }
115
126
  function parseContentBlocks(content) {
116
127
  let blocks = null;
117
128
  if (typeof content === "string") {
@@ -119,18 +130,23 @@ function parseContentBlocks(content) {
119
130
  const parsed = JSON.parse(content);
120
131
  if (Array.isArray(parsed)) {
121
132
  blocks = parsed;
133
+ } else if (parsed && typeof parsed === "object") {
134
+ return parseContentBlocks(unwrapMessageObject(parsed));
122
135
  }
123
136
  } catch {
124
- return { text: content, toolCalls: [] };
137
+ return { text: content, toolCalls: [], thinking: [] };
125
138
  }
126
139
  } else if (Array.isArray(content)) {
127
140
  blocks = content;
141
+ } else if (content && typeof content === "object") {
142
+ return parseContentBlocks(unwrapMessageObject(content));
128
143
  }
129
144
  if (!blocks) {
130
- return { text: typeof content === "string" ? content : "", toolCalls: [] };
145
+ return { text: typeof content === "string" ? content : "", toolCalls: [], thinking: [] };
131
146
  }
132
147
  let text = "";
133
148
  const toolCalls = [];
149
+ const thinking = [];
134
150
  for (const block of blocks) {
135
151
  const b = block;
136
152
  if (b.type === "text" && typeof b.text === "string") {
@@ -149,9 +165,12 @@ function parseContentBlocks(content) {
149
165
  match.isError = b.is_error ?? false;
150
166
  match.state = b.is_error ? "error" : "completed";
151
167
  }
168
+ } else if (b.type === "thinking") {
169
+ const t = b.thinking || b.text || "";
170
+ if (t) thinking.push(t);
152
171
  }
153
172
  }
154
- return { text, toolCalls };
173
+ return { text, toolCalls, thinking };
155
174
  }
156
175
  var IMAGE_EXTS = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "svg", "webp", "ico"]);
157
176
  function isImageFile(name) {
@@ -620,6 +639,17 @@ function icon(d, opts) {
620
639
  );
621
640
  return Component;
622
641
  }
642
+ var Brain = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
643
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z" }),
644
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z" }),
645
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4" }),
646
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17.599 6.5a3 3 0 0 0 .399-1.375" }),
647
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6.003 5.125A3 3 0 0 0 6.401 6.5" }),
648
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3.477 10.896a4 4 0 0 1 .585-.396" }),
649
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19.938 10.5a4 4 0 0 1 .585.396" }),
650
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6 18a4 4 0 0 1-1.967-.516" }),
651
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19.967 17.484A4 4 0 0 1 18 18" })
652
+ ] });
623
653
  var Bot = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
624
654
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 8V4H8" }),
625
655
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "16", height: "12", x: "4", y: "8", rx: "2" }),
@@ -829,6 +859,25 @@ var import_react8 = require("react");
829
859
  // src/components/ToolCallBlock.tsx
830
860
  var import_react7 = require("react");
831
861
  var import_jsx_runtime5 = require("react/jsx-runtime");
862
+ function ThinkingBlock({ thinking }) {
863
+ const [open, setOpen] = (0, import_react7.useState)(false);
864
+ const combined = thinking.join("\n\n");
865
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "my-2 rounded-lg border border-amber-500/20 bg-amber-500/[0.03] overflow-hidden", children: [
866
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
867
+ "button",
868
+ {
869
+ onClick: () => setOpen(!open),
870
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-amber-500/5 transition-colors",
871
+ children: [
872
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Brain, { className: "h-3.5 w-3.5 shrink-0 text-amber-500/60" }),
873
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs font-medium text-amber-400/70", children: "Thinking" }),
874
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ml-auto flex items-center gap-1.5", children: open ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronDown, { className: "h-3 w-3 text-white/30" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronRight, { className: "h-3 w-3 text-white/30" }) })
875
+ ]
876
+ }
877
+ ),
878
+ open && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-t border-amber-500/10 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { className: "whitespace-pre-wrap text-xs text-white/50 leading-relaxed max-h-96 overflow-y-auto", children: combined }) })
879
+ ] });
880
+ }
832
881
  function ToolCallBlock({ tool }) {
833
882
  const [open, setOpen] = (0, import_react7.useState)(false);
834
883
  const isRunning = tool.state === "running" || tool.state === "pending";
@@ -900,6 +949,7 @@ function ChatMessage({ message: msg }) {
900
949
  "max-w-[75%] rounded-2xl px-4 py-2.5",
901
950
  isUser ? "bg-accent/10 border border-accent/20 text-white" : "bg-white/5 border border-white/10 text-white/80"
902
951
  ), children: [
952
+ msg.thinking && msg.thinking.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ThinkingBlock, { thinking: msg.thinking }),
903
953
  msg.content && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "whitespace-pre-wrap text-sm leading-relaxed", children: [
904
954
  msg.content,
905
955
  msg.isStreaming && !msg.toolCalls?.some((tc) => tc.state === "running") && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ml-1 inline-block h-4 w-0.5 animate-pulse bg-accent align-text-bottom" })
@@ -1761,6 +1811,7 @@ function Playground({ client, defaultAgent, className }) {
1761
1811
  SessionHistory,
1762
1812
  StatusIndicator,
1763
1813
  Terminal,
1814
+ ThinkingBlock,
1764
1815
  ToolCallBlock,
1765
1816
  buildFileTree,
1766
1817
  cn,