eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 4.19 kB
JavaScript
import{sanitizeForTerminal}from"#cli/ui/output.js";import{formatElapsed}from"#cli/format-elapsed.js";import{formatCompactTokenCount}from"#cli/dev/tui/stream-format.js";import{formatAttributeContent}from"#cli/dev/tui/traces/trace-content.js";import{AGENT_USAGE_ATTRIBUTES}from"#tracing/agent-span-contract.js";function spanMetricChips(e){let t=[],n=numberAttribute(e,`agent.usage.input_tokens`),r=numberAttribute(e,`agent.usage.output_tokens`);n!==void 0&&t.push(`↑${formatCompactTokenCount(n)}`),r!==void 0&&t.push(`↓${formatCompactTokenCount(r)}`);let i=spanCostUsd(e);return i!==void 0&&t.push(formatCostUsd(i)),t}function summarizeLocalTrace(e){let t=[],n=0,r=0,i,a=0,o=0,s=0;for(let c of e){let e=stringAttribute(c,`agent.model.id`)??stringAttribute(c,`gen_ai.request.model`);if(e!==void 0&&!t.includes(e)&&t.push(e),c.statusCode===2&&(a+=1),c.name!==`agent.step`)continue;o+=numberAttribute(c,`agent.usage.input_tokens`)??0,s+=numberAttribute(c,`agent.usage.output_tokens`)??0,n+=numberAttribute(c,AGENT_USAGE_ATTRIBUTES.cacheReadTokens)??numberAttribute(c,`gen_ai.usage.cache_read.input_tokens`)??0,r+=numberAttribute(c,AGENT_USAGE_ATTRIBUTES.cacheWriteTokens)??numberAttribute(c,`gen_ai.usage.cache_write.input_tokens`)??numberAttribute(c,`gen_ai.usage.cache_creation.input_tokens`)??0;let l=spanCostUsd(c);l!==void 0&&(i=(i??0)+l)}return{cacheReadTokens:n,cacheWriteTokens:r,costUsd:i,errorCount:a,inputTokens:o,models:t,outputTokens:s}}function formatTokenSummary(e){let t=[`↑${formatCompactTokenCount(e.inputTokens)} in`,`↓${formatCompactTokenCount(e.outputTokens)} out`];return e.cacheReadTokens>0&&t.push(`${formatCompactTokenCount(e.cacheReadTokens)} cached`),e.cacheWriteTokens>0&&t.push(`${formatCompactTokenCount(e.cacheWriteTokens)} cache write`),t.join(` · `)}function formatCostUsd(e){return e>=1?`$${e.toFixed(2)}`:`$${e.toFixed(4)}`}function renderSpanDetailTree(e,t){let n=spanDetailEntries(e,t.width-t.margin.length-3),r=[];return n.forEach((e,r)=>{let i=r===n.length-1&&!t.childrenFollow;emit(e,t.margin,i?`└─ `:`├─ `)}),r;function emit(e,n,i){r.push(t.mute(`${n}${i}${e.head}`));let a=`${n}${i===`└─ `?` `:`│ `}`;for(let n of e.lines)r.push(t.mute(`${a} ${n}`));e.entries.forEach((t,n)=>{emit(t,a,n===e.entries.length-1?`└─ `:`├─ `)})}}function spanDetailEntries(e,t){let dim=e=>e,n=Math.max(40,t),r=[],push=(e,t=[],n=[])=>{r.push({entries:n,head:e,lines:t})},i=e.statusCode===2;push(`status: ${i&&e.statusMessage!==void 0?`ERROR — ${sanitizeForTerminal(e.statusMessage)}`:i?`ERROR`:`ok`}`),push(`duration: ${formatElapsed(durationMs(e.startTimeNs,e.endTimeNs))}`),push(`started: ${new Date(Number(e.startTimeNs/1000000n)).toISOString()}`),push(`span: ${e.spanId}`),e.parentSpanId!==void 0&&push(`parent: ${e.parentSpanId}`),e.scope!==void 0&&push(`scope: ${sanitizeForTerminal(e.scope)}`),e.kind!==void 0&&e.kind!==1&&push(`kind: ${spanKind(e.kind)}`);for(let t of Object.keys(e.attributes).sort()){let r=formatAttributeContent(t,e.attributes[t],dim,n-2),i=sanitizeForTerminal(t);r.length===1?push(`${i}: ${r[0]}`):push(`${i}:`,r)}return e.events.length>0&&push(`events:`,[],e.events.map(t=>{let r=Math.max(0,durationMs(e.startTimeNs,t.timeNs)),i=[];for(let e of Object.keys(t.attributes).sort()){let r=formatAttributeContent(e,t.attributes[e],dim,n-6),a=sanitizeForTerminal(e);r.length===1?i.push(`${a}: ${r[0]}`):i.push(`${a}:`,...r.map(e=>` ${e}`))}return{entries:[],head:`${sanitizeForTerminal(t.name)} +${formatElapsed(r)}`,lines:i}})),r}function spanCostUsd(e){return numberAttribute(e,`gen_ai.usage.gateway_cost`)??numberAttribute(e,`gen_ai.usage.cost`)}function spanKind(e){switch(e){case 2:return`server`;case 3:return`client`;case 4:return`producer`;case 5:return`consumer`;default:return`unknown (${e})`}}function numberAttribute(e,t){let n=e.attributes[t];if(typeof n==`number`)return n;if(typeof n==`string`&&n!==``){let e=Number(n);return Number.isFinite(e)?e:void 0}}function stringAttribute(e,t){let n=e.attributes[t];return typeof n==`string`&&n.length>0?n:void 0}function durationMs(e,t){return Number(t-e)/1e6}export{formatCostUsd,formatTokenSummary,renderSpanDetailTree,spanMetricChips,summarizeLocalTrace};