llmxray 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ar.md +301 -0
- package/README.fr.md +297 -0
- package/README.md +33 -1
- package/README.sr.md +297 -0
- package/README.zh-CN.md +297 -0
- package/dist/assets/{AITrainingPage-BVvM9c3w.js → AITrainingPage-DKjKWcx-.js} +1 -1
- package/dist/assets/{AnalyticsPage-BXq_Bseq.js → AnalyticsPage-jTBXre2c.js} +1 -1
- package/dist/assets/{BenchmarkPage-BCqqL1M2.js → BenchmarkPage-BVmzrGF3.js} +6 -6
- package/dist/assets/{ComparisonPage-czrwH66h.js → ComparisonPage-C9o6y6vj.js} +1 -1
- package/dist/assets/{CostDashboardPage-BR0kcGWe.js → CostDashboardPage-CHoN2eQ2.js} +1 -1
- package/dist/assets/DashboardPage-CMZSfb4t.js +114 -0
- package/dist/assets/{EmbeddingsPage-DrWx8pzx.js → EmbeddingsPage-DdbGCntf.js} +1 -1
- package/dist/assets/FimPlaygroundPage-BcrmoLxo.js +7 -0
- package/dist/assets/{GoogleCallbackPage-DagDM0id.js → GoogleCallbackPage-C9_rQxue.js} +1 -1
- package/dist/assets/{JsonTreeNode-CJDN2gMs.js → JsonTreeNode-RIieSDXb.js} +1 -1
- package/dist/assets/{ModelCapabilityIcons.vue_vue_type_script_setup_true_lang-ZVZG2QJf.js → ModelCapabilityIcons.vue_vue_type_script_setup_true_lang-BN_k6QDr.js} +1 -1
- package/dist/assets/ProtocolObservatoryPage-CXoj3a1O.js +2 -0
- package/dist/assets/{RAGPage-DuboRMs8.js → RAGPage-HwnlHxQ0.js} +1 -1
- package/dist/assets/{SessionPage-gdjMmXms.js → SessionPage-12S3fV1c.js} +1 -1
- package/dist/assets/{SettingsPage-BOgg5oN9.js → SettingsPage-B_hBcAPj.js} +1 -1
- package/dist/assets/{StatusBadge.vue_vue_type_script_setup_true_lang-CAUQKTSd.js → StatusBadge.vue_vue_type_script_setup_true_lang-BQhKjjl9.js} +1 -1
- package/dist/assets/{StorageGauge.vue_vue_type_style_index_0_lang-BXU36Aoc.js → StorageGauge.vue_vue_type_style_index_0_lang-DOKnxhnC.js} +1 -1
- package/dist/assets/{SystemPage-D15_nq0O.js → SystemPage-BtFTvlZl.js} +2 -2
- package/dist/assets/{TabBar.vue_vue_type_script_setup_true_lang-GaVAqJYj.js → TabBar.vue_vue_type_script_setup_true_lang-BStny7LH.js} +1 -1
- package/dist/assets/{TokenStreamDisplay.vue_vue_type_script_setup_true_lang-CU1jcClu.js → TokenStreamDisplay.vue_vue_type_script_setup_true_lang-DMEwK9YF.js} +1 -1
- package/dist/assets/{ToolWorkshopPage-CcnMYV0-.js → ToolWorkshopPage-BRXtDJIQ.js} +1 -1
- package/dist/assets/{agent-store-7ERQoYE_.js → agent-store-CR4CQ_VV.js} +1 -1
- package/dist/assets/{canvas-ai-db-BQgRWF3i.js → canvas-ai-db-Ck_6zOgd.js} +1 -1
- package/dist/assets/{download-Bt_RPvva.js → download-CaV4vzuu.js} +1 -1
- package/dist/assets/{generate-service-DZWvg2CZ.js → generate-service-Bhf2jPuC.js} +1 -1
- package/dist/assets/{google-auth-store-BlzSHGyV.js → google-auth-store-LaJFtciC.js} +1 -1
- package/dist/assets/{index-CJR-Mn7H.js → index-CQPzvMUz.js} +1 -1
- package/dist/assets/{index-BXlm4Yjw.js → index-CZ4a6rAU.js} +12 -12
- package/dist/assets/{index-ClS2OLai.js → index-Dy_48xr0.js} +1 -1
- package/dist/assets/{index-B0RKZCO8.css → index-aU4tMz4Z.css} +1 -1
- package/dist/assets/{info-Dakpd0oS.js → info-C9qZFgvQ.js} +1 -1
- package/dist/assets/{metrics-store-BxvSgW3I.js → metrics-store-B4lQqH-w.js} +1 -1
- package/dist/assets/{papaparse.min-B2JsqFEL.js → papaparse.min-CfA1otDr.js} +1 -1
- package/dist/assets/{pencil-qLgRz8v5.js → pencil-BcLPhQp1.js} +1 -1
- package/dist/assets/play-CYCSil_U.js +1 -0
- package/dist/assets/{rag-store-DXWEPNvK.js → rag-store-BXD_zIis.js} +3 -3
- package/dist/assets/{session-store-DccvjxkU.js → session-store-Dy1-rRkz.js} +1 -1
- package/dist/assets/{share-2-BV2yUwOL.js → share-2-D2IlHB5H.js} +1 -1
- package/dist/assets/square-Dtyb8Nls.js +1 -0
- package/dist/assets/{storage-store-CsJ0rV6C.js → storage-store-me3LAKpj.js} +1 -1
- package/dist/assets/{stream-handler-DzltRNC4.js → stream-handler-DDNDUY1M.js} +2 -2
- package/dist/assets/{tool-workshop-store-CLI2kTMZ.js → tool-workshop-store-C_CvI0_B.js} +1 -1
- package/dist/assets/{toolcall-store-CHxkee5s.js → toolcall-store-CUeITA8C.js} +1 -1
- package/dist/assets/{trash-2-BpPF0NKP.js → trash-2-Ct6xU7VV.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/assets/DashboardPage-RSlbctDt.js +0 -108
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as Z,r as $,a as D,b as N,e as m,f as e,t as o,q as R,u as c,i as w,l as G,F as P,k as S,g as k,j as p,h as H,p as j,X as Q,C as E,D as U,v as W,Z as V,B as Y}from"./index-BXlm4Yjw.js";import{canvasAiDB as B}from"./canvas-ai-db-BQgRWF3i.js";import{b as _,d as z}from"./format-BqVZ9rwM.js";import{_ as ee}from"./StorageGauge.vue_vue_type_style_index_0_lang-BXU36Aoc.js";const te=Z("training",()=>{const t=$([]),n=$(!1),g=$(new Set),l=$(null),r=$({phase:null,model:null,accepted:null,toolName:null,tag:null,search:"",sortBy:"timestamp",sortDir:"desc"}),f=D(()=>{let i=[...t.value];const u=r.value;if(u.phase&&(i=i.filter(x=>x.phase===u.phase)),u.model&&(i=i.filter(x=>x.model===u.model)),u.accepted!==null&&(i=i.filter(x=>x.accepted===u.accepted)),u.toolName&&(i=i.filter(x=>x.toolName===u.toolName)),u.tag&&(i=i.filter(x=>x.tags?.includes(u.tag)??!1)),u.search){const x=u.search.toLowerCase();i=i.filter(b=>b.userPrompt.toLowerCase().includes(x)||b.response.toLowerCase().includes(x)||b.toolName.toLowerCase().includes(x))}return i.sort((x,b)=>{let y=0;return u.sortBy==="timestamp"?y=x.timestamp-b.timestamp:u.sortBy==="phase"?y=x.phase.localeCompare(b.phase):u.sortBy==="model"&&(y=x.model.localeCompare(b.model)),u.sortDir==="desc"?-y:y}),i}),d=D(()=>{const i=t.value,u=new Map,x=new Map;let b=0,y=0;for(const A of i)A.accepted&&b++,u.set(A.phase,(u.get(A.phase)??0)+1),x.set(A.model,(x.get(A.model)??0)+1),y+=A.systemPrompt.length+A.userPrompt.length+A.response.length;return{total:i.length,accepted:b,rejected:i.length-b,phaseBreakdown:u,modelBreakdown:x,estimatedBytes:y*2}}),a=D(()=>{const i=new Set;for(const u of t.value)for(const x of u.tags??[])i.add(x);return[...i].sort()}),s=D(()=>[...new Set(t.value.map(i=>i.model))].sort()),v=D(()=>[...new Set(t.value.map(i=>i.toolName))].sort());async function C(){n.value=!0;try{t.value=await B.getAllPairs()}catch(i){console.error("Failed to load training pairs:",i)}finally{n.value=!1}}async function M(i,u){await B.updatePairResponse(i,u);const x=t.value.find(b=>b.id===i);x&&(x.response=u)}async function h(i,u){await B.updatePairTags(i,u);const x=t.value.find(b=>b.id===i);x&&(x.tags=u)}async function T(i){const u=t.value.find(b=>b.id===i);if(!u)return;const x=!u.accepted;await B.updateAccepted(i,x),u.accepted=x}async function I(i){await B.deletePairs(i);const u=new Set(i);t.value=t.value.filter(x=>!u.has(x.id));for(const x of i)g.value.delete(x);l.value&&u.has(l.value)&&(l.value=null)}async function L(i,u){for(const x of i){await B.updateAccepted(x,u);const b=t.value.find(y=>y.id===x);b&&(b.accepted=u)}}async function F(i,u){for(const x of i){const b=t.value.find(A=>A.id===x);if(!b)continue;const y=[...b.tags??[]];y.includes(u)||(y.push(u),await B.updatePairTags(x,y),b.tags=y)}}function K(i){B.exportSelectedAsJsonl(i)}function q(i){const u=new Set(g.value);u.has(i)?u.delete(i):u.add(i),g.value=u}function J(){g.value=new Set(f.value.map(i=>i.id))}function O(){g.value=new Set}function X(i){l.value=l.value===i?null:i}return{pairs:t,loading:n,selectedIds:g,expandedId:l,filters:r,filteredPairs:f,stats:d,allTags:a,allModels:s,allToolNames:v,loadPairs:C,updateResponse:M,updateTags:h,toggleAccepted:T,deletePairs:I,bulkSetAccepted:L,bulkAddTag:F,exportSelected:K,toggleSelection:q,selectAll:J,deselectAll:O,setExpanded:X}}),se={class:"grid grid-cols-2 gap-3 lg:grid-cols-4"},ae={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},oe={class:"text-[10px] text-text-muted uppercase tracking-wider"},ne={class:"text-xl font-bold text-text-primary"},le={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},re={class:"text-[10px] text-text-muted uppercase tracking-wider"},de={class:"text-xl font-bold text-text-primary"},ie={class:"flex items-center gap-2 text-[10px]"},ue={class:"text-success"},ce={class:"text-error"},pe={key:0,class:"h-1.5 rounded-full bg-surface-overlay overflow-hidden"},xe={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},ge={class:"text-[10px] text-text-muted uppercase tracking-wider"},me={class:"flex flex-wrap gap-1.5"},fe={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},be={class:"text-[10px] text-text-muted uppercase tracking-wider"},ve={key:0,class:"space-y-1"},ye={class:"text-text-secondary truncate"},he={class:"text-text-muted shrink-0"},$e={key:1,class:"text-[10px] text-text-muted italic"},ke=N({__name:"TrainingDashboard",props:{stats:{}},setup(t){const n=t,g=D(()=>["draft","insights","automap","fix"].map(a=>({key:a,count:n.stats.phaseBreakdown.get(a)??0}))),l=D(()=>[...n.stats.modelBreakdown.entries()].sort((d,a)=>a[1]-d[1]).slice(0,3)),r=D(()=>n.stats.total>0?Math.round(n.stats.accepted/n.stats.total*100):0),f={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(d,a)=>(p(),m("div",se,[e("div",ae,[e("p",oe,o(d.$t("training.dashboard.trainingPairs")),1),e("p",ne,o(t.stats.total),1),t.stats.estimatedBytes>0?(p(),R(ee,{key:0,used:t.stats.estimatedBytes,total:t.stats.estimatedBytes*5,compact:"",label:`~${c(_)(t.stats.estimatedBytes)} dataset`},null,8,["used","total","label"])):w("",!0)]),e("div",le,[e("p",re,o(d.$t("training.dashboard.acceptanceRate")),1),e("p",de,o(r.value)+"%",1),e("div",ie,[e("span",ue,o(t.stats.accepted)+" "+o(d.$t("training.dashboard.accepted")),1),a[0]||(a[0]=e("span",{class:"text-text-muted"},"/",-1)),e("span",ce,o(t.stats.rejected)+" "+o(d.$t("training.dashboard.rejected")),1)]),t.stats.total>0?(p(),m("div",pe,[e("div",{class:"h-full rounded-full bg-success transition-all duration-500",style:G({width:`${r.value}%`})},null,4)])):w("",!0)]),e("div",xe,[e("p",ge,o(d.$t("training.dashboard.byPhase")),1),e("div",me,[(p(!0),m(P,null,S(g.value,s=>(p(),m("span",{key:s.key,class:k(["rounded-full px-2 py-0.5 text-[10px] font-medium",f[s.key]])},o(s.key)+" "+o(s.count),3))),128))])]),e("div",fe,[e("p",be,o(d.$t("training.dashboard.topModels")),1),l.value.length>0?(p(),m("div",ve,[(p(!0),m(P,null,S(l.value,([s,v])=>(p(),m("div",{key:s,class:"flex items-center justify-between text-[10px]"},[e("span",ye,o(s),1),e("span",he,o(v),1)]))),128))])):(p(),m("p",$e,o(d.$t("common.empty.noData")),1))])]))}}),we={class:"flex flex-wrap items-center gap-2"},Ce=["value"],Te=["value"],Ae=["value"],Pe=["value"],Se=["value"],Be=["value"],De={class:"flex rounded-lg border border-border-default overflow-hidden"},Ie=["value"],Ne=["value"],je=["value","placeholder"],Me=["value"],Re=["title"],Ee=N({__name:"TrainingFilters",props:{filters:{},models:{},toolNames:{},tags:{}},emits:["update:filters"],setup(t,{emit:n}){const g=t,l=n;function r(d){l("update:filters",{...g.filters,...d})}const f=[{value:"",label:"All phases"},{value:"draft",label:"Draft"},{value:"insights",label:"Insights"},{value:"automap",label:"Auto-map"},{value:"fix",label:"Fix"}];return(d,a)=>(p(),m("div",we,[e("select",{value:t.filters.phase??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[0]||(a[0]=s=>r({phase:s.target.value||null}))},[(p(),m(P,null,S(f,s=>e("option",{key:s.label,value:s.value},o(s.label),9,Te)),64))],40,Ce),e("select",{value:t.filters.model??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[1]||(a[1]=s=>r({model:s.target.value||null}))},[a[10]||(a[10]=e("option",{value:""},"All models",-1)),(p(!0),m(P,null,S(t.models,s=>(p(),m("option",{key:s,value:s},o(s),9,Pe))),128))],40,Ae),e("select",{value:t.filters.toolName??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[2]||(a[2]=s=>r({toolName:s.target.value||null}))},[a[11]||(a[11]=e("option",{value:""},"All tools",-1)),(p(!0),m(P,null,S(t.toolNames,s=>(p(),m("option",{key:s,value:s},o(s),9,Be))),128))],40,Se),e("div",De,[e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors",t.filters.accepted===null?"bg-accent/10 text-accent":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[3]||(a[3]=s=>r({accepted:null}))},"All",2),e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors border-l border-border-default",t.filters.accepted===!0?"bg-success/10 text-success":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[4]||(a[4]=s=>r({accepted:!0}))},"Accepted",2),e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors border-l border-border-default",t.filters.accepted===!1?"bg-error/10 text-error":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[5]||(a[5]=s=>r({accepted:!1}))},"Rejected",2)]),t.tags.length>0?(p(),m("select",{key:0,value:t.filters.tag??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[6]||(a[6]=s=>r({tag:s.target.value||null}))},[a[12]||(a[12]=e("option",{value:""},"All tags",-1)),(p(!0),m(P,null,S(t.tags,s=>(p(),m("option",{key:s,value:s},o(s),9,Ne))),128))],40,Ie)):w("",!0),e("input",{value:t.filters.search,type:"text",placeholder:d.$t("training.filters.searchPrompts"),class:"flex-1 min-w-[150px] rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary placeholder-text-muted outline-none focus:border-accent",onInput:a[7]||(a[7]=s=>r({search:s.target.value}))},null,40,je),e("select",{value:t.filters.sortBy,class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[8]||(a[8]=s=>r({sortBy:s.target.value}))},[...a[13]||(a[13]=[e("option",{value:"timestamp"},"Sort by time",-1),e("option",{value:"phase"},"Sort by phase",-1),e("option",{value:"model"},"Sort by model",-1)])],40,Me),e("button",{class:"rounded-lg border border-border-default bg-surface px-2 py-1.5 text-xs text-text-muted hover:text-text-primary transition-colors",title:t.filters.sortDir==="desc"?"Newest first":"Oldest first",onClick:a[9]||(a[9]=s=>r({sortDir:t.filters.sortDir==="desc"?"asc":"desc"}))},o(t.filters.sortDir==="desc"?"↓":"↑"),9,Re)]))}}),Ue={class:"flex flex-wrap items-center gap-1.5"},Ve=["onClick"],ze=["placeholder"],Le=N({__name:"TrainingTagEditor",props:{tags:{},allTags:{}},emits:["update:tags"],setup(t,{emit:n}){const g=n,l=$("");function r(d,a){if(d.key==="Enter"||d.key===","){d.preventDefault();const s=l.value.trim().toLowerCase();s&&!a.includes(s)&&g("update:tags",[...a,s]),l.value=""}}function f(d,a){g("update:tags",d.filter(s=>s!==a))}return(d,a)=>(p(),m("div",Ue,[(p(!0),m(P,null,S(t.tags,s=>(p(),m("span",{key:s,class:"flex items-center gap-1 rounded-full bg-accent/10 px-2 py-0.5 text-[10px] text-accent"},[H(o(s)+" ",1),e("button",{class:"text-accent/60 hover:text-accent transition-colors",onClick:v=>f(t.tags,s)},[j(c(Q),{class:"h-2.5 w-2.5","stroke-width":3})],8,Ve)]))),128)),E(e("input",{"onUpdate:modelValue":a[0]||(a[0]=s=>l.value=s),type:"text",placeholder:d.$t("training.tags.addPlaceholder"),class:"w-20 bg-transparent text-[10px] text-text-primary placeholder-text-muted outline-none",onKeydown:a[1]||(a[1]=s=>r(s,t.tags))},null,40,ze),[[U,l.value]])]))}}),Fe={class:"rounded-lg border border-accent/30 bg-surface-raised p-4 space-y-4"},Ke={class:"flex items-center justify-between"},qe={class:"flex items-center gap-2"},Je={class:"text-xs text-text-secondary"},Oe={class:"text-[10px] text-text-muted"},Xe={class:"text-[10px] text-text-muted"},Ze={class:"flex items-center gap-2"},Ge={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-text-muted"},He={class:"max-h-32 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},Qe={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-text-muted"},We={class:"max-h-32 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},Ye={key:0},_e={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-accent"},et={class:"max-h-40 overflow-auto rounded-lg bg-accent/5 border border-accent/20 p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono italic"},tt={class:"mb-1 flex items-center justify-between"},st={class:"text-[10px] font-medium uppercase tracking-wider text-text-muted"},at={key:1,class:"max-h-64 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},ot={key:2,class:"mt-2 flex gap-2"},nt={class:"mb-1.5 text-[10px] font-medium uppercase tracking-wider text-text-muted"},lt={class:"flex items-center justify-end border-t border-border-default pt-3"},rt=N({__name:"TrainingDetailPanel",props:{pair:{},allTags:{}},emits:["close","update:response","update:tags","toggle-accepted","delete"],setup(t,{emit:n}){const g=t,l=n,r=$(!1),f=$(""),d=$(!1);function a(){f.value=g.pair.response,r.value=!0}function s(){l("update:response",g.pair.id,f.value),r.value=!1}function v(){r.value=!1}function C(){d.value?(l("delete",g.pair.id),d.value=!1):(d.value=!0,setTimeout(()=>{d.value=!1},3e3))}const M={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(h,T)=>(p(),m("div",Fe,[e("div",Ke,[e("div",qe,[e("span",{class:k(["rounded-full px-2 py-0.5 text-[10px] font-medium",M[t.pair.phase]])},o(t.pair.phase),3),e("span",Je,o(t.pair.toolName),1),e("span",Oe,o(t.pair.model),1),e("span",Xe,o(c(z)(t.pair.timestamp)),1)]),e("div",Ze,[e("button",{class:k(["rounded px-2 py-1 text-[10px] transition-colors",t.pair.accepted?"bg-success/10 text-success":"bg-error/10 text-error"]),onClick:T[0]||(T[0]=I=>l("toggle-accepted",t.pair.id))},o(t.pair.accepted?h.$t("training.detail.accepted"):h.$t("training.detail.rejected")),3),e("button",{class:"text-text-muted hover:text-text-primary transition-colors text-xs","aria-label":"Close panel",onClick:T[1]||(T[1]=I=>l("close"))}," ✕ ")])]),e("div",null,[e("p",Ge,o(h.$t("training.detail.systemPrompt")),1),e("pre",He,o(t.pair.systemPrompt),1)]),e("div",null,[e("p",Qe,o(h.$t("training.detail.userPrompt")),1),e("pre",We,o(t.pair.userPrompt),1)]),t.pair.reasoning?(p(),m("div",Ye,[e("p",_e,o(h.$t("training.detail.reasoning")),1),e("pre",et,o(t.pair.reasoning),1)])):w("",!0),e("div",null,[e("div",tt,[e("p",st,o(h.$t("training.detail.aiResponse")),1),r.value?w("",!0):(p(),m("button",{key:0,class:"text-[10px] text-accent hover:underline",onClick:a},o(h.$t("training.detail.editResponse")),1))]),r.value?E((p(),m("textarea",{key:0,"onUpdate:modelValue":T[2]||(T[2]=I=>f.value=I),rows:"8",class:"w-full rounded-lg border border-accent bg-surface px-3 py-2 text-xs text-text-primary font-mono outline-none resize-y"},null,512)),[[U,f.value]]):(p(),m("pre",at,o(t.pair.response),1)),r.value?(p(),m("div",ot,[e("button",{class:"rounded-lg bg-accent px-3 py-1 text-xs text-white hover:bg-accent-hover transition-colors",onClick:s},o(h.$t("common.actions.save")),1),e("button",{class:"rounded-lg px-3 py-1 text-xs text-text-muted hover:text-text-primary transition-colors",onClick:v},o(h.$t("common.actions.cancel")),1)])):w("",!0)]),e("div",null,[e("p",nt,o(h.$t("training.detail.tags")),1),j(Le,{tags:t.pair.tags??[],"all-tags":t.allTags,"onUpdate:tags":T[3]||(T[3]=I=>l("update:tags",t.pair.id,I))},null,8,["tags","all-tags"])]),e("div",lt,[e("button",{class:k(["rounded-lg px-3 py-1 text-xs transition-colors",d.value?"bg-error/10 text-error":"text-text-muted hover:text-error"]),onClick:C},o(d.value?h.$t("training.detail.confirmDelete"):h.$t("training.detail.deletePair")),3)])]))}}),dt={key:0,class:"rounded-lg bg-surface-overlay p-8 text-center"},it={class:"text-sm text-text-muted"},ut={key:1,class:"space-y-1"},ct=["onClick"],pt=["onClick"],xt={key:0,class:"text-[8px]"},gt={class:"shrink-0 text-text-secondary w-24 truncate"},mt={class:"shrink-0 text-text-muted w-28 truncate"},ft={class:"flex items-center gap-1 shrink-0"},bt={key:0,class:"text-[8px] text-text-muted"},vt={class:"flex-1 min-w-0 truncate text-text-muted"},yt={class:"shrink-0 text-[10px] text-text-muted"},ht=N({__name:"TrainingTable",props:{pairs:{},selectedIds:{},expandedId:{},allTags:{}},emits:["toggle-selection","set-expanded","update:response","update:tags","toggle-accepted","delete"],setup(t,{emit:n}){const g=n,l={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(r,f)=>t.pairs.length===0?(p(),m("div",dt,[e("p",it,o(r.$t("training.table.noResults")),1)])):(p(),m("div",ut,[(p(!0),m(P,null,S(t.pairs,d=>(p(),m("div",{key:d.id},[e("div",{class:k(["flex items-center gap-3 rounded-lg border border-border-default bg-surface-raised px-3 py-2.5 text-xs transition-colors cursor-pointer hover:border-accent/30",t.expandedId===d.id?"border-accent/50":""]),onClick:a=>g("set-expanded",d.id)},[e("button",{class:k(["flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",t.selectedIds.has(d.id)?"border-accent bg-accent text-white":"border-border-default hover:border-accent"]),onClick:W(a=>g("toggle-selection",d.id),["stop"])},[t.selectedIds.has(d.id)?(p(),m("span",xt,"✓")):w("",!0)],10,pt),e("span",{class:k(["shrink-0 rounded-full px-2 py-0.5 text-[9px] font-medium",l[d.phase]])},o(d.phase),3),e("span",gt,o(d.toolName),1),e("span",mt,o(d.model),1),e("span",{class:k(["shrink-0 rounded-full px-1.5 py-0.5 text-[9px]",d.accepted?"bg-success/10 text-success":"bg-error/10 text-error"])},o(d.accepted?r.$t("training.dashboard.accepted"):r.$t("training.dashboard.rejected")),3),e("div",ft,[(p(!0),m(P,null,S((d.tags??[]).slice(0,2),a=>(p(),m("span",{key:a,class:"rounded-full bg-accent/10 px-1.5 py-0.5 text-[8px] text-accent"},o(a),1))),128)),(d.tags??[]).length>2?(p(),m("span",bt,"+"+o((d.tags??[]).length-2),1)):w("",!0)]),e("span",vt,o(d.userPrompt.slice(0,80))+o(d.userPrompt.length>80?"...":""),1),e("span",yt,o(c(z)(d.timestamp)),1)],10,ct),t.expandedId===d.id?(p(),R(rt,{key:0,pair:d,"all-tags":t.allTags,class:"mt-1 ms-7",onClose:f[0]||(f[0]=a=>g("set-expanded",null)),"onUpdate:response":f[1]||(f[1]=(a,s)=>g("update:response",a,s)),"onUpdate:tags":f[2]||(f[2]=(a,s)=>g("update:tags",a,s)),onToggleAccepted:f[3]||(f[3]=a=>g("toggle-accepted",a)),onDelete:f[4]||(f[4]=a=>g("delete",a))},null,8,["pair","all-tags"])):w("",!0)]))),128))]))}}),$t={class:"flex items-center gap-2 rounded-lg border border-accent/30 bg-surface-raised px-4 py-2.5"},kt={class:"text-xs font-medium text-accent"},wt={class:"ms-auto flex items-center gap-2"},Ct={key:0,class:"flex items-center gap-1"},Tt=["placeholder"],At=N({__name:"TrainingBulkActions",props:{selectedCount:{}},emits:["export","mark-accepted","mark-rejected","add-tag","delete","deselect-all"],setup(t,{emit:n}){const g=n,l=$(!1),r=$(""),f=$(!1);function d(){const s=r.value.trim().toLowerCase();s&&(g("add-tag",s),r.value="",l.value=!1)}function a(){f.value?(g("delete"),f.value=!1):(f.value=!0,setTimeout(()=>{f.value=!1},3e3))}return(s,v)=>(p(),m("div",$t,[e("span",kt,o(s.$t("training.bulk.selected",{count:t.selectedCount})),1),e("div",wt,[e("button",{class:"rounded-lg bg-surface-overlay px-3 py-1 text-[10px] text-text-secondary hover:text-text-primary transition-colors",onClick:v[0]||(v[0]=C=>g("export"))},o(s.$t("training.bulk.exportJsonl")),1),e("button",{class:"rounded-lg bg-success/10 px-3 py-1 text-[10px] text-success hover:bg-success/20 transition-colors",onClick:v[1]||(v[1]=C=>g("mark-accepted"))},o(s.$t("training.bulk.markAccepted")),1),e("button",{class:"rounded-lg bg-error/10 px-3 py-1 text-[10px] text-error hover:bg-error/20 transition-colors",onClick:v[2]||(v[2]=C=>g("mark-rejected"))},o(s.$t("training.bulk.markRejected")),1),l.value?(p(),m("div",Ct,[E(e("input",{"onUpdate:modelValue":v[3]||(v[3]=C=>r.value=C),type:"text",placeholder:s.$t("training.bulk.tagPlaceholder"),class:"w-24 rounded border border-accent bg-surface px-2 py-0.5 text-[10px] text-text-primary outline-none",onKeydown:[V(d,["enter"]),v[4]||(v[4]=V(C=>l.value=!1,["escape"]))]},null,40,Tt),[[U,r.value]]),e("button",{class:"text-[10px] text-accent hover:underline",onClick:d},o(s.$t("common.actions.add")),1)])):(p(),m("button",{key:1,class:"rounded-lg bg-accent/10 px-3 py-1 text-[10px] text-accent hover:bg-accent/20 transition-colors",onClick:v[5]||(v[5]=C=>l.value=!0)},o(s.$t("training.bulk.addTag")),1)),e("button",{class:k(["rounded-lg px-3 py-1 text-[10px] transition-colors",f.value?"bg-error/10 text-error":"text-text-muted hover:text-error"]),onClick:a},o(f.value?s.$t("training.bulk.confirm"):s.$t("training.bulk.delete")),3),e("button",{class:"text-[10px] text-text-muted hover:text-text-primary transition-colors",onClick:v[6]||(v[6]=C=>g("deselect-all"))},o(s.$t("training.bulk.deselectAll")),1)])]))}}),Pt={class:"mx-auto max-w-6xl space-y-6"},St={class:"text-lg font-semibold text-text-primary"},Bt={class:"text-sm text-text-muted"},Dt={key:1,class:"flex items-center gap-3"},It={class:"text-[10px] text-text-muted"},Nt={key:2,class:"rounded-lg border border-border-default bg-surface-raised p-8 text-center"},jt={class:"text-sm text-text-muted mb-2"},Mt={class:"text-xs text-text-muted"},zt=N({__name:"AITrainingPage",setup(t){const n=te();return Y(()=>{n.loadPairs()}),(g,l)=>(p(),m("div",Pt,[e("div",null,[e("h2",St,o(g.$t("training.title")),1),e("p",Bt,o(g.$t("training.subtitle")),1)]),j(ke,{stats:c(n).stats},null,8,["stats"]),j(Ee,{filters:c(n).filters,models:c(n).allModels,"tool-names":c(n).allToolNames,tags:c(n).allTags,"onUpdate:filters":l[0]||(l[0]=r=>c(n).filters=r)},null,8,["filters","models","tool-names","tags"]),c(n).selectedIds.size>0?(p(),R(At,{key:0,"selected-count":c(n).selectedIds.size,onExport:l[1]||(l[1]=r=>c(n).exportSelected([...c(n).selectedIds])),onMarkAccepted:l[2]||(l[2]=r=>c(n).bulkSetAccepted([...c(n).selectedIds],!0)),onMarkRejected:l[3]||(l[3]=r=>c(n).bulkSetAccepted([...c(n).selectedIds],!1)),onAddTag:l[4]||(l[4]=r=>c(n).bulkAddTag([...c(n).selectedIds],r)),onDelete:l[5]||(l[5]=r=>c(n).deletePairs([...c(n).selectedIds])),onDeselectAll:l[6]||(l[6]=r=>c(n).deselectAll())},null,8,["selected-count"])):w("",!0),c(n).filteredPairs.length>0?(p(),m("div",Dt,[e("button",{class:"text-[10px] text-text-muted hover:text-accent transition-colors",onClick:l[7]||(l[7]=r=>c(n).selectedIds.size===c(n).filteredPairs.length?c(n).deselectAll():c(n).selectAll())},o(c(n).selectedIds.size===c(n).filteredPairs.length?g.$t("training.table.deselectAll"):g.$t("training.table.selectAll")+" "+c(n).filteredPairs.length),1),e("span",It,o(g.$t("training.table.pairsShown",{shown:c(n).filteredPairs.length,total:c(n).pairs.length})),1)])):w("",!0),j(ht,{pairs:c(n).filteredPairs,"selected-ids":c(n).selectedIds,"expanded-id":c(n).expandedId,"all-tags":c(n).allTags,onToggleSelection:l[8]||(l[8]=r=>c(n).toggleSelection(r)),onSetExpanded:l[9]||(l[9]=r=>c(n).setExpanded(r)),"onUpdate:response":l[10]||(l[10]=(r,f)=>c(n).updateResponse(r,f)),"onUpdate:tags":l[11]||(l[11]=(r,f)=>c(n).updateTags(r,f)),onToggleAccepted:l[12]||(l[12]=r=>c(n).toggleAccepted(r)),onDelete:l[13]||(l[13]=r=>c(n).deletePairs([r]))},null,8,["pairs","selected-ids","expanded-id","all-tags"]),c(n).pairs.length===0&&!c(n).loading?(p(),m("div",Nt,[e("p",jt,o(g.$t("training.empty.title")),1),e("p",Mt,o(g.$t("training.empty.description")),1)])):w("",!0)]))}});export{zt as default};
|
|
1
|
+
import{d as Z,r as $,a as D,b as N,e as m,f as e,t as o,q as R,u as c,i as w,l as G,F as P,k as S,g as k,j as p,h as H,p as j,X as Q,C as E,D as U,v as W,Z as V,B as Y}from"./index-CZ4a6rAU.js";import{canvasAiDB as B}from"./canvas-ai-db-Ck_6zOgd.js";import{b as _,d as z}from"./format-BqVZ9rwM.js";import{_ as ee}from"./StorageGauge.vue_vue_type_style_index_0_lang-DOKnxhnC.js";const te=Z("training",()=>{const t=$([]),n=$(!1),g=$(new Set),l=$(null),r=$({phase:null,model:null,accepted:null,toolName:null,tag:null,search:"",sortBy:"timestamp",sortDir:"desc"}),f=D(()=>{let i=[...t.value];const u=r.value;if(u.phase&&(i=i.filter(x=>x.phase===u.phase)),u.model&&(i=i.filter(x=>x.model===u.model)),u.accepted!==null&&(i=i.filter(x=>x.accepted===u.accepted)),u.toolName&&(i=i.filter(x=>x.toolName===u.toolName)),u.tag&&(i=i.filter(x=>x.tags?.includes(u.tag)??!1)),u.search){const x=u.search.toLowerCase();i=i.filter(b=>b.userPrompt.toLowerCase().includes(x)||b.response.toLowerCase().includes(x)||b.toolName.toLowerCase().includes(x))}return i.sort((x,b)=>{let y=0;return u.sortBy==="timestamp"?y=x.timestamp-b.timestamp:u.sortBy==="phase"?y=x.phase.localeCompare(b.phase):u.sortBy==="model"&&(y=x.model.localeCompare(b.model)),u.sortDir==="desc"?-y:y}),i}),d=D(()=>{const i=t.value,u=new Map,x=new Map;let b=0,y=0;for(const A of i)A.accepted&&b++,u.set(A.phase,(u.get(A.phase)??0)+1),x.set(A.model,(x.get(A.model)??0)+1),y+=A.systemPrompt.length+A.userPrompt.length+A.response.length;return{total:i.length,accepted:b,rejected:i.length-b,phaseBreakdown:u,modelBreakdown:x,estimatedBytes:y*2}}),a=D(()=>{const i=new Set;for(const u of t.value)for(const x of u.tags??[])i.add(x);return[...i].sort()}),s=D(()=>[...new Set(t.value.map(i=>i.model))].sort()),v=D(()=>[...new Set(t.value.map(i=>i.toolName))].sort());async function C(){n.value=!0;try{t.value=await B.getAllPairs()}catch(i){console.error("Failed to load training pairs:",i)}finally{n.value=!1}}async function M(i,u){await B.updatePairResponse(i,u);const x=t.value.find(b=>b.id===i);x&&(x.response=u)}async function h(i,u){await B.updatePairTags(i,u);const x=t.value.find(b=>b.id===i);x&&(x.tags=u)}async function T(i){const u=t.value.find(b=>b.id===i);if(!u)return;const x=!u.accepted;await B.updateAccepted(i,x),u.accepted=x}async function I(i){await B.deletePairs(i);const u=new Set(i);t.value=t.value.filter(x=>!u.has(x.id));for(const x of i)g.value.delete(x);l.value&&u.has(l.value)&&(l.value=null)}async function L(i,u){for(const x of i){await B.updateAccepted(x,u);const b=t.value.find(y=>y.id===x);b&&(b.accepted=u)}}async function F(i,u){for(const x of i){const b=t.value.find(A=>A.id===x);if(!b)continue;const y=[...b.tags??[]];y.includes(u)||(y.push(u),await B.updatePairTags(x,y),b.tags=y)}}function K(i){B.exportSelectedAsJsonl(i)}function q(i){const u=new Set(g.value);u.has(i)?u.delete(i):u.add(i),g.value=u}function J(){g.value=new Set(f.value.map(i=>i.id))}function O(){g.value=new Set}function X(i){l.value=l.value===i?null:i}return{pairs:t,loading:n,selectedIds:g,expandedId:l,filters:r,filteredPairs:f,stats:d,allTags:a,allModels:s,allToolNames:v,loadPairs:C,updateResponse:M,updateTags:h,toggleAccepted:T,deletePairs:I,bulkSetAccepted:L,bulkAddTag:F,exportSelected:K,toggleSelection:q,selectAll:J,deselectAll:O,setExpanded:X}}),se={class:"grid grid-cols-2 gap-3 lg:grid-cols-4"},ae={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},oe={class:"text-[10px] text-text-muted uppercase tracking-wider"},ne={class:"text-xl font-bold text-text-primary"},le={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},re={class:"text-[10px] text-text-muted uppercase tracking-wider"},de={class:"text-xl font-bold text-text-primary"},ie={class:"flex items-center gap-2 text-[10px]"},ue={class:"text-success"},ce={class:"text-error"},pe={key:0,class:"h-1.5 rounded-full bg-surface-overlay overflow-hidden"},xe={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},ge={class:"text-[10px] text-text-muted uppercase tracking-wider"},me={class:"flex flex-wrap gap-1.5"},fe={class:"rounded-lg border border-border-default bg-surface-raised p-3 space-y-2"},be={class:"text-[10px] text-text-muted uppercase tracking-wider"},ve={key:0,class:"space-y-1"},ye={class:"text-text-secondary truncate"},he={class:"text-text-muted shrink-0"},$e={key:1,class:"text-[10px] text-text-muted italic"},ke=N({__name:"TrainingDashboard",props:{stats:{}},setup(t){const n=t,g=D(()=>["draft","insights","automap","fix"].map(a=>({key:a,count:n.stats.phaseBreakdown.get(a)??0}))),l=D(()=>[...n.stats.modelBreakdown.entries()].sort((d,a)=>a[1]-d[1]).slice(0,3)),r=D(()=>n.stats.total>0?Math.round(n.stats.accepted/n.stats.total*100):0),f={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(d,a)=>(p(),m("div",se,[e("div",ae,[e("p",oe,o(d.$t("training.dashboard.trainingPairs")),1),e("p",ne,o(t.stats.total),1),t.stats.estimatedBytes>0?(p(),R(ee,{key:0,used:t.stats.estimatedBytes,total:t.stats.estimatedBytes*5,compact:"",label:`~${c(_)(t.stats.estimatedBytes)} dataset`},null,8,["used","total","label"])):w("",!0)]),e("div",le,[e("p",re,o(d.$t("training.dashboard.acceptanceRate")),1),e("p",de,o(r.value)+"%",1),e("div",ie,[e("span",ue,o(t.stats.accepted)+" "+o(d.$t("training.dashboard.accepted")),1),a[0]||(a[0]=e("span",{class:"text-text-muted"},"/",-1)),e("span",ce,o(t.stats.rejected)+" "+o(d.$t("training.dashboard.rejected")),1)]),t.stats.total>0?(p(),m("div",pe,[e("div",{class:"h-full rounded-full bg-success transition-all duration-500",style:G({width:`${r.value}%`})},null,4)])):w("",!0)]),e("div",xe,[e("p",ge,o(d.$t("training.dashboard.byPhase")),1),e("div",me,[(p(!0),m(P,null,S(g.value,s=>(p(),m("span",{key:s.key,class:k(["rounded-full px-2 py-0.5 text-[10px] font-medium",f[s.key]])},o(s.key)+" "+o(s.count),3))),128))])]),e("div",fe,[e("p",be,o(d.$t("training.dashboard.topModels")),1),l.value.length>0?(p(),m("div",ve,[(p(!0),m(P,null,S(l.value,([s,v])=>(p(),m("div",{key:s,class:"flex items-center justify-between text-[10px]"},[e("span",ye,o(s),1),e("span",he,o(v),1)]))),128))])):(p(),m("p",$e,o(d.$t("common.empty.noData")),1))])]))}}),we={class:"flex flex-wrap items-center gap-2"},Ce=["value"],Te=["value"],Ae=["value"],Pe=["value"],Se=["value"],Be=["value"],De={class:"flex rounded-lg border border-border-default overflow-hidden"},Ie=["value"],Ne=["value"],je=["value","placeholder"],Me=["value"],Re=["title"],Ee=N({__name:"TrainingFilters",props:{filters:{},models:{},toolNames:{},tags:{}},emits:["update:filters"],setup(t,{emit:n}){const g=t,l=n;function r(d){l("update:filters",{...g.filters,...d})}const f=[{value:"",label:"All phases"},{value:"draft",label:"Draft"},{value:"insights",label:"Insights"},{value:"automap",label:"Auto-map"},{value:"fix",label:"Fix"}];return(d,a)=>(p(),m("div",we,[e("select",{value:t.filters.phase??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[0]||(a[0]=s=>r({phase:s.target.value||null}))},[(p(),m(P,null,S(f,s=>e("option",{key:s.label,value:s.value},o(s.label),9,Te)),64))],40,Ce),e("select",{value:t.filters.model??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[1]||(a[1]=s=>r({model:s.target.value||null}))},[a[10]||(a[10]=e("option",{value:""},"All models",-1)),(p(!0),m(P,null,S(t.models,s=>(p(),m("option",{key:s,value:s},o(s),9,Pe))),128))],40,Ae),e("select",{value:t.filters.toolName??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[2]||(a[2]=s=>r({toolName:s.target.value||null}))},[a[11]||(a[11]=e("option",{value:""},"All tools",-1)),(p(!0),m(P,null,S(t.toolNames,s=>(p(),m("option",{key:s,value:s},o(s),9,Be))),128))],40,Se),e("div",De,[e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors",t.filters.accepted===null?"bg-accent/10 text-accent":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[3]||(a[3]=s=>r({accepted:null}))},"All",2),e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors border-l border-border-default",t.filters.accepted===!0?"bg-success/10 text-success":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[4]||(a[4]=s=>r({accepted:!0}))},"Accepted",2),e("button",{class:k(["px-2.5 py-1.5 text-[10px] transition-colors border-l border-border-default",t.filters.accepted===!1?"bg-error/10 text-error":"bg-surface text-text-muted hover:text-text-primary"]),onClick:a[5]||(a[5]=s=>r({accepted:!1}))},"Rejected",2)]),t.tags.length>0?(p(),m("select",{key:0,value:t.filters.tag??"",class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[6]||(a[6]=s=>r({tag:s.target.value||null}))},[a[12]||(a[12]=e("option",{value:""},"All tags",-1)),(p(!0),m(P,null,S(t.tags,s=>(p(),m("option",{key:s,value:s},o(s),9,Ne))),128))],40,Ie)):w("",!0),e("input",{value:t.filters.search,type:"text",placeholder:d.$t("training.filters.searchPrompts"),class:"flex-1 min-w-[150px] rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary placeholder-text-muted outline-none focus:border-accent",onInput:a[7]||(a[7]=s=>r({search:s.target.value}))},null,40,je),e("select",{value:t.filters.sortBy,class:"rounded-lg border border-border-default bg-surface px-2.5 py-1.5 text-xs text-text-primary outline-none focus:border-accent",onChange:a[8]||(a[8]=s=>r({sortBy:s.target.value}))},[...a[13]||(a[13]=[e("option",{value:"timestamp"},"Sort by time",-1),e("option",{value:"phase"},"Sort by phase",-1),e("option",{value:"model"},"Sort by model",-1)])],40,Me),e("button",{class:"rounded-lg border border-border-default bg-surface px-2 py-1.5 text-xs text-text-muted hover:text-text-primary transition-colors",title:t.filters.sortDir==="desc"?"Newest first":"Oldest first",onClick:a[9]||(a[9]=s=>r({sortDir:t.filters.sortDir==="desc"?"asc":"desc"}))},o(t.filters.sortDir==="desc"?"↓":"↑"),9,Re)]))}}),Ue={class:"flex flex-wrap items-center gap-1.5"},Ve=["onClick"],ze=["placeholder"],Le=N({__name:"TrainingTagEditor",props:{tags:{},allTags:{}},emits:["update:tags"],setup(t,{emit:n}){const g=n,l=$("");function r(d,a){if(d.key==="Enter"||d.key===","){d.preventDefault();const s=l.value.trim().toLowerCase();s&&!a.includes(s)&&g("update:tags",[...a,s]),l.value=""}}function f(d,a){g("update:tags",d.filter(s=>s!==a))}return(d,a)=>(p(),m("div",Ue,[(p(!0),m(P,null,S(t.tags,s=>(p(),m("span",{key:s,class:"flex items-center gap-1 rounded-full bg-accent/10 px-2 py-0.5 text-[10px] text-accent"},[H(o(s)+" ",1),e("button",{class:"text-accent/60 hover:text-accent transition-colors",onClick:v=>f(t.tags,s)},[j(c(Q),{class:"h-2.5 w-2.5","stroke-width":3})],8,Ve)]))),128)),E(e("input",{"onUpdate:modelValue":a[0]||(a[0]=s=>l.value=s),type:"text",placeholder:d.$t("training.tags.addPlaceholder"),class:"w-20 bg-transparent text-[10px] text-text-primary placeholder-text-muted outline-none",onKeydown:a[1]||(a[1]=s=>r(s,t.tags))},null,40,ze),[[U,l.value]])]))}}),Fe={class:"rounded-lg border border-accent/30 bg-surface-raised p-4 space-y-4"},Ke={class:"flex items-center justify-between"},qe={class:"flex items-center gap-2"},Je={class:"text-xs text-text-secondary"},Oe={class:"text-[10px] text-text-muted"},Xe={class:"text-[10px] text-text-muted"},Ze={class:"flex items-center gap-2"},Ge={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-text-muted"},He={class:"max-h-32 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},Qe={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-text-muted"},We={class:"max-h-32 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},Ye={key:0},_e={class:"mb-1 text-[10px] font-medium uppercase tracking-wider text-accent"},et={class:"max-h-40 overflow-auto rounded-lg bg-accent/5 border border-accent/20 p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono italic"},tt={class:"mb-1 flex items-center justify-between"},st={class:"text-[10px] font-medium uppercase tracking-wider text-text-muted"},at={key:1,class:"max-h-64 overflow-auto rounded-lg bg-surface p-3 text-xs text-text-secondary whitespace-pre-wrap font-mono"},ot={key:2,class:"mt-2 flex gap-2"},nt={class:"mb-1.5 text-[10px] font-medium uppercase tracking-wider text-text-muted"},lt={class:"flex items-center justify-end border-t border-border-default pt-3"},rt=N({__name:"TrainingDetailPanel",props:{pair:{},allTags:{}},emits:["close","update:response","update:tags","toggle-accepted","delete"],setup(t,{emit:n}){const g=t,l=n,r=$(!1),f=$(""),d=$(!1);function a(){f.value=g.pair.response,r.value=!0}function s(){l("update:response",g.pair.id,f.value),r.value=!1}function v(){r.value=!1}function C(){d.value?(l("delete",g.pair.id),d.value=!1):(d.value=!0,setTimeout(()=>{d.value=!1},3e3))}const M={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(h,T)=>(p(),m("div",Fe,[e("div",Ke,[e("div",qe,[e("span",{class:k(["rounded-full px-2 py-0.5 text-[10px] font-medium",M[t.pair.phase]])},o(t.pair.phase),3),e("span",Je,o(t.pair.toolName),1),e("span",Oe,o(t.pair.model),1),e("span",Xe,o(c(z)(t.pair.timestamp)),1)]),e("div",Ze,[e("button",{class:k(["rounded px-2 py-1 text-[10px] transition-colors",t.pair.accepted?"bg-success/10 text-success":"bg-error/10 text-error"]),onClick:T[0]||(T[0]=I=>l("toggle-accepted",t.pair.id))},o(t.pair.accepted?h.$t("training.detail.accepted"):h.$t("training.detail.rejected")),3),e("button",{class:"text-text-muted hover:text-text-primary transition-colors text-xs","aria-label":"Close panel",onClick:T[1]||(T[1]=I=>l("close"))}," ✕ ")])]),e("div",null,[e("p",Ge,o(h.$t("training.detail.systemPrompt")),1),e("pre",He,o(t.pair.systemPrompt),1)]),e("div",null,[e("p",Qe,o(h.$t("training.detail.userPrompt")),1),e("pre",We,o(t.pair.userPrompt),1)]),t.pair.reasoning?(p(),m("div",Ye,[e("p",_e,o(h.$t("training.detail.reasoning")),1),e("pre",et,o(t.pair.reasoning),1)])):w("",!0),e("div",null,[e("div",tt,[e("p",st,o(h.$t("training.detail.aiResponse")),1),r.value?w("",!0):(p(),m("button",{key:0,class:"text-[10px] text-accent hover:underline",onClick:a},o(h.$t("training.detail.editResponse")),1))]),r.value?E((p(),m("textarea",{key:0,"onUpdate:modelValue":T[2]||(T[2]=I=>f.value=I),rows:"8",class:"w-full rounded-lg border border-accent bg-surface px-3 py-2 text-xs text-text-primary font-mono outline-none resize-y"},null,512)),[[U,f.value]]):(p(),m("pre",at,o(t.pair.response),1)),r.value?(p(),m("div",ot,[e("button",{class:"rounded-lg bg-accent px-3 py-1 text-xs text-white hover:bg-accent-hover transition-colors",onClick:s},o(h.$t("common.actions.save")),1),e("button",{class:"rounded-lg px-3 py-1 text-xs text-text-muted hover:text-text-primary transition-colors",onClick:v},o(h.$t("common.actions.cancel")),1)])):w("",!0)]),e("div",null,[e("p",nt,o(h.$t("training.detail.tags")),1),j(Le,{tags:t.pair.tags??[],"all-tags":t.allTags,"onUpdate:tags":T[3]||(T[3]=I=>l("update:tags",t.pair.id,I))},null,8,["tags","all-tags"])]),e("div",lt,[e("button",{class:k(["rounded-lg px-3 py-1 text-xs transition-colors",d.value?"bg-error/10 text-error":"text-text-muted hover:text-error"]),onClick:C},o(d.value?h.$t("training.detail.confirmDelete"):h.$t("training.detail.deletePair")),3)])]))}}),dt={key:0,class:"rounded-lg bg-surface-overlay p-8 text-center"},it={class:"text-sm text-text-muted"},ut={key:1,class:"space-y-1"},ct=["onClick"],pt=["onClick"],xt={key:0,class:"text-[8px]"},gt={class:"shrink-0 text-text-secondary w-24 truncate"},mt={class:"shrink-0 text-text-muted w-28 truncate"},ft={class:"flex items-center gap-1 shrink-0"},bt={key:0,class:"text-[8px] text-text-muted"},vt={class:"flex-1 min-w-0 truncate text-text-muted"},yt={class:"shrink-0 text-[10px] text-text-muted"},ht=N({__name:"TrainingTable",props:{pairs:{},selectedIds:{},expandedId:{},allTags:{}},emits:["toggle-selection","set-expanded","update:response","update:tags","toggle-accepted","delete"],setup(t,{emit:n}){const g=n,l={draft:"bg-blue-500/20 text-blue-400",insights:"bg-amber-500/20 text-amber-400",automap:"bg-emerald-500/20 text-emerald-400",fix:"bg-rose-500/20 text-rose-400"};return(r,f)=>t.pairs.length===0?(p(),m("div",dt,[e("p",it,o(r.$t("training.table.noResults")),1)])):(p(),m("div",ut,[(p(!0),m(P,null,S(t.pairs,d=>(p(),m("div",{key:d.id},[e("div",{class:k(["flex items-center gap-3 rounded-lg border border-border-default bg-surface-raised px-3 py-2.5 text-xs transition-colors cursor-pointer hover:border-accent/30",t.expandedId===d.id?"border-accent/50":""]),onClick:a=>g("set-expanded",d.id)},[e("button",{class:k(["flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",t.selectedIds.has(d.id)?"border-accent bg-accent text-white":"border-border-default hover:border-accent"]),onClick:W(a=>g("toggle-selection",d.id),["stop"])},[t.selectedIds.has(d.id)?(p(),m("span",xt,"✓")):w("",!0)],10,pt),e("span",{class:k(["shrink-0 rounded-full px-2 py-0.5 text-[9px] font-medium",l[d.phase]])},o(d.phase),3),e("span",gt,o(d.toolName),1),e("span",mt,o(d.model),1),e("span",{class:k(["shrink-0 rounded-full px-1.5 py-0.5 text-[9px]",d.accepted?"bg-success/10 text-success":"bg-error/10 text-error"])},o(d.accepted?r.$t("training.dashboard.accepted"):r.$t("training.dashboard.rejected")),3),e("div",ft,[(p(!0),m(P,null,S((d.tags??[]).slice(0,2),a=>(p(),m("span",{key:a,class:"rounded-full bg-accent/10 px-1.5 py-0.5 text-[8px] text-accent"},o(a),1))),128)),(d.tags??[]).length>2?(p(),m("span",bt,"+"+o((d.tags??[]).length-2),1)):w("",!0)]),e("span",vt,o(d.userPrompt.slice(0,80))+o(d.userPrompt.length>80?"...":""),1),e("span",yt,o(c(z)(d.timestamp)),1)],10,ct),t.expandedId===d.id?(p(),R(rt,{key:0,pair:d,"all-tags":t.allTags,class:"mt-1 ms-7",onClose:f[0]||(f[0]=a=>g("set-expanded",null)),"onUpdate:response":f[1]||(f[1]=(a,s)=>g("update:response",a,s)),"onUpdate:tags":f[2]||(f[2]=(a,s)=>g("update:tags",a,s)),onToggleAccepted:f[3]||(f[3]=a=>g("toggle-accepted",a)),onDelete:f[4]||(f[4]=a=>g("delete",a))},null,8,["pair","all-tags"])):w("",!0)]))),128))]))}}),$t={class:"flex items-center gap-2 rounded-lg border border-accent/30 bg-surface-raised px-4 py-2.5"},kt={class:"text-xs font-medium text-accent"},wt={class:"ms-auto flex items-center gap-2"},Ct={key:0,class:"flex items-center gap-1"},Tt=["placeholder"],At=N({__name:"TrainingBulkActions",props:{selectedCount:{}},emits:["export","mark-accepted","mark-rejected","add-tag","delete","deselect-all"],setup(t,{emit:n}){const g=n,l=$(!1),r=$(""),f=$(!1);function d(){const s=r.value.trim().toLowerCase();s&&(g("add-tag",s),r.value="",l.value=!1)}function a(){f.value?(g("delete"),f.value=!1):(f.value=!0,setTimeout(()=>{f.value=!1},3e3))}return(s,v)=>(p(),m("div",$t,[e("span",kt,o(s.$t("training.bulk.selected",{count:t.selectedCount})),1),e("div",wt,[e("button",{class:"rounded-lg bg-surface-overlay px-3 py-1 text-[10px] text-text-secondary hover:text-text-primary transition-colors",onClick:v[0]||(v[0]=C=>g("export"))},o(s.$t("training.bulk.exportJsonl")),1),e("button",{class:"rounded-lg bg-success/10 px-3 py-1 text-[10px] text-success hover:bg-success/20 transition-colors",onClick:v[1]||(v[1]=C=>g("mark-accepted"))},o(s.$t("training.bulk.markAccepted")),1),e("button",{class:"rounded-lg bg-error/10 px-3 py-1 text-[10px] text-error hover:bg-error/20 transition-colors",onClick:v[2]||(v[2]=C=>g("mark-rejected"))},o(s.$t("training.bulk.markRejected")),1),l.value?(p(),m("div",Ct,[E(e("input",{"onUpdate:modelValue":v[3]||(v[3]=C=>r.value=C),type:"text",placeholder:s.$t("training.bulk.tagPlaceholder"),class:"w-24 rounded border border-accent bg-surface px-2 py-0.5 text-[10px] text-text-primary outline-none",onKeydown:[V(d,["enter"]),v[4]||(v[4]=V(C=>l.value=!1,["escape"]))]},null,40,Tt),[[U,r.value]]),e("button",{class:"text-[10px] text-accent hover:underline",onClick:d},o(s.$t("common.actions.add")),1)])):(p(),m("button",{key:1,class:"rounded-lg bg-accent/10 px-3 py-1 text-[10px] text-accent hover:bg-accent/20 transition-colors",onClick:v[5]||(v[5]=C=>l.value=!0)},o(s.$t("training.bulk.addTag")),1)),e("button",{class:k(["rounded-lg px-3 py-1 text-[10px] transition-colors",f.value?"bg-error/10 text-error":"text-text-muted hover:text-error"]),onClick:a},o(f.value?s.$t("training.bulk.confirm"):s.$t("training.bulk.delete")),3),e("button",{class:"text-[10px] text-text-muted hover:text-text-primary transition-colors",onClick:v[6]||(v[6]=C=>g("deselect-all"))},o(s.$t("training.bulk.deselectAll")),1)])]))}}),Pt={class:"mx-auto max-w-6xl space-y-6"},St={class:"text-lg font-semibold text-text-primary"},Bt={class:"text-sm text-text-muted"},Dt={key:1,class:"flex items-center gap-3"},It={class:"text-[10px] text-text-muted"},Nt={key:2,class:"rounded-lg border border-border-default bg-surface-raised p-8 text-center"},jt={class:"text-sm text-text-muted mb-2"},Mt={class:"text-xs text-text-muted"},zt=N({__name:"AITrainingPage",setup(t){const n=te();return Y(()=>{n.loadPairs()}),(g,l)=>(p(),m("div",Pt,[e("div",null,[e("h2",St,o(g.$t("training.title")),1),e("p",Bt,o(g.$t("training.subtitle")),1)]),j(ke,{stats:c(n).stats},null,8,["stats"]),j(Ee,{filters:c(n).filters,models:c(n).allModels,"tool-names":c(n).allToolNames,tags:c(n).allTags,"onUpdate:filters":l[0]||(l[0]=r=>c(n).filters=r)},null,8,["filters","models","tool-names","tags"]),c(n).selectedIds.size>0?(p(),R(At,{key:0,"selected-count":c(n).selectedIds.size,onExport:l[1]||(l[1]=r=>c(n).exportSelected([...c(n).selectedIds])),onMarkAccepted:l[2]||(l[2]=r=>c(n).bulkSetAccepted([...c(n).selectedIds],!0)),onMarkRejected:l[3]||(l[3]=r=>c(n).bulkSetAccepted([...c(n).selectedIds],!1)),onAddTag:l[4]||(l[4]=r=>c(n).bulkAddTag([...c(n).selectedIds],r)),onDelete:l[5]||(l[5]=r=>c(n).deletePairs([...c(n).selectedIds])),onDeselectAll:l[6]||(l[6]=r=>c(n).deselectAll())},null,8,["selected-count"])):w("",!0),c(n).filteredPairs.length>0?(p(),m("div",Dt,[e("button",{class:"text-[10px] text-text-muted hover:text-accent transition-colors",onClick:l[7]||(l[7]=r=>c(n).selectedIds.size===c(n).filteredPairs.length?c(n).deselectAll():c(n).selectAll())},o(c(n).selectedIds.size===c(n).filteredPairs.length?g.$t("training.table.deselectAll"):g.$t("training.table.selectAll")+" "+c(n).filteredPairs.length),1),e("span",It,o(g.$t("training.table.pairsShown",{shown:c(n).filteredPairs.length,total:c(n).pairs.length})),1)])):w("",!0),j(ht,{pairs:c(n).filteredPairs,"selected-ids":c(n).selectedIds,"expanded-id":c(n).expandedId,"all-tags":c(n).allTags,onToggleSelection:l[8]||(l[8]=r=>c(n).toggleSelection(r)),onSetExpanded:l[9]||(l[9]=r=>c(n).setExpanded(r)),"onUpdate:response":l[10]||(l[10]=(r,f)=>c(n).updateResponse(r,f)),"onUpdate:tags":l[11]||(l[11]=(r,f)=>c(n).updateTags(r,f)),onToggleAccepted:l[12]||(l[12]=r=>c(n).toggleAccepted(r)),onDelete:l[13]||(l[13]=r=>c(n).deletePairs([r]))},null,8,["pairs","selected-ids","expanded-id","all-tags"]),c(n).pairs.length===0&&!c(n).loading?(p(),m("div",Nt,[e("p",jt,o(g.$t("training.empty.title")),1),e("p",Mt,o(g.$t("training.empty.description")),1)])):w("",!0)]))}});export{zt as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as v,a as R,L as D,P as T,b as L,p as $,c as k,d as C,i as H,e as O,B as F,f as B,A as K,D as Y,S as G}from"./index-ClS2OLai.js";import{u as S}from"./metrics-store-BxvSgW3I.js";import{b as x,e as c,f as l,t as m,p as _,u as y,a as p,j as d,F as w,i as U,l as J,k as E,g as q,I as X}from"./index-BXlm4Yjw.js";import{u as W}from"./session-store-DccvjxkU.js";function P(u,n){if(u.length===0)return 0;const o=n/100*(u.length-1),a=Math.floor(o),r=Math.ceil(o);return a===r?u[a]:u[a]+(u[r]-u[a])*(o-a)}function N(u){const n=[...u].sort((o,a)=>o-a);return{p50:P(n,50),p95:P(n,95),p99:P(n,99)}}function V(u,n=10){if(u.length<n){if(u.length===0)return[];const r=N(u.map(f=>f.value));return[{label:new Date(u[u.length-1].timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),...r}]}const o=[],a=Math.max(1,Math.floor(u.length/20));for(let r=n-1;r<u.length;r+=a){const f=u.slice(Math.max(0,r-n+1),r+1),s=N(f.map(t=>t.value));o.push({label:new Date(u[r].timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),...s})}return o}const Z={class:"rounded-lg border border-border-default bg-surface-raised p-4"},tt={class:"mb-3 text-sm font-medium text-text-secondary"},et={key:0,class:"h-48"},st={key:1,class:"py-6 text-center text-xs text-text-muted"},ot=x({__name:"LatencyPercentilesChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>{const s=n.metricsHistory.map(t=>({timestamp:t.startedAt,value:t.totalDurationMs}));return V(s)}),a=p(()=>({labels:o.value.map(s=>s.label),datasets:[{label:"P50",data:o.value.map(s=>s.p50),borderColor:"#34d399",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P95",data:o.value.map(s=>s.p95),borderColor:"#fbbf24",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P99",data:o.value.map(s=>s.p99),borderColor:"#ef4444",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3}]})),r={responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10},usePointStyle:!0,pointStyle:"line"}},tooltip:{callbacks:{label:s=>`${s.dataset.label??""}: ${(s.parsed.y??0).toFixed(0)}ms`}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:s=>`${s}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",Z,[l("h3",tt,m(s.$t("cost.percentiles.latencyTitle")),1),f.value?(d(),c("div",et,[_(y(O),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",st,m(s.$t("cost.percentiles.noData")),1))]))}}),at={class:"rounded-lg border border-border-default bg-surface-raised p-4"},nt={class:"mb-3 text-sm font-medium text-text-secondary"},rt={key:0,class:"h-48"},lt={key:1,class:"py-6 text-center text-xs text-text-muted"},it=x({__name:"TtftPercentilesChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>{const s=n.metricsHistory.map(t=>({timestamp:t.startedAt,value:t.ttftMs}));return V(s)}),a=p(()=>({labels:o.value.map(s=>s.label),datasets:[{label:"P50",data:o.value.map(s=>s.p50),borderColor:"#34d399",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P95",data:o.value.map(s=>s.p95),borderColor:"#fbbf24",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P99",data:o.value.map(s=>s.p99),borderColor:"#ef4444",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3}]})),r={responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10},usePointStyle:!0,pointStyle:"line"}},tooltip:{callbacks:{label:s=>`${s.dataset.label??""}: ${(s.parsed.y??0).toFixed(0)}ms`}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:s=>`${s}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",at,[l("h3",nt,m(s.$t("cost.percentiles.ttftTitle")),1),f.value?(d(),c("div",rt,[_(y(O),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",lt,m(s.$t("cost.percentiles.noData")),1))]))}}),ct={class:"rounded-lg border border-border-default bg-surface-raised p-4"},dt={class:"mb-3 text-sm font-medium text-text-secondary"},ut={class:"h-48"},mt={class:"mt-2 text-[10px] text-text-muted"},pt={key:1,class:"py-6 text-center text-xs text-text-muted"},bt=x({__name:"InterTokenLatencyHistogram",setup(u){v.register(R,D,F,$,k,C);const n=S(),o=[10,25,50,75,100,150,200,300,400,500,750,1e3],a=p(()=>{const t=[];for(const b of n.metricsHistory)for(const g of b.tokenLatencies)t.push(g);if(t.length===0)return null;const e=new Array(o.length+1).fill(0);for(const b of t){let g=!1;for(let h=0;h<o.length;h++)if(b<=o[h]){e[h]++,g=!0;break}g||e[o.length]++}const i=o.map((b,g)=>g===0?`0-${b}`:`${o[g-1]}-${b}`);return i.push(`>${o[o.length-1]}`),{labels:i,counts:e,total:t.length}}),r=p(()=>a.value?{labels:a.value.labels,datasets:[{label:"Tokens",data:a.value.counts,backgroundColor:"#818cf8"}]}:{labels:[],datasets:[]}),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=t.parsed.y??0,i=a.value?.total??1;return`${e} tokens (${(e/i*100).toFixed(1)}%)`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:9},maxRotation:45},grid:{display:!1},title:{display:!0,text:"ms",color:"#94a3b8",font:{size:10}}},y:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"},title:{display:!0,text:"Count",color:"#94a3b8",font:{size:10}}}}},s=p(()=>a.value!==null);return(t,e)=>(d(),c("div",ct,[l("h3",dt,m(t.$t("cost.percentiles.histogramTitle")),1),s.value?(d(),c(w,{key:0},[l("div",ut,[_(y(B),{data:r.value,options:f},null,8,["data"])]),l("p",mt,m(t.$t("cost.percentiles.histogramHint")),1)],64)):(d(),c("p",pt,m(t.$t("cost.percentiles.noData")),1))]))}}),ft={class:"rounded-lg border border-border-default bg-surface-raised p-4"},gt={class:"mb-3 flex items-center justify-between"},_t={class:"text-sm font-medium text-text-secondary"},ht={key:0,class:"rounded-full bg-warning/15 px-2 py-0.5 text-[9px] font-medium text-warning"},xt={class:"h-48"},yt={class:"mt-2 text-[10px] text-text-muted"},vt={key:1,class:"py-6 text-center text-xs text-text-muted"},$t=500,kt=x({__name:"LoadDurationTrendChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>n.metricsHistory.slice(-50).map(e=>({label:new Date(e.startedAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),loadMs:e.loadDurationMs,model:e.model,isCold:e.loadDurationMs>$t}))),a=p(()=>({labels:o.value.map(t=>t.label),datasets:[{label:"Load Duration (ms)",data:o.value.map(t=>t.loadMs),borderColor:"#a855f7",backgroundColor:"rgba(168, 85, 247, 0.1)",fill:!0,tension:.3,pointBackgroundColor:o.value.map(t=>t.isCold?"#f97316":"#a855f7"),pointRadius:o.value.map(t=>t.isCold?4:2)}]})),r={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=o.value[t.dataIndex],i=t.parsed.y??0;return`${e?.model??""}: ${i.toFixed(0)}ms${e?.isCold?" (cold start)":""}`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:t=>`${t}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0),s=p(()=>o.value.filter(t=>t.isCold).length);return(t,e)=>(d(),c("div",ft,[l("div",gt,[l("h3",_t,m(t.$t("cost.loadDuration.title")),1),s.value>0?(d(),c("span",ht,m(s.value)+" "+m(t.$t("cost.loadDuration.coldStarts")),1)):U("",!0)]),f.value?(d(),c(w,{key:0},[l("div",xt,[_(y(O),{data:a.value,options:r},null,8,["data"])]),l("p",yt,m(t.$t("cost.loadDuration.hint")),1)],64)):(d(),c("p",vt,m(t.$t("cost.loadDuration.noData")),1))]))}}),Ct=[[/connection refused|ECONNREFUSED|fetch failed|network error|Failed to fetch/i,"connection","Connection refused"],[/timed?\s*out|ETIMEDOUT|deadline exceeded/i,"timeout","Timeout"],[/model.*not found|no such model|unknown model|pull.*first/i,"model_not_found","Model not found"],[/context length|context window|too long|maximum context|num_ctx/i,"context_exceeded","Context exceeded"],[/out of memory|OOM|CUDA.*memory|not enough memory|VRAM/i,"oom","Out of memory"],[/cancel|abort/i,"cancelled","Cancelled"],[/tool.*no implementation|tool.*failed|tool.*error/i,"tool_error","Tool error"]];function j(u){for(const[n,o,a]of Ct)if(n.test(u))return{category:o,label:a,original:u};return{category:"unknown",label:"Unknown error",original:u}}const Dt={connection:"#ef4444",timeout:"#f97316",model_not_found:"#eab308",context_exceeded:"#a855f7",oom:"#dc2626",cancelled:"#6b7280",tool_error:"#f472b6",unknown:"#94a3b8"},St={class:"rounded-lg border border-border-default bg-surface-raised p-4"},wt={class:"mb-3 text-sm font-medium text-text-secondary"},Rt={key:1,class:"py-6 text-center text-xs text-text-muted"},Mt=x({__name:"ErrorRateByModelChart",setup(u){v.register(R,D,F,$,k,C);const n=W(),o=p(()=>{const e=new Map;for(const i of n.sessions.values()){const b=i.model,g=e.get(b)??{total:0,errors:0,byCategory:{}};if(g.total++,i.status==="error"&&i.error){g.errors++;const{category:h}=j(i.error);g.byCategory[h]=(g.byCategory[h]??0)+1}e.set(b,g)}return[...e.entries()].map(([i,b])=>({model:i,...b,rate:b.total>0?b.errors/b.total:0})).filter(i=>i.total>0).sort((i,b)=>b.rate-i.rate)}),a=["connection","timeout","model_not_found","context_exceeded","oom","tool_error","cancelled","unknown"],r={connection:"Connection",timeout:"Timeout",model_not_found:"Not found",context_exceeded:"Context exceeded",oom:"Out of memory",tool_error:"Tool error",cancelled:"Cancelled",unknown:"Unknown"},f=p(()=>({labels:o.value.map(e=>e.model),datasets:a.filter(e=>o.value.some(i=>(i.byCategory[e]??0)>0)).map(e=>({label:r[e],data:o.value.map(i=>i.byCategory[e]??0),backgroundColor:Dt[e]}))})),s={indexAxis:"y",responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10}}}},scales:{x:{stacked:!0,ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{stacked:!0,ticks:{color:"#94a3b8",font:{size:11}},grid:{display:!1}}}},t=p(()=>o.value.some(e=>e.errors>0));return(e,i)=>(d(),c("div",St,[l("h3",wt,m(e.$t("cost.errors.title")),1),t.value?(d(),c("div",{key:0,style:J({height:Math.max(100,o.value.length*36)+"px"})},[_(y(B),{data:f.value,options:s},null,8,["data"])],4)):(d(),c("p",Rt,m(e.$t("cost.errors.noErrors")),1))]))}}),Tt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},zt={class:"mb-3 text-sm font-medium text-text-secondary"},At={key:0,class:"h-48"},Lt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ot=x({__name:"ErrorTimelineChart",setup(u){v.register(R,D,T,L,$,k,C);const n=W(),o=p(()=>{const t=[];for(const e of n.sessions.values())if(e.status==="error"&&e.error){const{category:i,label:b}=j(e.error);t.push({date:new Date(e.createdAt).toISOString().slice(0,10),category:i,model:e.model,error:b})}return t.sort((e,i)=>e.date.localeCompare(i.date))}),a=p(()=>{const t=new Map;for(const e of o.value)t.set(e.date,(t.get(e.date)??0)+1);return[...t.entries()].sort((e,i)=>e[0].localeCompare(i[0]))}),r=p(()=>({labels:a.value.map(([t])=>t),datasets:[{label:"Errors",data:a.value.map(([,t])=>t),borderColor:"#ef4444",backgroundColor:"rgba(239, 68, 68, 0.1)",fill:!0,tension:.3,pointRadius:3}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>0);return(t,e)=>(d(),c("div",Tt,[l("h3",zt,m(t.$t("analytics.errors.timelineTitle")),1),s.value?(d(),c("div",At,[_(y(O),{data:r.value,options:f},null,8,["data"])])):(d(),c("p",Lt,m(t.$t("analytics.errors.noErrors")),1))]))}}),Et={class:"rounded-lg border border-border-default bg-surface-raised p-4"},Ht={class:"mb-3 text-sm font-medium text-text-secondary"},Pt={key:0,class:"h-48"},qt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ft=x({__name:"RequestVolumeChart",setup(u){v.register(R,D,F,$,k,C);const n=S(),o=p(()=>{const s=new Map;for(const t of n.metricsHistory){const e=new Date(t.startedAt).toISOString().slice(0,10);s.set(e,(s.get(e)??0)+1)}return[...s.entries()].sort((t,e)=>t[0].localeCompare(e[0]))}),a=p(()=>({labels:o.value.map(([s])=>s),datasets:[{label:"Requests",data:o.value.map(([,s])=>s),backgroundColor:"#818cf8"}]})),r={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{display:!1}},y:{ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",Et,[l("h3",Ht,m(s.$t("analytics.usage.requestVolume")),1),f.value?(d(),c("div",Pt,[_(y(B),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",qt,m(s.$t("analytics.usage.noData")),1))]))}}),Bt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},Wt={class:"mb-3 text-sm font-medium text-text-secondary"},It={key:0,class:"h-48"},Nt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ut=x({__name:"ModelDistributionChart",setup(u){v.register(K,$,k,C);const n=S(),o=["#818cf8","#a855f7","#34d399","#fbbf24","#f472b6","#fb923c","#60a5fa","#c084fc"],a=p(()=>{const t=new Map;for(const e of n.metricsHistory)t.set(e.model,(t.get(e.model)??0)+1);return[...t.entries()].sort((e,i)=>i[1]-e[1])}),r=p(()=>({labels:a.value.map(([t])=>t),datasets:[{data:a.value.map(([,t])=>t),backgroundColor:a.value.map((t,e)=>o[e%o.length]),borderWidth:0}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"right",labels:{color:"#94a3b8",font:{size:10},padding:12}}}},s=p(()=>a.value.length>0);return(t,e)=>(d(),c("div",Bt,[l("h3",Wt,m(t.$t("analytics.usage.modelDistribution")),1),s.value?(d(),c("div",It,[_(y(Y),{data:r.value,options:f},null,8,["data"])])):(d(),c("p",Nt,m(t.$t("analytics.usage.noData")),1))]))}}),Vt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},jt={class:"mb-3 text-sm font-medium text-text-secondary"},Qt={key:0,class:"overflow-x-auto"},Kt={class:"min-w-[600px]"},Yt={class:"flex items-center"},Gt={class:"w-10 shrink-0 text-[10px] text-text-muted"},Jt=["title"],Xt={key:1,class:"py-6 text-center text-xs text-text-muted"},Zt=x({__name:"ActiveHoursHeatmap",setup(u){const n=S(),o=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],a=Array.from({length:24},(t,e)=>e),r=p(()=>{const t=Array.from({length:7},()=>new Array(24).fill(0));let e=0;for(const i of n.metricsHistory){const b=new Date(i.startedAt),g=(b.getDay()+6)%7,h=b.getHours();t[g][h]++,t[g][h]>e&&(e=t[g][h])}return{counts:t,max:e}});function f(t){if(t===0)return"bg-surface-overlay/30";const e=r.value.max>0?t/r.value.max:0;return e>.75?"bg-accent":e>.5?"bg-accent/70":e>.25?"bg-accent/40":"bg-accent/20"}const s=p(()=>n.metricsHistory.length>0);return(t,e)=>(d(),c("div",Vt,[l("h3",jt,m(t.$t("analytics.usage.activeHours")),1),s.value?(d(),c("div",Qt,[l("div",Kt,[l("div",Yt,[e[0]||(e[0]=l("div",{class:"w-10 shrink-0"},null,-1)),(d(!0),c(w,null,E(y(a),i=>(d(),c("div",{key:i,class:"flex-1 text-center text-[8px] text-text-muted"},m(i),1))),128))]),(d(),c(w,null,E(o,(i,b)=>l("div",{key:i,class:"flex items-center gap-0.5 mt-0.5"},[l("div",Gt,m(i),1),(d(!0),c(w,null,E(y(a),g=>(d(),c("div",{key:g,class:q(["flex-1 aspect-square rounded-sm transition-colors",f(r.value.counts[b][g])]),title:`${i} ${g}:00 — ${r.value.counts[b][g]} requests`},null,10,Jt))),128))])),64))])])):(d(),c("p",Xt,m(t.$t("analytics.usage.noData")),1))]))}}),te={class:"rounded-lg border border-border-default bg-surface-raised p-4"},ee={class:"mb-3 text-sm font-medium text-text-secondary"},se={class:"h-48"},oe={class:"mt-2 text-[10px] text-text-muted"},ae={key:1,class:"py-6 text-center text-xs text-text-muted"},ne=x({__name:"SettingsImpactScatter",setup(u){v.register(D,T,$,k,C);const n=W(),o=S(),a=p(()=>{const t=[];for(const e of n.sessions.values()){const i=e.options?.temperature;if(i===void 0)continue;const b=o.getMetrics(e.id);b&&t.push({x:i,y:b.tokensPerSecond,model:e.model})}return t}),r=p(()=>({datasets:[{label:"Temperature vs Speed",data:a.value.map(t=>({x:t.x,y:t.y})),backgroundColor:"#818cf880",borderColor:"#818cf8",pointRadius:5}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>`${a.value[t.dataIndex]?.model??""}: temp=${(t.parsed.x??0).toFixed(1)} → ${(t.parsed.y??0).toFixed(1)} tok/s`}}},scales:{x:{title:{display:!0,text:"Temperature",color:"#94a3b8",font:{size:10}},ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{title:{display:!0,text:"Tokens/sec",color:"#94a3b8",font:{size:10}},ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>=2);return(t,e)=>(d(),c("div",te,[l("h3",ee,m(t.$t("analytics.settings.title")),1),s.value?(d(),c(w,{key:0},[l("div",se,[_(y(G),{data:r.value,options:f},null,8,["data"])]),l("p",oe,m(t.$t("analytics.settings.hint")),1)],64)):(d(),c("p",ae,m(t.$t("analytics.settings.noData")),1))]))}}),re={class:"rounded-lg border border-border-default bg-surface-raised p-4"},le={class:"mb-3 text-sm font-medium text-text-secondary"},ie={key:0,class:"max-h-64 overflow-y-auto"},ce={class:"text-[10px] text-text-muted w-14 shrink-0"},de={class:"text-xs text-text-primary truncate flex-1"},ue={key:0,class:"rounded-full bg-warning/15 px-1.5 py-0.5 text-[8px] font-medium text-warning shrink-0"},me={key:1,class:"py-6 text-center text-xs text-text-muted"},pe=500,be=x({__name:"ModelLoadHistory",setup(u){const n=S(),o=p(()=>n.metricsHistory.slice(-30).map(r=>({time:new Date(r.startedAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),date:new Date(r.startedAt).toLocaleDateString(),model:r.model,loadMs:r.loadDurationMs,isCold:r.loadDurationMs>pe}))),a=p(()=>o.value.length>0);return(r,f)=>(d(),c("div",re,[l("h3",le,m(r.$t("analytics.modelLoad.title")),1),a.value?(d(),c("div",ie,[(d(!0),c(w,null,E(o.value,(s,t)=>(d(),c("div",{key:t,class:"flex items-center gap-3 border-b border-border-default/30 py-1.5 last:border-0"},[l("div",{class:q(["h-2 w-2 shrink-0 rounded-full",s.isCold?"bg-warning":"bg-success"])},null,2),l("span",ce,m(s.time),1),l("span",de,m(s.model),1),l("span",{class:q(["text-[10px] font-mono shrink-0",s.isCold?"text-warning":"text-text-muted"])},m(s.loadMs.toFixed(0))+"ms ",3),s.isCold?(d(),c("span",ue,m(r.$t("analytics.modelLoad.cold")),1)):U("",!0)]))),128))])):(d(),c("p",me,m(r.$t("analytics.modelLoad.noData")),1))]))}});function fe(u,n){const o=[];for(let a=0;a<=u.length-n;a++)o.push(u.slice(a,a+n).join(" "));return o}function ge(u,n,o){const a=u.trim().split(/\s+/).filter(Boolean),r=a.length,s=u.split(/[.!?]+/).filter(M=>M.trim().length>0).length,t=new Set(a.map(M=>M.toLowerCase())),e=r>0?t.size/r:0;let i=0;if(a.length>=8){const M=fe(a.map(z=>z.toLowerCase()),4);if(M.length>0){const z=new Map;for(const A of M)z.set(A,(z.get(A)??0)+1);let I=0;for(const A of z.values())A>1&&(I+=A);i=I/M.length}}const b=Math.min(r/50,1)*.4,g=e*.3,h=(1-i)*.3,Q=Math.min(5,Math.max(0,(b+g+h)*5));return{turnIndex:n,role:o,wordCount:r,sentenceCount:s,uniqueWordRatio:e,repetitionRatio:i,score:Q}}function _e(u){return u.filter(n=>n.role==="user"||n.role==="assistant").map((n,o)=>ge(n.content.replace(/<think>[\s\S]*?<\/think>/g,"").trim(),o,n.role))}const he={class:"rounded-lg border border-border-default bg-surface-raised p-4"},xe={class:"mb-3 text-sm font-medium text-text-secondary"},ye={class:"h-48"},ve={class:"mt-2 text-[10px] text-text-muted"},$e={key:1,class:"py-6 text-center text-xs text-text-muted"},ke=x({__name:"QualityOverTurnsChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=X(),o=p(()=>{const t=n.activeConversation;return!t||t.messages.length<2?[]:_e(t.messages)}),a=p(()=>o.value.filter(t=>t.role==="assistant")),r=p(()=>({labels:a.value.map((t,e)=>`Turn ${e+1}`),datasets:[{label:"Quality Score",data:a.value.map(t=>t.score),borderColor:"#818cf8",backgroundColor:"rgba(129, 140, 248, 0.1)",fill:!0,tension:.3,pointBackgroundColor:a.value.map(t=>t.score>=3.5?"#34d399":t.score>=2?"#fbbf24":"#ef4444"),pointRadius:4}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=a.value[t.dataIndex];return`Score: ${(t.parsed.y??0).toFixed(1)}/5 (${e?.wordCount??0} words)`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{min:0,max:5,ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>=2);return(t,e)=>(d(),c("div",he,[l("h3",xe,m(t.$t("analytics.quality.title")),1),s.value?(d(),c(w,{key:0},[l("div",ye,[_(y(O),{data:r.value,options:f},null,8,["data"])]),l("p",ve,m(t.$t("analytics.quality.hint")),1)],64)):(d(),c("p",$e,m(t.$t("analytics.quality.noData")),1))]))}}),Ce={class:"h-full overflow-y-auto p-6"},De={class:"mb-6 text-lg font-semibold text-text-primary"},Se={class:"mb-8"},we={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Re={class:"mb-8"},Me={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Te={class:"grid gap-6 lg:grid-cols-2"},ze={class:"mt-6"},Ae={class:"mb-8"},Le={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Oe={class:"grid gap-6 lg:grid-cols-2"},Ee={class:"mt-6"},He={class:"mb-8"},Pe={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},qe={class:"grid gap-6 lg:grid-cols-2"},Fe={class:"mt-6"},Be={class:"mb-8"},We={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Ie={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Qe=x({__name:"AnalyticsPage",setup(u){return(n,o)=>(d(),c("div",Ce,[l("h1",De,m(n.$t("analytics.title")),1),l("section",Se,[l("h2",we,m(n.$t("analytics.sections.quality")),1),_(ke)]),l("section",Re,[l("h2",Me,m(n.$t("analytics.sections.latency")),1),l("div",Te,[_(ot),_(it)]),l("div",ze,[_(bt)])]),l("section",Ae,[l("h2",Le,m(n.$t("analytics.sections.reliability")),1),l("div",Oe,[_(Mt),_(Ot)]),l("div",Ee,[_(kt)])]),l("section",He,[l("h2",Pe,m(n.$t("analytics.sections.usage")),1),l("div",qe,[_(Ft),_(Ut)]),l("div",Fe,[_(Zt)])]),l("section",Be,[l("h2",We,m(n.$t("analytics.sections.settings")),1),_(ne)]),l("section",null,[l("h2",Ie,m(n.$t("analytics.sections.modelMemory")),1),_(be)])]))}});export{Qe as default};
|
|
1
|
+
import{C as v,a as R,L as D,P as T,b as L,p as $,c as k,d as C,i as H,e as O,B as F,f as B,A as K,D as Y,S as G}from"./index-Dy_48xr0.js";import{u as S}from"./metrics-store-B4lQqH-w.js";import{b as x,e as c,f as l,t as m,p as _,u as y,a as p,j as d,F as w,i as U,l as J,k as E,g as q,I as X}from"./index-CZ4a6rAU.js";import{u as W}from"./session-store-Dy1-rRkz.js";function P(u,n){if(u.length===0)return 0;const o=n/100*(u.length-1),a=Math.floor(o),r=Math.ceil(o);return a===r?u[a]:u[a]+(u[r]-u[a])*(o-a)}function N(u){const n=[...u].sort((o,a)=>o-a);return{p50:P(n,50),p95:P(n,95),p99:P(n,99)}}function V(u,n=10){if(u.length<n){if(u.length===0)return[];const r=N(u.map(f=>f.value));return[{label:new Date(u[u.length-1].timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),...r}]}const o=[],a=Math.max(1,Math.floor(u.length/20));for(let r=n-1;r<u.length;r+=a){const f=u.slice(Math.max(0,r-n+1),r+1),s=N(f.map(t=>t.value));o.push({label:new Date(u[r].timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),...s})}return o}const Z={class:"rounded-lg border border-border-default bg-surface-raised p-4"},tt={class:"mb-3 text-sm font-medium text-text-secondary"},et={key:0,class:"h-48"},st={key:1,class:"py-6 text-center text-xs text-text-muted"},ot=x({__name:"LatencyPercentilesChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>{const s=n.metricsHistory.map(t=>({timestamp:t.startedAt,value:t.totalDurationMs}));return V(s)}),a=p(()=>({labels:o.value.map(s=>s.label),datasets:[{label:"P50",data:o.value.map(s=>s.p50),borderColor:"#34d399",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P95",data:o.value.map(s=>s.p95),borderColor:"#fbbf24",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P99",data:o.value.map(s=>s.p99),borderColor:"#ef4444",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3}]})),r={responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10},usePointStyle:!0,pointStyle:"line"}},tooltip:{callbacks:{label:s=>`${s.dataset.label??""}: ${(s.parsed.y??0).toFixed(0)}ms`}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:s=>`${s}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",Z,[l("h3",tt,m(s.$t("cost.percentiles.latencyTitle")),1),f.value?(d(),c("div",et,[_(y(O),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",st,m(s.$t("cost.percentiles.noData")),1))]))}}),at={class:"rounded-lg border border-border-default bg-surface-raised p-4"},nt={class:"mb-3 text-sm font-medium text-text-secondary"},rt={key:0,class:"h-48"},lt={key:1,class:"py-6 text-center text-xs text-text-muted"},it=x({__name:"TtftPercentilesChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>{const s=n.metricsHistory.map(t=>({timestamp:t.startedAt,value:t.ttftMs}));return V(s)}),a=p(()=>({labels:o.value.map(s=>s.label),datasets:[{label:"P50",data:o.value.map(s=>s.p50),borderColor:"#34d399",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P95",data:o.value.map(s=>s.p95),borderColor:"#fbbf24",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3},{label:"P99",data:o.value.map(s=>s.p99),borderColor:"#ef4444",backgroundColor:"transparent",borderWidth:1.5,pointRadius:2,tension:.3}]})),r={responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10},usePointStyle:!0,pointStyle:"line"}},tooltip:{callbacks:{label:s=>`${s.dataset.label??""}: ${(s.parsed.y??0).toFixed(0)}ms`}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:s=>`${s}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",at,[l("h3",nt,m(s.$t("cost.percentiles.ttftTitle")),1),f.value?(d(),c("div",rt,[_(y(O),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",lt,m(s.$t("cost.percentiles.noData")),1))]))}}),ct={class:"rounded-lg border border-border-default bg-surface-raised p-4"},dt={class:"mb-3 text-sm font-medium text-text-secondary"},ut={class:"h-48"},mt={class:"mt-2 text-[10px] text-text-muted"},pt={key:1,class:"py-6 text-center text-xs text-text-muted"},bt=x({__name:"InterTokenLatencyHistogram",setup(u){v.register(R,D,F,$,k,C);const n=S(),o=[10,25,50,75,100,150,200,300,400,500,750,1e3],a=p(()=>{const t=[];for(const b of n.metricsHistory)for(const g of b.tokenLatencies)t.push(g);if(t.length===0)return null;const e=new Array(o.length+1).fill(0);for(const b of t){let g=!1;for(let h=0;h<o.length;h++)if(b<=o[h]){e[h]++,g=!0;break}g||e[o.length]++}const i=o.map((b,g)=>g===0?`0-${b}`:`${o[g-1]}-${b}`);return i.push(`>${o[o.length-1]}`),{labels:i,counts:e,total:t.length}}),r=p(()=>a.value?{labels:a.value.labels,datasets:[{label:"Tokens",data:a.value.counts,backgroundColor:"#818cf8"}]}:{labels:[],datasets:[]}),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=t.parsed.y??0,i=a.value?.total??1;return`${e} tokens (${(e/i*100).toFixed(1)}%)`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:9},maxRotation:45},grid:{display:!1},title:{display:!0,text:"ms",color:"#94a3b8",font:{size:10}}},y:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"},title:{display:!0,text:"Count",color:"#94a3b8",font:{size:10}}}}},s=p(()=>a.value!==null);return(t,e)=>(d(),c("div",ct,[l("h3",dt,m(t.$t("cost.percentiles.histogramTitle")),1),s.value?(d(),c(w,{key:0},[l("div",ut,[_(y(B),{data:r.value,options:f},null,8,["data"])]),l("p",mt,m(t.$t("cost.percentiles.histogramHint")),1)],64)):(d(),c("p",pt,m(t.$t("cost.percentiles.noData")),1))]))}}),ft={class:"rounded-lg border border-border-default bg-surface-raised p-4"},gt={class:"mb-3 flex items-center justify-between"},_t={class:"text-sm font-medium text-text-secondary"},ht={key:0,class:"rounded-full bg-warning/15 px-2 py-0.5 text-[9px] font-medium text-warning"},xt={class:"h-48"},yt={class:"mt-2 text-[10px] text-text-muted"},vt={key:1,class:"py-6 text-center text-xs text-text-muted"},$t=500,kt=x({__name:"LoadDurationTrendChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=S(),o=p(()=>n.metricsHistory.slice(-50).map(e=>({label:new Date(e.startedAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),loadMs:e.loadDurationMs,model:e.model,isCold:e.loadDurationMs>$t}))),a=p(()=>({labels:o.value.map(t=>t.label),datasets:[{label:"Load Duration (ms)",data:o.value.map(t=>t.loadMs),borderColor:"#a855f7",backgroundColor:"rgba(168, 85, 247, 0.1)",fill:!0,tension:.3,pointBackgroundColor:o.value.map(t=>t.isCold?"#f97316":"#a855f7"),pointRadius:o.value.map(t=>t.isCold?4:2)}]})),r={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=o.value[t.dataIndex],i=t.parsed.y??0;return`${e?.model??""}: ${i.toFixed(0)}ms${e?.isCold?" (cold start)":""}`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10},maxRotation:45},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},callback:t=>`${t}ms`},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0),s=p(()=>o.value.filter(t=>t.isCold).length);return(t,e)=>(d(),c("div",ft,[l("div",gt,[l("h3",_t,m(t.$t("cost.loadDuration.title")),1),s.value>0?(d(),c("span",ht,m(s.value)+" "+m(t.$t("cost.loadDuration.coldStarts")),1)):U("",!0)]),f.value?(d(),c(w,{key:0},[l("div",xt,[_(y(O),{data:a.value,options:r},null,8,["data"])]),l("p",yt,m(t.$t("cost.loadDuration.hint")),1)],64)):(d(),c("p",vt,m(t.$t("cost.loadDuration.noData")),1))]))}}),Ct=[[/connection refused|ECONNREFUSED|fetch failed|network error|Failed to fetch/i,"connection","Connection refused"],[/timed?\s*out|ETIMEDOUT|deadline exceeded/i,"timeout","Timeout"],[/model.*not found|no such model|unknown model|pull.*first/i,"model_not_found","Model not found"],[/context length|context window|too long|maximum context|num_ctx/i,"context_exceeded","Context exceeded"],[/out of memory|OOM|CUDA.*memory|not enough memory|VRAM/i,"oom","Out of memory"],[/cancel|abort/i,"cancelled","Cancelled"],[/tool.*no implementation|tool.*failed|tool.*error/i,"tool_error","Tool error"]];function j(u){for(const[n,o,a]of Ct)if(n.test(u))return{category:o,label:a,original:u};return{category:"unknown",label:"Unknown error",original:u}}const Dt={connection:"#ef4444",timeout:"#f97316",model_not_found:"#eab308",context_exceeded:"#a855f7",oom:"#dc2626",cancelled:"#6b7280",tool_error:"#f472b6",unknown:"#94a3b8"},St={class:"rounded-lg border border-border-default bg-surface-raised p-4"},wt={class:"mb-3 text-sm font-medium text-text-secondary"},Rt={key:1,class:"py-6 text-center text-xs text-text-muted"},Mt=x({__name:"ErrorRateByModelChart",setup(u){v.register(R,D,F,$,k,C);const n=W(),o=p(()=>{const e=new Map;for(const i of n.sessions.values()){const b=i.model,g=e.get(b)??{total:0,errors:0,byCategory:{}};if(g.total++,i.status==="error"&&i.error){g.errors++;const{category:h}=j(i.error);g.byCategory[h]=(g.byCategory[h]??0)+1}e.set(b,g)}return[...e.entries()].map(([i,b])=>({model:i,...b,rate:b.total>0?b.errors/b.total:0})).filter(i=>i.total>0).sort((i,b)=>b.rate-i.rate)}),a=["connection","timeout","model_not_found","context_exceeded","oom","tool_error","cancelled","unknown"],r={connection:"Connection",timeout:"Timeout",model_not_found:"Not found",context_exceeded:"Context exceeded",oom:"Out of memory",tool_error:"Tool error",cancelled:"Cancelled",unknown:"Unknown"},f=p(()=>({labels:o.value.map(e=>e.model),datasets:a.filter(e=>o.value.some(i=>(i.byCategory[e]??0)>0)).map(e=>({label:r[e],data:o.value.map(i=>i.byCategory[e]??0),backgroundColor:Dt[e]}))})),s={indexAxis:"y",responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{color:"#94a3b8",font:{size:10}}}},scales:{x:{stacked:!0,ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{stacked:!0,ticks:{color:"#94a3b8",font:{size:11}},grid:{display:!1}}}},t=p(()=>o.value.some(e=>e.errors>0));return(e,i)=>(d(),c("div",St,[l("h3",wt,m(e.$t("cost.errors.title")),1),t.value?(d(),c("div",{key:0,style:J({height:Math.max(100,o.value.length*36)+"px"})},[_(y(B),{data:f.value,options:s},null,8,["data"])],4)):(d(),c("p",Rt,m(e.$t("cost.errors.noErrors")),1))]))}}),Tt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},zt={class:"mb-3 text-sm font-medium text-text-secondary"},At={key:0,class:"h-48"},Lt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ot=x({__name:"ErrorTimelineChart",setup(u){v.register(R,D,T,L,$,k,C);const n=W(),o=p(()=>{const t=[];for(const e of n.sessions.values())if(e.status==="error"&&e.error){const{category:i,label:b}=j(e.error);t.push({date:new Date(e.createdAt).toISOString().slice(0,10),category:i,model:e.model,error:b})}return t.sort((e,i)=>e.date.localeCompare(i.date))}),a=p(()=>{const t=new Map;for(const e of o.value)t.set(e.date,(t.get(e.date)??0)+1);return[...t.entries()].sort((e,i)=>e[0].localeCompare(i[0]))}),r=p(()=>({labels:a.value.map(([t])=>t),datasets:[{label:"Errors",data:a.value.map(([,t])=>t),borderColor:"#ef4444",backgroundColor:"rgba(239, 68, 68, 0.1)",fill:!0,tension:.3,pointRadius:3}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>0);return(t,e)=>(d(),c("div",Tt,[l("h3",zt,m(t.$t("analytics.errors.timelineTitle")),1),s.value?(d(),c("div",At,[_(y(O),{data:r.value,options:f},null,8,["data"])])):(d(),c("p",Lt,m(t.$t("analytics.errors.noErrors")),1))]))}}),Et={class:"rounded-lg border border-border-default bg-surface-raised p-4"},Ht={class:"mb-3 text-sm font-medium text-text-secondary"},Pt={key:0,class:"h-48"},qt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ft=x({__name:"RequestVolumeChart",setup(u){v.register(R,D,F,$,k,C);const n=S(),o=p(()=>{const s=new Map;for(const t of n.metricsHistory){const e=new Date(t.startedAt).toISOString().slice(0,10);s.set(e,(s.get(e)??0)+1)}return[...s.entries()].sort((t,e)=>t[0].localeCompare(e[0]))}),a=p(()=>({labels:o.value.map(([s])=>s),datasets:[{label:"Requests",data:o.value.map(([,s])=>s),backgroundColor:"#818cf8"}]})),r={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{display:!1}},y:{ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},f=p(()=>o.value.length>0);return(s,t)=>(d(),c("div",Et,[l("h3",Ht,m(s.$t("analytics.usage.requestVolume")),1),f.value?(d(),c("div",Pt,[_(y(B),{data:a.value,options:r},null,8,["data"])])):(d(),c("p",qt,m(s.$t("analytics.usage.noData")),1))]))}}),Bt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},Wt={class:"mb-3 text-sm font-medium text-text-secondary"},It={key:0,class:"h-48"},Nt={key:1,class:"py-6 text-center text-xs text-text-muted"},Ut=x({__name:"ModelDistributionChart",setup(u){v.register(K,$,k,C);const n=S(),o=["#818cf8","#a855f7","#34d399","#fbbf24","#f472b6","#fb923c","#60a5fa","#c084fc"],a=p(()=>{const t=new Map;for(const e of n.metricsHistory)t.set(e.model,(t.get(e.model)??0)+1);return[...t.entries()].sort((e,i)=>i[1]-e[1])}),r=p(()=>({labels:a.value.map(([t])=>t),datasets:[{data:a.value.map(([,t])=>t),backgroundColor:a.value.map((t,e)=>o[e%o.length]),borderWidth:0}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"right",labels:{color:"#94a3b8",font:{size:10},padding:12}}}},s=p(()=>a.value.length>0);return(t,e)=>(d(),c("div",Bt,[l("h3",Wt,m(t.$t("analytics.usage.modelDistribution")),1),s.value?(d(),c("div",It,[_(y(Y),{data:r.value,options:f},null,8,["data"])])):(d(),c("p",Nt,m(t.$t("analytics.usage.noData")),1))]))}}),Vt={class:"rounded-lg border border-border-default bg-surface-raised p-4"},jt={class:"mb-3 text-sm font-medium text-text-secondary"},Qt={key:0,class:"overflow-x-auto"},Kt={class:"min-w-[600px]"},Yt={class:"flex items-center"},Gt={class:"w-10 shrink-0 text-[10px] text-text-muted"},Jt=["title"],Xt={key:1,class:"py-6 text-center text-xs text-text-muted"},Zt=x({__name:"ActiveHoursHeatmap",setup(u){const n=S(),o=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],a=Array.from({length:24},(t,e)=>e),r=p(()=>{const t=Array.from({length:7},()=>new Array(24).fill(0));let e=0;for(const i of n.metricsHistory){const b=new Date(i.startedAt),g=(b.getDay()+6)%7,h=b.getHours();t[g][h]++,t[g][h]>e&&(e=t[g][h])}return{counts:t,max:e}});function f(t){if(t===0)return"bg-surface-overlay/30";const e=r.value.max>0?t/r.value.max:0;return e>.75?"bg-accent":e>.5?"bg-accent/70":e>.25?"bg-accent/40":"bg-accent/20"}const s=p(()=>n.metricsHistory.length>0);return(t,e)=>(d(),c("div",Vt,[l("h3",jt,m(t.$t("analytics.usage.activeHours")),1),s.value?(d(),c("div",Qt,[l("div",Kt,[l("div",Yt,[e[0]||(e[0]=l("div",{class:"w-10 shrink-0"},null,-1)),(d(!0),c(w,null,E(y(a),i=>(d(),c("div",{key:i,class:"flex-1 text-center text-[8px] text-text-muted"},m(i),1))),128))]),(d(),c(w,null,E(o,(i,b)=>l("div",{key:i,class:"flex items-center gap-0.5 mt-0.5"},[l("div",Gt,m(i),1),(d(!0),c(w,null,E(y(a),g=>(d(),c("div",{key:g,class:q(["flex-1 aspect-square rounded-sm transition-colors",f(r.value.counts[b][g])]),title:`${i} ${g}:00 — ${r.value.counts[b][g]} requests`},null,10,Jt))),128))])),64))])])):(d(),c("p",Xt,m(t.$t("analytics.usage.noData")),1))]))}}),te={class:"rounded-lg border border-border-default bg-surface-raised p-4"},ee={class:"mb-3 text-sm font-medium text-text-secondary"},se={class:"h-48"},oe={class:"mt-2 text-[10px] text-text-muted"},ae={key:1,class:"py-6 text-center text-xs text-text-muted"},ne=x({__name:"SettingsImpactScatter",setup(u){v.register(D,T,$,k,C);const n=W(),o=S(),a=p(()=>{const t=[];for(const e of n.sessions.values()){const i=e.options?.temperature;if(i===void 0)continue;const b=o.getMetrics(e.id);b&&t.push({x:i,y:b.tokensPerSecond,model:e.model})}return t}),r=p(()=>({datasets:[{label:"Temperature vs Speed",data:a.value.map(t=>({x:t.x,y:t.y})),backgroundColor:"#818cf880",borderColor:"#818cf8",pointRadius:5}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>`${a.value[t.dataIndex]?.model??""}: temp=${(t.parsed.x??0).toFixed(1)} → ${(t.parsed.y??0).toFixed(1)} tok/s`}}},scales:{x:{title:{display:!0,text:"Temperature",color:"#94a3b8",font:{size:10}},ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{title:{display:!0,text:"Tokens/sec",color:"#94a3b8",font:{size:10}},ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>=2);return(t,e)=>(d(),c("div",te,[l("h3",ee,m(t.$t("analytics.settings.title")),1),s.value?(d(),c(w,{key:0},[l("div",se,[_(y(G),{data:r.value,options:f},null,8,["data"])]),l("p",oe,m(t.$t("analytics.settings.hint")),1)],64)):(d(),c("p",ae,m(t.$t("analytics.settings.noData")),1))]))}}),re={class:"rounded-lg border border-border-default bg-surface-raised p-4"},le={class:"mb-3 text-sm font-medium text-text-secondary"},ie={key:0,class:"max-h-64 overflow-y-auto"},ce={class:"text-[10px] text-text-muted w-14 shrink-0"},de={class:"text-xs text-text-primary truncate flex-1"},ue={key:0,class:"rounded-full bg-warning/15 px-1.5 py-0.5 text-[8px] font-medium text-warning shrink-0"},me={key:1,class:"py-6 text-center text-xs text-text-muted"},pe=500,be=x({__name:"ModelLoadHistory",setup(u){const n=S(),o=p(()=>n.metricsHistory.slice(-30).map(r=>({time:new Date(r.startedAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),date:new Date(r.startedAt).toLocaleDateString(),model:r.model,loadMs:r.loadDurationMs,isCold:r.loadDurationMs>pe}))),a=p(()=>o.value.length>0);return(r,f)=>(d(),c("div",re,[l("h3",le,m(r.$t("analytics.modelLoad.title")),1),a.value?(d(),c("div",ie,[(d(!0),c(w,null,E(o.value,(s,t)=>(d(),c("div",{key:t,class:"flex items-center gap-3 border-b border-border-default/30 py-1.5 last:border-0"},[l("div",{class:q(["h-2 w-2 shrink-0 rounded-full",s.isCold?"bg-warning":"bg-success"])},null,2),l("span",ce,m(s.time),1),l("span",de,m(s.model),1),l("span",{class:q(["text-[10px] font-mono shrink-0",s.isCold?"text-warning":"text-text-muted"])},m(s.loadMs.toFixed(0))+"ms ",3),s.isCold?(d(),c("span",ue,m(r.$t("analytics.modelLoad.cold")),1)):U("",!0)]))),128))])):(d(),c("p",me,m(r.$t("analytics.modelLoad.noData")),1))]))}});function fe(u,n){const o=[];for(let a=0;a<=u.length-n;a++)o.push(u.slice(a,a+n).join(" "));return o}function ge(u,n,o){const a=u.trim().split(/\s+/).filter(Boolean),r=a.length,s=u.split(/[.!?]+/).filter(M=>M.trim().length>0).length,t=new Set(a.map(M=>M.toLowerCase())),e=r>0?t.size/r:0;let i=0;if(a.length>=8){const M=fe(a.map(z=>z.toLowerCase()),4);if(M.length>0){const z=new Map;for(const A of M)z.set(A,(z.get(A)??0)+1);let I=0;for(const A of z.values())A>1&&(I+=A);i=I/M.length}}const b=Math.min(r/50,1)*.4,g=e*.3,h=(1-i)*.3,Q=Math.min(5,Math.max(0,(b+g+h)*5));return{turnIndex:n,role:o,wordCount:r,sentenceCount:s,uniqueWordRatio:e,repetitionRatio:i,score:Q}}function _e(u){return u.filter(n=>n.role==="user"||n.role==="assistant").map((n,o)=>ge(n.content.replace(/<think>[\s\S]*?<\/think>/g,"").trim(),o,n.role))}const he={class:"rounded-lg border border-border-default bg-surface-raised p-4"},xe={class:"mb-3 text-sm font-medium text-text-secondary"},ye={class:"h-48"},ve={class:"mt-2 text-[10px] text-text-muted"},$e={key:1,class:"py-6 text-center text-xs text-text-muted"},ke=x({__name:"QualityOverTurnsChart",setup(u){v.register(R,D,T,L,$,k,C,H);const n=X(),o=p(()=>{const t=n.activeConversation;return!t||t.messages.length<2?[]:_e(t.messages)}),a=p(()=>o.value.filter(t=>t.role==="assistant")),r=p(()=>({labels:a.value.map((t,e)=>`Turn ${e+1}`),datasets:[{label:"Quality Score",data:a.value.map(t=>t.score),borderColor:"#818cf8",backgroundColor:"rgba(129, 140, 248, 0.1)",fill:!0,tension:.3,pointBackgroundColor:a.value.map(t=>t.score>=3.5?"#34d399":t.score>=2?"#fbbf24":"#ef4444"),pointRadius:4}]})),f={responsive:!0,maintainAspectRatio:!1,plugins:{legend:{display:!1},tooltip:{callbacks:{label:t=>{const e=a.value[t.dataIndex];return`Score: ${(t.parsed.y??0).toFixed(1)}/5 (${e?.wordCount??0} words)`}}}},scales:{x:{ticks:{color:"#94a3b8",font:{size:10}},grid:{color:"rgba(71, 85, 105, 0.3)"}},y:{min:0,max:5,ticks:{color:"#94a3b8",font:{size:10},stepSize:1},grid:{color:"rgba(71, 85, 105, 0.3)"}}}},s=p(()=>a.value.length>=2);return(t,e)=>(d(),c("div",he,[l("h3",xe,m(t.$t("analytics.quality.title")),1),s.value?(d(),c(w,{key:0},[l("div",ye,[_(y(O),{data:r.value,options:f},null,8,["data"])]),l("p",ve,m(t.$t("analytics.quality.hint")),1)],64)):(d(),c("p",$e,m(t.$t("analytics.quality.noData")),1))]))}}),Ce={class:"h-full overflow-y-auto p-6"},De={class:"mb-6 text-lg font-semibold text-text-primary"},Se={class:"mb-8"},we={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Re={class:"mb-8"},Me={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Te={class:"grid gap-6 lg:grid-cols-2"},ze={class:"mt-6"},Ae={class:"mb-8"},Le={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Oe={class:"grid gap-6 lg:grid-cols-2"},Ee={class:"mt-6"},He={class:"mb-8"},Pe={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},qe={class:"grid gap-6 lg:grid-cols-2"},Fe={class:"mt-6"},Be={class:"mb-8"},We={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Ie={class:"mb-4 text-sm font-semibold uppercase tracking-wide text-text-muted"},Qe=x({__name:"AnalyticsPage",setup(u){return(n,o)=>(d(),c("div",Ce,[l("h1",De,m(n.$t("analytics.title")),1),l("section",Se,[l("h2",we,m(n.$t("analytics.sections.quality")),1),_(ke)]),l("section",Re,[l("h2",Me,m(n.$t("analytics.sections.latency")),1),l("div",Te,[_(ot),_(it)]),l("div",ze,[_(bt)])]),l("section",Ae,[l("h2",Le,m(n.$t("analytics.sections.reliability")),1),l("div",Oe,[_(Mt),_(Ot)]),l("div",Ee,[_(kt)])]),l("section",He,[l("h2",Pe,m(n.$t("analytics.sections.usage")),1),l("div",qe,[_(Ft),_(Ut)]),l("div",Fe,[_(Zt)])]),l("section",Be,[l("h2",We,m(n.$t("analytics.sections.settings")),1),_(ne)]),l("section",null,[l("h2",Ie,m(n.$t("analytics.sections.modelMemory")),1),_(be)])]))}});export{Qe as default};
|