@amd-gaia/agent-ui 0.25.1 → 0.25.2-rc.2

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.
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{n as t,o as n,s as r,u as i}from"./apiBase-BmPG2Rib.js";import{B as a,J as o,K as s,Pt as c,cn as l,ct as u,et as d,gt as f,ht as p,i as m,it as h,mt as g,nt as _,qt as v,r as y,rt as b,sn as x,tt as S,z as C}from"./index-D-noqAc3.js";var w=e(i(),1),T=t();function E(){return window.gaiaUpdater}function D({onClose:e}){let[t,r]=(0,w.useState)({kind:`loading`}),i=(0,w.useRef)(null);(0,w.useEffect)(()=>{let e=E();e?e.listReleases().then(e=>{r(Array.isArray(e)?{kind:`list`,releases:e}:{kind:`error`,message:e.error})}).catch(()=>{r({kind:`error`,message:`Couldn't reach GitHub to list releases — check your connection; you can still download installers from the Releases page.`})}):r({kind:`error`,message:`Couldn't reach GitHub to list releases — check your connection; you can still download installers from the Releases page.`})},[]),n(!0,e),s(i,!0),(0,w.useEffect)(()=>{let e=i.current;e&&e.querySelector(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`)?.focus()},[]),(0,w.useEffect)(()=>{let e=i.current;if(!e)return;function t(t){if(t.key!==`Tab`||!e)return;let n=e.querySelectorAll(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`);if(n.length===0)return;let r=n[0],i=n[n.length-1];t.shiftKey?document.activeElement===r&&(t.preventDefault(),i?.focus()):document.activeElement===i&&(t.preventDefault(),r?.focus())}return e.addEventListener(`keydown`,t),()=>e.removeEventListener(`keydown`,t)},[]);function a(e,t){e.isCurrent||r({kind:`confirm`,release:e,releases:t})}async function o(t){r({kind:`installing`});let n=E();if(!n)r({kind:`error`,message:`Bridge unavailable — please restart the app.`});else try{await n.installVersion(t.tag),e()}catch(e){let t=e instanceof Error?e.message:String(e);r({kind:`error`,message:`Failed to start rollback: ${t}`})}}function c(e){if(!e)return``;try{return new Date(e).toLocaleDateString(void 0,{year:`numeric`,month:`short`,day:`numeric`})}catch{return e}}return(0,T.jsx)(`div`,{className:`version-picker-overlay`,onClick:t=>{t.target===t.currentTarget&&e()},children:(0,T.jsxs)(`div`,{className:`version-picker-dialog`,role:`dialog`,"aria-modal":`true`,"aria-label":`Roll back to a previous version`,ref:i,children:[(0,T.jsxs)(`div`,{className:`version-picker-header`,children:[(0,T.jsx)(`h3`,{children:`Roll back to a previous version`}),(0,T.jsx)(`button`,{className:`version-picker-close`,onClick:e,"aria-label":`Close`,type:`button`,children:`×`})]}),(0,T.jsxs)(`div`,{className:`version-picker-body`,children:[t.kind===`loading`&&(0,T.jsxs)(`div`,{className:`version-picker-loading`,"aria-busy":`true`,children:[(0,T.jsx)(`span`,{className:`version-picker-spinner`}),`Loading releases…`]}),t.kind===`error`&&(0,T.jsxs)(`div`,{className:`version-picker-error`,children:[(0,T.jsx)(`p`,{children:t.message}),(0,T.jsx)(`p`,{children:(0,T.jsx)(`a`,{href:`https://github.com/amd/gaia/releases`,target:`_blank`,rel:`noreferrer`,children:`Browse releases on GitHub`})})]}),t.kind===`list`&&(0,T.jsx)(`ul`,{className:`version-picker-list`,role:`listbox`,"aria-label":`Available releases`,children:t.releases.map(e=>(0,T.jsx)(`li`,{children:(0,T.jsxs)(`button`,{type:`button`,className:`version-picker-row`,"data-version":e.version,"aria-label":`${e.version}${e.isCurrent?` — installed`:``}${e.isPinned?` — pinned`:``}`,"aria-disabled":e.isCurrent?`true`:`false`,onClick:()=>a(e,t.releases),disabled:e.isCurrent,children:[(0,T.jsx)(`span`,{className:`vp-version`,children:e.version}),(0,T.jsx)(`span`,{className:`vp-date`,children:c(e.date)}),e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-badge vp-badge-current`,children:`Installed`}),e.isPinned&&!e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-badge vp-badge-pinned`,children:`Pinned`}),!e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-arrow`,"aria-hidden":`true`,children:`›`})]})},e.tag))}),t.kind===`list`&&(0,T.jsxs)(`p`,{className:`version-picker-more`,children:[`Showing the `,t.releases.length,` most recent.`,` `,(0,T.jsx)(`a`,{href:`https://github.com/amd/gaia/releases`,target:`_blank`,rel:`noreferrer`,children:`Browse all releases on GitHub`})]}),t.kind===`confirm`&&(0,T.jsxs)(`div`,{className:`version-picker-confirm`,children:[(0,T.jsxs)(`p`,{children:[`This will `,(0,T.jsxs)(`strong`,{children:[`downgrade to v`,t.release.version]}),` and restart the app.`]}),(0,T.jsxs)(`p`,{className:`vp-confirm-note`,children:[`Auto-update will be paused after rollback so the app stays on v`,t.release.version,`. You can resume updates from Settings → About.`]}),(0,T.jsxs)(`div`,{className:`vp-confirm-actions`,children:[(0,T.jsx)(`button`,{type:`button`,className:`vp-btn-cancel`,onClick:()=>r({kind:`list`,releases:t.releases}),children:`Back`}),(0,T.jsx)(`button`,{type:`button`,className:`vp-btn-confirm`,onClick:()=>o(t.release),children:`Confirm downgrade & restart`})]})]}),t.kind===`installing`&&(0,T.jsxs)(`div`,{className:`version-picker-loading`,"aria-busy":`true`,children:[(0,T.jsx)(`span`,{className:`version-picker-spinner`}),`Starting download…`]})]})]})})}function O(){let[e,t]=(0,w.useState)(null),[n,r]=(0,w.useState)(null),[i,a]=(0,w.useState)(``),[o,s]=(0,w.useState)(``),[c,u]=(0,w.useState)(!1),[f,p]=(0,w.useState)(null),[m,h]=(0,w.useState)(!1);(0,w.useEffect)(()=>{d().then(e=>{t(e),a(e.saved_base_url??e.base_url??``)}).catch(e=>r(e instanceof Error?e.message:String(e)))},[]);let _=(0,w.useCallback)(async e=>{u(!0),p(null);try{let n=await g(e);t(n),s(``),h(!1)}catch(e){h(C(e)),p(e instanceof Error?e.message:String(e))}finally{u(!1)}},[]),y=()=>void _({mode:`external`,base_url:i.trim(),api_key:o.trim()||void 0});if(n)return(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not read which model server GAIA uses`}),(0,T.jsx)(`p`,{children:n})]})]})]});if(!e)return null;let b=e.mode===`external`;return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`model-override-desc`,role:`status`,children:e.source===`env`?(0,T.jsxs)(T.Fragment,{children:[`GAIA uses the Lemonade Server at `,(0,T.jsx)(`code`,{children:e.base_url}),`, set by `,(0,T.jsx)(`code`,{children:`LEMONADE_BASE_URL`}),`.`]}):b?(0,T.jsxs)(T.Fragment,{children:[`GAIA uses your Lemonade Server at `,(0,T.jsx)(`code`,{children:e.base_url}),`.`]}):(0,T.jsx)(T.Fragment,{children:`GAIA uses its own Lemonade Server.`})}),e.source===`env`?(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Unset `,(0,T.jsx)(`code`,{children:`LEMONADE_BASE_URL`}),` and restart GAIA to change this here.`]}):(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Already run Lemonade? Use it, so this PC keeps one server and one copy of each model.`,` `,e.what_gaia_does]}),(0,T.jsxs)(`form`,{className:`model-input-row`,onSubmit:e=>{e.preventDefault(),y()},children:[(0,T.jsx)(`input`,{type:`text`,className:`model-input`,placeholder:`http://localhost:13305`,value:i,onChange:e=>{a(e.target.value),p(null)},disabled:c,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":`Lemonade Server address`}),(0,T.jsx)(`input`,{type:`password`,className:`model-input`,autoComplete:`off`,placeholder:e.api_key_stored?`API key (blank keeps the saved one)`:`API key, if it needs one`,value:o,onChange:e=>s(e.target.value),disabled:c,"aria-label":`Lemonade API key`}),(0,T.jsx)(`div`,{className:`model-btn-group`,children:(0,T.jsx)(`button`,{type:`submit`,className:`btn-model-save`,disabled:c||!i.trim(),children:c?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:13,className:`btn-spinner`}),` Checking…`]}):`Use this server`})})]}),b&&(0,T.jsx)(`div`,{className:`setting-actions`,children:(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,disabled:c,onClick:()=>void _({mode:`gaia`}),children:`Use GAIA’s own`})}),f&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:m?`Needs the API key`:`Not switched`}),(0,T.jsx)(`p`,{children:f})]})]})]})]})}var k={vulkan:`Vulkan`,rocm:`ROCm`,metal:`Metal`,cpu:`CPU`,npu:`NPU`,remote:`Remote (cloud)`},A={gaia:`GAIA's own Lemonade`,user:`Your Lemonade`,remote:`Lemonade on another machine`};function j(e){return e?k[e]??e:`unknown`}function M(e){if(!e)return`unknown`;let t=j(e.backend);return e.backend_source===`lemonade_default`?`${t} (Lemonade's default)`:t}function N(e){return e?`${Math.round(e/1024)}K tokens`:`unknown`}function P({label:e,value:t,title:n}){return(0,T.jsxs)(`div`,{className:`status-row`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e}),(0,T.jsx)(`span`,{className:`status-value model-server-value`,title:n??t,children:t})]})}function ee(){let e=c(e=>e.openSettings),[t,n]=(0,w.useState)(null),[r,i]=(0,w.useState)(null),[a,s]=(0,w.useState)(null),[l,d]=(0,w.useState)(null),[f,m]=(0,w.useState)(!1);(0,w.useEffect)(()=>{_().then(n).catch(e=>i(e instanceof Error?e.message:String(e)))},[]);let h=(0,w.useCallback)(async e=>{s(e),d(null);try{let t=await p(e);n(t),d({ok:!0,text:`Saved. It applies the next time the chat model loads.`})}catch(e){d({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{s(null)}},[]),g=t?.chat_model??null,y=(0,w.useCallback)(async()=>{if(g?.name){m(!0);try{if(!await u(g.name,g.ctx_size??void 0))return;d({ok:!0,text:`Reloading ${g.name}. Reopen this panel in a moment to see its backend.`})}catch(e){d({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{m(!1)}}},[g]),b=(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>e(`model`),children:`Change model`});if(r)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`settings-error`,role:`alert`,children:r})]});if(!t)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`loading-text`,children:`Checking the model server…`})]});if(!t.reachable)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`settings-error`,role:`alert`,children:t.error}),b]});let x=t.available_backends??[],S=t.preferred_backend??null,C=[`auto`,...x.map(e=>e.name)];S&&!C.includes(S)&&C.push(S);let E=S??`auto`,D=x.filter(e=>e.state===`installable`).map(e=>j(e.name)),O=!!g?.name&&g.recipe===`llamacpp`;return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsxs)(`div`,{className:`status-grid`,children:[(0,T.jsx)(P,{label:`Server`,value:`${A[t.owner]??t.owner}${t.version?` v${t.version}`:``}`}),(0,T.jsx)(P,{label:`Address`,value:t.base_url}),(0,T.jsx)(P,{label:`Chat model`,value:g?.name?o(g.name):`None loaded`,title:g?.name??void 0}),g&&(0,T.jsx)(P,{label:`Runs on`,value:M(g)}),g&&g.backend!==`remote`&&(0,T.jsx)(P,{label:`Context window`,value:N(g.ctx_size)}),(0,T.jsx)(P,{label:`Embedding model`,value:t.embedding_model?.name?`${t.embedding_model.name} · ${M(t.embedding_model)}`:`None loaded`})]}),t.embedding_note&&(0,T.jsx)(`p`,{className:`settings-hint`,children:t.embedding_note}),t.system_info_error&&(0,T.jsx)(`p`,{className:`settings-hint`,children:t.system_info_error}),(0,T.jsxs)(`div`,{className:`settings-field model-server-backend`,children:[(0,T.jsx)(`span`,{className:`settings-label`,children:`llama.cpp backend for chat models`}),x.length===0&&!S?(0,T.jsx)(`span`,{className:`settings-hint`,children:`This Lemonade does not report which backends this PC can run, so there is nothing to choose. Update Lemonade to pick one here.`}):(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`div`,{className:`segmented`,role:`radiogroup`,"aria-label":`llama.cpp backend`,children:C.map(e=>(0,T.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":E===e,className:E===e?`is-active`:``,disabled:a!==null,onClick:()=>{e!==E&&h(e)},children:[a===e?(0,T.jsx)(v,{size:12,className:`spin`}):null,e===`auto`?`Auto${t.default_backend?` (${j(t.default_backend)})`:``}`:j(e)]},e))}),(0,T.jsxs)(`span`,{className:`settings-hint`,children:[`Applies the next time a chat model loads. The embedding model keeps its own backend.`,D.length>0&&` ${D.join(`, `)} downloads on first use.`]})]}),l&&(0,T.jsx)(`p`,{className:l.ok?`settings-ok`:`settings-error`,role:l.ok?`status`:`alert`,children:l.text})]}),(0,T.jsxs)(`div`,{className:`settings-row`,children:[b,O&&(0,T.jsxs)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void y(),disabled:f,children:[f?(0,T.jsx)(v,{size:13,className:`spin`}):null,`Reload chat model now`]})]})]})}function F(){let[e,t]=(0,w.useState)(null),[n,i]=(0,w.useState)(!0),[o,s]=(0,w.useState)([]),[c,u]=(0,w.useState)(!1),d=y(),[p,g]=(0,w.useState)(``),[_,C]=(0,w.useState)(``),[E,k]=(0,w.useState)(!1),[A,j]=(0,w.useState)(!1),[M,N]=(0,w.useState)(null),[P,F]=(0,w.useState)(!1),L=(0,w.useRef)(null),[R,z]=(0,w.useState)(!1),[B,V]=(0,w.useState)(!1),[H,U]=(0,w.useState)(!1),[W,G]=(0,w.useState)(null);(0,w.useEffect)(()=>{r.system.info(`Checking system status...`);let e=r.system.time();h().then(n=>{t(n),r.system.timed(`System status received`,e,{lemonade:n.lemonade_running?`running`:`stopped`,model:n.model_loaded||`none`,embedding:n.embedding_model_loaded?`yes`:`no`,disk:`${n.disk_space_gb}GB free`,memory:n.memory_available_gb==null?`unknown`:`${n.memory_available_gb}GB available`}),n.lemonade_running||r.system.warn(`Lemonade Server is NOT running.`)}).catch(e=>{r.system.error(`Failed to get system status`,e),t(null)}).finally(()=>i(!1)),S().then(e=>s(e.servers)).catch(()=>{}),b().then(e=>{let t=e.custom_model??``;g(t),C(t),z(e.dynamic_tools),V(e.dynamic_tools_locked)}).catch(e=>{r.system.error(`Failed to load settings`,e)}).finally(()=>k(!0))},[]),(0,w.useEffect)(()=>()=>{L.current&&clearTimeout(L.current)},[]);let K=(0,w.useCallback)(async()=>{let e=p.trim(),t=e.length>0?e:``;j(!0),N(null),F(!1);try{r.system.info(`Saving custom_model override`,{custom_model:t});let e=(await f({custom_model:t})).custom_model??``;g(e),C(e),F(!0),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>F(!1),2200)}catch(e){let t=e instanceof Error?e.message:String(e);r.system.error(`Failed to save custom_model`,e),N(t)}finally{j(!1)}},[p]),te=(0,w.useCallback)(async()=>{if(B||H)return;let e=R,t=!e;z(t),U(!0),G(null);try{r.system.info(`Saving dynamic_tools setting`,{dynamic_tools:t});let e=await f({dynamic_tools:t});z(e.dynamic_tools),V(e.dynamic_tools_locked)}catch(t){let n=t instanceof Error?t.message:String(t);r.system.error(`Failed to save dynamic_tools`,t),z(e),G(n)}finally{U(!1)}},[R,B,H]),q=p.trim()!==_.trim(),J=e?e.default_model_name:a,{isLoadingModel:Y,isDownloadingModel:X,loadModel:ne,downloadModel:Z}=m(J??void 0),Q=!!e?.default_model_is_cloud,$=!Q&&!!(e?.lemonade_running&&e.model_loaded&&e.expected_model_loaded===!1),re=!Q&&!!(e?.lemonade_running&&e.model_loaded&&e.context_size_sufficient===!1),ie=!Q&&!(!e?.lemonade_running||e.model_loaded||e.model_downloaded!==!1),ae=($||re)&&J!==null;return(0,T.jsxs)(`div`,{className:`settings-pane`,children:[(0,T.jsx)(`h2`,{className:`settings-pane-title`,children:`Advanced`}),(0,T.jsx)(ee,{}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Local model server`}),n?(0,T.jsx)(`p`,{className:`loading-text`,children:`Checking system...`}):e?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`div`,{className:`status-grid`,children:[(0,T.jsx)(I,{label:`Model server`,value:e.lemonade_running?`Running${e.lemonade_version?` v${e.lemonade_version}`:``}`:e.lemonade_error?`Status unavailable`:`Not Running`,ok:e.lemonade_running,hint:e.lemonade_running?void 0:e.lemonade_error?`Could not query it: ${e.lemonade_error}`:e.start_command?`Run: ${e.start_command}`:e.start_instruction??`Not running.`}),(0,T.jsx)(I,{label:`Model`,value:e.model_loaded||`None loaded`,ok:!!e.model_loaded&&(Q||e.expected_model_loaded!==!1),hint:e.model_loaded?!Q&&e.expected_model_loaded===!1?`Expected: ${J}`:void 0:`None loaded yet — it loads with the first message.`}),e.model_size_gb!=null&&(0,T.jsx)(I,{label:`Model Size`,value:`${e.model_size_gb} GB`,ok:!0}),e.model_device&&!Q&&(0,T.jsx)(I,{label:`Device`,value:e.model_device.toUpperCase(),ok:e.model_device!==`cpu`}),e.model_context_size!=null&&(0,T.jsx)(I,{label:`Context Window`,value:`${(e.model_context_size/1024).toFixed(0)}K tokens`,ok:e.context_size_sufficient}),e.model_labels&&e.model_labels.length>0&&(0,T.jsx)(I,{label:`Capabilities`,value:e.model_labels.join(`, `),ok:!0}),(0,T.jsx)(I,{label:`Embedding Model`,value:e.embedding_model_loaded?`Available`:`Not loaded`,ok:e.embedding_model_loaded}),e.gpu_name&&(0,T.jsx)(I,{label:`GPU`,value:`${e.gpu_name}${e.gpu_vram_gb?` (${e.gpu_vram_gb} GB)`:``}`,ok:!0}),(0,T.jsx)(I,{label:`Disk Space`,value:`${e.disk_space_gb} GB free`,ok:e.disk_space_gb>5,hint:!e.model_loaded&&e.disk_space_gb<30?`Local models need about 6 GB — only ${e.disk_space_gb} GB free`:void 0}),(0,T.jsx)(I,{label:`Memory`,value:e.memory_available_gb==null?`unknown`:`${e.memory_available_gb} GB available`,ok:e.memory_available_gb!=null&&e.memory_available_gb>2}),e.processor_name&&(0,T.jsx)(I,{label:`Processor`,value:e.processor_name,ok:!0})]}),ie&&(0,T.jsxs)(`div`,{className:`model-action-row model-action-row--download`,children:[(0,T.jsxs)(`div`,{className:`model-action-info`,children:[(0,T.jsx)(`span`,{className:`model-action-label`,children:`Model not downloaded.`}),(0,T.jsxs)(`span`,{className:`model-action-desc`,children:[(0,T.jsx)(`strong`,{children:J}),` is GAIA’s default local model (about 6 GB).`]})]}),(0,T.jsx)(`button`,{className:`btn-model-action btn-model-action--download`,onClick:()=>Z(!1),disabled:X,children:X?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:13,className:`btn-spinner`}),` Downloading…`]}):`Download`})]}),ae&&(0,T.jsxs)(`div`,{className:`model-action-row model-action-row--load`,children:[(0,T.jsxs)(`div`,{className:`model-action-info`,children:[(0,T.jsx)(`span`,{className:`model-action-label`,children:$?`Wrong model loaded.`:`Context window too small.`}),(0,T.jsxs)(`span`,{className:`model-action-desc`,children:[`Load `,(0,T.jsx)(`strong`,{children:J}),` with `,32 .toFixed(0),`K token context.`]})]}),(0,T.jsx)(`button`,{className:`btn-model-action btn-model-action--load`,onClick:()=>ne(),disabled:Y,children:Y?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:13,className:`btn-spinner`}),` Loading…`]}):`Load Model`})]}),e.lemonade_running&&J!==null&&!Q&&(0,T.jsxs)(`div`,{className:`force-redownload-row`,children:[(0,T.jsx)(`span`,{className:`force-redownload-label`,children:`If the model file is corrupted:`}),(0,T.jsx)(`button`,{className:`btn-force-redownload`,onClick:()=>Z(!0),disabled:X,children:X?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:12,className:`btn-spinner`}),` Downloading…`]}):`Force Re-download`})]})]}):(0,T.jsx)(`div`,{className:`status-error`,children:(0,T.jsx)(`p`,{children:`Could not reach GAIA. Check that it is still running.`})})]}),(0,T.jsx)(O,{}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Custom model ID`}),(0,T.jsx)(`p`,{className:`model-override-desc`,children:`Run any model the local server knows by its ID. Leave empty to use the model chosen under Model.`}),(0,T.jsxs)(`div`,{className:`model-input-row`,children:[(0,T.jsx)(`input`,{type:`text`,className:`model-input${_?` has-override`:``}`,placeholder:`Use the model chosen under Model`,value:p,onChange:e=>{g(e.target.value),N(null),F(!1)},onKeyDown:e=>{e.key===`Enter`&&!A&&q&&E&&(e.preventDefault(),K())},disabled:!E||A,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":`Custom model override`}),(0,T.jsx)(`div`,{className:`model-btn-group`,children:(0,T.jsx)(`button`,{className:`btn-model-save${P?` saved`:``}`,onClick:()=>{K()},disabled:!E||A||!q&&!P,"aria-label":`Save custom model`,children:A?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:13,className:`btn-spinner`}),` Saving…`]}):P?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(x,{size:13}),` Saved`]}):`Save`})})]}),(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Accepts a Lemonade model ID (e.g. `,(0,T.jsx)(`code`,{children:`Qwen3-4B-Instruct-2507-GGUF`}),`)`,` `,`or a HuggingFace ID (e.g. `,(0,T.jsx)(`code`,{children:`unsloth/Qwen3-4B-GGUF`}),`).`]}),M&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not save`}),(0,T.jsx)(`p`,{children:M})]})]})]}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsxs)(`h4`,{children:[`Dynamic Tools `,(0,T.jsx)(`span`,{className:`beta-badge`,children:`BETA`})]}),(0,T.jsx)(`p`,{className:`model-override-desc`,children:`Trim each turn’s tool list to a semantically-matched subset to speed up the first response. It does not apply to the GAIA agent yet.`}),(0,T.jsxs)(`label`,{className:`setting-row`,children:[(0,T.jsx)(`span`,{children:`Enable dynamic tool loading`}),(0,T.jsxs)(`span`,{className:`toggle-switch`,children:[(0,T.jsx)(`input`,{type:`checkbox`,checked:R,onChange:()=>void te(),disabled:!E||H||B,"aria-label":R?`Disable dynamic tools`:`Enable dynamic tools`}),(0,T.jsx)(`span`,{className:`toggle-track`})]})]}),B&&(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Controlled by `,(0,T.jsx)(`code`,{children:`GAIA_DYNAMIC_TOOLS`}),` — unset that environment variable to change this here.`]}),W&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not save`}),(0,T.jsx)(`p`,{children:W})]})]})]}),o.length>0&&(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`MCP Servers`}),(0,T.jsx)(`div`,{className:`status-grid`,children:o.map(e=>(0,T.jsxs)(`div`,{className:`status-row`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e.name}),(0,T.jsx)(`div`,{className:`status-value-wrap`,children:e.connected?(0,T.jsxs)(`span`,{className:`status-value ok mcp-status-connected`,children:[(0,T.jsx)(x,{size:12}),e.tool_count,` tool`,e.tool_count===1?``:`s`]}):(0,T.jsxs)(`span`,{className:`status-value warn mcp-status-failed`,title:e.error??void 0,children:[(0,T.jsx)(l,{size:12}),`Failed`]})})]},e.name))})]}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`About`}),(0,T.jsxs)(`div`,{className:`about-info`,children:[(0,T.jsxs)(`p`,{children:[`GAIA v`,`0.25.1`,` `,(0,T.jsx)(`span`,{className:`beta-badge`,children:`BETA`})]}),(0,T.jsx)(`p`,{className:`about-sub`,children:`Privacy-first AI chat for AMD Ryzen AI PCs.`}),d.pinnedVersion&&(0,T.jsxs)(`p`,{className:`about-pinned-notice`,children:[`Auto-update paused (pinned to `,d.pinnedVersion,`).`,` `,(0,T.jsx)(`button`,{type:`button`,className:`about-resume-btn`,onClick:()=>{window.gaiaUpdater?.resumeUpdates().catch(e=>{r.system.error(`Resume updates failed`,e)})},children:`Resume updates`})]})]}),(0,T.jsx)(`div`,{className:`setting-actions`,children:(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>u(!0),children:`Roll back to a previous version`})})]}),c&&(0,T.jsx)(D,{onClose:()=>u(!1)})]})}function I({label:e,value:t,ok:n,hint:r}){return(0,T.jsxs)(`div`,{className:`status-row${r?` status-row--has-hint`:``}`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e}),(0,T.jsxs)(`div`,{className:`status-value-wrap`,children:[(0,T.jsx)(`span`,{className:`status-value ${n?`ok`:`warn`}`,children:t}),r&&(0,T.jsx)(`span`,{className:`status-hint`,children:(0,T.jsx)(`code`,{children:r})})]})]})}export{F as AdvancedSettings};
1
+ import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{n as t,o as n,s as r,u as i}from"./apiBase-BmPG2Rib.js";import{B as a,J as o,K as s,Pt as c,cn as l,ct as u,et as d,gt as f,ht as p,i as m,it as h,mt as g,nt as _,on as v,qt as y,r as b,rt as x,tt as S,z as C}from"./index-CfiDLYYM.js";var w=e(i(),1),T=t();function E(){return window.gaiaUpdater}function D({onClose:e}){let[t,r]=(0,w.useState)({kind:`loading`}),i=(0,w.useRef)(null);(0,w.useEffect)(()=>{let e=E();e?e.listReleases().then(e=>{r(Array.isArray(e)?{kind:`list`,releases:e}:{kind:`error`,message:e.error})}).catch(()=>{r({kind:`error`,message:`Couldn't reach GitHub to list releases — check your connection; you can still download installers from the Releases page.`})}):r({kind:`error`,message:`Couldn't reach GitHub to list releases — check your connection; you can still download installers from the Releases page.`})},[]),n(!0,e),s(i,!0),(0,w.useEffect)(()=>{let e=i.current;e&&e.querySelector(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`)?.focus()},[]),(0,w.useEffect)(()=>{let e=i.current;if(!e)return;function t(t){if(t.key!==`Tab`||!e)return;let n=e.querySelectorAll(`button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])`);if(n.length===0)return;let r=n[0],i=n[n.length-1];t.shiftKey?document.activeElement===r&&(t.preventDefault(),i?.focus()):document.activeElement===i&&(t.preventDefault(),r?.focus())}return e.addEventListener(`keydown`,t),()=>e.removeEventListener(`keydown`,t)},[]);function a(e,t){e.isCurrent||r({kind:`confirm`,release:e,releases:t})}async function o(t){r({kind:`installing`});let n=E();if(!n)r({kind:`error`,message:`Bridge unavailable — please restart the app.`});else try{await n.installVersion(t.tag),e()}catch(e){let t=e instanceof Error?e.message:String(e);r({kind:`error`,message:`Failed to start rollback: ${t}`})}}function c(e){if(!e)return``;try{return new Date(e).toLocaleDateString(void 0,{year:`numeric`,month:`short`,day:`numeric`})}catch{return e}}return(0,T.jsx)(`div`,{className:`version-picker-overlay`,onClick:t=>{t.target===t.currentTarget&&e()},children:(0,T.jsxs)(`div`,{className:`version-picker-dialog`,role:`dialog`,"aria-modal":`true`,"aria-label":`Roll back to a previous version`,ref:i,children:[(0,T.jsxs)(`div`,{className:`version-picker-header`,children:[(0,T.jsx)(`h3`,{children:`Roll back to a previous version`}),(0,T.jsx)(`button`,{className:`version-picker-close`,onClick:e,"aria-label":`Close`,type:`button`,children:`×`})]}),(0,T.jsxs)(`div`,{className:`version-picker-body`,children:[t.kind===`loading`&&(0,T.jsxs)(`div`,{className:`version-picker-loading`,"aria-busy":`true`,children:[(0,T.jsx)(`span`,{className:`version-picker-spinner`}),`Loading releases…`]}),t.kind===`error`&&(0,T.jsxs)(`div`,{className:`version-picker-error`,children:[(0,T.jsx)(`p`,{children:t.message}),(0,T.jsx)(`p`,{children:(0,T.jsx)(`a`,{href:`https://github.com/amd/gaia/releases`,target:`_blank`,rel:`noreferrer`,children:`Browse releases on GitHub`})})]}),t.kind===`list`&&(0,T.jsx)(`ul`,{className:`version-picker-list`,role:`listbox`,"aria-label":`Available releases`,children:t.releases.map(e=>(0,T.jsx)(`li`,{children:(0,T.jsxs)(`button`,{type:`button`,className:`version-picker-row`,"data-version":e.version,"aria-label":`${e.version}${e.isCurrent?` — installed`:``}${e.isPinned?` — pinned`:``}`,"aria-disabled":e.isCurrent?`true`:`false`,onClick:()=>a(e,t.releases),disabled:e.isCurrent,children:[(0,T.jsx)(`span`,{className:`vp-version`,children:e.version}),(0,T.jsx)(`span`,{className:`vp-date`,children:c(e.date)}),e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-badge vp-badge-current`,children:`Installed`}),e.isPinned&&!e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-badge vp-badge-pinned`,children:`Pinned`}),!e.isCurrent&&(0,T.jsx)(`span`,{className:`vp-arrow`,"aria-hidden":`true`,children:`›`})]})},e.tag))}),t.kind===`list`&&(0,T.jsxs)(`p`,{className:`version-picker-more`,children:[`Showing the `,t.releases.length,` most recent.`,` `,(0,T.jsx)(`a`,{href:`https://github.com/amd/gaia/releases`,target:`_blank`,rel:`noreferrer`,children:`Browse all releases on GitHub`})]}),t.kind===`confirm`&&(0,T.jsxs)(`div`,{className:`version-picker-confirm`,children:[(0,T.jsxs)(`p`,{children:[`This will `,(0,T.jsxs)(`strong`,{children:[`downgrade to v`,t.release.version]}),` and restart the app.`]}),(0,T.jsxs)(`p`,{className:`vp-confirm-note`,children:[`Auto-update will be paused after rollback so the app stays on v`,t.release.version,`. You can resume updates from Settings → About.`]}),(0,T.jsxs)(`div`,{className:`vp-confirm-actions`,children:[(0,T.jsx)(`button`,{type:`button`,className:`vp-btn-cancel`,onClick:()=>r({kind:`list`,releases:t.releases}),children:`Back`}),(0,T.jsx)(`button`,{type:`button`,className:`vp-btn-confirm`,onClick:()=>o(t.release),children:`Confirm downgrade & restart`})]})]}),t.kind===`installing`&&(0,T.jsxs)(`div`,{className:`version-picker-loading`,"aria-busy":`true`,children:[(0,T.jsx)(`span`,{className:`version-picker-spinner`}),`Starting download…`]})]})]})})}function O(){let[e,t]=(0,w.useState)(null),[n,r]=(0,w.useState)(null),[i,a]=(0,w.useState)(``),[o,s]=(0,w.useState)(``),[c,u]=(0,w.useState)(!1),[f,p]=(0,w.useState)(null),[m,h]=(0,w.useState)(!1);(0,w.useEffect)(()=>{d().then(e=>{t(e),a(e.saved_base_url??e.base_url??``)}).catch(e=>r(e instanceof Error?e.message:String(e)))},[]);let _=(0,w.useCallback)(async e=>{u(!0),p(null);try{let n=await g(e);t(n),s(``),h(!1)}catch(e){h(C(e)),p(e instanceof Error?e.message:String(e))}finally{u(!1)}},[]),v=()=>void _({mode:`external`,base_url:i.trim(),api_key:o.trim()||void 0});if(n)return(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not read which model server GAIA uses`}),(0,T.jsx)(`p`,{children:n})]})]})]});if(!e)return null;let b=e.mode===`external`;return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`model-override-desc`,role:`status`,children:e.source===`env`?(0,T.jsxs)(T.Fragment,{children:[`GAIA uses the Lemonade Server at `,(0,T.jsx)(`code`,{children:e.base_url}),`, set by `,(0,T.jsx)(`code`,{children:`LEMONADE_BASE_URL`}),`.`]}):b?(0,T.jsxs)(T.Fragment,{children:[`GAIA uses your Lemonade Server at `,(0,T.jsx)(`code`,{children:e.base_url}),`.`]}):(0,T.jsx)(T.Fragment,{children:`GAIA uses its own Lemonade Server.`})}),e.source===`env`?(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Unset `,(0,T.jsx)(`code`,{children:`LEMONADE_BASE_URL`}),` and restart GAIA to change this here.`]}):(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Already run Lemonade? Use it, so this PC keeps one server and one copy of each model.`,` `,e.what_gaia_does]}),(0,T.jsxs)(`form`,{className:`model-input-row`,onSubmit:e=>{e.preventDefault(),v()},children:[(0,T.jsx)(`input`,{type:`text`,className:`model-input`,placeholder:`http://localhost:13305`,value:i,onChange:e=>{a(e.target.value),p(null)},disabled:c,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":`Lemonade Server address`}),(0,T.jsx)(`input`,{type:`password`,className:`model-input`,autoComplete:`off`,placeholder:e.api_key_stored?`API key (blank keeps the saved one)`:`API key, if it needs one`,value:o,onChange:e=>s(e.target.value),disabled:c,"aria-label":`Lemonade API key`}),(0,T.jsx)(`div`,{className:`model-btn-group`,children:(0,T.jsx)(`button`,{type:`submit`,className:`btn-model-save`,disabled:c||!i.trim(),children:c?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{size:13,className:`btn-spinner`}),` Checking…`]}):`Use this server`})})]}),b&&(0,T.jsx)(`div`,{className:`setting-actions`,children:(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,disabled:c,onClick:()=>void _({mode:`gaia`}),children:`Use GAIA’s own`})}),f&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:m?`Needs the API key`:`Not switched`}),(0,T.jsx)(`p`,{children:f})]})]})]})]})}var k={vulkan:`Vulkan`,rocm:`ROCm`,metal:`Metal`,cpu:`CPU`,npu:`NPU`,remote:`Remote (cloud)`},A={gaia:`GAIA's own Lemonade`,user:`Your Lemonade`,remote:`Lemonade on another machine`};function j(e){return e?k[e]??e:`unknown`}function M(e){if(!e)return`unknown`;let t=j(e.backend);return e.backend_source===`lemonade_default`?`${t} (Lemonade's default)`:t}function N(e){return e?`${Math.round(e/1024)}K tokens`:`unknown`}function P({label:e,value:t,title:n}){return(0,T.jsxs)(`div`,{className:`status-row`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e}),(0,T.jsx)(`span`,{className:`status-value model-server-value`,title:n??t,children:t})]})}function ee(){let e=c(e=>e.openSettings),[t,n]=(0,w.useState)(null),[r,i]=(0,w.useState)(null),[a,s]=(0,w.useState)(null),[l,d]=(0,w.useState)(null),[f,m]=(0,w.useState)(!1);(0,w.useEffect)(()=>{_().then(n).catch(e=>i(e instanceof Error?e.message:String(e)))},[]);let h=(0,w.useCallback)(async e=>{s(e),d(null);try{let t=await p(e);n(t),d({ok:!0,text:`Saved. It applies the next time the chat model loads.`})}catch(e){d({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{s(null)}},[]),g=t?.chat_model??null,v=(0,w.useCallback)(async()=>{if(g?.name){m(!0);try{if(!await u(g.name,g.ctx_size??void 0))return;d({ok:!0,text:`Reloading ${g.name}. Reopen this panel in a moment to see its backend.`})}catch(e){d({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{m(!1)}}},[g]),b=(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>e(`model`),children:`Change model`});if(r)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`settings-error`,role:`alert`,children:r})]});if(!t)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`loading-text`,children:`Checking the model server…`})]});if(!t.reachable)return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsx)(`p`,{className:`settings-error`,role:`alert`,children:t.error}),b]});let x=t.available_backends??[],S=t.preferred_backend??null,C=[`auto`,...x.map(e=>e.name)];S&&!C.includes(S)&&C.push(S);let E=S??`auto`,D=x.filter(e=>e.state===`installable`).map(e=>j(e.name)),O=!!g?.name&&g.recipe===`llamacpp`;return(0,T.jsxs)(`section`,{className:`settings-section`,"aria-label":`Model server`,children:[(0,T.jsx)(`h4`,{children:`Model server`}),(0,T.jsxs)(`div`,{className:`status-grid`,children:[(0,T.jsx)(P,{label:`Server`,value:`${A[t.owner]??t.owner}${t.version?` v${t.version}`:``}`}),(0,T.jsx)(P,{label:`Address`,value:t.base_url}),(0,T.jsx)(P,{label:`Chat model`,value:g?.name?o(g.name):`None loaded`,title:g?.name??void 0}),g&&(0,T.jsx)(P,{label:`Runs on`,value:M(g)}),g&&g.backend!==`remote`&&(0,T.jsx)(P,{label:`Context window`,value:N(g.ctx_size)}),(0,T.jsx)(P,{label:`Embedding model`,value:t.embedding_model?.name?`${t.embedding_model.name} · ${M(t.embedding_model)}`:`None loaded`})]}),t.embedding_note&&(0,T.jsx)(`p`,{className:`settings-hint`,children:t.embedding_note}),t.system_info_error&&(0,T.jsx)(`p`,{className:`settings-hint`,children:t.system_info_error}),(0,T.jsxs)(`div`,{className:`settings-field model-server-backend`,children:[(0,T.jsx)(`span`,{className:`settings-label`,children:`llama.cpp backend for chat models`}),x.length===0&&!S?(0,T.jsx)(`span`,{className:`settings-hint`,children:`This Lemonade does not report which backends this PC can run, so there is nothing to choose. Update Lemonade to pick one here.`}):(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`div`,{className:`segmented`,role:`radiogroup`,"aria-label":`llama.cpp backend`,children:C.map(e=>(0,T.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":E===e,className:E===e?`is-active`:``,disabled:a!==null,onClick:()=>{e!==E&&h(e)},children:[a===e?(0,T.jsx)(y,{size:12,className:`spin`}):null,e===`auto`?`Auto${t.default_backend?` (${j(t.default_backend)})`:``}`:j(e)]},e))}),(0,T.jsxs)(`span`,{className:`settings-hint`,children:[`Applies the next time a chat model loads. The embedding model keeps its own backend.`,D.length>0&&` ${D.join(`, `)} downloads on first use.`]})]}),l&&(0,T.jsx)(`p`,{className:l.ok?`settings-ok`:`settings-error`,role:l.ok?`status`:`alert`,children:l.text})]}),(0,T.jsxs)(`div`,{className:`settings-row`,children:[b,O&&(0,T.jsxs)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void v(),disabled:f,children:[f?(0,T.jsx)(y,{size:13,className:`spin`}):null,`Reload chat model now`]})]})]})}function F(){let[e,t]=(0,w.useState)(null),[n,i]=(0,w.useState)(!0),[o,s]=(0,w.useState)([]),[c,u]=(0,w.useState)(!1),d=b(),[p,g]=(0,w.useState)(``),[_,C]=(0,w.useState)(``),[E,k]=(0,w.useState)(!1),[A,j]=(0,w.useState)(!1),[M,N]=(0,w.useState)(null),[P,F]=(0,w.useState)(!1),L=(0,w.useRef)(null),[R,z]=(0,w.useState)(!1),[B,V]=(0,w.useState)(!1),[H,U]=(0,w.useState)(!1),[W,G]=(0,w.useState)(null);(0,w.useEffect)(()=>{r.system.info(`Checking system status...`);let e=r.system.time();h().then(n=>{t(n),r.system.timed(`System status received`,e,{lemonade:n.lemonade_running?`running`:`stopped`,model:n.model_loaded||`none`,embedding:n.embedding_model_loaded?`yes`:`no`,disk:`${n.disk_space_gb}GB free`,memory:n.memory_available_gb==null?`unknown`:`${n.memory_available_gb}GB available`}),n.lemonade_running||r.system.warn(`Lemonade Server is NOT running.`)}).catch(e=>{r.system.error(`Failed to get system status`,e),t(null)}).finally(()=>i(!1)),S().then(e=>s(e.servers)).catch(()=>{}),x().then(e=>{let t=e.custom_model??``;g(t),C(t),z(e.dynamic_tools),V(e.dynamic_tools_locked)}).catch(e=>{r.system.error(`Failed to load settings`,e)}).finally(()=>k(!0))},[]),(0,w.useEffect)(()=>()=>{L.current&&clearTimeout(L.current)},[]);let K=(0,w.useCallback)(async()=>{let e=p.trim(),t=e.length>0?e:``;j(!0),N(null),F(!1);try{r.system.info(`Saving custom_model override`,{custom_model:t});let e=(await f({custom_model:t})).custom_model??``;g(e),C(e),F(!0),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>F(!1),2200)}catch(e){let t=e instanceof Error?e.message:String(e);r.system.error(`Failed to save custom_model`,e),N(t)}finally{j(!1)}},[p]),te=(0,w.useCallback)(async()=>{if(B||H)return;let e=R,t=!e;z(t),U(!0),G(null);try{r.system.info(`Saving dynamic_tools setting`,{dynamic_tools:t});let e=await f({dynamic_tools:t});z(e.dynamic_tools),V(e.dynamic_tools_locked)}catch(t){let n=t instanceof Error?t.message:String(t);r.system.error(`Failed to save dynamic_tools`,t),z(e),G(n)}finally{U(!1)}},[R,B,H]),q=p.trim()!==_.trim(),J=e?e.default_model_name:a,{isLoadingModel:Y,isDownloadingModel:X,loadModel:ne,downloadModel:Z}=m(J??void 0),Q=!!e?.default_model_is_cloud,$=!Q&&!!(e?.lemonade_running&&e.model_loaded&&e.expected_model_loaded===!1),re=!Q&&!!(e?.lemonade_running&&e.model_loaded&&e.context_size_sufficient===!1),ie=!Q&&!(!e?.lemonade_running||e.model_loaded||e.model_downloaded!==!1),ae=($||re)&&J!==null;return(0,T.jsxs)(`div`,{className:`settings-pane`,children:[(0,T.jsx)(`h2`,{className:`settings-pane-title`,children:`Advanced`}),(0,T.jsx)(ee,{}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Local model server`}),n?(0,T.jsx)(`p`,{className:`loading-text`,children:`Checking system...`}):e?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`div`,{className:`status-grid`,children:[(0,T.jsx)(I,{label:`Model server`,value:e.lemonade_running?`Running${e.lemonade_version?` v${e.lemonade_version}`:``}`:e.lemonade_error?`Status unavailable`:`Not Running`,ok:e.lemonade_running,hint:e.lemonade_running?void 0:e.lemonade_error?`Could not query it: ${e.lemonade_error}`:e.start_command?`Run: ${e.start_command}`:e.start_instruction??`Not running.`}),(0,T.jsx)(I,{label:`Model`,value:e.model_loaded||`None loaded`,ok:!!e.model_loaded&&(Q||e.expected_model_loaded!==!1),hint:e.model_loaded?!Q&&e.expected_model_loaded===!1?`Expected: ${J}`:void 0:`None loaded yet — it loads with the first message.`}),e.model_size_gb!=null&&(0,T.jsx)(I,{label:`Model Size`,value:`${e.model_size_gb} GB`,ok:!0}),e.model_device&&!Q&&(0,T.jsx)(I,{label:`Device`,value:e.model_device.toUpperCase(),ok:e.model_device!==`cpu`}),e.model_context_size!=null&&(0,T.jsx)(I,{label:`Context Window`,value:`${(e.model_context_size/1024).toFixed(0)}K tokens`,ok:e.context_size_sufficient}),e.model_labels&&e.model_labels.length>0&&(0,T.jsx)(I,{label:`Capabilities`,value:e.model_labels.join(`, `),ok:!0}),(0,T.jsx)(I,{label:`Embedding Model`,value:e.embedding_model_loaded?`Available`:`Not loaded`,ok:e.embedding_model_loaded}),e.gpu_name&&(0,T.jsx)(I,{label:`GPU`,value:`${e.gpu_name}${e.gpu_vram_gb?` (${e.gpu_vram_gb} GB)`:``}`,ok:!0}),(0,T.jsx)(I,{label:`Disk Space`,value:`${e.disk_space_gb} GB free`,ok:e.disk_space_gb>5,hint:!e.model_loaded&&e.disk_space_gb<30?`Local models need about 6 GB — only ${e.disk_space_gb} GB free`:void 0}),(0,T.jsx)(I,{label:`Memory`,value:e.memory_available_gb==null?`unknown`:`${e.memory_available_gb} GB available`,ok:e.memory_available_gb!=null&&e.memory_available_gb>2}),e.processor_name&&(0,T.jsx)(I,{label:`Processor`,value:e.processor_name,ok:!0})]}),ie&&(0,T.jsxs)(`div`,{className:`model-action-row model-action-row--download`,children:[(0,T.jsxs)(`div`,{className:`model-action-info`,children:[(0,T.jsx)(`span`,{className:`model-action-label`,children:`Model not downloaded.`}),(0,T.jsxs)(`span`,{className:`model-action-desc`,children:[(0,T.jsx)(`strong`,{children:J}),` is GAIA’s default local model (about 6 GB).`]})]}),(0,T.jsx)(`button`,{className:`btn-model-action btn-model-action--download`,onClick:()=>Z(!1),disabled:X,children:X?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{size:13,className:`btn-spinner`}),` Downloading…`]}):`Download`})]}),ae&&(0,T.jsxs)(`div`,{className:`model-action-row model-action-row--load`,children:[(0,T.jsxs)(`div`,{className:`model-action-info`,children:[(0,T.jsx)(`span`,{className:`model-action-label`,children:$?`Wrong model loaded.`:`Context window too small.`}),(0,T.jsxs)(`span`,{className:`model-action-desc`,children:[`Load `,(0,T.jsx)(`strong`,{children:J}),` with `,32 .toFixed(0),`K token context.`]})]}),(0,T.jsx)(`button`,{className:`btn-model-action btn-model-action--load`,onClick:()=>ne(),disabled:Y,children:Y?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{size:13,className:`btn-spinner`}),` Loading…`]}):`Load Model`})]}),e.lemonade_running&&J!==null&&!Q&&(0,T.jsxs)(`div`,{className:`force-redownload-row`,children:[(0,T.jsx)(`span`,{className:`force-redownload-label`,children:`If the model file is corrupted:`}),(0,T.jsx)(`button`,{className:`btn-force-redownload`,onClick:()=>Z(!0),disabled:X,children:X?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{size:12,className:`btn-spinner`}),` Downloading…`]}):`Force Re-download`})]})]}):(0,T.jsx)(`div`,{className:`status-error`,children:(0,T.jsx)(`p`,{children:`Could not reach GAIA. Check that it is still running.`})})]}),(0,T.jsx)(O,{}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`Custom model ID`}),(0,T.jsx)(`p`,{className:`model-override-desc`,children:`Run any model the local server knows by its ID. Leave empty to use the model chosen under Model.`}),(0,T.jsxs)(`div`,{className:`model-input-row`,children:[(0,T.jsx)(`input`,{type:`text`,className:`model-input${_?` has-override`:``}`,placeholder:`Use the model chosen under Model`,value:p,onChange:e=>{g(e.target.value),N(null),F(!1)},onKeyDown:e=>{e.key===`Enter`&&!A&&q&&E&&(e.preventDefault(),K())},disabled:!E||A,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":`Custom model override`}),(0,T.jsx)(`div`,{className:`model-btn-group`,children:(0,T.jsx)(`button`,{className:`btn-model-save${P?` saved`:``}`,onClick:()=>{K()},disabled:!E||A||!q&&!P,"aria-label":`Save custom model`,children:A?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(y,{size:13,className:`btn-spinner`}),` Saving…`]}):P?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(v,{size:13}),` Saved`]}):`Save`})})]}),(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Accepts a Lemonade model ID (e.g. `,(0,T.jsx)(`code`,{children:`Qwen3-4B-Instruct-2507-GGUF`}),`)`,` `,`or a HuggingFace ID (e.g. `,(0,T.jsx)(`code`,{children:`unsloth/Qwen3-4B-GGUF`}),`).`]}),M&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not save`}),(0,T.jsx)(`p`,{children:M})]})]})]}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsxs)(`h4`,{children:[`Dynamic Tools `,(0,T.jsx)(`span`,{className:`beta-badge`,children:`BETA`})]}),(0,T.jsx)(`p`,{className:`model-override-desc`,children:`Trim each turn’s tool list to a semantically-matched subset to speed up the first response. It does not apply to the GAIA agent yet.`}),(0,T.jsxs)(`label`,{className:`setting-row`,children:[(0,T.jsx)(`span`,{children:`Enable dynamic tool loading`}),(0,T.jsxs)(`span`,{className:`toggle-switch`,children:[(0,T.jsx)(`input`,{type:`checkbox`,checked:R,onChange:()=>void te(),disabled:!E||H||B,"aria-label":R?`Disable dynamic tools`:`Enable dynamic tools`}),(0,T.jsx)(`span`,{className:`toggle-track`})]})]}),B&&(0,T.jsxs)(`p`,{className:`model-status-hint`,children:[`Controlled by `,(0,T.jsx)(`code`,{children:`GAIA_DYNAMIC_TOOLS`}),` — unset that environment variable to change this here.`]}),W&&(0,T.jsxs)(`div`,{className:`model-warning`,role:`alert`,children:[(0,T.jsx)(l,{size:14}),(0,T.jsxs)(`div`,{className:`model-warning-content`,children:[(0,T.jsx)(`strong`,{children:`Could not save`}),(0,T.jsx)(`p`,{children:W})]})]})]}),o.length>0&&(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`MCP Servers`}),(0,T.jsx)(`div`,{className:`status-grid`,children:o.map(e=>(0,T.jsxs)(`div`,{className:`status-row`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e.name}),(0,T.jsx)(`div`,{className:`status-value-wrap`,children:e.connected?(0,T.jsxs)(`span`,{className:`status-value ok mcp-status-connected`,children:[(0,T.jsx)(v,{size:12}),e.tool_count,` tool`,e.tool_count===1?``:`s`]}):(0,T.jsxs)(`span`,{className:`status-value warn mcp-status-failed`,title:e.error??void 0,children:[(0,T.jsx)(l,{size:12}),`Failed`]})})]},e.name))})]}),(0,T.jsxs)(`section`,{className:`settings-section`,children:[(0,T.jsx)(`h4`,{children:`About`}),(0,T.jsxs)(`div`,{className:`about-info`,children:[(0,T.jsxs)(`p`,{children:[`GAIA v`,`0.25.2rc2`,` `,(0,T.jsx)(`span`,{className:`beta-badge`,children:`BETA`})]}),(0,T.jsx)(`p`,{className:`about-sub`,children:`Privacy-first AI chat for AMD Ryzen AI PCs.`}),d.pinnedVersion&&(0,T.jsxs)(`p`,{className:`about-pinned-notice`,children:[`Auto-update paused (pinned to `,d.pinnedVersion,`).`,` `,(0,T.jsx)(`button`,{type:`button`,className:`about-resume-btn`,onClick:()=>{window.gaiaUpdater?.resumeUpdates().catch(e=>{r.system.error(`Resume updates failed`,e)})},children:`Resume updates`})]})]}),(0,T.jsx)(`div`,{className:`setting-actions`,children:(0,T.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>u(!0),children:`Roll back to a previous version`})})]}),c&&(0,T.jsx)(D,{onClose:()=>u(!1)})]})}function I({label:e,value:t,ok:n,hint:r}){return(0,T.jsxs)(`div`,{className:`status-row${r?` status-row--has-hint`:``}`,children:[(0,T.jsx)(`span`,{className:`status-label`,children:e}),(0,T.jsxs)(`div`,{className:`status-value-wrap`,children:[(0,T.jsx)(`span`,{className:`status-value ${n?`ok`:`warn`}`,children:t}),r&&(0,T.jsx)(`span`,{className:`status-hint`,children:(0,T.jsx)(`code`,{children:r})})]})]})}export{F as AdvancedSettings};
@@ -1 +1 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,t as a,u as o}from"./apiBase-BmPG2Rib.js";import{$t as s,At as c,Ct as l,Dt as u,Et as d,Mt as f,Nt as p,Ot as m,Pt as h,St as g,Tt as _,bt as v,cn as y,dn as b,jt as x,kt as S,ln as C,qt as w,sn as T,wt as E,xt as D,yt as O}from"./index-D-noqAc3.js";var k={name:`ellipsis`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`19`,cy:`12`,r:`1`,key:`1wjl8i`}],[`circle`,{cx:`5`,cy:`12`,r:`1`,key:`1pcz8c`}]],aliases:[`more-horizontal`]};k.node;var A=t(k),j=n(),M=e(o(),1),N=i.api;function P(e){switch(e){case`connector.configured`:return`configured`;case`connector.disconnected`:return`disconnected`;case`connection.revoked`:return`disconnected`;case`connector.oauth.completed`:return`oauth_completed`;case`connection.connected`:return`oauth_completed`;case`connector.oauth.error`:return`oauth_error`;case`connector.tested`:return`tested`;case`connector.enabled`:return`enabled`;case`connector.disabled`:return`disabled`;case`connector.grant.changed`:return`grant_changed`;case`connector.activation.changed`:return`activation_changed`;default:return null}}function F(e){let t=(0,M.useRef)(e);(0,M.useEffect)(()=>{t.current=e},[e]),(0,M.useEffect)(()=>{let e=`${a()}/connectors/events`,n=null,r=1e3,i=null,o=!1,s=()=>{o||(n=new EventSource(e),n.onopen=()=>{r=1e3},n.onmessage=e=>{try{let n=JSON.parse(e.data),r=P(n.type);if(r===null){N.debug(`connectors-sse: ignoring event`,n.type);return}let i=n.payload??{},a=i.connector_id??i.provider??null;t.current({connectorId:a,reason:r,payload:i})}catch(e){N.warn(`connectors-sse: malformed event`,e)}},n.onerror=()=>{n?.close(),n=null,!o&&(i=setTimeout(s,r),r=Math.min(r*2,3e4))})};return s(),()=>{o=!0,i&&clearTimeout(i),n?.close()}},[])}function I(e){return e.type===`mcp_server`&&e.configured}function L({connector:e,onChanged:t}){let[n,i]=(0,M.useState)(!1),[a,o]=(0,M.useState)(!1),[s,c]=(0,M.useState)(null),[l,u]=(0,M.useState)(null),f=(0,M.useRef)(null),p=(0,M.useRef)(null);(0,M.useEffect)(()=>{if(!n)return;let e=e=>{let t=e.target;f.current&&!f.current.contains(t)&&p.current&&!p.current.contains(t)&&i(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[n]);let m=(0,M.useCallback)(()=>i(!1),[]);if(r(n,m),(0,M.useEffect)(()=>{if(!n)return;let e=()=>{if(!f.current)return;let e=f.current.getBoundingClientRect();u({top:e.bottom+4,right:window.innerWidth-e.right})};return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[n]),!I(e))return null;let h=e=>{e.stopPropagation(),e.preventDefault()},g=e=>{if(h(e),!n&&f.current){let e=f.current.getBoundingClientRect();u({top:e.bottom+4,right:window.innerWidth-e.right})}i(e=>!e)},v=async e=>{o(!0),c(null);try{await e(),i(!1),t()}catch(e){c(e instanceof Error?e.message:String(e))}finally{o(!1)}};return(0,j.jsxs)(`div`,{className:`connector-tile-menu`,onClick:h,onKeyDown:h,children:[(0,j.jsx)(`button`,{ref:f,type:`button`,className:`connector-tile-menu-trigger`,"aria-haspopup":`menu`,"aria-expanded":n,"aria-label":`Connector actions`,onClick:g,disabled:a,children:(0,j.jsx)(A,{size:14})}),n&&l&&(0,j.jsxs)(`div`,{ref:p,role:`menu`,className:`connector-tile-menu-popup`,style:{position:`fixed`,top:l.top,right:l.right},children:[e.enabled?(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void v(()=>E(e.id)),disabled:a,children:`Disable`}):(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void v(()=>d(e.id)),disabled:a,children:`Enable`}),(0,j.jsx)(`div`,{className:`connector-tile-menu-divider`}),(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item connector-tile-menu-item--danger`,onClick:()=>void v(()=>_(e.id)),disabled:a,children:`Disconnect`}),s&&(0,j.jsx)(`div`,{className:`connector-tile-menu-error`,children:s})]})]})}var R={"https://www.googleapis.com/auth/gmail.readonly":`Read emails`,"https://www.googleapis.com/auth/gmail.modify":`Organize emails (archive, label, trash)`,"https://www.googleapis.com/auth/gmail.send":`Send emails on your behalf`,"https://www.googleapis.com/auth/gmail.compose":`Compose emails`,"https://www.googleapis.com/auth/calendar.readonly":`View calendar events`,"https://www.googleapis.com/auth/calendar.events":`Create & respond to calendar events`,"https://www.googleapis.com/auth/drive.readonly":`Read Google Drive files`,"https://www.googleapis.com/auth/drive.file":`Manage Drive files created by this app`,"https://www.googleapis.com/auth/spreadsheets.readonly":`Read Google Sheets`,"https://www.googleapis.com/auth/spreadsheets":`Edit Google Sheets`,openid:`Identify you`,email:`See your email address`,profile:`See your basic profile info`,"https://graph.microsoft.com/Mail.ReadWrite":`Read & organize Outlook mail (archive, label, trash)`,"https://graph.microsoft.com/Mail.Send":`Send Outlook mail on your behalf`,"https://graph.microsoft.com/Calendars.ReadWrite":`Create & respond to Outlook calendar events`,"https://graph.microsoft.com/Calendars.Read":`View Outlook calendar events`,"https://graph.microsoft.com/User.Read":`Read your basic Microsoft profile`};function z(e){return R[e]??e.split(/[/.:]/).pop()??e}var B=[`use`];function V(e){return!(`revoke_supported`in e)||e.revoke_supported&&e.revoked_remotely?null:e.revoke_supported&&!e.revoked_remotely?`Disconnected locally, but the provider did not confirm the revoke (${String(e.revoke_error??`unknown error`)}). It may still show as connected in your account's app permissions.`:e.revoke_error?`Disconnected locally. ${String(e.revoke_error)}`:`Disconnected locally. This provider has no API to revoke access remotely — remove GAIA from your account's connected-apps page if you want to fully revoke it.`}function H(){let[e,t]=(0,M.useState)([]),[n,r]=(0,M.useState)([]),[i,a]=(0,M.useState)(!0),[o,s]=(0,M.useState)(null),[c,l]=(0,M.useState)(null),[d,p]=(0,M.useState)(null),m=(0,M.useCallback)(async()=>{try{let[{connectors:e},{agent_mcps:n}]=await Promise.all([f(),S()]);t(e),r(n),s(null)}catch(e){s(e instanceof Error?e.message:String(e))}finally{a(!1)}},[]);(0,M.useEffect)(()=>{m()},[m]);let h=e=>p(t=>t===e?null:e),g=(0,M.useCallback)(async e=>{try{let n=await u(e);t(t=>t.map(t=>t.id===e?n:t))}catch{m()}},[m]);return F((0,M.useCallback)(e=>{e.reason===`disconnected`&&l(V(e.payload)),e.connectorId?g(e.connectorId):m()},[g,m])),(0,j.jsxs)(`section`,{className:`connectors-section`,"aria-label":`Connectors`,children:[(0,j.jsx)(`p`,{className:`settings-help`,children:`Connect accounts and MCP servers so GAIA can use them on your behalf. Choose what GAIA may do with each one.`}),o&&(0,j.jsxs)(`div`,{className:`error-banner`,children:[(0,j.jsx)(y,{size:14}),(0,j.jsx)(`span`,{children:o})]}),c&&(0,j.jsxs)(`div`,{className:`error-banner`,role:`status`,onClick:()=>l(null),children:[(0,j.jsx)(y,{size:14}),(0,j.jsx)(`span`,{children:c})]}),i?(0,j.jsx)(`div`,{className:`connectors-loading`,children:(0,j.jsx)(w,{size:16,className:`spin`})}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`connectors-list`,children:e.map(e=>(0,j.jsx)(U,{connector:e,expanded:d===e.id,onToggle:()=>h(e.id),onChanged:()=>void g(e.id)},e.id))}),n.length>0&&(0,j.jsx)(J,{servers:n,expanded:d,onToggle:h})]})]})}function U({connector:e,expanded:t,onToggle:n,onChanged:r}){return(0,j.jsxs)(`div`,{className:`connector-tile${t?` connector-tile--open`:``}`,children:[(0,j.jsxs)(`button`,{className:`connector-tile-header`,onClick:n,"aria-expanded":t,children:[(0,j.jsx)(`span`,{className:`connector-tile-name`,children:e.display_name}),(0,j.jsx)(`span`,{className:`connector-tile-type`,children:e.type===`oauth_pkce`?`OAuth`:`MCP`}),e.configured?e.type===`mcp_server`&&e.enabled===!1?(0,j.jsx)(`span`,{className:`connector-status disabled`,children:`Disabled`}):(0,j.jsxs)(`span`,{className:`connector-status ok`,children:[(0,j.jsx)(T,{size:12}),e.account_id??`Configured`]}):(0,j.jsx)(`span`,{className:`connector-status idle`,children:`Not configured`}),(0,j.jsx)(L,{connector:e,onChanged:r}),(0,j.jsx)(`span`,{className:`connector-tile-chevron`,children:t?(0,j.jsx)(C,{size:14}):(0,j.jsx)(b,{size:14})})]}),t&&(0,j.jsxs)(`div`,{className:`connector-detail`,children:[e.type===`oauth_pkce`?(0,j.jsx)(W,{connector:e,onChanged:r}):(0,j.jsx)(K,{connector:e,onChanged:r}),e.configured&&(0,j.jsx)(X,{connectorId:e.id,connectorType:e.type})]})]})}function W({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(!1),[i,a]=(0,M.useState)(null),[o,c]=(0,M.useState)({}),[l,u]=(0,M.useState)(null),{agents:d}=h(),f=d.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e.id)),p=f.map(e=>e.namespaced_agent_id).join(`,`),[m,b]=(0,M.useState)(()=>new Set);(0,M.useEffect)(()=>{b(new Set(f.map(e=>e.namespaced_agent_id)))},[p]);let x=e=>b(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),S=()=>[...m];(0,M.useEffect)(()=>{let e=()=>{t()};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[t]);let C=e=>{let t=window;t.gaia?.openExternal?t.gaia.openExternal(e):window.open(e,`_blank`,`noopener`)},T=async()=>{r(!0),a(null);try{let t=await v(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,S());C(t.authorization_url)}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}},E=async()=>{r(!0),a(null),u(null);try{let t=await D(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,S());u(t)}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}};(0,M.useEffect)(()=>{e.configured&&u(null)},[e.configured]),F((0,M.useCallback)(t=>{t.connectorId===e.id&&(t.reason===`oauth_error`?(a(String(t.payload.error??`Device sign-in failed.`)),u(null)):t.reason===`oauth_completed`&&u(null))},[e.id]));let O=async()=>{r(!0),a(null);try{await _(e.id),t()}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}},k=async()=>{let n=(e.oauth_setup_fields??[]).filter(e=>e.required!==!1&&!o[e.key]?.trim()).map(e=>e.label);if(n.length)a(`Required: ${n.join(`, `)}`);else{r(!0),a(null);try{let n=e.available_scopes?.length?e.available_scopes:e.default_scopes,r=await g(e.id,{...o,scopes:n,grant_agents:S()}),i=typeof r.authorization_url==`string`?r.authorization_url:null;i&&C(i),t()}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}}},A=e.oauth_setup_fields??[],N=e.configurable===!1&&!e.configured&&A.length>0;return(0,j.jsxs)(`div`,{className:`configure-body`,children:[e.description&&(0,j.jsx)(`p`,{className:`connector-desc`,children:e.description}),N&&(0,j.jsxs)(`div`,{className:`oauth-setup-form`,children:[(0,j.jsx)(`p`,{className:`connector-desc`,children:`First-time setup — provide your OAuth client credentials below. They’re stored encrypted in your OS keyring and reused for future connections.`}),A.map(e=>(0,j.jsxs)(`label`,{className:`oauth-setup-field`,children:[(0,j.jsx)(`span`,{className:`oauth-setup-label`,children:e.label}),(0,j.jsx)(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.placeholder,value:o[e.key]??``,onChange:t=>c(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&(0,j.jsx)(`span`,{className:`oauth-setup-help`,children:e.help_md})]},e.key))]}),!e.configured&&f.length>0&&(0,j.jsxs)(`div`,{className:`oauth-grant-onconnect`,children:[(0,j.jsx)(`p`,{className:`oauth-grant-onconnect-label`,children:`Grant access to these agents when you connect:`}),f.map(e=>(0,j.jsxs)(`label`,{className:`oauth-grant-onconnect-item`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:m.has(e.namespaced_agent_id),onChange:()=>x(e.namespaced_agent_id)}),(0,j.jsx)(`span`,{children:e.name})]},e.namespaced_agent_id)),(0,j.jsx)(`p`,{className:`oauth-grant-onconnect-help`,children:`You can change these any time under Per-agent grants below.`})]}),!N&&(0,j.jsx)(G,{connector:e,onChanged:t}),i&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,i]}),(0,j.jsxs)(`div`,{className:`configure-actions`,children:[e.configured?(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:n,onClick:()=>void O(),children:n?(0,j.jsx)(w,{size:12,className:`spin`}):`Disconnect`}):N?(0,j.jsx)(`button`,{className:`btn-primary`,disabled:n,onClick:()=>void k(),children:n?(0,j.jsx)(w,{size:12,className:`spin`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(s,{size:12}),` Save & Connect`]})}):e.configurable===!1?(0,j.jsx)(`span`,{className:`connector-setup-required`,title:e.config_error??void 0,children:`Setup required`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`button`,{className:`btn-primary`,disabled:n||l!==null,onClick:()=>void T(),children:n?(0,j.jsx)(w,{size:12,className:`spin`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(s,{size:12}),` Connect`]})}),e.supports_device_code&&(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:n||l!==null,onClick:()=>void E(),title:`Enter a short code at a URL — no browser redirect or app registration needed`,children:`Sign in with a code`})]}),(e.docs_url||e.product_url)&&(0,j.jsxs)(`a`,{href:e.docs_url||e.product_url||`#`,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[`Learn more `,(0,j.jsx)(s,{size:11})]})]}),l&&!e.configured&&(0,j.jsxs)(`div`,{className:`device-code-block`,children:[(0,j.jsxs)(`p`,{className:`device-code-instructions`,children:[`Go to`,` `,(0,j.jsx)(`a`,{href:l.verification_uri,target:`_blank`,rel:`noopener noreferrer`,onClick:e=>{e.preventDefault(),C(l.verification_uri)},children:l.verification_uri}),` `,`and enter this code:`]}),(0,j.jsxs)(`div`,{className:`device-code-value`,children:[(0,j.jsx)(`code`,{children:l.user_code}),(0,j.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void navigator.clipboard?.writeText(l.user_code),title:`Copy code`,children:`Copy`})]}),(0,j.jsxs)(`p`,{className:`device-code-waiting`,children:[(0,j.jsx)(w,{size:12,className:`spin`}),` Waiting for sign-in…`]}),(0,j.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>u(null),children:`Cancel`})]})]})}function G({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(!1),[i,a]=(0,M.useState)({}),[o,s]=(0,M.useState)(!1),[c,l]=(0,M.useState)(!1),[u,d]=(0,M.useState)(null),f=e.oauth_setup_fields??[];if(f.length===0)return null;let p=e.oauth_client,m=p?.source===`keyring`?`Saved client: ${p.client_id}`:p?.source===`env`?`From environment: ${p.client_id}`:`No OAuth client configured`,h=async()=>{if(!i.client_id?.trim())d(`Client ID is required.`);else{s(!0),d(null),l(!1);try{await g(e.id,{...Object.fromEntries(Object.entries(i).map(([e,t])=>[e,t.trim()])),save_only:!0}),l(!0),a({}),t(),setTimeout(()=>l(!1),2200)}catch(e){d(e instanceof Error?e.message:String(e))}finally{s(!1)}}};return(0,j.jsxs)(`div`,{className:`oauth-client-editor`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`oauth-client-editor__toggle`,onClick:()=>r(e=>!e),"aria-expanded":n,children:[n?(0,j.jsx)(C,{size:12}):(0,j.jsx)(b,{size:12}),(0,j.jsx)(`span`,{children:`OAuth client`}),(0,j.jsx)(`span`,{className:`oauth-client-editor__status`,children:m})]}),n&&(0,j.jsxs)(`div`,{className:`oauth-setup-form`,children:[(0,j.jsxs)(`p`,{className:`connector-desc`,children:[`Bring your own OAuth client — saved encrypted in your OS keyring (same store as`,` `,(0,j.jsx)(`code`,{children:`gaia connectors configure`}),`) and reused for future connections. Environment variables are only used when no saved client exists.`]}),f.map(e=>(0,j.jsxs)(`label`,{className:`oauth-setup-field`,children:[(0,j.jsx)(`span`,{className:`oauth-setup-label`,children:e.label}),(0,j.jsx)(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.kind===`secret`&&p?.source===`keyring`&&p.has_secret?`••••••••`:e.placeholder,value:i[e.key]??``,onChange:t=>a(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&(0,j.jsx)(`span`,{className:`oauth-setup-help`,children:e.help_md})]},e.key)),u&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,u]}),(0,j.jsx)(`div`,{className:`configure-actions`,children:(0,j.jsx)(`button`,{className:`btn-model-save${c?` saved`:``}`,disabled:o||!i.client_id?.trim(),onClick:()=>void h(),children:o?(0,j.jsx)(w,{size:12,className:`spin`}):c?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(T,{size:12}),` Saved`]}):`Save client`})})]})]})}function K({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(()=>Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),[i,a]=(0,M.useState)(!1),[o,c]=(0,M.useState)(!1),[l,u]=(0,M.useState)(null);(0,M.useEffect)(()=>{r(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``])))},[e.mcp_env_keys.join(`,`)]);let f=e.mcp_env_keys.length===0,p=Object.values(n).every(e=>e.trim()===``),m=async()=>{let r=Object.fromEntries(Object.entries(n).filter(([,e])=>e.trim()!==``));if(f||Object.keys(r).length!==0){a(!0),u(null),c(!1);try{await g(e.id,r),c(!0),t(),setTimeout(()=>c(!1),2200)}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}}},h=async()=>{a(!0),u(null);try{await _(e.id),r(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),t()}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}},v=async()=>{a(!0),u(null);try{e.enabled?await E(e.id):await d(e.id),t()}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}};return(0,j.jsxs)(`div`,{className:`configure-body`,children:[e.description&&(0,j.jsx)(`p`,{className:`connector-desc`,children:e.description}),l&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,l]}),e.configured&&(0,j.jsxs)(`div`,{className:`connector-toggle-row`,children:[(0,j.jsx)(`span`,{className:`connector-toggle-label`,children:`Active`}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:e.enabled!==!1,onChange:()=>void v(),disabled:i,"aria-label":e.enabled?`Disable this MCP server`:`Enable this MCP server`}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]}),e.configured&&e.enabled===!1&&(0,j.jsx)(`p`,{className:`connector-toggle-help`,children:`Credentials and per-agent grants are preserved. Re-enable to make this server's tools available again.`}),e.mcp_env_keys.map(t=>(0,j.jsxs)(`div`,{className:`mcp-key-row`,children:[(0,j.jsx)(`label`,{className:`mcp-key-label`,children:t}),(0,j.jsx)(`input`,{type:`password`,className:`mcp-key-input`,placeholder:e.configured?`••••••••`:`Enter value`,value:n[t]??``,onChange:e=>r(n=>({...n,[t]:e.target.value})),spellCheck:!1,autoComplete:`off`})]},t)),(0,j.jsxs)(`div`,{className:`configure-actions`,children:[!(f&&e.configured)&&(0,j.jsx)(`button`,{className:`btn-model-save${o?` saved`:``}`,disabled:i||!f&&p,onClick:()=>void m(),children:i?(0,j.jsx)(w,{size:12,className:`spin`}):o?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(T,{size:12}),` Saved`]}):f?`Connect`:`Save`}),e.configured&&(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:i,onClick:()=>void h(),children:`Disconnect`}),e.product_url&&(0,j.jsxs)(`a`,{href:e.product_url,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[`Docs `,(0,j.jsx)(s,{size:11})]})]})]})}function q({agent:e,connectorId:t,grantedScopes:n,onChanged:r}){let i=e.required_connections?.find(e=>e.connector_id===t),a=e.namespaced_agent_id;if(!i||!a)return null;let[o,s]=(0,M.useState)(()=>new Set(n)),[c,l]=(0,M.useState)(null),[u,d]=(0,M.useState)(null);(0,M.useEffect)(()=>{s(new Set(n))},[n.join(`,`)]);let f=async e=>{if(c!==null)return;let i=new Set(o);i.has(e)?i.delete(e):i.add(e),s(i),l(e),d(null);try{i.size===0?await p(t,a):await m(t,a,[...i]),r()}catch(e){s(new Set(n)),d(e instanceof Error?e.message:String(e))}finally{l(null)}};return(0,j.jsxs)(`div`,{className:`grant-agent-card`,children:[(0,j.jsx)(`div`,{className:`grant-agent-card-name`,children:e.name}),(0,j.jsx)(`div`,{className:`grant-scope-list`,children:i.scopes.map(e=>(0,j.jsxs)(`label`,{className:`grant-scope-item`,children:[(0,j.jsx)(`span`,{className:`grant-scope-label`,children:z(e)}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:o.has(e),onChange:()=>void f(e),disabled:c!==null}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]},e))}),u&&(0,j.jsxs)(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[(0,j.jsx)(y,{size:11}),` `,u]})]})}function J({servers:e,expanded:t,onToggle:n}){return(0,j.jsxs)(`div`,{className:`agent-mcps-section`,children:[(0,j.jsx)(`div`,{className:`agent-mcps-section-header`,children:`Custom agent servers`}),(0,j.jsx)(`div`,{className:`connectors-list`,children:e.map(e=>{let r=`${e.agent_id}::${e.server_name}`;return(0,j.jsx)(Y,{server:e,expanded:t===r,onToggle:()=>n(r)},r)})})]})}function Y({server:e,expanded:t,onToggle:n}){let r=[e.command,...e.args].join(` `);return(0,j.jsxs)(`div`,{className:`agent-mcp-tile${t?` agent-mcp-tile--open`:``}`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`agent-mcp-tile-header`,onClick:n,"aria-expanded":t,children:[(0,j.jsx)(`span`,{className:`agent-mcp-server-name`,children:e.server_name}),(0,j.jsxs)(`span`,{className:`agent-mcp-agent-label`,children:[`via `,e.agent_name]}),e.disabled?(0,j.jsx)(`span`,{className:`agent-mcp-status disabled`,children:`Disabled`}):(0,j.jsxs)(`span`,{className:`agent-mcp-status enabled`,children:[(0,j.jsx)(T,{size:11}),` Active`]}),(0,j.jsx)(`span`,{className:`agent-mcp-readonly-badge`,children:`read-only`}),(0,j.jsx)(`span`,{className:`agent-mcp-chevron`,children:t?(0,j.jsx)(C,{size:14}):(0,j.jsx)(b,{size:14})})]}),t&&(0,j.jsxs)(`div`,{className:`agent-mcp-detail`,children:[r&&(0,j.jsx)(`div`,{className:`agent-mcp-command-row`,children:r}),(0,j.jsx)(`div`,{className:`agent-mcp-config-path`,children:e.config_path}),(0,j.jsxs)(`div`,{className:`agent-mcp-config-hint`,children:[`Edit the agent's `,(0,j.jsx)(`code`,{children:`mcp_servers.json`}),` to change this server.`]})]})]})}function X({connectorId:e,connectorType:t}){let{agents:n}=h(),[r,i]=(0,M.useState)({}),[a,o]=(0,M.useState)({}),[s,l]=(0,M.useState)(!0),u=(0,M.useCallback)(async()=>{try{let[{grants:t},{activations:n}]=await Promise.all([x(e),c(e)]);i(t),o(n)}catch{i({}),o({})}finally{l(!1)}},[e]);if((0,M.useEffect)(()=>{u()},[u]),F((0,M.useCallback)(t=>{t.connectorId===e&&(t.reason===`grant_changed`||t.reason===`activation_changed`||t.reason===`disconnected`)&&u()},[e,u])),s)return null;let d=n.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e)),f=t===`mcp_server`?n.filter(t=>t.namespaced_agent_id&&(t.consumes_mcp_servers||t.required_connections?.some(t=>t.connector_id===e))):[];return(0,j.jsxs)(`div`,{className:`connection-grants`,children:[(0,j.jsx)(`div`,{className:`grants-header`,children:`Per-agent grants`}),d.length===0?(0,j.jsx)(`div`,{className:`grants-empty`,children:`No agents require access to this connector.`}):d.map(t=>(0,j.jsx)(q,{agent:t,connectorId:e,grantedScopes:r[t.namespaced_agent_id]??[],onChanged:()=>void u()},t.namespaced_agent_id)),f.length>0&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`grants-header grants-header--activations`,children:`Active for`}),(0,j.jsx)(`div`,{className:`grants-help`,children:`Activations gate which agents see this connector's tools. Activating without a prior grant auto-creates one.`}),f.map(t=>(0,j.jsx)(Z,{agent:t,connectorId:e,active:!!a[t.namespaced_agent_id],grantedScopes:r[t.namespaced_agent_id]??[],onChanged:()=>void u()},`activation-${t.namespaced_agent_id}`))]})]})}function Z({agent:e,connectorId:t,active:n,grantedScopes:r,onChanged:i}){let a=e.required_connections?.find(e=>e.connector_id===t),o=e.namespaced_agent_id;if(!o)return null;let[s,c]=(0,M.useState)(n),[u,d]=(0,M.useState)(!1),[f,p]=(0,M.useState)(null);(0,M.useEffect)(()=>{c(n)},[n]);let m=async()=>{if(u)return;let e=!s;c(e),d(!0),p(null);try{if(e){let e=r.length===0?a?[...a.scopes]:[...B]:void 0;await O(t,o,e)}else await l(t,o);i()}catch(e){c(n),p(e instanceof Error?e.message:String(e))}finally{d(!1)}};return(0,j.jsxs)(`div`,{className:`grant-agent-card`,children:[(0,j.jsx)(`div`,{className:`grant-agent-card-name`,children:e.name}),(0,j.jsx)(`div`,{className:`grant-scope-list`,children:(0,j.jsxs)(`label`,{className:`grant-scope-item`,children:[(0,j.jsx)(`span`,{className:`grant-scope-label`,children:s?`Tools visible to this agent`:`Tools hidden from this agent`}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:s,onChange:()=>void m(),disabled:u}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]})}),f&&(0,j.jsxs)(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[(0,j.jsx)(y,{size:11}),` `,f]})]})}function Q(){return(0,j.jsxs)(`div`,{className:`settings-pane`,children:[(0,j.jsx)(`h2`,{className:`settings-pane-title`,children:`Connectors`}),(0,j.jsx)(H,{})]})}export{Q as ConnectorsPane};
1
+ import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,t as a,u as o}from"./apiBase-BmPG2Rib.js";import{$t as s,At as c,Ct as l,Dt as u,Et as d,Mt as f,Nt as p,Ot as m,Pt as h,St as g,Tt as _,bt as v,cn as y,dn as b,jt as x,kt as S,ln as C,on as w,qt as T,wt as E,xt as D,yt as O}from"./index-CfiDLYYM.js";var k={name:`ellipsis`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`19`,cy:`12`,r:`1`,key:`1wjl8i`}],[`circle`,{cx:`5`,cy:`12`,r:`1`,key:`1pcz8c`}]],aliases:[`more-horizontal`]};k.node;var A=t(k),j=n(),M=e(o(),1),N=i.api;function P(e){switch(e){case`connector.configured`:return`configured`;case`connector.disconnected`:return`disconnected`;case`connection.revoked`:return`disconnected`;case`connector.oauth.completed`:return`oauth_completed`;case`connection.connected`:return`oauth_completed`;case`connector.oauth.error`:return`oauth_error`;case`connector.tested`:return`tested`;case`connector.enabled`:return`enabled`;case`connector.disabled`:return`disabled`;case`connector.grant.changed`:return`grant_changed`;case`connector.activation.changed`:return`activation_changed`;default:return null}}function F(e){let t=(0,M.useRef)(e);(0,M.useEffect)(()=>{t.current=e},[e]),(0,M.useEffect)(()=>{let e=`${a()}/connectors/events`,n=null,r=1e3,i=null,o=!1,s=()=>{o||(n=new EventSource(e),n.onopen=()=>{r=1e3},n.onmessage=e=>{try{let n=JSON.parse(e.data),r=P(n.type);if(r===null){N.debug(`connectors-sse: ignoring event`,n.type);return}let i=n.payload??{},a=i.connector_id??i.provider??null;t.current({connectorId:a,reason:r,payload:i})}catch(e){N.warn(`connectors-sse: malformed event`,e)}},n.onerror=()=>{n?.close(),n=null,!o&&(i=setTimeout(s,r),r=Math.min(r*2,3e4))})};return s(),()=>{o=!0,i&&clearTimeout(i),n?.close()}},[])}function I(e){return e.type===`mcp_server`&&e.configured}function L({connector:e,onChanged:t}){let[n,i]=(0,M.useState)(!1),[a,o]=(0,M.useState)(!1),[s,c]=(0,M.useState)(null),[l,u]=(0,M.useState)(null),f=(0,M.useRef)(null),p=(0,M.useRef)(null);(0,M.useEffect)(()=>{if(!n)return;let e=e=>{let t=e.target;f.current&&!f.current.contains(t)&&p.current&&!p.current.contains(t)&&i(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[n]);let m=(0,M.useCallback)(()=>i(!1),[]);if(r(n,m),(0,M.useEffect)(()=>{if(!n)return;let e=()=>{if(!f.current)return;let e=f.current.getBoundingClientRect();u({top:e.bottom+4,right:window.innerWidth-e.right})};return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[n]),!I(e))return null;let h=e=>{e.stopPropagation(),e.preventDefault()},g=e=>{if(h(e),!n&&f.current){let e=f.current.getBoundingClientRect();u({top:e.bottom+4,right:window.innerWidth-e.right})}i(e=>!e)},v=async e=>{o(!0),c(null);try{await e(),i(!1),t()}catch(e){c(e instanceof Error?e.message:String(e))}finally{o(!1)}};return(0,j.jsxs)(`div`,{className:`connector-tile-menu`,onClick:h,onKeyDown:h,children:[(0,j.jsx)(`button`,{ref:f,type:`button`,className:`connector-tile-menu-trigger`,"aria-haspopup":`menu`,"aria-expanded":n,"aria-label":`Connector actions`,onClick:g,disabled:a,children:(0,j.jsx)(A,{size:14})}),n&&l&&(0,j.jsxs)(`div`,{ref:p,role:`menu`,className:`connector-tile-menu-popup`,style:{position:`fixed`,top:l.top,right:l.right},children:[e.enabled?(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void v(()=>E(e.id)),disabled:a,children:`Disable`}):(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void v(()=>d(e.id)),disabled:a,children:`Enable`}),(0,j.jsx)(`div`,{className:`connector-tile-menu-divider`}),(0,j.jsx)(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item connector-tile-menu-item--danger`,onClick:()=>void v(()=>_(e.id)),disabled:a,children:`Disconnect`}),s&&(0,j.jsx)(`div`,{className:`connector-tile-menu-error`,children:s})]})]})}var R={"https://www.googleapis.com/auth/gmail.readonly":`Read emails`,"https://www.googleapis.com/auth/gmail.modify":`Organize emails (archive, label, trash)`,"https://www.googleapis.com/auth/gmail.send":`Send emails on your behalf`,"https://www.googleapis.com/auth/gmail.compose":`Compose emails`,"https://www.googleapis.com/auth/calendar.readonly":`View calendar events`,"https://www.googleapis.com/auth/calendar.events":`Create & respond to calendar events`,"https://www.googleapis.com/auth/drive.readonly":`Read Google Drive files`,"https://www.googleapis.com/auth/drive.file":`Manage Drive files created by this app`,"https://www.googleapis.com/auth/spreadsheets.readonly":`Read Google Sheets`,"https://www.googleapis.com/auth/spreadsheets":`Edit Google Sheets`,openid:`Identify you`,email:`See your email address`,profile:`See your basic profile info`,"https://graph.microsoft.com/Mail.ReadWrite":`Read & organize Outlook mail (archive, label, trash)`,"https://graph.microsoft.com/Mail.Send":`Send Outlook mail on your behalf`,"https://graph.microsoft.com/Calendars.ReadWrite":`Create & respond to Outlook calendar events`,"https://graph.microsoft.com/Calendars.Read":`View Outlook calendar events`,"https://graph.microsoft.com/User.Read":`Read your basic Microsoft profile`};function z(e){return R[e]??e.split(/[/.:]/).pop()??e}var B=[`use`];function V(e){return!(`revoke_supported`in e)||e.revoke_supported&&e.revoked_remotely?null:e.revoke_supported&&!e.revoked_remotely?`Disconnected locally, but the provider did not confirm the revoke (${String(e.revoke_error??`unknown error`)}). It may still show as connected in your account's app permissions.`:e.revoke_error?`Disconnected locally. ${String(e.revoke_error)}`:`Disconnected locally. This provider has no API to revoke access remotely — remove GAIA from your account's connected-apps page if you want to fully revoke it.`}function H(){let[e,t]=(0,M.useState)([]),[n,r]=(0,M.useState)([]),[i,a]=(0,M.useState)(!0),[o,s]=(0,M.useState)(null),[c,l]=(0,M.useState)(null),[d,p]=(0,M.useState)(null),m=(0,M.useCallback)(async()=>{try{let[{connectors:e},{agent_mcps:n}]=await Promise.all([f(),S()]);t(e),r(n),s(null)}catch(e){s(e instanceof Error?e.message:String(e))}finally{a(!1)}},[]);(0,M.useEffect)(()=>{m()},[m]);let h=e=>p(t=>t===e?null:e),g=(0,M.useCallback)(async e=>{try{let n=await u(e);t(t=>t.map(t=>t.id===e?n:t))}catch{m()}},[m]);return F((0,M.useCallback)(e=>{e.reason===`disconnected`&&l(V(e.payload)),e.connectorId?g(e.connectorId):m()},[g,m])),(0,j.jsxs)(`section`,{className:`connectors-section`,"aria-label":`Connectors`,children:[(0,j.jsx)(`p`,{className:`settings-help`,children:`Connect accounts and MCP servers so GAIA can use them on your behalf. Choose what GAIA may do with each one.`}),o&&(0,j.jsxs)(`div`,{className:`error-banner`,children:[(0,j.jsx)(y,{size:14}),(0,j.jsx)(`span`,{children:o})]}),c&&(0,j.jsxs)(`div`,{className:`error-banner`,role:`status`,onClick:()=>l(null),children:[(0,j.jsx)(y,{size:14}),(0,j.jsx)(`span`,{children:c})]}),i?(0,j.jsx)(`div`,{className:`connectors-loading`,children:(0,j.jsx)(T,{size:16,className:`spin`})}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`connectors-list`,children:e.map(e=>(0,j.jsx)(U,{connector:e,expanded:d===e.id,onToggle:()=>h(e.id),onChanged:()=>void g(e.id)},e.id))}),n.length>0&&(0,j.jsx)(J,{servers:n,expanded:d,onToggle:h})]})]})}function U({connector:e,expanded:t,onToggle:n,onChanged:r}){return(0,j.jsxs)(`div`,{className:`connector-tile${t?` connector-tile--open`:``}`,children:[(0,j.jsxs)(`button`,{className:`connector-tile-header`,onClick:n,"aria-expanded":t,children:[(0,j.jsx)(`span`,{className:`connector-tile-name`,children:e.display_name}),(0,j.jsx)(`span`,{className:`connector-tile-type`,children:e.type===`oauth_pkce`?`OAuth`:`MCP`}),e.configured?e.type===`mcp_server`&&e.enabled===!1?(0,j.jsx)(`span`,{className:`connector-status disabled`,children:`Disabled`}):(0,j.jsxs)(`span`,{className:`connector-status ok`,children:[(0,j.jsx)(w,{size:12}),e.account_id??`Configured`]}):(0,j.jsx)(`span`,{className:`connector-status idle`,children:`Not configured`}),(0,j.jsx)(L,{connector:e,onChanged:r}),(0,j.jsx)(`span`,{className:`connector-tile-chevron`,children:t?(0,j.jsx)(C,{size:14}):(0,j.jsx)(b,{size:14})})]}),t&&(0,j.jsxs)(`div`,{className:`connector-detail`,children:[e.type===`oauth_pkce`?(0,j.jsx)(W,{connector:e,onChanged:r}):(0,j.jsx)(K,{connector:e,onChanged:r}),e.configured&&(0,j.jsx)(X,{connectorId:e.id,connectorType:e.type})]})]})}function W({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(!1),[i,a]=(0,M.useState)(null),[o,c]=(0,M.useState)({}),[l,u]=(0,M.useState)(null),{agents:d}=h(),f=d.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e.id)),p=f.map(e=>e.namespaced_agent_id).join(`,`),[m,b]=(0,M.useState)(()=>new Set);(0,M.useEffect)(()=>{b(new Set(f.map(e=>e.namespaced_agent_id)))},[p]);let x=e=>b(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),S=()=>[...m];(0,M.useEffect)(()=>{let e=()=>{t()};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[t]);let C=e=>{let t=window;t.gaia?.openExternal?t.gaia.openExternal(e):window.open(e,`_blank`,`noopener`)},w=async()=>{r(!0),a(null);try{let t=await v(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,S());C(t.authorization_url)}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}},E=async()=>{r(!0),a(null),u(null);try{let t=await D(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,S());u(t)}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}};(0,M.useEffect)(()=>{e.configured&&u(null)},[e.configured]),F((0,M.useCallback)(t=>{t.connectorId===e.id&&(t.reason===`oauth_error`?(a(String(t.payload.error??`Device sign-in failed.`)),u(null)):t.reason===`oauth_completed`&&u(null))},[e.id]));let O=async()=>{r(!0),a(null);try{await _(e.id),t()}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}},k=async()=>{let n=(e.oauth_setup_fields??[]).filter(e=>e.required!==!1&&!o[e.key]?.trim()).map(e=>e.label);if(n.length)a(`Required: ${n.join(`, `)}`);else{r(!0),a(null);try{let n=e.available_scopes?.length?e.available_scopes:e.default_scopes,r=await g(e.id,{...o,scopes:n,grant_agents:S()}),i=typeof r.authorization_url==`string`?r.authorization_url:null;i&&C(i),t()}catch(e){a(e instanceof Error?e.message:String(e))}finally{r(!1)}}},A=e.oauth_setup_fields??[],N=e.configurable===!1&&!e.configured&&A.length>0;return(0,j.jsxs)(`div`,{className:`configure-body`,children:[e.description&&(0,j.jsx)(`p`,{className:`connector-desc`,children:e.description}),N&&(0,j.jsxs)(`div`,{className:`oauth-setup-form`,children:[(0,j.jsx)(`p`,{className:`connector-desc`,children:`First-time setup — provide your OAuth client credentials below. They’re stored encrypted in your OS keyring and reused for future connections.`}),A.map(e=>(0,j.jsxs)(`label`,{className:`oauth-setup-field`,children:[(0,j.jsx)(`span`,{className:`oauth-setup-label`,children:e.label}),(0,j.jsx)(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.placeholder,value:o[e.key]??``,onChange:t=>c(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&(0,j.jsx)(`span`,{className:`oauth-setup-help`,children:e.help_md})]},e.key))]}),!e.configured&&f.length>0&&(0,j.jsxs)(`div`,{className:`oauth-grant-onconnect`,children:[(0,j.jsx)(`p`,{className:`oauth-grant-onconnect-label`,children:`Grant access to these agents when you connect:`}),f.map(e=>(0,j.jsxs)(`label`,{className:`oauth-grant-onconnect-item`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:m.has(e.namespaced_agent_id),onChange:()=>x(e.namespaced_agent_id)}),(0,j.jsx)(`span`,{children:e.name})]},e.namespaced_agent_id)),(0,j.jsx)(`p`,{className:`oauth-grant-onconnect-help`,children:`You can change these any time under Per-agent grants below.`})]}),!N&&(0,j.jsx)(G,{connector:e,onChanged:t}),i&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,i]}),(0,j.jsxs)(`div`,{className:`configure-actions`,children:[e.configured?(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:n,onClick:()=>void O(),children:n?(0,j.jsx)(T,{size:12,className:`spin`}):`Disconnect`}):N?(0,j.jsx)(`button`,{className:`btn-primary`,disabled:n,onClick:()=>void k(),children:n?(0,j.jsx)(T,{size:12,className:`spin`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(s,{size:12}),` Save & Connect`]})}):e.configurable===!1?(0,j.jsx)(`span`,{className:`connector-setup-required`,title:e.config_error??void 0,children:`Setup required`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`button`,{className:`btn-primary`,disabled:n||l!==null,onClick:()=>void w(),children:n?(0,j.jsx)(T,{size:12,className:`spin`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(s,{size:12}),` Connect`]})}),e.supports_device_code&&(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:n||l!==null,onClick:()=>void E(),title:`Enter a short code at a URL — no browser redirect or app registration needed`,children:`Sign in with a code`})]}),(e.docs_url||e.product_url)&&(0,j.jsxs)(`a`,{href:e.docs_url||e.product_url||`#`,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[`Learn more `,(0,j.jsx)(s,{size:11})]})]}),l&&!e.configured&&(0,j.jsxs)(`div`,{className:`device-code-block`,children:[(0,j.jsxs)(`p`,{className:`device-code-instructions`,children:[`Go to`,` `,(0,j.jsx)(`a`,{href:l.verification_uri,target:`_blank`,rel:`noopener noreferrer`,onClick:e=>{e.preventDefault(),C(l.verification_uri)},children:l.verification_uri}),` `,`and enter this code:`]}),(0,j.jsxs)(`div`,{className:`device-code-value`,children:[(0,j.jsx)(`code`,{children:l.user_code}),(0,j.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void navigator.clipboard?.writeText(l.user_code),title:`Copy code`,children:`Copy`})]}),(0,j.jsxs)(`p`,{className:`device-code-waiting`,children:[(0,j.jsx)(T,{size:12,className:`spin`}),` Waiting for sign-in…`]}),(0,j.jsx)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>u(null),children:`Cancel`})]})]})}function G({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(!1),[i,a]=(0,M.useState)({}),[o,s]=(0,M.useState)(!1),[c,l]=(0,M.useState)(!1),[u,d]=(0,M.useState)(null),f=e.oauth_setup_fields??[];if(f.length===0)return null;let p=e.oauth_client,m=p?.source===`keyring`?`Saved client: ${p.client_id}`:p?.source===`env`?`From environment: ${p.client_id}`:`No OAuth client configured`,h=async()=>{if(!i.client_id?.trim())d(`Client ID is required.`);else{s(!0),d(null),l(!1);try{await g(e.id,{...Object.fromEntries(Object.entries(i).map(([e,t])=>[e,t.trim()])),save_only:!0}),l(!0),a({}),t(),setTimeout(()=>l(!1),2200)}catch(e){d(e instanceof Error?e.message:String(e))}finally{s(!1)}}};return(0,j.jsxs)(`div`,{className:`oauth-client-editor`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`oauth-client-editor__toggle`,onClick:()=>r(e=>!e),"aria-expanded":n,children:[n?(0,j.jsx)(C,{size:12}):(0,j.jsx)(b,{size:12}),(0,j.jsx)(`span`,{children:`OAuth client`}),(0,j.jsx)(`span`,{className:`oauth-client-editor__status`,children:m})]}),n&&(0,j.jsxs)(`div`,{className:`oauth-setup-form`,children:[(0,j.jsxs)(`p`,{className:`connector-desc`,children:[`Bring your own OAuth client — saved encrypted in your OS keyring (same store as`,` `,(0,j.jsx)(`code`,{children:`gaia connectors configure`}),`) and reused for future connections. Environment variables are only used when no saved client exists.`]}),f.map(e=>(0,j.jsxs)(`label`,{className:`oauth-setup-field`,children:[(0,j.jsx)(`span`,{className:`oauth-setup-label`,children:e.label}),(0,j.jsx)(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.kind===`secret`&&p?.source===`keyring`&&p.has_secret?`••••••••`:e.placeholder,value:i[e.key]??``,onChange:t=>a(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&(0,j.jsx)(`span`,{className:`oauth-setup-help`,children:e.help_md})]},e.key)),u&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,u]}),(0,j.jsx)(`div`,{className:`configure-actions`,children:(0,j.jsx)(`button`,{className:`btn-model-save${c?` saved`:``}`,disabled:o||!i.client_id?.trim(),onClick:()=>void h(),children:o?(0,j.jsx)(T,{size:12,className:`spin`}):c?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(w,{size:12}),` Saved`]}):`Save client`})})]})]})}function K({connector:e,onChanged:t}){let[n,r]=(0,M.useState)(()=>Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),[i,a]=(0,M.useState)(!1),[o,c]=(0,M.useState)(!1),[l,u]=(0,M.useState)(null);(0,M.useEffect)(()=>{r(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``])))},[e.mcp_env_keys.join(`,`)]);let f=e.mcp_env_keys.length===0,p=Object.values(n).every(e=>e.trim()===``),m=async()=>{let r=Object.fromEntries(Object.entries(n).filter(([,e])=>e.trim()!==``));if(f||Object.keys(r).length!==0){a(!0),u(null),c(!1);try{await g(e.id,r),c(!0),t(),setTimeout(()=>c(!1),2200)}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}}},h=async()=>{a(!0),u(null);try{await _(e.id),r(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),t()}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}},v=async()=>{a(!0),u(null);try{e.enabled?await E(e.id):await d(e.id),t()}catch(e){u(e instanceof Error?e.message:String(e))}finally{a(!1)}};return(0,j.jsxs)(`div`,{className:`configure-body`,children:[e.description&&(0,j.jsx)(`p`,{className:`connector-desc`,children:e.description}),l&&(0,j.jsxs)(`div`,{className:`configure-error`,children:[(0,j.jsx)(y,{size:12}),` `,l]}),e.configured&&(0,j.jsxs)(`div`,{className:`connector-toggle-row`,children:[(0,j.jsx)(`span`,{className:`connector-toggle-label`,children:`Active`}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:e.enabled!==!1,onChange:()=>void v(),disabled:i,"aria-label":e.enabled?`Disable this MCP server`:`Enable this MCP server`}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]}),e.configured&&e.enabled===!1&&(0,j.jsx)(`p`,{className:`connector-toggle-help`,children:`Credentials and per-agent grants are preserved. Re-enable to make this server's tools available again.`}),e.mcp_env_keys.map(t=>(0,j.jsxs)(`div`,{className:`mcp-key-row`,children:[(0,j.jsx)(`label`,{className:`mcp-key-label`,children:t}),(0,j.jsx)(`input`,{type:`password`,className:`mcp-key-input`,placeholder:e.configured?`••••••••`:`Enter value`,value:n[t]??``,onChange:e=>r(n=>({...n,[t]:e.target.value})),spellCheck:!1,autoComplete:`off`})]},t)),(0,j.jsxs)(`div`,{className:`configure-actions`,children:[!(f&&e.configured)&&(0,j.jsx)(`button`,{className:`btn-model-save${o?` saved`:``}`,disabled:i||!f&&p,onClick:()=>void m(),children:i?(0,j.jsx)(T,{size:12,className:`spin`}):o?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(w,{size:12}),` Saved`]}):f?`Connect`:`Save`}),e.configured&&(0,j.jsx)(`button`,{className:`btn-secondary`,disabled:i,onClick:()=>void h(),children:`Disconnect`}),e.product_url&&(0,j.jsxs)(`a`,{href:e.product_url,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[`Docs `,(0,j.jsx)(s,{size:11})]})]})]})}function q({agent:e,connectorId:t,grantedScopes:n,onChanged:r}){let i=e.required_connections?.find(e=>e.connector_id===t),a=e.namespaced_agent_id;if(!i||!a)return null;let[o,s]=(0,M.useState)(()=>new Set(n)),[c,l]=(0,M.useState)(null),[u,d]=(0,M.useState)(null);(0,M.useEffect)(()=>{s(new Set(n))},[n.join(`,`)]);let f=async e=>{if(c!==null)return;let i=new Set(o);i.has(e)?i.delete(e):i.add(e),s(i),l(e),d(null);try{i.size===0?await p(t,a):await m(t,a,[...i]),r()}catch(e){s(new Set(n)),d(e instanceof Error?e.message:String(e))}finally{l(null)}};return(0,j.jsxs)(`div`,{className:`grant-agent-card`,children:[(0,j.jsx)(`div`,{className:`grant-agent-card-name`,children:e.name}),(0,j.jsx)(`div`,{className:`grant-scope-list`,children:i.scopes.map(e=>(0,j.jsxs)(`label`,{className:`grant-scope-item`,children:[(0,j.jsx)(`span`,{className:`grant-scope-label`,children:z(e)}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:o.has(e),onChange:()=>void f(e),disabled:c!==null}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]},e))}),u&&(0,j.jsxs)(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[(0,j.jsx)(y,{size:11}),` `,u]})]})}function J({servers:e,expanded:t,onToggle:n}){return(0,j.jsxs)(`div`,{className:`agent-mcps-section`,children:[(0,j.jsx)(`div`,{className:`agent-mcps-section-header`,children:`Custom agent servers`}),(0,j.jsx)(`div`,{className:`connectors-list`,children:e.map(e=>{let r=`${e.agent_id}::${e.server_name}`;return(0,j.jsx)(Y,{server:e,expanded:t===r,onToggle:()=>n(r)},r)})})]})}function Y({server:e,expanded:t,onToggle:n}){let r=[e.command,...e.args].join(` `);return(0,j.jsxs)(`div`,{className:`agent-mcp-tile${t?` agent-mcp-tile--open`:``}`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`agent-mcp-tile-header`,onClick:n,"aria-expanded":t,children:[(0,j.jsx)(`span`,{className:`agent-mcp-server-name`,children:e.server_name}),(0,j.jsxs)(`span`,{className:`agent-mcp-agent-label`,children:[`via `,e.agent_name]}),e.disabled?(0,j.jsx)(`span`,{className:`agent-mcp-status disabled`,children:`Disabled`}):(0,j.jsxs)(`span`,{className:`agent-mcp-status enabled`,children:[(0,j.jsx)(w,{size:11}),` Active`]}),(0,j.jsx)(`span`,{className:`agent-mcp-readonly-badge`,children:`read-only`}),(0,j.jsx)(`span`,{className:`agent-mcp-chevron`,children:t?(0,j.jsx)(C,{size:14}):(0,j.jsx)(b,{size:14})})]}),t&&(0,j.jsxs)(`div`,{className:`agent-mcp-detail`,children:[r&&(0,j.jsx)(`div`,{className:`agent-mcp-command-row`,children:r}),(0,j.jsx)(`div`,{className:`agent-mcp-config-path`,children:e.config_path}),(0,j.jsxs)(`div`,{className:`agent-mcp-config-hint`,children:[`Edit the agent's `,(0,j.jsx)(`code`,{children:`mcp_servers.json`}),` to change this server.`]})]})]})}function X({connectorId:e,connectorType:t}){let{agents:n}=h(),[r,i]=(0,M.useState)({}),[a,o]=(0,M.useState)({}),[s,l]=(0,M.useState)(!0),u=(0,M.useCallback)(async()=>{try{let[{grants:t},{activations:n}]=await Promise.all([x(e),c(e)]);i(t),o(n)}catch{i({}),o({})}finally{l(!1)}},[e]);if((0,M.useEffect)(()=>{u()},[u]),F((0,M.useCallback)(t=>{t.connectorId===e&&(t.reason===`grant_changed`||t.reason===`activation_changed`||t.reason===`disconnected`)&&u()},[e,u])),s)return null;let d=n.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e)),f=t===`mcp_server`?n.filter(t=>t.namespaced_agent_id&&(t.consumes_mcp_servers||t.required_connections?.some(t=>t.connector_id===e))):[];return(0,j.jsxs)(`div`,{className:`connection-grants`,children:[(0,j.jsx)(`div`,{className:`grants-header`,children:`Per-agent grants`}),d.length===0?(0,j.jsx)(`div`,{className:`grants-empty`,children:`No agents require access to this connector.`}):d.map(t=>(0,j.jsx)(q,{agent:t,connectorId:e,grantedScopes:r[t.namespaced_agent_id]??[],onChanged:()=>void u()},t.namespaced_agent_id)),f.length>0&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`grants-header grants-header--activations`,children:`Active for`}),(0,j.jsx)(`div`,{className:`grants-help`,children:`Activations gate which agents see this connector's tools. Activating without a prior grant auto-creates one.`}),f.map(t=>(0,j.jsx)(Z,{agent:t,connectorId:e,active:!!a[t.namespaced_agent_id],grantedScopes:r[t.namespaced_agent_id]??[],onChanged:()=>void u()},`activation-${t.namespaced_agent_id}`))]})]})}function Z({agent:e,connectorId:t,active:n,grantedScopes:r,onChanged:i}){let a=e.required_connections?.find(e=>e.connector_id===t),o=e.namespaced_agent_id;if(!o)return null;let[s,c]=(0,M.useState)(n),[u,d]=(0,M.useState)(!1),[f,p]=(0,M.useState)(null);(0,M.useEffect)(()=>{c(n)},[n]);let m=async()=>{if(u)return;let e=!s;c(e),d(!0),p(null);try{if(e){let e=r.length===0?a?[...a.scopes]:[...B]:void 0;await O(t,o,e)}else await l(t,o);i()}catch(e){c(n),p(e instanceof Error?e.message:String(e))}finally{d(!1)}};return(0,j.jsxs)(`div`,{className:`grant-agent-card`,children:[(0,j.jsx)(`div`,{className:`grant-agent-card-name`,children:e.name}),(0,j.jsx)(`div`,{className:`grant-scope-list`,children:(0,j.jsxs)(`label`,{className:`grant-scope-item`,children:[(0,j.jsx)(`span`,{className:`grant-scope-label`,children:s?`Tools visible to this agent`:`Tools hidden from this agent`}),(0,j.jsxs)(`span`,{className:`toggle-switch`,children:[(0,j.jsx)(`input`,{type:`checkbox`,checked:s,onChange:()=>void m(),disabled:u}),(0,j.jsx)(`span`,{className:`toggle-track`})]})]})}),f&&(0,j.jsxs)(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[(0,j.jsx)(y,{size:11}),` `,f]})]})}function Q(){return(0,j.jsxs)(`div`,{className:`settings-pane`,children:[(0,j.jsx)(`h2`,{className:`settings-pane-title`,children:`Connectors`}),(0,j.jsx)(H,{})]})}export{Q as ConnectorsPane};
@@ -1,4 +1,4 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,u as a}from"./apiBase-BmPG2Rib.js";import{$ as o,G as s,H as c,It as l,K as ee,Pt as u,Q as te,Qt as ne,Rt as re,U as ie,Ut as ae,Vt as oe,W as se,Xt as d,Y as f,Z as ce,_t as le,cn as p,ft as ue,in as de,lt as fe,on as pe,ot as me,q as he,st as m,t as h,vt as ge}from"./index-D-noqAc3.js";var g={name:`circle-stop`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`rect`,{x:`9`,y:`9`,width:`6`,height:`6`,rx:`1`,key:`1ssd4o`}]],aliases:[`stop-circle`]};g.node;var _=t(g),v={name:`link-2`,size:24,node:[[`path`,{d:`M9 17H7A5 5 0 0 1 7 7h2`,key:`8i5ue5`}],[`path`,{d:`M15 7h2a5 5 0 1 1 0 10h-2`,key:`1b9ql8`}],[`line`,{x1:`8`,x2:`16`,y1:`12`,y2:`12`,key:`1jonct`}]]};v.node;var _e=t(v),y={name:`loader`,size:24,node:[[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m16.2 7.8 2.9-2.9`,key:`r700ao`}],[`path`,{d:`M18 12h4`,key:`wj9ykh`}],[`path`,{d:`m16.2 16.2 2.9 2.9`,key:`1bxg5t`}],[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`m4.9 19.1 2.9-2.9`,key:`bwix9q`}],[`path`,{d:`M2 12h4`,key:`j09sii`}],[`path`,{d:`m4.9 4.9 2.9 2.9`,key:`giyufr`}]]};y.node;var ve=t(y),b={name:`refresh-ccw`,size:24,node:[[`path`,{d:`M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`14sxne`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16`,key:`1hlbsb`}],[`path`,{d:`M16 16h5v5`,key:`ccwih5`}]]};b.node;var ye=t(b),x=e(a(),1),S=n();function be(e){let[t,...n]=e.replace(/^RAG indexing failed for [^:]+:\s*/,``).trim().split(`
1
+ import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,u as a}from"./apiBase-BmPG2Rib.js";import{$ as o,G as s,H as c,It as l,K as ee,Pt as u,Q as te,Qt as ne,Rt as re,U as ie,Ut as ae,Vt as oe,W as se,Xt as d,Y as f,Z as ce,_t as le,cn as p,ft as ue,in as de,lt as fe,ot as pe,q as me,sn as he,st as m,t as h,vt as ge}from"./index-CfiDLYYM.js";var g={name:`circle-stop`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`rect`,{x:`9`,y:`9`,width:`6`,height:`6`,rx:`1`,key:`1ssd4o`}]],aliases:[`stop-circle`]};g.node;var _=t(g),v={name:`link-2`,size:24,node:[[`path`,{d:`M9 17H7A5 5 0 0 1 7 7h2`,key:`8i5ue5`}],[`path`,{d:`M15 7h2a5 5 0 1 1 0 10h-2`,key:`1b9ql8`}],[`line`,{x1:`8`,x2:`16`,y1:`12`,y2:`12`,key:`1jonct`}]]};v.node;var _e=t(v),y={name:`loader`,size:24,node:[[`path`,{d:`M12 2v4`,key:`3427ic`}],[`path`,{d:`m16.2 7.8 2.9-2.9`,key:`r700ao`}],[`path`,{d:`M18 12h4`,key:`wj9ykh`}],[`path`,{d:`m16.2 16.2 2.9 2.9`,key:`1bxg5t`}],[`path`,{d:`M12 18v4`,key:`jadmvz`}],[`path`,{d:`m4.9 19.1 2.9-2.9`,key:`bwix9q`}],[`path`,{d:`M2 12h4`,key:`j09sii`}],[`path`,{d:`m4.9 4.9 2.9 2.9`,key:`giyufr`}]]};y.node;var ve=t(y),b={name:`refresh-ccw`,size:24,node:[[`path`,{d:`M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`14sxne`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16`,key:`1hlbsb`}],[`path`,{d:`M16 16h5v5`,key:`ccwih5`}]]};b.node;var ye=t(b),x=e(a(),1),S=n();function be(e){let[t,...n]=e.replace(/^RAG indexing failed for [^:]+:\s*/,``).trim().split(`
2
2
  `);return{summary:t.trim(),more:n.join(`
3
3
  `).trim()}}function xe(e,t){let n=t.skipped??0,r=[];if(t.indexed>0?r.push(`Indexed ${t.indexed} file${t.indexed===1?``:`s`} from "${e}".`):t.failed===0&&r.push(`"${e}" has no documents GAIA can index.`),n>0&&r.push(`Skipped ${n} file${n===1?``:`s`} of a type GAIA doesn't index.`),t.failed>0){let e=t.errors[0]?` ${t.errors[0].split(`
4
- `)[0]}`:``;r.push(`${t.failed} file${t.failed===1?``:`s`} couldn't be indexed.${e}`)}return r.push(`Subfolders aren't included.`),r.join(` `)}function Se(e){let t=Math.floor((Date.now()-e)/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}function C(e){try{let t=new Date(e);if(isNaN(t.getTime()))return``;let n=new Date().getTime()-t.getTime(),r=Math.floor(n/1e3),i=Math.floor(r/60),a=Math.floor(i/60),o=Math.floor(a/24);return r<60?`just now`:i<60?`${i}m ago`:a<24?`${a}h ago`:o===1?`yesterday`:o<7?`${o}d ago`:t.toLocaleDateString(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}catch{return``}}function Ce(e){try{let t=new Date(e);return isNaN(t.getTime())?``:t.toLocaleString(void 0,{year:`numeric`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`})}catch{return``}}function w(){let{documents:e,setDocuments:t,setShowDocLibrary:n,setShowFileBrowser:a,currentSessionId:g,sessions:v,updateSessionInList:y,draftDocumentIds:b,addDraftDocuments:w,removeDraftDocument:T}=u(),E=v.find(e=>e.id===g)??null,[D,we]=(0,x.useState)(g?`chat`:`next`),O=D===`chat`?g:null,k=`“${E?.title||`Untitled chat`}”`,[A,j]=(0,x.useState)(``),Te=(0,x.useCallback)(()=>n(!1),[n]);r(!0,Te);let M=(0,x.useRef)(null);ee(M,!0);let[Ee,N]=(0,x.useState)(!1),[P,F]=(0,x.useState)(!1),[De,I]=(0,x.useState)(``),[L,R]=(0,x.useState)(``),[z,B]=(0,x.useState)(null),[V,H]=(0,x.useState)(null),[U,W]=(0,x.useState)(new Set),G=(0,x.useRef)(new Map),[,Oe]=(0,x.useState)(0);(0,x.useEffect)(()=>{i.doc.info(`Loading document library...`);let e=i.doc.time();m().then(n=>{let r=n.documents||[];t(r),i.doc.timed(`Loaded ${r.length} document(s), ${n.total_chunks||0} chunks, ${n.total_size_bytes||0} bytes total`,e)}).catch(e=>{i.doc.error(`Failed to load documents`,e),t([])})},[t]);let K=e.some(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`);(0,x.useEffect)(()=>{if(!K)return;let e=u.getState().documents;for(let t of e)(t.indexing_status===`indexing`||t.indexing_status===`pending`)&&!G.current.has(t.id)&&G.current.set(t.id,Date.now());let n=!1,r=setInterval(async()=>{if(Oe(e=>e+1),!n){n=!0;try{let e=u.getState().documents.filter(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`);for(let n of e)try{let e=await o(n.id);if(e.indexing_status!==`indexing`&&e.indexing_status!==`pending`){G.current.delete(n.id);let e=await m();t(e.documents||[]);break}}catch{}}finally{n=!1}}},2e3);return()=>clearInterval(r)},[K,t]),(0,x.useEffect)(()=>{let t=new Set(e.filter(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`).map(e=>e.id));for(let e of G.current.keys())t.has(e)||G.current.delete(e)},[e]),(0,x.useEffect)(()=>{let e=setInterval(async()=>{try{let e=(await m()).documents||[],n=u.getState().documents;(e.length!==n.length||e.some((e,t)=>{let r=n.find(t=>t.id===e.id);return!r||r.indexing_status!==e.indexing_status||r.indexed_at!==e.indexed_at||r.chunk_count!==e.chunk_count}))&&(t(e),i.doc.debug(`Document list refreshed (server-side changes detected)`))}catch{}},15e3);return()=>clearInterval(e)},[t]);let ke=e.reduce((e,t)=>e+t.file_size,0),q=e.reduce((e,t)=>e+t.chunk_count,0),J=(0,x.useCallback)(async(e,t)=>{if(!O){w([e]),j(`${t} will be attached to your next new chat.`),i.doc.info(`"${t}" will be attached to the next new chat`);return}await f(O,e);let n=u.getState().sessions.find(e=>e.id===O)?.document_ids??[];n.includes(e)||y(O,{document_ids:[...n,e]}),j(`Attached ${t} to ${k}.`),i.doc.info(`Attached "${t}" to session ${O}`)},[O,k,y,w]),Y=(0,x.useCallback)(async(e,t)=>{if(e.length===0)return;if(!O){w(e),i.doc.info(`"${t}" will be attached to the next new chat`);return}let n=[];for(let t of e)try{await f(O,t),n.push(t)}catch(e){i.doc.warn(`Could not attach document to session: ${e}`)}let r=u.getState().sessions.find(e=>e.id===O)?.document_ids??[],a=n.filter(e=>!r.includes(e));a.length>0&&y(O,{document_ids:[...r,...a]}),i.doc.info(`Attached "${t}" to session ${O}`)},[O,y,w]),X=(0,x.useCallback)(async(e,n,r)=>{let a=e.includes(`.`)?`.`+e.split(`.`).pop()?.toLowerCase():``,o=a&&!s(a)?se(a)?.message??`The file type "${a}" is not supported for indexing.`:null;if(o&&!r){i.doc.warn(`Unsupported file type: ${e} (${a})`),B({filename:e,error:o});return}i.doc.info(`Indexing document: ${e}`);let c=i.doc.time();F(!0),I(`Indexing ${e}...`),B(null),H(null),j(``);try{let r=await n();if(i.doc.timed(`Indexed "${e}": ${r?.chunk_count||`?`} chunks`,c),r?.id)try{await J(r.id,r.filename||e)}catch(t){i.doc.error(`Could not attach "${e}" to ${k}`,t),B({filename:e,error:`Indexed, but not attached to ${k}: ${t instanceof Error?t.message:t}`})}let a=await m();t(a.documents||[]),I(``)}catch(t){let{httpStatus:n,reason:a}=t??{};if(a===`is_folder`&&r){await r();return}i.doc.error(`Failed to index "${e}"`,t);let s=n===400&&o?o:t instanceof Error?t.message:`Upload failed`;B({filename:e,error:s,status:n,kind:a}),I(``)}finally{F(!1)}},[J,k,t]),Z=(0,x.useCallback)(async(e,n)=>{i.doc.info(`"${e}" is a folder; indexing its documents`),I(`Indexing the documents in ${n}...`);try{let r=await me(e,!1);await Y(r.documents.map(e=>e.id).filter(Boolean),n),H(xe(n,r));let i=await m();t(i.documents||[])}catch(t){i.doc.error(`Failed to index folder "${e}"`,t);let r=t instanceof Error?t.message:`Folder indexing failed`,{httpStatus:a}=t??{};B({filename:n,error:r,status:a})}finally{I(``)}},[Y,t]),Q=(0,x.useCallback)(async(e,t)=>{await X(t,()=>ge(e),()=>Z(e,t))},[X,Z]),$=(0,x.useCallback)(async e=>{await X(e.name,()=>le(e))},[X]),Ae=(0,x.useCallback)(async e=>{e.preventDefault(),N(!1);let t=Array.from(e.dataTransfer.files);i.doc.info(`Dropped ${t.length} file(s) into Document Library`);for(let e of t)await $(e)},[$]),je=(0,x.useCallback)(async n=>{let r=e.find(e=>e.id===n);i.doc.info(`Deleting document: ${r?.filename||n}`);try{await te(n),G.current.delete(n),T(n),t(e.filter(e=>e.id!==n)),i.doc.info(`Deleted document: ${r?.filename||n}`)}catch(e){i.doc.error(`Failed to delete document: ${r?.filename||n}`,e)}},[e,t,T]),Me=(0,x.useCallback)(async(e,t)=>{i.doc.info(`Opening folder for: ${e}`);try{await fe(e,!0)}catch(e){i.doc.error(`Failed to open folder for: ${t}`,e)}},[]),Ne=(0,x.useCallback)(async n=>{let r=e.find(e=>e.id===n);i.doc.info(`Cancelling indexing for: ${r?.filename||n}`);try{await ce(n),G.current.delete(n);let e=await m();t(e.documents||[]),i.doc.info(`Cancelled indexing for: ${r?.filename||n}`)}catch(e){i.doc.error(`Failed to cancel indexing: ${r?.filename||n}`,e)}},[e,t]),Pe=(0,x.useCallback)(async n=>{if(U.has(n))return;let r=e.find(e=>e.id===n);i.doc.info(`Reindexing document: ${r?.filename||n}`),W(e=>new Set(e).add(n));try{await ue(n),i.doc.info(`Reindex complete for: ${r?.filename||n}`)}catch(e){let t=e instanceof Error?e.message:String(e);i.doc.error(`Reindex failed for: ${r?.filename||n}`,e),B({filename:r?.filename||n,error:t})}finally{try{let e=await m();t(e.documents||[])}catch(e){i.doc.error(`Failed to refresh documents after reindex`,e)}W(e=>{let t=new Set(e);return t.delete(n),t})}},[e,t,U]),Fe=(0,x.useCallback)(async t=>{let n=e.find(e=>e.id===t)?.filename||t;j(``);try{await J(t,n)}catch(e){i.doc.error(`Failed to attach ${n} to ${k}`,e),B({filename:n,error:`Not attached to ${k}: ${e instanceof Error?e.message:e}`})}},[e,J,k]),Ie=(0,x.useCallback)(async e=>{if(e.preventDefault(),!L.trim())return;let t=L.trim();i.doc.info(`Indexing from path input: ${t}`),await Q(t,t.replace(/[\\/]+$/,``).split(/[\\/]/).pop()||`file`),R(``)},[L,Q]),Le=e=>{let t=e.indexing_status||`complete`,n=G.current.get(e.id),r=e.indexed_at?C(e.indexed_at):``,i=e.indexed_at?Ce(e.indexed_at):``;switch(t){case`indexing`:case`pending`:return(0,S.jsxs)(`div`,{className:`doc-indexing-status`,children:[(0,S.jsxs)(`div`,{className:`doc-indexing-bar`,children:[(0,S.jsx)(`div`,{className:`doc-indexing-bar-track`,children:(0,S.jsx)(`div`,{className:`doc-indexing-bar-fill`})}),(0,S.jsxs)(`span`,{className:`doc-indexing-label`,children:[(0,S.jsx)(ve,{size:12,className:`doc-spin`}),`Indexing`,n?` (${Se(n)})`:`...`]})]}),(0,S.jsxs)(`button`,{className:`btn-cancel`,onClick:t=>{t.stopPropagation(),Ne(e.id)},title:`Cancel indexing`,"aria-label":`Cancel indexing ${e.filename}`,children:[(0,S.jsx)(_,{size:14}),`Cancel`]})]});case`failed`:{let t=e.error_kind?c[e.error_kind]:void 0,n=e.last_error?be(e.last_error):null;return(0,S.jsxs)(`div`,{className:`doc-failure`,children:[(0,S.jsxs)(`div`,{className:`doc-indexing-status`,children:[(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-failed`,title:e.last_error||void 0,"aria-label":e.last_error?`Failed: ${e.last_error}`:`Indexing failed`,children:[(0,S.jsx)(p,{size:12}),` `,t?`Can't be read`:`Failed`]}),(0,S.jsxs)(`button`,{className:t?`btn-retry btn-retry-quiet`:`btn-retry`,onClick:t=>{t.stopPropagation(),Pe(e.id)},title:t?`Retry indexing (fix the file first, or this fails again)`:`Retry indexing`,"aria-label":`Retry indexing ${e.filename}`,disabled:U.has(e.id),children:[(0,S.jsx)(ye,{size:t?12:14}),U.has(e.id)?`Retrying…`:`Retry`]})]}),t&&(0,S.jsx)(`p`,{className:`doc-failure-hint`,children:t}),n&&(n.more?(0,S.jsxs)(`details`,{className:`doc-failure-reason`,children:[(0,S.jsx)(`summary`,{children:n.summary}),(0,S.jsx)(`p`,{children:n.more})]}):(0,S.jsx)(`p`,{className:`doc-failure-reason`,children:n.summary})),!n&&!t&&(0,S.jsx)(`p`,{className:`doc-failure-reason`,children:`GAIA didn't record why. Retry to see the error.`})]})}case`cancelled`:return(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-cancelled`,children:[(0,S.jsx)(_,{size:12}),` Cancelled`]});case`missing`:return(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-missing`,children:[(0,S.jsx)(p,{size:12}),` File missing`]});default:return(0,S.jsxs)(`span`,{className:`doc-meta`,children:[h(e.file_size),` · `,e.chunk_count,` chunk`,e.chunk_count===1?``:`s`,r&&(0,S.jsxs)(`span`,{className:`doc-timestamp`,title:`Indexed: ${i}`,children:[(0,S.jsx)(de,{size:10}),r]})]})}};return(0,S.jsx)(`div`,{ref:M,className:`modal-overlay`,onClick:()=>n(!1),role:`dialog`,"aria-modal":`true`,"aria-label":`Document library`,children:(0,S.jsxs)(`div`,{className:`modal-panel doc-modal`,onClick:e=>e.stopPropagation(),children:[(0,S.jsxs)(`div`,{className:`modal-header`,children:[(0,S.jsx)(`h3`,{children:`Document library`}),(0,S.jsx)(`button`,{className:`btn-icon`,onClick:()=>n(!1),"aria-label":`Close document library`,children:(0,S.jsx)(l,{size:18})})]}),(0,S.jsxs)(`div`,{className:`modal-body`,children:[(0,S.jsxs)(`div`,{className:`doc-target`,children:[g?(0,S.jsxs)(`label`,{className:`doc-target-choice`,children:[`Add documents to`,(0,S.jsxs)(`select`,{value:D,onChange:e=>{we(e.target.value),j(``)},children:[(0,S.jsxs)(`option`,{value:`chat`,children:[`This chat: `,k]}),(0,S.jsx)(`option`,{value:`next`,children:`Your next new chat`})]})]}):(0,S.jsx)(`span`,{children:`Documents you add here are attached to your next new chat.`}),(0,S.jsx)(`span`,{className:`doc-target-hint`,children:`A chat searches only the documents attached to it.`})]}),(0,S.jsx)(`div`,{className:`drop-zone ${Ee?`drag-over`:``} ${P?`uploading`:``}`,onDragOver:e=>{e.preventDefault(),N(!0)},onDragLeave:()=>N(!1),onDrop:Ae,children:P?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`upload-spinner`}),(0,S.jsx)(`p`,{children:De})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(re,{size:32,strokeWidth:1.5}),(0,S.jsx)(`p`,{children:`Drop files here to index`}),(0,S.jsx)(`span`,{className:`drop-hint`,children:`PDF, TXT, MD, code files, and 50+ formats`})]})}),(0,S.jsxs)(`form`,{className:`path-input-form`,onSubmit:Ie,children:[(0,S.jsx)(d,{size:16,className:`path-icon`}),(0,S.jsx)(`input`,{type:`text`,className:`path-input`,value:L,onChange:e=>R(e.target.value),placeholder:`Or enter a file or folder path: ${he()}`,"aria-label":`File path to index`}),(0,S.jsx)(`button`,{type:`submit`,className:`btn-secondary`,disabled:!L.trim()||P,children:`Index`}),(0,S.jsxs)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>{n(!1),a(!0)},title:`Browse files on this computer`,children:[(0,S.jsx)(ae,{size:14}),`Browse files`]})]}),A&&(0,S.jsx)(`p`,{className:`doc-target-notice`,role:`status`,children:A}),z&&(0,S.jsx)(ie,{filename:z.filename,error:z.error,status:z.status,kind:z.kind,onDismiss:()=>B(null)}),V&&(0,S.jsxs)(`div`,{className:`doc-folder-notice`,role:`status`,children:[(0,S.jsx)(pe,{size:14}),(0,S.jsx)(`span`,{children:V}),(0,S.jsx)(`button`,{className:`btn-icon-sm`,onClick:()=>H(null),"aria-label":`Dismiss folder indexing result`,children:(0,S.jsx)(l,{size:12})})]}),e.length>0&&(0,S.jsxs)(`div`,{className:`doc-stats`,children:[(0,S.jsxs)(`span`,{children:[e.length,` document`,e.length===1?``:`s`]}),(0,S.jsx)(`span`,{children:`·`}),(0,S.jsxs)(`span`,{children:[q,` chunk`,q===1?``:`s`]}),(0,S.jsx)(`span`,{children:`·`}),(0,S.jsx)(`span`,{children:h(ke)})]}),(0,S.jsxs)(`div`,{className:`doc-list`,children:[e.length===0&&!P&&(0,S.jsxs)(`div`,{className:`empty-docs`,children:[(0,S.jsx)(ne,{size:32,strokeWidth:1}),(0,S.jsx)(`p`,{children:`No documents indexed yet`}),(0,S.jsx)(`span`,{children:`Drop files above or enter a file path`})]}),e.map(e=>(0,S.jsxs)(`div`,{className:`doc-row ${e.indexing_status===`indexing`?`doc-row-indexing`:``}`,children:[(0,S.jsxs)(`div`,{className:`doc-info`,children:[(0,S.jsx)(`span`,{className:`doc-name`,children:e.filename}),Le(e)]}),(0,S.jsxs)(`div`,{className:`doc-row-actions`,children:[e.filepath&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-open-folder`,onClick:()=>Me(e.filepath,e.filename),title:`Open folder: ${e.filepath}`,"aria-label":`Open containing folder for ${e.filename}`,children:(0,S.jsx)(d,{size:14})}),e.indexing_status===`complete`&&!(O?E?.document_ids?.includes(e.id):b.includes(e.id))&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-attach`,onClick:()=>Fe(e.id),title:O?`Use in ${k}`:`Use in your next chat`,"aria-label":O?`Attach ${e.filename} to ${k}`:`Attach ${e.filename} to your next chat`,children:(0,S.jsx)(_e,{size:14})}),e.indexing_status!==`indexing`&&e.indexing_status!==`pending`&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-delete`,onClick:()=>je(e.id),title:`Remove`,"aria-label":`Remove ${e.filename}`,children:(0,S.jsx)(oe,{size:14})})]})]},e.id))]})]})]})})}export{w as DocumentLibrary};
4
+ `)[0]}`:``;r.push(`${t.failed} file${t.failed===1?``:`s`} couldn't be indexed.${e}`)}return r.push(`Subfolders aren't included.`),r.join(` `)}function Se(e){let t=Math.floor((Date.now()-e)/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}function C(e){try{let t=new Date(e);if(isNaN(t.getTime()))return``;let n=new Date().getTime()-t.getTime(),r=Math.floor(n/1e3),i=Math.floor(r/60),a=Math.floor(i/60),o=Math.floor(a/24);return r<60?`just now`:i<60?`${i}m ago`:a<24?`${a}h ago`:o===1?`yesterday`:o<7?`${o}d ago`:t.toLocaleDateString(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}catch{return``}}function Ce(e){try{let t=new Date(e);return isNaN(t.getTime())?``:t.toLocaleString(void 0,{year:`numeric`,month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`})}catch{return``}}function w(){let{documents:e,setDocuments:t,setShowDocLibrary:n,setShowFileBrowser:a,currentSessionId:g,sessions:v,updateSessionInList:y,draftDocumentIds:b,addDraftDocuments:w,removeDraftDocument:T}=u(),E=v.find(e=>e.id===g)??null,[D,we]=(0,x.useState)(g?`chat`:`next`),O=D===`chat`?g:null,k=`“${E?.title||`Untitled chat`}”`,[A,j]=(0,x.useState)(``),Te=(0,x.useCallback)(()=>n(!1),[n]);r(!0,Te);let M=(0,x.useRef)(null);ee(M,!0);let[Ee,N]=(0,x.useState)(!1),[P,F]=(0,x.useState)(!1),[De,I]=(0,x.useState)(``),[L,R]=(0,x.useState)(``),[z,B]=(0,x.useState)(null),[V,H]=(0,x.useState)(null),[U,W]=(0,x.useState)(new Set),G=(0,x.useRef)(new Map),[,Oe]=(0,x.useState)(0);(0,x.useEffect)(()=>{i.doc.info(`Loading document library...`);let e=i.doc.time();m().then(n=>{let r=n.documents||[];t(r),i.doc.timed(`Loaded ${r.length} document(s), ${n.total_chunks||0} chunks, ${n.total_size_bytes||0} bytes total`,e)}).catch(e=>{i.doc.error(`Failed to load documents`,e),t([])})},[t]);let K=e.some(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`);(0,x.useEffect)(()=>{if(!K)return;let e=u.getState().documents;for(let t of e)(t.indexing_status===`indexing`||t.indexing_status===`pending`)&&!G.current.has(t.id)&&G.current.set(t.id,Date.now());let n=!1,r=setInterval(async()=>{if(Oe(e=>e+1),!n){n=!0;try{let e=u.getState().documents.filter(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`);for(let n of e)try{let e=await o(n.id);if(e.indexing_status!==`indexing`&&e.indexing_status!==`pending`){G.current.delete(n.id);let e=await m();t(e.documents||[]);break}}catch{}}finally{n=!1}}},2e3);return()=>clearInterval(r)},[K,t]),(0,x.useEffect)(()=>{let t=new Set(e.filter(e=>e.indexing_status===`indexing`||e.indexing_status===`pending`).map(e=>e.id));for(let e of G.current.keys())t.has(e)||G.current.delete(e)},[e]),(0,x.useEffect)(()=>{let e=setInterval(async()=>{try{let e=(await m()).documents||[],n=u.getState().documents;(e.length!==n.length||e.some((e,t)=>{let r=n.find(t=>t.id===e.id);return!r||r.indexing_status!==e.indexing_status||r.indexed_at!==e.indexed_at||r.chunk_count!==e.chunk_count}))&&(t(e),i.doc.debug(`Document list refreshed (server-side changes detected)`))}catch{}},15e3);return()=>clearInterval(e)},[t]);let ke=e.reduce((e,t)=>e+t.file_size,0),q=e.reduce((e,t)=>e+t.chunk_count,0),J=(0,x.useCallback)(async(e,t)=>{if(!O){w([e]),j(`${t} will be attached to your next new chat.`),i.doc.info(`"${t}" will be attached to the next new chat`);return}await f(O,e);let n=u.getState().sessions.find(e=>e.id===O)?.document_ids??[];n.includes(e)||y(O,{document_ids:[...n,e]}),j(`Attached ${t} to ${k}.`),i.doc.info(`Attached "${t}" to session ${O}`)},[O,k,y,w]),Y=(0,x.useCallback)(async(e,t)=>{if(e.length===0)return;if(!O){w(e),i.doc.info(`"${t}" will be attached to the next new chat`);return}let n=[];for(let t of e)try{await f(O,t),n.push(t)}catch(e){i.doc.warn(`Could not attach document to session: ${e}`)}let r=u.getState().sessions.find(e=>e.id===O)?.document_ids??[],a=n.filter(e=>!r.includes(e));a.length>0&&y(O,{document_ids:[...r,...a]}),i.doc.info(`Attached "${t}" to session ${O}`)},[O,y,w]),X=(0,x.useCallback)(async(e,n,r)=>{let a=e.includes(`.`)?`.`+e.split(`.`).pop()?.toLowerCase():``,o=a&&!s(a)?se(a)?.message??`The file type "${a}" is not supported for indexing.`:null;if(o&&!r){i.doc.warn(`Unsupported file type: ${e} (${a})`),B({filename:e,error:o});return}i.doc.info(`Indexing document: ${e}`);let c=i.doc.time();F(!0),I(`Indexing ${e}...`),B(null),H(null),j(``);try{let r=await n();if(i.doc.timed(`Indexed "${e}": ${r?.chunk_count||`?`} chunks`,c),r?.id)try{await J(r.id,r.filename||e)}catch(t){i.doc.error(`Could not attach "${e}" to ${k}`,t),B({filename:e,error:`Indexed, but not attached to ${k}: ${t instanceof Error?t.message:t}`})}let a=await m();t(a.documents||[]),I(``)}catch(t){let{httpStatus:n,reason:a}=t??{};if(a===`is_folder`&&r){await r();return}i.doc.error(`Failed to index "${e}"`,t);let s=n===400&&o?o:t instanceof Error?t.message:`Upload failed`;B({filename:e,error:s,status:n,kind:a}),I(``)}finally{F(!1)}},[J,k,t]),Z=(0,x.useCallback)(async(e,n)=>{i.doc.info(`"${e}" is a folder; indexing its documents`),I(`Indexing the documents in ${n}...`);try{let r=await pe(e,!1);await Y(r.documents.map(e=>e.id).filter(Boolean),n),H(xe(n,r));let i=await m();t(i.documents||[])}catch(t){i.doc.error(`Failed to index folder "${e}"`,t);let r=t instanceof Error?t.message:`Folder indexing failed`,{httpStatus:a}=t??{};B({filename:n,error:r,status:a})}finally{I(``)}},[Y,t]),Q=(0,x.useCallback)(async(e,t)=>{await X(t,()=>ge(e),()=>Z(e,t))},[X,Z]),$=(0,x.useCallback)(async e=>{await X(e.name,()=>le(e))},[X]),Ae=(0,x.useCallback)(async e=>{e.preventDefault(),N(!1);let t=Array.from(e.dataTransfer.files);i.doc.info(`Dropped ${t.length} file(s) into Document Library`);for(let e of t)await $(e)},[$]),je=(0,x.useCallback)(async n=>{let r=e.find(e=>e.id===n);i.doc.info(`Deleting document: ${r?.filename||n}`);try{await te(n),G.current.delete(n),T(n),t(e.filter(e=>e.id!==n)),i.doc.info(`Deleted document: ${r?.filename||n}`)}catch(e){i.doc.error(`Failed to delete document: ${r?.filename||n}`,e)}},[e,t,T]),Me=(0,x.useCallback)(async(e,t)=>{i.doc.info(`Opening folder for: ${e}`);try{await fe(e,!0)}catch(e){i.doc.error(`Failed to open folder for: ${t}`,e)}},[]),Ne=(0,x.useCallback)(async n=>{let r=e.find(e=>e.id===n);i.doc.info(`Cancelling indexing for: ${r?.filename||n}`);try{await ce(n),G.current.delete(n);let e=await m();t(e.documents||[]),i.doc.info(`Cancelled indexing for: ${r?.filename||n}`)}catch(e){i.doc.error(`Failed to cancel indexing: ${r?.filename||n}`,e)}},[e,t]),Pe=(0,x.useCallback)(async n=>{if(U.has(n))return;let r=e.find(e=>e.id===n);i.doc.info(`Reindexing document: ${r?.filename||n}`),W(e=>new Set(e).add(n));try{await ue(n),i.doc.info(`Reindex complete for: ${r?.filename||n}`)}catch(e){let t=e instanceof Error?e.message:String(e);i.doc.error(`Reindex failed for: ${r?.filename||n}`,e),B({filename:r?.filename||n,error:t})}finally{try{let e=await m();t(e.documents||[])}catch(e){i.doc.error(`Failed to refresh documents after reindex`,e)}W(e=>{let t=new Set(e);return t.delete(n),t})}},[e,t,U]),Fe=(0,x.useCallback)(async t=>{let n=e.find(e=>e.id===t)?.filename||t;j(``);try{await J(t,n)}catch(e){i.doc.error(`Failed to attach ${n} to ${k}`,e),B({filename:n,error:`Not attached to ${k}: ${e instanceof Error?e.message:e}`})}},[e,J,k]),Ie=(0,x.useCallback)(async e=>{if(e.preventDefault(),!L.trim())return;let t=L.trim();i.doc.info(`Indexing from path input: ${t}`),await Q(t,t.replace(/[\\/]+$/,``).split(/[\\/]/).pop()||`file`),R(``)},[L,Q]),Le=e=>{let t=e.indexing_status||`complete`,n=G.current.get(e.id),r=e.indexed_at?C(e.indexed_at):``,i=e.indexed_at?Ce(e.indexed_at):``;switch(t){case`indexing`:case`pending`:return(0,S.jsxs)(`div`,{className:`doc-indexing-status`,children:[(0,S.jsxs)(`div`,{className:`doc-indexing-bar`,children:[(0,S.jsx)(`div`,{className:`doc-indexing-bar-track`,children:(0,S.jsx)(`div`,{className:`doc-indexing-bar-fill`})}),(0,S.jsxs)(`span`,{className:`doc-indexing-label`,children:[(0,S.jsx)(ve,{size:12,className:`doc-spin`}),`Indexing`,n?` (${Se(n)})`:`...`]})]}),(0,S.jsxs)(`button`,{className:`btn-cancel`,onClick:t=>{t.stopPropagation(),Ne(e.id)},title:`Cancel indexing`,"aria-label":`Cancel indexing ${e.filename}`,children:[(0,S.jsx)(_,{size:14}),`Cancel`]})]});case`failed`:{let t=e.error_kind?c[e.error_kind]:void 0,n=e.last_error?be(e.last_error):null;return(0,S.jsxs)(`div`,{className:`doc-failure`,children:[(0,S.jsxs)(`div`,{className:`doc-indexing-status`,children:[(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-failed`,title:e.last_error||void 0,"aria-label":e.last_error?`Failed: ${e.last_error}`:`Indexing failed`,children:[(0,S.jsx)(p,{size:12}),` `,t?`Can't be read`:`Failed`]}),(0,S.jsxs)(`button`,{className:t?`btn-retry btn-retry-quiet`:`btn-retry`,onClick:t=>{t.stopPropagation(),Pe(e.id)},title:t?`Retry indexing (fix the file first, or this fails again)`:`Retry indexing`,"aria-label":`Retry indexing ${e.filename}`,disabled:U.has(e.id),children:[(0,S.jsx)(ye,{size:t?12:14}),U.has(e.id)?`Retrying…`:`Retry`]})]}),t&&(0,S.jsx)(`p`,{className:`doc-failure-hint`,children:t}),n&&(n.more?(0,S.jsxs)(`details`,{className:`doc-failure-reason`,children:[(0,S.jsx)(`summary`,{children:n.summary}),(0,S.jsx)(`p`,{children:n.more})]}):(0,S.jsx)(`p`,{className:`doc-failure-reason`,children:n.summary})),!n&&!t&&(0,S.jsx)(`p`,{className:`doc-failure-reason`,children:`GAIA didn't record why. Retry to see the error.`})]})}case`cancelled`:return(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-cancelled`,children:[(0,S.jsx)(_,{size:12}),` Cancelled`]});case`missing`:return(0,S.jsxs)(`span`,{className:`doc-status-badge doc-status-missing`,children:[(0,S.jsx)(p,{size:12}),` File missing`]});default:return(0,S.jsxs)(`span`,{className:`doc-meta`,children:[h(e.file_size),` · `,e.chunk_count,` chunk`,e.chunk_count===1?``:`s`,r&&(0,S.jsxs)(`span`,{className:`doc-timestamp`,title:`Indexed: ${i}`,children:[(0,S.jsx)(de,{size:10}),r]})]})}};return(0,S.jsx)(`div`,{ref:M,className:`modal-overlay`,onClick:()=>n(!1),role:`dialog`,"aria-modal":`true`,"aria-label":`Document library`,children:(0,S.jsxs)(`div`,{className:`modal-panel doc-modal`,onClick:e=>e.stopPropagation(),children:[(0,S.jsxs)(`div`,{className:`modal-header`,children:[(0,S.jsx)(`h3`,{children:`Document library`}),(0,S.jsx)(`button`,{className:`btn-icon`,onClick:()=>n(!1),"aria-label":`Close document library`,children:(0,S.jsx)(l,{size:18})})]}),(0,S.jsxs)(`div`,{className:`modal-body`,children:[(0,S.jsxs)(`div`,{className:`doc-target`,children:[g?(0,S.jsxs)(`label`,{className:`doc-target-choice`,children:[`Add documents to`,(0,S.jsxs)(`select`,{value:D,onChange:e=>{we(e.target.value),j(``)},children:[(0,S.jsxs)(`option`,{value:`chat`,children:[`This chat: `,k]}),(0,S.jsx)(`option`,{value:`next`,children:`Your next new chat`})]})]}):(0,S.jsx)(`span`,{children:`Documents you add here are attached to your next new chat.`}),(0,S.jsx)(`span`,{className:`doc-target-hint`,children:`A chat searches only the documents attached to it.`})]}),(0,S.jsx)(`div`,{className:`drop-zone ${Ee?`drag-over`:``} ${P?`uploading`:``}`,onDragOver:e=>{e.preventDefault(),N(!0)},onDragLeave:()=>N(!1),onDrop:Ae,children:P?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`upload-spinner`}),(0,S.jsx)(`p`,{children:De})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(re,{size:32,strokeWidth:1.5}),(0,S.jsx)(`p`,{children:`Drop files here to index`}),(0,S.jsx)(`span`,{className:`drop-hint`,children:`PDF, TXT, MD, code files, and 50+ formats`})]})}),(0,S.jsxs)(`form`,{className:`path-input-form`,onSubmit:Ie,children:[(0,S.jsx)(d,{size:16,className:`path-icon`}),(0,S.jsx)(`input`,{type:`text`,className:`path-input`,value:L,onChange:e=>R(e.target.value),placeholder:`Or enter a file or folder path: ${me()}`,"aria-label":`File path to index`}),(0,S.jsx)(`button`,{type:`submit`,className:`btn-secondary`,disabled:!L.trim()||P,children:`Index`}),(0,S.jsxs)(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>{n(!1),a(!0)},title:`Browse files on this computer`,children:[(0,S.jsx)(ae,{size:14}),`Browse files`]})]}),A&&(0,S.jsx)(`p`,{className:`doc-target-notice`,role:`status`,children:A}),z&&(0,S.jsx)(ie,{filename:z.filename,error:z.error,status:z.status,kind:z.kind,onDismiss:()=>B(null)}),V&&(0,S.jsxs)(`div`,{className:`doc-folder-notice`,role:`status`,children:[(0,S.jsx)(he,{size:14}),(0,S.jsx)(`span`,{children:V}),(0,S.jsx)(`button`,{className:`btn-icon-sm`,onClick:()=>H(null),"aria-label":`Dismiss folder indexing result`,children:(0,S.jsx)(l,{size:12})})]}),e.length>0&&(0,S.jsxs)(`div`,{className:`doc-stats`,children:[(0,S.jsxs)(`span`,{children:[e.length,` document`,e.length===1?``:`s`]}),(0,S.jsx)(`span`,{children:`·`}),(0,S.jsxs)(`span`,{children:[q,` chunk`,q===1?``:`s`]}),(0,S.jsx)(`span`,{children:`·`}),(0,S.jsx)(`span`,{children:h(ke)})]}),(0,S.jsxs)(`div`,{className:`doc-list`,children:[e.length===0&&!P&&(0,S.jsxs)(`div`,{className:`empty-docs`,children:[(0,S.jsx)(ne,{size:32,strokeWidth:1}),(0,S.jsx)(`p`,{children:`No documents indexed yet`}),(0,S.jsx)(`span`,{children:`Drop files above or enter a file path`})]}),e.map(e=>(0,S.jsxs)(`div`,{className:`doc-row ${e.indexing_status===`indexing`?`doc-row-indexing`:``}`,children:[(0,S.jsxs)(`div`,{className:`doc-info`,children:[(0,S.jsx)(`span`,{className:`doc-name`,children:e.filename}),Le(e)]}),(0,S.jsxs)(`div`,{className:`doc-row-actions`,children:[e.filepath&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-open-folder`,onClick:()=>Me(e.filepath,e.filename),title:`Open folder: ${e.filepath}`,"aria-label":`Open containing folder for ${e.filename}`,children:(0,S.jsx)(d,{size:14})}),e.indexing_status===`complete`&&!(O?E?.document_ids?.includes(e.id):b.includes(e.id))&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-attach`,onClick:()=>Fe(e.id),title:O?`Use in ${k}`:`Use in your next chat`,"aria-label":O?`Attach ${e.filename} to ${k}`:`Attach ${e.filename} to your next chat`,children:(0,S.jsx)(_e,{size:14})}),e.indexing_status!==`indexing`&&e.indexing_status!==`pending`&&(0,S.jsx)(`button`,{className:`btn-icon-sm doc-delete`,onClick:()=>je(e.id),title:`Remove`,"aria-label":`Remove ${e.filename}`,children:(0,S.jsx)(oe,{size:14})})]})]},e.id))]})]})]})})}export{w as DocumentLibrary};
@@ -1,4 +1,4 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,u as a}from"./apiBase-BmPG2Rib.js";import{t as o}from"./eye-CwjwlxR5.js";import{G as s,It as c,K as l,Kt as u,Pt as d,Qt as f,Rt as p,U as ee,Ut as te,W as m,X as ne,Xt as re,Y as h,Yt as g,Zt as _,dt as ie,en as v,mn as ae,ot as y,pn as oe,pt as se,st as b,t as ce,un as le,vt as x}from"./index-D-noqAc3.js";var S={name:`code`,size:24,node:[[`path`,{d:`m16 18 6-6-6-6`,key:`eg8j8`}],[`path`,{d:`m8 6-6 6 6 6`,key:`ppft3o`}]]};S.node;var C=t(S),w={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};w.node;var ue=t(w),T={name:`house`,size:24,node:[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]],aliases:[`home`]};T.node;var E=t(T),D={name:`table`,size:24,node:[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M3 15h18`,key:`5xshup`}]]};D.node;var O=t(D),k=e(a(),1),A=n();function de(e){if(e.type===`folder`)return(0,A.jsx)(g,{size:16});let t=(e.extension||``).toLowerCase();return[`.csv`,`.xlsx`,`.xls`,`.tsv`].includes(t)?(0,A.jsx)(O,{size:16}):[`.py`,`.js`,`.ts`,`.java`,`.c`,`.cpp`,`.go`,`.rs`].includes(t)?(0,A.jsx)(C,{size:16}):[`.pdf`,`.doc`,`.docx`,`.txt`,`.md`].includes(t)?(0,A.jsx)(f,{size:16}):(0,A.jsx)(_,{size:16})}function fe(e){if(!e)return``;let t=new Date(e),n=new Date,r=n.getTime()-t.getTime(),i=Math.floor(r/36e5);if(i<1)return`Just now`;if(i<24)return`${i}h ago`;let a=Math.floor(i/24);return a<7?`${a}d ago`:t.toLocaleDateString(void 0,{month:`short`,day:`numeric`,year:t.getFullYear()===n.getFullYear()?void 0:`numeric`})}function pe(e){if(e.length===0)return``;let[t,...n]=e;return n.length>0?`${t} (+${n.length} more)`:t}function me(e){switch(e){case`home`:return(0,A.jsx)(E,{size:14});case`desktop`:return(0,A.jsx)(u,{size:14});case`documents`:return(0,A.jsx)(f,{size:14});case`download`:return(0,A.jsx)(v,{size:14});default:return(0,A.jsx)(g,{size:14})}}var he=[{label:`All Files`,value:``},{label:`Documents`,value:`pdf,doc,docx,txt,md`},{label:`Spreadsheets`,value:`csv,xlsx,xls,tsv`},{label:`Code`,value:`py,js,ts,java,c,cpp,go,rs,rb,sh`},{label:`Data`,value:`json,xml,yaml,yml,csv,tsv`}];async function j(e,t,n,r){let a=[],o=[];for(let t of e){let e=t.includes(`.`)?`.`+t.split(`.`).pop()?.toLowerCase():``;e&&!s(e)?o.push(t):a.push(t)}let c=[],l=[],u=0,f=``,p=new Set(t.filter(e=>e.type===`folder`).map(e=>e.path));for(let e of a)try{if(p.has(e)){let t=await y(e),n=[];t.documents.forEach(e=>{e.id&&n.push(e.id)}),n.length>0&&(n.forEach(e=>c.push(e)),l.push(e))}else{let t=await x(e);t?.id&&(c.push(t.id),l.push(e))}}catch(e){u++,f=e instanceof Error?e.message:`Unknown error`}if(n&&c.length>0){let e=[];for(let t of c)try{await h(n,t),e.push(t)}catch(e){i.doc.warn(`Could not attach document to session: ${e}`)}let t=d.getState().sessions.find(e=>e.id===n)?.document_ids??[],a=e.filter(e=>!t.includes(e));a.length>0&&r(n,{document_ids:[...t,...a]})}else c.length>0&&d.getState().addDraftDocuments(c);if(c.length>0)try{let e=await b();d.getState().setDocuments(e.documents||[])}catch(e){i.doc.error(`Could not refresh the document list after indexing`,e)}return{docIds:c,supported:a,succeededFiles:l,unsupported:o,failed:u,lastError:f}}function M(){let{setShowFileBrowser:e,currentSessionId:t,updateSessionInList:n,setPendingPrompt:a}=d(),u=(0,k.useCallback)(()=>e(!1),[e]);r(!0,u);let f=(0,k.useRef)(null);l(f,!0);let[h,g]=(0,k.useState)(``),[_,v]=(0,k.useState)(null),[y,b]=(0,k.useState)([]),[x,S]=(0,k.useState)([]),[C,w]=(0,k.useState)(!1),[T,E]=(0,k.useState)(null),[D,O]=(0,k.useState)(``),[M,N]=(0,k.useState)(null),[P,F]=(0,k.useState)([]),[ge,_e]=(0,k.useState)(!1),[I,L]=(0,k.useState)(!1),[R,ve]=(0,k.useState)(``),[z,B]=(0,k.useState)(new Set),[V,H]=(0,k.useState)(null),[ye,U]=(0,k.useState)(!1),[W,G]=(0,k.useState)(new Set),[K,q]=(0,k.useState)(null),J=(0,k.useRef)(null),[Y,X]=(0,k.useState)(null),Z=(0,k.useCallback)(async e=>{w(!0),E(null),N(null),O(``),F([]);try{let t=await ne(e);g(t.current_path),v(t.parent_path),b(t.entries),t.quick_links.length>0&&S(t.quick_links),i.ui.info(`Browsing: ${t.current_path} (${t.entries.length} items)`)}catch(e){let t=e instanceof Error?e.message:`Failed to load directory`;E(t),i.ui.error(`Browse failed`,e)}finally{w(!1)}},[]);(0,k.useEffect)(()=>{Z()},[Z]),(0,k.useEffect)(()=>()=>{J.current&&clearTimeout(J.current)},[]);let be=(0,k.useCallback)(async()=>{if(!D.trim())N(null),F([]);else{L(!0),E(null);try{let e=await se(D.trim(),R||void 0,30);N(e.results),F(e.searched_locations??[]),_e(e.truncated===!0),i.ui.info(`Search "${D}": ${e.total} results`)}catch(e){let t=e instanceof Error?e.message:`Search failed`;E(t),i.ui.error(`Search failed`,e)}finally{L(!1)}}},[D,R]),xe=e=>{e.key===`Enter`&&be()},Q=(0,k.useCallback)(e=>{e.type===`folder`&&(Z(e.path),B(new Set),H(null))},[Z]),Se=(0,k.useCallback)(async e=>{U(!0);try{let t=await ie(e);H(t)}catch(e){i.ui.error(`Preview failed`,e)}finally{U(!1)}},[]),Ce=(0,k.useCallback)(e=>{B(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),we=(0,k.useCallback)(async()=>{if(z.size===0)return;let e=Array.from(z);if(X(null),!e.some(e=>{let t=e.includes(`.`)?`.`+e.split(`.`).pop()?.toLowerCase():``;return!t||s(t)})){let t=e[0],n=t.lastIndexOf(`.`),r=n>0?t.slice(n).toLowerCase():``,i=m(r);X({filename:e.length===1?t.split(/[\\/]/).pop()||t:`${e.length} files`,error:i?i.message:`File type "${r}" is not supported for indexing.`})}else{G(new Set(e)),q(`Indexing ${e.length} file(s)...`);try{let r=await j(e,y,t,n);if(r.failed>0)q(`Done: ${r.docIds.length} indexed, ${r.failed} failed`),X({filename:`${r.failed} file(s)`,error:r.lastError||`Indexing failed for some files`});else{let e=r.unsupported.length>0?` (${r.unsupported.length} skipped — unsupported type)`:``;q(`Successfully indexed ${r.docIds.length} file(s)${e}`)}J.current&&clearTimeout(J.current),J.current=setTimeout(()=>q(null),5e3),B(new Set)}catch(t){i.doc.error(`Index selected failed`,t),X({filename:e.length===1?e[0].split(/[\\/]/).pop()||e[0]:`${e.length} files`,error:t instanceof Error?t.message:`An unexpected error occurred.`})}finally{G(new Set)}}},[z,t,n,y]),Te=(0,k.useCallback)(async()=>{if(z.size===0)return;let r=Array.from(z);X(null),G(new Set(r)),q(`Indexing ${r.length} file(s) for analysis...`);try{let i=await j(r,y,t,n);if(i.supported.length===0){let e=r[0].lastIndexOf(`.`),t=e>0?r[0].slice(e).toLowerCase():``,n=m(t);X({filename:r.length===1?r[0].split(/[\\/]/).pop()||r[0]:`${r.length} files`,error:n?.message??`File type "${t}" is not supported for indexing.`});return}if(i.docIds.length===0){X({filename:i.supported.length===1?i.supported[0].split(/[\\/]/).pop()||i.supported[0]:`${i.supported.length} files`,error:`Failed to index selected file(s). Please try again.`});return}i.failed>0&&q(`Warning: ${i.failed} file(s) failed to index and will be excluded.`);let o=(i.succeededFiles.length>0?i.succeededFiles:i.supported).map(e=>e.split(/[\\/]/).pop()||e),s=o.length===1?`Please analyze this document for me: ${o[0]}`:`Please analyze these documents for me:\n${o.map(e=>`- ${e}`).join(`
1
+ import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{l as t,n,o as r,s as i,u as a}from"./apiBase-BmPG2Rib.js";import{t as o}from"./eye-CwjwlxR5.js";import{G as s,It as c,K as l,Kt as u,Pt as d,Qt as f,Rt as p,U as ee,Ut as te,W as m,X as ne,Xt as re,Y as h,Yt as g,Zt as _,dt as ie,en as v,mn as ae,ot as y,pn as oe,pt as se,st as b,t as ce,un as le,vt as x}from"./index-CfiDLYYM.js";var S={name:`code`,size:24,node:[[`path`,{d:`m16 18 6-6-6-6`,key:`eg8j8`}],[`path`,{d:`m8 6-6 6 6 6`,key:`ppft3o`}]]};S.node;var C=t(S),w={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};w.node;var ue=t(w),T={name:`house`,size:24,node:[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]],aliases:[`home`]};T.node;var E=t(T),D={name:`table`,size:24,node:[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`M3 15h18`,key:`5xshup`}]]};D.node;var O=t(D),k=e(a(),1),A=n();function de(e){if(e.type===`folder`)return(0,A.jsx)(g,{size:16});let t=(e.extension||``).toLowerCase();return[`.csv`,`.xlsx`,`.xls`,`.tsv`].includes(t)?(0,A.jsx)(O,{size:16}):[`.py`,`.js`,`.ts`,`.java`,`.c`,`.cpp`,`.go`,`.rs`].includes(t)?(0,A.jsx)(C,{size:16}):[`.pdf`,`.doc`,`.docx`,`.txt`,`.md`].includes(t)?(0,A.jsx)(f,{size:16}):(0,A.jsx)(_,{size:16})}function fe(e){if(!e)return``;let t=new Date(e),n=new Date,r=n.getTime()-t.getTime(),i=Math.floor(r/36e5);if(i<1)return`Just now`;if(i<24)return`${i}h ago`;let a=Math.floor(i/24);return a<7?`${a}d ago`:t.toLocaleDateString(void 0,{month:`short`,day:`numeric`,year:t.getFullYear()===n.getFullYear()?void 0:`numeric`})}function pe(e){if(e.length===0)return``;let[t,...n]=e;return n.length>0?`${t} (+${n.length} more)`:t}function me(e){switch(e){case`home`:return(0,A.jsx)(E,{size:14});case`desktop`:return(0,A.jsx)(u,{size:14});case`documents`:return(0,A.jsx)(f,{size:14});case`download`:return(0,A.jsx)(v,{size:14});default:return(0,A.jsx)(g,{size:14})}}var he=[{label:`All Files`,value:``},{label:`Documents`,value:`pdf,doc,docx,txt,md`},{label:`Spreadsheets`,value:`csv,xlsx,xls,tsv`},{label:`Code`,value:`py,js,ts,java,c,cpp,go,rs,rb,sh`},{label:`Data`,value:`json,xml,yaml,yml,csv,tsv`}];async function j(e,t,n,r){let a=[],o=[];for(let t of e){let e=t.includes(`.`)?`.`+t.split(`.`).pop()?.toLowerCase():``;e&&!s(e)?o.push(t):a.push(t)}let c=[],l=[],u=0,f=``,p=new Set(t.filter(e=>e.type===`folder`).map(e=>e.path));for(let e of a)try{if(p.has(e)){let t=await y(e),n=[];t.documents.forEach(e=>{e.id&&n.push(e.id)}),n.length>0&&(n.forEach(e=>c.push(e)),l.push(e))}else{let t=await x(e);t?.id&&(c.push(t.id),l.push(e))}}catch(e){u++,f=e instanceof Error?e.message:`Unknown error`}if(n&&c.length>0){let e=[];for(let t of c)try{await h(n,t),e.push(t)}catch(e){i.doc.warn(`Could not attach document to session: ${e}`)}let t=d.getState().sessions.find(e=>e.id===n)?.document_ids??[],a=e.filter(e=>!t.includes(e));a.length>0&&r(n,{document_ids:[...t,...a]})}else c.length>0&&d.getState().addDraftDocuments(c);if(c.length>0)try{let e=await b();d.getState().setDocuments(e.documents||[])}catch(e){i.doc.error(`Could not refresh the document list after indexing`,e)}return{docIds:c,supported:a,succeededFiles:l,unsupported:o,failed:u,lastError:f}}function M(){let{setShowFileBrowser:e,currentSessionId:t,updateSessionInList:n,setPendingPrompt:a}=d(),u=(0,k.useCallback)(()=>e(!1),[e]);r(!0,u);let f=(0,k.useRef)(null);l(f,!0);let[h,g]=(0,k.useState)(``),[_,v]=(0,k.useState)(null),[y,b]=(0,k.useState)([]),[x,S]=(0,k.useState)([]),[C,w]=(0,k.useState)(!1),[T,E]=(0,k.useState)(null),[D,O]=(0,k.useState)(``),[M,N]=(0,k.useState)(null),[P,F]=(0,k.useState)([]),[ge,_e]=(0,k.useState)(!1),[I,L]=(0,k.useState)(!1),[R,ve]=(0,k.useState)(``),[z,B]=(0,k.useState)(new Set),[V,H]=(0,k.useState)(null),[ye,U]=(0,k.useState)(!1),[W,G]=(0,k.useState)(new Set),[K,q]=(0,k.useState)(null),J=(0,k.useRef)(null),[Y,X]=(0,k.useState)(null),Z=(0,k.useCallback)(async e=>{w(!0),E(null),N(null),O(``),F([]);try{let t=await ne(e);g(t.current_path),v(t.parent_path),b(t.entries),t.quick_links.length>0&&S(t.quick_links),i.ui.info(`Browsing: ${t.current_path} (${t.entries.length} items)`)}catch(e){let t=e instanceof Error?e.message:`Failed to load directory`;E(t),i.ui.error(`Browse failed`,e)}finally{w(!1)}},[]);(0,k.useEffect)(()=>{Z()},[Z]),(0,k.useEffect)(()=>()=>{J.current&&clearTimeout(J.current)},[]);let be=(0,k.useCallback)(async()=>{if(!D.trim())N(null),F([]);else{L(!0),E(null);try{let e=await se(D.trim(),R||void 0,30);N(e.results),F(e.searched_locations??[]),_e(e.truncated===!0),i.ui.info(`Search "${D}": ${e.total} results`)}catch(e){let t=e instanceof Error?e.message:`Search failed`;E(t),i.ui.error(`Search failed`,e)}finally{L(!1)}}},[D,R]),xe=e=>{e.key===`Enter`&&be()},Q=(0,k.useCallback)(e=>{e.type===`folder`&&(Z(e.path),B(new Set),H(null))},[Z]),Se=(0,k.useCallback)(async e=>{U(!0);try{let t=await ie(e);H(t)}catch(e){i.ui.error(`Preview failed`,e)}finally{U(!1)}},[]),Ce=(0,k.useCallback)(e=>{B(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),we=(0,k.useCallback)(async()=>{if(z.size===0)return;let e=Array.from(z);if(X(null),!e.some(e=>{let t=e.includes(`.`)?`.`+e.split(`.`).pop()?.toLowerCase():``;return!t||s(t)})){let t=e[0],n=t.lastIndexOf(`.`),r=n>0?t.slice(n).toLowerCase():``,i=m(r);X({filename:e.length===1?t.split(/[\\/]/).pop()||t:`${e.length} files`,error:i?i.message:`File type "${r}" is not supported for indexing.`})}else{G(new Set(e)),q(`Indexing ${e.length} file(s)...`);try{let r=await j(e,y,t,n);if(r.failed>0)q(`Done: ${r.docIds.length} indexed, ${r.failed} failed`),X({filename:`${r.failed} file(s)`,error:r.lastError||`Indexing failed for some files`});else{let e=r.unsupported.length>0?` (${r.unsupported.length} skipped — unsupported type)`:``;q(`Successfully indexed ${r.docIds.length} file(s)${e}`)}J.current&&clearTimeout(J.current),J.current=setTimeout(()=>q(null),5e3),B(new Set)}catch(t){i.doc.error(`Index selected failed`,t),X({filename:e.length===1?e[0].split(/[\\/]/).pop()||e[0]:`${e.length} files`,error:t instanceof Error?t.message:`An unexpected error occurred.`})}finally{G(new Set)}}},[z,t,n,y]),Te=(0,k.useCallback)(async()=>{if(z.size===0)return;let r=Array.from(z);X(null),G(new Set(r)),q(`Indexing ${r.length} file(s) for analysis...`);try{let i=await j(r,y,t,n);if(i.supported.length===0){let e=r[0].lastIndexOf(`.`),t=e>0?r[0].slice(e).toLowerCase():``,n=m(t);X({filename:r.length===1?r[0].split(/[\\/]/).pop()||r[0]:`${r.length} files`,error:n?.message??`File type "${t}" is not supported for indexing.`});return}if(i.docIds.length===0){X({filename:i.supported.length===1?i.supported[0].split(/[\\/]/).pop()||i.supported[0]:`${i.supported.length} files`,error:`Failed to index selected file(s). Please try again.`});return}i.failed>0&&q(`Warning: ${i.failed} file(s) failed to index and will be excluded.`);let o=(i.succeededFiles.length>0?i.succeededFiles:i.supported).map(e=>e.split(/[\\/]/).pop()||e),s=o.length===1?`Please analyze this document for me: ${o[0]}`:`Please analyze these documents for me:\n${o.map(e=>`- ${e}`).join(`
2
2
  `)}`;a(s),e(!1),B(new Set)}catch(e){i.doc.error(`Ask Agent failed`,e),X({filename:r.length===1?r[0].split(/[\\/]/).pop()||r[0]:`${r.length} files`,error:e instanceof Error?e.message:`An unexpected error occurred.`})}finally{G(new Set),q(null)}},[z,t,n,y,a,e]),Ee=h?h.replace(/\\/g,`/`).split(`/`).filter(Boolean):[],De=Ee.map((e,t)=>({label:e,path:Ee.slice(0,t+1).join(`/`)+(t===0&&e.includes(`:`)?`/`:``)})),Oe=pe(P),$=M?M.map(e=>({name:e.name,path:e.path,type:`file`,size:e.size,extension:e.extension||``,modified:e.modified||``})):y;return(0,A.jsx)(`div`,{ref:f,className:`modal-overlay`,onClick:()=>e(!1),role:`dialog`,"aria-modal":`true`,"aria-label":`File browser`,children:(0,A.jsxs)(`div`,{className:`modal-panel file-browser-modal ${V?`has-preview`:``}`,onClick:e=>e.stopPropagation(),children:[(0,A.jsxs)(`div`,{className:`modal-header`,children:[(0,A.jsxs)(`h3`,{children:[(0,A.jsx)(re,{size:18}),` File browser`]}),(0,A.jsx)(`button`,{className:`btn-icon`,onClick:()=>e(!1),"aria-label":`Close`,children:(0,A.jsx)(c,{size:18})})]}),(0,A.jsxs)(`div`,{className:`file-browser-body`,children:[(0,A.jsx)(`div`,{className:`fb-quick-links`,children:x.map(e=>(0,A.jsxs)(`button`,{className:`fb-quick-link`,onClick:()=>Z(e.path),title:e.path,children:[me(e.icon),(0,A.jsx)(`span`,{children:e.name})]},e.path))}),(0,A.jsxs)(`div`,{className:`fb-search-bar`,children:[(0,A.jsxs)(`div`,{className:`fb-search-input-wrap`,children:[(0,A.jsx)(te,{size:14,className:`fb-search-icon`}),(0,A.jsx)(`input`,{type:`text`,className:`fb-search-input`,placeholder:`Search files on your PC...`,value:D,onChange:e=>O(e.target.value),onKeyDown:xe,"aria-label":`Search files`}),D&&(0,A.jsx)(`button`,{className:`fb-search-clear`,onClick:()=>{O(``),N(null),F([])},"aria-label":`Clear search`,children:(0,A.jsx)(c,{size:12})})]}),(0,A.jsx)(`select`,{className:`fb-type-filter`,value:R,onChange:e=>ve(e.target.value),"aria-label":`File type filter`,children:he.map(e=>(0,A.jsx)(`option`,{value:e.value,children:e.label},e.value))}),(0,A.jsx)(`button`,{className:`fb-search-btn`,onClick:be,disabled:!D.trim()||I,children:I?`Searching...`:`Search`})]}),!M&&(0,A.jsxs)(`div`,{className:`fb-breadcrumb`,children:[(0,A.jsx)(`button`,{className:`fb-crumb`,onClick:()=>Z(`/`),children:(0,A.jsx)(ue,{size:12})}),De.map((e,t)=>(0,A.jsxs)(`span`,{className:`fb-crumb-item`,children:[(0,A.jsx)(le,{size:12,className:`fb-crumb-sep`}),(0,A.jsx)(`button`,{className:`fb-crumb`,onClick:()=>Z(e.path),children:e.label})]},t)),_&&(0,A.jsx)(`button`,{className:`fb-up-btn`,onClick:()=>Z(_),title:`Go up`,children:(0,A.jsx)(ae,{size:14})})]}),M&&(0,A.jsxs)(`div`,{className:`fb-search-header`,children:[(0,A.jsxs)(`div`,{className:`fb-search-summary`,children:[(0,A.jsxs)(`span`,{children:[`Found `,M.length,` result(s) for "`,D,`"`]}),Oe&&(0,A.jsxs)(`span`,{className:`fb-search-scope`,title:P.join(`
3
3
  `),children:[`Searching in: `,(0,A.jsx)(`code`,{children:Oe})]}),ge&&(0,A.jsx)(`span`,{children:`Search stopped early, so some matches may be missing. Try a more specific name.`})]}),(0,A.jsx)(`button`,{className:`fb-back-btn`,onClick:()=>{N(null),O(``),F([])},children:`Back to browsing`})]}),T&&(0,A.jsx)(`div`,{className:`fb-error`,children:T}),(0,A.jsxs)(`div`,{className:`fb-content`,children:[(0,A.jsxs)(`div`,{className:`fb-file-list`,children:[C&&(0,A.jsx)(`div`,{className:`fb-loading`,children:`Loading...`}),!C&&$.length===0&&(0,A.jsx)(`div`,{className:`fb-empty`,children:M?`No files found`:`This folder is empty`}),!C&&$.map(e=>{let t=e.extension||(e.name.includes(`.`)?`.`+e.name.split(`.`).pop()?.toLowerCase():``),n=e.type===`file`&&t&&!s(t),r=n?m(t):null;return(0,A.jsxs)(`div`,{className:`fb-entry ${e.type} ${z.has(e.path)?`selected`:``} ${n?`unsupported`:``}`,onClick:()=>e.type===`folder`?Q(e):Ce(e.path),onDoubleClick:()=>e.type===`folder`?Q(e):void 0,title:n?`${r?.label||`This`} file type cannot be indexed`:e.path,children:[(0,A.jsx)(`input`,{type:`checkbox`,className:`fb-entry-checkbox`,checked:z.has(e.path),onChange:()=>Ce(e.path),onClick:e=>e.stopPropagation(),"aria-label":`Select ${e.name}`}),(0,A.jsx)(`span`,{className:`fb-entry-icon`,children:de(e)}),(0,A.jsx)(`span`,{className:`fb-entry-name`,title:e.path,children:e.name}),n&&(0,A.jsx)(`span`,{className:`fb-unsupported-badge`,children:`Not indexable`}),e.type===`file`&&(0,A.jsx)(`button`,{type:`button`,className:`fb-entry-preview-btn`,onClick:t=>{t.stopPropagation(),Se(e.path)},"aria-label":`Preview ${e.name}`,title:`Preview file`,children:(0,A.jsx)(o,{size:14})}),(0,A.jsx)(`span`,{className:`fb-entry-size`,children:e.type===`file`?ce(e.size):``}),(0,A.jsx)(`span`,{className:`fb-entry-date`,children:fe(e.modified)})]},e.path)})]}),V&&(0,A.jsxs)(`div`,{className:`fb-preview`,children:[(0,A.jsxs)(`div`,{className:`fb-preview-header`,children:[(0,A.jsx)(`span`,{className:`fb-preview-name`,children:V.name}),(0,A.jsx)(`button`,{className:`btn-icon-sm`,onClick:()=>H(null),"aria-label":`Close preview`,children:(0,A.jsx)(c,{size:14})})]}),(0,A.jsxs)(`div`,{className:`fb-preview-meta`,children:[(0,A.jsx)(`span`,{children:V.size_display}),V.total_lines&&(0,A.jsxs)(`span`,{children:[V.total_lines,` lines`]}),V.columns&&(0,A.jsxs)(`span`,{children:[V.columns.length,` columns`]}),V.row_count!==null&&(0,A.jsxs)(`span`,{children:[V.row_count,` rows`]})]}),V.columns&&(0,A.jsxs)(`div`,{className:`fb-preview-columns`,children:[(0,A.jsx)(`strong`,{children:`Columns:`}),` `,V.columns.join(`, `)]}),ye?(0,A.jsx)(`div`,{className:`fb-preview-loading`,children:`Loading preview...`}):V.is_text&&V.preview_lines.length>0?(0,A.jsx)(`pre`,{className:`fb-preview-content`,children:V.preview_lines.slice(0,30).join(`
4
4
  `)}):(0,A.jsx)(`div`,{className:`fb-preview-binary`,children:`Binary file - no preview available`})]})]}),Y&&(0,A.jsx)(ee,{filename:Y.filename,error:Y.error,onDismiss:()=>X(null)}),(0,A.jsxs)(`div`,{className:`fb-actions`,children:[(0,A.jsx)(`div`,{className:`fb-selection-info`,children:z.size>0?`${z.size} item(s) selected`:`Select files to index or analyze`}),K&&(0,A.jsx)(`span`,{className:`fb-index-status`,children:K}),(0,A.jsxs)(`div`,{className:`fb-action-btns`,children:[(0,A.jsxs)(`button`,{className:`fb-action-btn secondary`,onClick:we,disabled:z.size===0||W.size>0,title:`Index selected files for RAG search`,children:[(0,A.jsx)(p,{size:14}),`Index Selected`]}),(0,A.jsxs)(`button`,{className:`fb-action-btn primary`,onClick:Te,disabled:z.size===0||W.size>0,title:`Index and send selected files to the chat agent for analysis`,children:[(0,A.jsx)(oe,{size:14}),`Ask Agent`]})]})]})]})]})})}export{M as FileBrowser};