eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 7.58 kB
JavaScript
import{buildConversationItems,conversationItemExpandable}from"#cli/dev/tui/traces/trace-conversation.js";const TRACE_VIEWER_HEADER_ROWS=3;function orderedTextSelection(e){let{anchor:t,head:n}=e;return t.line<n.line||t.line===n.line&&t.column<=n.column?{start:t,end:n}:{start:n,end:t}}function createTraceViewerState(){return{...clearedTraceView(),traces:[],traceIndex:0}}function clearedTraceView(){return{trace:void 0,conversationItems:[],expandedItems:new Set,selectedRow:0,scrollRow:0,panelOpen:!1,panelFocus:!1,panelScroll:0,textSelection:void 0}}function selectedTraceViewerSpan(e){return e.conversationItems[e.selectedRow]?.span}function traceViewerItemCount(e){return e.conversationItems.length}function applyTraceList(e,t,n={}){let r=e.traces[e.traceIndex]?.traceId,i=n.preferTraceId===void 0?-1:t.findIndex(e=>e.traceId===n.preferTraceId);i===-1&&(i=r===void 0?-1:t.findIndex(e=>e.traceId===r)),i===-1&&(i=t.length===0?0:Math.max(0,e.traceIndex)),i>=t.length&&(i=Math.max(0,t.length-1));let a=t[i]?.traceId!==r,o=t.length===0?e.notice??`No local traces yet — chat with your agent and spans stream in live.`:e.notice?.startsWith(`No local traces`)?void 0:e.notice;return a?{...e,...clearedTraceView(),traces:t,traceIndex:i,notice:o}:{...e,traces:t,traceIndex:i,notice:o}}function applyLoadedTrace(e,t){if(t===void 0)return e.trace===void 0?e:{...e,trace:void 0,conversationItems:[],selectedRow:0,scrollRow:0,panelOpen:!1,panelFocus:!1,panelScroll:0,notice:`This trace was pruned — pick another with [ and ].`};let n=selectedTraceViewerSpan(e)?.spanId,r=e.conversationItems[e.selectedRow]?.kind,i=buildConversationItems(t),a;if(n===void 0)a=e.selectedRow;else{let matches=e=>e.span.spanId===n&&e.kind===r,t=e.conversationItems.slice(0,e.selectedRow).filter(matches).length,o=i.flatMap((e,t)=>matches(e)?[t]:[]);a=o[Math.min(t,o.length-1)]??-1}a===-1&&(a=Math.min(e.selectedRow,i.length-1)),a<0&&(a=0);let o=e.notice?.startsWith(`This trace was pruned`)?void 0:e.notice;return{...e,trace:t,conversationItems:i,selectedRow:a,notice:o}}function reduceTraceViewerKey(e,t,n){let r=Math.max(0,n.panelTotalRows-n.panelViewportRows),i=e.panelScroll>r?{...e,panelScroll:r}:e;switch(t.type){case`escape`:return i.textSelection===void 0?i.panelFocus?{state:{...i,panelFocus:!1}}:i.panelOpen?{state:{...i,panelOpen:!1,panelScroll:0}}:{state:i,effect:`close`}:{state:{...i,textSelection:void 0}};case`ctrl-c`:return{state:i,effect:`close`};case`mouse`:{if(t.action===`press`&&(t.button===64||t.button===65)){let e=t.button===64?-3:3;if(i.panelOpen&&t.x-1>=n.contentWidth){let t=Math.min(r,Math.max(0,i.panelScroll+e));return{state:{...i,panelScroll:t}}}return{state:scrollConversation(i,e,n)}}if(t.action===`press`&&t.button===0){let e=selectionCellAt(i,n,t.x,t.y);return e===void 0?{state:{...i,textSelection:void 0}}:{state:{...i,textSelection:{anchor:e.point,head:e.point,dragging:!1,region:e.region}}}}if(t.action===`press`&&t.button===32){if(i.textSelection===void 0)return{state:i};let e=i.textSelection.region===`panel`?panelCellAt(i,n,t.x,t.y):conversationCellAt(i,n,t.x,t.y);if(e===void 0)return{state:i};let r=i.textSelection.dragging||e.line!==i.textSelection.anchor.line||e.column!==i.textSelection.anchor.column;return{state:{...i,textSelection:{...i.textSelection,head:e,dragging:r}}}}if(t.action!==`release`||t.button!==0)return{state:i};let e=i.textSelection,a={...i,textSelection:void 0};if(e!==void 0&&e.dragging)return{state:a,copySelection:e};let o=t.y-1-3;if(o<0)return{state:a};let s=conversationItemAtBodyRow(a,n,o);if(s===void 0)return{state:a};let c=a.conversationItems[s],l=new Set(a.expandedItems);return c!==void 0&&!l.has(s)&&conversationItemExpandable(c,n.contentWidth)?l.add(s):l.delete(s),{state:{...a,selectedRow:s,expandedItems:l}}}case`enter`:return traceViewerItemCount(i)===0?{state:i}:i.panelOpen?{state:{...i,panelOpen:!1,panelFocus:!1}}:{state:{...i,panelOpen:!0,panelScroll:0}};case`tab`:return i.panelOpen?{state:{...i,panelFocus:!i.panelFocus}}:{state:i};case`up`:case`ctrl-p`:return i.panelFocus?{state:{...i,panelScroll:Math.max(0,i.panelScroll-1)}}:{state:moveSelection(i,-1,n)};case`down`:case`ctrl-n`:return i.panelFocus?{state:{...i,panelScroll:Math.min(r,i.panelScroll+1)}}:{state:moveSelection(i,1,n)};case`home`:return i.panelFocus?{state:{...i,panelScroll:0}}:{state:moveSelection(i,-i.selectedRow,n)};case`end`:return i.panelFocus?{state:{...i,panelScroll:r}}:{state:moveSelection(i,traceViewerItemCount(i)-1-i.selectedRow,n)};case`left`:case`right`:{if(i.panelFocus)return{state:i};let e=i.conversationItems[i.selectedRow];if(e===void 0||!i.expandedItems.has(i.selectedRow)&&!conversationItemExpandable(e,n.contentWidth))return{state:i};let t=new Set(i.expandedItems);t.has(i.selectedRow)?t.delete(i.selectedRow):t.add(i.selectedRow);let r={...i,expandedItems:t};return{state:{...r,scrollRow:conversationScrollRow(r,n)}}}case`text`:return t.framing===`bracketed-paste`?{state:i}:t.value===`k`?i.panelFocus?{state:{...i,panelScroll:Math.max(0,i.panelScroll-1)}}:{state:moveSelection(i,-1,n)}:t.value===`j`?i.panelFocus?{state:{...i,panelScroll:Math.min(r,i.panelScroll+1)}}:{state:moveSelection(i,1,n)}:t.value===`q`?{state:i,effect:`close`}:t.value===`[`||t.value===`]`?{state:switchTrace(i,t.value===`[`?1:-1)}:{state:i};default:return{state:i}}}function switchTrace(e,t){if(e.traces.length===0)return e;let n=Math.min(Math.max(0,e.traceIndex+t),e.traces.length-1);return n===e.traceIndex?e:{...e,...clearedTraceView(),traceIndex:n}}function moveSelection(e,t,n){let r=traceViewerItemCount(e);if(r===0)return e;let i=Math.min(Math.max(0,e.selectedRow+t),r-1);return{...e,selectedRow:i,panelScroll:0,scrollRow:conversationScrollRow({...e,selectedRow:i},n)}}function cardLineOffsets(e,t){let n=[0];for(let r=0;r<e.conversationItems.length;r+=1)n.push(n[r]+(t[r]??1)+1);return n}function conversationLineTotal(e,t){let n=cardLineOffsets(e,t);return n[n.length-1]}function conversationScrollRow(e,t){let n=t.conversationLineCounts;if(n===void 0)return e.scrollRow;let r=t.timelineViewportRows,i=cardLineOffsets(e,n)[e.selectedRow]??0,a=n[e.selectedRow]??1,o=i+a;return e.scrollRow<=i&&o<=e.scrollRow+r?e.scrollRow:a>r?i:Math.max(0,o-r)}function conversationCellAt(e,t,n,r){let i=t.conversationLineCounts;if(i===void 0||e.conversationItems.length===0)return;let a=r-1-3;if(a<0||a>=t.timelineViewportRows)return;let o=n-1;if(o<0||o>=t.contentWidth)return;let s=conversationLineTotal(e,i),c=e.scrollRow+a;if(!(c>=s))return{column:o,line:c}}function panelCellAt(e,t,n,r){if(!e.panelOpen||t.panelTotalRows===0)return;let i=r-1-3;if(i<0||i>=t.panelViewportRows)return;let a=n-1-(t.contentWidth+1);if(a<0)return;let o=e.panelScroll+i;if(!(o>=t.panelTotalRows))return{column:a,line:o}}function selectionCellAt(e,t,n,r){let i=conversationCellAt(e,t,n,r);if(i!==void 0)return{point:i,region:`conversation`};let a=panelCellAt(e,t,n,r);if(a!==void 0)return{point:a,region:`panel`}}function conversationItemAtBodyRow(e,t,n){let r=t.conversationLineCounts;if(r===void 0)return;let i=e.scrollRow+n,a=cardLineOffsets(e,r);for(let t=0;t<e.conversationItems.length;t+=1)if(i<a[t+1])return t}function scrollConversation(e,t,n){let r=n.conversationLineCounts;if(r===void 0||e.conversationItems.length===0)return e;let i=n.timelineViewportRows,a=Math.max(0,conversationLineTotal(e,r)-i),o=Math.min(a,Math.max(0,e.scrollRow+t));return o===e.scrollRow?e:{...e,scrollRow:o}}export{TRACE_VIEWER_HEADER_ROWS,applyLoadedTrace,applyTraceList,createTraceViewerState,orderedTextSelection,reduceTraceViewerKey,selectedTraceViewerSpan,traceViewerItemCount};