@aria-cli/cli 1.0.15 → 1.0.19

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/config.js CHANGED
@@ -1 +1 @@
1
- import{ua as a,va as b,wa as c,xa as d,ya as e}from"./index-nnqfqvqh.js";import"./index-9j6r3gr8.js";export{e as saveConfig,d as loadConfig,c as loadAndMigrateConfig,b as getConfigPath,a as getAriaDir};
1
+ import{createRequire as Z}from"node:module";var R=Object.defineProperty;var U=(k)=>k;function W(k,b){this[k]=U.bind(null,b)}var X=(k,b)=>{for(var q in b)R(k,q,{get:b[q],enumerable:!0,configurable:!0,set:W.bind(b,q)})};var Y=(k,b)=>()=>(k&&(b=k(k=0)),b);var N=Z(import.meta.url);var p={};X(p,{saveConfig:()=>F,loadConfig:()=>j,loadAndMigrateConfig:()=>Q,getConfigPath:()=>H,getAriaDir:()=>G});import*as x from"fs";import*as O from"os";import{getModelById as _,getModelByShortName as $,isValidTier as L}from"@aria-cli/models";import{log as z}from"@aria-cli/types";function G(){if(process.env.ARIA_HOME)return process.env.ARIA_HOME;return`${process.env.HOME||O.homedir()}/.aria`}function H(){return`${G()}/config.json`}function Q(){try{let k=H();if(x.existsSync(k)){let b=JSON.parse(x.readFileSync(k,"utf-8"));try{if(b.defaultModel&&!b.preferredTier){let J=_(b.defaultModel)||$(b.defaultModel);if(!J)z.warn(`Unknown model "${b.defaultModel}" migrated to balanced tier (Sonnet 4.5)`);let K=J?.tier||"balanced";b.preferredTier=L(K)?K:"balanced",delete b.defaultModel,F(b)}if(b.preferredTier!==void 0&&!L(b.preferredTier))z.warn(`Invalid tier "${b.preferredTier}" corrected to balanced tier`),b.preferredTier="balanced",F(b);let q=!1;if(!b.awsRegion&&process.env.AWS_REGION)b.awsRegion=process.env.AWS_REGION,q=!0;if(!b.awsProfile&&process.env.AWS_PROFILE)b.awsProfile=process.env.AWS_PROFILE,q=!0;if(q)F(b)}catch(q){z.warn("Config migration failed, using config as-is:",q instanceof Error?q.message:q)}return b}}catch(k){z.warn("[Config] Failed to load config file:",k)}return{}}function F(k){let b=G();if(!x.existsSync(b))x.mkdirSync(b,{recursive:!0});x.writeFileSync(H(),JSON.stringify(k,null,2),"utf-8")}var j;var u=Y(()=>{j=Q});u();export{F as saveConfig,j as loadConfig,Q as loadAndMigrateConfig,H as getConfigPath,G as getAriaDir};
@@ -1 +1,4 @@
1
- import{k as a}from"./index-j035n0mr.js";import"./index-9j6r3gr8.js";export{a as ensureDaemon};
1
+ import{createRequire as KB}from"node:module";var FB=Object.defineProperty;var UB=(B)=>B;function bB(B,$){this[B]=UB.bind(null,$)}var T=(B,$)=>{for(var z in $)FB(B,z,{get:$[z],enumerable:!0,configurable:!0,set:bB.bind($,z)})};var y=(B,$)=>()=>(B&&($=B(B=0)),$);var H=KB(import.meta.url);var jB={};T(jB,{saveConfig:()=>E,loadConfig:()=>PB,loadAndMigrateConfig:()=>c,getConfigPath:()=>x,getAriaDir:()=>I});import*as P from"fs";import*as d from"os";import{getModelById as RB,getModelByShortName as qB,isValidTier as u}from"@aria-cli/models";import{log as A}from"@aria-cli/types";function I(){if(process.env.ARIA_HOME)return process.env.ARIA_HOME;return`${process.env.HOME||d.homedir()}/.aria`}function x(){return`${I()}/config.json`}function c(){try{let B=x();if(P.existsSync(B)){let $=JSON.parse(P.readFileSync(B,"utf-8"));try{if($.defaultModel&&!$.preferredTier){let Z=RB($.defaultModel)||qB($.defaultModel);if(!Z)A.warn(`Unknown model "${$.defaultModel}" migrated to balanced tier (Sonnet 4.5)`);let J=Z?.tier||"balanced";$.preferredTier=u(J)?J:"balanced",delete $.defaultModel,E($)}if($.preferredTier!==void 0&&!u($.preferredTier))A.warn(`Invalid tier "${$.preferredTier}" corrected to balanced tier`),$.preferredTier="balanced",E($);let z=!1;if(!$.awsRegion&&process.env.AWS_REGION)$.awsRegion=process.env.AWS_REGION,z=!0;if(!$.awsProfile&&process.env.AWS_PROFILE)$.awsProfile=process.env.AWS_PROFILE,z=!0;if(z)E($)}catch(z){A.warn("Config migration failed, using config as-is:",z instanceof Error?z.message:z)}return $}}catch(B){A.warn("[Config] Failed to load config file:",B)}return{}}function E(B){let $=I();if(!P.existsSync($))P.mkdirSync($,{recursive:!0});P.writeFileSync(x(),JSON.stringify(B,null,2),"utf-8")}var PB;var a=y(()=>{PB=c});import{RuntimeBootstrapRecordSchema as V$}from"@aria-cli/tools";function yB(B){return B==="control_ready"||B==="network_ready"||B==="mesh_ready"}function l(B,$){if($.nodeId!==B)throw Error(`[local-control-client] Runtime bootstrap node mismatch for ${B}: received ${$.nodeId}`);if(!yB($.phase))throw Error(`[local-control-client] Runtime bootstrap for ${B} is not attachable (phase=${$.phase})`);return $}var p=()=>{};async function HB(){let B=I();if(S?.ariaDir===B)return S.handler;let{CentralErrorHandler:$}=await import("@aria-cli/aria/error-handler"),z=new $({ariaDir:B});return S={ariaDir:B,handler:z},z}async function s(B,$){await(await HB()).report(B,{workingDir:process.cwd(),providerState:{lastProvider:"trusted-local-control",lastModel:$.endpoint,...typeof $.responseStatus==="number"?{lastStatusCode:$.responseStatus}:{}},configSnapshot:{transport:$.transport,endpoint:$.endpoint,...typeof $.responseStatus==="number"?{responseStatus:$.responseStatus}:{},payload:$.payload}})}var S;var i=y(()=>{a()});var XB={};T(XB,{resolveLocalControlClientSync:()=>v,resolveLocalControlClient:()=>N,requestRuntimeSocketLease:()=>w,createResilientAttachedClient:()=>L,attachLocalControlClient:()=>h,attachExistingLocalControlClient:()=>C});import*as o from"node:net";import{appendFileSync as OB,mkdirSync as MB}from"node:fs";import{join as BB}from"node:path";import{randomUUID as TB}from"node:crypto";import{createRuntimeSocketAttachedLocalControlClient as $B,createRuntimeSocketLocalControlClient as IB,createTrustedRuntimeError as DB,AttachedClientLeaseGrantSchema as NB,LocalControlSocketAttachClientRequestSchema as AB,LocalControlSocketAttachClientResponseSchema as EB,LocalControlSocketRequestSchema as kB,LocalControlSocketResponseSchema as wB}from"@aria-cli/tools";async function zB(B){await new Promise(($)=>setTimeout($,Math.max(B,0)))}function SB(){return r??=import("@aria-cli/server/runtime/host-supervisor"),r}function fB(){return n??=import("@aria-cli/server/runtime/node-metadata"),n}function CB(){return t??=import("@aria-cli/server/runtime/node-store"),t}async function QB(B){let{resolveOrCreateNode:$}=await fB();return $({ariaHome:B})}async function k(B,$){let{NodeStore:z}=await CB(),Z=new z({ariaHome:B});try{return Z.readRuntimeOwnerRecord($)}finally{Z.close()}}function f(B){if(!(B instanceof Error))return!1;let $=B.message;return $.includes("connect ENOENT")||$.includes("ECONNREFUSED")||$.includes("Missing runtime owner record")||$.includes("not attachable")||$.includes("not control-ready")}async function D(B){let $=await k(B.ariaHome,B.nodeId);if(!$)throw Error(`[local-control-client] Missing runtime owner record for node ${B.nodeId}`);let z=hB({runtimeSocket:$.runtimeSocket,pollIntervalMs:B.pollIntervalMs}),Z=l(B.nodeId,await z.getRuntimeBootstrap()),J,G,X;if(B.clientKind)X=await L({runtimeSocket:$.runtimeSocket,clientKind:B.clientKind,logDir:BB(B.ariaHome,"logs")}),J=X.getClientId(),G=X.getClientAuthToken();let Q=null;return{nodeId:B.nodeId,runtimeId:Z.runtimeId,port:Z.controlEndpoint.port,ownership:B.ownership,...J?{attachedClientId:J}:{},...G?{attachedClientAuthToken:G}:{},control:X?X.api:z,release:async(W)=>{if(Q)return Q;return Q=(async()=>{let U=X;X=void 0,J=void 0,G=void 0,await U?.release().catch(()=>{}),await B.release(W)})(),Q}}}async function w(B,$){let z=kB.parse({id:TB(),method:"attachClient",payload:$});return new Promise((Z,J)=>{let G=o.createConnection(B),X="",Q=!1,W=!1,U,K=new Promise((q)=>{U=q}),b=()=>{if(W)return;if(W=!0,U?.(),!Q)Q=!0,J(Error("Local control socket closed before establishing an attached-client lease"))};G.setEncoding("utf8"),G.once("connect",()=>{G.write(`${JSON.stringify(z)}
2
+ `)}),G.once("error",(q)=>{if(!Q){Q=!0,J(q);return}b()}),G.once("end",b),G.once("close",b),G.on("data",async(q)=>{X+=q;let M=X.indexOf(`
3
+ `);if(M===-1||Q)return;try{let V=wB.parse(JSON.parse(X.slice(0,M)));if(V.id!==z.id){Q=!0,G.destroy(),J(Error("Local control socket response ID mismatch"));return}if(!V.ok){let F=DB(V.error,V.diagnostic);await s(F,{endpoint:"attachClient",responseStatus:null,payload:V,transport:"runtime_socket_attach"}),Q=!0,G.destroy(),J(F);return}let Y=NB.parse(EB.parse(V.payload));Q=!0,Z({clientId:Y.clientId,clientAuthToken:Y.clientAuthToken,release:async()=>{if(!W)G.destroy();await K}})}catch(V){Q=!0,G.destroy(),J(V)}})})}async function C(B){let $=await QB(B.ariaHome);if(!await k(B.ariaHome,$.nodeId))return null;let z=Date.now()+LB;while(Date.now()<z)try{return await D({ariaHome:B.ariaHome,nodeId:$.nodeId,ownership:"reattached",release:async()=>{},pollIntervalMs:B.pollIntervalMs,clientKind:B.clientKind})}catch(Z){if(!f(Z))throw Z;if(!await k(B.ariaHome,$.nodeId))return null;await zB(xB)}return null}function hB(B){if(B.auth)return $B({runtimeSocket:B.runtimeSocket,pollIntervalMs:B.pollIntervalMs,auth:B.auth});return IB(B)}async function h(B){let $=async(X,Q)=>{let W=B.pollIntervalMs??100,U=Date.now()+Math.max(W*20,2000),K=null;while(Date.now()<U){if(B.signal?.aborted)throw Error(`[local-control-client] Attach-only client ${Q} aborted while waiting for a live runtime owner on node ${X}`);try{if(!await k(B.ariaHome,X))K=Error(`[local-control-client] No live runtime owner available for attach-only client ${Q} on node ${X}`);else return await D({ariaHome:B.ariaHome,nodeId:X,ownership:"reattached",release:async()=>{},pollIntervalMs:B.pollIntervalMs,clientKind:Q})}catch(b){if(!f(b))throw b;K=b}await zB(W)}throw K??Error(`[local-control-client] No live runtime owner available for attach-only client ${Q} on node ${X}`)},{getHostSupervisor:z,HostSupervisorSplitBrainError:Z}=await SB(),J=z(),G;try{G=await J.attach({ariaHome:B.ariaHome,arionName:B.arionName,clientKind:B.clientKind,memoriaFactory:B.memoriaFactory,router:B.router,authResolver:B.authResolver,runSessionConfig:B.runSessionConfig,mcpServers:B.mcpServers,daemonSafetyPolicy:B.daemonSafetyPolicy,autonomousIntervalMs:B.autonomousIntervalMs,signal:B.signal,silent:B.silent,runtimeLifecycle:B.runtimeLifecycle,port:B.port})}catch(X){if(X instanceof Z)return D({ariaHome:B.ariaHome,nodeId:X.nodeId,ownership:"reattached",release:async()=>{},pollIntervalMs:B.pollIntervalMs,clientKind:B.clientKind});throw X}try{return await G.runtime.waitForInitialDiscovery(),await D({ariaHome:B.ariaHome,nodeId:G.nodeId,ownership:G.ownership,pollIntervalMs:B.pollIntervalMs,clientKind:B.clientKind,release:(X)=>G.release(X)})}catch(X){throw await G.release(),X}}async function N(B){let $=await QB(B.ariaHome);try{return(await D({ariaHome:B.ariaHome,nodeId:$.nodeId,ownership:"reattached",release:async()=>{},pollIntervalMs:B.pollIntervalMs})).control}catch(z){if(f(z))return null;throw z}}function v(B){return null}function O(B){if(!(B instanceof Error))return!1;let $=B.message;if($.includes("attached-local-client-only"))return!0;if($.includes("ECONNRESET"))return!0;if($.includes("ECONNREFUSED"))return!0;if($.includes("EPIPE"))return!0;if($.includes("connect ENOENT"))return!0;if($.includes("socket hang up"))return!0;if($.includes("closed before"))return!0;return!1}function e(B){if(B<=0)return Promise.resolve();return new Promise(($)=>{setTimeout($,B).unref?.()})}async function L(B){let{runtimeSocket:$,clientKind:z="local-api"}=B,Z=!1,J,G,X=null,Q=null,W=(V)=>{if(!B.logDir)return;try{MB(B.logDir,{recursive:!0}),OB(BB(B.logDir,"reattach.jsonl"),JSON.stringify({ts:new Date().toISOString(),pid:process.pid,...V})+`
4
+ `)}catch{}};async function U(){if(Q)await Q().catch(()=>{}),Q=null;let V=await w($,AB.parse({clientKind:z,lease:!0,pid:process.pid,displayName:B.displayName}));J=V.clientId,G=V.clientAuthToken,Q=()=>V.release(),X=$B({runtimeSocket:$,auth:{clientId:V.clientId,clientAuthToken:V.clientAuthToken}}),W({event:"lease_acquired",clientId:V.clientId})}await U();async function K(V,Y){if(Z)throw Error("ResilientAttachedClient has been released");try{return await Y(X)}catch(F){if(!O(F))throw F;W({event:"reattach_start",method:V,error:F.message});for(let _=0;_<j.length;_++){if(Z)throw Error("ResilientAttachedClient has been released");await e(j[_]??0);try{await U();let R=await Y(X);return W({event:"reattach_success",method:V,attempt:_}),R}catch(R){if(W({event:"reattach_retry_failed",method:V,attempt:_,error:R.message,willRetry:O(R)&&_<j.length-1}),!O(R)||_===j.length-1)throw R}}throw F}}async function*b(V,Y){if(Z)throw Error("ResilientAttachedClient has been released");try{yield*Y(X);return}catch(F){if(!O(F))throw F;W({event:"reattach_stream_start",method:V,error:F.message});for(let _=0;_<j.length;_++){if(Z)throw Error("ResilientAttachedClient has been released");await e(j[_]??0);try{await U(),yield*Y(X),W({event:"reattach_stream_success",method:V,attempt:_});return}catch(R){if(W({event:"reattach_stream_retry_failed",method:V,attempt:_,error:R.message,willRetry:O(R)&&_<j.length-1}),!O(R)||_===j.length-1)throw R}}}}let q=new Set(["streamRun","subscribeRuntimeEvents","subscribeInbox","subscribePeers","subscribeDirectClientInbox"]);return{api:new Proxy({},{get(V,Y){if(Y==="then"||Y==="catch"||Y==="finally")return;if(q.has(Y))return(...F)=>b(Y,(_)=>_[Y](...F));return(...F)=>K(Y,(_)=>_[Y](...F))}}),getClientId:()=>J,getClientAuthToken:()=>G,release:async()=>{Z=!0;let V=Error("release() caller").stack;if(Q)await Q().catch(()=>{}),Q=null;W({event:"released",clientId:J,releaseStack:V})}}}var LB=1e4,xB=250,r,n,t,j;var g=y(()=>{p();i();j=[0,250,500,1000]});var vB={};T(vB,{resolveLocalControlClientSync:()=>v,resolveLocalControlClient:()=>N,requestRuntimeSocketLease:()=>w,createResilientAttachedClient:()=>L,attachLocalControlClient:()=>h,attachExistingLocalControlClient:()=>C});var ZB=y(()=>{g()});var VB={};T(VB,{createDaemonService:()=>tB});import{spawn as gB}from"node:child_process";import{existsSync as GB,mkdirSync as mB,openSync as uB,closeSync as dB}from"node:fs";import JB from"node:path";import{fileURLToPath as m}from"node:url";function lB(B){return new Promise(($)=>setTimeout($,Math.max(B,0)))}function pB(){let B=m(new URL("../../../server/dist/daemon-launcher.js",import.meta.url));if(GB(B))return{command:process.execPath,args:[B]};try{let z=m(import.meta.resolve("@aria-cli/server/daemon-launcher"));if(GB(z))return{command:process.execPath,args:[z]}}catch{}let $=m(new URL("../../../server/src/daemon-launcher.ts",import.meta.url));return{command:process.execPath,args:["--import","tsx",$]}}function sB(B,$,z){return(typeof z.arion==="string"?z.arion.trim():"")||$||B.config.activeArion?.trim()||"ARIA"}function iB(B){return{...typeof B.intervalMs==="number"?{intervalMs:B.intervalMs}:{},...B.allowedToolCategories||B.allowedShellCommands||typeof B.maxWriteOpsPerMinute==="number"||typeof B.maxGitPushesPerHour==="number"?{safetyPolicy:{...Array.isArray(B.allowedToolCategories)?{allowedToolCategories:B.allowedToolCategories}:{},...Array.isArray(B.allowedShellCommands)?{allowedShellCommands:B.allowedShellCommands}:{},...typeof B.maxWriteOpsPerMinute==="number"?{maxWriteOpsPerMinute:B.maxWriteOpsPerMinute}:{},...typeof B.maxGitPushesPerHour==="number"?{maxGitPushesPerHour:B.maxGitPushesPerHour}:{}}}:{}}}async function rB(B){let $=Date.now()+cB,z=null;while(Date.now()<$){try{let Z=await N({ariaHome:B.ariaHome});if(Z){let J=await Z.getRuntimeStatus();if(!B.requireRunning||J.autonomousLoop.status==="running")return J}}catch(Z){z=Z instanceof Error?Z:Error(String(Z))}await lB(aB)}throw Error(z?.message??"Timed out waiting for the daemon runtime to become reachable")}function nB(B){let $=pB(),z=[...$.args,"--arion",B.arionName];if(typeof B.input.port==="number")z.push("--port",String(B.input.port));if(typeof B.input.intervalMs==="number")z.push("--interval-ms",String(B.input.intervalMs));if(Array.isArray(B.input.allowedToolCategories)&&B.input.allowedToolCategories.length>0)z.push("--allowed-tool-categories",B.input.allowedToolCategories.join(","));if(Array.isArray(B.input.allowedShellCommands)&&B.input.allowedShellCommands.length>0)z.push("--allowed-shell-commands",B.input.allowedShellCommands.join(","));if(typeof B.input.maxWriteOpsPerMinute==="number")z.push("--max-write-ops-per-minute",String(B.input.maxWriteOpsPerMinute));if(typeof B.input.maxGitPushesPerHour==="number")z.push("--max-git-pushes-per-hour",String(B.input.maxGitPushesPerHour));let Z=JB.join(B.ariaHome,"logs");mB(Z,{recursive:!0});let J=uB(JB.join(Z,"daemon-stderr.log"),"a");gB($.command,z,{cwd:B.cwd,env:{...process.env,ARIA_HOME:B.ariaHome},detached:!0,stdio:["ignore","ignore",J]}).unref(),dB(J)}function tB(B){let $=B.cli.ariaDir,z=!1,Z=()=>B.getArionName?.()??B.arionName??"ARIA",J=(X)=>{let Q=typeof X.arion==="string"?X.arion.trim():"",W=Z();if(Q&&Q!==W)throw Error(`daemon operations are scoped to ${W}; switch scope with arion.become before targeting ${Q}`);return Q||W},G=async()=>{if(!B.localControl)return null;try{return await B.localControl.getRuntimeStatus(),B.localControl}catch{return null}};return{async start(X){let Q=sB(B.cli,J(X),X),W=await G();if(!W)return z=!0,nB({ariaHome:$,cwd:B.cwd,arionName:Q,input:X}),rB({ariaHome:$,requireRunning:!0});let U=await W.getRuntimeStatus();if(U.autonomousLoop.status==="running")return z=!1,U;if(!W.startAutonomousLoop)throw Error("Live runtime does not expose autonomous-loop start control");return z=!0,W.startAutonomousLoop(iB(X))},async status(X={}){J(X);let Q=await G();if(!Q)throw Error("No live runtime is available for daemon.status");return Q.getRuntimeStatus()},async stop(X={}){J(X);let Q=await G();if(!Q)throw Error("No live runtime is available for daemon.stop");if(!Q.stopAutonomousLoop)throw Error("Live runtime does not expose autonomous-loop stop control");return z=!1,Q.stopAutonomousLoop()},shouldStopOnShutdown(){return z},async releaseAll(){}}}var cB=15000,aB=250;var WB=y(()=>{ZB()});var $$={};T($$,{ensureDaemon:()=>B$});import _B from"node:path";function eB(B){try{return process.kill(B,0),!0}catch{return!1}}function YB(B){return(async()=>{try{let{resolveRuntimeRootDirectory:$,findRuntimeOwnerRecordByAriaHome:z,removeRuntimeOwnerRecord:Z}=await import("@aria-cli/server"),J=$(),G=z(J,B);if(!G?.runtimeSocket)return null;if(!eB(G.runtimePid))return Z(J,G.nodeId),null;let{createResilientAttachedClient:X}=await Promise.resolve().then(() => (g(),XB)),Q=await X({runtimeSocket:G.runtimeSocket,clientKind:"local-api",logDir:_B.join(B,"logs")});try{let W=await Q.api.getRuntimeBootstrap();if(!oB.has(W.phase))return await Q.release(),Z(J,G.nodeId),null}catch{return await Q.release(),null}return{control:Q.api,release:()=>Q.release()}}catch{return null}})()}async function B$(B){let $=await YB(B.ariaDir);if($)return $;let{createDaemonService:z}=await Promise.resolve().then(() => (WB(),VB)),Z=B.config.activeArion??"ARIA";await z({cli:B,cwd:process.cwd(),arionName:Z}).start({});let{resolveRuntimeRootDirectory:G}=await import("@aria-cli/server"),X=G(),Q=_B.join(X,"owners"),W=Date.now()+15000,U=null,K=null;try{let{watch:b,mkdirSync:q,existsSync:M}=await import("node:fs");if(!M(Q))q(Q,{recursive:!0,mode:448});try{U=b(Q,()=>K?.()),U.on("error",()=>{})}catch{}let V=50;while(Date.now()<W){let Y=await YB(B.ariaDir);if(Y)return Y;await new Promise((F)=>{K=F,setTimeout(F,V)}),K=null,V=Math.min(Math.round(V*1.5),200)}}finally{U?.close()}throw Error("Daemon started but socket not reachable. Check ARIA_HOME.")}var oB;var z$=y(()=>{oB=new Set(["control_ready","network_ready","mesh_ready"])});z$();export{B$ as ensureDaemon};
@@ -1 +1,321 @@
1
- import{$ as u,H as a,I as b,J as c,K as d,L as e,M as f,N as g,O as h,P as i,Q as j,R as k,S as l,T as m,U as n,V as o,W as p,X as q,Y as r,Z as s,_ as t}from"../index-76vaj0sr.js";import"../index-9j6r3gr8.js";export{h as toModelMessages,s as replaySessionFromJsonl,q as repairToolCallPairing,t as mergeWithJsonlRecovery,j as fromV1Columns,i as fromModelMessages,u as findJsonlForSession,m as extractToolCalls,o as extractToolCallId,n as extractThinking,l as extractTextContent,d as createUserMessage,e as createSystemMessage,f as createIncomingMessagePair,g as createErrorMessage,k as conversationMessageToHistoryMessages,r as TurnAccumulator,p as SessionHistory,c as ConversationMessageSchema,a as ContentBlockSchema,b as ArionRefSchema};
1
+ import{createRequire as $J}from"node:module";var KJ=Object.defineProperty;var XJ=(J)=>J;function YJ(J,K){this[J]=XJ.bind(null,K)}var ZJ=(J,K)=>{for(var X in K)KJ(J,X,{get:K[X],enumerable:!0,configurable:!0,set:YJ.bind(K,X)})};var D=(J,K)=>()=>(J&&(K=J(J=0)),K);var DJ=$J(import.meta.url);function b(J){N.__aria_stall_phase=J,N.__aria_stall_phase_ts=performance.now()}function z(){N.__aria_stall_phase=void 0,N.__aria_stall_phase_ts=void 0}function MJ(){let{__aria_stall_phase:J,__aria_stall_phase_ts:K}=N;if(!J||typeof K!=="number")return;return{label:J,ageMs:performance.now()-K}}function TJ(J){let K=J.thresholdMs??2000,X=performance.now(),Y=process.cpuUsage(),Z=setInterval(()=>{let W=performance.now(),$=W-X,Q=process.cpuUsage(Y);if(X=W,Y=process.cpuUsage(),$>K)if((Q.user+Q.system)/1000/$<0.05)J.onSleep?.($);else J.onStall($)},500);if(typeof Z==="object"&&Z!==null&&"unref"in Z)Z.unref();return()=>clearInterval(Z)}var yJ=2000,N;var I=D(()=>{N=globalThis});import{z as H}from"zod";import{log as g}from"@aria-cli/types";function M(J){return{id:crypto.randomUUID(),role:"user",content:[{type:"text",text:J}],createdAt:new Date().toISOString()}}function m(J){return{id:crypto.randomUUID(),role:"system",content:[{type:"text",text:J}],createdAt:new Date().toISOString()}}function d(J,K,X,Y){let Z=`synthetic_inbox_${crypto.randomUUID().slice(0,8)}`,W=new Date().toISOString(),$={id:crypto.randomUUID(),role:"assistant",content:[{type:"tool_use",id:Z,name:"check_messages",arguments:{unreadOnly:!0}}],createdAt:W},Q={id:crypto.randomUUID(),role:"tool",content:[{type:"tool_result",toolUseId:Z,content:JSON.stringify({messages:[{id:Y||crypto.randomUUID(),from:J,address:K,content:X,type:"incoming"}]}),status:"success"}],createdAt:W};return[$,Q]}function c(J,K){return{id:crypto.randomUUID(),role:"system",content:[{type:"error",content:J,...K?{suggestion:K}:{}}],createdAt:new Date().toISOString()}}function w(J){let K=[];for(let X of J)switch(X.role){case"assistant":{let Y=[],Z=[];for(let $ of X.content)if($.type==="text")Y.push($.text);else if($.type==="tool_use")Z.push({id:$.id,name:$.name,arguments:$.arguments,...$.thoughtSignature?{thoughtSignature:$.thoughtSignature}:{}});let W={role:"assistant",content:Y.join("")};if(Z.length>0)W.toolCalls=Z;K.push(W);break}case"tool":{for(let Y of X.content)if(Y.type==="tool_result")K.push({role:"tool",content:Y.content,toolCallId:Y.toolUseId});break}case"user":case"system":{let Y=[];for(let Z of X.content)if(Z.type==="text")Y.push(Z.text);K.push({role:X.role,content:Y.join("")});break}}return K}function a(J,K){let X=[];for(let Y of J){let Z=[],W=Y;if(W.thinking)for(let $ of W.thinking){let Q=$.thinking?$.thinking.split(/\s+/).filter(Boolean).length:0;Z.push({type:"thinking",content:$.thinking,wordCount:Q})}if(Y.role==="assistant"&&Y.toolCalls){if(Y.content)Z.push({type:"text",text:Y.content});for(let $ of Y.toolCalls)Z.push({type:"tool_use",id:$.id,name:$.name,arguments:$.arguments,...$.thoughtSignature?{thoughtSignature:$.thoughtSignature}:{}})}else if(Y.role==="tool")Z.push({type:"tool_result",toolUseId:Y.toolCallId??"",content:Y.content,status:"success"});else if(Y.content)Z.push({type:"text",text:Y.content});if(Z.length===0)Z.push({type:"text",text:""});X.push({id:crypto.randomUUID(),role:Y.role,content:Z,arion:K?.arion,createdAt:new Date().toISOString()})}return X}function j(J){let K=[];if(J.thinking)try{let X=JSON.parse(J.thinking);for(let Y of X)K.push({type:"thinking",content:Y.content??"",wordCount:Y.wordCount??0})}catch{g.warn(`[fromV1Columns] Corrupted thinking JSON in message row ${J.id} (session ${J.session_id}), skipping`)}if(J.tool_calls)try{let X=JSON.parse(J.tool_calls);for(let Y of X)K.push({type:"tool_use",id:Y.id,name:Y.name,arguments:Y.arguments??{},...Y.thoughtSignature?{thoughtSignature:Y.thoughtSignature}:{}})}catch{g.warn(`[fromV1Columns] Corrupted tool_calls JSON in message row ${J.id} (session ${J.session_id}), skipping`)}if(J.role==="tool"&&J.tool_call_id)K.push({type:"tool_result",toolUseId:J.tool_call_id,content:J.content,status:"success"});if(J.role!=="tool"&&J.content)K.push({type:"text",text:J.content});return{id:crypto.randomUUID(),role:J.role,content:K.length>0?K:[{type:"text",text:J.content??""}],arion:J.arion?{name:J.arion,emoji:"",color:void 0}:void 0,createdAt:J.created_at}}function l(J){let K=[];for(let X of J)for(let Y of X.content)switch(Y.type){case"thinking":K.push({id:`thinking-${crypto.randomUUID()}`,role:"thinking_history",content:Y.content,wordCount:Y.wordCount,durationSeconds:Y.durationMs?Y.durationMs/1000:void 0,verb:Y.verb,arionName:X.arion?.name,arionEmoji:X.arion?.emoji,arionColor:X.arion?.color});break;case"tool_use":K.push({id:`tool-${crypto.randomUUID()}`,role:"tool_history",tool:{id:Y.id,name:Y.name,status:"complete",args:Y.arguments,result:void 0,startTime:void 0,endTime:void 0}});break;case"tool_result":{let Z;for(let W=K.length-1;W>=0;W--){let $=K[W];if($.role==="tool_history"&&$.tool.id===Y.toolUseId){Z=$;break}}if(Z){if(Z.tool.status=Y.status==="error"?"error":"complete",Y.status==="error")Z.tool.error=Y.content;else Z.tool.result=Y.content;if(Y.resultData!==void 0)Z.tool.resultData=Y.resultData;if(Y.durationMs!==void 0)Z.tool.durationMs=Y.durationMs;if(Y.usage!==void 0)Z.tool.usage=Y.usage}break}case"handoff":K.push({id:`handoff-${crypto.randomUUID()}`,role:"handoff_history",target:Y.target,direction:Y.direction});break;case"error":K.push({id:`error-${crypto.randomUUID()}`,role:"error",content:Y.content,suggestion:Y.suggestion});break;case"text":K.push({id:`msg-${crypto.randomUUID()}`,role:X.role,content:Y.text,arion:X.arion?{name:X.arion.name,emoji:X.arion.emoji,color:X.arion.color}:void 0});break}return K}function _(J){return J.content.filter((K)=>K.type==="text").map((K)=>K.text).join("")}function B(J){let K=J.content.filter((X)=>X.type==="tool_use");if(K.length===0)return null;return JSON.stringify(K.map((X)=>({id:X.id,name:X.name,arguments:X.arguments,...X.thoughtSignature?{thoughtSignature:X.thoughtSignature}:{}})))}function L(J){let K=J.content.filter((X)=>X.type==="thinking");if(K.length===0)return null;return JSON.stringify(K.map((X)=>({id:crypto.randomUUID(),content:X.content,wordCount:X.wordCount})))}function U(J){for(let K of J.content)if(K.type==="tool_result")return K.toolUseId;return null}var WJ,HJ,QJ,VJ,FJ,GJ,x,OJ,h,y;var T=D(()=>{WJ=H.object({type:H.literal("text"),text:H.string()}),HJ=H.object({type:H.literal("thinking"),content:H.string(),wordCount:H.number(),durationMs:H.number().optional(),verb:H.string().optional()}),QJ=H.object({type:H.literal("tool_use"),id:H.string(),name:H.string(),arguments:H.record(H.string(),H.unknown()),thoughtSignature:H.string().optional()}),VJ=H.object({type:H.literal("tool_result"),toolUseId:H.string(),content:H.string(),status:H.enum(["success","error"]),durationMs:H.number().optional(),resultData:H.unknown().optional(),usage:H.object({inputTokens:H.number(),outputTokens:H.number(),totalTokens:H.number(),estimatedCost:H.number()}).optional()}),FJ=H.object({type:H.literal("handoff"),target:H.string(),direction:H.enum(["to","from"])}),GJ=H.object({type:H.literal("error"),content:H.string(),suggestion:H.string().optional()}),x=H.discriminatedUnion("type",[WJ,HJ,QJ,VJ,FJ,GJ]),OJ=["cyan","magenta","yellow","green","blue","red","white"],h=H.object({name:H.string(),emoji:H.string(),color:H.enum(OJ).optional()}),y=H.object({id:H.string(),role:H.enum(["user","assistant","system","tool"]),content:H.array(x),arion:h.optional(),costUSD:H.number().optional(),durationMs:H.number().optional(),tokenUsage:H.object({input:H.number(),output:H.number()}).optional(),createdAt:H.string()})});import EJ from"better-sqlite3";import i from"node:crypto";import{existsSync as A,copyFileSync as NJ,mkdirSync as f,readdirSync as jJ}from"node:fs";import S from"node:path";import{log as O}from"@aria-cli/types";class v{db;sessionFtsEnabled=!1;incrementalSessions=new Set;static resolvePerArionPath(J,K){let X=S.join(J,"arions",K),Y=S.join(X,"history.db");if(!A(Y))f(X,{recursive:!0});return Y}static migrateJsonlLogs(J,K){let X=S.join(J,"arions",K,"logs"),Y=S.join(J,"logs");if(!A(X)&&A(Y)){f(X,{recursive:!0});try{let Z=jJ(Y).filter((W)=>W.endsWith(".jsonl"));for(let W of Z){let $=S.join(Y,W),Q=S.join(X,W);if(!A(Q))NJ($,Q)}}catch{}}if(!A(X))f(X,{recursive:!0});return X}constructor(J){this.db=new EJ(J),this.db.pragma("journal_mode = WAL"),this.db.pragma("busy_timeout = 5000"),this.db.pragma("foreign_keys = ON"),this.initialize()}initialize(){this.db.exec(`
2
+ CREATE TABLE IF NOT EXISTS sessions (
3
+ id TEXT PRIMARY KEY,
4
+ created_at TEXT NOT NULL,
5
+ updated_at TEXT NOT NULL,
6
+ completed_at TEXT,
7
+ title TEXT,
8
+ arion TEXT NOT NULL,
9
+ model TEXT NOT NULL,
10
+ message_count INTEGER DEFAULT 0
11
+ );
12
+
13
+ CREATE TABLE IF NOT EXISTS messages (
14
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
15
+ session_id TEXT NOT NULL,
16
+ role TEXT NOT NULL,
17
+ content TEXT NOT NULL,
18
+ arion TEXT,
19
+ created_at TEXT NOT NULL,
20
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
21
+ );
22
+
23
+ CREATE TABLE IF NOT EXISTS input_history (
24
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
25
+ content TEXT NOT NULL UNIQUE,
26
+ used_at TEXT NOT NULL
27
+ );
28
+
29
+ CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
30
+ CREATE INDEX IF NOT EXISTS idx_sessions_updated ON sessions(updated_at DESC);
31
+ CREATE INDEX IF NOT EXISTS idx_input_history_used ON input_history(used_at DESC);
32
+ `);try{this.db.exec("ALTER TABLE sessions ADD COLUMN completed_at TEXT")}catch(J){if(!(J?.message??"").includes("duplicate column name"))throw J}try{this.db.exec("ALTER TABLE messages ADD COLUMN tool_call_id TEXT")}catch(J){if(!(J?.message??"").includes("duplicate column name"))throw J}try{this.db.exec("ALTER TABLE messages ADD COLUMN tool_calls TEXT")}catch(J){if(!(J?.message??"").includes("duplicate column name"))throw J}try{this.db.exec("ALTER TABLE messages ADD COLUMN thinking TEXT")}catch(J){if(!(J?.message??"").includes("duplicate column name"))throw J}try{this.db.exec("ALTER TABLE messages ADD COLUMN data TEXT")}catch(J){if(!(J?.message??"").includes("duplicate column name"))throw J}this.db.exec(`
33
+ CREATE TABLE IF NOT EXISTS run_metrics (
34
+ id TEXT PRIMARY KEY,
35
+ session_id TEXT NOT NULL,
36
+ turn_count INTEGER,
37
+ input_tokens INTEGER,
38
+ output_tokens INTEGER,
39
+ total_tokens INTEGER,
40
+ estimated_cost REAL,
41
+ wall_time_ms INTEGER,
42
+ tool_count INTEGER,
43
+ guardrail_fires INTEGER,
44
+ handoff_count INTEGER,
45
+ created_at TEXT DEFAULT (datetime('now')),
46
+ FOREIGN KEY (session_id) REFERENCES sessions(id)
47
+ );
48
+
49
+ CREATE INDEX IF NOT EXISTS idx_run_metrics_session ON run_metrics(session_id);
50
+ `),this.db.exec(`
51
+ CREATE TABLE IF NOT EXISTS session_runtime_state (
52
+ session_id TEXT PRIMARY KEY,
53
+ state_status TEXT NOT NULL DEFAULT 'idle',
54
+ active_run_id TEXT,
55
+ paused_state_json TEXT,
56
+ policy_snapshot_json TEXT,
57
+ last_event_seq INTEGER NOT NULL DEFAULT 0,
58
+ revision INTEGER NOT NULL DEFAULT 0,
59
+ lease_owner TEXT,
60
+ lease_expires_at TEXT,
61
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
62
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
63
+ );
64
+
65
+ CREATE TABLE IF NOT EXISTS session_interactions (
66
+ interaction_id TEXT PRIMARY KEY,
67
+ session_id TEXT NOT NULL,
68
+ request_id TEXT NOT NULL,
69
+ source TEXT NOT NULL,
70
+ kind TEXT NOT NULL,
71
+ status TEXT NOT NULL,
72
+ prompt_json TEXT NOT NULL,
73
+ response_json TEXT,
74
+ created_at TEXT NOT NULL,
75
+ answered_at TEXT,
76
+ applied_at TEXT,
77
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
78
+ );
79
+
80
+ CREATE INDEX IF NOT EXISTS idx_session_runtime_state_status
81
+ ON session_runtime_state(state_status, updated_at DESC);
82
+ CREATE INDEX IF NOT EXISTS idx_session_interactions_session
83
+ ON session_interactions(session_id, created_at DESC);
84
+ CREATE INDEX IF NOT EXISTS idx_session_interactions_status
85
+ ON session_interactions(status, created_at DESC);
86
+ `),this.initializeSessionFts();try{this.db.pragma("wal_checkpoint(PASSIVE)")}catch{}}initializeSessionFts(){try{this.db.exec(`
87
+ CREATE VIRTUAL TABLE IF NOT EXISTS fts_session_messages USING fts5(
88
+ message_id UNINDEXED,
89
+ session_id UNINDEXED,
90
+ content
91
+ );
92
+
93
+ CREATE TRIGGER IF NOT EXISTS trg_messages_ai_fts
94
+ AFTER INSERT ON messages BEGIN
95
+ INSERT INTO fts_session_messages (message_id, session_id, content)
96
+ VALUES (new.id, new.session_id, new.content);
97
+ END;
98
+
99
+ CREATE TRIGGER IF NOT EXISTS trg_messages_au_fts
100
+ AFTER UPDATE OF content, session_id ON messages BEGIN
101
+ DELETE FROM fts_session_messages WHERE message_id = old.id;
102
+ INSERT INTO fts_session_messages (message_id, session_id, content)
103
+ VALUES (new.id, new.session_id, new.content);
104
+ END;
105
+
106
+ CREATE TRIGGER IF NOT EXISTS trg_messages_ad_fts
107
+ AFTER DELETE ON messages BEGIN
108
+ DELETE FROM fts_session_messages WHERE message_id = old.id;
109
+ END;
110
+ `);let J=this.db.prepare("SELECT COUNT(*) as c FROM messages").get().c;if(this.db.prepare("SELECT COUNT(*) as c FROM fts_session_messages").get().c<J)this.db.exec(`
111
+ INSERT INTO fts_session_messages (message_id, session_id, content)
112
+ SELECT m.id, m.session_id, m.content
113
+ FROM messages m
114
+ LEFT JOIN fts_session_messages f ON f.message_id = m.id
115
+ WHERE f.message_id IS NULL;
116
+ `);this.sessionFtsEnabled=!0}catch(J){this.sessionFtsEnabled=!1,O.warn("[SessionHistory] Session FTS disabled:",J?.message??String(J))}}toFtsPrefixQuery(J){return J.trim().split(/\s+/).filter(Boolean).map((K)=>`"${K.replace(/"/g,'""')}"*`).join(" AND ")}withImmediateTransaction(J){this.db.exec("BEGIN IMMEDIATE");try{let K=J();return this.db.exec("COMMIT"),K}catch(K){try{this.db.exec("ROLLBACK")}catch{}throw K}}ensureSessionRuntimeRow(J){let K=new Date().toISOString();this.db.prepare(`INSERT INTO session_runtime_state (
117
+ session_id,
118
+ state_status,
119
+ last_event_seq,
120
+ revision,
121
+ updated_at
122
+ ) VALUES (?, 'idle', 0, 0, ?)
123
+ ON CONFLICT(session_id) DO NOTHING`).run(J,K)}readSessionRuntimeStateRow(J){return this.ensureSessionRuntimeRow(J),this.db.prepare("SELECT * FROM session_runtime_state WHERE session_id = ?").get(J)??null}parseJsonColumn(J,K,X){if(!K)return X;try{return JSON.parse(K)}catch{return O.warn(`[SessionHistory] Corrupted ${J} JSON, using fallback value`),X}}toSessionRuntimeState(J){if(!J)return null;return{sessionId:J.session_id,stateStatus:J.state_status,activeRunId:J.active_run_id,pausedState:this.parseJsonColumn("paused_state_json",J.paused_state_json,null),policySnapshot:this.parseJsonColumn("policy_snapshot_json",J.policy_snapshot_json,null),lastEventSeq:J.last_event_seq,revision:J.revision,leaseOwner:J.lease_owner,leaseExpiresAt:J.lease_expires_at,updatedAt:J.updated_at}}toSessionInteractionRecord(J){if(!J)return null;return{interactionId:J.interaction_id,sessionId:J.session_id,requestId:J.request_id,source:J.source,kind:J.kind,status:J.status,prompt:this.parseJsonColumn("prompt_json",J.prompt_json,{}),response:this.parseJsonColumn("response_json",J.response_json,null),createdAt:J.created_at,answeredAt:J.answered_at,appliedAt:J.applied_at}}assertSessionMutationGuard(J,K,X){let Y=Date.now(),Z=J.lease_expires_at?Date.parse(J.lease_expires_at):null;if(K&&J.lease_owner&&J.lease_owner!==K&&Z!==null&&Number.isFinite(Z)&&Z>Y)throw Error(`Session ${J.session_id} is leased by ${J.lease_owner} until ${J.lease_expires_at}`);if(X!==void 0&&J.revision!==X)throw Error(`Session ${J.session_id} revision mismatch: expected ${X}, got ${J.revision}`)}createSession(J,K,X){X??=i.randomUUID();let Y=new Date().toISOString();return this.withImmediateTransaction(()=>{this.db.prepare(`
124
+ INSERT INTO sessions (id, created_at, updated_at, arion, model, message_count)
125
+ VALUES (?, ?, ?, ?, ?, 0)
126
+ `).run(X,Y,Y,J,K),this.db.prepare(`INSERT INTO session_runtime_state (
127
+ session_id,
128
+ state_status,
129
+ last_event_seq,
130
+ revision,
131
+ updated_at
132
+ ) VALUES (?, 'idle', 0, 0, ?)`).run(X,Y)}),X}forkSession(J,K){let X=this.db.prepare("SELECT * FROM sessions WHERE id = ?").get(J);if(!X)throw Error(`Source session not found: ${J}`);let Y=i.randomUUID(),Z=new Date().toISOString(),W=K?.title??(X.title?`\uD83C\uDF74 ${X.title}`:"\uD83C\uDF74 Forked session"),$=K?.messageLimit!==void 0&&K.messageLimit>=0?this.db.prepare("SELECT * FROM messages WHERE session_id = ? ORDER BY id ASC LIMIT ?"):this.db.prepare("SELECT * FROM messages WHERE session_id = ? ORDER BY id ASC"),Q=K?.messageLimit!==void 0&&K.messageLimit>=0?$.all(J,K.messageLimit):$.all(J);return this.withImmediateTransaction(()=>{if(this.db.prepare(`INSERT INTO sessions (id, created_at, updated_at, arion, model, message_count, title)
133
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(Y,Z,Z,X.arion,X.model,Q.length,W),this.db.prepare(`INSERT INTO session_runtime_state (
134
+ session_id, state_status, last_event_seq, revision, updated_at
135
+ ) VALUES (?, 'idle', 0, 0, ?)`).run(Y,Z),Q.length>0){let F=this.db.prepare(`INSERT INTO messages (session_id, role, content, arion, tool_call_id, tool_calls, thinking, data, created_at)
136
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);for(let G of Q)F.run(Y,G.role,G.content,G.arion,G.tool_call_id,G.tool_calls,G.thinking,G.data,G.created_at)}}),{newSessionId:Y,sourceSessionId:J,messagesCopied:Q.length,title:W}}addMessage(J,K,X,Y){try{let Z=new Date().toISOString(),W=Y?.arion??null,$=Y?.toolCallId??null,Q=Y?.toolCalls?JSON.stringify(Y.toolCalls):null,F=Y?.thinking?JSON.stringify(Y.thinking):null;this.db.transaction(()=>{this.db.prepare(`INSERT INTO messages (session_id, role, content, arion, tool_call_id, tool_calls, thinking, created_at)
137
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(J,K,X,W,$,Q,F,Z),this.db.prepare(`UPDATE sessions
138
+ SET updated_at = ?,
139
+ message_count = message_count + 1,
140
+ title = COALESCE(title, CASE WHEN ? = 'user' THEN substr(?, 1, 60) END)
141
+ WHERE id = ?`).run(Z,K,X,J)})()}catch(Z){O.warn("[SessionHistory] Failed to persist message:",Z?.message??Z)}}addConversationMessage(J,K){try{let X=new Date().toISOString(),Y=_(K);if(K.role==="tool"&&!Y){let V=K.content.find((E)=>E.type==="tool_result");if(V&&V.type==="tool_result")Y=V.content}let Z=K.arion?.name??null,W=U(K),$=B(K),Q=L(K),F=JSON.stringify(K);this.db.transaction(()=>{this.db.prepare(`INSERT INTO messages (session_id, role, content, arion, tool_call_id, tool_calls, thinking, data, created_at)
142
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(J,K.role,Y,Z,W,$,Q,F,X),this.db.prepare(`UPDATE sessions
143
+ SET updated_at = ?,
144
+ message_count = message_count + 1,
145
+ title = COALESCE(title, CASE WHEN ? = 'user' THEN substr(?, 1, 60) END)
146
+ WHERE id = ?`).run(X,K.role,Y,J)})(),this.incrementalSessions.add(J)}catch(X){O.warn("[SessionHistory] Failed to persist conversation message:",X?.message??X)}}addConversationMessages(J,K){if(K.length===0)return;if(K.length===1){this.addConversationMessage(J,K[0]);return}try{let X=new Date().toISOString(),Y=this.db.prepare(`INSERT INTO messages (session_id, role, content, arion, tool_call_id, tool_calls, thinking, data, created_at)
147
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`),Z=this.db.prepare(`UPDATE sessions
148
+ SET updated_at = ?,
149
+ message_count = message_count + ?,
150
+ title = COALESCE(title, CASE WHEN ? = 'user' THEN substr(?, 1, 60) END)
151
+ WHERE id = ?`);this.db.transaction(()=>{let $=null;for(let Q of K){let F=_(Q);if(Q.role==="tool"&&!F){let C=Q.content.find((JJ)=>JJ.type==="tool_result");if(C&&C.type==="tool_result")F=C.content}if(Q.role==="user"&&!$)$=F;let G=Q.arion?.name??null,V=U(Q),E=B(Q),P=L(Q),R=JSON.stringify(Q);Y.run(J,Q.role,F,G,V,E,P,R,X)}Z.run(X,K.length,$?"user":"assistant",$??"",J)})()}catch(X){O.warn("[SessionHistory] Failed to persist conversation messages batch:",X?.message??X)}}replaceConversationMessages(J,K){if(this.incrementalSessions.has(J))return;try{let X=performance.now(),Y=this.db.prepare("SELECT COUNT(*) as cnt FROM messages WHERE session_id = ?").get(J)?.cnt??0,Z=performance.now();b(`SessionHistory:replaceConversationMessages(del=${Y},ins=${K.length})`);let W=new Date().toISOString(),$=this.db.prepare(`INSERT INTO messages (session_id, role, content, arion, tool_call_id, tool_calls, thinking, data, created_at)
152
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);this.db.transaction(()=>{this.db.prepare("DELETE FROM messages WHERE session_id = ?").run(J);let G=null;for(let V of K){let E=_(V);if(V.role==="tool"&&!E){let P=V.content.find((R)=>R.type==="tool_result");if(P&&P.type==="tool_result")E=P.content}if(V.role==="user"&&!G)G=E;$.run(J,V.role,E,V.arion?.name??null,U(V),B(V),L(V),JSON.stringify(V),W)}this.db.prepare(`UPDATE sessions
153
+ SET updated_at = ?,
154
+ message_count = ?,
155
+ title = CASE
156
+ WHEN ? IS NOT NULL AND length(?) > 0 THEN substr(?, 1, 60)
157
+ ELSE title
158
+ END
159
+ WHERE id = ?`).run(W,K.length,G,G,G,J)})();let F=performance.now()-X;if(z(),process.env.DEBUG&&(F>200||Y>500))try{process.stderr.write(`[SessionHistory][DIAG] replaceConversationMessages: total=${F.toFixed(0)}ms (count=${(Z-X).toFixed(0)}ms txn=${(F-(Z-X)).toFixed(0)}ms) existingRows=${Y} newRows=${K.length} session=${J}
160
+ `)}catch{}}catch(X){z(),O.warn("[SessionHistory] Failed to replace conversation messages batch:",X?.message??X)}}loadSessionMessages(J){let K=this.db.prepare("SELECT * FROM sessions WHERE id = ?").get(J);if(!K)return null;let Y=this.db.prepare("SELECT * FROM messages WHERE session_id = ? ORDER BY id ASC").all(J).map((Z)=>{if(Z.data)try{let W=JSON.parse(Z.data),$=y.safeParse(W);if($.success)return $.data;return O.warn(`[loadSessionMessages] Schema validation failed for message row ${Z.id} (session ${J}), falling back to v1 columns`),j(Z)}catch{return O.warn(`[loadSessionMessages] Corrupted data column in message row ${Z.id} (session ${J}), falling back to v1 columns`),j(Z)}return j(Z)});return{id:K.id,arion:K.arion,model:K.model,messages:Y}}loadSession(J){let K=this.loadSessionMessages(J);if(!K)return null;let X=this.toSessionRuntimeState(this.readSessionRuntimeStateRow(J)),Y=this.db.prepare(`SELECT * FROM session_interactions
161
+ WHERE session_id = ?
162
+ AND status = 'pending'
163
+ ORDER BY created_at DESC
164
+ LIMIT 1`).get(J)??null;return{session:K,runtimeState:X,pendingInteraction:this.toSessionInteractionRecord(Y)}}getSessionRuntimeState(J){return this.toSessionRuntimeState(this.readSessionRuntimeStateRow(J))}getInteraction(J){let K=this.db.prepare("SELECT * FROM session_interactions WHERE interaction_id = ?").get(J)??null;return this.toSessionInteractionRecord(K)}claimSessionForMutation(J,K,X){if(!K.trim())throw Error("claimSessionForMutation requires a non-empty ownerId");if(!Number.isFinite(X)||X<=0)throw Error("claimSessionForMutation requires a positive staleAfterMs");return this.withImmediateTransaction(()=>{let Y=this.readSessionRuntimeStateRow(J);if(!Y)throw Error(`Session ${J} not found`);this.assertSessionMutationGuard(Y,K);let Z=new Date().toISOString(),W=new Date(Date.now()+X).toISOString();return this.db.prepare(`UPDATE session_runtime_state
165
+ SET lease_owner = ?,
166
+ lease_expires_at = ?,
167
+ updated_at = ?
168
+ WHERE session_id = ?`).run(K,W,Z,J),this.toSessionRuntimeState(this.readSessionRuntimeStateRow(J))})}recordPausedRun(J,K,X,Y,Z,W){return this.withImmediateTransaction(()=>{let $=this.readSessionRuntimeStateRow(J);if(!$)throw Error(`Session ${J} not found`);this.assertSessionMutationGuard($,W?.ownerId,W?.expectedRevision);let Q=new Date().toISOString(),F=$.revision+1;if(this.db.prepare(`UPDATE session_runtime_state
169
+ SET state_status = 'paused',
170
+ active_run_id = ?,
171
+ paused_state_json = ?,
172
+ policy_snapshot_json = ?,
173
+ last_event_seq = ?,
174
+ revision = ?,
175
+ updated_at = ?
176
+ WHERE session_id = ?`).run(K,JSON.stringify(X),JSON.stringify(Y),W?.lastEventSeq??$.last_event_seq,F,Q,J),Z)this.db.prepare(`INSERT INTO session_interactions (
177
+ interaction_id,
178
+ session_id,
179
+ request_id,
180
+ source,
181
+ kind,
182
+ status,
183
+ prompt_json,
184
+ created_at
185
+ ) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?)`).run(Z.interactionId,J,Z.requestId,Z.source,Z.kind,JSON.stringify(Z.prompt),Q);return this.toSessionRuntimeState(this.readSessionRuntimeStateRow(J))})}recordInteractionResponse(J,K,X,Y){return this.withImmediateTransaction(()=>{let Z=this.readSessionRuntimeStateRow(J);if(!Z)throw Error(`Session ${J} not found`);this.assertSessionMutationGuard(Z,Y?.ownerId,Y?.expectedRevision);let W=this.db.prepare(`SELECT * FROM session_interactions
186
+ WHERE session_id = ?
187
+ AND interaction_id = ?`).get(J,K)??null;if(!W)throw Error(`Interaction ${K} not found for session ${J}`);if(W.status!=="pending")throw Error(`Interaction ${K} is not pending (current status: ${W.status})`);let $=new Date().toISOString();this.db.prepare(`UPDATE session_interactions
188
+ SET status = 'answered',
189
+ response_json = ?,
190
+ answered_at = ?
191
+ WHERE interaction_id = ?`).run(JSON.stringify(X),$,K),this.db.prepare(`UPDATE session_runtime_state
192
+ SET revision = revision + 1,
193
+ updated_at = ?
194
+ WHERE session_id = ?`).run($,J);let Q=this.db.prepare("SELECT * FROM session_interactions WHERE interaction_id = ?").get(K)??null;return this.toSessionInteractionRecord(Q)})}cancelInteraction(J,K,X){return this.withImmediateTransaction(()=>{let Y=this.readSessionRuntimeStateRow(J);if(!Y)throw Error(`Session ${J} not found`);this.assertSessionMutationGuard(Y,X?.ownerId,X?.expectedRevision);let Z=this.db.prepare(`SELECT * FROM session_interactions
195
+ WHERE session_id = ?
196
+ AND interaction_id = ?`).get(J,K)??null;if(!Z)throw Error(`Interaction ${K} not found for session ${J}`);if(Z.status!=="pending")throw Error(`Interaction ${K} is not pending (current status: ${Z.status})`);let W=new Date().toISOString();this.db.prepare(`UPDATE session_interactions
197
+ SET status = 'canceled',
198
+ answered_at = ?
199
+ WHERE interaction_id = ?`).run(W,K),this.db.prepare(`UPDATE session_runtime_state
200
+ SET state_status = 'completed',
201
+ active_run_id = NULL,
202
+ paused_state_json = NULL,
203
+ policy_snapshot_json = NULL,
204
+ revision = revision + 1,
205
+ updated_at = ?
206
+ WHERE session_id = ?`).run(W,J),this.db.prepare(`UPDATE sessions
207
+ SET completed_at = COALESCE(completed_at, ?),
208
+ updated_at = ?
209
+ WHERE id = ?`).run(W,W,J);let $=this.db.prepare("SELECT * FROM session_interactions WHERE interaction_id = ?").get(K)??null;return this.toSessionInteractionRecord($)})}completeRun(J,K,X){return this.withImmediateTransaction(()=>{let Y=this.readSessionRuntimeStateRow(J);if(!Y)throw Error(`Session ${J} not found`);this.assertSessionMutationGuard(Y,X?.ownerId,X?.expectedRevision);let Z=new Date().toISOString();return this.db.prepare(`UPDATE session_runtime_state
210
+ SET state_status = 'completed',
211
+ active_run_id = NULL,
212
+ paused_state_json = NULL,
213
+ policy_snapshot_json = NULL,
214
+ revision = revision + 1,
215
+ updated_at = ?
216
+ WHERE session_id = ?`).run(Z,J),this.db.prepare(`UPDATE session_interactions
217
+ SET status = CASE WHEN response_json IS NULL THEN 'expired' ELSE 'applied' END,
218
+ answered_at = COALESCE(answered_at, ?),
219
+ applied_at = CASE WHEN response_json IS NULL THEN applied_at ELSE ? END
220
+ WHERE session_id = ?
221
+ AND status IN ('pending', 'answered')`).run(Z,Z,J),this.db.prepare(`UPDATE sessions
222
+ SET completed_at = COALESCE(completed_at, ?),
223
+ updated_at = ?
224
+ WHERE id = ?`).run(Z,Z,J),this.toSessionRuntimeState(this.readSessionRuntimeStateRow(J))})}releaseSessionClaim(J,K){this.withImmediateTransaction(()=>{let X=this.readSessionRuntimeStateRow(J);if(!X)throw Error(`Session ${J} not found`);if(X.lease_owner&&X.lease_owner!==K)throw Error(`Cannot release session ${J} lease owned by ${X.lease_owner} with ${K}`);let Y=new Date().toISOString();this.db.prepare(`UPDATE session_runtime_state
225
+ SET lease_owner = NULL,
226
+ lease_expires_at = NULL,
227
+ updated_at = ?
228
+ WHERE session_id = ?`).run(Y,J)})}listSessions(J=20,K=0){return this.db.prepare(`
229
+ SELECT
230
+ s.*,
231
+ COALESCE(s.title, '') as preview
232
+ FROM sessions s
233
+ WHERE s.message_count > 0
234
+ ORDER BY s.updated_at DESC, s.rowid DESC
235
+ LIMIT ? OFFSET ?
236
+ `).all(J,K).map((Y)=>({id:Y.id,createdAt:new Date(Y.created_at),updatedAt:new Date(Y.updated_at),completedAt:Y.completed_at?new Date(Y.completed_at):void 0,title:Y.title,arion:Y.arion,model:Y.model,messageCount:Y.message_count,preview:this.truncatePreview(Y.preview??"",60)}))}searchSessions(J,K=20,X=0){let Z=`%${J.replace(/[%_\\]/g,"\\$&")}%`;return this.db.prepare(`
237
+ SELECT DISTINCT
238
+ s.*,
239
+ (SELECT content FROM messages WHERE session_id = s.id AND role = 'user' ORDER BY id LIMIT 1) as preview
240
+ FROM sessions s
241
+ LEFT JOIN messages m ON m.session_id = s.id
242
+ WHERE s.message_count > 0
243
+ AND (s.title LIKE ? ESCAPE '\\' OR m.content LIKE ? ESCAPE '\\')
244
+ ORDER BY s.updated_at DESC, s.rowid DESC
245
+ LIMIT ? OFFSET ?
246
+ `).all(Z,Z,K,X).map(($)=>({id:$.id,createdAt:new Date($.created_at),updatedAt:new Date($.updated_at),completedAt:$.completed_at?new Date($.completed_at):void 0,title:$.title,arion:$.arion,model:$.model,messageCount:$.message_count,preview:this.truncatePreview($.preview??"",60)}))}searchSessionsFts(J,K=100,X=0){let Y=J.trim();if(!Y)return[];if(!this.sessionFtsEnabled)return this.searchSessions(Y,K,X);let Z=this.toFtsPrefixQuery(Y);if(!Z)return[];try{return this.db.prepare(`
247
+ WITH matched AS (
248
+ SELECT session_id, MIN(bm25(fts_session_messages)) as rank
249
+ FROM fts_session_messages
250
+ WHERE fts_session_messages MATCH ?
251
+ GROUP BY session_id
252
+ )
253
+ SELECT
254
+ s.*,
255
+ COALESCE(s.title, '') as preview
256
+ FROM matched m
257
+ JOIN sessions s ON s.id = m.session_id
258
+ WHERE s.message_count > 0
259
+ ORDER BY m.rank ASC, s.updated_at DESC, s.rowid DESC
260
+ LIMIT ? OFFSET ?
261
+ `).all(Z,K,X).map(($)=>({id:$.id,createdAt:new Date($.created_at),updatedAt:new Date($.updated_at),completedAt:$.completed_at?new Date($.completed_at):void 0,title:$.title,arion:$.arion,model:$.model,messageCount:$.message_count,preview:this.truncatePreview($.preview??"",60)}))}catch(W){return this.searchSessions(Y,K,X)}}searchSessionSummaries(J,K=100,X=0){let Z=`%${J.replace(/[%_\\]/g,"\\$&")}%`;return this.db.prepare(`
262
+ SELECT
263
+ s.*,
264
+ COALESCE(s.title, '') as preview
265
+ FROM sessions s
266
+ WHERE s.message_count > 0
267
+ AND (
268
+ s.title LIKE ? ESCAPE '\\'
269
+ OR s.arion LIKE ? ESCAPE '\\'
270
+ OR s.model LIKE ? ESCAPE '\\'
271
+ OR s.id LIKE ? ESCAPE '\\'
272
+ )
273
+ ORDER BY s.updated_at DESC, s.rowid DESC
274
+ LIMIT ? OFFSET ?
275
+ `).all(Z,Z,Z,Z,K,X).map(($)=>({id:$.id,createdAt:new Date($.created_at),updatedAt:new Date($.updated_at),completedAt:$.completed_at?new Date($.completed_at):void 0,title:$.title,arion:$.arion,model:$.model,messageCount:$.message_count,preview:this.truncatePreview($.preview??"",60)}))}getSession(J){let K=this.db.prepare(`
276
+ SELECT * FROM sessions WHERE id = ?
277
+ `).get(J);if(!K)return null;let X=this.db.prepare(`
278
+ SELECT * FROM messages WHERE session_id = ? ORDER BY id ASC
279
+ `).all(J);return{id:K.id,arion:K.arion,model:K.model,messages:X.map((Y)=>({id:Y.id,role:Y.role,content:Y.content,arion:Y.arion??void 0,toolCallId:Y.tool_call_id??void 0,toolCalls:Y.tool_calls?(()=>{try{return JSON.parse(Y.tool_calls)}catch{O.warn(`[getSession] Corrupted tool_calls JSON in message row ${Y.id} (session ${J})`);return}})():void 0,thinking:Y.thinking?(()=>{try{return JSON.parse(Y.thinking)}catch{O.warn(`[getSession] Corrupted thinking JSON in message row ${Y.id} (session ${J})`);return}})():void 0,createdAt:new Date(Y.created_at)}))}}deleteSession(J){this.db.prepare("DELETE FROM sessions WHERE id = ?").run(J)}setSessionTitle(J,K){try{this.db.prepare("UPDATE sessions SET title = ? WHERE id = ?").run(K,J)}catch(X){O.warn("[SessionHistory] Failed to set session title:",X?.message??X)}}markCompleted(J){try{let K=new Date().toISOString();this.withImmediateTransaction(()=>{this.db.prepare(`UPDATE sessions
280
+ SET completed_at = COALESCE(completed_at, ?),
281
+ updated_at = ?
282
+ WHERE id = ?`).run(K,K,J),this.ensureSessionRuntimeRow(J),this.db.prepare(`UPDATE session_runtime_state
283
+ SET state_status = 'completed',
284
+ active_run_id = NULL,
285
+ paused_state_json = NULL,
286
+ policy_snapshot_json = NULL,
287
+ lease_owner = NULL,
288
+ lease_expires_at = NULL,
289
+ revision = revision + 1,
290
+ updated_at = ?
291
+ WHERE session_id = ?`).run(K,J)})}catch(K){O.warn("[SessionHistory] Failed to mark session completed:",K?.message??K)}}markStaleSessionsCompleted(J){try{let K=new Date(Date.now()-J*86400000).toISOString(),X=new Date().toISOString();return this.db.prepare(`UPDATE sessions
292
+ SET completed_at = COALESCE(completed_at, ?),
293
+ updated_at = ?
294
+ WHERE completed_at IS NULL
295
+ AND message_count > 0
296
+ AND updated_at < ?`).run(X,X,K).changes}catch(K){return O.warn("[SessionHistory] Failed to mark stale sessions completed:",K?.message??K),0}}getIncompleteSessions(J=10){return this.db.prepare(`
297
+ SELECT
298
+ s.*,
299
+ (SELECT content FROM messages WHERE session_id = s.id AND role = 'user' ORDER BY id LIMIT 1) as preview
300
+ FROM sessions s
301
+ WHERE s.message_count > 0
302
+ AND s.completed_at IS NULL
303
+ ORDER BY s.updated_at DESC, s.rowid DESC
304
+ LIMIT ?
305
+ `).all(J).map((X)=>({id:X.id,createdAt:new Date(X.created_at),updatedAt:new Date(X.updated_at),completedAt:X.completed_at?new Date(X.completed_at):void 0,title:X.title,arion:X.arion,model:X.model,messageCount:X.message_count,preview:this.truncatePreview(X.preview??"",60)}))}findSessionByPrefix(J){if(J.length===36)return this.db.prepare("SELECT id FROM sessions WHERE id = ? AND message_count > 0").get(J)?.id??null;if(J.length<8)return null;let K=this.db.prepare("SELECT id FROM sessions WHERE id LIKE ? AND message_count > 0 LIMIT 2").all(`${J}%`);return K.length===1?K[0].id:null}getSessionCount(){return this.db.prepare("SELECT COUNT(*) as count FROM sessions WHERE message_count > 0").get()?.count??0}truncatePreview(J,K){if(J.length<=K)return J;return J.slice(0,K-3)+"..."}addInputHistory(J){try{let K=new Date().toISOString();this.db.prepare(`
306
+ INSERT INTO input_history (content, used_at)
307
+ VALUES (?, ?)
308
+ ON CONFLICT(content) DO UPDATE SET used_at = excluded.used_at
309
+ `).run(J,K),this.db.prepare(`
310
+ DELETE FROM input_history
311
+ WHERE id NOT IN (
312
+ SELECT id FROM input_history ORDER BY used_at DESC LIMIT 500
313
+ )
314
+ `).run()}catch(K){O.warn("[SessionHistory] Failed to save input history:",K?.message??K)}}getInputHistory(J=100){return this.db.prepare(`
315
+ SELECT content FROM input_history
316
+ ORDER BY used_at DESC
317
+ LIMIT ?
318
+ `).all(J).map((X)=>X.content)}saveRunMetrics(J,K){try{this.db.prepare(`INSERT INTO run_metrics (id, session_id, turn_count, input_tokens, output_tokens, total_tokens, estimated_cost, wall_time_ms, tool_count, guardrail_fires, handoff_count)
319
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(K.id,J,K.turnCount??null,K.inputTokens??null,K.outputTokens??null,K.totalTokens??null,K.estimatedCost??null,K.wallTimeMs??null,K.toolCount??null,K.guardrailFires??null,K.handoffCount??null)}catch(X){O.warn("[SessionHistory] Failed to save run metrics:",X?.message??X)}}getRunMetrics(J){return this.db.prepare("SELECT * FROM run_metrics WHERE session_id = ? ORDER BY created_at ASC").all(J).map((X)=>({id:X.id,sessionId:X.session_id,turnCount:X.turn_count??void 0,inputTokens:X.input_tokens??void 0,outputTokens:X.output_tokens??void 0,totalTokens:X.total_tokens??void 0,estimatedCost:X.estimated_cost??void 0,wallTimeMs:X.wall_time_ms??void 0,toolCount:X.tool_count??void 0,guardrailFires:X.guardrail_fires??void 0,handoffCount:X.handoff_count??void 0,createdAt:X.created_at}))}close(){try{this.db.pragma("wal_checkpoint(TRUNCATE)")}catch{}this.db.close()}}var n=D(()=>{I();T()});function _J(J){return typeof J!=="string"||J.trim().length>0}function BJ(J){let{toolCalls:K,...X}=J;return X}function LJ(J,K,X){for(let Y=K;Y<J.length;Y++){let Z=J[Y];if(Z.role==="tool"&&Z.toolCallId===X)return!0}return!1}function r(J){let K=[];for(let X=0;X<J.length;X++){let Y=J[X];if(Y.role==="assistant"&&Y.toolCalls?.length){let Z=new Set(Y.toolCalls.map((V)=>V.id)),W=new Set,$=[],Q=X+1;while(Q<J.length&&J[Q].role==="tool"){let V=J[Q];if(V.toolCallId&&Z.has(V.toolCallId)&&!W.has(V.toolCallId))W.add(V.toolCallId),$.push(V);Q++}let F=Y.toolCalls.filter((V)=>{if(W.has(V.id))return!0;return!LJ(J,Q,V.id)}),G=F.filter((V)=>!W.has(V.id));if(F.length===Y.toolCalls.length)K.push(Y);else if(F.length>0)K.push({...Y,toolCalls:F});else if(_J(Y.content))K.push(BJ(Y));K.push(...$);for(let V of G)K.push({role:"tool",content:`[Tool execution interrupted — no result for ${V.name}]`,toolCallId:V.id});X=Q-1;continue}if(Y.role==="tool")continue;K.push(Y)}return K}class q{textParts=[];thinkingBlocks=[];toolUseBlocks=[];handoffBlocks=[];toolResultMessages=[];seenToolIds=new Set;toolArgsAccumulator=new Map;thinkingInProgress=!1;pendingThinkingContent="";arion;verb;tokenUsage;snapshotMessages;previewAssistantId=`preview-${Date.now()}`;ingest(J){switch(J.type){case"text_delta":return this.textParts.push(J.content),"continue";case"thinking_start":return this.thinkingInProgress=!0,this.pendingThinkingContent="","continue";case"thinking_delta":return this.pendingThinkingContent+=J.content,"continue";case"thinking_end":{this.thinkingInProgress=!1;let K=Array.isArray(J.blocks)&&J.blocks.length>0?J.blocks[0]:void 0,X=typeof K?.thinking==="string"?K.thinking:this.pendingThinkingContent,Y=X.split(/\s+/).filter(Boolean).length,Z={type:"thinking",content:X,wordCount:Y,durationMs:J.durationMs,verb:this.verb};return this.thinkingBlocks.push(Z),this.pendingThinkingContent="","continue"}case"tool_start":{if(this.seenToolIds.has(J.id))return"continue";this.seenToolIds.add(J.id);let K={type:"tool_use",id:J.id,name:J.name,arguments:J.input??{}};return this.toolUseBlocks.push(K),"continue"}case"tool_args_delta":{let X=(this.toolArgsAccumulator.get(J.id)??"")+J.args;this.toolArgsAccumulator.set(J.id,X);try{let Y=JSON.parse(X),Z=this.toolUseBlocks.find((W)=>W.type==="tool_use"&&W.id===J.id);if(Z)Z.arguments=Y}catch{}return"continue"}case"tool_result":{if(J.input){let W=this.toolUseBlocks.find(($)=>$.type==="tool_use"&&$.id===J.id);if(W){let $=typeof J.input==="object"&&!Array.isArray(J.input)?J.input:{};if(Object.keys(W.arguments).length===0)W.arguments=$}}let K=J.result,X="usage"in J&&J.usage&&typeof J.usage==="object"&&typeof J.usage.inputTokens==="number"&&typeof J.usage.outputTokens==="number"&&typeof J.usage.totalTokens==="number"&&typeof J.usage.estimatedCost==="number"?J.usage:void 0,Y={type:"tool_result",toolUseId:J.id,content:typeof K.message==="string"?K.message:"",status:K.success===!0?"success":"error",durationMs:J.durationMs,resultData:K.data,usage:X},Z={id:crypto.randomUUID(),role:"tool",content:[Y],arion:this.arion,createdAt:new Date().toISOString()};return this.toolResultMessages.push(Z),"continue"}case"handoff_start":{let K={type:"handoff",target:J.target,direction:"to"};return this.handoffBlocks.push(K),"continue"}case"handoff_result":{let K={type:"handoff",target:J.target,direction:"from"};return this.handoffBlocks.push(K),"continue"}case"turn_complete":return"flush";case"messages_snapshot":return this.snapshotMessages=J.messages,"continue";default:return"continue"}}flush(){let J=[];if(this.thinkingInProgress&&this.pendingThinkingContent){let Y=this.pendingThinkingContent.trim(),Z=Y.length===0?0:Y.split(/\s+/).length,W={type:"thinking",content:this.pendingThinkingContent,wordCount:Z,verb:this.verb};this.thinkingBlocks.push(W)}let K=[];K.push(...this.thinkingBlocks);let X=this.textParts.join("");if(X)K.push({type:"text",text:X});if(K.push(...this.toolUseBlocks),K.push(...this.handoffBlocks),K.length>0){let Y={id:crypto.randomUUID(),role:"assistant",content:K,arion:this.arion,tokenUsage:this.tokenUsage,createdAt:new Date().toISOString()};J.push(Y)}if(J.push(...this.toolResultMessages),this.toolResultMessages.length>0&&this.toolUseBlocks.length>0){let Y=new Set(this.toolResultMessages.flatMap((Z)=>Z.content.filter((W)=>W.type==="tool_result").map((W)=>W.toolUseId)));for(let Z of this.toolUseBlocks){let W=Z.id;if(W&&!Y.has(W)){let $={id:crypto.randomUUID(),role:"tool",content:[{type:"tool_result",toolUseId:W,content:"Tool execution cancelled by user.",status:"error"}],arion:this.arion,createdAt:new Date().toISOString()};J.push($)}}}return this.textParts=[],this.thinkingBlocks=[],this.toolUseBlocks=[],this.handoffBlocks=[],this.toolResultMessages=[],this.seenToolIds=new Set,this.toolArgsAccumulator=new Map,this.thinkingInProgress=!1,this.pendingThinkingContent="",this.tokenUsage=void 0,this.verb=void 0,this.previewAssistantId=`preview-${Date.now()}`,J}snapshot(){let J=[];if(J.push(...this.thinkingBlocks.map((Y)=>({...Y}))),this.thinkingInProgress&&this.pendingThinkingContent){let Y=this.pendingThinkingContent,Z={type:"thinking",content:Y,wordCount:Y.split(/\s+/).filter(Boolean).length,verb:this.verb};J.push(Z)}let K=this.textParts.join("");if(K){let Y=K.lastIndexOf(`
320
+ `);if(Y>=0)J.push({type:"text",text:K.slice(0,Y+1)})}for(let Y of this.toolUseBlocks){let Z={...Y};if(Z.type==="tool_use"&&Object.keys(Z.arguments).length===0){let W=this.toolArgsAccumulator.get(Z.id);if(W){let $=q.tryParsePartialArgs(W);if($)Z.arguments=$}}J.push(Z)}J.push(...this.handoffBlocks.map((Y)=>({...Y})));let X=[];if(J.length>0)X.push({id:this.previewAssistantId,role:"assistant",content:J,arion:this.arion,createdAt:new Date().toISOString()});return X.push(...this.toolResultMessages.map((Y)=>({...Y,content:[...Y.content]}))),X}getSnapshotMessages(){return this.snapshotMessages}hasPendingContent(){return this.textParts.length>0||this.thinkingBlocks.length>0||this.toolUseBlocks.length>0||this.handoffBlocks.length>0||this.toolResultMessages.length>0||this.thinkingInProgress}setArion(J){this.arion=J}setVerb(J){this.verb=J}setTokenUsage(J){if(this.tokenUsage)this.tokenUsage={input:this.tokenUsage.input+J.input,output:this.tokenUsage.output+J.output};else this.tokenUsage={...J}}static tryParsePartialArgs(J){let K=J.trim();if(!K.startsWith("{")||K.length<4)return;try{return JSON.parse(K)}catch{}try{let X=JSON.parse(K+"}");if(Object.keys(X).length>0)return X}catch{}try{let X=JSON.parse(K+'"}');if(Object.keys(X).length>0)return X}catch{}for(let X=K.length-1;X>0;X--)if(K[X]===",")try{let Y=JSON.parse(K.slice(0,X)+"}");if(Object.keys(Y).length>0)return Y}catch{}return}}import{readFileSync as UJ,existsSync as k}from"node:fs";function u(J){if(!k(J))return[];let X=UJ(J,"utf-8").split(`
321
+ `).filter((W)=>W.trim().length>0),Y=new q,Z=[];for(let W of X){let $;try{$=JSON.parse(W)}catch{continue}if(!$.event||typeof $.event.type!=="string")continue;if($.event.type==="user_message"){if(Y.hasPendingContent())Z.push(...Y.flush());let F=$.event.content??"",G=$.event.id,V=M(F);if(G)V.id=G;Z.push(V);continue}if(Y.ingest($.event)==="flush"){let F=Y.flush();Z.push(...F)}}if(Y.hasPendingContent()){let W=Y.flush();Z.push(...W)}return Z}function t(J){for(let X of J.content){if(X.type==="tool_use"&&X.id)return`tool_use:${X.id}`;if(X.type==="tool_result"&&X.toolUseId)return`tool_result:${X.toolUseId}`}let K=J.content.filter((X)=>X.type==="text").map((X)=>X.text).join("");return`${J.role}:${K}`}function e(J,K){if(!K)return{messages:J,backfillMessages:[]};let X;try{X=u(K)}catch{return{messages:J,backfillMessages:[]}}if(X.length===0)return{messages:J,backfillMessages:[]};if(J.length>=X.length)return{messages:J,backfillMessages:[]};let Y=new Set(J.map(t)),Z=[];for(let $ of X){let Q=t($);if(!Y.has(Q))Z.push($)}return{messages:[...J,...Z],backfillMessages:Z}}function o(J,K,X){let Y=`${J}/arions/${K}/logs/${X}.jsonl`;if(k(Y))return Y;let Z=`${J}/logs/${X}.jsonl`;if(k(Z))return Z;return null}var s=D(()=>{T()});var SJ={};ZJ(SJ,{toModelMessages:()=>w,replaySessionFromJsonl:()=>u,repairToolCallPairing:()=>r,mergeWithJsonlRecovery:()=>e,fromV1Columns:()=>j,fromModelMessages:()=>a,findJsonlForSession:()=>o,extractToolCalls:()=>B,extractToolCallId:()=>U,extractThinking:()=>L,extractTextContent:()=>_,createUserMessage:()=>M,createSystemMessage:()=>m,createIncomingMessagePair:()=>d,createErrorMessage:()=>c,conversationMessageToHistoryMessages:()=>l,TurnAccumulator:()=>q,SessionHistory:()=>v,ConversationMessageSchema:()=>y,ContentBlockSchema:()=>x,ArionRefSchema:()=>h});var qJ=D(()=>{n();T();s()});qJ();export{w as toModelMessages,u as replaySessionFromJsonl,r as repairToolCallPairing,e as mergeWithJsonlRecovery,j as fromV1Columns,a as fromModelMessages,o as findJsonlForSession,B as extractToolCalls,U as extractToolCallId,L as extractThinking,_ as extractTextContent,M as createUserMessage,m as createSystemMessage,d as createIncomingMessagePair,c as createErrorMessage,l as conversationMessageToHistoryMessages,q as TurnAccumulator,v as SessionHistory,y as ConversationMessageSchema,x as ContentBlockSchema,h as ArionRefSchema};