4 lines
30 KiB
JavaScript
4 lines
30 KiB
JavaScript
import{r as x,j as e}from"./router-zNjPR4CY.js";import{B as d}from"./badge-CDs67obV.js";import{am as Ie,C as A,b as G,d as U,g as f,B as C,S as me}from"./index-CuOHsLf7.js";import{S as Q}from"./separator-B_DSOSdz.js";import{u as X}from"./unified-ws-CBnrIqHW.js";import{j as ne,y as ye,a as be,n as ve,a2 as ae,aL as F,aM as Pe,aN as _e,aF as Ee,aO as Ae,ad as Re,d as re,e as P,f as H,W as ze,a5 as Le,aP as Be,A as De,aQ as Oe,_ as $e}from"./icons-DTcdLw9j.js";import"./utils-DjBw3JGv.js";import"./misc-BwRzHX8c.js";import"./radix-C-ZuImoP.js";class Ge{initialized=!1;listenerIdCounter=0;listeners=new Map;subscriptionActive=!1;subscriptionPromise=null;deferredUnsubTimer=null;initialize(){this.initialized||(X.addEventListener(t=>{if(t.domain!=="maisaka_monitor")return;const n={type:t.event,data:t.data};this.listeners.forEach(a=>{try{a(n)}catch(r){console.error("MaiSaka 监控事件监听器执行失败:",r)}})}),this.initialized=!0)}async ensureSubscribed(){this.subscriptionActive||(this.subscriptionPromise===null&&(this.subscriptionPromise=X.subscribe("maisaka_monitor","main").then(()=>{this.subscriptionActive=!0}).finally(()=>{this.subscriptionPromise=null})),await this.subscriptionPromise)}async subscribe(t){this.initialize();const n=++this.listenerIdCounter;return this.listeners.set(n,t),this.deferredUnsubTimer!==null&&(clearTimeout(this.deferredUnsubTimer),this.deferredUnsubTimer=null),await this.ensureSubscribed(),async()=>{this.listeners.delete(n),this.listeners.size===0&&this.subscriptionActive&&(this.deferredUnsubTimer=setTimeout(()=>{this.deferredUnsubTimer=null,this.listeners.size===0&&this.subscriptionActive&&(this.subscriptionActive=!1,X.unsubscribe("maisaka_monitor","main"))},200))}}}const Ue=new Ge,Y=3e3,Fe=1e4,He=200,Se="maisaka-monitor-background-collection",We="maisaka-monitor-db",qe=1;function ue({fallbackName:s,groupId:t,isGroupChat:n,sessionId:a,userId:r}){const l=n?t:r,o=s?.trim();return l&&o?.endsWith(`(${l})`)?o:o&&l&&o!==l&&o!==a?`${o}(${l})`:n&&t?t:!n&&r?r:s||a.slice(0,8)}let ie=0,S=[],k=new Map,b=new Map,v=null,M=!1,T=!1,Z=!1,B=0,ee=!1,J=null,E=null;const se=new Set;let L=null,xe=null,V=0,D=[],O=new Set,$=!1;function pe(s){const t=typeof s.session_id=="string"?s.session_id:"";return t?{sessionId:t,sessionName:typeof s.session_name=="string"?s.session_name:void 0,stage:typeof s.stage=="string"?s.stage:"",detail:typeof s.detail=="string"?s.detail:"",roundText:typeof s.round_text=="string"?s.round_text:"",agentState:typeof s.agent_state=="string"?s.agent_state:"",stageStartedAt:typeof s.stage_started_at=="number"?s.stage_started_at:Date.now()/1e3,updatedAt:typeof s.updated_at=="number"?s.updated_at:Date.now()/1e3}:null}function j(){se.forEach(s=>s())}function Ke(){return Z||(Z=!0,typeof window<"u"&&(T=window.localStorage.getItem(Se)==="true")),T}function le(){return typeof window>"u"||!window.indexedDB?null:(xe??=Ie(We,qe,{upgrade(s){s.createObjectStore("timeline",{keyPath:"id"}).createIndex("by-timestamp","timestamp"),s.createObjectStore("sessions",{keyPath:"sessionId"}),s.createObjectStore("meta",{keyPath:"key"})}}),xe)}function Xe(s){return{id:s.id,type:s.type,data:s.data,timestamp:s.timestamp,sessionId:s.sessionId}}async function Je(){if(!(typeof window>"u"))try{const s=le();if(!s)return;const t=await s,[n,a,r,l]=await Promise.all([t.getAllFromIndex("timeline","by-timestamp"),t.getAll("sessions"),t.get("meta","selectedSession"),t.get("meta","entryCounter")]);S=n.slice(-Y).map(Xe),k=new Map(a.map(o=>[o.sessionId,o])),v=typeof r?.value=="string"?r.value:null,ie=typeof l?.value=="number"?l.value:S.length,j()}catch(s){console.warn("读取 MaiSaka 观察 IndexedDB 缓存失败,已忽略:",s)}}async function Ve(s){const t=await s.getAllKeysFromIndex("timeline","by-timestamp"),n=t.length-Fe;if(n<=0)return;const a=s.transaction("timeline","readwrite");for(const r of t.slice(0,n))await a.store.delete(r);await a.done}async function Qe(){try{const s=le();if(!s)return;const t=D,n=Array.from(O),a=$;if(D=[],O=new Set,$=!1,t.length===0&&n.length===0&&!a)return;const r=await s,l=r.transaction(["timeline","sessions","meta"],"readwrite"),o=Date.now();for(const i of t)await l.objectStore("timeline").put({...i,persistedAt:o});for(const i of n){const m=k.get(i);m&&await l.objectStore("sessions").put(m)}await l.objectStore("meta").put({key:"selectedSession",value:v}),await l.objectStore("meta").put({key:"entryCounter",value:ie}),await l.done,V+=t.length,V>=He&&(V=0,await Ve(r))}catch(s){console.warn("保存 MaiSaka 观察 IndexedDB 缓存失败,已忽略:",s)}}async function Ye(){try{const s=le();if(!s)return;const n=(await s).transaction(["timeline","sessions","meta"],"readwrite");await Promise.all([n.objectStore("timeline").clear(),n.objectStore("sessions").clear(),n.objectStore("meta").clear()]),await n.done}catch(s){console.warn("清空 MaiSaka 观察 IndexedDB 缓存失败,已忽略:",s)}}function te(s,t){typeof window>"u"||(s&&D.push(s),t&&O.add(t),$=!0,L!==null&&window.clearTimeout(L),L=window.setTimeout(()=>{L=null,Qe()},300))}Je();function ke(){return B>0||T}function Ze(s){const t=[...S,s];S=t.length>Y?t.slice(t.length-Y):t}function fe(s,t,n){const a=s.data,r=typeof a.is_group_chat=="boolean"?a.is_group_chat:void 0,l=typeof a.group_id=="string"?a.group_id:null,o=typeof a.user_id=="string"?a.user_id:null,i=typeof a.platform=="string"?a.platform:void 0,m=typeof a.session_name=="string"?a.session_name:void 0,N=new Map(k),u=N.get(t);s.type==="session.start"||!u?N.set(t,{sessionId:t,sessionName:ue({fallbackName:m,groupId:l,isGroupChat:r,sessionId:t,userId:o}),isGroupChat:r,groupId:l,userId:o,platform:i,lastActivity:n,eventCount:(u?.eventCount??0)+1}):N.set(t,{...u,sessionName:ue({fallbackName:m??u.sessionName,groupId:l??u.groupId,isGroupChat:r??u.isGroupChat,sessionId:t,userId:o??u.userId}),isGroupChat:r??u.isGroupChat,groupId:l??u.groupId,userId:o??u.userId,platform:i??u.platform,lastActivity:n,eventCount:u.eventCount+1}),k=N}function he(s){const t=(n,a)=>{const r=n.get(a.sessionId);r&&a.updatedAt<r.updatedAt||n.set(a.sessionId,a)};if(s.type==="stage.snapshot"){const n=s.data.entries;if(!Array.isArray(n))return;const a=new Map(b);for(const r of n){if(!r||typeof r!="object")continue;const l=pe(r);l&&t(a,l)}b=a;return}if(s.type==="stage.status"){const n=pe(s.data);if(!n)return;const a=new Map(b);t(a,n),b=a;return}if(s.type==="stage.removed"){const n=s.data,a=typeof n.session_id=="string"?n.session_id:"";if(!a)return;const r=new Map(b);r.delete(a),b=r}}function es(s){const t=s.data,n=t.session_id,a=t.timestamp;if(s.type==="stage.snapshot"){he(s),j();return}if(!n||typeof a!="number")return;if(s.type==="stage.status"||s.type==="stage.removed"){he(s),fe(s,n,a),te(void 0,n),j();return}const r={id:`evt_${++ie}_${Date.now()}`,type:s.type,data:s.data,timestamp:a,sessionId:n};Ze(r),fe(s,n,a),v===null&&(v=n),te(r,n),j()}function ge(){ee||J!==null||(J=Ue.subscribe(es).then(s=>{if(E=s,!ke()){E=null,s(),M=!1,j();return}ee=!0,M=!0,j()}).catch(s=>{console.error("MaiSaka 监控订阅失败:",s),M=!1,j()}).finally(()=>{J=null}))}function je(){if(!ke()&&E){const s=E;E=null,ee=!1,M=!1,j(),s()}}function ss(){const[s,t]=x.useState(S),[n,a]=x.useState(new Map(k)),[r,l]=x.useState(new Map(b)),[o,i]=x.useState(v),[m,N]=x.useState(M),[u,R]=x.useState(Ke);x.useEffect(()=>{B+=1,ge();const h=()=>{t(S),a(new Map(k)),l(new Map(b)),i(v),N(M),R(T)};return se.add(h),h(),()=>{se.delete(h),B=Math.max(0,B-1),je()}},[]);const g=x.useCallback(()=>{S=[],k=new Map,b=new Map,v=null,t([]),a(new Map),l(new Map),i(null),D=[],O=new Set,$=!1,Ye(),j()},[]),W=x.useCallback(h=>{v=h,i(h),te(),j()},[]),w=x.useCallback(h=>{T=h,Z=!0,typeof window<"u"&&window.localStorage.setItem(Se,String(h)),h?ge():je(),j()},[]);return{timeline:o?s.filter(h=>h.sessionId===o):s,allTimeline:s,sessions:n,stageStatuses:r,selectedSession:o,setSelectedSession:W,connected:m,backgroundCollection:u,setBackgroundCollectionEnabled:w,clearTimeline:g}}function _(s){return s<1e3?`${Math.round(s)}ms`:`${(s/1e3).toFixed(2)}s`}function Ne(s,t){return`${s}:${t}`}function oe(s){return new Date(s*1e3).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function Ce(s){const t=Date.now()/1e3-s;return t<10?"刚刚":t<60?`${Math.round(t)}秒前`:t<3600?`${Math.round(t/60)}分钟前`:`${Math.round(t/3600)}小时前`}function ts({sessions:s,stageStatuses:t,selectedSession:n,onSelect:a,collapsed:r}){const l=Array.from(s.values()).sort((i,m)=>m.lastActivity-i.lastActivity),o=i=>{const m=i.sessionName.trim();return m?m.slice(0,1):i.isGroupChat?"群":"私"};return l.length===0?e.jsxs("div",{className:f("flex flex-col items-center justify-center h-full text-muted-foreground gap-2",r?"p-2":"p-4"),children:[e.jsx(re,{className:"h-8 w-8 opacity-40"}),e.jsx("p",{className:"text-sm text-center",children:"等待 MaiSaka 会话…"})]}):e.jsx("div",{className:f("flex flex-col gap-1",r?"items-center p-2":"p-2"),children:l.map(i=>{const m=t.get(i.sessionId);return e.jsxs("button",{onClick:()=>a(i.sessionId),title:i.sessionName,className:f("max-w-full overflow-hidden rounded-lg text-left text-sm transition-colors","hover:bg-accent/50",r?"flex h-10 w-10 items-center justify-center p-0":"flex w-full min-w-0 flex-col items-start gap-0.5 px-2.5 py-2",n===i.sessionId&&"bg-accent text-accent-foreground"),children:[e.jsxs("div",{className:f("flex w-full min-w-0 items-center",r?"justify-center":"justify-between gap-2"),children:[e.jsxs("div",{className:f("flex min-w-0 items-center gap-2 overflow-hidden",!r&&"flex-1"),children:[e.jsxs("span",{className:"relative flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-primary/10 text-xs font-semibold text-primary",children:[o(i),m&&e.jsx("span",{className:"absolute -right-0.5 -top-0.5 h-2.5 w-2.5 rounded-full bg-emerald-500 ring-2 ring-background"})]}),!1,!r&&e.jsx("span",{className:"block min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap font-medium",title:i.sessionName,children:i.sessionName})]}),!r&&e.jsx(d,{variant:"secondary",className:"h-4 shrink-0 px-1 text-[10px]",children:i.eventCount})]}),!r&&e.jsxs("div",{className:"flex w-full min-w-0 items-center justify-between gap-2 overflow-hidden text-xs text-muted-foreground",children:[e.jsx("span",{className:"shrink-0",children:Ce(i.lastActivity)}),m&&e.jsx("span",{className:"min-w-0 truncate text-primary",children:m.stage})]})]},i.sessionId)})})}function ns({status:s}){return s?e.jsxs("div",{className:"mb-3 rounded-md border bg-background px-3 py-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs(d,{variant:"default",className:"gap-1",children:[e.jsx(ne,{className:"h-3 w-3"}),s.stage||"未知阶段"]}),s.roundText&&e.jsx(d,{variant:"secondary",className:"text-[10px]",children:s.roundText}),s.agentState&&e.jsx(d,{variant:s.agentState==="running"?"default":"outline",className:"text-[10px]",children:s.agentState}),e.jsxs("span",{className:"ml-auto text-xs text-muted-foreground",children:["更新于 ",Ce(s.updatedAt)]})]}),s.detail&&e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:s.detail})]}):e.jsx("div",{className:"mb-3 rounded-md border bg-muted/30 px-3 py-2 text-sm text-muted-foreground",children:"当前聊天流暂无阶段状态"})}function as({data:s}){return e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-blue-500/15 text-blue-500",children:e.jsx(ve,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"font-medium text-sm",children:s.speaker_name}),e.jsx("span",{className:"text-xs text-muted-foreground",children:oe(s.timestamp)})]}),e.jsx("p",{className:"text-sm text-foreground/80 whitespace-pre-wrap wrap-break-word leading-relaxed",children:s.content||"[空消息]"})]})]})}function rs({data:s}){return e.jsxs("div",{className:"flex items-start gap-3 rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2",children:[e.jsx("div",{className:"mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-500",children:e.jsx(re,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"mb-1 flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-sm",children:s.speaker_name||"麦麦"}),e.jsx(d,{variant:"outline",className:"text-[10px]",children:"已发送"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:oe(s.timestamp)})]}),e.jsx("p",{className:"text-sm text-foreground/80 whitespace-pre-wrap wrap-break-word leading-relaxed",children:s.content||"[非文本消息]"})]})]})}function is({data:s}){return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-violet-500/15 text-violet-500",children:e.jsx($e,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("span",{className:"text-sm font-medium",children:["推理循环 #",s.cycle_id]}),e.jsxs(d,{variant:"outline",className:"text-[10px]",children:["回合 ",s.round_index+1,"/",s.max_rounds]}),e.jsxs(d,{variant:"secondary",className:"text-[10px]",children:["上下文 ",s.history_count," 条"]})]})]})}function ls({data:s}){const t={continue:{label:"继续执行",variant:"default",icon:De},wait:{label:"等待",variant:"secondary",icon:Be},no_reply:{label:"不回复",variant:"destructive",icon:H}},n=t[s.action]??t.continue,a=n.icon;return e.jsxs("div",{className:"flex items-start gap-3 rounded-md border bg-background px-3 py-2 shadow-sm",children:[e.jsx("div",{className:"mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-amber-500/15 text-amber-500",children:e.jsx(Oe,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e.jsx("span",{className:"text-sm font-medium",children:"反应"}),e.jsx(d,{variant:"outline",className:"text-[10px]",children:"react"}),e.jsxs(d,{variant:n.variant,className:"text-[10px] gap-0.5",children:[e.jsx(a,{className:"h-2.5 w-2.5"}),n.label]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:_(s.duration_ms)})]}),s.content&&e.jsx(I,{text:s.content,maxLines:3})]})]})}function os({toolCalls:s}){return s.length<=0?null:e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:s.map((t,n)=>e.jsxs(d,{variant:"secondary",className:"text-[10px] gap-1",children:[e.jsx(F,{className:"h-2.5 w-2.5"}),t.name]},`${t.id||t.name}-${n}`))})}function cs(s){const t=s.trim();t&&window.open(t,"_blank","noopener,noreferrer")}function Me(s){const t=s.planner?.content?.trim()??"";return s.interrupted===!0||t.startsWith("Planner ")&&s.planner?.prompt_tokens===0&&s.planner?.completion_tokens===0&&s.planner?.tool_calls.length===0}function ds({data:s}){const t=s.planner;return e.jsxs("div",{className:"rounded-md border border-amber-500/35 bg-amber-500/5 px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(ze,{className:"h-4 w-4 shrink-0 text-amber-500"}),e.jsx("span",{className:"font-medium",children:"Planner 被新消息打断"}),e.jsxs(d,{variant:"outline",className:"ml-auto text-[10px]",children:["#",s.cycle_id]}),t&&t.duration_ms>0&&e.jsx("span",{className:"text-xs text-muted-foreground",children:_(t.duration_ms)})]}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:t?.content||"收到新消息,已停止当前思考并准备重新决策。"})]})}function ms({data:s}){return e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-emerald-500/15 text-emerald-500",children:e.jsx(ae,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e.jsx("span",{className:"text-sm font-medium",children:"规划器思考"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:_(s.duration_ms)}),e.jsxs(d,{variant:"outline",className:"text-[10px]",children:[s.prompt_tokens,"+",s.completion_tokens," tokens"]})]}),s.content&&e.jsx(I,{text:s.content,maxLines:6}),e.jsx(os,{toolCalls:s.tool_calls})]})]})}function us({data:s}){const t=s.planner,n=t?.prompt_html_uri?.trim()??"";return e.jsx(A,{className:"border-l-4 border-l-emerald-500/60",children:e.jsxs(G,{className:"py-3 px-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(ae,{className:"h-4 w-4 text-emerald-500"}),e.jsx(U,{className:"text-sm font-medium",children:"主循环 planner"}),n&&e.jsxs(C,{variant:"ghost",size:"sm",className:"h-6 px-2 text-[10px]",onClick:()=>cs(n),title:"打开 planner HTML 记录",children:[e.jsx(Le,{className:"mr-1 h-3 w-3"}),"HTML"]}),e.jsx(d,{variant:"outline",className:"text-xs font-normal ml-auto",children:_(t?.duration_ms??0)}),s.request&&e.jsxs(d,{variant:"secondary",className:"text-[10px]",children:["上下文 ",s.request.selected_history_count," 条 / 可用工具 ",s.request.tool_count]}),t&&(t.prompt_tokens>0||t.completion_tokens>0)&&e.jsxs(d,{variant:"outline",className:"text-[10px]",children:[t.prompt_tokens,"+",t.completion_tokens," tokens"]})]}),t?.content?e.jsx(I,{text:t.content,maxLines:6,className:"text-foreground/90"}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"planner 本轮没有文本内容"})]})})}function xs({data:s}){const t=s.planner?.tool_calls??[],n=s.tools??[],a=n.length>0?n:t.map(i=>({tool_call_id:i.id,tool_name:i.name,tool_args:i.arguments??{},success:!0,duration_ms:0,summary:""})),r=i=>i?.trim().toLowerCase()==="finish",l=a.filter(i=>r(i.tool_name)),o=a.filter(i=>!r(i.tool_name));return a.length<=0?null:o.length<=0&&l.length>0?e.jsx("div",{className:"rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2",children:e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(P,{className:"h-4 w-4 shrink-0 text-emerald-500"}),e.jsx("span",{className:"font-medium",children:"本轮思考暂时结束"}),e.jsx("span",{className:"text-muted-foreground",children:"等待新的消息。"})]})}):e.jsx(A,{className:"border-l-4 border-l-teal-500/60",children:e.jsxs(G,{className:"py-3 px-4 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(F,{className:"h-4 w-4 text-teal-500"}),e.jsx(U,{className:"text-sm font-medium",children:"Planner 工具调用"}),e.jsxs(d,{variant:"secondary",className:"ml-auto text-[10px]",children:[o.length," 个"]})]}),l.length>0&&e.jsxs("div",{className:"flex items-center gap-2 rounded-md border border-emerald-500/30 bg-emerald-500/5 px-2.5 py-1.5 text-xs",children:[e.jsx(P,{className:"h-3.5 w-3.5 shrink-0 text-emerald-500"}),e.jsx("span",{className:"font-medium",children:"本轮思考暂时结束"}),e.jsx("span",{className:"text-muted-foreground",children:"等待新的消息。"})]}),e.jsx("div",{className:"space-y-2",children:o.map((i,m)=>e.jsxs("div",{className:"rounded-md border bg-muted/40 px-2.5 py-2 text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono font-medium",children:i.tool_name||"unknown"}),i.success?e.jsx(P,{className:"h-3.5 w-3.5 text-teal-500"}):e.jsx(H,{className:"h-3.5 w-3.5 text-red-500"}),i.duration_ms>0&&e.jsx("span",{className:"text-muted-foreground",children:_(i.duration_ms)})]}),Object.keys(i.tool_args??{}).length>0&&e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-all rounded bg-background/70 px-2 py-1 text-[11px] text-muted-foreground",children:JSON.stringify(i.tool_args,null,2)}),i.summary&&e.jsx("p",{className:"mt-1 text-muted-foreground whitespace-pre-wrap break-words",children:i.summary})]},`${i.tool_call_id||i.tool_name}-${m}`))})]})})}function ps({data:s}){return e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:f("mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full",s.success?"bg-teal-500/15 text-teal-500":"bg-red-500/15 text-red-500"),children:e.jsx(F,{className:"h-3.5 w-3.5"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[e.jsx("span",{className:"text-sm font-medium font-mono",children:s.tool_name}),s.success?e.jsx(P,{className:"h-3.5 w-3.5 text-teal-500"}):e.jsx(H,{className:"h-3.5 w-3.5 text-red-500"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:_(s.duration_ms)})]}),Object.keys(s.tool_args).length>0&&e.jsx("div",{className:"text-xs text-muted-foreground font-mono bg-muted/50 rounded px-2 py-1 mb-1 whitespace-pre-wrap break-all",children:JSON.stringify(s.tool_args,null,2)}),s.result_summary&&e.jsx(I,{text:s.result_summary,maxLines:3,className:"text-muted-foreground"})]})]})}function fs(s){const t=s.end_reason??"",n=s.end_detail?.trim();return n||(t==="finish"?"Planner 调用 finish,结束本轮思考并等待新消息。":t==="timing_no_reply"?"Timing Gate 选择 no_reply,本轮不会进入 Planner。":t==="max_rounds"?"已达到内部思考轮次上限,本轮处理结束。":t==="planner_interrupted"?"Planner 被新消息打断,当前轮结束。":t.startsWith("tool_pause:")?`工具 ${t.slice(11)} 要求暂停当前思考循环。`:t==="tool_pause"?"工具要求暂停当前思考循环。":t==="empty_planner_response"?"Planner 没有返回文本或工具调用,本轮思考结束。":t==="tool_continue"?"Planner 工具执行完成,继续下一轮内部思考。":"本轮思考完成。")}function hs(s){const t=s.end_reason??"";return t==="finish"?"finish 结束":t==="timing_no_reply"?"no_reply 结束":t==="max_rounds"?"轮次上限":t==="planner_interrupted"?"Planner 打断":t.startsWith("tool_pause:")||t==="tool_pause"?"工具暂停":t==="empty_planner_response"?"空响应":t==="tool_continue"?"继续下一轮":"循环结束"}function gs({data:s}){const t=Object.values(s.time_records).reduce((n,a)=>n+a,0);return e.jsxs("div",{className:"my-1 space-y-1.5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Q,{className:"flex-1"}),e.jsxs("div",{className:"flex items-center gap-2 rounded-full border bg-background px-3 py-1",children:[e.jsx(_e,{className:"h-3.5 w-3.5 text-slate-500"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:hs(s)}),e.jsxs(d,{variant:"outline",className:"text-[10px]",children:["#",s.cycle_id]}),e.jsx("span",{className:"text-[10px] text-muted-foreground",children:_(t*1e3)}),e.jsx(d,{variant:s.agent_state==="running"?"default":"secondary",className:"text-[10px]",children:s.agent_state})]}),e.jsx(Q,{className:"flex-1"})]}),e.jsx("p",{className:"text-center text-xs text-muted-foreground",children:fs(s)})]})}function I({text:s,maxLines:t=4,className:n}){const[a,r]=x.useState(!1),l=s.split(`
|
||
`),o=l.length>t;return!o||a?e.jsxs("div",{className:"relative",children:[e.jsx("p",{className:f("text-sm whitespace-pre-wrap wrap-break-word leading-relaxed",n),children:s}),o&&e.jsxs("button",{onClick:()=>r(!1),className:"text-xs text-primary hover:underline mt-1 flex items-center gap-0.5",children:[e.jsx(be,{className:"h-3 w-3"})," 收起"]})]}):e.jsxs("div",{children:[e.jsx("p",{className:f("text-sm whitespace-pre-wrap wrap-break-word leading-relaxed",n),children:l.slice(0,t).join(`
|
||
`)}),e.jsxs("button",{onClick:()=>r(!0),className:"text-xs text-primary hover:underline mt-1 flex items-center gap-0.5",children:[e.jsx(ye,{className:"h-3 w-3"})," 展开全部 (",l.length," 行)"]})]})}function js({data:s}){return e.jsx(A,{className:"border-l-4 border-l-purple-500/60",children:e.jsxs(G,{className:"py-2.5 px-4 space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(re,{className:"h-4 w-4 text-purple-500"}),e.jsx(U,{className:"text-sm font-medium",children:"回复器响应"}),e.jsx(d,{variant:"outline",className:"text-xs font-normal ml-auto",children:_(s.duration_ms)}),s.success?e.jsxs(d,{variant:"secondary",className:"text-xs gap-1",children:[e.jsx(P,{className:"h-3 w-3"})," 成功"]}):e.jsxs(d,{variant:"destructive",className:"text-xs gap-1",children:[e.jsx(H,{className:"h-3 w-3"})," 失败"]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:oe(s.timestamp)})]}),s.content&&e.jsx(I,{text:s.content,maxLines:6,className:"text-foreground/90"}),s.reasoning&&e.jsxs("details",{className:"mt-1",children:[e.jsx("summary",{className:"text-xs text-muted-foreground cursor-pointer hover:text-foreground",children:"思考过程"}),e.jsx(I,{text:s.reasoning,maxLines:8,className:"mt-1 text-muted-foreground"})]}),(s.prompt_tokens>0||s.completion_tokens>0)&&e.jsxs("div",{className:"flex gap-3 text-xs text-muted-foreground mt-1",children:[s.model_name&&e.jsxs("span",{children:["模型: ",s.model_name]}),e.jsxs("span",{children:["输入: ",s.prompt_tokens]}),e.jsxs("span",{children:["输出: ",s.completion_tokens]}),e.jsxs("span",{children:["总计: ",s.total_tokens]})]})]})})}function we({entry:s,showCycleMarkers:t}){switch(s.type){case"message.ingested":return e.jsx(as,{data:s.data});case"message.sent":return e.jsx(rs,{data:s.data});case"cycle.start":return t?e.jsx(is,{data:s.data}):null;case"timing_gate.result":return e.jsx(ls,{data:s.data});case"planner.response":return e.jsx(ms,{data:s.data});case"planner.finalized":return Me(s.data)?e.jsx(ds,{data:s.data}):s.data.timing_gate?.result?.action==="no_reply"?null:e.jsxs("div",{className:"space-y-2",children:[e.jsx(us,{data:s.data}),e.jsx(xs,{data:s.data})]});case"tool.execution":return e.jsx(ps,{data:s.data});case"cycle.end":return e.jsx(gs,{data:s.data});case"replier.response":return e.jsx(js,{data:s.data});default:return null}}function Ns(){const{timeline:s,sessions:t,stageStatuses:n,selectedSession:a,setSelectedSession:r,connected:l,backgroundCollection:o,setBackgroundCollectionEnabled:i,clearTimeline:m}=ss(),N=x.useRef(null),[u,R]=x.useState(!0),[g,W]=x.useState(()=>localStorage.getItem("maisaka-monitor-sidebar-collapsed")!=="false"),[w,ce]=x.useState(()=>localStorage.getItem("maisaka-monitor-show-cycle-markers")==="true");x.useEffect(()=>{localStorage.setItem("maisaka-monitor-sidebar-collapsed",String(g))},[g]),x.useEffect(()=>{localStorage.setItem("maisaka-monitor-show-cycle-markers",String(w))},[w]),x.useEffect(()=>{if(u&&N.current){const c=N.current.querySelector("[data-radix-scroll-area-viewport]");c&&(c.scrollTop=c.scrollHeight)}},[s,u]);const h=x.useCallback(c=>{const p=c.currentTarget.querySelector("[data-radix-scroll-area-viewport]");if(!p)return;const{scrollTop:z,scrollHeight:y,clientHeight:K}=p;R(y-z-K<80)},[]),q={messages:s.filter(c=>c.type==="message.ingested"||c.type==="message.sent").length,cycles:s.filter(c=>c.type==="cycle.start").length,toolCalls:s.reduce((c,p)=>p.type==="tool.execution"?c+1:p.type==="planner.finalized"?c+(p.data.tools?.length??0):c,0)},Te=a?n.get(a):void 0;return e.jsxs("div",{className:"flex h-[calc(100vh-180px)] gap-4",children:[e.jsxs(A,{className:f("shrink-0 flex flex-col transition-[width] duration-200",g?"w-16":"w-52"),children:[e.jsx(G,{className:f("py-3 space-y-0",g?"px-2":"px-3"),children:e.jsxs(U,{className:f("text-sm font-medium flex items-center gap-2",g&&"justify-center text-[0px]"),children:[!g&&e.jsx(ne,{className:"h-4 w-4"}),"聊天流",l&&e.jsx("span",{className:f("flex h-2 w-2 rounded-full bg-emerald-500",!g&&"ml-auto")}),e.jsx(C,{variant:"ghost",size:"icon",className:"h-6 w-6 shrink-0",onClick:()=>W(c=>!c),title:g?"展开侧边栏":"折叠侧边栏",children:g?e.jsx(ye,{className:"h-3.5 w-3.5"}):e.jsx(be,{className:"h-3.5 w-3.5"})})]})}),e.jsx(Q,{}),e.jsx(me,{className:"flex-1",children:e.jsx(ts,{sessions:t,stageStatuses:n,selectedSession:a,onSelect:r,collapsed:g})})]}),e.jsxs("div",{className:"flex-1 flex flex-col min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-4 text-sm",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(ve,{className:"h-3.5 w-3.5"}),e.jsxs("span",{children:[q.messages," 消息"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(ae,{className:"h-3.5 w-3.5"}),e.jsxs("span",{children:[q.cycles," 循环"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 text-muted-foreground",children:[e.jsx(F,{className:"h-3.5 w-3.5"}),e.jsxs("span",{children:[q.toolCalls," 工具调用"]})]})]}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsxs(C,{variant:o?"secondary":"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>i(!o),title:o?"关闭离开页面后的持续获取":"开启离开页面后的持续获取",children:[e.jsx(Pe,{className:f("h-3.5 w-3.5 mr-1",o&&"text-primary")}),"持续获取"]}),e.jsxs(C,{variant:w?"secondary":"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>ce(c=>!c),title:w?"隐藏推理循环标记":"显示推理循环标记",children:[e.jsx(_e,{className:f("h-3.5 w-3.5 mr-1",w&&"text-primary")}),"循环标记"]}),e.jsxs(C,{variant:"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>R(!u),children:[e.jsx(Ee,{className:f("h-3.5 w-3.5 mr-1",u&&"text-primary")}),u?"跟踪中":"已暂停"]}),e.jsxs(C,{variant:"ghost",size:"sm",className:"h-7 text-xs",onClick:m,children:[e.jsx(Ae,{className:"h-3.5 w-3.5 mr-1"}),"清空"]})]})]}),e.jsx(ns,{status:Te}),e.jsx(A,{className:"flex-1 overflow-hidden",children:e.jsx(me,{className:"h-full",ref:N,onScrollCapture:h,children:e.jsx("div",{className:"p-4 space-y-3",children:s.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-20 text-muted-foreground gap-3",children:[e.jsx(Re,{className:"h-10 w-10 opacity-30"}),e.jsx("p",{className:"text-sm",children:"等待 MaiSaka 推理事件…"}),e.jsx("p",{className:"text-xs opacity-60",children:"当 MaiSaka 处理新消息时,推理过程会实时展示在这里"})]}):(()=>{const c=new Set;return s.map(p=>{if(p.type==="timing_gate.result"){const y=p.data;y.action==="no_reply"&&c.add(Ne(y.session_id,y.cycle_id))}if(p.type==="planner.response"||p.type==="planner.finalized"){const y=p.data,K=Ne(y.session_id,y.cycle_id);if(p.type==="planner.finalized"&&Me(y)){const de=e.jsx(we,{entry:p,showCycleMarkers:w});return de?e.jsx("div",{className:"animate-in fade-in-0 slide-in-from-bottom-2 duration-300",children:de},p.id):null}if(c.has(K))return null}const z=e.jsx(we,{entry:p,showCycleMarkers:w});return z?e.jsx("div",{className:"animate-in fade-in-0 slide-in-from-bottom-2 duration-300",children:z},p.id):null})})()})})})]})]})}function Ts(){return e.jsxs("div",{className:"space-y-4 sm:space-y-6 p-4 sm:p-6",children:[e.jsx("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-4",children:e.jsx("div",{children:e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(ne,{className:"h-6 w-6 sm:h-7 sm:w-7"}),"麦麦观察"]})})}),e.jsx(Ns,{})]})}export{Ts as PlannerMonitorPage};
|