@akropolys/kiku 1.7.4 → 1.7.6

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
@@ -1162,6 +1162,11 @@ var ArrowUpIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", {
1162
1162
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 19V5" })
1163
1163
  ] });
1164
1164
  var StopIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }) });
1165
+ var ExternalIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1166
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1167
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("polyline", { points: "15 3 21 3 21 9" }),
1168
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1169
+ ] });
1165
1170
  var ContinueIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M8 5v14l11-7z" }) });
1166
1171
  var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1167
1172
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
@@ -1604,67 +1609,36 @@ function parseThinking(text) {
1604
1609
  isComplete: true
1605
1610
  };
1606
1611
  }
1607
- function ThinkingBlock({ text, isComplete }) {
1608
- const [isOpen, setIsOpen] = (0, import_react5.useState)(true);
1612
+ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
1613
+ const startRef = (0, import_react5.useRef)(Date.now());
1614
+ const [seconds, setSeconds] = (0, import_react5.useState)(() => isComplete ? null : 0);
1615
+ const [isOpen, setIsOpen] = (0, import_react5.useState)(!isComplete);
1609
1616
  (0, import_react5.useEffect)(() => {
1610
- if (!isComplete) {
1611
- setIsOpen(true);
1617
+ if (isComplete) {
1618
+ if (seconds !== null) {
1619
+ setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1e3)));
1620
+ setIsOpen(false);
1621
+ }
1622
+ return;
1612
1623
  }
1624
+ setIsOpen(true);
1625
+ const t = setInterval(() => {
1626
+ setSeconds(Math.round((Date.now() - startRef.current) / 1e3));
1627
+ }, 1e3);
1628
+ return () => clearInterval(t);
1613
1629
  }, [isComplete]);
1614
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: {
1615
- marginBottom: "12px",
1616
- borderLeft: "2px solid #e4e4e7",
1617
- paddingLeft: "10px",
1618
- fontSize: "0.825rem",
1619
- backgroundColor: "rgba(244, 244, 245, 0.4)",
1620
- padding: "8px 10px",
1621
- borderRadius: "0 6px 6px 0"
1622
- }, children: [
1623
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1624
- "div",
1625
- {
1626
- onClick: () => setIsOpen(!isOpen),
1627
- style: {
1628
- display: "flex",
1629
- alignItems: "center",
1630
- gap: "6px",
1631
- color: "#71717a",
1632
- cursor: "pointer",
1633
- fontWeight: 500,
1634
- userSelect: "none"
1635
- },
1636
- children: [
1637
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
1638
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
1639
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
1640
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 6v6l4 2" })
1641
- ] }),
1642
- "Thinking Process"
1643
- ] }),
1644
- !isComplete && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
1645
- width: "6px",
1646
- height: "6px",
1647
- borderRadius: "50%",
1648
- backgroundColor: "#3b82f6",
1649
- display: "inline-block",
1650
- animation: "hsk-pulse 1.2s infinite ease-in-out"
1651
- } }),
1652
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: {
1653
- fontSize: "0.7rem",
1654
- marginLeft: "auto",
1655
- transform: isOpen ? "rotate(90deg)" : "none",
1656
- transition: "transform 0.1s"
1657
- }, children: "\u25B6" })
1658
- ]
1659
- }
1660
- ),
1661
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: {
1662
- marginTop: "6px",
1663
- color: "#52525b",
1664
- whiteSpace: "pre-wrap",
1665
- lineHeight: "1.4",
1666
- fontStyle: "italic"
1667
- }, children: text })
1630
+ const finalSeconds = fixedSeconds ?? seconds;
1631
+ const label = isComplete ? finalSeconds !== null && finalSeconds !== void 0 ? `Thought for ${finalSeconds}s` : "Thought process" : `Thinking${seconds ? ` \xB7 ${seconds}s` : "\u2026"}`;
1632
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("hsk-cb-think", !isComplete && "hsk-cb-think--live"), children: [
1633
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "hsk-cb-think-head", onClick: () => setIsOpen((o) => !o), "aria-expanded": isOpen, children: [
1634
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
1635
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
1636
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M12 6v6l4 2" })
1637
+ ] }),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label }),
1639
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cn("hsk-cb-think-chevron", isOpen && "hsk-cb-think-chevron--open"), children: "\u25B6" })
1640
+ ] }),
1641
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-think-body", children: text })
1668
1642
  ] });
