@akropolys/kiku 1.7.5 → 1.7.7

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.mjs CHANGED
@@ -1130,6 +1130,11 @@ var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs6("svg", { width: "18", height: "18
1130
1130
  /* @__PURE__ */ jsx7("path", { d: "M12 19V5" })
1131
1131
  ] });
1132
1132
  var StopIcon = () => /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx7("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }) });
1133
+ var ExternalIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1134
+ /* @__PURE__ */ jsx7("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1135
+ /* @__PURE__ */ jsx7("polyline", { points: "15 3 21 3 21 9" }),
1136
+ /* @__PURE__ */ jsx7("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1137
+ ] });
1133
1138
  var ContinueIcon = () => /* @__PURE__ */ jsx7("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx7("path", { d: "M8 5v14l11-7z" }) });
1134
1139
  var CloseIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1135
1140
  /* @__PURE__ */ jsx7("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
@@ -1572,67 +1577,46 @@ function parseThinking(text) {
1572
1577
  isComplete: true
1573
1578
  };
1574
1579
  }
1575
- function ThinkingBlock({ text, isComplete }) {
1576
- const [isOpen, setIsOpen] = useState5(true);
1580
+ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
1581
+ const startRef = useRef5(Date.now());
1582
+ const [seconds, setSeconds] = useState5(() => isComplete ? null : 0);
1583
+ const [isOpen, setIsOpen] = useState5(!isComplete);
1577
1584
  useEffect3(() => {
1578
- if (!isComplete) {
1579
- setIsOpen(true);
1585
+ if (isComplete) {
1586
+ if (seconds !== null) {
1587
+ setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1e3)));
1588
+ setIsOpen(false);
1589
+ }
1590
+ return;
1580
1591
  }
1592
+ setIsOpen(true);
1593
+ const t = setInterval(() => {
1594
+ setSeconds(Math.round((Date.now() - startRef.current) / 1e3));
1595
+ }, 1e3);
1596
+ return () => clearInterval(t);
1581
1597
  }, [isComplete]);
1582
- return /* @__PURE__ */ jsxs6("div", { style: {
1583
- marginBottom: "12px",
1584
- borderLeft: "2px solid #e4e4e7",
1585
- paddingLeft: "10px",
1586
- fontSize: "0.825rem",
1587
- backgroundColor: "rgba(244, 244, 245, 0.4)",
1588
- padding: "8px 10px",
1589
- borderRadius: "0 6px 6px 0"
1590
- }, children: [
1598
+ const finalSeconds = fixedSeconds ?? seconds;
1599
+ const label = isComplete ? finalSeconds !== null && finalSeconds !== void 0 ? `Thought for ${finalSeconds}s` : "Thought process" : `Thinking${seconds ? ` \xB7 ${seconds}s` : "\u2026"}`;
1600
+ const expandable = !!text;
1601
+ return /* @__PURE__ */ jsxs6("div", { className: cn("hsk-cb-think", !isComplete && "hsk-cb-think--live"), children: [
1591
1602
  /* @__PURE__ */ jsxs6(
1592
- "div",
1603
+ "button",
1593
1604
  {
1594
- onClick: () => setIsOpen(!isOpen),
1595
- style: {
1596
- display: "flex",
1597
- alignItems: "center",
1598
- gap: "6px",
1599
- color: "#71717a",
1600
- cursor: "pointer",
1601
- fontWeight: 500,
1602
- userSelect: "none"
1603
- },
1605
+ type: "button",
1606
+ className: cn("hsk-cb-think-head", !expandable && "hsk-cb-think-head--static"),
1607
+ onClick: expandable ? () => setIsOpen((o) => !o) : void 0,
1608
+ "aria-expanded": expandable ? isOpen : void 0,
1604
1609
  children: [
1605
- /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
1606
- /* @__PURE__ */ jsxs6("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { animation: !isComplete ? "spin 3s linear infinite" : "none" }, children: [
1607
- /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "10" }),
1608
- /* @__PURE__ */ jsx7("path", { d: "M12 6v6l4 2" })
1609
- ] }),
1610
- "Thinking Process"
1610
+ /* @__PURE__ */ jsxs6("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: !isComplete ? "hsk-cb-think-spin" : void 0, children: [
1611
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "10" }),
1612
+ /* @__PURE__ */ jsx7("path", { d: "M12 6v6l4 2" })
1611
1613
  ] }),
1612
- !isComplete && /* @__PURE__ */ jsx7("span", { style: {
1613
- width: "6px",
1614
- height: "6px",
1615
- borderRadius: "50%",
1616
- backgroundColor: "#3b82f6",
1617
- display: "inline-block",
1618
- animation: "hsk-pulse 1.2s infinite ease-in-out"
1619
- } }),
1620
- /* @__PURE__ */ jsx7("span", { style: {
1621
- fontSize: "0.7rem",
1622
- marginLeft: "auto",
1623
- transform: isOpen ? "rotate(90deg)" : "none",
1624
- transition: "transform 0.1s"
1625
- }, children: "\u25B6" })
1614
+ /* @__PURE__ */ jsx7("span", { children: label }),
1615
+ expandable && /* @__PURE__ */ jsx7("span", { className: cn("hsk-cb-think-chevron", isOpen && "hsk-cb-think-chevron--open"), children: "\u25B6" })
1626
1616
  ]
