@x-otto/agent 0.0.1-alpha.5 → 0.1.0-alpha.9

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/index.js CHANGED
@@ -1,10 +1,21 @@
1
- import{AgentError as e,PROVIDER_IMAGE_INLINE_MAX_BYTES as t,TypedEventEmitter as n,createLogger as r}from"@x-otto/shared";import{randomUUID as i}from"node:crypto";import{CONVERSATION_SUMMARY_PREFIX as a,extractToolResultText as o,getToolCallsByAssistantMessage as s,hasToolCalls as c,modelSupportsImages as l}from"@x-otto/interchange";import{classifyAuthErrorType as u,classifyStreamError as d,extractAbortKind as f,extractAnthropicRateLimit as p,extractRetryAfterMs as m,hasTrailingInvokeXml as h,isAuthError as g,isNetworkDisconnectError as _}from"@x-otto/provider";var v=class extends e{constructor(e){super(e??`Agent aborted`,{code:`AGENT_ABORTED`}),this.name=`AbortError`}},y=class extends e{maxTurns;partialText;extensions;constructor(e,t=``,n=0){let r=e*(1+n);super(n>0?`Max tool turns exceeded: ${r} (base ${e} × ${1+n} extensions)`:`Max tool turns exceeded: ${e}`,{code:`AGENT_MAX_TOOL_TURNS`}),this.name=`MaxToolTurnsError`,this.maxTurns=e,this.partialText=t,this.extensions=n}get effectiveMaxTurns(){return this.maxTurns*(1+this.extensions)}},b=class extends e{dimension;used;budget;partialText;constructor(e,t,n,r=``){super(e===`tokens`?`Prompt output-token budget exceeded: ${t} / ${n} tokens`:`Prompt wall-clock budget exceeded: ${Math.round(t/1e3)}s / ${Math.round(n/1e3)}s`,{code:`AGENT_PROMPT_BUDGET_EXCEEDED`}),this.name=`PromptBudgetExceededError`,this.dimension=e,this.used=t,this.budget=n,this.partialText=r}},x=class extends e{liveCount;projectedCount;constructor(e,t){super(`Messages consistency violation: work memory has ${e} messages but session tree projection has ${t} (concurrent write or tree mutation detected)`,{code:`AGENT_MESSAGES_CONSISTENCY`}),this.name=`MessagesConsistencyError`,this.liveCount=e,this.projectedCount=t}};const S={now:()=>Date.now()},C={random:()=>Math.random()},w={uuid:()=>i()},T=(e,t)=>new Promise(n=>{if(t?.aborted){n();return}let r=()=>{clearTimeout(i),n()},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n()},e);t?.addEventListener(`abort`,r,{once:!0})}),E=[{id:`loop.start`,category:`agent_work_loop`,label:`Loop Start`,pausable:!0,traceable:!0},{id:`model.before`,category:`agent_work_loop`,label:`Model Before`,pausable:!0},{id:`model.after`,category:`agent_work_loop`,label:`Model After`,pausable:!0},{id:`tool.before`,category:`agent_work_loop`,label:`Tool Before`,pausable:!0},{id:`tool.after`,category:`agent_work_loop`,label:`Tool After`,pausable:!0},{id:`loop.end`,category:`agent_work_loop`,label:`Loop End`,pausable:!0,traceable:!0},{id:`loop.cleanup`,category:`agent_work_loop`,label:`Loop Cleanup`,pausable:!0},{id:`agent.aborted`,category:`agent_work_loop`,label:`Agent Aborted`,pausable:!0,traceable:!0},{id:`agent.error`,category:`agent_work_loop`,label:`Agent Error`,pausable:!0,traceable:!0},{id:`agent.done`,category:`agent_work_loop`,label:`Agent Done`,pausable:!0,traceable:!0},{id:`steering.check`,category:`work_loop_injection`,label:`Steering Check`,pausable:!0},{id:`follow.up.check`,category:`work_loop_injection`,label:`Follow Up Check`,pausable:!0},{id:`context.transform`,category:`work_loop_injection`,label:`Context Transform`,pausable:!0},{id:`tool.resolve`,category:`tool_executor`,label:`Tool Resolve`,pausable:!0},{id:`tool.validate`,category:`tool_executor`,label:`Tool Validate`,pausable:!0},{id:`tool.hook.before`,category:`tool_executor`,label:`Tool Hook Before`,pausable:!0},{id:`tool.hook.after`,category:`tool_executor`,label:`Tool Hook After`,pausable:!0},{id:`prompt.before`,category:`session_prompt_lifecycle`,label:`Prompt Before`,pausable:!0,traceable:!0},{id:`prompt.after`,category:`session_prompt_lifecycle`,label:`Prompt After`,pausable:!0,traceable:!0},{id:`context.build`,category:`session_prompt_lifecycle`,label:`Context Build`,pausable:!0,traceable:!0},{id:`messages.persist`,category:`session_prompt_lifecycle`,label:`Messages Persist`,pausable:!0,traceable:!0},{id:`memory.prune`,category:`work_loop_injection`,label:`Memory Prune`,traceable:!0},{id:`memory.archive`,category:`session_prompt_lifecycle`,label:`Memory Archive`,traceable:!0},{id:`stream.ttft`,category:`agent_work_loop`,label:`Stream First Token Latency`,traceable:!0},{id:`chat.message.before`,category:`lifecycle_hook`,label:`Chat Message Before`,hook:`interceptor`},{id:`chat.message.after`,category:`lifecycle_hook`,label:`Chat Message After`,hook:`interceptor`},{id:`chat.params`,category:`lifecycle_hook`,label:`Chat Params`,hook:`interceptor`},{id:`system.prompt.transform`,category:`lifecycle_hook`,label:`System Prompt Transform`,hook:`interceptor`},{id:`messages.transform`,category:`lifecycle_hook`,label:`Messages Transform`,hook:`interceptor`},{id:`tool.execute.before`,category:`lifecycle_hook`,label:`Tool Execute Before`,hook:`interceptor`},{id:`tool.execute.after`,category:`lifecycle_hook`,label:`Tool Execute After`,hook:`interceptor`},{id:`memory.prune.before`,category:`lifecycle_hook`,label:`Memory Prune Before`,hook:`interceptor`},{id:`session.idle`,category:`lifecycle_hook`,label:`Session Idle`,hook:`observer`},{id:`session.error`,category:`lifecycle_hook`,label:`Session Error`,hook:`observer`},{id:`status.change`,category:`turn_observable`,label:`Status Change`,observable:!0},{id:`turn.start`,category:`turn_observable`,label:`Turn Start`,observable:!0,traceable:!0},{id:`turn.end`,category:`turn_observable`,label:`Turn End`,observable:!0,traceable:!0},{id:`stream.event`,category:`turn_observable`,label:`Stream Event`,observable:!0,traceable:!0},{id:`tool.call.start`,category:`turn_observable`,label:`Tool Call Start`,observable:!0,traceable:!0},{id:`tool.call.end`,category:`turn_observable`,label:`Tool Call End`,observable:!0,traceable:!0},{id:`steering.injected`,category:`turn_observable`,label:`Steering Injected`,observable:!0},{id:`follow.up.start`,category:`turn_observable`,label:`Follow Up Start`,observable:!0},{id:`max.turns`,category:`turn_observable`,label:`Max Tool Turns Reached`,observable:!0,traceable:!0},{id:`progress.stall`,category:`turn_observable`,label:`Progress Stall Detected`,observable:!0,traceable:!0},{id:`tool.call.mismatch`,category:`turn_observable`,label:`Tool Call Protocol Mismatch`,observable:!0,traceable:!0},{id:`prompt.budget`,category:`turn_observable`,label:`Prompt Budget Exceeded`,observable:!0,traceable:!0},{id:`compaction.reactive`,category:`turn_observable`,label:`Reactive Compaction`,observable:!0,traceable:!0},{id:`image.cap`,category:`turn_observable`,label:`Image Cap`,traceable:!0},{id:`image.vision-gate`,category:`turn_observable`,label:`Vision Capability Gate`,traceable:!0},{id:`image.vision-delegate`,category:`turn_observable`,label:`Vision Delegation Result`,observable:!0,traceable:!0},{id:`image.degradation`,category:`turn_observable`,label:`Image Degradation`,observable:!0,traceable:!0},{id:`process.memory.sample`,category:`turn_observable`,label:`Process Memory Sample`,traceable:!0},{id:`stream.retry`,category:`turn_observable`,label:`Stream Retry`,observable:!0,traceable:!0},{id:`stream.retry.accelerated`,category:`turn_observable`,label:`Stream Retry Accelerated`,observable:!0,traceable:!0},{id:`turn.truncated`,category:`turn_observable`,label:`Turn Truncated`,observable:!0,traceable:!0},{id:`rate.limit.exhausted`,category:`turn_observable`,label:`Rate Limit Exhausted`,observable:!0,traceable:!0},{id:`stream.auth-failed`,category:`turn_observable`,label:`Stream Auth Failed`,observable:!0,traceable:!0},{id:`error`,category:`turn_observable`,label:`Error`,observable:!0},{id:`abort`,category:`turn_observable`,label:`Abort`,observable:!0},{id:`lifecycle.tool.completed`,category:`turn_observable`,label:`Lifecycle Tool Completed`,observable:!0},{id:`lifecycle.tool.completed.crossBoundary`,category:`turn_observable`,label:`Lifecycle Tool Completed (Cross Prompt Boundary)`,observable:!0},{id:`lifecycle.tool.timeout`,category:`turn_observable`,label:`Lifecycle Tool Timeout`,observable:!0,traceable:!0},{id:`wire.snapshot.capture`,category:`turn_observable`,label:`Wire Snapshot Capture`,traceable:!0}],D=E;function O(e){return D.filter(t=>t[e]!==void 0&&t[e]!==!1)}const ee=D.filter(e=>e.hook!==void 0).map(e=>e.id),k=D.filter(e=>e.observable===!0).map(e=>e.id),te=D.filter(e=>e.traceable===!0).map(e=>e.id),ne=D.filter(e=>e.pausable===!0).map(e=>({point:e.id,name:e.label,category:e.category})),A={maxToolTurns:120,traceResultMaxChars:512,maxToolResultChars:1e5,minToolResultChars:2e3,promptToolResultFraction:.5,maxToolConcurrency:10,progressDistinctRatio:.5,progressSignatureCap:512,progressSignatureArgsMaxChars:1024,stallWindowTurns:8,stallRepeatThreshold:4};function j(e,t){let n=Math.max(0,e.length-t);return e.slice(n).map((e,t)=>{let r=typeof e.content==`string`?e.content:JSON.stringify(e.content);return{index:n+t,role:e.role,preview:r.slice(0,200),toolName:e.role===`tool_result`?e.toolName:void 0,tokenEstimate:Math.ceil(r.length/4)}})}function M(e){return{turn:0,frameDepth:0,messagesCount:0,tokenUsage:{input:0,output:0},metadata:{},systemPrompt:``,messagesSummary:[],llmParams:{},...e}}function N(e){return(t,n,r={})=>{let i=e.getLlmParams?.(),a=r.summarySource??e.getMessagesForSummary?.();return e.debug?.pause(M({turn:e.getTurn(),point:t,frameDepth:n,messagesCount:r.messagesCount??e.getMessagesCount(),lastToolName:r.lastToolName,tokenUsage:e.getTokenUsage()??{input:0,output:0},metadata:r.metadata??{},...i?{systemPrompt:i.systemPrompt??``,llmParams:{temperature:i.temperature,maxTokens:i.maxTokens,thinkingLevel:i.thinkingLevel}}:{},...a?{messagesSummary:j(a,10)}:{}}))}}function P(e,t){if(e?.command.type===`stop`)throw new v(`Stopped by debugger`);let n=e?.payload;if(!(!n||!t)){if(n.systemPrompt!==void 0&&t.setSystemPrompt?.(n.systemPrompt),t.messages&&n.removeMessageIndices?.length){let e=[...n.removeMessageIndices].sort((e,t)=>t-e);for(let n of e)n>=0&&n<t.messages.length&&t.messages.splice(n,1)}if(t.messages&&n.injectMessages?.length){let e=t.now??S.now;for(let r of n.injectMessages)r.role===`user`&&t.messages.push({role:`user`,content:r.content,timestamp:e()})}n.llmParams&&(n.llmParams.temperature!==void 0&&t.setTemperature?.(n.llmParams.temperature),n.llmParams.maxTokens!==void 0&&t.setMaxTokens?.(n.llmParams.maxTokens),n.llmParams.thinkingLevel!==void 0&&t.setThinkingLevel?.(n.llmParams.thinkingLevel))}}function F(){return{writeToolSuccesses:0,signatures:new Map,totalCalls:0}}function I(e){e.writeToolSuccesses=0,e.signatures.clear(),e.totalCalls=0}function L(e,t){let n;if(typeof t==`object`&&t&&!Array.isArray(t)){let e=t,r=Object.keys(e).sort(),i=[];for(let t of r){let n;try{n=JSON.stringify(e[t])??`undefined`}catch{n=`[unserializable]`}i.push(`${t}:${n}`)}n=i.join(`,`)}else try{n=JSON.stringify(t)??`undefined`}catch{n=`[unserializable]`}let r=A.progressSignatureArgsMaxChars;return`${e}(${n.length>r?n.slice(0,r):n})`}function R(e,t){if(e.totalCalls++,!t.readonly&&!t.isError&&e.writeToolSuccesses++,e.signatures.size<A.progressSignatureCap){let n=L(t.toolName,t.args);e.signatures.set(n,(e.signatures.get(n)??0)+1)}}function z(e){return e.writeToolSuccesses>0?!0:e.totalCalls===0?!1:e.signatures.size/e.totalCalls>=A.progressDistinctRatio}const B=t;function V(e){return e.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,``).replace(/\x1b\[[\d;?]*[ -/]*[@-~]/g,``).replace(/\x1b\[[\d;?]*(?![\d;@-~])/g,``).replace(/(?:3[89]|4[0-9]);2;\d{1,3};\d{1,3};\d{1,3}m/g,``).replace(/(?:3[89]|4[0-9]);5;\d{1,3}m/g,``).replace(/(?:^|(?<=[\s;m]))(?:\d{1,3}(?:;\d{1,3})+|;\d{1,3})m/gi,``)}function H(e){return e.map(e=>e.type===`text`&&typeof e.text==`string`?{...e,text:V(e.text)}:e)}function U(e,t){return e.map(e=>{if(e.type!==`text`)return e;let n=V(e.text);if(n.length<=t)return{...e,text:n};let r=Math.floor(t*.7),i=t-r,a=n.length-t;return{...e,text:`${n.slice(0,r)}\n\n[… ${a} chars truncated (tool result exceeded ${t} char budget) …]\n\n${n.slice(n.length-i)}`}})}const W=2e3,re=4e3;function G(e){let t=0;for(let n of e)n.type===`text`?t+=n.text.length:t+=re;return t}var ie=class{consumed=0;constructor(e,t){this.totalChars=e,this.minPerTool=t}budgetFor(e){if(this.totalChars===void 0)return e;let t=Math.max(0,this.totalChars-this.consumed),n=Math.min(this.minPerTool,e);return Math.max(n,Math.min(e,t))}charge(e){this.consumed+=Math.max(0,e)}get consumedChars(){return this.consumed}};function ae(e,t){if(!(!e||e<=0))return Math.max(0,Math.floor(e*t*4))}async function oe(e,t,n,r){if(!e.some(e=>e.type===`text`&&e.text.length>t||e.type===`image`&&e.source.length*.75>B))return U(e,t);let i=0,a=0,o=e.filter(e=>e.type===`image`).length,s=[];for(let c of e){if(c.type===`image`){let e=c.source.length*.75;if(e<=B){s.push(c);continue}if(!r){s.push({type:`text`,text:`[image: ${Math.round(e)} bytes — omitted, no spill port configured]`});continue}let t=o>1?`${n}_img${a}`:`${n}_img`;a++;let i=await r(t,c.source);if(!i){s.push({type:`text`,text:`[image: ${Math.round(e)} bytes — omitted, no spill port configured]`});continue}s.push({type:`text`,text:`[image: ${Math.round(e)} bytes, stored to ${i}, use read tool to inspect if needed]`});continue}if(c.type!==`text`||c.text.length<=t){s.push(c.type===`text`?{...c,text:V(c.text)}:c);continue}if(!r){s.push(...U([c],t));continue}let l=e.filter(e=>e.type===`text`).length>1?`${n}_b${i}`:n;i++;let u=await r(l,c.text);if(!u){s.push(...U([c],t));continue}let d=V(c.text),f=Math.floor(W*.7),p=W-f;s.push({...c,text:`[tool result stored to ${u} (${d.length} chars). Use the read tool on that path to recover the full output.]\n\nPreview:\n${d.slice(0,f)}\n\n[… ${d.length-W} chars omitted …]\n\n${d.slice(d.length-p)}`})}return s}async function se(e,t,n){let r=Array(e.length),i=0,a=async()=>{for(;;){let t=i++;if(t>=e.length)return;try{await n(e[t]),r[t]={status:`fulfilled`,value:void 0}}catch(e){r[t]={status:`rejected`,reason:e}}}},o=Math.min(Number.isFinite(t)&&t>=1?Math.floor(t):1,e.length);return await Promise.all(Array.from({length:o},()=>a())),r}var ce=class{windowTurns;repeatThreshold;buckets=[];current={signatures:[],writeToolSuccesses:0};constructor(e={}){this.windowTurns=e.windowTurns??A.stallWindowTurns,this.repeatThreshold=e.repeatThreshold??A.stallRepeatThreshold}recordCall(e){this.current.signatures.length<A.progressSignatureCap&&this.current.signatures.push(L(e.toolName,e.args)),!e.readonly&&!e.isError&&this.current.writeToolSuccesses++}onTurnEnd(){this.buckets.push(this.current),this.buckets.length>this.windowTurns&&this.buckets.shift(),this.current={signatures:[],writeToolSuccesses:0}}evaluate(){let e=this.buckets.length;if(e<this.windowTurns)return{stalled:!1,maxRepeat:0,windowTurns:e};let t=0,n=new Map,r=0;for(let e of this.buckets){t+=e.writeToolSuccesses;for(let t of e.signatures){let e=(n.get(t)??0)+1;n.set(t,e),e>r&&(r=e)}}return{stalled:t===0&&r>=this.repeatThreshold,maxRepeat:r,windowTurns:e}}reset(){this.buckets.length=0,this.current={signatures:[],writeToolSuccesses:0}}};function le(e){let{sink:t,sessionId:n}=e,r=e.clock??S,i=e.onError??(()=>{});return{record(e){let a={ts:r.now(),sessionId:n,turn:e.turn,kind:e.kind,node:e.node,payload:e.payload,parentEventId:e.parentEventId,causalChain:e.causalChain,evalRunId:e.evalRunId};try{let e=t.append(a);e instanceof Promise&&e.catch(i)}catch(e){i(e)}}}}const K={record(){}},ue=new Set([`start`,`text_start`,`text_end`,`thinking_start`,`thinking_end`,`tool_call_start`,`tool_call_end`,`done`]);function de(e){return ue.has(e)}const fe=new Set([`text_end`,`thinking_end`,`tool_call_end`]);function pe(e){if(!(`partial`in e))return e;let{partial:t,...n}=e;return n}function me(e){let t,n=n=>{if(!t)return;let{payload:r,turn:i}=t;t=void 0,e.record({kind:`stream`,node:`stream.event`,turn:i,payload:n?r:pe(r)})};return{push(r,i){let a=r.type;if(!(typeof a!=`string`||!de(a))){if(n(!1),fe.has(a)){t={payload:r,turn:i};return}e.record({kind:`stream`,node:`stream.event`,turn:i,payload:r})}},flush(){n(!0)}}}function he(e,t){let n=[],r=()=>{if(n.length===0)return;let e=n;n=[],t.record({kind:`nondet`,payload:{draws:e}})},i=e=>{n.push(e),n.length>=4096&&r()};return{clock:{now(){let t=e.clock.now();return i({source:`clock`,value:t}),t}},random:{random(){let t=e.random.random();return i({source:`random`,value:t}),t}},id:{uuid(){let t=e.id.uuid();return i({source:`uuid`,value:t}),t}},flushNondetBatch:r}}function ge(e){let t={clock:[],random:[],uuid:[]};for(let n of e)t[n.source].push(n.value);let n=e=>{let n=t[e];if(n.length===0)throw Error(`Replay underrun: no more recorded "${e}" draws`);return n.shift()};return{clock:{now:()=>n(`clock`)},random:{random:()=>n(`random`)},id:{uuid:()=>n(`uuid`)}}}function _e(e){let t=[];for(let n of e){if(n.kind!==`nondet`)continue;let e=n.payload;if(e&&Array.isArray(e.draws))for(let n of e.draws)ve(n)&&t.push(n);else ve(n.payload)&&t.push(n.payload)}return t}function ve(e){return typeof e==`object`&&!!e&&`source`in e&&`value`in e}const ye={prune:`memory.prune`,archive:`memory.archive`};function q(e,t){let n=ye[t.phase];n!==void 0&&e.record({kind:`lifecycle`,node:n,turn:t.turn,payload:{trigger:t.trigger,sessionId:t.sessionId,...t.metrics}})}function be(e,t){let n=e.buildContext(),r=[];n.summary&&r.push({role:`user`,timestamp:t.now(),content:[{type:`text`,text:`${a}\n${n.summary}`}]}),r.push(...n.messages);let i=r.map(e=>{if(!Array.isArray(e.content))return e;let t=e.content.map(e=>e.type===`text`&&typeof e.text==`string`?{...e,text:V(e.text)}:e);return{...e,content:t}});return{messages:i,messagesBefore:i.length,hasSummary:!!n.summary}}function xe(e,t){return t.length===0?{fullSystemPrompt:e,systemPromptSegments:void 0}:{fullSystemPrompt:[e,...t].join(`
1
+ import{AgentError as e,PROVIDER_IMAGE_INLINE_MAX_BYTES as t,TypedEventEmitter as n,createLogger as r}from"@x-otto/shared";import{randomUUID as i}from"node:crypto";import{CONVERSATION_SUMMARY_PREFIX as a,extractToolResultText as o,getToolCallsByAssistantMessage as s,hasToolCalls as c,modelSupportsImages as l}from"@x-otto/interchange";import{classifyAuthErrorType as u,classifyStreamError as d,extractAbortKind as f,extractAnthropicRateLimit as p,extractRetryAfterMs as m,hasTrailingInvokeXml as h,isAuthError as g,isNetworkDisconnectError as _}from"@x-otto/provider";var v=class extends e{constructor(e){super(e??`Agent aborted`,{code:`AGENT_ABORTED`}),this.name=`AbortError`}},y=class extends e{maxTurns;partialText;extensions;constructor(e,t=``,n=0){let r=e*(1+n);super(n>0?`Max tool turns exceeded: ${r} (base ${e} × ${1+n} extensions)`:`Max tool turns exceeded: ${e}`,{code:`AGENT_MAX_TOOL_TURNS`}),this.name=`MaxToolTurnsError`,this.maxTurns=e,this.partialText=t,this.extensions=n}get effectiveMaxTurns(){return this.maxTurns*(1+this.extensions)}},b=class extends e{dimension;used;budget;partialText;constructor(e,t,n,r=``){super(e===`tokens`?`Prompt output-token budget exceeded: ${t} / ${n} tokens`:`Prompt wall-clock budget exceeded: ${Math.round(t/1e3)}s / ${Math.round(n/1e3)}s`,{code:`AGENT_PROMPT_BUDGET_EXCEEDED`}),this.name=`PromptBudgetExceededError`,this.dimension=e,this.used=t,this.budget=n,this.partialText=r}},x=class extends e{liveCount;projectedCount;constructor(e,t){super(`Messages consistency violation: work memory has ${e} messages but session tree projection has ${t} (concurrent write or tree mutation detected)`,{code:`AGENT_MESSAGES_CONSISTENCY`}),this.name=`MessagesConsistencyError`,this.liveCount=e,this.projectedCount=t}};const S={now:()=>Date.now()},C={random:()=>Math.random()},w={uuid:()=>i()},T=(e,t)=>new Promise(n=>{if(t?.aborted){n();return}let r=()=>{clearTimeout(i),n()},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n()},e);t?.addEventListener(`abort`,r,{once:!0})}),E=[{id:`loop.start`,category:`agent_work_loop`,label:`Loop Start`,pausable:!0,traceable:!0},{id:`model.before`,category:`agent_work_loop`,label:`Model Before`,pausable:!0},{id:`model.after`,category:`agent_work_loop`,label:`Model After`,pausable:!0},{id:`tool.before`,category:`agent_work_loop`,label:`Tool Before`,pausable:!0},{id:`tool.after`,category:`agent_work_loop`,label:`Tool After`,pausable:!0},{id:`loop.end`,category:`agent_work_loop`,label:`Loop End`,pausable:!0,traceable:!0},{id:`loop.cleanup`,category:`agent_work_loop`,label:`Loop Cleanup`,pausable:!0},{id:`agent.aborted`,category:`agent_work_loop`,label:`Agent Aborted`,pausable:!0,traceable:!0},{id:`agent.error`,category:`agent_work_loop`,label:`Agent Error`,pausable:!0,traceable:!0},{id:`agent.done`,category:`agent_work_loop`,label:`Agent Done`,pausable:!0,traceable:!0},{id:`steering.check`,category:`work_loop_injection`,label:`Steering Check`,pausable:!0},{id:`follow.up.check`,category:`work_loop_injection`,label:`Follow Up Check`,pausable:!0},{id:`context.transform`,category:`work_loop_injection`,label:`Context Transform`,pausable:!0},{id:`tool.resolve`,category:`tool_executor`,label:`Tool Resolve`,pausable:!0},{id:`tool.validate`,category:`tool_executor`,label:`Tool Validate`,pausable:!0},{id:`tool.hook.before`,category:`tool_executor`,label:`Tool Hook Before`,pausable:!0},{id:`tool.hook.after`,category:`tool_executor`,label:`Tool Hook After`,pausable:!0},{id:`prompt.before`,category:`session_prompt_lifecycle`,label:`Prompt Before`,pausable:!0,traceable:!0},{id:`prompt.after`,category:`session_prompt_lifecycle`,label:`Prompt After`,pausable:!0,traceable:!0},{id:`context.build`,category:`session_prompt_lifecycle`,label:`Context Build`,pausable:!0,traceable:!0},{id:`messages.persist`,category:`session_prompt_lifecycle`,label:`Messages Persist`,pausable:!0,traceable:!0},{id:`memory.prune`,category:`work_loop_injection`,label:`Memory Prune`,traceable:!0},{id:`memory.archive`,category:`session_prompt_lifecycle`,label:`Memory Archive`,traceable:!0},{id:`stream.ttft`,category:`agent_work_loop`,label:`Stream First Token Latency`,traceable:!0},{id:`chat.message.before`,category:`lifecycle_hook`,label:`Chat Message Before`,hook:`interceptor`},{id:`chat.message.after`,category:`lifecycle_hook`,label:`Chat Message After`,hook:`interceptor`},{id:`chat.params`,category:`lifecycle_hook`,label:`Chat Params`,hook:`interceptor`},{id:`system.prompt.transform`,category:`lifecycle_hook`,label:`System Prompt Transform`,hook:`interceptor`},{id:`messages.transform`,category:`lifecycle_hook`,label:`Messages Transform`,hook:`interceptor`},{id:`tool.execute.before`,category:`lifecycle_hook`,label:`Tool Execute Before`,hook:`interceptor`},{id:`tool.execute.after`,category:`lifecycle_hook`,label:`Tool Execute After`,hook:`interceptor`},{id:`memory.prune.before`,category:`lifecycle_hook`,label:`Memory Prune Before`,hook:`interceptor`},{id:`session.idle`,category:`lifecycle_hook`,label:`Session Idle`,hook:`observer`},{id:`session.error`,category:`lifecycle_hook`,label:`Session Error`,hook:`observer`},{id:`status.change`,category:`turn_observable`,label:`Status Change`,observable:!0},{id:`turn.start`,category:`turn_observable`,label:`Turn Start`,observable:!0,traceable:!0},{id:`turn.end`,category:`turn_observable`,label:`Turn End`,observable:!0,traceable:!0},{id:`stream.event`,category:`turn_observable`,label:`Stream Event`,observable:!0,traceable:!0},{id:`tool.call.start`,category:`turn_observable`,label:`Tool Call Start`,observable:!0,traceable:!0},{id:`tool.call.end`,category:`turn_observable`,label:`Tool Call End`,observable:!0,traceable:!0},{id:`steering.injected`,category:`turn_observable`,label:`Steering Injected`,observable:!0},{id:`follow.up.start`,category:`turn_observable`,label:`Follow Up Start`,observable:!0},{id:`max.turns`,category:`turn_observable`,label:`Max Tool Turns Reached`,observable:!0,traceable:!0},{id:`progress.stall`,category:`turn_observable`,label:`Progress Stall Detected`,observable:!0,traceable:!0},{id:`turn.idle`,category:`turn_observable`,label:`Idle Turn Detected`,observable:!0,traceable:!0},{id:`tool.call.mismatch`,category:`turn_observable`,label:`Tool Call Protocol Mismatch`,observable:!0,traceable:!0},{id:`prompt.budget`,category:`turn_observable`,label:`Prompt Budget Exceeded`,observable:!0,traceable:!0},{id:`compaction.reactive`,category:`turn_observable`,label:`Reactive Compaction`,observable:!0,traceable:!0},{id:`image.cap`,category:`turn_observable`,label:`Image Cap`,traceable:!0},{id:`image.vision-gate`,category:`turn_observable`,label:`Vision Capability Gate`,traceable:!0},{id:`image.vision-delegate`,category:`turn_observable`,label:`Vision Delegation Result`,observable:!0,traceable:!0},{id:`image.degradation`,category:`turn_observable`,label:`Image Degradation`,observable:!0,traceable:!0},{id:`process.memory.sample`,category:`turn_observable`,label:`Process Memory Sample`,traceable:!0},{id:`stream.retry`,category:`turn_observable`,label:`Stream Retry`,observable:!0,traceable:!0},{id:`stream.retry.accelerated`,category:`turn_observable`,label:`Stream Retry Accelerated`,observable:!0,traceable:!0},{id:`turn.truncated`,category:`turn_observable`,label:`Turn Truncated`,observable:!0,traceable:!0},{id:`rate.limit.exhausted`,category:`turn_observable`,label:`Rate Limit Exhausted`,observable:!0,traceable:!0},{id:`stream.auth-failed`,category:`turn_observable`,label:`Stream Auth Failed`,observable:!0,traceable:!0},{id:`error`,category:`turn_observable`,label:`Error`,observable:!0},{id:`abort`,category:`turn_observable`,label:`Abort`,observable:!0},{id:`lifecycle.tool.completed`,category:`turn_observable`,label:`Lifecycle Tool Completed`,observable:!0},{id:`lifecycle.tool.completed.crossBoundary`,category:`turn_observable`,label:`Lifecycle Tool Completed (Cross Prompt Boundary)`,observable:!0},{id:`lifecycle.tool.timeout`,category:`turn_observable`,label:`Lifecycle Tool Timeout`,observable:!0,traceable:!0},{id:`wire.snapshot.capture`,category:`turn_observable`,label:`Wire Snapshot Capture`,traceable:!0}],D=E;function O(e){return D.filter(t=>t[e]!==void 0&&t[e]!==!1)}const k=D.filter(e=>e.hook!==void 0).map(e=>e.id),ee=D.filter(e=>e.observable===!0).map(e=>e.id),te=D.filter(e=>e.traceable===!0).map(e=>e.id),ne=D.filter(e=>e.pausable===!0).map(e=>({point:e.id,name:e.label,category:e.category})),A={maxToolTurns:120,traceResultMaxChars:512,maxToolResultChars:1e5,minToolResultChars:2e3,promptToolResultFraction:.5,maxToolConcurrency:10,progressDistinctRatio:.5,progressSignatureCap:512,progressSignatureArgsMaxChars:1024,stallWindowTurns:8,stallRepeatThreshold:4,stallEmptyTurnThreshold:3,idleTurnMaxTextChars:400};function j(e,t){let n=Math.max(0,e.length-t);return e.slice(n).map((e,t)=>{let r=typeof e.content==`string`?e.content:JSON.stringify(e.content);return{index:n+t,role:e.role,preview:r.slice(0,200),toolName:e.role===`tool_result`?e.toolName:void 0,tokenEstimate:Math.ceil(r.length/4)}})}function M(e){return{turn:0,frameDepth:0,messagesCount:0,tokenUsage:{input:0,output:0},metadata:{},systemPrompt:``,messagesSummary:[],llmParams:{},...e}}function N(e){return(t,n,r={})=>{let i=e.getLlmParams?.(),a=r.summarySource??e.getMessagesForSummary?.();return e.debug?.pause(M({turn:e.getTurn(),point:t,frameDepth:n,messagesCount:r.messagesCount??e.getMessagesCount(),lastToolName:r.lastToolName,tokenUsage:e.getTokenUsage()??{input:0,output:0},metadata:r.metadata??{},...i?{systemPrompt:i.systemPrompt??``,llmParams:{temperature:i.temperature,maxTokens:i.maxTokens,thinkingLevel:i.thinkingLevel}}:{},...a?{messagesSummary:j(a,10)}:{}}))}}const P=[{key:`systemPrompt`,apply:(e,t)=>{e.systemPrompt!==void 0&&t.setSystemPrompt?.(e.systemPrompt)}},{key:`removeMessageIndices`,apply:(e,t)=>{if(t.messages&&e.removeMessageIndices?.length){let n=[...e.removeMessageIndices].sort((e,t)=>t-e);for(let e of n)e>=0&&e<t.messages.length&&t.messages.splice(e,1)}}},{key:`injectMessages`,apply:(e,t)=>{if(t.messages&&e.injectMessages?.length){let n=t.now??S.now;for(let r of e.injectMessages)r.role===`user`&&t.messages.push({role:`user`,content:r.content,timestamp:n()})}}},{key:`llmParams`,apply:(e,t)=>{e.llmParams&&(e.llmParams.temperature!==void 0&&t.setTemperature?.(e.llmParams.temperature),e.llmParams.maxTokens!==void 0&&t.setMaxTokens?.(e.llmParams.maxTokens),e.llmParams.thinkingLevel!==void 0&&t.setThinkingLevel?.(e.llmParams.thinkingLevel))}}];function F(e,t,n=P){if(e?.command.type===`stop`)throw new v(`Stopped by debugger`);let r=e?.payload;if(!(!r||!t))for(let e of n)r[e.key]!==void 0&&e.apply(r,t)}function I(){return{writeToolSuccesses:0,signatures:new Map,totalCalls:0}}function L(e){e.writeToolSuccesses=0,e.signatures.clear(),e.totalCalls=0}function R(e,t){let n;if(typeof t==`object`&&t&&!Array.isArray(t)){let e=t,r=Object.keys(e).sort(),i=[];for(let t of r){let n;try{n=JSON.stringify(e[t])??`undefined`}catch{n=`[unserializable]`}i.push(`${t}:${n}`)}n=i.join(`,`)}else try{n=JSON.stringify(t)??`undefined`}catch{n=`[unserializable]`}let r=A.progressSignatureArgsMaxChars;return`${e}(${n.length>r?n.slice(0,r):n})`}function z(e,t){if(e.totalCalls++,!t.readonly&&!t.isError&&e.writeToolSuccesses++,e.signatures.size<A.progressSignatureCap){let n=R(t.toolName,t.args);e.signatures.set(n,(e.signatures.get(n)??0)+1)}}function B(e){return e.writeToolSuccesses>0?!0:e.totalCalls===0?!1:e.signatures.size/e.totalCalls>=A.progressDistinctRatio}const V=t;function H(e){return e.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,``).replace(/\x1b\[[\d;?]*[ -/]*[@-~]/g,``).replace(/\x1b\[[\d;?]*(?![\d;@-~])/g,``).replace(/(?:3[89]|4[0-9]);2;\d{1,3};\d{1,3};\d{1,3}m/g,``).replace(/(?:3[89]|4[0-9]);5;\d{1,3}m/g,``).replace(/(?:^|(?<=[\s;m]))(?:\d{1,3}(?:;\d{1,3})+|;\d{1,3})m/gi,``)}function U(e){return e.map(e=>e.type===`text`&&typeof e.text==`string`?{...e,text:H(e.text)}:e)}function W(e,t){return e.map(e=>{if(e.type!==`text`)return e;let n=H(e.text);if(n.length<=t)return{...e,text:n};let r=Math.floor(t*.7),i=t-r,a=n.length-t;return{...e,text:`${n.slice(0,r)}\n\n[… ${a} chars truncated (tool result exceeded ${t} char budget) …]\n\n${n.slice(n.length-i)}`}})}const re=2e3,ie=4e3;function G(e){let t=0;for(let n of e)n.type===`text`?t+=n.text.length:t+=ie;return t}var ae=class{consumed=0;constructor(e,t){this.totalChars=e,this.minPerTool=t}budgetFor(e){if(this.totalChars===void 0)return e;let t=Math.max(0,this.totalChars-this.consumed),n=Math.min(this.minPerTool,e);return Math.max(n,Math.min(e,t))}charge(e){this.consumed+=Math.max(0,e)}get consumedChars(){return this.consumed}};function oe(e,t){if(!(!e||e<=0))return Math.max(0,Math.floor(e*t*4))}async function se(e,t,n,r){if(!e.some(e=>e.type===`text`&&e.text.length>t||e.type===`image`&&e.source.length*.75>V))return W(e,t);let i=0,a=0,o=e.filter(e=>e.type===`image`).length,s=[];for(let c of e){if(c.type===`image`){let e=c.source.length*.75;if(e<=V){s.push(c);continue}if(!r){s.push({type:`text`,text:`[image: ${Math.round(e)} bytes — omitted, no spill port configured]`});continue}let t=o>1?`${n}_img${a}`:`${n}_img`;a++;let i=await r(t,c.source);if(!i){s.push({type:`text`,text:`[image: ${Math.round(e)} bytes — omitted, no spill port configured]`});continue}s.push({type:`text`,text:`[image: ${Math.round(e)} bytes, stored to ${i}, use read tool to inspect if needed]`});continue}if(c.type!==`text`||c.text.length<=t){s.push(c.type===`text`?{...c,text:H(c.text)}:c);continue}if(!r){s.push(...W([c],t));continue}let l=e.filter(e=>e.type===`text`).length>1?`${n}_b${i}`:n;i++;let u=await r(l,c.text);if(!u){s.push(...W([c],t));continue}let d=H(c.text),f=Math.floor(re*.7),p=re-f;s.push({...c,text:`[tool result stored to ${u} (${d.length} chars). Use the read tool on that path to recover the full output.]\n\nPreview:\n${d.slice(0,f)}\n\n[… ${d.length-re} chars omitted …]\n\n${d.slice(d.length-p)}`})}return s}async function ce(e,t,n){let r=Array(e.length),i=0,a=async()=>{for(;;){let t=i++;if(t>=e.length)return;try{await n(e[t]),r[t]={status:`fulfilled`,value:void 0}}catch(e){r[t]={status:`rejected`,reason:e}}}},o=Math.min(Number.isFinite(t)&&t>=1?Math.floor(t):1,e.length);return await Promise.all(Array.from({length:o},()=>a())),r}var le=class{windowTurns;repeatThreshold;emptyTurnThreshold;buckets=[];current={signatures:[],writeToolSuccesses:0};constructor(e={}){this.windowTurns=e.windowTurns??A.stallWindowTurns,this.repeatThreshold=e.repeatThreshold??A.stallRepeatThreshold,this.emptyTurnThreshold=e.emptyTurnThreshold??A.stallEmptyTurnThreshold}recordCall(e){this.current.signatures.length<A.progressSignatureCap&&this.current.signatures.push(R(e.toolName,e.args)),!e.readonly&&!e.isError&&this.current.writeToolSuccesses++}onTurnEnd(){this.buckets.push(this.current),this.buckets.length>this.windowTurns&&this.buckets.shift(),this.current={signatures:[],writeToolSuccesses:0}}evaluate(){let e=this.buckets.length;if(e<this.windowTurns)return{stalled:!1,maxRepeat:0,windowTurns:e,trailingEmpty:0};let t=0,n=new Map,r=0;for(let e of this.buckets){t+=e.writeToolSuccesses;for(let t of e.signatures){let e=(n.get(t)??0)+1;n.set(t,e),e>r&&(r=e)}}let i=0;for(let e=this.buckets.length-1;e>=0&&!(this.buckets[e].signatures.length>0);e--)i++;return{stalled:t===0&&(r>=this.repeatThreshold||i>=this.emptyTurnThreshold),maxRepeat:r,windowTurns:e,trailingEmpty:i}}reset(){this.buckets.length=0,this.current={signatures:[],writeToolSuccesses:0}}};function ue(e){let{sink:t,sessionId:n}=e,r=e.clock??S,i=e.onError??(()=>{});return{record(e){let a={ts:r.now(),sessionId:n,turn:e.turn,kind:e.kind,node:e.node,payload:e.payload,parentEventId:e.parentEventId,causalChain:e.causalChain,evalRunId:e.evalRunId};try{let e=t.append(a);e instanceof Promise&&e.catch(i)}catch(e){i(e)}}}}const K={record(){}},de=new Set([`start`,`text_start`,`text_end`,`thinking_start`,`thinking_end`,`tool_call_start`,`tool_call_end`,`done`]);function fe(e){return de.has(e)}const pe=new Set([`text_end`,`thinking_end`,`tool_call_end`]);function me(e){if(!(`partial`in e))return e;let{partial:t,...n}=e;return n}function he(e){let t,n=n=>{if(!t)return;let{payload:r,turn:i}=t;t=void 0,e.record({kind:`stream`,node:`stream.event`,turn:i,payload:n?r:me(r)})};return{push(r,i){let a=r.type;if(!(typeof a!=`string`||!fe(a))){if(n(!1),pe.has(a)){t={payload:r,turn:i};return}e.record({kind:`stream`,node:`stream.event`,turn:i,payload:r})}},flush(){n(!0)}}}function ge(e,t){let n=[],r=()=>{if(n.length===0)return;let e=n;n=[],t.record({kind:`nondet`,payload:{draws:e}})},i=e=>{n.push(e),n.length>=4096&&r()};return{clock:{now(){let t=e.clock.now();return i({source:`clock`,value:t}),t}},random:{random(){let t=e.random.random();return i({source:`random`,value:t}),t}},id:{uuid(){let t=e.id.uuid();return i({source:`uuid`,value:t}),t}},flushNondetBatch:r}}function _e(e){let t={clock:[],random:[],uuid:[]};for(let n of e)t[n.source].push(n.value);let n=e=>{let n=t[e];if(n.length===0)throw Error(`Replay underrun: no more recorded "${e}" draws`);return n.shift()};return{clock:{now:()=>n(`clock`)},random:{random:()=>n(`random`)},id:{uuid:()=>n(`uuid`)}}}function ve(e){let t=[];for(let n of e){if(n.kind!==`nondet`)continue;let e=n.payload;if(e&&Array.isArray(e.draws))for(let n of e.draws)ye(n)&&t.push(n);else ye(n.payload)&&t.push(n.payload)}return t}function ye(e){return typeof e==`object`&&!!e&&`source`in e&&`value`in e}const be={prune:`memory.prune`,archive:`memory.archive`};function q(e,t){let n=be[t.phase];n!==void 0&&e.record({kind:`lifecycle`,node:n,turn:t.turn,payload:{trigger:t.trigger,sessionId:t.sessionId,...t.metrics}})}function xe(e,t){let n=e.buildContext(),r=[];n.summary&&r.push({role:`user`,timestamp:t.now(),content:[{type:`text`,text:`${a}\n${n.summary}`}]}),r.push(...n.messages);let i=r.map(e=>{if(!Array.isArray(e.content))return e;let t=e.content.map(e=>e.type===`text`&&typeof e.text==`string`?{...e,text:H(e.text)}:e);return{...e,content:t}});return{messages:i,messagesBefore:i.length,hasSummary:!!n.summary}}function Se(e,t){return t.length===0?{fullSystemPrompt:e,systemPromptSegments:void 0}:{fullSystemPrompt:[e,...t].join(`
2
2
 
3
- `),systemPromptSegments:[{text:e,cache:`stable`},...t.map(e=>({text:e,cache:`volatile`}))]}}async function Se(e,t,n,r,i,a){e.pruned&&t?.notifyPrune&&t.notifyPrune(e.pruneMetrics?.tokensSaved??0,e.pruneMetrics?{prunedCount:e.pruneMetrics.prunedCount,messagesBefore:e.pruneMetrics.messagesBefore,messagesAfter:e.pruneMetrics.messagesAfter}:void 0),e.compacted&&e.summary&&e.replacement&&t?.recordCompaction&&(t.recordCompaction(e.summary,e.replacement),n&&(n.compacted=!0,n.replacement=e.replacement),await we(r,i,a,e.messages.length))}async function Ce(e,t,n,r,i={}){let{recorder:a,hooks:o,persistence:s,sink:c}=i;if(!e||r?.aborted)return t;let l=t,u=e.needsPrune(l);if(!u&&!e.needsCompaction(l))return t;let d=!1;if(u&&o){let e={cancelled:!1};await o.execute(`memory.prune.before`,{sessionId:n,messageCount:l.length},e),d=e.cancelled}let f=await e.process(l,n,r,{skipPrune:d});return Te(a,n,`in_loop`,f),await Se(f,s,c,o,n,l.length),f.messages}async function we(e,t,n,r){e&&(await e.emit(`compaction.before`,{sessionId:t,messageCount:n}),await e.emit(`compaction.after`,{sessionId:t,retainedCount:r}))}function Te(e,t,n,r){e&&(r.pruned&&q(e,{phase:`prune`,sessionId:t,trigger:n,metrics:{...r.pruneMetrics}}),r.archivePath&&q(e,{phase:`archive`,sessionId:t,trigger:n,metrics:{archivePath:r.archivePath}}))}async function Ee(e,t,n,r,i={}){let{recorder:a,hooks:o,persistence:s,sink:c}=i;if(!e||r?.aborted)return null;let l=await e.process(t,n,r,{force:!0});return Te(a,n,`reactive_overflow`,l),await Se(l,s,c,o,n,t.length),!l.compacted&&!l.pruned?null:l.messages}function De(e){let{agentName:t,sessionId:n,tools:r,hooks:i,memory:a,recorder:o,persistence:s,onCompaction:c}=e;return{transformContext:async(e,l)=>{if(l?.aborted)return e;let u={messages:e};await i.execute(`messages.transform`,{messages:e,tools:r,agentName:t,sessionId:n},u);let d=e.length,f={compacted:!1},p=await Ce(a,u.messages,n,l,{recorder:o,hooks:i,persistence:s,sink:f});return f.compacted&&f.replacement&&c?.(d,f.replacement),p},reactiveCompact:a?async(e,t)=>{let r=e.length,l={compacted:!1},u=await Ee(a,e,n,t,{recorder:o,persistence:s,sink:l,hooks:i});return l.compacted&&l.replacement&&c?.(r,l.replacement),u}:void 0}}function Oe(e){return e===`low`||e===`medium`||e===`high`||e===`xhigh`||e===`max`}async function ke(e,t,n,r){let i={temperature:t.temperature,maxTokens:t.maxTokens,thinkingLevel:t.thinkingLevel,metadata:{}};await e.execute(`chat.params`,{sessionId:r,model:n.id,provider:n.provider,thinkingLevel:t.thinkingLevel},i),t.temperature=i.temperature,t.maxTokens=i.maxTokens,Oe(i.thinkingLevel)&&(t.thinkingLevel=i.thinkingLevel)}function Ae(e){if(e.role===`user`){if(typeof e.content==`string`)return e.content;if(Array.isArray(e.content))return e.content.map(e=>e.type===`text`?e.text:``).filter(e=>e.length>0).join(`
4
- `)}}async function je(e,t,n,r,i){let a={systemPrompt:t.systemPrompt,systemTail:t.systemTail?[...t.systemTail]:[]};return await e.execute(`system.prompt.transform`,{systemPrompt:t.systemPrompt,sessionId:n,tools:r,userText:i},a),{systemPrompt:a.systemPrompt,systemTail:a.systemTail}}const Me={async planPromptContext(e){let{persistence:t,clock:n,hooks:r,params:i,model:a,sessionId:o,tools:s,onContextSelected:c}=e,{messages:l,messagesBefore:u,hasSummary:d}=be(t,n);await c?.(l,d),await ke(r,i,a,o);let{systemPrompt:f,systemTail:p}=await je(r,i,o,s,e.userText??[...l].reverse().map(Ae).find(Boolean));return{messages:l,messagesBefore:u,hasSummary:d,stableSystem:f,systemTail:p}},buildTurnInput(e){let{fullSystemPrompt:t,systemPromptSegments:n}=xe(e.stableSystem,e.volatileTail);return{model:e.model,systemPrompt:t,...n?{systemPromptSegments:n}:{},...e.cacheRetention?{cacheRetention:e.cacheRetention}:{},messages:e.llmMessages,tools:e.tools.length>0?e.tools:void 0,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature}}};var Ne=class{map=new Map;set(e,t){this.map.set(e,t)}get(e){return this.map.get(e)}delete(e){this.map.delete(e)}};const Pe=new Ne;function Fe(e,t,n,r){e&&e.store.set(e.sessionId,{seq:n,modelId:t,context:r})}function Ie(e,t,n){return`${e===`capped`?`[earlier image capped`:`[earlier image omitted to fit context`}: ${t??`attachment`}, turn ${n}]`}function Le(e,t){if(e.length===0)return{messages:e,degradedCount:0};let n=Math.max(0,Math.min(t,e.length)),r=0;return{messages:e.map((e,t)=>{if(t>=n||!Array.isArray(e.content)||!e.content.some(e=>e.type===`image`))return e;let i=`toolName`in e?e.toolName:void 0,a=e.content.map(e=>e.type===`image`?(r++,{type:`text`,text:Ie(`omitted`,i,t)}):e);return{...e,content:a}}),degradedCount:r}}function Re(e,t=20){let n=0;for(let t of e)if(Array.isArray(t.content))for(let e of t.content)e.type===`image`&&n++;if(n<=t)return{messages:e,cappedCount:0};let r=n-t,i=0;return{messages:e.map((e,t)=>{if(!Array.isArray(e.content)||i>=r)return e;let n=!1;for(let t of e.content)if(t.type===`image`){n=!0;break}if(!n)return e;let a=`toolName`in e?e.toolName:void 0,o=e.content.map(e=>e.type!==`image`||i>=r?e:(i++,{type:`text`,text:Ie(`capped`,a,t)}));return{...e,content:o}}),cappedCount:i}}async function ze(e,t,n,r){if(l(t))return{messages:e,gatedCount:0,describedCount:0};let i=[];for(let t of e)if(Array.isArray(t.content))for(let e of t.content)e.type===`image`&&i.push({mime:e.mime,source:e.source});if(i.length===0)return{messages:e,gatedCount:0,describedCount:0};let a=i.map(()=>null);if(n)try{a=await n(i,r)}catch{a=i.map(()=>null)}let o=0,s=0;return{messages:e.map(e=>{if(!Array.isArray(e.content)||!e.content.some(e=>e.type===`image`))return e;let t=e.content.map(e=>{if(e.type!==`image`)return e;let t=a[s];return s++,t?(o++,{type:`text`,text:t}):{type:`text`,text:`[image not viewable: current model has no vision capability and no vision model is available for delegation]`}});return{...e,content:t}}),gatedCount:i.length,describedCount:o}}async function Be(e,t){let n=t.model.imageConstraints?.maxImagesPerRequest??t.maxImagesDefault,r=Re(e,n);r.cappedCount>0&&t.record(`image.cap`,{cappedCount:r.cappedCount,maxImages:n});let i=await ze(r.messages,t.model,t.describeImages,t.signal);if(i.gatedCount>0&&(t.record(`image.vision-gate`,{gatedCount:i.gatedCount,describedCount:i.describedCount,modelId:t.model.id}),t.describeImages)){let e={turnIndex:t.turnIndex,attemptedCount:i.gatedCount,describedCount:i.describedCount,failedCount:i.gatedCount-i.describedCount};t.record(`image.vision-delegate`,e),t.emitDelegate(e)}return i.messages}function Ve(e=process.env){let t=e.OTTO_AGENT_CONSISTENCY_ASSERT;return t===`warn`?`warn`:t===`off`?`off`:`on`}function He(e){let{persistence:t,messages:n,mode:r,logger:i}=e;return()=>{if(r===`off`)return;let e=t.buildContext().messages.length,a=n().length;if(a>=e)return;let o=`work memory has ${a} messages but session tree projection has ${e} (concurrent write or tree mutation detected)`;if(r===`warn`){(i??console).error(`[messages-consistency] ${o}`);return}throw new x(a,e)}}function Ue(e){return typeof e.content==`string`?e.content:e.content.map(e=>e.type===`text`?e.text:``).filter(e=>e.length>0).join(`
5
- `)}function We(){return{usage:{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0},hadToolActivity:!1,lastAssistantApi:void 0,count:0}}function J(e,t){for(let n of t){if(n.role!==`assistant`)continue;let t=n;e.usage.inputTokens+=t.usage.inputTokens,e.usage.outputTokens+=t.usage.outputTokens,e.usage.cacheReadTokens+=t.usage.cacheReadTokens,e.usage.cacheWriteTokens+=t.usage.cacheWriteTokens,e.lastAssistantApi=t.api,e.count+=1,c(t)&&(e.hadToolActivity=!0)}}function Ge(e,t,n){return{async pause(r,i,a){P(await e?.pause(M({point:r,messagesCount:i.length,metadata:a,systemPrompt:t.systemPrompt,messagesSummary:j(i,10),llmParams:{temperature:t.temperature,maxTokens:t.maxTokens,thinkingLevel:t.thinkingLevel}})),{now:()=>n.now(),setSystemPrompt:e=>{t.systemPrompt=e},setTemperature:e=>{t.temperature=e},setMaxTokens:e=>{t.maxTokens=e},setThinkingLevel:e=>{Oe(e)&&(t.thinkingLevel=e)}})}}}function Ke(e,t,n,r){let i=[{type:`text`,text:e}];if(r&&r.length>0)for(let e of r)i.push({type:`image`,mime:e.mediaType,source:e.data});return{role:`user`,timestamp:t.now(),content:i,...n?{internal:!0}:{}}}function qe(e){return e?.code===`AGENT_ABORTED`?`Tool call interrupted: aborted by user.`:e?.message?`Tool call interrupted: ${e.message}`:`Tool call interrupted before completion (session aborted or errored).`}function Y(e,t,n,r){let i=r.resolvedFrom??e,a=new Set(i.filter(e=>e.role===`tool_result`).map(e=>e.toolCallId));for(let i of t)a.has(i.id)||e.push({role:`tool_result`,toolCallId:i.id,toolName:i.name,content:[{type:`text`,text:r.text}],isError:r.isError,details:{},timestamp:n.now(),...r.internal?{internal:!0}:{}})}function Je(e,t,n){let r=-1;for(let t=e.length-1;t>=0;t--)if(e[t]?.role===`assistant`){r=t;break}if(r===-1)return;let i=s(e[r]);i.length!==0&&Y(e,i,t,{isError:!0,text:qe(n),resolvedFrom:e.slice(r+1)})}async function Ye(e){let{agentName:t,sessionId:n,model:r,tools:i,runner:a,hooks:o,memory:s,params:c,systemPrompt:l,systemTail:u,messages:d,recorder:f,persistence:p,onCompaction:m,onTurnPersist:h,isPauseRequested:g,describeImages:_}=e,{transformContext:v,reactiveCompact:y}=De({agentName:t,sessionId:n,tools:i,hooks:o,memory:s,recorder:f,persistence:p,onCompaction:m}),b=He({persistence:p,messages:()=>d,mode:Ve()});return a.run({model:r,systemPrompt:l,systemTail:u,cacheRetention:c.cacheRetention,tools:i,messages:d,thinkingLevel:c.thinkingLevel,temperature:c.temperature,maxTokens:c.maxTokens,transformContext:v,reactiveCompact:y,onTurnPersist:h,assertMessagesConsistent:b,isPauseRequested:g,describeImages:_})}function X(e,t,n){e.record({kind:`lifecycle`,node:t,payload:n})}async function Xe(e){let{text:t,sessionId:n,agentName:r,model:i,tools:a,runner:o,hooks:s,persistence:c,memory:l,debug:u}=e,d=e.clock??S,f=e.recorder??K,p={...e.params},m=Ge(u,p,d),h=c.messages(),g=h.length===0;await m.pause(`prompt.before`,h,{sessionId:n,isFirstMessage:g}),X(f,`prompt.before`,{sessionId:n,isFirstMessage:g,text:t});let _={message:(e.resumeLastRound?[...h].reverse().find(e=>e.role===`user`):void 0)??Ke(t,d,e.internal,e.images),sessionId:n,isFirstMessage:g,metadata:{}},v={message:_.message,cancelled:!1,metadata:{}};if(!e.resumeLastRound&&(await s.execute(`chat.message.before`,_,v),v.cancelled))return{cancelled:!0,newMessages:[],newMessagesUsageSummary:We(),params:p};let y=v.message,b,x,C,w;try{e.resumeLastRound||c.append(y);let t=await Me.planPromptContext({persistence:c,clock:d,hooks:s,params:p,model:i,sessionId:n,tools:a,userText:Ue(y),onContextSelected:async(e,t)=>{await m.pause(`context.build`,e,{sessionId:n,hasSummary:t}),X(f,`context.build`,{sessionId:n,hasSummary:t,messages:e.length})}});b=t.messages,x=t.messagesBefore,C=t.stableSystem,w=t.systemTail,c.persistInputBoundary?.()}catch(t){throw e.resumeLastRound||c.removeLast?.(),t}let T,E=[],D=We(),O=(e,t)=>{let n=T??x,r=b.slice(n);E.push(...r),J(D,r),b.splice(0,b.length,...t),T=t.length},ee=()=>{let e=T??x;if(e>=b.length)return;let t=b.slice(e);E.push(...t),J(D,t),c.persistNew(b,e),T=b.length};try{let t=await Ye({agentName:r,sessionId:n,model:i,tools:a,runner:o,hooks:s,memory:l,params:p,systemPrompt:C,systemTail:w,messages:b,recorder:f,persistence:c,onCompaction:O,onTurnPersist:ee,isPauseRequested:e.isPauseRequested,describeImages:e.describeImages}),u=T??x;c.persistNew(b,u);let d=b.slice(u);J(D,d);let h=[...E,...d];return await m.pause(`messages.persist`,b,{sessionId:n,newMessages:h.length}),X(f,`messages.persist`,{sessionId:n,newMessages:h.length}),await s.execute(`chat.message.after`,_,{message:v.message,cancelled:!1,metadata:{}}),await m.pause(`prompt.after`,b,{sessionId:n}),X(f,`prompt.after`,{sessionId:n}),await s.emit(`session.idle`,{sessionId:n,metadata:{}}),{cancelled:!1,message:t,newMessages:h,newMessagesUsageSummary:D,params:p}}catch(e){let t=e instanceof Error?e:Error(String(e));throw Je(b,d,{code:t.code,message:t.message}),c.persistNew(b,T??x),await s.emit(`session.error`,{sessionId:n,metadata:{},error:t}),t}}async function Ze(e){let t={totalEvents:0,kinds:{},turns:0,toolCalls:0};for await(let{entry:n}of e)t.totalEvents++,t.kinds[n.kind]=(t.kinds[n.kind]??0)+1,n.turn!==void 0&&n.turn+1>t.turns&&(t.turns=n.turn+1),n.kind===`tool`&&n.node===`tool.call.end`&&t.toolCalls++,t.firstTs===void 0&&(t.firstTs=n.ts),t.lastTs=n.ts;return t}async function Qe(e,t={}){let n=t.digestMax??120,r=[];for await(let t of e){let e=t.entry;r.push({seq:t.seq,ts:e.ts,kind:e.kind,node:e.node,turn:e.turn,digest:et(e.payload,n,e.node)})}return r}function $e(e,t,n){switch(e){case`stream.auth-failed`:{let e=typeof t.provider==`string`?t.provider:void 0,r=typeof t.modelId==`string`?t.modelId:void 0;return!e||!r?void 0:Z(`auth-failed ${r} (${e}): ${typeof t.reason==`string`?t.reason:``}`,n)}case`stream.retry`:case`stream.retry.accelerated`:{let e=typeof t.attempt==`number`?t.attempt:void 0,r=typeof t.maxRetries==`number`?t.maxRetries:void 0;if(e===void 0||r===void 0)return;let i=typeof t.reason==`string`?t.reason:``;return Z(`retry ${e}/${r}${typeof t.delayMs==`number`?` in ${t.delayMs}ms`:``}: ${i}`,n)}case`model.switch`:{let e=typeof t.from==`string`?t.from:null,r=typeof t.to==`string`?t.to:``;return Z(`model ${e?`${e} → `:``}${r}`,n)}case`effort.change`:{let e=typeof t.from==`string`?t.from:null,r=typeof t.to==`string`?t.to:``;return Z(`effort ${e?`${e} → `:``}${r}`,n)}case`retry.queued`:{let e=typeof t.attempt==`number`?t.attempt:void 0,r=typeof t.max==`number`?t.max:void 0;return e===void 0||r===void 0?void 0:Z(`retry ${e}/${r}${typeof t.mode==`string`&&t.mode?` [${t.mode}]`:``}`,n)}case`retry.cancelled`:{let e=typeof t.attempt==`number`?t.attempt:void 0;return e===void 0?`retry cancelled`:Z(`retry cancelled (after ${e})`,n)}case`retry.reset`:return`retry counter reset`;case`pause.requested`:return`pause requested`;case`pause.paused`:return`paused`;case`pause.cancelled`:return`pause cancelled`;case`pause.resumed`:return`resumed`;default:return}}function et(e,t=120,n){if(e!=null){if(typeof e==`string`)return Z(e,t);if(typeof e==`object`){let r=e;if(n!==void 0){let e=$e(n,r,t);if(e!==void 0)return e}if(typeof r.resultSummary==`object`&&r.resultSummary!==null){let e=r.resultSummary,n=typeof r.name==`string`?r.name:`tool`,i=e.isError?` ERR`:``,a=Array.isArray(e.contentPreview)&&e.contentPreview.length>0?e.contentPreview[0]:void 0,o=a?typeof a.preview==`string`?a.preview:typeof a.text==`string`?a.text:``:``,s=typeof r.durationMs==`number`?` ${r.durationMs}ms`:``;return Z(`${n}${i}${typeof r.errorCategory==`string`?` [${r.errorCategory}]`:``}${s}: ${o}`,t)}if(typeof r.result==`object`&&r.result!==null){let e=r.result,n=typeof r.name==`string`?r.name:`tool`,i=e.isError?` ERR`:``,a=Array.isArray(e.content)?e.content[0]:void 0;return Z(`${n}${i}: ${a&&typeof a.text==`string`?a.text:``}`,t)}if(typeof r.text==`string`)return Z(`"${r.text}"`,t);if(typeof r.name==`string`){let e=typeof r.arguments==`object`&&r.arguments!==null?JSON.stringify(r.arguments):``,n=typeof r.durationMs==`number`?` (${r.durationMs}ms)`:``;return Z(`${typeof r.toolCallIndex==`number`?`#${r.toolCallIndex} `:``}${r.name}(${e})${n}`,t)}if(typeof r.provider==`string`&&typeof r.modelId==`string`){let e=typeof r.reason==`string`?r.reason:``;return Z(`auth-failed ${r.modelId} (${r.provider}): ${e}`,t)}if(typeof r.attempt==`number`&&typeof r.maxRetries==`number`){let e=typeof r.reason==`string`?r.reason:``,n=typeof r.delayMs==`number`?` in ${r.delayMs}ms`:``;return Z(`retry ${r.attempt}/${r.maxRetries}${n}: ${e}`,t)}if(typeof r.reason==`string`)return Z(`done:${r.reason}`,t);if(typeof r.message==`object`&&r.message!==null){let e=r.message;if(typeof e.role==`string`&&e.content!==void 0)return Z(`${e.role}:${JSON.stringify(e.content)}`,t)}return Z(JSON.stringify(r),t)}return Z(String(e),t)}}function Z(e,t){return e.length<=t?e:`${e.slice(0,t)}…`}function tt(e){let t=new Map,n=new Map,r=new Map;for(let i of e){let e=i.entry,a=String(i.seq);if(t.set(a,{eventId:a,seq:i.seq,kind:e.kind,node:e.node,turn:e.turn,parentEventId:e.parentEventId,causalChain:e.causalChain}),e.parentEventId){let t=e.parentEventId;n.set(a,[...n.get(a)??[],t]),r.set(t,[...r.get(t)??[],a])}if(e.causalChain)for(let t of e.causalChain)t!==e.parentEventId&&(n.set(a,[...n.get(a)??[],t]),r.set(t,[...r.get(t)??[],a]))}let i=[...t.values()],a=[];for(let[e,t]of n)for(let n of t)a.push({from:n,to:e});return{nodes:i,edges:a,roots:i.filter(e=>!n.has(e.eventId)).map(e=>e.eventId),leaves:i.filter(e=>!r.has(e.eventId)).map(e=>e.eventId)}}function nt(e){let t=new Map,n=new Map;for(let r of e){let e=`entry`in r?r.entry:r;if(e.kind!==`tool`||e.node!==`tool.call.start`||e.turn===void 0)continue;let i=e.payload,a=typeof i?.id==`string`?i.id:``;if(!a||n.has(a))continue;n.set(a,e.turn);let o=t.get(e.turn);o?o.push(a):t.set(e.turn,[a])}return{turns:[...t.entries()].sort(([e],[t])=>e-t).map(([e,t])=>({turn:e,toolCallIds:t})),toolToTurn:n}}function rt(e,t){let n=e.find(e=>e.seq===t);if(!n?.entry.parentEventId)return[];let r=[String(t)],i=n.entry.parentEventId;for(let t=0;t<100&&i;t++){let t=e.find(e=>e.seq===Number(i));if(!t)break;r.unshift(String(t.seq)),i=t.entry.parentEventId??``}return r}function it(e,t=512){return{isError:e.isError??!1,contentCount:e.content.length,contentPreview:e.content.map(e=>{if(e.type===`text`){let n=V(e.text);return n.length>t?{type:`text`,preview:n.slice(0,t),totalLength:n.length}:{type:`text`,text:n}}return e}),details:e.details??void 0}}function at(e,t,n){let r=`[BACKGROUND TASK STARTED — DO NOT TREAT AS COMPLETE]\nTool '${e}' (task id: ${t}) has started running in the background and has NOT finished yet.\nDo NOT attempt to read its output, assume its result, or take any action that depends on\nits completion. You will receive a separate system message titled '[Tool completion]'\nwhen — and only when — this specific task actually finishes. Continue with other work\nor wait; do not fabricate or guess the result.`;return n?`${r}\n${n}`:r}function ot(e,t,n,r){return{role:`tool_result`,toolCallId:e,toolName:t,content:[{type:`text`,text:at(t,e,r)}],isError:!1,details:{},timestamp:n.now()}}function st(e,t,n,r){let i=lt(n),a=n.isError??!1;return{role:`system_notification`,content:`[Tool completion] '${e}' ${a?`failed`:`completed`}: ${i}`,isError:a,relatedToolCallId:t,timestamp:r.now()}}function ct(e,t,n,r){return{role:`system_notification`,content:`[Tool timeout] '${e}' did not complete within ${Math.round(n/1e3)}s; its result is unavailable. Do not assume it succeeded or read its output — re-issue the call if needed, or proceed without it.`,isError:!0,relatedToolCallId:t,timestamp:r.now()}}function lt(e){let t=e.content.find(e=>e.type===`text`);if(!t||t.type!==`text`)return e.isError?`error (no text output)`:`done (no text output)`;let n=V(t.text);return n.length>500?`${n.slice(0,500)}… [truncated]`:n}function ut(e){if(e.isError)return e.errorKind??`unknown`}function dt(e,t){let n=e;return{admit:()=>n===void 0?!0:n<=0?!1:(n--,!0),refund:()=>{n!==void 0&&(n=Math.min(n+1,e))},budgetExceededResult:n=>({role:`tool_result`,toolCallId:n.id,toolName:n.name,content:[{type:`text`,text:`Tool "${n.name}" rejected: per-turn tool-call budget of ${e} exhausted (remaining=0). The call was not executed.`}],isError:!0,details:{},timestamp:t.now()}),isPermissionRefund:e=>e.isError===!0&&e.errorKind===`permission`}}function ft(e,t){let n=new Map,r=null;return{register:t=>{let r=new AbortController;return n.set(t,r),AbortSignal.any([e,r.signal])},unregister:e=>{n.delete(e)},start:()=>{r!==null||n.size===0||(r=setInterval(()=>{t().then(e=>{if(e.length>0){for(let e of n.values())e.abort();r!==null&&(clearInterval(r),r=null)}}).catch(()=>{})},200),r.unref?.())},stop:()=>{r!==null&&(clearInterval(r),r=null)},size:()=>n.size}}function pt(e,t,n,r){return{process:async(i,a)=>{let o=H(i.content);i.content=o;let s=e.get(a.name)?.resultBudgetChars??A.maxToolResultChars,c=await oe(o,t?.budgetFor(s)??s,a.id,n);return t?.charge(G(c)),{role:`tool_result`,toolCallId:a.id,toolName:a.name,content:c,isError:i.isError??!1,details:i.details??{},timestamp:r.now()}}}}async function mt(e,t){let{signal:n,emitter:r,logger:i,clock:a,recorder:o,pause:s,turnIndex:c,budget:l,watcher:u,pipeline:d,windowStats:f,stallDetector:p,toolByName:m}=t;if(n.aborted)throw new v;let h=m.get(e.name),g=n;if(h?.interruptBehavior===`cancel`&&(g=u.register(e.id),u.start()),!l.admit())return u.unregister(e.id),l.budgetExceededResult(e);let _=ht.value++;r.emit(`tool.call.start`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments}}),o.record({kind:`tool`,node:`tool.call.start`,turn:c,payload:{id:e.id,name:e.name,arguments:e.arguments,turnIndex:c,toolCallIndex:_}}),i.info(`Executing tool %s`,e.name),await s(`tool.before`,1,{lastToolName:e.name});let y=a.now(),b=await t.toolExecutor.execute(e,g);if(u.unregister(e.id),l.isPermissionRefund(b)&&l.refund(),n.aborted)throw new v;let x=a.now()-y;i.info(`Tool %s completed%s (%d ms)`,e.name,b.isError?` with error`:``,x);let S=await d.process(b,e);f&&R(f,{toolName:e.name,args:e.arguments,readonly:m.get(e.name)?.readonly===!0,isError:b.isError??!1}),p?.recordCall({toolName:e.name,args:e.arguments,readonly:m.get(e.name)?.readonly===!0,isError:b.isError??!1});let C=ut(b);return r.emit(`tool.call.end`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments},result:b,contextChars:G(S.content)}),o.record({kind:`tool`,node:`tool.call.end`,turn:c,payload:{id:e.id,name:e.name,resultSummary:it(b,A.traceResultMaxChars),durationMs:x,toolCallIndex:_,...C?{errorCategory:C}:{}}}),await s(`tool.after`,1,{lastToolName:e.name}),S}const ht={value:0};async function gt(e,t,n,r,i,a,o){let{toolExecutor:c,messages:l,signal:u,emitter:d,logger:f,getSteeringMessages:p}=t,m=t.ports?.debug,h=t.ports?.clock??S,g=t.ports?.recorder??K,_=N({debug:m,getTurn:()=>n,getMessagesCount:()=>l.length,getTokenUsage:()=>r}),y=s(e).filter(e=>e.argumentsParseFailed!==!0),b=c.list(),x=new Map(b.map(e=>[e.name,e])),C=t.lifecycleAsync!==void 0,w=e=>{let t=x.get(e.name)?.lifecycleAsync;if(typeof t==`function`)try{return t(e.arguments)===!0}catch{return!1}return t===!0},T=C?y.filter(w):[],E=C?y.filter(e=>!w(e)):y;if(!C){let e=y.filter(w);e.length>0&&f.warn(`lifecycleAsync tool(s) called but ctx.lifecycleAsync controller not wired (falling back to synchronous execution, loop will block): %s`,e.map(e=>e.name).join(`, `))}let D=e=>{let t=x.get(e.name);return t?t.readonly?!0:t.isConcurrencySafe?.(e.arguments)===!0:!1},O=E.filter(D),ee=E.filter(e=>!D(e)),k=dt(t.budget.maxToolCallsPerTurn,h),{admit:te,refund:ne,budgetExceededResult:j,isPermissionRefund:M}=k;for(let e of y){let t=x.get(e.name);if(t?.async&&!t.readonly&&!t.isConcurrencySafe)throw Error(`Tool "${e.name}" declared async:true but is neither readonly nor isConcurrencySafe. Async tools must be concurrency-safe (isConcurrencySafe or readonly) to enter the parallel bucket.`)}let P=O.filter(e=>x.get(e.name)?.async===!0),F=O.filter(e=>!x.get(e.name)?.async),I=!1,L=t.lifecycleAsync?.currentPromptSeq()??0;for(let e of T){if(!te()){l.push(j(e));continue}let n=ot(e.id,e.name,h,x.get(e.name)?.lifecycleAsyncNote);l.push(n);let r=new AbortController,i=AbortSignal.any([u,r.signal]),a=c.execute(e,i);t.lifecycleAsync?.register({toolCallId:e.id,toolName:e.name,promise:(async()=>{let n;try{n=await a,M(n)&&ne(),n.content=H(n.content)}catch(t){f.warn(`lifecycleAsync tool %s (task id: %s) promise rejected: %s`,e.name,e.id,t instanceof Error?t.message:String(t)),n={content:[{type:`text`,text:`Tool ${e.name} failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}let{consumed:r}=await t.lifecycleAsync.notifyCompletion(e.id,n);if(!r)return;let i=t.lifecycleAsync?.currentPromptSeq();if(i!==void 0&&i!==L){f.info(`lifecycleAsync tool %s (task id: %s) crossed prompt boundary (startSeq=%d, nowSeq=%d) — completion notice suppressed, emitting crossBoundary event instead`,e.name,e.id,L,i),d.emit(`lifecycle.tool.completed.crossBoundary`,{toolCallId:e.id,toolName:e.name,result:n});return}let o=st(e.name,e.id,n,h);l.push(o)})(),promptSeq:L,consumed:!1,abortController:r}),d.emit(`tool.call.start`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments}}),f.info(`Started lifecycleAsync tool %s (task id: %s), not blocking loop`,e.name,e.id)}T.length>0&&(I=!0);let R=await p();await _(`steering.check`,1,{metadata:{hasSteeringMessages:R.length>0,steeringCount:R.length}});let z=I,B=()=>{Y(l,E,h,{isError:!1,text:`Skipped: superseded by the user’s new instruction (not executed; no error).`})};if(R.length>0)return B(),l.push(...R),d.emit(`steering.injected`,{messages:R}),{ranAnyTool:I};let V=ft(u,p);ht.value=0;let U={toolExecutor:c,toolByName:x,signal:u,emitter:d,logger:f,clock:h,recorder:g,pause:_,turnIndex:n,budget:k,watcher:V,pipeline:pt(x,o,t.ports?.spill,h),windowStats:i,stallDetector:a},W=async e=>{let t=await mt(e,U);l.push(t)};if(F.length>0){let e=A.maxToolConcurrency;f.info(`Executing %d concurrency-safe tools in parallel (cap %d)`,F.length,e);let t=await se(F,e,W);if(z=!0,t.some(e=>e.status===`rejected`&&e.reason instanceof v)||u.aborted)throw new v;let n=t.find(e=>e.status===`rejected`);if(n&&n.status===`rejected`)throw n.reason}if(P.length>0){f.info(`Starting %d async tools in parallel (Promise.all, no worker slot)`,P.length);let e=P.map(e=>mt(e,U)),t=await Promise.all(e);for(let e of t)l.push(e);z=!0,V.size()===0&&V.stop()}for(let e of ee){if(u.aborted)throw new v;let t=await p();if(t.length>0)return V.stop(),B(),l.push(...t),d.emit(`steering.injected`,{messages:t}),{ranAnyTool:z};await W(e),z=!0}return V.stop(),{ranAnyTool:z}}const _t={maxRetries:5,initialDelayMs:500,backoffFactor:2,maxDelayMs:6e4},vt={maxRetries:5,initialDelayMs:3e4,backoffFactor:1,maxDelayMs:3e4},yt={maxRetries:1,initialDelayMs:0,backoffFactor:1,maxDelayMs:0};function bt(e,t,n,r){if(r!==void 0&&r>=0)return Math.min(Math.round(r),t.maxDelayMs);let i=t.initialDelayMs*t.backoffFactor**+e,a=.9+.2*n;return Math.min(Math.round(i*a),t.maxDelayMs)}function xt(e,t,n,r,i){r.hasAttemptedImageDegradation=!0;let a=0;for(let e=t.length-1;e>=0;e--)if(t[e].role===`user`){a=e;break}let{messages:o,degradedCount:s}=Le(t,a);if(s===0)return;let{logger:c,emitter:l}=i,u=i.ports?.recorder??K;return c.warn(`Image degradation triggered (turn %d, trigger=%s): degraded %d images`,n+1,e,s),l.emit(`image.degradation`,{turnIndex:n,degradedCount:s,trigger:e}),u.record({kind:`lifecycle`,node:`image.degradation`,turn:n,payload:{degradedCount:s,trigger:e}}),{action:`retry`,contextMessages:o}}async function St(e,t,n,r,i){let{signal:a,emitter:o,logger:s}=t,c=t.ports?.recorder??K;if(e===`context-overflow`&&t.contextTransform?.reactiveCompact&&!i.hasAttemptedReactiveCompact){i.hasAttemptedReactiveCompact=!0;let e=r.length,l=await t.contextTransform.reactiveCompact(r,a);if(l)return s.warn(`Reactive compaction on context overflow (turn %d): %d -> %d messages`,n+1,e,l.length),o.emit(`compaction.reactive`,{turnIndex:n,messagesBefore:e,messagesAfter:l.length}),c.record({kind:`lifecycle`,node:`compaction.reactive`,turn:n,payload:{messagesBefore:e,messagesAfter:l.length}}),{action:`retry`,contextMessages:l}}if((e===`context-overflow`||e===`image-constraint`)&&!i.hasAttemptedImageDegradation){let a=xt(e,r,n,i,t);if(a)return a}}async function Ct(e,t,n,r,i,a,o,s,c){let{signal:l,emitter:u,logger:d}=n,p=n.ports?.recorder??K,h=f(e),g=t===`retryable`&&h===`idle`?n.retry?.idleTimeoutRetry??yt:t===`retryable`&&_(e)?n.retry?.networkDisconnectRetry??vt:a;if(!(t===`retryable`&&i.transientRetries<g.maxRetries))return;let y=e instanceof Error?e.message:String(e),b=m(e),x=bt(i.transientRetries,g,s.random(),b);i.transientRetries++,d.warn(`Retryable stream error (turn %d, attempt %d/%d, delay %dms): %s`,r+1,i.transientRetries,g.maxRetries,x,y),u.emit(`stream.retry`,{turnIndex:r,attempt:i.transientRetries,maxRetries:g.maxRetries,delayMs:x,reason:y}),p.record({kind:`lifecycle`,node:`stream.retry`,turn:r,payload:{attempt:i.transientRetries,maxRetries:g.maxRetries,delayMs:x,reason:y}}),o&&(o.skip=!1);let S=0;for(;S<x;){if(l.aborted)throw new v;if(o?.skip){o.skip=!1,d.info(`Retry accelerated by user (turn %d, attempt %d/%d, after %dms of %dms)`,r+1,i.transientRetries,g.maxRetries,S,x),u.emit(`stream.retry.accelerated`,{turnIndex:r,attempt:i.transientRetries,maxRetries:g.maxRetries}),p.record({kind:`lifecycle`,node:`stream.retry.accelerated`,turn:r,payload:{attempt:i.transientRetries,maxRetries:g.maxRetries,elapsedMs:S}});break}let e=Math.min(1e3,x-S);await c(e,l),S+=e}if(l.aborted)throw new v;return{action:`retry`}}function wt(e,t,n,r){if(!g(e)||r.hasAttemptedAuthRetry)return;r.hasAttemptedAuthRetry=!0;let i=e instanceof Error?e.message:String(e);return t.logger.warn(`Auth error on first attempt (turn %d, provider=%s, model=%s), retrying once: %s`,n+1,t.model.provider,t.model.id,i),{action:`retry`}}function Tt(e,t,n){let{emitter:r,logger:i}=t,a=t.ports?.recorder??K,o=p(e);if(o?.status===`rejected`){let t=e instanceof Error?e.message:String(e);r.emit(`rate.limit.exhausted`,{limitType:o.type,resetsAt:o.resetsAt,message:t}),a.record({kind:`lifecycle`,node:`rate.limit.exhausted`,turn:n,payload:{limitType:o.type,resetsAt:o.resetsAt}})}else if(g(e)){let o=e instanceof Error?e.message:String(e);i.warn(`Auth failed (turn %d, provider=%s, model=%s): %s`,n+1,t.model.provider,t.model.id,o);let s=u(e);r.emit(`stream.auth-failed`,{turnIndex:n,provider:t.model.provider,modelId:t.model.id,reason:o,errorType:s}),a.record({kind:`lifecycle`,node:`stream.auth-failed`,turn:n,payload:{provider:t.model.provider,modelId:t.model.id,reason:o,errorType:s}})}}async function Et(e,t,n,r,i,a,o,s,c){let{signal:l}=t;if(e instanceof v||e instanceof Error&&e.name===`AbortError`||l.aborted)throw e;let u=d(e);return await St(u,t,n,r,i)||await Ct(e,u,t,n,i,a,o,s,c)||wt(e,t,n,i)||(Tt(e,t,n),{action:`rethrow`})}function Dt(e){for(let t=e.content.length-1;t>=0;t--){let n=e.content[t];if(n.type===`text`)return n.text}return null}function Ot(e,t,n){return`${e===`tokens`?`You have used ${t} of your ${n} output-token budget for this prompt.`:`You have used ${Math.round(t/1e3)}s of your ${Math.round(n/1e3)}s time budget for this prompt.`} Do not start any new tool work or call any tools. Wrap up now: briefly summarize the concrete progress you made, list what still remains or is blocked, and give the user a clear next step. Respond with text only.`}function kt(e,t,n,r,i){if(e.stopReason!==`refusal`)return null;let{emitter:a,logger:o}=t;return o.warn(`Model refused to respond on turn %d; terminating cleanly`,n+1),a.emit(`turn.truncated`,{turnIndex:n,action:`refusal`}),i.recorder.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`refusal`}}),{kind:`terminate`}}function At(e,t,n,r,i){if(e.stopReason!==`end_turn`||e.usage.outputTokens>0||c(e)||e.content.some(e=>e.type===`text`&&e.text.trim().length>0)||e.content.some(e=>e.type===`thinking`))return null;let{emitter:a,logger:o,messages:s}=t,{clock:l,recorder:u}=i;if(r.emptyResponseRetryCount<2){r.emptyResponseRetryCount++;let e=r.emptyResponseRetryCount;return s.push({role:`user`,content:[{type:`text`,text:`<engine_empty_response retry="N">
3
+ `),systemPromptSegments:[{text:e,cache:`stable`},...t.map(e=>({text:e,cache:`volatile`}))]}}async function Ce(e,t,n,r,i,a){e.pruned&&t?.notifyPrune&&t.notifyPrune(e.pruneMetrics?.tokensSaved??0,e.pruneMetrics?{prunedCount:e.pruneMetrics.prunedCount,messagesBefore:e.pruneMetrics.messagesBefore,messagesAfter:e.pruneMetrics.messagesAfter}:void 0),e.compacted&&e.summary&&e.replacement&&t?.recordCompaction&&(t.recordCompaction(e.summary,e.replacement),n&&(n.compacted=!0,n.replacement=e.replacement),await Te(r,i,a,e.messages.length))}async function we(e,t,n,r,i={}){let{recorder:a,hooks:o,persistence:s,sink:c}=i;if(!e||r?.aborted)return t;let l=t,u=e.needsPrune(l);if(!u&&!e.needsCompaction(l))return t;let d=!1;if(u&&o){let e={cancelled:!1};await o.execute(`memory.prune.before`,{sessionId:n,messageCount:l.length},e),d=e.cancelled}let f=await e.process(l,n,r,{skipPrune:d});return Ee(a,n,`in_loop`,f),await Ce(f,s,c,o,n,l.length),f.messages}async function Te(e,t,n,r){e&&(await e.emit(`compaction.before`,{sessionId:t,messageCount:n}),await e.emit(`compaction.after`,{sessionId:t,retainedCount:r}))}function Ee(e,t,n,r){e&&(r.pruned&&q(e,{phase:`prune`,sessionId:t,trigger:n,metrics:{...r.pruneMetrics}}),r.archivePath&&q(e,{phase:`archive`,sessionId:t,trigger:n,metrics:{archivePath:r.archivePath}}))}async function De(e,t,n,r,i={}){let{recorder:a,hooks:o,persistence:s,sink:c}=i;if(!e||r?.aborted)return null;let l=await e.process(t,n,r,{force:!0});return Ee(a,n,`reactive_overflow`,l),await Ce(l,s,c,o,n,t.length),!l.compacted&&!l.pruned?null:l.messages}function Oe(e){let{agentName:t,sessionId:n,tools:r,hooks:i,memory:a,recorder:o,persistence:s,onCompaction:c}=e;return{transformContext:async(e,l)=>{if(l?.aborted)return e;let u={messages:e};await i.execute(`messages.transform`,{messages:e,tools:r,agentName:t,sessionId:n},u);let d=e.length,f={compacted:!1},p=await we(a,u.messages,n,l,{recorder:o,hooks:i,persistence:s,sink:f});return f.compacted&&f.replacement&&c?.(d,f.replacement),p},reactiveCompact:a?async(e,t)=>{let r=e.length,l={compacted:!1},u=await De(a,e,n,t,{recorder:o,persistence:s,sink:l,hooks:i});return l.compacted&&l.replacement&&c?.(r,l.replacement),u}:void 0}}function ke(e){return e===`low`||e===`medium`||e===`high`||e===`xhigh`||e===`max`}async function Ae(e,t,n,r){let i={temperature:t.temperature,maxTokens:t.maxTokens,thinkingLevel:t.thinkingLevel,metadata:{}};await e.execute(`chat.params`,{sessionId:r,model:n.id,provider:n.provider,thinkingLevel:t.thinkingLevel},i),t.temperature=i.temperature,t.maxTokens=i.maxTokens,ke(i.thinkingLevel)&&(t.thinkingLevel=i.thinkingLevel)}function je(e){if(e.role===`user`){if(typeof e.content==`string`)return e.content;if(Array.isArray(e.content))return e.content.map(e=>e.type===`text`?e.text:``).filter(e=>e.length>0).join(`
4
+ `)}}async function Me(e,t,n,r,i){let a={systemPrompt:t.systemPrompt,systemTail:t.systemTail?[...t.systemTail]:[]};return await e.execute(`system.prompt.transform`,{systemPrompt:t.systemPrompt,sessionId:n,tools:r,userText:i},a),{systemPrompt:a.systemPrompt,systemTail:a.systemTail}}const Ne={async planPromptContext(e){let{persistence:t,clock:n,hooks:r,params:i,model:a,sessionId:o,tools:s,onContextSelected:c}=e,{messages:l,messagesBefore:u,hasSummary:d}=xe(t,n);await c?.(l,d),await Ae(r,i,a,o);let{systemPrompt:f,systemTail:p}=await Me(r,i,o,s,e.userText??[...l].reverse().map(je).find(Boolean));return{messages:l,messagesBefore:u,hasSummary:d,stableSystem:f,systemTail:p}},buildTurnInput(e){let{fullSystemPrompt:t,systemPromptSegments:n}=Se(e.stableSystem,e.volatileTail);return{model:e.model,systemPrompt:t,...n?{systemPromptSegments:n}:{},...e.cacheRetention?{cacheRetention:e.cacheRetention}:{},messages:e.llmMessages,tools:e.tools.length>0?e.tools:void 0,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature}}};var Pe=class{map=new Map;set(e,t){this.map.set(e,t)}get(e){return this.map.get(e)}delete(e){this.map.delete(e)}};const Fe=new Pe;function Ie(e,t,n,r){e&&e.store.set(e.sessionId,{seq:n,modelId:t,context:r})}function Le(e,t,n){return`${e===`capped`?`[earlier image capped`:`[earlier image omitted to fit context`}: ${t??`attachment`}, turn ${n}]`}function Re(e,t){if(e.length===0)return{messages:e,degradedCount:0};let n=Math.max(0,Math.min(t,e.length)),r=0;return{messages:e.map((e,t)=>{if(t>=n||!Array.isArray(e.content)||!e.content.some(e=>e.type===`image`))return e;let i=`toolName`in e?e.toolName:void 0,a=e.content.map(e=>e.type===`image`?(r++,{type:`text`,text:Le(`omitted`,i,t)}):e);return{...e,content:a}}),degradedCount:r}}function ze(e,t=20){let n=0;for(let t of e)if(Array.isArray(t.content))for(let e of t.content)e.type===`image`&&n++;if(n<=t)return{messages:e,cappedCount:0};let r=n-t,i=0;return{messages:e.map((e,t)=>{if(!Array.isArray(e.content)||i>=r)return e;let n=!1;for(let t of e.content)if(t.type===`image`){n=!0;break}if(!n)return e;let a=`toolName`in e?e.toolName:void 0,o=e.content.map(e=>e.type!==`image`||i>=r?e:(i++,{type:`text`,text:Le(`capped`,a,t)}));return{...e,content:o}}),cappedCount:i}}async function Be(e,t,n,r){if(l(t))return{messages:e,gatedCount:0,describedCount:0};let i=[];for(let t of e)if(Array.isArray(t.content))for(let e of t.content)e.type===`image`&&i.push({mime:e.mime,source:e.source});if(i.length===0)return{messages:e,gatedCount:0,describedCount:0};let a=i.map(()=>null);if(n)try{a=await n(i,r)}catch{a=i.map(()=>null)}let o=0,s=0;return{messages:e.map(e=>{if(!Array.isArray(e.content)||!e.content.some(e=>e.type===`image`))return e;let t=e.content.map(e=>{if(e.type!==`image`)return e;let t=a[s];return s++,t?(o++,{type:`text`,text:t}):{type:`text`,text:`[image not viewable: current model has no vision capability and no vision model is available for delegation]`}});return{...e,content:t}}),gatedCount:i.length,describedCount:o}}async function Ve(e,t){let n=t.model.imageConstraints?.maxImagesPerRequest??t.maxImagesDefault,r=ze(e,n);r.cappedCount>0&&t.record(`image.cap`,{cappedCount:r.cappedCount,maxImages:n});let i=await Be(r.messages,t.model,t.describeImages,t.signal);if(i.gatedCount>0&&(t.record(`image.vision-gate`,{gatedCount:i.gatedCount,describedCount:i.describedCount,modelId:t.model.id}),t.describeImages)){let e={turnIndex:t.turnIndex,attemptedCount:i.gatedCount,describedCount:i.describedCount,failedCount:i.gatedCount-i.describedCount};t.record(`image.vision-delegate`,e),t.emitDelegate(e)}return i.messages}function He(e=process.env){let t=e.OTTO_AGENT_CONSISTENCY_ASSERT;return t===`warn`?`warn`:t===`off`?`off`:`on`}function Ue(e){let{persistence:t,messages:n,mode:r,logger:i}=e;return()=>{if(r===`off`)return;let e=t.buildContext().messages.length,a=n().length;if(a>=e)return;let o=`work memory has ${a} messages but session tree projection has ${e} (concurrent write or tree mutation detected)`;if(r===`warn`){(i??console).error(`[messages-consistency] ${o}`);return}throw new x(a,e)}}function We(e){return typeof e.content==`string`?e.content:e.content.map(e=>e.type===`text`?e.text:``).filter(e=>e.length>0).join(`
5
+ `)}function Ge(){return{usage:{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0},hadToolActivity:!1,lastAssistantApi:void 0,count:0}}function J(e,t){for(let n of t){if(n.role!==`assistant`)continue;let t=n;e.usage.inputTokens+=t.usage.inputTokens,e.usage.outputTokens+=t.usage.outputTokens,e.usage.cacheReadTokens+=t.usage.cacheReadTokens,e.usage.cacheWriteTokens+=t.usage.cacheWriteTokens,e.lastAssistantApi=t.api,e.count+=1,c(t)&&(e.hadToolActivity=!0)}}function Ke(e,t,n){let r=N({debug:e,getTurn:()=>0,getMessagesCount:()=>0,getTokenUsage:()=>void 0,getLlmParams:()=>({systemPrompt:t.systemPrompt,temperature:t.temperature,maxTokens:t.maxTokens,thinkingLevel:t.thinkingLevel})});return{async pause(e,i,a){F(await r(e,0,{messagesCount:i.length,summarySource:i,metadata:a}),{now:()=>n.now(),setSystemPrompt:e=>{t.systemPrompt=e},setTemperature:e=>{t.temperature=e},setMaxTokens:e=>{t.maxTokens=e},setThinkingLevel:e=>{ke(e)&&(t.thinkingLevel=e)}})}}}function qe(e,t,n,r){let i=[{type:`text`,text:e}];if(r&&r.length>0)for(let e of r)i.push({type:`image`,mime:e.mediaType,source:e.data});return{role:`user`,timestamp:t.now(),content:i,...n?{internal:!0}:{}}}function Je(e){return e?.code===`AGENT_ABORTED`?`Tool call interrupted: aborted by user.`:e?.message?`Tool call interrupted: ${e.message}`:`Tool call interrupted before completion (session aborted or errored).`}function Y(e,t,n,r){let i=r.resolvedFrom??e,a=new Set(i.filter(e=>e.role===`tool_result`).map(e=>e.toolCallId));for(let i of t)a.has(i.id)||e.push({role:`tool_result`,toolCallId:i.id,toolName:i.name,content:[{type:`text`,text:r.text}],isError:r.isError,details:{},timestamp:n.now(),...r.internal?{internal:!0}:{}})}function Ye(e,t,n){let r=-1;for(let t=e.length-1;t>=0;t--)if(e[t]?.role===`assistant`){r=t;break}if(r===-1)return;let i=s(e[r]);i.length!==0&&Y(e,i,t,{isError:!0,text:Je(n),resolvedFrom:e.slice(r+1)})}async function Xe(e){let{agentName:t,sessionId:n,model:r,tools:i,runner:a,hooks:o,memory:s,params:c,systemPrompt:l,systemTail:u,messages:d,recorder:f,persistence:p,onCompaction:m,onTurnPersist:h,isPauseRequested:g,describeImages:_}=e,{transformContext:v,reactiveCompact:y}=Oe({agentName:t,sessionId:n,tools:i,hooks:o,memory:s,recorder:f,persistence:p,onCompaction:m}),b=Ue({persistence:p,messages:()=>d,mode:He()});return a.run({model:r,systemPrompt:l,systemTail:u,cacheRetention:c.cacheRetention,tools:i,messages:d,thinkingLevel:c.thinkingLevel,temperature:c.temperature,maxTokens:c.maxTokens,transformContext:v,reactiveCompact:y,onTurnPersist:h,assertMessagesConsistent:b,isPauseRequested:g,describeImages:_})}function X(e,t,n){e.record({kind:`lifecycle`,node:t,payload:n})}async function Ze(e){let{text:t,sessionId:n,agentName:r,model:i,tools:a,runner:o,hooks:s,persistence:c,memory:l,debug:u}=e,d=e.clock??S,f=e.recorder??K,p={...e.params},m=Ke(u,p,d),h=c.messages(),g=h.length===0;await m.pause(`prompt.before`,h,{sessionId:n,isFirstMessage:g}),X(f,`prompt.before`,{sessionId:n,isFirstMessage:g,text:t});let _={message:(e.resumeLastRound?[...h].reverse().find(e=>e.role===`user`):void 0)??qe(t,d,e.internal,e.images),sessionId:n,isFirstMessage:g,metadata:{}},v={message:_.message,cancelled:!1,metadata:{}};if(!e.resumeLastRound&&(await s.execute(`chat.message.before`,_,v),v.cancelled))return{cancelled:!0,newMessages:[],newMessagesUsageSummary:Ge(),params:p};let y=v.message,b,x,C,w;try{e.resumeLastRound||c.append(y);let t=await Ne.planPromptContext({persistence:c,clock:d,hooks:s,params:p,model:i,sessionId:n,tools:a,userText:We(y),onContextSelected:async(e,t)=>{await m.pause(`context.build`,e,{sessionId:n,hasSummary:t}),X(f,`context.build`,{sessionId:n,hasSummary:t,messages:e.length})}});b=t.messages,x=t.messagesBefore,C=t.stableSystem,w=t.systemTail,c.persistInputBoundary?.()}catch(t){throw e.resumeLastRound||c.removeLast?.(),t}let T,E=[],D=Ge(),O=(e,t)=>{let n=T??x,r=b.slice(n);E.push(...r),J(D,r),b.splice(0,b.length,...t),T=t.length},k=()=>{let e=T??x;if(e>=b.length)return;let t=b.slice(e);E.push(...t),J(D,t),c.persistNew(b,e),T=b.length};try{let t=await Xe({agentName:r,sessionId:n,model:i,tools:a,runner:o,hooks:s,memory:l,params:p,systemPrompt:C,systemTail:w,messages:b,recorder:f,persistence:c,onCompaction:O,onTurnPersist:k,isPauseRequested:e.isPauseRequested,describeImages:e.describeImages}),u=T??x;c.persistNew(b,u);let d=b.slice(u);J(D,d);let h=[...E,...d];return await m.pause(`messages.persist`,b,{sessionId:n,newMessages:h.length}),X(f,`messages.persist`,{sessionId:n,newMessages:h.length}),await s.execute(`chat.message.after`,_,{message:v.message,cancelled:!1,metadata:{}}),await m.pause(`prompt.after`,b,{sessionId:n}),X(f,`prompt.after`,{sessionId:n}),await s.emit(`session.idle`,{sessionId:n,metadata:{}}),{cancelled:!1,message:t,newMessages:h,newMessagesUsageSummary:D,params:p}}catch(e){let t=e instanceof Error?e:Error(String(e));throw Ye(b,d,{code:t.code,message:t.message}),c.persistNew(b,T??x),await s.emit(`session.error`,{sessionId:n,metadata:{},error:t}),t}}async function Qe(e){let t={totalEvents:0,kinds:{},turns:0,toolCalls:0};for await(let{entry:n}of e)t.totalEvents++,t.kinds[n.kind]=(t.kinds[n.kind]??0)+1,n.turn!==void 0&&n.turn+1>t.turns&&(t.turns=n.turn+1),n.kind===`tool`&&n.node===`tool.call.end`&&t.toolCalls++,t.firstTs===void 0&&(t.firstTs=n.ts),t.lastTs=n.ts;return t}async function $e(e,t={}){let n=t.digestMax??120,r=[];for await(let t of e){let e=t.entry;r.push({seq:t.seq,ts:e.ts,kind:e.kind,node:e.node,turn:e.turn,digest:tt(e.payload,n,e.node)})}return r}function et(e,t,n){switch(e){case`stream.auth-failed`:{let e=typeof t.provider==`string`?t.provider:void 0,r=typeof t.modelId==`string`?t.modelId:void 0;return!e||!r?void 0:Z(`auth-failed ${r} (${e}): ${typeof t.reason==`string`?t.reason:``}`,n)}case`stream.retry`:case`stream.retry.accelerated`:{let e=typeof t.attempt==`number`?t.attempt:void 0,r=typeof t.maxRetries==`number`?t.maxRetries:void 0;if(e===void 0||r===void 0)return;let i=typeof t.reason==`string`?t.reason:``;return Z(`retry ${e}/${r}${typeof t.delayMs==`number`?` in ${t.delayMs}ms`:``}: ${i}`,n)}case`model.switch`:{let e=typeof t.from==`string`?t.from:null,r=typeof t.to==`string`?t.to:``;return Z(`model ${e?`${e} → `:``}${r}`,n)}case`effort.change`:{let e=typeof t.from==`string`?t.from:null,r=typeof t.to==`string`?t.to:``;return Z(`effort ${e?`${e} → `:``}${r}`,n)}case`retry.queued`:{let e=typeof t.attempt==`number`?t.attempt:void 0,r=typeof t.max==`number`?t.max:void 0;return e===void 0||r===void 0?void 0:Z(`retry ${e}/${r}${typeof t.mode==`string`&&t.mode?` [${t.mode}]`:``}`,n)}case`retry.cancelled`:{let e=typeof t.attempt==`number`?t.attempt:void 0;return e===void 0?`retry cancelled`:Z(`retry cancelled (after ${e})`,n)}case`retry.reset`:return`retry counter reset`;case`pause.requested`:return`pause requested`;case`pause.paused`:return`paused`;case`pause.cancelled`:return`pause cancelled`;case`pause.resumed`:return`resumed`;default:return}}function tt(e,t=120,n){if(e!=null){if(typeof e==`string`)return Z(e,t);if(typeof e==`object`){let r=e;if(n!==void 0){let e=et(n,r,t);if(e!==void 0)return e}if(typeof r.resultSummary==`object`&&r.resultSummary!==null){let e=r.resultSummary,n=typeof r.name==`string`?r.name:`tool`,i=e.isError?` ERR`:``,a=Array.isArray(e.contentPreview)&&e.contentPreview.length>0?e.contentPreview[0]:void 0,o=a?typeof a.preview==`string`?a.preview:typeof a.text==`string`?a.text:``:``,s=typeof r.durationMs==`number`?` ${r.durationMs}ms`:``;return Z(`${n}${i}${typeof r.errorCategory==`string`?` [${r.errorCategory}]`:``}${s}: ${o}`,t)}if(typeof r.result==`object`&&r.result!==null){let e=r.result,n=typeof r.name==`string`?r.name:`tool`,i=e.isError?` ERR`:``,a=Array.isArray(e.content)?e.content[0]:void 0;return Z(`${n}${i}: ${a&&typeof a.text==`string`?a.text:``}`,t)}if(typeof r.text==`string`)return Z(`"${r.text}"`,t);if(typeof r.name==`string`){let e=typeof r.arguments==`object`&&r.arguments!==null?JSON.stringify(r.arguments):``,n=typeof r.durationMs==`number`?` (${r.durationMs}ms)`:``;return Z(`${typeof r.toolCallIndex==`number`?`#${r.toolCallIndex} `:``}${r.name}(${e})${n}`,t)}if(typeof r.provider==`string`&&typeof r.modelId==`string`){let e=typeof r.reason==`string`?r.reason:``;return Z(`auth-failed ${r.modelId} (${r.provider}): ${e}`,t)}if(typeof r.attempt==`number`&&typeof r.maxRetries==`number`){let e=typeof r.reason==`string`?r.reason:``,n=typeof r.delayMs==`number`?` in ${r.delayMs}ms`:``;return Z(`retry ${r.attempt}/${r.maxRetries}${n}: ${e}`,t)}if(typeof r.reason==`string`)return Z(`done:${r.reason}`,t);if(typeof r.message==`object`&&r.message!==null){let e=r.message;if(typeof e.role==`string`&&e.content!==void 0)return Z(`${e.role}:${JSON.stringify(e.content)}`,t)}return Z(JSON.stringify(r),t)}return Z(String(e),t)}}function Z(e,t){return e.length<=t?e:`${e.slice(0,t)}…`}function nt(e){let t=new Map,n=new Map,r=new Map;for(let i of e){let e=i.entry,a=String(i.seq);if(t.set(a,{eventId:a,seq:i.seq,kind:e.kind,node:e.node,turn:e.turn,parentEventId:e.parentEventId,causalChain:e.causalChain}),e.parentEventId){let t=e.parentEventId;n.set(a,[...n.get(a)??[],t]),r.set(t,[...r.get(t)??[],a])}if(e.causalChain)for(let t of e.causalChain)t!==e.parentEventId&&(n.set(a,[...n.get(a)??[],t]),r.set(t,[...r.get(t)??[],a]))}let i=[...t.values()],a=[];for(let[e,t]of n)for(let n of t)a.push({from:n,to:e});return{nodes:i,edges:a,roots:i.filter(e=>!n.has(e.eventId)).map(e=>e.eventId),leaves:i.filter(e=>!r.has(e.eventId)).map(e=>e.eventId)}}function rt(e){let t=new Map,n=new Map;for(let r of e){let e=`entry`in r?r.entry:r;if(e.kind!==`tool`||e.node!==`tool.call.start`||e.turn===void 0)continue;let i=e.payload,a=typeof i?.id==`string`?i.id:``;if(!a||n.has(a))continue;n.set(a,e.turn);let o=t.get(e.turn);o?o.push(a):t.set(e.turn,[a])}return{turns:[...t.entries()].sort(([e],[t])=>e-t).map(([e,t])=>({turn:e,toolCallIds:t})),toolToTurn:n}}function it(e,t){let n=e.find(e=>e.seq===t);if(!n?.entry.parentEventId)return[];let r=[String(t)],i=n.entry.parentEventId;for(let t=0;t<100&&i;t++){let t=e.find(e=>e.seq===Number(i));if(!t)break;r.unshift(String(t.seq)),i=t.entry.parentEventId??``}return r}function at(e,t=512){return{isError:e.isError??!1,contentCount:e.content.length,contentPreview:e.content.map(e=>{if(e.type===`text`){let n=H(e.text);return n.length>t?{type:`text`,preview:n.slice(0,t),totalLength:n.length}:{type:`text`,text:n}}return e}),details:e.details??void 0}}function ot(e,t,n){let r=`[BACKGROUND TASK STARTED — DO NOT TREAT AS COMPLETE]\nTool '${e}' (task id: ${t}) has started running in the background and has NOT finished yet.\nDo NOT attempt to read its output, assume its result, or take any action that depends on\nits completion. You will receive a separate system message titled '[Tool completion]'\nwhen — and only when — this specific task actually finishes. Continue with other work\nor wait; do not fabricate or guess the result.`;return n?`${r}\n${n}`:r}function st(e,t,n,r){return{role:`tool_result`,toolCallId:e,toolName:t,content:[{type:`text`,text:ot(t,e,r)}],isError:!1,details:{},timestamp:n.now()}}function ct(e,t,n,r){let i=ut(n),a=n.isError??!1;return{role:`system_notification`,content:`[Tool completion] '${e}' ${a?`failed`:`completed`}: ${i}`,isError:a,relatedToolCallId:t,timestamp:r.now()}}function lt(e,t,n,r){return{role:`system_notification`,content:`<engine_timeout tool="${e}" id="${t}" ms="${n}">\n'${e}' did not complete within ${Math.round(n/1e3)}s; its result is unavailable. Do not assume it succeeded or read its output — re-issue the call if needed, or proceed without it.\n</engine_timeout>`,isError:!0,relatedToolCallId:t,timestamp:r.now()}}function ut(e){let t=e.content.find(e=>e.type===`text`);if(!t||t.type!==`text`)return e.isError?`error (no text output)`:`done (no text output)`;let n=H(t.text);return n.length>500?`${n.slice(0,500)}… [truncated]`:n}function dt(e){if(e.isError)return e.errorKind??`unknown`}function ft(e,t){let n=e;return{admit:()=>n===void 0?!0:n<=0?!1:(n--,!0),refund:()=>{n!==void 0&&(n=Math.min(n+1,e))},budgetExceededResult:n=>({role:`tool_result`,toolCallId:n.id,toolName:n.name,content:[{type:`text`,text:`Tool "${n.name}" rejected: per-turn tool-call budget of ${e} exhausted (remaining=0). The call was not executed.`}],isError:!0,details:{},timestamp:t.now()}),isPermissionRefund:e=>e.isError===!0&&e.errorKind===`permission`}}function pt(e,t){let n=new Map,r=null,i=[];return{register:t=>{let r=new AbortController;return n.set(t,r),AbortSignal.any([e,r.signal])},unregister:e=>{n.delete(e)},start:()=>{r!==null||n.size===0||(r=setInterval(()=>{t().then(e=>{if(e.length>0){i.push(...e);for(let e of n.values())e.abort();r!==null&&(clearInterval(r),r=null)}}).catch(()=>{})},200),r.unref?.())},stop:()=>{r!==null&&(clearInterval(r),r=null)},size:()=>n.size,drainPendingSteering:()=>{let e=i;return i=[],e}}}function mt(e,t,n,r){return{process:async(i,a)=>{let o=U(i.content);i.content=o;let s=e.get(a.name)?.resultBudgetChars??A.maxToolResultChars,c=await se(o,t?.budgetFor(s)??s,a.id,n);return t?.charge(G(c)),{role:`tool_result`,toolCallId:a.id,toolName:a.name,content:c,isError:i.isError??!1,details:i.details??{},timestamp:r.now()}}}}async function ht(e,t){let{signal:n,emitter:r,logger:i,clock:a,recorder:o,pause:s,turnIndex:c,budget:l,watcher:u,pipeline:d,windowStats:f,stallDetector:p,toolByName:m}=t;if(n.aborted)throw new v;let h=m.get(e.name),g=n;if(h?.interruptBehavior===`cancel`&&(g=u.register(e.id),u.start()),!l.admit())return u.unregister(e.id),l.budgetExceededResult(e);let _=gt.value++;r.emit(`tool.call.start`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments}}),o.record({kind:`tool`,node:`tool.call.start`,turn:c,payload:{id:e.id,name:e.name,arguments:e.arguments,turnIndex:c,toolCallIndex:_}}),i.info(`Executing tool %s`,e.name),await s(`tool.before`,1,{lastToolName:e.name});let y=a.now(),b=await t.toolExecutor.execute(e,g);if(u.unregister(e.id),l.isPermissionRefund(b)&&l.refund(),n.aborted)throw new v;let x=a.now()-y;i.info(`Tool %s completed%s (%d ms)`,e.name,b.isError?` with error`:``,x);let S=await d.process(b,e);f&&z(f,{toolName:e.name,args:e.arguments,readonly:m.get(e.name)?.readonly===!0,isError:b.isError??!1}),p?.recordCall({toolName:e.name,args:e.arguments,readonly:m.get(e.name)?.readonly===!0,isError:b.isError??!1});let C=dt(b);return r.emit(`tool.call.end`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments},result:b,contextChars:G(S.content)}),o.record({kind:`tool`,node:`tool.call.end`,turn:c,payload:{id:e.id,name:e.name,resultSummary:at(b,A.traceResultMaxChars),durationMs:x,toolCallIndex:_,...C?{errorCategory:C}:{}}}),await s(`tool.after`,1,{lastToolName:e.name}),S}const gt={value:0};async function _t(e,t,n,r,i,a,o){let{toolExecutor:c,messages:l,signal:u,emitter:d,logger:f,getSteeringMessages:p}=t,m=t.ports?.debug,h=t.ports?.clock??S,g=t.ports?.recorder??K,_=N({debug:m,getTurn:()=>n,getMessagesCount:()=>l.length,getTokenUsage:()=>r}),y=s(e).filter(e=>e.argumentsParseFailed!==!0),b=c.list(),x=new Map(b.map(e=>[e.name,e])),C=t.lifecycleAsync!==void 0,w=e=>{let t=x.get(e.name)?.lifecycleAsync;if(typeof t==`function`)try{return t(e.arguments)===!0}catch{return!1}return t===!0},T=C?y.filter(w):[],E=C?y.filter(e=>!w(e)):y;if(!C){let e=y.filter(w);e.length>0&&f.warn(`lifecycleAsync tool(s) called but ctx.lifecycleAsync controller not wired (falling back to synchronous execution, loop will block): %s`,e.map(e=>e.name).join(`, `))}let D=e=>{let t=x.get(e.name);return t?t.readonly?!0:t.isConcurrencySafe?.(e.arguments)===!0:!1},O=E.filter(D),k=E.filter(e=>!D(e)),ee=ft(t.budget.maxToolCallsPerTurn,h),{admit:te,budgetExceededResult:ne}=ee;for(let e of y){let t=x.get(e.name);if(t?.async&&!t.readonly&&!t.isConcurrencySafe)throw Error(`Tool "${e.name}" declared async:true but is neither readonly nor isConcurrencySafe. Async tools must be concurrency-safe (isConcurrencySafe or readonly) to enter the parallel bucket.`)}let j=O.filter(e=>x.get(e.name)?.async===!0),M=O.filter(e=>!x.get(e.name)?.async),P=!1,F=t.lifecycleAsync?.currentPromptSeq()??0;for(let e of T){if(!te()){l.push(ne(e));continue}let n=st(e.id,e.name,h,x.get(e.name)?.lifecycleAsyncNote);l.push(n);let r=new AbortController,i=AbortSignal.any([u,r.signal]),a=c.execute(e,i);t.lifecycleAsync?.register({toolCallId:e.id,toolName:e.name,promise:(async()=>{let n;try{n=await a,n.content=U(n.content)}catch(t){f.warn(`lifecycleAsync tool %s (task id: %s) promise rejected: %s`,e.name,e.id,t instanceof Error?t.message:String(t)),n={content:[{type:`text`,text:`Tool ${e.name} failed: ${t instanceof Error?t.message:String(t)}`}],isError:!0}}let{consumed:r}=await t.lifecycleAsync.notifyCompletion(e.id,n);if(!r)return;let i=t.lifecycleAsync?.currentPromptSeq();if(i!==void 0&&i!==F){f.info(`lifecycleAsync tool %s (task id: %s) crossed prompt boundary (startSeq=%d, nowSeq=%d) — completion notice suppressed, emitting crossBoundary event instead`,e.name,e.id,F,i),d.emit(`lifecycle.tool.completed.crossBoundary`,{toolCallId:e.id,toolName:e.name,result:n});return}let o=ct(e.name,e.id,n,h);l.push(o)})(),promptSeq:F,consumed:!1,abortController:r}),d.emit(`tool.call.start`,{toolCall:{id:e.id,name:e.name,arguments:e.arguments}}),f.info(`Started lifecycleAsync tool %s (task id: %s), not blocking loop`,e.name,e.id)}T.length>0&&(P=!0);let I=await p();await _(`steering.check`,1,{metadata:{hasSteeringMessages:I.length>0,steeringCount:I.length}});let L=P,R=()=>{Y(l,E,h,{isError:!1,text:`Skipped: superseded by the user’s new instruction (not executed; no error).`})};if(I.length>0)return R(),l.push(...I),d.emit(`steering.injected`,{messages:I}),{ranAnyTool:P};let z=pt(u,p),B=()=>{let e=z.drainPendingSteering();return e.length===0?!1:(z.stop(),R(),l.push(...e),d.emit(`steering.injected`,{messages:e}),!0)};gt.value=0;let V={toolExecutor:c,toolByName:x,signal:u,emitter:d,logger:f,clock:h,recorder:g,pause:_,turnIndex:n,budget:ee,watcher:z,pipeline:mt(x,o,t.ports?.spill,h),windowStats:i,stallDetector:a},H=async e=>{let t=await ht(e,V);l.push(t)};if(M.length>0){let e=A.maxToolConcurrency;f.info(`Executing %d concurrency-safe tools in parallel (cap %d)`,M.length,e);let t=await ce(M,e,H);if(L=!0,t.some(e=>e.status===`rejected`&&e.reason instanceof v)||u.aborted){if(B()&&!u.aborted)return{ranAnyTool:L};throw new v}let n=t.find(e=>e.status===`rejected`);if(n&&n.status===`rejected`)throw n.reason}if(j.length>0){f.info(`Starting %d async tools in parallel (Promise.all, no worker slot)`,j.length);let e=j.map(e=>ht(e,V)),t=await Promise.all(e);for(let e of t)l.push(e);L=!0}if(B())return{ranAnyTool:L};z.size()===0&&z.stop();for(let e of k){if(u.aborted)throw B(),new v;let t=[...await p(),...z.drainPendingSteering()];if(t.length>0)return z.stop(),R(),l.push(...t),d.emit(`steering.injected`,{messages:t}),{ranAnyTool:L};await H(e),L=!0}return B()||z.stop(),{ranAnyTool:L}}const vt={maxRetries:5,initialDelayMs:500,backoffFactor:2,maxDelayMs:6e4},yt={maxRetries:5,initialDelayMs:3e4,backoffFactor:1,maxDelayMs:3e4},bt={maxRetries:1,initialDelayMs:0,backoffFactor:1,maxDelayMs:0};function xt(e,t,n,r){if(r!==void 0&&r>=0)return Math.min(Math.round(r),t.maxDelayMs);let i=t.initialDelayMs*t.backoffFactor**+e,a=.9+.2*n;return Math.min(Math.round(i*a),t.maxDelayMs)}function St(e,t,n,r,i){r.hasAttemptedImageDegradation=!0;let a=0;for(let e=t.length-1;e>=0;e--)if(t[e].role===`user`){a=e;break}let{messages:o,degradedCount:s}=Re(t,a);if(s===0)return;let{logger:c,emitter:l}=i,u=i.ports?.recorder??K;return c.warn(`Image degradation triggered (turn %d, trigger=%s): degraded %d images`,n+1,e,s),l.emit(`image.degradation`,{turnIndex:n,degradedCount:s,trigger:e}),u.record({kind:`lifecycle`,node:`image.degradation`,turn:n,payload:{degradedCount:s,trigger:e}}),{action:`retry`,contextMessages:o}}async function Ct(e,t,n,r,i){let{signal:a,emitter:o,logger:s}=t,c=t.ports?.recorder??K;if(e===`context-overflow`&&t.contextTransform?.reactiveCompact&&!i.hasAttemptedReactiveCompact){i.hasAttemptedReactiveCompact=!0;let e=r.length,l=await t.contextTransform.reactiveCompact(r,a);if(l)return s.warn(`Reactive compaction on context overflow (turn %d): %d -> %d messages`,n+1,e,l.length),o.emit(`compaction.reactive`,{turnIndex:n,messagesBefore:e,messagesAfter:l.length}),c.record({kind:`lifecycle`,node:`compaction.reactive`,turn:n,payload:{messagesBefore:e,messagesAfter:l.length}}),{action:`retry`,contextMessages:l}}if((e===`context-overflow`||e===`image-constraint`)&&!i.hasAttemptedImageDegradation){let a=St(e,r,n,i,t);if(a)return a}}async function wt(e,t,n,r,i,a,o,s,c){let{signal:l,emitter:u,logger:d}=n,p=n.ports?.recorder??K,h=f(e),g=t===`retryable`&&h===`idle`?n.retry?.idleTimeoutRetry??bt:t===`retryable`&&_(e)?n.retry?.networkDisconnectRetry??yt:a;if(!(t===`retryable`&&i.transientRetries<g.maxRetries))return;let y=e instanceof Error?e.message:String(e),b=m(e),x=xt(i.transientRetries,g,s.random(),b);i.transientRetries++,d.warn(`Retryable stream error (turn %d, attempt %d/%d, delay %dms): %s`,r+1,i.transientRetries,g.maxRetries,x,y),u.emit(`stream.retry`,{turnIndex:r,attempt:i.transientRetries,maxRetries:g.maxRetries,delayMs:x,reason:y}),p.record({kind:`lifecycle`,node:`stream.retry`,turn:r,payload:{attempt:i.transientRetries,maxRetries:g.maxRetries,delayMs:x,reason:y}}),o&&(o.skip=!1);let S=0;for(;S<x;){if(l.aborted)throw new v;if(o?.skip){o.skip=!1,d.info(`Retry accelerated by user (turn %d, attempt %d/%d, after %dms of %dms)`,r+1,i.transientRetries,g.maxRetries,S,x),u.emit(`stream.retry.accelerated`,{turnIndex:r,attempt:i.transientRetries,maxRetries:g.maxRetries}),p.record({kind:`lifecycle`,node:`stream.retry.accelerated`,turn:r,payload:{attempt:i.transientRetries,maxRetries:g.maxRetries,elapsedMs:S}});break}let e=Math.min(1e3,x-S);await c(e,l),S+=e}if(l.aborted)throw new v;return{action:`retry`}}function Tt(e,t,n,r){if(!g(e)||r.hasAttemptedAuthRetry)return;r.hasAttemptedAuthRetry=!0;let i=e instanceof Error?e.message:String(e);return t.logger.warn(`Auth error on first attempt (turn %d, provider=%s, model=%s), retrying once: %s`,n+1,t.model.provider,t.model.id,i),{action:`retry`}}function Et(e,t,n){let{emitter:r,logger:i}=t,a=t.ports?.recorder??K,o=p(e);if(o?.status===`rejected`){let t=e instanceof Error?e.message:String(e);r.emit(`rate.limit.exhausted`,{limitType:o.type,resetsAt:o.resetsAt,message:t}),a.record({kind:`lifecycle`,node:`rate.limit.exhausted`,turn:n,payload:{limitType:o.type,resetsAt:o.resetsAt}})}else if(g(e)){let o=e instanceof Error?e.message:String(e);i.warn(`Auth failed (turn %d, provider=%s, model=%s): %s`,n+1,t.model.provider,t.model.id,o);let s=u(e);r.emit(`stream.auth-failed`,{turnIndex:n,provider:t.model.provider,modelId:t.model.id,reason:o,errorType:s}),a.record({kind:`lifecycle`,node:`stream.auth-failed`,turn:n,payload:{provider:t.model.provider,modelId:t.model.id,reason:o,errorType:s}})}}async function Dt(e,t,n,r,i,a,o,s,c){let{signal:l}=t;if(e instanceof v||e instanceof Error&&e.name===`AbortError`||l.aborted)throw e;let u=d(e);return await Ct(u,t,n,r,i)||await wt(e,u,t,n,i,a,o,s,c)||Tt(e,t,n,i)||(Et(e,t,n),{action:`rethrow`})}function Ot(e){for(let t=e.content.length-1;t>=0;t--){let n=e.content[t];if(n.type===`text`)return n.text}return null}function kt(e,t,n){return`<engine_budget dimension="${e}">\n${e===`tokens`?`You have used ${t} of your ${n} output-token budget for this prompt.`:`You have used ${Math.round(t/1e3)}s of your ${Math.round(n/1e3)}s time budget for this prompt.`} Do not start any new tool work or call any tools. Wrap up now: briefly summarize the concrete progress you made, list what still remains or is blocked, and give the user a clear next step. Respond with text only.
6
+ </engine_budget>`}function At(e,t,n,r,i){if(e.stopReason!==`refusal`)return null;let{emitter:a,logger:o}=t;return o.warn(`Model refused to respond on turn %d; terminating cleanly`,n+1),a.emit(`turn.truncated`,{turnIndex:n,action:`refusal`}),i.recorder.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`refusal`}}),{kind:`terminate`}}function jt(e,t,n,r,i){if(e.stopReason!==`end_turn`||c(e)||e.content.some(e=>e.type===`text`&&e.text.trim().length>0))return null;if(e.content.some(e=>e.type===`thinking`))return i.recorder.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`thinking-only`}}),t.emitter.emit(`turn.truncated`,{turnIndex:n,action:`thinking-only`}),null;let{emitter:a,logger:o}=t,{recorder:s}=i;if(r.emptyResponseRetryCount<2){r.emptyResponseRetryCount++;let s=r.emptyResponseRetryCount;return Q(e,t,n,i,`<engine_empty_response retry="N">
6
7
  Your previous response was empty (no output produced). Please respond with content or tool calls, or explicitly state that you cannot proceed.
7
- </engine_empty_response>`.replace(`retry="N"`,`retry="${e}"`)}],timestamp:l.now(),internal:!0}),o.warn(`Empty response (end_turn + 0 output tokens) on turn %d; injecting steering retry (%d/%d)`,n+1,e,2),a.emit(`turn.truncated`,{turnIndex:n,action:`empty-response`}),u.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`empty-response`,retryCount:e}}),{kind:`continue`}}return o.warn(`Empty response persisted after %d retries on turn %d; terminating (not silently)`,2,n+1),u.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`empty-response`,retryCount:r.emptyResponseRetryCount,exhausted:!0}}),{kind:`terminate`}}function jt(e,t,n,r,i){if(e.stopReason!==`max_tokens`||c(e))return null;let{emitter:a,logger:o,messages:s}=t,{clock:l,recorder:u}=i;return r.continuationCount<5?(r.continuationCount++,s.push({role:`user`,content:[{type:`text`,text:`Your previous response was cut off because it reached the output token limit. Continue exactly where you left off — do not repeat content already produced.`}],timestamp:l.now(),internal:!0}),o.warn(`Output truncated (max_tokens) on turn %d; appending continuation prompt (%d/%d)`,n+1,r.continuationCount,5),a.emit(`turn.truncated`,{turnIndex:n,action:`continue`}),u.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`continue`,continuation:r.continuationCount}}),{kind:`continue`}):(o.warn(`Output still truncated after %d continuations; returning partial response`,5),{kind:`terminate`})}function Mt(e,t,n,r,i){let{emitter:a,logger:o}=t,{clock:s}=i,c=Bt(t,r,s);if(!c)return null;let{dimension:l,used:u,budget:d}=c;if(t.budget.budgetSteerWrapUp&&!r.budgetSteeringIssued)return r.budgetSteeringIssued=!0,Ht(e,t,n,i,Ot(l,u,d),{type:`prompt.budget`,emit:()=>a.emit(`prompt.budget`,{turnIndex:n,dimension:l,used:u,budget:d,steered:!0}),recordNode:`prompt.budget`,recordPayload:{dimension:l,used:u,budget:d,steered:!0}}),o.info(`Prompt %s budget exceeded (%d/%d); steering model to wrap up`,l,u,d),{kind:`continue`};let f=e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
8
- `).trim();throw a.emit(`prompt.budget`,{turnIndex:n,dimension:l,used:u,budget:d,steered:!1}),recorder.record({kind:`lifecycle`,node:`prompt.budget`,turn:n,payload:{dimension:l,used:u,budget:d,steered:!1}}),new b(l,u,d,f)}function Nt(e,t,n,r,i){let{emitter:a,logger:o}=t,{clock:s}=i;if(r.toolTurnCount<Q(t))return{kind:`run-tools`};let c=Q(t),l=t.budget.maxToolTurnExtensions??0,u=z(r.windowStats);if(r.extensionsUsed<l&&u)return r.extensionsUsed++,a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!0}),recorder.record({kind:`lifecycle`,node:`max.turns`,turn:n,payload:{maxTurns:c,extended:!0,extension:r.extensionsUsed,maxExtensions:l}}),o.info(`Tool budget exhausted (%d); extending %d/%d (per-turn transformContext compacts on token threshold)`,c,r.extensionsUsed,l),r.toolTurnCount=0,I(r.windowStats),r.pendingBudgetNotice=`[Tool budget extended: window ${r.extensionsUsed}/${l} · output tokens this prompt: ${r.promptOutputTokens}]`,{kind:`run-tools`};if(t.budget.budgetSteerWrapUp&&!r.budgetSteeringIssued){r.budgetSteeringIssued=!0;let s=r.extensionsUsed<l&&!u;return Ht(e,t,n,i,`You have reached your tool-call budget for this turn. Do not start any new tool work or call any tools. Wrap up now: briefly summarize the concrete progress you made, list what still remains or is blocked, and give the user a clear next step. Respond with text only.`,{type:`max.turns`,emit:()=>a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!1,steered:!0,...s?{progressDenied:!0}:{}}),recordNode:`max.turns`,recordPayload:{maxTurns:c,extended:!1,steered:!0,progressDenied:s,extension:r.extensionsUsed,maxExtensions:l}}),o.info(s?`Tool budget window showed no progress (loop suspected); steering model to wrap up`:`Tool budget exhausted (%d); steering model to wrap up in one final turn`,c),{kind:`continue`}}let d=e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
9
- `).trim(),f=r.extensionsUsed<l&&!u;throw a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!1,...f?{progressDenied:!0}:{}}),recorder.record({kind:`lifecycle`,node:`max.turns`,turn:n,payload:{maxTurns:c,extended:!1,steered:!1,progressDenied:f,extension:r.extensionsUsed,maxExtensions:l}}),new y(c,d,l)}function Pt(e,t,n,r,i){if(e.stopReason!==`max_tokens`)return null;let a=s(e).filter(e=>e.argumentsParseFailed===!0);if(a.length===0)return null;let{logger:o,messages:c}=t;for(let e of a)c.push({role:`tool_result`,toolCallId:e.id,toolName:e.name,content:[{type:`text`,text:`Tool call arguments were cut off by the output token limit and could not be parsed. Re-issue the call, splitting large content into smaller pieces if necessary.`}],isError:!0,details:{},timestamp:i.clock.now(),internal:!0}),o.warn(`Tool call %s (%s) had truncated arguments (max_tokens) on turn %d; synthesized error result`,e.id,e.name,n+1);return i.recorder.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`broken-tool-call`,count:a.length}}),null}function Ft(e,t,n,r,i){let a=r.stallDetector;if(!a||(a.onTurnEnd(),r.stallSteeringIssued))return null;let o=a.evaluate();if(!o.stalled)return null;let{emitter:s,logger:c}=t,{clock:l,recorder:u}=i;return r.stallSteeringIssued=!0,Ht(e,t,n,i,`Progress check: your recent tool calls repeat the same operations without producing changes — you may be stuck in a loop. Either switch to a different approach now (different tools, different angle, or narrower scope), or if the task genuinely cannot advance, stop and report: what you tried, what blocked you, and what the user should do next.`,{type:`progress.stall`,emit:()=>s.emit(`progress.stall`,{turnIndex:n,windowTurns:o.windowTurns,maxRepeat:o.maxRepeat}),recordNode:`progress.stall`,recordPayload:{windowTurns:o.windowTurns,maxRepeat:o.maxRepeat}}),c.info(`Stall detected (same signature repeated %d times over %d turns, zero write successes); steering model to change approach`,o.maxRepeat,o.windowTurns),{kind:`continue`}}function It(e,t,n,r,i){return c(e)?Mt(e,t,n,r,i)??Nt(e,t,n,r,i):null}function Lt(e,t,n,r,i){if(c(e))return null;let a=Dt(e);if(a===null||!h(a,new Set(t.toolExecutor.list().map(e=>e.name))))return null;let{emitter:o,logger:s,messages:l}=t,{clock:u,recorder:d}=i;return r.protocolMismatchRetryCount<2?(r.protocolMismatchRetryCount++,l.push({role:`user`,content:[{type:`text`,text:`Your previous response indicated a tool call (stop reason was tool_use) but contained no valid tool invocation — do NOT write tool calls as literal text or XML in the response body. Re-issue the tool call using the proper tool-calling mechanism, or respond with text only.`}],timestamp:u.now(),internal:!0}),s.warn(`Tool-call protocol mismatch on turn %d (stopReason=%s, message ends with literal <invoke> XML instead of a structured tool call — wire-layer recovery did not catch it); injecting correction prompt (%d/%d)`,n+1,e.stopReason,r.protocolMismatchRetryCount,2),o.emit(`tool.call.mismatch`,{turnIndex:n,outcome:`retry`,retryCount:r.protocolMismatchRetryCount}),d.record({kind:`lifecycle`,node:`tool.call.mismatch`,turn:n,payload:{outcome:`retry`,retryCount:r.protocolMismatchRetryCount}}),{kind:`continue`}):(s.warn(`Tool-call protocol mismatch persisted after %d retries on turn %d; terminating (not silently)`,2,n+1),o.emit(`tool.call.mismatch`,{turnIndex:n,outcome:`terminate`,retryCount:r.protocolMismatchRetryCount}),d.record({kind:`lifecycle`,node:`tool.call.mismatch`,turn:n,payload:{outcome:`terminate`,retryCount:r.protocolMismatchRetryCount}}),{kind:`terminate`})}const Rt=[kt,At,jt,Pt,Ft,Lt,It];function zt(e,t,n,r,i={}){let a={clock:i.clock??S,recorder:i.recorder??K};for(let i of Rt){let o=i(e,t,n,r,a);if(o)return o}return{kind:`terminate`}}function Q(e){let t=e.budget.maxToolTurns??A.maxToolTurns;return e.budget.promptOutputTokenBudget!==void 0&&e.budget.promptOutputTokenBudget>0?t*4:t}function Bt(e,t,n){let r=e.budget.promptOutputTokenBudget;if(r!==void 0&&r>0&&t.promptOutputTokens>=r)return{dimension:`tokens`,used:t.promptOutputTokens,budget:r};let i=e.budget.promptWallClockBudgetMs;if(i!==void 0&&i>0){let e=n.now()-t.promptStartedAt;if(e>=i)return{dimension:`time`,used:e,budget:i}}return null}function Vt(e,t,n){Y(t,s(e),n,{isError:!0,text:`Tool budget reached; not executed — wrap-up requested.`,internal:!0})}function Ht(e,t,n,r,i,a){let{emitter:o,logger:s,messages:c}=t,{clock:l,recorder:u}=r;Vt(e,c,l),c.push({role:`user`,content:[{type:`text`,text:i}],timestamp:l.now(),internal:!0}),a.emit(),u.record({kind:`lifecycle`,node:a.recordNode,turn:n,payload:a.recordPayload})}function Ut(e,t){let n=t.maxOutputTokens;if(!n||n<=0)return e?e*8:void 0;if(e===void 0)return n;if(!(e>=n))return Math.min(e*8,n)}const Wt=new Set([`start`,`text_delta`,`thinking_delta`,`tool_call_delta`]);function Gt(e){let t=e.type;return typeof t==`string`&&Wt.has(t)}function Kt(e){return e.filter(e=>e.exposure!==`deferred`&&e.exposure!==`hidden`).map(e=>({name:e.name,description:e.description,parameters:e.parameters}))}async function qt(e,t,n,r){let{signal:i,emitter:a,logger:o}=e,s=e.ports?.debug,l=e.ports?.recorder??K,u=e.ports?.clock??S;e.assertMessagesConsistent?.();let d=N({debug:s,getTurn:()=>n,getMessagesCount:()=>e.messages.length,getTokenUsage:()=>r,getLlmParams:()=>t,getMessagesForSummary:()=>e.messages}),f=[...e.messages];e.contextTransform?.transformContext&&(f=await e.contextTransform.transformContext(f,i),f.length!==e.messages.length&&o.info(`Context transformed for turn %d: %d -> %d messages`,n+1,e.messages.length,f.length),await d(`context.transform`,0,{messagesCount:f.length,summarySource:f,metadata:{originalCount:e.messages.length,transformedCount:f.length}}));let p=Kt(e.toolExecutor.list());P(await d(`model.before`,0),{messages:e.messages,setSystemPrompt:e=>{t.systemPrompt=e},setTemperature:e=>{t.temperature=e},setMaxTokens:e=>{t.maxTokens=e},setThinkingLevel:e=>{t.thinkingLevel=e}});let m={hasAttemptedReactiveCompact:!1,hasAttemptedImageDegradation:!1,transientRetries:0,hasAttemptedAuthRetry:!1},h=e.retry?.streamRetry??_t,g=e.ports?.random??C,_=e.ports?.sleep??T,y=!1,b=(e.systemTail??[]).filter(e=>e.length>0);for(;;){let r=await Be(f,{model:e.model,describeImages:e.contextTransform?.describeImages,signal:e.signal,turnIndex:n,maxImagesDefault:20,record:(e,t)=>l.record({kind:`lifecycle`,node:e,turn:n,payload:t}),emitDelegate:t=>e.emitter.emit(`image.vision-delegate`,t)}),s=await e.convertToLLM(r),x=Me.buildTurnInput({stableSystem:t.systemPrompt,volatileTail:b,llmMessages:s,model:e.model,tools:p,cacheRetention:e.cacheRetention,thinkingLevel:t.thinkingLevel,maxTokens:t.maxTokens,temperature:t.temperature});e.wireSnapshot&&(Fe(e.wireSnapshot,e.model.id,n,x),l.record({kind:`lifecycle`,node:`wire.snapshot.capture`,turn:n,payload:{sessionId:e.wireSnapshot.sessionId}}));let S=e.stream(x,i),C=me(l),w=u.now(),T=!1;try{for await(let e of S)if(e.type!==`error`&&(a.emit(`stream.event`,{event:e}),C.push(e,n)),!T&&Gt(e)&&(T=!0,l.record({kind:`lifecycle`,node:`stream.ttft`,turn:n,payload:{ttftMs:u.now()-w}})),i.aborted)throw new v;C.flush();let r=await S.result();if(o.info(`Turn %d completed with stop reason %s (input=%d, output=%d)`,n+1,r.stopReason,r.usage.inputTokens,r.usage.outputTokens),r.stopReason===`max_tokens`&&!c(r)&&!y){let r=Ut(t.maxTokens,e.model),i=t.maxTokens??e.model.maxOutputTokens;if(r!==void 0&&r>i){y=!0,o.warn(`Output truncated (max_tokens, no tool calls) on turn %d; escalating maxTokens %s -> %d and re-running`,n+1,t.maxTokens??`(default)`,r),t.maxTokens=r,a.emit(`turn.truncated`,{turnIndex:n,action:`escalate`,maxTokens:r}),l.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`escalate`,maxTokens:r}});continue}}return await d(`model.after`,0),r}catch(t){C.flush();let r=await Et(t,e,n,f,m,h,e.retry?.retryAccelerate,g,_);if(r.action===`retry`){r.contextMessages&&(f=r.contextMessages);continue}throw t}}}async function Jt(e){let t=e.context,{signal:n,emitter:r,logger:i,transitionTo:a}=t,o=e.recorder;for(;;){if(n.aborted)throw new v;r.emit(`turn.start`,{turnIndex:e.turnIndex.current,toolTurnCount:e.turnState.toolTurnCount,maxToolTurns:Q(t),promptOutputTokens:e.turnState.promptOutputTokens,promptOutputTokenBudget:t.budget.promptOutputTokenBudget}),o.record({kind:`lifecycle`,node:`turn.start`,turn:e.turnIndex.current}),i.info(`Turn %d started`,e.turnIndex.current+1);let s=await qt(t,e.params,e.turnIndex.current,e.lastTokenUsage.current);e.messages.push(s),e.lastAssistantMessage.current=s,e.lastTokenUsage.current={input:s.usage.inputTokens,output:s.usage.outputTokens},e.turnState.promptOutputTokens+=s.usage.outputTokens,r.emit(`turn.end`,{turnIndex:e.turnIndex.current,message:s}),o.record({kind:`lifecycle`,node:`turn.end`,turn:e.turnIndex.current,payload:{stopReason:s.stopReason,usage:s.usage,model:s.model,provider:s.provider}});let c=e.turnIndex.current;e.turnIndex.current++;let l=zt(s,t,c,e.turnState,{clock:e.clock,recorder:o});if(l.kind===`terminate`)return t.lifecycleAsync?.hasPending()?`pending`:(t.onTurnPersist?.(),`terminate`);if(l.kind===`continue`){t.onTurnPersist?.();continue}a(`tool_executing`);let{ranAnyTool:u}=await gt(s,t,c,e.lastTokenUsage.current,e.turnState.windowStats,e.turnState.stallDetector,e.toolResultAllowance);if(u&&e.turnState.toolTurnCount++,e.turnState.pendingBudgetNotice&&(t.messages.push({role:`user`,content:[{type:`text`,text:e.turnState.pendingBudgetNotice}],timestamp:e.clock.now(),internal:!0}),e.turnState.pendingBudgetNotice=void 0),t.onTurnPersist?.(),t.ports?.nondetFlush?.(),t.lifecycleAsync?.hasPending())return`pending`;a(`streaming`)}}function Yt(e,t){return e===void 0||e<=0?new Promise(()=>{}):new Promise(n=>{setTimeout(()=>{t(),n()},e).unref?.()})}async function Xt(e,t,n,r){let i=!1,a=[],o=n.aborted,s=!1,c=e.then(()=>{i=!0}),l=new Promise(e=>{if(n.aborted){o=!0,i=!0,e();return}n.addEventListener(`abort`,()=>{o=!0,i=!0,e()},{once:!0})}),u=(async()=>{for(;!i;){let e=await t().catch(()=>[]);if(e.length>0){a=e,i=!0;return}if(i)return;await new Promise(e=>{setTimeout(e,200).unref?.()})}})(),d=Yt(r,()=>{s=!0,i=!0});return await Promise.race([c,l,u,d]),{steeringMessages:a,aborted:o,timedOut:s}}async function Zt(e,t,n){if(t.aborted)return`aborted`;let r=!1,i=!1,a=new Promise(e=>{t.addEventListener(`abort`,()=>{r=!0,e()},{once:!0})}),o=Yt(n,()=>{i=!0});return await Promise.race([e,a,o]),r?`aborted`:i?`timed-out`:`settled`}async function Qt(e){let t=e.context,{signal:n,logger:r,emitter:i,transitionTo:a,getSteeringMessages:o}=t;for(;;){if(n.aborted)throw new v;if(a(`streaming`),await Jt({context:e.context,params:e.params,turnState:e.turnState,messages:e.messages,turnIndex:e.turnIndex,lastTokenUsage:e.lastTokenUsage,lastAssistantMessage:e.lastAssistantMessage,toolResultAllowance:e.toolResultAllowance.current,recorder:e.recorder,clock:e.clock})===`pending`){if(t.lifecycleAsync){let{steeringMessages:a,aborted:s,timedOut:c}=await Xt(t.lifecycleAsync.waitForPending(),o,n,t.retry?.lifecycleAsyncTimeoutMs);if(s)throw new v;if(c){let n=t.retry?.lifecycleAsyncTimeoutMs??0;i.emit(`lifecycle.tool.timeout`,{turnIndex:e.turnIndex.current,timeoutMs:n}),e.recorder.record({kind:`lifecycle`,node:`lifecycle.tool.timeout`,turn:e.turnIndex.current,payload:{timeoutMs:n}}),r.warn(`Timed out after %d ms waiting for pending lifecycleAsync tool(s); abandoning the wait so the loop can proceed (RFC-366)`,n);for(let r of t.lifecycleAsync.listPending())e.messages.push(ct(r.toolName,r.toolCallId,n,{now:()=>(t.ports?.clock??S).now()})),r.consumed=!0}a.length>0&&(e.messages.push(...a),i.emit(`steering.injected`,{messages:a}),r.info(`Steering message(s) consumed while %d lifecycleAsync tool(s) still pending`,a.length))}continue}if(t.budget.isPauseRequested?.()){r.info(`Turn boundary reached with pause requested — yielding without followUp check`);break}await e.pause(`loop.end`,0),e.recorder.record({kind:`lifecycle`,node:`loop.end`,turn:e.turnIndex.current});let s=await t.getFollowUpMessages();if(await e.pause(`follow.up.check`,0,{metadata:{hasFollowUp:s.length>0,followUpCount:s.length}}),s.length===0)break;e.messages.push(...s),r.info(`Queued %d follow-up message(s)`,s.length),i.emit(`follow.up.start`,{messages:s}),e.turnState.toolTurnCount=0,e.turnState.extensionsUsed=0,e.turnState.budgetSteeringIssued=!1,I(e.turnState.windowStats),e.turnState.promptOutputTokens=0,e.turnState.promptStartedAt=e.clock.now(),e.turnState.stallDetector?.reset(),e.turnState.stallSteeringIssued=!1,e.turnState.protocolMismatchRetryCount=0,e.turnState.emptyResponseRetryCount=0,e.toolResultAllowance.current=e.createToolResultAllowance()}if(t.lifecycleAsync?.hasPending()){r.info(`Waiting for remaining lifecycleAsync pending tool(s) to settle before returning (reached loop exit with pending still outstanding)`);let a=await Zt(t.lifecycleAsync.waitForPending(),n,t.retry?.lifecycleAsyncTimeoutMs);if(a===`aborted`)throw new v;if(a===`timed-out`){let n=t.retry?.lifecycleAsyncTimeoutMs??0;i.emit(`lifecycle.tool.timeout`,{turnIndex:e.turnIndex.current,timeoutMs:n}),e.recorder.record({kind:`lifecycle`,node:`lifecycle.tool.timeout`,turn:e.turnIndex.current,payload:{timeoutMs:n}}),r.warn(`Timed out after %d ms waiting for pending lifecycleAsync tool(s) at loop exit; returning without them (RFC-366)`,n);for(let r of t.lifecycleAsync.listPending())e.messages.push(ct(r.toolName,r.toolCallId,n,{now:()=>(t.ports?.clock??S).now()})),r.consumed=!0}}if(!e.lastAssistantMessage.current)throw Error(`Agent loop completed without producing a message`);return await e.pause(`agent.done`,0),e.recorder.record({kind:`lifecycle`,node:`agent.done`,turn:e.turnIndex.current}),r.info(`Agent loop finished after %d turn(s)`,e.turnIndex.current),e.lastAssistantMessage.current}async function $t(e){let t={current:0},n=e.budget.stallDetection,r={continuationCount:0,toolTurnCount:0,extensionsUsed:0,budgetSteeringIssued:!1,windowStats:F(),promptOutputTokens:0,promptStartedAt:(e.ports?.clock??S).now(),stallDetector:n===!1?void 0:new ce(n??{}),stallSteeringIssued:!1,protocolMismatchRetryCount:0,emptyResponseRetryCount:0},i={current:null},a={current:void 0},o=()=>new ie(ae(e.model.contextWindow,A.promptToolResultFraction),A.minToolResultChars),s=o(),{messages:c,signal:l,logger:u}=e,d=e.ports?.debug,f=e.ports?.clock??S,p=e.ports?.recorder??K,m={systemPrompt:e.systemPrompt,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature},h=N({debug:d,getTurn:()=>t.current,getMessagesCount:()=>c.length,getTokenUsage:()=>a.current,getLlmParams:()=>m,getMessagesForSummary:()=>c});try{return u.info(`Agent loop started for model %s with %d messages`,e.model.id,c.length),await h(`loop.start`,0),p.record({kind:`lifecycle`,node:`loop.start`,turn:t.current}),Qt({context:e,params:m,turnState:r,messages:c,turnIndex:t,lastTokenUsage:a,lastAssistantMessage:i,toolResultAllowance:{current:s},createToolResultAllowance:o,pause:h,recorder:p,clock:f})}catch(e){throw e instanceof v||l.aborted?(u.warn(`Agent loop aborted at turn %d`,t.current+1),await h(`agent.aborted`,0),p.record({kind:`lifecycle`,node:`agent.aborted`,turn:t.current}),e):(u.error(`Agent loop failed at turn %d: %s`,t.current+1,e instanceof Error?e.message:String(e)),await h(`agent.error`,0),p.record({kind:`lifecycle`,node:`agent.error`,turn:t.current,payload:{message:e instanceof Error?e.message:String(e)}}),e)}finally{e.ports?.nondetFlush?.(),await h(`loop.cleanup`,0)}}const en=r(`@x-otto/agent:tool-executor`);function tn(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.keys(e);if(t.length!==1||t[0]!==`_truncated`)return!1;let n=e._truncated;return typeof n==`object`&&!!n&&!Array.isArray(n)}function $(e){return{content:[{type:`text`,text:`Tool ${e} execution was aborted`}],isError:!0,errorKind:`aborted`,details:{}}}var nn=class{tools;hookExecutor;agentName;sessionId;debug;clock;depth;parentTaskId;approval;constructor(e){this.tools=new Map;for(let t of e.tools)this.tools.set(t.name,t);this.hookExecutor=e.hookExecutor,this.agentName=e.agentName??``,this.sessionId=e.sessionId??``,this.debug=e.debug,this.clock=e.clock??S,this.depth=e.depth,this.parentTaskId=e.parentTaskId,this.approval=e.approval}list(){return[...this.tools.values()]}async execute(e,t){let{id:n,name:r}=e,i=this.tools.get(r),a=(e,t)=>this.debug?.pause(M({point:e,frameDepth:2,lastToolName:r,metadata:{...t,sessionId:this.sessionId}}));if(P(await a(`tool.resolve`,{found:!!i,toolCallId:n})),!i)return{content:[{type:`text`,text:`Unknown tool: ${r}`}],isError:!0,errorKind:`not_found`};let o=this.clock.now(),s=e.arguments;try{if(this.hookExecutor){P(await a(`tool.hook.before`,{toolCallId:n}));let e=await this.hookExecutor.executeBeforeHooks({toolName:r,toolCallId:n,args:s,agentName:this.agentName,sessionId:this.sessionId,paths:rn(i,s),readonly:i.readonly});if(e.kind===`deny`)return{content:[{type:`text`,text:e.reason}],isError:!0,errorKind:`permission`};if(s=e.args,e.kind===`ask`){let n=e.reason;if(!this.approval)return{content:[{type:`text`,text:`Tool ${r} requires approval but no approval handler is configured: ${n}`}],isError:!0,errorKind:`permission`};let i=await this.approval(r,s,n,e.risk);if(t.aborted)return $(r);if(!i)return{content:[{type:`text`,text:`Tool ${r} was rejected by user: ${n}`}],isError:!0,errorKind:`permission`}}}let c=i.parameters.safeParse(s);if(!c.success&&tn(s)){let e=s._truncated,t=i.parameters.safeParse(e);t.success&&(en.warn({toolName:r,toolCallId:n},`RFC-142: unwrapped legacy _truncated wrapper from model tool-call arguments (context-poisoning residue); executing with inner arguments`),c=t)}let{success:l}=c;if(P(await a(`tool.validate`,{valid:l,toolCallId:n})),!c.success)return{content:[{type:`text`,text:`Invalid arguments for tool ${r}: ${String(c.error)}\n\nDo NOT wrap arguments in any extra key; emit the tool's schema fields at the top level and retry.`}],isError:!0,errorKind:`validation`};if(t.aborted)return $(r);let u=await i.execute({id:e.id,params:c.data,signal:t,sessionId:this.sessionId||void 0,agentName:this.agentName||void 0,depth:this.depth,...this.parentTaskId===void 0?{}:{parentTaskId:this.parentTaskId}});if(t.aborted)return $(r);if(u.isError&&u.errorKind===`sandbox-denied`&&this.approval){let n=typeof u.details?.denialReason==`string`?u.details.denialReason:`sandbox policy`,a=`[sandbox-escalation] sandbox denied (${typeof u.details?.sandboxBackend==`string`?u.details.sandboxBackend:`unknown`}: ${n}); approve to retry this command without sandbox`,o=await this.approval(r,s,a,`medium`);!t.aborted&&o&&(u=await i.execute({id:e.id,params:c.data,signal:t,sessionId:this.sessionId||void 0,agentName:this.agentName||void 0,depth:this.depth,...this.parentTaskId===void 0?{}:{parentTaskId:this.parentTaskId}}))}return t.aborted||(this.hookExecutor&&(u=(await this.hookExecutor.executeAfterHooks({toolName:e.name,toolCallId:e.id,args:s,result:u,agentName:this.agentName,sessionId:this.sessionId,durationMs:this.clock.now()-o,readonly:i.readonly})).result,P(await a(`tool.hook.after`,{toolCallId:n,durationMs:this.clock.now()-o}))),t.aborted)?$(r):u}catch(n){if(t.aborted)return $(r);let i=n instanceof Error?n.message:String(n),a=n?.errorKind,o=n?.pluginSource;return{content:[{type:`text`,text:`Tool ${e.name} failed: ${i}`}],isError:!0,errorKind:a??`runtime`,details:{error:n instanceof Error?n.name:`UnknownError`},...o?{pluginSource:o}:{}}}}};function rn(e,t){if(!e.pathParams?.length)return[];let n=[];for(let r of e.pathParams){let i=t[r];typeof i==`string`&&n.push(e.resolvePath?e.resolvePath(i):i)}return n}function an(e,t){return new nn({tools:e,...t})}const on=r(`@x-otto/agent`),sn={idle:new Set([`streaming`,`aborted`,`error`,`archived`]),streaming:new Set([`tool_executing`,`completed`,`aborted`,`error`]),tool_executing:new Set([`streaming`,`aborted`,`error`]),completed:new Set([`streaming`,`idle`,`aborted`,`error`,`archived`]),error:new Set([`idle`,`aborted`,`streaming`,`archived`]),aborted:new Set([`streaming`,`idle`,`error`,`archived`]),archived:new Set([`idle`])};function cn(e,t,n){let r=an(t.tools,{hookExecutor:e.toolHookExecutor,agentName:e.agentName,sessionId:e.sessionId,debug:e.debug,clock:e.clock,depth:e.depth,parentTaskId:e.parentTaskId,approval:e.approval});return{model:t.model,systemPrompt:t.systemPrompt,systemTail:t.systemTail,cacheRetention:t.cacheRetention,messages:t.messages,thinkingLevel:t.thinkingLevel,maxTokens:t.maxTokens,temperature:t.temperature,convertToLLM:t.convertToLLM??un,onTurnPersist:t.onTurnPersist,assertMessagesConsistent:t.assertMessagesConsistent,logger:e.agentLogger,toolExecutor:r,stream:e.stream,signal:n.signal,emitter:n.emitter,getSteeringMessages:n.getSteeringMessages,getFollowUpMessages:n.getFollowUpMessages,transitionTo:n.transitionTo,lifecycleAsync:n.lifecycleAsync,wireSnapshot:e.wireSnapshotStore?{sessionId:e.sessionId??``,store:e.wireSnapshotStore}:void 0,ports:{clock:e.clock,debug:e.debug,recorder:e.recorder,nondetFlush:e.nondetFlush,spill:e.spill},budget:{maxToolTurns:e.maxToolTurns,maxToolTurnExtensions:e.maxToolTurnExtensions,budgetSteerWrapUp:e.budgetSteerWrapUp,promptOutputTokenBudget:e.promptOutputTokenBudget,promptWallClockBudgetMs:e.promptWallClockBudgetMs,stallDetection:e.stallDetection,isPauseRequested:t.isPauseRequested,maxToolCallsPerTurn:e.maxToolCallsPerTurn},retry:{retryAccelerate:e.retryAccelerate,streamRetry:e.streamRetry,networkDisconnectRetry:e.networkDisconnectRetry,idleTimeoutRetry:e.idleTimeoutRetry,lifecycleAsyncTimeoutMs:e.lifecycleAsyncTimeoutMs},contextTransform:{transformContext:t.transformContext,reactiveCompact:t.reactiveCompact,describeImages:t.describeImages}}}var ln=class extends n{state;abortController=null;pendingAbort=!1;steeringQueue=[];followUpQueue=[];pendingLifecycleTools=new Map;promptSeq=0;get currentPromptSeq(){return this.promptSeq}config;get status(){return this.state.status}get turnCount(){return this.state.turnCount}constructor(e){super(),this.config={stream:e.stream,agentLogger:e.logger,maxToolTurns:e.maxToolTurns??A.maxToolTurns,maxToolTurnExtensions:e.maxToolTurnExtensions??0,budgetSteerWrapUp:e.budgetSteerWrapUp??!1,promptOutputTokenBudget:e.promptOutputTokenBudget,promptWallClockBudgetMs:e.promptWallClockBudgetMs,stallDetection:e.stallDetection,agentName:e.agentName??``,sessionId:e.sessionId??``,toolHookExecutor:e.toolHookExecutor,debug:e.debug,clock:e.clock,recorder:e.recorder,nondetFlush:e.nondetFlush,depth:e.depth,parentTaskId:e.parentTaskId,maxToolCallsPerTurn:e.maxToolCallsPerTurn,retryAccelerate:e.retryAccelerate,streamRetry:e.streamRetry,networkDisconnectRetry:e.networkDisconnectRetry,idleTimeoutRetry:e.idleTimeoutRetry,lifecycleAsyncTimeoutMs:e.lifecycleAsyncTimeoutMs,spill:e.spill,approval:e.approval},this.state={status:`idle`,turnCount:0,tokenUsage:{input:0,output:0,cacheRead:0},isStreaming:!1,currentStreamMessage:null,error:void 0},this.on(`status.change`,({to:e})=>{this.state.isStreaming=e===`streaming`}),this.on(`turn.end`,({message:e})=>{this.state.turnCount++,this.state.currentStreamMessage=null,this.state.tokenUsage.input+=e.usage.inputTokens,this.state.tokenUsage.output+=e.usage.outputTokens,this.state.tokenUsage.cacheRead+=e.usage.cacheReadTokens}),this.on(`stream.event`,({event:e})=>{e.type===`start`&&(this.state.currentStreamMessage=e.partial)})}getState(){return{...this.state,tokenUsage:{...this.state.tokenUsage}}}async run(e){if(this.state.status===`streaming`||this.state.status===`tool_executing`)throw Error(`Cannot run in ${this.state.status} status`);if(this.state.status===`archived`)throw Error(`Cannot run: session is archived`);return this.state.status===`error`&&(this.state.error=void 0),this.cancelStalePendingLifecycleTools(),this.promptSeq++,this.runLoop(e)}cancelStalePendingLifecycleTools(){for(let[e,t]of this.pendingLifecycleTools){if(t.consumed){this.pendingLifecycleTools.delete(e);continue}t.abortController.abort(),this.config.agentLogger.info(`Cancelling stale lifecycleAsync tool %s (task id: %s) from prompt %d — new prompt %d starting`,t.toolName,t.toolCallId,t.promptSeq,this.promptSeq+1)}}steer(e){this.steeringQueue.push(e)}removeSteer(e){let t=this.steeringQueue.findIndex(t=>t.uuid===e);return t===-1?!1:(this.steeringQueue.splice(t,1),!0)}followUp(e){this.followUpQueue.push(e)}registerPendingLifecycleTool(e){this.pendingLifecycleTools.set(e.toolCallId,e)}hasPendingLifecycleTools(){for(let e of this.pendingLifecycleTools.values())if(!e.consumed)return!0;return!1}listPendingLifecycleTools(){let e=[];for(let t of this.pendingLifecycleTools.values())t.consumed||e.push(t);return e}async waitForPendingLifecycleTools(){let e=[...this.pendingLifecycleTools.values()].filter(e=>!e.consumed).map(e=>e.promise);e.length!==0&&await Promise.allSettled(e)}async notifyToolCompletion(e,t){let n=this.pendingLifecycleTools.get(e);return!n||n.consumed?{consumed:!1}:(n.consumed=!0,this.emit(`lifecycle.tool.completed`,{toolCallId:e,toolName:n.toolName,isError:t.isError??!1,result:t}),{consumed:!0,entry:n})}abort(){this.state.status===`aborted`&&!this.abortController||(this.abortController?this.abortController.abort():this.pendingAbort=!0,this.transitionTo(`aborted`),this.emit(`abort`))}archive(){this.transitionTo(`archived`)}unarchive(){this.transitionTo(`idle`)}reset(){this.abortController&&=(this.abortController.abort(),null),this.pendingAbort=!1,this.steeringQueue=[],this.followUpQueue=[],this.pendingLifecycleTools.clear(),this.state.turnCount=0,this.state.tokenUsage={input:0,output:0,cacheRead:0},this.state.currentStreamMessage=null,this.state.error=void 0;let e=this.state.status;this.state.status=`idle`,e!==`idle`&&this.emit(`status.change`,{from:e,to:`idle`})}async runLoop(e){let t=new AbortController;this.abortController=t,this.pendingAbort&&(this.pendingAbort=!1,t.abort());let n=t.signal;try{let t=await $t(cn(this.config,e,{signal:n,emitter:this,getSteeringMessages:()=>this.drainSteeringQueue(),getFollowUpMessages:()=>this.drainFollowUpQueue(),transitionTo:e=>this.transitionTo(e),lifecycleAsync:{register:e=>this.registerPendingLifecycleTool(e),hasPending:()=>this.hasPendingLifecycleTools(),waitForPending:()=>this.waitForPendingLifecycleTools(),listPending:()=>this.listPendingLifecycleTools(),notifyCompletion:(e,t)=>this.notifyToolCompletion(e,t),currentPromptSeq:()=>this.currentPromptSeq}}));return this.transitionTo(`completed`),t}catch(e){throw e instanceof v||n.aborted?(this.transitionTo(`aborted`),e):(this.state.error=e instanceof Error?e:Error(String(e)),this.transitionTo(`error`),this.emit(`error`,{error:this.state.error}),this.state.error)}finally{this.abortController===t&&(this.abortController=null),this.state.isStreaming=!1}}transitionTo(e){let t=this.state.status;if(t!==e){if(!sn[t]?.has(e)){on.warn(`Invalid state transition: %s → %s (ignored)`,t,e);return}this.state.status=e,this.emit(`status.change`,{from:t,to:e})}}async drainSteeringQueue(){let e=[...this.steeringQueue];return this.steeringQueue=[],e}async drainFollowUpQueue(){let e=[...this.followUpQueue];return this.followUpQueue=[],e}};function un(e){return e.filter(e=>typeof e==`object`&&!!e&&`role`in e&&(e.role===`user`||e.role===`assistant`||e.role===`tool_result`||e.role===`system_notification`))}function dn(e){return new ln(e)}export{v as AbortError,ln as Agent,ne as BREAKPOINT_POINTS,A as ENGINE_DEFAULTS,ee as ENGINE_LIFECYCLE_TIMINGS,E as ENGINE_NODES,re as IMAGE_CONTEXT_CHARS_EQUIVALENT,B as MAX_IMAGE_INLINE_BYTES,y as MaxToolTurnsError,x as MessagesConsistencyError,k as OBSERVABLE_NODE_IDS,b as PromptBudgetExceededError,te as TRACEABLE_NODE_IDS,Ne as WireSnapshotStore,Ce as applyMemoryTransform,ze as applyVisionGate,st as buildLifecycleAsyncCompletionNotice,ot as buildLifecycleAsyncPlaceholder,at as buildLifecycleAsyncPlaceholderText,Fe as captureWireSnapshot,tt as causalDag,U as clampToolResultContent,oe as clampWithSpill,P as consumePause,dn as createAgent,he as createRecordingPorts,ge as createReplayPorts,me as createStreamTracePersister,an as createToolExecutor,le as createTraceRecorder,et as digestTracePayload,_e as extractNondetDraws,o as extractToolResultText,Ee as forceMemoryTransform,O as nodesWithCapability,K as noopRecorder,H as normalizeToolResultContent,Xe as prompt,q as recordMemoryLifecycle,se as runBounded,de as shouldPersistStreamEvent,V as stripAnsi,j as summarizeMessages,Ze as summarizeTrace,S as systemClock,w as systemId,C as systemRandom,G as toolResultContextChars,Qe as traceToSpans,rt as traceWhy,nt as turnToolTopology,Pe as wireSnapshotStore};
8
+ </engine_empty_response>`.replace(`retry="N"`,`retry="${s}"`),{type:`turn.truncated`,emit:()=>a.emit(`turn.truncated`,{turnIndex:n,action:`empty-response`}),recordNode:`turn.truncated`,recordPayload:{action:`empty-response`,retryCount:s}}),o.warn(`Empty response (end_turn, no meaningful content blocks) on turn %d; injecting steering retry (%d/%d)`,n+1,s,2),{kind:`continue`}}return o.warn(`Empty response persisted after %d retries on turn %d; terminating (not silently)`,2,n+1),a.emit(`turn.truncated`,{turnIndex:n,action:`empty-response`,exhausted:!0}),s.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`empty-response`,retryCount:r.emptyResponseRetryCount,exhausted:!0}}),{kind:`terminate`}}function Mt(e,t,n,r,i){if(e.stopReason!==`max_tokens`||c(e))return null;let{emitter:a,logger:o,messages:s}=t,{clock:l,recorder:u}=i;return r.continuationCount<5?(r.continuationCount++,s.push({role:`user`,content:[{type:`text`,text:`<engine_truncation>
9
+ Your previous response was cut off because it reached the output token limit. Continue exactly where you left off do not repeat content already produced.
10
+ </engine_truncation>`}],timestamp:l.now(),internal:!0}),o.warn(`Output truncated (max_tokens) on turn %d; appending continuation prompt (%d/%d)`,n+1,r.continuationCount,5),a.emit(`turn.truncated`,{turnIndex:n,action:`continue`}),u.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`continue`,continuation:r.continuationCount}}),{kind:`continue`}):(o.warn(`Output still truncated after %d continuations; returning partial response`,5),a.emit(`turn.truncated`,{turnIndex:n,action:`continue-exhausted`,exhausted:!0}),u.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`continue-exhausted`,continuation:r.continuationCount,exhausted:!0}}),{kind:`terminate`})}function Nt(e,t,n,r,i){let{emitter:a,logger:o}=t,{clock:s,recorder:c}=i,l=Wt(t,r,s);if(!l)return null;let{dimension:u,used:d,budget:f}=l;if(t.budget.budgetSteerWrapUp&&!r.budgetSteeringIssued)return r.budgetSteeringIssued=!0,Q(e,t,n,i,kt(u,d,f),{type:`prompt.budget`,emit:()=>a.emit(`prompt.budget`,{turnIndex:n,dimension:u,used:d,budget:f,steered:!0}),recordNode:`prompt.budget`,recordPayload:{dimension:u,used:d,budget:f,steered:!0}}),o.info(`Prompt %s budget exceeded (%d/%d); steering model to wrap up`,u,d,f),{kind:`continue`};let p=e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
11
+ `).trim();throw a.emit(`prompt.budget`,{turnIndex:n,dimension:u,used:d,budget:f,steered:!1}),c.record({kind:`lifecycle`,node:`prompt.budget`,turn:n,payload:{dimension:u,used:d,budget:f,steered:!1}}),new b(u,d,f,p)}function Pt(e,t,n,r,i){let{emitter:a,logger:o}=t,{recorder:s}=i;if(r.toolTurnCount<Ut(t))return{kind:`run-tools`};let c=Ut(t),l=t.budget.maxToolTurnExtensions??0,u=B(r.windowStats);if(r.extensionsUsed<l&&u)return r.extensionsUsed++,a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!0}),s.record({kind:`lifecycle`,node:`max.turns`,turn:n,payload:{maxTurns:c,extended:!0,extension:r.extensionsUsed,maxExtensions:l}}),o.info(`Tool budget exhausted (%d); extending %d/%d (per-turn transformContext compacts on token threshold)`,c,r.extensionsUsed,l),r.toolTurnCount=0,L(r.windowStats),r.pendingBudgetNotice=`<engine_budget_extended window="${r.extensionsUsed}" max="${l}" tokens="${r.promptOutputTokens}" />`,{kind:`run-tools`};if(t.budget.budgetSteerWrapUp&&!r.budgetSteeringIssued){r.budgetSteeringIssued=!0;let s=r.extensionsUsed<l&&!u;return Q(e,t,n,i,`<engine_budget>
12
+ You have reached your tool-call budget for this turn. Do not start any new tool work or call any tools. Wrap up now: briefly summarize the concrete progress you made, list what still remains or is blocked, and give the user a clear next step. Respond with text only.
13
+ </engine_budget>`,{type:`max.turns`,emit:()=>a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!1,steered:!0,...s?{progressDenied:!0}:{}}),recordNode:`max.turns`,recordPayload:{maxTurns:c,extended:!1,steered:!0,progressDenied:s,extension:r.extensionsUsed,maxExtensions:l}}),o.info(s?`Tool budget window showed no progress (loop suspected); steering model to wrap up`:`Tool budget exhausted (%d); steering model to wrap up in one final turn`,c),{kind:`continue`}}let d=e.content.filter(e=>e.type===`text`).map(e=>e.text).join(`
14
+ `).trim(),f=r.extensionsUsed<l&&!u;throw a.emit(`max.turns`,{turnIndex:n,maxTurns:c,extended:!1,...f?{progressDenied:!0}:{}}),s.record({kind:`lifecycle`,node:`max.turns`,turn:n,payload:{maxTurns:c,extended:!1,steered:!1,progressDenied:f,extension:r.extensionsUsed,maxExtensions:l}}),new y(c,d,l)}function Ft(e,t,n,r,i){if(e.stopReason!==`max_tokens`)return null;let a=s(e).filter(e=>e.argumentsParseFailed===!0);if(a.length===0)return null;let{logger:o,messages:c}=t;for(let e of a)c.push({role:`tool_result`,toolCallId:e.id,toolName:e.name,content:[{type:`text`,text:`Tool call arguments were cut off by the output token limit and could not be parsed. Re-issue the call, splitting large content into smaller pieces if necessary.`}],isError:!0,details:{},timestamp:i.clock.now(),internal:!0}),o.warn(`Tool call %s (%s) had truncated arguments (max_tokens) on turn %d; synthesized error result`,e.id,e.name,n+1);return i.recorder.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`broken-tool-call`,count:a.length}}),null}function It(e,t,n,r,i){let a=r.stallDetector;if(!a||(a.onTurnEnd(),r.stallSteeringIssued))return null;let o=a.evaluate();if(!o.stalled)return null;let{emitter:s,logger:c}=t;return r.stallSteeringIssued=!0,Q(e,t,n,i,`<engine_stall>
15
+ Progress check: your recent tool calls repeat the same operations without producing changes — you may be stuck in a loop. Either switch to a different approach now (different tools, different angle, or narrower scope), or if the task genuinely cannot advance, stop and report: what you tried, what blocked you, and what the user should do next.
16
+ </engine_stall>`,{type:`progress.stall`,emit:()=>s.emit(`progress.stall`,{turnIndex:n,windowTurns:o.windowTurns,maxRepeat:o.maxRepeat,trailingEmpty:o.trailingEmpty}),recordNode:`progress.stall`,recordPayload:{windowTurns:o.windowTurns,maxRepeat:o.maxRepeat,trailingEmpty:o.trailingEmpty}}),c.info(`Stall detected (max signature repeat %d, trailing empty turns %d, over %d turns, zero write successes); steering model to change approach`,o.maxRepeat,o.trailingEmpty,o.windowTurns),{kind:`continue`}}function Lt(e,t,n,r,i){if(t.budget.idleTurnDetection===!1||c(e))return null;let a=e.stopReason;if(a!==`end_turn`&&a!==`stop_sequence`||r.toolTurnCount>0||!r.idleNudgeIssued&&n!==0)return null;let o=t.budget.idleTurnDetection?.maxTextChars??A.idleTurnMaxTextChars,s=e.content.reduce((e,t)=>t.type===`text`?e+t.text.length:e,0);if(s===0||s>=o)return null;let{emitter:l,logger:u}=t,{recorder:d}=i;return r.idleNudgeIssued?(u.info(`Idle turn persisted after nudge on turn %d; terminating (model confirmed completion or still idle)`,n+1),l.emit(`turn.idle`,{turnIndex:n,outcome:`terminate`,textChars:s}),d.record({kind:`lifecycle`,node:`turn.idle`,turn:n,payload:{outcome:`terminate`,textChars:s}}),{kind:`terminate`}):(r.idleNudgeIssued=!0,Q(e,t,n,i,`<engine_idle>
17
+ Your last response described an intention but performed no action, and no tools were called during this entire request. If the user asked you to do something, start doing it now — call the tools you need. If you were answering a question and your answer is already complete, or if you need information only the user can provide, say so explicitly and stop.
18
+ </engine_idle>`,{type:`turn.idle`,emit:()=>l.emit(`turn.idle`,{turnIndex:n,outcome:`nudge`,textChars:s}),recordNode:`turn.idle`,recordPayload:{outcome:`nudge`,textChars:s}}),u.info(`Idle turn detected on turn %d (%d text chars, zero tool calls, stopReason=%s); nudging model to act or confirm completion`,n+1,s,a),{kind:`continue`})}function Rt(e,t,n,r,i){return c(e)?Nt(e,t,n,r,i)??Pt(e,t,n,r,i):null}function zt(e,t,n,r,i){if(c(e))return null;let a=Ot(e);if(a===null||!h(a,new Set(t.toolExecutor.list().map(e=>e.name))))return null;let{emitter:o,logger:s,messages:l}=t,{clock:u,recorder:d}=i;return r.protocolMismatchRetryCount<2?(r.protocolMismatchRetryCount++,l.push({role:`user`,content:[{type:`text`,text:`<engine_protocol>
19
+ Your previous response indicated a tool call (stop reason was tool_use) but contained no valid tool invocation — do NOT write tool calls as literal text or XML in the response body. Re-issue the tool call using the proper tool-calling mechanism, or respond with text only.
20
+ </engine_protocol>`}],timestamp:u.now(),internal:!0}),s.warn(`Tool-call protocol mismatch on turn %d (stopReason=%s, message ends with literal <invoke> XML instead of a structured tool call — wire-layer recovery did not catch it); injecting correction prompt (%d/%d)`,n+1,e.stopReason,r.protocolMismatchRetryCount,2),o.emit(`tool.call.mismatch`,{turnIndex:n,outcome:`retry`,retryCount:r.protocolMismatchRetryCount}),d.record({kind:`lifecycle`,node:`tool.call.mismatch`,turn:n,payload:{outcome:`retry`,retryCount:r.protocolMismatchRetryCount}}),{kind:`continue`}):(s.warn(`Tool-call protocol mismatch persisted after %d retries on turn %d; terminating (not silently)`,2,n+1),o.emit(`tool.call.mismatch`,{turnIndex:n,outcome:`terminate`,retryCount:r.protocolMismatchRetryCount}),d.record({kind:`lifecycle`,node:`tool.call.mismatch`,turn:n,payload:{outcome:`terminate`,retryCount:r.protocolMismatchRetryCount}}),{kind:`terminate`})}function Bt(e,t){t.emptyResponseRetryCount!==0&&(c(e)||e.content.some(e=>e.type===`text`&&e.text.trim().length>0||e.type===`thinking`))&&t.emptyResponseRetryCount--}const Vt=[At,jt,Mt,Ft,It,zt,Lt,Rt];function Ht(e,t,n,r,i={}){let a={clock:i.clock??S,recorder:i.recorder??K};Bt(e,r);for(let i of Vt){let o=i(e,t,n,r,a);if(o)return o}return{kind:`terminate`}}function Ut(e){let t=e.budget.maxToolTurns??A.maxToolTurns;return e.budget.promptOutputTokenBudget!==void 0&&e.budget.promptOutputTokenBudget>0?t*4:t}function Wt(e,t,n){let r=e.budget.promptOutputTokenBudget;if(r!==void 0&&r>0&&t.promptOutputTokens>=r)return{dimension:`tokens`,used:t.promptOutputTokens,budget:r};let i=e.budget.promptWallClockBudgetMs;if(i!==void 0&&i>0){let e=n.now()-t.promptStartedAt;if(e>=i)return{dimension:`time`,used:e,budget:i}}return null}function Gt(e,t,n){Y(t,s(e),n,{isError:!0,text:`Tool budget reached; not executed — wrap-up requested.`,internal:!0})}function Q(e,t,n,r,i,a){let{messages:o}=t,{clock:s,recorder:c}=r;Gt(e,o,s),o.push({role:`user`,content:[{type:`text`,text:i}],timestamp:s.now(),internal:!0}),a.emit(),c.record({kind:`lifecycle`,node:a.recordNode,turn:n,payload:a.recordPayload})}function Kt(e,t){let n=t.maxOutputTokens;if(!n||n<=0)return e?e*8:void 0;if(e===void 0)return n;if(!(e>=n))return Math.min(e*8,n)}const qt=new Set([`start`,`text_delta`,`thinking_delta`,`tool_call_delta`]);function Jt(e){let t=e.type;return typeof t==`string`&&qt.has(t)}function Yt(e){return e.filter(e=>e.exposure!==`deferred`&&e.exposure!==`hidden`).map(e=>({name:e.name,description:e.description,parameters:e.parameters}))}async function Xt(e,t,n,r){let{signal:i,emitter:a,logger:o}=e,s=e.ports?.debug,l=e.ports?.recorder??K,u=e.ports?.clock??S;e.assertMessagesConsistent?.();let d=N({debug:s,getTurn:()=>n,getMessagesCount:()=>e.messages.length,getTokenUsage:()=>r,getLlmParams:()=>t,getMessagesForSummary:()=>e.messages}),f=[...e.messages];e.contextTransform?.transformContext&&(f=await e.contextTransform.transformContext(f,i),f.length!==e.messages.length&&o.info(`Context transformed for turn %d: %d -> %d messages`,n+1,e.messages.length,f.length),await d(`context.transform`,0,{messagesCount:f.length,summarySource:f,metadata:{originalCount:e.messages.length,transformedCount:f.length}}));let p=Yt(e.toolExecutor.list());F(await d(`model.before`,0),{messages:e.messages,setSystemPrompt:e=>{t.systemPrompt=e},setTemperature:e=>{t.temperature=e},setMaxTokens:e=>{t.maxTokens=e},setThinkingLevel:e=>{t.thinkingLevel=e}});let m={hasAttemptedReactiveCompact:!1,hasAttemptedImageDegradation:!1,transientRetries:0,hasAttemptedAuthRetry:!1},h=e.retry?.streamRetry??vt,g=e.ports?.random??C,_=e.ports?.sleep??T,y=!1,b=(e.systemTail??[]).filter(e=>e.length>0);for(;;){let r=await Ve(f,{model:e.model,describeImages:e.contextTransform?.describeImages,signal:e.signal,turnIndex:n,maxImagesDefault:20,record:(e,t)=>l.record({kind:`lifecycle`,node:e,turn:n,payload:t}),emitDelegate:t=>e.emitter.emit(`image.vision-delegate`,t)}),s=await e.convertToLLM(r),x=Ne.buildTurnInput({stableSystem:t.systemPrompt,volatileTail:b,llmMessages:s,model:e.model,tools:p,cacheRetention:e.cacheRetention,thinkingLevel:t.thinkingLevel,maxTokens:t.maxTokens,temperature:t.temperature});e.wireSnapshot&&(Ie(e.wireSnapshot,e.model.id,n,x),l.record({kind:`lifecycle`,node:`wire.snapshot.capture`,turn:n,payload:{sessionId:e.wireSnapshot.sessionId}}));let S=e.stream(x,i),C=he(l),w=u.now(),T=!1;try{for await(let e of S)if(e.type!==`error`&&(a.emit(`stream.event`,{event:e}),C.push(e,n)),!T&&Jt(e)&&(T=!0,l.record({kind:`lifecycle`,node:`stream.ttft`,turn:n,payload:{ttftMs:u.now()-w}})),i.aborted)throw new v;C.flush();let r=await S.result();if(o.info(`Turn %d completed with stop reason %s (input=%d, output=%d)`,n+1,r.stopReason,r.usage.inputTokens,r.usage.outputTokens),r.stopReason===`max_tokens`&&!c(r)&&!y){let r=Kt(t.maxTokens,e.model),i=t.maxTokens??e.model.maxOutputTokens;if(r!==void 0&&r>i){y=!0,o.warn(`Output truncated (max_tokens, no tool calls) on turn %d; escalating maxTokens %s -> %d and re-running`,n+1,t.maxTokens??`(default)`,r),t.maxTokens=r,a.emit(`turn.truncated`,{turnIndex:n,action:`escalate`,maxTokens:r}),l.record({kind:`lifecycle`,node:`turn.truncated`,turn:n,payload:{action:`escalate`,maxTokens:r}});continue}}return await d(`model.after`,0),r}catch(t){C.flush();let r=await Dt(t,e,n,f,m,h,e.retry?.retryAccelerate,g,_);if(r.action===`retry`){r.contextMessages&&(f=r.contextMessages);continue}throw t}}}async function Zt(e){let t=e.context,{signal:n,emitter:r,logger:i,transitionTo:a}=t,o=e.recorder;for(;;){if(n.aborted)throw new v;r.emit(`turn.start`,{turnIndex:e.turnIndex.current,toolTurnCount:e.turnState.toolTurnCount,maxToolTurns:Ut(t),promptOutputTokens:e.turnState.promptOutputTokens,promptOutputTokenBudget:t.budget.promptOutputTokenBudget}),o.record({kind:`lifecycle`,node:`turn.start`,turn:e.turnIndex.current}),i.info(`Turn %d started`,e.turnIndex.current+1);let s=await Xt(t,e.params,e.turnIndex.current,e.lastTokenUsage.current);e.messages.push(s),e.lastAssistantMessage.current=s,e.lastTokenUsage.current={input:s.usage.inputTokens,output:s.usage.outputTokens},e.turnState.promptOutputTokens+=s.usage.outputTokens,r.emit(`turn.end`,{turnIndex:e.turnIndex.current,message:s}),o.record({kind:`lifecycle`,node:`turn.end`,turn:e.turnIndex.current,payload:{stopReason:s.stopReason,usage:s.usage,model:s.model,provider:s.provider}});let c=e.turnIndex.current;e.turnIndex.current++;let l=Ht(s,t,c,e.turnState,{clock:e.clock,recorder:o});if(l.kind===`terminate`)return t.lifecycleAsync?.hasPending()?`pending`:(t.onTurnPersist?.(),`terminate`);if(l.kind===`continue`){t.onTurnPersist?.();continue}a(`tool_executing`);let{ranAnyTool:u}=await _t(s,t,c,e.lastTokenUsage.current,e.turnState.windowStats,e.turnState.stallDetector,e.toolResultAllowance);if(u&&e.turnState.toolTurnCount++,e.turnState.pendingBudgetNotice&&(t.messages.push({role:`user`,content:[{type:`text`,text:e.turnState.pendingBudgetNotice}],timestamp:e.clock.now(),internal:!0}),e.turnState.pendingBudgetNotice=void 0),t.onTurnPersist?.(),t.ports?.nondetFlush?.(),t.lifecycleAsync?.hasPending())return`pending`;a(`streaming`)}}function Qt(e,t){return e===void 0||e<=0?new Promise(()=>{}):new Promise(n=>{setTimeout(()=>{t(),n()},e).unref?.()})}async function $t(e,t,n,r){let i=!1,a=[],o=n.aborted,s=!1,c=e.then(()=>{i=!0}),l=new Promise(e=>{if(n.aborted){o=!0,i=!0,e();return}n.addEventListener(`abort`,()=>{o=!0,i=!0,e()},{once:!0})}),u=(async()=>{for(;!i;){let e=await t().catch(()=>[]);if(e.length>0){a=e,i=!0;return}if(i)return;await new Promise(e=>{setTimeout(e,200).unref?.()})}})(),d=Qt(r,()=>{s=!0,i=!0});return await Promise.race([c,l,u,d]),{steeringMessages:a,aborted:o,timedOut:s}}async function en(e,t,n){if(t.aborted)return`aborted`;let r=!1,i=!1,a=new Promise(e=>{t.addEventListener(`abort`,()=>{r=!0,e()},{once:!0})}),o=Qt(n,()=>{i=!0});return await Promise.race([e,a,o]),r?`aborted`:i?`timed-out`:`settled`}async function tn(e){let t=e.context,{signal:n,logger:r,emitter:i,transitionTo:a,getSteeringMessages:o}=t;for(;;){if(n.aborted)throw new v;if(a(`streaming`),await Zt({context:e.context,params:e.params,turnState:e.turnState,messages:e.messages,turnIndex:e.turnIndex,lastTokenUsage:e.lastTokenUsage,lastAssistantMessage:e.lastAssistantMessage,toolResultAllowance:e.toolResultAllowance.current,recorder:e.recorder,clock:e.clock})===`pending`){if(t.lifecycleAsync){let{steeringMessages:a,aborted:s,timedOut:c}=await $t(t.lifecycleAsync.waitForPending(),o,n,t.retry?.lifecycleAsyncTimeoutMs);if(s)throw new v;if(c){let n=t.retry?.lifecycleAsyncTimeoutMs??0;i.emit(`lifecycle.tool.timeout`,{turnIndex:e.turnIndex.current,timeoutMs:n}),e.recorder.record({kind:`lifecycle`,node:`lifecycle.tool.timeout`,turn:e.turnIndex.current,payload:{timeoutMs:n}}),r.warn(`Timed out after %d ms waiting for pending lifecycleAsync tool(s); abandoning the wait so the loop can proceed (RFC-366)`,n);for(let r of t.lifecycleAsync.listPending())e.messages.push(lt(r.toolName,r.toolCallId,n,{now:()=>(t.ports?.clock??S).now()})),r.consumed=!0}a.length>0&&(e.messages.push(...a),i.emit(`steering.injected`,{messages:a}),r.info(`Steering message(s) consumed while %d lifecycleAsync tool(s) still pending`,a.length))}continue}if(t.budget.isPauseRequested?.()){r.info(`Turn boundary reached with pause requested — yielding without followUp check`);break}await e.pause(`loop.end`,0),e.recorder.record({kind:`lifecycle`,node:`loop.end`,turn:e.turnIndex.current});let s=await t.getFollowUpMessages();if(await e.pause(`follow.up.check`,0,{metadata:{hasFollowUp:s.length>0,followUpCount:s.length}}),s.length===0)break;e.messages.push(...s),r.info(`Queued %d follow-up message(s)`,s.length),i.emit(`follow.up.start`,{messages:s}),e.turnState.toolTurnCount=0,e.turnState.extensionsUsed=0,e.turnState.budgetSteeringIssued=!1,L(e.turnState.windowStats),e.turnState.promptOutputTokens=0,e.turnState.promptStartedAt=e.clock.now(),e.turnState.stallDetector?.reset(),e.turnState.stallSteeringIssued=!1,e.turnState.protocolMismatchRetryCount=0,e.turnState.emptyResponseRetryCount=0,e.turnState.idleNudgeIssued=!1,e.turnState.continuationCount=0,e.toolResultAllowance.current=e.createToolResultAllowance()}if(t.lifecycleAsync?.hasPending()){r.info(`Waiting for remaining lifecycleAsync pending tool(s) to settle before returning (reached loop exit with pending still outstanding)`);let a=await en(t.lifecycleAsync.waitForPending(),n,t.retry?.lifecycleAsyncTimeoutMs);if(a===`aborted`)throw new v;if(a===`timed-out`){let n=t.retry?.lifecycleAsyncTimeoutMs??0;i.emit(`lifecycle.tool.timeout`,{turnIndex:e.turnIndex.current,timeoutMs:n}),e.recorder.record({kind:`lifecycle`,node:`lifecycle.tool.timeout`,turn:e.turnIndex.current,payload:{timeoutMs:n}}),r.warn(`Timed out after %d ms waiting for pending lifecycleAsync tool(s) at loop exit; returning without them (RFC-366)`,n);for(let r of t.lifecycleAsync.listPending())e.messages.push(lt(r.toolName,r.toolCallId,n,{now:()=>(t.ports?.clock??S).now()})),r.consumed=!0}}if(!e.lastAssistantMessage.current)throw Error(`Agent loop completed without producing a message`);return await e.pause(`agent.done`,0),e.recorder.record({kind:`lifecycle`,node:`agent.done`,turn:e.turnIndex.current}),r.info(`Agent loop finished after %d turn(s)`,e.turnIndex.current),e.lastAssistantMessage.current}async function nn(e){let t={current:0},n=e.budget.stallDetection,r={continuationCount:0,toolTurnCount:0,extensionsUsed:0,budgetSteeringIssued:!1,windowStats:I(),promptOutputTokens:0,promptStartedAt:(e.ports?.clock??S).now(),stallDetector:n===!1?void 0:new le(n??{}),stallSteeringIssued:!1,protocolMismatchRetryCount:0,emptyResponseRetryCount:0,idleNudgeIssued:!1},i={current:null},a={current:void 0},o=()=>new ae(oe(e.model.contextWindow,A.promptToolResultFraction),A.minToolResultChars),s=o(),{messages:c,signal:l,logger:u}=e,d=e.ports?.debug,f=e.ports?.clock??S,p=e.ports?.recorder??K,m={systemPrompt:e.systemPrompt,thinkingLevel:e.thinkingLevel,maxTokens:e.maxTokens,temperature:e.temperature},h=N({debug:d,getTurn:()=>t.current,getMessagesCount:()=>c.length,getTokenUsage:()=>a.current,getLlmParams:()=>m,getMessagesForSummary:()=>c});try{return u.info(`Agent loop started for model %s with %d messages`,e.model.id,c.length),await h(`loop.start`,0),p.record({kind:`lifecycle`,node:`loop.start`,turn:t.current}),tn({context:e,params:m,turnState:r,messages:c,turnIndex:t,lastTokenUsage:a,lastAssistantMessage:i,toolResultAllowance:{current:s},createToolResultAllowance:o,pause:h,recorder:p,clock:f})}catch(e){throw e instanceof v||l.aborted?(u.warn(`Agent loop aborted at turn %d`,t.current+1),await h(`agent.aborted`,0),p.record({kind:`lifecycle`,node:`agent.aborted`,turn:t.current}),e):(u.error(`Agent loop failed at turn %d: %s`,t.current+1,e instanceof Error?e.message:String(e)),await h(`agent.error`,0),p.record({kind:`lifecycle`,node:`agent.error`,turn:t.current,payload:{message:e instanceof Error?e.message:String(e)}}),e)}finally{e.ports?.nondetFlush?.(),await h(`loop.cleanup`,0)}}const rn=r(`@x-otto/agent:tool-executor`);function an(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.keys(e);if(t.length!==1||t[0]!==`_truncated`)return!1;let n=e._truncated;return typeof n==`object`&&!!n&&!Array.isArray(n)}function $(e){return{content:[{type:`text`,text:`Tool ${e} execution was aborted`}],isError:!0,errorKind:`aborted`,details:{}}}var on=class{tools;hookExecutor;agentName;sessionId;debug;clock;depth;parentTaskId;approval;constructor(e){this.tools=new Map;for(let t of e.tools)this.tools.set(t.name,t);this.hookExecutor=e.hookExecutor,this.agentName=e.agentName??``,this.sessionId=e.sessionId??``,this.debug=e.debug,this.clock=e.clock??S,this.depth=e.depth,this.parentTaskId=e.parentTaskId,this.approval=e.approval}list(){return[...this.tools.values()]}async execute(e,t){let{id:n,name:r}=e,i=this.tools.get(r),a=N({debug:this.debug,getTurn:()=>0,getMessagesCount:()=>0,getTokenUsage:()=>void 0});if(F(await a(`tool.resolve`,2,{lastToolName:r,metadata:{found:!!i,toolCallId:n,sessionId:this.sessionId}})),!i)return{content:[{type:`text`,text:`Unknown tool: ${r}`}],isError:!0,errorKind:`not_found`};let o=this.clock.now(),s=e.arguments;try{if(this.hookExecutor){F(await a(`tool.hook.before`,2,{lastToolName:r,metadata:{toolCallId:n,sessionId:this.sessionId}}));let e=await this.hookExecutor.executeBeforeHooks({toolName:r,toolCallId:n,args:s,agentName:this.agentName,sessionId:this.sessionId,paths:sn(i,s),readonly:i.readonly});if(e.kind===`deny`)return{content:[{type:`text`,text:e.reason}],isError:!0,errorKind:`permission`};if(s=e.args,e.kind===`ask`){let n=e.reason;if(!this.approval)return{content:[{type:`text`,text:`Tool ${r} requires approval but no approval handler is configured: ${n}`}],isError:!0,errorKind:`permission`};let i=await this.approval(r,s,n,e.risk);if(t.aborted)return $(r);if(!i)return{content:[{type:`text`,text:`Tool ${r} was rejected by user: ${n}`}],isError:!0,errorKind:`permission`}}}let c=i.parameters.safeParse(s);if(!c.success&&an(s)){let e=s._truncated,t=i.parameters.safeParse(e);t.success&&(rn.warn({toolName:r,toolCallId:n},`RFC-142: unwrapped legacy _truncated wrapper from model tool-call arguments (context-poisoning residue); executing with inner arguments`),c=t)}let{success:l}=c;if(F(await a(`tool.validate`,2,{lastToolName:r,metadata:{valid:l,toolCallId:n,sessionId:this.sessionId}})),!c.success)return{content:[{type:`text`,text:`Invalid arguments for tool ${r}: ${String(c.error)}\n\nDo NOT wrap arguments in any extra key; emit the tool's schema fields at the top level and retry.`}],isError:!0,errorKind:`validation`};if(t.aborted)return $(r);let u=await i.execute({id:e.id,params:c.data,signal:t,sessionId:this.sessionId||void 0,agentName:this.agentName||void 0,depth:this.depth,...this.parentTaskId===void 0?{}:{parentTaskId:this.parentTaskId}});if(t.aborted)return $(r);if(u.isError&&u.errorKind===`sandbox-denied`&&this.approval){let n=typeof u.details?.denialReason==`string`?u.details.denialReason:`sandbox policy`,a=`[sandbox-escalation] sandbox denied (${typeof u.details?.sandboxBackend==`string`?u.details.sandboxBackend:`unknown`}: ${n}); approve to retry this command without sandbox`,o=await this.approval(r,s,a,`medium`);!t.aborted&&o&&(u=await i.execute({id:e.id,params:c.data,signal:t,sessionId:this.sessionId||void 0,agentName:this.agentName||void 0,depth:this.depth,...this.parentTaskId===void 0?{}:{parentTaskId:this.parentTaskId}}))}return t.aborted||(this.hookExecutor&&(u=(await this.hookExecutor.executeAfterHooks({toolName:e.name,toolCallId:e.id,args:s,result:u,agentName:this.agentName,sessionId:this.sessionId,durationMs:this.clock.now()-o,readonly:i.readonly})).result,F(await a(`tool.hook.after`,2,{lastToolName:r,metadata:{toolCallId:n,durationMs:this.clock.now()-o,sessionId:this.sessionId}}))),t.aborted)?$(r):u}catch(n){if(t.aborted)return $(r);let i=n instanceof Error?n.message:String(n),a=n?.errorKind,o=n?.pluginSource;return{content:[{type:`text`,text:`Tool ${e.name} failed: ${i}`}],isError:!0,errorKind:a??`runtime`,details:{error:n instanceof Error?n.name:`UnknownError`},...o?{pluginSource:o}:{}}}}};function sn(e,t){if(!e.pathParams?.length)return[];let n=[];for(let r of e.pathParams){let i=t[r];typeof i==`string`&&n.push(e.resolvePath?e.resolvePath(i):i)}return n}function cn(e,t){return new on({tools:e,...t})}const ln=r(`@x-otto/agent`),un={idle:new Set([`streaming`,`aborted`,`error`,`archived`]),streaming:new Set([`tool_executing`,`completed`,`aborted`,`error`]),tool_executing:new Set([`streaming`,`aborted`,`error`]),completed:new Set([`streaming`,`idle`,`aborted`,`error`,`archived`]),error:new Set([`idle`,`aborted`,`streaming`,`archived`]),aborted:new Set([`streaming`,`idle`,`error`,`archived`]),archived:new Set([`idle`])};function dn(e,t,n){let r=cn(t.tools,{hookExecutor:e.toolHookExecutor,agentName:e.agentName,sessionId:e.sessionId,debug:e.debug,clock:e.clock,depth:e.depth,parentTaskId:e.parentTaskId,approval:e.approval});return{model:t.model,systemPrompt:t.systemPrompt,systemTail:t.systemTail,cacheRetention:t.cacheRetention,messages:t.messages,thinkingLevel:t.thinkingLevel,maxTokens:t.maxTokens,temperature:t.temperature,convertToLLM:t.convertToLLM??pn,onTurnPersist:t.onTurnPersist,assertMessagesConsistent:t.assertMessagesConsistent,logger:e.agentLogger,toolExecutor:r,stream:e.stream,signal:n.signal,emitter:n.emitter,getSteeringMessages:n.getSteeringMessages,getFollowUpMessages:n.getFollowUpMessages,transitionTo:n.transitionTo,lifecycleAsync:n.lifecycleAsync,wireSnapshot:e.wireSnapshotStore?{sessionId:e.sessionId??``,store:e.wireSnapshotStore}:void 0,ports:{clock:e.clock,debug:e.debug,recorder:e.recorder,nondetFlush:e.nondetFlush,spill:e.spill},budget:{maxToolTurns:e.maxToolTurns,maxToolTurnExtensions:e.maxToolTurnExtensions,budgetSteerWrapUp:e.budgetSteerWrapUp,promptOutputTokenBudget:e.promptOutputTokenBudget,promptWallClockBudgetMs:e.promptWallClockBudgetMs,stallDetection:e.stallDetection,idleTurnDetection:e.idleTurnDetection,isPauseRequested:t.isPauseRequested,maxToolCallsPerTurn:e.maxToolCallsPerTurn},retry:{retryAccelerate:e.retryAccelerate,streamRetry:e.streamRetry,networkDisconnectRetry:e.networkDisconnectRetry,idleTimeoutRetry:e.idleTimeoutRetry,lifecycleAsyncTimeoutMs:e.lifecycleAsyncTimeoutMs},contextTransform:{transformContext:t.transformContext,reactiveCompact:t.reactiveCompact,describeImages:t.describeImages}}}var fn=class extends n{state;abortController=null;pendingAbort=!1;steeringQueue=[];followUpQueue=[];pendingLifecycleTools=new Map;promptSeq=0;get currentPromptSeq(){return this.promptSeq}config;get status(){return this.state.status}get turnCount(){return this.state.turnCount}constructor(e){super(),this.config={stream:e.stream,agentLogger:e.logger,maxToolTurns:e.maxToolTurns??A.maxToolTurns,maxToolTurnExtensions:e.maxToolTurnExtensions??0,budgetSteerWrapUp:e.budgetSteerWrapUp??!1,promptOutputTokenBudget:e.promptOutputTokenBudget,promptWallClockBudgetMs:e.promptWallClockBudgetMs,stallDetection:e.stallDetection,idleTurnDetection:e.idleTurnDetection,agentName:e.agentName??``,sessionId:e.sessionId??``,toolHookExecutor:e.toolHookExecutor,debug:e.debug,clock:e.clock,recorder:e.recorder,nondetFlush:e.nondetFlush,depth:e.depth,parentTaskId:e.parentTaskId,maxToolCallsPerTurn:e.maxToolCallsPerTurn,retryAccelerate:e.retryAccelerate,streamRetry:e.streamRetry,networkDisconnectRetry:e.networkDisconnectRetry,idleTimeoutRetry:e.idleTimeoutRetry,lifecycleAsyncTimeoutMs:e.lifecycleAsyncTimeoutMs,spill:e.spill,approval:e.approval},this.state={status:`idle`,turnCount:0,tokenUsage:{input:0,output:0,cacheRead:0},isStreaming:!1,currentStreamMessage:null,error:void 0},this.on(`status.change`,({to:e})=>{this.state.isStreaming=e===`streaming`}),this.on(`turn.end`,({message:e})=>{this.state.turnCount++,this.state.currentStreamMessage=null,this.state.tokenUsage.input+=e.usage.inputTokens,this.state.tokenUsage.output+=e.usage.outputTokens,this.state.tokenUsage.cacheRead+=e.usage.cacheReadTokens}),this.on(`stream.event`,({event:e})=>{e.type===`start`&&(this.state.currentStreamMessage=e.partial)})}getState(){return{...this.state,tokenUsage:{...this.state.tokenUsage}}}async run(e){if(this.state.status===`streaming`||this.state.status===`tool_executing`)throw Error(`Cannot run in ${this.state.status} status`);if(this.state.status===`archived`)throw Error(`Cannot run: session is archived`);return this.state.status===`error`&&(this.state.error=void 0),this.cancelStalePendingLifecycleTools(),this.promptSeq++,this.runLoop(e)}cancelStalePendingLifecycleTools(){for(let[e,t]of this.pendingLifecycleTools){if(t.consumed){this.pendingLifecycleTools.delete(e);continue}t.abortController.abort(),this.config.agentLogger.info(`Cancelling stale lifecycleAsync tool %s (task id: %s) from prompt %d — new prompt %d starting`,t.toolName,t.toolCallId,t.promptSeq,this.promptSeq+1)}}steer(e){this.steeringQueue.push(e)}removeSteer(e){let t=this.steeringQueue.findIndex(t=>t.uuid===e);return t===-1?!1:(this.steeringQueue.splice(t,1),!0)}followUp(e){this.followUpQueue.push(e)}registerPendingLifecycleTool(e){this.pendingLifecycleTools.set(e.toolCallId,e)}hasPendingLifecycleTools(){for(let e of this.pendingLifecycleTools.values())if(!e.consumed)return!0;return!1}listPendingLifecycleTools(){let e=[];for(let t of this.pendingLifecycleTools.values())t.consumed||e.push(t);return e}async waitForPendingLifecycleTools(){let e=[...this.pendingLifecycleTools.values()].filter(e=>!e.consumed).map(e=>e.promise);e.length!==0&&await Promise.allSettled(e)}async notifyToolCompletion(e,t){let n=this.pendingLifecycleTools.get(e);return!n||n.consumed?{consumed:!1}:(n.consumed=!0,this.emit(`lifecycle.tool.completed`,{toolCallId:e,toolName:n.toolName,isError:t.isError??!1,result:t}),{consumed:!0,entry:n})}abort(){this.state.status===`aborted`&&!this.abortController||(this.abortController?this.abortController.abort():this.pendingAbort=!0,this.transitionTo(`aborted`),this.emit(`abort`))}archive(){this.transitionTo(`archived`)}unarchive(){this.transitionTo(`idle`)}reset(){this.abortController&&=(this.abortController.abort(),null),this.pendingAbort=!1,this.steeringQueue=[],this.followUpQueue=[],this.pendingLifecycleTools.clear(),this.state.turnCount=0,this.state.tokenUsage={input:0,output:0,cacheRead:0},this.state.currentStreamMessage=null,this.state.error=void 0;let e=this.state.status;this.state.status=`idle`,e!==`idle`&&this.emit(`status.change`,{from:e,to:`idle`})}async runLoop(e){let t=new AbortController;this.abortController=t,this.pendingAbort&&(this.pendingAbort=!1,t.abort());let n=t.signal;try{let t=await nn(dn(this.config,e,{signal:n,emitter:this,getSteeringMessages:()=>this.drainSteeringQueue(),getFollowUpMessages:()=>this.drainFollowUpQueue(),transitionTo:e=>this.transitionTo(e),lifecycleAsync:{register:e=>this.registerPendingLifecycleTool(e),hasPending:()=>this.hasPendingLifecycleTools(),waitForPending:()=>this.waitForPendingLifecycleTools(),listPending:()=>this.listPendingLifecycleTools(),notifyCompletion:(e,t)=>this.notifyToolCompletion(e,t),currentPromptSeq:()=>this.currentPromptSeq}}));return this.transitionTo(`completed`),t}catch(e){throw e instanceof v||n.aborted?(this.transitionTo(`aborted`),e):(this.state.error=e instanceof Error?e:Error(String(e)),this.transitionTo(`error`),this.emit(`error`,{error:this.state.error}),this.state.error)}finally{this.abortController===t&&(this.abortController=null),this.state.isStreaming=!1}}transitionTo(e){let t=this.state.status;if(t!==e){if(!un[t]?.has(e)){ln.warn(`Invalid state transition: %s → %s (ignored)`,t,e);return}this.state.status=e,this.emit(`status.change`,{from:t,to:e})}}async drainSteeringQueue(){let e=[...this.steeringQueue];return this.steeringQueue=[],e}async drainFollowUpQueue(){let e=[...this.followUpQueue];return this.followUpQueue=[],e}};function pn(e){return e.filter(e=>typeof e==`object`&&!!e&&`role`in e&&(e.role===`user`||e.role===`assistant`||e.role===`tool_result`||e.role===`system_notification`))}function mn(e){return new fn(e)}export{v as AbortError,fn as Agent,ne as BREAKPOINT_POINTS,A as ENGINE_DEFAULTS,k as ENGINE_LIFECYCLE_TIMINGS,E as ENGINE_NODES,ie as IMAGE_CONTEXT_CHARS_EQUIVALENT,V as MAX_IMAGE_INLINE_BYTES,y as MaxToolTurnsError,x as MessagesConsistencyError,ee as OBSERVABLE_NODE_IDS,b as PromptBudgetExceededError,te as TRACEABLE_NODE_IDS,Pe as WireSnapshotStore,we as applyMemoryTransform,Be as applyVisionGate,ct as buildLifecycleAsyncCompletionNotice,st as buildLifecycleAsyncPlaceholder,ot as buildLifecycleAsyncPlaceholderText,Ie as captureWireSnapshot,nt as causalDag,W as clampToolResultContent,se as clampWithSpill,F as consumePause,mn as createAgent,ge as createRecordingPorts,_e as createReplayPorts,he as createStreamTracePersister,cn as createToolExecutor,ue as createTraceRecorder,tt as digestTracePayload,ve as extractNondetDraws,o as extractToolResultText,De as forceMemoryTransform,O as nodesWithCapability,K as noopRecorder,U as normalizeToolResultContent,Ze as prompt,q as recordMemoryLifecycle,ce as runBounded,fe as shouldPersistStreamEvent,H as stripAnsi,j as summarizeMessages,Qe as summarizeTrace,S as systemClock,w as systemId,C as systemRandom,G as toolResultContextChars,$e as traceToSpans,it as traceWhy,rt as turnToolTopology,Fe as wireSnapshotStore};
10
21
  //# sourceMappingURL=index.js.map