1669
1643
  }
1670
1644
  function ChatModal({
@@ -1684,7 +1658,7 @@ function ChatModal({
1684
1658
  visionCategoryHint
1685
1659
  }) {
1686
1660
  const client = (0, import_sdk6.useAkropolysContext)();
1687
- const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, continueGenerating, reset, referencedIds } = (0, import_sdk5.useKiku)();
1661
+ const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = (0, import_sdk5.useKiku)();
1688
1662
  const [input, setInput] = (0, import_react5.useState)("");
1689
1663
  const [shopperName, setShopperNameState] = (0, import_react5.useState)(() => {
1690
1664
  try {
@@ -1774,6 +1748,15 @@ function ChatModal({
1774
1748
  const [keyPhase, setKeyPhase] = (0, import_react5.useState)("idle");
1775
1749
  const [mintedKey, setMintedKey] = (0, import_react5.useState)(null);
1776
1750
  const [mintedPub, setMintedPub] = (0, import_react5.useState)(null);
1751
+ const [copied, setCopied] = (0, import_react5.useState)(null);
1752
+ const copyValue = (value, which) => {
1753
+ try {
1754
+ navigator.clipboard?.writeText(value);
1755
+ } catch {
1756
+ }
1757
+ setCopied(which);
1758
+ setTimeout(() => setCopied((c) => c === which ? null : c), 1600);
1759
+ };
1777
1760
  const [keyCountdown, setKeyCountdown] = (0, import_react5.useState)(KIKU_KEY_REVEAL_SECONDS);
1778
1761
  const [minting, setMinting] = (0, import_react5.useState)(false);
1779
1762
  const [showKikuPicker, setShowKikuPicker] = (0, import_react5.useState)(false);
@@ -2046,21 +2029,29 @@ function ChatModal({
2046
2029
  ] }),
2047
2030
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
2048
2031
  displayMessages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-empty", children: [
2049
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-logo", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 100 100", className: "hsk-brand-mark", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z", transform: "translate(22.7 19) scale(0.62)", fillRule: "evenodd" }) }) }),
2050
2032
  awaitingName ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2051
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-title hsk-cb-onboard-title", children: "My name is Kiku" }),
2052
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-sub", children: "Ask me to search, visualize, or capture anything for you \u2014 on this site or any other." }),
2053
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-onboard-ask", children: "What should I call you?" }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-onboard-skip", onClick: () => setNameSkipped(true), children: "Skip" })
2033
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("h2", { className: "hsk-cb-hello", children: [
2034
+ "Hi, I'm ",
2035
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("b", { children: "kiku" }),
2036
+ "."
2037
+ ] }),
2038
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-hello-lead", children: "I can search, visualize, or capture anything for you \u2014 on this site or any other." }),
2039
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-hello-ask", children: "What should I call you?" }),
2040
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-hello-skip", onClick: () => setNameSkipped(true), children: "Skip for now" })
2055
2041
  ] }) : shopperName ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2056
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-empty-title", children: [
2057
- "Hey, ",
2058
- shopperName
2042
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("h2", { className: "hsk-cb-hello", children: [
2043
+ "Hi, ",
2044
+ shopperName,
2045
+ "."
2059
2046
  ] }),
2060
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-sub", children: "What can I find for you today?" })
2047
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-hello-lead", children: "What can I find for you today?" })
2061
2048
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2062
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-title", children: "Hey, I'm kiku" }),
2063
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-empty-sub", children: "Ask me to search, visualize, or capture anything \u2014 I look across the whole site in real time." })
2049
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("h2", { className: "hsk-cb-hello", children: [
2050
+ "Hi, I'm ",
2051
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("b", { children: "kiku" }),
2052
+ "."
2053
+ ] }),
2054
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-hello-lead", children: "Ask me to search, visualize, or capture anything \u2014 I look across the whole site in real time." })
2064
2055
  ] }),
