@runfusion/fusion 0.25.0 → 0.26.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 +6 -0
- package/dist/bin.js +47492 -45420
- package/dist/client/assets/{AgentDetailView-ZbHEbYRT.js → AgentDetailView-Cv-vgOj3.js} +3 -3
- package/dist/client/assets/{AgentsView-B3jYk8Kt.js → AgentsView-D6Zi5zfP.js} +4 -4
- package/dist/client/assets/ChatView-CAHjY9uO.js +1 -0
- package/dist/client/assets/{DevServerView-DyGDEiBP.js → DevServerView--_WBvIDQ.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-D5UIeIl6.js → DirectoryPicker-xedtR-Rd.js} +1 -1
- package/dist/client/assets/{DocumentsView-DNHu1T8K.js → DocumentsView-Bg2oaZks.js} +1 -1
- package/dist/client/assets/{EvalsView-CpRobtDi.js → EvalsView-B3uOCXfr.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-DOY_oZi7.js → ExperimentalAgentOnboardingModal-Bx6yXVS5.js} +1 -1
- package/dist/client/assets/{InsightsView-vp0RE8Mg.js → InsightsView-Q1zvtF4F.js} +1 -1
- package/dist/client/assets/{MemoryView-PSc5lGJt.js → MemoryView-xcN_eouf.js} +1 -1
- package/dist/client/assets/{NodesView-DMj6HGeC.js → NodesView-RxXg58_Q.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-DL_QcN56.js → PiExtensionsManager-Cc8aAZXg.js} +2 -2
- package/dist/client/assets/{PluginManager-BtYKm8IT.js → PluginManager-BEkyBajl.js} +1 -1
- package/dist/client/assets/{ResearchView-BzCcDAS4.css → ResearchView-BEI4ZSGs.css} +1 -1
- package/dist/client/assets/ResearchView-CERNf7sJ.js +1 -0
- package/dist/client/assets/{SettingsModal-CUCyaAyE.js → SettingsModal-B1r0yASu.js} +1 -1
- package/dist/client/assets/SettingsModal-BLsac7CJ.js +31 -0
- package/dist/client/assets/SettingsModal-Cis-4Lot.css +1 -0
- package/dist/client/assets/{SetupWizardModal-BKscasuh.js → SetupWizardModal-D1q548_L.js} +1 -1
- package/dist/client/assets/{SkillsView-BdELqTy7.js → SkillsView-ClLM6u6p.js} +1 -1
- package/dist/client/assets/StashRecoveryView-B_8WIQEo.css +1 -0
- package/dist/client/assets/StashRecoveryView-ze0pEZ5U.js +1 -0
- package/dist/client/assets/{TodoView-DFNGBDNV.js → TodoView-CTmIfy2M.js} +1 -1
- package/dist/client/assets/createLucideIcon-BazL2hk5.js +21 -0
- package/dist/client/assets/dashboard-view-4xAN3yO5.js +21 -0
- package/dist/client/assets/dashboard-view-BkTMSZYn.css +1 -0
- package/dist/client/assets/dashboard-view-CyWN-d02.js +63 -0
- package/dist/client/assets/dashboard-view-DdGlfuu-.css +1 -0
- package/dist/client/assets/{folder-open-k1xmUMyr.js → folder-open-BZuKESeq.js} +1 -1
- package/dist/client/assets/index-Bdw6llW6.js +692 -0
- package/dist/client/assets/index-CZGlyJuS.css +1 -0
- package/dist/client/assets/{star-ne32r3Y4.js → star-D75YKEq-.js} +1 -1
- package/dist/client/assets/{upload-MS-2Gx53.js → upload-BYYTgWFj.js} +1 -1
- package/dist/client/assets/{users-C519GSjH.js → users-RS90Aii3.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +4340 -3059
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/manifest.json +6 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +26 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/manifest.test.ts +20 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +14 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/{src/dashboard/RoadmapsView.css → bundled.css} +13 -219
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +29535 -0
- package/dist/plugins/fusion-plugin-roadmap/package.json +4 -41
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +2 -3
- package/dist/client/assets/ChatView-DhPkiEGs.js +0 -1
- package/dist/client/assets/ResearchView-BhWqfdV0.js +0 -1
- package/dist/client/assets/SettingsModal-BAgB4_AR.js +0 -31
- package/dist/client/assets/SettingsModal-DzsLquBu.css +0 -1
- package/dist/client/assets/index-Qq2JOOWx.css +0 -1
- package/dist/client/assets/index-TFYXEVpn.js +0 -692
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/api-client.test.ts +0 -101
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/index.test.ts +0 -92
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-routes.test.ts +0 -48
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-suggestions.test.ts +0 -31
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/RoadmapsView.tsx +0 -2559
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/RoadmapsView.test.tsx +0 -1144
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/useRoadmaps.test.ts +0 -1756
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/api.ts +0 -70
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/test-setup.ts +0 -7
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/types.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useConfirm.ts +0 -8
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useRoadmaps.ts +0 -1188
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useViewportMode.ts +0 -20
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard-view.tsx +0 -6
- package/dist/plugins/fusion-plugin-roadmap/src/index.ts +0 -74
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-routes.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-schema.ts +0 -41
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.d.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts +0 -283
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js +0 -21
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.ts +0 -310
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts +0 -5
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js +0 -361
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.ts +0 -408
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts +0 -68
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js +0 -300
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.ts +0 -381
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.d.ts +0 -3
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-handoff.test.ts +0 -445
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-ordering.test.ts +0 -334
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts +0 -1318
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-handoff.ts +0 -163
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts +0 -37
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js +0 -188
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.ts +0 -311
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts +0 -299
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js +0 -765
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.ts +0 -1001
|
@@ -1,48 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion-plugin-examples/roadmap",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Roadmap plugin package for Fusion",
|
|
6
|
-
"private": true,
|
|
7
5
|
"exports": {
|
|
8
6
|
".": {
|
|
9
|
-
"
|
|
10
|
-
"import": "./src/index.ts"
|
|
11
|
-
},
|
|
12
|
-
"./server": {
|
|
13
|
-
"types": "./src/server/index.d.ts",
|
|
14
|
-
"import": "./src/server/index.ts"
|
|
15
|
-
},
|
|
16
|
-
"./dashboard-view": {
|
|
17
|
-
"types": "./src/dashboard-view.tsx",
|
|
18
|
-
"import": "./src/dashboard-view.tsx"
|
|
19
|
-
},
|
|
20
|
-
"./roadmap-suggestions": {
|
|
21
|
-
"types": "./src/roadmap-suggestions.d.ts",
|
|
22
|
-
"import": "./src/roadmap-suggestions.ts"
|
|
7
|
+
"import": "./bundled.js"
|
|
23
8
|
}
|
|
24
9
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"test": "vitest run --silent=passed-only --reporter=dot"
|
|
28
|
-
},
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"@fusion/core": "workspace:*",
|
|
31
|
-
"@fusion/dashboard": "workspace:*",
|
|
32
|
-
"@fusion/plugin-sdk": "workspace:*",
|
|
33
|
-
"express": "^5.1.0",
|
|
34
|
-
"lucide-react": "^0.542.0",
|
|
35
|
-
"react": "^19.0.0",
|
|
36
|
-
"react-dom": "^19.2.4"
|
|
37
|
-
},
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@testing-library/jest-dom": "^6.6.3",
|
|
40
|
-
"@testing-library/react": "^16.3.2",
|
|
41
|
-
"@testing-library/user-event": "^14.6.1",
|
|
42
|
-
"@types/express": "^5.0.5",
|
|
43
|
-
"@types/node": "^25.5.2",
|
|
44
|
-
"@types/react": "^19.0.0",
|
|
45
|
-
"typescript": "^5.7.0",
|
|
46
|
-
"vitest": "^3.2.4"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
10
|
+
"private": true
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -80,8 +80,7 @@
|
|
|
80
80
|
"typebox": "^1.0.0",
|
|
81
81
|
"typescript": "^5.7.0",
|
|
82
82
|
"vitest": "^3.1.0",
|
|
83
|
-
"yaml": "^2.8.3"
|
|
84
|
-
"@fusion/pi-llama-cpp": "0.17.2"
|
|
83
|
+
"yaml": "^2.8.3"
|
|
85
84
|
},
|
|
86
85
|
"repository": {
|
|
87
86
|
"type": "git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as s,a as Ns,j as t}from"./vendor-react-K0fH_qHe.js";import{i as at,b1 as Ut,t as Xt,b2 as js,b3 as Ot,b4 as Ms,w as Mt,b5 as Le,b6 as Rs,b7 as As,b8 as Es,b9 as Ts,ba as Ds,bb as Ps,s as Qt,bc as $s,bd as Ls,be as Fs,bf as Is,bg as zs,bh as _s,bi as Us,k as Zt,bj as Os,p as Hs,bk as Bs,bl as Ws,u as Gs,bm as Vs,ab as es,ac as ts,bn as Ks,bo as qs,S as Js,W as kt,P as tt,I as Xe,am as Ys,bp as Ht,bq as Bt,B as nt,a8 as Xs,a9 as Qs,a as Zs,br as en,bs as tn,bt as sn,aQ as nn,bu as an,bv as Wt,bw as rn,h as on,j as Gt,m as cn}from"./index-TFYXEVpn.js";import"./vendor-xterm-DzcZoU0P.js";const Ct="kb-chat-active-session";function Vt(n){const r=typeof n=="string"?n.trim():"",o=r.indexOf("/");return!r||o<=0||o>=r.length-1?{}:{modelProvider:r.slice(0,o),modelId:r.slice(o+1)}}function ln(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const o=r.map(d=>{if(!d||typeof d!="object")return null;const c=d,x=typeof c.toolName=="string"?c.toolName:"";if(!x)return null;const A=c.args;return{toolName:x,...A&&typeof A=="object"?{args:A}:{},isError:!!c.isError,result:c.result,status:"completed"}}).filter(d=>d!==null);return o.length>0?o:void 0}function dn(n){const r=n?.fallback;if(!r||typeof r!="object")return;const o=r,d=typeof o.primaryModel=="string"?o.primaryModel:"",c=typeof o.fallbackModel=="string"?o.fallbackModel:"",x=o.triggerPoint;if(!(!d||!c||x!=="session-creation"&&x!=="prompt-time"))return{primaryModel:d,fallbackModel:c,triggerPoint:x}}function Nt(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:ln(n.metadata),fallbackInfo:dn(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function un(n,r){const[o,d]=s.useState([]),[c,x]=s.useState(null),[A,E]=s.useState(!0),[P,w]=s.useState([]),[X,p]=s.useState(!1),[J,C]=s.useState(!1),[Z,b]=s.useState(""),[T,m]=s.useState(""),[j,M]=s.useState([]),[D,F]=s.useState(""),[G,$]=s.useState(""),[K,v]=s.useState(!0),[h,u]=s.useState(new Map),i=s.useRef(null),f=s.useRef(!1),y=s.useRef(""),I=s.useRef(null),de=s.useRef(o),Y=s.useRef(c),ae=s.useRef(J);de.current=o,Y.current=c,ae.current=J,s.useEffect(()=>{y.current=D},[D]);const re=s.useRef(new Set),me=s.useRef(0),Ge=s.useRef(n);Ge.current!==n&&(Ge.current=n,me.current++),s.useEffect(()=>{const g=me.current;at(void 0,n).then(k=>{if(me.current!==g)return;const S=new Map;for(const R of k)S.set(R.id,R);u(S)}).catch(()=>{})},[n]);const he=s.useCallback(async()=>{E(!0);try{const k=[...(await Ut(n)).sessions].sort((S,R)=>new Date(R.updatedAt).getTime()-new Date(S.updatedAt).getTime());d(k)}catch{}finally{E(!1)}},[n]);s.useEffect(()=>{he()},[he]);const _=s.useRef(()=>{}),oe=s.useRef(!1);s.useEffect(()=>{oe.current=!1},[n]),s.useEffect(()=>{if(A||oe.current||Y.current)return;const g=Xt(Ct,n);if(!g){oe.current=!0;return}const k=o.find(S=>S.id===g);if(k){oe.current=!0,_.current(g,k);return}oe.current=!0},[A,o,n]);const ie=s.useCallback(async(g,k)=>{p(!0);try{const S=await js(g,{limit:50,...k},n),R=S.messages.map(Nt);k?.offset&&k.offset>0?w(q=>[...R,...q]):w(R),v(S.messages.length>=50)}catch{}finally{p(!1)}},[n]),we=s.useCallback(()=>{I.current?.(),I.current=null,y.current="",F(""),b(""),m(""),M([]),C(!1)},[]),fe=s.useCallback(g=>{if(i.current||!g)return!0;f.current=!1,C(!0);const{handlers:k}=Ot({sessionId:g,tempUserMessageId:"",setStreamingText:b,setStreamingThinking:m,setStreamingToolCalls:M,cancelStreamingFlushesRef:I,addToast:r,onFallbackSession:(R,q)=>{const L=Vt(R.fallbackModel);d(ee=>ee.map(U=>U.id===q?{...U,...L}:U)),x(ee=>ee&&ee.id===q?{...ee,...L}:ee)},onDone:()=>{b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,ie(g)},onError:R=>{b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null;const q=typeof R=="string"&&R.trim()?R:"Failed to get response";r?.(q,"error"),ie(g)}}),S=Ms(g,k,n);return i.current=S,!0},[r,ie,n]),Re=s.useCallback((g,k)=>{const S=Y.current?.id??null;if(g&&S===g&&!k)return;i.current&&(i.current.close(),i.current=null);const R=k??o.find(q=>q.id===g);x(R||null),we(),v(!0),g?ie(g):w([]),R?.isGenerating&&(b(""),fe(R.id)),g?Mt(Ct,g,n):Le(Ct,n)},[fe,o,ie,n,we]);_.current=Re;const Ve=s.useCallback(async g=>{const k=await Rs(g,n);i.current&&(i.current.close(),i.current=null);const S={id:k.session.id,title:k.session.title,agentId:k.session.agentId,status:k.session.status,modelProvider:k.session.modelProvider,modelId:k.session.modelId,createdAt:k.session.createdAt,updatedAt:k.session.updatedAt};return d(R=>R.some(q=>q.id===S.id)?R:[S,...R]),we(),Re(S.id,S),w([]),S},[n,we,Re]),ye=s.useCallback(async g=>{await As(g,{status:"archived"},n),d(k=>k.filter(S=>S.id!==g)),c?.id===g&&(x(null),w([]))},[c,n]),Se=s.useCallback(async g=>{c?.id===g&&i.current&&(i.current.close(),i.current=null),await Es(g,n),d(k=>k.filter(S=>S.id!==g)),c?.id===g&&(x(null),w([]))},[c,n]),Ie=s.useCallback(async()=>{!c||!K||await ie(c.id,{offset:P.length})},[c,K,ie,P.length]),Ae=s.useCallback(()=>{c&&(f.current=!0,I.current?.(),I.current=null,i.current?.close(),i.current=null,Ts(c.id,n).catch(()=>{}),C(!1),b(""),m(""),M([]))},[c,n]),Ee=s.useCallback(()=>{y.current="",F("")},[]),ge=s.useRef(()=>{}),ke=Ds(),pe=s.useCallback((g,k)=>{if(!c)return;if(ae.current){y.current=g,F(g),r?.("Still waiting for previous response — message queued","warning");return}f.current=!1,i.current&&(i.current.close(),i.current=null);const S=`temp-${Date.now()}`,R={id:S,sessionId:c.id,role:"user",content:g,createdAt:new Date().toISOString()};w(L=>[...L,R]),b(""),m(""),M([]),C(!0);const{handlers:q}=Ot({sessionId:c.id,tempUserMessageId:S,setStreamingText:b,setStreamingThinking:m,setStreamingToolCalls:M,cancelStreamingFlushesRef:I,addToast:r,onFallbackSession:(L,ee)=>{const U=Vt(L.fallbackModel);d(te=>te.map(H=>H.id===ee?{...H,...U}:H)),x(te=>te&&te.id===ee?{...te,...U}:te)},onDone:({messageId:L,message:ee,accumulated:U})=>{const te=ee?Nt(ee):{id:L||`msg-${Date.now()}`,sessionId:c.id,role:"assistant",content:U.text,thinkingOutput:U.thinking,toolCalls:U.toolCalls.length>0?U.toolCalls:void 0,fallbackInfo:U.fallbackInfo,createdAt:new Date().toISOString()};re.current.add(te.id),w(O=>[...O,te]),b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,setTimeout(()=>{re.current.delete(te.id)},1e3),he();const H=y.current.trim();H&&(y.current="",F(""),ge.current(H))},onError:(L,ee)=>{w(H=>H.filter(O=>O.id!==ee)),b(""),m(""),M([]),C(!1),ae.current=!1,i.current=null,console.error("[useChat] Stream error:",L);const U=typeof L=="string"&&L.trim()?L:"Failed to get response";if(typeof L=="string"&&$s(L)&&(ke.isHiddenNow()||ke.wasRecentlyHidden(5e3))?(console.info("[useChat] Suppressed tab-suspension stream error:",L),c?.id&&ie(c.id)):r?.(U,"error"),!f.current){const H=y.current.trim();H&&(y.current="",F(""),ge.current(H))}}});i.current=Ps(c.id,g,q,k,n)},[c,n,he,r,ie,ke]);ge.current=pe;const ue=G?o.filter(g=>g.title?.toLowerCase().includes(G.toLowerCase())||g.agentId.toLowerCase().includes(G.toLowerCase())):o;return s.useEffect(()=>{if(!Y.current?.isGenerating||(i.current||fe(Y.current.id),!ae.current||i.current||!Y.current))return;const g=setInterval(async()=>{if(!ae.current||i.current||!Y.current){clearInterval(g);return}try{(await Ut(n)).sessions.find(R=>R.id===Y.current?.id)?.isGenerating||(clearInterval(g),await ie(Y.current.id),b(""),m(""),M([]),C(!1))}catch{}},3e3);return()=>clearInterval(g)},[fe,ie,n,c]),s.useEffect(()=>{const g=me.current,k=n?`?projectId=${encodeURIComponent(n)}`:"",S=()=>me.current!==g,R=H=>{if(S())return;const O=JSON.parse(H.data);d(B=>B.some(Q=>Q.id===O.id)?B:[O,...B])},q=H=>{if(S())return;const O=JSON.parse(H.data);d(B=>[...B.map(se=>se.id===O.id?O:se)]),Y.current?.id===O.id&&(x(O),O.isGenerating&&!i.current&&(b(""),fe(O.id)))},L=H=>{if(S())return;const{id:O}=JSON.parse(H.data);d(B=>B.filter(Q=>Q.id!==O)),Y.current?.id===O&&(x(null),w([]))},ee=H=>{if(S())return;const O=JSON.parse(H.data),B=Nt(O);if(!re.current.has(B.id)){if(Y.current?.id===B.sessionId&&ae.current&&!i.current&&B.role==="assistant"){w(Q=>Q.some(se=>se.id===B.id)?Q:[...Q,B]),b(""),m(""),M([]),C(!1);return}Y.current?.id===B.sessionId&&!ae.current&&w(Q=>{if(Q.some(se=>se.id===B.id))return Q;if(B.role==="user"){const se=Q.findIndex(be=>be.role==="user"&&be.id.startsWith("temp-")&&be.content.trim()===B.content.trim());if(se>=0){const be=[...Q];return be[se]=B,be}}return[...Q,B]})}},U=H=>{if(S())return;const{id:O}=JSON.parse(H.data);w(B=>B.filter(Q=>Q.id!==O))};return Qt(`/api/events${k}`,{events:{"chat:session:created":R,"chat:session:updated":q,"chat:session:deleted":L,"chat:message:added":ee,"chat:message:deleted":U}})},[fe,n]),s.useEffect(()=>()=>{i.current&&(i.current.close(),i.current=null)},[]),{sessions:o,activeSession:c,sessionsLoading:A,messages:P,messagesLoading:X,isStreaming:J,streamingText:Z,streamingThinking:T,streamingToolCalls:j,pendingMessage:D,selectSession:Re,createSession:Ve,archiveSession:ye,deleteSession:Se,sendMessage:pe,stopStreaming:Ae,clearPendingMessage:Ee,loadMoreMessages:Ie,hasMoreMessages:K,searchQuery:G,setSearchQuery:$,filteredSessions:ue,refreshSessions:he,agentsMap:h}}const Ce="fusion:chat-active-room";function Rt(n){return[...n].sort((r,o)=>new Date(o.updatedAt).getTime()-new Date(r.updatedAt).getTime())}function Qe(n,r){const o=n.findIndex(c=>c.id===r.id);if(o===-1)return Rt([r,...n]);const d=[...n];return d[o]=r,Rt(d)}function Ne(n){try{return JSON.parse(n.data)}catch{return null}}function mn(n,r){const[o,d]=s.useState([]),[c,x]=s.useState(!0),[A,E]=s.useState(null),[P,w]=s.useState(null),[X,p]=s.useState([]),[J,C]=s.useState([]),[Z,b]=s.useState(!1),T=s.useRef(o),m=s.useRef(P),j=s.useRef(0),M=s.useRef(n);T.current=o,m.current=P,M.current!==n&&(M.current=n,j.current+=1);const D=s.useCallback(async(h,u=!0)=>{if(!h){p([]),C([]),b(!1);return}u&&C([]),b(!0);try{const[i,f]=await Promise.all([Ls(h.id,n),Fs(h.id,{limit:100},n)]);p(i.members),C(f.messages)}catch{p([]),C([])}finally{b(!1)}},[n]),F=s.useCallback(async()=>{x(!0);try{const h=await Is({},n),u=Rt(h.rooms);d(u),E(null);const i=Xt(Ce,n);if(i){const f=u.find(y=>y.id===i)??null;f?(w(f),D(f,!0)):Le(Ce,n)}}catch(h){const u=h instanceof Error?h.message:"Failed to load chat rooms";E(u),r?.(u,"error")}finally{x(!1)}},[r,D,n]),G=s.useCallback(h=>{if(!h){w(null),Le(Ce,n),D(null,!0);return}const u=T.current.find(i=>i.id===h)??null;w(u),u&&(Mt(Ce,u.id,n),D(u,!0))},[D,n]),$=s.useCallback(async h=>{const i=(await zs({name:h.name,memberAgentIds:h.memberAgentIds},n)).room;return d(f=>Qe(f,i)),w(i),Mt(Ce,i.id,n),await D(i,!0),i},[D,n]),K=s.useCallback(async h=>{await _s(h,n),d(u=>u.filter(i=>i.id!==h)),m.current?.id===h&&(w(null),p([]),C([]),Le(Ce,n))},[n]),v=s.useCallback(async(h,u)=>{const i=m.current?.id;if(!i)throw new Error("Select a room before sending a message");await Us(i,{content:h,...u?.attachments?{attachments:u.attachments}:{}},n)},[n]);return s.useEffect(()=>{F()},[F]),s.useEffect(()=>{const h=j.current,u=n?`/api/events?projectId=${encodeURIComponent(n)}`:"/api/events";return Qt(u,{onReconnect:()=>{F()},events:{"chat:room:created":i=>{if(j.current!==h)return;const f=Ne(i);f&&d(y=>Qe(y,f))},"chat:room:updated":i=>{if(j.current!==h)return;const f=Ne(i);f&&(d(y=>Qe(y,f)),m.current?.id===f.id&&w(f))},"chat:room:deleted":i=>{if(j.current!==h)return;const f=Ne(i);f?.id&&(d(y=>y.filter(I=>I.id!==f.id)),m.current?.id===f.id&&(w(null),p([]),C([]),Le(Ce,n)))},"chat:room:member:added":i=>{if(j.current!==h)return;const f=Ne(i);!f||m.current?.id!==f.roomId||p(y=>y.some(I=>I.agentId===f.agentId)?y:[...y,f])},"chat:room:member:removed":i=>{if(j.current!==h)return;const f=Ne(i);!f||m.current?.id!==f.roomId||p(y=>y.filter(I=>I.agentId!==f.agentId))},"chat:room:message:added":i=>{if(j.current!==h)return;const f=Ne(i);f&&(d(y=>{const I=y.find(de=>de.id===f.roomId);return I?Qe(y,{...I,updatedAt:f.createdAt}):y}),m.current?.id===f.roomId&&C(y=>y.some(I=>I.id===f.id)?y:[...y,f]))},"chat:room:message:updated":i=>{if(j.current!==h)return;const f=Ne(i);!f||m.current?.id!==f.roomId||C(y=>y.map(I=>I.id===f.id?f:I))},"chat:room:message:deleted":i=>{if(j.current!==h)return;const f=Ne(i);f?.id&&C(y=>y.filter(I=>I.id!==f.id))}}})},[n,F]),s.useEffect(()=>{P&&(o.some(h=>h.id===P.id)||(w(null),p([]),C([]),Le(Ce,n)))},[P,n,o]),{rooms:o,roomsLoading:c,roomsError:A,activeRoom:P,activeRoomMembers:X,messages:J,messagesLoading:Z,selectRoom:G,createRoom:$,deleteRoom:K,sendRoomMessage:v,refreshRooms:F}}function hn(n,r=[]){const o=n.trim().replace(/^#/,"");if(!o)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(o))return{ok:!1,error:"Use lowercase letters only."};const d=o.toLowerCase();return d.length>80?{ok:!1,error:"Room names can be at most 80 characters."}:/^[a-z0-9_-]+$/.test(d)?/^[-_]|[-_]$/.test(d)?{ok:!1,error:"Room names cannot start or end with a hyphen or underscore."}:r.some(c=>c.toLowerCase()===d)?{ok:!1,error:"A room with this name already exists."}:{ok:!0,name:d}:{ok:!1,error:"Use lowercase letters, numbers, hyphens, or underscores only."}}function fn({isOpen:n,onClose:r,onCreate:o,projectId:d,existingRoomNames:c=[]}){const[x,A]=s.useState(""),[E,P]=s.useState([]),[w,X]=s.useState(""),[p,J]=s.useState([]),[C,Z]=s.useState(!1),[b,T]=s.useState(null),[m,j]=s.useState(!1),M=s.useRef(null),D=s.useRef(null);s.useEffect(()=>{n&&(D.current=document.activeElement instanceof HTMLElement?document.activeElement:null,Z(!0),T(null),at(void 0,d).then(u=>P(u)).catch(()=>{P([]),T("Failed to load agents.")}).finally(()=>Z(!1)))},[n,d]),s.useEffect(()=>{if(!n){A(""),X(""),J([]),T(null),j(!1);return}const u=window.requestAnimationFrame(()=>M.current?.focus());return()=>window.cancelAnimationFrame(u)},[n]),s.useEffect(()=>{if(!n)return;const u=i=>{i.key==="Escape"&&r()};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[n,r]),s.useEffect(()=>{n||D.current?.focus()},[n]);const F=s.useMemo(()=>hn(x,c),[x,c]),G=s.useMemo(()=>{const u=w.trim().toLowerCase();return u?E.filter(i=>i.name.toLowerCase().includes(u)):E},[E,w]),$=s.useMemo(()=>E.filter(u=>p.includes(u.id)),[E,p]),K=F.ok&&p.length>0&&!m&&!C;if(!n)return null;const v=u=>{m||J(i=>i.includes(u)?i.filter(f=>f!==u):[...i,u])},h=async()=>{if(!F.ok){T(F.error);return}if(p.length===0){T("Select at least one member.");return}T(null),j(!0);try{await o({name:F.name,displayName:`#${F.name}`,memberAgentIds:p}),r()}catch(u){T(u instanceof Error?u.message:"Failed to create room.")}finally{j(!1)}};return Ns.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:u=>u.target===u.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:u=>u.stopPropagation(),children:[t.jsxs("div",{className:"modal-header",children:[t.jsx("h3",{children:"Create room"}),t.jsx("button",{type:"button",className:"modal-close","aria-label":"Close",onClick:r,children:"×"})]}),t.jsxs("div",{className:"form-group create-room-modal-name-group",children:[t.jsx("label",{htmlFor:"create-room-name",children:"Room name"}),t.jsxs("div",{className:"create-room-modal-name-field",children:[t.jsx("span",{"aria-hidden":"true",className:"create-room-modal-name-hash",children:"#"}),t.jsx("input",{ref:M,id:"create-room-name",className:"input",value:x,disabled:m,onChange:u=>{const i=u.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();A(i)}})]}),!F.ok&&t.jsx("div",{className:"form-error",children:F.error})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{htmlFor:"create-room-member-search",children:"Members"}),t.jsx("input",{id:"create-room-member-search",className:"input",placeholder:"Search agents",value:w,disabled:m,onChange:u=>X(u.target.value)})]}),$.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:$.map(u=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>v(u.id),disabled:m,children:[u.name," ×"]},u.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:C?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):G.length===0?t.jsx("div",{className:"create-room-modal-empty",children:E.length===0?"No agents in this project yet.":"No agents match your search."}):G.map(u=>{const i=p.includes(u.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${i?" create-room-modal-member-row--selected":""}`,onClick:()=>v(u.id),disabled:m,children:[t.jsx(Zt,{agent:u,size:20}),t.jsx("span",{children:u.name}),t.jsx("span",{className:"create-room-modal-member-role",children:u.role})]},u.id)})}),b&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:b})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:m,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void h(),disabled:!K,children:m?"Creating...":"Create room"})]})]})}),document.body)}function ss(n){const r=new Date(n),d=new Date().getTime()-r.getTime(),c=Math.floor(d/1e3),x=Math.floor(c/60),A=Math.floor(x/60),E=Math.floor(A/24);return c<60?"just now":x<60?`${x}m ago`:A<24?`${A}h ago`:E<7?`${E}d ago`:r.toLocaleDateString()}function Kt(n,r){if(!n||!r)return null;const o=r.toLowerCase();if(o.includes("claude")){let c=r.replace(/^claude[- ]/i,"Claude ").replace(/sonnet[- ](\d+)[- ](\d+)/i,"Sonnet $1.$2").replace(/sonnet[- ](\d+)/i,"Sonnet $1").replace(/haiku[- ](\d+)/i,"Haiku $1").replace(/opus[- ](\d+)/i,"Opus $1").replace(/sonnet/i,"Sonnet").replace(/haiku/i,"Haiku").replace(/opus/i,"Opus").replace(/-/g," ").trim();return c=c.replace(/\s+/g," "),c.length>30?c.slice(0,30)+"…":c}if(o.includes("gpt")||o.includes("openai")){const c=r.replace(/^gpt-4-turbo$/i,"GPT-4 Turbo").replace(/^gpt-4o-mini$/i,"GPT-4o Mini").replace(/^gpt-4o$/i,"GPT-4o").replace(/^gpt-4$/i,"GPT-4").replace(/^gpt-o1-preview$/i,"GPT-o1 Preview").replace(/^gpt-o1-mini$/i,"GPT-o1 Mini").replace(/^gpt-o1$/i,"GPT-o1").replace(/^gpt/i,"GPT").trim();return c.length>30?c.slice(0,30)+"…":c}if(o.includes("gemini")){const c=r.replace(/^gemini[- ]/i,"Gemini ").replace(/pro[- ](\d+)[- ](\d+)/i,"Pro $1.$2").replace(/pro[- ](\d+)/i,"Pro $1").replace(/-/g," ").replace(/\s+/g," ").trim();return c.length>30?c.slice(0,30)+"…":c}const d=r.replace(/-/g," ").replace(/^\w/,c=>c.toUpperCase()).replace(/\s+/g," ").trim();return d.length>30?d.slice(0,30)+"…":d}function st(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function gn(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([o,d])=>{const c=typeof d=="string"?d:(()=>{try{return JSON.stringify(d)}catch{return String(d)}})();return`${o}=${st(c,50)}`}).join(", ")}function pn(n){if(n===void 0)return null;if(typeof n=="string")return st(n,200);try{return st(JSON.stringify(n),200)}catch{return st(String(n),200)}}function ns(n){if(!n||n.length===0)return null;const r=(p,J)=>{const C=p.status==="running",Z=p.status==="completed"&&p.isError,b=gn(p.args),T=pn(p.result),m=C?b:T?`result: ${T}`:b?`args: ${b}`:null,j=C?"running":Z?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${C?" chat-tool-call--running":""}${Z?" chat-tool-call--error":""}`,open:C,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-call-name",title:p.toolName,children:p.toolName}),m&&t.jsx("span",{className:"chat-tool-call-preview",title:m,children:m}),t.jsx("span",{className:"chat-tool-call-status-text",children:j})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[b&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:"args"}),t.jsx("span",{className:"chat-tool-call-value",children:b})]}),T&&t.jsxs("div",{className:`chat-tool-call-row${Z?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:"result"}),t.jsx("span",{className:"chat-tool-call-value",children:T})]})]})]},`${p.toolName}-${J}`)},o="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:o,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(Wt,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(n[0],0)]});const d=n.filter(p=>p.status==="running").length,c=n.filter(p=>p.status==="completed"&&p.isError).length,x=d>0,A=Array.from(new Set(n.map(p=>p.toolName))),E=A.slice(0,5),P=Math.max(0,A.length-E.length),w=P>0?`${E.join(", ")}, +${P} more`:E.join(", "),X=x?`(${d} running)`:c>0?`(${c} ${c===1?"error":"errors"})`:null;return t.jsx("div",{className:o,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:x,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(Wt,{size:12,"aria-hidden":"true"}),t.jsxs("span",{className:"chat-tool-calls-count",children:[n.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:w,children:w}),X&&t.jsx("span",{className:"chat-tool-calls-group-status",children:X})]}),n.map((p,J)=>r(p,J))]})})}const as={pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},Fe="__fn_agent__",bn=280,Ze=180,et=500,qt="fusion:chat-sidebar-width",Jt="fusion:chat-scope",vn=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function Yt(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const o=r[1]??"",d=r[2]??"",c=r.index+o.length;return{filter:d,start:c,end:n.length}}function xn(n,r){const o=n.slice(0,r),d=/(^|[\s\n])@([\w-]*)$/.exec(o);if(!d)return null;const c=d[2]??"",x=o.length-c.length-1;return{filter:c,start:x,end:r}}function wn({projectId:n,onClose:r,onCreate:o}){const[d,c]=s.useState("agent"),[x,A]=s.useState([]),[E,P]=s.useState(!0),[w,X]=s.useState(""),[p,J]=s.useState([]),[C,Z]=s.useState(!0),[b,T]=s.useState(""),[m,j]=s.useState([]),[M,D]=s.useState([]);s.useEffect(()=>{let v=!1;return P(!0),at(void 0,n).then(h=>{v||A(h)}).catch(()=>{v||A([])}).finally(()=>{v||P(!1)}),()=>{v=!0}},[n]),s.useEffect(()=>{Z(!0),on().then(v=>{J(v.models),j(v.favoriteProviders),D(v.favoriteModels)}).catch(()=>{J([]),j([]),D([])}).finally(()=>{Z(!1)})},[]);const F=s.useCallback(async v=>{const h=m,i=h.includes(v)?h.filter(f=>f!==v):[v,...h];j(i);try{await Gt({favoriteProviders:i,favoriteModels:M})}catch{j(h)}},[m,M]),G=s.useCallback(async v=>{const h=M,i=h.includes(v)?h.filter(f=>f!==v):[v,...h];D(i);try{await Gt({favoriteProviders:m,favoriteModels:i})}catch{D(h)}},[M,m]),$=v=>{if(v.preventDefault(),d==="agent"){if(!w)return;o({agentId:w});return}if(!b)return;const h=b.indexOf("/");if(h<=0)return;const u=b.slice(0,h),i=b.slice(h+1);o({agentId:Fe,modelProvider:u,modelId:i})},K=d==="agent"?!w:!b;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:r,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:v=>v.stopPropagation(),children:[t.jsx("h3",{children:"New Chat"}),t.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{c("agent"),T("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{c("model"),X("")},children:"Model"})]}),t.jsxs("form",{onSubmit:$,children:[d==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",E?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):x.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:x.map(v=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${w===v.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>X(v.id),"data-testid":`agent-option-${v.id}`,children:[t.jsx(nt,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:v.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:v.role})]},v.id))})]}),d==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:C?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(cn,{models:p,value:b,onChange:T,label:"Model",placeholder:"Select a model",favoriteProviders:m,onToggleFavorite:F,favoriteModels:M,onToggleModelFavorite:G})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:r,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:K,children:"Create"})]})]})]})})}const jt=s.memo(function({message:r,forcePlain:o,agentName:d,hideAssistantIdentity:c,showAssistantModelTag:x,activeModelTag:A,activeModelProvider:E,activeSessionId:P,mentionAgentsByName:w,copyAction:X}){const p=r.role==="assistant",J=s.useMemo(()=>{if(p)return null;const b=r.content,T=/@([\w-]+)/g,m=[];let j=0,M=T.exec(b);for(;M;){const[D,F=""]=M,G=M.index;G>j&&m.push(b.slice(j,G));const $=F.replace(/_/g," ").toLowerCase(),K=w.get($);K?m.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",K.name.replace(/\s+/g,"_")]},`${K.id}-${G}`)):m.push(D),j=G+D.length,M=T.exec(b)}return j<b.length&&m.push(b.slice(j)),m.length===0?b:m},[p,r.content,w]),C=s.useMemo(()=>{const b=r.attachments;if(!b||b.length===0||!P)return null;const T=`/api/chat/sessions/${encodeURIComponent(P)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:b.map(m=>{const j=m.mimeType.startsWith("image/"),M=m.id||m.filename,D=`${T}${encodeURIComponent(m.filename)}`;return j?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:D,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:D,alt:m.originalName})},M):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:D,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(an,{size:14}),t.jsx("span",{children:m.originalName})]},M)})})},[r.attachments,P]),Z=s.useMemo(()=>p?o?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:r.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(es,{remarkPlugins:[ts],components:as,children:r.content})}):null,[p,o,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}`,"data-testid":`chat-message-${r.id}`,children:[p&&!c&&t.jsxs("div",{className:"chat-message-avatar",children:[E?t.jsx(tt,{provider:E,size:"sm"}):t.jsx(nt,{size:14}),t.jsx("span",{children:d}),x&&A&&t.jsx("span",{className:"chat-model-tag",children:A})]}),p?Z:t.jsx("div",{className:"chat-message-content",children:J}),X,ns(r.toolCalls),r.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:r.thinkingOutput})]}),C,t.jsx("div",{className:"chat-message-time",children:ss(r.createdAt)})]})});function Nn({projectId:n,addToast:r}){const{activeSession:o,sessionsLoading:d,messages:c,messagesLoading:x,isStreaming:A,streamingText:E,streamingThinking:P,streamingToolCalls:w,selectSession:X,createSession:p,archiveSession:J,deleteSession:C,sendMessage:Z,stopStreaming:b,pendingMessage:T,clearPendingMessage:m,searchQuery:j,setSearchQuery:M,filteredSessions:D}=un(n,r),[F,G]=s.useState(!1),[$,K]=s.useState(""),[v,h]=s.useState(null),[u,i]=s.useState(null),[f,y]=s.useState(null),[I,de]=s.useState(!0),[Y,ae]=s.useState(bn),[re,me]=s.useState("direct"),[Ge,he]=s.useState(!1),_=mn(n,r),[oe,ie]=s.useState(new Map),[we,fe]=s.useState([]),[Re,Ve]=s.useState(!0),[ye,Se]=s.useState(!1),[Ie,Ae]=s.useState(""),[Ee,ge]=s.useState(0),[ke,pe]=s.useState(""),[ue,g]=s.useState(!1),[k,S]=s.useState(0),[R,q]=s.useState(-1),[L,ee]=s.useState(!1),[U,te]=s.useState([]),[H,O]=s.useState(!1),[B,Q]=s.useState(!1),[se,be]=s.useState({}),[,ze]=s.useState(!1),[rs,os]=s.useState({top:0,left:0}),z=Os({projectId:n}),rt=s.useCallback(e=>{if(!e||!z.mentionActive)return;const a=e.getBoundingClientRect();os({top:a.top-260,left:a.left+8})},[z.mentionActive]),At=s.useRef(null),ot=s.useRef(!1),it=s.useRef(null),ve=s.useRef(null),Te=s.useRef(null),ne=s.useRef(null),Et=s.useRef(null),Tt=s.useRef([]),_e=s.useRef(0),Ue=s.useRef(new Map),V=Hs()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(qt);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const l=Math.max(Ze,Math.min(et,a));ae(l)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(Jt);(e==="direct"||e==="rooms")&&me(e)}catch{}},[]),s.useEffect(()=>{try{localStorage.setItem(Jt,re)}catch{}},[re]);const{keyboardOverlap:Ke,viewportHeight:Dt,viewportOffsetTop:Pt,keyboardOpen:Oe}=Bs({enabled:V&&!!o}),$t=Ke>0||Pt>0,is=Oe&&$t?{"--keyboard-overlap":`${Ke}px`,"--vv-offset-top":`${Pt}px`,...Dt!==null?{"--vv-height":`${Dt}px`}:{}}:{},ce=s.useMemo(()=>{const e=Ie.trim().toLowerCase();return(e?we.filter(l=>l.name.toLowerCase().includes(e)):we).slice(0,10)},[we,Ie]),He=s.useMemo(()=>Array.from(oe.values()),[oe]),je=s.useMemo(()=>He.filter(e=>Ws(e.name,ke)),[He,ke]),ct=s.useMemo(()=>{const e=new Map;for(const a of He)e.set(a.name.toLowerCase(),a);return e},[He]);s.useEffect(()=>{ge(0)},[ce]),s.useEffect(()=>{S(0)},[ke,ue]),s.useEffect(()=>()=>{ve.current!==null&&window.clearTimeout(ve.current)},[]);const Lt=s.useCallback(()=>{const e=Te.current;if(!e)return;const l=e.scrollTop+e.clientHeight>=e.scrollHeight-50;Q(!l),ot.current=!l},[]),qe=s.useCallback(e=>{if(!e.isConnected)return;let a=0,l=0,N=-1;const W=6,le=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===N?l+=1:(l=0,N=e.scrollHeight),a+=1,a>=W||l>=2){Q(!1),ot.current=!1;return}window.requestAnimationFrame(le)}};le()},[]),Be=s.useCallback(()=>{const e=Te.current;e&&qe(e)},[qe]);s.useLayoutEffect(()=>{const e=o?.id??null;if(!e){it.current=null;return}const a={sessionId:e,loaded:!x,hasMessages:c.length>0},l=it.current,N=l?.sessionId!==e,W=l?.sessionId===e&&!l.loaded&&a.loaded,le=l?.sessionId===e&&!l.hasMessages&&a.hasMessages;if(!(l===null||N||W||le))return;const xe=Te.current;xe&&(qe(xe),it.current=a)},[o?.id,c.length,x,qe]),s.useEffect(()=>{ot.current||Be()},[c,E,P,A,Be]),s.useEffect(()=>{Ke<=0||!Te.current||Be()},[Ke,Be]),Gs(V&&Oe),s.useEffect(()=>{const e=()=>h(null);if(v)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[v]),s.useEffect(()=>{if(!V||!Oe)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[V,Oe]),s.useEffect(()=>{if(!V||!o)return;const e=()=>{const a=ne.current;a&&document.activeElement===a&&(a.blur(),window.setTimeout(()=>{a.focus({preventScroll:!0})},0))};return document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",e)}},[V,o]),s.useEffect(()=>{let e=!1;const a=n;return at(void 0,n).then(l=>{if(e||a!==n)return;const N=new Map;for(const W of l)N.set(W.id,W);ie(N)}).catch(()=>{}),()=>{e=!0}},[n]),s.useEffect(()=>{let e=!1;return Ve(!0),Vs(n).then(a=>{e||fe(a)}).catch(()=>{e||fe([])}).finally(()=>{e||Ve(!1)}),()=>{e=!0}},[n]),s.useEffect(()=>{Tt.current=U},[U]),s.useEffect(()=>()=>{for(const e of Tt.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of Ue.current.values())window.clearTimeout(e);Ue.current.clear()},[]);const Je=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const l of Array.from(e)){if(!vn.includes(l.type))continue;const N=l.type.startsWith("image/");a.push({file:l,previewUrl:N?URL.createObjectURL(l):""})}a.length>0&&te(l=>[...l,...a])},[]),cs=s.useCallback(e=>{te(a=>{const l=a[e];return l?.previewUrl&&URL.revokeObjectURL(l.previewUrl),a.filter((N,W)=>W!==e)})},[]),ls=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const l=Array.from(a).filter(N=>N.type.startsWith("image/"));l.length!==0&&Je(l)},[Je]),ds=s.useCallback(async e=>{try{await p(e),G(!1),V&&de(!1)}catch{r("Failed to create chat session","error")}},[p,r,V]),lt=s.useCallback(()=>{K(""),Se(!1),Ae(""),g(!1),pe(""),q(-1),te(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[]),dt=s.useCallback(()=>{const e=$.trim(),a=U.map(l=>l.file);if(!(!e&&a.length===0||!o)){if(e==="/clear"){lt(),b(),m(),p({agentId:o.agentId,modelProvider:o.modelProvider??void 0,modelId:o.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}lt(),Z(e,a)}},[$,U,o,lt,b,m,p,r,Z]),ut=s.useCallback(async()=>{const e=$.trim();if(e){if(re==="rooms"){if(!_.activeRoom)return;await _.sendRoomMessage(e),K("");return}dt()}},[$,re,_,dt]),mt=s.useCallback(e=>{K(a=>{const l=Yt(a);if(!l)return a;const N=`/skill:${e.name} `,W=a.slice(0,l.start)+N+a.slice(l.end);return window.requestAnimationFrame(()=>{ne.current&&(ne.current.style.height="auto",ne.current.style.height=`${Math.min(ne.current.scrollHeight,120)}px`,ne.current.focus())}),W}),Se(!1),Ae(""),ge(0)},[]),ht=s.useCallback(e=>{const a=ne.current;if(!a||R<0)return;const l=a.selectionStart??_e.current,N=a.selectionEnd??l,W=Math.max(l,N),le=Math.min(R,W),xe=`${`@${e.name.replace(/\s+/g,"_")}`} `,St=$.slice(0,le)+xe+$.slice(W),$e=le+xe.length;K(St),g(!1),pe(""),S(0),q(-1),window.requestAnimationFrame(()=>{ne.current&&(ne.current.style.height="auto",ne.current.style.height=`${Math.min(ne.current.scrollHeight,120)}px`,ne.current.focus(),ne.current.setSelectionRange($e,$e))})},[R,$]),Ft=s.useCallback(e=>{if(_e.current=e.currentTarget.selectionStart??_e.current,z.mentionActive&&z.files.length>0){if(z.handleKeyDown(e,$),e.key==="Enter"||e.key==="Tab"){const a=z.files[z.selectedIndex];if(a){const l=z.selectFile(a,$);K(l),z.dismissMention(),ze(!1)}}return}if(ue&&e.key==="ArrowDown"){e.preventDefault(),je.length>0&&S(a=>(a+1)%je.length);return}if(ue&&e.key==="ArrowUp"){e.preventDefault(),je.length>0&&S(a=>a===0?je.length-1:a-1);return}if(ue&&e.key==="Enter"){e.preventDefault();const a=je[k]??je[0];a&&ht(a);return}if(ue&&e.key==="Escape"){e.preventDefault(),g(!1),pe(""),q(-1);return}if(ye&&e.key==="ArrowDown"){e.preventDefault(),ce.length>0&&ge(a=>(a+1)%ce.length);return}if(ye&&e.key==="ArrowUp"){e.preventDefault(),ce.length>0&&ge(a=>a===0?ce.length-1:a-1);return}if(ye&&(e.key==="Enter"||e.key==="Tab")&&ce.length>0){e.preventDefault();const a=ce[Ee]??ce[0];a&&mt(a);return}if(ye&&e.key==="Escape"){e.preventDefault(),Se(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),ut())},[ue,je,k,ht,ye,ce,Ee,mt,ut,z,$]),Ye=s.useCallback((e,a)=>{const l=xn(e,a);if(l){g(!0),pe(l.filter),q(l.start);return}g(!1),pe(""),q(-1)},[]),It=s.useCallback(e=>{const a=e.target,l=a.value,N=a.selectionStart??l.length;_e.current=N,K(l);const W=Yt(l);W?(Se(!0),Ae(W.filter)):(Se(!1),Ae("")),Ye(l,N),z.detectMention(l,N),ze(z.mentionActive),z.mentionActive&&rt(a),a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,120)}px`},[Ye]),ft=s.useCallback(e=>{const a=e.currentTarget,l=a.selectionStart??a.value.length;_e.current=l,Ye(a.value,l),z.detectMention(a.value,l),ze(z.mentionActive),z.mentionActive&&rt(a)},[Ye,z,rt]),us=s.useCallback(e=>{e.key!=="Escape"&&ft(e)},[ft]),ms=s.useCallback(()=>{ve.current!==null&&window.clearTimeout(ve.current),ve.current=window.setTimeout(()=>{Se(!1),g(!1),pe(""),q(-1),ze(!1),z.dismissMention(),ve.current=null},120)},[z]),hs=s.useCallback(()=>{ve.current!==null&&(window.clearTimeout(ve.current),ve.current=null),typeof window<"u"&&window.innerWidth<=768&&window.setTimeout(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)},0)},[]),fs=s.useCallback(async e=>{h(null);try{await J(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[J,r]),gs=s.useCallback(async e=>{i(null),h(null);try{await C(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[C,r]),We=s.useCallback(e=>{try{localStorage.setItem(qt,String(e))}catch{}},[]),ps=s.useCallback(e=>{if(V)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const l=e.clientX,N=Y;let W=N;document.body.style.userSelect="none";const le=xe=>{const St=xe.clientX-l,$e=Math.max(Ze,Math.min(et,N+St));W=$e,ae($e),We($e)},Pe=xe=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(xe.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",le),document.removeEventListener("pointerup",Pe),We(W)};document.addEventListener("pointermove",le),document.addEventListener("pointerup",Pe)},[V,We,Y]),bs=s.useCallback(e=>{if(V||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,l=e.key==="ArrowLeft"?-a:a,N=Math.max(Ze,Math.min(et,Y+l));ae(N),We(N)},[V,We,Y]),vs=s.useCallback(e=>{X(e),V&&de(!1)},[X,V]),xs=s.useCallback(()=>{X(""),de(!0)},[X]),ws=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(rn,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>G(!0),children:[t.jsx(Xe,{size:16}),"New Chat"]})]}),Me=Kt(o?.modelProvider,o?.modelId),De=o?.modelProvider??null,gt=!!(o||A||c.length>0),zt=o?.agentId===Fe?Me??"Fusion":o?.title||oe.get(o?.agentId??"")?.name||o?.agentId||"Chat",ys=!!(Me&&Me!==zt),pt=oe.get(o?.agentId??"")?.name||(o?.agentId===Fe?Me??"Fusion":o?.agentId?.slice(0,30)??"Fusion"),bt=!1,vt=o?.agentId===Fe,Ss=T.length>50?`${T.slice(0,50)}…`:T,ks=s.useCallback(()=>{ee(e=>!e)},[]),xt=s.useCallback((e,a)=>{const l=Ue.current.get(e);l&&window.clearTimeout(l),be(W=>({...W,[e]:a}));const N=window.setTimeout(()=>{be(W=>{const{[e]:le,...Pe}=W;return Pe}),Ue.current.delete(e)},2e3);Ue.current.set(e,N)},[]),_t=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),xt(e,"success")}catch{xt(e,"error")}},[xt]),Cs=s.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(es,{remarkPlugins:[ts],components:as,children:e})}),[]),wt=o?.agentId===Fe,yt=s.useCallback((e,a,l)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${se[e]==="success"?" chat-message-copy-action--success":""}${se[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":l??`chat-copy-response-${e}`,"aria-label":se[e]==="success"?"Response copied":se[e]==="error"?"Copy failed":"Copy response",onClick:()=>{_t(e,a)},children:se[e]==="success"?t.jsx(Ks,{size:14}):t.jsx(qs,{size:14})}),[se,_t]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${I?"":" chat-sidebar--hidden"}`,style:V?void 0:{width:`${Y}px`},children:[t.jsxs("div",{className:"chat-sidebar-scope-toggle",role:"tablist","data-testid":"chat-sidebar-scope-toggle",children:[t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${re==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":re==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>me("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${re==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":re==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>me("rooms"),children:"Rooms"})]}),re==="direct"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"chat-sidebar-search-container",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(Js,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:j,onChange:e=>M(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:d?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):D.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):D.map(e=>t.jsxs("div",{className:`chat-session-item${o?.id===e.id?" chat-session-item--active":""}`,onClick:()=>vs(e.id),onContextMenu:a=>{a.preventDefault(),h({sessionId:e.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),i(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(kt,{size:14})}),t.jsx("div",{className:"chat-session-title",children:e.title||"Untitled"}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||"No messages"}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsxs("span",{className:"chat-session-meta-model",children:[e.modelProvider&&t.jsx(tt,{provider:e.modelProvider,size:"sm"}),t.jsx("span",{children:oe.get(e.agentId)?.name||(e.agentId===Fe?Kt(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?ss(e.updatedAt):""})]})]},e.id))})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[t.jsx("div",{className:"chat-sidebar-rooms-header",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>he(!0),children:[t.jsx(Xe,{size:14}),"Create room"]})}),_.rooms.length===0?t.jsx("div",{className:"chat-sidebar-rooms-empty","data-testid":"chat-sidebar-rooms-empty",children:"No rooms yet."}):t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:_.rooms.map(e=>{const a=_.activeRoom?.id===e.id,l=a?_.activeRoomMembers.length:"—";return t.jsxs("div",{role:"button",tabIndex:0,className:`chat-room-item${a?" chat-room-item--active":""}`,"data-testid":`chat-room-item-${e.slug}`,onClick:()=>{_.selectRoom(e.id),V&&de(!1)},onKeyDown:N=>{(N.key==="Enter"||N.key===" ")&&(N.preventDefault(),_.selectRoom(e.id),V&&de(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),t.jsxs("span",{className:"chat-room-item-meta",children:[l," ",l===1?"member":"members"]})]}),t.jsx("button",{type:"button",className:"btn-icon chat-room-item-delete","data-testid":`chat-room-delete-${e.slug}`,"aria-label":`Delete room ${e.name}`,onClick:N=>{N.stopPropagation(),y(e.id)},children:t.jsx(kt,{size:14})})]},e.id)})})]}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>G(!0),"data-testid":"chat-new-btn",children:[t.jsx(Xe,{size:14}),"New Chat"]})})]}),!V&&I&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Ze,"aria-valuemax":et,"aria-valuenow":Y,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:ps,onKeyDown:bs}),v&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:v.y,left:v.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>fs(v.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Ys,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{h(null),i(v.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(kt,{size:14}),"Delete"]})]}),u&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>i(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>i(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void gs(u),children:"Delete"})]})]})}),f&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>y(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Room?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. This room and all its messages will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>y(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await _.deleteRoom(f),y(null)}catch{r("Failed to delete room","error")}})()},children:"Delete"})]})]})}),re==="rooms"?t.jsxs("div",{className:"chat-thread",children:[_.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[V&&t.jsx("button",{className:"btn-icon",onClick:()=>{_.selectRoom(null),de(!0)},"data-testid":"chat-back-btn",children:t.jsx(Ht,{size:16})}),t.jsxs("div",{className:"chat-thread-header-title",children:["#",_.activeRoom.name]}),t.jsx("div",{className:"chat-room-thread-members",children:_.activeRoomMembers.map(e=>t.jsx(Zt,{agent:oe.get(e.agentId)??null},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:Te,onScroll:Lt,children:[_.messagesLoading?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):_.messages.length===0?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):_.messages.map(e=>{const a=e.senderAgentId?oe.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",l={id:e.id,sessionId:e.roomId,role:e.role,content:e.content,thinkingOutput:e.thinkingOutput??void 0,toolCalls:void 0,fallbackInfo:void 0,attachments:e.attachments,createdAt:e.createdAt};return t.jsx(jt,{message:l,forcePlain:L,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:_.activeRoom?.id??null,mentionAgentsByName:ct},e.id)}),t.jsx("div",{ref:At})]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),_.activeRoom&&t.jsx("div",{className:"chat-input-area",children:t.jsxs("div",{className:"chat-input-row",children:[t.jsx("div",{className:"chat-input-wrapper",children:t.jsx("textarea",{ref:ne,className:"chat-input-textarea",placeholder:"Type a message...",value:$,onChange:It,onKeyDown:Ft,rows:1,"data-testid":"chat-input"})}),t.jsx("button",{type:"button",className:"chat-input-send",onClick:()=>{ut()},disabled:!$.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Bt,{size:16})})]})})]}):t.jsxs("div",{className:`chat-thread${Oe&&$t?" chat-thread--keyboard-active":""}`,style:is,children:[(gt||!V)&&t.jsxs("div",{className:"chat-thread-header",children:[V&>&&t.jsx("button",{className:"btn-icon",onClick:xs,"data-testid":"chat-back-btn",children:t.jsx(Ht,{size:16})}),t.jsxs("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:[De?t.jsx(tt,{provider:De,size:"md"}):t.jsx(nt,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:zt}),ys&&t.jsx("span",{className:"chat-model-tag",children:Me})]}),gt&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${L?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":L?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:ks,children:L?t.jsx(Xs,{size:14}):t.jsx(Qs,{size:14})}),!V&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>G(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(Xe,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:Te,onScroll:Lt,children:[A?t.jsxs(t.Fragment,{children:[c.map(e=>t.jsx(jt,{message:e,forcePlain:L,agentName:pt,hideAssistantIdentity:vt,showAssistantModelTag:bt,activeModelTag:Me,activeModelProvider:De,activeSessionId:o?.id??null,mentionAgentsByName:ct,copyAction:wt&&e.role==="assistant"?yt(e.id,e.content):void 0},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!vt&&t.jsxs("div",{className:"chat-message-avatar",children:[De?t.jsx(tt,{provider:De,size:"sm"}):t.jsx(nt,{size:14}),t.jsx("span",{children:pt}),bt]}),E?Cs(E,L):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:P?"Thinking…":"Connecting…"}),wt&&E&&yt("__streaming__",E,"chat-copy-response-streaming"),ns(w),P&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:P})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):x?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):c.length===0&&!o?ws():c.length===0&&o?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:c.map(e=>t.jsx(jt,{message:e,forcePlain:L,agentName:pt,hideAssistantIdentity:vt,showAssistantModelTag:bt,activeModelTag:Me,activeModelProvider:De,activeSessionId:o?.id??null,mentionAgentsByName:ct,copyAction:wt&&e.role==="assistant"?yt(e.id,e.content):void 0},e.id))}),t.jsx("div",{ref:At})]}),B&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:Be,children:[t.jsx(Zs,{size:14}),"Latest"]}),o&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:Et,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Je(e.target.files),e.target.value=""}}),ye&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:Re?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):ce.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:Ie?"No skills found":"No skills available"}):ce.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===Ee,className:`chat-skill-menu-item${a===Ee?" chat-skill-menu-item--highlighted":""}`,onMouseDown:l=>l.preventDefault(),onMouseEnter:()=>ge(a),onClick:()=>mt(e),children:[t.jsx("span",{className:"chat-skill-menu-item-name",children:e.name}),t.jsx("span",{className:"chat-skill-menu-item-description",title:e.relativePath,children:e.relativePath})]},e.id))}),U.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:U.map((e,a)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${a}`,children:[e.previewUrl?t.jsx("img",{src:e.previewUrl,alt:e.file.name}):t.jsx("span",{className:"chat-attachment-preview-name",children:e.file.name}),t.jsx("button",{type:"button",className:"chat-attachment-remove",onClick:()=>cs(a),"data-testid":`chat-attachment-remove-${a}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${a}`))}),t.jsxs("div",{className:"chat-input-row",children:[t.jsx("button",{type:"button",className:"btn-icon chat-attach-btn","data-testid":"chat-attach-btn","aria-label":"Attach files",onClick:()=>Et.current?.click(),children:t.jsx(en,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${H?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),O(!0)},onDragLeave:()=>O(!1),onDrop:e=>{e.preventDefault(),O(!1),Je(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:ne,className:"chat-input-textarea",placeholder:"Type a message...",value:$,onChange:It,onKeyDown:Ft,onKeyUp:us,onClick:ft,onBlur:ms,onFocus:hs,onPaste:ls,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(tn,{agents:He,filter:ke,highlightedIndex:k,visible:ue,onSelect:ht,position:"below"}),t.jsx(sn,{visible:z.mentionActive&&!ue,position:rs,files:z.files,selectedIndex:z.selectedIndex,onSelect:e=>{const a=z.selectFile(e,$);K(a),z.dismissMention(),ze(!1),ne.current?.focus()},loading:z.loading}),T&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${Ss}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:m,children:"×"})]})]}),A?t.jsx("button",{className:"chat-input-stop",onClick:b,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(nn,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{dt()},disabled:!$.trim()&&U.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Bt,{size:16})})]})]})]}),t.jsx(fn,{isOpen:Ge,onClose:()=>he(!1),projectId:n,existingRoomNames:_.rooms.map(e=>e.name),onCreate:async e=>{await _.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),he(!1)}}),F&&t.jsx(wn,{projectId:n,onClose:()=>G(!1),onCreate:ds})]})}export{Nn as ChatView};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";import{au as oe,av as de,s as ue,aw as he,ax as me,ay as be,az as fe,aA as ve,aB as xe,aC as pe,u as ye,aD as ge,x as je,aE as Re,L as Se,S as _e}from"./index-TFYXEVpn.js";import"./vendor-xterm-DzcZoU0P.js";const O={webSearch:!0,pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function X(n){const t=n?.researchGlobalDefaults,c=n?.researchSettings;return{enabled:c?.enabled??n?.researchEnabled??n?.researchGlobalEnabled??!0,searchProvider:c?.searchProvider??t?.searchProvider,synthesisProvider:c?.synthesisProvider??t?.synthesisProvider,synthesisModelId:c?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:c?.enabledSources?.webSearch??t?.enabledSources?.webSearch??O.webSearch,pageFetch:c?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??O.pageFetch,github:c?.enabledSources?.github??t?.enabledSources?.github??O.github,localDocs:c?.enabledSources?.localDocs??t?.enabledSources?.localDocs??O.localDocs,llmSynthesis:c?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??O.llmSynthesis},limits:{maxConcurrentRuns:c?.limits?.maxConcurrentRuns??n?.researchMaxConcurrentRuns??n?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:c?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??n?.researchMaxSourcesPerRun??n?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:c?.limits?.maxDurationMs??n?.researchDefaultTimeout??n?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:c?.limits?.requestTimeoutMs??n?.researchGlobalFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const we=300,Ne=4e3,ke=["queued","running","cancelling","retry_waiting"];function Z(n,t){if(n instanceof pe){const c=n;return{message:n.message,status:n.status,code:c.researchCode??"INTERNAL_ERROR",setupHint:c.setupHint,retryable:c.retryable}}return n instanceof Error?{message:n.message,code:"INTERNAL_ERROR"}:{message:t,code:"INTERNAL_ERROR"}}function Ee(n){if(!n)return{cancelable:!1,retryable:!1,isTransitioning:!1,blockingReason:"No run selected"};const t=ke.includes(n.status),c=n.status==="queued"||n.status==="running",f=n.lifecycle?.retryable,u=n.status==="failed"||n.status==="timed_out",r=!!(u&&f);let p;return!c&&t?p="Run is already transitioning":!c&&n.status==="completed"?p="Completed runs cannot be cancelled":!c&&n.status==="cancelled"?p="Run is already cancelled":!c&&n.status==="retry_exhausted"?p="Retry attempts exhausted":!c&&n.status==="failed"?p="Failed runs cannot be cancelled":!c&&n.status==="timed_out"&&(p="Timed out runs cannot be cancelled"),!r&&u&&f===!1&&(p=n.lifecycle?.errorCode==="RETRY_EXHAUSTED"?"Retry attempts exhausted":"Run is not retryable"),{cancelable:c,retryable:r,isTransitioning:t,blockingReason:p}}function Ce(n){const t=n?.projectId,[c,f]=i.useState([]),[u,r]=i.useState(null),[p,R]=i.useState(null),[g,w]=i.useState({available:!0}),[k,P]=i.useState(!0),[L,T]=i.useState(null),[M,j]=i.useState(null),[S,F]=i.useState(""),E=i.useRef(0),N=i.useRef(0),_=i.useRef(t);i.useEffect(()=>{_.current!==t&&(_.current=t,N.current++)},[t]);const v=i.useCallback(async(o=S)=>{const a=++E.current,l=t;T(null),j(null);try{const y=await oe({q:o||void 0,limit:100},l);if(a!==E.current||l!==t)return;f(y.runs),w(y.availability),u&&!y.runs.some(b=>b.id===u)&&(r(null),R(null))}catch(y){if(a!==E.current||l!==t)return;const b=Z(y,"Failed to load research runs");T(b.message),j(b)}finally{a===E.current&&P(!1)}},[t,S,u]),x=i.useCallback(async o=>{const a=await de(o,t);return R(a.run),w(a.availability),a.run},[t]);return i.useEffect(()=>{P(!0);const o=window.setTimeout(()=>{v(S)},we);return()=>window.clearTimeout(o)},[v,S]),i.useEffect(()=>{if(!u){R(null);return}x(u)},[x,u]),i.useEffect(()=>{const o=N.current,a=()=>N.current!==o,l=t?`?projectId=${encodeURIComponent(t)}`:"";let y=!0;const b=()=>{!y||a()||(v(),u&&x(u))},D=ue(`/api/events${l}`,{events:{"research:run:created":b,"research:run:updated":b,"research:run:completed":b,"research:run:failed":b,"research:run:cancelled":b},onReconnect:b}),U=window.setInterval(b,Ne);return()=>{y=!1,D(),window.clearInterval(U)}},[t,v,u,x]),{runs:c,selectedRun:p,selectedRunId:u,setSelectedRunId:r,availability:g,loading:k,error:L,searchQuery:S,setSearchQuery:F,refresh:v,createRun:o=>xe(o,t),cancelRun:async o=>{try{j(null);const a=await ve(o,t);return u===o&&R(a.run),await v(),a}catch(a){const l=Z(a,"Failed to cancel run");throw j(l),l}},retryRun:async o=>{try{j(null);const a=await fe(o,t);return u===o&&R(a.run),await v(),a}catch(a){const l=Z(a,"Failed to retry run");throw j(l),l}},exportRun:(o,a)=>be(o,a,t),createTaskFromRun:(o,a,l,y,b,D)=>me(o,{title:a,findingId:l,description:y,priority:b,attachExport:D},t),attachRunToTask:(o,a,l,y)=>he(o,{taskId:a,findingId:l,attachExport:y},t),uiError:M,runActionState:Ee(p),statusCounts:c.reduce((o,a)=>(o[a.status]+=1,o),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function Pe({open:n,mode:t,run:c,finding:f,projectId:u,onClose:r,onConfirm:p}){ye(n);const[R,g]=i.useState(!1),[w,k]=i.useState(""),[P,L]=i.useState(""),[T,M]=i.useState("normal"),[j,S]=i.useState(""),[F,E]=i.useState([]),[N,_]=i.useState(!1),[v,x]=i.useState(!1),o=i.useMemo(()=>{const a=(f.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${f.heading||"Research finding"} — ${a}`.trim()},[f.content,f.heading]);return i.useEffect(()=>{n&&(g(!1),k(`Research: ${f.heading||c.title}`),L(o),M("normal"),S(""),t==="enrich"&&(_(!0),ge(50,0,u).then(a=>E(a.filter(l=>l.column!=="archived"))).finally(()=>_(!1))))},[n,t,u,f.heading,o,c.title]),n?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:r,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:a=>a.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:t==="create"?"Create task from finding":"Enrich existing task"}),e.jsx("button",{className:"modal-close",type:"button","aria-label":"Close",onClick:r,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Run:"})," ",c.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",f.id,f.heading?` — ${f.heading}`:""]}),e.jsx("p",{children:o||"No preview available."})]}),t==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:["Title",e.jsx("input",{className:"input",value:w,onChange:a=>k(a.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:P,onChange:a=>L(a.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:T,onChange:a=>M(a.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"normal",children:"Normal"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"urgent",children:"Urgent"})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:["Target task",e.jsx("input",{className:"input",list:"research-task-action-task-list",value:j,placeholder:N?"Loading tasks…":"Enter task ID",onChange:a=>S(a.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:F.map(a=>e.jsx("option",{value:a.id,children:a.title},a.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:R,onChange:a=>g(a.target.checked)}),e.jsx("span",{children:"Attach markdown export artifact"})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:r,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:v||t==="enrich"&&!j,onClick:()=>{x(!0),p({taskId:t==="enrich"?j:void 0,title:t==="create"?w.trim():void 0,description:t==="create"?P.trim():void 0,priority:t==="create"?T:void 0,attachExport:R}).finally(()=>x(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const Te=["web-search","page-fetch","github","local-docs","llm-synthesis"],Ae={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},Ie={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};function qe({projectId:n,addToast:t,onOpenSettings:c,readinessVersion:f=0}){const{runs:u,selectedRun:r,selectedRunId:p,setSelectedRunId:R,availability:g,loading:w,error:k,searchQuery:P,setSearchQuery:L,createRun:T,cancelRun:M,retryRun:j,exportRun:S,createTaskFromRun:F,attachRunToTask:E,statusCounts:N,refresh:_,uiError:v,runActionState:x}=Ce({projectId:n}),[o,a]=i.useState(""),[l,y]=i.useState(()=>X(void 0)),[b,D]=i.useState([]),[U,z]=i.useState(!1),[ee,se]=i.useState([]),[A,$]=i.useState(null),[I,H]=i.useState(null),Q=g.supportedProviders??Te,G=s=>l.enabledSources[Ae[s]];i.useEffect(()=>{const s=Q.filter(d=>G(d));se(d=>{const m=d.filter(h=>s.includes(h));return m.length>0?m:s})},[l.enabledSources,Q]),i.useEffect(()=>{let s=!1;return Promise.all([je(n),Re().catch(()=>({providers:[]}))]).then(([d,m])=>{s||(y(X(d)),D(m.providers.filter(h=>h.type==="api_key").map(h=>({id:h.id,authenticated:h.authenticated}))))}).catch(()=>{s||y(X(void 0))}),()=>{s=!0}},[n,f]);const ie=i.useMemo(()=>r?r.status:"No run selected",[r]),ce=i.useMemo(()=>r?r.status==="queued"||r.status==="retry_waiting"?"status-dot status-dot--pending":r.status==="running"?"status-dot status-dot--connecting":r.status==="completed"?"status-dot status-dot--online":r.status==="failed"||r.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[r]),K=g.supportedExportFormats??["markdown","json","html"],V=l.searchProvider,te=l.enabledSources.webSearch&&!V,ae=l.enabledSources.llmSynthesis&&(!l.synthesisProvider||!l.synthesisModelId),Y=i.useMemo(()=>new Map(b.map(s=>[s.id,s.authenticated])),[b]),J=i.useMemo(()=>{const s=new Set;return l.enabledSources.webSearch&&V&&s.add(V),l.enabledSources.llmSynthesis&&l.synthesisProvider&&s.add(l.synthesisProvider),[...s].filter(d=>Y.has(d))},[l.enabledSources.llmSynthesis,l.enabledSources.webSearch,l.synthesisProvider,V,Y]).find(s=>Y.get(s)!==!0),q=i.useMemo(()=>g.available?l.enabled?te||ae?{reason:"Research defaults are incomplete.",details:"Select the required provider/model defaults in Research settings.",settingsSection:"research-global"}:J?{reason:`Missing API key for ${J}.`,details:"Add provider credentials in Authentication settings.",settingsSection:"authentication"}:null:{reason:"Research is disabled for this project.",details:"Enable project research settings to create runs.",settingsSection:"research-project"}:{reason:g.reason??"Research is unavailable for this project.",details:g.setupInstructions,settingsSection:"research-project"},[g.available,g.reason,g.setupInstructions,l.enabled,J,te,ae]),B=async(s,d,m)=>{$(s);try{await d(),t?.(m,"success"),await _()}catch(h){t?.(h instanceof Error?h.message:"Action failed","error")}finally{$(null)}},W=async s=>{if(r){$(`export-${s}`);try{const d=await S(r.id,s),m=new Blob([d.content],{type:"text/plain;charset=utf-8"}),h=URL.createObjectURL(m),C=document.createElement("a");C.href=h,C.download=d.filename,document.body.appendChild(C),C.click(),C.remove(),URL.revokeObjectURL(h),t?.(`Exported ${d.filename}`,"success")}catch(d){t?.(d instanceof Error?d.message:"Export failed","error")}finally{$(null)}}},le=async()=>{if(o.trim()){z(!0);try{const s=ee.filter(m=>G(m));if(s.length===0){z(!1),t?.("No enabled research sources are available for this project.","error");return}const d=await T({query:o.trim(),providers:s});R(d.run.id),a(""),t?.("Research run created","success"),await _()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{z(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":"Research view",children:[e.jsxs("header",{className:"research-view__header",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"research-view__title",children:"Research"}),e.jsx("p",{className:"research-view__subtitle",children:"Create and track research runs with cited findings."})]}),e.jsx("button",{className:"btn",type:"button",onClick:()=>void _(),children:"Refresh"})]}),q?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:q.reason}),q.details&&e.jsx("p",{children:q.details}),e.jsxs("p",{children:["Current defaults: provider ",l.searchProvider??"(not set)",", max sources ",l.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void _(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>c?.(q.settingsSection),children:"Open Settings"})]})]}):e.jsxs("div",{className:"research-view__layout",children:[e.jsxs("aside",{className:"research-view__sidebar card",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:"Query"}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:o,onChange:s=>a(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:Q.map(s=>e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:ee.includes(s),disabled:!G(s),onChange:()=>{G(s)&&se(d=>d.includes(s)?d.filter(m=>m!==s):[...d,s])}}),e.jsx("span",{children:Ie[s]??s})]},s))})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!o.trim()||U,onClick:()=>void le(),children:[U?e.jsx(Se,{className:"animate-spin",size:14}):null,"Create Run"]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:"Search"}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(_e,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:P,onChange:s=>L(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:u.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item card${p===s.id?" research-view__history-item--active":""}`,onClick:()=>R(s.id),children:[e.jsx("span",{className:"card-id",children:s.id}),e.jsx("span",{children:s.title})]},s.id))})]}),e.jsxs("div",{className:"research-view__reader card",children:[w&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!w&&k&&e.jsx("p",{"data-testid":"research-state-error",children:k}),!w&&!k&&u.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),r&&e.jsxs("div",{children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:ce}),e.jsx("strong",{children:ie})]}),e.jsx("h3",{className:"research-view__run-title",children:r.title}),e.jsx("p",{className:"research-view__run-query",children:r.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:r.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",title:x.cancelable?void 0:x.blockingReason,disabled:A==="cancel"||A==="retry"||!x.cancelable,onClick:()=>void B("cancel",()=>M(r.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",title:x.retryable?void 0:x.blockingReason,disabled:A==="cancel"||A==="retry"||!x.retryable,onClick:()=>void B("retry",()=>j(r.id),"Run retried"),children:"Retry"}),K.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-markdown",onClick:()=>void W("markdown"),children:"Export MD"}),K.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-json",onClick:()=>void W("json"),children:"Export JSON"}),K.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:A==="export-html",onClick:()=>void W("html"),children:"Export HTML"})]}),r.error&&e.jsx("p",{className:"research-view__error",children:r.error}),v&&e.jsxs("div",{className:"form-error",role:"alert",children:[e.jsx("p",{children:v.message}),v.setupHint&&e.jsx("p",{children:v.setupHint}),v.code==="MISSING_CREDENTIALS"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>c?.("authentication"),children:"Open Authentication Settings"}),v.code==="FEATURE_DISABLED"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>c?.("research-project"),children:"Open Research Settings"})]}),x.blockingReason&&e.jsx("p",{className:"research-view__run-query",children:x.blockingReason}),Array.isArray(r.results?.findings)&&r.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:r.results.findings.map((s,d)=>{const h=s.id?.trim()||`finding-${d+1}`;return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:s.heading}),e.jsx("p",{children:s.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>H({mode:"create",findingId:h}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>H({mode:"enrich",findingId:h}),children:"Enrich Task"})]})]},h)})}),Array.isArray(r.results?.citations)&&r.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:r.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),r.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:r.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!r&&u.length>0&&e.jsx("p",{children:"Select a run to view details."}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Running"}),e.jsx("div",{className:"research-view__stat-value",children:N.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Completed"}),e.jsx("div",{className:"research-view__stat-value",children:N.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Failed"}),e.jsx("div",{className:"research-view__stat-value",children:N.failed})]})]})]})]}),r&&I&&(()=>{const s=r.results?.findings?.findIndex((m,h)=>(m.id?.trim()||`finding-${h+1}`)===I.findingId)??-1,d=s>=0?r.results.findings[s]:null;return d?e.jsx(Pe,{open:!0,mode:I.mode,run:r,finding:{id:I.findingId,heading:d.heading,content:d.content},projectId:n,onClose:()=>H(null),onConfirm:async({taskId:m,title:h,description:C,priority:re,attachExport:ne})=>{I.mode==="create"?await B("create-task",()=>F(r.id,h,I.findingId,C,re,ne),"Task created from research"):m&&await B("attach-task",()=>E(r.id,m,I.findingId,ne),"Task enriched from research"),H(null)}}):null})()]})}export{qe as ResearchView};
|