@townco/gui-template 0.1.90 → 0.1.93
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/dist/assets/acp-sdk-C76JZERC.js +1 -0
- package/dist/assets/{framer-motion-DBbHpXpX.js → framer-motion-C-FfYRqi.js} +2 -2
- package/dist/assets/{icons-1FDIcXQd.js → icons-Hw9CPBRX.js} +1 -1
- package/dist/assets/{index-rBLGThrv.js → index-BtK_kE58.js} +1 -1
- package/dist/assets/{markdown-C0NpIQMG.js → markdown-D44wP98Y.js} +13 -13
- package/dist/assets/{radix-BaMamYBO.js → radix-CCc9gvVp.js} +2 -2
- package/dist/assets/{react-DGEdbr_j.js → react-CiYvVQki.js} +6 -6
- package/dist/assets/{vendor-CfDyrXXV.js → vendor-D6ejVflZ.js} +279 -279
- package/dist/index.html +8 -8
- package/package.json +4 -4
- package/dist/assets/acp-sdk-CS-scXJG.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as l,j as e,M as Xn,c as jt,h as Jn}from"./react-
|
|
1
|
+
import{r as l,j as e,M as Xn,c as jt,h as Jn}from"./react-CiYvVQki.js";import{bb as Te,bc as Zn,bd as Ot,be as B,bf as ee,bg as v,bh as H,bi as se,bj as We,bk as Y,bl as X,bm as ke,bn as oe,bo as ea,bp as et,bq as kt,br as ta,bs as sa,bt as na,bu as xe,bv as aa,ab as oa,bw as ra,bx as Ft,by as ye}from"./vendor-D6ejVflZ.js";import{P as Bt,a as ia}from"./acp-sdk-C76JZERC.js";import{S as le,C as rs,P as la,R as ca,T as da,a as is,b as ls,c as ua,d as cs,I as ds,e as us,f as ms,g as ps,L as fs,h as gs,i as ma,j as pa,k as hs,l as xs,m as bs,n as fa,O as at,o as ys,p as ot,q as vs,r as rt,D as it,s as ws,t as js,u as ga,v as Ns,w as Ss,x as ha,y as ks,V as xa,z as Cs,A as Ts,B as ba,E as ya,F as Is}from"./radix-CCc9gvVp.js";import{c as Le,d as lt,e as ct,P as va,E as wa,S as _s,f as Rs,g as ja,h as Ct,i as Na,j as Sa,k as ka,l as Ca,m as de,A as Ms,n as Ht,o as dt,F as Ta,p as Ia,q as _a,r as Ra,s as ut,t as mt,G as Es,u as Fe,v as As,w as Ps,B as Wt,x as Ma,y as Ea,z as Tt,H as tt,T as Aa,I as xt,J as Vt,K as qt,N as Be,O as He,Q as It,U as Pa,W as Da,V as Ua,Y as za,_ as La,$ as $a,a0 as Oa,a1 as Ds,a2 as Fa,a3 as Ba,a4 as Ha,a5 as Kt,a6 as Wa,a7 as Va,a8 as qa,a9 as Ka}from"./icons-Hw9CPBRX.js";import{A as Nt,m as Se}from"./framer-motion-C-FfYRqi.js";import{g as Us}from"./markdown-D44wP98Y.js";import"./katex-Dnem94XJ.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const i of r.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&n(i)}).observe(document,{childList:!0,subtree:!0});function a(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function n(o){if(o.ep)return;o.ep=!0;const r=a(o);fetch(o.href,r)}})();var Qa={};const Xe=typeof process<"u"&&process.versions?.node;let Ga,Ya=0;const Xa=new Set;function Ja(t){for(const s of Xa)s(t)}const Qt={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},Za={trace:Te.TRACE,debug:Te.DEBUG,info:Te.INFO,warn:Te.WARN,error:Te.ERROR,fatal:Te.FATAL};class eo{service;minLevel;logFilePath;logsDir;writeQueue=[];isWriting=!1;enableConsoleOutput;constructor(s,a="debug"){this.service=s,this.minLevel=a,typeof process<"u"&&(this.minLevel="info"),this.enableConsoleOutput=typeof process<"u"&&Qa?.TOWN_LOG_CONSOLE==="true"||!1}setupFileLogging(){}async writeToFile(s){if(!(!this.logFilePath||!Xe)&&(this.writeQueue.push(s),!this.isWriting)){for(this.isWriting=!0;this.writeQueue.length>0;){const n=`${this.writeQueue.splice(0,this.writeQueue.length).join(`
|
|
2
2
|
`)}
|
|
3
3
|
`;try{await require("node:fs").promises.appendFile(this.logFilePath,n,"utf-8")}catch{}}this.isWriting=!1}}shouldLog(s){return Qt[s]>=Qt[this.minLevel]}log(s,a,n){if(!this.shouldLog(s))return;const o={id:`log_${++Ya}`,timestamp:new Date().toISOString(),level:s,service:this.service,message:a,...n&&{metadata:n}};if(Ja(o),Xe&&this.logFilePath,Xe&&this.logFilePath){const c={timestamp:o.timestamp,level:o.level,service:o.service,message:o.message,...o.metadata&&{metadata:o.metadata}};this.writeToFile(JSON.stringify(c)).catch(()=>{})}if(Xe&&this.enableConsoleOutput){const c=o.timestamp,m=o.level.toUpperCase().padEnd(5),u=`[${this.service}]`,d=o.metadata?` ${JSON.stringify(o.metadata)}`:"";console.log(`${c} ${m} ${u} ${o.message}${d}`)}const r=Zn.getLogger(this.service),i=Ot.trace.getSpan(Ot.context.active());r.emit({severityNumber:Za[s],severityText:s.toUpperCase(),body:a,attributes:{service:this.service,...n&&Object.fromEntries(Object.entries(n).map(([c,m])=>[`log.${c}`,typeof m=="object"?JSON.stringify(m):m])),...i&&{trace_id:i.spanContext().traceId,span_id:i.spanContext().spanId}}})}trace(s,a){this.log("trace",s,a)}debug(s,a){this.log("debug",s,a)}info(s,a){this.log("info",s,a)}warn(s,a){this.log("warn",s,a)}error(s,a){this.log("error",s,a)}fatal(s,a){this.log("fatal",s,a)}}function fe(t,s="debug"){return new eo(t,s)}const to=B({baseUrl:v().url("Invalid base URL. Must be a valid URL (e.g., http://localhost:3000)").refine(t=>{try{const s=new URL(t);return!(s.port&&s.hostname.includes(":"))}catch{return!1}},{message:"Invalid URL format. Check for typos like duplicate ports (e.g., http://localhost:3102:3100)"}),apiKey:v().optional(),timeout:H().optional(),headers:ee(v(),v()).optional()}),V=fe("http-transport");class so{connected=!1;sessionUpdateCallbacks=new Set;errorCallbacks=new Set;messageQueue=[];currentSessionId=null;chunkResolvers=[];streamComplete=!1;sseAbortController=null;reconnectAttempts=0;maxReconnectAttempts=5;reconnectDelay=1e3;reconnecting=!1;abortController=null;options;isReceivingMessages=!1;isInReplayMode=!1;agentInfo;constructor(s){const a=to.safeParse(s);if(!a.success){const n=a.error.issues.map(o=>`${o.path.join(".")}: ${o.message}`).join("; ");throw new Error(`Invalid HTTP transport configuration: ${n}`)}this.options={...s,baseUrl:s.baseUrl.replace(/\/$/,"")}}async connect(){if(!this.connected)try{this.abortController=new AbortController;const s={protocolVersion:Bt,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}},a=await this.sendRpcRequest("initialize",s);if(a.agentInfo){const r=a._meta,i=r&&typeof r=="object",c=i&&"agentDescription"in r?String(r.agentDescription):void 0,m=i&&"suggestedPrompts"in r&&Array.isArray(r.suggestedPrompts)?r.suggestedPrompts:void 0,u=i&&"tools"in r&&Array.isArray(r.tools)?r.tools:void 0,d=i&&"mcps"in r&&Array.isArray(r.mcps)?r.mcps:void 0,g=i&&"subagents"in r&&Array.isArray(r.subagents)?r.subagents:void 0,f=i&&"initialMessage"in r&&r.initialMessage&&typeof r.initialMessage=="object"?r.initialMessage:void 0,x=i&&"uiConfig"in r&&r.uiConfig&&typeof r.uiConfig=="object"?r.uiConfig:void 0,h=i&&"promptParameters"in r&&Array.isArray(r.promptParameters)?r.promptParameters:void 0;this.agentInfo={name:a.agentInfo.name,...a.agentInfo.title?{displayName:a.agentInfo.title}:{},version:a.agentInfo.version,...c?{description:c}:{},...m?{suggestedPrompts:m}:{},...f?{initialMessage:f}:{},...x?{uiConfig:x}:{},...u?{tools:u}:{},...d?{mcps:d}:{},...g?{subagents:g}:{},...h?{promptParameters:h}:{}}}V.info("ACP connection initialized",{initResponse:a});const n={cwd:"/",mcpServers:[]},o=await this.sendRpcRequest("session/new",n);this.currentSessionId=o.sessionId,V.info("Session created",{sessionId:this.currentSessionId}),await this.connectSSE(),this.connected=!0,this.reconnectAttempts=0}catch(s){this.connected=!1;const a=s instanceof Error?s:new Error(String(s));throw this.notifyError(a),a}}async loadSession(s){this.connected&&(V.warn("Transport already connected, disconnecting first",{sessionId:s}),await this.disconnect());try{this.abortController=new AbortController;const a={protocolVersion:Bt,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}};V.info("Loading session - initializing connection",{sessionId:s});const n=await this.sendRpcRequest("initialize",a);if(n.agentInfo){const i=n._meta,c=i&&typeof i=="object",m=c&&"agentDescription"in i?String(i.agentDescription):void 0,u=c&&"suggestedPrompts"in i&&Array.isArray(i.suggestedPrompts)?i.suggestedPrompts:void 0,d=c&&"tools"in i&&Array.isArray(i.tools)?i.tools:void 0,g=c&&"mcps"in i&&Array.isArray(i.mcps)?i.mcps:void 0,f=c&&"subagents"in i&&Array.isArray(i.subagents)?i.subagents:void 0,x=c&&"initialMessage"in i&&i.initialMessage&&typeof i.initialMessage=="object"?i.initialMessage:void 0,h=c&&"uiConfig"in i&&i.uiConfig&&typeof i.uiConfig=="object"?i.uiConfig:void 0,p=c&&"promptParameters"in i&&Array.isArray(i.promptParameters)?i.promptParameters:void 0;this.agentInfo={name:n.agentInfo.name,...n.agentInfo.title?{displayName:n.agentInfo.title}:{},version:n.agentInfo.version,...m?{description:m}:{},...u?{suggestedPrompts:u}:{},...x?{initialMessage:x}:{},...h?{uiConfig:h}:{},...d?{tools:d}:{},...g?{mcps:g}:{},...f?{subagents:f}:{},...p?{promptParameters:p}:{}}}if(!n.agentCapabilities?.loadSession)throw V.error("Agent does not support loading sessions",{capabilities:n.agentCapabilities}),new Error("Agent does not support loading sessions");V.info("ACP connection initialized, loading session",{sessionId:s,capabilities:n.agentCapabilities}),this.isInReplayMode=!0,this.currentSessionId=s,await this.connectSSE();const o={sessionId:s,cwd:"/",mcpServers:[]};V.info("Sending session/load request",{loadRequest:o});const r=await this.sendRpcRequest("session/load",o);V.info("Session loaded successfully",{sessionId:this.currentSessionId,loadResponse:r}),this.connected=!0,this.reconnectAttempts=0}catch(a){this.connected=!1;const n=a instanceof Error?a:new Error(String(a));throw V.error("Failed to load session",{sessionId:s,error:n.message,stack:n.stack}),this.notifyError(n),n}}async listSessions(){try{const s={method:"GET"};this.options.headers&&(s.headers=this.options.headers);const a=await fetch(`${this.options.baseUrl}/sessions`,s);if(!a.ok)throw new Error(`HTTP ${a.status}: ${await a.text()}`);return(await a.json()).sessions||[]}catch(s){return V.error("Failed to list sessions",{error:s}),[]}}async disconnect(){if(this.connected)try{this.abortController&&(this.abortController.abort(),this.abortController=null),this.sseAbortController&&(this.sseAbortController.abort(),this.sseAbortController=null),this.connected=!1,this.currentSessionId=null,this.messageQueue=[],this.chunkResolvers=[],this.streamComplete=!1,this.reconnecting=!1,this.reconnectAttempts=0}catch(s){const a=s instanceof Error?s:new Error(String(s));throw this.notifyError(a),a}}async send(s,a){if(!this.connected||!this.currentSessionId)throw new Error("Transport not connected");this.isInReplayMode&&(V.info("Exiting replay mode - user sent a message"),this.isInReplayMode=!1);try{this.streamComplete=!1,this.messageQueue=[];const n=s.content.map(c=>c.type==="text"?{type:"text",text:c.text}:c.type==="image"?"source"in c&&c.source?{type:"image",data:c.source.data,mimeType:c.source.media_type}:"data"in c&&"mimeType"in c?{type:"image",data:c.data,mimeType:c.mimeType}:c:c),o={sessionId:this.currentSessionId,prompt:n};a?.promptParameters&&(o._meta={promptParameters:a.promptParameters});const r=await this.sendRpcRequest("session/prompt",o);V.debug("Prompt sent",{promptResponse:r}),this.streamComplete=!0;const i=this.chunkResolvers.shift();i?i({type:"content",id:this.currentSessionId||"unknown",role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0}):this.messageQueue.push({type:"content",id:this.currentSessionId||"unknown",role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0})}catch(n){this.streamComplete=!0;const o=n instanceof Error?n:new Error(String(n));throw this.notifyError(o),o}}async cancel(s){if(!this.connected){V.warn("Cannot cancel: transport not connected");return}const a=s||this.currentSessionId;if(!a){V.warn("Cannot cancel: no session ID");return}V.info("Cancelling session",{sessionId:a}),this.streamComplete=!0,this.messageQueue.length=0,await this.sendNotification("session/cancel",{sessionId:a});const n={type:"content",id:a,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0};for(;this.chunkResolvers.length>0;){const o=this.chunkResolvers.shift();o&&o(n)}}async editAndResend(s,a,n){if(!this.connected)throw new Error("Transport not connected");const o=s||this.currentSessionId;if(!o)throw new Error("No session ID available");this.isInReplayMode&&(V.info("Exiting replay mode - user edited a message"),this.isInReplayMode=!1),this.streamComplete=!1,this.messageQueue=[],V.info("Edit and resend",{sessionId:o,messageIndex:a});const r={"Content-Type":"application/json",...this.options.headers},i=this.options.timeout??600*1e3,c=new AbortController,m=setTimeout(()=>c.abort(),i);try{const u=await fetch(`${this.options.baseUrl}/sessions/${o}/edit-and-resend`,{method:"POST",headers:r,body:JSON.stringify({messageIndex:a,prompt:n}),signal:c.signal});if(clearTimeout(m),!u.ok){const g=await u.text();throw new Error(`HTTP ${u.status}: ${g}`)}this.streamComplete=!0;const d=this.chunkResolvers.shift();d?d({type:"content",id:o,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0}):this.messageQueue.push({type:"content",id:o,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0})}catch(u){throw clearTimeout(m),this.streamComplete=!0,u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${i}ms`):u}}async*receive(){this.isReceivingMessages=!0;try{for(;!this.streamComplete;)if(this.messageQueue.length>0){const s=this.messageQueue.shift();if(s&&(yield s,s.type==="content"&&s.isComplete))return}else{const s=await new Promise(a=>{this.chunkResolvers.push(a)});if(s.type==="content"&&s.isComplete){yield s;return}else yield s}for(;this.messageQueue.length>0;){const s=this.messageQueue.shift();s&&(yield s)}yield{type:"content",id:this.currentSessionId||"unknown",role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0}}finally{this.isReceivingMessages=!1}}isConnected(){return this.connected}onSessionUpdate(s){return this.sessionUpdateCallbacks.add(s),()=>{this.sessionUpdateCallbacks.delete(s)}}onError(s){return this.errorCallbacks.add(s),()=>{this.errorCallbacks.delete(s)}}getAgentInfo(){return this.agentInfo||{}}async sendNotification(s,a){const n={jsonrpc:"2.0",method:s,params:a};V.debug("Sending notification",{method:s,params:a});const o={"Content-Type":"application/json",...this.options.headers};try{const r=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:o,body:JSON.stringify(n)});if(!r.ok){const i=await r.text();V.error("Notification failed",{status:r.status,errorText:i})}}catch(r){V.error("Error sending notification",{error:r})}}async sendRpcRequest(s,a){const o={jsonrpc:"2.0",id:this.generateRequestId(),method:s,params:a};V.debug("Sending RPC request",{method:s,params:a,request:o});const r={"Content-Type":"application/json",...this.options.headers},i=this.options.timeout??600*1e3,c=new AbortController,m=setTimeout(()=>c.abort(),i);try{const u=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:r,body:JSON.stringify(o),signal:c.signal});if(clearTimeout(m),!u.ok){const g=await u.text();throw new Error(`HTTP ${u.status}: ${g}`)}const d=await u.json();if(d.error)throw new Error(`ACP error: ${d.error.message||JSON.stringify(d.error)}`);return d.result||d}catch(u){throw clearTimeout(m),u instanceof Error&&u.name==="AbortError"?new Error(`Request timeout after ${i}ms`):u}}async connectSSE(){if(!this.currentSessionId)throw new Error("Cannot connect SSE without a session ID");const s=`${this.options.baseUrl}/events`,a={"X-Session-ID":this.currentSessionId,...this.options.headers};this.sseAbortController=new AbortController;try{const n=await fetch(s,{method:"GET",headers:a,signal:this.sseAbortController.signal});if(!n.ok)throw new Error(`SSE connection failed: HTTP ${n.status}`);if(!n.body)throw new Error("Response body is null");V.debug("SSE connection opened"),this.reconnectAttempts=0,this.reconnectDelay=1e3;const o=n.body.getReader(),r=new TextDecoder;let i="";(async()=>{try{for(;;){const{done:c,value:m}=await o.read();if(c){V.debug("SSE stream closed by server"),this.connected&&await this.handleSSEDisconnect();break}i+=r.decode(m,{stream:!0});const u=i.split(`
|
|
4
4
|
`);i=u.pop()||"";let d={event:"message",data:""};for(const g of u)g.startsWith("event:")?d.event=g.substring(6).trim():g.startsWith("data:")?d.data=g.substring(5).trim():g===""&&(d.event==="message"&&d.data&&this.handleSSEMessage(d.data),d={event:"message",data:""})}}catch(c){if(c instanceof Error&&c.name==="AbortError"){V.debug("SSE stream aborted");return}V.error("Error reading SSE stream",{error:c}),this.connected&&!this.reconnecting&&await this.handleSSEDisconnect()}})()}catch(n){throw V.error("SSE connection error",{error:n}),n}}async handleSSEDisconnect(){if(this.reconnecting||!this.connected)return;if(this.reconnecting=!0,this.sseAbortController&&(this.sseAbortController.abort(),this.sseAbortController=null),this.reconnectAttempts>=this.maxReconnectAttempts){const a=new Error(`SSE reconnection failed after ${this.maxReconnectAttempts} attempts`);this.notifyError(a),this.connected=!1,this.reconnecting=!1;return}this.reconnectAttempts++;const s=Math.min(this.reconnectDelay*2**(this.reconnectAttempts-1),32e3);V.debug("SSE reconnecting",{delay:s,attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts}),await new Promise(a=>setTimeout(a,s));try{await this.connectSSE(),V.info("SSE reconnected successfully"),this.reconnecting=!1}catch(a){V.error("SSE reconnection failed",{error:a}),this.reconnecting=!1}}handleSSEMessage(s){try{const a=JSON.parse(s);V.debug("Received SSE message",{message:a});const n=ia.safeParse(a);if(!n.success){V.error("Invalid ACP message from SSE",{issues:n.error.issues});return}const o=n.data;V.debug("Parsed ACP message",{method:"method"in o?o.method:"(no method)"}),"method"in o&&o.method==="session/update"&&(V.debug("Received session/update notification"),"params"in o&&o.params&&(V.debug("Calling handleSessionNotification",{params:o.params}),this.handleSessionNotification(o.params)))}catch(a){V.error("Error parsing SSE message",{error:a}),this.notifyError(a instanceof Error?a:new Error(String(a)))}}handleSessionNotification(s){if(this.streamComplete){V.debug("Skipping session notification - stream complete/cancelled");return}V.debug("handleSessionNotification called",{params:s});const n=s.update,o=this.currentSessionId||s.sessionId;if(V.debug("Update session type",{sessionUpdate:n?.sessionUpdate}),n?.sessionUpdate==="tool_call"){V.debug("Tool call notification",{tokenUsage:n.tokenUsage});const r=n._meta&&typeof n._meta=="object"&&"messageId"in n._meta?String(n._meta.messageId):void 0,i=n._meta&&typeof n._meta=="object"&&"prettyName"in n._meta&&typeof n._meta.prettyName=="string"?n._meta.prettyName:void 0,c=n._meta&&typeof n._meta=="object"&&"icon"in n._meta&&typeof n._meta.icon=="string"?n._meta.icon:void 0,m=n._meta&&typeof n._meta=="object"&&"subline"in n._meta&&typeof n._meta.subline=="string"?n._meta.subline:void 0,u=n._meta&&typeof n._meta=="object"&&"batchId"in n._meta&&typeof n._meta.batchId=="string"?n._meta.batchId:void 0,d=n._meta&&typeof n._meta=="object"&&"subagentPort"in n._meta&&typeof n._meta.subagentPort=="number"?n._meta.subagentPort:void 0,g=n._meta&&typeof n._meta=="object"&&"subagentSessionId"in n._meta&&typeof n._meta.subagentSessionId=="string"?n._meta.subagentSessionId:void 0,f=n._meta&&typeof n._meta=="object"&&"subagentMessages"in n._meta&&Array.isArray(n._meta.subagentMessages)?n._meta.subagentMessages:void 0,x=n._meta&&typeof n._meta=="object"&&"compactionAction"in n._meta&&typeof n._meta.compactionAction=="string"?n._meta.compactionAction:void 0,h=n._meta&&typeof n._meta=="object"&&"originalTokens"in n._meta&&typeof n._meta.originalTokens=="number"?n._meta.originalTokens:void 0,p=n._meta&&typeof n._meta=="object"&&"finalTokens"in n._meta&&typeof n._meta.finalTokens=="number"?n._meta.finalTokens:void 0,N=n._meta&&typeof n._meta=="object"&&"originalContentPreview"in n._meta&&typeof n._meta.originalContentPreview=="string"?n._meta.originalContentPreview:void 0,S=n._meta&&typeof n._meta=="object"&&"originalContentPath"in n._meta&&typeof n._meta.originalContentPath=="string"?n._meta.originalContentPath:void 0,w={id:n.toolCallId??"",batchId:u,title:n.title??"",prettyName:i,icon:c,subline:m,kind:n.kind||"other",status:n.status||"pending",locations:n.locations,rawInput:n.rawInput,tokenUsage:n.tokenUsage,content:n.content?.map(P=>{if(typeof P!="object"||P===null)return{type:"text",text:""};const I=P;if(I.type==="content"&&typeof I.content=="object"&&I.content!==null){const C=I.content;if(C.type==="text")return{type:"content",content:{type:"text",text:typeof C.text=="string"?C.text:""}}}return I.type==="text"?{type:"text",text:typeof I.text=="string"?I.text:""}:I.type==="diff"?{type:"diff",path:typeof I.path=="string"?I.path:"",oldText:typeof I.oldText=="string"?I.oldText:"",newText:typeof I.newText=="string"?I.newText:"",line:typeof I.line=="number"?I.line:null}:I.type==="terminal"?{type:"terminal",terminalId:typeof I.terminalId=="string"?I.terminalId:""}:{type:"text",text:""}}),startedAt:Date.now(),subagentPort:d,subagentSessionId:g,subagentMessages:f,_meta:x||h||p||N||S?{compactionAction:x,originalTokens:h,finalTokens:p,originalContentPreview:N,originalContentPath:S}:void 0},k={type:"tool_call",sessionId:o,status:"active",toolCall:w,messageId:r},E=n._meta&&typeof n._meta=="object"&&"isReplay"in n._meta&&n._meta.isReplay===!0;if(V.info("Creating tool_call session update",{toolCallId:w.id,title:w.title,hasSubagentPort:!!d,hasSubagentSessionId:!!g,hasSubagentMessages:!!f,subagentMessagesCount:f?.length,isReplay:E,isInReplayMode:this.isInReplayMode}),E||this.isInReplayMode)this.notifySessionUpdate(k);else{const P={type:"tool_call",id:o,toolCall:w,messageId:r},I=this.chunkResolvers.shift();I?I(P):this.messageQueue.push(P)}}else if(n?.sessionUpdate==="tool_call_update"){const r=n._meta&&typeof n._meta=="object"&&"messageId"in n._meta?String(n._meta.messageId):void 0,i=n._meta&&typeof n._meta=="object"&&"prettyName"in n._meta&&typeof n._meta.prettyName=="string"?n._meta.prettyName:void 0,c=n._meta&&typeof n._meta=="object"&&"icon"in n._meta&&typeof n._meta.icon=="string"?n._meta.icon:void 0,m=n._meta&&typeof n._meta=="object"&&"batchId"in n._meta&&typeof n._meta.batchId=="string"?n._meta.batchId:void 0,u=n._meta&&typeof n._meta=="object"&&"subagentPort"in n._meta&&typeof n._meta.subagentPort=="number"?n._meta.subagentPort:void 0,d=n._meta&&typeof n._meta=="object"&&"subagentSessionId"in n._meta&&typeof n._meta.subagentSessionId=="string"?n._meta.subagentSessionId:void 0,g=n._meta&&typeof n._meta=="object"&&"subagentMessages"in n._meta&&Array.isArray(n._meta.subagentMessages)?n._meta.subagentMessages:void 0;(u||d||g)&&V.info("Extracted subagent info from tool_call_update",{toolCallId:n.toolCallId,subagentPort:u,subagentSessionId:d,subagentMessagesCount:g?.length});const f=n._meta&&typeof n._meta=="object"&&"compactionAction"in n._meta&&typeof n._meta.compactionAction=="string"?n._meta.compactionAction:void 0,x=n._meta&&typeof n._meta=="object"&&"originalTokens"in n._meta&&typeof n._meta.originalTokens=="number"?n._meta.originalTokens:void 0,h=n._meta&&typeof n._meta=="object"&&"finalTokens"in n._meta&&typeof n._meta.finalTokens=="number"?n._meta.finalTokens:void 0,p=n._meta&&typeof n._meta=="object"&&"originalContentPreview"in n._meta&&typeof n._meta.originalContentPreview=="string"?n._meta.originalContentPreview:void 0,N=n._meta&&typeof n._meta=="object"&&"originalContentPath"in n._meta&&typeof n._meta.originalContentPath=="string"?n._meta.originalContentPath:void 0,S={id:n.toolCallId??"",status:n.status,title:n.title,prettyName:i,icon:c,batchId:m,rawInput:n.rawInput,locations:n.locations,rawOutput:n.rawOutput,tokenUsage:n.tokenUsage,content:n.content?.map(k=>{if(typeof k!="object"||k===null)return{type:"text",text:""};const E=k;if(E.type==="content"&&typeof E.content=="object"&&E.content!==null){const P=E.content;if(P.type==="text")return{type:"content",content:{type:"text",text:typeof P.text=="string"?P.text:""}}}return E.type==="text"?{type:"text",text:typeof E.text=="string"?E.text:""}:E.type==="diff"?{type:"diff",path:typeof E.path=="string"?E.path:"",oldText:typeof E.oldText=="string"?E.oldText:"",newText:typeof E.newText=="string"?E.newText:"",line:typeof E.line=="number"?E.line:null}:E.type==="terminal"?{type:"terminal",terminalId:typeof E.terminalId=="string"?E.terminalId:""}:{type:"text",text:""}}),error:n.error,completedAt:n.status==="completed"||n.status==="failed"?Date.now():void 0,subagentPort:u,subagentSessionId:d,subagentMessages:g,_meta:f||x||h||p||N?{compactionAction:f,originalTokens:x,finalTokens:h,originalContentPreview:p,originalContentPath:N}:void 0},w={type:"tool_call_update",sessionId:o,status:"active",toolCallUpdate:S,messageId:r};if(this.isInReplayMode)this.notifySessionUpdate(w);else{const k={type:"tool_call_update",id:o,toolCallUpdate:S,messageId:r},E=this.chunkResolvers.shift();E?E(k):this.messageQueue.push(k)}V.debug("Processed tool_call_update",{sessionUpdate:w,isReplay:this.isInReplayMode})}else if(n&&"sessionUpdate"in n&&n.sessionUpdate==="hook_notification"){const r=n;V.debug("Received hook_notification",{id:r.id,notificationType:r.notification.type,hookType:r.notification.hookType});const i={type:"hook_notification",id:r.id,notification:r.notification,messageId:r.messageId},c=this.chunkResolvers.shift();c?c(i):this.messageQueue.push(i)}else if(n&&"sessionUpdate"in n&&n.sessionUpdate==="tool_output"){const r=n,i=r._meta&&typeof r._meta=="object"&&"messageId"in r._meta?String(r._meta.messageId):void 0,c={id:r.toolCallId??"",rawOutput:r.rawOutput,content:r.content?.map(u=>{if(typeof u!="object"||u===null)return{type:"text",text:""};const d=u;if(d.type==="content"&&typeof d.content=="object"&&d.content!==null){const g=d.content;if(g.type==="text")return{type:"content",content:{type:"text",text:typeof g.text=="string"?g.text:""}}}return d.type==="text"?{type:"text",text:typeof d.text=="string"?d.text:""}:d.type==="diff"?{type:"diff",path:typeof d.path=="string"?d.path:"",oldText:typeof d.oldText=="string"?d.oldText:"",newText:typeof d.newText=="string"?d.newText:"",line:typeof d.line=="number"?d.line:null}:d.type==="terminal"?{type:"terminal",terminalId:typeof d.terminalId=="string"?d.terminalId:""}:d.type==="image"?{type:"image",data:typeof d.data=="string"?d.data:"",mimeType:typeof d.mimeType=="string"?d.mimeType:"image/png",alt:typeof d.alt=="string"?d.alt:void 0}:{type:"text",text:""}})},m={type:"tool_call_update",sessionId:o,status:"active",toolCallUpdate:c,messageId:i};if(this.isInReplayMode)this.notifySessionUpdate(m);else{const u={type:"tool_call_update",id:o,toolCallUpdate:c,messageId:i},d=this.chunkResolvers.shift();d?d(u):this.messageQueue.push(u)}V.debug("Queued tool_output as tool_call_update chunk",{sessionUpdate:m})}else if(n&&"sessionUpdate"in n&&n.sessionUpdate==="sources"){const r=n;V.debug("Received sources notification",{sourcesCount:r.sources.length});const i={type:"sources",sources:r.sources},c=this.chunkResolvers.shift();c?c(i):this.messageQueue.push(i)}else if(n?.sessionUpdate==="agent_message_chunk"){const r=n._meta&&typeof n._meta=="object"&&"isReplay"in n._meta&&n._meta.isReplay===!0;if(this.isInReplayMode&&!r)return;const i=n._meta&&typeof n._meta=="object"&&"tokenUsage"in n._meta?n._meta.tokenUsage:void 0,c=n._meta&&typeof n._meta=="object"&&"contextInputTokens"in n._meta&&typeof n._meta.contextInputTokens=="number"?n._meta.contextInputTokens:void 0,m=n._meta&&typeof n._meta=="object"&&"context_size"in n._meta?n._meta.context_size:void 0,u={type:"generic",sessionId:o,status:"active",_meta:n._meta},d=n.content;if(d&&typeof d=="object"){const f=d;let x=null;if(f.type==="text"&&typeof f.text=="string"&&(x={type:"content",id:s.sessionId,role:"assistant",contentDelta:{type:"text",text:f.text},tokenUsage:i,contextInputTokens:c,_meta:m?{context_size:m}:void 0,isComplete:!1}),x&&!r){const h=this.chunkResolvers.shift();h?h(x):this.messageQueue.push(x)}if(x&&typeof f.text=="string"&&(r||!this.isReceivingMessages)){const h={type:"generic",sessionId:o,status:"active",message:{id:`msg_${Date.now()}_assistant`,role:"assistant",content:[{type:"text",text:f.text}],timestamp:new Date().toISOString()}};this.notifySessionUpdate(h)}}const g=u._meta&&"context_size"in u._meta;(!r||g)&&this.notifySessionUpdate(u)}else if(n?.sessionUpdate==="user_message_chunk"){V.debug("Received user_message_chunk",{update:n});const r=n.content;if(r&&typeof r=="object"){const i=r;if(i.type==="text"&&typeof i.text=="string"){const c={type:"generic",sessionId:o,status:"active",message:{id:`msg_${Date.now()}_user`,role:"user",content:[{type:"text",text:i.text}],timestamp:new Date().toISOString()}};V.debug("Notifying session update for user message"),this.notifySessionUpdate(c)}}}else{const r={type:"generic",sessionId:o,status:"active"};this.notifySessionUpdate(r)}}generateRequestId(){return`req-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}notifySessionUpdate(s){for(const a of this.sessionUpdateCallbacks)try{a(s)}catch(n){V.error("Error in session update callback",{error:n})}}notifyError(s){for(const a of this.errorCallbacks)try{a(s)}catch(n){V.error("Error in error callback",{error:n})}}}class no{constructor(){throw new Error("StdioTransport is not available in the browser. Use HttpTransport or WebSocketTransport instead.")}async connect(){throw new Error("StdioTransport not available in browser")}async disconnect(){}async send(){throw new Error("StdioTransport not available in browser")}async*receive(){throw new Error("StdioTransport not available in browser")}isConnected(){return!1}onSessionUpdate(){return()=>{}}onError(){return()=>{}}}class ao{ws=null;connected=!1;sessionUpdateCallbacks=new Set;errorCallbacks=new Set;constructor(s){}async connect(){throw new Error("WebSocketTransport not yet implemented. Waiting for HTTP ACP server.")}async disconnect(){this.ws&&(this.ws.close(),this.ws=null),this.connected=!1}async send(s){throw!this.connected||!this.ws?new Error("Transport not connected"):new Error("WebSocketTransport not yet implemented. Waiting for HTTP ACP server.")}async*receive(){throw new Error("WebSocketTransport not yet implemented. Waiting for HTTP ACP server.")}async cancel(s){throw new Error("WebSocketTransport not yet implemented. Waiting for HTTP ACP server.")}isConnected(){return this.connected}onSessionUpdate(s){return this.sessionUpdateCallbacks.add(s),()=>{this.sessionUpdateCallbacks.delete(s)}}onError(s){return this.errorCallbacks.add(s),()=>{this.errorCallbacks.delete(s)}}}const Ie=fe("acp-client","debug");class oo{constructor(s){this.config=s,this.transport=this.createTransport(),this.setupTransportListeners(),s.autoConnect&&this.connect().catch(a=>{Ie.error("Failed to auto-connect",{error:a instanceof Error?a.message:String(a)})})}transport;sessions=new Map;currentSessionId=null;sessionUpdateHandlers=new Set;errorHandlers=new Set;async connect(){await this.transport.connect()}async disconnect(){await this.transport.disconnect(),this.currentSessionId=null}isConnected(){return this.transport.isConnected()}async startSession(s){const a="currentSessionId"in this.transport?this.transport.currentSessionId:void 0;if(a){const c=new Date().toISOString(),m=this.transport.getAgentInfo?.()?.name,u={id:a,status:"connected",config:s?{...s,agentPath:s.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:c,agentName:m}};return this.sessions.set(a,u),this.currentSessionId=a,a}const n=this.generateSessionId(),o=new Date().toISOString(),r=this.transport.getAgentInfo?.()?.name,i={id:n,status:"connecting",config:s?{...s,agentPath:s.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:o,agentName:r}};return this.sessions.set(n,i),this.currentSessionId=n,this.updateSessionStatus(n,"connected"),n}async loadSession(s,a){if(!this.transport.loadSession)throw new Error("Transport does not support loading sessions");const n=new Date().toISOString(),o={id:s,status:"connecting",config:a?{...a,agentPath:a.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:n}};if(this.sessions.set(s,o),this.currentSessionId=s,await this.transport.loadSession(s),this.transport.getAgentInfo){const r=this.transport.getAgentInfo();r.name&&o.metadata&&(o.metadata.agentName=r.name)}return this.updateSessionStatus(s,"connected"),s}async listSessions(){return this.transport.listSessions?this.transport.listSessions():[]}async sendMessage(s,a,n,o){const r=a||this.currentSessionId;if(!r)throw new Error("No active session. Start a session first.");if(!this.transport.isConnected())throw new Error("Transport not connected");const i=this.sessions.get(r);if(!i)throw new Error(`Session ${r} not found`);const c=[];if(n&&n.length>0)for(const u of n)u.mimeType.startsWith("image/")&&c.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.data}});c.push({type:"text",text:s});const m={id:this.generateMessageId(),role:"user",content:c,timestamp:new Date().toISOString()};i.messages.push(m),this.updateSessionStatus(r,"active"),await this.transport.send(m,o?{promptParameters:o}:void 0)}async*receiveMessages(){if(!this.transport.isConnected())throw new Error("Transport not connected");yield*this.transport.receive()}async cancel(s){const a=s||this.currentSessionId;if(!a){Ie.warn("Cannot cancel: no session ID");return}Ie.info("Cancelling session",{sessionId:a}),await this.transport.cancel(a)}async editAndResend(s,a,n,o){const r=n||this.currentSessionId;if(!r)throw new Error("No active session. Start a session first.");if(!this.transport.isConnected())throw new Error("Transport not connected");if(!this.transport.editAndResend)throw new Error("Transport does not support edit and resend");const i=[];if(o&&o.length>0)for(const c of o)c.mimeType.startsWith("image/")&&i.push({type:"image",data:c.data,mimeType:c.mimeType});i.push({type:"text",text:a}),Ie.info("Edit and resend",{sessionId:r,messageIndex:s}),await this.transport.editAndResend(r,s,i)}getSession(s){return this.sessions.get(s)}getCurrentSession(){return this.currentSessionId?this.sessions.get(this.currentSessionId):void 0}getAllSessions(){return Array.from(this.sessions.values())}onSessionUpdate(s){return this.sessionUpdateHandlers.add(s),()=>{this.sessionUpdateHandlers.delete(s)}}onError(s){return this.errorHandlers.add(s),()=>{this.errorHandlers.delete(s)}}getAgentInfo(){return this.transport.getAgentInfo?.()||{}}createTransport(){switch(this.config.type){case"stdio":return new no(this.config.options);case"http":return new so(this.config.options);case"websocket":return new ao(this.config.options);default:throw new Error(`Unknown transport type: ${this.config.type}`)}}setupTransportListeners(){this.transport.onSessionUpdate(s=>{this.handleSessionUpdate(s)}),this.transport.onError(s=>{this.handleError(s)})}handleSessionUpdate(s){if(s.sessionId){const a=this.sessions.get(s.sessionId);a&&(s.status&&(a.status=s.status),s.message&&a.messages.push(s.message),s.error&&(a.error=s.error))}for(const a of this.sessionUpdateHandlers)try{a(s)}catch(n){Ie.error("Error in session update handler",{error:n instanceof Error?n.message:String(n)})}}handleError(s){for(const a of this.errorHandlers)try{a(s)}catch(n){Ie.error("Error in error handler",{error:n instanceof Error?n.message:String(n)})}}updateSessionStatus(s,a){const n=this.sessions.get(s);n&&(n.status=a,this.handleSessionUpdate({sessionId:s,status:a}))}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}generateMessageId(){return`msg_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}const _e=fe("acp-client-hook");function ro(t){const[s,a]=l.useState(null),[n,o]=l.useState(null),[r,i]=l.useState(null);return l.useEffect(()=>{const m=new URLSearchParams(window.location.search).get("session");m&&(_e.info("Session ID found in URL",{sessionId:m}),i(m));try{_e.info("Initializing ACP client",{serverUrl:t.serverUrl});const u=new oo({type:"http",options:{baseUrl:t.serverUrl}});return a(u),_e.info("ACP client initialized successfully"),()=>{_e.debug("Disconnecting ACP client"),u.disconnect().catch(d=>{_e.error("Failed to disconnect ACP client",{error:d instanceof Error?d.message:String(d)})})}}catch(u){const d=u instanceof Error?u.message:"Failed to initialize ACP client";o(d),_e.error("Failed to initialize ACP client",{error:u instanceof Error?u.message:String(u),stack:u instanceof Error?u.stack:void 0});return}},[t.serverUrl]),{client:s,error:n,sessionId:r}}const _t=se(["pending","in_progress","completed","failed"]),io=se(["read","edit","delete","move","search","execute","think","fetch","switch_mode","other"]),zs=B({path:v(),line:H().nullable().optional()}),Rt=B({inputTokens:H().optional(),outputTokens:H().optional(),totalTokens:H().optional()}),Mt=We("type",[B({type:Y("content"),content:B({type:Y("text"),text:v()})}),B({type:Y("text"),text:v()}),B({type:Y("image"),data:v(),mimeType:v().optional(),alt:v().optional()}),B({type:Y("image"),url:v(),alt:v().optional()}),B({type:Y("diff"),path:v(),oldText:v(),newText:v(),line:H().nullable().optional()}),B({type:Y("terminal"),terminalId:v()})]),Ls=B({id:v(),title:v(),prettyName:v().optional(),icon:v().optional(),status:_t,content:X(Mt).optional()}),lo=We("type",[B({type:Y("text"),text:v()}),B({type:Y("tool_call"),toolCall:Ls})]),$s=B({id:v(),content:v(),toolCalls:X(Ls).optional(),contentBlocks:X(lo).optional(),isStreaming:ke().optional()}),Os=B({id:v(),batchId:v().optional(),title:v(),prettyName:v().optional(),icon:v().optional(),verbiage:B({active:v(),past:v(),paramKey:v().optional()}).optional(),subline:v().optional(),kind:io,status:_t,contentPosition:H().optional(),locations:X(zs).optional(),rawInput:ee(v(),oe()).optional(),rawOutput:ee(v(),oe()).optional(),content:X(Mt).optional(),error:v().optional(),startedAt:H().optional(),completedAt:H().optional(),tokenUsage:Rt.optional(),_meta:B({truncationWarning:v().optional(),compactionAction:se(["compacted","truncated"]).optional(),originalTokens:H().optional(),finalTokens:H().optional(),originalContentPreview:v().optional(),originalContentPath:v().optional()}).optional(),subagentPort:H().optional(),subagentSessionId:v().optional(),subagentMessages:X($s).optional(),subagentStreaming:ke().optional()}),co=B({id:v(),status:_t.optional(),title:v().optional(),prettyName:v().optional(),icon:v().optional(),batchId:v().optional(),rawInput:ee(v(),oe()).optional(),locations:X(zs).optional(),rawOutput:ee(v(),oe()).optional(),content:X(Mt).optional(),error:v().optional(),completedAt:H().optional(),tokenUsage:Rt.optional(),subagentPort:H().optional(),subagentSessionId:v().optional(),subagentMessages:X($s).optional(),_meta:B({truncationWarning:v().optional(),compactionAction:se(["compacted","truncated"]).optional(),originalTokens:H().optional(),finalTokens:H().optional(),originalContentPreview:v().optional(),originalContentPath:v().optional()}).optional()});function Gt(t,s){return{...t,status:s.status??t.status,title:s.title??t.title,prettyName:s.prettyName??t.prettyName,icon:s.icon??t.icon,batchId:s.batchId??t.batchId,rawInput:s.rawInput??t.rawInput,locations:s.locations??t.locations,rawOutput:s.rawOutput??t.rawOutput,content:s.content?[...t.content??[],...s.content]:t.content,error:s.error??t.error,completedAt:s.completedAt??t.completedAt,tokenUsage:s.tokenUsage??t.tokenUsage,subagentPort:s.subagentPort??t.subagentPort,subagentSessionId:s.subagentSessionId??t.subagentSessionId,subagentMessages:s.subagentMessages??t.subagentMessages,_meta:s._meta??t._meta}}const ne=fe("chat-store","debug"),Ze=[];function bt(t){const s={id:`hook_${Date.now()}_${t.hookType}_${t.callback}`,hookType:t.hookType,callback:t.callback,...t.toolCallId?{toolCallId:t.toolCallId}:{}};switch(t.type){case"hook_triggered":return{...s,status:"triggered",threshold:t.threshold,currentPercentage:t.currentPercentage,triggeredAt:t.triggeredAt??Date.now()};case"hook_completed":return{...s,status:"completed",metadata:t.metadata,completedAt:t.completedAt??Date.now()};case"hook_error":return{...s,status:"error",error:t.error,completedAt:t.completedAt??Date.now()}}}let Je={sessionId:null,toolCallId:null,todos:Ze};const uo=t=>{const s=t.sessionId;if(!s)return Ze;const n=(t.toolCalls[s]||[]).filter(i=>i.title==="todo_write").sort((i,c)=>(c.startedAt||0)-(i.startedAt||0));if(n.length===0)return Ze;const o=n[0];if(!o?.rawInput?.todos||!Array.isArray(o.rawInput.todos))return Ze;if(Je.sessionId===s&&Je.toolCallId===o.id)return Je.todos;const r=o.rawInput.todos.map((i,c)=>({id:`${o.id}-${c}`,text:i.status==="in_progress"?i.activeForm:i.content,status:i.status}));return Je={sessionId:s,toolCallId:o.id,todos:r},r},F=ea(t=>({connectionStatus:"disconnected",sessionId:null,error:null,messages:[],isStreaming:!1,streamingStartTime:null,toolCalls:{},totalBilled:{inputTokens:0,outputTokens:0,totalTokens:0},currentContext:{inputTokens:0,outputTokens:0,totalTokens:0},latestContextSize:null,currentModel:"claude-sonnet-4-5-20250929",tokenDisplayMode:"context",logs:[],activeTab:"chat",input:{value:"",isSubmitting:!1,attachedFiles:[]},setConnectionStatus:s=>t({connectionStatus:s}),setSessionId:s=>t({sessionId:s}),setError:s=>t({error:s}),addMessage:s=>t(a=>({messages:[...a.messages,s]})),updateMessage:(s,a)=>t(n=>{const o=n.messages.find(u=>u.id===s);let r=n.totalBilled,i=n.currentContext,c=a;if(a.tokenUsage){const u=o?.tokenUsage;ne.debug("updateMessage: incoming tokenUsage",{incoming:a.tokenUsage,existing:u});const d={inputTokens:Math.max(a.tokenUsage.inputTokens??0,u?.inputTokens??0),outputTokens:Math.max(a.tokenUsage.outputTokens??0,u?.outputTokens??0),totalTokens:Math.max(a.tokenUsage.inputTokens??0,u?.inputTokens??0)+Math.max(a.tokenUsage.outputTokens??0,u?.outputTokens??0)};ne.debug("updateMessage: merged tokenUsage",{merged:d}),c={...a,tokenUsage:d};const g=d.inputTokens-(u?.inputTokens??0),f=d.outputTokens-(u?.outputTokens??0),x=d.totalTokens-(u?.totalTokens??0);r={inputTokens:n.totalBilled.inputTokens+g,outputTokens:n.totalBilled.outputTokens+f,totalTokens:n.totalBilled.totalTokens+x},i={inputTokens:d.inputTokens,outputTokens:n.currentContext.outputTokens+f,totalTokens:d.totalTokens}}const m=n.messages.map(u=>u.id===s?{...u,...c}:u);if(a.tokenUsage&&c.tokenUsage){const u=o?.tokenUsage,d=c.tokenUsage,g=(d.inputTokens??0)-(u?.inputTokens??0),f=(d.outputTokens??0)-(u?.outputTokens??0),x=(d.totalTokens??0)-(u?.totalTokens??0),h=m.filter(S=>S.tokenUsage).map(S=>({id:S.id,role:S.role,tokens:S.tokenUsage})),p=m.reduce((S,w)=>({inputTokens:S.inputTokens+(w.tokenUsage?.inputTokens??0),outputTokens:S.outputTokens+(w.tokenUsage?.outputTokens??0),totalTokens:S.totalTokens+(w.tokenUsage?.totalTokens??0)}),{inputTokens:0,outputTokens:0,totalTokens:0}),N=p.inputTokens===r.inputTokens&&p.outputTokens===r.outputTokens&&p.totalTokens===r.totalTokens;ne.debug("updateMessage: tokenUsage update",{messageId:s,updates:a.tokenUsage,existing:u,messageMax:d,delta:{inputDelta:g,outputDelta:f,totalDelta:x},totalBilled:r,currentContext:i,actualSum:p,billedCorrect:N?"✅":"❌",messageCount:m.length,messagesWithTokens:h.length,breakdown:h})}return{messages:m,totalBilled:r,currentContext:i}}),clearMessages:()=>t({messages:[]}),setIsStreaming:s=>t({isStreaming:s}),setStreamingStartTime:s=>t({streamingStartTime:s}),addToolCall:(s,a)=>t(n=>({toolCalls:{...n.toolCalls,[s]:[...n.toolCalls[s]||[],a]}})),addToolCallToCurrentMessage:s=>t(a=>{const n=a.messages.findLastIndex(m=>m.role==="assistant");if(n===-1){ne.debug("No assistant message found, creating one for tool call at position 0");const m={id:`msg_${Date.now()}_assistant`,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,toolCalls:[{...s,contentPosition:0}]};return{messages:[...a.messages,m]}}const o=[...a.messages],r=o[n];if(!r)return a;const i=r.content.length,c={...s,contentPosition:i};return o[n]={...r,toolCalls:[...r.toolCalls||[],c]},{messages:o}}),updateToolCallInCurrentMessage:s=>t(a=>{const n=a.messages.findLastIndex(d=>d.role==="assistant");if(n===-1)return ne.warn("No assistant message found to update tool call in"),a;const o=[...a.messages],r=o[n];if(!r)return a;const i=r.toolCalls||[],c=i.findIndex(d=>d.id===s.id);if(c===-1)return ne.warn(`Tool call ${s.id} not found in message`),a;const m=i[c];if(!m)return a;const u=[...i];return u[c]=Gt(m,s),o[n]={...r,toolCalls:u},{messages:o}}),addHookNotificationToCurrentMessage:s=>t(a=>{const n=a.messages.findLastIndex(d=>d.role==="assistant");if(n===-1){ne.debug("No assistant message found, creating one for hook notification");const d={...bt(s),contentPosition:0},g={id:`msg_${Date.now()}_assistant`,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,hookNotifications:[d]};return{messages:[...a.messages,g]}}const o=[...a.messages],r=o[n];if(!r)return a;const i=r.hookNotifications||[],c=r.content.length;if(s.type==="hook_triggered"){ne.debug("Adding hook_triggered notification for loading state",{hookType:s.hookType,callback:s.callback,contentPosition:c});const d={...bt(s),contentPosition:c},g=[...i,d];return o[n]={...r,hookNotifications:g},{messages:o}}let m;const u=i.findIndex(d=>d.hookType===s.hookType&&d.callback===s.callback&&d.status==="triggered");if(u!==-1){const d=i[u];m=[...i];const g=s.type==="hook_completed"||s.type==="hook_error"?s.completedAt??Date.now():Date.now();m[u]={...d,status:s.type==="hook_completed"?"completed":"error",completedAt:g,...s.type==="hook_completed"&&s.metadata?{metadata:s.metadata}:{},...s.type==="hook_error"?{error:s.error}:{}},ne.debug("Merged hook notification with triggered state",{hookType:s.hookType,status:m[u]?.status})}else{const d={...bt(s),contentPosition:c};m=[...i,d],ne.debug("Added hook notification without prior triggered state",{hookType:s.hookType,callback:s.callback,contentPosition:c})}return o[n]={...r,hookNotifications:m},{messages:o}}),addSourcesToCurrentMessage:s=>t(a=>{const n=a.messages.findLastIndex(i=>i.role==="assistant");if(n===-1){ne.debug("No assistant message found, creating one for sources");const i={id:`msg_${Date.now()}_assistant`,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,sources:s};return{messages:[...a.messages,i]}}const o=[...a.messages],r=o[n];return r?(o[n]={...r,sources:[...r.sources||[],...s]},ne.debug("Added sources to current message",{sourcesCount:s.length,totalSources:(r.sources?.length||0)+s.length}),{messages:o}):a}),updateToolCall:(s,a)=>t(n=>{const o=n.toolCalls[s]||[],r=o.findIndex(m=>m.id===a.id);if(r===-1)return n;const i=o[r];if(!i)return n;const c=[...o];return c[r]=Gt(i,a),{toolCalls:{...n.toolCalls,[s]:c}}}),setInputValue:s=>t(a=>({input:{...a.input,value:s}})),setInputSubmitting:s=>t(a=>({input:{...a.input,isSubmitting:s}})),addFileAttachment:s=>t(a=>({input:{...a.input,attachedFiles:[...a.input.attachedFiles,s]}})),removeFileAttachment:s=>t(a=>({input:{...a.input,attachedFiles:a.input.attachedFiles.filter((n,o)=>o!==s)}})),setSelectedPromptParameters:s=>t(a=>({input:{...a.input,selectedPromptParameters:s}})),clearInput:()=>t(s=>({input:{value:"",isSubmitting:!1,attachedFiles:[],selectedPromptParameters:void 0}})),addTokenUsage:s=>t(a=>({totalBilled:{inputTokens:a.totalBilled.inputTokens+(s.inputTokens??0),outputTokens:a.totalBilled.outputTokens+(s.outputTokens??0),totalTokens:a.totalBilled.totalTokens+(s.totalTokens??0)},currentContext:{inputTokens:s.inputTokens??a.currentContext.inputTokens,outputTokens:a.currentContext.outputTokens+(s.outputTokens??0),totalTokens:(s.inputTokens??a.currentContext.inputTokens)+(a.currentContext.outputTokens+(s.outputTokens??0))}})),setLatestContextSize:s=>t({latestContextSize:s}),setCurrentModel:s=>t({currentModel:s}),resetTokens:()=>t({totalBilled:{inputTokens:0,outputTokens:0,totalTokens:0},currentContext:{inputTokens:0,outputTokens:0,totalTokens:0},latestContextSize:null}),cycleTokenDisplayMode:()=>t(s=>{const a=["context","input","output"],o=(a.indexOf(s.tokenDisplayMode)+1)%a.length,r=a[o];return r?{tokenDisplayMode:r}:s}),addLog:s=>t(a=>({logs:[...a.logs,s]})),clearLogs:()=>t({logs:[]}),setActiveTab:s=>t({activeTab:s}),truncateMessagesFrom:s=>t(a=>({messages:a.messages.slice(0,s),totalBilled:{inputTokens:0,outputTokens:0,totalTokens:0},currentContext:{inputTokens:0,outputTokens:0,totalTokens:0},latestContextSize:null}))})),Q=fe("use-chat-messages","debug");function Fs(t,s){const a=F(C=>C.messages),n=F(C=>C.isStreaming),o=F(C=>C.sessionId),r=F(C=>C.setIsStreaming),i=F(C=>C.setStreamingStartTime),c=F(C=>C.addMessage),m=F(C=>C.updateMessage),u=F(C=>C.setError),d=F(C=>C.setLatestContextSize),g=F(C=>C.addToolCall),f=F(C=>C.updateToolCall),x=F(C=>C.addToolCallToCurrentMessage),h=F(C=>C.updateToolCallInCurrentMessage),p=F(C=>C.addHookNotificationToCurrentMessage),N=F(C=>C.addSourcesToCurrentMessage),S=F(C=>C.truncateMessagesFrom),w=l.useRef(null),k=l.useRef(!1),E=l.useCallback(async(C,A,O)=>{if(Q.debug("[sendMessage] Called with",{contentLength:C.length,attachmentsCount:A?.length||0,hasAttachments:!!A&&A.length>0,hasPromptParameters:!!O,promptParameters:O}),!t){Q.error("No client available"),u("No client available");return}let q=o;if(!q){Q.info("Creating new session before sending first message");const K=await s();if(!K){Q.error("Failed to create session"),u("Failed to create session");return}q=K,Q.info("Session created successfully",{sessionId:K})}const W=`msg_${Date.now()}_assistant`;try{const K=Date.now();r(!0),i(K);const D={id:`msg_${Date.now()}_user`,role:"user",content:C,timestamp:new Date().toISOString(),isStreaming:!1,...A&&A.length>0?{images:A.filter(y=>y.mimeType.startsWith("image/")).map(y=>({mimeType:y.mimeType,data:y.data}))}:{}};c(D);const U={id:W,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!0,streamingStartTime:K};c(U),w.current=W,k.current=!1;const T=t.receiveMessages();t.sendMessage(C,q,A,O).catch(y=>{const R=y instanceof Error?y.message:String(y);u(R),r(!1),i(null)});let M="",j=!1;for await(const y of T){if(k.current){Q.info("Stream cancelled, exiting loop");break}if(y.type==="content"){const R=y._meta,_=R?.context_size||y.context_size;if(_!=null){const z=_;Q.info("✅ Received context_size from backend",{context_size:z,totalEstimated:z.totalEstimated,source:R?.context_size?"_meta":"direct"}),d(z)}else Q.debug("Chunk does not have context_size",{hasContextSize:"context_size"in y,hasMeta:"_meta"in y,metaKeys:R?Object.keys(R):null});if(y.tokenUsage&&Q.debug("Received tokenUsage from backend",{tokenUsage:y.tokenUsage}),y.isComplete){m(W,{content:M,isStreaming:!1,streamingStartTime:void 0,...y.tokenUsage?{tokenUsage:y.tokenUsage}:{}}),r(!1),i(null),w.current=null,j=!0;break}else y.contentDelta.type==="text"&&(M+=y.contentDelta.text,m(W,{content:M,...y.tokenUsage?{tokenUsage:y.tokenUsage}:{}}),document.hidden||await new Promise(z=>setTimeout(z,16)))}else y.type==="tool_call"?(Q.debug("Received tool_call chunk",{chunk:y}),g(q,y.toolCall),x(y.toolCall)):y.type==="tool_call_update"?(Q.debug("Received tool_call_update chunk",{chunk:y}),f(q,y.toolCallUpdate),h(y.toolCallUpdate)):y.type==="hook_notification"?(Q.debug("Received hook_notification chunk",{chunk:y}),p(y.notification)):y.type==="sources"&&(Q.debug("Received sources chunk",{chunk:y}),N(y.sources))}j||(k.current?(Q.info("Stream cancelled by user"),m(W,{content:`${M}
|