@townco/gui-template 0.1.120 → 0.1.121

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.
@@ -1,4 +1,4 @@
1
- import{r as l,j as e,M as va,c as et,h as wa}from"./react-DiSrVJhY.js";import{bb as $e,bc as ja,bd as rs,be as le,bf as q,bg as w,bh as ee,bi as F,bj as ae,bk as ue,bl as it,bm as vt,bn as te,bo as Ce,bp as Ht,bq as Na,br as Ca,bs as Sa,bt as ka,bu as Te,bv as Ta,bw as pe,am as Ia,bx as Ra,by as is}from"./vendor-Dm9xAZV8.js";import{P as ls,a as _a}from"./acp-sdk-D4VsTV6L.js";import{S as ve,P as Ma,C as Ms,a as Ea,R as Aa,T as Pa,b as Es,c as As,d as Da,e as Ps,I as Ds,f as Us,g as zs,h as $s,L as Ls,i as Os,j as Ua,k as za,l as Fs,m as Bs,n as Hs,o as $a,O as Nt,p as Ws,q as Ct,r as Vs,s as St,D as kt,t as qs,u as Ks,v as La,w as Ys,x as Qs,y as Oa,z as Gs,V as Fa,A as Xs,B as Js,E as Ba,F as Ha,G as Zs}from"./radix-BaZ_UeJz.js";import{c as tt,d as lt,e as Tt,P as Wa,E as Va,S as en,f as tn,g as qa,h as Wt,i as Ka,j as Ya,k as Qa,l as Ga,m as ge,A as Xa,n as It,F as Ja,o as Za,p as eo,q as to,r as We,s as Rt,t as _t,G as sn,u as nn,v as an,B as cs,w as so,x as no,y as ao,z as Vt,H as oo,I as qt,J as wt,T as ro,K as de,N as io,O as on,Q as ds,U as lo,V as us,W as at,Y as Kt,_ as co,$ as uo,a0 as mo,a1 as po,a2 as fo,a3 as go,a4 as ho,a5 as xo,a6 as bo,a7 as yo,a8 as vo}from"./icons-B0Ax5AoZ.js";import{A as ot,m as ke}from"./framer-motion-DEDjTHcO.js";import{g as rn}from"./markdown-jcH7_RT5.js";import"./katex-C5cjGaLm.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();var wo={};const ht=typeof process<"u"&&process.versions?.node;let jo,No=0;const $t=new Set;function Co(t){return $t.add(t),()=>$t.delete(t)}function So(t){for(const s of $t)s(t)}const ms={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},ko={trace:$e.TRACE,debug:$e.DEBUG,info:$e.INFO,warn:$e.WARN,error:$e.ERROR,fatal:$e.FATAL};class To{service;minLevel;logsDir;enableConsoleOutput;constructor(s,n="debug"){this.service=s,this.minLevel=n,typeof process<"u"&&(this.minLevel="info"),this.enableConsoleOutput=typeof process<"u"&&wo?.TOWN_LOG_CONSOLE==="true"||!1}setupFileLogging(){}async writeToFile(s){this.logsDir}shouldLog(s){return ms[s]>=ms[this.minLevel]}log(s,n,o){if(!this.shouldLog(s))return;const r={id:`log_${++No}`,timestamp:new Date().toISOString(),level:s,service:this.service,message:n,...o&&{metadata:o}};if(So(r),ht&&this.logsDir,ht&&this.logsDir){const c={timestamp:r.timestamp,level:r.level,service:r.service,message:r.message,...r.metadata&&{metadata:r.metadata}};this.writeToFile(JSON.stringify(c)).catch(()=>{})}if(ht&&this.enableConsoleOutput){const c=r.timestamp,u=r.level.toUpperCase().padEnd(5),d=`[${this.service}]`,m=r.metadata?` ${JSON.stringify(r.metadata)}`:"";console.log(`${c} ${u} ${d} ${r.message}${m}`)}const i=ja.getLogger(this.service),a=rs.trace.getSpan(rs.context.active());i.emit({severityNumber:ko[s],severityText:s.toUpperCase(),body:n,attributes:{service:this.service,...o&&Object.fromEntries(Object.entries(o).map(([c,u])=>[`log.${c}`,typeof u=="object"?JSON.stringify(u):u])),...a&&{trace_id:a.spanContext().traceId,span_id:a.spanContext().spanId}}})}trace(s,n){this.log("trace",s,n)}debug(s,n){this.log("debug",s,n)}info(s,n){this.log("info",s,n)}warn(s,n){this.log("warn",s,n)}error(s,n){this.log("error",s,n)}fatal(s,n){this.log("fatal",s,n)}}function me(t,s="debug"){return new To(t,s)}const ln=le(["user","assistant","system","tool"]),Io=le(["text","image","file","tool_call","tool_result"]),ct=q({type:Io}),Ro=ct.extend({type:ee("text"),text:w()}),_o=ct.extend({type:ee("image"),url:w().url().optional(),source:q({type:ee("base64"),media_type:le(["image/jpeg","image/png","image/gif","image/webp"]),data:w()}).optional()}),Mo=ct.extend({type:ee("file"),name:w(),path:w().optional(),url:w().url().optional(),mimeType:w(),size:F().optional()}),Eo=ct.extend({type:ee("tool_call"),id:w(),name:w(),arguments:ae(w(),ue())}),Ao=ct.extend({type:ee("tool_result"),callId:w(),result:ue(),error:w().optional()}),cn=it("type",[Ro,_o,Mo,Eo,Ao]),dn=q({id:w(),role:ln,content:te(cn),timestamp:vt(),metadata:ae(w(),ue()).optional()}),Po=q({type:ee("content"),id:w(),role:ln,contentDelta:cn,isComplete:Ce(),tokenUsage:q({inputTokens:F().optional(),outputTokens:F().optional(),totalTokens:F().optional()}).optional(),contextInputTokens:F().optional(),_meta:q({context_size:q({systemPromptTokens:F(),userMessagesTokens:F(),assistantMessagesTokens:F(),toolInputTokens:F(),toolResultsTokens:F(),totalEstimated:F(),llmReportedInputTokens:F().optional()}).optional()}).optional()}),Do=q({type:ee("tool_call"),id:w(),toolCall:Ht(),messageId:w().optional()}),Uo=q({type:ee("tool_call_update"),id:w(),toolCallUpdate:Ht(),messageId:w().optional()}),Mt=le(["context_size","tool_response"]),zo=q({type:ee("hook_triggered"),hookType:Mt,threshold:F(),currentPercentage:F(),callback:w(),triggeredAt:F().optional(),toolCallId:w().optional()}),$o=q({type:ee("hook_completed"),hookType:Mt,callback:w(),metadata:q({action:w().optional(),messagesRemoved:F().optional(),tokensSaved:F().optional()}).passthrough().optional(),completedAt:F().optional(),toolCallId:w().optional()}),Lo=q({type:ee("hook_error"),hookType:Mt,callback:w(),error:w(),completedAt:F().optional(),toolCallId:w().optional()}),Oo=it("type",[zo,$o,Lo]),Fo=q({type:ee("hook_notification"),id:w(),notification:Oo,messageId:w().optional()}),un=q({id:w(),url:w().url(),title:w(),snippet:w().optional(),favicon:w().optional(),toolCallId:w(),sourceName:w().optional()}),Bo=q({type:ee("sources"),sources:te(un)});it("type",[Po,Do,Uo,Fo,Bo]);const Ho=q({id:w(),url:w().url(),title:w(),snippet:w().optional(),favicon:w().optional(),toolCallId:w(),sourceName:w().optional()}),ps=q({systemPromptTokens:F(),toolOverheadTokens:F().optional(),mcpOverheadTokens:F().optional(),userMessagesTokens:F(),assistantMessagesTokens:F(),toolInputTokens:F(),toolResultsTokens:F(),totalEstimated:F(),llmReportedInputTokens:F().optional(),modelContextWindow:F().optional()}),Yt=le(["pending","in_progress","completed","failed"]),Wo=le(["read","edit","delete","move","search","execute","think","fetch","switch_mode","other"]),mn=q({path:w(),line:F().nullable().optional()}),Qt=q({inputTokens:F().optional(),outputTokens:F().optional(),totalTokens:F().optional()}),Gt=it("type",[q({type:ee("content"),content:q({type:ee("text"),text:w()})}),q({type:ee("text"),text:w()}),q({type:ee("image"),data:w(),mimeType:w().optional(),alt:w().optional()}),q({type:ee("image"),url:w(),alt:w().optional()}),q({type:ee("diff"),path:w(),oldText:w(),newText:w(),line:F().nullable().optional()}),q({type:ee("terminal"),terminalId:w()})]),pn=q({id:w(),title:w(),prettyName:w().optional(),icon:w().optional(),status:Yt,content:te(Gt).optional()}),Vo=it("type",[q({type:ee("text"),text:w()}),q({type:ee("tool_call"),toolCall:pn})]),fn=q({id:w(),content:w(),toolCalls:te(pn).optional(),contentBlocks:te(Vo).optional(),isStreaming:Ce().optional(),context_size:ps.optional(),_meta:q({semanticName:w().optional(),agentDefinitionName:w().optional(),currentActivity:w().optional(),statusGenerating:Ce().optional(),context_size:ps.optional()}).passthrough().optional()}),gn=q({id:w(),batchId:w().optional(),title:w(),prettyName:w().optional(),icon:w().optional(),verbiage:q({active:w(),past:w(),paramKey:w().optional()}).optional(),subline:w().optional(),kind:Wo,status:Yt,contentPosition:F().optional(),locations:te(mn).optional(),rawInput:ae(w(),ue()).optional(),rawOutput:ae(w(),ue()).optional(),content:te(Gt).optional(),error:w().optional(),startedAt:F().optional(),completedAt:F().optional(),tokenUsage:Qt.optional(),_meta:q({truncationWarning:w().optional(),compactionAction:le(["compacted","truncated"]).optional(),originalTokens:F().optional(),finalTokens:F().optional(),originalContentPreview:w().optional(),originalContentPath:w().optional()}).optional(),subagentPort:F().optional(),subagentSessionId:w().optional(),subagentMessages:te(fn).optional(),subagentStreaming:Ce().optional(),subagentCompleted:Ce().optional()}),qo=q({id:w(),status:Yt.optional(),title:w().optional(),prettyName:w().optional(),icon:w().optional(),batchId:w().optional(),rawInput:ae(w(),ue()).optional(),locations:te(mn).optional(),rawOutput:ae(w(),ue()).optional(),content:te(Gt).optional(),error:w().optional(),completedAt:F().optional(),tokenUsage:Qt.optional(),subagentPort:F().optional(),subagentSessionId:w().optional(),subagentMessages:te(fn).optional(),subagentCompleted:Ce().optional(),_meta:q({truncationWarning:w().optional(),compactionAction:le(["compacted","truncated"]).optional(),originalTokens:F().optional(),finalTokens:F().optional(),originalContentPreview:w().optional(),originalContentPath:w().optional()}).optional()});function fs(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,subagentCompleted:s.subagentCompleted??t.subagentCompleted,_meta:s._meta??t._meta}}const Ko=q({mimeType:w(),data:w()}),Yo=q({id:w(),hookType:Mt,callback:w(),status:le(["triggered","completed","error"]),threshold:F().optional(),currentPercentage:F().optional(),metadata:q({action:w().optional(),messagesRemoved:F().optional(),tokensSaved:F().optional(),tokensBeforeCompaction:F().optional(),summaryTokens:F().optional(),originalTokens:F().optional(),finalTokens:F().optional(),truncationWarning:w().optional()}).passthrough().optional(),error:w().optional(),triggeredAt:F().optional(),completedAt:F().optional(),contentPosition:F().optional(),toolCallId:w().optional()}),Qo=q({id:w(),role:le(["user","assistant","system"]),content:w(),timestamp:vt(),isStreaming:Ce().default(!1),streamingStartTime:F().optional(),metadata:ae(w(),ue()).optional(),toolCalls:te(gn).optional(),hookNotifications:te(Yo).optional(),tokenUsage:Qt.optional(),images:te(Ko).optional(),sources:te(Ho).optional()}),Go=q({value:w(),isSubmitting:Ce(),attachedFiles:te(q({name:w(),path:w(),size:F(),mimeType:w(),data:w()})),selectedPromptParameters:ae(w(),w()).optional()});q({sessionId:w().nullable(),isConnected:Ce(),isStreaming:Ce(),messages:te(Qo),input:Go,error:w().nullable()});le(["disconnected","connecting","connected","error"]);let gs=0,hs=0;function je(t){const s=Date.now();s!==hs&&(gs=0,hs=s);const n=gs++,o=Math.random().toString(36).substring(2,7);return`msg_${s}_${n}_${o}_${t}`}const Xo=q({baseUrl:w().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:w().optional(),timeout:F().optional(),headers:ae(w(),w()).optional()}),L=me("http-transport");class Jo{connected=!1;sessionUpdateCallbacks=new Set;errorCallbacks=new Set;fileSystemChangeCallbacks=new Map;messageQueue=[];currentSessionId=null;chunkResolvers=[];streamComplete=!1;sseAbortController=null;reconnectAttempts=0;maxReconnectAttempts=5;reconnectDelay=1e3;reconnecting=!1;abortController=null;options;isReceivingMessages=!1;isInReplayMode=!1;pendingReplayUpdates=[];agentInfo;constructor(s){const n=Xo.safeParse(s);if(!n.success){const o=n.error.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join("; ");throw new Error(`Invalid HTTP transport configuration: ${o}`)}this.options={...s,baseUrl:s.baseUrl.replace(/\/$/,"")}}async connect(){if(!this.connected)try{this.abortController=new AbortController;const s={protocolVersion:ls,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}},n=await this.sendRpcRequest("initialize",s);if(n.agentInfo){const i=n._meta,a=i&&typeof i=="object",c=a&&"agentDescription"in i?String(i.agentDescription):void 0,u=a&&"suggestedPrompts"in i&&Array.isArray(i.suggestedPrompts)?i.suggestedPrompts:void 0,d=a&&"tools"in i&&Array.isArray(i.tools)?i.tools:void 0,m=a&&"mcps"in i&&Array.isArray(i.mcps)?i.mcps:void 0,p=a&&"subagents"in i&&Array.isArray(i.subagents)?i.subagents:void 0,g=a&&"initialMessage"in i&&i.initialMessage&&typeof i.initialMessage=="object"?i.initialMessage:void 0,x=a&&"uiConfig"in i&&i.uiConfig&&typeof i.uiConfig=="object"?i.uiConfig:void 0,h=a&&"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,...c?{description:c}:{},...u?{suggestedPrompts:u}:{},...g?{initialMessage:g}:{},...x?{uiConfig:x}:{},...d?{tools:d}:{},...m?{mcps:m}:{},...p?{subagents:p}:{},...h?{promptParameters:h}:{}}}L.info("ACP connection initialized",{initResponse:n});const o={cwd:"/",mcpServers:[]},r=await this.sendRpcRequest("session/new",o);this.currentSessionId=r.sessionId,L.info("Session created",{sessionId:this.currentSessionId}),await this.connectSSE(),this.connected=!0,this.reconnectAttempts=0}catch(s){this.connected=!1;const n=s instanceof Error?s:new Error(String(s));throw this.notifyError(n),n}}async loadSession(s){this.connected&&(L.warn("Transport already connected, disconnecting first",{sessionId:s}),await this.disconnect());try{this.abortController=new AbortController;const n={protocolVersion:ls,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}};L.info("Loading session - initializing connection",{sessionId:s});const o=await this.sendRpcRequest("initialize",n);if(o.agentInfo){const a=o._meta,c=a&&typeof a=="object",u=c&&"agentDescription"in a?String(a.agentDescription):void 0,d=c&&"suggestedPrompts"in a&&Array.isArray(a.suggestedPrompts)?a.suggestedPrompts:void 0,m=c&&"tools"in a&&Array.isArray(a.tools)?a.tools:void 0,p=c&&"mcps"in a&&Array.isArray(a.mcps)?a.mcps:void 0,g=c&&"subagents"in a&&Array.isArray(a.subagents)?a.subagents:void 0,x=c&&"initialMessage"in a&&a.initialMessage&&typeof a.initialMessage=="object"?a.initialMessage:void 0,h=c&&"uiConfig"in a&&a.uiConfig&&typeof a.uiConfig=="object"?a.uiConfig:void 0,f=c&&"promptParameters"in a&&Array.isArray(a.promptParameters)?a.promptParameters:void 0;this.agentInfo={name:o.agentInfo.name,...o.agentInfo.title?{displayName:o.agentInfo.title}:{},version:o.agentInfo.version,...u?{description:u}:{},...d?{suggestedPrompts:d}:{},...x?{initialMessage:x}:{},...h?{uiConfig:h}:{},...m?{tools:m}:{},...p?{mcps:p}:{},...g?{subagents:g}:{},...f?{promptParameters:f}:{}}}if(!o.agentCapabilities?.loadSession)throw L.error("Agent does not support loading sessions",{capabilities:o.agentCapabilities}),new Error("Agent does not support loading sessions");L.info("ACP connection initialized, loading session",{sessionId:s,capabilities:o.agentCapabilities}),this.isInReplayMode=!0,this.currentSessionId=s,await this.connectSSE();const r={sessionId:s,cwd:"/",mcpServers:[]};L.info("Sending session/load request",{loadRequest:r});const i=await this.sendRpcRequest("session/load",r);L.info("Session loaded successfully",{sessionId:this.currentSessionId,loadResponse:i}),this.connected=!0,this.reconnectAttempts=0}catch(n){this.connected=!1;const o=n instanceof Error?n:new Error(String(n));throw L.error("Failed to load session",{sessionId:s,error:o.message,stack:o.stack}),this.notifyError(o),o}}async listSessions(){try{const s={method:"GET"};this.options.headers&&(s.headers=this.options.headers);const n=await fetch(`${this.options.baseUrl}/sessions`,s);if(!n.ok)throw new Error(`HTTP ${n.status}: ${await n.text()}`);return(await n.json()).sessions||[]}catch(s){return L.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 n=s instanceof Error?s:new Error(String(s));throw this.notifyError(n),n}}async send(s,n){if(!this.connected||!this.currentSessionId)throw new Error("Transport not connected");this.isInReplayMode&&(L.info("Exiting replay mode - user sent a message"),this.isInReplayMode=!1);try{this.streamComplete=!1,this.messageQueue=[];const o=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),r={sessionId:this.currentSessionId,prompt:o};n?.promptParameters&&(r._meta={promptParameters:n.promptParameters});const i=await this.sendRpcRequest("session/prompt",r);L.debug("Prompt sent",{promptResponse:i}),this.streamComplete=!0;const a=this.chunkResolvers.shift();a?a({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(o){this.streamComplete=!0;const r=o instanceof Error?o:new Error(String(o));throw this.notifyError(r),r}}async cancel(s){if(!this.connected){L.warn("Cannot cancel: transport not connected");return}const n=s||this.currentSessionId;if(!n){L.warn("Cannot cancel: no session ID");return}L.info("Cancelling session",{sessionId:n}),this.streamComplete=!0,this.messageQueue.length=0,await this.sendNotification("session/cancel",{sessionId:n});const o={type:"content",id:n,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0};for(;this.chunkResolvers.length>0;){const r=this.chunkResolvers.shift();r&&r(o)}}async editAndResend(s,n,o){if(!this.connected)throw new Error("Transport not connected");const r=s||this.currentSessionId;if(!r)throw new Error("No session ID available");this.isInReplayMode&&(L.info("Exiting replay mode - user edited a message"),this.isInReplayMode=!1),this.streamComplete=!1,this.messageQueue=[],L.info("Edit and resend",{sessionId:r,messageIndex:n});const i={"Content-Type":"application/json",...this.options.headers},a=this.options.timeout??600*1e3,c=new AbortController,u=setTimeout(()=>c.abort(),a);try{const d=await fetch(`${this.options.baseUrl}/sessions/${r}/edit-and-resend`,{method:"POST",headers:i,body:JSON.stringify({messageIndex:n,prompt:o}),signal:c.signal});if(clearTimeout(u),!d.ok){const p=await d.text();throw new Error(`HTTP ${d.status}: ${p}`)}this.streamComplete=!0;const m=this.chunkResolvers.shift();m?m({type:"content",id:r,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0}):this.messageQueue.push({type:"content",id:r,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0})}catch(d){throw clearTimeout(u),this.streamComplete=!0,d instanceof Error&&d.name==="AbortError"?new Error(`Request timeout after ${a}ms`):d}}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(n=>{this.chunkResolvers.push(n)});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){if(this.sessionUpdateCallbacks.add(s),this.pendingReplayUpdates.length>0){L.info("Replaying queued session updates to ALL callbacks",{count:this.pendingReplayUpdates.length,callbackCount:this.sessionUpdateCallbacks.size,updateTypes:this.pendingReplayUpdates.map(o=>o.type),updateDetails:this.pendingReplayUpdates.map(o=>{if(o.type==="tool_call")return{type:"tool_call",toolCallId:o.toolCall?.id};if(o.type==="sources")return{type:"sources",count:o.sources?.length,ids:o.sources?.map(r=>r.id)};if(o.type==="generic"&&o.message){const r=o.message.content?.[0];return{type:"message",role:o.message.role,contentLength:r?.type==="text"?r.text?.length:0}}return{type:o.type}})});const n=[...this.pendingReplayUpdates];this.pendingReplayUpdates=[],setTimeout(()=>{L.info("Starting replay of queued updates to all callbacks",{updateCount:n.length,callbackCount:this.sessionUpdateCallbacks.size});for(const o of n)try{L.info("Replaying update to all callbacks",{type:o.type}),this.notifySessionUpdate(o)}catch(r){L.error("Error replaying session update",{error:r})}L.info("Finished replay of queued updates")},0)}return()=>{this.sessionUpdateCallbacks.delete(s)}}onError(s){return this.errorCallbacks.add(s),()=>{this.errorCallbacks.delete(s)}}onFileSystemChange(s,n){return L.debug("Registering file system change callback",{sessionId:s}),this.fileSystemChangeCallbacks.set(s,n),()=>{L.debug("Unregistering file system change callback",{sessionId:s}),this.fileSystemChangeCallbacks.delete(s)}}notifyFileSystemChange(s){const n=this.fileSystemChangeCallbacks.get(s.sessionId);L.debug("notifyFileSystemChange",{sessionId:s.sessionId,hasCallback:!!n,callbackCount:this.fileSystemChangeCallbacks.size}),n&&n(s)}getAgentInfo(){return this.agentInfo||{}}async sendNotification(s,n){const o={jsonrpc:"2.0",method:s,params:n};L.debug("Sending notification",{method:s,params:n});const r={"Content-Type":"application/json",...this.options.headers};try{const i=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:r,body:JSON.stringify(o)});if(!i.ok){const a=await i.text();L.error("Notification failed",{status:i.status,errorText:a})}}catch(i){L.error("Error sending notification",{error:i})}}async sendRpcRequest(s,n){const r={jsonrpc:"2.0",id:this.generateRequestId(),method:s,params:n};L.debug("Sending RPC request",{method:s,params:n,request:r});const i={"Content-Type":"application/json",...this.options.headers},a=this.options.timeout??600*1e3,c=new AbortController,u=setTimeout(()=>c.abort(),a);try{const d=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:i,body:JSON.stringify(r),signal:c.signal});if(clearTimeout(u),!d.ok){const p=await d.text();throw new Error(`HTTP ${d.status}: ${p}`)}const m=await d.json();if(m.error)throw new Error(`ACP error: ${m.error.message||JSON.stringify(m.error)}`);return m.result||m}catch(d){throw clearTimeout(u),d instanceof Error&&d.name==="AbortError"?new Error(`Request timeout after ${a}ms`):d}}async connectSSE(){if(!this.currentSessionId)throw new Error("Cannot connect SSE without a session ID");const s=`${this.options.baseUrl}/events`,n={"X-Session-ID":this.currentSessionId,...this.options.headers};this.sseAbortController=new AbortController;try{const o=await fetch(s,{method:"GET",headers:n,signal:this.sseAbortController.signal});if(!o.ok)throw new Error(`SSE connection failed: HTTP ${o.status}`);if(!o.body)throw new Error("Response body is null");L.debug("SSE connection opened"),this.reconnectAttempts=0,this.reconnectDelay=1e3;const r=o.body.getReader(),i=new TextDecoder;let a="";(async()=>{try{for(;;){const{done:c,value:u}=await r.read();if(c){L.debug("SSE stream closed by server"),this.connected&&await this.handleSSEDisconnect();break}a+=i.decode(u,{stream:!0});const d=a.split(`
1
+ import{r as l,j as e,M as va,c as et,h as wa}from"./react-BxR0bfXp.js";import{bb as $e,bc as ja,bd as rs,be as le,bf as q,bg as w,bh as ee,bi as F,bj as ae,bk as ue,bl as it,bm as vt,bn as te,bo as Ce,bp as Ht,bq as Na,br as Ca,bs as Sa,bt as ka,bu as Te,bv as Ta,bw as pe,am as Ia,bx as Ra,by as is}from"./vendor-B9CCG_zb.js";import{P as ls,a as _a}from"./acp-sdk-C2gyHhUs.js";import{S as ve,P as Ma,C as Ms,a as Ea,R as Aa,T as Pa,b as Es,c as As,d as Da,e as Ps,I as Ds,f as Us,g as zs,h as $s,L as Ls,i as Os,j as Ua,k as za,l as Fs,m as Bs,n as Hs,o as $a,O as Nt,p as Ws,q as Ct,r as Vs,s as St,D as kt,t as qs,u as Ks,v as La,w as Ys,x as Qs,y as Oa,z as Gs,V as Fa,A as Xs,B as Js,E as Ba,F as Ha,G as Zs}from"./radix-DV56ifF6.js";import{c as tt,d as lt,e as Tt,P as Wa,E as Va,S as en,f as tn,g as qa,h as Wt,i as Ka,j as Ya,k as Qa,l as Ga,m as ge,A as Xa,n as It,F as Ja,o as Za,p as eo,q as to,r as We,s as Rt,t as _t,G as sn,u as nn,v as an,B as cs,w as so,x as no,y as ao,z as Vt,H as oo,I as qt,J as wt,T as ro,K as de,N as io,O as on,Q as ds,U as lo,V as us,W as at,Y as Kt,_ as co,$ as uo,a0 as mo,a1 as po,a2 as fo,a3 as go,a4 as ho,a5 as xo,a6 as bo,a7 as yo,a8 as vo}from"./icons-C7QEqI8s.js";import{A as ot,m as ke}from"./framer-motion-DNsiqoUk.js";import{g as rn}from"./markdown-D50x6v1C.js";import"./katex-Dnem94XJ.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();var wo={};const ht=typeof process<"u"&&process.versions?.node;let jo,No=0;const $t=new Set;function Co(t){return $t.add(t),()=>$t.delete(t)}function So(t){for(const s of $t)s(t)}const ms={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},ko={trace:$e.TRACE,debug:$e.DEBUG,info:$e.INFO,warn:$e.WARN,error:$e.ERROR,fatal:$e.FATAL};class To{service;minLevel;logsDir;enableConsoleOutput;constructor(s,n="debug"){this.service=s,this.minLevel=n,typeof process<"u"&&(this.minLevel="info"),this.enableConsoleOutput=typeof process<"u"&&wo?.TOWN_LOG_CONSOLE==="true"||!1}setupFileLogging(){}async writeToFile(s){this.logsDir}shouldLog(s){return ms[s]>=ms[this.minLevel]}log(s,n,o){if(!this.shouldLog(s))return;const r={id:`log_${++No}`,timestamp:new Date().toISOString(),level:s,service:this.service,message:n,...o&&{metadata:o}};if(So(r),ht&&this.logsDir,ht&&this.logsDir){const c={timestamp:r.timestamp,level:r.level,service:r.service,message:r.message,...r.metadata&&{metadata:r.metadata}};this.writeToFile(JSON.stringify(c)).catch(()=>{})}if(ht&&this.enableConsoleOutput){const c=r.timestamp,u=r.level.toUpperCase().padEnd(5),d=`[${this.service}]`,m=r.metadata?` ${JSON.stringify(r.metadata)}`:"";console.log(`${c} ${u} ${d} ${r.message}${m}`)}const i=ja.getLogger(this.service),a=rs.trace.getSpan(rs.context.active());i.emit({severityNumber:ko[s],severityText:s.toUpperCase(),body:n,attributes:{service:this.service,...o&&Object.fromEntries(Object.entries(o).map(([c,u])=>[`log.${c}`,typeof u=="object"?JSON.stringify(u):u])),...a&&{trace_id:a.spanContext().traceId,span_id:a.spanContext().spanId}}})}trace(s,n){this.log("trace",s,n)}debug(s,n){this.log("debug",s,n)}info(s,n){this.log("info",s,n)}warn(s,n){this.log("warn",s,n)}error(s,n){this.log("error",s,n)}fatal(s,n){this.log("fatal",s,n)}}function me(t,s="debug"){return new To(t,s)}const ln=le(["user","assistant","system","tool"]),Io=le(["text","image","file","tool_call","tool_result"]),ct=q({type:Io}),Ro=ct.extend({type:ee("text"),text:w()}),_o=ct.extend({type:ee("image"),url:w().url().optional(),source:q({type:ee("base64"),media_type:le(["image/jpeg","image/png","image/gif","image/webp"]),data:w()}).optional()}),Mo=ct.extend({type:ee("file"),name:w(),path:w().optional(),url:w().url().optional(),mimeType:w(),size:F().optional()}),Eo=ct.extend({type:ee("tool_call"),id:w(),name:w(),arguments:ae(w(),ue())}),Ao=ct.extend({type:ee("tool_result"),callId:w(),result:ue(),error:w().optional()}),cn=it("type",[Ro,_o,Mo,Eo,Ao]),dn=q({id:w(),role:ln,content:te(cn),timestamp:vt(),metadata:ae(w(),ue()).optional()}),Po=q({type:ee("content"),id:w(),role:ln,contentDelta:cn,isComplete:Ce(),tokenUsage:q({inputTokens:F().optional(),outputTokens:F().optional(),totalTokens:F().optional()}).optional(),contextInputTokens:F().optional(),_meta:q({context_size:q({systemPromptTokens:F(),userMessagesTokens:F(),assistantMessagesTokens:F(),toolInputTokens:F(),toolResultsTokens:F(),totalEstimated:F(),llmReportedInputTokens:F().optional()}).optional()}).optional()}),Do=q({type:ee("tool_call"),id:w(),toolCall:Ht(),messageId:w().optional()}),Uo=q({type:ee("tool_call_update"),id:w(),toolCallUpdate:Ht(),messageId:w().optional()}),Mt=le(["context_size","tool_response"]),zo=q({type:ee("hook_triggered"),hookType:Mt,threshold:F(),currentPercentage:F(),callback:w(),triggeredAt:F().optional(),toolCallId:w().optional()}),$o=q({type:ee("hook_completed"),hookType:Mt,callback:w(),metadata:q({action:w().optional(),messagesRemoved:F().optional(),tokensSaved:F().optional()}).passthrough().optional(),completedAt:F().optional(),toolCallId:w().optional()}),Lo=q({type:ee("hook_error"),hookType:Mt,callback:w(),error:w(),completedAt:F().optional(),toolCallId:w().optional()}),Oo=it("type",[zo,$o,Lo]),Fo=q({type:ee("hook_notification"),id:w(),notification:Oo,messageId:w().optional()}),un=q({id:w(),url:w().url(),title:w(),snippet:w().optional(),favicon:w().optional(),toolCallId:w(),sourceName:w().optional()}),Bo=q({type:ee("sources"),sources:te(un)});it("type",[Po,Do,Uo,Fo,Bo]);const Ho=q({id:w(),url:w().url(),title:w(),snippet:w().optional(),favicon:w().optional(),toolCallId:w(),sourceName:w().optional()}),ps=q({systemPromptTokens:F(),toolOverheadTokens:F().optional(),mcpOverheadTokens:F().optional(),userMessagesTokens:F(),assistantMessagesTokens:F(),toolInputTokens:F(),toolResultsTokens:F(),totalEstimated:F(),llmReportedInputTokens:F().optional(),modelContextWindow:F().optional()}),Yt=le(["pending","in_progress","completed","failed"]),Wo=le(["read","edit","delete","move","search","execute","think","fetch","switch_mode","other"]),mn=q({path:w(),line:F().nullable().optional()}),Qt=q({inputTokens:F().optional(),outputTokens:F().optional(),totalTokens:F().optional()}),Gt=it("type",[q({type:ee("content"),content:q({type:ee("text"),text:w()})}),q({type:ee("text"),text:w()}),q({type:ee("image"),data:w(),mimeType:w().optional(),alt:w().optional()}),q({type:ee("image"),url:w(),alt:w().optional()}),q({type:ee("diff"),path:w(),oldText:w(),newText:w(),line:F().nullable().optional()}),q({type:ee("terminal"),terminalId:w()})]),pn=q({id:w(),title:w(),prettyName:w().optional(),icon:w().optional(),status:Yt,content:te(Gt).optional()}),Vo=it("type",[q({type:ee("text"),text:w()}),q({type:ee("tool_call"),toolCall:pn})]),fn=q({id:w(),content:w(),toolCalls:te(pn).optional(),contentBlocks:te(Vo).optional(),isStreaming:Ce().optional(),context_size:ps.optional(),_meta:q({semanticName:w().optional(),agentDefinitionName:w().optional(),currentActivity:w().optional(),statusGenerating:Ce().optional(),context_size:ps.optional()}).passthrough().optional()}),gn=q({id:w(),batchId:w().optional(),title:w(),prettyName:w().optional(),icon:w().optional(),verbiage:q({active:w(),past:w(),paramKey:w().optional()}).optional(),subline:w().optional(),kind:Wo,status:Yt,contentPosition:F().optional(),locations:te(mn).optional(),rawInput:ae(w(),ue()).optional(),rawOutput:ae(w(),ue()).optional(),content:te(Gt).optional(),error:w().optional(),startedAt:F().optional(),completedAt:F().optional(),tokenUsage:Qt.optional(),_meta:q({truncationWarning:w().optional(),compactionAction:le(["compacted","truncated"]).optional(),originalTokens:F().optional(),finalTokens:F().optional(),originalContentPreview:w().optional(),originalContentPath:w().optional()}).optional(),subagentPort:F().optional(),subagentSessionId:w().optional(),subagentMessages:te(fn).optional(),subagentStreaming:Ce().optional(),subagentCompleted:Ce().optional()}),qo=q({id:w(),status:Yt.optional(),title:w().optional(),prettyName:w().optional(),icon:w().optional(),batchId:w().optional(),rawInput:ae(w(),ue()).optional(),locations:te(mn).optional(),rawOutput:ae(w(),ue()).optional(),content:te(Gt).optional(),error:w().optional(),completedAt:F().optional(),tokenUsage:Qt.optional(),subagentPort:F().optional(),subagentSessionId:w().optional(),subagentMessages:te(fn).optional(),subagentCompleted:Ce().optional(),_meta:q({truncationWarning:w().optional(),compactionAction:le(["compacted","truncated"]).optional(),originalTokens:F().optional(),finalTokens:F().optional(),originalContentPreview:w().optional(),originalContentPath:w().optional()}).optional()});function fs(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,subagentCompleted:s.subagentCompleted??t.subagentCompleted,_meta:s._meta??t._meta}}const Ko=q({mimeType:w(),data:w()}),Yo=q({id:w(),hookType:Mt,callback:w(),status:le(["triggered","completed","error"]),threshold:F().optional(),currentPercentage:F().optional(),metadata:q({action:w().optional(),messagesRemoved:F().optional(),tokensSaved:F().optional(),tokensBeforeCompaction:F().optional(),summaryTokens:F().optional(),originalTokens:F().optional(),finalTokens:F().optional(),truncationWarning:w().optional()}).passthrough().optional(),error:w().optional(),triggeredAt:F().optional(),completedAt:F().optional(),contentPosition:F().optional(),toolCallId:w().optional()}),Qo=q({id:w(),role:le(["user","assistant","system"]),content:w(),timestamp:vt(),isStreaming:Ce().default(!1),streamingStartTime:F().optional(),metadata:ae(w(),ue()).optional(),toolCalls:te(gn).optional(),hookNotifications:te(Yo).optional(),tokenUsage:Qt.optional(),images:te(Ko).optional(),sources:te(Ho).optional()}),Go=q({value:w(),isSubmitting:Ce(),attachedFiles:te(q({name:w(),path:w(),size:F(),mimeType:w(),data:w()})),selectedPromptParameters:ae(w(),w()).optional()});q({sessionId:w().nullable(),isConnected:Ce(),isStreaming:Ce(),messages:te(Qo),input:Go,error:w().nullable()});le(["disconnected","connecting","connected","error"]);let gs=0,hs=0;function je(t){const s=Date.now();s!==hs&&(gs=0,hs=s);const n=gs++,o=Math.random().toString(36).substring(2,7);return`msg_${s}_${n}_${o}_${t}`}const Xo=q({baseUrl:w().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:w().optional(),timeout:F().optional(),headers:ae(w(),w()).optional()}),L=me("http-transport");class Jo{connected=!1;sessionUpdateCallbacks=new Set;errorCallbacks=new Set;fileSystemChangeCallbacks=new Map;messageQueue=[];currentSessionId=null;chunkResolvers=[];streamComplete=!1;sseAbortController=null;reconnectAttempts=0;maxReconnectAttempts=5;reconnectDelay=1e3;reconnecting=!1;abortController=null;options;isReceivingMessages=!1;isInReplayMode=!1;pendingReplayUpdates=[];agentInfo;constructor(s){const n=Xo.safeParse(s);if(!n.success){const o=n.error.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join("; ");throw new Error(`Invalid HTTP transport configuration: ${o}`)}this.options={...s,baseUrl:s.baseUrl.replace(/\/$/,"")}}async connect(){if(!this.connected)try{this.abortController=new AbortController;const s={protocolVersion:ls,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}},n=await this.sendRpcRequest("initialize",s);if(n.agentInfo){const i=n._meta,a=i&&typeof i=="object",c=a&&"agentDescription"in i?String(i.agentDescription):void 0,u=a&&"suggestedPrompts"in i&&Array.isArray(i.suggestedPrompts)?i.suggestedPrompts:void 0,d=a&&"tools"in i&&Array.isArray(i.tools)?i.tools:void 0,m=a&&"mcps"in i&&Array.isArray(i.mcps)?i.mcps:void 0,p=a&&"subagents"in i&&Array.isArray(i.subagents)?i.subagents:void 0,g=a&&"initialMessage"in i&&i.initialMessage&&typeof i.initialMessage=="object"?i.initialMessage:void 0,x=a&&"uiConfig"in i&&i.uiConfig&&typeof i.uiConfig=="object"?i.uiConfig:void 0,h=a&&"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,...c?{description:c}:{},...u?{suggestedPrompts:u}:{},...g?{initialMessage:g}:{},...x?{uiConfig:x}:{},...d?{tools:d}:{},...m?{mcps:m}:{},...p?{subagents:p}:{},...h?{promptParameters:h}:{}}}L.info("ACP connection initialized",{initResponse:n});const o={cwd:"/",mcpServers:[]},r=await this.sendRpcRequest("session/new",o);this.currentSessionId=r.sessionId,L.info("Session created",{sessionId:this.currentSessionId}),await this.connectSSE(),this.connected=!0,this.reconnectAttempts=0}catch(s){this.connected=!1;const n=s instanceof Error?s:new Error(String(s));throw this.notifyError(n),n}}async loadSession(s){this.connected&&(L.warn("Transport already connected, disconnecting first",{sessionId:s}),await this.disconnect());try{this.abortController=new AbortController;const n={protocolVersion:ls,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}}};L.info("Loading session - initializing connection",{sessionId:s});const o=await this.sendRpcRequest("initialize",n);if(o.agentInfo){const a=o._meta,c=a&&typeof a=="object",u=c&&"agentDescription"in a?String(a.agentDescription):void 0,d=c&&"suggestedPrompts"in a&&Array.isArray(a.suggestedPrompts)?a.suggestedPrompts:void 0,m=c&&"tools"in a&&Array.isArray(a.tools)?a.tools:void 0,p=c&&"mcps"in a&&Array.isArray(a.mcps)?a.mcps:void 0,g=c&&"subagents"in a&&Array.isArray(a.subagents)?a.subagents:void 0,x=c&&"initialMessage"in a&&a.initialMessage&&typeof a.initialMessage=="object"?a.initialMessage:void 0,h=c&&"uiConfig"in a&&a.uiConfig&&typeof a.uiConfig=="object"?a.uiConfig:void 0,f=c&&"promptParameters"in a&&Array.isArray(a.promptParameters)?a.promptParameters:void 0;this.agentInfo={name:o.agentInfo.name,...o.agentInfo.title?{displayName:o.agentInfo.title}:{},version:o.agentInfo.version,...u?{description:u}:{},...d?{suggestedPrompts:d}:{},...x?{initialMessage:x}:{},...h?{uiConfig:h}:{},...m?{tools:m}:{},...p?{mcps:p}:{},...g?{subagents:g}:{},...f?{promptParameters:f}:{}}}if(!o.agentCapabilities?.loadSession)throw L.error("Agent does not support loading sessions",{capabilities:o.agentCapabilities}),new Error("Agent does not support loading sessions");L.info("ACP connection initialized, loading session",{sessionId:s,capabilities:o.agentCapabilities}),this.isInReplayMode=!0,this.currentSessionId=s,await this.connectSSE();const r={sessionId:s,cwd:"/",mcpServers:[]};L.info("Sending session/load request",{loadRequest:r});const i=await this.sendRpcRequest("session/load",r);L.info("Session loaded successfully",{sessionId:this.currentSessionId,loadResponse:i}),this.connected=!0,this.reconnectAttempts=0}catch(n){this.connected=!1;const o=n instanceof Error?n:new Error(String(n));throw L.error("Failed to load session",{sessionId:s,error:o.message,stack:o.stack}),this.notifyError(o),o}}async listSessions(){try{const s={method:"GET"};this.options.headers&&(s.headers=this.options.headers);const n=await fetch(`${this.options.baseUrl}/sessions`,s);if(!n.ok)throw new Error(`HTTP ${n.status}: ${await n.text()}`);return(await n.json()).sessions||[]}catch(s){return L.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 n=s instanceof Error?s:new Error(String(s));throw this.notifyError(n),n}}async send(s,n){if(!this.connected||!this.currentSessionId)throw new Error("Transport not connected");this.isInReplayMode&&(L.info("Exiting replay mode - user sent a message"),this.isInReplayMode=!1);try{this.streamComplete=!1,this.messageQueue=[];const o=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),r={sessionId:this.currentSessionId,prompt:o};n?.promptParameters&&(r._meta={promptParameters:n.promptParameters});const i=await this.sendRpcRequest("session/prompt",r);L.debug("Prompt sent",{promptResponse:i}),this.streamComplete=!0;const a=this.chunkResolvers.shift();a?a({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(o){this.streamComplete=!0;const r=o instanceof Error?o:new Error(String(o));throw this.notifyError(r),r}}async cancel(s){if(!this.connected){L.warn("Cannot cancel: transport not connected");return}const n=s||this.currentSessionId;if(!n){L.warn("Cannot cancel: no session ID");return}L.info("Cancelling session",{sessionId:n}),this.streamComplete=!0,this.messageQueue.length=0,await this.sendNotification("session/cancel",{sessionId:n});const o={type:"content",id:n,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0};for(;this.chunkResolvers.length>0;){const r=this.chunkResolvers.shift();r&&r(o)}}async editAndResend(s,n,o){if(!this.connected)throw new Error("Transport not connected");const r=s||this.currentSessionId;if(!r)throw new Error("No session ID available");this.isInReplayMode&&(L.info("Exiting replay mode - user edited a message"),this.isInReplayMode=!1),this.streamComplete=!1,this.messageQueue=[],L.info("Edit and resend",{sessionId:r,messageIndex:n});const i={"Content-Type":"application/json",...this.options.headers},a=this.options.timeout??600*1e3,c=new AbortController,u=setTimeout(()=>c.abort(),a);try{const d=await fetch(`${this.options.baseUrl}/sessions/${r}/edit-and-resend`,{method:"POST",headers:i,body:JSON.stringify({messageIndex:n,prompt:o}),signal:c.signal});if(clearTimeout(u),!d.ok){const p=await d.text();throw new Error(`HTTP ${d.status}: ${p}`)}this.streamComplete=!0;const m=this.chunkResolvers.shift();m?m({type:"content",id:r,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0}):this.messageQueue.push({type:"content",id:r,role:"assistant",contentDelta:{type:"text",text:""},isComplete:!0})}catch(d){throw clearTimeout(u),this.streamComplete=!0,d instanceof Error&&d.name==="AbortError"?new Error(`Request timeout after ${a}ms`):d}}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(n=>{this.chunkResolvers.push(n)});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){if(this.sessionUpdateCallbacks.add(s),this.pendingReplayUpdates.length>0){L.info("Replaying queued session updates to ALL callbacks",{count:this.pendingReplayUpdates.length,callbackCount:this.sessionUpdateCallbacks.size,updateTypes:this.pendingReplayUpdates.map(o=>o.type),updateDetails:this.pendingReplayUpdates.map(o=>{if(o.type==="tool_call")return{type:"tool_call",toolCallId:o.toolCall?.id};if(o.type==="sources")return{type:"sources",count:o.sources?.length,ids:o.sources?.map(r=>r.id)};if(o.type==="generic"&&o.message){const r=o.message.content?.[0];return{type:"message",role:o.message.role,contentLength:r?.type==="text"?r.text?.length:0}}return{type:o.type}})});const n=[...this.pendingReplayUpdates];this.pendingReplayUpdates=[],setTimeout(()=>{L.info("Starting replay of queued updates to all callbacks",{updateCount:n.length,callbackCount:this.sessionUpdateCallbacks.size});for(const o of n)try{L.info("Replaying update to all callbacks",{type:o.type}),this.notifySessionUpdate(o)}catch(r){L.error("Error replaying session update",{error:r})}L.info("Finished replay of queued updates")},0)}return()=>{this.sessionUpdateCallbacks.delete(s)}}onError(s){return this.errorCallbacks.add(s),()=>{this.errorCallbacks.delete(s)}}onFileSystemChange(s,n){return L.debug("Registering file system change callback",{sessionId:s}),this.fileSystemChangeCallbacks.set(s,n),()=>{L.debug("Unregistering file system change callback",{sessionId:s}),this.fileSystemChangeCallbacks.delete(s)}}notifyFileSystemChange(s){const n=this.fileSystemChangeCallbacks.get(s.sessionId);L.debug("notifyFileSystemChange",{sessionId:s.sessionId,hasCallback:!!n,callbackCount:this.fileSystemChangeCallbacks.size}),n&&n(s)}getAgentInfo(){return this.agentInfo||{}}async sendNotification(s,n){const o={jsonrpc:"2.0",method:s,params:n};L.debug("Sending notification",{method:s,params:n});const r={"Content-Type":"application/json",...this.options.headers};try{const i=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:r,body:JSON.stringify(o)});if(!i.ok){const a=await i.text();L.error("Notification failed",{status:i.status,errorText:a})}}catch(i){L.error("Error sending notification",{error:i})}}async sendRpcRequest(s,n){const r={jsonrpc:"2.0",id:this.generateRequestId(),method:s,params:n};L.debug("Sending RPC request",{method:s,params:n,request:r});const i={"Content-Type":"application/json",...this.options.headers},a=this.options.timeout??600*1e3,c=new AbortController,u=setTimeout(()=>c.abort(),a);try{const d=await fetch(`${this.options.baseUrl}/rpc`,{method:"POST",headers:i,body:JSON.stringify(r),signal:c.signal});if(clearTimeout(u),!d.ok){const p=await d.text();throw new Error(`HTTP ${d.status}: ${p}`)}const m=await d.json();if(m.error)throw new Error(`ACP error: ${m.error.message||JSON.stringify(m.error)}`);return m.result||m}catch(d){throw clearTimeout(u),d instanceof Error&&d.name==="AbortError"?new Error(`Request timeout after ${a}ms`):d}}async connectSSE(){if(!this.currentSessionId)throw new Error("Cannot connect SSE without a session ID");const s=`${this.options.baseUrl}/events`,n={"X-Session-ID":this.currentSessionId,...this.options.headers};this.sseAbortController=new AbortController;try{const o=await fetch(s,{method:"GET",headers:n,signal:this.sseAbortController.signal});if(!o.ok)throw new Error(`SSE connection failed: HTTP ${o.status}`);if(!o.body)throw new Error("Response body is null");L.debug("SSE connection opened"),this.reconnectAttempts=0,this.reconnectDelay=1e3;const r=o.body.getReader(),i=new TextDecoder;let a="";(async()=>{try{for(;;){const{done:c,value:u}=await r.read();if(c){L.debug("SSE stream closed by server"),this.connected&&await this.handleSSEDisconnect();break}a+=i.decode(u,{stream:!0});const d=a.split(`
2
2
  `);a=d.pop()||"";let m={event:"message",data:""};for(const p of d)p.startsWith("event:")?m.event=p.substring(6).trim():p.startsWith("data:")?m.data=p.substring(5).trim():p===""&&(m.event==="message"&&m.data&&this.handleSSEMessage(m.data),m={event:"message",data:""})}}catch(c){if(c instanceof Error&&c.name==="AbortError"){L.debug("SSE stream aborted");return}L.error("Error reading SSE stream",{error:c}),this.connected&&!this.reconnecting&&await this.handleSSEDisconnect()}})()}catch(o){throw L.error("SSE connection error",{error:o}),o}}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 n=new Error(`SSE reconnection failed after ${this.maxReconnectAttempts} attempts`);this.notifyError(n),this.connected=!1,this.reconnecting=!1;return}this.reconnectAttempts++;const s=Math.min(this.reconnectDelay*2**(this.reconnectAttempts-1),32e3);L.debug("SSE reconnecting",{delay:s,attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts}),await new Promise(n=>setTimeout(n,s));try{await this.connectSSE(),L.info("SSE reconnected successfully"),this.reconnecting=!1}catch(n){L.error("SSE reconnection failed",{error:n}),this.reconnecting=!1}}handleSSEMessage(s){try{const n=JSON.parse(s);if(L.debug("Received SSE message",{message:n}),n&&typeof n=="object"&&n.method==="session/update"&&n.params?.update?.sessionUpdate==="sources"){try{this.handleSessionNotification(n.params)}catch(a){L.error("Error in handleSessionNotification for sources",{error:a})}return}const r=_a.safeParse(n);if(!r.success){L.error("Invalid ACP message from SSE",{issues:r.error.issues});return}const i=r.data;L.debug("Parsed ACP message",{method:"method"in i?i.method:"(no method)"}),"method"in i&&i.method==="session/update"&&(L.debug("Received session/update notification"),"params"in i&&i.params&&(L.debug("Calling handleSessionNotification",{params:i.params}),this.handleSessionNotification(i.params)))}catch(n){L.error("Error parsing SSE message",{error:n}),this.notifyError(n instanceof Error?n:new Error(String(n)))}}handleSessionNotification(s){const r=s.update?.sessionUpdate==="sources";if(this.streamComplete&&!r){L.debug("Skipping session notification - stream complete/cancelled");return}L.debug("handleSessionNotification called",{params:s});const a=s.update,c=this.currentSessionId||s.sessionId;if(L.warn("📥 SSE UPDATE RECEIVED",{sessionUpdate:a?.sessionUpdate,hasUpdate:!!a,isInReplayMode:this.isInReplayMode,callbackCount:this.sessionUpdateCallbacks.size}),a?.sessionUpdate==="sandbox_files_changed"){const d=a;d._meta?.isReplay===!0||(L.debug("Sandbox files changed",{paths:d.paths,source:d._meta?.source}),this.notifyFileSystemChange({sessionId:c,...d.paths&&{paths:d.paths},...d._meta?.source&&{source:d._meta.source}}));return}if(a?.sessionUpdate==="tool_call"){L.debug("Tool call notification",{tokenUsage:a.tokenUsage});const d=a._meta&&typeof a._meta=="object"&&"messageId"in a._meta?String(a._meta.messageId):void 0,m=a._meta&&typeof a._meta=="object"&&"prettyName"in a._meta&&typeof a._meta.prettyName=="string"?a._meta.prettyName:void 0,p=a._meta&&typeof a._meta=="object"&&"icon"in a._meta&&typeof a._meta.icon=="string"?a._meta.icon:void 0,g=a._meta&&typeof a._meta=="object"&&"subline"in a._meta&&typeof a._meta.subline=="string"?a._meta.subline:void 0,x=a._meta&&typeof a._meta=="object"&&"batchId"in a._meta&&typeof a._meta.batchId=="string"?a._meta.batchId:void 0,h=a._meta&&typeof a._meta=="object"&&"subagentPort"in a._meta&&typeof a._meta.subagentPort=="number"?a._meta.subagentPort:void 0,f=a._meta&&typeof a._meta=="object"&&"subagentSessionId"in a._meta&&typeof a._meta.subagentSessionId=="string"?a._meta.subagentSessionId:void 0,y=a._meta&&typeof a._meta=="object"&&"subagentMessages"in a._meta&&Array.isArray(a._meta.subagentMessages)?a._meta.subagentMessages:void 0,N=a._meta&&typeof a._meta=="object"&&"compactionAction"in a._meta&&typeof a._meta.compactionAction=="string"?a._meta.compactionAction:void 0,v=a._meta&&typeof a._meta=="object"&&"originalTokens"in a._meta&&typeof a._meta.originalTokens=="number"?a._meta.originalTokens:void 0,C=a._meta&&typeof a._meta=="object"&&"finalTokens"in a._meta&&typeof a._meta.finalTokens=="number"?a._meta.finalTokens:void 0,$=a._meta&&typeof a._meta=="object"&&"originalContentPreview"in a._meta&&typeof a._meta.originalContentPreview=="string"?a._meta.originalContentPreview:void 0,B=a._meta&&typeof a._meta=="object"&&"originalContentPath"in a._meta&&typeof a._meta.originalContentPath=="string"?a._meta.originalContentPath:void 0,D={id:a.toolCallId??"",batchId:x,title:a.title??"",prettyName:m,icon:p,subline:g,kind:a.kind||"other",status:a.status||"pending",locations:a.locations,rawInput:a.rawInput,tokenUsage:a.tokenUsage,content:a.content?.map(E=>{if(typeof E!="object"||E===null)return{type:"text",text:""};const _=E;if(_.type==="content"&&typeof _.content=="object"&&_.content!==null){const K=_.content;if(K.type==="text")return{type:"content",content:{type:"text",text:typeof K.text=="string"?K.text:""}}}return _.type==="text"?{type:"text",text:typeof _.text=="string"?_.text:""}:_.type==="diff"?{type:"diff",path:typeof _.path=="string"?_.path:"",oldText:typeof _.oldText=="string"?_.oldText:"",newText:typeof _.newText=="string"?_.newText:"",line:typeof _.line=="number"?_.line:null}:_.type==="terminal"?{type:"terminal",terminalId:typeof _.terminalId=="string"?_.terminalId:""}:{type:"text",text:""}}),startedAt:Date.now(),subagentPort:h,subagentSessionId:f,subagentMessages:y,_meta:N||v||C||$||B?{compactionAction:N,originalTokens:v,finalTokens:C,originalContentPreview:$,originalContentPath:B}:void 0},I={type:"tool_call",sessionId:c,status:"active",toolCall:D,messageId:d},M=a._meta&&typeof a._meta=="object"&&"isReplay"in a._meta&&a._meta.isReplay===!0;if(L.info("Creating tool_call session update",{toolCallId:D.id,title:D.title,hasSubagentPort:!!h,hasSubagentSessionId:!!f,hasSubagentMessages:!!y,subagentMessagesCount:y?.length,isReplay:M,isInReplayMode:this.isInReplayMode}),M||this.isInReplayMode)this.sessionUpdateCallbacks.size===0?(L.debug("Queueing tool_call for late-subscribing callbacks",{toolCallId:D.id}),this.pendingReplayUpdates.push(I)):this.notifySessionUpdate(I);else{const E={type:"tool_call",id:c,toolCall:D,messageId:d},_=this.chunkResolvers.shift();_?_(E):this.messageQueue.push(E)}}else if(a?.sessionUpdate==="tool_call_update"){const d=a._meta&&typeof a._meta=="object"&&"messageId"in a._meta?String(a._meta.messageId):void 0,m=a._meta&&typeof a._meta=="object"&&"prettyName"in a._meta&&typeof a._meta.prettyName=="string"?a._meta.prettyName:void 0,p=a._meta&&typeof a._meta=="object"&&"icon"in a._meta&&typeof a._meta.icon=="string"?a._meta.icon:void 0,g=a._meta&&typeof a._meta=="object"&&"batchId"in a._meta&&typeof a._meta.batchId=="string"?a._meta.batchId:void 0,x=a._meta&&typeof a._meta=="object"&&"subagentPort"in a._meta&&typeof a._meta.subagentPort=="number"?a._meta.subagentPort:void 0,h=a._meta&&typeof a._meta=="object"&&"subagentSessionId"in a._meta&&typeof a._meta.subagentSessionId=="string"?a._meta.subagentSessionId:void 0,f=a._meta&&typeof a._meta=="object"&&"subagentMessages"in a._meta&&Array.isArray(a._meta.subagentMessages)?a._meta.subagentMessages:void 0;(x||h||f)&&L.info("Extracted subagent info from tool_call_update",{toolCallId:a.toolCallId,subagentPort:x,subagentSessionId:h,subagentMessagesCount:f?.length});const y=a._meta&&typeof a._meta=="object"&&"compactionAction"in a._meta&&typeof a._meta.compactionAction=="string"?a._meta.compactionAction:void 0,N=a._meta&&typeof a._meta=="object"&&"originalTokens"in a._meta&&typeof a._meta.originalTokens=="number"?a._meta.originalTokens:void 0,v=a._meta&&typeof a._meta=="object"&&"finalTokens"in a._meta&&typeof a._meta.finalTokens=="number"?a._meta.finalTokens:void 0,C=a._meta&&typeof a._meta=="object"&&"originalContentPreview"in a._meta&&typeof a._meta.originalContentPreview=="string"?a._meta.originalContentPreview:void 0,$=a._meta&&typeof a._meta=="object"&&"originalContentPath"in a._meta&&typeof a._meta.originalContentPath=="string"?a._meta.originalContentPath:void 0,B="subagentCompleted"in a&&typeof a.subagentCompleted=="boolean"?a.subagentCompleted:a._meta&&typeof a._meta=="object"&&"subagentCompleted"in a._meta&&typeof a._meta.subagentCompleted=="boolean"?a._meta.subagentCompleted:void 0,D={id:a.toolCallId??"",status:a.status,title:a.title,prettyName:m,icon:p,batchId:g,rawInput:a.rawInput,locations:a.locations,rawOutput:a.rawOutput,tokenUsage:a.tokenUsage,subagentCompleted:B,content:a.content?.map(M=>{if(typeof M!="object"||M===null)return{type:"text",text:""};const E=M;if(E.type==="content"&&typeof E.content=="object"&&E.content!==null){const _=E.content;if(_.type==="text")return{type:"content",content:{type:"text",text:typeof _.text=="string"?_.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:a.error,completedAt:a.status==="completed"||a.status==="failed"?Date.now():void 0,subagentPort:x,subagentSessionId:h,subagentMessages:f,_meta:y||N||v||C||$?{compactionAction:y,originalTokens:N,finalTokens:v,originalContentPreview:C,originalContentPath:$}:void 0},I={type:"tool_call_update",sessionId:c,status:"active",toolCallUpdate:D,messageId:d};if(this.isInReplayMode)this.sessionUpdateCallbacks.size===0?(L.debug("Queueing tool_call_update for late-subscribing callbacks",{toolCallId:D.id}),this.pendingReplayUpdates.push(I)):this.notifySessionUpdate(I);else{const M={type:"tool_call_update",id:c,toolCallUpdate:D,messageId:d},E=this.chunkResolvers.shift();E?E(M):this.messageQueue.push(M)}L.debug("Processed tool_call_update",{sessionUpdate:I,isReplay:this.isInReplayMode})}else if(a&&"sessionUpdate"in a&&a.sessionUpdate==="hook_notification"){const d=a;L.debug("Received hook_notification",{id:d.id,notificationType:d.notification.type,hookType:d.notification.hookType});const m={type:"hook_notification",id:d.id,notification:d.notification,messageId:d.messageId},p=this.chunkResolvers.shift();p?p(m):this.messageQueue.push(m)}else if(a&&"sessionUpdate"in a&&a.sessionUpdate==="tool_output"){const d=a,m=d._meta&&typeof d._meta=="object"&&"messageId"in d._meta?String(d._meta.messageId):void 0,p={id:d.toolCallId??"",rawOutput:d.rawOutput,content:d.content?.map(x=>{if(typeof x!="object"||x===null)return{type:"text",text:""};const h=x;if(h.type==="content"&&typeof h.content=="object"&&h.content!==null){const f=h.content;if(f.type==="text")return{type:"content",content:{type:"text",text:typeof f.text=="string"?f.text:""}}}return h.type==="text"?{type:"text",text:typeof h.text=="string"?h.text:""}:h.type==="diff"?{type:"diff",path:typeof h.path=="string"?h.path:"",oldText:typeof h.oldText=="string"?h.oldText:"",newText:typeof h.newText=="string"?h.newText:"",line:typeof h.line=="number"?h.line:null}:h.type==="terminal"?{type:"terminal",terminalId:typeof h.terminalId=="string"?h.terminalId:""}:h.type==="image"?{type:"image",data:typeof h.data=="string"?h.data:"",mimeType:typeof h.mimeType=="string"?h.mimeType:"image/png",alt:typeof h.alt=="string"?h.alt:void 0}:{type:"text",text:""}})},g={type:"tool_call_update",sessionId:c,status:"active",toolCallUpdate:p,messageId:m};if(this.isInReplayMode)this.sessionUpdateCallbacks.size===0?(L.debug("Queueing tool_output for late-subscribing callbacks",{toolCallId:p.id}),this.pendingReplayUpdates.push(g)):this.notifySessionUpdate(g);else{const x={type:"tool_call_update",id:c,toolCallUpdate:p,messageId:m},h=this.chunkResolvers.shift();h?h(x):this.messageQueue.push(x)}L.debug("Queued tool_output as tool_call_update chunk",{sessionUpdate:g})}else if(a&&"sessionUpdate"in a&&a.sessionUpdate==="sources"){const d=a,m={type:"sources",sessionId:c,status:"active",sources:d.sources};if(this.isInReplayMode)this.sessionUpdateCallbacks.size===0?this.pendingReplayUpdates.push(m):this.notifySessionUpdate(m);else{const p={type:"sources",sources:d.sources},g=this.chunkResolvers.shift();g?g(p):this.messageQueue.push(p)}}else if(a?.sessionUpdate==="agent_message_chunk"){const d=a._meta&&typeof a._meta=="object"&&"isReplay"in a._meta&&a._meta.isReplay===!0;if(this.isInReplayMode&&!d)return;const m=a._meta&&typeof a._meta=="object"&&"tokenUsage"in a._meta?a._meta.tokenUsage:void 0,p=a._meta&&typeof a._meta=="object"&&"contextInputTokens"in a._meta&&typeof a._meta.contextInputTokens=="number"?a._meta.contextInputTokens:void 0,g=a._meta&&typeof a._meta=="object"&&"context_size"in a._meta?a._meta.context_size:void 0,x={type:"generic",sessionId:c,status:"active",_meta:a._meta},h=a.content;if(h&&typeof h=="object"){const y=h;let N=null;if(y.type==="text"&&typeof y.text=="string"&&(N={type:"content",id:s.sessionId,role:"assistant",contentDelta:{type:"text",text:y.text},tokenUsage:m,contextInputTokens:p,_meta:g?{context_size:g}:void 0,isComplete:!1}),N){const v=this.chunkResolvers.shift();v?v(N):this.messageQueue.push(N)}if(N&&typeof y.text=="string"&&(d||!this.isReceivingMessages)){const v={type:"generic",sessionId:c,status:"active",message:{id:je("assistant"),role:"assistant",content:[{type:"text",text:y.text}],timestamp:new Date().toISOString()}};d&&this.sessionUpdateCallbacks.size===0?(L.debug("Queueing assistant message for late-subscribing callbacks",{textLength:y.text.length}),this.pendingReplayUpdates.push(v)):this.notifySessionUpdate(v)}}const f=x._meta&&"context_size"in x._meta;(!d||f)&&this.notifySessionUpdate(x)}else if(a?.sessionUpdate==="user_message_chunk"){L.debug("Received user_message_chunk",{update:a});const d=a._meta&&typeof a._meta=="object"&&"isReplay"in a._meta&&a._meta.isReplay===!0,m=a.content;if(m&&typeof m=="object"){const p=m;if(p.type==="text"&&typeof p.text=="string"){const g={type:"generic",sessionId:c,status:"active",message:{id:je("user"),role:"user",content:[{type:"text",text:p.text}],timestamp:new Date().toISOString()}};d&&this.sessionUpdateCallbacks.size===0?(L.debug("Queueing user message for late-subscribing callbacks",{textLength:p.text.length}),this.pendingReplayUpdates.push(g)):(L.debug("Notifying session update for user message"),this.notifySessionUpdate(g))}}}else{L.warn("⚠️ UNHANDLED SESSION UPDATE - falling through to generic",{sessionUpdate:a?.sessionUpdate,updateKeys:a?Object.keys(a):[],hasSources:a&&"sources"in a});const d={type:"generic",sessionId:c,status:"active"};this.notifySessionUpdate(d)}}generateRequestId(){return`req-${Date.now()}-${Math.random().toString(36).substring(2,9)}`}notifySessionUpdate(s){for(const n of this.sessionUpdateCallbacks)try{n(s)}catch(o){L.error("Error in session update callback",{error:o})}}notifyError(s){for(const n of this.errorCallbacks)try{n(s)}catch(o){L.error("Error in error callback",{error:o})}}}class Zo{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 er{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 Le=me("acp-client","debug");class tr{constructor(s){this.config=s,this.transport=this.createTransport(),this.setupTransportListeners(),s.autoConnect&&this.connect().catch(n=>{Le.error("Failed to auto-connect",{error:n instanceof Error?n.message:String(n)})})}transport;sessions=new Map;currentSessionId=null;sessionUpdateHandlers=new Set;errorHandlers=new Set;async connect(){await this.transport.connect();const s="currentSessionId"in this.transport?this.transport.currentSessionId:void 0;if(s){const n=new Date().toISOString(),o=this.transport.getAgentInfo?.()?.name,r={id:s,status:"connected",config:{agentPath:""},messages:[],metadata:{startedAt:n,agentName:o}};this.sessions.set(s,r),this.currentSessionId=s}}async disconnect(){await this.transport.disconnect(),this.currentSessionId=null}isConnected(){return this.transport.isConnected()}async startSession(s){const n="currentSessionId"in this.transport?this.transport.currentSessionId:void 0;if(n){const c=new Date().toISOString(),u=this.transport.getAgentInfo?.()?.name,d={id:n,status:"connected",config:s?{...s,agentPath:s.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:c,agentName:u}};return this.sessions.set(n,d),this.currentSessionId=n,n}const o=this.generateSessionId(),r=new Date().toISOString(),i=this.transport.getAgentInfo?.()?.name,a={id:o,status:"connecting",config:s?{...s,agentPath:s.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:r,agentName:i}};return this.sessions.set(o,a),this.currentSessionId=o,this.updateSessionStatus(o,"connected"),o}async loadSession(s,n){if(!this.transport.loadSession)throw new Error("Transport does not support loading sessions");const o=new Date().toISOString(),r={id:s,status:"connecting",config:n?{...n,agentPath:n.agentPath||""}:{agentPath:""},messages:[],metadata:{startedAt:o}};if(this.sessions.set(s,r),this.currentSessionId=s,await this.transport.loadSession(s),this.transport.getAgentInfo){const i=this.transport.getAgentInfo();i.name&&r.metadata&&(r.metadata.agentName=i.name)}return this.updateSessionStatus(s,"connected"),s}async listSessions(){return this.transport.listSessions?this.transport.listSessions():[]}async sendMessage(s,n,o,r){const i=n||this.currentSessionId;if(!i)throw new Error("No active session. Start a session first.");if(!this.transport.isConnected())throw new Error("Transport not connected");const a=this.sessions.get(i);if(!a)throw new Error(`Session ${i} not found`);const c=[];if(o&&o.length>0)for(const d of o)d.mimeType.startsWith("image/")&&c.push({type:"image",source:{type:"base64",media_type:d.mimeType,data:d.data}});c.push({type:"text",text:s});const u={id:je("user"),role:"user",content:c,timestamp:new Date().toISOString()};a.messages.push(u),this.updateSessionStatus(i,"active"),await this.transport.send(u,r?{promptParameters:r}:void 0)}async*receiveMessages(){if(!this.transport.isConnected())throw new Error("Transport not connected");yield*this.transport.receive()}async cancel(s){const n=s||this.currentSessionId;if(!n){Le.warn("Cannot cancel: no session ID");return}Le.info("Cancelling session",{sessionId:n}),await this.transport.cancel(n)}async editAndResend(s,n,o,r){const i=o||this.currentSessionId;if(!i)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 a=[];if(r&&r.length>0)for(const c of r)c.mimeType.startsWith("image/")&&a.push({type:"image",data:c.data,mimeType:c.mimeType});a.push({type:"text",text:n}),Le.info("Edit and resend",{sessionId:i,messageIndex:s}),await this.transport.editAndResend(i,s,a)}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)}}onFileSystemChange(s,n){return this.transport&&"onFileSystemChange"in this.transport?this.transport.onFileSystemChange(s,n):()=>{}}getAgentInfo(){return this.transport.getAgentInfo?.()||{}}getBaseUrl(){if(this.config.type==="http")return this.config.options.baseUrl}createTransport(){switch(this.config.type){case"stdio":return new Zo(this.config.options);case"http":return new Jo(this.config.options);case"websocket":return new er(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 n=this.sessions.get(s.sessionId);n&&(s.status&&(n.status=s.status),s.message&&n.messages.push(s.message),s.error&&(n.error=s.error))}for(const n of this.sessionUpdateHandlers)try{n(s)}catch(o){Le.error("Error in session update handler",{error:o instanceof Error?o.message:String(o)})}}handleError(s){for(const n of this.errorHandlers)try{n(s)}catch(o){Le.error("Error in error handler",{error:o instanceof Error?o.message:String(o)})}}updateSessionStatus(s,n){const o=this.sessions.get(s);o&&(o.status=n,this.handleSessionUpdate({sessionId:s,status:n}))}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}const Oe=me("acp-client-hook");function sr(t){const[s,n]=l.useState(null),[o,r]=l.useState(null),[i,a]=l.useState(null);return l.useEffect(()=>{const u=new URLSearchParams(window.location.search).get("session");u&&(Oe.info("Session ID found in URL",{sessionId:u}),a(u));try{Oe.info("Initializing ACP client",{serverUrl:t.serverUrl});const d=new tr({type:"http",options:{baseUrl:t.serverUrl}});return n(d),Oe.info("ACP client initialized successfully"),()=>{Oe.debug("Disconnecting ACP client"),d.disconnect().catch(m=>{Oe.error("Failed to disconnect ACP client",{error:m instanceof Error?m.message:String(m)})})}}catch(d){const m=d instanceof Error?d.message:"Failed to initialize ACP client";r(m),Oe.error("Failed to initialize ACP client",{error:d instanceof Error?d.message:String(d),stack:d instanceof Error?d.stack:void 0});return}},[t.serverUrl]),{client:s,error:o,sessionId:i}}const se=me("chat-store","debug"),yt=[];function Et(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 xt={sessionId:null,toolCallId:null,todos:yt};const nr=t=>{const s=t.sessionId;if(!s)return yt;const o=(t.toolCalls[s]||[]).filter(a=>a.title==="todo_write").sort((a,c)=>(c.startedAt||0)-(a.startedAt||0));if(o.length===0)return yt;const r=o[0];if(!r?.rawInput?.todos||!Array.isArray(r.rawInput.todos))return yt;if(xt.sessionId===s&&xt.toolCallId===r.id)return xt.todos;const i=r.rawInput.todos.map((a,c)=>({id:`${r.id}-${c}`,text:a.status==="in_progress"?a.activeForm:a.content,status:a.status}));return xt={sessionId:s,toolCallId:r.id,todos:i},i},H=Na(t=>({connectionStatus:"disconnected",sessionId:null,error:null,messages:[],isStreaming:!1,streamingStartTime:null,sources:[],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(n=>({messages:[...n.messages,s]})),updateMessage:(s,n)=>t(o=>{const r=o.messages.find(d=>d.id===s);let i=o.totalBilled,a=o.currentContext,c=n;if(n.tokenUsage){const d=r?.tokenUsage;se.debug("updateMessage: incoming tokenUsage",{incoming:n.tokenUsage,existing:d});const m={inputTokens:Math.max(n.tokenUsage.inputTokens??0,d?.inputTokens??0),outputTokens:Math.max(n.tokenUsage.outputTokens??0,d?.outputTokens??0),totalTokens:Math.max(n.tokenUsage.inputTokens??0,d?.inputTokens??0)+Math.max(n.tokenUsage.outputTokens??0,d?.outputTokens??0)};se.debug("updateMessage: merged tokenUsage",{merged:m}),c={...n,tokenUsage:m};const p=m.inputTokens-(d?.inputTokens??0),g=m.outputTokens-(d?.outputTokens??0),x=m.totalTokens-(d?.totalTokens??0);i={inputTokens:o.totalBilled.inputTokens+p,outputTokens:o.totalBilled.outputTokens+g,totalTokens:o.totalBilled.totalTokens+x},a={inputTokens:m.inputTokens,outputTokens:o.currentContext.outputTokens+g,totalTokens:m.totalTokens}}const u=o.messages.map(d=>d.id===s?{...d,...c}:d);if(n.tokenUsage&&c.tokenUsage){const d=r?.tokenUsage,m=c.tokenUsage,p=(m.inputTokens??0)-(d?.inputTokens??0),g=(m.outputTokens??0)-(d?.outputTokens??0),x=(m.totalTokens??0)-(d?.totalTokens??0),h=u.filter(N=>N.tokenUsage).map(N=>({id:N.id,role:N.role,tokens:N.tokenUsage})),f=u.reduce((N,v)=>({inputTokens:N.inputTokens+(v.tokenUsage?.inputTokens??0),outputTokens:N.outputTokens+(v.tokenUsage?.outputTokens??0),totalTokens:N.totalTokens+(v.tokenUsage?.totalTokens??0)}),{inputTokens:0,outputTokens:0,totalTokens:0}),y=f.inputTokens===i.inputTokens&&f.outputTokens===i.outputTokens&&f.totalTokens===i.totalTokens;se.debug("updateMessage: tokenUsage update",{messageId:s,updates:n.tokenUsage,existing:d,messageMax:m,delta:{inputDelta:p,outputDelta:g,totalDelta:x},totalBilled:i,currentContext:a,actualSum:f,billedCorrect:y?"✅":"❌",messageCount:u.length,messagesWithTokens:h.length,breakdown:h})}return{messages:u,totalBilled:i,currentContext:a}}),clearMessages:()=>t({messages:[],sources:[]}),addSources:s=>t(n=>{if(!s||s.length===0)return n;const o=new Map;for(const r of n.sources)o.set(r.id,r);for(const r of s)o.set(r.id,r);return{sources:Array.from(o.values())}}),setIsStreaming:s=>t({isStreaming:s}),setStreamingStartTime:s=>t({streamingStartTime:s}),addToolCall:(s,n)=>t(o=>({toolCalls:{...o.toolCalls,[s]:[...o.toolCalls[s]||[],n]}})),addToolCallToCurrentMessage:s=>t(n=>{const o=n.messages.findLastIndex(u=>u.role==="assistant");if(o===-1){se.debug("No assistant message found, creating one for tool call at position 0");const u={id:je("assistant"),role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,toolCalls:[{...s,contentPosition:0}]};return{messages:[...n.messages,u]}}const r=[...n.messages],i=r[o];if(!i)return n;const a=i.content.length,c={...s,contentPosition:a};return r[o]={...i,toolCalls:[...i.toolCalls||[],c]},{messages:r}}),updateToolCallInCurrentMessage:s=>t(n=>{const o=n.messages.findLastIndex(p=>p.role==="assistant");if(o===-1)return se.warn("No assistant message found to update tool call in"),n;const r=[...n.messages],i=r[o];if(!i)return n;const a=i.toolCalls||[],c=a.findIndex(p=>p.id===s.id);if(c===-1)return se.warn(`Tool call ${s.id} not found in message`),n;const u=a[c];if(!u)return n;const d=[...a],m=fs(u,s);return d[c]=m,r[o]={...i,toolCalls:d},{messages:r}}),addHookNotificationToCurrentMessage:s=>t(n=>{const o=n.messages.findLastIndex(m=>m.role==="assistant");if(o===-1){se.debug("No assistant message found, creating one for hook notification");const m={...Et(s),contentPosition:0},p={id:je("assistant"),role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,hookNotifications:[m]};return{messages:[...n.messages,p]}}const r=[...n.messages],i=r[o];if(!i)return n;const a=i.hookNotifications||[],c=i.content.length;if(s.type==="hook_triggered"){se.debug("Adding hook_triggered notification for loading state",{hookType:s.hookType,callback:s.callback,contentPosition:c});const m={...Et(s),contentPosition:c},p=[...a,m];return r[o]={...i,hookNotifications:p},{messages:r}}let u;const d=a.findIndex(m=>m.hookType===s.hookType&&m.callback===s.callback&&m.status==="triggered");if(d!==-1){const m=a[d];u=[...a];const p=s.type==="hook_completed"||s.type==="hook_error"?s.completedAt??Date.now():Date.now();u[d]={...m,status:s.type==="hook_completed"?"completed":"error",completedAt:p,...s.type==="hook_completed"&&s.metadata?{metadata:s.metadata}:{},...s.type==="hook_error"?{error:s.error}:{}},se.debug("Merged hook notification with triggered state",{hookType:s.hookType,status:u[d]?.status})}else{const m={...Et(s),contentPosition:c};u=[...a,m],se.debug("Added hook notification without prior triggered state",{hookType:s.hookType,callback:s.callback,contentPosition:c})}return r[o]={...i,hookNotifications:u},{messages:r}}),addSourcesToCurrentMessage:s=>t(n=>{const o=n.messages.findLastIndex(c=>c.role==="assistant");if(o===-1){se.debug("No assistant message found, creating one for sources");const c={id:je("assistant"),role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!1,sources:s},u=new Map;for(const d of n.sources)u.set(d.id,d);for(const d of s)u.set(d.id,d);return{messages:[...n.messages,c],sources:[...u.values()]}}const r=[...n.messages],i=r[o];if(!i)return n;r[o]={...i,sources:[...i.sources||[],...s]},se.debug("Added sources to current message",{sourcesCount:s.length,totalSources:(i.sources?.length||0)+s.length});const a=new Map;for(const c of n.sources)a.set(c.id,c);for(const c of s)a.set(c.id,c);return{messages:r,sources:[...a.values()]}}),addSourcesByToolCallId:s=>t(n=>{se.info("addSourcesByToolCallId called",{sourcesCount:s.length,messagesCount:n.messages.length,sourceDetails:s.map(c=>({id:c.id,toolCallId:c.toolCallId,title:c.title?.slice(0,30)}))}),se.info("Current messages state",{messages:n.messages.map((c,u)=>({index:u,role:c.role,contentLength:c.content?.length||0,toolCallIds:c.toolCalls?.map(d=>d.id)||[],existingSources:c.sources?.length||0}))});const o=new Map;for(const c of s){if(!c.toolCallId){se.warn("Source missing toolCallId",{sourceId:c.id});continue}const u=o.get(c.toolCallId)||[];u.push(c),o.set(c.toolCallId,u)}if(o.size===0)return se.warn("No sources with toolCallId to distribute"),n;const r=[...n.messages];let i=0;for(const[c,u]of o){const d=r.findIndex(m=>m.role==="assistant"&&m.toolCalls?.some(p=>p.id===c));if(se.info("Looking for message with toolCallId",{toolCallId:c,foundIndex:d,sourcesCount:u.length}),d!==-1){const m=r[d];m&&(r[d]={...m,sources:[...m.sources||[],...u]},i+=u.length,se.info("Added sources to message",{messageIndex:d,messageId:m.id,toolCallId:c,sourcesAdded:u.length,totalSourcesNow:r[d]?.sources?.length,messageContentPreview:m.content.slice(0,100)}))}else{se.warn("Tool call not found in any message, using fallback",{toolCallId:c});const m=r.findLastIndex(p=>p.role==="assistant");if(m!==-1){const p=r[m];p&&(r[m]={...p,sources:[...p.sources||[],...u]},i+=u.length,se.info("Added sources to last assistant message (fallback)",{lastAssistantIndex:m,sourcesAdded:u.length}))}else se.error("No assistant message found to add sources to")}}se.info("Finished distributing sources",{totalSources:s.length,sourcesAdded:i,toolCallIds:Array.from(o.keys())});const a=new Map;for(const c of n.sources)a.set(c.id,c);for(const c of s)a.set(c.id,c);return{messages:r,sources:[...a.values()]}}),updateToolCall:(s,n)=>t(o=>{const r=o.toolCalls[s]||[],i=r.findIndex(u=>u.id===n.id);if(i===-1)return o;const a=r[i];if(!a)return o;const c=[...r];return c[i]=fs(a,n),{toolCalls:{...o.toolCalls,[s]:c}}}),setInputValue:s=>t(n=>({input:{...n.input,value:s}})),setInputSubmitting:s=>t(n=>({input:{...n.input,isSubmitting:s}})),addFileAttachment:s=>t(n=>({input:{...n.input,attachedFiles:[...n.input.attachedFiles,s]}})),removeFileAttachment:s=>t(n=>({input:{...n.input,attachedFiles:n.input.attachedFiles.filter((o,r)=>r!==s)}})),setSelectedPromptParameters:s=>t(n=>({input:{...n.input,selectedPromptParameters:s}})),clearInput:()=>t(s=>({input:{value:"",isSubmitting:!1,attachedFiles:[],selectedPromptParameters:void 0}})),addTokenUsage:s=>t(n=>({totalBilled:{inputTokens:n.totalBilled.inputTokens+(s.inputTokens??0),outputTokens:n.totalBilled.outputTokens+(s.outputTokens??0),totalTokens:n.totalBilled.totalTokens+(s.totalTokens??0)},currentContext:{inputTokens:s.inputTokens??n.currentContext.inputTokens,outputTokens:n.currentContext.outputTokens+(s.outputTokens??0),totalTokens:(s.inputTokens??n.currentContext.inputTokens)+(n.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 n=["context","input","output"],r=(n.indexOf(s.tokenDisplayMode)+1)%n.length,i=n[r];return i?{tokenDisplayMode:i}:s}),addLog:s=>t(n=>({logs:[...n.logs,s]})),clearLogs:()=>t({logs:[]}),setActiveTab:s=>t({activeTab:s}),truncateMessagesFrom:s=>t(n=>({messages:n.messages.slice(0,s),totalBilled:{inputTokens:0,outputTokens:0,totalTokens:0},currentContext:{inputTokens:0,outputTokens:0,totalTokens:0},latestContextSize:null}))})),re=me("use-chat-session","debug");function Lt(t,s=!1){if(typeof window>"u"){re.debug("safeUpdateUrl: window is undefined, skipping");return}try{const n=new URL(window.location.href);n.searchParams.set("session",t);const o=n.toString();re.info("safeUpdateUrl: updating URL",{sessionId:t,useReplace:s,newUrl:o}),s?window.history.replaceState({},"",o):window.history.pushState({},"",o),re.info("safeUpdateUrl: URL updated successfully")}catch(n){re.warn("Failed to update URL with session ID",{sessionId:t,error:n instanceof Error?n.message:String(n)})}}function ar(t,s){const n=H(f=>f.connectionStatus),o=H(f=>f.sessionId),r=H(f=>f.setConnectionStatus),i=H(f=>f.setSessionId),a=H(f=>f.setError),c=H(f=>f.clearMessages),u=H(f=>f.resetTokens),d=H(f=>f.addMessage),m=H(f=>f.setLatestContextSize);l.useEffect(()=>t?t.onSessionUpdate(y=>{const N=y._meta,v=N?.context_size||y.context_size;if(v!=null){const C=v;re.info("✅ Received context_size from session update",{context_size:C,totalEstimated:C.totalEstimated,isReplay:N?.isReplay}),m(C)}if(y.message&&(re.debug("Session update with message",{message:y.message}),y.message.role!=="tool")){const C=y.message.content.map(M=>M.type==="text"?M.text:"").join(""),$=[];for(const M of y.message.content)if(M.type==="image"){const E=M;E.source?.data?$.push({mimeType:E.source.media_type||"image/png",data:E.source.data}):E.data&&$.push({mimeType:E.mimeType||"image/png",data:E.data})}const B=H.getState().messages,D=B[B.length-1],I=N?.isReplay===!0;if(y.message.role==="assistant"&&D?.role==="assistant"&&C&&I)re.debug("Appending replay text to existing assistant message",{existingLength:D.content.length,appendingLength:C.length}),H.getState().updateMessage(D.id,{content:D.content+C});else if(y.message.role==="assistant"&&D?.role==="assistant"&&D.content===""&&C)re.debug("Appending text to existing empty assistant message"),H.getState().updateMessage(D.id,{content:D.content+C});else{const M={id:y.message.id,role:y.message.role,content:C,timestamp:y.message.timestamp,isStreaming:!1,...$.length>0?{images:$}:{}};d(M)}}}):void 0,[t,d,m]);const p=l.useCallback(async()=>{if(!t){a("No client available");return}try{r("connecting"),a(null),await t.connect();const f=t.getCurrentSession();f?.id&&i(f.id),r("connected")}catch(f){re.error("Failed to connect",{error:f instanceof Error?f.message:String(f)});const y=f instanceof Error?f.message:String(f);a(y),r("error")}},[t,r,i,a]),g=l.useCallback(async f=>{if(!t){a("No client available");return}try{r("connecting"),a(null),c(),u();const y=await t.loadSession(f);i(y),r("connected"),re.info("Session loaded successfully",{sessionId:y})}catch(y){re.warn("Failed to load session, creating new one instead",{sessionId:f,error:y instanceof Error?y.message:String(y)});try{await p();const N=await t.startSession();i(N),c(),u(),Lt(N,!0),re.info("Created new session after failed load",{sessionId:N})}catch(N){const v=N instanceof Error?N.message:String(N);a(`Failed to load or create session: ${v}`),r("error")}}},[t,r,i,a,c,u,p]),x=l.useCallback(async()=>{if(!t)return a("No client available"),null;try{const f=await t.startSession();return i(f),H.getState().messages.length===0&&(c(),u()),Lt(f,!1),f}catch(f){const y=f instanceof Error?f.message:String(f);return a(y),null}},[t,i,a,c,u]),h=l.useCallback(async()=>{if(t)try{await t.disconnect(),r("disconnected"),i(null)}catch(f){const y=f instanceof Error?f.message:String(f);a(y)}},[t,r,i,a]);return l.useEffect(()=>{!t||n!=="disconnected"||(s?(re.info("Loading initial session from URL",{sessionId:s}),g(s)):p())},[t,n,s,p,g]),{connectionStatus:n,sessionId:o,connect:p,loadSession:g,startSession:x,disconnect:h}}const Z=me("use-chat-messages","debug");function hn(t,s){const n=H(I=>I.messages),o=H(I=>I.isStreaming),r=H(I=>I.sessionId),i=H(I=>I.setIsStreaming),a=H(I=>I.setStreamingStartTime),c=H(I=>I.addMessage),u=H(I=>I.updateMessage),d=H(I=>I.setError),m=H(I=>I.setLatestContextSize),p=H(I=>I.addToolCall),g=H(I=>I.updateToolCall),x=H(I=>I.addToolCallToCurrentMessage),h=H(I=>I.updateToolCallInCurrentMessage),f=H(I=>I.addHookNotificationToCurrentMessage),y=H(I=>I.addSourcesByToolCallId),N=H(I=>I.truncateMessagesFrom),v=l.useRef(null),C=l.useRef(!1),$=l.useCallback(async(I,M,E)=>{if(Z.debug("[sendMessage] Called with",{contentLength:I.length,attachmentsCount:M?.length||0,hasAttachments:!!M&&M.length>0,hasPromptParameters:!!E,promptParameters:E}),!t){Z.error("No client available"),d("No client available");return}let _=r;if(!_){Z.info("Creating new session before sending first message");const Y=await s();if(!Y){Z.error("Failed to create session"),d("Failed to create session");return}_=Y,Z.info("Session created successfully",{sessionId:Y})}const K=je("assistant");try{const Y=Date.now();i(!0),a(Y);const U={id:je("user"),role:"user",content:I,timestamp:new Date().toISOString(),isStreaming:!1,...M&&M.length>0?{images:M.filter(S=>S.mimeType.startsWith("image/")).map(S=>({mimeType:S.mimeType,data:S.data}))}:{}};c(U),typeof window<"u"&&_&&(new URL(window.location.href).searchParams.has("session")||(Z.info("Updating URL with session ID",{sessionId:_}),Lt(_,!1)));const W={id:K,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!0,streamingStartTime:Y};c(W),v.current=K,C.current=!1;const V=t.receiveMessages();t.sendMessage(I,_,M,E).catch(S=>{const P=S instanceof Error?S.message:String(S);d(P),i(!1),a(null)});let T="",k=!1;for await(const S of V){if(C.current){Z.info("Stream cancelled, exiting loop");break}if(S.type==="content"){const P=S._meta,j=P?.context_size||S.context_size;if(j!=null){const O=j;Z.info("✅ Received context_size from backend",{context_size:O,totalEstimated:O.totalEstimated,source:P?.context_size?"_meta":"direct"}),m(O)}else Z.debug("Chunk does not have context_size",{hasContextSize:"context_size"in S,hasMeta:"_meta"in S,metaKeys:P?Object.keys(P):null});if(S.tokenUsage&&Z.debug("Received tokenUsage from backend",{tokenUsage:S.tokenUsage}),S.isComplete){u(K,{content:T,isStreaming:!1,streamingStartTime:void 0,...S.tokenUsage?{tokenUsage:S.tokenUsage}:{}}),i(!1),a(null),v.current=null,k=!0;break}else S.contentDelta.type==="text"&&(T+=S.contentDelta.text,u(K,{content:T,...S.tokenUsage?{tokenUsage:S.tokenUsage}:{}}),document.hidden||await new Promise(O=>setTimeout(O,16)))}else S.type==="tool_call"?(Z.debug("Received tool_call chunk",{chunk:S}),p(_,S.toolCall),x(S.toolCall)):S.type==="tool_call_update"?(Z.debug("Received tool_call_update chunk",{chunk:S}),g(_,S.toolCallUpdate),h(S.toolCallUpdate)):S.type==="hook_notification"?(Z.debug("Received hook_notification chunk",{chunk:S}),f(S.notification)):S.type==="sources"&&(Z.debug("Received sources chunk",{chunk:S}),y(S.sources))}k||(C.current?(Z.info("Stream cancelled by user"),u(K,{content:`${T}
3
3
 
4
4
  [Cancelled]`,isStreaming:!1,streamingStartTime:void 0})):(Z.warn("Stream ended without isComplete flag"),u(K,{isStreaming:!1,streamingStartTime:void 0})),i(!1),a(null),v.current=null)}catch(Y){const U=Y instanceof Error?Y.message:String(Y);d(U),i(!1),a(null),v.current=null,u(K,{isStreaming:!1,streamingStartTime:void 0})}},[t,r,s,c,u,i,a,d,m,p,g,x,h,f,y]),B=l.useCallback(async()=>{if(!t||!o){Z.debug("Cannot cancel: not streaming or no client");return}Z.info("Cancelling current turn"),C.current=!0;try{await t.cancel(r||void 0)}catch(I){Z.error("Error cancelling turn",{error:I})}},[t,o,r]),D=l.useCallback(async(I,M,E)=>{if(Z.debug("[editAndResend] Called with",{userMessageIndex:I,contentLength:M.length,attachmentsCount:E?.length||0}),!t){Z.error("No client available"),d("No client available");return}if(!r){Z.error("No session available"),d("No session available");return}let _=0,K=-1;for(let W=0;W<n.length;W++)if(n[W]?.role==="user"){if(_===I){K=W;break}_++}if(K===-1){Z.error("User message not found",{userMessageIndex:I,totalUserMessages:_}),d("User message not found");return}const Y=n[K];Z.debug("[editAndResend] Found target message",{userMessageIndex:I,targetArrayIndex:K,messageRole:Y?.role});const U=je("assistant");try{const W=Date.now();i(!0),a(W),N(K);const V={id:je("user"),role:"user",content:M,timestamp:new Date().toISOString(),isStreaming:!1,...E&&E.length>0?{images:E.filter(j=>j.mimeType.startsWith("image/")).map(j=>({mimeType:j.mimeType,data:j.data}))}:{}};c(V);const T={id:U,role:"assistant",content:"",timestamp:new Date().toISOString(),isStreaming:!0,streamingStartTime:W};c(T),v.current=U,C.current=!1;const k=t.receiveMessages();t.editAndResend(I,M,r,E).catch(j=>{const O=j instanceof Error?j.message:String(j);d(O),i(!1),a(null)});let S="",P=!1;for await(const j of k){if(C.current){Z.info("Stream cancelled, exiting loop");break}if(j.type==="content"){const Q=j._meta?.context_size||j.context_size;if(Q!=null){const z=Q;Z.info("✅ Received context_size from backend",{context_size:z,totalEstimated:z.totalEstimated}),m(z)}if(j.isComplete){u(U,{content:S,isStreaming:!1,streamingStartTime:void 0,...j.tokenUsage?{tokenUsage:j.tokenUsage}:{}}),i(!1),a(null),v.current=null,P=!0;break}else j.contentDelta.type==="text"&&(S+=j.contentDelta.text,u(U,{content:S,...j.tokenUsage?{tokenUsage:j.tokenUsage}:{}}),document.hidden||await new Promise(z=>setTimeout(z,16)))}else j.type==="tool_call"?(Z.debug("Received tool_call chunk",{chunk:j}),p(r,j.toolCall),x(j.toolCall)):j.type==="tool_call_update"?(Z.debug("Received tool_call_update chunk",{chunk:j}),g(r,j.toolCallUpdate),h(j.toolCallUpdate)):j.type==="hook_notification"?(Z.debug("Received hook_notification chunk",{chunk:j}),f(j.notification)):j.type==="sources"&&(Z.debug("Received sources chunk",{chunk:j}),y(j.sources))}P||(C.current?(Z.info("Stream cancelled by user"),u(U,{content:`${S}