1627
1617
  }
1628
1618
  ),
1629
- isOpen && /* @__PURE__ */ jsx7("div", { style: {
1630
- marginTop: "6px",
1631
- color: "#52525b",
1632
- whiteSpace: "pre-wrap",
1633
- lineHeight: "1.4",
1634
- fontStyle: "italic"
1635
- }, children: text })
1619
+ expandable && isOpen && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-think-body", children: text })
1636
1620
  ] });
1637
1621
  }
1638
1622
  function ChatModal({
@@ -1652,7 +1636,7 @@ function ChatModal({
1652
1636
  visionCategoryHint
1653
1637
  }) {
1654
1638
  const client = useAkropolysContext3();
1655
- const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, continueGenerating, reset, referencedIds } = useKiku2();
1639
+ const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = useKiku2();
1656
1640
  const [input, setInput] = useState5("");
1657
1641
  const [shopperName, setShopperNameState] = useState5(() => {
1658
1642
  try {
@@ -1742,6 +1726,15 @@ function ChatModal({
1742
1726
  const [keyPhase, setKeyPhase] = useState5("idle");
1743
1727
  const [mintedKey, setMintedKey] = useState5(null);
1744
1728
  const [mintedPub, setMintedPub] = useState5(null);
1729
+ const [copied, setCopied] = useState5(null);
1730
+ const copyValue = (value, which) => {
1731
+ try {
1732
+ navigator.clipboard?.writeText(value);
1733
+ } catch {
1734
+ }
1735
+ setCopied(which);
1736
+ setTimeout(() => setCopied((c) => c === which ? null : c), 1600);
1737
+ };
1745
1738
  const [keyCountdown, setKeyCountdown] = useState5(KIKU_KEY_REVEAL_SECONDS);
1746
1739
  const [minting, setMinting] = useState5(false);
1747
1740
  const [showKikuPicker, setShowKikuPicker] = useState5(false);
@@ -2065,9 +2058,12 @@ function ChatModal({
2065
2058
  /* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
2066
2059
  /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-body", children: [
2067
2060
  (() => {
2068
- const { thinking, content, isComplete } = parseThinking(displayContent);
2061
+ const parsed = parseThinking(displayContent);
2062
+ const thinking = msg.thinking || parsed.thinking;
2063
+ const content = parsed.content;
2064
+ const isComplete = msg.thinking ? content.length > 0 || !(isLast && streaming) : parsed.isComplete;
2069
2065
  return /* @__PURE__ */ jsxs6(Fragment3, { children: [
2070
- thinking && /* @__PURE__ */ jsx7(ThinkingBlock, { text: thinking, isComplete }),
2066
+ (thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */ jsx7(ThinkingBlock, { text: thinking, isComplete, seconds: msg.thoughtForSeconds }),
2071
2067
  content && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-text", children: [
2072
2068
  renderMarkdown(content, isLast && streaming),
2073
2069
  isLast && streaming && /* @__PURE__ */ jsx7("span", { style: { display: "inline-block", width: "0.5em", height: "1.05em", marginLeft: "2px", verticalAlign: "text-bottom", background: "currentColor", opacity: 0.55, borderRadius: "1px" } })
@@ -2160,11 +2156,24 @@ function ChatModal({
2160
2156
  ] }),
2161
2157
  /* @__PURE__ */ jsx7("span", { className: "hsk-cb-thinking-text", children: "Thinking\u2026" })
2162
2158
  ] }),
2163
- stopped && !loading && !streaming && messages[messages.length - 1]?.role === "assistant" && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-stopped", children: [
2164
- /* @__PURE__ */ jsx7("span", { className: "hsk-cb-stopped-label", children: "You stopped this response." }),
2159
+ lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ jsxs6(
2160
+ "a",
2161
+ {
2162
+ className: "hsk-cb-memory-pill",
2163
+ href: String(lastAction.url),
2164
+ target: "_blank",
2165
+ rel: "noopener noreferrer",
2166
+ children: [
2167
+ "Open my memory on mimi",
2168
+ /* @__PURE__ */ jsx7(ExternalIcon, {})
2169
+ ]
2170
+ }
2171
+ ),
2172
+ (stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-stopped", children: [
2173
+ /* @__PURE__ */ jsx7("span", { className: "hsk-cb-stopped-label", children: stopped ? "You stopped this response." : "This response was interrupted." }),
2165
2174
  /* @__PURE__ */ jsxs6("button", { className: "hsk-cb-continue", onClick: continueGenerating, children: [
2166
2175
  /* @__PURE__ */ jsx7(ContinueIcon, {}),
2167
- "Continue generating"
2176
+ messages[messages.length - 1]?.role === "assistant" ? "Continue generating" : "Generate response"
2168
2177
  ] })
2169
2178
  ] }),
2170
2179
  error && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
@@ -2197,12 +2206,7 @@ function ChatModal({
2197
2206
  /* @__PURE__ */ jsx7("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your secret \u2014 shown only once" }),
2198
2207
  /* @__PURE__ */ jsx7("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children: mintedKey }),
2199
2208
  /* @__PURE__ */ jsxs6("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
2200
- /* @__PURE__ */ jsx7("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => {
2201
- try {
2202
- navigator.clipboard?.writeText(mintedKey);
2203
- } catch {
2204
- }
2205
- }, children: "Copy secret" }),
2209
+ /* @__PURE__ */ jsx7("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedKey, "secret"), children: copied === "secret" ? "Copied" : "Copy secret" }),
2206
2210
  /* @__PURE__ */ jsx7("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Keep it private \u2014 use it to unlock your memory at mimi.akropolys.cloud. If lost, the memory is lost with it." })
2207
2211
  ] })
2208
2212
  ] }),
@@ -2210,12 +2214,7 @@ function ChatModal({
2210
2214
  /* @__PURE__ */ jsx7("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your public id" }),
2211
2215
  /* @__PURE__ */ jsx7("code", { style: { display: "block", fontSize: 13, fontWeight: 600, marginBottom: 6, wordBreak: "break-all", opacity: 0.85 }, children: mintedPub }),
2212
2216
  /* @__PURE__ */ jsxs6("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
2213
- /* @__PURE__ */ jsx7("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => {
2214
- try {
2215
- navigator.clipboard?.writeText(mintedPub);
2216
- } catch {
2217
- }
2218
- }, children: "Copy id" }),
2217
+ /* @__PURE__ */ jsx7("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedPub, "pub"), children: copied === "pub" ? "Copied" : "Copy id" }),
2219
2218
  /* @__PURE__ */ jsx7("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Paste this on any site to keep saving to the same memory." })
2220
2219
  ] })
2221
2220
  ] }),