1import{r as c,bI as gt,j as e,bG as xs,bN as Es,bM as ft,J as ze,e as we,b as vt,d as V,k as E,aZ as fs,B as w,w as yt,h as k,C as Nt,l as bt,g as G,M as Is,I as H,Y as vs,q as Ls,ab as Ye,ct as _t,R as wt,aT as Ms,L as Ds,bz as kt,a$ as Ct,b0 as St,b1 as At,T as ye,O as he,cu as Tt,cv as Pt,cw as ys,cx as Rt,cy as Et,cz as It,cA as Lt,cB as Mt,cC as Dt,a_ as Ge,b9 as Ne,t as le,b3 as Ot,c as Os,U as Bt,cD as Je}from"./index-1xHaW6cT.js";import{T as be,a as _e,b as B,c as U}from"./tabs-DT-o9Otr.js";import{u as je}from"./useOrganization-fBdDXQKk.js";import{C as T,a as L,d as M,b as O,c as P}from"./card-BMnK6vlX.js";import{A as Ie,h as ls,a as Le,b as Me,c as De,d as Oe,e as Be,g as qe,f as Ke}from"./alert-dialog-bOh4qXSo.js";import{M as qt,T as Kt}from"./test-tube-B4s8iHqw.js";import{C as $t}from"./calendar-Qx8a4ZXK.js";import{B as Ut}from"./building-2-BnffHfZP.js";import{R as Ns}from"./rotate-ccw-xZfcR3Z1.js";import{f as pe}from"./format-CddkPNEY.js";import{u as Ft}from"./useApiAnalytics-CGfoM0P7.js";import{P as zt}from"./progress-CWPW7aBS.js";import{T as Bs,a as qs,b as $e,c as se,d as Ks,e as te}from"./table-C7nVAS0O.js";import{a as Ze,A as Gt,L as $s,b as Ht,U as Us,B as Vt,C as Wt}from"./user-check-RC8wg8yp.js";import{Z as Qt}from"./zap-IO6Oz7LO.js";import{T as Yt}from"./trending-up-8VvHxECN.js";import{C as bs}from"./coins-D1awenyz.js";import{S as Fs}from"./scroll-area-Bv9D8bFI.js";import{B as zs,T as Jt,M as Zt}from"./thumbs-up-S71CDcwY.js";import{C as ke}from"./copy-BLV_afbW.js";import{S as _s}from"./star-YXT_WaTO.js";import{L as Xt}from"./lightbulb-BOdb4Rso.js";import{B as ea}from"./bug-007ZqN4M.js";import{U as ws}
1from"./user-plus-BPnQKb6I.js";import{R as He,S as sa}from"./search-DrhPw-W4.js";import{C as us}from"./circle-check-big-q8bTO_bi.js";import{C as Ue}from"./circle-x-DglVz2ik.js";import{A as ta,d as Xe,e as es,f as ss}from"./ClaudeTroubleshooting-CZWaf_je.js";import{S as Ce}from"./switch-D0_Kt0bJ.js";import{L as q}from"./label-Ss3MiU5e.js";import{S as aa}from"./sparkles-Bre0hHom.js";import{e as ra,t as na}from"./radio-group-ByU1SVKD.js";import{C as ks}from"./circle-check-CdqL7YcS.js";import{E as Ve}from"./external-link-DgWh9mSW.js";import{D as ce}from"./database-D-UBCwxV.js";import{P as Gs}from"./plug-B_aVYGjU.js";import{S as Hs}from"./shield-check-BcZ8RX6n.js";import{C as Cs}from"./chart-column-C9SfsUR1.js";import{A as Fe}from"./activity-BOWIXy0x.js";import{D as os,a as cs,b as Pe,c as Re,d as ts,e as Ee}from"./dialog-DTQzDJ2I.js";import{C as as}from"./checkbox-C-JFwZ-c.js";import{S as Q,a as Y,b as J,c as Z,d as K}from"./select-bmDMNmgK.js";import{K as Vs}from"./key-B7VIWALC.js";import{P as ue}from"./plus-CRs0zrjj.js";import{T as X}from"./trash-2-jcAUFpCZ.js";import{D as ia}from"./download-OyHPExJh.js";import{W as Ws}from"./webhook-rAivZa41.js";import{P as la}from"./package-CbBTM-KU.js";import{u as oa}from"./useProjects-CZdwidIY.js";import{f as ds}from"./formatDistanceToNow-CnJdnPV1.js";import{u as Qs}from"./useDataRights-C5rTxFmU.js";import{A as ca}from"./arrow-right-DOL-sfQi.js";import{u as da}from"./useConversationThreads-Dx2CFyKC.js";import{S as Ys}from"./shield-BjyCPzIg.js";import{C as hs}from"./cpu-thpwIKaN.js";import{C as ma,a as xa,b as ua}from"./collapsible-B_oBfp2k.js";import{C as ha}from"./chevron-down-C-IjVGda.js";import{u as xe}from"./useMutation-B_fZ8btO.js";import{S as pa}from"./send-B1oFA0BA.js";import{S as ja,G as ga,I as fa}from"./GmailConnectorCard-BdLfEO71.js";import{C as va}from"./ConnectPanel-BlQ4Wb-l.js";import"./alert-CJq524XI.js";import ya from"./Customers-D4bCb1z4.js";import"./en-US-wfBU2YNu.js";import"./index-D17hSi50.js";import"./index-CbagegQf.js";import"./chevron-up-Cjn0caCV.js";import"./service-utils-CjouMzMd.js";import"./endOfMonth-BsqzHdGd.js";import"./ProviderIcon-DW3-d9wU.js";import"./circle-alert-DKC7hNSp.js";import"./ellipsis-vertical-DQ6aTyYE.js";import"./folder-open-kvCB4Bgc.js";import"./info-BZij-kbR.js";import"./eye-D9EhUDBJ.js";import"./file-spreadsheet-DPQshaov.js";import"./textarea-ny2ClKtr.js";import"./inbox-DOx1CDq3.js";import"./dollar-sign-BeJFv61_.js";import"./box-CuoCqyt8.js";import"./users-CEoB-r-P.js";var Na=Object.defineProperty,ne=(s,r)=>Na(s,"name",{value:r,configurable:!0}),Js="Avatar",[ba,ni]=gt(Js),_a=[0,()=>{}],[wa,Zs]=ba(Js),Xs=c.forwardRef(ne(function(r,n){const{__scopeAvatar:t,...d}=r,[i,N]=c.useState("idle"),[f,m]=at();return e.jsx(wa,{scope:t,imageLoadingStatus:i,setImageLoadingStatus:N,imageCount:f,setImageCount:m,children:e.jsx(xs.span,{...d,ref:n})})},"Avatar")),ka="AvatarImage",et=c.forwardRef(ne(function(r,n){const{__scopeAvatar:t,src:d,onLoadingStatusChange:i,...N}=r,f=Zs(ka,t);f.setImageCount;const m=tt(d,{referrerPolicy:N.referrerPolicy,crossOrigin:N.crossOrigin,loadingStatus:f.imageLoadingStatus,setLoadingStatus:f.setImageLoadingStatus}),p=ft(l=>{i==null||i(l)}),x=c.useRef(m);return Es(()=>{const l=x.current;x.current=m,m!==l&&p(m)},[m,p]),m==="loaded"?e.jsx(xs.img,{...N,ref:n,src:d}):null},"AvatarImage")),Ca="AvatarFallback",st=c.forwardRef(ne(function(r,n){const{__scopeAvatar:t,delayMs:d,...i}=r,N=Zs(Ca,t),[f,m]=c.useState(d===void 0);return c.useEffect(()=>{if(d!==void 0){const p=window.setTimeout(()=>m(!0),d);return()=>window.clearTimeout(p)}},[d]),f&&N.imageLoadingStatus!=="loaded"?e.jsx(xs.span,{...i,ref:n}):null},"AvatarFallback"));function tt(s,{loadingStatus:r,setLoadingStatus:n,referrerPolicy:t,crossOrigin:d}){return Es(()=>{if(!s){n("error");return}const i=new window.Image,N=ne(m=>{const p=m.currentTarget;n(ms(p))},"handleLoad"),f=ne(()=>n("error"),"handleError");return i.addEventListener("load",N),i.addEventListener("error",f),t&&(i.referrerPolicy=t),i.crossOrigin=d??null,i.src=s,n(ms(i)),()=>{i.removeEventListener("load",N),i.removeEventListener("error",f),n("idle")}},[s,d,t,n]),r}ne(tt,"useImageLoadingStatus");
1function ms(s){return s.complete?s.naturalWidth>0?"loaded":"error":"loading"}ne(ms,"getImageLoadingStatus");function at(){return _a}ne(at,"useImageCount");function Sa(s){}ne(Sa,"useUpdateImageCount");const rt=c.forwardRef(({className:s,...r},n)=>e.jsx(Xs,{ref:n,className:ze("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",s),...r}));rt.displayName=Xs.displayName;const Aa=c.forwardRef(({className:s,...r},n)=>e.jsx(et,{ref:n,className:ze("aspect-square h-full w-full",s),...r}));Aa.displayName=et.displayName;const nt=c.forwardRef(({className:s,...r},n)=>e.jsx(st,{ref:n,className:ze("flex h-full w-full items-center justify-center rounded-full bg-muted",s),...r}));nt.displayName=st.displayName;function Ta(){var a,y,j;const{user:s}=we(),{organization:r}=je(),n=vt(),{toast:t}=V(),[d,i]=c.useState(!1),[N,f]=c.useState(!1),m=((a=s==null?void 0:s.user_metadata)==null?void 0:a.display_name)||((y=s==null?void 0:s.email)==null?void 0:y.split("@")[0])||"User",p=m.slice(0,2).toUpperCase(),x=async()=>{i(!0),await k.auth.signOut(),t({title:"Signed out"}),n("/auth")},l=async()=>{if(!(s!=null&&s.id))return;f(!0);const{error:b}=await k.from("user_preferences").upsert({user_id:s.id,onboarding_completed:!1,show_tips:!0});if(f(!1),b){t({title:"Could not restart onboarding",description:b.message,variant:"destructive"});return}try{localStorage.removeItem("brainmate_workspace_setup_done")}catch{}t({title:"Onboarding reset",description:"Reloadingâ¦"}),setTimeout(()=>{window.location.href="/app"},400)};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsx(M,{className:"text-base",children:"Profile"}),e.jsx(O,{children:"Your account information"})]}),e.jsx(P,{className:"space-y-6",children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(rt,{className:"h-16 w-16",children:e.jsx(nt,{className:"text-lg bg-primary/10 text-primary",children:p})}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("h3",{className:"text-lg font-semibold",children:m}),e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(qt,{className:"h-3.5 w-3.5"}),s==null?void 0:s.email]}),(s==null?void 0:s.created_at)&&e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx($t,{className:"h-3 w-3"}),"Member since ",pe(new Date(s.created_at),"MMMM yyyy")]})]})]})})]}),r&&e.jsxs(T,{children:[e.jsx(L,{children:e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Ut,{className:"h-4 w-4"}),"Organization"]})}),e.jsx(P,{children:e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Name"}),e.jsx("p",{className:"text-sm font-medium",children:r.name})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Plan"}),e.jsx(E,{variant:"outline",children:r.plan_tier||"Pilot"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Organization ID"}),e.jsxs("p",{className:"text-xs font-mono text-muted-foreground",children:[(j=r.id)==null?void 0:j.slice(0,8),"â¦"]})]})]})})]}),e.jsx(fs,{}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Ns,{className:"h-4 w-4"}),"Restart onboarding"]}),e.jsx(O,{children:"Re-open the setup wizard on your next visit to /app."})]}),e.jsx(P,{children:e.jsxs(Ie,{children:[e.jsx(ls,{asChild:!0,children:e.jsxs(w,{variant:"outline",size:"sm",className:"gap-2",disabled:N,children:[e.jsx(Ns,{className:"h-3.5 w-3.5"}),N?"Resettingâ¦":"Restart onboarding"]})}),e.jsxs(Le,{children:[e.jsxs(Me,{children:[e.jsx(De,{children:"Restart onboarding?"}),e.jsx(Oe,{children:"The setup wizard will open again the next time you visit the app. Your projects, API keys, and memories are not affected."})]}),e.jsxs(Be,{children:[e.jsx(qe,{children:"Cancel"}),e.jsx(Ke,{onClick:l,children:"Restart"})]})]})]})})]}),e.jsx(fs,{}),e.jsxs(w,{variant:"destructive",onClick:x,disabled:d,className:"gap-2",children:[e.jsx(yt,{className:"h-4 w-4"}),d?"Signing outâ¦":"Sign Out"]})]})}function Pa(){var f,m;const{organization:s}=je(),r=Ft(s==null?void 0:s.id,"30d"),{summary:n,loading:t,surfaceModelBreakdown:d}=r,i=(s==null?void 0:s.plan_tier)||"pilot",N=i==="pilot";return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Ze,{className:"h-4 w-4"}),"Current Plan"]}),e.jsx(O,{children:"Your subscription and usage limits"})]}),e.jsxs(P,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 rounded-lg bg-primary/5 border border-primary/20",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-lg font-bold capitalize",children:i}),e.jsx(E,{variant:"default",className:"text-xs",children:"Active"})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:N?"Early access pilot â full platform access included":"Enterprise plan with custom limits"})]}),N&&e.jsxs(w,{variant:"outline",size:"sm",className:"gap-1",disabled:!0,children:[e.jsx(Gt,{className:"h-3.5 w-3.5"}),"Upgrade"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[e.jsx(rs,{label:"API Requests (30d)",value:t?"â":((f=n==null?void 0:n.totalRequests)==null?void 0:f.toLocaleStr
1ing())??"0",limit:"Unlimited (pilot)",percent:null,icon:Qt}),e.jsx(rs,{label:"Total Tokens (30d)",value:t?"â":((m=n==null?void 0:n.totalTokens)==null?void 0:m.toLocaleString())??"0",limit:"Unlimited (pilot)",percent:null,icon:Yt}),e.jsx(rs,{label:"Estimated Cost (30d)",value:t?"â":`$${((n==null?void 0:n.totalCost)??0).toFixed(2)}`,limit:"No cap",percent:null,icon:Ze})]})]})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(bs,{className:"h-4 w-4"}),"Where your AI spend went (last 30 days)"]}),e.jsx(O,{children:"Cost grouped by surface and model"})]}),e.jsx(P,{children:t?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loadingâ¦"}):d.length===0?e.jsxs("div",{className:"py-8 text-center",children:[e.jsx(bs,{className:"h-10 w-10 text-muted-foreground/40 mx-auto mb-3"}),e.jsx("p",{className:"text-sm font-medium mb-1",children:"No usage in the last 30 days"}),e.jsx("p",{className:"text-xs text-muted-foreground max-w-sm mx-auto",children:"Once you start making AI calls through BrainMate, your spend breakdown by surface (Telegram, Claude Desktop, Cursor, web, MCPâ¦) and model will appear here."})]}):e.jsxs(Bs,{children:[e.jsx(qs,{children:e.jsxs($e,{children:[e.jsx(se,{children:"Surface"}),e.jsx(se,{children:"Model"}),e.jsx(se,{className:"text-right",children:"Requests"}),e.jsx(se,{className:"text-right",children:"Tokens"}),e.jsx(se,{className:"text-right",children:"Cost"})]})}),e.jsx(Ks,{children:d.map(p=>e.jsxs($e,{children:[e.jsx(te,{className:"text-sm font-medium capitalize",children:p.surface}),e.jsx(te,{className:"text-sm text-muted-foreground",children:p.model}),e.jsx(te,{className:"text-right text-sm",children:p.requests.toLocaleString()}),e.jsx(te,{className:"text-right text-sm",children:p.tokens.toLocaleString()}),e.jsxs(te,{className:"text-right text-sm",children:["$",p.cost.toFixed(4)]})]},`${p.surface}|${p.model}`))})]})})]}),e.jsxs(T,{children:[e.jsx(L,{children:e.jsx(M,{className:"text-base",children:"Billing Information"})}),e.jsx(P,{children:e.jsxs("div",{className:"py-8 text-center",children:[e.jsx(Ze,{className:"h-10 w-10 text-muted-foreground/40 mx-auto mb-3"}),e.jsx("p",{className:"text-sm font-medium mb-1",children:"No payment method required"}),e.jsx("p",{className:"text-xs text-muted-foreground max-w-sm mx-auto",children:"As a pilot participant, you have full access at no cost. Billing configuration will be available when you upgrade to a paid plan."})]})})]})]})}function rs({label:s,value:r,limit:n,percent:t,icon:d}){return e.jsxs("div",{className:"p-4 rounded-lg border border-border space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(d,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:s})]}),e.jsx("p",{className:"text-xl font-bold",children:r}),e.jsx("p",{className:"text-[10px] text-muted-foreground",children:n}),t!==null&&e.jsx(zt,{value:t,className:"h-1.5"})]})}const Ra=[{id:"quickstart",title:"Quick Start",badge:"Start here"},{id:"sdk",title:"TypeScript SDK",badge:"npm"},{id:"keys",title:"API Keys & Auth"},{id:"proxy",title:"Governed Proxy API"},{id:"clients",title:"MCP & AI Clients"},{id:"telemetry",title:"Agent Telemetry API"},{id:"webhooks",title:"Webhooks & OTLP"},{id:"governance",title:"Governance Policies"},{id:"limits",title:"Rate Limits & Budgets"}];function Ea(){const[s,r]=c.useState("quickstart");return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-4 gap-6",children:[e.jsx(T,{className:"lg:col-span-1 h-fit",children:e.jsxs(P,{className:"p-3 space-y-1",children:[e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-muted-foreground/60 px-2 py-1",children:"Integration Docs"}),Ra.map(n=>e.jsxs(w,{variant:s===n.id?"secondary":"ghost",size:"sm",className:"w-full justify-start gap-2 text-xs",onClick:()=>r(n.id),children:[e.jsx(Nt,{className:`h-3 w-3 transition-transform ${s===n.id?"rotate-90":""}`}),n.title,n.badge&&e.jsx(E,{variant:"outline",className:"text-[9px] ml-auto",children:n.badge})]},n.id))]})}),e.jsx("div",{className:"lg:col-span-3",children:e.jsx(Fs,{className:"h-[calc(100vh-320p
1x)]",children:e.jsxs("div",{className:"pr-4",children:[s==="quickstart"&&e.jsx(Ia,{}),s==="sdk"&&e.jsx(La,{}),s==="keys"&&e.jsx(Ma,{}),s==="proxy"&&e.jsx(Oa,{}),s==="clients"&&e.jsx(Da,{}),s==="telemetry"&&e.jsx(Ba,{}),s==="webhooks"&&e.jsx(qa,{}),s==="governance"&&e.jsx(Ka,{}),s==="limits"&&e.jsx($a,{})]})})})]})}function F({code:s,language:r="typescript"}){const{toast:n}=V(),[t,d]=c.useState(!1),i=()=>{navigator.clipboard.writeText(s),d(!0),n({title:"Copied to clipboard"}),setTimeout(()=>d(!1),2e3)};return e.jsxs("div",{className:"relative group rounded-lg bg-muted border border-border overflow-hidden my-4",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border bg-muted/50",children:[e.jsx("span",{className:"text-[10px] text-muted-foreground uppercase tracking-wide",children:r}),e.jsxs(w,{variant:"ghost",size:"sm",className:"h-6 px-2 text-xs gap-1",onClick:i,children:[t?e.jsx(bt,{className:"h-3 w-3"}):e.jsx(ke,{className:"h-3 w-3"}),t?"Copied":"Copy"]})]}),e.jsx("pre",{className:"p-4 overflow-x-auto text-sm font-mono leading-relaxed",children:e.jsx("code",{children:s})})]})}function ie({children:s}){return e.jsxs("h2",{className:"text-xl font-bold mb-4 flex items-center gap-2",children:[e.jsx(zs,{className:"h-5 w-5 text-primary"}),s]})}const ae="https://api.brainmate.dev/v1",ns="https://nupykfunfdwjibrqxjgc.supabase.co/functions/v1/mcp-gateway";function Ia(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Quick Start"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Two ways in: the ",e.jsx("strong",{children:"@brainmate/sdk"})," package for governed memory (recommended), or the OpenAI-compatible governed proxy as a drop-in base URL. Both use the same ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"bm_live_â¦"})," key."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"1. Get your API key"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Open ",e.jsx("strong",{children:"Settings â API & Developer"})," and click ",e.jsx("strong",{children:"New API key"}),", pick a tenant and (optionally) a project. The full secret is shown once â copy it before closing. Keep it server-side only."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"2a. Memory via the SDK"}),e.jsx(F,{language:"bash",code:"npm install @brainmate/sdk"}),e.jsx(F,{language:"typescript",code:`import { BrainMate } from "@brainmate/sdk"; 2 3const bm = new BrainMate({ apiKey: process.env.BRAINMATE_API_KEY! }); 4const { projects } = await bm.projects.list(); 5 6const memory = await bm.recall({ projectId: projects[0].id, query: "pricing decisions" });`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"2b. Governed AI calls via the proxy"}),e.jsx(F,{language:"typescript",code:`import OpenAI from "openai"; 7 8const client = new OpenAI({ 9 baseURL: "${ae}/proxy", 10 apiKey: process.env.BRAINMATE_API_KEY, 11}); 12 13const response = await client.chat.completions.create({ 14 model: "gpt-5-mini", 15 messages: [{ role: "user", content: "Hello" }], 16});`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"3. Verify"}),e.jsx(F,{language:"bash",code:`curl ${ae}/health`}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Every proxied request flows through the 5-phase guard pipeline and appears in ",e.jsx("strong",{children:"Memory Hub â Telemetry"}),". Per-key usage and project links live in ",e.jsx("strong",{children:"Settings â API & Developer"}),"."]})]})}function La(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"TypeScript SDK"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[e.jsx("a",{className:"text-primary hover:underline",href:"https://www.npmjs.com/package/@brainmate/sdk",target:"_blank",rel:"noreferrer",children:"@brainmate/sdk"})," â recall and remember structured memory with hard tenant isolation. Endpoint: ",e.jsxs("code",{className:"text-xs bg-muted px-1 rounded",children:[ae,"/memory"]}),". The SDK throws in browsers unless you pass ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"{ allowBrowser: true }"}),"."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Recall â act â remember"}),e.jsx(F,{language:"typescript",code:`import { BrainMate } from "@brainmate/sdk"; 17 18const bm = new BrainMate({ apiKey: process.env.BRAINMATE_API_KEY! }); 19 20const memory = await bm.recall({ 21 projectId, 22 query: "How did we decide to price the product?", 23 types: ["DECISION", "FACT"], 24 limit: 10, 25}); 26 27const result = await bm.remember({ 28 projectId, 29 insights: [{ type: "DECISION", text: "Price at $49/mo starting Q3" }], 30}); 31 32// Conflicts are never silently overwritten 33for (const c of result.conflicts) console.log(c.conflictType, c.reasoning);`}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Insight types: ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"FACT"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"DECISION"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"ASSUMPTION"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"OPEN_QUESTION"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"ARTIFACT"}),"."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Vercel AI SDK"}),e.jsx(F,{language:"typescript",code:`import { streamText } from "ai";
34import { brainMateMemoryProvider } from "@brainmate/sdk/ai-sdk"; 35 36const { systemPrompt } = await brainMateMemoryProvider({ bm, projectId, query: lastUserMessage }); 37return streamText({ model, system: systemPrompt, messages });`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Governed fetch"}),e.jsx(F,{language:"typescript",code:`import { createLovableGovernedFetch } from "@brainmate/sdk/lovable-proxy"; 38 39const fetchAI = createLovableGovernedFetch({ 40 apiKey: process.env.BRAINMATE_API_KEY!, 41 agentName: "my-app", 42});`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Errors"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["All methods throw ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"BrainMateError"})," with a stable ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"code"}),": UNAUTHORIZED, FORBIDDEN, TENANT_MISMATCH, TENANT_MISCONFIGURED, VALIDATION_ERROR, CONFLICT, NOT_FOUND, RATE_LIMITED (auto-retried), BUDGET_EXCEEDED, SERVER_ERROR (auto-retried), TIMEOUT (30s default), NETWORK_ERROR."]})]})}function Ma(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"API Keys & Auth"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["All requests authenticate with ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"Authorization: Bearer bm_live_â¦"}),". Manage keys in ",e.jsx("strong",{children:"Settings â API & Developer"}),"."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Creating a key"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Click ",e.jsx("strong",{children:"New API key"}),", name it, choose a tenant and optionally link a project. The full secret is shown once â afterwards only the prefix is stored. Lost keys must be rotated."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Key format"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Keys look like ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"bm_live_<random>"}),". Only the SHA-256 hash and short prefix are persisted server-side."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Tenant isolation & scoping"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:["Every key belongs to exactly one tenant. A ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"projectId"})," from another tenant returns ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"403 TENANT_MISMATCH"}),"."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Project-linked"})," keys are restricted to one project's data, policies, and budgets."]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Rotation & revocation"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Rotate, revoke, or re-link keys from the keys table in ",e.jsx("strong",{children:"Settings â API & Developer"}),". Revocation applies on the next request."]})]})}function Da(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"MCP & AI Clients"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"BrainMate runs a remote Model Context Protocol server so Claude Desktop, Cursor, Lovable Desktop, ChatGPT and Telegram share one memory layer."}),e.jsxs("div",{className:"rounded-lg border border-primary/30 bg-primary/5 p-3 text-sm",children:["Want configs with your key pre-filled? Open"," ",e.jsx("a",{href:"/app/settings?tab=integrations",className:"text-primary font-medium hover:underline",children:"Settings â Integrations"})," and use the Connect flow."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"MCP endpoint"}),e.jsx(F,{language:"http",code:`${ae}/mcp 43Authorization: Bearer bm_live_your_key`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Claude Desktop"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Edit ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"~/Library/Application Support/Claude/claude_desktop_config.json"})," (macOS) or ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"%APPDATA%\\Claude\\claude_desktop_config.json"})," (Windows):"]}),e.jsx(F,{language:"json",code:`{ 44 "mcpServers": { 45 "brainmate": { 46 "command": "npx", 47 "args": ["-y", "mcp-remote", "${ae}/mcp", 48 "--header", "Authorization: Bearer bm_live_your_key"] 49 } 50 } 51}`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Cursor / Lovable Desktop"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Add to ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:".cursor/mcp.json"})," (or the client's MCP settings):"]}),e.jsx(F,{language:"json",code:`{ 52 "mcpServers": { 53 "brainmate": { 54 "url": "${ae}/mcp", 55 "headers": { "Authorization": "Bearer bm_live_your_key" } 56 } 57 } 58}`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Core tools"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"session_bootstrap"})," â load identity, projects and recent context at session start"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"recall_memory"})," â governed, cited recall of insights"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"remember_insight"})," â write a fact/decision (conflict-checked)"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"log_turn"})," â log a conversation turn to the cross-client timeline"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"recall_threads"})," â search recent turns from any client"]}),e.jsxs("li",{children:["Plus ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"list_projects"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"list_insights"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"list_scopes"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"list_artifacts"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"health_check"})]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Telegram"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Link your account under ",e.jsx("strong",{children:"Settings â Integrations â Telegram"}),". Messages to the bot are logged as turns and become recallable from every other client."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Cross-client memory"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"All clients write to one timeline under your identity. Turns are retained for 30 days; extracted insights persist and are searchable from any client."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"MCP Gateway â rerouting primary model calls"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"For hosts that let you reroute primary model calls through a custom base URL, point them at the MCP Gateway so every call is governed, verified and audited."}),e.jsx("h4",{className:"text-xs font-semibold mt-4",children:"Anthropic-compatible base URL clients"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Use this only in hosts that let you reroute primary Claude/Anthropic model calls through a custom base URL."}),e.jsx(F,{language:"json",code:`{ 59 "providers": { 60 "brainmate": { 61 "base_url": "${ns}/v1/messages", 62 "api_key": "bm_live_your_key", 63 "headers": { 64 "x-brainmate-client": "claude_desktop" 65 } 66 } 67 } 68}`}),e.jsx("h4",{className:"text-xs font-semibold mt-4",children:"OpenAI-compatible base URL clients"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Use this when the host supports a custom OpenAI-compatible endpoint for primary model calls."}),e.jsx(F,{language:"json",code:`{ 69 "openai": { 70 "baseURL": "${ns}/v1/chat/completions", 71 "apiKey": "bm_live_your_key", 72 "defaultHeaders": { 73 "x-brainmate-client": "cursor" 74 } 75 } 76}`}),e.jsx("h4",{className:"text-xs font-semibold mt-4",children:"Tool-only MCP hosts"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["If your host can use MCP tools but cannot reroute its native chat endpoint, use the ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"brainmate.model.complete"})," tool for governed calls. Native host chat that still goes directly to Anthropic/OpenAI remains outside BrainMate enforcement."]}),e.jsx("h4",{className:"text-xs font-semibold mt-4",children:"Raw curl"}),e.jsx(F,{language:"bash",code:`curl ${ns}/v1/chat/completions \\ 77 -H "Authorization: Bearer bm_live_your_key" \\ 78 -H "Content-Type: application/json" \\ 79 -H "x-brainmate-client: copilot" \\ 80 -d '{ 81 "model": "google/gemini-2.5-pro", 82 "messages": [{"role":"user","content":"hello"}] 83 }'`})]})}function Oa(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Governed Proxy API"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"The governed proxy is an OpenAI-compatible endpoint that adds governance, verification, and audit to every request."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Endpoint"}),e.jsx(F,{language:"http",code:`POST ${ae}/proxy/chat/completions`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Request Body"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Standard OpenAI chat completion format. All parameters (model, messages, temperature, etc.) are forwarded to the upstream provider after governance checks."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Response Headers"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"x-brainmate-trace-id"})," â Unique trace ID for this request"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"x-brainmate-guard-result"})," â Guard pipeline result (pass/halt/error)"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"x-brainmate-model-used"})," â Actual model used (may differ from requested)"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"x-brainmate-tokens-saved"})," â Tokens saved by LoReTokens compression"]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Guard Pipeline"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Every request passes through 5 phases:"}),e.jsxs("ol",{className:"text-sm text-muted-foreground space-y-1 list-decimal list-inside",children:[e.jsx("li",{children:"Pre-AI validation (policy rules, forbidden topics)"}),e.jsx("li",{children:"Model routing (multi-family selection)"}),e.jsx("li",{children:"Response verification (grounding, confidence)"}),e.jsx("li",{children:"Data integrity (numerical verification)"}),e.jsx("li",{children:"Audit logging (immutable, hash-chained)"})]})]})}function Ba(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Agent Telemetry API"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Report agent sessions and steps for deep observability."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Create Session"}),e.jsx(F,{language:"http",code:`POST ${ae}/proxy/agent-telemetry/sessions 84Authorization: Bearer bm_live_your_key 85Content-Type: application/json 86 87{ 88 "session_type": "task", 89 "metadata": { "task": "data-analysis" } 90}`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Report Step"}),e.jsx(F,{language:"http",code:`POST ${ae}/proxy/agent-telemetry/steps 91Authorization: Bearer bm_live_your_key 92Content-Type: application/json 93 94{ 95 "session_id": "sess_...", 96 "step_type": "llm_call", 97 "step_number": 1, 98 "model_used": "gpt-4o", 99 "input_tokens": 1500, 100 "output_tokens": 300, 101 "latency_ms": 2400, 102 "guard_result": "pass" 103}`})]})}function qa(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Webhooks"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Receive real-time notifications for governance events."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Supported Events"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"guard.halt"})," â A request was blocked by the guard pipeline"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"budget.warning"})," â Token or cost budget approaching limit"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"budget.exceeded"})," â Budget limit reached"]}),e.jsxs("li",{children:[e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"verification.failed"})," â Response failed verification checks"]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Inbound turns (n8n, Zapier, bots)"}),e.jsx(F,{language:"bash",code:`curl -X POST ${ae}/turns \\ 104 -H "Authorization: Bearer bm_live_your_key" \\ 105 -H "Content-Type: application/json" \\
106 -d '{"userMessage":"...","assistantMessage":"..."}'`}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Configuration"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Configure webhooks in ",e.jsx("strong",{children:"Settings â API & Developer"}),". Each webhook requires an HTTPS endpoint and supports HMAC-SHA256 signature verification."]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"OTLP export"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["To stream traces, metrics, and guard events to Datadog, Grafana, or any OTLP collector, enable OTLP export in ",e.jsx("strong",{children:"Settings â API & Developer â OpenTelemetry export"}),". Data is emitted as OpenTelemetry spans and metrics in OTLP/HTTP (protobuf)."]}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside mt-2",children:[e.jsx("li",{children:"Request traces with latency, model, and guard result"}),e.jsx("li",{children:"Token usage and cost metrics"}),e.jsx("li",{children:"Guard halt events with reasons"}),e.jsx("li",{children:"Agent session timelines"})]})]})}function Ka(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Governance Policies"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Policy-as-code for AI behavior enforcement."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Policy Types"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-3",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Forbidden Topic"})," â Block responses containing specified topics"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Required Grounding"})," â Require verified source data for all claims"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Confidence Threshold"})," â Minimum verification score (0-100)"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Scope Restriction"})," â Limit AI to specific knowledge domains"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Token Budget"})," â Daily/monthly token consumption limits per key"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Cost Cap"})," â Maximum monthly cost per key"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Rate Limit"})," â Requests per minute per key"]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Managing Policies"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Policies are managed under ",e.jsx("strong",{children:"Govern â Policies"}),". Organization-level policies use the ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"governance_policies"})," table with versioned JSONB configuration and are evaluated at the edge before every proxied request."]})]})}function $a(){return e.jsxs("div",{className:"space-y-4",children:[e.jsx(ie,{children:"Rate Limits & Budgets"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Control consumption at the API key level."}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Rate Limits"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"RPM"})," â Requests per minute. Default: 60. Configurable per key."]}),e.jsxs("li",{children:["Rate-limited responses return HTTP 429 with ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"Retry-After"})," header."]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Token Budgets"}),e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-2 list-disc list-inside",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Daily token budget"})," â Max tokens per 24h period. Resets at midnight UTC."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Monthly cost cap"})," â Max USD spend per calendar month."]}),e.jsxs("li",{children:["When a cap is reached, requests return HTTP 429 with ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:'error: "budget_exceeded"'})," (SDK: ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"BUDGET_EXCEEDED"}),")."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Pilot keys"})," carry a hard ",e.jsx("strong",{children:"$2.00/month"}
106)," proxy cap. The 429 payload includes a link to discuss a production pilot."]})]}),e.jsx("h3",{className:"text-sm font-semibold mt-6",children:"Enforcement"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Budget enforcement happens at the proxy layer before the request reaches the upstream AI provider. Usage is tracked in real-time via the ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"api_request_log"})," table."]})]})}const Ss={bug:{label:"Bug Report",icon:ea,color:"destructive"},suggestion:{label:"Suggestion",icon:Xt,color:"secondary"},praise:{label:"Praise",icon:Jt,color:"default"},general:{label:"General",icon:Is,color:"outline"}};function Ua(){const[s,r]=c.useState([]),[n,t]=c.useState(!0),[d,i]=c.useState("all");c.useEffect(()=>{(async()=>{try{const{data:x,error:l}=await k.from("pilot_feedback").select("*").order("created_at",{ascending:!1});if(l){console.error("Error fetching feedback:",l);return}r(x||[])}catch(x){console.error("Error fetching feedback:",x)}finally{t(!1)}})();const p=k.channel("admin-feedback").on("postgres_changes",{event:"INSERT",schema:"public",table:"pilot_feedback"},x=>{r(l=>[x.new,...l])}).subscribe();return()=>{k.removeChannel(p)}},[]);const N=d==="all"?s:s.filter(m=>m.feedback_type===d),f={total:s.length,bugs:s.filter(m=>m.feedback_type==="bug").length,suggestions:s.filter(m=>m.feedback_type==="suggestion").length,praise:s.filter(m=>m.feedback_type==="praise").length,avgRating:s.filter(m=>m.rating).reduce((m,p)=>m+(p.rating||0),0)/(s.filter(m=>m.rating).length||1)};return n?e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(G,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-4",children:[e.jsx(T,{children:e.jsxs(P,{className:"pt-4",children:[e.jsx("div",{className:"text-2xl font-bold",children:f.total}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"Total Feedback"})]})}),e.jsx(T,{children:e.jsxs(P,{className:"pt-4",children:[e.jsx("div",{className:"text-2xl font-bold text-destructive",children:f.bugs}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"Bug Reports"})]})}),e.jsx(T,{children:e.jsxs(P,{className:"pt-4",children:[e.jsx("div",{className:"text-2xl font-bold text-primary",children:f.suggestions}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"Suggestions"})]})}),e.jsx(T,{children:e.jsxs(P,{className:"pt-4",children:[e.jsx("div",{className:"text-2xl font-bold text-green-500",children:f.praise}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"Praise"})]})}),e.jsx(T,{children:e.jsxs(P,{className:"pt-4",children:[e.jsxs("div",{className:"flex items-center gap-1 text-2xl font-bold",children:[f.avgRating.toFixed(1),e.jsx(_s,{className:"h-5 w-5 fill-yellow-400 text-yellow-400"})]}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"Avg Rating"})]})})]}),e.jsxs(T,{children:[e.jsx(L,{children:e.jsx(M,{children:"Pilot Feedback"})}),e.jsx(P,{children:e.jsxs(be,{value:d,onValueChange:i,children:[e.jsxs(_e,{children:[e.jsxs(B,{value:"all",children:["All (",s.length,")"]}),e.jsxs(B,{value:"bug",children:["Bugs (",f.bugs,")"]}),e.jsxs(B,{value:"suggestion",children:["Suggestions (",f.suggestions,")"]}),e.jsxs(B,{value:"praise",children:["Praise (",f.praise,")"]})]}),e.jsx(U,{value:d,children:e.jsx(Fs,{className:"h-[500px] mt-4",children:e.jsx("div",{className:"space-y-4",children:N.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No feedback yet"}):N.map(m=>{const p=Ss[m.feedback_type]||Ss.general,x=p.icon;return e.jsx(T,{className:"border-l-4",style:{borderLeftColor:"hsl(var(--primary))"},children:e.jsx(P,{className:"pt-4",children:e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex items-start gap-3 flex-1",children:[e.jsx(x,{className:"h-5 w-5 mt-0.5 text-muted-foreground"}),e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(E,{variant:p.color,children:p.label}),m.rating&&e.jsx("div",{className:"flex items-center gap-0.5",children:Array.from({length:5}).map((l,a)=>e.jsx(_s,{className:`h-3 w-3 ${a<m.rating?"fill-yellow-400 text-yellow-400":"text-muted-foreground"}`},a))})]}),m.content&&e.jsx("p",{className:"text-sm",children:m.content}),e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsx("span",{children:pe(ne
106w Date(m.created_at),"MMM d, yyyy h:mm a")}),m.page_url&&e.jsx("span",{className:"truncate max-w-[200px]",children:m.page_url}),e.jsxs("span",{className:"font-mono text-[10px]",children:[m.user_id.slice(0,8),"..."]})]})]})]})})})},m.id)})})})})]})})]})]})}function Fa(){const[s,r]=c.useState([]),[n,t]=c.useState(!0),[d,i]=c.useState(null),[N,f]=c.useState(""),[m,p]=c.useState(""),[x,l]=c.useState(!1),{toast:a}=V(),y=async()=>{t(!0);const{data:u,error:v}=await k.from("early_access_requests").select("*").order("created_at",{ascending:!1});v?a({title:"Error loading requests",description:v.message,variant:"destructive"}):r(u||[]),t(!1)};c.useEffect(()=>{y()},[]);const j=u=>`${window.location.origin}/register?token=${u}`,b=u=>{navigator.clipboard.writeText(j(u)),a({title:"Invite link copied",description:"Share it with the user."})},C=async()=>{const u=m.trim().toLowerCase();if(!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(u)){a({title:"Enter a valid email",variant:"destructive"});return}l(!0);const v=vs(),{data:g,error:I}=await k.rpc("admin_create_invite",{p_name:N.trim()||u,p_email:u,p_invite_token:v});if(I){a({title:"Invite failed",description:I.message,variant:"destructive"}),l(!1);return}try{await k.functions.invoke("send-transactional-email",{body:{templateName:"access-approved",recipientEmail:u,idempotencyKey:`access-approved-${g}-${v.slice(0,8)}`,templateData:{name:N.trim()||u,inviteLink:j(v)}}}),a({title:"Invite sent",description:`${u} has an approved invite in their inbox.`})}catch(ee){console.error("Failed to send invite email:",ee),b(v),a({title:"Invite created, email failed",description:"The link is on your clipboard â send it manually."})}f(""),p(""),l(!1),y()},_=async(u,v)=>{i(u);const g=v==="approved"?vs():void 0,I={p_request_id:u,p_status:v};g&&(I.p_invite_token=g);const{error:ee}=await k.rpc("admin_update_early_access",I);if(ee)a({title:"Update failed",description:ee.message,variant:"destructive"});else if(a({title:`User ${v}`,description:`Early access request has been ${v}.`}),r(W=>W.map(z=>z.id===u?{...z,status:v,invite_token:g||z.invite_token}:z)),v==="approved"&&g){const W=s.find(z=>z.id===u);if(W)try{await k.functions.invoke("send-transactional-email",{body:{templateName:"access-approved",recipientEmail:W.email,idempotencyKey:`access-approved-${u}`,templateData:{name:W.name,inviteLink:j(g)}}})}catch(z){console.error("Failed to send approval email:",z)}}i(null)},h=u=>{switch(u){case"approved":return e.jsx(E,{className:"bg-emerald-500/10 text-emerald-500 border-emerald-500/20",children:"Approved"});case"rejected":return e.jsx(E,{variant:"destructive",children:"Rejected"});default:return e.jsxs(E,{variant:"secondary",children:[e.jsx(Ls,{className:"h-3 w-3 mr-1"}),"Pending"]})}};return n?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(G,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"border rounded-lg p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ws,{className:"h-4 w-4 text-primary"}),e.jsx("span",{className:"text-sm font-medium",children:"Invite by email"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Creates an approved invite and emails the registration link â no access request needed first."}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2",children:[e.jsx(H,{placeholder:"Name (optional)",value:N,onChange:u=>f(u.target.value),className:"sm:max-w-[200px]"}),e.jsx(H,{type:"email",placeholder:"[email protected]",value:m,onChange:u=>p(u.target.value)}),e.jsxs(w,{onClick:C,disabled:x,className:"gap-2 shrink-0",children:[x?e.jsx(G,{className:"h-3 w-3 animate-spin"}):e.jsx(ws,{className:"h-3 w-3"}),"Send invite"]})]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:[s.length," request(s)"]}),e.jsxs(w,{variant:"outline",size:"sm",onClick:y,className:"gap-2",children:[e.jsx(He,{className:"h-3 w-3"})," Refresh"]})]}),s.length===0?e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:"No early access requests yet."}):e.jsx("div",{className:"border rounded-lg divide-y divide-border",children:s.map(u=>e.jsxs("div",{className:"p-4 flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"font-medium text-foreground truncate",children:u.name}),h(u.status),u.invite_used&&e.jsx(E,{variant:"outline",className:"text-xs",children:"Registered"})]}),e.jsx("p",{className:"text-sm text-muted-foreground truncate",children:u.email}),u.reason&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 line-clamp-2",children:u.reason}
106),e.jsx("p",{className:"text-xs text-muted-foreground/60 mt-1",children:u.created_at?new Date(u.created_at).toLocaleDateString():""})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[u.status==="approved"&&u.invite_token&&!u.invite_used&&e.jsxs(w,{size:"sm",variant:"outline",className:"gap-1",onClick:()=>b(u.invite_token),children:[e.jsx($s,{className:"h-3 w-3"}),"Copy Link"]}),u.status!=="approved"&&e.jsxs(w,{size:"sm",variant:"outline",className:"gap-1 text-emerald-600 border-emerald-200 hover:bg-emerald-50",disabled:d===u.id,onClick:()=>_(u.id,"approved"),children:[d===u.id?e.jsx(G,{className:"h-3 w-3 animate-spin"}):e.jsx(us,{className:"h-3 w-3"}),"Approve"]}),u.status!=="rejected"&&e.jsxs(w,{size:"sm",variant:"outline",className:"gap-1 text-destructive border-destructive/20 hover:bg-destructive/5",disabled:d===u.id,onClick:()=>_(u.id,"rejected"),children:[d===u.id?e.jsx(G,{className:"h-3 w-3 animate-spin"}):e.jsx(Ue,{className:"h-3 w-3"}),"Reject"]})]})]},u.id))})]})}function za(){const[s,r]=c.useState(Ye.enabled);c.useEffect(()=>{r(Ye.enabled)},[]);const n=t=>{_t(t),r(t)};return e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(aa,{className:"h-5 w-5 text-primary"}),"TOON Compression",e.jsx(E,{variant:"outline",className:"ml-2 text-xs",children:"Beta"})]}),e.jsx(O,{children:"Token-Oriented Object Notation. Compresses structured/tabular AI context payloads (integration tool results, knowledge snapshots) by ~2â4x while keeping LoReTokens for prose. Falls back to JSON if compression isn't worthwhile. Setting persists across reloads."})]}),e.jsxs(P,{children:[e.jsxs("div",{className:"flex items-center justify-between rounded-lg border p-4",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(q,{htmlFor:"toon-toggle",className:"text-base",children:"Enable TOON for structured payloads"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Min ratio gate: ",Ye.minCompressionRatio,"à â payloads below this stay as JSON. Telemetry is logged as ",e.jsx("code",{children:"toon_compression"})," events."]})]}),e.jsx(Ce,{id:"toon-toggle",checked:s,onCheckedChange:n,"aria-label":"Toggle TOON compression"})]}),e.jsxs("p",{className:"mt-3 text-xs text-muted-foreground",children:["Status: ",e.jsx("span",{className:s?"text-emerald-500 font-medium":"text-muted-foreground",children:s?"Active â structured payloads will use TOON when worthwhile":"Off â all payloads ship as JSON"})]})]})]})}const Ga={google_sheets:!0,google_drive:!0,gmail:!0,lovable_project:!0,brainmate_native:!0,slack:!0,notion:!0,n8n:!0,zapier:!0,quickbooks:!1},Ha={google_sheets:!0,google_drive:!0,gmail:!0,lovable_project:!0,brainmate_native:!0,slack:!0,notion:!1,n8n:!0,zapier:!0,quickbooks:!1};function Va(){const{toast:s}=V(),[r,n]=c.useState([]),[t,d]=c.useState(!0),[i,N]=c.useState(null),[f,m]=c.useState({}),p=c.useMemo(()=>ra().filter(a=>!a.comingSoon),[]);async function x(){d(!0);const{data:{user:a}}=await k.auth.getUser();if(!a){d(!1);return}const{data:y}=await k.from("integrations").select("id, provider, status, last_error").eq("user_id",a.id),j=new Map;(y||[]).forEach(b=>{j.has(b.provider)||j.set(b.provider,b)}),n(p.map(b=>{const C=j.get(b.id);return{providerId:b.id,providerName:b.name,category:b.category,hasRealTest:Ga[b.id]??!1,hasRealAction:Ha[b.id]??!1,integrationId:(C==null?void 0:C.id)??null,status:(C==null?void 0:C.status)??null,lastError:(C==null?void 0:C.last_error)??null}})),d(!1)}c.useEffect(()=>{x()},[]);async function l(a){if(a.integrationId){N(a.providerId);try{const y=await na(a.integrationId);m(j=>({...j,[a.providerId]:{ok:y.success,message:y.message}})),s({title:y.success?`${a.providerName} OK`:`${a.providerName} failed`,description:y.message,variant:y.success?"default":"destructive"}),await x()}catch(y){m(j=>({...j,[a.providerId]:{ok:!1,message:(y==null?void 0:y.message)??String(y)}}))}finally{N(null)}}}return e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsx(M,{className:"text-base",children:"Connector Health"}),e.jsx(O,{children:"Pre-flight before an onboarding call. Every row should show real Test + real Action, and â for providers you've connected â a green probe. Test any connected provider without leaving Settings."})]}),e.jsx(P,{children:t?e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(G,{className:"h-4 w-4 animate-spin"})," Loading providersâ¦"]}):e.jsx("div",{className:"overflow-auto border border-border/60 rounded-md",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/40",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-3 py-2 font-medium",children:"Provider"}),e.jsx("th",{className:"text-left px-3 py-2 font-medium",children:"Category"}),e.jsx("th",{className:"text-center px-3 py-2 font-medium",children:"Real Test"}),e.jsx("th",{className:"text-center px-3 py-2 font-medium",children:"Real Action"}),e.jsx("th",{className:"text-left px-3 py-2 font-medium",children:"My connection"}),e.jsx("th",{className:"text-right px-3 py-2 font-medium",children:"Probe"})]})}),e.jsx("tbody",{children:r.map(a=>{const y=f[a.providerId];return e.jsxs("tr",{className:"border-t border-border/60",children:[e.jsx("td",{className:"px-3 py-2 font-medium",children:a.providerName}),e.jsx("td",{className:"px-3 py-2 text-muted-foreground",children:a.category}),e.jsx("td",{className:"px-3 py-2 text-center",children:a.hasRealTest?e.jsx(ks,{className:"inline h-4 w-4 text-emerald-500"}):e.jsx(Ue,{className:"inline h-4 w-4 text-muted-foreground"})}),e.jsx("td",{className:"px-3 py-2 text-center",children:a.hasRealAction?e.jsx(ks,{className:"inline h-4 w-4 text-emerald-500"}):e.jsx(Ue,{className:"inline h-4 w-4 text-muted-foreground"})}),e.jsxs("td",{className:"px-3 py-2",children:[a.integrationId?e.jsx(E,{variant:"outline",className:a.status==="connected"?"border-emerald-500/40 text-emerald-300":a.status==="error"?"border-destructive/40 text-destructive":"",children:a.status??"configured"}):e.jsx("span",{className:"text-muted-foreground text-xs",children:"not connected"}),y&&e.jsx("div",{className:`mt-1 text-xs ${y.ok?"text-emerald-500":"text-destructive"}`,children:y.message}),!y&&a.lastError&&e.jsx("div",{className:"mt-1 text-xs text-destructive break-all",children:a.lastError})]}),e.jsx("td",{className:"px-3 py-2 text-right",children:e.jsxs(w,{size:"sm",variant:"outline",disabled:!a.integrationId||i===a.providerId,onClick:()=>l(a),className:"gap-1.5",children:[i===a.providerId?e.jsx(G,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ve,{className:"h-3.5 w-3.5"}),"Run probe"]})})]},a.providerId)})})]})})})]})}function Ae(s){return s instanceof Error?s.message:String(s)}function Wa(){const{toast:s}=V(),[r,n]=c.useState(!1),[t,d]=c.useState(null),[i,N]=c.useState(!1),[f,m]=c.useState(null),[p,x]=c.useState(!1),[l,a]=c.useState(null),[y,j]=c.useState(!1),[b,C]=c.useState(null),_=async()=>{n(!0),d(null);try{const{data:g,error:I}=await k.functions.invoke("backfill-internal-sessions",{body:{}});if(I)throw I;d(g),s({title:"Backfill complete",description:`Created ${g.sessions_created} sessions and ${g.steps_created} steps. ${g.groups_already_backfilled} groups already backfilled.`})}catch(g){s({title:"Backfill failed",description:Ae(g),variant:"destructive"})}finally{n(!1)}},h=async()=>{N(!0),m(null);try{const{data:g,error:I}=await k.functions.invoke("backfill-proxy-sessions",{body:{}});if(I)throw I;m(g),s({title:"Proxy backfill complete",description:`Created ${g.sessions_created} sessions and ${g.steps_created} steps. ${g.groups_already_backfilled} groups already backfilled.`})}catch(g){s({title:"Proxy backfill failed",description:Ae(g),variant:"destructive"})}finally{N(!1)}},u=async()=>{x(!0),a(null);try{const{data:g,error:I}=await k.functions.invoke("backfill-ab-comparisons",{body:{days:30,limit:500}});if(I)throw I;a(g),s({title:"A/B backfill complete",description:`Inserted ${g.inserted} comparisons (skipped ${g.skipped_existing} existing).`})}catch(g){s({title:"A/B backfill failed",description:Ae(g),variant:"destructive"})}finally{x(!1)}},v=async()=>{j(!0),C(null);try{const{data:g,error:I}=await k.functions.invoke("event-coverage-report",{body:{}});if(I)throw I;C(g),s({title:"Coverage report ready",description:`${g.live_event_types} live, ${g.warm_event_types} warm of ${g.distinct_event_types} types.`})}catch(g){s({title:"Coverage report failed",description:Ae(g),variant:"destructive"})}finally{j(!1)}};return e.jsxs("div",{className:"space-y-6",children:[e.jsx(za,{}),e.jsxs(be,{defaultValue:"early-access",children:[e.jsxs(_e,{children:[e.jsxs(B,{value:"early-access",className:"gap-2",children:[e.jsx(Ht,{className:"h-4 w-4"}),"Early Access"]}),e.jsxs(B,{value:"feedback",className:"gap-2",children:[e.jsx(Is,{className:"h-4 w-4"}),"Feedback"]}),e.jsxs(B,{value:"pilot-guide",className:"gap-2",children:[e.jsx(wt,{className:"h-4 w-4"}),"Pilot Guide"]}),e.jsxs(B,{value:"data-tools",className:"gap-2",children:[e.jsx(ce,{className:"h-4 w-4"}),"Data Tools"]}),e.jsxs(B,{value:"connectors",className:"gap-2",children:[e.jsx(Gs,{className:"h-4 w-4"}),"Connectors"]})]}),e.jsx(U,{value:"early-access",children:e.jsx(Fa,{})}),e.jsx(U,{value:"feedback",children:e.jsx(Ua,{})}),e.jsx(U,{value:"pilot-guide",children:e.jsx("div",{className:"space-y-4 mt
106-4",children:e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsx(M,{className:"text-base",children:"Pilot Program Overview"}),e.jsx(O,{children:"Key information for managing pilot participants"})]}),e.jsx(P,{children:e.jsxs(ta,{type:"single",collapsible:!0,className:"w-full",children:[e.jsxs(Xe,{value:"onboarding",children:[e.jsx(es,{children:"Onboarding Flow"}),e.jsxs(ss,{className:"text-sm text-muted-foreground space-y-2",children:[e.jsx("p",{children:'1. User applies via the landing page "Get API Key" form'}),e.jsx("p",{children:"2. Admin reviews application in Early Access tab"}),e.jsx("p",{children:"3. Admin approves â user receives invite email"}),e.jsx("p",{children:"4. User registers, creates org, gets API key"}),e.jsx("p",{children:"5. User points their AI client at BrainMate's governed proxy"})]})]}),e.jsxs(Xe,{value:"security",children:[e.jsx(es,{children:"Security & Data"}),e.jsx(ss,{className:"text-sm text-muted-foreground space-y-2",children:e.jsx("p",{children:"All data encrypted in transit and at rest. Tenant isolation via RLS policies. Hash-chained audit log for compliance."})})]}),e.jsxs(Xe,{value:"faq",children:[e.jsx(es,{children:"FAQ"}),e.jsxs(ss,{className:"text-sm text-muted-foreground space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Q: Can pilot users invite team members?"}),e.jsx("br",{}),"A: Not yet â each tester has their own account. Multi-user is on the roadmap."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Q: What happens after the pilot?"}),e.jsx("br",{}),"A: Pilot participants transition to early adopter pricing. All data is preserved."]})]})]})]})})]})})}),e.jsx(U,{value:"data-tools",children:e.jsxs("div",{className:"space-y-4 mt-4",children:[e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(ce,{className:"h-4 w-4"}),"Backfill Internal Sessions"]}),e.jsx(O,{children:"Reconstruct historical BrainMate Mate runs as agent sessions from telemetry events. Scans the last 90 days, only sessionizes multi-step runs (â¥2 mate invocations or DAG runs). Idempotent â safe to re-run."})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsxs(w,{onClick:_,disabled:r,className:"gap-2",children:[r?e.jsx(G,{className:"h-4 w-4 animate-spin"}):e.jsx(ce,{className:"h-4 w-4"}),r?"Backfillingâ¦":"Run Backfill"]}),t&&e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1 p-3 rounded-md bg-muted/50",children:[e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:t.sessions_created})," sessions created"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:t.steps_created})," steps created"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:t.groups_already_backfilled})," groups already backfilled (skipped)"]}),e.jsxs("div",{className:"pt-1",children:["View results in ",e.jsx("span",{className:"text-muted-foreground",children:"Observe â Agent Sessions â BrainMate Mates tab"})]})]})]})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(ce,{className:"h-4 w-4"}),"Backfill Proxy Sessions"]}),e.jsxs(O,{children:["Reconstruct historical external proxy traffic as agent sessions from ",e.jsx("code",{children:"api_request_log"}),". Scans the last 90 days, groups by api_key + 30-minute bucket. Idempotent â safe to re-run. Backlinks log rows so they stop showing as synthetic."]})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsxs(w,{onClick:h,disabled:i,className:"gap-2",children:[i?e.jsx(G,{className:"h-4 w-4 animate-spin"}):e.jsx(ce,{className:"h-4 w-4"}),i?"Backfillingâ¦":"Run Proxy Backfill"]}),f&&e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1 p-3 rounded-md bg-muted/50",children:[e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:f.sessions_created})," sessions created"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:f.steps_created})," steps created"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:f.groups_already_backfilled})," groups already backfilled (skipped)"]}),e.jsxs("div",{className:"pt-1",children:["View results in ",e.jsx("span",{className:"text-muted-foreground",children:"Observe â Agent Sessions â Proxy (External Apps) â Live Proxy Traffic"})]})]})]})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Hs,{className:"h-4 w-4 text-emerald-500"}),"Telemetry Fidelity: Verified API Only"]}),e.jsxs(O,{children:["All cost, token, and savings KPIs are now derived ",e.jsx("strong",{children:"exclusively"})," from real provider API responses (tagged ",e.jsx("code",{children:"verified=api"}),"). The previous backfill tools synthesized historical data from message text and guessed models, which polluted the dashboard with ~$11K of fabricated cost. Those rows have been purged and the backfill action has been permanently removed. If a model call does not return real",e.jsx("code",{children:" usage"}),", the chat pipeline now ",e.jsx("strong",{children:"skips"})," the telemetry write rather than estimating."]})]}),e.jsx(P,{className:"space-y-2",children:e.jsxs("div",{className:"text-xs text-muted-foreground p-3 rounded-md bg-emerald-500/5 border border-emerald-500/20",children:[e.jsx("div",{className:"text-emerald-500 font-medium mb-1",children:"Acknowledged tradeoff"}),"Apr 6 â ~Apr 24 will show low activity because real token counts were never logged during that window. This is the honest answer â guessed numbers will not be substituted."]})})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Cs,{className:"h-4 w-4 text-primary"}),"Backfill A/B Comparisons"]}),e.jsxs(O,{children:["Re-prices the last 30 days of successful proxy requests (up to 500) at the GPT-5 baseline rate and inserts the difference into ",e.jsx("code",{children:"ab_test_results"}),". No external API calls â savings are computed on the same token counts. Idempotent."]})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsxs(w,{onClick:u,disabled:p,className:"gap-2",children:[p?e.jsx(G,{className:"h-4 w-4 animate-spin"}):e.jsx(Cs,{className:"h-4 w-4"}),p?"Backfillingâ¦":"Run A/B Backfill"]}),l&&e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1 p-3 rounded-md bg-muted/50",children:[e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:l.inserted})," rows inserted"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:l.skipped_existing})," already existed (skipped)"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:l.scanned})," proxy rows scanned"]})]})]})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"text-base flex items-center gap-2",children:[e.jsx(Fe,{className:"h-4 w-4 text-primary"}),"Event Coverage Report"]}),e.jsxs(O,{children:["Lists every telemetry event type observed in the last 30 days with its emission count. ",e.jsx("strong",{children:"Live"})," = â¥10 emissions, ",e.jsx("strong",{children:"warm"})," = 1â9, missing = cold. Use this to identify dead event constants."]})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsxs(w,{onClick:v,disabled:y,className:"gap-2",children:[y?e.jsx(G,{className:"h-4 w-4 animate-spin"}):e.jsx(Fe,{className:"h-4 w-4"}),y?"Loadingâ¦":"Run Coverage Report"]}),b&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"text-xs text-muted-foreground p-3 rounded-md bg-muted/50 space-y-1",children:[e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:b.total_events.toLocaleStr
106ing()})," total events · ",e.jsx("strong",{className:"text-foreground",children:b.distinct_event_types})," distinct types"]}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-emerald-500",children:b.live_event_types})," live · ",e.jsx("strong",{className:"text-amber-500",children:b.warm_event_types})," warm"]})]}),e.jsx("div",{className:"max-h-80 overflow-auto border rounded-md text-xs",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{className:"sticky top-0 bg-muted/80 backdrop-blur",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-3 py-2",children:"Event type"}),e.jsx("th",{className:"text-right px-3 py-2",children:"Count"}),e.jsx("th",{className:"text-right px-3 py-2",children:"Status"})]})}),e.jsx("tbody",{children:b.types.map(g=>e.jsxs("tr",{className:"border-t",children:[e.jsx("td",{className:"px-3 py-1.5 font-mono",children:g.event_type}),e.jsx("td",{className:"px-3 py-1.5 text-right tabular-nums",children:g.count.toLocaleString()}),e.jsx("td",{className:"px-3 py-1.5 text-right",children:e.jsx("span",{className:g.status==="live"?"text-emerald-500":g.status==="warm"?"text-amber-500":"text-muted-foreground",children:g.status})})]},g.event_type))})]})})]})]})]})]})}),e.jsx(U,{value:"connectors",children:e.jsx("div",{className:"mt-4",children:e.jsx(Va,{})})})]})]})}const As=["recall","remember","ingest","list"];function Qa(){const{organization:s}=je(),{activeEntity:r,entities:n,viewMode:t}=Ms(),{user:d}=we(),{toast:i}=V(),[N,f]=c.useState([]),[m,p]=c.useState(!0),[x,l]=c.useState(!1),[a,y]=c.useState(""),[j,b]=c.useState(["recall","remember","ingest","list"]),[C,_]=c.useState(!1),[h,u]=c.useState(null),[v,g]=c.useState(!1),[I,ee]=c.useState(""),[W,z]=c.useState(""),[de,S]=c.useState([]),[D,re]=c.useState(null),[ge,ps]=c.useState(!1),[Se,Qe]=c.useState(!1),it=new Map(n.map(o=>[o.id,o])),lt=new Map(de.map(o=>[o.id,o])),js=o=>o?de.filter(A=>A.tenant_id===o):de,gs=n.length>0,ot=t==="entity"&&r?r.name:t==="unassigned"?"Unassigned":"All entities";async function me(){if(!(s!=null&&s.id)||!(d!=null&&d.id))return;p(!0);let o=k.from("api_keys").select("id, name, key_prefix, project_id, tenant_id, scopes_allowed, capabilities, rate_limit_rpm, created_at, last_used_at, revoked_at, is_active, total_requests").eq("org_id",s.id);t==="entity"&&r?o=o.eq("tenant_id",r.id):t==="unassigned"&&(o=o.is("tenant_id",null));const{data:A,error:R}=await o.order("created_at",{ascending:!1});R&&i({title:"Failed to load keys",description:R.message,variant:"destructive"}),f(A??[]);const{data:$}=await k.from("projects").select("id, name, tenant_id").order("name");S($??[]),p(!1)}async function ct(o,A){var $;const{error:R}=await k.from("api_keys").update({project_id:A}).eq("id",o);if(R){i({title:"Failed to update project link",description:R.message,variant:"destructive"});return}if(A){const{data:fe}=await k.from("scopes").select("id").eq("project_id",A).limit(1);(!fe||fe.length===0)&&await k.from("scopes").insert({project_id:A,name:"default",status:"active"})}i({title:A?"Project linked":"Project unlinked",description:A?`This key now grounds answers in "${(($=lt.get(A))==null?void 0:$.name)??"the project"}".`:"Memory injection disabled for this key."}),me()}c.useEffect(()=>{me()},[s==null?void 0:s.id,r==null?void 0:r.id,t,d==null?void 0:d.id]);async function dt(){const o=I||(r==null?void 0:r.id);if(!(s!=null&&s.id)||!(d!=null&&d.id)||!a.trim()||!o){i({title:"Pick an entity first",description:"Choose which entity this key belongs to.",variant:"destructive"});return}_(!0);const{data:A,error:R}=await k.rpc("create_memory_api_key",{p_org_id:s.id,p_name:a.trim(),p_tenant_id:o,p_scopes_allowed:"all",p_capabilities:j,p_rate_limit_rpm:60,p_default_project_id:W||null});if(_(!1),R){i({title:"Failed to create key",description:R.message,variant:"destructive"});return}const $=A==null?void 0:A.raw_key;u($),y(""),await me()}async function mt(){var $;const o=D;if(!o||!(s!=null&&s.id))return;Qe(!0);const{data:A,error:R}=await k.rpc("create_memory_api_key",{p_org_id:s.id,p_name:o.name,p_tenant_id:o.tenant_id,p_scopes_allowed:o.scopes_allowed??"all",p_capabilities:($=o.capabilities)!=null&&$.length?o.capabilities:As,p_rate_limit_rpm:o.rate_limit_rpm??60,p_default_project_id:o.project_id});if(R){Qe(!1),i({title:"Rotation failed â nothing changed",description:R.message,variant:"destructive"});return}if(!ge){const{error:fe}=await k.rpc("revoke_memory_api_key",{p_key_id:o.id});fe&&i({title:"New key created, old key still active",description:`Could not retire the old key: ${fe.message}`,variant:"destructive"})}Qe(!1),re(null),u(A==null?void 0:A.raw_key),g(!1),l(!0),await me()}async function xt(o){if(!confirm("Revoke this key? External tools using it will stop working immediately."))return;const{error:A}=await k.rpc("revoke_memory_api_key",{p_key_id:o});if(A){i({title:"Failed to revoke",description:A.message,variant:"destructive"});return}i({title:"Key revoked"}),me()}async function ut(o,A){if(!confirm(`Permanently remove the revoked key "${A}"? This only clears the record â it is already disabled.`))return;const{error:R}=await k.from("api_keys").delete().eq("id",o);if(R){i({title:"Couldn't remove key",description:R.message,variant:"destructive"});return}i({title:"Key removed"}),me()}async function ht(){const o=N.filter(R=>R.revoked_at||!R.is_active).map(R=>R.id);if(!o.length||!confirm(`Permanently remove ${o.length} revoked key${o.length>
1061?"s":""}? They are already disabled.`))return;const{error:A}=await k.from("api_keys").delete().in("id",o);if(A){i({title:"Couldn't clear revoked keys",description:A.message,variant:"destructive"});return}i({title:`Removed ${o.length} revoked key${o.length>1?"s":""}`}),me()}function pt(o){navigator.clipboard.writeText(o),i({title:"Copied"})}function jt(o){const A=new Blob([`# BrainMate API key 107# Store this somewhere safe â it will not be shown again. 108 109${o} 110`],{type:"text/plain"}),R=URL.createObjectURL(A),$=document.createElement("a");$.href=R,$.download=`brainmate-api-key-${new Date().toISOString().slice(0,10)}.txt`,document.body.appendChild($),$.click(),$.remove(),URL.revokeObjectURL(R)}return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(T,{children:[e.jsxs(L,{className:"flex flex-row items-start justify-between",children:[e.jsxs("div",{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(Vs,{className:"h-5 w-5"})," Memory API keys"]}),e.jsxs(O,{children:["Let Claude Desktop, Cursor, ChatGPT (with MCP), or any agent read & write your BrainMate memory.",e.jsxs(Ds,{to:"/developers",className:"ml-2 inline-flex items-center gap-1 text-primary hover:underline",children:["Docs ",e.jsx(Ve,{className:"h-3 w-3"})]})]})]}),e.jsx(kt,{children:e.jsxs(Ct,{children:[e.jsx(St,{asChild:!0,children:e.jsx("span",{children:e.jsxs(w,{onClick:()=>{var R;u(null),g(!1);const o=(r==null?void 0:r.id)??((R=n[0])==null?void 0:R.id)??"";ee(o);const A=de.filter($=>$.tenant_id===o);z(A.length===1?A[0].id:""),l(!0)},disabled:!gs,children:[e.jsx(ue,{className:"h-4 w-4 mr-2"})," New key"]})})}),!gs&&e.jsx(At,{children:"Create an entity first â keys must be scoped to one."})]})})]}),e.jsxs(P,{children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2 rounded-md border border-border/60 bg-muted/30 px-3 py-2 text-xs text-muted-foreground",children:[e.jsx("span",{children:"Showing keys for:"}),e.jsx("span",{className:"font-medium text-foreground",children:ot}),t==="all"&&e.jsx("span",{className:"ml-1",children:"â switch the top-bar entity to isolate to one entity."}),N.some(o=>o.revoked_at||!o.is_active)&&e.jsxs(w,{variant:"ghost",size:"sm",className:"ml-auto h-7 text-xs text-destructive",onClick:ht,children:[e.jsx(X,{className:"h-3.5 w-3.5 mr-1.5"})," Clear revoked keys"]})]}),m?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loadingâ¦"}):N.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No keys yet. Create one to start using BrainMate from external tools."}):e.jsx("div",{className:"space-y-2",children:N.map(o=>{const A=o.tenant_id?it.get(o.tenant_id):null;return e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:o.name}),A?e.jsxs(E,{variant:"outline",className:"gap-1.5",children:[e.jsx("span",{className:"h-2 w-2 rounded-full",style:{backgroundColor:A.color}}),A.name]}):o.tenant_id?e.jsx(E,{variant:"outline",className:"text-muted-foreground",children:"Other entity"}):e.jsx(E,{variant:"outline",className:"text-muted-foreground",children:"Unassigned"}),!o.project_id&&!o.revoked_at&&e.jsxs(E,{variant:"outline",className:"gap-1 text-amber-500 border-amber-500/40",children:[e.jsx(ye,{className:"h-3 w-3"})," Ungrounded â no memory injected"]}),o.revoked_at?e.jsx(E,{variant:"destructive",children:"Revoked"}):o.is_active?e.jsx(E,{variant:"outline",className:"text-emerald-500 border-emerald-500/30",children:"Active"}):e.jsx(E,{variant:"secondary",children:"Inactive"})]}),e.jsxs("div",{className:"text-xs text-muted-foreground font-mono",children:[o.key_prefix,"â¦"]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[o.total_requests.toLocaleString()," requests · ",o.rate_limit_rpm,"/min ·"," ","created ",pe(new Date(o.created_at),"PP"),o.last_used_at&&e.jsxs(e.Fragment,{children:[" · last used ",pe(new Date(o.last_used_at),"PP")]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Capabilities: ",(o.capabilities??[]).join(", ")||"â"]}
110),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Memory:"}),e.jsxs(Q,{value:o.project_id??"none",onValueChange:R=>ct(o.id,R==="none"?null:R),children:[e.jsx(Y,{className:"h-7 w-[220px] text-xs",children:e.jsx(J,{placeholder:"No project"})}),e.jsxs(Z,{children:[e.jsx(K,{value:"none",children:"No project (ungrounded)"}),js(o.tenant_id).map(R=>e.jsx(K,{value:R.id,children:R.name},R.id))]})]})]})]}),!o.revoked_at&&o.is_active?e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsxs(w,{variant:"outline",size:"sm",onClick:()=>{re(o),ps(!1)},children:[e.jsx(He,{className:"h-4 w-4 mr-2"})," Rotate"]}),e.jsx(w,{variant:"ghost",size:"icon",onClick:()=>xt(o.id),children:e.jsx(X,{className:"h-4 w-4 text-destructive"})})]}):e.jsxs(w,{variant:"ghost",size:"sm",onClick:()=>ut(o.id,o.name),children:[e.jsx(X,{className:"h-4 w-4 mr-2 text-destructive"})," Remove"]})]},o.id)})})]})]}),e.jsx(os,{open:x,onOpenChange:o=>{h&&!v&&!o||(l(o),o||(u(null),g(!1)))},children:e.jsx(cs,{children:h?e.jsxs(e.Fragment,{children:[e.jsxs(Pe,{children:[e.jsx(Re,{children:"Copy your key now"}),e.jsxs(ts,{className:"flex items-start gap-2 text-amber-500",children:[e.jsx(ye,{className:"h-4 w-4 mt-0.5 flex-none"}),e.jsx("span",{children:"This is the only time the full key will be shown. Store it somewhere safe â you cannot recover it later."})]})]}),e.jsxs("div",{className:"space-y-3 py-2",children:[e.jsx("div",{className:"rounded-md border border-border bg-muted/30 p-3 font-mono text-sm break-all",children:h}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs(w,{onClick:()=>pt(h),variant:"secondary",children:[e.jsx(ke,{className:"h-4 w-4 mr-2"})," Copy"]}),e.jsxs(w,{onClick:()=>jt(h),variant:"secondary",children:[e.jsx(ia,{className:"h-4 w-4 mr-2"})," Download"]})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-muted-foreground pt-2 cursor-pointer",children:[e.jsx(as,{checked:v,onCheckedChange:o=>g(!!o)}),"I've saved this key somewhere safe"]})]}),e.jsx(Ee,{children:e.jsx(w,{disabled:!v,onClick:()=>{l(!1),u(null),g(!1)},children:"Done"})})]}):e.jsxs(e.Fragment,{children:[e.jsxs(Pe,{children:[e.jsx(Re,{children:"Create Memory API key"}),e.jsx(ts,{children:"This key gives external tools access to your BrainMate projects."})]}),e.jsxs("div",{className:"space-y-4 py-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(q,{children:"Entity"}),e.jsxs(Q,{value:I,onValueChange:o=>{ee(o);const A=de.filter(R=>R.tenant_id===o);z(A.length===1?A[0].id:"")},children:[e.jsx(Y,{children:e.jsx(J,{placeholder:"Select an entity"})}),e.jsx(Z,{children:n.map(o=>e.jsx(K,{value:o.id,children:o.name},o.id))})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"This key will only see this entity's projects and memory."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(q,{children:"Project (memory source)"}),e.jsxs(Q,{value:W,onValueChange:z,children:[e.jsx(Y,{children:e.jsx(J,{placeholder:"Select a project"})}),e.jsx(Z,{children:js(I).map(o=>e.jsx(K,{value:o.id,children:o.name},o.id))})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Without a project, requests on this key run ungrounded â no memory is injected."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(q,{htmlFor:"name",children:"Name"}),e.jsx(H,{id:"name",value:a,onChange:o=>y(o.target.value),placeholder:"e.g. Claude Desktop, Cursor laptop"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(q,{children:"Capabilities"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:As.map(o=>e.jsxs("label",{className:"flex items-center gap-2 rounded-md border border-border p-2 text-sm cursor-pointer",children:[e.jsx(as,{checked:j.includes(o),onCheckedChange:A=>
110b(R=>A?Array.from(new Set([...R,o])):R.filter($=>$!==o))}),e.jsx("span",{className:"font-mono",children:o})]},o))})]})]}),e.jsxs(Ee,{children:[e.jsx(w,{variant:"ghost",onClick:()=>l(!1),children:"Cancel"}),e.jsx(w,{onClick:dt,disabled:C||!a.trim()||j.length===0||!I||!W,children:C?"Creatingâ¦":"Create key"})]})]})})}),e.jsx(os,{open:!!D,onOpenChange:o=>{!o&&!Se&&re(null)},children:e.jsxs(cs,{children:[e.jsxs(Pe,{children:[e.jsxs(Re,{children:["Rotate â",D==null?void 0:D.name,"â"]}),e.jsx(ts,{children:"We'll create a new secret with the same entity, project, capabilities and rate limit, then retire this one. Anything still using the old secret stops working once it's retired."})]}),e.jsxs("label",{className:"flex items-start gap-2 text-sm cursor-pointer py-2",children:[e.jsx(as,{checked:ge,onCheckedChange:o=>ps(!!o),className:"mt-0.5"}),e.jsxs("span",{children:["Keep the old key working for now",e.jsx("span",{className:"block text-xs text-muted-foreground",children:"Use this if you need time to update your app â you can delete the old key afterwards."})]})]}),e.jsxs(Ee,{children:[e.jsx(w,{variant:"ghost",onClick:()=>re(null),disabled:Se,children:"Cancel"}),e.jsx(w,{onClick:mt,disabled:Se,children:Se?"Rotatingâ¦":"Rotate key"})]})]})})]})}const We="https://api.brainmate.dev/v1/turns",Ya=`curl -X POST ${We} \\ 111 -H "Authorization: Bearer $BRAINMATE_API_KEY" \\ 112 -H "Content-Type: application/json" \\ 113 -d '{ 114 "sourceClient": "n8n", 115 "externalThreadId": "support-ticket-4821", 116 "userMessage": "Customer asked about refund policy", 117 "assistantMessage": "Refunds are issued within 14 days of purchase." 118 }'`,Ja=`// n8n â HTTP Request node 119Method: POST 120URL: ${We} 121Auth: Header Auth -> Authorization: Bearer {{$env.BRAINMATE_API_KEY}} 122Body (JSON): 123{ 124 "sourceClient": "n8n", 125 "externalThreadId": "{{$json.conversationId}}", 126 "userMessage": "{{$json.input}}", 127 "assistantMessage": "{{$json.output}}" 128}`,Za=`// Zapier â Webhooks by Zapier -> POST 129URL: ${We} 130Payload Type: JSON 131Headers: Authorization | Bearer YOUR_BM_LIVE_KEY 132Data: 133 sourceClient = zapier 134 externalThreadId = {{conversation_id}} 135 userMessage = {{question}} 136 assistantMessage = {{answer}}`,Xa="npm install @brainmate/sdk",er=`import { BrainMate } from "@brainmate/sdk"; 137 138const bm = new BrainMate({ apiKey: process.env.BRAINMATE_API_KEY! }); 139const { results } = await bm.recall({ projectId, query: "What did we decide about pricing?" });`,sr=`import { BrainMate } from "@brainmate/sdk"; 140 141const bm = new BrainMate({ apiKey: process.env.BRAINMATE_API_KEY! }); 142 143// 1. Recall â what has the org already decided? 144const memory = await bm.recall({ 145 projectId, 146 query: "refund policy for enterprise tier", 147 limit: 8, 148 includeEvidence: true, 149}); 150 151// 2. Act â your own model call / business logic here. 152 153// 3. Remember â persist the new decision for every other client. 154await bm.remember({ 155 projectId, 156 insights: [ 157 { type: "DECISION", text: "Approved 30-day refund exceptions for enterprise SOC2 pilots" }, 158 ], 159});`,tr=`// app/api/chat/route.ts â Next.js + Vercel AI SDK 160import { BrainMate } from "@brainmate/sdk"; 161import { brainMateMemoryProvider } from "@brainmate/sdk/ai-sdk"; 162import { streamText } from "ai"; 163import { openai } from "@ai-sdk/openai"; 164 165const bm = new BrainMate({ apiKey: process.env.BRAINMATE_API_KEY! }); 166 167export async function POST(req: Request) { 168 const { messages, projectId } = await req.json(); 169 170 const { systemPrompt } = await brainMateMemoryProvider({ 171 bm, 172 projectId, 173 query: messages[messages.length - 1].content, 174 }); 175 176 return streamText({ 177 model: openai("gpt-4o"), 178 system: systemPrompt, 179 messages, 180 }).toDataStreamResponse(); 181}`,ar=`# No SDK? Any language can call the same endpoints. 182curl -X POST https://api.brainmate.dev/v1/memory/recall \\ 183 -H "Authorization: Bearer $BRAINMATE_API_KEY" \\ 184 -H "Content-Type: application/json" \\ 185 -d '{ "projectId": "proj_abc", "query": "pricing decisions", "limit": 5 }'`;function oe({code:s}){const{toast:r}=V();return e.jsxs("div",{className:"relative",children:[e.jsx("pre",{className:"overflow-x-auto rounded-md border border-border bg-muted/40 p-3 text-xs font-mono leading-relaxed",children:s}),e.jsx(w,{variant:"ghost",size:"icon",className:"absolute right-1.5 top-1.5 h-7 w-7",onClick:()=>{navigator.clipboard.writeText(s),r({title:"Copied"})},children:e.jsx(ke,{className:"h-3.5 w-3.5"})})]})}function rr(){return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(Ws,{className:"h-5 w-5"})," Send conversations from any tool"]}),e.jsxs(O,{children:["Post a message pair to ",e.jsx("span",{className:"font-mono",children:We})," with one of your keys and it joins the same memory as Claude Desktop, Cursor and Telegram. No SDK required."]})]}),e.jsxs(P,{children:[e.jsxs(be,{defaultValue:"curl",children:[e.jsxs(_e,{children:[e.jsx(B,{value:"curl",children:"curl"}),e.jsx(B,{value:"n8n",children:"n8n"}),e.jsx(B,{value:"zapier",children:"Zapier"})]}),e.jsx(U,{value:"curl",className:"mt-3",children:e.jsx(oe,{code:Ya})}),e.jsx(U,{value:"n8n",className:"mt-3",children:e.jsx(oe,{code:Ja})}),e.jsx(U,{value:"zapier",className:"mt-3",children:e.jsx(oe,{code:Za})})]}),e.jsxs("p",{className:"mt-3 text-xs text-muted-foreground",children:["Either send a paired ",e.jsx("span",{className:"font-mono",children:"userMessage"})," /"," ",e.jsx("span",{className:"font-mono",children:"assistantMessage"}),", or a single"," ",e.jsx("span",{className:"font-mono",children:"role"})," + ",e.jsx("span",{className:"font-mono",children:"content"})," turn."]})]})]}),e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(la,{className:"h-5 w-5"})," TypeScript SDK",e.jsx(E,{variant:"outline",className:"font-mono text-xs",children:"@brainmate/sdk"})]}),e.jsx(O,{children:"Three lines to pull governed, cited context into any N
185ode or edge app â then working patterns for agents, Next.js chat routes and non-JavaScript stacks."})]}),e.jsxs(P,{className:"space-y-3",children:[e.jsx(oe,{code:Xa}),e.jsxs(be,{defaultValue:"quickstart",children:[e.jsxs(_e,{children:[e.jsx(B,{value:"quickstart",children:"Quickstart"}),e.jsx(B,{value:"agent",children:"Agent loop"}),e.jsx(B,{value:"ai-sdk",children:"Vercel AI SDK"}),e.jsx(B,{value:"fetch",children:"Raw HTTP"})]}),e.jsx(U,{value:"quickstart",className:"mt-3",children:e.jsx(oe,{code:er})}),e.jsxs(U,{value:"agent",className:"mt-3",children:[e.jsx(oe,{code:sr}),e.jsx("p",{className:"mt-2 text-xs text-muted-foreground",children:"Recall â act â remember. Anything written back is visible to every other connected client in the same entity."})]}),e.jsxs(U,{value:"ai-sdk",className:"mt-3",children:[e.jsx(oe,{code:tr}),e.jsxs("p",{className:"mt-2 text-xs text-muted-foreground",children:["Requires ",e.jsx("span",{className:"font-mono",children:"ai"})," and"," ",e.jsx("span",{className:"font-mono",children:"@ai-sdk/openai"}),". Keep the key server-side."]})]}),e.jsx(U,{value:"fetch",className:"mt-3",children:e.jsx(oe,{code:ar})})]}),e.jsxs("a",{href:"https://brainmate.dev/developers",target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1 text-xs text-primary hover:underline",children:["Full SDK reference ",e.jsx(Ve,{className:"h-3 w-3"})]})]})]})]})}const nr={recall_memory:"Recall memory",read_repo_file:"Read repo file",search_repo:"Search repo",query_telemetry:"Query telemetry",remember_insight:"Remember insight (Phase 2)"};function ir(){const s="ABCDEFGHJKMNPQRSTUVWXYZ23456789";let r="";for(let n=0;n<6;n++)r+=s[Math.floor(Math.random()*s.length)];return r}function lr(){const{user:s}=we(),{toast:r}=V(),{projects:n}=oa(),[t,d]=c.useState(null),[i,N]=c.useState([]),[f,m]=c.useState(!0);async function p(){if(!s)return;const{data:_}=await k.from("telegram_users").select("*").eq("user_id",s.id).maybeSingle();if(d(_),_!=null&&_.id){const{data:h}=await k.from("telegram_messages").select("id,direction,body,tokens_in,tokens_out,cost_usd,tools_used,model,created_at").eq("telegram_user_id",_.id).order("created_at",{ascending:!1}).limit(20);N(h||[])}m(!1)}c.useEffect(()=>{p()},[s==null?void 0:s.id]);async function x(){if(!s)return;const _=ir(),h=new Date(Date.now()+15*60*1e3).toISOString(),u={pair_code:_,pair_code_expires_at:h};t?await k.from("telegram_users").update(u).eq("id",t.id):await k.from("telegram_users").insert({user_id:s.id,telegram_user_id:-Date.now(),...u}),r({title:"Pairing code ready",description:`Send /start ${_} to the bot. Expires in 15 minutes.`}),p()}async function l(){t&&(await k.from("telegram_users").delete().eq("id",t.id),d(null),N([]),r({title:"Unlinked"}))}async function a(_){t&&(await k.from("telegram_users").update({active_project_id:_}).eq("id",t.id),p())}async function y(_,h){if(!t)return;const u={...t.tools_enabled||{},[_]:h};await k.from("telegram_users").update({tools_enabled:u}).eq("id",t.id),p()}const j=i.reduce((_,h)=>_+Number(h.cost_usd||0),0),b=i.reduce((_,h)=>_+(h.tokens_in||0)+(h.tokens_out||0),0),C=(t==null?void 0:t.pair_code)&&t.pair_code_expires_at&&new Date(t.pair_code_expires_at)>new Date;return f?e.jsx(T,{children:e.jsx(P,{className:"p-6 text-sm text-muted-foreground",children:"Loadingâ¦"})}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(Zt,{className:"h-4 w-4"})," Telegram thinking partner"]}),e.jsx(O,{children:"Chat with your BrainMate brain from Telegram. Read-only: recalls memory, reads your repo, queries telemetry. Burns no Lovable credits â uses your existing AI keys."})]}),e.jsxs(P,{className:"space-y-4",children:[!(t!=null&&t.is_authorized)&&e.jsxs("div",{className:"rounded border border-border p-4 space-y-3 bg-muted/30",children:[e.jsxs("div",{className:"text-sm space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"1."})," Open the bot in Telegram and send ",e.jsx("code",{children:"/start"})," first."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"2."}),' Click "Generate pairing code" below.']}),e.jsxs("p",{children:[e.jsx("strong",{children:"3."})," Send ",e.jsx("code",{children:"/start <code>"})," to the bot to link this account."]})]}),C?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"text-lg font-mono px-3 py-1 rounded bg-background border",children:t==null?void 0:t.pair_code}),e.jsxs(w,{size:"sm",variant:"outline",onClick:()=>{navigator.clipboard.writeText(`/start ${t==null?void 0:t.pair_code}`),r({title:"Copied"})},children:[e.jsx(ke,{className:"h-3 w-3 mr-1"})," Copy /start command"]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["expires ",ds(new Date(t.pair_code_expires_at),{addSuffix:!0})]})]}):e.jsxs(w,{size:"sm",onClick:x,children:[e.jsx(He,{className:"h-3 w-3 mr-1"})," Generate pairing code"]})]}),(t==null?void 0:t.is_authorized)&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm",children:["Linked as ",e.jsxs("strong",{children:["@",t.telegram_username||t.telegram_user_id]}),e.jsx(E,{variant:"outline",className:"ml-2",children:"authorized"})]}),e.jsxs(w,{size:"sm",variant:"outline",onClick:l,children:[e.jsx(Us,{className:"h-3 w-3 mr-1"})," Unlink"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted-foreground",children:"Active project"}),e.jsxs(Q,{value:t.active_project_id||"",onValueChange:a,children:[e.jsx(Y,{className:"h-9 mt-1",children:e.jsx(J,{placeholder:"Pick a project"})}),e.jsx(Z,{children:n.map(_=>e.jsx(K,{value:_.id,children:_.name},_.id))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Tools enabled"}),Object.entries(nr).map(([_,h])=>{var u;return e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm",children:h}),e.jsx(Ce,{checked:!!((u=t.tools_enabled)!=null&&u[_]),disabled:_==="remember_insight",onCheckedChange:v=>y(_,v)})]},_)})]})]})]})]}),(t==null?void 0:t.is_authorized)&&e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsx(M,{className:"text-sm",children:"Recent activity"}),e.jsxs(O,{children:["Last ",i.length," messages â ",b.toLocaleStr
185ing()," tokens, $",j.toFixed(4)," estimated"]})]}),e.jsxs(P,{className:"space-y-2 max-h-96 overflow-y-auto",children:[i.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"No messages yet."}),i.map(_=>{var h;return e.jsxs("div",{className:"border border-border rounded p-2 text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(E,{variant:_.direction==="inbound"?"outline":"secondary",className:"text-[10px]",children:_.direction}),e.jsx("span",{className:"text-muted-foreground",children:ds(new Date(_.created_at),{addSuffix:!0})}),_.model&&e.jsxs("span",{className:"text-muted-foreground",children:["· ",_.model]}),(_.tokens_in||_.tokens_out)>0&&e.jsxs("span",{className:"text-muted-foreground",children:["· ",_.tokens_in,"+",_.tokens_out,"tok · $",Number(_.cost_usd).toFixed(4)]}),((h=_.tools_used)==null?void 0:h.length)>0&&e.jsxs("span",{className:"text-muted-foreground",children:["· ",_.tools_used.join(", ")]})]}),e.jsx("div",{className:"whitespace-pre-wrap line-clamp-3 font-mono",children:_.body})]},_.id)})]})]}),e.jsxs(T,{children:[e.jsx(L,{children:e.jsx(M,{className:"text-sm",children:"First-time setup"})}),e.jsx(P,{className:"text-xs space-y-2 text-muted-foreground",children:e.jsxs("p",{children:["Create a bot once via ",e.jsxs("a",{className:"underline",href:"https://t.me/BotFather",target:"_blank",rel:"noreferrer",children:["BotFather ",e.jsx(Ve,{className:"inline h-3 w-3"})]}),", then connect it via Connectors â Telegram. The webhook is already registered for this project."]})})]})]})}const is={telegram:"Telegram",claude_desktop:"Claude Desktop",lovable_desktop:"Lovable Desktop",cursor:"Cursor",copilot:"GitHub Copilot",windsurf:"Windsurf",chatgpt:"ChatGPT",web:"BrainMate Web",unknown:"Unknown client",other:"Other"};function or(){const{user:s}=we(),[r,n]=c.useState([]),[t,d]=c.useState(!0),[i,N]=c.useState(null),{busy:f,deleteMemory:m}=Qs(),{toast:p}=V(),x=async()=>{if(!s)return;d(!0);const{data:a,error:y}=await k.from("conversation_threads").select("source_client, turn_count, last_active_at").eq("user_id",s.id).order("last_active_at",{ascending:!1});if(y){console.error("[MemorySourcesPanel]",y),n([]),d(!1);return}const j=new Map;for(const b of a??[]){const C=j.get(b.source_client);C?(C.thread_count+=1,C.turn_count+=b.turn_count??0,new Date(b.last_active_at)>new Date(C.last_active_at)&&(C.last_active_at=b.last_active_at)):j.set(b.source_client,{source_client:b.source_client,thread_count:1,turn_count:b.turn_count??0,last_active_at:b.last_active_at})}n(Array.from(j.values())),d(!1)};c.useEffect(()=>{x()},[s==null?void 0:s.id]);const l=async a=>{try{const y=await m({scope:"client",value:a.source_client});p({title:`${is[a.source_client]??a.source_client} data removed`,description:`${y.threads_deleted} thread${y.threads_deleted===1?"":"s"}, ${y.turns_deleted} turn${y.turns_deleted===1?"":"s"} and ${y.insights_marked_deleted} derived insight${y.insights_marked_deleted===1?"":"s"} deleted.`})}catch(y){p({title:"Couldn't remove this source's data",description:y.message,variant:"destructive"})}finally{N(null),x()}};return e.jsxs(T,{className:"mt-6",children:[e.jsx(L,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(M,{children:"Connected memory sources"}),e.jsx(O,{children:"Every AI client currently writing into your cross-client memory layer. The more sources connected, the richer the context BrainMate can pull from any interface."})]}),e.jsx(w,{variant:"ghost",size:"sm",onClick:x,disabled:t,children:e.jsx(He,{className:`h-4 w-4 ${t?"animate-spin":""}`})})]})}),e.jsx(P,{children:t?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loadingâ¦"}):r.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No conversations captured yet. Use BrainMate via Telegram, Claude Desktop, Lovable Desktop, or Cursor â every turn will appear here automatically."}):e.jsxs("div",{className:"space-y-2",children:[r.map(a=>e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border bg-card/50 px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(E,{variant:"outline",className:"font-mono text-xs",children:is[a.source_client]??a.source_client}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[a.thread_count," thread",a.thread_count===1?"":"s"," · ",a.turn_count," turn",a.turn_count===1?"":"s"]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:["active ",ds(new Date(a.last_active_at),{addSuffix:!0})]}),e.jsxs(w,{variant:"ghost",size:"sm",className:"h-7 text-xs text-destructive hover:text-destructive",disabled:f,onClick:()=>N(a),children:[e.jsx(X,{className:"h-3.5 w-3.5 mr-1.5"})," Revoke & delete"]})]})]},a.source_client)),e.jsx("div",{className:"pt-2",children:e.jsxs(Ds,{to:"/app/threads",className:"inline-flex items-center gap-1 text-xs text-primary hover:underline",children:["Browse all threads ",e.jsx(ca,{className:"h-3 w-3"})]})})]})}),e.jsx(Ie,{open:!!i,onOpenChange:a=>{a||N(null)},children:e.jsxs(Le,{children:[e.jsxs(Me,{children:[e.jsxs(De,{children:["Delete everything from ",i?is[i.source_client]??i.source_client:"","?"]}),e.jsxs(Oe,{children:["This removes ",(i==null?void 0:i.thread_count)??0," conversation",(i==null?void 0:i.thread_count)===1?"":"s"," and ",(i==null?void 0:i.turn_count)??0," message",(i==null?void 0:i.turn_count)===1?"":"s"," captured from this source, plus anything BrainMate learned from them. This cannot be undone. The source stops contributing until it connects again."]})]}),e.jsxs(Be,{children:[e.jsx(qe,{disabled:f,children:"Cancel"}),e.jsx(Ke,{disabled:f,onClick:a=>{a.preventDefault(),i&&l(i)},children:f?"Deletingâ¦":"Delete permanently"})]})]})})]})}const Ts={telegram:{label:"Telegram",color:"bg-sky-500/15 text-sky-300 border-sky-500/30"},claude_desktop:{label:"Claude",color:"bg-orange-500/15 text-orange-300 border-orange-500/30"},lovable_desktop:{label:"Lovable",color:"bg-fuchsia-500/15 text-fuchsia-300 border-fuchsia-500/30"},cursor:{label:"Cursor",color:"bg-emerald-500/15 text-emerald-300 border-emerald-500/30"},copilot:{label:"Copilot",color:"bg-indigo-500/15 text-indigo-300 border-indigo-500/30"},chatgpt:{label:"ChatGPT",color:"bg-teal-500/15 text-teal-300 border-teal-500/30"},gmail:{label:"Gmail",color:"bg-rose-500/15 text-rose-300 border-rose-500/30"},web:{label:"Web",color:"bg-slate-500/15 text-slate-300 border-slate-500/30"},unknown:{label:"Unknown",color:"bg-muted text-muted-foreground border-border"}};function cr({client:s,className:r}){const n=Ts[s??"unknown"]??Ts.unknown;return e.jsx(E,{variant:"outline",className:ze("font-mono text-[10px] tracking-wide",n.color,r),children:n.label})}const dr=["telegram","claude_desktop","lovable_desktop","cursor","copilot","chatgpt","gmail","web"];function mr(){const{busy:s,deleteMemory:r}=Qs(),{threads:n}=da(),[t,d]=c.useState(""),[i,N]=c.useState([]);c.useEffect(()=>{const m=new Set;
185n.forEach(p=>m.add(p.source_client)),N(Array.from(m))},[n]);async function f(m,p){try{const x=m==="all"?await r({scope:"all"}):await r({scope:"client",value:p});he.success(`Deleted ${x.threads_deleted} threads · ${x.turns_deleted} turns`+(x.insights_marked_deleted?` · ${x.insights_marked_deleted} insights`:""))}catch(x){he.error(`Delete failed: ${String(x)}`)}}return e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(Ys,{className:"w-4 h-4"})," Privacy & Data Rights"]}),e.jsx(O,{children:"GDPR-grade controls. Every deletion is recorded in the immutable audit chain."})]}),e.jsxs(P,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:"Delete memory from a single client"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Wipes every thread and turn that came from the selected client. Insights are kept."}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(Q,{value:t,onValueChange:d,children:[e.jsx(Y,{className:"w-[240px]",children:e.jsx(J,{placeholder:"Pick a clientâ¦"})}),e.jsx(Z,{children:(i.length>0?i:dr).map(m=>e.jsx(K,{value:m,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(cr,{client:m})," ",m]})},m))})]}),e.jsxs(Ie,{children:[e.jsx(ls,{asChild:!0,children:e.jsxs(w,{variant:"outline",size:"sm",disabled:!t||s,children:[s?e.jsx(G,{className:"w-3.5 h-3.5 mr-1.5 animate-spin"}):e.jsx(X,{className:"w-3.5 h-3.5 mr-1.5"}),"Delete client memory"]})}),e.jsxs(Le,{children:[e.jsxs(Me,{children:[e.jsxs(De,{children:["Delete all ",t," memory?"]}),e.jsxs(Oe,{children:["Permanently removes every thread and turn from ",t,". Insights already extracted into the knowledge tree are preserved. This action is irreversible and logged."]})]}),e.jsxs(Be,{children:[e.jsx(qe,{children:"Cancel"}),e.jsx(Ke,{onClick:()=>f("client",t),children:"Yes, delete"})]})]})]})]})]}),e.jsxs("div",{className:"space-y-2 pt-4 border-t border-border/40",children:[e.jsx("p",{className:"text-sm font-medium text-rose-300",children:"Delete everything"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Wipes every thread, every turn, and marks every active insight as deleted across all clients."}),e.jsxs(Ie,{children:[e.jsx(ls,{asChild:!0,children:e.jsxs(w,{variant:"destructive",size:"sm",disabled:s,children:[s?e.jsx(G,{className:"w-3.5 h-3.5 mr-1.5 animate-spin"}):e.jsx(X,{className:"w-3.5 h-3.5 mr-1.5"}),"Delete all my memory"]})}),e.jsxs(Le,{children:[e.jsxs(Me,{children:[e.jsx(De,{children:"Delete ALL memory?"}),e.jsx(Oe,{children:"This wipes every conversation thread, every turn, and marks every active insight as deleted. There is no undo. The action will be appended to the immutable audit chain."})]}),e.jsxs(Be,{children:[e.jsx(qe,{children:"Cancel"}),e.jsx(Ke,{onClick:()=>f("all"),children:"Yes, delete everything"})]})]})]})]})]})]})}const xr=["openai","anthropic","google","ollama","openrouter","custom"];function ur(){const{activeEntity:s}=Ms(),[r,n]=c.useState([]),[t,d]=c.useState({provider:"openai",label:"",base_url:"",model_id:""}),[i,N]=c.useState(!1);async function f(){if(!s)return;const{data:l}=await k.from("model_endpoints").select("id, provider, label, base_url, model_id, enabled").eq("tenant_id",s.id).order("created_at",{ascending:!1});n(l??[])}c.useEffect(()=>{f()},[s==null?void 0:s.id]);async function m(){if(!s)return;if(!t.label||!t.base_url){he.error("Label and base URL are required");return}N(!0);const{error:l}=await k.from("model_endpoints").insert({tenant_id:s.id,provider:t.provider,label:t.label,base_url:t.base_url,model_id:t.model_id||null});if(N(!1),l){he.error(l.message);return}d({provider:"openai",label:"",base_url:"",model_id:""}),he.success("Endpoint registered"),await f()}async function p(l,a){await k.from("model_endpoints").update({enabled:a}).eq("id",l),await f()}async function x(l){await k.from("model_endpoints").delete().eq("id",l),he.success("Endpoint removed"),await f()}return e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(hs,{className:"w-4 h-4"})," Bring-Your-Own-Model Endpoints"]}),e.jsx(O,{children:"Register your own AI provider URLs. Memory, governance, and recall stay BrainMate-native â only the model becomes pluggable."})]}),e.jsxs(P,{className:"space-y-6",children:[e.jsxs("div",{className:"grid gap-3 md:grid-cols-5 items-end",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(q,{className:"text-xs",children:"Provider"}),e.jsxs(Q,{value:t.provider,onValueChange:l=>d({...t,provider:l}),children:[e.jsx(Y,{children:e.jsx(J,{})}),e.jsx(Z,{children:xr.map(l=>e.jsx(K,{value:l,children:l},l))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(q,{className:"text-xs",children:"Label"}),e.jsx(H,{value:t.label,onChange:l=>d({...t,label:l.target.value}),placeholder:"My GPT-5"})]}),e.jsxs("div",{className:"space-y-1 md:col-span-2",children:[e.jsx(q,{className:"text-xs",children:"Base URL"}),e.jsx(H,{value:t.base_url,onChange:l=>d({...t,base_url:l.target.value}),placeholder:"https://api.openai.com/v1"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(q,{className:"text-xs",children:"Model ID"}),e.jsx(H,{value:t.model_id,onChange:l=>d({...t,model_id:l.target.value}),placeholder:"gpt-5"})]}),e.jsxs(w,{className:"md:col-span-5 w-full md:w-auto md:justify-self-end",onClick:m,disabled:i,children:[e.jsx(ue,{className:"w-3.5 h-3.5 mr-1.5"})," Register endpoint"]})]}),e.jsx("div",{className:"space-y-2",children:r.length===0?e.jsx("p",{className:"text-sm text-muted-foreground italic",children:"No endpoints registered yet."}):r.map(l=>e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border/40 px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx(E,{variant:"outline",className:"font-mono",children:l.provider}),e.jsx("span",{className:"font-medium truncate",children:l.label}),e.jsx("span",{className:"text-xs text-muted-foreground truncate",children:l.base_url}),l.model_id&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["· ",l.model_id]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(Ce,{checked:l.enabled,onCheckedChange:a=>p(l.id,a)}),e.jsx(w,{variant:"ghost",size:"icon",onClick:()=>x(l.id),children:e.jsx(X,{className:"w-3.5 h-3.5"})})]})]},l.id))})]})]})}const Ps={"openai/gpt-6-astra":"Flagship strategic reasoning: business models, market sizing, competitor analysis, and the public pilot advisor.","openai/gpt-6-sol":"Balanced reasoning for financial projections and cash-flow modelling.","openai/gpt-6-luna":"Low-latency micro-work: quick summaries, simple edits, formatting.","openai/gpt-5.6-sol":"Alternate mid-tier reasoning; fallback for GPT-6 Sol.","openai/gpt-5.6-terra":"Cost-efficient mid-tier general work.","openai/gpt-5.6-luna":"Ultra-cheap fallback for micro-work.","claude-opus-5-5":"Deepest review work: architecture reviews and invariant audits.","claude-sonnet-5":"CodeMate engine: security reviews, refactor plans, tech-debt assessment, debug traces.","claude-haiku-4-5":"Fast Anthropic tier for light structured tasks.","google/gemini-3.8-flash":"Default workhorse: data work, structured output, long-context reads, most Mate traffic.","google/gemini-3.7-flash":"Previous-generation workhorse, retained as first Gemini fallback.","google/gemini-3.1-pro-preview":"High-context alternative for very large document reads."},hr={openai:"OpenAI",anthropic:"Anthropic",gemini:"Google"},pr={premium:"default",standard:"secondary",budget:"outline"};function jr(s,r){const n=s[r]??s[`anthropic/${r}`];return n||null}function gr(){const[s,r]=c.useState(""),[n,t]=c.useState(!1),d=c.useMemo(()=>{const x=Object.values(Et),l=x[x.length-1];return(l==null?void 0:l.models)??{}},[]),i=c.useMemo(()=>{const x=new Map,l=(a,y)=>{const j=x.get(a)??[];j.push(y),x.set(a,j)};for(const[a,y]of Object.entries(Tt))l(y,a==="DEFAULT"?"Default Mate preference":`${a} preference`);for(const[a,y]of Object.entries(Pt))l(y,`Intent: ${a}`);return l(It,"System default model"),l(Lt,"Premium reasoning model"),l(Mt,"Code analysis model"),x},[]),N=c.useMemo(()=>Object.values(ys),[]),{active:f,archived:m}=c.useMemo(()=>{const x=s.trim().toLowerCase(),l=N.filter(a=>!x||a.id.toLowerCase().includes(x)||a.displayName.toLowerCase().includes(x));return{active:l.filter(a=>i.has(a.id)),archived:l.filter(a=>!i.has(a.id))}},[N,i,s]),p=x=>{const l=ys[x],a=jr(d,x),y=Dt[x]??[],j=i.get(x)??[];return e.jsxs("div",{className:"rounded-lg border border-border bg-card/50 p-4 space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("h4",{className:"font-semibold",children:l.displayName}),e.jsx(E,{variant:"outline",children:hr[l.family]}),e.jsx(E,{variant:pr[l.costTier]??"outline",className:"capitalize",children:l.costTier})]}),e.jsx("code",{className:"text-xs text-muted-foreground break-all",children:x})]}),e.jsx("div",{className:"text-right text-xs text-muted-foreground shrink-0",children:a?e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:["$",a.input_per_million.toFixed(2)," / 1M in"]}),e.jsxs("div",{children:["$",a.output_per_million.toFixed(2)," / 1M out"]})]}):e.jsx("div",{children:"No published price (baseline used)"})})]}),Ps[x]&&e.jsx("p",{className:"text-sm text-muted-foreground",children:Ps[x]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-xs sm:grid-cols-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Reasoning"}),e.jsx("div",{className:"capitalize",children:l.reasoning})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Code"}),e.jsx("div",{className:"capitalize",children:l.codeGeneration})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Speed"}),e.jsx("div",{className:"capitalize",children:l.speed})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-muted-foreground",children:"Context"}
185),e.jsxs("div",{children:[(l.contextWindow/1e3).toLocaleString(),"k tokens"]})]})]}),j.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5",children:j.map(b=>e.jsx(E,{variant:"secondary",className:"font-normal",children:b},b))}),y.length>0&&e.jsxs("div",{className:"text-xs text-muted-foreground break-words",children:[e.jsx("span",{className:"font-medium text-foreground",children:"Fallback: "}),y.join(" â ")]})]},x)};return e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(hs,{className:"h-5 w-5"}),"Model Catalog"]}),e.jsxs(O,{children:["Live view of every model the router can select, what it is used for, its price, and its fallback chain. Pricing version ",Rt,". Read-only."]})]}),e.jsxs(P,{className:"space-y-4",children:[e.jsxs("div",{className:"relative",children:[e.jsx(sa,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(H,{value:s,onChange:x=>r(x.target.value),placeholder:"Search models",className:"pl-9"})]}),e.jsxs("div",{className:"flex flex-wrap gap-4 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[f.length," in active routing"]}),e.jsxs("span",{children:[m.length," retained for history"]})]}),e.jsx("div",{className:"space-y-3",children:f.map(x=>p(x.id))}),e.jsxs(ma,{open:n,onOpenChange:t,children:[e.jsx(xa,{asChild:!0,children:e.jsxs(w,{variant:"outline",className:"w-full justify-between",children:["Retained models (not actively routed)",e.jsx(ha,{className:`h-4 w-4 transition-transform ${n?"rotate-180":""}`})]})}),e.jsxs(ua,{className:"space-y-3 pt-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Kept registered so historical records and cost replays still resolve. Never removed."}),m.map(x=>p(x.id))]})]})]})]})}function fr({apiKeys:s,createApiKey:r,revokeApiKey:n,deleteApiKey:t,onKeyUpdated:d}){const{toast:i}=V(),[N,f]=c.useState(!1),[m,p]=c.useState(""),[x,l]=c.useState(""),[a,y]=c.useState(null),[j,b]=c.useState(!1),[C,_]=c.useState([]),[h,u]=c.useState(new Map),[v,g]=c.useState(null),[I,ee]=c.useState("");c.useEffect(()=>{(async()=>{const{data:D}=await k.from("projects").select("id, name").order("name");D&&(_(D),u(new Map(D.map(re=>[re.id,re.name]))))})()},[]);const W=async()=>{if(!m.trim())return;b(!0);const S=x&&x!=="none"?x:void 0,D=await r(m.trim(),S);D!=null&&D.rawKey&&(y(D.rawKey),i({title:"API Key Created",description:"Copy your key now â it won't be shown again."})),p(""),l(""),b(!1)},z=async(S,D)=>{const{error:re}=await k.from("api_keys").update({project_id:D}).eq("id",S);if(re){i({title:"Error",description:"Failed to update project link.",variant:"destructive"});return}if(D){const{data:ge}=await k.from("scopes").select("id").eq("project_id",D).limit(1);(!ge||ge.length===0)&&await k.from("scopes").insert({project_id:D,name:"default",status:"active"})}i({title:D?"Project Linked":"Project Unlinked",description:D?`Key now feeds into "${h.get(D)}" â context injection & memory active.`:"Key unlinked. Context injection disabled."}),g(null),ee(""),d==null||d()},de=S=>{navigator.clipboard.writeText(S),i({title:"Copied",description:"API key copied to clipboard."})};return e.jsxs(T,{children:[e.jsxs(L,{className:"flex flex-row items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(Vs,{className:"h-5 w-5"})," API Keys"]}),e.jsx(O,{children:"Manage keys for your applications. Link to a project for context-aware AI governance."})]}),e.jsxs(w,{size:"sm",onClick:()=>{f(!0),y(null)},children:[e.jsx(ue,{className:"h-4 w-4 mr-1"})," New Key"]})]}),e.jsxs(P,{className:"space-y-4",children:[N&&e.jsx("div",{className:"border border-border rounded-lg p-4 space-y-3 bg-muted/50",children:a?e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm font-medium text-destructive",children:"â ï¸ Copy this key now â it won't be shown again."}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"flex-1 bg-background border rounded px-3 py-2 text-sm font-mono break-all",children:a}),e.jsx(w,{size:"icon",variant:"outline",onClick:()=>de(a),children:e.jsx(ke,{className:"h-4 w-4"})})]}),e.jsx(w,{variant:"outline",size:"sm",onClick:()=>{f(!1),y(null)},children:"Done"})]}):e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"flex items-end gap-2",children:e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsx(q,{className:"text-xs",children:"Key Name"}),e.jsx(H,{placeholder:"e.g., Production, Staging",value:m,onChange:S=>p(S.target.value),onKeyDown:S=>S.key==="Enter"&&W()})]})}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs(q,{className:"text-xs flex items-center gap-1",children:[e.jsx(ce,{className:"h-3 w-3"})," Link to Project (optional)"]}),e.jsxs(Q,{value:x,onValueChange:l,children:[e.jsx(Y,{className:"text-sm",children:e.jsx(J,{placeholder:"No project â generic governance only"})}),e.jsxs(Z,{children:[e.jsx(K,{value:"none",children:"No project â generic governance"}),C.map(S=>e.jsx(K,{value:S.id,children:S.name},S.id))]})]}),e.jsx("p",{className:"text-[10px] text-muted-foreground",children:"Linking enables context injection and grounded output verification."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(w,{onClick:W,disabled:j||!m.trim(),children:j?"Creating...":"Create"}),e.jsx(w,{variant:"ghost",onClick:()=>{f(!1),l("")},children:"Cancel"})]})]})}),s.length===0&&!N?e.jsx("p",{className:"text-sm text-muted-foreground text-center py-8",children:"No API keys yet. Create one to start using the governed proxy."}):e.jsx("div",{className:"divide-y divide-border",children:s.map(S=>e.jsxs("div",{className:"py-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-sm",children:S.name}),e.jsx(E,{variant:S.is_active?"default":"secondary",className:"text-xs",children:S.is_active?"Active":"Revoked"}),S.project_id&&h.get(S.project_id)&&e.jsxs(E,{variant:"outline",className:"text-[10px] bg-primary/10 text-primary border-primary/20 flex items-center gap-1",children:[e.jsx(ce,{className:"h-2.5 w-2.5"})," ",h.get(S.project_id)]})]}),e.jsxs("div",{className:"flex items-center gap-4 text-xs text-muted-foreground",children:[e.jsxs("code",{children:[S.key_prefix,"...â¢â¢â¢â¢"]}
185),e.jsxs("span",{children:[S.total_requests.toLocaleString()," requests"]}),e.jsxs("span",{children:[S.total_tokens.toLocaleString()," tokens"]}),e.jsxs("span",{children:[S.rate_limit_rpm," rpm"]})]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[S.is_active&&S.project_id&&e.jsx(w,{size:"icon",variant:"ghost",className:"h-8 w-8 text-muted-foreground hover:text-amber-600",onClick:()=>z(S.id,null),title:"Unlink project",children:e.jsx(Us,{className:"h-4 w-4"})}),S.is_active&&!S.project_id&&e.jsxs(w,{size:"sm",variant:"ghost",className:"h-8 text-xs text-primary gap-1",onClick:()=>{g(S.id),ee("")},title:"Link to a project",children:[e.jsx($s,{className:"h-3.5 w-3.5"})," Link"]}),S.is_active&&e.jsx(w,{size:"icon",variant:"ghost",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>n(S.id),title:"Revoke key",children:e.jsx(Vt,{className:"h-4 w-4"})}),e.jsx(w,{size:"icon",variant:"ghost",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>t(S.id),title:"Delete key",children:e.jsx(X,{className:"h-4 w-4"})})]})]}),v===S.id&&e.jsxs("div",{className:"flex items-center gap-2 pl-1",children:[e.jsxs(Q,{value:I,onValueChange:ee,children:[e.jsx(Y,{className:"text-xs h-8 w-64",children:e.jsx(J,{placeholder:"Select a projectâ¦"})}),e.jsx(Z,{children:C.map(D=>e.jsx(K,{value:D.id,children:D.name},D.id))})]}),e.jsx(w,{size:"sm",className:"h-8 text-xs",disabled:!I,onClick:()=>z(S.id,I),children:"Link"}),e.jsx(w,{size:"sm",variant:"ghost",className:"h-8 text-xs",onClick:()=>g(null),children:"Cancel"})]}),S.is_active&&!S.project_id&&v!==S.id&&e.jsxs("div",{className:"flex items-start gap-2 rounded-md bg-amber-500/10 border border-amber-500/20 px-3 py-2 text-xs text-amber-700 dark:text-amber-400",children:[e.jsx(ye,{className:"h-3.5 w-3.5 mt-0.5 shrink-0"}),e.jsxs("span",{children:[e.jsx("strong",{children:"No project linked."}),' Context injection, memory persistence, and grounding verification are disabled. Click "Link" above to activate the full flywheel.']})]})]},S.id))})]})]})}function vr(s){const r=s.match(/^(\d+)(h|d)$/);if(!r)return 24;const[,n,t]=r;return t==="d"?parseInt(n)*24:parseInt(n)}function yr(s,r){const n=Ge(),t="all",{data:d=[],isLoading:i}=Ne({queryKey:["sla-commitments",s],queryFn:async()=>{if(!s)return[];const{data:p,error:x}=await k.from("sla_commitments").select("*").eq("org_id",s).eq("is_active",!0);if(x)throw x;return p||[]},enabled:!!s}),{data:N=[]}=Ne({queryKey:["sla-statuses",s,d.length,t],queryFn:async()=>{var x,l;if(!s||d.length===0)return[];const p=[];for(const a of d){const y=vr(a.sla_window),j=new Date(Date.now()-y*60*60*1e3).toISOString();let b=k.from("api_request_log").select("latency_ms, status").eq("org_id",s).gte("created_at",j).eq("status","success");a.api_key_id&&(b=b.eq("api_key_id",a.api_key_id));const C=(await b.order("latency_ms",{ascending:!0})).data??[];if(C.length===0){p.push({commitment:a,current_value:null,breached:!1,margin_percent:null});continue}let _=null;if(a.metric==="p99_latency_ms"){const v=Math.floor(C.length*.99);_=((x=C[Math.min(v,C.length-1)])==null?void 0:x.latency_ms)??null}else if(a.metric==="p95_latency_ms"){const v=Math.floor(C.length*.95);_=((l=C[Math.min(v,C.length-1)])==null?void 0:l.latency_ms)??null}else a.metric==="avg_latency_ms"&&(_=C.reduce((g,I)=>g+(I.latency_ms||0),0)/C.length);const h=_!==null&&_>a.threshold,u=_!==null?(a.threshold-_)/a.threshold*100:null;p.push({commitment:a,current_value:_,breached:h,margin_percent:u})}return p},enabled:!!s&&d.length>0,refetchInterval:6e4}),f=xe({mutationFn:async p=>{if(!s)throw new Error("No organization");const{error:x}=await k.from("sla_commitments").insert({org_id:s,metric:p.metric,threshold:p.threshold,sla_window:p.sla_window,api_key_id:p.api_key_id||null});if(x)throw x},onSuccess:()=>{n.invalidateQueries({queryKey:["sla-commitments",s]})}}),m=xe({mutationFn:async p=>{const{error:x}=await k.from("sla_commitments").update({is_active:!1}).eq("id",p);if(x)throw x},onSuccess:()=>{n.invalidateQueries({queryKey:["sla-commitments",s]})}});return{commitments:d,slaStatuses:N,isLoading:i,createCommitment:f,deleteCommitment:m}}function Nr({orgId:s}){const{slaStatuses:r,isLoading:n,createCommitment:t,deleteCommitment:d}=yr(s),{toast:i}=V(),[N,f]=c.useState(!1),[m,p]=c.useState("p99_latency_ms"),[x,l]=c.useState(""),[a,y]=c.useState("24h"),j=()=>{x&&t.mutate({metric:m,threshold:parseFloat(x),sla_window:a},{onSuccess:()=>{i({title:"SLA commitment created"}),f(!1),l("")},onError:h=>i({title:"Error",description:h.message,variant:"destructive"})})},b=(h,u)=>h?"destructive":u!==null&&u<10?"secondary":"default",C=(h,u)=>h?e.jsx(ye,{className:"h-4 w-4 text-destructive"}):u!==null&&u<10?e.jsx(ye,{className:"h-4 w-4 text-accent-foreground"}):e.jsx(us,{className:"h-4 w-4 text-primary"}),_={p99_latency_ms:"P99 Latency",p95_latency_ms:"P95 Latency",avg_latency_ms:"Avg Latency"};return e.jsxs(T,{children:[e.jsxs(L,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsxs("div",{children:[e.jsxs(M,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Ys,{className:"h-4 w-4"}),"SLA Commitments"]}),e.jsx(O,{children:"Service level agreement tracking"})]}),e.jsxs(w,{variant:"outline",size:"sm",onClick:()=>f(!N),children:[e.jsx(ue,{className:"h-3 w-3 mr-1"}),"Add"]})]}),e.jsxs(P,{className:"space-y-3",children:[N&&e.jsxs("div",{className:"border border-border rounded-md p-3 space-y-2 bg-muted/50",children:[e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Metric"}),e.jsxs(Q,{value:m,onValueChange:p,children:[e.jsx(Y,{className:"h-8 text-xs",children:e.jsx(J,{})}),e.jsxs(Z,{children:[e.jsx(K,{value:"p99_latency_ms",children:"P99 Latency (ms)"}),e.jsx(K,{value:"p95_latency_ms",children:"P95 Latency (ms)"}),e.jsx(K,{value:"avg_latency_ms",children:"Avg Latency (ms)"})]})]})]}),e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Threshold (ms)"}),e.jsx(H,{className:"h-8 text-xs",type:"number",value:x,onChange:h=>l(h.target.value),placeholder:"500"})]}),e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Window"}),e.jsxs(Q,{value:a,onValueChange:y,children:[e.jsx(Y,{className:"h-8 text-xs",children:e.jsx(J,{})}),e.jsxs(Z,{children:[e.jsx(K,{value:"1h",children:"1 hour"}),e.jsx(K,{value:"24h",children:"24 hours"}),e.jsx(K,{value:"7d",children:"7 days"})]})]})]})]}),e.jsx(w,{size:"sm",className:"w-full h-7 text-xs",onClick:j,disabled:!x,children:"Create Commitment"})]}),n&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading..."}),r.length===0&&!n&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"No SLA commitments configured."}),r.map(h=>e.jsxs("div",{className:"flex items-center justify-between border border-border rounded-md p-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[C(h.breached,h.margin_percent),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium",children:_[h.commitment.metric]||h.commitment.metric}),e.jsxs("p",{className:"text-[10px] text-muted-foreground",children:[h.current_value!==null?`${Math.round(h.current_value)}ms`:"No data"," / ",h.commitment.threshold,"ms",e.jsxs("span",{className:"ml-1",children:["(",h.commitment.sla_window,")"]})]})]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(E,{variant:b(h.breached,h.margin_percent),className:"text-[10px]",children:h.breached?"BREACH":h.margin_percent!==null&&h.margin_percent<10?"AT RISK":"OK"}),e.jsx(w,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>d.mutate(h.commitment.id),children:e.jsx(X,{className:"h-3 w-3"})})]})]},h.commitment.id))]})]})}const br=[{value:"guard_halt",label:"Guard Halt"},{value:"rate_limited",label:"Rate Limited"},{value:"budget_exceeded",label:"Budget Exceeded"},{value:"sla_breach",label:"SLA Breach"},{value:"api_request",label:"All Requests"}];function _r({orgId:s}){const{toast:r}=V(),n=Ge(),[t,d]=c.useState(!1),[i,N]=c.useState(""),[f,m]=c.useState("generic"),[p,x]=c.useState(["guard_halt"]),[l,a]=c.useState(null),{data:y=[],isLoading:j}=Ne({queryKey:["webhook-endpoints",s],queryFn:async()=>
185{if(!s)return[];const{data:v,error:g}=await k.from("webhook_endpoints_safe").select("*").eq("org_id",s).order("created_at",{ascending:!1});if(g)throw g;return v||[]},enabled:!!s});function b(){const v=new Uint8Array(32);return crypto.getRandomValues(v),Array.from(v).map(g=>g.toString(16).padStart(2,"0")).join("")}const C=xe({mutationFn:async()=>{if(!s||!i)throw new Error("Missing data");const{error:v}=await k.from("webhook_endpoints").insert({org_id:s,url:i,secret:b(),event_types:p,format:f});if(v)throw v},onSuccess:()=>{n.invalidateQueries({queryKey:["webhook-endpoints",s]}),r({title:"Webhook endpoint created"}),d(!1),N(""),x(["guard_halt"])},onError:v=>r({title:"Error",description:v.message,variant:"destructive"})}),_=xe({mutationFn:async v=>{const{error:g}=await k.from("webhook_endpoints").delete().eq("id",v);if(g)throw g},onSuccess:()=>{n.invalidateQueries({queryKey:["webhook-endpoints",s]}),r({title:"Webhook endpoint deleted"})}}),h=async v=>{a(v.id);try{const{error:g}=await k.functions.invoke("webhook-dispatch",{body:{org_id:s,event_type:"test_ping",payload:{message:"BrainMate webhook test ping",timestamp:new Date().toISOString()}}});r(g?{title:"Test failed",description:g.message,variant:"destructive"}:{title:"Test ping sent"})}catch(g){r({title:"Test failed",description:String(g),variant:"destructive"})}finally{a(null)}},u=v=>{x(g=>g.includes(v)?g.filter(I=>I!==v):[...g,v])};return e.jsxs(T,{children:[e.jsxs(L,{className:"flex flex-row items-center justify-between space-y-0 pb-2",children:[e.jsxs("div",{children:[e.jsxs(M,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Ws,{className:"h-4 w-4"}),"Webhooks"]}),e.jsx(O,{children:"Real-time alert delivery to external services"})]}),e.jsxs(w,{variant:"outline",size:"sm",onClick:()=>d(!t),children:[e.jsx(ue,{className:"h-3 w-3 mr-1"}),"Add"]})]}),e.jsxs(P,{className:"space-y-3",children:[t&&e.jsxs("div",{className:"border border-border rounded-md p-3 space-y-2 bg-muted/50",children:[e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Endpoint URL"}),e.jsx(H,{className:"h-8 text-xs",value:i,onChange:v=>N(v.target.value),placeholder:"https://hooks.slack.com/..."})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Format"}),e.jsxs(Q,{value:f,onValueChange:m,children:[e.jsx(Y,{className:"h-8 text-xs",children:e.jsx(J,{})}),e.jsxs(Z,{children:[e.jsx(K,{value:"generic",children:"Generic JSON"}),e.jsx(K,{value:"slack",children:"Slack"}),e.jsx(K,{value:"pagerduty",children:"PagerDuty"})]})]})]}),e.jsxs("div",{children:[e.jsx(q,{className:"text-xs",children:"Events"}),e.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:br.map(v=>e.jsx(E,{variant:p.includes(v.value)?"default":"outline",className:"text-[10px] cursor-pointer",onClick:()=>u(v.value),children:v.label},v.value))})]})]}),e.jsx(w,{size:"sm",className:"w-full h-7 text-xs",onClick:()=>C.mutate(),disabled:!i||p.length===0,children:"Create Endpoint"})]}),j&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading..."}),y.length===0&&!j&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"No webhook endpoints configured."}),y.map(v=>e.jsxs("div",{className:"flex items-center justify-between border border-border rounded-md p-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[v.is_active?e.jsx(us,{className:"h-3 w-3 text-primary shrink-0"}):e.jsx(Ue,{className:"h-3 w-3 text-muted-foreground shrink-0"}),e.jsx("p",{className:"text-xs font-mono truncate",children:v.url})]}),e.jsxs("div",{className:"flex gap-1 mt-1",children:[e.jsx(E,{variant:"outline",className:"text-[10px]",children:v.format}),v.event_types.map(g=>e.jsx(E,{variant:"secondary",className:"text-[10px]",children:g},g))]})]}),e.jsxs("div",{className:"flex items-center gap-1 ml-2",children:[e.jsx(w,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>h(v),disabled:l===v.id,children:l===v.id?e.jsx(G,{className:"h-3 w-3 animate-spin"}):e.jsx(Kt,{className:"h-3 w-3"})}),e.jsx(w,{variant:"ghost",size:"icon",className:"h-6 w-6",onClick:()=>_.mutate(v.id),children:e.jsx(X,{className:"h-3 w-3"})})]})]},v.id))]})]})}const Te=s=>k.from(s);function wr({orgId:s}){const r=Ge(),[n,t]=c.useState(!1),[d,i]=c.useState(""),[N,f]=c.useState(""),[m,p]=c.useState(!1),[x,l]=c.useState(null),{data:a,isLoading:y}=Ne({queryKey:["otlp-destinations",s],queryFn:async()=>{const{data:h,error:u}=await Te("otlp_destinations").select("*").eq("org_id",s).order("created_at",{ascending:!1});if(u)throw u;return h??[]},enabled:!!s}),j=async()=>
185{if(!d.trim()||!s)return;p(!0);const{error:h}=await Te("otlp_destinations").insert({org_id:s,endpoint_url:d.trim(),auth_header_encrypted:N.trim()||null});p(!1),h?le({title:"Error",description:h.message,variant:"destructive"}):(le({title:"OTLP destination added"}),r.invalidateQueries({queryKey:["otlp-destinations"]}),t(!1),i(""),f(""))},b=async(h,u)=>{const{error:v}=await Te("otlp_destinations").update({is_active:u,updated_at:new Date().toISOString()}).eq("id",h);v?le({title:"Error",description:v.message,variant:"destructive"}):r.invalidateQueries({queryKey:["otlp-destinations"]})},C=async h=>{const{error:u}=await Te("otlp_destinations").delete().eq("id",h);u?le({title:"Error",description:u.message,variant:"destructive"}):(r.invalidateQueries({queryKey:["otlp-destinations"]}),le({title:"Destination deleted"}))},_=async h=>{l(h.id);try{const u={resourceSpans:[{resource:{attributes:[{key:"service.name",value:{stringValue:"brainmate-governance"}},{key:"test",value:{stringValue:"connection-test"}}]},scopeSpans:[{scope:{name:"brainmate.test"},spans:[{traceId:"00000000000000000000000000000001",spanId:"0000000000000001",name:"brainmate.test.ping",kind:1,startTimeUnixNano:String(Date.now()*1e6),endTimeUnixNano:String(Date.now()*1e6),attributes:[],status:{code:1}}]}]}]},v={"Content-Type":"application/json"};h.auth_header_encrypted&&(v.Authorization=h.auth_header_encrypted);const g=await fetch(h.endpoint_url,{method:"POST",headers:v,body:JSON.stringify(u)});g.ok?le({title:"Connection successful",description:`Endpoint responded with ${g.status}`}):le({title:"Connection failed",description:`Endpoint responded with ${g.status}`,variant:"destructive"})}catch(u){const v=u instanceof Error?u:new Error(String(u));le({title:"Connection failed",description:v.message||"Network error",variant:"destructive"})}finally{l(null)}};return s?e.jsxs(T,{children:[e.jsxs(L,{className:"flex flex-row items-center justify-between",children:[e.jsxs(M,{className:"text-lg flex items-center gap-2",children:[e.jsx(Fe,{className:"h-5 w-5"}),"OTLP Export Destinations"]}),e.jsxs(w,{size:"sm",onClick:()=>t(!0),children:[e.jsx(ue,{className:"h-4 w-4 mr-1"})," Add Destination"]})]}),e.jsx(P,{children:y?e.jsx("p",{className:"text-muted-foreground text-sm",children:"Loadingâ¦"}):a!=null&&a.length?e.jsxs(Bs,{children:[e.jsx(qs,{children:e.jsxs($e,{children:[e.jsx(se,{children:"Endpoint"}),e.jsx(se,{children:"Exported"}),e.jsx(se,{children:"Last Export"}),e.jsx(se,{children:"Active"}),e.jsx(se,{className:"w-24"})]})}),e.jsx(Ks,{children:a.map(h=>e.jsxs($e,{children:[e.jsx(te,{className:"text-sm font-mono max-w-xs truncate",children:h.endpoint_url}),e.jsx(te,{children:e.jsxs(E,{variant:"secondary",children:[(h.export_count||0).toLocaleString()," spans"]})}),e.jsx(te,{className:"text-xs",children:h.last_export_at?pe(new Date(h.last_export_at),"MMM d, HH:mm"):"Never"}),e.jsx(te,{children:e.jsx(Ce,{checked:h.is_active,onCheckedChange:u=>b(h.id,u)})}),e.jsx(te,{children:e.jsxs("div",{className:"flex gap-1",children:[e.jsx(w,{variant:"ghost",size:"icon",onClick:()=>_(h),disabled:x===h.id,children:e.jsx(pa,{className:"h-4 w-4"})}),e.jsx(w,{variant:"ghost",size:"icon",onClick:()=>C(h.id),children:e.jsx(X,{className:"h-4 w-4 text-destructive"})})]})})]},h.id))})]}):e.jsxs("div",{className:"py-8 text-center",children:[e.jsx(Fe,{className:"h-10 w-10 text-muted-foreground mx-auto mb-3"}),e.jsx("p",{className:"text-sm font-medium text-foreground mb-1",children:"No OTLP destinations configured"}),e.jsx("p",{className:"text-xs text-muted-foreground max-w-sm mx-auto",children:"Export governance telemetry to Datadog, Grafana, or any OTLP-compatible backend."})]})}),e.jsx(os,{open:n,onOpenChange:t,children:e.jsxs(cs,{children:[e.jsx(Pe,{children:e.jsx(Re,{children:"Add OTLP Export Destination"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(q,{children:"OTLP Endpoint URL"}),e.jsx(H,{value:d,onChange:h=>i(h.target.value),placeholder:"https://otel-collector.example.com/v1/traces"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Must accept OTLP JSON over HTTP PO
185ST"})]}),e.jsxs("div",{children:[e.jsx(q,{children:"Authorization Header (optional)"}),e.jsx(H,{value:N,onChange:h=>f(h.target.value),placeholder:"Bearer your-token-here",type:"password"})]})]}),e.jsxs(Ee,{children:[e.jsx(w,{variant:"outline",onClick:()=>t(!1),children:"Cancel"}),e.jsx(w,{onClick:j,disabled:m||!d.trim(),children:m?"Addingâ¦":"Add Destination"})]})]})})]}):null}const Rs=[{value:"telemetry_events",label:"Telemetry Events"},{value:"api_request_log",label:"API Request Log"},{value:"webhook_delivery_log",label:"Webhook Delivery Log"}];function kr({orgId:s}){const{toast:r}=V(),n=Ge(),[t,d]=c.useState(""),[i,N]=c.useState(30),{data:f=[],isLoading:m}=Ne({queryKey:["retention-policies",s],queryFn:async()=>{if(!s)return[];const{data:j,error:b}=await k.from("retention_policies").select("*").eq("org_id",s).order("created_at",{ascending:!0});if(b)throw b;return j},enabled:!!s}),p=xe({mutationFn:async()=>{if(!s||!t)return;const{error:j}=await k.from("retention_policies").insert({org_id:s,table_name:t,retention_days:i});if(j)throw j},onSuccess:()=>{n.invalidateQueries({queryKey:["retention-policies"]}),d(""),N(30),r({title:"Retention policy created"})},onError:j=>r({title:"Error",description:j.message,variant:"destructive"})}),x=xe({mutationFn:async({id:j,is_active:b})=>{const{error:C}=await k.from("retention_policies").update({is_active:b}).eq("id",j);if(C)throw C},onSuccess:()=>n.invalidateQueries({queryKey:["retention-policies"]})}),l=xe({mutationFn:async j=>{const{error:b}=await k.from("retention_policies").delete().eq("id",j);if(b)throw b},onSuccess:()=>{n.invalidateQueries({queryKey:["retention-policies"]}),r({title:"Policy deleted"})}}),a=f.map(j=>j.table_name),y=Rs.filter(j=>!a.includes(j.value));return s?e.jsxs(T,{children:[e.jsxs(L,{children:[e.jsxs(M,{className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"})," Data Retention"]}),e.jsx(O,{children:"Automatically purge old data based on retention windows. Runs daily."})]}),e.jsxs(P,{className:"space-y-4",children:[f.map(j=>{var b;return e.jsxs("div",{className:"flex items-center justify-between p-3 rounded-lg border bg-card",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-sm",children:((b=Rs.find(C=>C.value===j.table_name))==null?void 0:b.label)??j.table_name}),e.jsx(E,{variant:j.is_active?"default":"secondary",children:j.is_active?"Active":"Paused"})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Ls,{className:"h-3 w-3"}),j.retention_days," days"]}),e.jsxs("span",{children:[j.rows_deleted_total??0," rows purged total"]}),j.last_run_at&&e.jsxs("span",{children:["Last run: ",pe(new Date(j.last_run_at),"MMM d, HH:mm")]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ce,{checked:j.is_active,onCheckedChange:C=>x.mutate({id:j.id,is_active:C})}),e.jsx(w,{variant:"ghost",size:"icon",onClick:()=>l.mutate(j.id),children:e.jsx(X,{className:"h-4 w-4 text-destructive"})})]})]},j.id)}),y.length>0&&e.jsxs("div",{className:"flex items-end gap-2 pt-2 border-t",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(q,{className:"text-xs",children:"Table"}),e.jsxs(Q,{value:t,onValueChange:d,children:[e.jsx(Y,{children:e.jsx(J,{placeholder:"Select table"})}),e.jsx(Z,{children:y.map(j=>e.jsx(K,{value:j.value,children:j.label},j.value))})]})]}),e.jsxs("div",{className:"w-24",children:[e.jsx(q,{className:"text-xs",children:"Days"}),e.jsx(H,{type:"number",min:1,max:365,value:i,onChange:j=>N(Number(j.target.value))})]}),e.jsxs(w,{onClick:()=>p.mutate(),disabled:!t||p.isPending,children:[e.jsx(ue,{className:"h-4 w-4 mr-1"})," Add"]})]}),m&&e.jsx("p",{className:"text-sm text-muted-foreground text-center py-4",children:"Loading..."})]})]}):e.jsx(T,{children:e.jsx(P,{className:"py-8 text-center text-muted-foreground",children:"Create an organization first"})})}function Cr(){const{apiKeys:s,createApiKey:r,revokeApiKey:n,deleteApiKey:t,refetch:d}=je();return e.jsx(fr,{apiKeys:s,createApiKey:r,revokeApiKey:n,deleteApiKey:t,onKeyUpdated:d})}function Sr(){const{organization:s}=je();return e.jsxs("div",{className:"space-y-6",children:[e.jsx(_r,{orgId:s==null?void 0:s.id}),e.jsx(wr,{orgId:s==null?void 0:s.id}),e.jsx(kr,{orgId:s==null?void 0:s.id})]})}function Ar(){const{organization:s}=je();return e.jsx(Nr,{orgId:s==null?void 0:s.id})}const Tr=["[email protected]"];function Pr(){const{isAdmin:s}=Ot(),{user:r}=we(),[n,t]=c.useState(!1);c.useEffect(()=>{let l=!0;return k.auth.getSession().then(({data:{session:a}})=>{var j,b;const y=((b=(j=a==null?void 0:a.user)==null?void 0:j.email)==null?void 0:b.toLowerCase())??"";l&&t(Tr.includes(y))}),()=>{l=!1}},[]);const[d,i]=Os(),N=d.get("tab")||"developer",m=N==="catalog"?"catalog":{account:"account",developer:"developer",integrations:"integrations",docs:"docs",admin:"admin",operations:"developer",keys:"developer",models:"developer",connections:"integrations",telegram:"integrations",apps:"integrations",clients:"integrations",billing:"account",privacy:"account"}[N]??"developer",p=m==="catalog"&&!n||m==="admin"&&!s?"developer":m,x=l=>{const a=new URLSearchParams(d);a.set("tab",l),i(a,{replace:!0})};
185return e.jsxs("div",{className:"p-6 max-w-6xl mx-auto space-y-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Settings"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"API keys, integrations, account and documentation"})]}),e.jsxs(be,{value:p,onValueChange:x,children:[e.jsxs(_e,{children:[e.jsxs(B,{value:"developer",className:"gap-2",children:[e.jsx(Wt,{className:"h-4 w-4"}),"API & Developer"]}),e.jsxs(B,{value:"integrations",className:"gap-2",children:[e.jsx(Gs,{className:"h-4 w-4"}),"Integrations"]}),e.jsxs(B,{value:"account",className:"gap-2",children:[e.jsx(Bt,{className:"h-4 w-4"}),"Account"]}),e.jsxs(B,{value:"docs",className:"gap-2",children:[e.jsx(zs,{className:"h-4 w-4"}),"Docs"]}),n&&e.jsxs(B,{value:"catalog",className:"gap-2",children:[e.jsx(hs,{className:"h-4 w-4"}),"Model Catalog"]}),s&&e.jsxs(B,{value:"admin",className:"gap-2",children:[e.jsx(Hs,{className:"h-4 w-4"}),"Admin"]})]}),e.jsxs(U,{value:"developer",className:"space-y-8",children:[e.jsxs(ve,{title:"API keys",description:"Create keys and link them to projects.",children:[e.jsx(Cr,{}),e.jsx(Qa,{})]}),e.jsxs(ve,{title:"Quickstart & endpoints",description:"SDK snippets, cURL and model endpoints.",children:[e.jsx(rr,{}),e.jsx(ur,{})]}),e.jsx(ve,{title:"Developer operations",description:"Webhooks, OpenTelemetry export and data retention.",children:e.jsx(Sr,{})})]}),e.jsxs(U,{value:"integrations",className:"space-y-8",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx("span",{children:"Google service account (Sheets & Drive):"}),e.jsx(ja,{compact:!0})]}),e.jsxs(ve,{title:"Apps & SaaS",description:"Gmail, Slack, Google Drive & Sheets, QuickBooks, Notion and more.",children:[e.jsx(ga,{}),e.jsx(fa,{userId:r==null?void 0:r.id})]}),e.jsxs(ve,{title:"AI clients & chat",description:"Route Claude, Cursor, ChatGPT, Lovable Desktop and Telegram through BrainMate.",children:[e.jsx(va,{}),e.jsx(lr,{}),e.jsx(or,{})]})]}),e.jsxs(U,{value:"account",className:"space-y-6",children:[e.jsx(Ta,{}),e.jsx(Pa,{}),e.jsx(mr,{}),e.jsx(Ar,{})]}),e.jsx(U,{value:"docs",children:e.jsx(Ea,{})}),n&&e.jsx(U,{value:"catalog",className:"space-y-6",children:e.jsx(gr,{})}),s&&e.jsxs(U,{value:"admin",children:[e.jsx(Wa,{}),e.jsx("div",{className:"mt-8",children:e.jsx(ya,{})})]})]})]})}function ve({title:s,description:r,children:n}){return e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold tracking-tight",children:s}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r})]}),n]})}function ii(){const[s]=Os(),r=s.get("section");if(r==="projects")return e.jsx(Je,{to:"/app/tools/projects",replace:!0});if(r==="integrations"){const n=new URLSearchParams(s);n.delete("section");const t=n.get("tab");return n.set("tab","integrations"),t==="clients"&&n.set("sub","clients"),e.jsx(Je,{to:`/app/settings?${n.toString()}`,replace:!0})}if(r!==null){const n=new URLSearchParams(s);n.delete("section");const t=n.toString();return e.jsx(Je,{to:`/app/settings${t?`?${t}`:""}`,replace:!0})}return e.jsx("div",{className:"h-full min-h-0 overflow-auto",children:e.jsx(Pr,{})})}export{ii as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.