2065
2056
  !awaitingName && activeChips.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2066
2057
  "button",
@@ -2089,9 +2080,12 @@ function ChatModal({
2089
2080
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparkleIcon2, {}) }),
2090
2081
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-body", children: [
2091
2082
  (() => {
2092
- const { thinking, content, isComplete } = parseThinking(displayContent);
2083
+ const parsed = parseThinking(displayContent);
2084
+ const thinking = msg.thinking || parsed.thinking;
2085
+ const content = parsed.content;
2086
+ const isComplete = msg.thinking ? content.length > 0 || !(isLast && streaming) : parsed.isComplete;
2093
2087
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2094
- thinking && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThinkingBlock, { text: thinking, isComplete }),
2088
+ thinking && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThinkingBlock, { text: thinking, isComplete, seconds: msg.thoughtForSeconds }),
2095
2089
  content && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-ai-text", children: [
2096
2090
  renderMarkdown(content, isLast && streaming),
2097
2091
  isLast && streaming && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { display: "inline-block", width: "0.5em", height: "1.05em", marginLeft: "2px", verticalAlign: "text-bottom", background: "currentColor", opacity: 0.55, borderRadius: "1px" } })
@@ -2184,8 +2178,21 @@ function ChatModal({
2184
2178
  ] }),
2185
2179
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-thinking-text", children: "Thinking\u2026" })
2186
2180
  ] }),
2187
- stopped && !loading && !streaming && messages[messages.length - 1]?.role === "assistant" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-stopped", children: [
2188
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-stopped-label", children: "You stopped this response." }),
2181
+ lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2182
+ "a",
2183
+ {
2184
+ className: "hsk-cb-memory-pill",
2185
+ href: String(lastAction.url),
2186
+ target: "_blank",
2187
+ rel: "noopener noreferrer",
2188
+ children: [
2189
+ "Open my memory on mimi",
2190
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ExternalIcon, {})
2191
+ ]
2192
+ }
2193
+ ),
2194
+ (stopped || interrupted) && !loading && !streaming && messages[messages.length - 1]?.role === "assistant" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-stopped", children: [
2195
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hsk-cb-stopped-label", children: stopped ? "You stopped this response." : "This response was interrupted." }),
2189
2196
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { className: "hsk-cb-continue", onClick: continueGenerating, children: [
2190
2197
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContinueIcon, {}),
2191
2198
  "Continue generating"
@@ -2221,12 +2228,7 @@ function ChatModal({
2221
2228
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your secret \u2014 shown only once" }),
2222
2229
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children: mintedKey }),
2223
2230
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
2224
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => {
2225
- try {
2226
- navigator.clipboard?.writeText(mintedKey);
2227
- } catch {
2228
- }
2229
- }, children: "Copy secret" }),
2231
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedKey, "secret"), children: copied === "secret" ? "Copied" : "Copy secret" }),
2230
2232
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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." })
2231
2233
  ] })
2232
2234
  ] }),
@@ -2234,12 +2236,7 @@ function ChatModal({
2234
2236
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your public id" }),
2235
2237
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { style: { display: "block", fontSize: 13, fontWeight: 600, marginBottom: 6, wordBreak: "break-all", opacity: 0.85 }, children: mintedPub }),
2236
2238
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
2237
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => {
2238
- try {
2239
- navigator.clipboard?.writeText(mintedPub);
2240
- } catch {
2241
- }
2242
- }, children: "Copy id" }),
2239
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedPub, "pub"), children: copied === "pub" ? "Copied" : "Copy id" }),
2243
2240
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Paste this on any site to keep saving to the same memory." })
2244
2241
  ] })
2245
2242
  ] }),