opencami 1.6.0 → 1.7.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/README.md +48 -31
- package/dist/client/assets/{CSPContext-Bq8j4nl9.js → CSPContext-a-MQmQQt.js} +1 -1
- package/dist/client/assets/{DirectionContext-BdX86BHP.js → DirectionContext-DRcND-Cm.js} +1 -1
- package/dist/client/assets/_sessionKey-BAmpzUOP.js +23 -0
- package/dist/client/assets/agents-BkeWu_3a.js +2 -0
- package/dist/client/assets/{agents-screen-DwIY8hze.js → agents-screen-Cb76bcxn.js} +1 -1
- package/dist/client/assets/bots-CyJwr-JU.js +2 -0
- package/dist/client/assets/{bots-screen-c78I920d.js → bots-screen-CzNjLsQH.js} +1 -1
- package/dist/client/assets/{button-Dg7VFQQn.js → button-DNC5N25i.js} +1 -1
- package/dist/client/assets/{composite-DBl8R3ae.js → composite-Bliqcmg4.js} +1 -1
- package/dist/client/assets/{connect-NYvOqiBJ.js → connect-BX1MWO82.js} +1 -1
- package/dist/client/assets/{file-explorer-screen-BSMbs0vi.js → file-explorer-screen-CpY1O_ag.js} +1 -1
- package/dist/client/assets/files-HiN5rXWq.js +2 -0
- package/dist/client/assets/{index-CMATW8VA.js → index-BlC2sH55.js} +1 -1
- package/dist/client/assets/{index-rOIRO-8E.js → index-Dg0mbvtv.js} +1 -1
- package/dist/client/assets/{keyboard-shortcuts-dialog-BTGWdJMl.js → keyboard-shortcuts-dialog-C2Hq19LN.js} +1 -1
- package/dist/client/assets/{main-B_dlfHME.js → main-CEuT8-Qi.js} +14 -5
- package/dist/client/assets/{markdown-BVzT7z4x.js → markdown-DKD6ZLRJ.js} +1 -1
- package/dist/client/assets/memory-lhzf-8Q4.js +2 -0
- package/dist/client/assets/{memory-screen-C-Z9o31m.js → memory-screen-Zq9qfnJK.js} +1 -1
- package/dist/client/assets/{menu-DHNgWk_8.js → menu-47ooFeSm.js} +1 -1
- package/dist/client/assets/{opencami-logo-BQQETnJG.js → opencami-logo-DA69yVKc.js} +1 -1
- package/dist/client/assets/{owner-CpRnf1fI.js → owner-CFRNz_Tp.js} +1 -1
- package/dist/client/assets/{popupStateMapping-BRPDXnjv.js → popupStateMapping-D5k-jOeY.js} +1 -1
- package/dist/client/assets/{proxy-BcUh9kMA.js → proxy-Cawf6X0W.js} +1 -1
- package/dist/client/assets/{react-irH8OzhB.js → react-K9goXsVv.js} +1 -1
- package/dist/client/assets/{search-dialog-B96zx_ng.js → search-dialog-C5Yae9rb.js} +1 -1
- package/dist/client/assets/{session-export-dialog-DPuHnhgv.js → session-export-dialog-CBeTfbll.js} +1 -1
- package/dist/client/assets/settings-dialog-CoeG9M1b.js +1 -0
- package/dist/client/assets/skills-BEkw619A.js +2 -0
- package/dist/client/assets/{skills-panel-WDUfIwnI.js → skills-panel-DFL-3BRH.js} +1 -1
- package/dist/client/assets/styles-D4EBtWYc.css +1 -0
- package/dist/client/assets/{switch-DPocNFRG.js → switch-DAFvLxNX.js} +1 -1
- package/dist/client/assets/{tabs-B0cro1hL.js → tabs-B2Y_7MvG.js} +1 -1
- package/dist/client/assets/{tooltip-Dg9fy-vT.js → tooltip-D57Pal0B.js} +1 -1
- package/dist/client/assets/{use-file-explorer-state-DzT0bksg.js → use-file-explorer-state-DppKEjcl.js} +1 -1
- package/dist/client/assets/{useButton-Cbl_9oFG.js → useButton-DVAfkehQ.js} +1 -1
- package/dist/client/assets/{useCompositeItem-BDAzTxVe.js → useCompositeItem-CzdGhGcj.js} +1 -1
- package/dist/client/assets/{useControlled-Dscz_s4f.js → useControlled-Cl9XA2_f.js} +1 -1
- package/dist/client/assets/{useMutation-B1FlDsNN.js → useMutation-C5bTdeC1.js} +1 -1
- package/dist/client/assets/{visuallyHidden-ONmQ-0U2.js → visuallyHidden-CO3ZD5AQ.js} +1 -1
- package/dist/server/assets/{_sessionKey-B0ZlLAjH.js → _sessionKey-BBG3ZUlo.js} +279 -27
- package/dist/server/assets/{_tanstack-start-manifest_v-D5UVTs1o.js → _tanstack-start-manifest_v-DmMFarHb.js} +1 -1
- package/dist/server/assets/{index-CiUjUD0t.js → index-BgMPaOsU.js} +1 -1
- package/dist/server/assets/{router-Uuagl6O7.js → router-Bl2uabfY.js} +38 -9
- package/dist/server/assets/{search-dialog-DZTS5SEi.js → search-dialog-BtSQW9SR.js} +2 -2
- package/dist/server/assets/{settings-dialog-CSYDj2qm.js → settings-dialog-D3fOAswX.js} +11 -4
- package/dist/server/server.js +2 -2
- package/package.json +1 -1
- package/dist/client/assets/_sessionKey-DsjnpErt.js +0 -14
- package/dist/client/assets/agents-DwxKcpP6.js +0 -2
- package/dist/client/assets/bots-CRlm-3-d.js +0 -2
- package/dist/client/assets/files-BJbMx0_w.js +0 -2
- package/dist/client/assets/memory-S3Yws6a5.js +0 -2
- package/dist/client/assets/settings-dialog-DZcRCaPj.js +0 -1
- package/dist/client/assets/skills-YZe3I63y.js +0 -2
- package/dist/client/assets/styles-Bwo-K6Y4.css +0 -1
package/README.md
CHANGED
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
A beautiful web client for [OpenClaw](https://github.com/openclaw/openclaw).
|
|
6
6
|
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g opencami
|
|
9
|
-
opencami
|
|
10
|
-
```
|
|
11
|
-
|
|
12
7
|
[](https://www.npmjs.com/package/opencami)
|
|
13
8
|
[](LICENSE)
|
|
14
9
|
|
|
@@ -16,14 +11,18 @@ opencami
|
|
|
16
11
|
|
|
17
12
|
## Quick Start
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
```bash
|
|
15
|
+
curl -fsSL https://opencami.xyz/install.sh | bash
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or via npm:
|
|
20
19
|
|
|
21
20
|
```bash
|
|
22
21
|
npm install -g opencami
|
|
23
22
|
opencami
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Opens your browser to the chat interface.
|
|
27
26
|
|
|
28
27
|
### Options
|
|
29
28
|
|
|
@@ -43,30 +42,48 @@ docker run -p 3000:3000 opencami
|
|
|
43
42
|
|
|
44
43
|
## Features
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
45
|
+
### 💬 Chat & Communication
|
|
46
|
+
- ⚡ **Real-time streaming** — persistent WebSocket + SSE, token-by-token
|
|
47
|
+
- 🖼️ **Image attachments** — drag & drop with compression
|
|
48
|
+
- 🔊 **Voice playback (TTS)** — ElevenLabs → OpenAI → Edge TTS fallback
|
|
49
|
+
- 🎤 **Voice input (STT)** — ElevenLabs Scribe → OpenAI Whisper → Browser
|
|
50
|
+
- 🔔 **Browser notifications** — background tab alerts when assistant replies
|
|
51
|
+
|
|
52
|
+
### 🧠 Smart Features
|
|
53
|
+
- 🏷️ **Smart titles** — LLM-generated session titles
|
|
54
|
+
- 💡 **Smart follow-ups** — contextual suggestions after each response
|
|
55
|
+
- 🧠 **Thinking level toggle** — reasoning depth (off/low/medium/high) per message
|
|
56
|
+
- 🔎 **Search sources badge** — see which search engines were used
|
|
57
|
+
- 📊 **Context window meter** — visual token usage indicator
|
|
58
|
+
|
|
59
|
+
### 🔧 Workspace
|
|
60
|
+
- 📂 **File explorer** — browse & edit 30+ file types with built-in editor
|
|
61
|
+
- 🧠 **Memory viewer** — browse and edit MEMORY.md and daily memory files
|
|
62
|
+
- 🤖 **Agent manager** — create, edit, delete agents from the sidebar
|
|
63
|
+
- 🧩 **Skills browser** — discover and install skills from ClawHub
|
|
64
|
+
- ⏰ **Cron jobs panel** — manage scheduled automations
|
|
65
|
+
- 🔧 **Workspace settings** — toggle each tool on/off in Settings
|
|
66
|
+
|
|
67
|
+
### 🎨 Customization
|
|
68
|
+
- 🎨 **Model selector** — switch AI models per message
|
|
69
|
+
- 🎭 **Persona picker** — 20 AI personalities
|
|
70
|
+
- 🦎 **Chameleon theme** — light/dark/system with accent colors
|
|
71
|
+
- 🔤 **Text size** — S / M / L / XL
|
|
72
|
+
- 🔌 **Multi-provider LLM** — OpenAI, OpenRouter, Ollama, or custom
|
|
73
|
+
|
|
74
|
+
### 📁 Organization
|
|
75
|
+
- 📁 **Session folders** — grouped by kind (chats, subagents, cron, other)
|
|
76
|
+
- 📌 **Pin sessions** — pinned always on top
|
|
77
|
+
- 🗑️ **Bulk delete** — select multiple sessions, delete at once
|
|
78
|
+
- 🛡️ **Protected sessions** — prevent accidental deletion
|
|
79
|
+
- 📥 **Export** — Markdown, JSON, or plain text
|
|
80
|
+
|
|
81
|
+
### 📱 Platform
|
|
82
|
+
- 📱 **PWA** — installable, offline shell, auto-update
|
|
83
|
+
- 🖥️ **Tauri desktop app** (Beta) — native wrapper for macOS/Windows/Linux
|
|
84
|
+
- ⌨️ **Keyboard shortcuts** — full power-user navigation
|
|
85
|
+
- 💬 **Slash commands** — inline help and actions
|
|
86
|
+
- 🔍 **Conversation search** — current (⌘F) and global (⌘⇧F)
|
|
70
87
|
|
|
71
88
|
## Development
|
|
72
89
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t}from"./main-
|
|
1
|
+
import{r as t}from"./main-CEuT8-Qi.js";const e=t.createContext(void 0),o={disableStyleElements:!1};function s(){return t.useContext(e)??o}export{s as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as l}from"./main-
|
|
1
|
+
import{r as l}from"./main-CEuT8-Qi.js";const E=["top","right","bottom","left"],p=Math.min,h=Math.max,L=Math.round,k=Math.floor,q=t=>({x:t,y:t}),x={left:"right",right:"left",bottom:"top",top:"bottom"},d={start:"end",end:"start"};function R(t,e,n){return h(t,p(e,n))}function T(t,e){return typeof t=="function"?t(e):t}function m(t){return t.split("-")[0]}function g(t){return t.split("-")[1]}function b(t){return t==="x"?"y":"x"}function A(t){return t==="y"?"height":"width"}const P=new Set(["top","bottom"]);function y(t){return P.has(m(t))?"y":"x"}function M(t){return b(y(t))}function v(t,e,n){n===void 0&&(n=!1);const s=g(t),i=M(t),o=A(i);let r=i==="x"?s===(n?"end":"start")?"right":"left":s==="start"?"bottom":"top";return e.reference[o]>e.floating[o]&&(r=a(r)),[r,a(r)]}function z(t){const e=a(t);return[c(t),e,c(e)]}function c(t){return t.replace(/start|end/g,e=>d[e])}const u=["left","right"],f=["right","left"],O=["top","bottom"],S=["bottom","top"];function C(t,e,n){switch(t){case"top":case"bottom":return n?e?f:u:e?u:f;case"left":case"right":return e?O:S;default:return[]}}function B(t,e,n,s){const i=g(t);let o=C(m(t),n==="start",s);return i&&(o=o.map(r=>r+"-"+i),e&&(o=o.concat(o.map(c)))),o}function a(t){return t.replace(/left|right|bottom|top/g,e=>x[e])}function w(t){return{top:0,right:0,bottom:0,left:0,...t}}function F(t){return typeof t!="number"?w(t):{top:t,right:t,bottom:t,left:t}}function G(t){const{x:e,y:n,width:s,height:i}=t;return{width:s,height:i,top:n,left:e,right:e+s,bottom:n+i,x:e,y:n}}const j=l.createContext(void 0);function H(){return l.useContext(j)?.direction??"ltr"}export{y as a,a as b,z as c,B as d,T as e,k as f,m as g,v as h,g as i,h as j,M as k,F as l,p as m,G as n,A as o,R as p,b as q,L as r,E as s,q as t,H as u};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/settings-dialog-CoeG9M1b.js","assets/main-CEuT8-Qi.js","assets/button-DNC5N25i.js","assets/use-file-explorer-state-DppKEjcl.js","assets/useButton-DVAfkehQ.js","assets/owner-CFRNz_Tp.js","assets/popupStateMapping-D5k-jOeY.js","assets/visuallyHidden-CO3ZD5AQ.js","assets/composite-Bliqcmg4.js","assets/react-K9goXsVv.js","assets/switch-DAFvLxNX.js","assets/useControlled-Cl9XA2_f.js","assets/tabs-B2Y_7MvG.js","assets/useCompositeItem-CzdGhGcj.js","assets/DirectionContext-DRcND-Cm.js","assets/CSPContext-a-MQmQQt.js","assets/index-BlC2sH55.js","assets/tooltip-D57Pal0B.js","assets/menu-47ooFeSm.js","assets/useMutation-C5bTdeC1.js","assets/opencami-logo-DA69yVKc.js","assets/proxy-Cawf6X0W.js","assets/markdown-DKD6ZLRJ.js","assets/index-T4TOjvD0.js","assets/session-export-dialog-CBeTfbll.js","assets/keyboard-shortcuts-dialog-C2Hq19LN.js","assets/search-dialog-C5Yae9rb.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{j as n,r as o,L as qe,u as ct,_ as Kt,d as zt,w as Jr,a as Qr,z as Zr}from"./main-CEuT8-Qi.js";import{u as Mt}from"./visuallyHidden-CO3ZD5AQ.js";import{T as De,a as Le,b as Pe,c as _e,s as Fe,d as es,g as Nn}from"./tooltip-D57Pal0B.js";import{B as xe,u as ts,c as M,ac as fn,ag as Be,t as ns,H as B,J as Qn,V as Ut,aj as rs,ak as ss,al as os,a as Zn,am as is,C as as,an as ls,M as mn,b as st,I as cs,ao as us,a3 as ds,s as rn,ap as fs,G as ms,l as er,L as ps,O as hs,X as pn,x as gs,h as xs,aq as tr,ar as ys,Y as hn,p as nr,n as rr,as as Yt,at as En,au as ws,av as bs,aw as Ss}from"./button-DNC5N25i.js";import{D as vs,a as js,b as ks,c as Cs,d as Ns,j as Es,k as Ts,l as Rs,m as Ms,n as As,o as Is,p as Os,q as Ds,r as Ls,s as sr,u as Ps}from"./use-file-explorer-state-DppKEjcl.js";import{d as or,a as We,g as ir,t as _s,u as Re,f as Ks,n as zs}from"./useButton-DVAfkehQ.js";import{u as Us}from"./useControlled-Cl9XA2_f.js";import{_ as $s,$ as Hs,a0 as Tn,t as ar,u as Fs,V as Ce,e as Ws,a as At}from"./popupStateMapping-D5k-jOeY.js";import{u as Xs,e as Ys,q as Bs}from"./owner-CFRNz_Tp.js";import{u as Gs}from"./CSPContext-a-MQmQQt.js";import{u as lr}from"./DirectionContext-DRcND-Cm.js";import{M as $t,a as Ht,b as Ft,c as Xe}from"./menu-47ooFeSm.js";import{u as cr}from"./useMutation-C5bTdeC1.js";import{O as qs,a as Vs}from"./opencami-logo-DA69yVKc.js";import{m as be,A as Oe}from"./proxy-Cawf6X0W.js";import{M as Js}from"./markdown-DKD6ZLRJ.js";import{u as Qs,p as ur}from"./index-BlC2sH55.js";import{c as dr}from"./react-K9goXsVv.js";function sn(e){if(!e)return"main";const t=e.trim();if(t.length===0)return"main";const r=t.split(":"),a=(r[r.length-1]??"").trim();return a.length>0?a:t}function Me(e){return(Array.isArray(e.content)?e.content:[]).map(r=>r.type==="text"?String(r.text??""):"").join("").trim()}function Je(e){return(Array.isArray(e.content)?e.content:[]).filter(r=>r.type==="toolCall")}function Zs(e){if(typeof e=="number"&&Number.isFinite(e))return e<1e12?e*1e3:e;if(typeof e=="string"){const t=Date.parse(e);if(!Number.isNaN(t))return t}return null}function on(e){const t=[e.createdAt,e.created_at,e.timestamp,e.time,e.ts];for(const r of t){const s=Zs(r);if(s)return s}return Date.now()}const eo=["agent:main:main","main"];function an(e){return eo.includes(e)}const to=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function no(e){if(e.includes(":subagent:")||e.startsWith("agent:codex:")||e.includes(":openai:"))return"subagent";if(e.startsWith("isolated:")||e.includes(":cron:"))return"cron";if(e.startsWith("agent:")&&!e.startsWith("agent:main:"))return"other";if(e.startsWith("agent:main:")){const t=e.slice(11);return to.test(t)?"webchat":"chat"}return"other"}function ro(e){return Array.isArray(e)?e.map(t=>{const r=typeof t.key=="string"&&t.key.trim().length>0?t.key.trim():sn(t.friendlyId??t.key),s=typeof t.friendlyId=="string"&&t.friendlyId.trim().length>0?t.friendlyId.trim():sn(r),a=no(r),i=t,l=typeof i.totalTokens=="number"?i.totalTokens:void 0,c=typeof i.contextTokens=="number"?i.contextTokens:void 0,u=typeof i.status=="string"?i.status:void 0;return{key:r,friendlyId:s,title:typeof t.title=="string"?t.title:void 0,derivedTitle:typeof t.derivedTitle=="string"?t.derivedTitle:void 0,label:typeof t.label=="string"?t.label:void 0,updatedAt:typeof t.updatedAt=="number"?t.updatedAt:void 0,lastMessage:t.lastMessage??null,kind:a,status:u,totalTokens:l,contextTokens:c}}):[]}async function Ke(e){try{const t=await e.json();return t?.error?String(t.error):t?.message?String(t.message):JSON.stringify(t)}catch{try{return await e.text()}catch{return e.statusText||"Request failed"}}}const so="Missing gateway auth. Set CLAWDBOT_GATEWAY_TOKEN (recommended) or CLAWDBOT_GATEWAY_PASSWORD in the server environment.";function Rn(e){return e.includes(so)}function Mn(e,t){const r=crypto.randomUUID(),s=`opt-${r}`,a=Date.now(),i=[];if(t&&t.length>0)for(const c of t)c.type==="image"&&c.base64&&i.push({type:"image",source:{type:"base64",media_type:c.file.type,data:c.base64}});return e.trim()?i.push({type:"text",text:e}):t&&t.length>0&&i.push({type:"text",text:""}),{clientId:r,optimisticId:s,optimisticMessage:{role:"user",content:i,__optimisticId:s,clientId:r,status:"sending",timestamp:a}}}const ce={sessions:["chat","sessions"],history:function(t,r){return["chat","history",t,r]}};async function oo(){const e=await fetch("/api/sessions");if(!e.ok)throw new Error(await Ke(e));const t=await e.json();return ro(t.sessions)}async function io(e){const t=new URLSearchParams({limit:"200"});e.sessionKey&&t.set("sessionKey",e.sessionKey),e.friendlyId&&t.set("friendlyId",e.friendlyId);const r=await fetch(`/api/history?${t.toString()}`);if(!r.ok)throw new Error(await Ke(r));return await r.json()}async function ao(){const e=new AbortController,t=window.setTimeout(()=>e.abort(),2500);try{const r=await fetch("/api/ping",{signal:e.signal});if(!r.ok)throw new Error(await Ke(r));return await r.json()}catch(r){throw r instanceof DOMException&&r.name==="AbortError"?new Error("Gateway check timed out"):r}finally{window.clearTimeout(t)}}function gn(e,t,r,s){const a=ce.history(t,r);e.setQueryData(a,function(l){const c=l,u=Array.isArray(c?.messages)?c.messages:[],d=s(u);return{sessionKey:c?.sessionKey??r,sessionId:c?.sessionId,messages:d}})}function Bt(e,t,r,s){gn(e,t,r,function(i){return[...i,s]})}function lo(e,t,r,s,a){const i=`opt-${s}`;gn(e,t,r,function(c){return c.map(u=>u.clientId===s||u.__optimisticId===s||u.__optimisticId===i?a(u):u)})}function co(e,t,r,s,a){gn(e,t,r,function(l){return l.filter(c=>!(c.clientId===s||c.__optimisticId===s||a&&c.__optimisticId===a))})}function ln(e,t,r){const s=ce.history(t,r);e.setQueryData(s,{sessionKey:r,messages:[]})}function uo(e,t,r,s,a){const i=ce.history(t,r),l=ce.history(s,a),c=e.getQueryData(i);if(!c)return;const u=Array.isArray(c.messages)?c.messages:[];e.setQueryData(l,{sessionKey:a,sessionId:c.sessionId,messages:u}),e.removeQueries({queryKey:i,exact:!0})}function fo(e,t,r,s){e.setQueryData(ce.sessions,function(i){return Array.isArray(i)?i.map(l=>l.key!==t&&l.friendlyId!==r?l:{...l,lastMessage:s}):i})}function mo(e,t,r){e.setQueryData(ce.sessions,function(a){return Array.isArray(a)?a.filter(i=>i.key!==t&&i.friendlyId!==r):a}),e.removeQueries({queryKey:["chat","history",r],exact:!1}),t&&t!==r&&e.removeQueries({queryKey:["chat","history",t],exact:!1})}async function po(e,t,r,s){e.setQueryData(ce.sessions,function(i){return Array.isArray(i)?i.map(l=>l.key===t||l.friendlyId===r?{...l,label:s}:l):i});try{const a=await fetch("/api/sessions",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionKey:t,friendlyId:r,label:s})});if(!a.ok){const i=await Ke(a);console.error("[updateSessionLabel] Failed to persist:",i)}}catch(a){console.error("[updateSessionLabel] Network error:",a)}}function fr(e){return!e.content||!Array.isArray(e.content)?"":e.content.filter(t=>t.type==="text").map(t=>t.text||"").join(`
|
|
3
|
+
`)}function ho(e,t,r){const s=[];s.push(`# Conversation: ${e}`),s.push(`Date: ${r.toLocaleString()}`),s.push("");for(const a of t){const i=a.role||"unknown",l=fr(a);if(l){const c=i==="user"?"User":"Assistant";s.push(`## ${c}`),s.push(""),s.push(l),s.push("")}}return s.join(`
|
|
4
|
+
`)}function go(e,t,r){const s={title:e,exportDate:r.toISOString(),messages:t.map(a=>({role:a.role,content:a.content,timestamp:a.timestamp}))};return JSON.stringify(s,null,2)}function xo(e,t,r){const s=[];s.push(`Conversation: ${e}`),s.push(`Date: ${r.toLocaleString()}`),s.push("─".repeat(60)),s.push("");for(const a of t){const i=a.role||"unknown",l=fr(a);if(l){const c=i==="user"?"User":"Assistant";s.push(`${c}:`),s.push(l),s.push("")}}return s.join(`
|
|
5
|
+
`)}function yo(e,t,r){const s=new Date;let a,i,l;switch(r){case"markdown":a=ho(e,t,s),i=`${Gt(e)}.md`,l="text/markdown";break;case"json":a=go(e,t,s),i=`${Gt(e)}.json`,l="application/json";break;case"txt":a=xo(e,t,s),i=`${Gt(e)}.txt`,l="text/plain";break;default:throw new Error(`Unsupported format: ${r}`)}wo(a,i,l)}function Gt(e){return e.replace(/[^a-z0-9-_\s]/gi,"").replace(/\s+/g,"-").toLowerCase().slice(0,50)||"conversation"}function wo(e,t,r){const s=new Blob([e],{type:r}),a=URL.createObjectURL(s),i=document.createElement("a");i.href=a,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a)}function bo({open:e,onOpenChange:t,sessionTitle:r,onSave:s,onCancel:a}){return n.jsx(vs,{open:e,onOpenChange:t,children:n.jsx(js,{children:n.jsxs("div",{className:"p-4",children:[n.jsx(ks,{className:"mb-1",children:"Rename"}),n.jsx(Cs,{className:"mb-4",children:"Enter a new name for this session."}),n.jsx("input",{type:"text",defaultValue:r,onKeyDown:i=>{i.key==="Enter"&&(i.preventDefault(),s(i.currentTarget.value))},className:"w-full rounded-lg border border-primary-200 bg-primary-50 px-3 py-2 text-sm text-primary-900 outline-none focus:border-primary-400",placeholder:"Session name",autoFocus:!0}),n.jsxs("div",{className:"mt-4 flex justify-end gap-2",children:[n.jsx(Ns,{onClick:a,children:"Cancel"}),n.jsx(xe,{onClick:i=>{const l=i.currentTarget.parentElement?.previousElementSibling;s(l.value)},children:"Save"})]})]})})})}function So(e){const{children:t,open:r,defaultOpen:s=!1,onOpenChange:a,onOpenChangeComplete:i,actionsRef:l,handle:c,triggerId:u,defaultTriggerId:d=null}=e,f=Es(),p=!!f,m=ts(()=>c?.store??new Ts({open:r??s,activeTriggerId:u!==void 0?u:d,modal:!0,disablePointerDismissal:!0,nested:p,role:"alertdialog"})).current;m.useControlledProp("open",r,s),m.useControlledProp("activeTriggerId",u,d),m.useSyncedValue("nested",p),m.useContextCallback("onOpenChange",a),m.useContextCallback("onOpenChangeComplete",i);const h=m.useState("payload");Rs({store:m,actionsRef:l,parentContext:f?.store.context});const w=o.useMemo(()=>({store:m}),[m]);return n.jsx(Ms.Provider,{value:w,children:typeof t=="function"?t({payload:h}):t})}function vo({children:e,...t}){return n.jsx(So,{...t,children:e})}function jo({className:e,children:t}){return n.jsxs(As,{children:[n.jsx(Is,{className:"fixed inset-0 bg-primary-950/20 transition-all duration-150 data-[state=open]:opacity-100 data-[state=closed]:opacity-0"}),n.jsx(Os,{className:M("fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2","w-[min(400px,92vw)] rounded-xl border border-primary-200 bg-primary-50 p-0 shadow-xl","transition-all duration-150","data-[state=open]:opacity-100 data-[state=closed]:opacity-0","data-[state=open]:scale-100 data-[state=closed]:scale-95",e),children:t})]})}function ko({className:e,...t}){return n.jsx(Ds,{className:M("text-lg font-medium text-primary-900",e),...t})}function Co({className:e,...t}){return n.jsx(Ls,{className:M("text-sm text-primary-600",e),...t})}function No({className:e,...t}){return n.jsx(sr,{render:n.jsx(xe,{variant:"outline",className:M(e)}),...t})}function Eo({className:e,...t}){return n.jsx(sr,{render:n.jsx(xe,{variant:"destructive",className:M(e)}),...t})}function To({open:e,onOpenChange:t,sessionTitle:r,onConfirm:s,onCancel:a}){return n.jsx(vo,{open:e,onOpenChange:t,children:n.jsx(jo,{children:n.jsxs("div",{className:"p-4",children:[n.jsx(ko,{className:"mb-1",children:"Delete Session"}),n.jsxs(Co,{className:"mb-4",children:['Are you sure you want to delete "',r,'"? This action cannot be undone.']}),n.jsxs("div",{className:"flex justify-end gap-2",children:[n.jsx(No,{onClick:a,children:"Cancel"}),n.jsx(Eo,{onClick:s,children:"Delete"})]})]})})})}function Ro(e){const{open:t,defaultOpen:r,onOpenChange:s,disabled:a}=e,i=t!==void 0,[l,c]=Us({controlled:t,default:r,name:"Collapsible",state:"open"}),{mounted:u,setMounted:d,transitionStatus:f}=$s(l,!0,!0),[p,m]=o.useState(l),[{height:h,width:w},g]=o.useState({height:void 0,width:void 0}),j=or(),[k,y]=o.useState(),_=k??j,[R,H]=o.useState(!1),[T,U]=o.useState(!1),q=o.useRef(null),E=o.useRef(null),W=o.useRef(null),F=o.useRef(null),b=Hs(F,!1),A=We(N=>{const C=!l,K=ir(_s,N.nativeEvent);if(s(C,K),K.isCanceled)return;const x=F.current;E.current==="css-animation"&&x!=null&&x.style.removeProperty("animation-name"),!R&&!T&&(E.current!=null&&E.current!=="css-animation"&&!u&&C&&d(!0),E.current==="css-animation"&&(!p&&C&&m(!0),!u&&C&&d(!0))),c(C),E.current==="none"&&u&&!C&&d(!1)});return Re(()=>{i&&E.current==="none"&&!T&&!l&&d(!1)},[i,T,l,t,d]),o.useMemo(()=>({abortControllerRef:q,animationTypeRef:E,disabled:a,handleTrigger:A,height:h,mounted:u,open:l,panelId:_,panelRef:F,runOnceAnimationsFinish:b,setDimensions:g,setHiddenUntilFound:H,setKeepMounted:U,setMounted:d,setOpen:c,setPanelIdState:y,setVisible:m,transitionDimensionRef:W,transitionStatus:f,visible:p,width:w}),[q,E,a,A,h,u,l,_,F,b,g,H,U,d,c,m,W,f,p,w])}const mr=o.createContext(void 0);function pr(){const e=o.useContext(mr);if(e===void 0)throw new Error(fn(15));return e}let gt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=Tn.startingStyle]="startingStyle",e[e.endingStyle=Tn.endingStyle]="endingStyle",e})({}),Mo=(function(e){return e.panelOpen="data-panel-open",e})({});const Ao={[gt.open]:""},Io={[gt.closed]:""},Oo={open(e){return e?{[Mo.panelOpen]:""}:null}},Do={open(e){return e?Ao:Io}},hr={...Do,...ar},Lo=o.forwardRef(function(t,r){const{render:s,className:a,defaultOpen:i=!1,disabled:l=!1,onOpenChange:c,open:u,...d}=t,f=We(c),p=Ro({open:u,defaultOpen:i,onOpenChange:f,disabled:l}),m=o.useMemo(()=>({open:p.open,disabled:p.disabled,transitionStatus:p.transitionStatus}),[p.open,p.disabled,p.transitionStatus]),h=o.useMemo(()=>({...p,onOpenChange:f,state:m}),[p,f,m]),w=Be("div",t,{state:m,ref:r,props:d,stateAttributesMapping:hr});return n.jsx(mr.Provider,{value:h,children:w})}),Po={...Oo,...ar},_o=o.forwardRef(function(t,r){const{panelId:s,open:a,handleTrigger:i,state:l,disabled:c}=pr(),{className:u,disabled:d=c,id:f,render:p,nativeButton:m=!0,...h}=t,{getButtonProps:w,buttonRef:g}=Ks({disabled:d,focusableWhenDisabled:!0,native:m}),j=o.useMemo(()=>({"aria-controls":a?s:void 0,"aria-expanded":a,onClick:i}),[s,a,i]);return Be("button",t,{state:l,ref:[r,g],props:[j,h,w],stateAttributesMapping:Po})});let Ko=(function(e){return e.disabled="data-disabled",e.orientation="data-orientation",e})({});function zo(e){const{abortControllerRef:t,animationTypeRef:r,externalRef:s,height:a,hiddenUntilFound:i,keepMounted:l,id:c,mounted:u,onOpenChange:d,open:f,panelRef:p,runOnceAnimationsFinish:m,setDimensions:h,setMounted:w,setOpen:g,setVisible:j,transitionDimensionRef:k,visible:y,width:_}=e,R=o.useRef(!1),H=o.useRef(null),T=o.useRef(f),U=o.useRef(f),q=Fs(),E=o.useMemo(()=>r.current==="css-animation"?!y:!f&&!u,[f,u,y,r]),W=We(b=>{if(!b)return;if(r.current==null||k.current==null){const C=getComputedStyle(b),K=C.animationName!=="none"&&C.animationName!=="",x=C.transitionDuration!=="0s"&&C.transitionDuration!=="";K&&x||(C.animationName==="none"&&C.transitionDuration!=="0s"?r.current="css-transition":C.animationName!=="none"&&C.transitionDuration==="0s"?r.current="css-animation":r.current="none"),b.getAttribute(Ko.orientation)==="horizontal"||C.transitionProperty.indexOf("width")>-1?k.current="width":k.current="height"}if(r.current!=="css-transition")return;(a===void 0||_===void 0)&&(h({height:b.scrollHeight,width:b.scrollWidth}),U.current&&b.style.setProperty("transition-duration","0s"));let A=-1,N=-1;return A=Ce.request(()=>{U.current=!1,N=Ce.request(()=>{setTimeout(()=>{b.style.removeProperty("transition-duration")})})}),()=>{Ce.cancel(A),Ce.cancel(N)}}),F=ns(s,p,W);return Re(()=>{if(r.current!=="css-transition")return;const b=p.current;if(!b)return;let A=-1;if(t.current!=null&&(t.current.abort(),t.current=null),f){const N={"justify-content":b.style.justifyContent,"align-items":b.style.alignItems,"align-content":b.style.alignContent,"justify-items":b.style.justifyItems};Object.keys(N).forEach(C=>{b.style.setProperty(C,"initial","important")}),!U.current&&!l&&b.setAttribute(gt.startingStyle,""),h({height:b.scrollHeight,width:b.scrollWidth}),A=Ce.request(()=>{Object.entries(N).forEach(([C,K])=>{K===""?b.style.removeProperty(C):b.style.setProperty(C,K)})})}else{if(b.scrollHeight===0&&b.scrollWidth===0)return;h({height:b.scrollHeight,width:b.scrollWidth});const N=new AbortController;t.current=N;const C=N.signal;let K=null;const x=gt.endingStyle;return K=new MutationObserver(L=>{L.some(I=>I.type==="attributes"&&I.attributeName===x)&&(K?.disconnect(),K=null,m(()=>{h({height:0,width:0}),b.style.removeProperty("content-visibility"),w(!1),t.current===N&&(t.current=null)},C))}),K.observe(b,{attributes:!0,attributeFilter:[x]}),()=>{K?.disconnect(),q.cancel(),t.current===N&&(N.abort(),t.current=null)}}return()=>{Ce.cancel(A)}},[t,r,q,i,l,u,f,p,m,h,w]),Re(()=>{if(r.current!=="css-animation")return;const b=p.current;b&&(H.current=b.style.animationName||H.current,b.style.setProperty("animation-name","none"),h({height:b.scrollHeight,width:b.scrollWidth}),!T.current&&!R.current&&b.style.removeProperty("animation-name"),f?(t.current!=null&&(t.current.abort(),t.current=null),w(!0),j(!0)):(t.current=new AbortController,m(()=>{w(!1),j(!1),t.current=null},t.current.signal)))},[t,r,f,p,m,h,w,j,y]),Xs(()=>{const b=Ce.request(()=>{T.current=!1});return()=>Ce.cancel(b)}),Re(()=>{if(!i)return;const b=p.current;if(!b)return;let A=-1,N=-1;return f&&R.current&&(b.style.transitionDuration="0s",h({height:b.scrollHeight,width:b.scrollWidth}),A=Ce.request(()=>{R.current=!1,N=Ce.request(()=>{setTimeout(()=>{b.style.removeProperty("transition-duration")})})})),()=>{Ce.cancel(A),Ce.cancel(N)}},[i,f,p,h]),Re(()=>{const b=p.current;b&&i&&E&&(b.setAttribute("hidden","until-found"),r.current==="css-transition"&&b.setAttribute(gt.startingStyle,""))},[i,E,r,p]),o.useEffect(function(){const A=p.current;if(!A)return;function N(C){R.current=!0,g(!0),d(!0,ir(zs,C))}return A.addEventListener("beforematch",N),()=>{A.removeEventListener("beforematch",N)}},[d,p,g]),o.useMemo(()=>({props:{hidden:E,id:c,ref:F}}),[E,c,F])}let An=(function(e){return e.collapsiblePanelHeight="--collapsible-panel-height",e.collapsiblePanelWidth="--collapsible-panel-width",e})({});const Uo=o.forwardRef(function(t,r){const{className:s,hiddenUntilFound:a,keepMounted:i,render:l,id:c,...u}=t,{abortControllerRef:d,animationTypeRef:f,height:p,mounted:m,onOpenChange:h,open:w,panelId:g,panelRef:j,runOnceAnimationsFinish:k,setDimensions:y,setHiddenUntilFound:_,setKeepMounted:R,setMounted:H,setPanelIdState:T,setOpen:U,setVisible:q,state:E,transitionDimensionRef:W,visible:F,width:b,transitionStatus:A}=pr(),N=a??!1,C=i??!1;Re(()=>{if(c)return T(c),()=>{T(void 0)}},[c,T]),Re(()=>{_(N)},[_,N]),Re(()=>{R(C)},[R,C]);const{props:K}=zo({abortControllerRef:d,animationTypeRef:f,externalRef:r,height:p,hiddenUntilFound:N,id:g,keepMounted:C,mounted:m,onOpenChange:h,open:w,panelRef:j,runOnceAnimationsFinish:k,setDimensions:y,setMounted:H,setOpen:U,setVisible:q,transitionDimensionRef:W,visible:F,width:b});Ws({open:w&&A==="idle",ref:j,onComplete(){w&&y({height:void 0,width:void 0})}});const x=o.useMemo(()=>({...E,transitionStatus:A}),[E,A]),L=Be("div",t,{state:x,ref:[r,j],props:[K,{style:{[An.collapsiblePanelHeight]:p===void 0?"auto":`${p}px`,[An.collapsiblePanelWidth]:b===void 0?"auto":`${b}px`}},u],stateAttributesMapping:hr});return C||N||!C&&m?L:null});function It(e){return n.jsx(Lo,{...e})}function Ot({className:e,...t}){return n.jsx(_o,{className:M("group inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-left text-xs font-medium text-primary-500 transition-colors hover:bg-primary-100 hover:text-primary-700 data-panel-open:text-primary-700",e),...t})}function Dt({className:e,contentClassName:t,children:r,...s}){return n.jsx(Uo,{className:M('flex h-(--collapsible-panel-height) flex-col overflow-hidden text-sm transition-all duration-150 ease-out data-ending-style:h-0 data-starting-style:h-0 [&[hidden]:not([hidden="until-found"])]:hidden',e),...s,children:n.jsx("div",{className:M("pt-1",t),children:r})})}const gr=o.createContext(void 0);function Wt(){const e=o.useContext(gr);if(e===void 0)throw new Error(fn(53));return e}let Lt=(function(e){return e.scrollAreaCornerHeight="--scroll-area-corner-height",e.scrollAreaCornerWidth="--scroll-area-corner-width",e})({});const jt=500,In=16;function Ne(e,t,r){if(!e)return 0;const s=getComputedStyle(e),a=r==="x"?"Inline":"Block";return r==="x"&&t==="margin"?parseFloat(s[`${t}InlineStart`])*2:parseFloat(s[`${t}${a}Start`])+parseFloat(s[`${t}${a}End`])}let $o=(function(e){return e.orientation="data-orientation",e.hovering="data-hovering",e.scrolling="data-scrolling",e.hasOverflowX="data-has-overflow-x",e.hasOverflowY="data-has-overflow-y",e.overflowXStart="data-overflow-x-start",e.overflowXEnd="data-overflow-x-end",e.overflowYStart="data-overflow-y-start",e.overflowYEnd="data-overflow-y-end",e})({});const kt="base-ui-disable-scrollbar",xr={className:kt,getElement(e){return n.jsx("style",{nonce:e,href:kt,precedence:"base-ui:low",children:`.${kt}{scrollbar-width:none}.${kt}::-webkit-scrollbar{display:none}`})}};let ot=(function(e){return e.hasOverflowX="data-has-overflow-x",e.hasOverflowY="data-has-overflow-y",e.overflowXStart="data-overflow-x-start",e.overflowXEnd="data-overflow-x-end",e.overflowYStart="data-overflow-y-start",e.overflowYEnd="data-overflow-y-end",e})({});const xn={hasOverflowX:e=>e?{[ot.hasOverflowX]:""}:null,hasOverflowY:e=>e?{[ot.hasOverflowY]:""}:null,overflowXStart:e=>e?{[ot.overflowXStart]:""}:null,overflowXEnd:e=>e?{[ot.overflowXEnd]:""}:null,overflowYStart:e=>e?{[ot.overflowYStart]:""}:null,overflowYEnd:e=>e?{[ot.overflowYEnd]:""}:null,cornerHidden:()=>null},Ho={x:0,y:0},On={width:0,height:0},Fo={xStart:!1,xEnd:!1,yStart:!1,yEnd:!1},Wo={x:!1,y:!1,corner:!1},Xo=o.forwardRef(function(t,r){const{render:s,className:a,overflowEdgeThreshold:i,...l}=t,c=Yo(i),u=or(),d=At(),f=At(),{nonce:p,disableStyleElements:m}=Gs(),[h,w]=o.useState(!1),[g,j]=o.useState(!1),[k,y]=o.useState(!1),[_,R]=o.useState(!1),[H,T]=o.useState(On),[U,q]=o.useState(On),[E,W]=o.useState(Fo),[F,b]=o.useState(Wo),A=o.useRef(null),N=o.useRef(null),C=o.useRef(null),K=o.useRef(null),x=o.useRef(null),L=o.useRef(null),S=o.useRef(null),I=o.useRef(!1),P=o.useRef(0),$=o.useRef(0),Y=o.useRef(0),re=o.useRef(0),te=o.useRef("vertical"),Z=o.useRef(Ho),J=We(D=>{const me=D.x-Z.current.x,O=D.y-Z.current.y;Z.current=D,O!==0&&(y(!0),d.start(jt,()=>{y(!1)})),me!==0&&(j(!0),f.start(jt,()=>{j(!1)}))}),ie=We(D=>{D.button===0&&(I.current=!0,P.current=D.clientY,$.current=D.clientX,te.current=D.currentTarget.getAttribute($o.orientation),N.current&&(Y.current=N.current.scrollTop,re.current=N.current.scrollLeft),x.current&&te.current==="vertical"&&x.current.setPointerCapture(D.pointerId),L.current&&te.current==="horizontal"&&L.current.setPointerCapture(D.pointerId))}),V=We(D=>{if(!I.current)return;const me=D.clientY-P.current,O=D.clientX-$.current;if(N.current){const G=N.current.scrollHeight,X=N.current.clientHeight,ne=N.current.scrollWidth,se=N.current.clientWidth;if(x.current&&C.current&&te.current==="vertical"){const ee=Ne(C.current,"padding","y"),Se=Ne(x.current,"margin","y"),Ae=x.current.offsetHeight,he=C.current.offsetHeight-Ae-ee-Se,Te=me/he;N.current.scrollTop=Y.current+Te*(G-X),D.preventDefault(),y(!0),d.start(jt,()=>{y(!1)})}if(L.current&&K.current&&te.current==="horizontal"){const ee=Ne(K.current,"padding","x"),Se=Ne(L.current,"margin","x"),Ae=L.current.offsetWidth,he=K.current.offsetWidth-Ae-ee-Se,Te=O/he;N.current.scrollLeft=re.current+Te*(ne-se),D.preventDefault(),j(!0),f.start(jt,()=>{j(!1)})}}}),Q=We(D=>{I.current=!1,x.current&&te.current==="vertical"&&x.current.releasePointerCapture(D.pointerId),L.current&&te.current==="horizontal"&&L.current.releasePointerCapture(D.pointerId)});function ve(D){R(D.pointerType==="touch")}function Ee(D){if(ve(D),D.pointerType!=="touch"){const me=Ys(A.current,D.target);w(me)}}const de=o.useMemo(()=>({hasOverflowX:!F.x,hasOverflowY:!F.y,overflowXStart:E.xStart,overflowXEnd:E.xEnd,overflowYStart:E.yStart,overflowYEnd:E.yEnd,cornerHidden:F.corner}),[F.x,F.y,F.corner,E]),ae={role:"presentation",onPointerEnter:Ee,onPointerMove:Ee,onPointerDown:ve,onPointerLeave(){w(!1)},style:{position:"relative",[Lt.scrollAreaCornerHeight]:`${H.height}px`,[Lt.scrollAreaCornerWidth]:`${H.width}px`}},pe=Be("div",t,{state:de,ref:[r,A],props:[ae,l],stateAttributesMapping:xn}),fe=o.useMemo(()=>({handlePointerDown:ie,handlePointerMove:V,handlePointerUp:Q,handleScroll:J,cornerSize:H,setCornerSize:T,thumbSize:U,setThumbSize:q,touchModality:_,cornerRef:S,scrollingX:g,setScrollingX:j,scrollingY:k,setScrollingY:y,hovering:h,setHovering:w,viewportRef:N,rootRef:A,scrollbarYRef:C,scrollbarXRef:K,thumbYRef:x,thumbXRef:L,rootId:u,hiddenState:F,setHiddenState:b,overflowEdges:E,setOverflowEdges:W,viewportState:de,overflowEdgeThreshold:c}),[ie,V,Q,J,H,U,_,g,j,k,y,h,w,u,F,E,de,c]);return n.jsxs(gr.Provider,{value:fe,children:[!m&&xr.getElement(p),pe]})});function Yo(e){if(typeof e=="number"){const t=Math.max(0,e);return{xStart:t,xEnd:t,yStart:t,yEnd:t}}return{xStart:Math.max(0,e?.xStart||0),xEnd:Math.max(0,e?.xEnd||0),yStart:Math.max(0,e?.yStart||0),yEnd:Math.max(0,e?.yEnd||0)}}const Bo=o.createContext(void 0);function Ue(e,t=Number.MIN_SAFE_INTEGER,r=Number.MAX_SAFE_INTEGER){return Math.max(t,Math.min(e,r))}function Go(e,t){if(typeof IntersectionObserver>"u")return()=>{};const r=new IntersectionObserver(s=>{s.forEach(a=>{a.intersectionRatio>0&&(t(),r.disconnect())})});return r.observe(e),()=>{r.disconnect()}}let Ye=(function(e){return e.scrollAreaOverflowXStart="--scroll-area-overflow-x-start",e.scrollAreaOverflowXEnd="--scroll-area-overflow-x-end",e.scrollAreaOverflowYStart="--scroll-area-overflow-y-start",e.scrollAreaOverflowYEnd="--scroll-area-overflow-y-end",e})({}),Dn=!1;function qo(){Dn||Bs||(typeof CSS<"u"&&"registerProperty"in CSS&&[Ye.scrollAreaOverflowXStart,Ye.scrollAreaOverflowXEnd,Ye.scrollAreaOverflowYStart,Ye.scrollAreaOverflowYEnd].forEach(e=>{try{CSS.registerProperty({name:e,syntax:"<length>",inherits:!1,initialValue:"0px"})}catch{}}),Dn=!0)}const Vo=o.forwardRef(function(t,r){const{render:s,className:a,...i}=t,{viewportRef:l,scrollbarYRef:c,scrollbarXRef:u,thumbYRef:d,thumbXRef:f,cornerRef:p,cornerSize:m,setCornerSize:h,setThumbSize:w,rootId:g,setHiddenState:j,hiddenState:k,handleScroll:y,setHovering:_,setOverflowEdges:R,overflowEdges:H,overflowEdgeThreshold:T}=Wt(),U=lr(),q=o.useRef(!0),E=At(),W=At(),F=We(()=>{const x=l.current,L=c.current,S=u.current,I=d.current,P=f.current,$=p.current;if(!x)return;const Y=x.scrollHeight,re=x.scrollWidth,te=x.clientHeight,Z=x.clientWidth,J=x.scrollTop,ie=x.scrollLeft;if(Y===0||re===0)return;const V=te>=Y,Q=Z>=re,ve=Z/re,Ee=te/Y,de=Math.max(0,re-Z),ae=Math.max(0,Y-te);let pe=0,fe=0;Q||(U==="rtl"?pe=Ue(-ie,0,de):pe=Ue(ie,0,de),fe=de-pe);const D=V?0:Ue(J,0,ae),me=V?0:ae-D,O=Q?0:Z,G=V?0:te;let X=0,ne=0;!Q&&!V&&(X=L?.offsetWidth||0,ne=S?.offsetHeight||0);const se=m.width===0&&m.height===0,ee=se?X:0,Se=se?ne:0,Ae=Ne(S,"padding","x"),he=Ne(L,"padding","y"),Te=Ne(P,"margin","x"),ut=Ne(I,"margin","y"),xt=O-Ae-Te,Ge=G-he-ut,Ze=S?Math.min(S.offsetWidth-ee,xt):xt,yt=L?Math.min(L.offsetHeight-Se,Ge):Ge,et=Math.max(In,Ze*ve),tt=Math.max(In,yt*Ee);if(w(oe=>oe.height===tt&&oe.width===et?oe:{width:et,height:tt}),L&&I){const oe=L.offsetHeight-tt-he-ut,we=Y-te,ze=we===0?0:J/we,mt=Math.min(oe,Math.max(0,ze*oe));I.style.transform=`translate3d(0,${mt}px,0)`}if(S&&P){const oe=S.offsetWidth-et-Ae-Te,we=re-Z,ze=we===0?0:ie/we,mt=U==="rtl"?Ue(ze*oe,-oe,0):Ue(ze*oe,0,oe);P.style.transform=`translate3d(${mt}px,0,0)`}const dt=Ue(pe,0,de),wt=Ue(fe,0,de),bt=Ue(D,0,ae),ft=Ue(me,0,ae),St=[[Ye.scrollAreaOverflowXStart,dt],[Ye.scrollAreaOverflowXEnd,wt],[Ye.scrollAreaOverflowYStart,bt],[Ye.scrollAreaOverflowYEnd,ft]];for(const[oe,we]of St)x.style.setProperty(oe,`${we}px`);$&&(Q||V?h({width:0,height:0}):!Q&&!V&&h({width:X,height:ne})),j(oe=>{const we=V||Q;return oe.y===V&&oe.x===Q&&oe.corner===we?oe:{y:V,x:Q,corner:we}});const je={xStart:!Q&&dt>T.xStart,xEnd:!Q&&wt>T.xEnd,yStart:!V&&bt>T.yStart,yEnd:!V&&ft>T.yEnd};R(oe=>oe.xStart===je.xStart&&oe.xEnd===je.xEnd&&oe.yStart===je.yStart&&oe.yEnd===je.yEnd?oe:je)});Re(()=>{if(!l.current)return;qo();let x=!1;return Go(l.current,()=>{if(!x){x=!0;return}F()})},[F,l]),Re(()=>{queueMicrotask(F)},[F,k,U]),Re(()=>{l.current?.matches(":hover")&&_(!0)},[l,_]),o.useEffect(()=>{const x=l.current;if(typeof ResizeObserver>"u"||!x)return;let L=!1;const S=new ResizeObserver(()=>{if(!L){L=!0;return}F()});return S.observe(x),W.start(0,()=>{const I=x.getAnimations({subtree:!0});I.length!==0&&Promise.all(I.map(P=>P.finished)).then(F).catch(()=>{})}),()=>{S.disconnect(),W.clear()}},[F,l,W]);function b(){q.current=!1}const A={role:"presentation",...g&&{"data-id":`${g}-viewport`},...(!k.x||!k.y)&&{tabIndex:0},className:xr.className,style:{overflow:"scroll"},onScroll(){l.current&&(F(),q.current||y({x:l.current.scrollLeft,y:l.current.scrollTop}),E.start(100,()=>{q.current=!0}))},onWheel:b,onTouchMove:b,onPointerMove:b,onPointerEnter:b,onKeyDown:b},N=o.useMemo(()=>({hasOverflowX:!k.x,hasOverflowY:!k.y,overflowXStart:H.xStart,overflowXEnd:H.xEnd,overflowYStart:H.yStart,overflowYEnd:H.yEnd,cornerHidden:k.corner}),[k.x,k.y,k.corner,H]),C=Be("div",t,{ref:[r,l],state:N,props:[A,i],stateAttributesMapping:xn}),K=o.useMemo(()=>({computeThumbPosition:F}),[F]);return n.jsx(Bo.Provider,{value:K,children:C})}),yr=o.createContext(void 0);function Jo(){const e=o.useContext(yr);if(e===void 0)throw new Error(fn(54));return e}let Pt=(function(e){return e.scrollAreaThumbHeight="--scroll-area-thumb-height",e.scrollAreaThumbWidth="--scroll-area-thumb-width",e})({});const Qo=o.forwardRef(function(t,r){const{render:s,className:a,orientation:i="vertical",keepMounted:l=!1,...c}=t,{hovering:u,scrollingX:d,scrollingY:f,hiddenState:p,overflowEdges:m,scrollbarYRef:h,scrollbarXRef:w,viewportRef:g,thumbYRef:j,thumbXRef:k,handlePointerDown:y,handlePointerUp:_,rootId:R,thumbSize:H}=Wt(),T=o.useMemo(()=>({hovering:u,scrolling:{horizontal:d,vertical:f}[i],orientation:i,hasOverflowX:!p.x,hasOverflowY:!p.y,overflowXStart:m.xStart,overflowXEnd:m.xEnd,overflowYStart:m.yStart,overflowYEnd:m.yEnd,cornerHidden:p.corner}),[u,d,f,i,p,m]),U=lr();o.useEffect(()=>{const A=g.current,N=i==="vertical"?h.current:w.current;if(!N)return;function C(K){if(!(!A||!N||K.ctrlKey)){if(K.preventDefault(),i==="vertical"){if(A.scrollTop===0&&K.deltaY<0)return}else if(A.scrollLeft===0&&K.deltaX<0)return;if(i==="vertical"){if(A.scrollTop===A.scrollHeight-A.clientHeight&&K.deltaY>0)return}else if(A.scrollLeft===A.scrollWidth-A.clientWidth&&K.deltaX>0)return;i==="vertical"?A.scrollTop+=K.deltaY:A.scrollLeft+=K.deltaX}}return N.addEventListener("wheel",C,{passive:!1}),()=>{N.removeEventListener("wheel",C)}},[i,w,h,g]);const q={...R&&{"data-id":`${R}-scrollbar`},onPointerDown(A){if(A.button===0&&A.currentTarget===A.target&&g.current){if(j.current&&h.current&&i==="vertical"){const N=Ne(j.current,"margin","y"),C=Ne(h.current,"padding","y"),K=j.current.offsetHeight,x=h.current.getBoundingClientRect(),L=A.clientY-x.top-K/2-C+N/2,S=g.current.scrollHeight,I=g.current.clientHeight,P=h.current.offsetHeight-K-C-N,Y=L/P*(S-I);g.current.scrollTop=Y}if(k.current&&w.current&&i==="horizontal"){const N=Ne(k.current,"margin","x"),C=Ne(w.current,"padding","x"),K=k.current.offsetWidth,x=w.current.getBoundingClientRect(),L=A.clientX-x.left-K/2-C+N/2,S=g.current.scrollWidth,I=g.current.clientWidth,P=w.current.offsetWidth-K-C-N,$=L/P;let Y;U==="rtl"?(Y=(1-$)*(S-I),g.current.scrollLeft<=0&&(Y=-Y)):Y=$*(S-I),g.current.scrollLeft=Y}y(A)}},onPointerUp:_,style:{position:"absolute",touchAction:"none",WebkitUserSelect:"none",userSelect:"none",...i==="vertical"&&{top:0,bottom:`var(${Lt.scrollAreaCornerHeight})`,insetInlineEnd:0,[Pt.scrollAreaThumbHeight]:`${H.height}px`},...i==="horizontal"&&{insetInlineStart:0,insetInlineEnd:`var(${Lt.scrollAreaCornerWidth})`,bottom:0,[Pt.scrollAreaThumbWidth]:`${H.width}px`}}},E=Be("div",t,{ref:[r,i==="vertical"?h:w],state:T,props:[q,c],stateAttributesMapping:xn}),W=o.useMemo(()=>({orientation:i}),[i]),F=i==="vertical"?p.y:p.x;return l||!F?n.jsx(yr.Provider,{value:W,children:E}):null}),Zo=o.forwardRef(function(t,r){const{render:s,className:a,...i}=t,{thumbYRef:l,thumbXRef:c,handlePointerDown:u,handlePointerMove:d,handlePointerUp:f,setScrollingX:p,setScrollingY:m}=Wt(),{orientation:h}=Jo(),w=o.useMemo(()=>({orientation:h}),[h]);return Be("div",t,{ref:[r,h==="vertical"?l:c],state:w,props:[{onPointerDown:u,onPointerMove:d,onPointerUp(j){h==="vertical"&&m(!1),h==="horizontal"&&p(!1),f(j)},style:{...h==="vertical"&&{height:`var(${Pt.scrollAreaThumbHeight})`},...h==="horizontal"&&{width:`var(${Pt.scrollAreaThumbWidth})`}}},i]})}),ei=o.forwardRef(function(t,r){const{render:s,className:a,...i}=t,{cornerRef:l,cornerSize:c,hiddenState:u}=Wt(),d=Be("div",t,{ref:[r,l],props:[{style:{position:"absolute",bottom:0,insetInlineEnd:0,width:c.width,height:c.height}},i]});return u.corner?null:d});function wr({className:e,...t}){return n.jsx(Xo,{className:M("group/scroll-area relative outline-none focus-visible:outline-none",e),...t})}function br({className:e,...t}){return n.jsx(Vo,{className:M("h-full w-full outline-none focus-visible:outline-none",e),...t})}function Sr({className:e,...t}){return n.jsx(Qo,{className:M("flex w-2 touch-none select-none p-0.5 outline-none focus-visible:outline-none","opacity-0 transition-opacity duration-150","data-hovering:opacity-100 data-scrolling:opacity-100 group-hover/scroll-area:opacity-100",e),...t})}function vr({className:e,...t}){return n.jsx(Zo,{className:M("flex-1 rounded-full bg-primary-500 outline-none focus-visible:outline-none",e),...t})}function ti({className:e,...t}){return n.jsx(ei,{className:M("bg-primary-100 outline-none focus-visible:outline-none",e),...t})}function ni(e){return e==="subagent"?is:e==="cron"?as:ls}function ri(e){return!e||!Array.isArray(e.content)?"":e.content.map(r=>r.type==="text"?String(r.text??""):"").join(" ").replace(/\s+/g," ").trim()}function si(e){if(typeof e=="number"&&Number.isFinite(e))return e<1e12?e*1e3:e;if(typeof e=="string"){const t=Date.parse(e);if(!Number.isNaN(t))return t}return null}function oi(e){if(!e)return null;const t=[e.createdAt,e.created_at,e.timestamp,e.time,e.ts];for(const r of t){const s=si(r);if(s)return s}return null}function ii(e){const t=e-Date.now(),r=Math.abs(t),s=[["minute",6e4],["hour",36e5],["day",864e5]];let a="minute",i=6e4;r>=s[2][1]?[a,i]=s[2]:r>=s[1][1]&&([a,i]=s[1]);const l=Math.round(t/i);return new Intl.RelativeTimeFormat("en",{numeric:"auto"}).format(l,a)}function ai(e){const t=String(e??"").toLowerCase().trim();return t?t==="error"||t==="failed"?"error":t==="completed"||t==="ended"||t==="done"?"success":null:null}function li({session:e,active:t,isGenerating:r=!1,isPinned:s,selectionMode:a=!1,selected:i=!1,onToggleSelect:l,onSelect:c,onTogglePin:u,onRename:d,onDelete:f,onExport:p}){const m=e.label||e.title||e.derivedTitle||e.friendlyId,h=ni(e.kind),w=e.kind==="subagent"&&(e.lastMessage?.role==="assistant"||e.lastMessage?.role==="toolResult")?ri(e.lastMessage):"",g=w.length>50?`${w.slice(0,50).trimEnd()}…`:w,j=e.kind==="subagent"?ai(e.status):null,k=e.kind==="cron"?oi(e.lastMessage):null;return n.jsxs(qe,{to:"/chat/$sessionKey",params:{sessionKey:e.friendlyId},onClick:y=>{if(a){y.preventDefault(),y.stopPropagation(),l?.(e);return}c?.()},className:M("group inline-flex items-center justify-between","w-full text-left pl-1.5 pr-0.5 min-h-8 py-1 rounded-lg transition-colors duration-0","select-none",t?"bg-[var(--opencami-accent-light)] text-[var(--opencami-accent)]":"bg-transparent text-primary-950 [&:hover:not(:has(button:hover))]:bg-primary-200"),children:[n.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[a?n.jsx("span",{"aria-hidden":"true",className:M("inline-flex items-center justify-center size-4 shrink-0 rounded border transition-colors",i?"bg-primary-700 border-primary-700 text-white":"border-primary-300 bg-surface"),children:i?n.jsx("svg",{viewBox:"0 0 12 12",className:"size-3",fill:"none",stroke:"currentColor",strokeWidth:2,children:n.jsx("path",{d:"M2.5 6l2.5 2.5 4.5-5"})}):null}):null,n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[n.jsx(B,{icon:h,size:12,strokeWidth:1.75,className:"text-primary-500/70 shrink-0"}),n.jsxs("div",{className:"min-w-0 truncate text-sm font-[450]",title:m,children:[s?n.jsx("span",{className:"mr-1 text-xs text-primary-700","aria-hidden":"true",children:"📌"}):null,m]}),e.kind==="subagent"?r?n.jsx("span",{"aria-label":"Session active",className:"size-1.5 rounded-full bg-green-500 shrink-0"}):j==="success"?n.jsx(B,{icon:Qn,size:12,strokeWidth:1.8,className:"text-green-600/80 shrink-0"}):j==="error"?n.jsx(B,{icon:Ut,size:12,strokeWidth:1.8,className:"text-red-600/80 shrink-0"}):null:null]}),g?n.jsx("div",{className:"text-[11px] text-primary-600/80 line-clamp-1 mt-0.5 pl-[18px]",children:g}):null,e.kind==="cron"&&k?n.jsx("div",{className:"text-[10px] text-primary-500/75 line-clamp-1 mt-0.5 pl-[18px] font-mono",children:ii(k)}):null]})]}),a?null:n.jsxs($t,{children:[n.jsx(Ht,{type:"button",onClick:y=>{y.preventDefault(),y.stopPropagation()},className:M("ml-2 inline-flex size-7 items-center justify-center rounded-md text-primary-700","opacity-0 transition-opacity group-hover:opacity-100 hover:bg-primary-200","aria-expanded:opacity-100 aria-expanded:bg-primary-200"),children:n.jsx(B,{icon:rs,size:20,strokeWidth:1.5})}),n.jsxs(Ft,{side:"bottom",align:"end",children:[n.jsxs(Xe,{onClick:y=>{y.preventDefault(),y.stopPropagation(),u(e)},className:"gap-2",children:[n.jsx("span",{className:"text-xs","aria-hidden":"true",children:"📌"})," ",s?"Unpin Session":"Pin Session"]}),n.jsxs(Xe,{onClick:y=>{y.preventDefault(),y.stopPropagation(),d(e)},className:"gap-2",children:[n.jsx(B,{icon:ss,size:20,strokeWidth:1.5})," ","Rename"]}),n.jsxs(Xe,{onClick:y=>{y.preventDefault(),y.stopPropagation(),p(e)},className:"gap-2",children:[n.jsx(B,{icon:os,size:20,strokeWidth:1.5})," ","Export"]}),an(e.key)?null:n.jsxs(Xe,{onClick:y=>{y.preventDefault(),y.stopPropagation(),f(e)},className:"text-red-700 gap-2 hover:bg-red-50/80 data-highlighted:bg-red-50/80",children:[n.jsx(B,{icon:Zn,size:20,strokeWidth:1.5})," ","Delete"]})]})]})]})}function ci(e,t){return e.active!==t.active||e.isGenerating!==t.isGenerating||e.isPinned!==t.isPinned||e.selectionMode!==t.selectionMode||e.selected!==t.selected||e.onToggleSelect!==t.onToggleSelect||e.onSelect!==t.onSelect||e.onTogglePin!==t.onTogglePin||e.onRename!==t.onRename||e.onDelete!==t.onDelete||e.onExport!==t.onExport?!1:e.session===t.session?!0:e.session.key===t.session.key&&e.session.friendlyId===t.session.friendlyId&&e.session.label===t.session.label&&e.session.title===t.session.title&&e.session.derivedTitle===t.session.derivedTitle&&e.session.updatedAt===t.session.updatedAt&&e.session.kind===t.session.kind&&e.session.status===t.session.status&&e.session.lastMessage===t.session.lastMessage}const qt=o.memo(li,ci),jr="opencami-pinned-sessions",kr="opencami-sidebar-folders",He={webchat:!1,subagent:!1,cron:!1,other:!1};async function ui(e){const t=new URLSearchParams;e&&t.set("sessionKey",e);const r=await fetch(`/api/sessions?${t.toString()}`,{method:"DELETE"});if(!r.ok)throw new Error(await Ke(r))}async function di(e,t,r){const s=[];let a=0;const i=Array.from({length:Math.min(t,e.length)},async function(){for(;a<e.length;){const c=a;a+=1;try{await r(e[c])}catch(u){s.push(u)}}});return await Promise.all(i),s}function fi(){if(typeof window>"u")return[];try{const e=localStorage.getItem(jr);if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>typeof r=="string"):[]}catch{return[]}}function mi(e){if(!(typeof window>"u"))try{const t=Array.from(new Set(e));localStorage.setItem(jr,JSON.stringify(t))}catch{}}function pi(){if(typeof window>"u")return{...He};try{const e=localStorage.getItem(kr);if(!e)return{...He};const t=JSON.parse(e);return!t||typeof t!="object"?{...He}:{webchat:typeof t.webchat=="boolean"?t.webchat:He.webchat,subagent:typeof t.subagent=="boolean"?t.subagent:He.subagent,cron:typeof t.cron=="boolean"?t.cron:He.cron,other:typeof t.other=="boolean"?t.other:He.other}}catch{return{...He}}}function hi(e){if(!(typeof window>"u"))try{localStorage.setItem(kr,JSON.stringify(e))}catch{}}function Et(e,t,r){return r&&e.key?e.key===r:e.friendlyId===t}function gi(e){if(!e)return!1;const t=e.toLowerCase();return t.includes("running")||t.includes("active")||t.includes("stream")||t.includes("generat")}function Vt(e,t,r,s){return Et(e,t,r)&&s?!0:gi(e.status)}const xi=o.memo(function({sessions:t,activeFriendlyId:r,activeSessionKey:s,isStreaming:a=!1,defaultOpen:i=!0,onSelect:l,onRename:c,onDelete:u,onExport:d}){const f=o.useDeferredValue(t),p=ct(),[m,h]=o.useState(()=>fi()),[w,g]=o.useState(()=>pi()),[j,k]=o.useState(!1),[y,_]=o.useState(()=>new Set),R=o.useMemo(()=>new Set(m),[m]),H=f.filter(S=>R.has(S.key)),T=f.filter(S=>!R.has(S.key)),U=H.length>0&&T.length>0,q=o.useMemo(()=>{const S={chat:[],webchat:[],subagent:[],cron:[],other:[]};for(const I of T){const P=I.kind??"other";S[P].push(I)}return S},[T]),E=o.useMemo(()=>f.filter(S=>y.has(S.key)),[y,f]),W=E.length,F=o.useCallback(()=>{k(S=>(S&&_(new Set),!S))},[]),b=o.useCallback(S=>{an(S.key)||_(I=>{const P=new Set(I);return P.has(S.key)?P.delete(S.key):P.add(S.key),P})},[]),A=o.useCallback(()=>{_(new Set(f.filter(S=>!an(S.key)).map(S=>S.key)))},[f]),N=o.useCallback(()=>{k(!1),_(new Set)},[]),C=o.useCallback(async()=>{if(E.length===0||!window.confirm(`Delete ${E.length} sessions? This will archive them.`))return;const I=[];await di(E,10,async P=>{try{await ui(P.key)}catch($){throw I.push(P.label||P.title||P.derivedTitle||P.friendlyId),$}}),I.length>0&&(console.error("[sidebar] Bulk delete failed for some sessions",I),window.alert(`Could not delete ${I.length} session${I.length!==1?"s":""}:
|
|
6
|
+
|
|
7
|
+
${I.join(`
|
|
8
|
+
`)}`)),k(!1),_(new Set),p.invalidateQueries({queryKey:ce.sessions})},[p,E]),K=o.useCallback(S=>{h(I=>{const $=I.includes(S.key)?I.filter(Y=>Y!==S.key):[...I,S.key];return mi($),$})},[]),x=o.useCallback((S,I)=>{g(P=>{const $={...P,[S]:I};return hi($),$})},[]);function L(S,I,P){return P.length===0?null:n.jsxs(It,{className:"flex flex-col",open:w[S],onOpenChange:$=>x(S,$),children:[n.jsxs(Ot,{className:M("w-full justify-between border-l-2 border-primary-200/70 px-2 py-1 text-[11px] font-medium text-primary-500/80 text-balance"),children:[n.jsx("span",{className:"truncate",children:I}),n.jsx("span",{className:M("rounded-full bg-primary-100 px-1.5 py-0.5 text-[10px] font-medium text-primary-700 tabular-nums"),children:P.length})]}),n.jsx(Dt,{contentClassName:"flex flex-col gap-px",children:P.map($=>n.jsx(qt,{session:$,active:Et($,r,s),isGenerating:Vt($,r,s,a),isPinned:!1,selectionMode:j,selected:y.has($.key),onToggleSelect:b,onSelect:l,onTogglePin:K,onRename:c,onDelete:u,onExport:d},$.key))})]})}return n.jsxs(It,{className:"flex h-full flex-col flex-1 min-h-0 w-full",defaultOpen:i,children:[n.jsxs("div",{className:"flex items-center justify-between pr-2 shrink-0",children:[n.jsxs(Ot,{className:"w-fit pl-1.5 text-balance",children:["Sessions",n.jsx("span",{className:"opacity-0 transition-opacity duration-150 group-hover:opacity-100",children:n.jsx(B,{icon:mn,className:"size-3 transition-transform duration-150 group-data-panel-open:rotate-90"})})]}),n.jsx("button",{type:"button",onClick:F,className:M("text-[11px] font-medium px-1.5 py-0.5 rounded-md transition-colors",j?"text-primary-900 bg-primary-200":"text-primary-500 hover:text-primary-700 hover:bg-primary-100"),children:j?"Done":"Select"})]}),n.jsx(Dt,{className:"w-full flex-1 min-h-0 h-auto data-starting-style:h-0 data-ending-style:h-0",contentClassName:"flex flex-1 min-h-0 flex-col overflow-y-auto",children:n.jsxs(wr,{className:"flex-1 min-h-0",children:[n.jsx(br,{className:"min-h-0",children:n.jsxs("div",{className:"flex flex-col gap-2 pl-2 pr-2",children:[H.length>0?n.jsx("div",{className:"flex flex-col gap-px",children:H.map(S=>n.jsx(qt,{session:S,active:Et(S,r,s),isGenerating:Vt(S,r,s,a),isPinned:!0,selectionMode:j,selected:y.has(S.key),onToggleSelect:b,onSelect:l,onTogglePin:K,onRename:c,onDelete:u,onExport:d},S.key))}):null,U?n.jsx("div",{className:"my-1 border-t border-primary-200/80"}):null,q.chat.length>0?n.jsxs("div",{className:"flex flex-col gap-px",children:[n.jsx("div",{className:M("border-l-2 border-primary-200/70 px-2 py-1 text-[11px] font-medium text-primary-500/80 text-balance"),children:"💬 Chats"}),n.jsx("div",{className:"flex flex-col gap-px",children:q.chat.map(S=>n.jsx(qt,{session:S,active:Et(S,r,s),isGenerating:Vt(S,r,s,a),isPinned:!1,selectionMode:j,selected:y.has(S.key),onToggleSelect:b,onSelect:l,onTogglePin:K,onRename:c,onDelete:u,onExport:d},S.key))})]}):null,L("webchat","🦎 OpenCami",q.webchat),L("subagent","🤖 Sub-agents",q.subagent),L("cron","⏰ Cron / Isolated",q.cron),L("other","📁 Other",q.other)]})}),n.jsx(Sr,{orientation:"vertical",children:n.jsx(vr,{})})]})}),j?n.jsxs("div",{className:"shrink-0 border-t border-primary-200 bg-surface px-2 py-2 flex flex-col gap-1.5",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsxs("span",{className:"text-xs text-primary-600 font-medium",children:[W," selected"]}),n.jsx("button",{type:"button",onClick:A,className:"text-[11px] font-medium text-primary-600 hover:text-primary-800",children:"Select all"})]}),n.jsxs("div",{className:"flex gap-1.5",children:[n.jsxs("button",{type:"button",onClick:C,disabled:W===0,className:M("flex-1 inline-flex items-center justify-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium transition-colors",W>0?"bg-red-100 text-red-700 hover:bg-red-200":"bg-primary-100 text-primary-400 cursor-not-allowed"),children:[n.jsx(B,{icon:Zn,size:14,strokeWidth:1.5}),"Delete"]}),n.jsx("button",{type:"button",onClick:N,className:"flex-1 inline-flex items-center justify-center rounded-md px-2 py-1.5 text-xs font-medium bg-primary-100 text-primary-700 hover:bg-primary-200 transition-colors",children:"Cancel"})]})]}):null]})},yi);function yi(e,t){if(e.activeFriendlyId!==t.activeFriendlyId||e.activeSessionKey!==t.activeSessionKey||e.isStreaming!==t.isStreaming||e.defaultOpen!==t.defaultOpen||e.onSelect!==t.onSelect||e.onRename!==t.onRename||e.onDelete!==t.onDelete||e.onExport!==t.onExport)return!1;if(e.sessions===t.sessions)return!0;if(e.sessions.length!==t.sessions.length)return!1;for(let r=0;r<e.sessions.length;r+=1){const s=e.sessions[r],a=t.sessions[r];if(s.key!==a.key||s.friendlyId!==a.friendlyId||s.label!==a.label||s.title!==a.title||s.derivedTitle!==a.derivedTitle||s.updatedAt!==a.updatedAt||s.kind!==a.kind||s.status!==a.status||s.lastMessage!==a.lastMessage)return!1}return!0}function wi(){const[e,t]=o.useState(!1),[r,s]=o.useState(!1),[a,i]=o.useState(null),[l,c]=o.useState(null),u=o.useCallback(async()=>{if(t(!0),i(null),!(r||l)){s(!0);try{const h=await fetch("/api/paths");if(!h.ok)throw new Error(await Ke(h));const w=await h.json();c({agentId:String(w.agentId??"main"),stateDir:String(w.stateDir??""),sessionsDir:String(w.sessionsDir??""),storePath:String(w.storePath??"")})}catch(h){i(h instanceof Error?h.message:String(h))}finally{s(!1)}}},[l,r]),d=o.useCallback(()=>{u()},[u]),f=o.useCallback(()=>{t(!1)},[]),p=o.useCallback(()=>{if(l?.sessionsDir)try{navigator.clipboard.writeText(l.sessionsDir)}catch{}},[l]),m=o.useCallback(()=>{if(l?.storePath)try{navigator.clipboard.writeText(l.storePath)}catch{}},[l]);return{settingsOpen:e,setSettingsOpen:t,pathsLoading:r,pathsError:a,paths:l,handleOpenSettings:d,closeSettings:f,copySessionsDir:p,copyStorePath:m}}let ke=null,yn=!1,Tt=null;function bi(e){ke=e}function Jt(){return ke!==null}function ht(e){yn=e}function Qt(){return yn}function _t(){ke=null,yn=!1}function Si(e,t){if(ke){if(e&&ke.sessionKey===e){_t();return}t&&ke.friendlyId===t&&_t()}}function vi(e){Tt={friendlyId:e,at:Date.now()}}function Cr(e,t=15e3){return!(!Tt||Tt.friendlyId!==e||Date.now()-Tt.at>t)}function ji(e,t){if(!ke)return null;if(e&&ke.sessionKey===e){const r=ke;return ke=null,r}if(t&&ke.friendlyId===t){const r=ke;return ke=null,r}return null}const ki=8e3,Ve=new Map;function Ci(e){e&&Ve.set(e,{id:e,expiresAt:Date.now()+ki})}function Ni(e){e&&Ve.delete(e)}function Ei(e){if(Ve.size===0)return e;const t=Date.now();let r=!1;const s=e.filter(a=>{const i=Ve.get(a.key),l=Ve.get(a.friendlyId);return i&&i.expiresAt<=t||l&&l.expiresAt<=t?(i&&i.expiresAt<=t&&Ve.delete(a.key),l&&l.expiresAt<=t&&Ve.delete(a.friendlyId),!0):i||l?(r=!0,!1):!0});return r?s:e}function Ti(){const e=ct(),[t,r]=o.useState(!1),[s,a]=o.useState(null),i=cr({mutationFn:async function(u){const d=new URLSearchParams;u.sessionKey&&d.set("sessionKey",u.sessionKey),u.friendlyId&&d.set("friendlyId",u.friendlyId);const f=await fetch(`/api/sessions?${d.toString()}`,{method:"DELETE"});if(!f.ok)throw new Error(await Ke(f));return u},onMutate:async function(u){a(null),Ci(u.sessionKey||u.friendlyId),Si(u.sessionKey,u.friendlyId),await e.cancelQueries({queryKey:ce.sessions});const d=e.getQueryData(ce.sessions);return mo(e,u.sessionKey,u.friendlyId),u.isActive&&(u.sessionKey||u.friendlyId)&&ln(e,u.friendlyId||u.sessionKey,u.sessionKey||u.friendlyId),{previousSessions:d,isActive:u.isActive}},onError:function(u,d,f){f?.previousSessions&&e.setQueryData(ce.sessions,f.previousSessions),Ni(d.sessionKey||d.friendlyId),a(u instanceof Error?u.message:String(u))},onSuccess:function(u){u.isActive&&_t(),e.invalidateQueries({queryKey:ce.sessions})},onSettled:function(){r(!1)}});return{deleteSession:o.useCallback(async(c,u,d)=>{!c&&!u||(r(!0),await i.mutateAsync({sessionKey:c,friendlyId:u,isActive:d}))},[i]),deleting:t,error:s}}function Ri(){const e=ct(),[t,r]=o.useState(!1),[s,a]=o.useState(null),i=cr({mutationFn:async function(u){const d=await fetch("/api/sessions",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({sessionKey:u.sessionKey,label:u.newTitle})});if(!d.ok)throw new Error(await Ke(d));return u},onMutate:async function(u){a(null),await e.cancelQueries({queryKey:ce.sessions});const d=e.getQueryData(ce.sessions);return e.setQueryData(ce.sessions,function(p){return Array.isArray(p)?p.map(m=>m.key!==u.sessionKey?m:{...m,label:u.newTitle,title:u.newTitle}):p}),{previousSessions:d}},onError:function(u,d,f){f?.previousSessions&&e.setQueryData(ce.sessions,f.previousSessions),a(u instanceof Error?u.message:String(u))},onSuccess:function(){e.invalidateQueries({queryKey:ce.sessions})},onSettled:function(){r(!1)}});return{renameSession:o.useCallback(async(c,u)=>{!c||!u.trim()||(r(!0),await i.mutateAsync({sessionKey:c,newTitle:u.trim()}))},[i]),renaming:t,error:s}}const Mi=o.lazy(()=>Kt(()=>import("./settings-dialog-CoeG9M1b.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23])).then(e=>({default:e.SettingsDialog}))),Ai=o.lazy(()=>Kt(()=>import("./session-export-dialog-CBeTfbll.js"),__vite__mapDeps([24,1,3,2,4,5,6,7,8,9])).then(e=>({default:e.SessionExportDialog})));function Ii({sessions:e,activeFriendlyId:t,activeSessionKey:r,isStreaming:s=!1,creatingSession:a,onCreateSession:i,isCollapsed:l,onToggleCollapse:c,onSelectSession:u,onActiveSessionDelete:d,onOpenSearch:f}){const{settingsOpen:p,setSettingsOpen:m,pathsLoading:h,pathsError:w,paths:g,handleOpenSettings:j,closeSettings:k,copySessionsDir:y,copyStorePath:_}=wi(),{deleteSession:R}=Ti(),{renameSession:H}=Ri(),T={duration:.15,ease:l?"easeIn":"easeOut"},[U,q]=o.useState(!1),[E,W]=o.useState(null),[F,b]=o.useState(""),[A,N]=o.useState(!1),[C,K]=o.useState(null),[x,L]=o.useState(null),[S,I]=o.useState(""),[P,$]=o.useState(!1),[Y,re]=o.useState(null),[te,Z]=o.useState(null),[J,ie]=o.useState(""),V=ct();function Q(D){W(D.key),b(D.label||D.title||D.derivedTitle||""),q(!0)}function ve(D){E&&H(E,D),q(!1),W(null)}function Ee(D){K(D.key),L(D.friendlyId),I(D.label||D.title||D.derivedTitle||D.friendlyId),N(!0)}function de(){if(C&&x){const D=x===t;D&&d&&d(),R(C,x,D)}N(!1),K(null),L(null)}function ae(D){re(D.key),Z(D.friendlyId),ie(D.label||D.title||D.derivedTitle||D.friendlyId),$(!0)}function pe(D){if(Y&&te){const me=ce.history(te,Y),O=V.getQueryData(me);O?.messages&&yo(J,O.messages,D)}$(!1),re(null),Z(null)}const fe={className:"border-r border-primary-200 h-full overflow-hidden bg-primary-100 flex flex-col"};return n.jsxs(be.aside,{initial:!1,animate:{width:l?48:"var(--opencami-sidebar-width)"},transition:T,className:fe.className,children:[n.jsxs(be.div,{layout:!0,transition:{layout:T},className:M("flex items-center h-12 px-2 justify-between"),children:[n.jsx(Oe,{initial:!1,children:l?null:n.jsx(be.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,children:n.jsxs(qe,{to:"/new",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),children:[n.jsx(qs,{className:"size-5"}),n.jsx(Vs,{})]})})}),n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{onClick:c,render:n.jsx(xe,{size:"icon-sm",variant:"ghost",children:n.jsx(B,{icon:cs,size:20,strokeWidth:1.5})})}),n.jsx(_e,{side:"right",children:l?"Open Sidebar":"Close Sidebar"})]})})]}),n.jsxs("div",{className:"px-2 mb-4 flex flex-col gap-1",children:[n.jsxs(be.div,{layout:!0,transition:{layout:T},className:"w-full space-y-2",children:[n.jsxs(xe,{disabled:a,variant:"ghost",size:"sm",onClick:i,onMouseUp:u,className:"w-full pl-1.5 justify-start",children:[n.jsx(B,{icon:us,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"New Session"})})]}),(()=>{try{const D=localStorage.getItem("opencami-file-explorer");return D===null?!0:D==="true"}catch{return!0}})()&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{asChild:!0,children:n.jsxs(qe,{to:"/files",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),onClick:u,children:[n.jsx(B,{icon:ds,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Files"})})]})}),l&&n.jsx(_e,{side:"right",children:"Files"})]})}),(()=>{try{const D=localStorage.getItem("opencami-memory-viewer");return D===null?!0:D==="true"}catch{return!0}})()&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{asChild:!0,children:n.jsxs(qe,{to:"/memory",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),onClick:u,children:[n.jsx(B,{icon:rn,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Memory"})})]})}),l&&n.jsx(_e,{side:"right",children:"Memory"})]})}),(()=>{try{return localStorage.getItem("opencami-skills-browser")==="true"}catch{return!1}})()&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{asChild:!0,children:n.jsxs(qe,{to:"/skills",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),onClick:u,children:[n.jsx(B,{icon:fs,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Skills"})})]})}),l&&n.jsx(_e,{side:"right",children:"Skills"})]})}),(()=>{try{return localStorage.getItem("opencami-agent-manager")==="true"}catch{return!1}})()&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{asChild:!0,children:n.jsxs(qe,{to:"/agents",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),onClick:u,children:[n.jsx(B,{icon:rn,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Agents"})})]})}),l&&n.jsx(_e,{side:"right",children:"Agents"})]})}),(()=>{try{return localStorage.getItem("opencami-cron-manager")==="true"}catch{return!1}})()&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{asChild:!0,children:n.jsxs(qe,{to:"/bots",className:M(st({variant:"ghost",size:"sm"}),"w-full pl-1.5 justify-start"),onClick:u,children:[n.jsx(B,{icon:ms,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Cron Jobs"})})]})}),l&&n.jsx(_e,{side:"right",children:"Cron Jobs"})]})})]}),n.jsx(be.div,{layout:!0,transition:{layout:T},className:"w-full",children:n.jsxs(xe,{variant:"ghost",size:"sm",onClick:f,className:"w-full pl-1.5 justify-start",children:[n.jsx(B,{icon:er,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Search"})})]})})]}),n.jsx("div",{className:"flex-1 min-h-0 overflow-hidden",children:n.jsx(Oe,{initial:!1,children:!l&&n.jsx(be.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"pt-0 flex flex-col w-full min-h-0 h-full",children:n.jsx("div",{className:"flex-1 min-h-0",children:n.jsx(xi,{sessions:e,activeFriendlyId:t,activeSessionKey:r,isStreaming:s,onSelect:u,onRename:Q,onDelete:Ee,onExport:ae})})},"content")})}),n.jsx("div",{className:"px-2 py-3 border-t border-primary-200 bg-primary-100",children:n.jsx(be.div,{layout:!0,transition:{layout:T},className:"w-full",children:n.jsxs(xe,{variant:"ghost",size:"sm",onClick:j,title:l?"Settings":void 0,className:"w-full justify-start pl-1.5",children:[n.jsx(B,{icon:ps,size:20,strokeWidth:1.5,className:"min-w-5"}),n.jsx(Oe,{initial:!1,mode:"wait",children:!l&&n.jsx(be.span,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:T,className:"overflow-hidden whitespace-nowrap",children:"Settings"})})]})})}),p&&n.jsx(o.Suspense,{fallback:null,children:n.jsx(Mi,{open:p,onOpenChange:m,pathsLoading:h,pathsError:w,paths:g,onClose:k,onCopySessionsDir:y,onCopyStorePath:_})}),n.jsx(bo,{open:U,onOpenChange:q,sessionTitle:F,onSave:ve,onCancel:()=>q(!1)}),n.jsx(To,{open:A,onOpenChange:N,sessionTitle:S,onConfirm:de,onCancel:()=>N(!1)}),P&&n.jsx(o.Suspense,{fallback:null,children:n.jsx(Ai,{open:P,onOpenChange:$,sessionTitle:J,onExport:pe,onCancel:()=>$(!1)})})]})}function Oi(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let r=0;r<e.length;r+=1){const s=e[r],a=t[r];if(s.key!==a.key||s.friendlyId!==a.friendlyId||s.label!==a.label||s.title!==a.title||s.derivedTitle!==a.derivedTitle||s.updatedAt!==a.updatedAt||s.kind!==a.kind||s.status!==a.status||s.lastMessage!==a.lastMessage)return!1}return!0}function Di(e,t){return!(e.activeFriendlyId!==t.activeFriendlyId||e.activeSessionKey!==t.activeSessionKey||e.isStreaming!==t.isStreaming||e.creatingSession!==t.creatingSession||e.isCollapsed!==t.isCollapsed||!Oi(e.sessions,t.sessions))}const Li=o.memo(Ii,Di);function Ln(e){if(e<=0)return"0";if(e>=1e6){const t=e/1e6,r=t.toFixed(1);return r.endsWith(".0")?`${Math.round(t)}M`:`${r}M`}if(e>=1e5)return`${Math.round(e/1e3)}K`;if(e>=1e4)return`${Math.round(e/1e3)}K`;if(e>=1e3){const t=e/1e3,r=t.toFixed(1);return r.endsWith(".0")?`${Math.round(t)}K`:`${r}K`}return String(Math.round(e))}function Pn(e){return e>=90?{bar:"bg-red-500",text:"text-red-600 dark:text-red-400"}:e>=70?{bar:"bg-yellow-500",text:"text-yellow-600 dark:text-yellow-400"}:{bar:"bg-emerald-500",text:"text-emerald-600 dark:text-emerald-400"}}function Pi({totalTokens:e,contextTokens:t,className:r}){const{percentage:s,usedStr:a,maxStr:i,colors:l,hasData:c,isNearlyFull:u}=o.useMemo(()=>{if(typeof t!="number"||t<=0)return{percentage:0,usedStr:"",maxStr:"",colors:Pn(0),hasData:!1,isNearlyFull:!1};const p=typeof e=="number"&&e>0?e:0,m=Math.min(100,Math.round(p/t*100));return{percentage:m,usedStr:Ln(p),maxStr:Ln(t),colors:Pn(m),hasData:!0,isNearlyFull:m>=95}},[e,t]);if(!c)return null;const d=typeof e=="number"&&e>0?e.toLocaleString():"0",f=typeof t=="number"?t.toLocaleString():"0";return n.jsxs("div",{className:M("group relative flex items-center gap-1.5",r),title:`Context: ${d} / ${f} tokens (${s}%)`,children:[n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("div",{className:"w-12 h-1.5 rounded-full bg-primary-200 dark:bg-primary-700 overflow-hidden shrink-0 group-hover:h-2 transition-all",children:n.jsx("div",{className:M("h-full rounded-full transition-all duration-500 ease-out",l.bar,u&&"animate-pulse"),style:{width:`${s}%`}})}),n.jsx("span",{className:M("text-[10px] leading-none font-medium tabular-nums whitespace-nowrap",u?l.text:"text-primary-500 dark:text-primary-400"),children:a})]}),n.jsx("div",{className:M("absolute right-0 top-full mt-1 z-50","pointer-events-none opacity-0 scale-95","group-hover:pointer-events-auto group-hover:opacity-100 group-hover:scale-100","transition-all duration-150 origin-top-right"),children:n.jsxs("div",{className:M("rounded-md border border-primary-200 dark:border-primary-700","bg-surface shadow-lg px-3 py-2","text-xs whitespace-nowrap"),children:[n.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[n.jsx("span",{className:"text-primary-500 dark:text-primary-400",children:"Context window"}),n.jsxs("span",{className:M("font-semibold",l.text),children:[s,"%"]})]}),n.jsxs("div",{className:"flex items-center gap-1.5 text-primary-700 dark:text-primary-300",children:[n.jsx("span",{className:"font-medium",children:a}),n.jsx("span",{className:"text-primary-400",children:"/"}),n.jsx("span",{children:i}),n.jsx("span",{className:"text-primary-400",children:"tokens"})]}),n.jsx("div",{className:"w-full h-1.5 rounded-full bg-primary-200 dark:bg-primary-700 overflow-hidden mt-1.5",children:n.jsx("div",{className:M("h-full rounded-full transition-all duration-500 ease-out",l.bar),style:{width:`${s}%`}})}),u&&n.jsx("div",{className:"mt-1.5 text-[10px] text-red-500 dark:text-red-400 font-medium",children:"⚠ Context nearly full — consider /compact"})]})})]})}const _i=o.memo(Pi);function Ki({activeTitle:e,wrapperRef:t,showSidebarButton:r=!1,onOpenSidebar:s,totalTokens:a,contextTokens:i}){return n.jsxs("div",{ref:t,"data-tauri-drag-region":!0,className:"border-b border-primary-200 px-4 h-12 flex min-w-0 items-center overflow-x-hidden bg-surface tauri-drag-header",children:[r?n.jsx(xe,{size:"icon-sm",variant:"ghost",onClick:s,className:"mr-2 text-primary-800 hover:bg-primary-100",style:{WebkitAppRegion:"no-drag"},"aria-label":"Open sidebar",children:n.jsx(B,{icon:hs,size:18,strokeWidth:1.6})}):null,n.jsx("div",{className:"flex-1 min-w-0 overflow-hidden",children:n.jsx("div",{className:"truncate text-sm font-medium",children:e})}),n.jsx(_i,{totalTokens:a,contextTokens:i,className:"ml-3 hidden sm:flex"})]})}const zi=o.memo(Ki);function Ui(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function $i(e){const t=new Date(e);return Ui(t,new Date)?new Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit"}).format(t):new Intl.DateTimeFormat("en-GB",{day:"2-digit",month:"short"}).format(t)}function Hi(e){return new Intl.DateTimeFormat("en-GB",{day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}).format(new Date(e))}function Fi({timestamp:e}){const t=$i(e),r=Hi(e);return n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{className:"inline-flex items-center text-xs text-primary-600",children:t}),n.jsx(_e,{side:"top",children:r})]})})}function Wi({text:e,align:t,timestamp:r,forceVisible:s=!1}){const[a,i]=o.useState(!1),[l,c]=o.useState("idle"),u=o.useRef(null),d=o.useRef(null),f=o.useRef(null),[p,m]=o.useState(()=>{if(typeof window>"u")return!0;try{const k=localStorage.getItem("opencami-tts-enabled");return k===null?!0:k==="true"}catch{return!0}});o.useEffect(()=>{function k(y){y.key==="opencami-tts-enabled"&&m(y.newValue===null?!0:y.newValue==="true")}return window.addEventListener("storage",k),()=>window.removeEventListener("storage",k)},[]),o.useEffect(()=>()=>{f.current?.abort(),u.current&&(u.current.pause(),u.current=null),d.current&&(URL.revokeObjectURL(d.current),d.current=null)},[]);const h=async()=>{try{await navigator.clipboard.writeText(e),i(!0),window.setTimeout(()=>i(!1),1400)}catch{i(!1)}},w=async()=>{if(l==="playing"){f.current?.abort(),u.current&&(u.current.pause(),u.current=null),d.current&&(URL.revokeObjectURL(d.current),d.current=null),c("idle");return}f.current?.abort();const k=new AbortController;f.current=k,c("loading");try{const y=await fetch("/api/tts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:e}),signal:k.signal});if(!y.ok)throw new Error("TTS failed");const _=await y.blob(),R=URL.createObjectURL(_);d.current=R;const H=new Audio(R);u.current=H,H.onended=()=>{c("idle"),d.current&&(URL.revokeObjectURL(d.current),d.current=null),u.current=null},H.onerror=()=>{c("idle"),d.current&&(URL.revokeObjectURL(d.current),d.current=null),u.current=null},await H.play(),c("playing")}catch(y){if(y instanceof Error&&y.name==="AbortError"){c("idle");return}c("idle"),d.current&&(URL.revokeObjectURL(d.current),d.current=null),u.current=null}},g=t==="end"?"justify-end":"justify-start",j=t==="start"&&p&&e.trim().length>0;return n.jsxs("div",{className:M("flex items-center gap-2 text-xs text-primary-600 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 duration-100 ease-out",s?"opacity-100":"opacity-0",g),children:[n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{type:"button",onClick:()=>{h().catch(()=>{})},className:"inline-flex items-center justify-center rounded border border-transparent bg-transparent p-1 text-primary-700 hover:text-primary-900 hover:bg-primary-100",children:n.jsx(B,{icon:a?pn:gs,size:16,strokeWidth:1.6})}),n.jsx(_e,{side:"top",children:"Copy"})]})}),j&&n.jsx(De,{children:n.jsxs(Le,{children:[n.jsx(Pe,{type:"button",onClick:()=>{w().catch(()=>{})},disabled:l==="loading",className:M("inline-flex items-center justify-center rounded border border-transparent bg-transparent p-1 text-primary-700 hover:text-primary-900 hover:bg-primary-100",l==="loading"&&"opacity-60 cursor-wait"),children:n.jsx(B,{icon:l==="loading"?xs:l==="playing"?tr:ys,size:16,strokeWidth:1.6,className:M(l==="loading"&&"animate-spin")})}),n.jsx(_e,{side:"top",children:l==="loading"?"Generating speech…":l==="playing"?"Stop":"Listen"})]})}),n.jsx(Fi,{timestamp:r})]})}function Nr({children:e,className:t,...r}){return n.jsx("div",{className:M("flex gap-3 w-full",t),...r,children:e})}function Xi({children:e,markdown:t=!1,className:r,...s}){const a=M("rounded-[12px] break-words whitespace-normal min-w-0 max-w-full overflow-x-hidden",r);return t?n.jsx(Js,{className:a,...s,children:e}):n.jsx("div",{className:a,...s,children:e})}function Yi(){const[e,t]=o.useState(()=>typeof window<"u"?window.innerWidth<768:!1);return o.useEffect(()=>{if(typeof window>"u")return;const r=window.matchMedia("(max-width: 767px)"),s=a=>t(a.matches);return r.addEventListener("change",s),t(r.matches),()=>r.removeEventListener("change",s)},[]),e}function Bi({content:e}){const t=Yi();return n.jsx("div",{className:"inline-flex flex-col",children:n.jsxs(It,{defaultOpen:!t,children:[n.jsxs(Ot,{render:n.jsx(xe,{variant:"ghost",className:"h-auto gap-1.5 px-1.5 py-0.5 -mx-2"}),children:[n.jsx("span",{className:"text-sm font-medium text-primary-900",children:"Thinking"}),n.jsx(B,{icon:hn,size:14,strokeWidth:1.5,className:"text-primary-900 transition-transform duration-150 group-data-panel-open:rotate-180"})]}),n.jsx(Dt,{children:n.jsx("div",{className:"pt-1 mb-3",children:n.jsx("p",{className:"text-sm text-primary-700 whitespace-pre-wrap",children:e})})})]})})}function Gi({toolPart:e,defaultOpen:t=!1}){const{state:r,input:s,output:a,toolCallId:i}=e,l=(d,f=3200)=>{const p=d===void 0?"undefined":d;let m;if(typeof p=="string")try{m=JSON.stringify(JSON.parse(p),null,2)}catch{m=p}else m=JSON.stringify(p,null,2);return m.length<=f?m:`${m.slice(0,f).trimEnd()}
|
|
9
|
+
…[truncated]`},c=r==="output-error"?Ut:r==="output-available"?Qn:nr,u=r==="output-error"?"text-red-600/80":r==="output-available"?"text-green-600/80":"text-primary-500/80";return n.jsx("div",{className:"inline-flex flex-col w-full",children:n.jsxs(It,{defaultOpen:t,children:[n.jsxs(Ot,{render:n.jsx(xe,{variant:"ghost",className:"h-auto w-full justify-start gap-1.5 rounded-md px-1.5 py-1"}),children:[n.jsx(B,{icon:c,size:12,strokeWidth:1.7,className:u}),n.jsx("span",{className:"text-sm font-medium text-primary-900",children:e.type}),n.jsx(B,{icon:hn,size:14,strokeWidth:1.5,className:"ml-auto text-primary-700/80 transition-transform duration-150 group-data-panel-open:rotate-180"})]}),n.jsx(Dt,{className:"mt-1",children:n.jsxs("div",{className:"space-y-2 rounded-md border border-primary-200 bg-primary-100/70 p-2",children:[n.jsxs("div",{className:"rounded border border-primary-200 bg-primary-50 px-2 py-1.5",children:[n.jsx("div",{className:"text-[11px] font-medium text-primary-600",children:"Tool"}),n.jsx("div",{className:"font-mono text-xs text-primary-800 break-all",children:e.type})]}),s&&Object.keys(s).length>0&&n.jsxs("div",{className:"rounded border border-primary-200 bg-primary-50 px-2 py-1.5",children:[n.jsx("h4",{className:"mb-1 text-[11px] font-medium text-primary-600",children:"Input"}),n.jsx("pre",{className:"max-h-44 overflow-auto whitespace-pre-wrap break-all font-mono text-xs leading-relaxed text-primary-800",children:l(s)})]}),a!=null&&n.jsxs("div",{className:"rounded border border-primary-200 bg-primary-50 px-2 py-1.5",children:[n.jsx("h4",{className:"mb-1 text-[11px] font-medium text-primary-600",children:"Output"}),n.jsx("pre",{className:"max-h-44 overflow-auto whitespace-pre-wrap break-all font-mono text-xs leading-relaxed text-primary-800",children:l(a)})]}),r==="output-error"&&e.errorText&&n.jsxs("div",{className:"rounded border border-red-200 bg-red-50 px-2 py-1.5",children:[n.jsx("h4",{className:"mb-1 text-[11px] font-medium text-red-600",children:"Error"}),n.jsx("div",{className:"text-xs text-red-700",children:e.errorText})]}),i&&n.jsxs("div",{className:"text-[11px] text-primary-500/80 font-mono tabular-nums",children:["ID: ",i.slice(0,16),"..."]})]})})]})})}function _n(e){try{return new URL(e).hostname.replace("www.","")}catch{return e}}function Kn({domain:e}){return n.jsx("div",{className:"flex items-center justify-center w-5 h-5 rounded-full bg-white dark:bg-zinc-800 border border-cyan-500/20 overflow-hidden",title:e,children:n.jsx("img",{src:`https://www.google.com/s2/favicons?domain=${e}&sz=32`,alt:"",className:"w-4 h-4 object-contain",loading:"lazy",onError:t=>{const r=t.target;r.style.display="none";const s=r.parentElement;s&&(s.textContent=e.charAt(0).toUpperCase(),s.classList.add("text-[10px]","font-medium","text-cyan-400"))}})})}function qi({sources:e}){const[t,r]=o.useState(!1);if(!e.length)return null;const s=[...new Set(e.map(a=>_n(a.url)))];return n.jsxs("div",{className:"mt-2 w-full",children:[n.jsxs("button",{onClick:()=>r(!t),className:M("inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs","bg-cyan-500/10 hover:bg-cyan-500/20 border border-cyan-500/30","text-cyan-300 transition-colors"),children:[n.jsx(B,{icon:er,size:14}),n.jsx("span",{className:"font-medium",children:"Sources"}),n.jsx("span",{className:"px-1.5 py-0.5 rounded-full bg-cyan-500/20 text-cyan-400 font-semibold",children:e.length}),n.jsxs("div",{className:"flex items-center gap-0.5 ml-1",children:[s.slice(0,3).map(a=>n.jsx(Kn,{domain:a},a)),s.length>3&&n.jsxs("span",{className:"text-cyan-500/70 text-[10px] ml-0.5",children:["+",s.length-3]})]}),n.jsx(B,{icon:mn,size:12,className:M("transition-transform",t&&"rotate-90")})]}),t&&n.jsx("div",{className:"mt-2 rounded-lg border border-cyan-500/20 bg-cyan-500/5 max-h-80 overflow-y-auto",children:e.map((a,i)=>{const l=_n(a.url);return n.jsxs("a",{href:a.url,target:"_blank",rel:"noopener noreferrer",className:"flex items-start gap-2 p-2.5 border-b border-cyan-500/10 last:border-b-0 hover:bg-cyan-500/5 transition-colors",children:[n.jsx(Kn,{domain:l}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("div",{className:"text-sm font-medium text-primary-900 hover:underline line-clamp-1",children:a.title||l}),n.jsx("div",{className:"text-xs text-muted-foreground",children:l}),a.snippet&&n.jsx("p",{className:"text-xs text-muted-foreground/80 line-clamp-2 mt-0.5",children:a.snippet})]})]},`${a.url}-${i}`)})})]})}function Vi(e,t){const r=t!==void 0,s=t?.isError??!1;let a;r?s?a="output-error":a="output-available":a="input-available";let i;s&&t?.content?.[0]?.type==="text"&&(i=t.content[0].text||"Unknown error");const l=t?.content?.map(u=>u.type==="text"?String(u.text??""):"").join("").trim(),c=t?.details??(l&&l.length>0?l:void 0);return{type:e.name||"unknown",state:a,input:e.arguments,output:c,toolCallId:e.id,errorText:i}}function zn(e){return Je(e).map(r=>{const s=r.id??"",a=r.name??"",i=r.partialJson??"",l=r.arguments?JSON.stringify(r.arguments):"";return`${s}|${a}|${i}|${l}`}).join("||")}function Ji(e){if(!e)return"missing";const r=(Array.isArray(e.content)?e.content:[]).map(a=>a.type==="text"?String(a.text??""):"").join("").trim(),s=e.details?JSON.stringify(e.details):"";return`${e.toolCallId??""}|${e.toolName??""}|${e.isError?"1":"0"}|${r}|${s}`}function Un(e,t){if(!t)return"";const r=Je(e);return r.length===0?"":r.map(s=>s.id?Ji(t.get(s.id)):"missing").join("||")}function Qi(e){if(typeof e=="number"&&Number.isFinite(e))return e<1e12?e*1e3:e;if(typeof e=="string"){const t=Date.parse(e);if(!Number.isNaN(t))return t}return null}function $n(e){const t=[e.createdAt,e.created_at,e.timestamp,e.time,e.ts];for(const r of t){const s=Qi(r);if(s)return s}return null}function cn(e){const r=(Array.isArray(e.content)?e.content:[]).find(s=>s.type==="thinking");return r&&"thinking"in r?String(r.thinking??""):null}function Zi(e){const t=Array.isArray(e.content)?e.content:[],r=[];for(const s of t)s.type==="image"&&"source"in s&&typeof s.source?.data=="string"&&r.push(s);return r}const at=/^📎 Uploaded file:\s*(\/uploads\/\S+)\s*$/;function ea(e){if(e===null||Number.isNaN(e))return"Unknown size";if(e<1024)return`${e} B`;const t=["KB","MB","GB","TB"];let r=e/1024,s=0;for(;r>=1024&&s<t.length-1;)r/=1024,s++;return`${r.toFixed(1)} ${t[s]}`}function ta(e){if(!e)return[];const t=e.trimStart();if(t.startsWith(">")||t.startsWith("```"))return[];const r=e.split(`
|
|
10
|
+
`),s=[];for(const i of r){if(at.test(i)){s.push(i);continue}if(s.length>0&&i.trim()===""){s.push(i);continue}break}const a=r[0]??"";return at.test(a)?s.filter(i=>at.test(i)):[]}function na(e){const t=[],r=new Set;for(const s of ta(e)){const i=s.match(at)?.[1];!i||r.has(i)||(r.add(i),t.push({path:i,filename:i.split("/").pop()||i}))}return t}function ra(e){const t=e.split(`
|
|
11
|
+
`);if(!at.test(t[0]??""))return e.trim();let r=0;for(;r<t.length&&at.test(t[r]);)r++;for(;r<t.length&&t[r].trim()==="";)r++;return t.slice(r).join(`
|
|
12
|
+
`).replace(/\n{3,}/g,`
|
|
13
|
+
|
|
14
|
+
`).trim()}function sa({message:e,toolResultsByCallId:t,forceActionsVisible:r=!1,isStreaming:s=!1,isLastAssistant:a=!1,aggregatedSearchSources:i,wrapperRef:l,wrapperClassName:c,wrapperScrollMarginTop:u,messageDomId:d,highlighted:f=!1}){const{settings:p}=Qs(),m=e.role||"assistant",h=Me(e),w=cn(e),g=Zi(e),j=m==="user",k=on(e),y=zt(),_=Ps(b=>b.openInEditor),R=o.useMemo(()=>na(h),[h]),[H,T]=o.useState({}),U=o.useMemo(()=>ra(h),[h]);o.useEffect(()=>{let b=!1;async function A(){const N={};await Promise.all(R.map(async C=>{try{const K=await fetch(`/api/files/info?path=${encodeURIComponent(C.path)}`);if(!K.ok){N[C.path]=null;return}const x=await K.json();N[C.path]=typeof x.size=="number"?x.size:null}catch{N[C.path]=null}})),b||T(N)}return R.length>0?A():T({}),()=>{b=!0}},[R]);const q=async b=>{_(b),await y({to:"/files"})},E=m==="assistant"?Je(e):[],W=E.length>0,F=a&&!s&&p.showSearchSources&&i?i:[];return n.jsxs("div",{ref:l,id:d,"data-message-id":d,style:{contentVisibility:"auto",containIntrinsicSize:"auto 120px",...typeof u=="number"?{scrollMarginTop:`${u}px`}:void 0},className:M("opencami-message-item group mx-auto flex w-full max-w-[var(--opencami-chat-width)] flex-col gap-1 py-[var(--opencami-msg-padding-y)]",c,f&&"opencami-message-highlight",j?"items-end":"items-start"),children:[w&&p.showReasoningBlocks&&n.jsx("div",{className:"w-full max-w-[var(--opencami-chat-width)]",children:n.jsx(Bi,{content:w})}),g.length>0&&n.jsx("div",{className:M("flex flex-wrap gap-2 mb-2",j?"justify-end":"justify-start"),children:g.map((b,A)=>n.jsx("img",{src:`data:${b.source.media_type};base64,${b.source.data}`,alt:`Attachment ${A+1}`,loading:"lazy",decoding:"async",className:"max-w-[300px] max-h-[300px] rounded-lg object-cover"},A))}),R.length>0&&n.jsx("div",{className:M("mb-2 flex w-full flex-col gap-2",j?"items-end":"items-start"),children:R.map(b=>n.jsxs("button",{type:"button",onClick:()=>{q(b.path)},className:"flex max-w-full items-center gap-3 rounded-xl border border-primary-200 bg-primary-50 px-3 py-2 text-left hover:bg-primary-100",children:[n.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-primary-100",children:n.jsx(B,{icon:rr,size:18,className:"text-primary-600"})}),n.jsxs("div",{className:"min-w-0",children:[n.jsx("p",{className:"truncate text-sm font-medium text-primary-900",children:b.filename}),n.jsx("p",{className:"text-xs text-primary-600",children:ea(H[b.path]??null)})]})]},b.path))}),n.jsx(Nr,{className:M("min-w-0 max-w-full",j?"flex-row-reverse":""),children:n.jsx(Xi,{markdown:!j,className:M("text-primary-900 opencami-text-size min-w-0 max-w-full",j?"opencami-message-user bg-primary-100 px-4 py-[var(--opencami-user-bubble-py)] max-w-[85%]":"opencami-message-assistant bg-transparent w-full",!j&&s&&"stream-fade-in"),children:U})}),W&&p.showToolMessages&&n.jsx("div",{className:"mt-2 flex w-full min-w-0 max-w-[var(--opencami-chat-width)] flex-col gap-3 overflow-x-hidden",children:E.map(b=>{const A=b.id?t?.get(b.id):void 0,N=Vi(b,A);return n.jsx(Gi,{toolPart:N,defaultOpen:!1},b.id||b.name)})}),F.length>0&&n.jsx("div",{className:"w-full max-w-[var(--opencami-chat-width)]",children:n.jsx(qi,{sources:F})}),!W&&n.jsx(Wi,{text:h,timestamp:k,align:j?"end":"start",forceVisible:r})]})}function oa(e,t){return!(e.forceActionsVisible!==t.forceActionsVisible||e.isStreaming!==t.isStreaming||e.isLastAssistant!==t.isLastAssistant||e.aggregatedSearchSources!==t.aggregatedSearchSources||e.wrapperClassName!==t.wrapperClassName||e.wrapperRef!==t.wrapperRef||e.wrapperScrollMarginTop!==t.wrapperScrollMarginTop||e.messageDomId!==t.messageDomId||e.highlighted!==t.highlighted||(e.message.role||"assistant")!==(t.message.role||"assistant")||Me(e.message)!==Me(t.message)||cn(e.message)!==cn(t.message)||zn(e.message)!==zn(t.message)||Un(e.message,e.toolResultsByCallId)!==Un(t.message,t.toolResultsByCallId)||$n(e.message)!==$n(t.message))}const Zt=o.memo(sa,oa),ia=[/```[\s\S]*?```/g,/`[^`]+`/g,/\b(function|const|let|var|class|import|export|return|async|await)\b/g];function aa(e){const t=[],r=e.match(/"([^"]+)"|'([^']+)'/g);r&&t.push(...r.map(i=>i.replace(/['"]/g,"")));const s=e.match(/\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*\b/g);s&&t.push(...s.filter(i=>!["I","The","A","An","This"].includes(i)));const a=e.match(/`([^`]+)`/g);return a&&t.push(...a.map(i=>i.replace(/`/g,""))),[...new Set(t)].slice(0,5)}function la(e){return ia.some(t=>t.test(e))}function ca(e){return/^[\s]*[-*•\d]+[.)\s]/m.test(e)||/\b(first|second|third|1\.|2\.|3\.)/i.test(e)}function ua(e){return/\b(alternatively|another|other option|could also|you might|consider)\b/i.test(e)}function da(e){return/\b(because|since|due to|reason|why|how|what|when|where)\b/i.test(e)}function fa(e){return/\b(however|but|note|warning|caution|careful|important|keep in mind|be aware)\b/i.test(e)}function ma(e){const t=[],r=aa(e);if(la(e)&&(t.push({text:"Can you explain this code step by step?",type:"clarify"}),t.push({text:"How would I modify this for my use case?",type:"actionable"})),ca(e)&&(t.push({text:"Can you elaborate on the first point?",type:"expand"}),t.push({text:"Which of these is most important to start with?",type:"actionable"})),ua(e)&&(t.push({text:"What are the pros and cons of each approach?",type:"alternative"}),t.push({text:"Which option would you recommend and why?",type:"clarify"})),da(e)&&t.length<3&&t.push({text:"Can you give me a practical example?",type:"example"}),fa(e)&&t.length<3&&t.push({text:"What potential issues should I watch out for?",type:"clarify"}),r.length>0&&t.length<3){const i=r[0];t.push({text:`Tell me more about ${i}`,type:"expand"})}const s=[{text:"Can you give me a concrete example?",type:"example"},{text:"What would be the next steps?",type:"actionable"},{text:"How does this work in practice?",type:"expand"},{text:"Are there any common mistakes to avoid?",type:"clarify"},{text:"Can you simplify this explanation?",type:"clarify"}],a=new Set(t.map(i=>i.type));for(const i of s){if(t.length>=3)break;a.has(i.type)||(t.push(i),a.add(i.type))}for(const i of s){if(t.length>=3)break;t.some(l=>l.text===i.text)||t.push(i)}return t.slice(0,3)}function Hn(e){return ma(e).map(t=>t.text)}const pa={openai:{baseUrl:"https://api.openai.com/v1",model:"gpt-4.1-nano"},openrouter:{baseUrl:"https://openrouter.ai/api/v1",model:"openai/gpt-oss-120b"},ollama:{baseUrl:"http://localhost:11434/v1",model:"llama3.2"},custom:{baseUrl:"",model:""}},Rt={useLlmTitles:!0,useLlmFollowUps:!0,llmProvider:"openai",llmBaseUrl:"",llmModel:"",llmApiKey:""};function Er(e){return pa[e]}function ha(e){return e.llmBaseUrl.trim()?e.llmBaseUrl.trim():Er(e.llmProvider).baseUrl}function ga(e){return e.llmModel.trim()?e.llmModel.trim():Er(e.llmProvider).model}function Fn(e,t){return e.llmProvider==="ollama"?!0:e.llmProvider==="custom"?!!e.llmApiKey.trim()||e.llmBaseUrl.trim()&&e.llmModel.trim():t||!!e.llmApiKey.trim()}function xa(e){if(!e||typeof e!="object")return{settings:Rt};const{settings:t}=e;if(!t)return{settings:Rt};const{openaiApiKey:r,...s}=t,a=s.llmApiKey??r??"";return{settings:{...Rt,...s,llmApiKey:a}}}const Qe=dr()(ur(e=>({settings:{...Rt},updateSettings:t=>e(r=>({settings:{...r.settings,...t}})),clearApiKey:()=>e(t=>({settings:{...t.settings,llmApiKey:""}}))}),{name:"llm-settings",version:2,migrate:e=>xa(e)}));function Ql(){const e=Qe(l=>l.settings),t=Qe(l=>l.updateSettings),r=Qe(l=>l.clearApiKey),[s,a]=o.useState({hasEnvKey:!1,hasOpenRouterKey:!1,hasUserKey:!!e.llmApiKey,isAvailable:Fn(e,!1),isLoading:!0,error:null});o.useEffect(()=>{let l=!1;async function c(){try{const u=await fetch("/api/llm-features");if(!u.ok)throw new Error("Failed to check LLM status");const d=await u.json();if(l)return;const f=!!e.llmApiKey,p=e.llmProvider==="openrouter"?!!d.hasOpenRouterKey:d.hasEnvKey;a({hasEnvKey:d.hasEnvKey,hasOpenRouterKey:!!d.hasOpenRouterKey,hasUserKey:f,isAvailable:Fn(e,p),isLoading:!1,error:null})}catch(u){if(l)return;a(d=>({...d,isLoading:!1,error:u instanceof Error?u.message:"Failed to check status"}))}}return c(),()=>{l=!0}},[e.llmApiKey,e.llmProvider,e.llmBaseUrl,e.llmModel]);const i=o.useCallback(async l=>{try{const c=Tr({...e,llmApiKey:l}),d=await(await fetch("/api/llm-features",{method:"POST",headers:{"Content-Type":"application/json",...c},body:JSON.stringify({action:"test"})})).json();return d.ok?{valid:d.valid??!1,error:d.error}:{valid:!1,error:d.error||"Test failed"}}catch(c){return{valid:!1,error:c instanceof Error?c.message:"Network error"}}},[e]);return{settings:e,updateSettings:t,clearApiKey:r,status:s,testApiKey:i}}function Tr(e){const t=e.llmApiKey,r=ha(e),s=ga(e);return t?{"X-OpenAI-API-Key":t,...r?{"X-LLM-Base-URL":r}:{},...s?{"X-LLM-Model":s}:{}}:{...r?{"X-LLM-Base-URL":r}:{},...s?{"X-LLM-Model":s}:{}}}function Rr(){const e=Qe.getState().settings;return Tr(e)}async function ya(e,t){const r={"Content-Type":"application/json",...Rr()},s=await fetch("/api/llm-features",{method:"POST",headers:r,body:JSON.stringify({action:"followups",conversationContext:e}),signal:t});if(!s.ok)throw new Error(`API error: ${s.status}`);const a=await s.json();return a.ok&&Array.isArray(a.suggestions)&&a.suggestions.length>0?a.suggestions:[]}function wa(e,t,r){const s=Qe(_=>_.settings),a=s.useLlmFollowUps,{minResponseLength:i=50,timeoutMs:l=8e3,heuristicsOnly:c}=r??{},u=c??!a,[d,f]=o.useState([]),[p,m]=o.useState(!1),[h,w]=o.useState(null),[g,j]=o.useState(null),k=o.useRef(""),y=o.useRef(null);return o.useEffect(()=>{if(!e||e.trim().length<i){f([]),j(null),m(!1),w(null);return}const _=e.slice(0,200)+e.length;if(_===k.current)return;if(k.current=_,y.current&&y.current.abort(),u){const U=Hn(e);f(U),j("heuristic"),m(!1),w(null);return}const R=new AbortController;y.current=R,m(!0),w(null);const H=Hn(e);f(H),j("heuristic");const T=t?`Context: ${t}
|
|
15
|
+
|
|
16
|
+
Assistant's response:
|
|
17
|
+
${e.slice(0,2e3)}`:`Assistant's response:
|
|
18
|
+
${e.slice(0,2e3)}`;return ya(T,R.signal).then(U=>{R.signal.aborted||(U.length>0&&(f(U),j("llm")),m(!1))}).catch(U=>{R.signal.aborted||(w(U instanceof Error?U.message:String(U)),m(!1))}),()=>{}},[e,t,i,l,u,s.llmApiKey,s.llmBaseUrl,s.llmModel,s.llmProvider]),{suggestions:d,isLoading:p,error:h,source:g}}function ba({responseText:e,contextSummary:t,onSuggestionClick:r,disabled:s=!1,className:a}){const{suggestions:i,isLoading:l,source:c}=wa(e,t,{minResponseLength:50,timeoutMs:8e3});return i.length===0&&!l?null:n.jsxs("div",{className:M("flex flex-col gap-2 mt-3",a),children:[n.jsxs("div",{className:"flex items-center gap-1.5 text-xs text-primary-500",children:[n.jsx("span",{className:"text-primary-400",children:"✨"}),n.jsx("span",{children:l?n.jsxs("span",{className:"flex items-center gap-1",children:["Thinking of follow-ups",n.jsx(B,{icon:nr,size:12,strokeWidth:2,className:"animate-spin text-primary-400"})]}):c==="llm"?"AI suggestions":"Follow-up suggestions"})]}),n.jsx("div",{className:"flex flex-wrap gap-2",children:i.map((u,d)=>n.jsxs("button",{type:"button",disabled:s,onClick:()=>r(u),className:M("group inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full","text-sm text-primary-700 bg-primary-50 border border-primary-200","hover:bg-primary-100 hover:border-primary-300 hover:text-primary-900","focus:outline-none focus:ring-2 focus:ring-primary-500/20 focus:ring-offset-1","transition-all duration-150 cursor-pointer","disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-primary-50 disabled:hover:border-primary-200",l&&"opacity-75"),children:[n.jsx("span",{children:u}),n.jsx(B,{icon:mn,size:14,strokeWidth:2,className:"text-primary-400 group-hover:text-primary-600 group-hover:translate-x-0.5 transition-all duration-150"})]},`${d}-${u.slice(0,20)}`))})]})}const Wn=o.memo(ba);function Sa({className:e,variant:t="outline",scrollRef:r,...s}){const[a,i]=o.useState(!0),[l,c]=o.useState(!1),u=o.useRef(0),d=o.useCallback(()=>{const f=r.current;if(!f)return;const p=Math.abs(f.scrollHeight-f.scrollTop-f.clientHeight)<100;i(p)},[r]);return o.useLayoutEffect(()=>{const f=r.current;if(!f)return;const p=()=>{u.current=f.scrollTop,d()},m=new MutationObserver(()=>{f&&(f.scrollTop!==u.current&&(u.current=f.scrollTop),d())});return d(),f.addEventListener("scroll",p),m.observe(f,{childList:!0,subtree:!0}),()=>{f.removeEventListener("scroll",p),m.disconnect()}},[d,r]),o.useLayoutEffect(()=>{if(a){c(!1);return}const f=window.setTimeout(()=>{c(!0)},200);return()=>window.clearTimeout(f)},[a]),n.jsx(xe,{variant:"secondary",size:"icon-sm",className:M("pointer-events-auto rounded-full shadow-md","transition-all duration-100 ease-in-out",!a&&l?"translate-y-0 scale-100 opacity-100":"pointer-events-none translate-y-4 scale-98 opacity-0",e),onClick:()=>{const f=r.current;f&&(f.scrollTop=f.scrollHeight,i(!0))},...s,children:n.jsx(B,{icon:hn,size:18,strokeWidth:1.8})})}function va({className:e,viewportRef:t,scrollRef:r,viewportProps:s}){return n.jsxs(wr,{className:M("relative flex flex-1 min-h-0 flex-col",e),children:[n.jsx(br,{className:"relative will-change-transform overflow-x-hidden",ref:t,...s}),n.jsx("div",{className:"relative mx-auto w-full min-w-0 max-w-full px-5 sm:max-w-[768px]",children:n.jsx("div",{className:"pointer-events-none absolute bottom-10 right-10 z-50",children:n.jsx(Sa,{scrollRef:r})})}),n.jsx(Sr,{orientation:"vertical",children:n.jsx(vr,{})}),n.jsx(ti,{})]})}function ja(e,t){if(e===t)return!0;const r=Object.keys(e),s=Object.keys(t);if(r.length!==s.length)return!1;for(const a of r)if(e[a]!==t[a])return!1;return!0}function ka(e,t){return!(e.className!==t.className||e.viewportRef!==t.viewportRef||e.scrollRef!==t.scrollRef||!ja(e.viewportProps,t.viewportProps))}const Ca=o.memo(va,ka);function Na({viewportNode:e,children:t}){return e?Jr.createPortal(n.jsx("div",{className:"relative flex w-full min-w-0 max-w-full flex-col overflow-x-hidden",children:t}),e):null}function Ea({children:e,className:t,onUserScroll:r,...s}){const a=o.useRef(null),[i,l]=o.useState(null),c=o.useCallback(function(d){a.current=d,l(d)},[]);return o.useLayoutEffect(()=>{const u=a.current;if(!u)return;const d=()=>{r?.(u.scrollTop)};return u.addEventListener("scroll",d),()=>u.removeEventListener("scroll",d)},[r]),n.jsxs(n.Fragment,{children:[n.jsx(Ca,{className:t,viewportRef:c,scrollRef:a,viewportProps:s}),n.jsx(Na,{viewportNode:i,children:e})]})}const Ta=o.memo(Ea);function Ra({children:e,className:t,...r}){return n.jsx("div",{className:M("flex w-full min-w-0 max-w-full flex-col min-h-full overflow-x-hidden",t),...r,children:n.jsx("div",{className:"mx-auto w-full min-w-0 max-w-full px-2 md:px-5 sm:max-w-[768px] flex flex-col flex-1 min-h-full overflow-x-hidden",children:n.jsx("div",{className:"flex min-w-0 max-w-full flex-col space-y-3 md:space-y-6",children:e})})})}function Ma({...e}){return n.jsx("div",{className:"h-px w-full shrink-0 scroll-mt-4 pt-6","aria-hidden":"true",...e})}function Aa({as:e="span",className:t,duration:r=4,spread:s=20,children:a,...i}){const l=Math.min(Math.max(s,5),45),c=e;return n.jsx(c,{className:M("bg-size-[200%_auto] bg-clip-text font-medium text-transparent","animate-[shimmer_4s_infinite_linear]",t),style:{backgroundImage:`linear-gradient(to right, var(--color-primary-600) ${50-l}%, var(--color-primary-950) 50%, var(--color-primary-600) ${50+l}%)`,animationDuration:`${r}s`},...i,children:a})}function Ia({className:e}){return n.jsxs("div",{className:M("flex items-center gap-2",e),children:[n.jsxs("div",{className:"relative flex h-1.5 w-1.5",children:[n.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-primary-400 opacity-75"}),n.jsx("span",{className:"relative inline-flex rounded-full h-1.5 w-1.5 bg-size-[200%_auto] animate-[shimmer_2s_infinite_linear]",style:{backgroundImage:"linear-gradient(to right, var(--color-primary-600) 0%, var(--color-primary-950) 50%, var(--color-primary-600) 100%)"}})]}),n.jsx(Aa,{className:"text-sm",duration:2,children:"Generating..."})]})}function Oa({messages:e,loading:t,empty:r,emptyState:s,notice:a,noticePosition:i="start",waitingForResponse:l,isStreaming:c=!1,sessionKey:u,pinToTop:d,pinGroupMinHeight:f,headerHeight:p,contentStyle:m,onFollowUpClick:h,jumpToMessageId:w}){const g=o.useRef(null),j=o.useRef(null),k=o.useRef(!1),y=o.useRef(d),_=o.useRef(void 0),[R,H]=o.useState(null),T=o.useMemo(()=>e.filter(x=>x.role!=="toolResult"),[e]),U=o.useMemo(()=>{const x=new Map;for(const L of e){if(L.role!=="toolResult")continue;const S=L.toolCallId;typeof S=="string"&&S.trim().length>0&&x.set(S,L)}return x},[e]),q=o.useMemo(()=>{const x=P=>P?P.replace(/SECURITY NOTICE:[\s\S]*?<<<EXTERNAL_UNTRUSTED_CONTENT>>>/g,"").replace(/<<<\/?EXTERNAL_UNTRUSTED_CONTENT>>>/g,"").replace(/<<<\/?END_EXTERNAL_UNTRUSTED_CONTENT>>>/g,"").replace(/Source: Web (?:Search|Fetch)\n---/g,"").replace(/\n{2,}/g,`
|
|
19
|
+
`).trim():"",L=(P,$,Y)=>{try{const re=JSON.parse(P),te=Array.isArray(re)?re:re?.results??re?.web?.results??[];if(!Array.isArray(te))return!1;let Z=!1;for(const J of te)J?.url&&J?.title&&!Y.has(J.url)&&(Y.add(J.url),$.push({title:x(J.title),url:J.url,snippet:x(J.description||J.snippet||J.content||"")}),Z=!0);return Z}catch{return!1}},S=[],I=new Set;for(const P of T){if(P.role!=="assistant")continue;const $=Je(P);for(const Y of $){if(!Y.id)continue;const re=Y.name==="web_search",te=Y.name==="web_fetch",Z=Y.name==="exec";if(!re&&!te&&!Z)continue;const J=U.get(Y.id);if(!J)continue;const ie=J.content?.map(V=>V.type==="text"?String(V.text??""):"").join("").trim();if(ie){if(re||Z){if(Z&&(!ie.includes('"results"')||!ie.includes('"url"')))continue;let V=ie;const Q=ie.indexOf("{");Q>0&&(V=ie.slice(Q));const ve=V.lastIndexOf("}");ve>0&&(V=V.slice(0,ve+1)),L(V,S,I)}else if(te){const V=Y.arguments?.url;if(V&&!I.has(V)){I.add(V);let Q;try{Q=new URL(V).hostname}catch{Q=V}S.push({title:Q,url:V})}}}}}return S},[T,U]),E=T.map((x,L)=>({message:x,index:L})).filter(({message:x})=>x.role!=="user").map(({index:x})=>x).pop(),W=T.map((x,L)=>({message:x,index:L})).filter(({message:x})=>x.role==="user").map(({index:x})=>x).pop(),F=l&&(typeof W!="number"||typeof E!="number"||E<W),b=typeof W=="number"?W:-1,A=d&&b>=0,N=typeof E=="number"?T[E]:void 0,C=N?Me(N):"",K=!l&&!c&&C.length>0&&h!==void 0&&(typeof W!="number"||typeof E!="number"||E>W);return o.useLayoutEffect(()=>{if(!t){if(d){const x=!y.current||_.current!==W;y.current=!0,_.current=W,x&&j.current&&(k.current=!0,j.current.scrollIntoView({behavior:"auto",block:"start"}),window.setTimeout(()=>{k.current=!1},0));return}y.current=!1,_.current=W,g.current&&(k.current=!0,g.current.scrollIntoView({behavior:"auto",block:"end"}),window.setTimeout(()=>{k.current=!1},0))}},[t,T.length,u,d,W]),o.useEffect(()=>{if(!w||t)return;const x=document.getElementById(`message-${w}`);if(!x)return;x.scrollIntoView({behavior:"smooth",block:"center"}),H(w);const L=window.setTimeout(()=>{H(S=>S===w?null:S)},1800);return()=>window.clearTimeout(L)},[w,t,T]),n.jsx(Ta,{className:"flex-1 min-h-0 -mb-4",children:n.jsxs(Ra,{className:"pt-6",style:m,children:[a&&i==="start"?a:null,r&&!a?s??n.jsx("div",{"aria-hidden":!0}):A?n.jsxs(n.Fragment,{children:[T.slice(0,b).map((x,L)=>{const S=typeof x.id=="string"?x.id:void 0,I=S||L,P=typeof E=="number"&&L===E,$=typeof E=="number"&&L===E,Y=x.role==="assistant"&&Je(x).length>0;return n.jsx(Zt,{message:x,toolResultsByCallId:Y?U:void 0,forceActionsVisible:P,isStreaming:$&&c,isLastAssistant:$,aggregatedSearchSources:$?q:void 0,messageDomId:S?`message-${S}`:void 0,highlighted:R===S},I)}),n.jsxs("div",{className:"flex flex-col gap-[var(--opencami-msg-gap)]",style:{minHeight:`${Math.max(0,f)}px`},children:[T.slice(b).map((x,L)=>{const S=b+L,I=typeof x.id=="string"?x.id:void 0,P=I||S,$=typeof E=="number"&&S===E,Y=typeof E=="number"&&S===E,re=S===W?j:void 0,te=S===W?"scroll-mt-0":void 0,Z=S===W?p:void 0,J=x.role==="assistant"&&Je(x).length>0;return n.jsx(Zt,{message:x,toolResultsByCallId:J?U:void 0,forceActionsVisible:$,isStreaming:Y&&c,isLastAssistant:Y,aggregatedSearchSources:Y?q:void 0,wrapperRef:re,wrapperClassName:te,wrapperScrollMarginTop:Z,messageDomId:I?`message-${I}`:void 0,highlighted:R===I},P)}),F?n.jsx("div",{className:"py-2",children:n.jsx(Ia,{})}):null,K&&h?n.jsx(Wn,{responseText:C,onSuggestionClick:h,disabled:l}):null]})]}):n.jsxs(n.Fragment,{children:[T.map((x,L)=>{const S=typeof x.id=="string"?x.id:void 0,I=S||L,P=typeof E=="number"&&L===E,$=typeof E=="number"&&L===E,Y=x.role==="assistant"&&Je(x).length>0;return n.jsx(Zt,{message:x,toolResultsByCallId:Y?U:void 0,forceActionsVisible:P,isStreaming:$&&c,isLastAssistant:$,aggregatedSearchSources:$?q:void 0,messageDomId:S?`message-${S}`:void 0,highlighted:R===S},I)}),K&&h?n.jsx(Wn,{responseText:C,onSuggestionClick:h,disabled:l}):null]}),a&&i==="end"?a:null,n.jsx(Ma,{ref:g})]})})}function Da(e,t){return e.messages===t.messages&&e.loading===t.loading&&e.empty===t.empty&&e.emptyState===t.emptyState&&e.notice===t.notice&&e.noticePosition===t.noticePosition&&e.waitingForResponse===t.waitingForResponse&&e.isStreaming===t.isStreaming&&e.sessionKey===t.sessionKey&&e.pinToTop===t.pinToTop&&e.pinGroupMinHeight===t.pinGroupMinHeight&&e.headerHeight===t.headerHeight&&e.contentStyle===t.contentStyle&&e.onFollowUpClick===t.onFollowUpClick&&e.jumpToMessageId===t.jumpToMessageId}const La=o.memo(Oa,Da),Mr=o.createContext({isLoading:!1,value:"",setValue:()=>{},maxHeight:240,onSubmit:void 0,disabled:!1,textareaRef:Qr.createRef()});let lt=null,Xn=!1;function Pa(){Xn||typeof window>"u"||(Xn=!0,window.addEventListener("keydown",e=>{if(e.defaultPrevented||e.metaKey||e.ctrlKey||e.altKey)return;const t=e.target;if(!t)return;const r=t.tagName.toLowerCase();if(r==="input"||r==="textarea"||r==="select"||t.isContentEditable)return;const s=e.key.length===1,a=e.key==="Backspace";!s&&!a||!lt||lt.disabled||lt.focus()}))}function Ar(){return o.useContext(Mr)}function _a({className:e,isLoading:t=!1,maxHeight:r=240,value:s,onValueChange:a,onSubmit:i,children:l,disabled:c=!1,onClick:u,...d}){const[f,p]=o.useState(s||""),m=o.useRef(null);Pa();function h(g){p(g),a?.(g)}function w(g){c||m.current?.focus(),u?.(g)}return n.jsx(De,{children:n.jsx(Mr.Provider,{value:{isLoading:t,value:s??f,setValue:a??h,maxHeight:r,onSubmit:i,disabled:c,textareaRef:m},children:n.jsx("div",{onClick:w,className:M("bg-surface cursor-text rounded-[22px] outline outline-ink/10 shadow-[0px_12px_32px_0px_rgba(0,0,0,0.05)] py-3 gap-3 flex flex-col",c&&"cursor-not-allowed opacity-60",e),...d,children:l})})})}function Ka({className:e,onKeyDown:t,disableAutosize:r=!1,inputRef:s,...a}){const{value:i,setValue:l,maxHeight:c,onSubmit:u,disabled:d,textareaRef:f}=Ar();function p(g){!g||r||(g.style.height="auto",typeof c=="number"?g.style.height=`${Math.min(g.scrollHeight,c)}px`:g.style.height=`min(${g.scrollHeight}px, ${c})`)}function m(g){f.current=g,typeof s=="function"?s(g):s&&"current"in s&&(s.current=g),g?lt=g:lt===g&&(lt=null),p(g)}o.useLayoutEffect(()=>{if(!f.current||r)return;const g=f.current;g.style.height="auto",typeof c=="number"?g.style.height=`${Math.min(g.scrollHeight,c)}px`:g.style.height=`min(${g.scrollHeight}px, ${c})`},[i,c,r]);function h(g){p(g.target),l(g.target.value)}function w(g){g.key==="Enter"&&!g.shiftKey&&(g.preventDefault(),u?.()),t?.(g)}return n.jsx("textarea",{ref:m,value:i,onChange:h,onKeyDown:w,className:M("text-primary-950 opencami-text-size min-h-[28px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 pl-4 pr-1 placeholder:text-primary-500",e),rows:1,readOnly:d,"aria-disabled":d,...a})}function za({children:e,className:t,...r}){return n.jsx("div",{className:M("flex items-center gap-2",t),...r,children:e})}function Yn({tooltip:e,children:t,className:r,side:s="top",...a}){const{disabled:i}=Ar();return n.jsxs(Le,{...a,children:[n.jsx(Pe,{disabled:i,onClick:l=>l.stopPropagation(),children:t}),n.jsx(_e,{side:s,className:r,children:e})]})}const Ir="opencami-selected-model";function Ua(){if(typeof window>"u")return null;try{return localStorage.getItem(Ir)}catch{return null}}function $a(e){if(!(typeof window>"u"))try{localStorage.setItem(Ir,e)}catch{}}function Ha({className:e,onModelChange:t}){const[r,s]=o.useState([]),[a,i]=o.useState(""),[l,c]=o.useState(!0),[u,d]=o.useState(null),f=o.useRef(null);o.useEffect(()=>{let g=!0;async function j(){f.current?.abort();const k=new AbortController;f.current=k;try{c(!0),d(null);const y=await fetch("/api/models",{signal:k.signal});if(!y.ok)throw new Error("Failed to fetch models");const _=await y.json();if(!g)return;if(_.ok&&_.models.length>0){s(_.models);const R=Ua(),H=R&&_.models.some(T=>T.id===R)?R:_.defaultModel;i(H),t?.(H)}else throw new Error("No models available")}catch(y){if(y instanceof Error&&y.name==="AbortError"||!g)return;console.error("[model-selector] Error fetching models:",y),d(y instanceof Error?y.message:"Failed to load models"),s([{id:"default",name:"Default Model"}]),i("default")}finally{g&&c(!1)}}return j(),()=>{g=!1,f.current?.abort()}},[t]);function p(g){i(g),$a(g),t?.(g)}if(l)return n.jsxs("div",{className:M("flex items-center gap-2 text-xs text-primary-500",e),children:[n.jsx(B,{icon:Yt,size:14}),n.jsx("span",{children:"Loading..."})]});if(u||r.length===0)return null;const m=r.find(g=>g.id===a),h=m?.name||"Select Model",w=(()=>{if(!m?.name)return h;const j=m.name.replace(/\s*\([^)]*\)\s*$/,"").trim(),k=j.split(/\s+/);return k.length>3?k.slice(0,3).join(" "):j})();return r.length===1?n.jsxs("div",{className:M("flex items-center gap-2 text-xs text-primary-500",e),children:[n.jsx(B,{icon:Yt,size:14}),n.jsx("span",{className:"font-[450] md:hidden",children:w}),n.jsx("span",{className:"font-[450] hidden md:inline",children:h})]}):n.jsxs($t,{children:[n.jsxs(Ht,{className:M("inline-flex h-7 items-center gap-2 rounded-md px-2 text-xs font-[450] text-primary-600 hover:text-primary-900 hover:bg-primary-100",e),children:[n.jsx(B,{icon:Yt,size:14}),n.jsx("span",{className:"md:hidden",children:w}),n.jsx("span",{className:"hidden md:inline",children:h})]}),n.jsx(Ft,{side:"top",align:"start",children:r.map(g=>n.jsxs(Xe,{onClick:()=>p(g.id),className:"justify-between min-w-[180px]",children:[n.jsx("span",{children:g.name}),a===g.id&&n.jsx(B,{icon:pn,size:14,className:"text-primary-600"})]},g.id))})]})}const Or="opencami-personas-enabled",un="opencami-active-persona";function Fa(){if(typeof window>"u")return!0;try{const e=localStorage.getItem(Or);return e===null?!0:e==="true"}catch{return!0}}function Wa(){if(typeof window>"u")return null;try{const e=localStorage.getItem(un);return e?JSON.parse(e):null}catch{return null}}function Bn(e){if(!(typeof window>"u"))try{e?localStorage.setItem(un,JSON.stringify(e)):localStorage.removeItem(un)}catch{}}const Xa={core:"Core",creative:"Creative",curator:"Curator",learning:"Learning",lifestyle:"Lifestyle",professional:"Professional"};function Ya({className:e,onSelect:t}){const[r,s]=o.useState({}),[a,i]=o.useState(null),[l,c]=o.useState(!0),[u,d]=o.useState(!1),[f,p]=o.useState(Fa),m=o.useRef(null);o.useEffect(()=>{const j=k=>{k.key===Or&&p(k.newValue===null?!0:k.newValue==="true")};return window.addEventListener("storage",j),()=>window.removeEventListener("storage",j)},[]),o.useEffect(()=>{let j=!0;async function k(){m.current?.abort();const y=new AbortController;m.current=y;try{c(!0);const _=await fetch("/api/personas",{signal:y.signal});if(!_.ok){d(!1);return}const R=await _.json();if(!j)return;R.ok&&R.available?(s(R.personas),d(!0),i(Wa())):d(!1)}catch(_){if(_ instanceof Error&&_.name==="AbortError"||!j)return;d(!1)}finally{j&&c(!1)}}return k(),()=>{j=!1,m.current?.abort()}},[]);const h=o.useCallback(j=>{i(j),Bn(j),t(`/persona ${j.id}`)},[t]),w=o.useCallback(()=>{i(null),Bn(null),t("/persona exit")},[t]);if(l||!u||!f)return null;const g=Object.entries(r);return g.length===0?null:n.jsxs($t,{children:[n.jsxs(Ht,{className:M("inline-flex h-7 items-center gap-1.5 rounded-md px-2 text-xs font-[450] text-primary-600 hover:text-primary-900 hover:bg-primary-100",e),children:[n.jsx("span",{className:"text-sm","aria-hidden":"true",children:"🎭"}),a?n.jsxs("span",{className:"flex items-center gap-1",children:[n.jsx("span",{children:a.emoji}),n.jsx("span",{children:a.name})]}):n.jsx("span",{children:"Persona"})]}),n.jsxs(Ft,{side:"top",align:"start",className:"w-[300px] max-h-[360px] overflow-y-auto",children:[a&&n.jsxs(n.Fragment,{children:[n.jsxs(Xe,{onClick:w,className:"text-red-600 hover:bg-red-50",children:[n.jsx("span",{className:"text-sm",children:"✕"}),n.jsx("span",{children:"Exit Persona"}),n.jsxs("span",{className:"ml-auto text-[10px] text-primary-400",children:[a.emoji," ",a.name]})]}),n.jsx("div",{className:"my-1 h-px bg-primary-200"})]}),g.map(([j,k])=>n.jsxs("div",{children:[n.jsx("div",{className:"px-2 pb-0.5 pt-2 text-[10px] font-semibold uppercase tracking-wider text-primary-400",children:Xa[j]??j}),k.map(y=>n.jsxs(Xe,{onClick:()=>h(y),className:"justify-between",children:[n.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[n.jsx("span",{className:"text-sm flex-shrink-0",children:y.emoji}),n.jsx("span",{className:"truncate",children:y.name})]}),n.jsx("span",{className:"text-[11px] text-primary-400 truncate ml-2 max-w-[140px]",children:y.description})]},y.id))]},j))]})]})}const Ba=[{command:"/new",description:"Start a new conversation",usage:"/new"},{command:"/reset",description:"Reset conversation context",usage:"/reset"},{command:"/abort",description:"Abort current generation",usage:"/abort"},{command:"/status",description:"Show session status card",usage:"/status"},{command:"/usage",description:"Show token usage",usage:"/usage [off|tokens|full]"},{command:"/models",description:"List available models",usage:"/models"},{command:"/agents",description:"List available agents",usage:"/agents"},{command:"/sessions",description:"List active sessions",usage:"/sessions"},{command:"/model",description:"Switch model for this session",usage:"/model <alias>"},{command:"/reasoning",description:"Toggle reasoning mode",usage:"/reasoning [on|off|stream]"},{command:"/think",description:"Set thinking budget",usage:"/think [off|minimal|low|medium|high]"},{command:"/verbose",description:"Toggle verbose output",usage:"/verbose [on|full|off]"},{command:"/tts",description:"Text-to-speech controls",usage:"/tts [status|off|always]"},{command:"/settings",description:"Show current settings",usage:"/settings"},{command:"/help",description:"Show help",usage:"/help"}];function Ga({className:e,onCommandSelect:t}){const[r,s]=o.useState(!1);function a(i){t?.(i),s(!1)}return n.jsxs(n.Fragment,{children:[n.jsx(xe,{variant:"ghost",size:"sm",onClick:()=>s(!0),className:M("h-7 w-7 p-0",e),title:"Show commands (Ctrl+/)",children:n.jsx(B,{icon:En,size:16,className:"text-primary-500"})}),r&&n.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm",children:n.jsxs("div",{className:"bg-white dark:bg-neutral-900 border border-primary-200 dark:border-neutral-700 rounded-xl shadow-2xl w-full max-w-lg max-h-[80vh] overflow-hidden",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-primary-200 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-800",children:[n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(B,{icon:En,size:18,className:"text-primary-600 dark:text-primary-400"}),n.jsx("h2",{className:"font-semibold text-primary-900 dark:text-white",children:"Slash Commands"})]}),n.jsx(xe,{variant:"ghost",size:"sm",onClick:()=>s(!1),className:"h-7 w-7 p-0",children:n.jsx(B,{icon:Ut,size:16})})]}),n.jsxs("div",{className:"overflow-y-auto max-h-[60vh] p-2 bg-white dark:bg-neutral-900",children:[n.jsx("div",{className:"text-xs text-primary-500 dark:text-neutral-400 px-2 py-1 mb-2",children:"Type these commands in the chat input"}),Ba.map(i=>n.jsxs("button",{onClick:()=>a(i.command),className:"w-full flex items-start gap-3 px-3 py-2 rounded-lg hover:bg-primary-100 dark:hover:bg-neutral-800 transition-colors text-left",children:[n.jsx("code",{className:"text-sm font-mono font-medium text-primary-700 dark:text-primary-300 bg-primary-100 dark:bg-neutral-800 px-1.5 py-0.5 rounded min-w-[80px]",children:i.command}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("div",{className:"text-sm text-primary-900 dark:text-neutral-100",children:i.description}),i.usage&&i.usage!==i.command&&n.jsx("div",{className:"text-xs text-primary-500 dark:text-neutral-500 font-mono mt-0.5",children:i.usage})]})]},i.command))]}),n.jsx("div",{className:"px-4 py-2 border-t border-primary-200 dark:border-neutral-700 bg-neutral-50 dark:bg-neutral-800",children:n.jsxs("div",{className:"text-xs text-primary-500 dark:text-neutral-400",children:["Press ",n.jsx("kbd",{className:"px-1 py-0.5 bg-primary-200 dark:bg-neutral-700 rounded text-primary-700 dark:text-neutral-300",children:"Esc"})," to close"]})})]})})]})}const qa=10*1024*1024,it=1280,Va=.75,Ja=300*1024,Qa=["image/png","image/jpeg","image/gif","image/webp"],Dr=["pdf","txt","md","csv","json","xml","yaml","yml","log","py","js","ts","html","css"],Za=[".png",".jpg",".jpeg",".gif",".webp",...Dr.map(e=>`.${e}`)].join(",");function el(){if(typeof document>"u")return!1;try{const e=document.createElement("canvas");return!!(e.getContext&&e.getContext("2d"))}catch{return!1}}async function tl(e){if(!el())throw new Error("Image compression not available in this browser");return new Promise((t,r)=>{const s=new Image,a=URL.createObjectURL(e),i=()=>{URL.revokeObjectURL(a)};s.onload=()=>{try{let l=s.width,c=s.height;(l>it||c>it)&&(l>c?(c=Math.round(c*it/l),l=it):(l=Math.round(l*it/c),c=it));const u=document.createElement("canvas");u.width=l,u.height=c;const d=u.getContext("2d");if(!d){i(),r(new Error("Failed to get canvas context"));return}d.drawImage(s,0,0,l,c);const f=e.type==="image/png"?"image/png":"image/jpeg";let p=Va,m=u.toDataURL(f,p);if(f==="image/jpeg"){const w=Ja*1.37;for(;m.length>w&&p>.3;)p-=.1,m=u.toDataURL(f,p)}const h=m.split(",")[1];if(!h){i(),r(new Error("Failed to encode image"));return}i(),t(h)}catch(l){i(),r(l instanceof Error?l:new Error("Image compression failed"))}},s.onerror=()=>{i(),r(new Error("Failed to load image"))},s.src=a})}function Lr(e){return Qa.includes(e.type)}function nl(e){const t=e.name.includes(".")?e.name.split(".").pop()?.toLowerCase():"";return!!(t&&Dr.includes(t))}async function rl(e){const t=crypto.randomUUID();if(!Lr(e))return{id:t,file:e,preview:null,type:"file",base64:null,error:"Unsupported image type. Please use PNG, JPG, GIF, or WebP images."};if(e.size>qa)return{id:t,file:e,preview:null,type:"image",base64:null,error:"Image is too large. Maximum size is 10MB."};try{const r=await tl(e),s=URL.createObjectURL(e);return{id:t,file:e,preview:s,type:"image",base64:r}}catch(r){return{id:t,file:e,preview:null,type:"image",base64:null,error:r instanceof Error?r.message:"Failed to process image"}}}function sl({onFilesSelect:e,disabled:t=!1,className:r}){const s=o.useRef(null),a=o.useCallback(()=>{s.current?.click()},[]),i=o.useCallback(async l=>{const c=Array.from(l.target.files??[]);c.length!==0&&(l.target.value="",e(c))},[e]);return n.jsxs(n.Fragment,{children:[n.jsx("input",{ref:s,type:"file",accept:Za,multiple:!0,onChange:i,className:"hidden","aria-hidden":"true"}),n.jsx(xe,{variant:"ghost",size:"icon-sm",onClick:a,disabled:t,className:r,"aria-label":"Attach file",type:"button",children:n.jsx(B,{icon:ws,size:18,strokeWidth:1.8})})]})}function Gn(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ol(e){const t=e.split(".");return t.length>1&&t.pop()?.toUpperCase()||""}function il({attachment:e,onRemove:t,className:r}){o.useEffect(()=>()=>{e.preview&&URL.revokeObjectURL(e.preview)},[e.preview]);const s=!!e.error;return e.type==="file"&&!s?n.jsxs("div",{className:M("inline-flex max-w-full items-center gap-2 rounded-full border border-primary-200 bg-primary-50 px-3 py-1.5 text-xs text-primary-800",r),children:[n.jsxs("span",{className:"truncate",children:["📄 ",e.file.name," (",Gn(e.file.size),")"]}),n.jsx("button",{onClick:()=>t(e.id),className:"shrink-0 text-primary-500 hover:text-primary-800","aria-label":"Remove attachment",type:"button",children:"✕"})]}):n.jsxs("div",{className:M("relative flex items-center gap-3 rounded-xl border p-2 pr-3",s?"border-red-300 bg-red-50":"border-primary-200 bg-primary-50",r),children:[n.jsx("div",{className:"relative shrink-0",children:e.type==="image"&&e.preview?n.jsx("img",{src:e.preview,alt:e.file.name,className:"h-12 w-12 rounded-lg object-cover"}):n.jsx("div",{className:"flex h-12 w-12 items-center justify-center rounded-lg bg-primary-100",children:n.jsx(B,{icon:rr,size:24,className:"text-primary-500"})})}),n.jsxs("div",{className:"min-w-0 flex-1",children:[n.jsx("p",{className:"truncate text-sm font-medium text-primary-900",children:e.file.name}),s?n.jsx("p",{className:"text-xs text-red-600",children:e.error}):n.jsxs("p",{className:"text-xs text-primary-500",children:[ol(e.file.name)," •"," ",Gn(e.file.size)]})]}),n.jsx(xe,{variant:"ghost",size:"icon-sm",onClick:()=>t(e.id),className:"h-6 w-6 shrink-0 rounded-full hover:bg-primary-200","aria-label":"Remove attachment",type:"button",children:n.jsx(B,{icon:Ut,size:14})})]})}function al({attachments:e,onRemove:t,className:r}){return e.length===0?null:n.jsx("div",{className:M("flex flex-wrap gap-2 px-4",r),children:e.map(s=>n.jsx(il,{attachment:s,onRemove:t},s.id))})}function ll({commands:e,selectedIndex:t,onSelect:r,className:s}){return e.length===0?null:n.jsx("div",{className:M("absolute left-2 right-2 md:left-5 md:right-5 bottom-full mb-2 z-20 rounded-xl border border-white/10 bg-neutral-900/95 shadow-2xl backdrop-blur-sm overflow-hidden",s),role:"listbox","aria-label":"Slash commands",children:n.jsx("div",{className:"max-h-56 overflow-y-auto p-1",children:e.map((a,i)=>{const l=i===t;return n.jsx("button",{type:"button",role:"option","aria-selected":l,onMouseDown:c=>{c.preventDefault(),r(a)},className:M("w-full rounded-md px-3 py-2 text-left transition-colors",l?"bg-neutral-800":"hover:bg-neutral-800/80"),children:n.jsxs("div",{className:"flex items-start gap-3",children:[n.jsx("code",{className:"min-w-[90px] font-mono text-xs text-primary-300",children:a.command}),n.jsx("span",{className:"text-xs text-neutral-300",children:a.description})]})},a.command)})})})}const cl=o.memo(ll),dn=dr()(ur(e=>({level:"low",setLevel:t=>e({level:t})}),{name:"thinking-level"}));function ul(){const e=dn(r=>r.level),t=dn(r=>r.setLevel);return{level:e,setLevel:t}}const en=[{value:"off",label:"Off",description:"No reasoning",shortLabel:"Off"},{value:"low",label:"Low",description:"Think",shortLabel:"Low"},{value:"medium",label:"Medium",description:"Think harder",shortLabel:"Medium"},{value:"high",label:"High",description:"Ultrathink",shortLabel:"High"}];function dl({className:e}){const{level:t,setLevel:r}=ul(),s=en.find(a=>a.value===t)??en[1];return n.jsxs($t,{children:[n.jsxs(Ht,{className:M("inline-flex h-7 items-center gap-2 rounded-md px-2 text-xs font-[450] text-primary-600 hover:text-primary-900 hover:bg-primary-100",e),children:[n.jsx(B,{icon:rn,size:20,strokeWidth:1.5,className:M(t==="off"?"text-primary-400":"text-primary-700")}),n.jsx("span",{className:"text-pretty",children:s.shortLabel})]}),n.jsx(Ft,{side:"top",align:"start",className:"min-w-[190px]",children:en.map(a=>n.jsxs(Xe,{onClick:()=>r(a.value),className:"justify-between",children:[n.jsxs("span",{className:"flex flex-col text-pretty",children:[n.jsx("span",{className:"text-sm text-primary-900",children:a.label}),n.jsx("span",{className:"text-xs text-primary-500",children:a.description})]}),t===a.value&&n.jsx(B,{icon:pn,size:20,strokeWidth:1.5,className:"text-primary-600"})]},a.value))})]})}const qn=[{command:"/haiku",description:"Switch to Claude Haiku 4.5"},{command:"/sonnet",description:"Switch to Claude Sonnet 4.5"},{command:"/opus",description:"Switch to Claude Opus 4.5"},{command:"/opus46",description:"Switch to Claude Opus 4.6"},{command:"/codex",description:"Switch to GPT 5.3 Codex"},{command:"/glm",description:"Switch to GLM 4.7"},{command:"/kimi",description:"Switch to Kimi K2.5"},{command:"/minimax",description:"Switch to MiniMax M2.1"},{command:"/grok",description:"Switch to Grok 4.1 Fast"},{command:"/model",description:"Show model picker or switch model"},{command:"/new",description:"New chat (optional: /new model)"},{command:"/reset",description:"Reset session"},{command:"/stop",description:"Stop current generation"},{command:"/compact",description:"Compact conversation context"},{command:"/help",description:"Show available commands"},{command:"/commands",description:"List all commands"},{command:"/status",description:"Show session status & usage"},{command:"/whoami",description:"Show your sender ID"},{command:"/context",description:"Show context window details"},{command:"/usage",description:"Toggle usage footer (off/tokens/full/cost)"},{command:"/think",description:"Set thinking level (off/low/medium/high)"},{command:"/reasoning",description:"Toggle reasoning (on/off/stream)"},{command:"/verbose",description:"Toggle verbose mode (on/full/off)"},{command:"/elevated",description:"Toggle elevated permissions (on/off/ask)"},{command:"/exec",description:"Configure exec settings"},{command:"/queue",description:"Show/configure message queue"},{command:"/tts",description:"Text-to-speech (off/always/tagged/status)"},{command:"/subagents",description:"List/stop/log sub-agent runs"},{command:"/followups",description:"Show follow-up suggestions"},{command:"/skill",description:"Run a skill by name"},{command:"/allowlist",description:"List/add/remove allowlist entries"},{command:"/approve",description:"Resolve exec approval (allow/deny)"},{command:"/config",description:"Show/get/set config (owner-only)"},{command:"/debug",description:"Runtime overrides (owner-only)"},{command:"/send",description:"Toggle message sending (on/off)"},{command:"/restart",description:"Restart gateway"},{command:"/activation",description:"Set activation mode (mention/always)"},{command:"/dock-telegram",description:"Switch replies to Telegram"},{command:"/dock-discord",description:"Switch replies to Discord"},{command:"/bash",description:"Run host shell command"}];function fl({onSubmit:e,isLoading:t,disabled:r,wrapperRef:s,inputRef:a}){const[i,l]=o.useState(""),[c,u]=o.useState(""),[d,f]=o.useState([]),[p,m]=o.useState(0),[h,w]=o.useState(!1),[g,j]=o.useState(!1),[k,y]=o.useState(!1),[_,R]=o.useState(0),[H,T]=o.useState(!1),U=o.useRef(null),q=o.useRef([]),E=o.useRef(null),W=o.useRef(null),F=o.useRef(null),b=o.useRef(null),A=o.useMemo(()=>/^\/\S*$/.test(i)&&!h,[i,h]),N=o.useMemo(()=>A?i.slice(1).toLowerCase():"",[A,i]),C=o.useMemo(()=>A?N?qn.filter(O=>O.command.slice(1).toLowerCase().startsWith(N)):qn:[],[A,N]),K=o.useCallback(O=>{b.current=O,a&&(typeof a=="function"?a(O):a.current=O)},[a]),x=o.useCallback(()=>{typeof window>"u"||window.requestAnimationFrame(()=>{b.current?.focus()})},[]),L=o.useCallback(()=>{l(""),f([]),m(0),w(!1),x()},[x]),S=o.useCallback(O=>{l(G=>{const X=`📎 Uploaded file: ${O}
|
|
20
|
+
|
|
21
|
+
Please analyze this file.`;return G.trim()?`${G.trim()}
|
|
22
|
+
|
|
23
|
+
${X}`:X})},[]),I=o.useCallback(async()=>{await fetch("/api/files/mkdir",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:"/uploads"})})},[]),P=o.useCallback(async O=>{const G=crypto.randomUUID();if(!nl(O))return{id:G,file:O,preview:null,type:"file",base64:null,error:"Unsupported file type for upload."};try{await I();const X=new FormData;X.append("path","/uploads"),X.append("file",O);const ne=await fetch("/api/files/upload",{method:"POST",body:X});if(!ne.ok){const Se=await ne.text();throw new Error(Se||"File upload failed")}const ee=(await ne.json()).files?.[0]?.path;if(!ee)throw new Error("Upload succeeded but no path was returned");return S(ee),{id:G,file:O,preview:null,type:"file",base64:null,uploadedPath:ee}}catch(X){return{id:G,file:O,preview:null,type:"file",base64:null,error:X instanceof Error?X.message:"File upload failed"}}},[S,I]),$=o.useCallback(async O=>{if(O.length===0)return;const G=await Promise.all(O.map(X=>Lr(X)?rl(X):P(X)));f(X=>[...X,...G]),x()},[x,P]),Y=o.useCallback(O=>{f(G=>G.filter(X=>X.id!==O))},[]),re=o.useCallback(O=>{Array.from(O.dataTransfer.types).includes("Files")&&(O.preventDefault(),O.dataTransfer.dropEffect="copy",j(!0))},[]),te=o.useCallback(O=>{O.preventDefault();const G=O.relatedTarget;G&&O.currentTarget.contains(G)||j(!1)},[]),Z=o.useCallback(async O=>{O.preventDefault(),j(!1);const G=Array.from(O.dataTransfer.files??[]);G.length!==0&&await $(G)},[$]),J=o.useCallback(O=>{l(O),m(0),w(!1),x()},[x]),ie=o.useCallback(O=>{l(O),m(0),w(!1)},[]),V=o.useCallback(O=>{l(`${O.command} `),m(0),w(!1),x()},[x]),Q=o.useCallback(()=>{if(r)return;if(A&&C.length>0){const X=Math.min(p,C.length-1);V(C[X]);return}const O=i.trim(),G=d.filter(X=>!X.error&&X.base64);O.length===0&&G.length===0||(e(O,{reset:L,setValue:J,model:c||void 0,attachments:G}),x())},[r,A,C,p,V,i,d,e,L,J,c,x]),ve=o.useCallback(O=>{e(O,{reset:L,setValue:J,model:c||void 0,attachments:[]}),x()},[x,e,L,J,c]),Ee=o.useCallback(O=>{if(A){if(O.key==="Escape"){O.preventDefault(),w(!0),m(0);return}if(C.length!==0){if(O.key==="ArrowDown"){O.preventDefault(),m(G=>(G+1)%C.length);return}if(O.key==="ArrowUp"){O.preventDefault(),m(G=>(G-1+C.length)%C.length);return}if(O.key==="Tab"){O.preventDefault();const G=Math.min(p,C.length-1);V(C[G])}}}},[A,C,p,V]);o.useEffect(()=>()=>{W.current?.abort(),E.current&&clearInterval(E.current),U.current&&U.current.state!=="inactive"&&U.current.stop(),F.current&&F.current.abort()},[]);const de=o.useCallback(()=>{if(typeof window>"u")return"auto";try{return localStorage.getItem("opencami-stt-provider")||"auto"}catch{return"auto"}},[]),ae=o.useCallback(()=>{U.current&&U.current.state!=="inactive"&&U.current.stop(),F.current&&F.current.stop(),E.current&&(clearInterval(E.current),E.current=null),y(!1),R(0)},[]),pe=o.useCallback(async()=>{const O=de();if(O==="browser"){const G=window.SpeechRecognition||window.webkitSpeechRecognition;if(!G){alert("Web Speech API is not supported in this browser.");return}const X=new G;X.continuous=!0,X.interimResults=!1,X.lang=navigator.language||"en-US",F.current=X,y(!0),R(0),E.current=setInterval(()=>{R(se=>se>=119?(ae(),0):se+1)},1e3);let ne="";X.onresult=se=>{for(let ee=se.resultIndex;ee<se.results.length;ee++)se.results[ee].isFinal&&(ne+=se.results[ee][0].transcript)},X.onend=()=>{y(!1),R(0),E.current&&clearInterval(E.current),ne.trim()&&(l(se=>se+(se?" ":"")+ne.trim()),x())},X.onerror=()=>{y(!1),R(0),E.current&&clearInterval(E.current)},X.start();return}try{const G=await navigator.mediaDevices.getUserMedia({audio:!0}),X=MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4",ne=new MediaRecorder(G,{mimeType:X});U.current=ne,q.current=[],ne.ondataavailable=se=>{se.data.size>0&&q.current.push(se.data)},ne.onstop=async()=>{G.getTracks().forEach(ee=>ee.stop());const se=new Blob(q.current,{type:X});if(se.size!==0){T(!0);try{const ee=new FormData;ee.append("audio",se,`recording.${X==="audio/webm"?"webm":"mp4"}`),O!=="auto"&&ee.append("provider",O),W.current?.abort();const Se=new AbortController;W.current=Se;const he=await(await fetch("/api/stt",{method:"POST",body:ee,signal:Se.signal})).json();he.ok&&he.text?(l(Te=>Te+(Te?" ":"")+he.text),x()):he.ok||(console.warn("STT failed:",he.error),alert(he.error||"Speech-to-text failed. Try the Browser provider in Settings."))}catch(ee){if(ee instanceof Error&&ee.name==="AbortError")return;console.warn("STT request failed:",ee),alert("Could not reach speech-to-text service.")}finally{T(!1)}}},y(!0),R(0),E.current=setInterval(()=>{R(se=>se>=119?(ae(),0):se+1)},1e3),ne.start()}catch(G){const X=G instanceof Error?G.message:String(G);if(X.includes("NotAllowedError")||X.includes("Permission"))try{(await navigator.permissions.query({name:"microphone"})).state==="denied"?alert("Microphone access is blocked. Please enable it in your browser/app settings."):alert("Microphone permission was not granted. Please try again and allow access when prompted.")}catch{alert("Could not access microphone. Please check your browser settings and allow microphone access for this site.")}else alert("Could not access microphone: "+X)}},[de,ae,x]),fe=o.useCallback(()=>{k?ae():pe()},[k,ae,pe]),D=d.filter(O=>!O.error&&O.base64),me=r||i.trim().length===0&&D.length===0;return n.jsxs("div",{className:"mx-auto w-full max-w-[var(--opencami-chat-width)] px-2 md:px-5 relative pb-1 md:pb-3",ref:s,onDragOver:re,onDragLeave:te,onDrop:Z,children:[g&&n.jsx("div",{className:"pointer-events-none absolute inset-2 z-20 flex items-center justify-center rounded-2xl border-2 border-dashed border-primary-400 bg-primary-50/90 text-sm font-medium text-primary-700",children:"Drop files here"}),n.jsxs(_a,{value:i,onValueChange:ie,onSubmit:Q,isLoading:t,disabled:r,children:[n.jsx(al,{attachments:d,onRemove:Y}),A&&C.length>0&&n.jsx(cl,{commands:C,selectedIndex:Math.min(p,C.length-1),onSelect:V}),n.jsx(Ka,{placeholder:"Type a message…",inputRef:K,onKeyDown:Ee}),n.jsxs(za,{className:"justify-between px-3",children:[n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx(Ha,{onModelChange:u}),n.jsx(dl,{}),n.jsx(Ya,{onSelect:ve}),n.jsx(Ga,{onCommandSelect:O=>ie(O+" ")})]}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx(sl,{onFilesSelect:$,disabled:r}),n.jsx(Yn,{tooltip:k?"Stop recording":"Voice input",children:n.jsx(xe,{onClick:fe,disabled:r||H,size:"icon-sm",variant:k?"destructive":"ghost",className:`rounded-full ${k?"animate-pulse":""}`,"aria-label":k?"Stop recording":"Voice input",children:H?n.jsx("span",{className:"size-4 animate-spin rounded-full border-2 border-current border-t-transparent"}):k?n.jsxs("span",{className:"flex items-center gap-1",children:[n.jsx("span",{className:"size-2 rounded-full bg-red-500"}),n.jsxs("span",{className:"text-xs tabular-nums",children:[Math.floor(_/60),":",String(_%60).padStart(2,"0")]}),n.jsx(B,{icon:tr,size:14,strokeWidth:2})]}):n.jsx(B,{icon:bs,size:18,strokeWidth:2})})}),n.jsx(Yn,{tooltip:"Send message",children:n.jsx(xe,{onClick:Q,disabled:me,size:"icon-sm",className:"rounded-full","aria-label":"Send message",children:n.jsx(B,{icon:Ss,size:18,strokeWidth:2})})})]})]})]})]})}const ml=o.memo(fl);function pl({title:e,description:t,detail:r,actionLabel:s,onAction:a,className:i}){return n.jsx("div",{className:M("w-full max-w-[var(--opencami-chat-width)]",i),children:n.jsx(Nr,{children:n.jsxs("div",{className:"w-full rounded-xl border border-primary-200 bg-primary-50 p-4 text-primary-900",children:[n.jsx("div",{className:"text-balance font-medium",children:e}),n.jsx("div",{className:"mt-2 text-pretty text-primary-700",children:t}),r?n.jsx("div",{className:"mt-2 text-xs text-primary-600",children:r}):null,s&&a?n.jsx("div",{className:"mt-3",children:n.jsx(xe,{size:"sm",variant:"outline",onClick:a,children:s})}):null]})})})}function hl({state:e,error:t,onRetry:r,className:s}){const a=e==="checking",i=a?"Checking gateway connection...":"OpenClaw gateway is unreachable",l=a?"This dashboard needs access to the OpenClaw gateway configured by your server environment variables.":"";return n.jsx(pl,{title:i,description:a?l:n.jsxs(n.Fragment,{children:["We could not reach the gateway from the dashboard server. Start the gateway and confirm your server environment has"," ",n.jsx("span",{className:"font-mono",children:"CLAWDBOT_GATEWAY_URL"})," plus"," ",n.jsx("span",{className:"font-mono",children:"CLAWDBOT_GATEWAY_TOKEN"})," (or"," ",n.jsx("span",{className:"font-mono",children:"CLAWDBOT_GATEWAY_PASSWORD"}),")."]}),detail:a?null:t,actionLabel:a?void 0:"Retry",onAction:a?void 0:r,className:s})}function gl(){const e=o.useRef(null),t=o.useRef(null),r=o.useRef(null),[s,a]=o.useState(0),[i,l]=o.useState(0);return o.useLayoutEffect(()=>{const c=e.current,u=t.current,d=r.current;if(!d)return;const f=()=>{const m=c?.offsetHeight??0,h=u?.offsetHeight??0,w=d.clientHeight;d.style.setProperty("--chat-header-height",`${Math.max(0,m)}px`),d.style.setProperty("--chat-composer-height",`${Math.max(0,h)}px`),l(m),a(Math.max(0,w-m-h))};f();const p=new ResizeObserver(()=>f());return c&&p.observe(c),u&&p.observe(u),()=>p.disconnect()},[]),{headerRef:e,composerRef:t,mainRef:r,pinGroupMinHeight:s,headerHeight:i}}function xl({activeFriendlyId:e,activeSessionKey:t,forcedSessionKey:r,isNewChat:s,isRedirecting:a,activeExists:i,sessionsReady:l,queryClient:c}){const u=r||t||e,d=ce.history(e,u),f=Mt({queryKey:d,queryFn:async function(){const y=c.getQueryData(d),_=Array.isArray(y?.messages)?y.messages.filter(T=>T.status==="sending"||T.__optimisticId?!0:!!T.clientId):[],R=await io({sessionKey:u,friendlyId:e});if(!_.length)return R;const H=yl(R.messages,_);return{...R,messages:H}},enabled:!s&&!!e&&!a&&(!l||i),placeholderData:function(){return c.getQueryData(d)},gcTime:1e3*60*10}),p=o.useRef(""),m=o.useRef([]),h=o.useMemo(()=>{const k=Array.isArray(f.data?.messages)?f.data.messages:[],y=k[k.length-1],_=y&&typeof y.id=="string"?y.id:"",R=`${k.length}:${y?.role??""}:${_}:${Me(y??{content:[]}).slice(-32)}`;return R===p.current?m.current:(p.current=R,m.current=k,k)},[f.data?.messages]),w=f.error instanceof Error?f.error.message:null,g=o.useMemo(()=>{if(r)return r;const k=f.data?.sessionKey;return typeof k=="string"&&k.trim().length>0?k.trim():t},[t,r,f.data?.sessionKey]);return{historyQuery:f,historyMessages:h,displayMessages:h,historyError:w,resolvedSessionKey:g,activeCanonicalKey:s?"new":g||e,sessionKeyForHistory:u}}function yl(e,t){if(!t.length)return e;const r=[...e];for(const s of t)e.some(i=>{if(s.clientId&&i.clientId&&s.clientId===i.clientId||s.__optimisticId&&i.__optimisticId&&s.__optimisticId===i.__optimisticId)return!0;if(s.role&&i.role&&s.role!==i.role)return!1;const l=Me(s);if(!l||l!==Me(i))return!1;const c=on(s),u=on(i);return Math.abs(c-u)<=1e4})||r.push(s);return r}function wl(e){const[t,r]=o.useState(!1);return o.useLayoutEffect(()=>{const s=window.matchMedia("(max-width: 768px)"),a=()=>r(s.matches);return a(),s.addEventListener("change",a),()=>s.removeEventListener("change",a)},[]),o.useLayoutEffect(()=>{t&&Fe(e,function(a){return{...a,isSidebarCollapsed:!0}})},[t,e]),{isMobile:t}}function bl({activeFriendlyId:e,isNewChat:t,forcedSessionKey:r}){const s=Mt({queryKey:ce.sessions,queryFn:oo,refetchInterval:3e4}),a=o.useMemo(()=>{const p=s.data??[];return Ei(p)},[s.data]),i=o.useMemo(()=>a.find(p=>p.friendlyId===e),[a,e]),l=o.useMemo(()=>t||r||Cr(e)?!0:a.some(p=>p.friendlyId===e),[e,r,t,a]),c=i?.key??"",u=o.useMemo(()=>i?i.label||i.title||i.derivedTitle||i.friendlyId:e,[e,i]),d=s.error instanceof Error?s.error.message:null,f=o.useMemo(()=>({totalTokens:i?.totalTokens,contextTokens:i?.contextTokens}),[i?.totalTokens,i?.contextTokens]);return{sessionsQuery:s,sessions:a,activeSession:i,activeExists:l,activeSessionKey:c,activeTitle:u,activeTokens:f,sessionsError:d}}function Sl(){const e=Qe(d=>d.settings),[t,r]=o.useState(!1),[s,a]=o.useState(null),[i,l]=o.useState(null),c=o.useRef(null);return{generateTitle:o.useCallback(async d=>{c.current&&c.current.abort();const f=new AbortController;c.current=f,r(!0);try{const p={"Content-Type":"application/json",...Rr()},m=await fetch("/api/llm-features",{method:"POST",headers:p,body:JSON.stringify({action:"title",message:d}),signal:f.signal});if(!m.ok)throw new Error(`API error: ${m.status}`);const h=await m.json();if(f.signal.aborted)throw new Error("Aborted");const w=h.title||d.slice(0,50),g=w.length>64?w.slice(0,61)+"...":w,j=h.source||"heuristic";return a(g),l(j),{title:g,source:j,error:h.error}}catch(p){if(p instanceof Error&&p.name==="AbortError")throw p;const m=vl(d);return a(m),l("heuristic"),{title:m,source:"heuristic",error:p instanceof Error?p.message:"Unknown error"}}finally{r(!1),c.current===f&&(c.current=null)}},[e.llmApiKey,e.llmBaseUrl,e.llmModel,e.llmProvider]),isGenerating:t,lastTitle:s,lastSource:i}}function vl(e){let t=e.replace(/```[\s\S]*?```/g," ");t=t.replace(/`[^`]+`/g," "),t=t.replace(/https?:\/\/[^\s]+/g," "),t=t.replace(/[^\w\s.,!?'-]/g," "),t=t.replace(/\s+/g," ").trim();let a=t.split(/\s+/).filter(i=>{if(i.length<=2){const l=i.toUpperCase();return["AI","ML","UI","UX","API","CSS","JS"].includes(l)}return!0}).slice(0,6).join(" ");return a=a.replace(/[.,!?]+$/,""),a.length>60&&(a=a.slice(0,57)+"..."),a||e.slice(0,50)}function jl(){return Qe(e=>e.settings.useLlmTitles)}const tn={active:!1,text:"",tools:[],sessionKey:null};function kl(e){const[t,r]=o.useState(tn),s=o.useRef(null),a=o.useRef(e.onDone),i=o.useRef(e.onError),l=o.useRef(e.onAssistantDelta);a.current=e.onDone,i.current=e.onError,l.current=e.onAssistantDelta;const c=o.useCallback(d=>{if(s.current&&(s.current.close(),s.current=null),d?.preserveState){r(f=>({...f,active:!1}));return}r(tn)},[]),u=o.useCallback(d=>{s.current&&(s.current.close(),s.current=null),r({active:!0,text:"",tools:[],sessionKey:d});const f=new EventSource(`/api/stream?sessionKey=${encodeURIComponent(d)}`);s.current=f,f.addEventListener("delta",p=>{try{const m=JSON.parse(p.data);r(h=>({...h,text:h.text+m.text})),l.current?.({text:m.text,sessionKey:m.sessionKey})}catch{}}),f.addEventListener("tool",p=>{try{const m=JSON.parse(p.data);r(h=>{const w=h.tools.findIndex(j=>j.id===m.id),g=[...h.tools];return w>=0?g[w]={name:m.name,status:m.status,id:m.id}:g.push({name:m.name,status:m.status,id:m.id}),{...h,tools:g}})}catch{}}),f.addEventListener("done",p=>{try{const m=JSON.parse(p.data);f.close(),s.current=null,r(h=>({...h,active:!1})),a.current(m.sessionKey)}catch{}}),f.onerror=()=>{f.readyState===EventSource.CLOSED&&(f.close(),s.current=null,r(tn),i.current?.("Stream connection lost"))}},[]);return{streaming:t,startStream:u,stopStream:c}}function Cl(e){const t=o.useCallback(r=>{const s=r.target,a=s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.isContentEditable;if(r.key==="Escape"){e.onEscape?.();return}if(r.key==="?"&&!a&&!r.metaKey&&!r.ctrlKey){r.preventDefault(),e.onShowHelp?.();return}if(a)return;const l=navigator.platform.toUpperCase().indexOf("MAC")>=0?r.metaKey:r.ctrlKey;if(l&&r.key==="k"&&!r.shiftKey){r.preventDefault(),e.onNewChat?.();return}if(l&&r.key==="/"){r.preventDefault(),e.onFocusInput?.();return}if(l&&r.shiftKey&&r.key==="C"){r.preventDefault(),e.onCopyLastResponse?.();return}if(l&&r.key==="f"&&!r.shiftKey){r.preventDefault(),e.onSearch?.();return}if(l&&r.shiftKey&&r.key==="F"){r.preventDefault(),e.onSearchGlobal?.();return}},[e]);o.useEffect(()=>(window.addEventListener("keydown",t),()=>{window.removeEventListener("keydown",t)}),[t])}function Vn(e){const{threshold:t=50,edgeWidth:r,onMove:s,onSwipe:a,onCancel:i,direction:l,enabled:c=!0}=e,u=o.useRef({startX:0,startY:0,tracking:!1,directionLocked:!1}),d=o.useCallback(m=>{if(!c)return;const h=m.touches[0];h&&(r!==void 0&&h.clientX>r||(u.current={startX:h.clientX,startY:h.clientY,tracking:!0,directionLocked:!1}))},[c,r]),f=o.useCallback(m=>{const h=u.current;if(!h.tracking)return;const w=m.touches[0];if(!w)return;const g=w.clientX-h.startX,j=w.clientY-h.startY,k=Math.abs(g),y=Math.abs(j);if(!h.directionLocked){if(k<5&&y<5)return;if(y>k){h.tracking=!1,i?.();return}h.directionLocked=!0}l==="left"&&g>0||l==="right"&&g<0||(m.preventDefault(),s?.(g))},[l,s,i]),p=o.useCallback(m=>{const h=u.current;if(!h.tracking)return;h.tracking=!1;const w=m.changedTouches[0];if(!w){i?.();return}const g=w.clientX-h.startX,j=Math.abs(g);if(!h.directionLocked||j<t){i?.();return}const k=g>0?"right":"left";if(l&&k!==l){i?.();return}a(k)},[l,i,a,t]);return{onTouchStart:d,onTouchMove:f,onTouchEnd:p}}const Pr="opencami-browser-notifications-enabled",nn="opencami-browser-notifications-permission-asked",Nl=5e3;function Ct(){return typeof window<"u"&&"Notification"in window}function Jn(){if(typeof window>"u")return!1;try{return localStorage.getItem(Pr)==="true"}catch{return!1}}function El(){const e=zt(),t=o.useRef(0),[r,s]=o.useState(()=>Jn()),a=o.useCallback(async()=>{if(!Ct())return"denied";try{return await Notification.requestPermission()}catch{return"denied"}},[]),i=o.useCallback(async c=>{s(c);try{localStorage.setItem(Pr,String(c))}catch{}if(c&&Ct()&&Notification.permission==="default"){await a();try{localStorage.setItem(nn,"true")}catch{}}},[a]),l=o.useCallback(c=>{if(!r||!Ct()||document.hidden!==!0||Notification.permission!=="granted")return;const u=Date.now();if(u-t.current<Nl)return;t.current=u;const d=c.text.slice(0,100),f=new Notification("OpenCami",{body:d,icon:"/pwa-192x192.png"});f.onclick=()=>{window.focus(),e({to:"/chat/$sessionKey",params:{sessionKey:c.sessionFriendlyId}}),f.close()}},[r,e]);return o.useEffect(()=>{if(!Ct())return;const c=()=>{if(Notification.permission!=="default")return;let d=!1;try{d=localStorage.getItem(nn)==="true"}catch{d=!1}d||a().finally(()=>{try{localStorage.setItem(nn,"true")}catch{}})},u={once:!0,passive:!0};return window.addEventListener("pointerdown",c,u),window.addEventListener("keydown",c,{once:!0}),()=>{window.removeEventListener("pointerdown",c),window.removeEventListener("keydown",c)}},[a]),o.useEffect(()=>{const c=()=>s(Jn());return window.addEventListener("storage",c),()=>window.removeEventListener("storage",c)},[]),{notificationsEnabled:r,setNotificationsEnabled:i,requestNotificationPermission:a,maybeNotifyAssistantMessage:l}}const Tl=o.lazy(()=>Kt(()=>import("./keyboard-shortcuts-dialog-C2Hq19LN.js"),__vite__mapDeps([25,1,3,2,4,5,6,7,8,9])).then(e=>({default:e.KeyboardShortcutsDialog}))),Rl=o.lazy(()=>Kt(()=>import("./search-dialog-C5Yae9rb.js"),__vite__mapDeps([26,1,2,3,4,5,6,7,8,9,17,14,11,15,18,13,19,20,21,22,16,23])).then(e=>({default:e.SearchDialog}))),Nt="opencami-search-jump-target";function Ml({activeFriendlyId:e,isNewChat:t=!1,onSessionResolved:r,forcedSessionKey:s}){const a=zt(),i=ct(),[l,c]=o.useState(!1),[u,d]=o.useState(!1),[f,p]=o.useState(null),[m,h]=o.useState(!1),{headerRef:w,composerRef:g,mainRef:j,pinGroupMinHeight:k,headerHeight:y}=gl(),[_,R]=o.useState(()=>Jt()||Qt()),[H,T]=o.useState(()=>Jt()||Qt()),[U,q]=o.useState(!1),[E,W]=o.useState(!1),[F,b]=o.useState("global"),[A,N]=o.useState(null),[C,K]=o.useState(!1),x=dn(v=>v.level),{maybeNotifyAssistantMessage:L}=El(),S=o.useRef(null),I=o.useRef(null),P=o.useRef(null),$=o.useRef(""),Y=o.useRef(()=>{}),re=o.useRef(!1),te=o.useRef(""),{isMobile:Z}=wl(i),{sessionsQuery:J,sessions:ie,activeExists:V,activeSessionKey:Q,activeTitle:ve,activeTokens:Ee,sessionsError:de}=bl({activeFriendlyId:e,isNewChat:t,forcedSessionKey:s}),{historyQuery:ae,historyMessages:pe,displayMessages:fe,historyError:D,resolvedSessionKey:me,activeCanonicalKey:O,sessionKeyForHistory:G}=xl({activeFriendlyId:e,activeSessionKey:Q,forcedSessionKey:s,isNewChat:t,isRedirecting:m,activeExists:V,sessionsReady:J.isSuccess,queryClient:i}),X=Mt({queryKey:es,queryFn:function(){return Nn(i)},initialData:function(){return Nn(i)},staleTime:1/0}),ne=Mt({queryKey:["gateway","status"],queryFn:ao,retry:!1,refetchOnWindowFocus:!1,refetchOnReconnect:!1,refetchOnMount:"always"}),se=o.useRef(Date.now()),ee=ne.error instanceof Error?ne.error.message:ne.data&&!ne.data.ok?ne.data.error||"Gateway unavailable":null,Se=ee??de??D,Ae=o.useCallback(()=>{ne.refetch()},[ne]),he=X.data?.isSidebarCollapsed??!1,Te=Vn({enabled:Z&&he,edgeWidth:40,threshold:50,direction:"right",onSwipe:()=>{Fe(i,v=>({...v,isSidebarCollapsed:!1}))}}),ut=Vn({enabled:Z&&!he,threshold:50,direction:"left",onSwipe:()=>{Fe(i,v=>({...v,isSidebarCollapsed:!0}))}}),xt=o.useCallback(()=>{p(null),h(!0),a({to:"/new",replace:!0})},[a]),Ge=o.useCallback(()=>{I.current&&(window.clearInterval(I.current),I.current=null),P.current&&(window.clearTimeout(P.current),P.current=null)},[]),Ze=o.useCallback(()=>{Ge(),ht(!1),R(!1),K(!1)},[Ge]),yt=jl(),{generateTitle:et}=Sl(),tt=o.useRef(new Set),dt=150,wt=600,bt=o.useCallback(()=>{!e||t||(I.current&&window.clearInterval(I.current),K(!0),I.current=window.setInterval(()=>{Y.current()},dt))},[e,t]),ft=o.useRef(()=>{}),St=o.useRef(()=>{}),{streaming:je,startStream:oe,stopStream:we}=kl({onDone:v=>ft.current(v),onError:v=>St.current(v),onAssistantDelta:({text:v})=>{te.current+=v,L({text:te.current,sessionFriendlyId:e})}});ft.current=o.useCallback(async v=>{await ae.refetch(),we({preserveState:!0}),Ze(),i.invalidateQueries({queryKey:ce.sessions})},[ae,i,we,Ze]),St.current=o.useCallback(v=>{console.warn("[stream] SSE error, falling back to polling")},[]);const ze=o.useMemo(()=>{if(!je.text)return null;const v=[];for(const z of je.tools)v.push({type:"toolCall",name:z.name,id:z.id});return v.push({type:"text",text:je.text}),{role:"assistant",content:v,id:"__streaming__",__streaming:!0,timestamp:Date.now()}},[je.text,je.tools]),mt=o.useMemo(()=>{if(!ze)return fe;const v=[...fe].map((le,ge)=>({message:le,index:ge})).filter(({message:le})=>le.role==="assistant").map(({index:le})=>le).pop(),z=[...fe].map((le,ge)=>({message:le,index:ge})).filter(({message:le})=>le.role==="user").map(({index:le})=>le).pop();if(typeof v=="number"&&(typeof z!="number"||v>z)&&typeof v=="number"){const le=fe[v];if(Me(le).length>=je.text.length)return fe;const Ie=[...fe];return Ie[v]=ze,Ie}return[...fe,ze]},[fe,ze,je.text]),_r=o.useMemo(()=>({}),[]);Y.current=function(){ae.refetch()},o.useEffect(()=>{if(m){f&&p(null);return}if(nt){f&&p(null);return}if(J.isSuccess&&!V){f&&p(null);return}const v=de??D??ee;if(!v){f?.startsWith("Failed to load")&&p(null);return}Rn(v)&&a({to:"/connect",replace:!0});const z=de?`Failed to load sessions. ${de}`:D?`Failed to load history. ${D}`:ee?`Gateway unavailable. ${ee}`:null;z&&p(z)},[f,ee,D,m,a,de]);const nt=!t&&!s&&!Cr(e)&&J.isSuccess&&ie.length>0&&!ie.some(v=>v.friendlyId===e)&&!ae.isFetching&&!ae.isSuccess;o.useEffect(()=>{if(m){if(t){h(!1);return}!nt&&J.isSuccess&&h(!1)}},[t,m,J.isSuccess,nt]),o.useEffect(()=>{t||J.isSuccess&&ie.length!==0&&nt&&(_t(),ln(i,e,G),a({to:"/new",replace:!0}))},[e,ae.isFetching,ae.isSuccess,t,a,i,G,ie,J.isSuccess,nt]);const wn=nt||m,vt=o.useRef("fast");o.useEffect(()=>{const v=pe[pe.length-1];if(!v||v.role!=="assistant")return;const z=`${pe.length}:${Me(v).slice(-64)}`;z!==$.current&&($.current=z,vt.current!=="fast"&&I.current&&(window.clearInterval(I.current),I.current=window.setInterval(()=>{Y.current()},dt),vt.current="fast"),P.current&&window.clearTimeout(P.current),P.current=window.setTimeout(()=>{I.current&&(window.clearInterval(I.current),I.current=window.setInterval(()=>{Y.current()},wt),vt.current="slow"),P.current=window.setTimeout(()=>{Ze(),vt.current="fast"},3e3)},1500))},[pe,Ze]),o.useEffect(()=>{if(!yt||t||m)return;const v=s||me||Q;if(!v||tt.current.has(v))return;const z=pe.filter(ge=>ge.role==="user"),ue=pe.filter(ge=>ge.role==="assistant");if(z.length===0||ue.length===0||z.length!==1)return;const le=Me(z[0]);!le||le.length<5||(tt.current.add(v),(async()=>{try{const ge=await et(le);ge.title&&await po(i,v,e,ge.title)}catch(ge){console.error("[smart-title] Error generating title:",ge)}})())},[yt,t,m,s,me,Q,e,pe,et,i]),o.useEffect(()=>{if(t||e){if(Ge(),we(),$.current="",K(!1),re.current){re.current=!1;return}if(Jt()||Qt()){R(!0),T(!0);return}R(!1),T(!1)}},[e,t,Ge,we]),o.useEffect(()=>{if(!(typeof window>"u"))try{const v=sessionStorage.getItem(Nt);if(!v){N(null);return}const z=JSON.parse(v);if(typeof z.at=="number"&&Date.now()-z.at>300*1e3){sessionStorage.removeItem(Nt),N(null);return}if(z.friendlyId===e&&typeof z.messageId=="string"&&z.messageId.length>0){N(z.messageId),sessionStorage.removeItem(Nt);return}N(null)}catch{N(null)}},[e]),o.useLayoutEffect(()=>{if(t)return;const v=ji(s||me||Q,e);if(!v)return;re.current=!0;const z=ce.history(v.friendlyId,v.sessionKey),ue=i.getQueryData(z);(Array.isArray(ue?.messages)?ue.messages:[]).some(Ie=>!!(v.optimisticMessage.clientId&&(Ie.clientId===v.optimisticMessage.clientId||Ie.__optimisticId===v.optimisticMessage.clientId)||v.optimisticMessage.__optimisticId&&Ie.__optimisticId===v.optimisticMessage.__optimisticId))||Bt(i,v.friendlyId,v.sessionKey,v.optimisticMessage),R(!0),T(!0),Xt(v.sessionKey,v.friendlyId,v.message,!0,v.attachments)},[e,Q,s,t,i,me]);function Xt(v,z,ue,le=!1,ge,Ie){let rt="";if(!le){const{clientId:ye,optimisticMessage:pt}=Mn(ue,ge);rt=ye,Bt(i,z,v,pt),fo(i,v,z,pt)}ht(!0),c(!0),p(null),R(!0),T(!0);const $e=ge?.map(ye=>({mimeType:ye.file.type,content:ye.base64}));te.current="",oe(v),bt(),fetch("/api/send",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({sessionKey:v,friendlyId:z,message:ue,thinking:x,idempotencyKey:crypto.randomUUID(),attachments:$e,model:Ie||void 0})}).then(async ye=>{if(!ye.ok)throw new Error(await Ke(ye))}).catch(ye=>{const pt=ye instanceof Error?ye.message:String(ye);if(Rn(pt)){a({to:"/connect",replace:!0});return}rt&&lo(i,z,v,rt,function(Vr){return{...Vr,status:"error"}}),p(`Failed to send message. ${pt}`),ht(!1),R(!1),T(!1)}).finally(()=>{c(!1)})}const bn=o.useCallback(async()=>{d(!0);try{const v=await fetch("/api/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({})});if(!v.ok)throw new Error(await Ke(v));const z=await v.json(),ue=typeof z.sessionKey=="string"?z.sessionKey:"",le=typeof z.friendlyId=="string"&&z.friendlyId.trim().length>0?z.friendlyId.trim():sn(ue);if(!ue||!le)throw new Error("Invalid session response");return i.invalidateQueries({queryKey:ce.sessions}),{sessionKey:ue,friendlyId:le}}finally{d(!1)}},[i]),Kr=o.useCallback((v,z)=>{const ue=z.attachments;if(v.length===0&&(!ue||ue.length===0))return;if(z.reset(),t){const{clientId:ge,optimisticId:Ie,optimisticMessage:rt}=Mn(v,ue);Bt(i,"new","new",rt),ht(!0),c(!0),R(!0),T(!0),bn().then(({sessionKey:$e,friendlyId:ye})=>{if(vi(ye),bi({sessionKey:$e,friendlyId:ye,message:v,optimisticMessage:rt,attachments:ue}),r){r({sessionKey:$e,friendlyId:ye});return}a({to:"/chat/$sessionKey",params:{sessionKey:ye},replace:!0})}).catch($e=>{co(i,"new","new",ge,Ie),z.setValue(v),p(`Failed to create session. ${$e instanceof Error?$e.message:String($e)}`),ht(!1),R(!1),T(!1),c(!1)});return}Xt(s||me||Q,e,v,!1,ue,z.model)},[e,Q,bn,s,t,a,r,i,me]),Sn=o.useCallback(()=>{R(!1),T(!1),ln(i,"new","new"),a({to:"/new"}),Z&&Fe(i,function(z){return{...z,isSidebarCollapsed:!0}})},[Z,a,i]),zr=o.useCallback(()=>{Fe(i,function(z){return{...z,isSidebarCollapsed:!z.isSidebarCollapsed}})},[i]),Ur=o.useCallback(()=>{Z&&Fe(i,function(z){return{...z,isSidebarCollapsed:!0}})},[Z,i]),$r=o.useCallback(()=>{Fe(i,function(z){return{...z,isSidebarCollapsed:!1}})},[i]),Hr=o.useCallback(v=>{if(t||!v.trim())return;const z=s||me||Q;z&&Xt(z,e,v.trim())},[e,Q,s,t,me]),Fr=o.useCallback(()=>{S.current?.focus()},[]),Wr=o.useCallback(()=>{if(U){q(!1);return}document.activeElement instanceof HTMLElement&&document.activeElement.blur()},[U]),Xr=o.useCallback(()=>{const v=[...fe].reverse().find(ue=>ue.role==="assistant");if(!v)return;const z=Me(v);z&&navigator.clipboard.writeText(z).catch(()=>{})},[fe]),Yr=o.useCallback(()=>{q(!0)},[]),Br=o.useCallback(()=>{b(t?"global":"current"),W(!0)},[t]),vn=o.useCallback(()=>{b("global"),W(!0)},[]);Cl({onNewChat:Sn,onFocusInput:Fr,onEscape:Wr,onCopyLastResponse:Xr,onShowHelp:Yr,onSearch:Br,onSearchGlobal:vn});const jn=ae.isLoading&&!ae.data||m,kn=!!ee&&ne.errorUpdatedAt>se.current,Gr=!jn&&fe.length===0,qr=o.useMemo(()=>!kn||!Se?null:n.jsx(hl,{state:"error",error:Se,onRetry:Ae}),[Se,Ae,kn]),Cn=n.jsx(Li,{sessions:ie,activeFriendlyId:e,activeSessionKey:G,creatingSession:u,onCreateSession:Sn,isCollapsed:Z?!1:he,onToggleCollapse:zr,onSelectSession:Ur,onActiveSessionDelete:xt,onOpenSearch:vn});return n.jsxs("div",{className:"h-screen bg-surface text-primary-900",children:[n.jsxs("div",{className:M("h-full overflow-hidden",Z?"relative":"grid grid-cols-[auto_minmax(0,1fr)]"),children:[wn?null:Z?n.jsxs(n.Fragment,{children:[!he&&n.jsx("div",{className:"fixed inset-0 z-40 bg-black/40 transition-opacity duration-200",onClick:()=>Fe(i,v=>({...v,isSidebarCollapsed:!0})),...ut}),n.jsx("div",{className:M("fixed inset-y-0 left-0 z-50 w-[var(--opencami-sidebar-width)] transition-transform duration-150 safe-area-top",he?"-translate-x-full":"translate-x-0"),...ut,children:Cn})]}):Cn,n.jsxs("main",{className:"flex flex-col h-full min-h-0 min-w-0 overflow-x-hidden",ref:j,...Te,children:[n.jsx(zi,{activeTitle:ve,wrapperRef:w,showSidebarButton:Z,onOpenSidebar:$r,totalTokens:Ee.totalTokens,contextTokens:Ee.contextTokens}),wn?null:n.jsxs(n.Fragment,{children:[n.jsx(La,{messages:mt,loading:jn,empty:Gr,notice:qr,noticePosition:"end",waitingForResponse:_,isStreaming:C,sessionKey:O,pinToTop:H,pinGroupMinHeight:k,headerHeight:y,contentStyle:_r,onFollowUpClick:Hr,jumpToMessageId:A}),n.jsx(ml,{onSubmit:Kr,isLoading:l,disabled:l,wrapperRef:g,inputRef:S})]})]})]}),U&&n.jsx(o.Suspense,{fallback:null,children:n.jsx(Tl,{open:U,onOpenChange:q})}),E&&n.jsx(o.Suspense,{fallback:null,children:n.jsx(Rl,{open:E,onOpenChange:W,sessions:ie,currentFriendlyId:e,currentSessionKey:Q,mode:F,onJumpToMessage:v=>{if(W(!1),!!v.friendlyId){if(v.messageId&&v.friendlyId===e){N(v.messageId);return}if(v.messageId&&typeof window<"u")try{sessionStorage.setItem(Nt,JSON.stringify({friendlyId:v.friendlyId,messageId:v.messageId,at:Date.now()}))}catch{}a({to:"/chat/$sessionKey",params:{sessionKey:v.friendlyId}})}}})})]})}function Al(){const e=ct(),t=zt(),[r,s]=o.useState(null),a=Zr.useParams(),i=typeof a.sessionKey=="string"?a.sessionKey:"main",l=i==="new",c=r?.friendlyId===i?r.sessionKey:void 0,u=o.useCallback(function(f){uo(e,"new","new",f.friendlyId,f.sessionKey),s({friendlyId:f.friendlyId,sessionKey:f.sessionKey}),t({to:"/chat/$sessionKey",params:{sessionKey:f.friendlyId},replace:!0})},[t,e]);return n.jsx(Ml,{activeFriendlyId:i,isNewChat:l,forcedSessionKey:c,onSessionResolved:l?u:void 0})}const Zl=Object.freeze(Object.defineProperty({__proto__:null,component:Al},Symbol.toStringTag,{value:"Module"}));export{Zl as $,ce as c,Er as g,Ql as u};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/agents-screen-Cb76bcxn.js","assets/main-CEuT8-Qi.js","assets/visuallyHidden-CO3ZD5AQ.js","assets/button-DNC5N25i.js","assets/switch-DAFvLxNX.js","assets/useControlled-Cl9XA2_f.js","assets/useButton-DVAfkehQ.js","assets/tooltip-D57Pal0B.js","assets/popupStateMapping-D5k-jOeY.js","assets/owner-CFRNz_Tp.js","assets/DirectionContext-DRcND-Cm.js","assets/opencami-logo-DA69yVKc.js","assets/proxy-Cawf6X0W.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{j as e,r as t,_ as r}from"./main-CEuT8-Qi.js";const n=t.lazy(()=>r(()=>import("./agents-screen-Cb76bcxn.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12])).then(s=>({default:s.AgentsScreen})));function o(){return e.jsx(t.Suspense,{fallback:e.jsx("div",{className:"flex h-screen items-center justify-center text-primary-500 text-sm",children:"Loading…"}),children:e.jsx(n,{})})}export{o as component};
|