gemi 0.98.0 → 0.100.0

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/ai/index.js CHANGED
@@ -1,26 +1,26 @@
1
1
  // @bun
2
- import{Ab as p9,Bb as q$,Cb as _$,Db as j3,zb as R}from"../chunk-wc46df4w.js";import{Me as U3,Pe as L3,cf as M6,df as S6,ef as a,ff as YQ,tf as C3,vf as e,wf as d}from"../chunk-h15bd9vn.js";import{Af as uQ,xf as F3,zf as gQ}from"../chunk-9xf2fx98.js";import{Ef as SQ}from"../chunk-eqtsfvvd.js";import{Kg as LQ}from"../chunk-48dek9s7.js";import"../chunk-f6s7ddjz.js";import"../chunk-n63xjrck.js";import"../chunk-68zf43ah.js";class f extends Error{status;body;requestId;constructor(Q,$,Z){super(`Provider request failed with status ${Q}: ${k3($)}`);this.name="ProviderHttpError",this.status=Q,this.body=$,this.requestId=Z}}class KQ extends Error{timeoutMs;constructor(Q){super(`Provider request timed out after ${Q}ms`);this.name="ProviderTimeoutError",this.timeoutMs=Q}}function k3(Q){let $=d9(Q);if($?.message)return $.message;if(typeof Q==="string")return Q.slice(0,500);return"no error body"}function d9(Q){if(!Q||typeof Q!=="object")return null;let $=Q,J=$.error&&typeof $.error==="object"?$.error:Q;if(typeof J.message!=="string"&&typeof J.code!=="string"&&typeof J.type!=="string")return null;let W=J.innererror?.code??J.code;return{message:J.message,type:J.type,code:W,param:J.param}}function T(Q){if(!Q||typeof Q!=="object")return{};let{status:$,requestId:Z}=Q;return{...typeof $==="number"&&$>=100&&$<=599?{status:$}:{},...typeof Z==="string"&&Z?{requestId:Z}:{}}}function k(Q){if(Q instanceof KQ)return{code:"provider_error",message:Q.message,retryable:!0};if(x3(Q))return{code:"aborted",message:"The request was aborted.",retryable:!1};if(Q instanceof f)return T3(Q.status,d9(Q.body),Q.message);if(Q instanceof TypeError)return{code:"provider_error",message:`Could not reach the provider: ${Q.message}`,retryable:!0};if(Q instanceof Error)return{code:"provider_error",message:Q.message,retryable:!1};return{code:"unknown",message:String(Q),retryable:!1}}function T3(Q,$,Z){let J=$?.message??Z,W=($?.code??"").toLowerCase(),X=($?.type??"").toLowerCase(),G=`${W} ${X} ${J}`.toLowerCase();if(Q===429){let H=W==="insufficient_quota"||G.includes("quota");return{code:"rate_limited",message:J,retryable:!H}}if(Q>=500||Q===408||Q===409)return{code:"provider_error",message:J,retryable:!0};if(A3(G))return{code:"context_length_exceeded",message:J,retryable:!1};if(E3(G))return{code:"content_filtered",message:J,retryable:!1};if($?.param?.startsWith("tools")||G.includes("invalid schema for function"))return{code:"invalid_tool_input",message:J,retryable:!1};return{code:"provider_error",message:J,retryable:!1}}function A3(Q){return Q.includes("context_length_exceeded")||Q.includes("maximum context length")||Q.includes("context window")||Q.includes("reduce the length")}function E3(Q){return Q.includes("content_filter")||Q.includes("content_policy_violation")||Q.includes("responsibleaipolicyviolation")||Q.includes("content management policy")}function x3(Q){if(!Q||typeof Q!=="object")return!1;let $=Q;return $.name==="AbortError"||$.code==="ABORT_ERR"}class A extends Error{constructor(){super("The run was stopped");this.name="RunAborted"}}function h(Q,$){if($.aborted)return Promise.reject(new A);return new Promise((Z,J)=>{let W=()=>J(new A);$.addEventListener("abort",W,{once:!0}),Q.then(Z,J).finally(()=>$.removeEventListener("abort",W))})}function N(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function S(Q,$){if(!$)return Q;let Z={inputTokens:Q.inputTokens+($.inputTokens??0),outputTokens:Q.outputTokens+($.outputTokens??0),totalTokens:Q.totalTokens+($.totalTokens??0)};if($.reasoningTokens!==void 0||Q.reasoningTokens!==void 0)Z.reasoningTokens=(Q.reasoningTokens??0)+($.reasoningTokens??0);if($.cachedInputTokens!==void 0||Q.cachedInputTokens!==void 0)Z.cachedInputTokens=(Q.cachedInputTokens??0)+($.cachedInputTokens??0);if($.imageInputTokens!==void 0||Q.imageInputTokens!==void 0)Z.imageInputTokens=(Q.imageInputTokens??0)+($.imageInputTokens??0);if($.imageOutputTokens!==void 0||Q.imageOutputTokens!==void 0)Z.imageOutputTokens=(Q.imageOutputTokens??0)+($.imageOutputTokens??0);return Z}function zQ(Q){if(!Q.trim())return{};try{return JSON.parse(Q)}catch{}let $=[],Z=!1,J=!1;for(let G of Q){if(Z){if(J)J=!1;else if(G==="\\")J=!0;else if(G==='"')Z=!1;continue}if(G==='"')Z=!0;else if(G==="{")$.push("}");else if(G==="[")$.push("]");else if(G==="}"||G==="]")$.pop()}let W=Q;if(Z)W+='"';W=W.replace(/[,:]\s*$/,"");let X=$.reverse().join("");try{return JSON.parse(W+X)}catch{try{return JSON.parse(W.replace(/,?\s*"[^"]*"\s*$/,"")+X)}catch{return{}}}}function BQ(Q){return{name:"output",schema:Q.toJSONSchema(),strict:a(Q)}}function DQ(Q,$){let Z=Q.safeParse(zQ($));if(Z.ok===!0)return{ok:!0,value:Z.value};return{ok:!1,error:{code:"invalid_output",message:`The model's structured answer did not match the output schema: ${Z.errors.join(", ")}`,retryable:!0}}}function UQ(Q){if(Q.length>0)Q[0];return Q}function r(Q,$,Z){let J=Q.content[Q.content.length-1];if(J&&J.type===$){J.text=(J.text??"")+Z;return}Q.content.push($==="text"?{type:"text",text:Z}:{type:"reasoning",text:Z})}function FQ(Q,$,Z){let J=Q.content[Q.content.length-1];if(J&&J.type==="reasoning"&&J.id===$){J.text=(J.text??"")+Z;return}Q.content.push($?{type:"reasoning",id:$,text:Z}:{type:"reasoning",text:Z})}function w3(Q){return cQ(Q)}async function cQ(Q,$={}){let Z=`gen_${crypto.randomUUID()}`,J=await I3(Q);if($.settled?.(J),!J.ok){if(Q.logErrors!==!1&&J.error.code!=="aborted")b3(Z,J.error,$.origin);if(Q.throwOnError)throw new QQ({runId:Z,messages:J.messages,finishReason:J.finishReason,usage:J.usage,error:J.error})}return J}function b3(Q,$,Z){let J=`[gemi/ai] generate() failed (${$.code}${$.status!==void 0?` ${$.status}`:""}): ${$.message}`,W={...Z,generateId:Q,error:$},X=!1;try{e.error(J,W),X=!0}catch{}if(!X||Bun.env.NODE_ENV==="development")console.error(J,W)}async function I3(Q){let $=Q.messages??[];if($.length===0&&!Q.prompt)throw Error("generate() was given neither a `prompt` nor `messages`, so there is nothing to send the model.");let Z=[...$];if(Q.prompt)Z.push({id:`msg_${crypto.randomUUID()}`,role:"user",content:[{type:"text",text:Q.prompt}],createdAt:new Date().toISOString()});let J={id:`msg_${crypto.randomUUID()}`,role:"assistant",content:[],createdAt:new Date().toISOString()},W=Q.signal??new AbortController().signal,X=N(),G="stop",H,V={},Y="";try{let D=Q.provider.stream({messages:[...Z],systemPrompt:Q.instructions?.trim()?Q.instructions:void 0,output:BQ(Q.output),reasoning:Q.reasoning,maxOutputTokens:Q.maxOutputTokens,temperature:Q.temperature,signal:Q.signal})[Symbol.asyncIterator]();try{for(;;){let F=await h(Promise.resolve(D.next()),W);if(F.done)break;let U=F.value;switch(U.type){case"output-delta":Y+=U.delta;break;case"text-delta":r(J,"text",U.delta);break;case"reasoning-delta":FQ(J,U.id,U.delta);break;case"finish":if(X=S(X,U.usage),!H)G=U.reason;break;case"error":G="error",H=U.error,V=T(U);break}}}finally{if(W.aborted)Promise.resolve(D.return?.()).catch(()=>{})}}catch(B){if(B instanceof A||W.aborted)G="aborted",H=v3(W);else G="error",H=Q.provider.normalizeError(B),V=T(B)}let K=!1,z;if(!H)if(G==="length")H={code:"invalid_output",message:"The model ran out of output tokens before finishing its structured answer, so it was cut off. Raise maxOutputTokens, or ask for a shorter answer.",retryable:!0};else if(!Y.trim())H={code:"invalid_output",message:"The model finished without giving a structured answer.",retryable:!0};else{let B=DQ(Q.output,Y);if(B.ok===!0)K=!0,z=B.value;else H=B.error}if(K)J.content.push({type:"output",value:z});else if(Y)r(J,"text",Y);for(let B of J.content)if((B.type==="text"||B.type==="reasoning")&&typeof B.text==="string")B.text=UQ(B.text);if(J.finishReason=G,J.usage=X,Z.push(J),K)return{ok:!0,output:z,messages:Z,usage:X,finishReason:G};return{ok:!1,error:{...H,...V},messages:Z,usage:X,finishReason:G}}function v3(Q){return Q.reason?.name==="TimeoutError"?{code:"timeout",message:"The generation timed out.",retryable:!0}:{code:"aborted",message:"The generation was stopped.",retryable:!1}}import{createHmac as f3,hkdfSync as h3,randomBytes as l9,timingSafeEqual as y3}from"crypto";class $Q{spent=new Map;sweepAt=1024;async consume(Q,$){return this.consumeSync(Q,$)}consumeSync(Q,$,Z=Date.now()){if(this.spent.size>=this.sweepAt)this.sweep(Z);let J=this.spent.get(Q);if(J!==void 0&&J>Z)return!1;return this.spent.set(Q,$),!0}get size(){return this.spent.size}sweep(Q){for(let[$,Z]of this.spent)if(Z<=Q)this.spent.delete($);this.sweepAt=Math.max(1024,this.spent.size*2)}}class mQ{injectedClient;prefix;constructor(Q={}){this.injectedClient=Q.client,this.prefix=Q.prefix??"gemi:ai:nonce"}async consume(Q,$){let Z=Math.max(1,Math.ceil($-Date.now()));return await this.client.send("SET",[`${this.prefix}:${Q}`,"1","PX",String(Z),"NX"])==="OK"}get client(){if(this.injectedClient)return this.injectedClient;let Q=LQ(),$=Q.bound(d)?Q.make(d).client:void 0;if(!$)throw Error("RedisNonceStore could not reach the Redis client. Register RedisServiceProvider on your application, or pass a client: new RedisNonceStore({ client }).");return $}}var l=new $Q;var pQ="agt2",jQ="agt1",i9=[pQ,jQ],dQ=86400000,g3=Date.now()+dQ;function o9(Q){return Q<=g3}var n9="gemi.ai.pending-call.v1",s9="gemi.ai.nested-run.v1",u3="gemi.ai.execution-receipt.v1",c3="gemi.ai.signing",CQ=new Map;function ZQ(Q,$){let Z=lQ($),J=`${Q}\x00${Z}`,W=CQ.get(J);if(!W){if(W=Buffer.from(h3("sha256",Z,c3,Q,32)),CQ.size>64)CQ.clear();CQ.set(J,W)}return W}function lQ(Q){let $=Q??process.env.SECRET;if(!$)throw Error("Signing a pending tool call needs an app secret. Set SECRET in the environment.");return $}function x(Q){if(Q===null||typeof Q!=="object")return JSON.stringify(Q)??"null";if(Array.isArray(Q))return`[${Q.map(x).join(",")}]`;let $=Q;return`{${Object.keys($).filter((J)=>$[J]!==void 0).sort().map((J)=>`${JSON.stringify(J)}:${x($[J])}`).join(",")}}`}function m3(Q){return Q.map(($)=>`${$.length}:${$}`).join("")}function y(Q,$){return f3("sha256",Q).update(m3($)).digest()}function t9(Q,$){let Z=Buffer.from(Q.split(".")[4],"base64url");return Z.length===$.length&&y3(Z,$)}function iQ(Q){return x(Q??null)}function a9(Q,$,Z){return[pQ,Q.runId,Q.toolCallId,Q.name,Q.kind,$,String(Z),x(Q.input),x(Q.path??[]),iQ(Q.subject)]}function p3(Q,$,Z){let J=[jQ,Q.runId,Q.toolCallId,Q.name,Q.kind,$,String(Z),x(Q.input)];if(Q.path&&Q.path.length>0)J.push(x(Q.path));return J}var r9=(Q)=>Buffer.from(Q,"utf8").toString("base64url"),d3=(Q)=>Buffer.from(Q,"base64url").toString("utf8");function e9(Q,$={}){let Z=ZQ(n9,$.secret),W=($.now??Date.now())+($.ttlMs??dQ),X=l9(12).toString("base64url"),G=y(Z,a9(Q,X,W)).toString("base64url");return[pQ,r9(Q.runId),X,W.toString(36),G].join(".")}function oQ(Q){return PQ(Q,i9)}function PQ(Q,$){let Z=Q.split(".");if(Z.length!==5||!$.includes(Z[0]))return null;let J=Number.parseInt(Z[3],36);if(!Number.isFinite(J))return null;try{return{runId:d3(Z[1]),nonce:Z[2],expiresAt:J,version:Z[0]}}catch{return null}}function Q$(Q,$,Z={}){let J=PQ(Q,i9);if(!J)return{ok:!1,reason:"malformed"};if(J.version===jQ&&!o9(J.expiresAt))return{ok:!1,reason:"forged"};let W=J.version===jQ?y(lQ(Z.secret),p3($,J.nonce,J.expiresAt)):y(ZQ(n9,Z.secret),a9($,J.nonce,J.expiresAt));if(!t9(Q,W))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>J.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:J.runId,nonce:J.nonce,expiresAt:J.expiresAt}}var nQ="agn2",OQ="agn1",$$=[nQ,OQ];function Z$(Q,$,Z){return[...J$(Q,$,Z,nQ),iQ(Q.subject)]}function J$(Q,$,Z,J=OQ){return[J,Q.runId,x(Q.path),Q.nestedRunId,$,String(Z),x([...Q.open].sort()),x(Q.input)]}function W$(Q,$={}){let Z=ZQ(s9,$.secret),W=($.now??Date.now())+($.ttlMs??dQ),X=l9(12).toString("base64url"),G=y(Z,Z$(Q,X,W)).toString("base64url");return[nQ,r9(Q.runId),X,W.toString(36),G].join(".")}function X$(Q,$,Z={}){let J=PQ(Q,$$);if(!J)return{ok:!1,reason:"malformed"};if(J.version===OQ&&!o9(J.expiresAt))return{ok:!1,reason:"forged"};let W={...$,runId:J.runId},X=J.version===OQ?y(lQ(Z.secret),J$(W,J.nonce,J.expiresAt)):y(ZQ(s9,Z.secret),Z$(W,J.nonce,J.expiresAt));if(!t9(Q,X))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>J.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:J.runId,nonce:J.nonce,expiresAt:J.expiresAt}}function G$(Q,$,Z={}){let J=ZQ(u3,Z.secret);return y(J,[Q,$.runId,$.toolCallId,$.name,$.kind,x($.input),x($.path??[]),iQ($.subject)]).toString("base64url")}function V$(Q,$){return Y$($,oQ(Q))}function H$(Q,$){return Y$($,PQ(Q,$$))}async function Y$(Q,$){if(!$)return!1;return Q.consume($.nonce,$.expiresAt)}class JQ extends R{id;code="attachment_not_found";constructor(Q){super(`No attachment ${Q}.`);this.id=Q;this.name="AttachmentNotFoundError"}}class i extends R{code="invalid_attachment_scope";constructor(Q){super(Q);this.name="InvalidAttachmentScopeError"}}function sQ(Q){if(!Q||typeof Q.key!=="string"||Q.key.length===0)throw new i("An attachment scope needs a non-empty key. Return `null` from `attachmentScope()` for a request that has no subject \u2014 an empty key is a bucket every caller shares.");return Q}var I="gemi_att_";function tQ(){return`${I}${crypto.randomUUID()}`}class WQ{store;storage;scope;constructor(Q,$,Z){this.store=Q;this.storage=$;this.scope=Z;sQ(Z)}async get(Q){let $=await this.store.find(this.scope,Q);if(!$||$.scopeKey!==this.scope.key)throw new JQ(Q);return $}async read(Q){return await this.readRecord(Q,await this.get(Q))}async readRecord(Q,$){if(!$.objectName)throw new JQ(Q);return await this.storage.read({name:$.objectName})}async file(Q){let $=await this.get(Q),J=(await this.readRecord(Q,$)).body,W=J instanceof Blob?J:J?await new Response(J).blob():new Blob([]);return new File([W],$.name,{type:$.mimeType})}async put(Q,$={}){let Z=tQ(),J=$.mimeType??Q.type??"",W=$.name??(Q instanceof File?Q.name:Z),X=await this.storage.put({name:aQ(Z,W),body:Q,contentType:J||void 0}),G={id:Z,scopeKey:this.scope.key,objectName:X,name:W,mimeType:J||"application/octet-stream",size:Q.size,createdAt:new Date().toISOString(),destination:$.fileId?"both":"storage",...$.fileId?{fileId:$.fileId}:{}};return await this.store.put(this.scope,G),G}}function aQ(Q,$){let Z=/\.([A-Za-z0-9]{1,8})$/.exec($);return`attachments/${Q}${Z?`.${Z[1].toLowerCase()}`:""}`}class qQ{rows=new Map;async put(Q,$){sQ(Q),this.rows.set($.id,{...$,scopeKey:Q.key})}async find(Q,$){sQ(Q);let Z=this.rows.get($);if(!Z||Z.scopeKey!==Q.key)return null;return Z}get size(){return this.rows.size}}var _Q=new qQ;var rQ=new TextEncoder;function K$(Q){return`id: ${Q.seq}
2
+ import{Ab as l9,Bb as _$,Cb as M$,Db as q3,zb as T}from"../chunk-wc46df4w.js";import{Me as L3,Pe as P3,cf as T6,df as k6,ef as a,ff as YQ,tf as O3,vf as e,wf as d}from"../chunk-h15bd9vn.js";import{Af as cQ,xf as C3,zf as uQ}from"../chunk-9xf2fx98.js";import{Ef as SQ}from"../chunk-eqtsfvvd.js";import{Kg as jQ}from"../chunk-48dek9s7.js";import"../chunk-f6s7ddjz.js";import"../chunk-n63xjrck.js";import"../chunk-68zf43ah.js";class h extends Error{status;body;requestId;constructor(Q,$,Z){super(`Provider request failed with status ${Q}: ${E3($)}`);this.name="ProviderHttpError",this.status=Q,this.body=$,this.requestId=Z}}class KQ extends Error{timeoutMs;constructor(Q){super(`Provider request timed out after ${Q}ms`);this.name="ProviderTimeoutError",this.timeoutMs=Q}}function E3(Q){let $=i9(Q);if($?.message)return $.message;if(typeof Q==="string")return Q.slice(0,500);return"no error body"}function i9(Q){if(!Q||typeof Q!=="object")return null;let $=Q,J=$.error&&typeof $.error==="object"?$.error:Q;if(typeof J.message!=="string"&&typeof J.code!=="string"&&typeof J.type!=="string")return null;let W=J.innererror?.code??J.code;return{message:J.message,type:J.type,code:W,param:J.param}}function A(Q){if(!Q||typeof Q!=="object")return{};let{status:$,requestId:Z}=Q;return{...typeof $==="number"&&$>=100&&$<=599?{status:$}:{},...typeof Z==="string"&&Z?{requestId:Z}:{}}}function k(Q){if(Q instanceof KQ)return{code:"provider_error",message:Q.message,retryable:!0};if(I3(Q))return{code:"aborted",message:"The request was aborted.",retryable:!1};if(Q instanceof h)return x3(Q.status,i9(Q.body),Q.message);if(Q instanceof TypeError)return{code:"provider_error",message:`Could not reach the provider: ${Q.message}`,retryable:!0};if(Q instanceof Error)return{code:"provider_error",message:Q.message,retryable:!1};return{code:"unknown",message:String(Q),retryable:!1}}function x3(Q,$,Z){let J=$?.message??Z,W=($?.code??"").toLowerCase(),X=($?.type??"").toLowerCase(),G=`${W} ${X} ${J}`.toLowerCase();if(Q===429){let V=W==="insufficient_quota"||G.includes("quota");return{code:"rate_limited",message:J,retryable:!V}}if(Q>=500||Q===408||Q===409)return{code:"provider_error",message:J,retryable:!0};if(b3(G))return{code:"context_length_exceeded",message:J,retryable:!1};if(w3(G))return{code:"content_filtered",message:J,retryable:!1};if($?.param?.startsWith("tools")||G.includes("invalid schema for function"))return{code:"invalid_tool_input",message:J,retryable:!1};return{code:"provider_error",message:J,retryable:!1}}function b3(Q){return Q.includes("context_length_exceeded")||Q.includes("maximum context length")||Q.includes("context window")||Q.includes("reduce the length")}function w3(Q){return Q.includes("content_filter")||Q.includes("content_policy_violation")||Q.includes("responsibleaipolicyviolation")||Q.includes("content management policy")}function I3(Q){if(!Q||typeof Q!=="object")return!1;let $=Q;return $.name==="AbortError"||$.code==="ABORT_ERR"}class E extends Error{constructor(){super("The run was stopped");this.name="RunAborted"}}function y(Q,$){if($.aborted)return Promise.reject(new E);return new Promise((Z,J)=>{let W=()=>J(new E);$.addEventListener("abort",W,{once:!0}),Q.then(Z,J).finally(()=>$.removeEventListener("abort",W))})}function M(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function R(Q,$){if(!$)return Q;let Z={inputTokens:Q.inputTokens+($.inputTokens??0),outputTokens:Q.outputTokens+($.outputTokens??0),totalTokens:Q.totalTokens+($.totalTokens??0)};if($.reasoningTokens!==void 0||Q.reasoningTokens!==void 0)Z.reasoningTokens=(Q.reasoningTokens??0)+($.reasoningTokens??0);if($.cachedInputTokens!==void 0||Q.cachedInputTokens!==void 0)Z.cachedInputTokens=(Q.cachedInputTokens??0)+($.cachedInputTokens??0);if($.imageInputTokens!==void 0||Q.imageInputTokens!==void 0)Z.imageInputTokens=(Q.imageInputTokens??0)+($.imageInputTokens??0);if($.imageOutputTokens!==void 0||Q.imageOutputTokens!==void 0)Z.imageOutputTokens=(Q.imageOutputTokens??0)+($.imageOutputTokens??0);return Z}function zQ(Q){if(!Q.trim())return{};try{return JSON.parse(Q)}catch{}let $=[],Z=!1,J=!1;for(let G of Q){if(Z){if(J)J=!1;else if(G==="\\")J=!0;else if(G==='"')Z=!1;continue}if(G==='"')Z=!0;else if(G==="{")$.push("}");else if(G==="[")$.push("]");else if(G==="}"||G==="]")$.pop()}let W=Q;if(Z)W+='"';W=W.replace(/[,:]\s*$/,"");let X=$.reverse().join("");try{return JSON.parse(W+X)}catch{try{return JSON.parse(W.replace(/,?\s*"[^"]*"\s*$/,"")+X)}catch{return{}}}}function BQ(Q){return{name:"output",schema:Q.toJSONSchema(),strict:a(Q)}}function DQ(Q,$){let Z=Q.safeParse(zQ($));if(Z.ok===!0)return{ok:!0,value:Z.value};return{ok:!1,error:{code:"invalid_output",message:`The model's structured answer did not match the output schema: ${Z.errors.join(", ")}`,retryable:!0}}}function UQ(Q){if(Q.length>0)Q[0];return Q}function r(Q,$,Z){let J=Q.content[Q.content.length-1];if(J&&J.type===$){J.text=(J.text??"")+Z;return}Q.content.push($==="text"?{type:"text",text:Z}:{type:"reasoning",text:Z})}function FQ(Q,$,Z){let J=Q.content[Q.content.length-1];if(J&&J.type==="reasoning"&&J.id===$){J.text=(J.text??"")+Z;return}Q.content.push($?{type:"reasoning",id:$,text:Z}:{type:"reasoning",text:Z})}function v3(Q){return mQ(Q)}async function mQ(Q,$={}){let Z=`gen_${crypto.randomUUID()}`,J=await h3(Q);if($.settled?.(J),!J.ok){if(Q.logErrors!==!1&&J.error.code!=="aborted")f3(Z,J.error,$.origin);if(Q.throwOnError)throw new QQ({runId:Z,messages:J.messages,finishReason:J.finishReason,usage:J.usage,error:J.error})}return J}function f3(Q,$,Z){let J=`[gemi/ai] generate() failed (${$.code}${$.status!==void 0?` ${$.status}`:""}): ${$.message}`,W={...Z,generateId:Q,error:$},X=!1;try{e.error(J,W),X=!0}catch{}if(!X||Bun.env.NODE_ENV==="development")console.error(J,W)}async function h3(Q){let $=Q.messages??[];if($.length===0&&!Q.prompt)throw Error("generate() was given neither a `prompt` nor `messages`, so there is nothing to send the model.");let Z=[...$];if(Q.prompt)Z.push({id:`msg_${crypto.randomUUID()}`,role:"user",content:[{type:"text",text:Q.prompt}],createdAt:new Date().toISOString()});let J={id:`msg_${crypto.randomUUID()}`,role:"assistant",content:[],createdAt:new Date().toISOString()},W=Q.signal??new AbortController().signal,X=M(),G="stop",V,H={},Y="";try{let U=Q.provider.stream({messages:[...Z],systemPrompt:Q.instructions?.trim()?Q.instructions:void 0,output:BQ(Q.output),reasoning:Q.reasoning,maxOutputTokens:Q.maxOutputTokens,temperature:Q.temperature,signal:Q.signal})[Symbol.asyncIterator]();try{for(;;){let j=await y(Promise.resolve(U.next()),W);if(j.done)break;let D=j.value;switch(D.type){case"output-delta":Y+=D.delta;break;case"text-delta":r(J,"text",D.delta);break;case"reasoning-delta":FQ(J,D.id,D.delta);break;case"finish":if(X=R(X,D.usage),!V)G=D.reason;break;case"error":G="error",V=D.error,H=A(D);break}}}finally{if(W.aborted)Promise.resolve(U.return?.()).catch(()=>{})}}catch(B){if(B instanceof E||W.aborted)G="aborted",V=y3(W);else G="error",V=Q.provider.normalizeError(B),H=A(B)}let K=!1,z;if(!V)if(G==="length")V={code:"invalid_output",message:"The model ran out of output tokens before finishing its structured answer, so it was cut off. Raise maxOutputTokens, or ask for a shorter answer.",retryable:!0};else if(!Y.trim())V={code:"invalid_output",message:"The model finished without giving a structured answer.",retryable:!0};else{let B=DQ(Q.output,Y);if(B.ok===!0)K=!0,z=B.value;else V=B.error}if(K)J.content.push({type:"output",value:z});else if(Y)r(J,"text",Y);for(let B of J.content)if((B.type==="text"||B.type==="reasoning")&&typeof B.text==="string")B.text=UQ(B.text);if(J.finishReason=G,J.usage=X,Z.push(J),K)return{ok:!0,output:z,messages:Z,usage:X,finishReason:G};return{ok:!1,error:{...V,...H},messages:Z,usage:X,finishReason:G}}function y3(Q){return Q.reason?.name==="TimeoutError"?{code:"timeout",message:"The generation timed out.",retryable:!0}:{code:"aborted",message:"The generation was stopped.",retryable:!1}}import{createHmac as g3,hkdfSync as u3,randomBytes as o9,timingSafeEqual as c3}from"crypto";class $Q{spent=new Map;sweepAt=1024;async consume(Q,$){return this.consumeSync(Q,$)}consumeSync(Q,$,Z=Date.now()){if(this.spent.size>=this.sweepAt)this.sweep(Z);let J=this.spent.get(Q);if(J!==void 0&&J>Z)return!1;return this.spent.set(Q,$),!0}get size(){return this.spent.size}sweep(Q){for(let[$,Z]of this.spent)if(Z<=Q)this.spent.delete($);this.sweepAt=Math.max(1024,this.spent.size*2)}}class pQ{injectedClient;prefix;constructor(Q={}){this.injectedClient=Q.client,this.prefix=Q.prefix??"gemi:ai:nonce"}async consume(Q,$){let Z=Math.max(1,Math.ceil($-Date.now()));return await this.client.send("SET",[`${this.prefix}:${Q}`,"1","PX",String(Z),"NX"])==="OK"}get client(){if(this.injectedClient)return this.injectedClient;let Q=jQ(),$=Q.bound(d)?Q.make(d).client:void 0;if(!$)throw Error("RedisNonceStore could not reach the Redis client. Register RedisServiceProvider on your application, or pass a client: new RedisNonceStore({ client }).");return $}}var l=new $Q;var dQ="agt2",CQ="agt1",n9=[dQ,CQ],lQ=86400000,m3=Date.now()+lQ;function s9(Q){return Q<=m3}var t9="gemi.ai.pending-call.v1",a9="gemi.ai.nested-run.v1",p3="gemi.ai.execution-receipt.v1",d3="gemi.ai.signing",LQ=new Map;function ZQ(Q,$){let Z=iQ($),J=`${Q}\x00${Z}`,W=LQ.get(J);if(!W){if(W=Buffer.from(u3("sha256",Z,d3,Q,32)),LQ.size>64)LQ.clear();LQ.set(J,W)}return W}function iQ(Q){let $=Q??process.env.SECRET;if(!$)throw Error("Signing a pending tool call needs an app secret. Set SECRET in the environment.");return $}function I(Q){if(Q===null||typeof Q!=="object")return JSON.stringify(Q)??"null";if(Array.isArray(Q))return`[${Q.map(I).join(",")}]`;let $=Q;return`{${Object.keys($).filter((J)=>$[J]!==void 0).sort().map((J)=>`${JSON.stringify(J)}:${I($[J])}`).join(",")}}`}function l3(Q){return Q.map(($)=>`${$.length}:${$}`).join("")}function g(Q,$){return g3("sha256",Q).update(l3($)).digest()}function r9(Q,$){let Z=Buffer.from(Q.split(".")[4],"base64url");return Z.length===$.length&&c3(Z,$)}function oQ(Q){return I(Q??null)}function e9(Q,$,Z){return[dQ,Q.runId,Q.toolCallId,Q.name,Q.kind,$,String(Z),I(Q.input),I(Q.path??[]),oQ(Q.subject)]}function i3(Q,$,Z){let J=[CQ,Q.runId,Q.toolCallId,Q.name,Q.kind,$,String(Z),I(Q.input)];if(Q.path&&Q.path.length>0)J.push(I(Q.path));return J}var Q$=(Q)=>Buffer.from(Q,"utf8").toString("base64url"),o3=(Q)=>Buffer.from(Q,"base64url").toString("utf8");function $$(Q,$={}){let Z=ZQ(t9,$.secret),W=($.now??Date.now())+($.ttlMs??lQ),X=o9(12).toString("base64url"),G=g(Z,e9(Q,X,W)).toString("base64url");return[dQ,Q$(Q.runId),X,W.toString(36),G].join(".")}function nQ(Q){return OQ(Q,n9)}function OQ(Q,$){let Z=Q.split(".");if(Z.length!==5||!$.includes(Z[0]))return null;let J=Number.parseInt(Z[3],36);if(!Number.isFinite(J))return null;try{return{runId:o3(Z[1]),nonce:Z[2],expiresAt:J,version:Z[0]}}catch{return null}}function Z$(Q,$,Z={}){let J=OQ(Q,n9);if(!J)return{ok:!1,reason:"malformed"};if(J.version===CQ&&!s9(J.expiresAt))return{ok:!1,reason:"forged"};let W=J.version===CQ?g(iQ(Z.secret),i3($,J.nonce,J.expiresAt)):g(ZQ(t9,Z.secret),e9($,J.nonce,J.expiresAt));if(!r9(Q,W))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>J.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:J.runId,nonce:J.nonce,expiresAt:J.expiresAt}}var sQ="agn2",PQ="agn1",J$=[sQ,PQ];function W$(Q,$,Z){return[...X$(Q,$,Z,sQ),oQ(Q.subject)]}function X$(Q,$,Z,J=PQ){return[J,Q.runId,I(Q.path),Q.nestedRunId,$,String(Z),I([...Q.open].sort()),I(Q.input)]}function G$(Q,$={}){let Z=ZQ(a9,$.secret),W=($.now??Date.now())+($.ttlMs??lQ),X=o9(12).toString("base64url"),G=g(Z,W$(Q,X,W)).toString("base64url");return[sQ,Q$(Q.runId),X,W.toString(36),G].join(".")}function V$(Q,$,Z={}){let J=OQ(Q,J$);if(!J)return{ok:!1,reason:"malformed"};if(J.version===PQ&&!s9(J.expiresAt))return{ok:!1,reason:"forged"};let W={...$,runId:J.runId},X=J.version===PQ?g(iQ(Z.secret),X$(W,J.nonce,J.expiresAt)):g(ZQ(a9,Z.secret),W$(W,J.nonce,J.expiresAt));if(!r9(Q,X))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>J.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:J.runId,nonce:J.nonce,expiresAt:J.expiresAt}}function H$(Q,$,Z={}){let J=ZQ(p3,Z.secret);return g(J,[Q,$.runId,$.toolCallId,$.name,$.kind,I($.input),I($.path??[]),oQ($.subject)]).toString("base64url")}function Y$(Q,$){return z$($,nQ(Q))}function K$(Q,$){return z$($,OQ(Q,J$))}async function z$(Q,$){if(!$)return!1;return Q.consume($.nonce,$.expiresAt)}class JQ extends T{id;code="attachment_not_found";constructor(Q){super(`No attachment ${Q}.`);this.id=Q;this.name="AttachmentNotFoundError"}}class i extends T{code="invalid_attachment_scope";constructor(Q){super(Q);this.name="InvalidAttachmentScopeError"}}function tQ(Q){if(!Q||typeof Q.key!=="string"||Q.key.length===0)throw new i("An attachment scope needs a non-empty key. Return `null` from `attachmentScope()` for a request that has no subject \u2014 an empty key is a bucket every caller shares.");return Q}var f="gemi_att_";function aQ(){return`${f}${crypto.randomUUID()}`}class WQ{store;storage;scope;constructor(Q,$,Z){this.store=Q;this.storage=$;this.scope=Z;tQ(Z)}async get(Q){let $=await this.store.find(this.scope,Q);if(!$||$.scopeKey!==this.scope.key)throw new JQ(Q);return $}async read(Q){return await this.readRecord(Q,await this.get(Q))}async readRecord(Q,$){if(!$.objectName)throw new JQ(Q);return await this.storage.read({name:$.objectName})}async file(Q){let $=await this.get(Q),J=(await this.readRecord(Q,$)).body,W=J instanceof Blob?J:J?await new Response(J).blob():new Blob([]);return new File([W],$.name,{type:$.mimeType})}async put(Q,$={}){let Z=aQ(),J=$.mimeType??Q.type??"",W=$.name??(Q instanceof File?Q.name:Z),X=await this.storage.put({name:rQ(Z,W),body:Q,contentType:J||void 0}),G={id:Z,scopeKey:this.scope.key,objectName:X,name:W,mimeType:J||"application/octet-stream",size:Q.size,createdAt:new Date().toISOString(),destination:$.fileId?"both":"storage",...$.fileId?{fileId:$.fileId}:{}};return await this.store.put(this.scope,G),G}}function rQ(Q,$){let Z=/\.([A-Za-z0-9]{1,8})$/.exec($);return`attachments/${Q}${Z?`.${Z[1].toLowerCase()}`:""}`}class qQ{rows=new Map;async put(Q,$){tQ(Q),this.rows.set($.id,{...$,scopeKey:Q.key})}async find(Q,$){tQ(Q);let Z=this.rows.get($);if(!Z||Z.scopeKey!==Q.key)return null;return Z}get size(){return this.rows.size}}var NQ=new qQ;var eQ=new TextEncoder;function B$(Q){return`id: ${Q.seq}
3
3
  data: ${JSON.stringify(Q.event)}
4
4
 
5
- `}var l3=5000,i3=`: keepalive
5
+ `}var n3=5000,s3=`: keepalive
6
6
 
7
- `;function eQ(Q,$=l3){let Z=null,J=!1,W=()=>{if(J)return;if(Z!==null)clearTimeout(Z);Z=setTimeout(()=>{if(Z=null,J)return;try{Q.enqueue(rQ.encode(i3))}catch{X();return}W()},$)},X=()=>{if(J=!0,Z!==null)clearTimeout(Z);Z=null};return W(),{touch:W,stop:X}}function o3(){return{"Content-Type":"text/event-stream","Cache-Control":"no-store, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}}function z$(Q,$=200){let Z=Q[Symbol.asyncIterator](),J=-1,W,X=new ReadableStream({start(G){W=eQ(G)},async pull(G){try{let H=await Z.next();if(H.done){W.stop(),G.close();return}J=H.value.seq,G.enqueue(rQ.encode(K$(H.value))),W.touch()}catch(H){let V={type:"error",error:s3(H)};W.stop(),G.enqueue(rQ.encode(K$({seq:J+1,event:V}))),G.close()}},cancel(G){W.stop(),Z.return?.(G)}});return new Response(X,{status:$,headers:o3()})}var n3=new Set(["frame_cursor_evicted","live_run_not_found"]);function s3(Q){let $=Q&&typeof Q==="object"?Q.code:void 0;if(Q instanceof Error&&typeof $==="string"&&n3.has($))return{code:"unknown",message:Q.message,retryable:!1};return console.error("[gemi/ai] agent stream failed",Q),{code:"unknown",message:"The run's stream failed.",retryable:!1}}class g extends Error{pending;path;nested;constructor(Q){super(`A nested agent run is waiting on the user for ${Q.pending.length} tool call(s).`);this.name="PendingEscalation",this.pending=Q.pending,this.path=Q.path,this.nested=Q.nested}}class u{name;description;inputSchema;outputSchema;requiresApproval;deferred;answeredBy;timeoutMs;execute;constructor(Q){this.name=Q.name,this.description=Q.description,this.inputSchema=Q.inputSchema,this.outputSchema=Q.outputSchema,this.requiresApproval=Q.requiresApproval===!0,this.deferred=Q.deferred===!0,this.answeredBy=Q.answeredBy==="client"?"client":"server",this.execute=Q.execute??void 0,this.timeoutMs=Q.timeoutMs}static create(Q){if(typeof Q.inputSchema!=="function")V9(Q.inputSchema,`The tool "${Q.name}"`,"inputSchema");if(Q.timeoutMs!==void 0)Z9(Q.timeoutMs,`The tool "${Q.name}"`,"timeoutMs");return new u(Q)}static ask(Q){return u.create({name:Q.name,description:Q.description,inputSchema:X9,outputSchema:Q.outputSchema,answeredBy:"client"})}}var X9={toJSONSchema:()=>({type:"object",properties:{question:{type:"string",description:"What to ask the user"}},required:["question"],additionalProperties:!1}),parse(Q){let $=X9.safeParse(Q);if($.ok===!1)throw Error($.errors.join(", "));return $.value},safeParse(Q){if(typeof Q!=="object"||Q===null||typeof Q.question!=="string")return{ok:!1,errors:["question: expected a string"]};return{ok:!0,value:{question:Q.question}}}};class RQ{name;description;tools;deferred;constructor(Q){this.name=Q.name,this.description=Q.description,this.tools=Q.tools,this.deferred=Q.deferred===!0}static create(Q){return new RQ(Q)}}class G9{name;description;instructions;files;constructor(Q){this.name=Q.name,this.description=Q.description,this.instructions=Q.instructions,this.files=Q.files}static create(Q){return new G9(Q)}}var XQ="skills",t3="Instructions this agent can load on demand. Load the relevant one before acting in the area it covers.";function V9(Q,$,Z){let J=Q?.toJSONSchema?.();if(J?.type==="object")return;let W=!J?"no JSON Schema":J.anyOf?"a union (`anyOf`) \u2014 `s.union(...)`":J.type!==void 0?`a schema of type ${JSON.stringify(J.type)}`:"an unconstrained schema (`s.json()`)";throw Error(`${$} declares an \`${Z}\` whose root is ${W}, but the provider only accepts an object there (OpenAI rejects \`anyOf\` or a non-object at the root of tool parameters and structured output). Wrap it in an object, e.g. \`s.object({ value: s.union([...]) })\`, and read \`.value\` off the result.`)}function Z9(Q,$,Z){if(typeof Q==="number"&&Q>0)return;throw Error(`${$} sets \`${Z}\` to ${String(Q)}, but it has to be a positive number of milliseconds. Use \`null\` for no limit.`)}function B$(Q){if(Q===void 0)return;if(Q===null||!Number.isFinite(Q))return null;return Q}var a3=2147483647;function D$(Q,$){if(Q===null||Q>a3)return()=>{};let Z=setTimeout($,Q);return()=>clearTimeout(Z)}function Q9(Q){if(Q<1000)return`${Q}ms`;if(Q<60000)return`${+(Q/1000).toFixed(1)}s`;return`${+(Q/60000).toFixed(1)}m`}var H9={type:"object",properties:{},required:[],additionalProperties:!1},Y9=600000;class QQ extends Error{code;retryable;status;requestId;toolCallId;runId;result;constructor(Q){super(Q.error.message);this.name="AgentRunError",this.code=Q.error.code,this.retryable=Q.error.retryable,this.status=Q.error.status,this.requestId=Q.error.requestId,this.toolCallId=Q.error.toolCallId,this.runId=Q.runId,this.result=Q}}var r3=8,e3=3;class K9{name;tools;skills;provider;output;instructions;maxSteps;maxDepth;reasoning;maxRunDurationMs;config;constructor(Q){this.name=Q.name,this.instructions=Q.instructions,this.provider=Q.provider,this.tools=Q.tools??[],this.skills=Q.skills??[],this.output=Q.output,this.maxSteps=Q.maxSteps??r3,this.maxDepth=Q.maxDepth??e3,this.reasoning=Q.reasoning;let $=B$(Q.maxRunDurationMs);this.maxRunDurationMs=$===void 0?Y9:$;let{registry:Z,providerTools:J}=QZ(this.tools,this.skills);this.config={name:this.name,instructions:this.instructions,provider:this.provider,registry:Z,providerTools:J,output:Q.output,maxSteps:this.maxSteps,maxDepth:this.maxDepth,reasoning:this.reasoning,maxOutputTokens:Q.maxOutputTokens,temperature:Q.temperature,logErrors:Q.logErrors??!0,maxRunDurationMs:$}}static create(Q){if(Q.output)V9(Q.output,`The agent "${Q.name}"`,"output");if(Q.maxRunDurationMs!=null)Z9(Q.maxRunDurationMs,`The agent "${Q.name}"`,"maxRunDurationMs");return new K9(Q)}stream(Q){let $={...this.config,provider:Q.provider??this.config.provider,maxSteps:Q.maxSteps??this.config.maxSteps,reasoning:Q.reasoning??this.config.reasoning,maxOutputTokens:Q.maxOutputTokens??this.config.maxOutputTokens,temperature:Q.temperature??this.config.temperature,maxRunDurationMs:Q.maxRunDurationMs!==void 0?B$(Q.maxRunDurationMs):this.config.maxRunDurationMs};if(Q.maxRunDurationMs!=null)Z9(Q.maxRunDurationMs,`Agent.stream for "${this.name}"`,"maxRunDurationMs");return new M$($,Q)}}function J9(Q){let $=Q.inputSchema;return{name:Q.tool.name,description:Q.tool.description,parameters:$?$.toJSONSchema():H9,strict:$?a($):!0,deferred:Q.deferred}}function $9(Q){return typeof Q.inputSchema==="function"?void 0:Q.inputSchema}function QZ(Q,$){let Z=new Map,J=[],W=(X)=>{if(Z.has(X.tool.name))throw Error(`Two tools are named "${X.tool.name}". Tool names are global within an agent \u2014 the client discriminates a tool part by name alone.`);Z.set(X.tool.name,X)};for(let X of Q){if(X instanceof RQ){if(X.name===XQ)throw Error(`"${XQ}" is reserved for the namespace skills are lowered into. Rename the namespace \u2014 silently shadowing it would make every skill unreachable with no error to read.`);let H=[];for(let V of X.tools){let Y={tool:V,namespace:X.name,deferred:X.deferred||V.deferred,inputSchema:$9(V)};W(Y),H.push(J9(Y))}J.push({name:X.name,description:X.description,tools:H});continue}let G={tool:X,deferred:X.deferred,inputSchema:$9(X)};W(G),J.push(J9(G))}if($.length>0){let X=[];for(let G of $){let H=$Z(G);W({tool:H,namespace:XQ,deferred:!1,inputSchema:$9(H)}),X.push({name:G.name,description:G.description,parameters:H9,strict:!0,deferred:!1})}J.push({name:XQ,description:t3,tools:X})}return{registry:Z,providerTools:J}}function $Z(Q){return u.create({name:Q.name,description:Q.description,inputSchema:{toJSONSchema:()=>H9,parse:()=>({}),safeParse:()=>({ok:!0,value:{}})},execute:async()=>{let Z=[typeof Q.instructions==="function"?await Q.instructions():Q.instructions];for(let J of Q.files??[])Z.push(`--- ${J} ---
8
- ${await ZZ(J)}`);return Z.join(`
7
+ `;function Q9(Q,$=n3){let Z=null,J=!1,W=()=>{if(J)return;if(Z!==null)clearTimeout(Z);Z=setTimeout(()=>{if(Z=null,J)return;try{Q.enqueue(eQ.encode(s3))}catch{X();return}W()},$)},X=()=>{if(J=!0,Z!==null)clearTimeout(Z);Z=null};return W(),{touch:W,stop:X}}function t3(){return{"Content-Type":"text/event-stream","Cache-Control":"no-store, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}}function D$(Q,$=200){let Z=Q[Symbol.asyncIterator](),J=-1,W,X=new ReadableStream({start(G){W=Q9(G)},async pull(G){try{let V=await Z.next();if(V.done){W.stop(),G.close();return}J=V.value.seq,G.enqueue(eQ.encode(B$(V.value))),W.touch()}catch(V){let H={type:"error",error:r3(V)};W.stop(),G.enqueue(eQ.encode(B$({seq:J+1,event:H}))),G.close()}},cancel(G){W.stop(),Z.return?.(G)}});return new Response(X,{status:$,headers:t3()})}var a3=new Set(["frame_cursor_evicted","live_run_not_found"]);function r3(Q){let $=Q&&typeof Q==="object"?Q.code:void 0;if(Q instanceof Error&&typeof $==="string"&&a3.has($))return{code:"unknown",message:Q.message,retryable:!1};return console.error("[gemi/ai] agent stream failed",Q),{code:"unknown",message:"The run's stream failed.",retryable:!1}}class u extends Error{pending;path;nested;constructor(Q){super(`A nested agent run is waiting on the user for ${Q.pending.length} tool call(s).`);this.name="PendingEscalation",this.pending=Q.pending,this.path=Q.path,this.nested=Q.nested}}class c{name;description;inputSchema;outputSchema;requiresApproval;deferred;answeredBy;timeoutMs;execute;constructor(Q){this.name=Q.name,this.description=Q.description,this.inputSchema=Q.inputSchema,this.outputSchema=Q.outputSchema,this.requiresApproval=Q.requiresApproval===!0,this.deferred=Q.deferred===!0,this.answeredBy=Q.answeredBy==="client"?"client":"server",this.execute=Q.execute??void 0,this.timeoutMs=Q.timeoutMs}static create(Q){if(typeof Q.inputSchema!=="function")H9(Q.inputSchema,`The tool "${Q.name}"`,"inputSchema");if(Q.timeoutMs!==void 0)J9(Q.timeoutMs,`The tool "${Q.name}"`,"timeoutMs");return new c(Q)}static ask(Q){return c.create({name:Q.name,description:Q.description,inputSchema:G9,outputSchema:Q.outputSchema,answeredBy:"client"})}}var G9={toJSONSchema:()=>({type:"object",properties:{question:{type:"string",description:"What to ask the user"}},required:["question"],additionalProperties:!1}),parse(Q){let $=G9.safeParse(Q);if($.ok===!1)throw Error($.errors.join(", "));return $.value},safeParse(Q){if(typeof Q!=="object"||Q===null||typeof Q.question!=="string")return{ok:!1,errors:["question: expected a string"]};return{ok:!0,value:{question:Q.question}}}};class RQ{name;description;tools;deferred;constructor(Q){this.name=Q.name,this.description=Q.description,this.tools=Q.tools,this.deferred=Q.deferred===!0}static create(Q){return new RQ(Q)}}class V9{name;description;instructions;files;constructor(Q){this.name=Q.name,this.description=Q.description,this.instructions=Q.instructions,this.files=Q.files}static create(Q){return new V9(Q)}}var XQ="skills",e3="Instructions this agent can load on demand. Load the relevant one before acting in the area it covers.";function H9(Q,$,Z){let J=Q?.toJSONSchema?.();if(J?.type==="object")return;let W=!J?"no JSON Schema":J.anyOf?"a union (`anyOf`) \u2014 `s.union(...)`":J.type!==void 0?`a schema of type ${JSON.stringify(J.type)}`:"an unconstrained schema (`s.json()`)";throw Error(`${$} declares an \`${Z}\` whose root is ${W}, but the provider only accepts an object there (OpenAI rejects \`anyOf\` or a non-object at the root of tool parameters and structured output). Wrap it in an object, e.g. \`s.object({ value: s.union([...]) })\`, and read \`.value\` off the result.`)}function J9(Q,$,Z){if(typeof Q==="number"&&Q>0)return;throw Error(`${$} sets \`${Z}\` to ${String(Q)}, but it has to be a positive number of milliseconds. Use \`null\` for no limit.`)}function U$(Q){if(Q===void 0)return;if(Q===null||!Number.isFinite(Q))return null;return Q}var QZ=2147483647;function F$(Q,$){if(Q===null||Q>QZ)return()=>{};let Z=setTimeout($,Q);return()=>clearTimeout(Z)}function $9(Q){if(Q<1000)return`${Q}ms`;if(Q<60000)return`${+(Q/1000).toFixed(1)}s`;return`${+(Q/60000).toFixed(1)}m`}var Y9={type:"object",properties:{},required:[],additionalProperties:!1},K9=600000;class QQ extends Error{code;retryable;status;requestId;toolCallId;runId;result;constructor(Q){super(Q.error.message);this.name="AgentRunError",this.code=Q.error.code,this.retryable=Q.error.retryable,this.status=Q.error.status,this.requestId=Q.error.requestId,this.toolCallId=Q.error.toolCallId,this.runId=Q.runId,this.result=Q}}var $Z=8,ZZ=3;class z9{name;tools;skills;provider;output;instructions;maxSteps;maxDepth;reasoning;maxRunDurationMs;config;constructor(Q){this.name=Q.name,this.instructions=Q.instructions,this.provider=Q.provider,this.tools=Q.tools??[],this.skills=Q.skills??[],this.output=Q.output,this.maxSteps=Q.maxSteps??$Z,this.maxDepth=Q.maxDepth??ZZ,this.reasoning=Q.reasoning;let $=U$(Q.maxRunDurationMs);this.maxRunDurationMs=$===void 0?K9:$;let{registry:Z,providerTools:J}=JZ(this.tools,this.skills);this.config={name:this.name,instructions:this.instructions,provider:this.provider,registry:Z,providerTools:J,output:Q.output,maxSteps:this.maxSteps,maxDepth:this.maxDepth,reasoning:this.reasoning,maxOutputTokens:Q.maxOutputTokens,temperature:Q.temperature,logErrors:Q.logErrors??!0,maxRunDurationMs:$}}static create(Q){if(Q.output)H9(Q.output,`The agent "${Q.name}"`,"output");if(Q.maxRunDurationMs!=null)J9(Q.maxRunDurationMs,`The agent "${Q.name}"`,"maxRunDurationMs");return new z9(Q)}stream(Q){let $={...this.config,provider:Q.provider??this.config.provider,maxSteps:Q.maxSteps??this.config.maxSteps,reasoning:Q.reasoning??this.config.reasoning,maxOutputTokens:Q.maxOutputTokens??this.config.maxOutputTokens,temperature:Q.temperature??this.config.temperature,maxRunDurationMs:Q.maxRunDurationMs!==void 0?U$(Q.maxRunDurationMs):this.config.maxRunDurationMs};if(Q.maxRunDurationMs!=null)J9(Q.maxRunDurationMs,`Agent.stream for "${this.name}"`,"maxRunDurationMs");return new R$($,Q)}}function W9(Q){let $=Q.inputSchema;return{name:Q.tool.name,description:Q.tool.description,parameters:$?$.toJSONSchema():Y9,strict:$?a($):!0,deferred:Q.deferred}}function Z9(Q){return typeof Q.inputSchema==="function"?void 0:Q.inputSchema}function JZ(Q,$){let Z=new Map,J=[],W=(X)=>{if(Z.has(X.tool.name))throw Error(`Two tools are named "${X.tool.name}". Tool names are global within an agent \u2014 the client discriminates a tool part by name alone.`);Z.set(X.tool.name,X)};for(let X of Q){if(X instanceof RQ){if(X.name===XQ)throw Error(`"${XQ}" is reserved for the namespace skills are lowered into. Rename the namespace \u2014 silently shadowing it would make every skill unreachable with no error to read.`);let V=[];for(let H of X.tools){let Y={tool:H,namespace:X.name,deferred:X.deferred||H.deferred,inputSchema:Z9(H)};W(Y),V.push(W9(Y))}J.push({name:X.name,description:X.description,tools:V});continue}let G={tool:X,deferred:X.deferred,inputSchema:Z9(X)};W(G),J.push(W9(G))}if($.length>0){let X=[];for(let G of $){let V=WZ(G);W({tool:V,namespace:XQ,deferred:!1,inputSchema:Z9(V)}),X.push({name:G.name,description:G.description,parameters:Y9,strict:!0,deferred:!1})}J.push({name:XQ,description:e3,tools:X})}return{registry:Z,providerTools:J}}function WZ(Q){return c.create({name:Q.name,description:Q.description,inputSchema:{toJSONSchema:()=>Y9,parse:()=>({}),safeParse:()=>({ok:!0,value:{}})},execute:async()=>{let Z=[typeof Q.instructions==="function"?await Q.instructions():Q.instructions];for(let J of Q.files??[])Z.push(`--- ${J} ---
8
+ ${await XZ(J)}`);return Z.join(`
9
9
 
10
- `)}})}async function ZZ(Q){try{return await Bun.file(Q).text()}catch($){return`(could not be read: ${$.message})`}}function JZ(Q){return typeof Q==="object"&&Q!==null&&typeof Q.next==="function"&&Symbol.asyncIterator in Q}function U$(Q,$){let Z=[...Q],J=new Map(Z.map((W,X)=>[W.id,X]));for(let W of $){let X=J.get(W.id);if(X===void 0)J.set(W.id,Z.length),Z.push(W);else Z[X]=W}return Z}function NQ(Q){let $=new Set;for(let J of Q)for(let W of J.content)if(W.type==="tool-result")$.add(W.toolCallId);let Z=new Set;for(let J of Q)for(let W of J.content)if(W.type==="tool-call"&&!$.has(W.toolCallId))Z.add(W.toolCallId);return Z}function F$(Q){for(let $=Q.length-1;$>=0;$--){let Z=Q[$].content;for(let J=Z.length-1;J>=0;J--){let W=Z[J];if(W.type==="output"&&W.partial!==!0)return W.value}}return}function L$(Q,$){return $===void 0?`"${Q}"`:`"${Q}" labelled "${$}"`}function N$(Q){return Q.content.map(($)=>$.type==="text"?$.text:`<${$.type}>`).join("")}function WZ(Q){if(Q.prompt!==void 0)return`user:${Q.prompt}`;let $=Q.messages?.[0];return $?`${$.role}:${N$($)}`:null}function MQ(Q){let $=new Set;for(let Z of Q)for(let J of Z.content){if(J.type!=="tool-call")continue;for(let W of J.attachments??[])if("shown"in W&&W.shown)$.add(W.shown.messageId)}return $}var C$=1;function XZ(Q,$,Z){let J=Z.mimeType||$.type||"";if(J&&Q.attachment.mimeType!==J)return`was ${JSON.stringify(Q.attachment.mimeType)} on the turn that escalated and is ${JSON.stringify(J)} on the replay`;let W=Boolean(Z.showModel);if(W!==Boolean(Q.shown))return W?"was stored without showModel on the turn that escalated and asks for showModel on the replay":"was stored with showModel on the turn that escalated and asks for a plain put on the replay";return null}function GZ(Q,$,Z){if(Q.agent!==$.name||Q.label!==Z.label)return`was ${L$(Q.agent,Q.label)} on the turn that escalated and is ${L$($.name,Z.label)} on the replay`;let J=WZ(Z),W=Q.messages[0],X=W?`${W.role}:${N$(W)}`:null;if(J!==null&&X!==null&&J!==X)return`was started with ${JSON.stringify(X)} on the turn that escalated and with ${JSON.stringify(J)} on the replay`;return null}function j$(Q,$){let Z=Q??[];if(Z.length<$.length)return null;for(let J=0;J<$.length;J++)if(Z[J]!==$[J])return null;return Z.slice($.length)}class W9{read;create;fill;index=0;replayable;constructor(Q,$,Z){this.read=Q;this.create=$;this.fill=Z;this.replayable=Q()?.length??0}next(){let Q=this.index++;return{at:Q,recorded:Q<this.replayable?this.read()?.[Q]:void 0,write:($)=>{let Z=this.read()??this.create();if(this.fill)for(let J=Z.length;J<Q;J++)Z[J]=this.fill();Z[Q]=$}}}}class M${runId;config;params;context;controller=new AbortController;buffer=[];waiters=new Set;seq=0;ended=!1;history=[];produced=[];current=null;outputTruncated=!1;amended=new Map;unreported=new Set;usage=N();finishReason="stop";failure;output;stopReason;timedOutAfter;cancelDeadline=()=>{};settled;depth;maxDepth;chain;signingRunId;pathPrefix;onPending;nestedSettling=new Set;shownQueue=new Map;constructor(Q,$){this.config=Q,this.params=$,this.context=$.context??{},this.runId=$.runId??`run_${crypto.randomUUID()}`,this.history=[...$.messages];let Z=$.nesting;if(this.depth=Z?.depth??0,this.maxDepth=Z?.maxDepth??Q.maxDepth,this.chain=Z?.chain??[Q.name],this.signingRunId=Z?.signingRunId??this.runId,this.pathPrefix=Z?.signingPath??[],this.onPending=Z?.onPending??"escalate",$.signal)if($.signal.aborted)this.controller.abort();else $.signal.addEventListener("abort",()=>this.stop(),{once:!0});let J=Q.maxRunDurationMs!==void 0?Q.maxRunDurationMs:Z?null:Y9;this.cancelDeadline=D$(J,()=>this.expire(J)),this.settled=this.execute(),SQ.getStore()?.waitUntil(this.settled)}emit(Q){if(this.ended)return;this.buffer.push({seq:++this.seq,event:Q}),this.wake()}wake(){let Q=[...this.waiters];this.waiters.clear();for(let $ of Q)$()}nextFrame(){return new Promise((Q)=>this.waiters.add(Q))}async*frames(Q=0){let $=Q>0?Q-1:0;for(;;){while($<this.buffer.length)yield this.buffer[$++];if(this.ended)return;await this.nextFrame()}}async*[Symbol.asyncIterator](){for await(let Q of this.frames())yield Q.event}toResponse(Q){let $=this.frames(Q?.from),Z=new TextEncoder,J=!1,W,X=new ReadableStream({start:async(G)=>{W=eQ(G);try{for await(let H of $){if(J)break;G.enqueue(Z.encode(`id: ${H.seq}
11
- data: ${JSON.stringify(H.event)}
10
+ `)}})}async function XZ(Q){try{return await Bun.file(Q).text()}catch($){return`(could not be read: ${$.message})`}}function GZ(Q){return typeof Q==="object"&&Q!==null&&typeof Q.next==="function"&&Symbol.asyncIterator in Q}function j$(Q,$){let Z=[...Q],J=new Map(Z.map((W,X)=>[W.id,X]));for(let W of $){let X=J.get(W.id);if(X===void 0)J.set(W.id,Z.length),Z.push(W);else Z[X]=W}return Z}function _Q(Q){let $=new Set;for(let J of Q)for(let W of J.content)if(W.type==="tool-result")$.add(W.toolCallId);let Z=new Set;for(let J of Q)for(let W of J.content)if(W.type==="tool-call"&&!$.has(W.toolCallId))Z.add(W.toolCallId);return Z}function L$(Q){for(let $=Q.length-1;$>=0;$--){let Z=Q[$].content;for(let J=Z.length-1;J>=0;J--){let W=Z[J];if(W.type==="output"&&W.partial!==!0)return W.value}}return}function C$(Q,$){return $===void 0?`"${Q}"`:`"${Q}" labelled "${$}"`}function S$(Q){return Q.content.map(($)=>$.type==="text"?$.text:`<${$.type}>`).join("")}function VZ(Q){if(Q.prompt!==void 0)return`user:${Q.prompt}`;let $=Q.messages?.[0];return $?`${$.role}:${S$($)}`:null}function MQ(Q){let $=new Set;for(let Z of Q)for(let J of Z.content){if(J.type!=="tool-call")continue;for(let W of J.attachments??[])if("shown"in W&&W.shown)$.add(W.shown.messageId)}return $}var P$=1;function HZ(Q,$,Z){let J=Z.mimeType||$.type||"";if(J&&Q.attachment.mimeType!==J)return`was ${JSON.stringify(Q.attachment.mimeType)} on the turn that escalated and is ${JSON.stringify(J)} on the replay`;let W=Boolean(Z.showModel);if(W!==Boolean(Q.shown))return W?"was stored without showModel on the turn that escalated and asks for showModel on the replay":"was stored with showModel on the turn that escalated and asks for a plain put on the replay";return null}function YZ(Q,$,Z){if(Q.agent!==$.name||Q.label!==Z.label)return`was ${C$(Q.agent,Q.label)} on the turn that escalated and is ${C$($.name,Z.label)} on the replay`;let J=VZ(Z),W=Q.messages[0],X=W?`${W.role}:${S$(W)}`:null;if(J!==null&&X!==null&&J!==X)return`was started with ${JSON.stringify(X)} on the turn that escalated and with ${JSON.stringify(J)} on the replay`;return null}function O$(Q,$){let Z=Q??[];if(Z.length<$.length)return null;for(let J=0;J<$.length;J++)if(Z[J]!==$[J])return null;return Z.slice($.length)}class X9{read;create;fill;index=0;replayable;constructor(Q,$,Z){this.read=Q;this.create=$;this.fill=Z;this.replayable=Q()?.length??0}next(){let Q=this.index++;return{at:Q,recorded:Q<this.replayable?this.read()?.[Q]:void 0,write:($)=>{let Z=this.read()??this.create();if(this.fill)for(let J=Z.length;J<Q;J++)Z[J]=this.fill();Z[Q]=$}}}}class R${runId;config;params;context;controller=new AbortController;buffer=[];waiters=new Set;seq=0;ended=!1;history=[];produced=[];current=null;outputTruncated=!1;amended=new Map;unreported=new Set;usage=M();finishReason="stop";failure;output;stopReason;timedOutAfter;cancelDeadline=()=>{};settled;depth;maxDepth;chain;signingRunId;pathPrefix;onPending;nestedSettling=new Set;shownQueue=new Map;constructor(Q,$){this.config=Q,this.params=$,this.context=$.context??{},this.runId=$.runId??`run_${crypto.randomUUID()}`,this.history=[...$.messages];let Z=$.nesting;if(this.depth=Z?.depth??0,this.maxDepth=Z?.maxDepth??Q.maxDepth,this.chain=Z?.chain??[Q.name],this.signingRunId=Z?.signingRunId??this.runId,this.pathPrefix=Z?.signingPath??[],this.onPending=Z?.onPending??"escalate",$.signal)if($.signal.aborted)this.controller.abort();else $.signal.addEventListener("abort",()=>this.stop(),{once:!0});let J=Q.maxRunDurationMs!==void 0?Q.maxRunDurationMs:Z?null:K9;this.cancelDeadline=F$(J,()=>this.expire(J)),this.settled=this.execute(),SQ.getStore()?.waitUntil(this.settled)}emit(Q){if(this.ended)return;this.buffer.push({seq:++this.seq,event:Q}),this.wake()}wake(){let Q=[...this.waiters];this.waiters.clear();for(let $ of Q)$()}nextFrame(){return new Promise((Q)=>this.waiters.add(Q))}async*frames(Q=0){let $=Q>0?Q-1:0;for(;;){while($<this.buffer.length)yield this.buffer[$++];if(this.ended)return;await this.nextFrame()}}async*[Symbol.asyncIterator](){for await(let Q of this.frames())yield Q.event}toResponse(Q){let $=this.frames(Q?.from),Z=new TextEncoder,J=!1,W,X=new ReadableStream({start:async(G)=>{W=Q9(G);try{for await(let V of $){if(J)break;G.enqueue(Z.encode(`id: ${V.seq}
11
+ data: ${JSON.stringify(V.event)}
12
12
 
13
- `)),W.touch()}}catch{}W.stop();try{G.close()}catch{}},cancel:()=>{J=!0,W.stop()}});return new Response(X,{headers:{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}})}result(Q){if(!Q?.throwOnError)return this.settled;return this.settled.then(($)=>{if($.error)throw new QQ({...$,error:$.error});return $})}stop(Q){if(this.ended||this.controller.signal.aborted)return;this.stopReason=Q?.reason,this.controller.abort()}expire(Q){if(this.ended||this.controller.signal.aborted)return;this.timedOutAfter=Q,this.stopReason=`The run reached its time limit of ${Q9(Q)} and was stopped.`,this.controller.abort(new DOMException(this.stopReason,"TimeoutError"))}async execute(){this.emit({type:"run-start",runId:this.runId,threadId:this.params.threadId});try{let $=await this.resolveToolSchemas(),Z=$?[]:await this.ingestTurn();if($)this.fail($),this.finishReason="error";else if(Z.length>0)this.finishReason="awaiting-input",this.emit({type:"awaiting-input",runId:this.runId,pending:Z});else await this.loop()}catch($){if($ instanceof A||this.controller.signal.aborted)await this.finalizeAborted();else this.fail(this.config.provider.normalizeError($),T($)),await this.finalizeMessage("error"),this.finishReason="error"}this.cancelDeadline(),this.emit({type:"usage",usage:this.usage}),this.emit({type:"run-end",runId:this.runId,finishReason:this.finishReason}),this.ended=!0,this.wake();let Q=this.finishReason==="error"?this.failure:void 0;if(Q&&this.config.logErrors)this.logFailure(Q);return{runId:this.runId,messages:this.produced,finishReason:this.finishReason,usage:this.usage,output:this.output,...Q?{error:Q}:{}}}async resolveToolSchemas(){let Q=[...this.config.registry.values()].filter((V)=>!V.inputSchema);if(Q.length===0)return;let $={context:this.context,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,signal:this.controller.signal},Z=new Map,J=await Promise.all(Q.map(async(V)=>{try{let Y=V.tool.inputSchema,K=await Y($);V9(K,`The tool "${V.tool.name}"`,"inputSchema"),Z.set(V.tool.name,K);return}catch(Y){return`"${V.tool.name}": ${Y instanceof Error?Y.message:String(Y)}`}}));if(this.controller.signal.aborted)throw new A;let W=J.filter((V)=>V!==void 0);if(W.length>0)return{code:"tool_error",message:`Could not resolve the input schema of ${W.join("; ")}`,retryable:!1};let X=new Map;for(let[V,Y]of this.config.registry)X.set(V,Z.has(V)?{...Y,inputSchema:Z.get(V)}:Y);let G=(V)=>Z.has(V.name)?J9(X.get(V.name)):V,H=this.config.providerTools.map((V)=>("tools"in V)?{...V,tools:V.tools.map(G)}:G(V));this.config={...this.config,registry:X,providerTools:H};return}fail(Q,$={}){let Z={...Q,...$};this.failure=Z,this.emit({type:"error",error:this.redact(Z,{source:"run",failure:Z})})}redact(Q,$){let Z=q$(this.params.redactError,Q,$,(J)=>this.writeLog(`[gemi/ai] agent "${this.config.name}" redactError threw`,{error:J}));return _$(Z,Q),Z}logFailure(Q){let $=`[gemi/ai] agent "${this.config.name}" run failed (${Q.code}${Q.status!==void 0?` ${Q.status}`:""}): ${Q.message}`;this.writeLog($,{error:Q})}logToolFailure(Q,$){let Z=$ instanceof Error?$.message:String($);this.writeLog(`[gemi/ai] agent "${this.config.name}" tool "${String(Q.name)}" threw: ${Z}`,{toolCallId:Q.toolCallId,error:$})}writeLog(Q,$){let Z={agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},...this.depth>0?{chain:this.chain}:{},...$},J=!1;try{e.error(Q,Z),J=!0}catch{}if(!J||Bun.env.NODE_ENV==="development")console.error(Q,Z)}async loop(){let Q=Math.max(1,this.config.maxSteps);for(let $=1;$<=Q;$++){let Z=this.startMessage(),J=await this.runStep(Z);if(J.error){this.fail(J.error,J.detail),await this.finalizeMessage("error"),this.finishReason="error";return}let W=Z.content.filter((G)=>G.type==="tool-call");if(W.length===0){this.finishReason=J.reason,await this.finalizeMessage(J.reason);return}let X=await this.runTools(Z,W,$);if(X.length>0){this.finishReason="awaiting-input",await this.finalizeMessage("awaiting-input"),this.emit({type:"awaiting-input",runId:this.runId,pending:X});return}if($===Q){this.finishReason="max-steps",await this.finalizeMessage("max-steps");return}await this.finalizeMessage(J.reason)}}startMessage(){let Q={id:`msg_${crypto.randomUUID()}`,role:"assistant",content:[],createdAt:new Date().toISOString()};return this.current=Q,this.history.push(Q),this.produced.push(Q),this.emit({type:"message-start",messageId:Q.id,role:"assistant"}),Q}async finalizeMessage(Q){let $=this.current;if(!$)return;this.current=null;let Z=this.outputTruncated;if(this.outputTruncated=!1,$.finishReason=Q,Z)$.outputTruncated=!0;for(let J of $.content)if(J.type==="text"||J.type==="reasoning"){if(typeof J.text==="string")J.text=UQ(J.text)}this.emit({type:"message-end",messageId:$.id,finishReason:Q,...Z?{outputTruncated:!0}:{},...$.usage?{usage:$.usage}:{}}),await this.report($),await this.reportDeferred()}async report(Q){if(!this.params.onMessage)return;try{await this.params.onMessage(Q)}catch{}}async runStep(Q){let $=this.controller.signal,Z=this.config.provider,J={reason:"stop"},W=new Map,X="",H=Z.stream({messages:this.historyForProvider(Q),systemPrompt:await this.systemPrompt(),tools:this.config.providerTools.length>0?this.config.providerTools:void 0,output:this.config.output?BQ(this.config.output):void 0,reasoning:this.config.reasoning,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature,signal:$})[Symbol.asyncIterator]();for(;;){let Y=await h(Promise.resolve(H.next()),$);if(Y.done)break;let K=Y.value;switch(K.type){case"text-delta":{r(Q,"text",K.delta),this.emit({type:"text-delta",messageId:Q.id,delta:K.delta});break}case"reasoning-delta":{FQ(Q,K.id,K.delta),this.emit({type:"reasoning-delta",messageId:Q.id,delta:K.delta,id:K.id});break}case"output-delta":{X+=K.delta,this.emit({type:"output-delta",messageId:Q.id,delta:K.delta,snapshot:zQ(X)});break}case"tool-search":{this.emit({type:"tool-search",loaded:K.loaded});break}case"tool-call-delta":{let z=W.get(K.toolCallId)??{name:K.name,args:""};z.args+=K.argsDelta,z.name=K.name||z.name,W.set(K.toolCallId,z),this.emit({type:"tool-call",messageId:Q.id,part:{type:"tool-call",toolCallId:K.toolCallId,name:z.name,input:zQ(z.args),partial:!0}});break}case"tool-call":{W.delete(K.toolCallId);let z={type:"tool-call",toolCallId:K.toolCallId,name:K.name,input:P$(K.args)};Q.content.push(z),this.emit({type:"tool-call",messageId:Q.id,part:z});break}case"finish":{if(this.usage=S(this.usage,K.usage),Q.usage=S(Q.usage??N(),K.usage),!J.error)J={reason:K.reason};break}case"error":{J={reason:"error",error:K.error,detail:T(K)};break}case"file-rejected":{this.markFileRejected(K.fileId,K.message,T(K));break}}}for(let[Y,K]of W){let z={type:"tool-call",toolCallId:Y,name:K.name,input:P$(K.args)};Q.content.push(z),this.emit({type:"tool-call",messageId:Q.id,part:z})}let V=J.reason==="length";if(V)this.outputTruncated=!0;if(this.config.output&&X&&!J.error&&!V){let Y=DQ(this.config.output,X);if(Y.ok===!0)this.output=Y.value,Q.content.push({type:"output",value:Y.value});else this.emit({type:"error",error:Y.error})}return J}async systemPrompt(){let Q=[this.config.instructions,this.params.instructions].filter(($)=>Boolean($&&$.trim()));return Q.length>0?Q.join(`
13
+ `)),W.touch()}}catch{}W.stop();try{G.close()}catch{}},cancel:()=>{J=!0,W.stop()}});return new Response(X,{headers:{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}})}result(Q){if(!Q?.throwOnError)return this.settled;return this.settled.then(($)=>{if($.error)throw new QQ({...$,error:$.error});return $})}stop(Q){if(this.ended||this.controller.signal.aborted)return;this.stopReason=Q?.reason,this.controller.abort()}expire(Q){if(this.ended||this.controller.signal.aborted)return;this.timedOutAfter=Q,this.stopReason=`The run reached its time limit of ${$9(Q)} and was stopped.`,this.controller.abort(new DOMException(this.stopReason,"TimeoutError"))}async execute(){this.emit({type:"run-start",runId:this.runId,threadId:this.params.threadId});try{let $=await this.resolveToolSchemas(),Z=$?[]:await this.ingestTurn();if($)this.fail($),this.finishReason="error";else if(Z.length>0)this.finishReason="awaiting-input",this.emit({type:"awaiting-input",runId:this.runId,pending:Z});else await this.loop()}catch($){if($ instanceof E||this.controller.signal.aborted)await this.finalizeAborted();else this.fail(this.config.provider.normalizeError($),A($)),await this.finalizeMessage("error"),this.finishReason="error"}this.cancelDeadline(),this.emit({type:"usage",usage:this.usage}),this.emit({type:"run-end",runId:this.runId,finishReason:this.finishReason}),this.ended=!0,this.wake();let Q=this.finishReason==="error"?this.failure:void 0;if(Q&&this.config.logErrors)this.logFailure(Q);return{runId:this.runId,messages:this.produced,finishReason:this.finishReason,usage:this.usage,output:this.output,...Q?{error:Q}:{}}}async resolveToolSchemas(){let Q=[...this.config.registry.values()].filter((H)=>!H.inputSchema);if(Q.length===0)return;let $={context:this.context,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,signal:this.controller.signal},Z=new Map,J=await Promise.all(Q.map(async(H)=>{try{let Y=H.tool.inputSchema,K=await Y($);H9(K,`The tool "${H.tool.name}"`,"inputSchema"),Z.set(H.tool.name,K);return}catch(Y){return`"${H.tool.name}": ${Y instanceof Error?Y.message:String(Y)}`}}));if(this.controller.signal.aborted)throw new E;let W=J.filter((H)=>H!==void 0);if(W.length>0)return{code:"tool_error",message:`Could not resolve the input schema of ${W.join("; ")}`,retryable:!1};let X=new Map;for(let[H,Y]of this.config.registry)X.set(H,Z.has(H)?{...Y,inputSchema:Z.get(H)}:Y);let G=(H)=>Z.has(H.name)?W9(X.get(H.name)):H,V=this.config.providerTools.map((H)=>("tools"in H)?{...H,tools:H.tools.map(G)}:G(H));this.config={...this.config,registry:X,providerTools:V};return}fail(Q,$={}){let Z={...Q,...$};this.failure=Z,this.emit({type:"error",error:this.redact(Z,{source:"run",failure:Z})})}redact(Q,$){let Z=_$(this.params.redactError,Q,$,(J)=>this.writeLog(`[gemi/ai] agent "${this.config.name}" redactError threw`,{error:J}));return M$(Z,Q),Z}logFailure(Q){let $=`[gemi/ai] agent "${this.config.name}" run failed (${Q.code}${Q.status!==void 0?` ${Q.status}`:""}): ${Q.message}`;this.writeLog($,{error:Q})}logToolFailure(Q,$){let Z=$ instanceof Error?$.message:String($);this.writeLog(`[gemi/ai] agent "${this.config.name}" tool "${String(Q.name)}" threw: ${Z}`,{toolCallId:Q.toolCallId,error:$})}writeLog(Q,$){let Z={agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},...this.depth>0?{chain:this.chain}:{},...$},J=!1;try{e.error(Q,Z),J=!0}catch{}if(!J||Bun.env.NODE_ENV==="development")console.error(Q,Z)}async loop(){let Q=Math.max(1,this.config.maxSteps);for(let $=1;$<=Q;$++){let Z=this.startMessage(),J=await this.runStep(Z);if(J.error){this.fail(J.error,J.detail),await this.finalizeMessage("error"),this.finishReason="error";return}let W=Z.content.filter((G)=>G.type==="tool-call");if(W.length===0){this.finishReason=J.reason,await this.finalizeMessage(J.reason);return}let X=await this.runTools(Z,W,$);if(X.length>0){this.finishReason="awaiting-input",await this.finalizeMessage("awaiting-input"),this.emit({type:"awaiting-input",runId:this.runId,pending:X});return}if($===Q){this.finishReason="max-steps",await this.finalizeMessage("max-steps");return}await this.finalizeMessage(J.reason)}}startMessage(){let Q={id:`msg_${crypto.randomUUID()}`,role:"assistant",content:[],createdAt:new Date().toISOString()};return this.current=Q,this.history.push(Q),this.produced.push(Q),this.emit({type:"message-start",messageId:Q.id,role:"assistant"}),Q}async finalizeMessage(Q){let $=this.current;if(!$)return;this.current=null;let Z=this.outputTruncated;if(this.outputTruncated=!1,$.finishReason=Q,Z)$.outputTruncated=!0;for(let J of $.content)if(J.type==="text"||J.type==="reasoning"){if(typeof J.text==="string")J.text=UQ(J.text)}this.emit({type:"message-end",messageId:$.id,finishReason:Q,...Z?{outputTruncated:!0}:{},...$.usage?{usage:$.usage}:{}}),await this.report($),await this.reportDeferred()}async report(Q){if(!this.params.onMessage)return;try{await this.params.onMessage(Q)}catch{}}async runStep(Q){let $=this.controller.signal,Z=this.config.provider,J={reason:"stop"},W=new Map,X="",V=Z.stream({messages:this.historyForProvider(Q),systemPrompt:await this.systemPrompt(),tools:this.config.providerTools.length>0?this.config.providerTools:void 0,output:this.config.output?BQ(this.config.output):void 0,reasoning:this.config.reasoning,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature,signal:$})[Symbol.asyncIterator]();for(;;){let Y=await y(Promise.resolve(V.next()),$);if(Y.done)break;let K=Y.value;switch(K.type){case"text-delta":{r(Q,"text",K.delta),this.emit({type:"text-delta",messageId:Q.id,delta:K.delta});break}case"reasoning-delta":{FQ(Q,K.id,K.delta),this.emit({type:"reasoning-delta",messageId:Q.id,delta:K.delta,id:K.id});break}case"output-delta":{X+=K.delta,this.emit({type:"output-delta",messageId:Q.id,delta:K.delta,snapshot:zQ(X)});break}case"tool-search":{this.emit({type:"tool-search",loaded:K.loaded});break}case"tool-call-delta":{let z=W.get(K.toolCallId)??{name:K.name,args:""};z.args+=K.argsDelta,z.name=K.name||z.name,W.set(K.toolCallId,z),this.emit({type:"tool-call",messageId:Q.id,part:{type:"tool-call",toolCallId:K.toolCallId,name:z.name,input:zQ(z.args),partial:!0}});break}case"tool-call":{W.delete(K.toolCallId);let z={type:"tool-call",toolCallId:K.toolCallId,name:K.name,input:N$(K.args)};Q.content.push(z),this.emit({type:"tool-call",messageId:Q.id,part:z});break}case"finish":{if(this.usage=R(this.usage,K.usage),Q.usage=R(Q.usage??M(),K.usage),!J.error)J={reason:K.reason};break}case"error":{J={reason:"error",error:K.error,detail:A(K)};break}case"file-rejected":{this.markFileRejected(K.fileId,K.message,A(K));break}}}for(let[Y,K]of W){let z={type:"tool-call",toolCallId:Y,name:K.name,input:N$(K.args)};Q.content.push(z),this.emit({type:"tool-call",messageId:Q.id,part:z})}let H=J.reason==="length";if(H)this.outputTruncated=!0;if(this.config.output&&X&&!J.error&&!H){let Y=DQ(this.config.output,X);if(Y.ok===!0)this.output=Y.value,Q.content.push({type:"output",value:Y.value});else this.emit({type:"error",error:Y.error})}return J}async systemPrompt(){let Q=[this.config.instructions,this.params.instructions].filter(($)=>Boolean($&&$.trim()));return Q.length>0?Q.join(`
14
14
 
15
- `):void 0}async runTools(Q,$,Z){let J=[],W=[];for(let X of $){let G=this.config.registry.get(String(X.name));if(!G){this.addResult(Q,{type:"tool-result",toolCallId:X.toolCallId,name:X.name,status:"error",error:{code:"tool_error",message:`There is no tool named "${String(X.name)}".`,toolCallId:X.toolCallId,retryable:!0}});continue}let H=G.inputSchema.safeParse(X.input);if(H.ok===!1){this.addResult(Q,{type:"tool-result",toolCallId:X.toolCallId,name:X.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${String(X.name)}": ${H.errors.join(", ")}`,toolCallId:X.toolCallId,retryable:!0}});continue}X.input=H.value;let V=O$(G.tool);if(V){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(X));continue}J.push({toolCallId:X.toolCallId,name:X.name,input:H.value,kind:V,signature:e9(this.claimsFor(X.toolCallId,String(X.name),V,H.value)),...this.pathPrefix.length>0?{path:[...this.pathPrefix]}:{}});continue}W.push(this.executeTool(G,Q.id,X,H.value,Z).then(async(Y)=>{this.addResult(Q,Y),await this.settleShown(X.toolCallId)}).catch((Y)=>{if(Y instanceof g){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(X));return}J.push(...Y.pending);return}}))}return await h(Promise.all(W).then(()=>{return}),this.controller.signal),J}claimsFor(Q,$,Z,J){return{runId:this.signingRunId,toolCallId:Q,name:$,kind:Z,input:J,path:this.pathPrefix.length>0?[...this.pathPrefix]:void 0,subject:this.params.subject??null}}deniedByPolicy(Q){return{type:"tool-result",toolCallId:Q.toolCallId,name:Q.name,status:"denied",cause:"refused",reason:`"${String(Q.name)}" needs the user, and this run was started with onPending: "deny". Answer from what you already have.`}}async executeTool(Q,$,Z,J,W,X){let G=Q.tool.timeoutMs;if(G===void 0)return this.runToolBody(Q,$,Z,J,W,X,this.controller.signal,()=>!1);let H=new AbortController,V=this.controller.signal,Y=()=>H.abort(V.reason);if(V.aborted)Y();else V.addEventListener("abort",Y,{once:!0});let K=!1,z=this.runToolBody(Q,$,Z,J,W,X,H.signal,()=>K),B=()=>{},D=new Promise((F)=>{B=D$(G,()=>{let U=`"${String(Z.name)}" did not finish within ${Q9(G)} (timeoutMs: ${G}) and was cancelled.`;H.abort(new DOMException(U,"TimeoutError")),F({type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:{code:"timeout",message:U,toolCallId:Z.toolCallId,retryable:!0}})})});z.catch(()=>{});try{return await Promise.race([z,D])}finally{K=!0,B()}}async runToolBody(Q,$,Z,J,W,X,G,H){let V=this.toolFiles(Z,G),Y={context:this.context,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,toolCallId:Z.toolCallId,signal:G,step:W,depth:this.depth,resumed:X!==void 0,attachments:V.attachments,generateImage:V.generateImage,editImage:V.editImage,turn:this.toolTurn($),runAgent:this.nestedRunner($,Z,G,X),generate:(K)=>this.generateForTool(K,G,Z.toolCallId)};try{let K=Q.tool.execute(J,Y),z;if(JZ(K)){let B=await K.next();while(!B.done){if(H())throw K.return(void 0).catch(()=>{}),new A;this.emit({type:"tool-progress",toolCallId:Z.toolCallId,data:B.value}),B=await K.next()}z=B.value}else z=await K;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"ok",output:z}}catch(K){if(K instanceof A||this.controller.signal.aborted)throw new A;if(K instanceof g)throw K;let z=K instanceof R;if(!z&&this.config.logErrors)this.logToolFailure(Z,K);let B={code:"tool_error",message:K instanceof Error?K.message:String(K),toolCallId:Z.toolCallId,retryable:z?K.retryable:!0};return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:this.redact(B,{source:"tool",toolName:String(Z.name),cause:K})}}}async generateForTool(Q,$,Z){let J=this.controller.signal;return cQ({...Q,signal:Q.signal?AbortSignal.any([$,Q.signal]):$},{origin:{agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},toolCallId:Z},settled:(W)=>{if(this.usage=S(this.usage,W.usage),J.aborted)throw new A}})}nestedRunner(Q,$,Z,J){let W=new W9(()=>$.nested,()=>$.nested=[]);return async(X,G={})=>{let{at:H,recorded:V,write:Y}=W.next();if(V){let K=GZ(V,X,G);if(K)throw new R(`Nested run ${H} of "${String($.name)}" ${K}. `+"runAgent is memoized by call index, so a body whose runAgent calls depend on a condition that changed between turns cannot be resumed \u2014 the answer would be paired with a different sub-run. "+"Make the sequence of runAgent calls, and what each one is asked, the same every time this tool runs, or branch on ctx.resumed.");if(V.finishReason!=="awaiting-input")return{runId:V.runId,agent:V.agent,messages:V.messages,finishReason:V.finishReason??"stop",usage:V.usage??N(),output:F$(V.messages),nested:V}}return this.runNested(Q,$,Z,X,G,Y,V,J?.answers??[])}}async runNested(Q,$,Z,J,W,X,G,H){let V=[...this.chain,J.name];if(this.chain.includes(J.name))throw new R(`"${J.name}" is already running further up this chain: ${V.join(" -> ")}. An agent cannot run itself, directly or through another agent.`);let Y=this.depth+1;if(Y>this.maxDepth)throw new R(`Nested agent runs are ${this.maxDepth} deep at most and this one would be ${Y}: ${V.join(" -> ")}. Raise maxDepth on the agent at the root of the run if the tree is meant to be this deep.`);let K=W.label,z=[...this.pathPrefix,$.toolCallId],B=this.onPending==="deny"?"deny":W.onPending??"escalate",D=G!==void 0,F=D?NQ(G.messages):new Set,U=D?H.filter((L)=>{let b=j$(L.path,z);if(b===null)return!1;return F.has(b.length>0?b[0]:L.toolCallId)}):[],O=J.stream({messages:D?G.messages:W.messages??[],turn:D?{toolResults:U}:W.prompt?{text:W.prompt}:void 0,context:this.context,attachments:this.params.attachments,body:this.params.body,signal:Z,threadId:this.params.threadId,redactError:this.params.redactError,nonces:this.params.nonces,receipts:this.params.receipts,subject:this.params.subject,instructions:W.instructions,maxOutputTokens:W.maxOutputTokens,temperature:W.temperature,runId:D?G.runId:void 0,nesting:{depth:Y,maxDepth:this.maxDepth,chain:V,signingRunId:this.signingRunId,signingPath:z,onPending:B}}),j=[],q=(L)=>this.emit({type:"nested-event",toolCallId:$.toolCallId,runId:O.runId,agent:J.name,label:K,event:L}),_=(async()=>{for await(let L of O){if(L.type==="awaiting-input")j=L.pending;if(q(L),L.type==="run-start"&&!D)for(let b of W.messages??[])q({type:"message",message:b});if(L.type==="error")this.emit({type:"error",error:L.error,nested:{toolCallId:$.toolCallId,runId:O.runId,agent:J.name}})}})(),w=(async()=>{let L=await O.result();await _;let b=D?U$(G.messages,L.messages):U$(W.messages??[],L.messages),M={runId:O.runId,agent:J.name,label:K,messages:b,finishReason:L.finishReason,usage:D?S(G.usage??N(),L.usage):L.usage,...L.finishReason==="awaiting-input"?{signature:W$({runId:this.signingRunId,path:z,nestedRunId:O.runId,open:[...NQ(b)],input:$.input,subject:this.params.subject??null})}:{}};return X(M),this.usage=S(this.usage,L.usage),{result:L,record:M}})(),v=w.then(()=>{return},()=>{return});this.nestedSettling.add(v);let C,P;try{({result:C,record:P}=await w)}finally{this.nestedSettling.delete(v)}if(this.controller.signal.aborted)throw new A;if(C.finishReason==="awaiting-input"){if(j.length===0)throw new R(`"${J.name}" ended awaiting input but asked nothing, so there is no question to escalate.`);throw this.emit({type:"tool-call",messageId:Q,part:$,resent:!0}),new g({pending:j,path:z,nested:P})}return{runId:P.runId,agent:J.name,messages:P.messages,finishReason:C.finishReason,usage:P.usage??N(),output:C.output??F$(P.messages),...C.error?{error:C.error}:{},nested:P}}addResult(Q,$){Q.content.push($),this.emit({type:"tool-result",messageId:Q.id,part:$})}toolFiles(Q,$){let Z=this.params.attachments??null,J=new W9(()=>Q.attachments,()=>Q.attachments=[],()=>({failed:!0})),W=()=>{if(!Z)throw new i("This request has no attachment scope, so a tool cannot store or read files on it. `attachmentScope()` returned null \u2014 put the chat route behind authentication, send a `threadId`, or override `attachmentScope()` on the controller.");return Z},X=async(Y,K,z)=>{let B=W(),D=K.mimeType||Y.type||"",F=K.name??(Y instanceof File?Y.name:"attachment"),U;if(K.showModel){let j=this.config.provider;if(!j.capabilities.fileInput)throw new R(`"${String(Q.name)}" asked to show a file to ${j.model}, which does not accept file input. Drop \`showModel\` for this provider, or run this agent on a model that takes files \u2014 \`capabilities.fileInput\` is what says which do.`);U=await j.upload(new File([Y],F,{type:D||void 0}))}return{attachment:await B.put(Y,{name:F,mimeType:D,fileId:U}),...z?{generated:z}:{},...U?{shown:{fileId:U,messageId:`msg_${crypto.randomUUID()}`,createdAt:new Date().toISOString()}}:{}}},G=(Y,K,z)=>{let B=Y.generated?"image":"put";if(B===K)return;throw new R(`Attachment ${z} of "${String(Q.name)}" was ${B==="image"?"a generated image":"a stored file"} on the first attempt and is ${K==="image"?"a generated image":"a stored file"} now. ctx.attachments.put, ctx.generateImage and ctx.editImage share one memo indexed by call order within a tool call, so the sequence has to be the same every time this tool runs. Branch on ctx.resumed if it cannot be.`)},H=async(Y,K,z)=>{let{at:B,recorded:D,write:F}=J.next();if(D&&"attachment"in D){if(G(D,"image",B),D.shown)this.queueShown(Q.toolCallId,D);return{attachment:D.attachment,size:D.generated.size,mimeType:D.attachment.mimeType,usage:D.generated.usage}}let U=await z();this.usage=S(this.usage,U.usage);let O=U.mimeType==="image/jpeg"?"jpg":"png",j=await X(U.image,{name:K.name??`${Y.name}.${O}`,mimeType:U.mimeType,...K.showModel?{showModel:!0}:{}},{size:U.size,usage:U.usage});if(F(j),j.shown)this.queueShown(Q.toolCallId,j);return{attachment:j.attachment,size:U.size,mimeType:U.mimeType,usage:U.usage}},V=async(Y)=>typeof Y==="string"?await W().file(Y):Y;return{generateImage:(Y,K)=>H(Y,K,()=>Y.generate({...K,signal:$})),editImage:(Y,K)=>H(Y,K,async()=>{let{images:z,mask:B,...D}=K;return await Y.edit({...D,images:await Promise.all(z.map(V)),...B?{mask:await V(B)}:{},signal:$})}),attachments:{get:(Y)=>W().get(Y),read:(Y)=>W().read(Y),file:(Y)=>W().file(Y),put:async(Y,K={})=>{let{at:z,recorded:B,write:D}=J.next();if(B&&"attachment"in B){G(B,"put",z);let U=XZ(B,Y,K);if(U)throw new R(`Attachment ${z} of "${String(Q.name)}" ${U}. `+"ctx.attachments.put is memoized by call index within a tool call, so a body whose put calls depend on a condition that changed between turns cannot be replayed \u2014 the model would be shown a file under an id that names different bytes. "+"Make the sequence of put calls the same every time this tool runs, or branch on ctx.resumed.");if(B.shown)this.queueShown(Q.toolCallId,B);return B.attachment}let F=await X(Y,K);if(D(F),F.shown)this.queueShown(Q.toolCallId,F);return F.attachment}}}}toolTurn(Q){let $=this.history.findIndex((X)=>X.id===Q),Z=MQ(this.history),J;for(let X=$-1;X>=0;X--){let G=this.history[X];if(G.role!=="user"||Z.has(G.id))continue;J=G;break}let W=[];for(let X of J?.content??[]){if(X.type!=="file")continue;let G=X.attachmentId;if(typeof G!=="string"||!G.startsWith(I))continue;if(!W.includes(G))W.push(G)}return Object.freeze({attachments:Object.freeze(W)})}queueShown(Q,$){let Z=$.shown;if(!Z)return;let J=this.shownQueue.get(Q)??[];if(J.some((W)=>W.id===Z.messageId))return;J.push({id:Z.messageId,role:"user",content:[{type:"file",fileId:Z.fileId,name:$.attachment.name,mimeType:$.attachment.mimeType,attachmentId:$.attachment.id}],createdAt:Z.createdAt,finishReason:"stop"}),this.shownQueue.set(Q,J)}async settleShown(Q){let $=this.shownQueue.get(Q);if(!$||$.length===0)return;if(this.shownQueue.delete(Q),this.ended||this.controller.signal.aborted)return;for(let Z of $){if(this.history.some((J)=>J.id===Z.id))continue;this.history.push(Z),this.produced.push(Z),this.emit({type:"message",message:Z}),this.unreported.add(Z)}}historyForProvider(Q){let $=this.history.filter((X)=>X!==Q),Z=MQ($),J=[];for(let X of $){if(!Z.has(X.id))continue;for(let G of X.content)if(G.type==="file")J.push(G)}if(J.length<=C$)return $;let W=new Set(J.slice(0,J.length-C$));return $.map((X)=>{if(!X.content.some((G)=>G.type==="file"&&W.has(G)))return X;return{...X,content:X.content.map((G)=>G.type==="file"&&W.has(G)?{type:"text",text:`[A ${G.mimeType||"file"} produced by a tool (attachment ${G.attachmentId}) was attached here and has been dropped from this request: only the most recent tool-produced file is kept attached, to keep the context bounded. Call the tool again if you need to look at it.]`}:G)}})}async ingestTurn(){let Q=this.params.turn,$=this.openCalls(),Z=[];if($.length>0){let J=new Set,W=new Set,X=new Map;for(let G of Q?.toolResults??[]){let H=`${(G.path??[]).join("/")}#${G.toolCallId}`;if(W.has(H))continue;W.add(H);let V=(B)=>this.emit({type:"error",error:{code:"invalid_tool_result",message:B,toolCallId:G.toolCallId,retryable:!1}}),Y=j$(G.path,this.pathPrefix);if(Y===null){V(`The answer for "${G.toolCallId}" is addressed to a tool call this run is not inside.`);continue}if(Y.length>0){let B=Y[0],D=$.find((O)=>O.call.toolCallId===B);if(!D){V(`No pending tool call with id "${B}" to deliver a nested answer to.`);continue}let F=this.parkedBelow(D.call,Y,G.toolCallId);if(F.ok===!1){let O=`The answer for "${G.toolCallId}" is addressed under "${B}", which`;V(F.reason==="unparked"?`${O} has no sub-agent run waiting on that question.`:F.reason==="expired"?`${O} parked a sub-agent run that has since expired. Ask again.`:`${O} carries a record of a parked sub-agent run the server did not sign.`);continue}let U=X.get(B);if(!U){if(!await this.spend(H$,F.signature)){V(`The answer for "${G.toolCallId}" is addressed under "${B}", which has already been re-entered on that record. Ask again.`);continue}U=[],X.set(B,U),J.add(B)}U.push(G);continue}let K=$.find((B)=>B.call.toolCallId===G.toolCallId);if(!K){V(`No pending tool call with id "${G.toolCallId}".`);continue}let z=await this.resolveAnswer(K,G,Z);if(z===null)continue;if(J.add(G.toolCallId),z!=="open")this.attachToHistory(K,z),await this.settleShown(G.toolCallId)}for(let[G,H]of X){let V=$.find((K)=>K.call.toolCallId===G),Y=await this.reenter(V,H,Z);if(Y)this.attachToHistory(V,Y),await this.settleShown(G)}for(let G of $){if(J.has(G.call.toolCallId))continue;this.attachToHistory(G,{type:"tool-result",toolCallId:G.call.toolCallId,name:G.call.name,status:"denied",cause:"refused"})}await this.reportDeferred()}if(Q&&(Q.text||Q.files&&Q.files.length>0)){let J={id:`msg_${crypto.randomUUID()}`,role:"user",content:[...Q.text?[{type:"text",text:Q.text}]:[],...(Q.files??[]).map((W)=>({type:"file",...W.fileId?{fileId:W.fileId}:{},name:W.name,mimeType:W.mimeType,...W.attachmentId?{attachmentId:W.attachmentId}:{}}))],createdAt:new Date().toISOString(),finishReason:"stop"};if(this.history.push(J),this.produced.push(J),this.depth>0)this.emit({type:"message",message:J});await this.report(J)}return Z}parkedBelow(Q,$,Z){let J=$.length>1?$[1]:Z,W=[...this.pathPrefix,Q.toolCallId],X=(Q.nested??[]).find((H)=>H.finishReason==="awaiting-input"&&NQ(H.messages).has(J));if(!X)return{ok:!1,reason:"unparked"};if(typeof X.signature!=="string")return{ok:!1,reason:"unsigned"};let G=X$(X.signature,{path:W,nestedRunId:X.runId,open:[...NQ(X.messages)],input:Q.input,subject:this.params.subject??null});if(G.ok===!1)return{ok:!1,reason:G.reason==="expired"?"expired":"unsigned"};return{ok:!0,signature:X.signature}}async reenter(Q,$,Z){let J=String(Q.call.name),W=this.config.registry.get(J);if(!W||!W.tool.execute)return{type:"tool-result",toolCallId:Q.call.toolCallId,name:Q.call.name,status:"error",error:{code:"invalid_tool_result",message:`The tool "${J}" no longer exists, so the sub-agent's question cannot be delivered.`,toolCallId:Q.call.toolCallId,retryable:!1}};let X=W.inputSchema.safeParse(Q.call.input);if(X.ok===!1)return{type:"tool-result",toolCallId:Q.call.toolCallId,name:Q.call.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${J}": ${X.errors.join(", ")}`,toolCallId:Q.call.toolCallId,retryable:!0}};let G=this.amendCall(Q);G.input=X.value;try{return await h(this.executeTool(W,Q.message.id,G,X.value,0,{answers:$}),this.controller.signal)}catch(H){if(H instanceof g)return Z.push(...H.pending),null;throw H}}amendCall(Q){let $=this.amend(Q.message),Z=$.content.indexOf(Q.call),J={...Q.call,nested:(Q.call.nested??[]).map((W)=>({...W})),...Q.call.attachments?{attachments:Q.call.attachments.map((W)=>({...W}))}:{}};if(Z>=0)$.content[Z]=J;return this.unreported.add($),J}openCalls(){let Q=new Set;for(let Z of this.history)for(let J of Z.content)if(J.type==="tool-result")Q.add(J.toolCallId);let $=[];for(let Z of this.history)for(let J of Z.content)if(J.type==="tool-call"&&!Q.has(J.toolCallId))$.push({message:Z,call:J});return $}async spend(Q,$){try{return await Q($,this.params.nonces??l)}catch(Z){return this.writeLog(`[gemi/ai] agent "${this.config.name}" could not spend a nonce`,{error:Z}),!1}}async recordReceipt(Q,$){let Z=await $;try{await Q.store.complete(Q.id,Z,Q.expiresAt)}catch(J){this.writeLog(`[gemi/ai] agent "${this.config.name}" could not record a tool receipt`,{error:J})}return Z}async resolveAnswer(Q,$,Z){let J=Q.call,W=String(J.name),X=this.config.registry.get(W),G=(z)=>{return this.emit({type:"error",error:{code:"invalid_tool_result",message:z,toolCallId:J.toolCallId,retryable:!1}}),null};if(!X)return G(`The tool "${W}" no longer exists, so its answer cannot be checked.`);let H=O$(X.tool);if(!H)return G(`"${W}" is a server tool with no pending question.`);if(typeof $.signature!=="string"||$.signature.length===0)return G(`The answer for "${W}" carried no signature.`);let V=oQ($.signature);if(!V)return G(`The signature for "${W}" is malformed.`);let Y=Q$($.signature,{...this.claimsFor(J.toolCallId,W,H,J.input),runId:V.runId});if(Y.ok===!1)return G(Y.reason==="expired"?`The approval for "${W}" has expired. Ask again.`:`The answer for "${W}" does not match the call the server made.`);let K;if(this.params.receipts&&H==="approval"&&"approve"in $&&$.approve===!0){let z=this.params.receipts,B=G$(this.config.name,{...this.claimsFor(J.toolCallId,W,H,J.input),runId:V.runId}),D;try{D=await z.claim(B,V.expiresAt)}catch(F){return this.writeLog(`[gemi/ai] agent "${this.config.name}" could not claim a tool receipt`,{error:F}),G(`The approval for "${W}" could not be checked. Ask again.`)}if(D.status==="replay")return{...D.result,toolCallId:J.toolCallId,name:J.name};if(D.status==="blocked")return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"error",error:{code:"tool_error",message:`"${W}" was already approved and started, and its result is not recorded yet: it is still running, or it stopped before finishing. It was not run again.`,toolCallId:J.toolCallId,retryable:!1}};K={store:z,id:B,expiresAt:V.expiresAt}}if(!await this.spend(V$,$.signature))return await K?.store.release(K.id).catch((z)=>{this.writeLog(`[gemi/ai] agent "${this.config.name}" could not release a tool receipt`,{error:z})}),G(`The answer for "${W}" has already been used. Ask again.`);if("approve"in $){if(H!=="approval")return G(`"${W}" is answered by the client, not approved.`);if($.approve===!0){let z=this.amendCall(Q),B=this.executeTool(X,Q.message.id,z,z.input,0);try{return await h(K?this.recordReceipt(K,B):B,this.controller.signal)}catch(D){if(D instanceof g)return Z.push(...D.pending),"open";throw D}}return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"denied",cause:"refused",reason:$.reason}}if("output"in $){if(H==="approval")return G(`"${W}" is approved, not answered: the server produces its result.`);let z=X.tool.outputSchema,B=z?z.safeParse($.output):{ok:!0,value:$.output};if(B.ok===!1)return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"error",error:{code:"invalid_tool_result",message:`The answer for "${W}" did not match its output schema: ${B.errors.join(", ")}`,toolCallId:J.toolCallId,retryable:!0}};return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"ok",output:B.value}}return G(`The answer for "${W}" carried neither an approval nor an output.`)}attachToHistory(Q,$){let Z=this.amend(Q.message);Z.content.push($),this.unreported.add(Z),this.emit({type:"tool-result",messageId:Z.id,part:$})}markFileRejected(Q,$,Z){for(let G of this.history){if(!G.content.some((Y)=>Y.type==="file"&&Y.fileId===Q&&!Y.providerRejected))continue;let V=this.produced.includes(G)?G:this.amend(G);if(V.content=V.content.map((Y)=>Y.type==="file"&&Y.fileId===Q&&!Y.providerRejected?{...Y,providerRejected:!0}:Y),V!==this.current)this.unreported.add(V)}if(!this.config.logErrors)return;let J=`[gemi/ai] agent "${this.config.name}": the provider refused file ${Q}${Z.status!==void 0?` (${Z.status})`:""}; it was left out of the request and will not be sent again: ${$}`,W={agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},fileId:Q,...Z},X=!1;try{e.warning(J,W),X=!0}catch{}if(!X||Bun.env.NODE_ENV==="development")console.warn(J,W)}amend(Q){let $=this.amended.get(Q.id);if($)return $;let Z={...Q,content:[...Q.content]},J=this.history.indexOf(Q);if(J>=0)this.history[J]=Z;return this.produced.push(Z),this.amended.set(Q.id,Z),Z}async reportDeferred(){let Q=[...this.unreported];this.unreported.clear();for(let $ of Q)await this.report($)}async finalizeAborted(){if(this.nestedSettling.size>0)await Promise.all([...this.nestedSettling]);for(let $ of this.openCalls()){if($.message===this.current)continue;this.attachToHistory($,{type:"tool-result",toolCallId:$.call.toolCallId,name:$.call.name,status:"denied",cause:"stopped",reason:this.stopReason})}await this.reportDeferred();let Q=this.current;if(Q){let $=new Set(Q.content.filter((Z)=>Z.type==="tool-result").map((Z)=>Z.toolCallId));for(let Z of[...Q.content]){if(Z.type!=="tool-call"||$.has(Z.toolCallId))continue;delete Z.partial,this.addResult(Q,{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"denied",cause:"stopped",reason:this.stopReason})}}if(this.timedOutAfter!==void 0){this.fail({code:"timeout",message:`The run did not finish within its time limit of ${Q9(this.timedOutAfter)} (maxRunDurationMs: ${this.timedOutAfter}) and was stopped.`,retryable:!0}),this.finishReason="error",await this.finalizeMessage("error");return}this.finishReason="aborted",await this.finalizeMessage("aborted")}}function O$(Q){if(Q.answeredBy==="client")return Q.inputSchema===X9?"question":"client";return Q.requiresApproval?"approval":null}function P$(Q){if(!Q||!Q.trim())return{};try{return JSON.parse(Q)}catch{return Q}}function VZ(Q,$){return Q.descriptors($).map((Z)=>u.create({name:Z.name,description:Z.description,inputSchema:Z.inputSchema,requiresApproval:Z.requiresApproval,execute:(J,W)=>{let X=SQ.getStore()?.req;if(!X)throw new R(`"${Z.name}" calls an api route as the user who started this run, and this run was not started inside a request. Run it from an AgentController, or give this agent tools that do not go through the MCP registry.`);return Q.execute({kind:"local",req:X},Z.name,J,W)}}))}function HZ(Q){if(Q==="auto")return;let $=/^(\d+)x(\d+)$/.exec(Q);if(!$)throw Error(`An image size is "WIDTHxHEIGHT" or "auto"; got ${JSON.stringify(Q)}.`);let Z=Number($[1]),J=Number($[2]);if(Z%16!==0||J%16!==0)throw Error(`Image size ${Q} is not supported: width and height must both be divisible by 16.`);if(Math.max(Z/J,J/Z)>3)throw Error(`Image size ${Q} is not supported: the maximum aspect ratio is 3:1, either way up.`)}function S$(Q,$){if(Q.size!==void 0)try{HZ(Q.size)}catch(Z){throw Error(`${$}: ${Z.message}`)}if(Q.background==="transparent"&&Q.format==="jpeg")throw Error(`${$}: a transparent background needs "png"; JPEG has no alpha channel.`);if(Q.compression!==void 0){let Z=Q.compression;if(!Number.isInteger(Z)||Z<0||Z>100)throw Error(`${$}: compression is an integer from 0 to 100; got ${Z}.`)}}function R$(Q,$){if(Q instanceof File)return Q;let Z=Q.type||"image/png",J=Z==="image/jpeg"?"jpg":Z.split("/")[1]??"png";return new File([Q],`${$}.${J}`,{type:Z})}class z9{name;provider;settings;constructor(Q){let{name:$,provider:Z,...J}=Q;S$(J,`ImageModel "${$}"`),this.name=$,this.provider=Z,this.settings=J}static create(Q){return new z9(Q)}async generate(Q){let $=this.merge(Q);return k$(await this.provider.generate({prompt:Q.prompt,...$,signal:Q.signal}))}async edit(Q){let $=this.merge(Q);return k$(await this.provider.edit({prompt:Q.prompt,...$,images:Q.images.map((Z,J)=>R$(Z,`image-${J}`)),...Q.mask?{mask:R$(Q.mask,"mask")}:{},signal:Q.signal}))}merge(Q){let $={...this.settings,...Q.size!==void 0?{size:Q.size}:{},...Q.quality!==void 0?{quality:Q.quality}:{},...Q.background!==void 0?{background:Q.background}:{},...Q.format!==void 0?{format:Q.format}:{},...Q.compression!==void 0?{compression:Q.compression}:{}};return S$($,`ImageModel "${this.name}"`),$}}function k$(Q){return{image:new Blob([Q.bytes],{type:Q.mimeType}),mimeType:Q.mimeType,size:Q.size,usage:Q.usage}}function c(Q){return typeof process>"u"?void 0:process.env?.[Q]}var YZ="preview";function T$(Q){let $=Q.trim().replace(/\/+$/,"");if(!$)return"";return`${$.replace(/\/openai(?:\/v1)?$/i,"")}/openai`}function KZ(Q){return/^\d{4}-\d{2}-\d{2}/.test(Q)?"":"/v1"}function kQ(Q,$={}){return{base:(Q.baseURL??c("OPENAI_BASE_URL")??"https://api.openai.com/v1").replace(/\/+$/,""),query:"",headers:async()=>{let J=Q.apiKey??c("OPENAI_API_KEY");return{...J?{authorization:`Bearer ${J}`}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}function zZ(Q){let $=Q.baseURL??Q.endpoint??c("AZURE_OPENAI_ENDPOINT");if($)return T$($);let Z=Q.resourceName??c("AZURE_OPENAI_RESOURCE_NAME")??c("AZURE_RESOURCE_NAME");return Z?T$(`https://${Z.trim()}.cognitiveservices.azure.com`):""}function TQ(Q,$={}){let Z=Q.apiVersion??c("AZURE_OPENAI_API_VERSION")??YZ;return{base:`${zZ(Q)}${KZ(Z)}`,query:`?api-version=${encodeURIComponent(Z)}`,headers:async()=>{if(Q.getToken)return{authorization:`Bearer ${await Q.getToken()}`,...Q.headers};let J=Q.apiKey??c("AZURE_OPENAI_API_KEY");return{...J?{"api-key":J}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}var BZ=500,E$=20000;function DZ(Q,$){if(!Q)return;let Z=Q.trim();if(/^\d+(\.\d+)?$/.test(Z))return Math.max(0,Number(Z)*1000);let J=Date.parse(Z);if(Number.isNaN(J))return;return Math.max(0,J-$)}function A$(Q,$){let Z=Math.min(E$,BZ*2**Q);return Math.round(Z*(0.5+$()*0.5))}function UZ(Q){return Q===429||Q===408||Q===409||Q>=500}function FZ(Q,$){return UZ(Q)&&k($).retryable}function x$(Q){return Q.reason??new DOMException("The operation was aborted.","AbortError")}function LZ(Q,$){return new Promise((Z,J)=>{let W=setTimeout(Z,Q);$?.addEventListener("abort",()=>{clearTimeout(W),J(x$($))},{once:!0})})}async function GQ(Q,$,Z){let J=Z.fetchImpl??((K,z)=>fetch(K,z)),W=Z.sleep??LZ,X=Z.random??Math.random,G=Z.now??Date.now,H=Math.max(0,Z.maxRetries),V=async(K)=>{let z=Z.signal;if(!z)return await W(K);z.throwIfAborted();let B;try{await Promise.race([W(K,z),new Promise((D,F)=>{B=()=>F(x$(z)),z.addEventListener("abort",B,{once:!0})})])}finally{if(B)z.removeEventListener("abort",B)}},Y;for(let K=0;K<=H;K++){Z.signal?.throwIfAborted();let z=new AbortController,B=()=>z.abort(Z.signal?.reason);Z.signal?.addEventListener("abort",B,{once:!0});let D=!1,F=Z.timeoutMs>0?setTimeout(()=>{D=!0,z.abort()},Z.timeoutMs):void 0,U;try{U=await J(Q,{...$,signal:z.signal})}catch(_){if(F!==void 0)clearTimeout(F);if(Z.signal?.removeEventListener("abort",B),Z.signal?.aborted)throw _;if(Y=D?new KQ(Z.timeoutMs):_,D&&Z.retryTimeouts===!1)throw Y;if(K===H)throw Y;await V(A$(K,X));continue}if(F!==void 0)clearTimeout(F);if(U.ok)return U;Z.signal?.removeEventListener("abort",B);let O=await CZ(U),j=new f(U.status,O,U.headers.get("x-request-id")??void 0);if(K===H||!FZ(U.status,j))throw j;let q=DZ(U.headers.get("retry-after"),G());await V(q===void 0?A$(K,X):Math.min(q,E$)),Y=j}throw Y??Error("Provider request failed with no response.")}async function CZ(Q){let $;try{$=await Q.text()}catch{return null}try{return JSON.parse($)}catch{return $}}var B9=300000;function D9(Q){return{generationsUrl:`${Q.base}/images/generations${Q.query}`,editsUrl:`${Q.base}/images/edits${Q.query}`,headers:Q.headers,timeoutMs:Q.timeoutMs,maxRetries:Q.maxRetries}}class AQ extends Error{code;retryable;constructor(Q,$={}){super(Q.message,$);this.name="ImageRequestError",this.code=Q.code,this.retryable=Q.retryable}}var jZ={png:"image/png",jpeg:"image/jpeg"};function OZ(Q){let $=Number(Q?.input_tokens??0),Z=Number(Q?.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q?.total_tokens??$+Z)},W=Q?.input_tokens_details?.image_tokens;if(typeof W==="number")J.imageInputTokens=W;let X=Q?.output_tokens_details?.image_tokens;if(typeof X==="number")J.imageOutputTokens=X;return J}function PZ(Q){let $=atob(Q),Z=new Uint8Array($.length);for(let J=0;J<$.length;J++)Z[J]=$.charCodeAt(J);return Z}function qZ(Q){let Z=Q?.data?.[0]?.b64_json;if(typeof Z!=="string"||Z.length===0)throw new AQ({code:"provider_error",message:"The provider answered an image call with no base64 image data.",retryable:!1});let J=typeof Q.output_format==="string"?Q.output_format:"png";return{bytes:PZ(Z),mimeType:jZ[J]??`image/${J}`,size:typeof Q.size==="string"?Q.size:"",...typeof Q.background==="string"?{background:Q.background}:{},usage:OZ(Q.usage)}}async function w$(Q,$,Z,J){let W;try{W=await GQ(Q,$,{maxRetries:Z.maxRetries,timeoutMs:Z.timeoutMs,retryTimeouts:!1,signal:J.signal,fetchImpl:Z.fetchImpl})}catch(X){if(J.signal?.aborted)throw X;throw new AQ(k(X),{cause:X})}return qZ(await W.json())}async function b$(Q,$,Z={}){return await w$(Q.generationsUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify($)},Q,Z)}async function I$(Q,$,Z={}){return await w$(Q.editsUrl,{method:"POST",headers:await Q.headers(),body:$},Q,Z)}class EQ{static models(){return[]}modelName(){return this.model}async generate(Q){return await b$(this.endpoint(),this.body(Q),{signal:Q.signal})}async edit(Q){let $=new FormData;for(let[Z,J]of Object.entries(this.body(Q)))if(J!==void 0)$.set(Z,String(J));for(let Z of Q.images)$.append("image[]",Z,Z.name);if(Q.mask)$.set("mask",Q.mask,Q.mask.name);return await I$(this.endpoint(),$,{signal:Q.signal})}body(Q){return{model:this.modelName(),prompt:Q.prompt,...Q.size?{size:Q.size}:{},...Q.quality?{quality:Q.quality}:{},...Q.background?{background:Q.background}:{},...Q.format?{output_format:Q.format}:{},...Q.compression!==void 0?{output_compression:Q.compression}:{}}}normalizeError(Q){return k(Q)}}var v$=["gpt-image-2","gpt-image-1.5","gpt-image-1"];class U9 extends EQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new U9(Q,$)}static models(){return v$}endpoint(){return D9(kQ(this.config,{timeoutMs:B9}))}}class F9 extends EQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new F9(Q,$)}static models(){return v$}modelName(){return this.config.deployment??this.model}endpoint(){return D9(TQ(this.config,{timeoutMs:B9}))}}var y$=3;function L9(Q){let $=new Map;for(let Z of Q)for(let J of Z.content??[]){if(J.type!=="file"||!J.fileId||$.has(J.fileId))continue;$.set(J.fileId,{name:J.name,mimeType:J.mimeType})}return $}function g$(Q,$,Z=new Map){if(!($ instanceof f))return[];if($.status!==400&&$.status!==404)return[];let J=NZ($.body);if(!J)return[];let W=_Z(Q.input);if(W.length===0)return[];let X=/^input\[(\d+)\]\.content\[(\d+)\]\.file_id$/.exec(J.param??"");if(X){let Y=Q.input[Number(X[1])],K=j9(Y)[Number(X[2])],z=K&&typeof K.file_id==="string"?K.file_id:void 0;if(z)return[z]}let G=J.message??"",H=h$(W.map((Y)=>Y.fileId).filter((Y)=>MZ(G,Y)));if(H.length>0)return H;let V=/Expected (image type|context stuffing file type) to be a supported format:.*but got \.([a-z0-9]+)\.?\s*$/is.exec(G);if(V){let Y=V[1].toLowerCase()==="image type"?"input_image":"input_file",K=V[2].toLowerCase(),z=h$(W.filter((D)=>D.type===Y).map((D)=>D.fileId)),B=z.filter((D)=>(Z.get(D)?.name??"").trim().toLowerCase().endsWith(`.${K}`));if(B.length===1)return B;if(B.length===0&&z.length===1)return z}return[]}function u$(Q,$,Z=new Map){return{...Q,input:Q.input.map((J)=>{let W=j9(J);if(!W.some((X)=>f$(X,$)))return J;return{...J,content:W.map((X)=>f$(X,$)?{type:"input_text",text:C9(Z.get(String(X.file_id))?.name)}:X)}})}}function C9(Q){return`[${Q?`attachment ${JSON.stringify(Q)}`:"an attachment"} could not be read by the provider and is not shown to you. Tell the user if it matters to the answer; uploading it again may help.]`}function f$(Q,$){return typeof Q.file_id==="string"&&$.has(Q.file_id)}function j9(Q){let $=Q?.content;return Array.isArray($)?$:[]}function _Z(Q){let $=[];for(let Z of Q)for(let J of j9(Z))if(typeof J.file_id==="string"&&J.file_id)$.push({type:String(J.type),fileId:J.file_id});return $}function NZ(Q){if(!Q||typeof Q!=="object")return null;let $=Q,Z=$.error&&typeof $.error==="object"?$.error:Q;return{message:typeof Z.message==="string"?Z.message:void 0,param:typeof Z.param==="string"?Z.param:void 0}}function MZ(Q,$){let Z=$.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^A-Za-z0-9_-])${Z}($|[^A-Za-z0-9_-])`).test(Q)}function h$(Q){return[...new Set(Q)]}async function*SZ(Q){let $="",Z="",J=[],W,X=()=>{if(J.length===0&&!Z)return null;let V={event:Z,data:J.join(`
16
- `),id:W};return Z="",J=[],W=void 0,V.data?V:null},G=(V)=>{let Y=V.endsWith("\r")?V.slice(0,-1):V;if(Y==="")return X();if(Y.startsWith(":"))return null;let K=Y.indexOf(":"),z=K===-1?Y:Y.slice(0,K),B=K===-1?"":Y.slice(K+1);if(B.startsWith(" "))B=B.slice(1);if(z==="event")Z=B;else if(z==="data")J.push(B);else if(z==="id")W=B;return null};for await(let V of Q){$+=V;let Y=$.indexOf(`
15
+ `):void 0}async runTools(Q,$,Z){let J=[],W=[];for(let X of $){let G=this.config.registry.get(String(X.name));if(!G){this.addResult(Q,{type:"tool-result",toolCallId:X.toolCallId,name:X.name,status:"error",error:{code:"tool_error",message:`There is no tool named "${String(X.name)}".`,toolCallId:X.toolCallId,retryable:!0}});continue}let V=G.inputSchema.safeParse(X.input);if(V.ok===!1){this.addResult(Q,{type:"tool-result",toolCallId:X.toolCallId,name:X.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${String(X.name)}": ${V.errors.join(", ")}`,toolCallId:X.toolCallId,retryable:!0}});continue}X.input=V.value;let H=q$(G.tool);if(H){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(X));continue}J.push({toolCallId:X.toolCallId,name:X.name,input:V.value,kind:H,signature:$$(this.claimsFor(X.toolCallId,String(X.name),H,V.value)),...this.pathPrefix.length>0?{path:[...this.pathPrefix]}:{}});continue}W.push(this.executeTool(G,Q.id,X,V.value,Z).then(async(Y)=>{this.addResult(Q,Y),await this.settleShown(X.toolCallId)}).catch((Y)=>{if(Y instanceof u){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(X));return}J.push(...Y.pending);return}}))}return await y(Promise.all(W).then(()=>{return}),this.controller.signal),J}claimsFor(Q,$,Z,J){return{runId:this.signingRunId,toolCallId:Q,name:$,kind:Z,input:J,path:this.pathPrefix.length>0?[...this.pathPrefix]:void 0,subject:this.params.subject??null}}deniedByPolicy(Q){return{type:"tool-result",toolCallId:Q.toolCallId,name:Q.name,status:"denied",cause:"refused",reason:`"${String(Q.name)}" needs the user, and this run was started with onPending: "deny". Answer from what you already have.`}}async executeTool(Q,$,Z,J,W,X){let G=Q.tool.timeoutMs;if(G===void 0)return this.runToolBody(Q,$,Z,J,W,X,this.controller.signal,()=>!1);let V=new AbortController,H=this.controller.signal,Y=()=>V.abort(H.reason);if(H.aborted)Y();else H.addEventListener("abort",Y,{once:!0});let K=!1,z=this.runToolBody(Q,$,Z,J,W,X,V.signal,()=>K),B=()=>{},U=new Promise((j)=>{B=F$(G,()=>{let D=`"${String(Z.name)}" did not finish within ${$9(G)} (timeoutMs: ${G}) and was cancelled.`;V.abort(new DOMException(D,"TimeoutError")),j({type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:{code:"timeout",message:D,toolCallId:Z.toolCallId,retryable:!0}})})});z.catch(()=>{});try{return await Promise.race([z,U])}finally{K=!0,B()}}async runToolBody(Q,$,Z,J,W,X,G,V){let H=this.toolFiles(Z,G),Y={context:this.context,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,toolCallId:Z.toolCallId,signal:G,step:W,depth:this.depth,resumed:X!==void 0,attachments:H.attachments,generateImage:H.generateImage,editImage:H.editImage,turn:this.toolTurn($),runAgent:this.nestedRunner($,Z,G,X),generate:(K)=>this.generateForTool(K,G,Z.toolCallId)};try{let K=Q.tool.execute(J,Y),z;if(GZ(K)){let B=await K.next();while(!B.done){if(V())throw K.return(void 0).catch(()=>{}),new E;this.emit({type:"tool-progress",toolCallId:Z.toolCallId,data:B.value}),B=await K.next()}z=B.value}else z=await K;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"ok",output:z}}catch(K){if(K instanceof E||this.controller.signal.aborted)throw new E;if(K instanceof u)throw K;let z=K instanceof T;if(!z&&this.config.logErrors)this.logToolFailure(Z,K);let B={code:"tool_error",message:K instanceof Error?K.message:String(K),toolCallId:Z.toolCallId,retryable:z?K.retryable:!0};return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:this.redact(B,{source:"tool",toolName:String(Z.name),cause:K})}}}async generateForTool(Q,$,Z){let J=this.controller.signal;return mQ({...Q,signal:Q.signal?AbortSignal.any([$,Q.signal]):$},{origin:{agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},toolCallId:Z},settled:(W)=>{if(this.usage=R(this.usage,W.usage),J.aborted)throw new E}})}nestedRunner(Q,$,Z,J){let W=new X9(()=>$.nested,()=>$.nested=[]);return async(X,G={})=>{let{at:V,recorded:H,write:Y}=W.next();if(H){let K=YZ(H,X,G);if(K)throw new T(`Nested run ${V} of "${String($.name)}" ${K}. `+"runAgent is memoized by call index, so a body whose runAgent calls depend on a condition that changed between turns cannot be resumed \u2014 the answer would be paired with a different sub-run. "+"Make the sequence of runAgent calls, and what each one is asked, the same every time this tool runs, or branch on ctx.resumed.");if(H.finishReason!=="awaiting-input")return{runId:H.runId,agent:H.agent,messages:H.messages,finishReason:H.finishReason??"stop",usage:H.usage??M(),output:L$(H.messages),nested:H}}return this.runNested(Q,$,Z,X,G,Y,H,J?.answers??[])}}async runNested(Q,$,Z,J,W,X,G,V){let H=[...this.chain,J.name];if(this.chain.includes(J.name))throw new T(`"${J.name}" is already running further up this chain: ${H.join(" -> ")}. An agent cannot run itself, directly or through another agent.`);let Y=this.depth+1;if(Y>this.maxDepth)throw new T(`Nested agent runs are ${this.maxDepth} deep at most and this one would be ${Y}: ${H.join(" -> ")}. Raise maxDepth on the agent at the root of the run if the tree is meant to be this deep.`);let K=W.label,z=[...this.pathPrefix,$.toolCallId],B=this.onPending==="deny"?"deny":W.onPending??"escalate",U=G!==void 0,j=U?_Q(G.messages):new Set,D=U?V.filter((q)=>{let C=O$(q.path,z);if(C===null)return!1;return j.has(C.length>0?C[0]:q.toolCallId)}):[],L=J.stream({messages:U?G.messages:W.messages??[],turn:U?{toolResults:D}:W.prompt?{text:W.prompt}:void 0,context:this.context,attachments:this.params.attachments,body:this.params.body,signal:Z,threadId:this.params.threadId,redactError:this.params.redactError,nonces:this.params.nonces,receipts:this.params.receipts,subject:this.params.subject,instructions:W.instructions,maxOutputTokens:W.maxOutputTokens,temperature:W.temperature,runId:U?G.runId:void 0,nesting:{depth:Y,maxDepth:this.maxDepth,chain:H,signingRunId:this.signingRunId,signingPath:z,onPending:B}}),F=[],S=(q)=>this.emit({type:"nested-event",toolCallId:$.toolCallId,runId:L.runId,agent:J.name,label:K,event:q}),N=(async()=>{for await(let q of L){if(q.type==="awaiting-input")F=q.pending;if(S(q),q.type==="run-start"&&!U)for(let C of W.messages??[])S({type:"message",message:C});if(q.type==="error")this.emit({type:"error",error:q.error,nested:{toolCallId:$.toolCallId,runId:L.runId,agent:J.name}})}})(),v=(async()=>{let q=await L.result();await N;let C=U?j$(G.messages,q.messages):j$(W.messages??[],q.messages),O={runId:L.runId,agent:J.name,label:K,messages:C,finishReason:q.finishReason,usage:U?R(G.usage??M(),q.usage):q.usage,...q.finishReason==="awaiting-input"?{signature:G$({runId:this.signingRunId,path:z,nestedRunId:L.runId,open:[..._Q(C)],input:$.input,subject:this.params.subject??null})}:{}};return X(O),this.usage=R(this.usage,q.usage),{result:q,record:O}})(),b=v.then(()=>{return},()=>{return});this.nestedSettling.add(b);let _,w;try{({result:_,record:w}=await v)}finally{this.nestedSettling.delete(b)}if(this.controller.signal.aborted)throw new E;if(_.finishReason==="awaiting-input"){if(F.length===0)throw new T(`"${J.name}" ended awaiting input but asked nothing, so there is no question to escalate.`);throw this.emit({type:"tool-call",messageId:Q,part:$,resent:!0}),new u({pending:F,path:z,nested:w})}return{runId:w.runId,agent:J.name,messages:w.messages,finishReason:_.finishReason,usage:w.usage??M(),output:_.output??L$(w.messages),..._.error?{error:_.error}:{},nested:w}}addResult(Q,$){Q.content.push($),this.emit({type:"tool-result",messageId:Q.id,part:$})}toolFiles(Q,$){let Z=this.params.attachments??null,J=new X9(()=>Q.attachments,()=>Q.attachments=[],()=>({failed:!0})),W=()=>{if(!Z)throw new i("This request has no attachment scope, so a tool cannot store or read files on it. `attachmentScope()` returned null \u2014 put the chat route behind authentication, send a `threadId`, or override `attachmentScope()` on the controller.");return Z},X=async(Y,K,z)=>{let B=W(),U=K.mimeType||Y.type||"",j=K.name??(Y instanceof File?Y.name:"attachment"),D;if(K.showModel){let F=this.config.provider;if(!F.capabilities.fileInput)throw new T(`"${String(Q.name)}" asked to show a file to ${F.model}, which does not accept file input. Drop \`showModel\` for this provider, or run this agent on a model that takes files \u2014 \`capabilities.fileInput\` is what says which do.`);D=await F.upload(new File([Y],j,{type:U||void 0}))}return{attachment:await B.put(Y,{name:j,mimeType:U,fileId:D}),...z?{generated:z}:{},...D?{shown:{fileId:D,messageId:`msg_${crypto.randomUUID()}`,createdAt:new Date().toISOString()}}:{}}},G=(Y,K,z)=>{let B=Y.generated?"image":"put";if(B===K)return;throw new T(`Attachment ${z} of "${String(Q.name)}" was ${B==="image"?"a generated image":"a stored file"} on the first attempt and is ${K==="image"?"a generated image":"a stored file"} now. ctx.attachments.put, ctx.generateImage and ctx.editImage share one memo indexed by call order within a tool call, so the sequence has to be the same every time this tool runs. Branch on ctx.resumed if it cannot be.`)},V=async(Y,K,z)=>{let{at:B,recorded:U,write:j}=J.next();if(U&&"attachment"in U){if(G(U,"image",B),U.shown)this.queueShown(Q.toolCallId,U);return{attachment:U.attachment,size:U.generated.size,mimeType:U.attachment.mimeType,usage:U.generated.usage}}let D=await z();this.usage=R(this.usage,D.usage);let L=D.mimeType==="image/jpeg"?"jpg":"png",F=await X(D.image,{name:K.name??`${Y.name}.${L}`,mimeType:D.mimeType,...K.showModel?{showModel:!0}:{}},{size:D.size,usage:D.usage});if(j(F),F.shown)this.queueShown(Q.toolCallId,F);return{attachment:F.attachment,size:D.size,mimeType:D.mimeType,usage:D.usage}},H=async(Y)=>typeof Y==="string"?await W().file(Y):Y;return{generateImage:(Y,K)=>V(Y,K,()=>Y.generate({...K,signal:$})),editImage:(Y,K)=>V(Y,K,async()=>{let{images:z,mask:B,...U}=K;return await Y.edit({...U,images:await Promise.all(z.map(H)),...B?{mask:await H(B)}:{},signal:$})}),attachments:{get:(Y)=>W().get(Y),read:(Y)=>W().read(Y),file:(Y)=>W().file(Y),put:async(Y,K={})=>{let{at:z,recorded:B,write:U}=J.next();if(B&&"attachment"in B){G(B,"put",z);let D=HZ(B,Y,K);if(D)throw new T(`Attachment ${z} of "${String(Q.name)}" ${D}. `+"ctx.attachments.put is memoized by call index within a tool call, so a body whose put calls depend on a condition that changed between turns cannot be replayed \u2014 the model would be shown a file under an id that names different bytes. "+"Make the sequence of put calls the same every time this tool runs, or branch on ctx.resumed.");if(B.shown)this.queueShown(Q.toolCallId,B);return B.attachment}let j=await X(Y,K);if(U(j),j.shown)this.queueShown(Q.toolCallId,j);return j.attachment}}}}toolTurn(Q){let $=this.history.findIndex((X)=>X.id===Q),Z=MQ(this.history),J;for(let X=$-1;X>=0;X--){let G=this.history[X];if(G.role!=="user"||Z.has(G.id))continue;J=G;break}let W=[];for(let X of J?.content??[]){if(X.type!=="file")continue;let G=X.attachmentId;if(typeof G!=="string"||!G.startsWith(f))continue;if(!W.includes(G))W.push(G)}return Object.freeze({attachments:Object.freeze(W)})}queueShown(Q,$){let Z=$.shown;if(!Z)return;let J=this.shownQueue.get(Q)??[];if(J.some((W)=>W.id===Z.messageId))return;J.push({id:Z.messageId,role:"user",content:[{type:"file",fileId:Z.fileId,name:$.attachment.name,mimeType:$.attachment.mimeType,attachmentId:$.attachment.id}],createdAt:Z.createdAt,finishReason:"stop"}),this.shownQueue.set(Q,J)}async settleShown(Q){let $=this.shownQueue.get(Q);if(!$||$.length===0)return;if(this.shownQueue.delete(Q),this.ended||this.controller.signal.aborted)return;for(let Z of $){if(this.history.some((J)=>J.id===Z.id))continue;this.history.push(Z),this.produced.push(Z),this.emit({type:"message",message:Z}),this.unreported.add(Z)}}historyForProvider(Q){let $=this.history.filter((X)=>X!==Q),Z=MQ($),J=[];for(let X of $){if(!Z.has(X.id))continue;for(let G of X.content)if(G.type==="file")J.push(G)}if(J.length<=P$)return $;let W=new Set(J.slice(0,J.length-P$));return $.map((X)=>{if(!X.content.some((G)=>G.type==="file"&&W.has(G)))return X;return{...X,content:X.content.map((G)=>G.type==="file"&&W.has(G)?{type:"text",text:`[A ${G.mimeType||"file"} produced by a tool (attachment ${G.attachmentId}) was attached here and has been dropped from this request: only the most recent tool-produced file is kept attached, to keep the context bounded. Call the tool again if you need to look at it.]`}:G)}})}async ingestTurn(){let Q=this.params.turn,$=this.openCalls(),Z=[];if($.length>0){let J=new Set,W=new Set,X=new Map;for(let G of Q?.toolResults??[]){let V=`${(G.path??[]).join("/")}#${G.toolCallId}`;if(W.has(V))continue;W.add(V);let H=(B)=>this.emit({type:"error",error:{code:"invalid_tool_result",message:B,toolCallId:G.toolCallId,retryable:!1}}),Y=O$(G.path,this.pathPrefix);if(Y===null){H(`The answer for "${G.toolCallId}" is addressed to a tool call this run is not inside.`);continue}if(Y.length>0){let B=Y[0],U=$.find((L)=>L.call.toolCallId===B);if(!U){H(`No pending tool call with id "${B}" to deliver a nested answer to.`);continue}let j=this.parkedBelow(U.call,Y,G.toolCallId);if(j.ok===!1){let L=`The answer for "${G.toolCallId}" is addressed under "${B}", which`;H(j.reason==="unparked"?`${L} has no sub-agent run waiting on that question.`:j.reason==="expired"?`${L} parked a sub-agent run that has since expired. Ask again.`:`${L} carries a record of a parked sub-agent run the server did not sign.`);continue}let D=X.get(B);if(!D){if(!await this.spend(K$,j.signature)){H(`The answer for "${G.toolCallId}" is addressed under "${B}", which has already been re-entered on that record. Ask again.`);continue}D=[],X.set(B,D),J.add(B)}D.push(G);continue}let K=$.find((B)=>B.call.toolCallId===G.toolCallId);if(!K){H(`No pending tool call with id "${G.toolCallId}".`);continue}let z=await this.resolveAnswer(K,G,Z);if(z===null)continue;if(J.add(G.toolCallId),z!=="open")this.attachToHistory(K,z),await this.settleShown(G.toolCallId)}for(let[G,V]of X){let H=$.find((K)=>K.call.toolCallId===G),Y=await this.reenter(H,V,Z);if(Y)this.attachToHistory(H,Y),await this.settleShown(G)}for(let G of $){if(J.has(G.call.toolCallId))continue;this.attachToHistory(G,{type:"tool-result",toolCallId:G.call.toolCallId,name:G.call.name,status:"denied",cause:"refused"})}await this.reportDeferred()}if(Q&&(Q.text||Q.files&&Q.files.length>0)){let J={id:`msg_${crypto.randomUUID()}`,role:"user",content:[...Q.text?[{type:"text",text:Q.text}]:[],...(Q.files??[]).map((W)=>({type:"file",...W.fileId?{fileId:W.fileId}:{},name:W.name,mimeType:W.mimeType,...W.attachmentId?{attachmentId:W.attachmentId}:{}}))],createdAt:new Date().toISOString(),finishReason:"stop"};if(this.history.push(J),this.produced.push(J),this.depth>0)this.emit({type:"message",message:J});else if(Q.localId)this.emit({type:"message-id",localId:Q.localId,messageId:J.id});await this.report(J)}return Z}parkedBelow(Q,$,Z){let J=$.length>1?$[1]:Z,W=[...this.pathPrefix,Q.toolCallId],X=(Q.nested??[]).find((V)=>V.finishReason==="awaiting-input"&&_Q(V.messages).has(J));if(!X)return{ok:!1,reason:"unparked"};if(typeof X.signature!=="string")return{ok:!1,reason:"unsigned"};let G=V$(X.signature,{path:W,nestedRunId:X.runId,open:[..._Q(X.messages)],input:Q.input,subject:this.params.subject??null});if(G.ok===!1)return{ok:!1,reason:G.reason==="expired"?"expired":"unsigned"};return{ok:!0,signature:X.signature}}async reenter(Q,$,Z){let J=String(Q.call.name),W=this.config.registry.get(J);if(!W||!W.tool.execute)return{type:"tool-result",toolCallId:Q.call.toolCallId,name:Q.call.name,status:"error",error:{code:"invalid_tool_result",message:`The tool "${J}" no longer exists, so the sub-agent's question cannot be delivered.`,toolCallId:Q.call.toolCallId,retryable:!1}};let X=W.inputSchema.safeParse(Q.call.input);if(X.ok===!1)return{type:"tool-result",toolCallId:Q.call.toolCallId,name:Q.call.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${J}": ${X.errors.join(", ")}`,toolCallId:Q.call.toolCallId,retryable:!0}};let G=this.amendCall(Q);G.input=X.value;try{return await y(this.executeTool(W,Q.message.id,G,X.value,0,{answers:$}),this.controller.signal)}catch(V){if(V instanceof u)return Z.push(...V.pending),null;throw V}}amendCall(Q){let $=this.amend(Q.message),Z=$.content.indexOf(Q.call),J={...Q.call,nested:(Q.call.nested??[]).map((W)=>({...W})),...Q.call.attachments?{attachments:Q.call.attachments.map((W)=>({...W}))}:{}};if(Z>=0)$.content[Z]=J;return this.unreported.add($),J}openCalls(){let Q=new Set;for(let Z of this.history)for(let J of Z.content)if(J.type==="tool-result")Q.add(J.toolCallId);let $=[];for(let Z of this.history)for(let J of Z.content)if(J.type==="tool-call"&&!Q.has(J.toolCallId))$.push({message:Z,call:J});return $}async spend(Q,$){try{return await Q($,this.params.nonces??l)}catch(Z){return this.writeLog(`[gemi/ai] agent "${this.config.name}" could not spend a nonce`,{error:Z}),!1}}async recordReceipt(Q,$){let Z=await $;try{await Q.store.complete(Q.id,Z,Q.expiresAt)}catch(J){this.writeLog(`[gemi/ai] agent "${this.config.name}" could not record a tool receipt`,{error:J})}return Z}async resolveAnswer(Q,$,Z){let J=Q.call,W=String(J.name),X=this.config.registry.get(W),G=(z)=>{return this.emit({type:"error",error:{code:"invalid_tool_result",message:z,toolCallId:J.toolCallId,retryable:!1}}),null};if(!X)return G(`The tool "${W}" no longer exists, so its answer cannot be checked.`);let V=q$(X.tool);if(!V)return G(`"${W}" is a server tool with no pending question.`);if(typeof $.signature!=="string"||$.signature.length===0)return G(`The answer for "${W}" carried no signature.`);let H=nQ($.signature);if(!H)return G(`The signature for "${W}" is malformed.`);let Y=Z$($.signature,{...this.claimsFor(J.toolCallId,W,V,J.input),runId:H.runId});if(Y.ok===!1)return G(Y.reason==="expired"?`The approval for "${W}" has expired. Ask again.`:`The answer for "${W}" does not match the call the server made.`);let K;if(this.params.receipts&&V==="approval"&&"approve"in $&&$.approve===!0){let z=this.params.receipts,B=H$(this.config.name,{...this.claimsFor(J.toolCallId,W,V,J.input),runId:H.runId}),U;try{U=await z.claim(B,H.expiresAt)}catch(j){return this.writeLog(`[gemi/ai] agent "${this.config.name}" could not claim a tool receipt`,{error:j}),G(`The approval for "${W}" could not be checked. Ask again.`)}if(U.status==="replay")return{...U.result,toolCallId:J.toolCallId,name:J.name};if(U.status==="blocked")return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"error",error:{code:"tool_error",message:`"${W}" was already approved and started, and its result is not recorded yet: it is still running, or it stopped before finishing. It was not run again.`,toolCallId:J.toolCallId,retryable:!1}};K={store:z,id:B,expiresAt:H.expiresAt}}if(!await this.spend(Y$,$.signature))return await K?.store.release(K.id).catch((z)=>{this.writeLog(`[gemi/ai] agent "${this.config.name}" could not release a tool receipt`,{error:z})}),G(`The answer for "${W}" has already been used. Ask again.`);if("approve"in $){if(V!=="approval")return G(`"${W}" is answered by the client, not approved.`);if($.approve===!0){let z=this.amendCall(Q),B=this.executeTool(X,Q.message.id,z,z.input,0);try{return await y(K?this.recordReceipt(K,B):B,this.controller.signal)}catch(U){if(U instanceof u)return Z.push(...U.pending),"open";throw U}}return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"denied",cause:"refused",reason:$.reason}}if("output"in $){if(V==="approval")return G(`"${W}" is approved, not answered: the server produces its result.`);let z=X.tool.outputSchema,B=z?z.safeParse($.output):{ok:!0,value:$.output};if(B.ok===!1)return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"error",error:{code:"invalid_tool_result",message:`The answer for "${W}" did not match its output schema: ${B.errors.join(", ")}`,toolCallId:J.toolCallId,retryable:!0}};return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"ok",output:B.value}}return G(`The answer for "${W}" carried neither an approval nor an output.`)}attachToHistory(Q,$){let Z=this.amend(Q.message);Z.content.push($),this.unreported.add(Z),this.emit({type:"tool-result",messageId:Z.id,part:$})}markFileRejected(Q,$,Z){for(let G of this.history){if(!G.content.some((Y)=>Y.type==="file"&&Y.fileId===Q&&!Y.providerRejected))continue;let H=this.produced.includes(G)?G:this.amend(G);if(H.content=H.content.map((Y)=>Y.type==="file"&&Y.fileId===Q&&!Y.providerRejected?{...Y,providerRejected:!0}:Y),H!==this.current)this.unreported.add(H)}if(!this.config.logErrors)return;let J=`[gemi/ai] agent "${this.config.name}": the provider refused file ${Q}${Z.status!==void 0?` (${Z.status})`:""}; it was left out of the request and will not be sent again: ${$}`,W={agent:this.config.name,runId:this.runId,...this.params.threadId?{threadId:this.params.threadId}:{},fileId:Q,...Z},X=!1;try{e.warning(J,W),X=!0}catch{}if(!X||Bun.env.NODE_ENV==="development")console.warn(J,W)}amend(Q){let $=this.amended.get(Q.id);if($)return $;let Z={...Q,content:[...Q.content]},J=this.history.indexOf(Q);if(J>=0)this.history[J]=Z;return this.produced.push(Z),this.amended.set(Q.id,Z),Z}async reportDeferred(){let Q=[...this.unreported];this.unreported.clear();for(let $ of Q)await this.report($)}async finalizeAborted(){if(this.nestedSettling.size>0)await Promise.all([...this.nestedSettling]);for(let $ of this.openCalls()){if($.message===this.current)continue;this.attachToHistory($,{type:"tool-result",toolCallId:$.call.toolCallId,name:$.call.name,status:"denied",cause:"stopped",reason:this.stopReason})}await this.reportDeferred();let Q=this.current;if(Q){let $=new Set(Q.content.filter((Z)=>Z.type==="tool-result").map((Z)=>Z.toolCallId));for(let Z of[...Q.content]){if(Z.type!=="tool-call"||$.has(Z.toolCallId))continue;delete Z.partial,this.addResult(Q,{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"denied",cause:"stopped",reason:this.stopReason})}}if(this.timedOutAfter!==void 0){this.fail({code:"timeout",message:`The run did not finish within its time limit of ${$9(this.timedOutAfter)} (maxRunDurationMs: ${this.timedOutAfter}) and was stopped.`,retryable:!0}),this.finishReason="error",await this.finalizeMessage("error");return}this.finishReason="aborted",await this.finalizeMessage("aborted")}}function q$(Q){if(Q.answeredBy==="client")return Q.inputSchema===G9?"question":"client";return Q.requiresApproval?"approval":null}function N$(Q){if(!Q||!Q.trim())return{};try{return JSON.parse(Q)}catch{return Q}}function KZ(Q,$){return Q.descriptors($).map((Z)=>c.create({name:Z.name,description:Z.description,inputSchema:Z.inputSchema,requiresApproval:Z.requiresApproval,execute:(J,W)=>{let X=SQ.getStore()?.req;if(!X)throw new T(`"${Z.name}" calls an api route as the user who started this run, and this run was not started inside a request. Run it from an AgentController, or give this agent tools that do not go through the MCP registry.`);return Q.execute({kind:"local",req:X},Z.name,J,W)}}))}function zZ(Q){if(Q==="auto")return;let $=/^(\d+)x(\d+)$/.exec(Q);if(!$)throw Error(`An image size is "WIDTHxHEIGHT" or "auto"; got ${JSON.stringify(Q)}.`);let Z=Number($[1]),J=Number($[2]);if(Z%16!==0||J%16!==0)throw Error(`Image size ${Q} is not supported: width and height must both be divisible by 16.`);if(Math.max(Z/J,J/Z)>3)throw Error(`Image size ${Q} is not supported: the maximum aspect ratio is 3:1, either way up.`)}function T$(Q,$){if(Q.size!==void 0)try{zZ(Q.size)}catch(Z){throw Error(`${$}: ${Z.message}`)}if(Q.background==="transparent"&&Q.format==="jpeg")throw Error(`${$}: a transparent background needs "png"; JPEG has no alpha channel.`);if(Q.compression!==void 0){let Z=Q.compression;if(!Number.isInteger(Z)||Z<0||Z>100)throw Error(`${$}: compression is an integer from 0 to 100; got ${Z}.`)}}function k$(Q,$){if(Q instanceof File)return Q;let Z=Q.type||"image/png",J=Z==="image/jpeg"?"jpg":Z.split("/")[1]??"png";return new File([Q],`${$}.${J}`,{type:Z})}class B9{name;provider;settings;constructor(Q){let{name:$,provider:Z,...J}=Q;T$(J,`ImageModel "${$}"`),this.name=$,this.provider=Z,this.settings=J}static create(Q){return new B9(Q)}async generate(Q){let $=this.merge(Q);return A$(await this.provider.generate({prompt:Q.prompt,...$,signal:Q.signal}))}async edit(Q){let $=this.merge(Q);return A$(await this.provider.edit({prompt:Q.prompt,...$,images:Q.images.map((Z,J)=>k$(Z,`image-${J}`)),...Q.mask?{mask:k$(Q.mask,"mask")}:{},signal:Q.signal}))}merge(Q){let $={...this.settings,...Q.size!==void 0?{size:Q.size}:{},...Q.quality!==void 0?{quality:Q.quality}:{},...Q.background!==void 0?{background:Q.background}:{},...Q.format!==void 0?{format:Q.format}:{},...Q.compression!==void 0?{compression:Q.compression}:{}};return T$($,`ImageModel "${this.name}"`),$}}function A$(Q){return{image:new Blob([Q.bytes],{type:Q.mimeType}),mimeType:Q.mimeType,size:Q.size,usage:Q.usage}}function m(Q){return typeof process>"u"?void 0:process.env?.[Q]}var BZ="preview";function E$(Q){let $=Q.trim().replace(/\/+$/,"");if(!$)return"";return`${$.replace(/\/openai(?:\/v1)?$/i,"")}/openai`}function DZ(Q){return/^\d{4}-\d{2}-\d{2}/.test(Q)?"":"/v1"}function TQ(Q,$={}){return{base:(Q.baseURL??m("OPENAI_BASE_URL")??"https://api.openai.com/v1").replace(/\/+$/,""),query:"",headers:async()=>{let J=Q.apiKey??m("OPENAI_API_KEY");return{...J?{authorization:`Bearer ${J}`}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}function UZ(Q){let $=Q.baseURL??Q.endpoint??m("AZURE_OPENAI_ENDPOINT");if($)return E$($);let Z=Q.resourceName??m("AZURE_OPENAI_RESOURCE_NAME")??m("AZURE_RESOURCE_NAME");return Z?E$(`https://${Z.trim()}.cognitiveservices.azure.com`):""}function kQ(Q,$={}){let Z=Q.apiVersion??m("AZURE_OPENAI_API_VERSION")??BZ;return{base:`${UZ(Q)}${DZ(Z)}`,query:`?api-version=${encodeURIComponent(Z)}`,headers:async()=>{if(Q.getToken)return{authorization:`Bearer ${await Q.getToken()}`,...Q.headers};let J=Q.apiKey??m("AZURE_OPENAI_API_KEY");return{...J?{"api-key":J}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}var FZ=500,b$=20000;function jZ(Q,$){if(!Q)return;let Z=Q.trim();if(/^\d+(\.\d+)?$/.test(Z))return Math.max(0,Number(Z)*1000);let J=Date.parse(Z);if(Number.isNaN(J))return;return Math.max(0,J-$)}function x$(Q,$){let Z=Math.min(b$,FZ*2**Q);return Math.round(Z*(0.5+$()*0.5))}function LZ(Q){return Q===429||Q===408||Q===409||Q>=500}function CZ(Q,$){return LZ(Q)&&k($).retryable}function w$(Q){return Q.reason??new DOMException("The operation was aborted.","AbortError")}function PZ(Q,$){return new Promise((Z,J)=>{let W=setTimeout(Z,Q);$?.addEventListener("abort",()=>{clearTimeout(W),J(w$($))},{once:!0})})}async function GQ(Q,$,Z){let J=Z.fetchImpl??((K,z)=>fetch(K,z)),W=Z.sleep??PZ,X=Z.random??Math.random,G=Z.now??Date.now,V=Math.max(0,Z.maxRetries),H=async(K)=>{let z=Z.signal;if(!z)return await W(K);z.throwIfAborted();let B;try{await Promise.race([W(K,z),new Promise((U,j)=>{B=()=>j(w$(z)),z.addEventListener("abort",B,{once:!0})})])}finally{if(B)z.removeEventListener("abort",B)}},Y;for(let K=0;K<=V;K++){Z.signal?.throwIfAborted();let z=new AbortController,B=()=>z.abort(Z.signal?.reason);Z.signal?.addEventListener("abort",B,{once:!0});let U=!1,j=Z.timeoutMs>0?setTimeout(()=>{U=!0,z.abort()},Z.timeoutMs):void 0,D;try{D=await J(Q,{...$,signal:z.signal})}catch(N){if(j!==void 0)clearTimeout(j);if(Z.signal?.removeEventListener("abort",B),Z.signal?.aborted)throw N;if(Y=U?new KQ(Z.timeoutMs):N,U&&Z.retryTimeouts===!1)throw Y;if(K===V)throw Y;await H(x$(K,X));continue}if(j!==void 0)clearTimeout(j);if(D.ok)return D;Z.signal?.removeEventListener("abort",B);let L=await OZ(D),F=new h(D.status,L,D.headers.get("x-request-id")??void 0);if(K===V||!CZ(D.status,F))throw F;let S=jZ(D.headers.get("retry-after"),G());await H(S===void 0?x$(K,X):Math.min(S,b$)),Y=F}throw Y??Error("Provider request failed with no response.")}async function OZ(Q){let $;try{$=await Q.text()}catch{return null}try{return JSON.parse($)}catch{return $}}var D9=300000;function U9(Q){return{generationsUrl:`${Q.base}/images/generations${Q.query}`,editsUrl:`${Q.base}/images/edits${Q.query}`,headers:Q.headers,timeoutMs:Q.timeoutMs,maxRetries:Q.maxRetries}}class AQ extends Error{code;retryable;constructor(Q,$={}){super(Q.message,$);this.name="ImageRequestError",this.code=Q.code,this.retryable=Q.retryable}}var qZ={png:"image/png",jpeg:"image/jpeg"};function NZ(Q){let $=Number(Q?.input_tokens??0),Z=Number(Q?.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q?.total_tokens??$+Z)},W=Q?.input_tokens_details?.image_tokens;if(typeof W==="number")J.imageInputTokens=W;let X=Q?.output_tokens_details?.image_tokens;if(typeof X==="number")J.imageOutputTokens=X;return J}function _Z(Q){let $=atob(Q),Z=new Uint8Array($.length);for(let J=0;J<$.length;J++)Z[J]=$.charCodeAt(J);return Z}function MZ(Q){let Z=Q?.data?.[0]?.b64_json;if(typeof Z!=="string"||Z.length===0)throw new AQ({code:"provider_error",message:"The provider answered an image call with no base64 image data.",retryable:!1});let J=typeof Q.output_format==="string"?Q.output_format:"png";return{bytes:_Z(Z),mimeType:qZ[J]??`image/${J}`,size:typeof Q.size==="string"?Q.size:"",...typeof Q.background==="string"?{background:Q.background}:{},usage:NZ(Q.usage)}}async function I$(Q,$,Z,J){let W;try{W=await GQ(Q,$,{maxRetries:Z.maxRetries,timeoutMs:Z.timeoutMs,retryTimeouts:!1,signal:J.signal,fetchImpl:Z.fetchImpl})}catch(X){if(J.signal?.aborted)throw X;throw new AQ(k(X),{cause:X})}return MZ(await W.json())}async function v$(Q,$,Z={}){return await I$(Q.generationsUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify($)},Q,Z)}async function f$(Q,$,Z={}){return await I$(Q.editsUrl,{method:"POST",headers:await Q.headers(),body:$},Q,Z)}class EQ{static models(){return[]}modelName(){return this.model}async generate(Q){return await v$(this.endpoint(),this.body(Q),{signal:Q.signal})}async edit(Q){let $=new FormData;for(let[Z,J]of Object.entries(this.body(Q)))if(J!==void 0)$.set(Z,String(J));for(let Z of Q.images)$.append("image[]",Z,Z.name);if(Q.mask)$.set("mask",Q.mask,Q.mask.name);return await f$(this.endpoint(),$,{signal:Q.signal})}body(Q){return{model:this.modelName(),prompt:Q.prompt,...Q.size?{size:Q.size}:{},...Q.quality?{quality:Q.quality}:{},...Q.background?{background:Q.background}:{},...Q.format?{output_format:Q.format}:{},...Q.compression!==void 0?{output_compression:Q.compression}:{}}}normalizeError(Q){return k(Q)}}var h$=["gpt-image-2","gpt-image-1.5","gpt-image-1"];class F9 extends EQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new F9(Q,$)}static models(){return h$}endpoint(){return U9(TQ(this.config,{timeoutMs:D9}))}}class j9 extends EQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new j9(Q,$)}static models(){return h$}modelName(){return this.config.deployment??this.model}endpoint(){return U9(kQ(this.config,{timeoutMs:D9}))}}var u$=3;function L9(Q){let $=new Map;for(let Z of Q)for(let J of Z.content??[]){if(J.type!=="file"||!J.fileId||$.has(J.fileId))continue;$.set(J.fileId,{name:J.name,mimeType:J.mimeType})}return $}function c$(Q,$,Z=new Map){if(!($ instanceof h))return[];if($.status!==400&&$.status!==404)return[];let J=RZ($.body);if(!J)return[];let W=SZ(Q.input);if(W.length===0)return[];let X=/^input\[(\d+)\]\.content\[(\d+)\]\.file_id$/.exec(J.param??"");if(X){let Y=Q.input[Number(X[1])],K=P9(Y)[Number(X[2])],z=K&&typeof K.file_id==="string"?K.file_id:void 0;if(z)return[z]}let G=J.message??"",V=g$(W.map((Y)=>Y.fileId).filter((Y)=>TZ(G,Y)));if(V.length>0)return V;let H=/Expected (image type|context stuffing file type) to be a supported format:.*but got \.([a-z0-9]+)\.?\s*$/is.exec(G);if(H){let Y=H[1].toLowerCase()==="image type"?"input_image":"input_file",K=H[2].toLowerCase(),z=g$(W.filter((U)=>U.type===Y).map((U)=>U.fileId)),B=z.filter((U)=>(Z.get(U)?.name??"").trim().toLowerCase().endsWith(`.${K}`));if(B.length===1)return B;if(B.length===0&&z.length===1)return z}return[]}function m$(Q,$,Z=new Map){return{...Q,input:Q.input.map((J)=>{let W=P9(J);if(!W.some((X)=>y$(X,$)))return J;return{...J,content:W.map((X)=>y$(X,$)?{type:"input_text",text:C9(Z.get(String(X.file_id))?.name)}:X)}})}}function C9(Q){return`[${Q?`attachment ${JSON.stringify(Q)}`:"an attachment"} could not be read by the provider and is not shown to you. Tell the user if it matters to the answer; uploading it again may help.]`}function y$(Q,$){return typeof Q.file_id==="string"&&$.has(Q.file_id)}function P9(Q){let $=Q?.content;return Array.isArray($)?$:[]}function SZ(Q){let $=[];for(let Z of Q)for(let J of P9(Z))if(typeof J.file_id==="string"&&J.file_id)$.push({type:String(J.type),fileId:J.file_id});return $}function RZ(Q){if(!Q||typeof Q!=="object")return null;let $=Q,Z=$.error&&typeof $.error==="object"?$.error:Q;return{message:typeof Z.message==="string"?Z.message:void 0,param:typeof Z.param==="string"?Z.param:void 0}}function TZ(Q,$){let Z=$.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(^|[^A-Za-z0-9_-])${Z}($|[^A-Za-z0-9_-])`).test(Q)}function g$(Q){return[...new Set(Q)]}async function*kZ(Q){let $="",Z="",J=[],W,X=()=>{if(J.length===0&&!Z)return null;let H={event:Z,data:J.join(`
16
+ `),id:W};return Z="",J=[],W=void 0,H.data?H:null},G=(H)=>{let Y=H.endsWith("\r")?H.slice(0,-1):H;if(Y==="")return X();if(Y.startsWith(":"))return null;let K=Y.indexOf(":"),z=K===-1?Y:Y.slice(0,K),B=K===-1?"":Y.slice(K+1);if(B.startsWith(" "))B=B.slice(1);if(z==="event")Z=B;else if(z==="data")J.push(B);else if(z==="id")W=B;return null};for await(let H of Q){$+=H;let Y=$.indexOf(`
17
17
  `);while(Y!==-1){let K=$.slice(0,Y);$=$.slice(Y+1);let z=G(K);if(z)yield z;Y=$.indexOf(`
18
- `)}}if($.length>0){let V=G($);if(V)yield V}let H=X();if(H)yield H}async function*c$(Q,$={}){let Z=new Map,J=new Set,W=!1;for await(let X of SZ(Q)){if(X.data==="[DONE]")break;let G;try{G=JSON.parse(X.data)}catch{continue}switch(typeof G.type==="string"?G.type:X.event){case"response.output_text.delta":{let V=String(G.delta??"");if(!V)break;yield $.structuredOutput?{type:"output-delta",delta:V}:{type:"text-delta",delta:V};break}case"response.reasoning_summary_text.delta":case"response.reasoning_text.delta":{let V=String(G.delta??"");if(!V)break;yield{type:"reasoning-delta",delta:V,id:G.item_id};break}case"response.output_item.added":{let V=G.item;if(!V)break;if(V.type==="function_call"){let Y=String(V.id??G.item_id??V.call_id??"");Z.set(Y,{callId:String(V.call_id??Y),name:String(V.name??""),namespace:typeof V.namespace==="string"&&V.namespace?V.namespace:void 0,done:!1})}break}case"response.function_call_arguments.delta":{let V=Z.get(String(G.item_id??""));if(!V)break;let Y=String(G.delta??"");if(!Y)break;yield{type:"tool-call-delta",toolCallId:V.callId,name:V.name,argsDelta:Y,...V.namespace?{namespace:V.namespace}:{}};break}case"response.function_call_arguments.done":{let V=String(G.item_id??""),Y=Z.get(V);if(!Y)break;Y.done=!0,yield{type:"tool-call",toolCallId:Y.callId,name:Y.name,args:String(G.arguments??""),...Y.namespace?{namespace:Y.namespace}:{}};break}case"response.output_item.done":{let V=G.item;if(!V)break;if(V.type==="function_call"){let Y=String(V.id??G.item_id??V.call_id??""),K=Z.get(Y);if(K?.done)break;let z=(typeof V.namespace==="string"?V.namespace:"")||K?.namespace;if(yield{type:"tool-call",toolCallId:String(V.call_id??Y),name:String(V.name??K?.name??""),args:String(V.arguments??""),...z?{namespace:z}:{}},K)K.done=!0;break}if(V.type==="tool_search_call"||V.type==="tool_search_output"){let Y=RZ(V);if(Y.loaded.length===0&&Y.namespaces.length===0)break;let K=String(V.tool_search_call_id??V.id??"");if(J.has(K))break;J.add(K),yield{type:"tool-search",...Y}}break}case"response.refusal.done":{yield{type:"error",error:{code:"content_filtered",message:String(G.refusal??"The model refused to answer."),retryable:!1}};break}case"response.completed":{W=!0,yield{type:"finish",reason:"stop",usage:O9(G.response?.usage)};break}case"response.incomplete":{W=!0;let V=O9(G.response?.usage),Y=G.response?.incomplete_details?.reason;if(Y==="content_filter"){yield{type:"error",error:{code:"content_filtered",message:kZ(G.response?.content_filters),retryable:!1}},yield{type:"finish",reason:"error",usage:V};break}yield{type:"finish",reason:Y==="max_output_tokens"?"length":"stop",usage:V};break}case"response.failed":case"error":{W=!0;let V=G.response?.error??G.error??G;yield{type:"error",error:TZ(V)},yield{type:"finish",reason:"error",usage:O9(G.response?.usage)};break}}if(W)return}if(!W)yield{type:"error",error:{code:"provider_error",message:"The provider stream ended without a terminal event.",retryable:!0}},yield{type:"finish",reason:"error",usage:o()}}function RZ(Q){let $=[],Z=[];return m$(Q.results??Q.tools??Q.loaded??Q.output,$,Z,0),{loaded:P9($),namespaces:P9(Z)}}function m$(Q,$,Z,J){if(!Array.isArray(Q)||J>4)return;for(let W of Q){if(typeof W==="string"){$.push(W);continue}if(!W||typeof W!=="object")continue;let X=W,G=typeof X.name==="string"?X.name:typeof X.tool_name==="string"?X.tool_name:"",H=X.tools??X.functions;if(Array.isArray(H)){if(G)Z.push(G);m$(H,$,Z,J+1);continue}if(G)$.push(G)}}function P9(Q){return Q.filter(($,Z)=>Q.indexOf($)===Z)}function kZ(Q){if(!Array.isArray(Q))return"The provider's content filter blocked this request.";let Z=[];for(let J of Q){if(!J||typeof J!=="object")continue;let W=J,X=W.content_filter_results;if(!X||typeof X!=="object")continue;for(let[G,H]of Object.entries(X))if(H&&typeof H==="object"&&H.filtered===!0)Z.push(`${G} (${String(W.source_type??"unknown")})`)}return Z.length===0?"The provider's content filter blocked this request.":`The provider's content filter blocked this request. Categories: ${P9(Z).join(", ")}.`}function TZ(Q){let $=typeof Q?.message==="string"?Q.message:"The provider stream failed.",Z=String(Q?.code??"").toLowerCase();if(Z==="rate_limit_exceeded")return{code:"rate_limited",message:$,retryable:!0};if(Z==="context_length_exceeded")return{code:"context_length_exceeded",message:$,retryable:!1};if(Z.includes("content_filter"))return{code:"content_filtered",message:$,retryable:!1};return{code:"provider_error",message:$,retryable:!0}}function o(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function O9(Q){if(!Q)return o();let $=Number(Q.input_tokens??0),Z=Number(Q.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q.total_tokens??$+Z)},W=Q.output_tokens_details?.reasoning_tokens;if(typeof W==="number")J.reasoningTokens=W;let X=Q.input_tokens_details?.cached_tokens;if(typeof X==="number")J.cachedInputTokens=X;return J}async function*p$(Q){if(!Q)return;let $=Q.getReader(),Z=new TextDecoder;try{while(!0){let{done:W,value:X}=await $.read();if(W)break;if(X)yield Z.decode(X,{stream:!0})}let J=Z.decode();if(J)yield J}finally{$.releaseLock()}}function q9(Q){return{responsesUrl:`${Q.base}/responses${Q.query}`,filesUrl:`${Q.base}/files${Q.query}`,headers:Q.headers,timeoutMs:Q.timeoutMs,maxRetries:Q.maxRetries}}async function*_9(Q,$,Z){let J,W=$,X=new Set;for(let G=0;J===void 0;G++)try{J=await GQ(Q.responsesUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify(W)},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,signal:Z.signal,fetchImpl:Q.fetchImpl})}catch(H){let V=G<y$?g$(W,H,Z.files).filter((K)=>!X.has(K)):[];if(V.length>0){let K=k(H).message;for(let z of V)X.add(z),yield{type:"file-rejected",fileId:z,message:K,...T(H)};W=u$(W,new Set(V),Z.files);continue}let Y=k(H);if(Y.code!=="aborted")yield{type:"error",error:Y,...T(H)};yield{type:"finish",reason:Y.code==="aborted"?"aborted":"error",usage:o()};return}try{yield*c$(p$(J.body),{structuredOutput:Z.structuredOutput})}catch(G){let H=k(G);if(H.code==="aborted"){yield{type:"finish",reason:"aborted",usage:o()};return}yield{type:"error",error:H},yield{type:"finish",reason:"error",usage:o()}}}async function N9(Q,$,Z="user_data"){let J=new FormData;J.set("purpose",Z),J.set("file",$);let X=await(await GQ(Q.filesUrl,{method:"POST",headers:await Q.headers(),body:J},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,fetchImpl:Q.fetchImpl})).json();if(!X?.id)throw Error("The provider accepted the upload but returned no file id.");return X.id}function M9(Q){let $=AZ(Q);if($.startsWith("gpt-3.5")||$.startsWith("text-")||$.startsWith("davinci"))return{reasoning:!1,structuredOutput:!1,fileInput:!1,parallelToolCalls:!0,toolSearch:!1};let Z=EZ($);if(Z?.kind==="o")return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:Z.major>1,toolSearch:d$(Z)};if(Z?.kind==="gpt")return{reasoning:Z.major>=5,structuredOutput:Z.major>4||$.startsWith("gpt-4o")||$.startsWith("gpt-4.1"),fileInput:Z.major>4||$.startsWith("gpt-4o")||$.startsWith("gpt-4.1"),parallelToolCalls:!0,toolSearch:d$(Z)};return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:!0,toolSearch:!0}}function d$(Q){if(Q.kind==="o")return Q.major>=5;return Q.major>5||Q.major===5&&Q.minor>=2}function AZ(Q){return Q.trim().toLowerCase()}function EZ(Q){let $=/^gpt-(\d+)(?:\.(\d+))?/.exec(Q);if($?.[1])return{kind:"gpt",major:Number($[1]),minor:Number($[2]??0)};let Z=/^o(\d+)(?:[-.]|$)/.exec(Q);if(Z?.[1])return{kind:"o",major:Number(Z[1]),minor:0};return null}function R9(Q,$){let{capabilities:Z}=$,J={model:$.model,input:xZ(Q.messages,Z),stream:!0};if(Q.systemPrompt)J.instructions=Q.systemPrompt;let W=uZ(Q.tools,Z);if(W.length>0){if(J.tools=W,!Z.parallelToolCalls)J.parallel_tool_calls=!1}if(Q.output)J.text={format:{type:"json_schema",name:Q.output.name,schema:Q.output.schema,strict:Q.output.strict}};if(Q.reasoning&&Z.reasoning)J.reasoning=Q.reasoning==="none"?{effort:"none"}:{effort:Q.reasoning,summary:"auto"};if(typeof Q.temperature==="number")J.temperature=Q.temperature;if(typeof Q.maxOutputTokens==="number")J.max_output_tokens=Q.maxOutputTokens;return J}function xZ(Q,$){let Z=[];for(let J of Q){let W=J.role,X=[],G=()=>{if(X.length===0)return;Z.push({type:"message",role:W,content:X}),X=[]};for(let H of J.content??[])switch(H.type){case"text":{if(!H.text)break;X.push(n(W,H.text));break}case"output":{if(H.partial)break;X.push(n(W,JSON.stringify(H.value)));break}case"file":{if(W==="assistant")break;let V=IZ(H);if(!$.fileInput){if(V)X.push(n(W,S9(H,!1)));break}if(H.fileId?.startsWith(I))throw Error(`FilePart.fileId holds a gemi attachment id (${H.fileId}). That field is the *provider's* file id, from \`fileId\` on the upload response; the \`attachmentId\` goes in \`FilePart.attachmentId\`, is shown to the model as text, and is resolved by a tool through \`ctx.attachments\`.`);if(!H.fileId&&!V)throw Error("FilePart.fileId is empty and there is no `attachmentId` either. `fileId` is the *provider's* file id and `attachmentId` is gemi's (`gemi_att_\u2026`), both from the upload response; an upload always answers at least one, so a part with neither was built from something other than that answer.");if(H.providerRejected){if(V)X.push(n(W,S9(H,!1)));X.push(n(W,C9(H.name)));break}if(V)X.push(n(W,S9(H,!!H.fileId)));if(H.fileId)X.push(vZ(H));break}case"reasoning":{G();let V=yZ(H);if(V)Z.push(V);break}case"tool-call":{if(H.partial)break;G(),Z.push({type:"function_call",call_id:H.toolCallId,name:String(H.name),arguments:JSON.stringify(H.input??{})});break}case"tool-result":{G(),Z.push({type:"function_call_output",call_id:H.toolCallId,output:gZ(H)});break}}G()}return bZ(Z)}var wZ="No result was recorded for this tool call. Assume it did not complete.";function bZ(Q){let $=new Set,Z=new Set,J=[];for(let X of Q){if(X.type==="function_call"){let G=String(X.call_id);if($.has(G))continue;$.add(G)}else if(X.type==="function_call_output"){let G=String(X.call_id);if(!$.has(G)||Z.has(G))continue;Z.add(G)}J.push(X)}if(Z.size===$.size)return J;let W=[];for(let X of J){if(W.push(X),X.type!=="function_call")continue;let G=String(X.call_id);if(Z.has(G))continue;Z.add(G),W.push({type:"function_call_output",call_id:G,output:wZ})}return W}function n(Q,$){return{type:Q==="assistant"?"output_text":"input_text",text:$}}function IZ(Q){let $=Q.attachmentId;return typeof $==="string"&&$.startsWith(I)?$:void 0}function S9(Q,$){let Z=[`id=${JSON.stringify(Q.attachmentId)}`];if(Q.name)Z.push(`name=${JSON.stringify(Q.name)}`);if(Q.mimeType)Z.push(`mimeType=${JSON.stringify(Q.mimeType)}`);let J=`attachment ${Z.join(" ")}`;return $?`[${J}]`:`[${J} \u2014 its contents are not shown to you; a tool can read the file by this id]`}function vZ(Q){let $=Q.mimeType?.trim().toLowerCase()??"";return{type:($?$.startsWith("image/")&&$!=="image/svg+xml":fZ(Q.name))?"input_image":"input_file",file_id:Q.fileId}}function fZ(Q){let $=/\.([a-z0-9]+)$/.exec(Q?.trim().toLowerCase()??"");return $?.[1]!==void 0&&hZ.has($[1])}var hZ=new Set(["jpeg","jpg","png","gif","webp"]);function yZ(Q){if(!Q.id)return null;let $={type:"reasoning",id:Q.id};return $.summary=Q.text?[{type:"summary_text",text:Q.text}]:[],$}function gZ(Q){if(Q.status==="ok")return typeof Q.output==="string"?Q.output:JSON.stringify(Q.output??null);if(Q.status==="denied"){let $=Q.reason?` Reason given: ${Q.reason}`:"";if(Q.cause==="stopped")return`The run was stopped before this tool call could complete, so it did not run.${$}`;if(Q.cause==="interrupted")return`The run was interrupted (the server stopped) while this tool call was in progress, so its result was lost. It may have run in part or in full: check its effects before repeating it.${$}`;return`The user declined this tool call, so it did not run.${$}`}return`The tool call failed and produced no result. Error (${Q.error?.code??"unknown"}): ${Q.error?.message??"no message"}`}function l$(Q){return Array.isArray(Q.tools)}function uZ(Q,$){if(!Q||Q.length===0)return[];if(!$.toolSearch){let W=[];for(let X of Q)if(l$(X))for(let G of X.tools)W.push(xQ(G,!1));else W.push(xQ(X,!1));return W}let Z=[],J=!1;for(let W of Q)if(l$(W)){let X=W.tools.map((G)=>{if(G.deferred)J=!0;return xQ(G,!0)});Z.push({type:"namespace",name:W.name,description:W.description,tools:X})}else{if(W.deferred)J=!0;Z.push(xQ(W,!0))}if(J)Z.push({type:"tool_search"});return Z}function xQ(Q,$){let Z={type:"function",name:Q.name,description:Q.description,parameters:Q.parameters,strict:Q.strict};if($&&Q.deferred)Z.defer_loading=!0;return Z}class s{static models(){return[]}normalizeError(Q){return k(Q)}}var i$=["gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.4-nano","gpt-5.2","gpt-5.1","gpt-5","gpt-5-mini","gpt-5-nano","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4o","gpt-4o-mini","o4-mini","o3","o3-mini"];class k9 extends s{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=M9(Q),this.config=$}static model(Q,$){return new k9(Q,$)}static models(){return i$}stream(Q){let $=R9(Q,{model:this.model,capabilities:this.capabilities});return _9(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output),files:L9(Q.messages)})}upload(Q){return N9(this.endpoint(),Q)}endpoint(){return q9(kQ(this.config))}}class T9 extends s{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=M9(Q),this.config=$}static model(Q,$){return new T9(Q,$)}static models(){return i$}stream(Q){let $=R9(Q,{model:this.deployment(),capabilities:this.capabilities});return _9(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output),files:L9(Q.messages)})}upload(Q){return N9(this.endpoint(),Q,"assistants")}deployment(){return this.config.deployment??this.model}endpoint(){return q9(TQ(this.config))}}function cZ(Q){switch(Q.type){case"text-delta":case"reasoning-delta":case"tool-call-delta":case"tool-call":case"tool-search":case"output-delta":return!0;default:return!1}}var o$=Symbol("timed-out");class VQ extends s{model;capabilities;entries;options;constructor(Q,$={}){super();if(Q.length===0)throw Error("FallbackProvider needs at least one provider.");for(let Z of Q)if(Z.timeoutMs!==void 0&&!(Z.timeoutMs>0))throw Error(`FallbackProvider: timeoutMs for ${Z.provider.model} must be a positive number, got ${Z.timeoutMs}.`);this.entries=[...Q],this.options=$,this.model=Q[0].provider.model,this.capabilities=mZ(Q.map((Z)=>Z.provider.capabilities))}static chain(Q,$){return new VQ(Q,$)}from(Q){if(!Number.isInteger(Q)||Q<0||Q>=this.entries.length)throw RangeError(`FallbackProvider.from(${Q}): the chain has ${this.entries.length} entries.`);return new VQ(this.entries.slice(Q),this.options)}leg(Q){let $=this.from(Q).entries[0];return new VQ([$],this.options)}upload(Q){return this.entries[0].provider.upload(Q)}normalizeError(Q){return this.entries[0].provider.normalizeError(Q)}stream(Q){return this.run(Q)}async*run(Q){let $,Z=Q.signal;for(let J=0;J<this.entries.length;J++){let W=this.entries[J],X=J===this.entries.length-1,G=J+1,H=W.provider.model,V=new AbortController,Y=()=>V.abort(Z?.reason);if(Z?.aborted)V.abort(Z.reason);else Z?.addEventListener("abort",Y,{once:!0});let K=[],z=!1,B=!1,D,F,U=!1,O,j=!1,q=(C)=>{let P=$?S(S(N(),$),C.usage):C.usage;return $=void 0,{...C,usage:P}};try{O=W.provider.stream({...Q,...W.reasoning!==void 0?{reasoning:W.reasoning}:{},signal:V.signal})[Symbol.asyncIterator]();let C=!0;for(;;){let P=C&&W.timeoutMs!==void 0?await pZ(O.next(),W.timeoutMs):await O.next();if(P===o$){U=!0,F={error:{code:"provider_error",message:`${H} sent nothing within ${W.timeoutMs}ms.`,retryable:!0}};break}if(C=!1,P.done){j=!0;break}let L=P.value;if(z){if(L.type==="finish")D=S(D??N(),L.usage),B=!0,yield q(L);else{if(L.type==="error")F={error:L.error};yield L}continue}if(cZ(L)){z=!0,yield*K.splice(0),yield L;continue}if(L.type==="error")F={error:L.error,...L.status!==void 0?{status:L.status}:{},...L.requestId!==void 0?{requestId:L.requestId}:{}};else if(L.type==="finish"){if(D=S(D??N(),L.usage),L.reason==="error"&&!F)F={error:{code:"provider_error",message:`${H} ended the call with an error and did not say which.`,retryable:!1}}}K.push(L)}}catch(C){let P=W.provider.normalizeError(C);if(z){if(P.code!=="aborted")yield{type:"error",error:P,...T(C)};this.report({index:J,model:H,attempt:G,usage:D,outcome:A9(P),error:P}),yield q({type:"finish",reason:P.code==="aborted"?"aborted":"error",usage:N()});return}F={error:P,...T(C)}}finally{if(Z?.removeEventListener("abort",Y),!j)V.abort(),O?.return?.()?.catch(()=>{})}if(z){if(!B&&$)yield{type:"finish",reason:F?"error":"stop",usage:$},$=void 0;this.report({index:J,model:H,attempt:G,usage:D,outcome:F?A9(F.error):"ok",...F?{error:F.error}:{}});return}if(Z?.aborted){this.report({index:J,model:H,attempt:G,usage:D,outcome:"aborted"}),yield q({type:"finish",reason:"aborted",usage:D??N()});return}if(!F){this.report({index:J,model:H,attempt:G,usage:D,outcome:"ok"});for(let C of K)yield C.type==="finish"?q(C):C;return}let _=!X&&F.error.code!=="aborted"&&this.shouldFallBack(F.error,{index:J,model:H,timedOut:U,...F.status!==void 0?{status:F.status}:{},...F.requestId!==void 0?{requestId:F.requestId}:{}});if(this.report({index:J,model:H,attempt:G,usage:D,outcome:_?"fallback":A9(F.error),error:F.error}),_){if(D)$=S($??N(),D);continue}let w=!1,v;for(let C of K){if(C.type==="finish"){v=C;continue}if(C.type==="error")w=!0;yield C}if(!w&&F.error.code!=="aborted")yield{type:"error",error:F.error,...F.status!==void 0?{status:F.status}:{},...F.requestId!==void 0?{requestId:F.requestId}:{}};yield q({type:"finish",reason:F.error.code==="aborted"?"aborted":v?.reason??"error",usage:D??N()});return}}shouldFallBack(Q,$){let Z=this.options.fallbackOn??((J)=>J.retryable);try{return Z(Q,$)}catch{return!1}}report(Q){if(Q.usage===void 0)delete Q.usage;try{this.options.onUsage?.(Q)}catch{}}}function A9(Q){return Q.code==="aborted"?"aborted":"failed"}function mZ(Q){return{reasoning:Q.every(($)=>$.reasoning),structuredOutput:Q.every(($)=>$.structuredOutput),fileInput:Q.every(($)=>$.fileInput),parallelToolCalls:Q.every(($)=>$.parallelToolCalls),toolSearch:Q.every(($)=>$.toolSearch)}}function pZ(Q,$){let Z,J=new Promise((W)=>{Z=setTimeout(()=>W(o$),$)});return Promise.race([Q,J]).finally(()=>clearTimeout(Z))}async function dZ(Q,$,Z={}){let J=Z.samples??1;if(!Number.isInteger(J)||J<1)throw RangeError(`evalChain: samples must be a positive integer, got ${J}.`);let W=[];for(let X=0;X<Q.entries.length;X++){let G=Q.leg(X),H={index:X,model:G.model,results:[],errors:[]};for(let V=0;V<J;V++)try{H.results.push(await $(G,{index:X,sample:V}))}catch(Y){H.errors.push({sample:V,error:Y})}W.push(H)}return W}class t extends Error{runId;requested;oldest;code="frame_cursor_evicted";constructor(Q,$,Z){super(`Frame ${$} of run ${Q} has been evicted; the oldest frame still buffered is ${Z}. Reload the thread instead of resuming.`);this.runId=Q;this.requested=$;this.oldest=Z}}class HQ extends Error{runId;code="live_run_not_found";constructor(Q){super(`No live run ${Q} in this process.`);this.runId=Q}}class wQ{ttlMs;maxFrames;maxAgeMs;runs=new Map;byThread=new Map;byClientRun=new Map;constructor(Q={}){this.ttlMs=Q.ttlMs??60000,this.maxFrames=Q.maxFrames??4096,this.maxAgeMs=Q.maxAgeMs===void 0?3600000:Q.maxAgeMs}register(Q,$={}){let Z={run:Q,threadId:$.threadId,owner:$.owner??null,clientRunId:$.clientRunId,frames:[],lastSeq:-1,lostBefore:0,ended:!1,evicted:!1,evictAt:null,expireAt:null,wake:new Set,version:0};if(this.runs.set(Q.runId,Z),$.threadId)this.byThread.set($.threadId,Q.runId);if($.clientRunId)this.byClientRun.set($.clientRunId,Q.runId);return this.scheduleExpiry(Z,$.maxRunDurationMs),this.pump(Z,$)}findByClientRunId(Q){let $=this.byClientRun.get(Q);return $&&this.runs.has($)?$:null}async find(Q){let $=this.byThread.get(Q.threadId);if(!$)return null;let Z=this.runs.get($);if(!Z)return null;return{runId:$,seq:Z.lastSeq}}get(Q){return this.runs.get(Q)?.run??null}ownerOf(Q){return this.runs.get(Q)?.owner??null}mayAccess(Q,$){let Z=this.ownerOf(Q);return Z===null||Z===$}isRunning(Q){let $=this.runs.get(Q);return!!$&&!$.ended&&!$.evicted}replay(Q,$){let Z=this.runs.get(Q);if(!Z)throw new HQ(Q);if($!==void 0&&$<Z.lostBefore)throw new t(Q,$,Z.lostBefore);let J=Z.frames[0]?.seq;return this.drain(Z,Q,$??J??Z.lastSeq+1)}clear(){for(let Q of this.runs.values()){if(Q.evictAt)clearTimeout(Q.evictAt);if(Q.expireAt)clearTimeout(Q.expireAt);Q.ended=!0,this.notify(Q)}this.runs.clear(),this.byThread.clear(),this.byClientRun.clear()}get size(){return this.runs.size}async pump(Q,$){let Z=Promise.resolve();try{for await(let J of Q.run.frames()){if(Q.evicted){let X=$.onEvent;if(X)Z=Z.then(()=>X(J.event)).catch((G)=>E9($,G));continue}if(Q.frames.push(J),Q.lastSeq=J.seq,Q.frames.length>this.maxFrames){let X=Q.frames.shift();if(X)Q.lostBefore=X.seq+1}this.notify(Q);let W=$.onEvent;if(W)Z=Z.then(()=>W(J.event)).catch((X)=>E9($,X))}}catch(J){E9($,J)}finally{if(Q.ended=!0,Q.expireAt)clearTimeout(Q.expireAt),Q.expireAt=null;this.notify(Q),this.scheduleEviction(Q),await Z}}async*drain(Q,$,Z){let J=Z;while(!0){let W=Q.version;for(;;){if(J<Q.lostBefore)throw new t($,J,Q.lostBefore);let X=Q.frames,G=X[0]?.seq;if(G===void 0)break;let H=Math.max(0,J-G);if(H>=X.length)break;let V=X[H];yield V,J=V.seq+1}if(Q.ended&&J>Q.lastSeq||Q.evicted)return;await this.wait(Q,W)}}wait(Q,$){if(Q.version!==$)return Promise.resolve();return new Promise((Z)=>Q.wake.add(Z))}notify(Q){Q.version++;let $=Array.from(Q.wake);Q.wake.clear();for(let Z of $)Z()}scheduleEviction(Q){if(Q.evictAt)return;let $=setTimeout(()=>{let Z=Q.run.runId;if(!Q.ended)Q.evicted=!0,Q.frames=[];if(this.runs.get(Z)===Q)this.runs.delete(Z);if(Q.threadId&&this.byThread.get(Q.threadId)===Z)this.byThread.delete(Q.threadId);if(Q.clientRunId&&this.byClientRun.get(Q.clientRunId)===Z)this.byClientRun.delete(Q.clientRunId);this.notify(Q)},this.ttlMs);$.unref?.(),Q.evictAt=$}scheduleExpiry(Q,$){if(this.maxAgeMs===null||$===null)return;let Z=$===void 0?this.maxAgeMs:Math.max(this.maxAgeMs,$+this.ttlMs);if(!Number.isFinite(Z)||Z>2147483647)return;let J=setTimeout(()=>{if(Q.expireAt=null,Q.ended)return;try{Q.run.stop({reason:`The run was still going ${Math.round(Z/1000)}s after it started, past the live-run registry's age limit.`})}catch{}this.scheduleEviction(Q)},Z);J.unref?.(),Q.expireAt=J}}var x9=new wQ;function E9(Q,$){try{Q.onInternalError?.($)}catch{}}class bQ{maxEntries;records=new Map;constructor(Q=1e5){this.maxEntries=Q}async record(Q,$){if(this.records.has(Q))return;this.records.set(Q,{...$});while(this.records.size>this.maxEntries){let Z=this.records.keys().next().value;if(Z===void 0)break;this.records.delete(Z)}}async get(Q){let $=this.records.get(Q);return $?{...$}:null}}var w9=new bQ;class I9{now;receipts=new Map;sweepAt=1024;constructor(Q=Date.now){this.now=Q}async claim(Q,$){let Z=this.now();if(this.receipts.size>=this.sweepAt)this.sweep(Z);let J=this.receipts.get(Q);if(J&&J.expiresAt>Z)return J.result?{status:"replay",result:structuredClone(J.result)}:{status:"blocked"};return this.receipts.set(Q,{expiresAt:$}),{status:"claimed"}}async complete(Q,$,Z){this.receipts.set(Q,{result:structuredClone($),expiresAt:Z})}async release(Q){let $=this.receipts.get(Q);if($&&!$.result)this.receipts.delete(Q)}get size(){return this.receipts.size}sweep(Q){for(let[$,Z]of this.receipts)if(Z.expiresAt<=Q)this.receipts.delete($);this.sweepAt=Math.max(1024,this.receipts.size*2)}}var n$="pending",b9="done:",lZ=`
18
+ `)}}if($.length>0){let H=G($);if(H)yield H}let V=X();if(V)yield V}async function*p$(Q,$={}){let Z=new Map,J=new Set,W=!1,X,G=(V,H)=>({type:"finish",reason:V,usage:H,...X?{model:X}:{}});for await(let V of kZ(Q)){if(V.data==="[DONE]")break;let H;try{H=JSON.parse(V.data)}catch{continue}let Y=typeof H.type==="string"?H.type:V.event,K=H.response?.model;if(typeof K==="string"&&K)X=K;switch(Y){case"response.output_text.delta":{let z=String(H.delta??"");if(!z)break;yield $.structuredOutput?{type:"output-delta",delta:z}:{type:"text-delta",delta:z};break}case"response.reasoning_summary_text.delta":case"response.reasoning_text.delta":{let z=String(H.delta??"");if(!z)break;yield{type:"reasoning-delta",delta:z,id:H.item_id};break}case"response.output_item.added":{let z=H.item;if(!z)break;if(z.type==="function_call"){let B=String(z.id??H.item_id??z.call_id??"");Z.set(B,{callId:String(z.call_id??B),name:String(z.name??""),namespace:typeof z.namespace==="string"&&z.namespace?z.namespace:void 0,done:!1})}break}case"response.function_call_arguments.delta":{let z=Z.get(String(H.item_id??""));if(!z)break;let B=String(H.delta??"");if(!B)break;yield{type:"tool-call-delta",toolCallId:z.callId,name:z.name,argsDelta:B,...z.namespace?{namespace:z.namespace}:{}};break}case"response.function_call_arguments.done":{let z=String(H.item_id??""),B=Z.get(z);if(!B)break;B.done=!0,yield{type:"tool-call",toolCallId:B.callId,name:B.name,args:String(H.arguments??""),...B.namespace?{namespace:B.namespace}:{}};break}case"response.output_item.done":{let z=H.item;if(!z)break;if(z.type==="function_call"){let B=String(z.id??H.item_id??z.call_id??""),U=Z.get(B);if(U?.done)break;let j=(typeof z.namespace==="string"?z.namespace:"")||U?.namespace;if(yield{type:"tool-call",toolCallId:String(z.call_id??B),name:String(z.name??U?.name??""),args:String(z.arguments??""),...j?{namespace:j}:{}},U)U.done=!0;break}if(z.type==="tool_search_call"||z.type==="tool_search_output"){let B=AZ(z);if(B.loaded.length===0&&B.namespaces.length===0)break;let U=String(z.tool_search_call_id??z.id??"");if(J.has(U))break;J.add(U),yield{type:"tool-search",...B}}break}case"response.refusal.done":{yield{type:"error",error:{code:"content_filtered",message:String(H.refusal??"The model refused to answer."),retryable:!1}};break}case"response.completed":{W=!0,yield G("stop",O9(H.response?.usage));break}case"response.incomplete":{W=!0;let z=O9(H.response?.usage),B=H.response?.incomplete_details?.reason;if(B==="content_filter"){yield{type:"error",error:{code:"content_filtered",message:EZ(H.response?.content_filters),retryable:!1}},yield G("error",z);break}yield G(B==="max_output_tokens"?"length":"stop",z);break}case"response.failed":case"error":{W=!0;let z=H.response?.error??H.error??H;yield{type:"error",error:xZ(z)},yield G("error",O9(H.response?.usage));break}}if(W)return}if(!W)yield{type:"error",error:{code:"provider_error",message:"The provider stream ended without a terminal event.",retryable:!0}},yield G("error",o())}function AZ(Q){let $=[],Z=[];return d$(Q.results??Q.tools??Q.loaded??Q.output,$,Z,0),{loaded:q9($),namespaces:q9(Z)}}function d$(Q,$,Z,J){if(!Array.isArray(Q)||J>4)return;for(let W of Q){if(typeof W==="string"){$.push(W);continue}if(!W||typeof W!=="object")continue;let X=W,G=typeof X.name==="string"?X.name:typeof X.tool_name==="string"?X.tool_name:"",V=X.tools??X.functions;if(Array.isArray(V)){if(G)Z.push(G);d$(V,$,Z,J+1);continue}if(G)$.push(G)}}function q9(Q){return Q.filter(($,Z)=>Q.indexOf($)===Z)}function EZ(Q){if(!Array.isArray(Q))return"The provider's content filter blocked this request.";let Z=[];for(let J of Q){if(!J||typeof J!=="object")continue;let W=J,X=W.content_filter_results;if(!X||typeof X!=="object")continue;for(let[G,V]of Object.entries(X))if(V&&typeof V==="object"&&V.filtered===!0)Z.push(`${G} (${String(W.source_type??"unknown")})`)}return Z.length===0?"The provider's content filter blocked this request.":`The provider's content filter blocked this request. Categories: ${q9(Z).join(", ")}.`}function xZ(Q){let $=typeof Q?.message==="string"?Q.message:"The provider stream failed.",Z=String(Q?.code??"").toLowerCase();if(Z==="rate_limit_exceeded")return{code:"rate_limited",message:$,retryable:!0};if(Z==="context_length_exceeded")return{code:"context_length_exceeded",message:$,retryable:!1};if(Z.includes("content_filter"))return{code:"content_filtered",message:$,retryable:!1};return{code:"provider_error",message:$,retryable:!0}}function o(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function O9(Q){if(!Q)return o();let $=Number(Q.input_tokens??0),Z=Number(Q.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q.total_tokens??$+Z)},W=Q.output_tokens_details?.reasoning_tokens;if(typeof W==="number")J.reasoningTokens=W;let X=Q.input_tokens_details?.cached_tokens;if(typeof X==="number")J.cachedInputTokens=X;return J}async function*l$(Q){if(!Q)return;let $=Q.getReader(),Z=new TextDecoder;try{while(!0){let{done:W,value:X}=await $.read();if(W)break;if(X)yield Z.decode(X,{stream:!0})}let J=Z.decode();if(J)yield J}finally{$.releaseLock()}}function N9(Q){return{responsesUrl:`${Q.base}/responses${Q.query}`,filesUrl:`${Q.base}/files${Q.query}`,headers:Q.headers,timeoutMs:Q.timeoutMs,maxRetries:Q.maxRetries}}async function*_9(Q,$,Z){let J,W=$,X=new Set;for(let G=0;J===void 0;G++)try{J=await GQ(Q.responsesUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify(W)},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,signal:Z.signal,fetchImpl:Q.fetchImpl})}catch(V){let H=G<u$?c$(W,V,Z.files).filter((K)=>!X.has(K)):[];if(H.length>0){let K=k(V).message;for(let z of H)X.add(z),yield{type:"file-rejected",fileId:z,message:K,...A(V)};W=m$(W,new Set(H),Z.files);continue}let Y=k(V);if(Y.code!=="aborted")yield{type:"error",error:Y,...A(V)};yield{type:"finish",reason:Y.code==="aborted"?"aborted":"error",usage:o()};return}try{yield*p$(l$(J.body),{structuredOutput:Z.structuredOutput})}catch(G){let V=k(G);if(V.code==="aborted"){yield{type:"finish",reason:"aborted",usage:o()};return}yield{type:"error",error:V},yield{type:"finish",reason:"error",usage:o()}}}async function M9(Q,$,Z="user_data"){let J=new FormData;J.set("purpose",Z),J.set("file",$);let X=await(await GQ(Q.filesUrl,{method:"POST",headers:await Q.headers(),body:J},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,fetchImpl:Q.fetchImpl})).json();if(!X?.id)throw Error("The provider accepted the upload but returned no file id.");return X.id}function S9(Q){let $=bZ(Q);if($.startsWith("gpt-3.5")||$.startsWith("text-")||$.startsWith("davinci"))return{reasoning:!1,structuredOutput:!1,fileInput:!1,parallelToolCalls:!0,toolSearch:!1};let Z=wZ($);if(Z?.kind==="o")return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:Z.major>1,toolSearch:i$(Z)};if(Z?.kind==="gpt")return{reasoning:Z.major>=5,structuredOutput:Z.major>4||$.startsWith("gpt-4o")||$.startsWith("gpt-4.1"),fileInput:Z.major>4||$.startsWith("gpt-4o")||$.startsWith("gpt-4.1"),parallelToolCalls:!0,toolSearch:i$(Z)};return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:!0,toolSearch:!0}}function i$(Q){if(Q.kind==="o")return Q.major>=5;return Q.major>5||Q.major===5&&Q.minor>=2}function bZ(Q){return Q.trim().toLowerCase()}function wZ(Q){let $=/^gpt-(\d+)(?:\.(\d+))?/.exec(Q);if($?.[1])return{kind:"gpt",major:Number($[1]),minor:Number($[2]??0)};let Z=/^o(\d+)(?:[-.]|$)/.exec(Q);if(Z?.[1])return{kind:"o",major:Number(Z[1]),minor:0};return null}function T9(Q,$){let{capabilities:Z}=$,J={model:$.model,input:IZ(Q.messages,Z),stream:!0};if(Q.systemPrompt)J.instructions=Q.systemPrompt;let W=pZ(Q.tools,Z);if(W.length>0){if(J.tools=W,!Z.parallelToolCalls)J.parallel_tool_calls=!1}if(Q.output)J.text={format:{type:"json_schema",name:Q.output.name,schema:Q.output.schema,strict:Q.output.strict}};if(Q.reasoning&&Z.reasoning)J.reasoning=Q.reasoning==="none"?{effort:"none"}:{effort:Q.reasoning,summary:"auto"};if(typeof Q.temperature==="number")J.temperature=Q.temperature;if(typeof Q.maxOutputTokens==="number")J.max_output_tokens=Q.maxOutputTokens;return J}function IZ(Q,$){let Z=[];for(let J of Q){let W=J.role,X=[],G=()=>{if(X.length===0)return;Z.push({type:"message",role:W,content:X}),X=[]};for(let V of J.content??[])switch(V.type){case"text":{if(!V.text)break;X.push(n(W,V.text));break}case"output":{if(V.partial)break;X.push(n(W,JSON.stringify(V.value)));break}case"file":{if(W==="assistant")break;let H=hZ(V);if(!$.fileInput){if(H)X.push(n(W,R9(V,!1)));break}if(V.fileId?.startsWith(f))throw Error(`FilePart.fileId holds a gemi attachment id (${V.fileId}). That field is the *provider's* file id, from \`fileId\` on the upload response; the \`attachmentId\` goes in \`FilePart.attachmentId\`, is shown to the model as text, and is resolved by a tool through \`ctx.attachments\`.`);if(!V.fileId&&!H)throw Error("FilePart.fileId is empty and there is no `attachmentId` either. `fileId` is the *provider's* file id and `attachmentId` is gemi's (`gemi_att_\u2026`), both from the upload response; an upload always answers at least one, so a part with neither was built from something other than that answer.");if(V.providerRejected){if(H)X.push(n(W,R9(V,!1)));X.push(n(W,C9(V.name)));break}if(H)X.push(n(W,R9(V,!!V.fileId)));if(V.fileId)X.push(yZ(V));break}case"reasoning":{G();let H=cZ(V);if(H)Z.push(H);break}case"tool-call":{if(V.partial)break;G(),Z.push({type:"function_call",call_id:V.toolCallId,name:String(V.name),arguments:JSON.stringify(V.input??{})});break}case"tool-result":{G(),Z.push({type:"function_call_output",call_id:V.toolCallId,output:mZ(V)});break}}G()}return fZ(Z)}var vZ="No result was recorded for this tool call. Assume it did not complete.";function fZ(Q){let $=new Set,Z=new Set,J=[];for(let X of Q){if(X.type==="function_call"){let G=String(X.call_id);if($.has(G))continue;$.add(G)}else if(X.type==="function_call_output"){let G=String(X.call_id);if(!$.has(G)||Z.has(G))continue;Z.add(G)}J.push(X)}if(Z.size===$.size)return J;let W=[];for(let X of J){if(W.push(X),X.type!=="function_call")continue;let G=String(X.call_id);if(Z.has(G))continue;Z.add(G),W.push({type:"function_call_output",call_id:G,output:vZ})}return W}function n(Q,$){return{type:Q==="assistant"?"output_text":"input_text",text:$}}function hZ(Q){let $=Q.attachmentId;return typeof $==="string"&&$.startsWith(f)?$:void 0}function R9(Q,$){let Z=[`id=${JSON.stringify(Q.attachmentId)}`];if(Q.name)Z.push(`name=${JSON.stringify(Q.name)}`);if(Q.mimeType)Z.push(`mimeType=${JSON.stringify(Q.mimeType)}`);let J=`attachment ${Z.join(" ")}`;return $?`[${J}]`:`[${J} \u2014 its contents are not shown to you; a tool can read the file by this id]`}function yZ(Q){let $=Q.mimeType?.trim().toLowerCase()??"";return{type:($?$.startsWith("image/")&&$!=="image/svg+xml":gZ(Q.name))?"input_image":"input_file",file_id:Q.fileId}}function gZ(Q){let $=/\.([a-z0-9]+)$/.exec(Q?.trim().toLowerCase()??"");return $?.[1]!==void 0&&uZ.has($[1])}var uZ=new Set(["jpeg","jpg","png","gif","webp"]);function cZ(Q){if(!Q.id)return null;let $={type:"reasoning",id:Q.id};return $.summary=Q.text?[{type:"summary_text",text:Q.text}]:[],$}function mZ(Q){if(Q.status==="ok")return typeof Q.output==="string"?Q.output:JSON.stringify(Q.output??null);if(Q.status==="denied"){let $=Q.reason?` Reason given: ${Q.reason}`:"";if(Q.cause==="stopped")return`The run was stopped before this tool call could complete, so it did not run.${$}`;if(Q.cause==="interrupted")return`The run was interrupted (the server stopped) while this tool call was in progress, so its result was lost. It may have run in part or in full: check its effects before repeating it.${$}`;return`The user declined this tool call, so it did not run.${$}`}return`The tool call failed and produced no result. Error (${Q.error?.code??"unknown"}): ${Q.error?.message??"no message"}`}function o$(Q){return Array.isArray(Q.tools)}function pZ(Q,$){if(!Q||Q.length===0)return[];if(!$.toolSearch){let W=[];for(let X of Q)if(o$(X))for(let G of X.tools)W.push(xQ(G,!1));else W.push(xQ(X,!1));return W}let Z=[],J=!1;for(let W of Q)if(o$(W)){let X=W.tools.map((G)=>{if(G.deferred)J=!0;return xQ(G,!0)});Z.push({type:"namespace",name:W.name,description:W.description,tools:X})}else{if(W.deferred)J=!0;Z.push(xQ(W,!0))}if(J)Z.push({type:"tool_search"});return Z}function xQ(Q,$){let Z={type:"function",name:Q.name,description:Q.description,parameters:Q.parameters,strict:Q.strict};if($&&Q.deferred)Z.defer_loading=!0;return Z}class s{static models(){return[]}normalizeError(Q){return k(Q)}}var n$=["gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.4-nano","gpt-5.2","gpt-5.1","gpt-5","gpt-5-mini","gpt-5-nano","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4o","gpt-4o-mini","o4-mini","o3","o3-mini"];class k9 extends s{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=S9(Q),this.config=$}static model(Q,$){return new k9(Q,$)}static models(){return n$}stream(Q){let $=T9(Q,{model:this.model,capabilities:this.capabilities});return _9(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output),files:L9(Q.messages)})}upload(Q){return M9(this.endpoint(),Q)}endpoint(){return N9(TQ(this.config))}}class A9 extends s{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=S9(Q),this.config=$}static model(Q,$){return new A9(Q,$)}static models(){return n$}stream(Q){let $=T9(Q,{model:this.deployment(),capabilities:this.capabilities});return _9(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output),files:L9(Q.messages)})}upload(Q){return M9(this.endpoint(),Q,"assistants")}deployment(){return this.config.deployment??this.model}endpoint(){return N9(kQ(this.config))}}class bQ{now;entries=new Map;constructor(Q=Date.now){this.now=Q}allow(Q,$){let Z=this.entries.get(Q);if(Z?.openUntil===void 0)return!0;let J=this.now();if(J<Z.openUntil)return!1;if(Z.probeUntil!==void 0&&J<Z.probeUntil)return!1;return Z.probeUntil=J+$.cooldownMs,!0}record(Q,$,Z){let J=this.entries.get(Q)??{failures:0},W=J.openUntil!==void 0;if($==="success")return this.entries.delete(Q),W?"closed":void 0;if($==="none"){delete J.probeUntil;return}if(J.failures+=1,this.entries.set(Q,J),W||J.failures>=Z.failures)return J.openUntil=this.now()+Z.cooldownMs,delete J.probeUntil,W?void 0:"open";return}state(Q){let $=this.entries.get(Q);if($?.openUntil===void 0)return"closed";return this.now()<$.openUntil?"open":"half-open"}}function dZ(Q){switch(Q.type){case"text-delta":case"reasoning-delta":case"tool-call-delta":case"tool-call":case"tool-search":case"output-delta":return!0;default:return!1}}var s$=Symbol("timed-out");class VQ extends s{model;capabilities;entries;options;circuit;constructor(Q,$={}){super();if(Q.length===0)throw Error("FallbackProvider needs at least one provider.");for(let J of Q)if(J.timeoutMs!==void 0&&!(J.timeoutMs>0))throw Error(`FallbackProvider: timeoutMs for ${J.provider.model} must be a positive number, got ${J.timeoutMs}.`);this.entries=[...Q];let Z=$.circuit;if(Z){let J=Z.failures??3,W=Z.cooldownMs??30000;if(!Number.isInteger(J)||J<1)throw Error(`FallbackProvider: circuit.failures must be a positive integer, got ${J}.`);if(!(W>0))throw Error(`FallbackProvider: circuit.cooldownMs must be a positive number, got ${W}.`);let X=new Set;for(let V of Q){let H=E9(V);if(X.has(H))throw Error(`FallbackProvider: two legs share the circuit key "${H}". Give one of them a \`circuitKey\`.`);X.add(H)}let G=Z.store??new bQ;this.options={...$,circuit:{...Z,store:G}},this.circuit={policy:{failures:J,cooldownMs:W},store:G,...Z.onStateChange?{onStateChange:Z.onStateChange}:{}}}else this.options=$,this.circuit=void 0;this.model=Q[0].provider.model,this.capabilities=lZ(Q.map((J)=>J.provider.capabilities))}static chain(Q,$){return new VQ(Q,$)}from(Q){if(!Number.isInteger(Q)||Q<0||Q>=this.entries.length)throw RangeError(`FallbackProvider.from(${Q}): the chain has ${this.entries.length} entries.`);return new VQ(this.entries.slice(Q),this.options)}leg(Q){let $=this.from(Q).entries[0];return new VQ([$],this.options)}upload(Q){return this.entries[0].provider.upload(Q)}normalizeError(Q){return this.entries[0].provider.normalizeError(Q)}stream(Q){return this.run(Q)}async*run(Q){let $,Z=Q.signal,J=0;for(let W=0;W<this.entries.length;W++){let X=this.entries[W],G=W===this.entries.length-1,V=X.provider.model;if(this.circuit&&!G&&!await this.allow(X))continue;J+=1;let H=!1,Y=async(C)=>{if(H)return;H=!0,await this.record(W,X,C)},K=new AbortController,z=()=>K.abort(Z?.reason);if(Z?.aborted)K.abort(Z.reason);else Z?.addEventListener("abort",z,{once:!0});let B=[],U=!1,j=!1,D,L,F,S=!1,N,v=!1,b=(C)=>{let O=$?R(R(M(),$),C.usage):C.usage;return $=void 0,{...C,usage:O}};try{N=X.provider.stream({...Q,...X.reasoning!==void 0?{reasoning:X.reasoning}:{},signal:K.signal})[Symbol.asyncIterator]();let C=!0;for(;;){let O=C&&X.timeoutMs!==void 0?await iZ(N.next(),X.timeoutMs):await N.next();if(O===s$){S=!0,F={error:{code:"provider_error",message:`${V} sent nothing within ${X.timeoutMs}ms.`,retryable:!0}};break}if(C=!1,O.done){v=!0;break}let P=O.value;if(P.type==="finish"&&P.model)L=P.model;if(U){if(P.type==="finish")D=R(D??M(),P.usage),j=!0,yield b(P);else{if(P.type==="error")F={error:P.error};yield P}continue}if(dZ(P)){U=!0,await Y("success"),yield*B.splice(0),yield P;continue}if(P.type==="error")F={error:P.error,...P.status!==void 0?{status:P.status}:{},...P.requestId!==void 0?{requestId:P.requestId}:{}};else if(P.type==="finish"){if(D=R(D??M(),P.usage),P.reason==="error"&&!F)F={error:{code:"provider_error",message:`${V} ended the call with an error and did not say which.`,retryable:!1}}}B.push(P)}}catch(C){let O=X.provider.normalizeError(C);if(U){if(O.code!=="aborted")yield{type:"error",error:O,...A(C)};this.report({index:W,model:V,responseModel:L,attempt:J,usage:D,outcome:x9(O),error:O}),yield b({type:"finish",reason:O.code==="aborted"?"aborted":"error",usage:M(),...L?{model:L}:{}});return}F={error:O,...A(C)}}finally{if(Z?.removeEventListener("abort",z),!v)K.abort(),N?.return?.()?.catch(()=>{})}if(U){if(!j&&$)yield{type:"finish",reason:F?"error":"stop",usage:$},$=void 0;this.report({index:W,model:V,responseModel:L,attempt:J,usage:D,outcome:F?x9(F.error):"ok",...F?{error:F.error}:{}});return}if(Z?.aborted){await Y("none"),this.report({index:W,model:V,responseModel:L,attempt:J,usage:D,outcome:"aborted"}),yield b({type:"finish",reason:"aborted",usage:D??M(),...L?{model:L}:{}});return}if(!F){await Y("success"),this.report({index:W,model:V,responseModel:L,attempt:J,usage:D,outcome:"ok"});for(let C of B)yield C.type==="finish"?b(C):C;return}let _=!G&&F.error.code!=="aborted"&&this.shouldFallBack(F.error,{index:W,model:V,timedOut:S,...F.status!==void 0?{status:F.status}:{},...F.requestId!==void 0?{requestId:F.requestId}:{}});if(await Y(_?"failure":"none"),this.report({index:W,model:V,responseModel:L,attempt:J,usage:D,outcome:_?"fallback":x9(F.error),error:F.error}),_){if(D)$=R($??M(),D);continue}let w=!1,q;for(let C of B){if(C.type==="finish"){q=C;continue}if(C.type==="error")w=!0;yield C}if(!w&&F.error.code!=="aborted")yield{type:"error",error:F.error,...F.status!==void 0?{status:F.status}:{},...F.requestId!==void 0?{requestId:F.requestId}:{}};yield b({type:"finish",reason:F.error.code==="aborted"?"aborted":q?.reason??"error",usage:D??M(),...L?{model:L}:{}});return}}async allow(Q){if(!this.circuit)return!0;try{return await this.circuit.store.allow(E9(Q),this.circuit.policy)}catch{return!0}}async record(Q,$,Z){if(!this.circuit)return;let J=E9($),W;try{W=await this.circuit.store.record(J,Z,this.circuit.policy)}catch{return}if(!W)return;try{this.circuit.onStateChange?.({index:Q,model:$.provider.model,key:J,state:W})}catch{}}shouldFallBack(Q,$){let Z=this.options.fallbackOn??((J)=>J.retryable);try{return Z(Q,$)}catch{return!1}}report(Q){if(Q.usage===void 0)delete Q.usage;if(Q.responseModel===void 0)delete Q.responseModel;try{this.options.onUsage?.(Q)}catch{}}}function E9(Q){return Q.circuitKey??Q.provider.model}function x9(Q){return Q.code==="aborted"?"aborted":"failed"}function lZ(Q){return{reasoning:Q.every(($)=>$.reasoning),structuredOutput:Q.every(($)=>$.structuredOutput),fileInput:Q.every(($)=>$.fileInput),parallelToolCalls:Q.every(($)=>$.parallelToolCalls),toolSearch:Q.every(($)=>$.toolSearch)}}function iZ(Q,$){let Z,J=new Promise((W)=>{Z=setTimeout(()=>W(s$),$)});return Promise.race([Q,J]).finally(()=>clearTimeout(Z))}async function oZ(Q,$,Z={}){let J=Z.samples??1;if(!Number.isInteger(J)||J<1)throw RangeError(`evalChain: samples must be a positive integer, got ${J}.`);let W=[];for(let X=0;X<Q.entries.length;X++){let G=Q.leg(X),V={index:X,model:G.model,results:[],errors:[]};for(let H=0;H<J;H++)try{V.results.push(await $(G,{index:X,sample:H}))}catch(Y){V.errors.push({sample:H,error:Y})}W.push(V)}return W}class t extends Error{runId;requested;oldest;code="frame_cursor_evicted";constructor(Q,$,Z){super(`Frame ${$} of run ${Q} has been evicted; the oldest frame still buffered is ${Z}. Reload the thread instead of resuming.`);this.runId=Q;this.requested=$;this.oldest=Z}}class HQ extends Error{runId;code="live_run_not_found";constructor(Q){super(`No live run ${Q} in this process.`);this.runId=Q}}class wQ{ttlMs;maxFrames;maxAgeMs;runs=new Map;byThread=new Map;byClientRun=new Map;constructor(Q={}){this.ttlMs=Q.ttlMs??60000,this.maxFrames=Q.maxFrames??4096,this.maxAgeMs=Q.maxAgeMs===void 0?3600000:Q.maxAgeMs}register(Q,$={}){let Z={run:Q,threadId:$.threadId,owner:$.owner??null,clientRunId:$.clientRunId,frames:[],lastSeq:-1,lostBefore:0,ended:!1,evicted:!1,evictAt:null,expireAt:null,wake:new Set,version:0};if(this.runs.set(Q.runId,Z),$.threadId)this.byThread.set($.threadId,Q.runId);if($.clientRunId)this.byClientRun.set($.clientRunId,Q.runId);return this.scheduleExpiry(Z,$.maxRunDurationMs),this.pump(Z,$)}findByClientRunId(Q){let $=this.byClientRun.get(Q);return $&&this.runs.has($)?$:null}async find(Q){let $=this.byThread.get(Q.threadId);if(!$)return null;let Z=this.runs.get($);if(!Z)return null;return{runId:$,seq:Z.lastSeq}}get(Q){return this.runs.get(Q)?.run??null}ownerOf(Q){return this.runs.get(Q)?.owner??null}mayAccess(Q,$){let Z=this.ownerOf(Q);return Z===null||Z===$}isRunning(Q){let $=this.runs.get(Q);return!!$&&!$.ended&&!$.evicted}replay(Q,$){let Z=this.runs.get(Q);if(!Z)throw new HQ(Q);if($!==void 0&&$<Z.lostBefore)throw new t(Q,$,Z.lostBefore);let J=Z.frames[0]?.seq;return this.drain(Z,Q,$??J??Z.lastSeq+1)}clear(){for(let Q of this.runs.values()){if(Q.evictAt)clearTimeout(Q.evictAt);if(Q.expireAt)clearTimeout(Q.expireAt);Q.ended=!0,this.notify(Q)}this.runs.clear(),this.byThread.clear(),this.byClientRun.clear()}get size(){return this.runs.size}async pump(Q,$){let Z=Promise.resolve();try{for await(let J of Q.run.frames()){if(Q.evicted){let X=$.onEvent;if(X)Z=Z.then(()=>X(J.event)).catch((G)=>b9($,G));continue}if(Q.frames.push(J),Q.lastSeq=J.seq,Q.frames.length>this.maxFrames){let X=Q.frames.shift();if(X)Q.lostBefore=X.seq+1}this.notify(Q);let W=$.onEvent;if(W)Z=Z.then(()=>W(J.event)).catch((X)=>b9($,X))}}catch(J){b9($,J)}finally{if(Q.ended=!0,Q.expireAt)clearTimeout(Q.expireAt),Q.expireAt=null;this.notify(Q),this.scheduleEviction(Q),await Z}}async*drain(Q,$,Z){let J=Z;while(!0){let W=Q.version;for(;;){if(J<Q.lostBefore)throw new t($,J,Q.lostBefore);let X=Q.frames,G=X[0]?.seq;if(G===void 0)break;let V=Math.max(0,J-G);if(V>=X.length)break;let H=X[V];yield H,J=H.seq+1}if(Q.ended&&J>Q.lastSeq||Q.evicted)return;await this.wait(Q,W)}}wait(Q,$){if(Q.version!==$)return Promise.resolve();return new Promise((Z)=>Q.wake.add(Z))}notify(Q){Q.version++;let $=Array.from(Q.wake);Q.wake.clear();for(let Z of $)Z()}scheduleEviction(Q){if(Q.evictAt)return;let $=setTimeout(()=>{let Z=Q.run.runId;if(!Q.ended)Q.evicted=!0,Q.frames=[];if(this.runs.get(Z)===Q)this.runs.delete(Z);if(Q.threadId&&this.byThread.get(Q.threadId)===Z)this.byThread.delete(Q.threadId);if(Q.clientRunId&&this.byClientRun.get(Q.clientRunId)===Z)this.byClientRun.delete(Q.clientRunId);this.notify(Q)},this.ttlMs);$.unref?.(),Q.evictAt=$}scheduleExpiry(Q,$){if(this.maxAgeMs===null||$===null)return;let Z=$===void 0?this.maxAgeMs:Math.max(this.maxAgeMs,$+this.ttlMs);if(!Number.isFinite(Z)||Z>2147483647)return;let J=setTimeout(()=>{if(Q.expireAt=null,Q.ended)return;try{Q.run.stop({reason:`The run was still going ${Math.round(Z/1000)}s after it started, past the live-run registry's age limit.`})}catch{}this.scheduleEviction(Q)},Z);J.unref?.(),Q.expireAt=J}}var w9=new wQ;function b9(Q,$){try{Q.onInternalError?.($)}catch{}}class IQ{maxEntries;records=new Map;constructor(Q=1e5){this.maxEntries=Q}async record(Q,$){if(this.records.has(Q))return;this.records.set(Q,{...$});while(this.records.size>this.maxEntries){let Z=this.records.keys().next().value;if(Z===void 0)break;this.records.delete(Z)}}async get(Q){let $=this.records.get(Q);return $?{...$}:null}}var I9=new IQ;class f9{now;receipts=new Map;sweepAt=1024;constructor(Q=Date.now){this.now=Q}async claim(Q,$){let Z=this.now();if(this.receipts.size>=this.sweepAt)this.sweep(Z);let J=this.receipts.get(Q);if(J&&J.expiresAt>Z)return J.result?{status:"replay",result:structuredClone(J.result)}:{status:"blocked"};return this.receipts.set(Q,{expiresAt:$}),{status:"claimed"}}async complete(Q,$,Z){this.receipts.set(Q,{result:structuredClone($),expiresAt:Z})}async release(Q){let $=this.receipts.get(Q);if($&&!$.result)this.receipts.delete(Q)}get size(){return this.receipts.size}sweep(Q){for(let[$,Z]of this.receipts)if(Z.expiresAt<=Q)this.receipts.delete($);this.sweepAt=Math.max(1024,this.receipts.size*2)}}var t$="pending",v9="done:",nZ=`
19
19
  if redis.call('SET', KEYS[1], ARGV[1], 'PX', ARGV[2], 'NX') then return 'claimed' end
20
20
  local held = redis.call('GET', KEYS[1])
21
21
  if not held then return ARGV[1] end
22
- return held`,iZ=`
22
+ return held`,sZ=`
23
23
  if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end
24
- return 0`;class v9{injectedClient;prefix;constructor(Q={}){this.injectedClient=Q.client,this.prefix=Q.prefix??"gemi:ai:receipt"}async claim(Q,$){let Z=await this.client.send("EVAL",[lZ,"1",this.key(Q),n$,s$($)]);if(Z==="claimed")return{status:"claimed"};let J=String(Z??"");if(J.startsWith(b9))return{status:"replay",result:JSON.parse(J.slice(b9.length))};return{status:"blocked"}}async complete(Q,$,Z){await this.client.send("SET",[this.key(Q),b9+JSON.stringify($),"PX",s$(Z)])}async release(Q){await this.client.send("EVAL",[iZ,"1",this.key(Q),n$])}key(Q){return`${this.prefix}:${Q}`}get client(){if(this.injectedClient)return this.injectedClient;let Q=LQ(),$=Q.bound(d)?Q.make(d).client:void 0;if(!$)throw Error("RedisReceiptStore could not reach the Redis client. Register RedisServiceProvider on your application, or pass a client: new RedisReceiptStore({ client }).");return $}}function s$(Q){return String(Math.max(1,Math.ceil(Q-Date.now())))}class IQ{ttlMs;clientOwnedIds;threads=new Map;lastSweep=0;constructor(Q={}){this.ttlMs=Q.ttlMs??86400000,this.clientOwnedIds=Q.clientOwnedIds??!1}async createThread(Q){let $=crypto.randomUUID();return this.threads.set($,{messages:[],touchedAt:Date.now()}),this.sweep(),{threadId:$}}async loadThread(Q){this.sweep();let $=this.threads.get(Q);if(!$)return this.clientOwnedIds?[]:null;return $.touchedAt=Date.now(),$.messages.slice()}async appendMessages(Q,$){this.sweep();let Z=this.threads.get(Q);if(!Z){if(!this.clientOwnedIds)throw Error(`Thread ${Q} does not exist here, or has expired.`);Z={messages:[],touchedAt:Date.now()},this.threads.set(Q,Z)}for(let J of $){let W=Z.messages.findIndex((X)=>X.id===J.id);if(W===-1)Z.messages.push(J);else Z.messages[W]=J}Z.touchedAt=Date.now()}async removeMessages(Q,$){this.sweep();let Z=this.threads.get(Q);if(!Z)return;let J=new Set($);Z.messages=Z.messages.filter((W)=>!J.has(W.id)),Z.touchedAt=Date.now()}delete(Q){this.threads.delete(Q)}get size(){return this.threads.size}sweep(Q=Date.now()){if(Q-this.lastSweep<60000)return;this.lastSweep=Q;for(let[$,Z]of this.threads)if(Q-Z.touchedAt>this.ttlMs)this.threads.delete($)}}var f9=new IQ;function e$(Q={}){return{messages:Q.messages?[...Q.messages]:[],pending:Q.pending?[...Q.pending]:[],error:null,threadId:Q.threadId,seq:Q.seq??-1,cursorRunId:Q.cursorRunId,runMessageIds:[],loadedTools:[]}}function Q3(Q,$,Z=new Date().toISOString()){if(!($.event.type==="run-start"&&$.event.runId!==Q.cursorRunId)&&$.seq<=Q.seq)return Q;return{...$3(Q,$.event,Z),seq:$.seq}}function $3(Q,$,Z){switch($.type){case"run-start":return{...Q,runId:$.runId,cursorRunId:$.runId,threadId:$.threadId??Q.threadId,runMessageIds:[],loadedTools:[],finishReason:void 0,usage:void 0};case"message-start":return m(Q,$.messageId,Z,(J)=>({...J,role:$.role}));case"text-delta":if(a$(Q,$.messageId))return Q;return m(Q,$.messageId,Z,(J)=>({...J,content:aZ(J.content,$.delta)}));case"reasoning-delta":if(a$(Q,$.messageId))return Q;return m(Q,$.messageId,Z,(J)=>({...J,content:rZ(J.content,$.delta,$.id)}));case"output-delta":return m(Q,$.messageId,Z,(J)=>({...J,content:r$(J.content,{type:"output",value:$.snapshot,partial:!0},(W)=>W.type==="output")}));case"tool-call":return m(Q,$.messageId,Z,(J)=>{let W=J.content.findIndex((z)=>z.type==="tool-call"&&z.toolCallId===$.part.toolCallId),X=W===-1?void 0:J.content[W],G=$.part.progress??X?.progress,H=$.part.nested??X?.nested,V=$.part.attachments??X?.attachments,Y={...$.part,...G?{progress:G}:{},...H?{nested:H}:{},...V?{attachments:V}:{}},K=J.content.slice();if(W===-1)K.push(Y);else K[W]=Y;return{...J,content:K}});case"tool-search":{let J=$.loaded.filter((W)=>!Q.loadedTools.includes(W));if(J.length===0)return Q;return{...Q,loadedTools:[...Q.loadedTools,...J]}}case"tool-progress":return t$(Q,$.toolCallId,(J)=>({...J,progress:[...J.progress??[],$.data]}));case"nested-event":{let J=$;return t$(Q,$.toolCallId,(W)=>{let X=W.nested??[],G=X.findIndex((K)=>K.runId===J.runId),H=X[G]??{runId:J.runId,agent:J.agent,messages:[]},V=sZ(H,J,Z),Y=G===-1?[...X,V]:X.map((K,z)=>z===G?V:K);return{...W,nested:Y}})}case"tool-result":{let J=m(Q,$.messageId,Z,(W)=>({...W,content:r$(W.content,$.part,(X)=>X.type==="tool-result"&&X.toolCallId===$.part.toolCallId)}));return{...J,pending:J.pending.filter((W)=>W.toolCallId!==$.part.toolCallId)}}case"message":{let J=Q.messages.findIndex((G)=>G.id===$.message.id),W=Q.messages.slice();if(J===-1)W.push($.message);else W[J]=$.message;let X=Q.runMessageIds.includes($.message.id)?Q.runMessageIds:[...Q.runMessageIds,$.message.id];return{...Q,messages:W,runMessageIds:X}}case"awaiting-input":return{...Q,runId:$.runId,pending:[...$.pending]};case"message-end":return m(Q,$.messageId,Z,(J)=>({...J,finishReason:$.finishReason,...$.outputTruncated?{outputTruncated:!0}:{},...$.usage?{usage:$.usage}:{},content:$.outputTruncated||$.finishReason==="length"?J.content.filter((W)=>!(W.type==="output"&&W.partial)):J.content.map((W)=>W.type==="output"&&W.partial?{...W,partial:!1}:W)}));case"usage":return{...Q,usage:$.usage};case"error":return{...Q,error:$.error,pending:[]};case"run-end":return{...Q,runId:void 0,finishReason:$.finishReason,messages:Z3(Q,$.finishReason)};default:return Q}}function Z3(Q,$){return Q.messages.map((Z)=>Z.role==="assistant"&&Q.runMessageIds.includes(Z.id)?oZ(Z,$):Z)}function oZ(Q,$){let Z=Q.content.map((W)=>W.type==="tool-call"&&W.nested?.some((X)=>X.finishReason===void 0)?{...W,nested:W.nested.map((X)=>X.finishReason===void 0?nZ(X,$):X)}:W);if(Q.finishReason===void 0)return{...Q,finishReason:$,content:Z};return Z.some((W,X)=>W!==Q.content[X])?{...Q,content:Z}:Q}function nZ(Q,$){let Z={messages:Q.messages,pending:[],error:null,seq:-1,runMessageIds:Q.messages.map((J)=>J.id),loadedTools:[]};return{...Q,finishReason:$,messages:Z3(Z,$)}}function t$(Q,$,Z){for(let J=Q.messages.length-1;J>=0;J--){let W=Q.messages[J],X=W.content.findIndex((Y)=>Y.type==="tool-call"&&Y.toolCallId===$);if(X===-1)continue;if(W.finishReason!==void 0&&!tZ(Q,W,$))return Q;let G=W.content.slice();G[X]=Z(G[X]);let H=Q.messages.slice();H[J]={...W,content:G};let V=Q.runMessageIds.includes(W.id)?Q.runMessageIds:[...Q.runMessageIds,W.id];return{...Q,runMessageIds:V,messages:H}}return Q}function sZ(Q,$,Z){let J={messages:Q.messages,pending:[],error:null,seq:-1,runMessageIds:Q.messages.map((X)=>X.id),loadedTools:[],finishReason:Q.finishReason},W=$3(J,$.event,Z);return{...Q,...$.label!==void 0?{label:$.label}:{},messages:W.messages,...W.finishReason!==void 0?{finishReason:W.finishReason}:{},...W.usage!==void 0?{usage:W.usage}:{}}}function tZ(Q,$,Z){if($.finishReason!=="awaiting-input")return!1;return!Q.messages.some((J)=>J.content.some((W)=>W.type==="tool-result"&&W.toolCallId===Z))}function a$(Q,$){let Z=Q.messages.find((J)=>J.id===$);return Z!==void 0&&Z.finishReason!==void 0}function m(Q,$,Z,J){let W=Q.messages.findIndex((H)=>H.id===$),X=Q.runMessageIds.includes($)?Q.runMessageIds:[...Q.runMessageIds,$];if(W===-1){let H={id:$,role:"assistant",content:[],createdAt:Z};return{...Q,runMessageIds:X,messages:[...Q.messages,J(H)]}}let G=Q.messages.slice();return G[W]=J(G[W]),{...Q,runMessageIds:X,messages:G}}function aZ(Q,$){let Z=Q[Q.length-1];if(Z&&Z.type==="text")return[...Q.slice(0,-1),{type:"text",text:Z.text+$}];return[...Q,{type:"text",text:$}]}function rZ(Q,$,Z){let J=Q[Q.length-1];if(J&&J.type==="reasoning"&&J.id===Z)return[...Q.slice(0,-1),{...J,text:(J.text??"")+$}];return[...Q,Z?{type:"reasoning",id:Z,text:$}:{type:"reasoning",text:$}]}function r$(Q,$,Z){let J=Q.findIndex(Z);if(J===-1)return[...Q,$];let W=Q.slice();return W[J]=$,W}class y9{store;threadId;report;chain=Promise.resolve();done=new Set;closed=!1;state;runId;constructor(Q,$,Z,J){this.store=Q;this.threadId=$;this.report=J;this.state=e$({messages:Z})}finish(Q){if(this.closed)return;this.done.add(Q.id),this.write(()=>[h9(Q)])}frame(Q){if(this.closed)return;let $=Q.event;if($.type==="run-start")this.runId=$.runId;switch(this.state=Q3(this.state,Q),$.type){case"message":this.write(()=>[h9($.message)]);return;case"tool-call":if($.part.partial)return;this.checkpoint($.messageId);return;case"message-start":case"tool-result":this.checkpoint($.messageId);return;default:return}}close(Q=[]){this.closed=!0;for(let $ of Q)this.done.add($.id)}settled(){return this.chain}checkpoint(Q){if(this.done.has(Q))return;let $=this.state.messages.find((J)=>J.id===Q);if(!$)return;let Z=this.runId;this.write(()=>{let J=h9($);if(J.finishReason===void 0&&Z)J.runId=Z;return[J]})}write(Q){let $;try{$=Q()}catch(Z){this.report(Z);return}this.chain=this.chain.then(()=>this.store.appendMessages(this.threadId,$)).catch((Z)=>this.report(Z))}}function h9(Q){return structuredClone(Q)}async function J3(Q,$){let Z=[],J=null,W=Q.slice();for(let X=0;X<W.length;X++){let G=W[X];if(G.role!=="assistant"||G.finishReason!==void 0)continue;if(G.runId&&await $(G.runId))continue;J??=new Set(Q.flatMap((Y)=>Y.content.flatMap((K)=>K.type==="tool-result"?[K.toolCallId]:[])));let H=G.content.map((Y)=>Y.type==="tool-call"?W3(Y):Y);for(let Y of G.content){if(Y.type!=="tool-call"||J.has(Y.toolCallId))continue;let K={type:"tool-result",toolCallId:Y.toolCallId,name:Y.name,status:"denied",cause:"interrupted"};H.push(K)}let V={...G,content:H,finishReason:"interrupted"};W[X]=V,Z.push(V)}return{messages:W,settled:Z}}function W3(Q){let{partial:$,...Z}=Q;if(!Z.nested?.some((J)=>J.finishReason===void 0))return Z;return{...Z,nested:Z.nested.map(eZ)}}function eZ(Q){if(Q.finishReason!==void 0)return Q;return{...Q,finishReason:"interrupted",messages:Q.messages.map(($)=>$.role==="assistant"&&$.finishReason===void 0?{...$,finishReason:"interrupted",content:$.content.map((Z)=>Z.type==="tool-call"?W3(Z):Z)}:$)}}var Q6=U3,vQ=new Map,X3=new WeakMap,fQ=new Map,$6=4194304,Z6=1000,J6=5,G3=65536,O3=()=>{};class P3{byKey=new Map;take(Q,$,Z){let J=this.byKey.get(Q);if(!J?.has($)&&(J?.size??0)>=Z)return null;if(!J)J=new Map,this.byKey.set(Q,J);J.set($,(J.get($)??0)+1);let W=!1;return()=>{if(W)return;W=!0;let X=this.byKey.get(Q),G=(X?.get($)??1)-1;if(!X)return;if(G>0)X.set($,G);else if(X.delete($),X.size===0)this.byKey.delete(Q)}}}var V3=new WeakMap;function W6(Q){let $=V3.get(Q);if(!$)$=new P3,V3.set(Q,$);return $}class q3 extends Q6{static kind="agent-controller";store=f9;liveRuns=x9;attachments=_Q;attachmentStorage=C3;fileOwners=w9;nonces=l;receipts;requireKnownFiles=!1;hookHoldMs=30000;instructions(Q,$){}context(Q,$){return{}}requireThread=!1;maxBodyBytes=$6;maxHistoryMessages=Z6;maxConcurrentRuns=J6;runLimitKey(Q,$){return $.owner}authorizeRequest(Q,$){}runOwner(Q){let $=Q.ctx?.()?.user,Z=$?.id??$?.publicId;if(Z!==void 0&&Z!==null&&String(Z)!=="")return`user:${String(Z)}`;return null}async stream(Q=new YQ){let $=await g9(Q,this.maxBodyBytes);if($.error)return hQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:void 0,W=B6(Z);if(W.error)return hQ({body:{},error:W.error});let X=W.turn,G=J!==void 0&&Z.regenerate===!0,H=typeof Z.clientRunId==="string"?Z.clientRunId:void 0,V=_3(Z);if(this.requireThread&&!J)return E(400,{code:"thread_required",message:"This agent takes a turn only on a thread: send a threadId."});if(G&&!this.store.removeMessages)return E(501,{code:"regenerate_unsupported",message:"This agent's store cannot remove messages, so a thread's answer cannot be regenerated. Implement `removeMessages` on the AgentStore."});if(!J&&Array.isArray(Z.messages)&&Z.messages.length>this.maxHistoryMessages)return m9(413,"history_too_long",`The conversation has ${Z.messages.length} messages; this agent takes at most ${this.maxHistoryMessages}.`);let Y=await this.runOwner(Q),K=H?{cancelled:!1,owner:Y}:null;if(K)fQ.set(H,K);let z=null,B=[],D=async()=>{try{return await F()}finally{if(J&&B.length>0&&z===null)await this.store.appendMessages(J,B).catch((U)=>this.reportHookFailure(U))}},F=async()=>{let U;if(J){let M=await this.store.loadThread(J);if(!M)return E(404,{code:"thread_not_found",message:`Thread ${J} does not exist here, or has expired.`});if(U=await this.settleThread(J,M,{write:!0}),G){let p=L6(U);if(!p)return E(409,{code:"nothing_to_regenerate",message:`Thread ${J} has no user turn to answer again.`});B=U.slice(p.index),await this.store.removeMessages(J,B.map((R3)=>R3.id)),U=U.slice(0,p.index),X=p.turn}}else U=Array.isArray(Z.messages)?Z.messages:[],N6(this.nonces);let O=await this.instructions(Q,{body:V})||void 0,j=await this.context(Q,{body:V}),q=await this.attachmentsFor(Q,J,{body:V});if(K?.cancelled)return z3();let _=J?new y9(this.store,J,U,(M)=>this.reportHookFailure(M)):null,w=`run_${crypto.randomUUID()}`,v={req:Q,runId:w,threadId:J},C=this.agent.stream({runId:w,messages:U,turn:X,threadId:J,..._?{onMessage:(M)=>_.finish(M)}:{},instructions:O,context:j,attachments:q,body:V,redactError:(M,p)=>this.redactError(M,p,v),nonces:this.nonces,receipts:this.receipts,subject:Y}),P=this.liveRuns.register(C,{threadId:J,owner:Y,clientRunId:H,onEvent:(M)=>this.dispatchEvent(M,v),onInternalError:(M)=>this.reportHookFailure(M),maxRunDurationMs:this.agent.maxRunDurationMs});if(z=C,_)this.follow(C,_);let{stored:L,hooks:b}=this.persistRun(C,v,P,_);return X3.set(C,L),Q.ctx?.()?.waitUntil(b),C.toResponse()};try{await this.authorizeRequest(Q,{route:"stream",threadId:J,body:V});let U=await this.foreignFile([...X?.files??[],...J?[]:j6(Z.messages)],Y);if(U)return U;if(K?.cancelled)return z3();let O=await this.runLimitKey(Q,{owner:Y,threadId:J}),j=O===null?O3:W6(this.liveRuns).take(O,J?`thread:${J}`:`run:${crypto.randomUUID()}`,this.maxConcurrentRuns);if(!j)return m9(429,"too_many_runs",`You already have ${this.maxConcurrentRuns} conversations answering. Wait for one to finish, or stop it, and send again.`);try{return J?await this.withThread(J,Y,D):await D()}finally{let q=z;if(q)q.result().then(j,j);else j()}}finally{if(K&&fQ.get(H)===K)fQ.delete(H)}}async withThread(Q,$,Z){let J=vQ.get(Q)??Promise.resolve(),W,X=new Promise((H)=>{W=H}),G=J.then(()=>X);vQ.set(Q,G),await J;try{let H=await this.liveRuns.find({threadId:Q});if(H&&this.liveRuns.isRunning(H.runId)&&!this.liveRuns.mayAccess(H.runId,$))return yQ();let V=H?this.liveRuns.get(H.runId):null;if(V)V.stop({reason:"superseded by a later turn on this thread"}),await X3.get(V);return await Z()}finally{if(W(),vQ.get(Q)===G)vQ.delete(Q)}}async attach(Q=new YQ){let $=await g9(Q,G3);if($.error)return hQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:F6(Q,"threadId");if(!J)return E(400,{code:"invalid_request",message:"attach needs a threadId: it is the handle that survives a refresh."});await this.authorizeRequest(Q,{route:"attach",threadId:J});let W=await this.liveRuns.find({threadId:J});if(W&&!this.liveRuns.mayAccess(W.runId,await this.runOwner(Q)))return yQ();if(!W)return E(404,{code:"no_live_run",message:`No run in progress for thread ${J} in this process.`});let X=typeof Z.runId==="string"?Z.runId:void 0,G=X&&X!==W.runId?void 0:U6(Q,Z);try{return z$(this.liveRuns.replay(W.runId,G))}catch(H){if(H instanceof t)return E(410,{code:H.code,message:H.message,oldestSeq:H.oldest});if(H instanceof HQ)return E(404,{code:H.code,message:H.message});throw H}}async stop(Q=new YQ){let $=await g9(Q,G3);if($.error)return hQ($);let Z=$.body;await this.authorizeRequest(Q,{route:"stop",threadId:typeof Z.threadId==="string"?Z.threadId:void 0});let J=await this.runOwner(Q),W=typeof Z.runId==="string"?Z.runId:void 0;if(!W&&typeof Z.clientRunId==="string"){if(W=this.liveRuns.findByClientRunId(Z.clientRunId)??void 0,!W){let G=fQ.get(Z.clientRunId);if(G){if(G.owner!==null&&G.owner!==J)return yQ();return G.cancelled=!0,{stopped:!0}}}}if(!W&&typeof Z.threadId==="string")W=(await this.liveRuns.find({threadId:Z.threadId}))?.runId;let X=W?this.liveRuns.get(W):null;if(!X)return{stopped:!1};if(!this.liveRuns.mayAccess(X.runId,J))return yQ();return X.stop({reason:typeof Z.reason==="string"?Z.reason:void 0}),{stopped:!0}}attachmentScope(Q,$,Z){let J=Q.ctx()?.user,W=J?.id??J?.publicId;if(W!==void 0&&W!==null&&String(W)!=="")return{key:`user:${String(W)}`};if($)return{key:`thread:${$}`};return null}attachmentLimits(Q){return null}attachmentDestination(Q,$){return"both"}async attachmentsFor(Q,$,Z={body:{}}){let J=await this.attachmentScope(Q,$,Z);if(!J)return null;return new WQ(this.attachments,this.attachmentStorage,J)}async upload(Q=new YQ){let $=await Q.rawRequest.formData(),Z=$.get("file");if(!(Z instanceof Blob))throw Error("upload expects a multipart body with a `file` field.");let J=Z instanceof File&&Z.name?Z.name:"upload",W=Z.type||"application/octet-stream",X=G6($.get("body")),G=$.get("threadId");await this.authorizeRequest(Q,{route:"upload",threadId:typeof G==="string"&&G.length>0?G:void 0,body:X});let H=H6(await this.attachmentLimits(Q),Z,J,W);if(H)throw new N3(H.code,H.message);let V=typeof G==="string"&&G.length>0&&await this.store.loadThread(G)!==null?G:void 0,Y=await this.runOwner(Q),K=(_)=>this.fileOwners.record(_,{owner:Y,name:J,mimeType:W,size:Z.size,createdAt:new Date().toISOString()}),z=await this.attachmentDestination(Z,Q),B=O6(z,$.get("destination")),D=await this.attachmentScope(Q,V,{body:X}),F=B!=="provider"&&!D;if(F){if(B==="storage")throw Error('This upload was routed to storage, but `attachmentScope()` returned null for the request, so there is no subject to file the attachment under. Guard the route (`this.agent(Chat).middleware({ upload: "auth" })`), send a `threadId` with the upload, or override `attachmentScope()`.');P6()}if(B==="provider"||!D){let _=await H3(this.agent.provider,Z);await K(_);let w={fileId:_,name:J,mimeType:W,size:Z.size,destination:"provider"};if(F)w.downgraded="no_scope";return w}let U=tQ(),O=await this.attachmentStorage.put({name:aQ(U,J),body:Z,contentType:W}),j=B==="both"?await H3(this.agent.provider,Z):void 0;if(j)await K(j);let q={id:U,scopeKey:D.key,fileId:j,objectName:O,name:J,mimeType:W,size:Z.size,createdAt:new Date().toISOString(),destination:B};return await this.attachments.put(D,q),{fileId:j,attachmentId:U,name:J,mimeType:W,size:Z.size,destination:B}}async foreignFile(Q,$){let Z=new Set(Q.map((J)=>J.fileId).filter((J)=>typeof J==="string"));for(let J of Z){let W=await this.fileOwners.get(J);if(W?W.owner!==null&&W.owner!==$:this.requireKnownFiles)return C6()}return null}onMessage(Q,$){}onToolCall(Q,$){}onAwaitingInput(Q,$){}redactError(Q,$,Z){return p9(Q,$)}onError(Q,$){}onStreamComplete(Q,$){}reportHookFailure(Q){console.error("[gemi/ai] agent controller hook failed",Q)}async dispatchEvent(Q,$){switch(Q.type){case"tool-call":if(!Q.part.partial&&!Q.resent)await this.onToolCall({toolCallId:Q.part.toolCallId,name:String(Q.part.name),input:Q.part.input},$);return;case"awaiting-input":await this.onAwaitingInput(Q.pending,$);return;case"error":await this.onError(j3(Q.error),$);return;default:return}}async readThread(Q){let $=await this.store.loadThread(Q);return $?await this.settleThread(Q,$,{write:!1}):null}isRunLive(Q,$){return this.liveRuns.get(Q)!==null}async settleThread(Q,$,{write:Z}){let{messages:J,settled:W}=await J3($,(X)=>this.isRunLive(X,Q));if(Z&&W.length>0)try{await this.store.appendMessages(Q,W)}catch(X){this.reportHookFailure(X)}return J}follow(Q,$){(async()=>{try{for await(let Z of Q.frames())$.frame(Z)}catch(Z){this.reportHookFailure(Z)}})()}persistRun(Q,$,Z,J=null){let W=Promise.resolve(),X=(async()=>{let H;try{H=await Q.result()}catch(Y){J?.close(),await J?.settled(),W=this.safely(()=>this.onError({code:"unknown",message:Y instanceof Error?Y.message:String(Y),retryable:!1},$));return}let V=H.messages;if(J?.close(V),await J?.settled(),$.threadId&&V.length>0)try{await this.store.appendMessages($.threadId,V)}catch(Y){this.reportHookFailure(Y)}W=this.notifyRun(H,V,$)})(),G=X.then(()=>_6(Promise.all([W,Z]).then(()=>{}),this.hookHoldMs));return{stored:X,hooks:G}}async notifyRun(Q,$,Z){for(let J of $)await this.safely(()=>this.onMessage(J,Z));await this.safely(()=>this.onStreamComplete(Q,Z))}async safely(Q){try{await Q()}catch($){this.reportHookFailure($)}}}var u9=["turn","clientRunId","threadId","messages","regenerate"],X6=["text","files","toolResults"];function _3(Q,$=S3(Q)?u9:[...u9,...X6]){let Z={};for(let[J,W]of Object.entries(Q)){if($.includes(J))continue;Object.defineProperty(Z,J,{value:W,writable:!0,enumerable:!0,configurable:!0})}return Z}function G6(Q){if(Q===null)return{};let $;if(typeof Q==="string")try{$=JSON.parse(Q)}catch{throw new c9("The upload's `body` field is not valid JSON.")}if($===null||typeof $!=="object"||Array.isArray($))throw new c9("The upload's `body` field must be a JSON object.");return _3($,u9)}class c9 extends gQ{constructor(Q){super(Q);this.name="InvalidUploadError",this.payload={api:{status:400,data:{error:{code:"invalid_request",message:Q}}},view:{}}}}async function H3(Q,$){try{return await Q.upload($)}catch(Z){if(Z instanceof f&&V6.has(Z.status))throw new M3(k(Z).message);throw Z}}var V6=new Set([400,413,415,422]);class N3 extends gQ{constructor(Q,$){super($);this.name="LimitedUploadError",this.payload={api:{status:422,data:{error:{code:Q,message:$}}},view:{}}}}function H6(Q,$,Z,J){if(!Q)return null;let{maxBytes:W,accept:X}=Q;if(typeof W==="number"&&$.size>W)return{code:"file_too_large",message:`${JSON.stringify(Z)} is ${Y3($.size)}; the limit is ${Y3(W)}.`};if(X&&X.length>0&&!X.some((G)=>Y6(G,Z,J)))return{code:"unsupported_file_type",message:`${JSON.stringify(Z)} is not a type this chat accepts. Accepted: ${X.join(", ")}.`};return null}function Y6(Q,$,Z){let J=Q.trim().toLowerCase();if(!J)return!1;if(J.startsWith("."))return $.toLowerCase().endsWith(J);let W=Z.toLowerCase().split(";")[0].trim();if(J.endsWith("/*"))return W.startsWith(J.slice(0,-1));return W===J}function Y3(Q){if(Q<1024)return`${Q} B`;let $=["KB","MB","GB"],Z=Q/1024,J=0;while(Z>=1024&&J<$.length-1)Z/=1024,J++;return`${Math.round(Z*10)/10} ${$[J]}`}class M3 extends gQ{constructor(Q){super(Q);this.name="RejectedUploadError";let $=/(unsupported|invalid) (extension|file type|format|mime)|supported (extensions|formats?)/i.test(Q)?"unsupported_file_type":"file_rejected";this.payload={api:{status:422,data:{error:{code:$,message:Q}}},view:{}}}}async function g9(Q,$){let Z=Q?.rawRequest;if(!Z||Z.method==="GET"||Z.method==="HEAD"||!Z.body)return{body:{}};if(!K6(Z.headers.get("Content-Type")))return{body:{},status:415,code:"unsupported_media_type",error:"The request body must be sent as application/json."};let J=Number(Z.headers.get("Content-Length"));if(Number.isFinite(J)&&J>$)return K3($);let W;try{let G=await z6(Z,$);if(G===null)return K3($);W=G}catch{return{body:{},error:"The request body could not be read."}}if(!W.trim())return{body:{}};let X;try{X=JSON.parse(W)}catch{return{body:{},error:"The request body is not valid JSON."}}if(X===null||typeof X!=="object"||Array.isArray(X))return{body:{},error:"The request body must be a JSON object."};return{body:X}}function K6(Q){return L3(Q)==="application/json"}async function z6(Q,$){if(!Number.isFinite($)||!Q.body)return await Q.text();let Z=Q.body.getReader(),J=[],W=0;for(;;){let{done:H,value:V}=await Z.read();if(H)break;if(W+=V.byteLength,W>$)return await Z.cancel().catch(O3),null;J.push(V)}let X=new Uint8Array(W),G=0;for(let H of J)X.set(H,G),G+=H.byteLength;return new TextDecoder().decode(X)}function K3(Q){return{body:{},status:413,code:"body_too_large",error:`The request body is larger than this agent accepts (${Q} bytes).`}}function m9(Q,$,Z){return E(Q,{...uQ(F3(Q),Z,Q),code:$})}function hQ(Q){if(Q.status===413)return m9(413,Q.code??"body_too_large",Q.error??"");return E(Q.status??400,{code:Q.code??"invalid_request",message:Q.error})}function S3(Q){return Boolean(Q.turn)&&typeof Q.turn==="object"}function B6(Q){let $=S3(Q)?Q.turn:Q,Z={};if(typeof $.text==="string")Z.text=$.text;if(Array.isArray($.files)){let J=D6($.files);if(typeof J==="string")return{error:J};Z.files=J}if(Array.isArray($.toolResults))Z.toolResults=$.toolResults;return Object.keys(Z).length>0?{turn:Z}:{}}function D6(Q){let $=[];for(let[Z,J]of Q.entries()){let W=`turn.files[${Z}]`;if(!J||typeof J!=="object"||Array.isArray(J))return`${W} must be an object.`;let X={};for(let K of["fileId","attachmentId","name","mimeType"]){let z=J[K];if(z===void 0||z===null||z==="")continue;if(typeof z!=="string")return`${W}.${K} must be a string.`;X[K]=z}let{fileId:G,attachmentId:H,name:V,mimeType:Y}=X;if(G?.startsWith(I))return`${W}.fileId holds a gemi attachment id (${G}). \`fileId\` is the provider's id from the upload response; put this one in \`attachmentId\`.`;if(H!==void 0&&!H.startsWith(I))return`${W}.attachmentId is not a gemi attachment id: it must start with "${I}".`;if(!G&&!H)return`${W} has neither a \`fileId\` nor an \`attachmentId\`. Send the ids the upload response answered.`;$.push({...G?{fileId:G}:{},...H?{attachmentId:H}:{},...V!==void 0?{name:V}:{},...Y!==void 0?{mimeType:Y}:{}})}return $}function U6(Q,$){if(typeof $.from==="number"&&Number.isFinite($.from))return Math.max(0,Math.floor($.from));if(typeof $.cursor==="number"&&Number.isFinite($.cursor)){let J=Math.floor($.cursor);if(J>=0)return J+1;return}let Z=Q?.rawRequest?.headers?.get("Last-Event-ID");if(Z){let J=Number.parseInt(Z,10);if(Number.isFinite(J))return Math.max(0,J+1)}return}function F6(Q,$){let Z=Q?.search?.get($);return typeof Z==="string"?Z:void 0}function L6(Q){let $=MQ(Q);for(let Z=Q.length-1;Z>=0;Z--){let J=Q[Z];if(J.role!=="user"||$.has(J.id))continue;let W="",X=[];for(let G of J.content){if(G.type==="text")W+=G.text;if(G.type==="file")X.push({...G.fileId?{fileId:G.fileId}:{},...G.attachmentId?{attachmentId:G.attachmentId}:{},...G.name?{name:G.name}:{},...G.mimeType?{mimeType:G.mimeType}:{}})}if(!W&&X.length===0)continue;return{index:Z,turn:{...W?{text:W}:{},...X.length>0?{files:X}:{}}}}return null}function z3(){return E(409,{code:"stopped",message:"The turn was stopped before it started."})}function yQ(){return E(403,uQ("permission","This run belongs to someone else.",403))}function C6(){return E(403,uQ("permission","A file in this turn was uploaded by someone else.",403))}function j6(Q){if(!Array.isArray(Q))return[];let $=[];for(let Z of Q){let J=Z?.content;if(!Array.isArray(J))continue;for(let W of J)if(W&&typeof W==="object"&&typeof W.fileId==="string")$.push({fileId:W.fileId})}return $}function E(Q,$){return new Response(JSON.stringify({error:$}),{status:Q,headers:{"Content-Type":"application/json"}})}function O6(Q,$){if(typeof $!=="string"||$.length===0)return Q;if($!=="both"&&$!=="provider"&&$!=="storage")throw Error(`Unknown attachment destination "${$}". Expected "both", "provider" or "storage".`);if($===Q||Q==="both"&&$==="storage")return $;if(Q==="both"&&$==="provider")throw Error('This upload asked for the "provider" destination under a "both" policy. A client may ask for "storage", which keeps a file away from the model provider, but it may not ask the server to stop keeping its own copy while the vendor still gets the file \u2014 that is the app\'s retention decision. Change `attachmentDestination()` if this file should not be kept.');throw Error(`This upload asked for the "${$}" destination, but the server's policy for it is "${Q}", and a client hint may only ask for "storage" under a "both" policy. Change \`attachmentDestination()\` if the file really should go there.`)}var B3=!1;function P6(){if(B3)return;B3=!0,console.warn("[gemi/ai] An upload had no attachment scope, so its bytes were sent to the model provider only and no attachment id was minted \u2014 a tool cannot forward this file. Guard the route with auth, send a `threadId` with the upload, or override `attachmentScope()`.")}var q6=2147483647;function _6(Q,$){let Z=Q.then(()=>{},()=>{});if(!($<=q6))return Z;let J,W=new Promise((X)=>{J=setTimeout(X,$)});return Promise.race([Z,W]).finally(()=>clearTimeout(J))}var D3=!1;function N6(Q){if(D3||Bun.env.NODE_ENV!=="production")return;if(!(Q instanceof $Q))return;D3=!0,console.warn("[gemi/ai] A stateless agent chat is spending approval nonces in process memory. With more than one instance a replayed approval is accepted once per instance. Set `nonces = new RedisNonceStore()` (or your own NonceStore) on the AgentController.")}export{VZ as toAgentTools,a as supportsStrict,S6 as s,p9 as redactError,x9 as liveRuns,w3 as generate,dZ as evalChain,l as defaultNonceStore,w9 as defaultFileOwners,_Q as defaultAttachmentStore,f9 as defaultAgentStore,RQ as ToolNamespace,R as ToolError,G9 as Skill,WQ as ScopedAttachments,XQ as SKILLS_NAMESPACE,v9 as RedisReceiptStore,mQ as RedisNonceStore,g as PendingEscalation,k9 as OpenAIProvider,U9 as OpenAIImageProvider,I9 as MemoryReceiptStore,$Q as MemoryNonceStore,wQ as MemoryLiveRuns,bQ as MemoryFileOwners,qQ as MemoryAttachmentStore,IQ as MemoryAgentStore,HQ as LiveRunNotFoundError,M6 as JSONSchemaError,i as InvalidAttachmentScopeError,AQ as ImageRequestError,EQ as ImageProvider,z9 as ImageModel,t as FrameCursorEvictedError,VQ as FallbackProvider,Y9 as DEFAULT_MAX_RUN_DURATION_MS,T9 as AzureOpenAIProvider,F9 as AzureOpenAIImageProvider,JQ as AttachmentNotFoundError,u as AgentTool,QQ as AgentRunError,s as AgentProvider,q3 as AgentController,K9 as Agent};
24
+ return 0`;class h9{injectedClient;prefix;constructor(Q={}){this.injectedClient=Q.client,this.prefix=Q.prefix??"gemi:ai:receipt"}async claim(Q,$){let Z=await this.client.send("EVAL",[nZ,"1",this.key(Q),t$,a$($)]);if(Z==="claimed")return{status:"claimed"};let J=String(Z??"");if(J.startsWith(v9))return{status:"replay",result:JSON.parse(J.slice(v9.length))};return{status:"blocked"}}async complete(Q,$,Z){await this.client.send("SET",[this.key(Q),v9+JSON.stringify($),"PX",a$(Z)])}async release(Q){await this.client.send("EVAL",[sZ,"1",this.key(Q),t$])}key(Q){return`${this.prefix}:${Q}`}get client(){if(this.injectedClient)return this.injectedClient;let Q=jQ(),$=Q.bound(d)?Q.make(d).client:void 0;if(!$)throw Error("RedisReceiptStore could not reach the Redis client. Register RedisServiceProvider on your application, or pass a client: new RedisReceiptStore({ client }).");return $}}function a$(Q){return String(Math.max(1,Math.ceil(Q-Date.now())))}class vQ{ttlMs;clientOwnedIds;threads=new Map;lastSweep=0;constructor(Q={}){this.ttlMs=Q.ttlMs??86400000,this.clientOwnedIds=Q.clientOwnedIds??!1}async createThread(Q){let $=crypto.randomUUID();return this.threads.set($,{messages:[],touchedAt:Date.now()}),this.sweep(),{threadId:$}}async loadThread(Q){this.sweep();let $=this.threads.get(Q);if(!$)return this.clientOwnedIds?[]:null;return $.touchedAt=Date.now(),$.messages.slice()}async appendMessages(Q,$){this.sweep();let Z=this.threads.get(Q);if(!Z){if(!this.clientOwnedIds)throw Error(`Thread ${Q} does not exist here, or has expired.`);Z={messages:[],touchedAt:Date.now()},this.threads.set(Q,Z)}for(let J of $){let W=Z.messages.findIndex((X)=>X.id===J.id);if(W===-1)Z.messages.push(J);else Z.messages[W]=J}Z.touchedAt=Date.now()}async removeMessages(Q,$){this.sweep();let Z=this.threads.get(Q);if(!Z)return;let J=new Set($);Z.messages=Z.messages.filter((W)=>!J.has(W.id)),Z.touchedAt=Date.now()}delete(Q){this.threads.delete(Q)}get size(){return this.threads.size}sweep(Q=Date.now()){if(Q-this.lastSweep<60000)return;this.lastSweep=Q;for(let[$,Z]of this.threads)if(Q-Z.touchedAt>this.ttlMs)this.threads.delete($)}}var y9=new vQ;function $3(Q={}){return{messages:Q.messages?[...Q.messages]:[],pending:Q.pending?[...Q.pending]:[],error:null,threadId:Q.threadId,seq:Q.seq??-1,cursorRunId:Q.cursorRunId,runMessageIds:[],loadedTools:[]}}function Z3(Q,$,Z=new Date().toISOString()){if(!($.event.type==="run-start"&&$.event.runId!==Q.cursorRunId)&&$.seq<=Q.seq)return Q;return{...J3(Q,$.event,Z),seq:$.seq}}function J3(Q,$,Z){switch($.type){case"run-start":return{...Q,runId:$.runId,cursorRunId:$.runId,threadId:$.threadId??Q.threadId,runMessageIds:[],loadedTools:[],finishReason:void 0,usage:void 0};case"message-start":return p(Q,$.messageId,Z,(J)=>({...J,role:$.role}));case"text-delta":if(e$(Q,$.messageId))return Q;return p(Q,$.messageId,Z,(J)=>({...J,content:Q6(J.content,$.delta)}));case"reasoning-delta":if(e$(Q,$.messageId))return Q;return p(Q,$.messageId,Z,(J)=>({...J,content:$6(J.content,$.delta,$.id)}));case"output-delta":return p(Q,$.messageId,Z,(J)=>({...J,content:Q3(J.content,{type:"output",value:$.snapshot,partial:!0},(W)=>W.type==="output")}));case"tool-call":return p(Q,$.messageId,Z,(J)=>{let W=J.content.findIndex((z)=>z.type==="tool-call"&&z.toolCallId===$.part.toolCallId),X=W===-1?void 0:J.content[W],G=$.part.progress??X?.progress,V=$.part.nested??X?.nested,H=$.part.attachments??X?.attachments,Y={...$.part,...G?{progress:G}:{},...V?{nested:V}:{},...H?{attachments:H}:{}},K=J.content.slice();if(W===-1)K.push(Y);else K[W]=Y;return{...J,content:K}});case"tool-search":{let J=$.loaded.filter((W)=>!Q.loadedTools.includes(W));if(J.length===0)return Q;return{...Q,loadedTools:[...Q.loadedTools,...J]}}case"tool-progress":return r$(Q,$.toolCallId,(J)=>({...J,progress:[...J.progress??[],$.data]}));case"nested-event":{let J=$;return r$(Q,$.toolCallId,(W)=>{let X=W.nested??[],G=X.findIndex((K)=>K.runId===J.runId),V=X[G]??{runId:J.runId,agent:J.agent,messages:[]},H=rZ(V,J,Z),Y=G===-1?[...X,H]:X.map((K,z)=>z===G?H:K);return{...W,nested:Y}})}case"tool-result":{let J=p(Q,$.messageId,Z,(W)=>({...W,content:Q3(W.content,$.part,(X)=>X.type==="tool-result"&&X.toolCallId===$.part.toolCallId)}));return{...J,pending:J.pending.filter((W)=>W.toolCallId!==$.part.toolCallId)}}case"message":{let J=Q.messages.findIndex((G)=>G.id===$.message.id),W=Q.messages.slice();if(J===-1)W.push($.message);else W[J]=$.message;let X=Q.runMessageIds.includes($.message.id)?Q.runMessageIds:[...Q.runMessageIds,$.message.id];return{...Q,messages:W,runMessageIds:X}}case"message-id":{let J=Q.messages.findIndex((X)=>X.id===$.localId);if(J===-1)return Q;let W=Q.messages.some((X)=>X.id===$.messageId)?Q.messages.filter((X,G)=>G!==J):Q.messages.map((X,G)=>G===J?{...X,id:$.messageId}:X);return{...Q,messages:W}}case"awaiting-input":return{...Q,runId:$.runId,pending:[...$.pending]};case"message-end":return p(Q,$.messageId,Z,(J)=>({...J,finishReason:$.finishReason,...$.outputTruncated?{outputTruncated:!0}:{},...$.usage?{usage:$.usage}:{},content:$.outputTruncated||$.finishReason==="length"?J.content.filter((W)=>!(W.type==="output"&&W.partial)):J.content.map((W)=>W.type==="output"&&W.partial?{...W,partial:!1}:W)}));case"usage":return{...Q,usage:$.usage};case"error":return{...Q,error:$.error,pending:[]};case"run-end":return{...Q,runId:void 0,finishReason:$.finishReason,messages:W3(Q,$.finishReason)};default:return Q}}function W3(Q,$){return Q.messages.map((Z)=>Z.role==="assistant"&&Q.runMessageIds.includes(Z.id)?tZ(Z,$):Z)}function tZ(Q,$){let Z=Q.content.map((W)=>W.type==="tool-call"&&W.nested?.some((X)=>X.finishReason===void 0)?{...W,nested:W.nested.map((X)=>X.finishReason===void 0?aZ(X,$):X)}:W);if(Q.finishReason===void 0)return{...Q,finishReason:$,content:Z};return Z.some((W,X)=>W!==Q.content[X])?{...Q,content:Z}:Q}function aZ(Q,$){let Z={messages:Q.messages,pending:[],error:null,seq:-1,runMessageIds:Q.messages.map((J)=>J.id),loadedTools:[]};return{...Q,finishReason:$,messages:W3(Z,$)}}function r$(Q,$,Z){for(let J=Q.messages.length-1;J>=0;J--){let W=Q.messages[J],X=W.content.findIndex((Y)=>Y.type==="tool-call"&&Y.toolCallId===$);if(X===-1)continue;if(W.finishReason!==void 0&&!eZ(Q,W,$))return Q;let G=W.content.slice();G[X]=Z(G[X]);let V=Q.messages.slice();V[J]={...W,content:G};let H=Q.runMessageIds.includes(W.id)?Q.runMessageIds:[...Q.runMessageIds,W.id];return{...Q,runMessageIds:H,messages:V}}return Q}function rZ(Q,$,Z){let J={messages:Q.messages,pending:[],error:null,seq:-1,runMessageIds:Q.messages.map((X)=>X.id),loadedTools:[],finishReason:Q.finishReason},W=J3(J,$.event,Z);return{...Q,...$.label!==void 0?{label:$.label}:{},messages:W.messages,...W.finishReason!==void 0?{finishReason:W.finishReason}:{},...W.usage!==void 0?{usage:W.usage}:{}}}function eZ(Q,$,Z){if($.finishReason!=="awaiting-input")return!1;return!Q.messages.some((J)=>J.content.some((W)=>W.type==="tool-result"&&W.toolCallId===Z))}function e$(Q,$){let Z=Q.messages.find((J)=>J.id===$);return Z!==void 0&&Z.finishReason!==void 0}function p(Q,$,Z,J){let W=Q.messages.findIndex((V)=>V.id===$),X=Q.runMessageIds.includes($)?Q.runMessageIds:[...Q.runMessageIds,$];if(W===-1){let V={id:$,role:"assistant",content:[],createdAt:Z};return{...Q,runMessageIds:X,messages:[...Q.messages,J(V)]}}let G=Q.messages.slice();return G[W]=J(G[W]),{...Q,runMessageIds:X,messages:G}}function Q6(Q,$){let Z=Q[Q.length-1];if(Z&&Z.type==="text")return[...Q.slice(0,-1),{type:"text",text:Z.text+$}];return[...Q,{type:"text",text:$}]}function $6(Q,$,Z){let J=Q[Q.length-1];if(J&&J.type==="reasoning"&&J.id===Z)return[...Q.slice(0,-1),{...J,text:(J.text??"")+$}];return[...Q,Z?{type:"reasoning",id:Z,text:$}:{type:"reasoning",text:$}]}function Q3(Q,$,Z){let J=Q.findIndex(Z);if(J===-1)return[...Q,$];let W=Q.slice();return W[J]=$,W}class u9{store;threadId;report;chain=Promise.resolve();done=new Set;closed=!1;state;runId;constructor(Q,$,Z,J){this.store=Q;this.threadId=$;this.report=J;this.state=$3({messages:Z})}finish(Q){if(this.closed)return;this.done.add(Q.id),this.write(()=>[g9(Q)])}frame(Q){if(this.closed)return;let $=Q.event;if($.type==="run-start")this.runId=$.runId;switch(this.state=Z3(this.state,Q),$.type){case"message":this.write(()=>[g9($.message)]);return;case"tool-call":if($.part.partial)return;this.checkpoint($.messageId);return;case"message-start":case"tool-result":this.checkpoint($.messageId);return;default:return}}close(Q=[]){this.closed=!0;for(let $ of Q)this.done.add($.id)}settled(){return this.chain}checkpoint(Q){if(this.done.has(Q))return;let $=this.state.messages.find((J)=>J.id===Q);if(!$)return;let Z=this.runId;this.write(()=>{let J=g9($);if(J.finishReason===void 0&&Z)J.runId=Z;return[J]})}write(Q){let $;try{$=Q()}catch(Z){this.report(Z);return}this.chain=this.chain.then(()=>this.store.appendMessages(this.threadId,$)).catch((Z)=>this.report(Z))}}function g9(Q){return structuredClone(Q)}async function X3(Q,$){let Z=[],J=null,W=Q.slice();for(let X=0;X<W.length;X++){let G=W[X];if(G.role!=="assistant"||G.finishReason!==void 0)continue;if(G.runId&&await $(G.runId))continue;J??=new Set(Q.flatMap((Y)=>Y.content.flatMap((K)=>K.type==="tool-result"?[K.toolCallId]:[])));let V=G.content.map((Y)=>Y.type==="tool-call"?G3(Y):Y);for(let Y of G.content){if(Y.type!=="tool-call"||J.has(Y.toolCallId))continue;let K={type:"tool-result",toolCallId:Y.toolCallId,name:Y.name,status:"denied",cause:"interrupted"};V.push(K)}let H={...G,content:V,finishReason:"interrupted"};W[X]=H,Z.push(H)}return{messages:W,settled:Z}}function G3(Q){let{partial:$,...Z}=Q;if(!Z.nested?.some((J)=>J.finishReason===void 0))return Z;return{...Z,nested:Z.nested.map(Z6)}}function Z6(Q){if(Q.finishReason!==void 0)return Q;return{...Q,finishReason:"interrupted",messages:Q.messages.map(($)=>$.role==="assistant"&&$.finishReason===void 0?{...$,finishReason:"interrupted",content:$.content.map((Z)=>Z.type==="tool-call"?G3(Z):Z)}:$)}}var J6=L3,fQ=new Map,V3=new WeakMap,hQ=new Map,W6=4194304,X6=1000,G6=5,H3=65536,N3=()=>{};class _3{byKey=new Map;take(Q,$,Z){let J=this.byKey.get(Q);if(!J?.has($)&&(J?.size??0)>=Z)return null;if(!J)J=new Map,this.byKey.set(Q,J);J.set($,(J.get($)??0)+1);let W=!1;return()=>{if(W)return;W=!0;let X=this.byKey.get(Q),G=(X?.get($)??1)-1;if(!X)return;if(G>0)X.set($,G);else if(X.delete($),X.size===0)this.byKey.delete(Q)}}}var Y3=new WeakMap;function V6(Q){let $=Y3.get(Q);if(!$)$=new _3,Y3.set(Q,$);return $}class M3 extends J6{static kind="agent-controller";store=y9;liveRuns=w9;attachments=NQ;attachmentStorage=O3;fileOwners=I9;nonces=l;receipts;requireKnownFiles=!1;hookHoldMs=30000;instructions(Q,$){}context(Q,$){return{}}requireThread=!1;maxBodyBytes=W6;maxHistoryMessages=X6;maxConcurrentRuns=G6;runLimitKey(Q,$){return $.owner}authorizeRequest(Q,$){}runOwner(Q){let $=Q.ctx?.()?.user,Z=$?.id??$?.publicId;if(Z!==void 0&&Z!==null&&String(Z)!=="")return`user:${String(Z)}`;return null}async stream(Q=new YQ){let $=await c9(Q,this.maxBodyBytes);if($.error)return yQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:void 0,W=F6(Z);if(W.error)return yQ({body:{},error:W.error});let X=W.turn,G=J!==void 0&&Z.regenerate===!0,V=typeof Z.clientRunId==="string"?Z.clientRunId:void 0,H=S3(Z);if(this.requireThread&&!J)return x(400,{code:"thread_required",message:"This agent takes a turn only on a thread: send a threadId."});if(G&&!this.store.removeMessages)return x(501,{code:"regenerate_unsupported",message:"This agent's store cannot remove messages, so a thread's answer cannot be regenerated. Implement `removeMessages` on the AgentStore."});if(!J&&Array.isArray(Z.messages)&&Z.messages.length>this.maxHistoryMessages)return d9(413,"history_too_long",`The conversation has ${Z.messages.length} messages; this agent takes at most ${this.maxHistoryMessages}.`);let Y=await this.runOwner(Q),K=V?{cancelled:!1,owner:Y}:null;if(K)hQ.set(V,K);let z=null,B=[],U=async()=>{try{return await j()}finally{if(J&&B.length>0&&z===null)await this.store.appendMessages(J,B).catch((D)=>this.reportHookFailure(D))}},j=async()=>{let D;if(J){let O=await this.store.loadThread(J);if(!O)return x(404,{code:"thread_not_found",message:`Thread ${J} does not exist here, or has expired.`});if(D=await this.settleThread(J,O,{write:!0}),G){let P=P6(D);if(!P)return x(409,{code:"nothing_to_regenerate",message:`Thread ${J} has no user turn to answer again.`});B=D.slice(P.index),await this.store.removeMessages(J,B.map((A3)=>A3.id)),D=D.slice(0,P.index),X=X?.localId?{...P.turn,localId:X.localId}:P.turn}}else D=Array.isArray(Z.messages)?Z.messages:[],R6(this.nonces);let L=await this.instructions(Q,{body:H})||void 0,F=await this.context(Q,{body:H}),S=await this.attachmentsFor(Q,J,{body:H});if(K?.cancelled)return U3();let N=J?new u9(this.store,J,D,(O)=>this.reportHookFailure(O)):null,v=`run_${crypto.randomUUID()}`,b={req:Q,runId:v,threadId:J},_=this.agent.stream({runId:v,messages:D,turn:X,threadId:J,...N?{onMessage:(O)=>N.finish(O)}:{},instructions:L,context:F,attachments:S,body:H,redactError:(O,P)=>this.redactError(O,P,b),nonces:this.nonces,receipts:this.receipts,subject:Y}),w=this.liveRuns.register(_,{threadId:J,owner:Y,clientRunId:V,onEvent:(O)=>this.dispatchEvent(O,b),onInternalError:(O)=>this.reportHookFailure(O),maxRunDurationMs:this.agent.maxRunDurationMs});if(z=_,N)this.follow(_,N);let{stored:q,hooks:C}=this.persistRun(_,b,w,N);return V3.set(_,q),Q.ctx?.()?.waitUntil(C),_.toResponse()};try{await this.authorizeRequest(Q,{route:"stream",threadId:J,body:H});let D=await this.foreignFile([...X?.files??[],...J?[]:q6(Z.messages)],Y);if(D)return D;if(K?.cancelled)return U3();let L=await this.runLimitKey(Q,{owner:Y,threadId:J}),F=L===null?N3:V6(this.liveRuns).take(L,J?`thread:${J}`:`run:${crypto.randomUUID()}`,this.maxConcurrentRuns);if(!F)return d9(429,"too_many_runs",`You already have ${this.maxConcurrentRuns} conversations answering. Wait for one to finish, or stop it, and send again.`);try{return J?await this.withThread(J,Y,U):await U()}finally{let S=z;if(S)S.result().then(F,F);else F()}}finally{if(K&&hQ.get(V)===K)hQ.delete(V)}}async withThread(Q,$,Z){let J=fQ.get(Q)??Promise.resolve(),W,X=new Promise((V)=>{W=V}),G=J.then(()=>X);fQ.set(Q,G),await J;try{let V=await this.liveRuns.find({threadId:Q});if(V&&this.liveRuns.isRunning(V.runId)&&!this.liveRuns.mayAccess(V.runId,$))return gQ();let H=V?this.liveRuns.get(V.runId):null;if(H)H.stop({reason:"superseded by a later turn on this thread"}),await V3.get(H);return await Z()}finally{if(W(),fQ.get(Q)===G)fQ.delete(Q)}}async attach(Q=new YQ){let $=await c9(Q,H3);if($.error)return yQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:C6(Q,"threadId");if(!J)return x(400,{code:"invalid_request",message:"attach needs a threadId: it is the handle that survives a refresh."});await this.authorizeRequest(Q,{route:"attach",threadId:J});let W=await this.liveRuns.find({threadId:J});if(W&&!this.liveRuns.mayAccess(W.runId,await this.runOwner(Q)))return gQ();if(!W)return x(404,{code:"no_live_run",message:`No run in progress for thread ${J} in this process.`});let X=typeof Z.runId==="string"?Z.runId:void 0,G=X&&X!==W.runId?void 0:L6(Q,Z);try{return D$(this.liveRuns.replay(W.runId,G))}catch(V){if(V instanceof t)return x(410,{code:V.code,message:V.message,oldestSeq:V.oldest});if(V instanceof HQ)return x(404,{code:V.code,message:V.message});throw V}}async stop(Q=new YQ){let $=await c9(Q,H3);if($.error)return yQ($);let Z=$.body;await this.authorizeRequest(Q,{route:"stop",threadId:typeof Z.threadId==="string"?Z.threadId:void 0});let J=await this.runOwner(Q),W=typeof Z.runId==="string"?Z.runId:void 0;if(!W&&typeof Z.clientRunId==="string"){if(W=this.liveRuns.findByClientRunId(Z.clientRunId)??void 0,!W){let G=hQ.get(Z.clientRunId);if(G){if(G.owner!==null&&G.owner!==J)return gQ();return G.cancelled=!0,{stopped:!0}}}}if(!W&&typeof Z.threadId==="string")W=(await this.liveRuns.find({threadId:Z.threadId}))?.runId;let X=W?this.liveRuns.get(W):null;if(!X)return{stopped:!1};if(!this.liveRuns.mayAccess(X.runId,J))return gQ();return X.stop({reason:typeof Z.reason==="string"?Z.reason:void 0}),{stopped:!0}}attachmentScope(Q,$,Z){let J=Q.ctx()?.user,W=J?.id??J?.publicId;if(W!==void 0&&W!==null&&String(W)!=="")return{key:`user:${String(W)}`};if($)return{key:`thread:${$}`};return null}attachmentLimits(Q){return null}attachmentDestination(Q,$){return"both"}async attachmentsFor(Q,$,Z={body:{}}){let J=await this.attachmentScope(Q,$,Z);if(!J)return null;return new WQ(this.attachments,this.attachmentStorage,J)}async upload(Q=new YQ){let $=await Q.rawRequest.formData(),Z=$.get("file");if(!(Z instanceof Blob))throw Error("upload expects a multipart body with a `file` field.");let J=Z instanceof File&&Z.name?Z.name:"upload",W=Z.type||"application/octet-stream",X=Y6($.get("body")),G=$.get("threadId");await this.authorizeRequest(Q,{route:"upload",threadId:typeof G==="string"&&G.length>0?G:void 0,body:X});let V=z6(await this.attachmentLimits(Q),Z,J,W);if(V)throw new R3(V.code,V.message);let H=typeof G==="string"&&G.length>0&&await this.store.loadThread(G)!==null?G:void 0,Y=await this.runOwner(Q),K=(N)=>this.fileOwners.record(N,{owner:Y,name:J,mimeType:W,size:Z.size,createdAt:new Date().toISOString()}),z=await this.attachmentDestination(Z,Q),B=N6(z,$.get("destination")),U=await this.attachmentScope(Q,H,{body:X}),j=B!=="provider"&&!U;if(j){if(B==="storage")throw Error('This upload was routed to storage, but `attachmentScope()` returned null for the request, so there is no subject to file the attachment under. Guard the route (`this.agent(Chat).middleware({ upload: "auth" })`), send a `threadId` with the upload, or override `attachmentScope()`.');_6()}if(B==="provider"||!U){let N=await K3(this.agent.provider,Z);await K(N);let v={fileId:N,name:J,mimeType:W,size:Z.size,destination:"provider"};if(j)v.downgraded="no_scope";return v}let D=aQ(),L=await this.attachmentStorage.put({name:rQ(D,J),body:Z,contentType:W}),F=B==="both"?await K3(this.agent.provider,Z):void 0;if(F)await K(F);let S={id:D,scopeKey:U.key,fileId:F,objectName:L,name:J,mimeType:W,size:Z.size,createdAt:new Date().toISOString(),destination:B};return await this.attachments.put(U,S),{fileId:F,attachmentId:D,name:J,mimeType:W,size:Z.size,destination:B}}async foreignFile(Q,$){let Z=new Set(Q.map((J)=>J.fileId).filter((J)=>typeof J==="string"));for(let J of Z){let W=await this.fileOwners.get(J);if(W?W.owner!==null&&W.owner!==$:this.requireKnownFiles)return O6()}return null}onMessage(Q,$){}onToolCall(Q,$){}onAwaitingInput(Q,$){}redactError(Q,$,Z){return l9(Q,$)}onError(Q,$){}onStreamComplete(Q,$){}reportHookFailure(Q){console.error("[gemi/ai] agent controller hook failed",Q)}async dispatchEvent(Q,$){switch(Q.type){case"tool-call":if(!Q.part.partial&&!Q.resent)await this.onToolCall({toolCallId:Q.part.toolCallId,name:String(Q.part.name),input:Q.part.input},$);return;case"awaiting-input":await this.onAwaitingInput(Q.pending,$);return;case"error":await this.onError(q3(Q.error),$);return;default:return}}async readThread(Q){let $=await this.store.loadThread(Q);return $?await this.settleThread(Q,$,{write:!1}):null}isRunLive(Q,$){return this.liveRuns.get(Q)!==null}async settleThread(Q,$,{write:Z}){let{messages:J,settled:W}=await X3($,(X)=>this.isRunLive(X,Q));if(Z&&W.length>0)try{await this.store.appendMessages(Q,W)}catch(X){this.reportHookFailure(X)}return J}follow(Q,$){(async()=>{try{for await(let Z of Q.frames())$.frame(Z)}catch(Z){this.reportHookFailure(Z)}})()}persistRun(Q,$,Z,J=null){let W=Promise.resolve(),X=(async()=>{let V;try{V=await Q.result()}catch(Y){J?.close(),await J?.settled(),W=this.safely(()=>this.onError({code:"unknown",message:Y instanceof Error?Y.message:String(Y),retryable:!1},$));return}let H=V.messages;if(J?.close(H),await J?.settled(),$.threadId&&H.length>0)try{await this.store.appendMessages($.threadId,H)}catch(Y){this.reportHookFailure(Y)}W=this.notifyRun(V,H,$)})(),G=X.then(()=>S6(Promise.all([W,Z]).then(()=>{}),this.hookHoldMs));return{stored:X,hooks:G}}async notifyRun(Q,$,Z){for(let J of $)await this.safely(()=>this.onMessage(J,Z));await this.safely(()=>this.onStreamComplete(Q,Z))}async safely(Q){try{await Q()}catch($){this.reportHookFailure($)}}}var m9=["turn","clientRunId","threadId","messages","regenerate"],H6=["text","files","toolResults"];function S3(Q,$=k3(Q)?m9:[...m9,...H6]){let Z={};for(let[J,W]of Object.entries(Q)){if($.includes(J))continue;Object.defineProperty(Z,J,{value:W,writable:!0,enumerable:!0,configurable:!0})}return Z}function Y6(Q){if(Q===null)return{};let $;if(typeof Q==="string")try{$=JSON.parse(Q)}catch{throw new p9("The upload's `body` field is not valid JSON.")}if($===null||typeof $!=="object"||Array.isArray($))throw new p9("The upload's `body` field must be a JSON object.");return S3($,m9)}class p9 extends uQ{constructor(Q){super(Q);this.name="InvalidUploadError",this.payload={api:{status:400,data:{error:{code:"invalid_request",message:Q}}},view:{}}}}async function K3(Q,$){try{return await Q.upload($)}catch(Z){if(Z instanceof h&&K6.has(Z.status))throw new T3(k(Z).message);throw Z}}var K6=new Set([400,413,415,422]);class R3 extends uQ{constructor(Q,$){super($);this.name="LimitedUploadError",this.payload={api:{status:422,data:{error:{code:Q,message:$}}},view:{}}}}function z6(Q,$,Z,J){if(!Q)return null;let{maxBytes:W,accept:X}=Q;if(typeof W==="number"&&$.size>W)return{code:"file_too_large",message:`${JSON.stringify(Z)} is ${z3($.size)}; the limit is ${z3(W)}.`};if(X&&X.length>0&&!X.some((G)=>B6(G,Z,J)))return{code:"unsupported_file_type",message:`${JSON.stringify(Z)} is not a type this chat accepts. Accepted: ${X.join(", ")}.`};return null}function B6(Q,$,Z){let J=Q.trim().toLowerCase();if(!J)return!1;if(J.startsWith("."))return $.toLowerCase().endsWith(J);let W=Z.toLowerCase().split(";")[0].trim();if(J.endsWith("/*"))return W.startsWith(J.slice(0,-1));return W===J}function z3(Q){if(Q<1024)return`${Q} B`;let $=["KB","MB","GB"],Z=Q/1024,J=0;while(Z>=1024&&J<$.length-1)Z/=1024,J++;return`${Math.round(Z*10)/10} ${$[J]}`}class T3 extends uQ{constructor(Q){super(Q);this.name="RejectedUploadError";let $=/(unsupported|invalid) (extension|file type|format|mime)|supported (extensions|formats?)/i.test(Q)?"unsupported_file_type":"file_rejected";this.payload={api:{status:422,data:{error:{code:$,message:Q}}},view:{}}}}async function c9(Q,$){let Z=Q?.rawRequest;if(!Z||Z.method==="GET"||Z.method==="HEAD"||!Z.body)return{body:{}};if(!D6(Z.headers.get("Content-Type")))return{body:{},status:415,code:"unsupported_media_type",error:"The request body must be sent as application/json."};let J=Number(Z.headers.get("Content-Length"));if(Number.isFinite(J)&&J>$)return B3($);let W;try{let G=await U6(Z,$);if(G===null)return B3($);W=G}catch{return{body:{},error:"The request body could not be read."}}if(!W.trim())return{body:{}};let X;try{X=JSON.parse(W)}catch{return{body:{},error:"The request body is not valid JSON."}}if(X===null||typeof X!=="object"||Array.isArray(X))return{body:{},error:"The request body must be a JSON object."};return{body:X}}function D6(Q){return P3(Q)==="application/json"}async function U6(Q,$){if(!Number.isFinite($)||!Q.body)return await Q.text();let Z=Q.body.getReader(),J=[],W=0;for(;;){let{done:V,value:H}=await Z.read();if(V)break;if(W+=H.byteLength,W>$)return await Z.cancel().catch(N3),null;J.push(H)}let X=new Uint8Array(W),G=0;for(let V of J)X.set(V,G),G+=V.byteLength;return new TextDecoder().decode(X)}function B3(Q){return{body:{},status:413,code:"body_too_large",error:`The request body is larger than this agent accepts (${Q} bytes).`}}function d9(Q,$,Z){return x(Q,{...cQ(C3(Q),Z,Q),code:$})}function yQ(Q){if(Q.status===413)return d9(413,Q.code??"body_too_large",Q.error??"");return x(Q.status??400,{code:Q.code??"invalid_request",message:Q.error})}function k3(Q){return Boolean(Q.turn)&&typeof Q.turn==="object"}function F6(Q){let $=k3(Q)?Q.turn:Q,Z={};if(typeof $.text==="string")Z.text=$.text;if(Array.isArray($.files)){let J=j6($.files);if(typeof J==="string")return{error:J};Z.files=J}if(Array.isArray($.toolResults))Z.toolResults=$.toolResults;if(Object.keys(Z).length===0)return{};if($===Q.turn&&$.localId!==void 0&&$.localId!==null&&$.localId!==""){let{localId:J}=$;if(typeof J!=="string")return{error:"turn.localId must be a string."};if(J.length>D3)return{error:`turn.localId is longer than ${D3} characters.`};Z.localId=J}return{turn:Z}}var D3=200;function j6(Q){let $=[];for(let[Z,J]of Q.entries()){let W=`turn.files[${Z}]`;if(!J||typeof J!=="object"||Array.isArray(J))return`${W} must be an object.`;let X={};for(let K of["fileId","attachmentId","name","mimeType"]){let z=J[K];if(z===void 0||z===null||z==="")continue;if(typeof z!=="string")return`${W}.${K} must be a string.`;X[K]=z}let{fileId:G,attachmentId:V,name:H,mimeType:Y}=X;if(G?.startsWith(f))return`${W}.fileId holds a gemi attachment id (${G}). \`fileId\` is the provider's id from the upload response; put this one in \`attachmentId\`.`;if(V!==void 0&&!V.startsWith(f))return`${W}.attachmentId is not a gemi attachment id: it must start with "${f}".`;if(!G&&!V)return`${W} has neither a \`fileId\` nor an \`attachmentId\`. Send the ids the upload response answered.`;$.push({...G?{fileId:G}:{},...V?{attachmentId:V}:{},...H!==void 0?{name:H}:{},...Y!==void 0?{mimeType:Y}:{}})}return $}function L6(Q,$){if(typeof $.from==="number"&&Number.isFinite($.from))return Math.max(0,Math.floor($.from));if(typeof $.cursor==="number"&&Number.isFinite($.cursor)){let J=Math.floor($.cursor);if(J>=0)return J+1;return}let Z=Q?.rawRequest?.headers?.get("Last-Event-ID");if(Z){let J=Number.parseInt(Z,10);if(Number.isFinite(J))return Math.max(0,J+1)}return}function C6(Q,$){let Z=Q?.search?.get($);return typeof Z==="string"?Z:void 0}function P6(Q){let $=MQ(Q);for(let Z=Q.length-1;Z>=0;Z--){let J=Q[Z];if(J.role!=="user"||$.has(J.id))continue;let W="",X=[];for(let G of J.content){if(G.type==="text")W+=G.text;if(G.type==="file")X.push({...G.fileId?{fileId:G.fileId}:{},...G.attachmentId?{attachmentId:G.attachmentId}:{},...G.name?{name:G.name}:{},...G.mimeType?{mimeType:G.mimeType}:{}})}if(!W&&X.length===0)continue;return{index:Z,turn:{...W?{text:W}:{},...X.length>0?{files:X}:{}}}}return null}function U3(){return x(409,{code:"stopped",message:"The turn was stopped before it started."})}function gQ(){return x(403,cQ("permission","This run belongs to someone else.",403))}function O6(){return x(403,cQ("permission","A file in this turn was uploaded by someone else.",403))}function q6(Q){if(!Array.isArray(Q))return[];let $=[];for(let Z of Q){let J=Z?.content;if(!Array.isArray(J))continue;for(let W of J)if(W&&typeof W==="object"&&typeof W.fileId==="string")$.push({fileId:W.fileId})}return $}function x(Q,$){return new Response(JSON.stringify({error:$}),{status:Q,headers:{"Content-Type":"application/json"}})}function N6(Q,$){if(typeof $!=="string"||$.length===0)return Q;if($!=="both"&&$!=="provider"&&$!=="storage")throw Error(`Unknown attachment destination "${$}". Expected "both", "provider" or "storage".`);if($===Q||Q==="both"&&$==="storage")return $;if(Q==="both"&&$==="provider")throw Error('This upload asked for the "provider" destination under a "both" policy. A client may ask for "storage", which keeps a file away from the model provider, but it may not ask the server to stop keeping its own copy while the vendor still gets the file \u2014 that is the app\'s retention decision. Change `attachmentDestination()` if this file should not be kept.');throw Error(`This upload asked for the "${$}" destination, but the server's policy for it is "${Q}", and a client hint may only ask for "storage" under a "both" policy. Change \`attachmentDestination()\` if the file really should go there.`)}var F3=!1;function _6(){if(F3)return;F3=!0,console.warn("[gemi/ai] An upload had no attachment scope, so its bytes were sent to the model provider only and no attachment id was minted \u2014 a tool cannot forward this file. Guard the route with auth, send a `threadId` with the upload, or override `attachmentScope()`.")}var M6=2147483647;function S6(Q,$){let Z=Q.then(()=>{},()=>{});if(!($<=M6))return Z;let J,W=new Promise((X)=>{J=setTimeout(X,$)});return Promise.race([Z,W]).finally(()=>clearTimeout(J))}var j3=!1;function R6(Q){if(j3||Bun.env.NODE_ENV!=="production")return;if(!(Q instanceof $Q))return;j3=!0,console.warn("[gemi/ai] A stateless agent chat is spending approval nonces in process memory. With more than one instance a replayed approval is accepted once per instance. Set `nonces = new RedisNonceStore()` (or your own NonceStore) on the AgentController.")}export{KZ as toAgentTools,a as supportsStrict,k6 as s,l9 as redactError,w9 as liveRuns,v3 as generate,oZ as evalChain,l as defaultNonceStore,I9 as defaultFileOwners,NQ as defaultAttachmentStore,y9 as defaultAgentStore,RQ as ToolNamespace,T as ToolError,V9 as Skill,WQ as ScopedAttachments,XQ as SKILLS_NAMESPACE,h9 as RedisReceiptStore,pQ as RedisNonceStore,u as PendingEscalation,k9 as OpenAIProvider,F9 as OpenAIImageProvider,f9 as MemoryReceiptStore,$Q as MemoryNonceStore,wQ as MemoryLiveRuns,IQ as MemoryFileOwners,bQ as MemoryCircuitStore,qQ as MemoryAttachmentStore,vQ as MemoryAgentStore,HQ as LiveRunNotFoundError,T6 as JSONSchemaError,i as InvalidAttachmentScopeError,AQ as ImageRequestError,EQ as ImageProvider,B9 as ImageModel,t as FrameCursorEvictedError,VQ as FallbackProvider,K9 as DEFAULT_MAX_RUN_DURATION_MS,A9 as AzureOpenAIProvider,j9 as AzureOpenAIImageProvider,JQ as AttachmentNotFoundError,c as AgentTool,QQ as AgentRunError,s as AgentProvider,M3 as AgentController,z9 as Agent};
25
25
 
26
- //# debugId=9939549B72201E5764756E2164756E21
26
+ //# debugId=E0F78A2E0703D55564756E2164756E21