gemi 0.65.0 → 0.66.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/Agent.d.ts +55 -1
- package/dist/ai/Agent.d.ts.map +1 -1
- package/dist/ai/AgentProvider.d.ts +8 -44
- package/dist/ai/AgentProvider.d.ts.map +1 -1
- package/dist/ai/ImageModel.d.ts +127 -0
- package/dist/ai/ImageModel.d.ts.map +1 -0
- package/dist/ai/ImageProvider.d.ts +94 -0
- package/dist/ai/ImageProvider.d.ts.map +1 -0
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +12 -12
- package/dist/ai/index.js.map +12 -8
- package/dist/ai/providers/call.d.ts +12 -0
- package/dist/ai/providers/call.d.ts.map +1 -1
- package/dist/ai/providers/endpoints.d.ts +153 -0
- package/dist/ai/providers/endpoints.d.ts.map +1 -0
- package/dist/ai/providers/fakeProvider.d.ts +54 -0
- package/dist/ai/providers/fakeProvider.d.ts.map +1 -1
- package/dist/ai/providers/http.d.ts +28 -0
- package/dist/ai/providers/http.d.ts.map +1 -1
- package/dist/ai/providers/images.d.ts +126 -0
- package/dist/ai/providers/images.d.ts.map +1 -0
- package/dist/ai/store/Attachments.d.ts +52 -0
- package/dist/ai/store/Attachments.d.ts.map +1 -1
- package/dist/ai/types.d.ts +26 -0
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/{chunk-j3b3qerv.js → chunk-gyc91g26.js} +1 -1
- package/dist/{chunk-x917yccy.js → chunk-qttk7k60.js} +1 -1
- package/dist/{chunk-fk127cwf.js → chunk-w6fnt1xv.js} +2 -2
- package/dist/{chunk-fk127cwf.js.map → chunk-w6fnt1xv.js.map} +1 -1
- package/dist/client/ProgressManager.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-j3b3qerv.js.map → chunk-gyc91g26.js.map} +0 -0
- /package/dist/{chunk-x917yccy.js.map → chunk-qttk7k60.js.map} +0 -0
package/dist/ai/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Ib as
|
|
2
|
+
import{Ib as X$,Jb as r}from"../chunk-hq496pa4.js";import{Ce as m6,Te as g,ef as p6}from"../chunk-a85fn4zf.js";import"../chunk-g2ywq30n.js";import"../chunk-pcxxnnad.js";import"../chunk-p5m0da00.js";import"../chunk-5g1j29p2.js";import"../chunk-r6v21jn6.js";import{createHmac as i6,randomBytes as lQ,timingSafeEqual as dQ}from"crypto";var zQ="agt1",iQ=86400000;function m(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 q(Q){if(Q===null||typeof Q!=="object")return JSON.stringify(Q)??"null";if(Array.isArray(Q))return`[${Q.map(q).join(",")}]`;let $=Q;return`{${Object.keys($).filter((J)=>$[J]!==void 0).sort().map((J)=>`${JSON.stringify(J)}:${q($[J])}`).join(",")}}`}function n6(Q){return Q.map(($)=>`${$.length}:${$}`).join("")}function p(Q,$){return i6("sha256",Q).update(n6($)).digest()}function nQ(Q,$,Z){let J=[zQ,Q.runId,Q.toolCallId,Q.name,Q.kind,$,String(Z),q(Q.input)];if(Q.path&&Q.path.length>0)J.push(q(Q.path));return J}var oQ=(Q)=>Buffer.from(Q,"utf8").toString("base64url"),o6=(Q)=>Buffer.from(Q,"base64url").toString("utf8");function sQ(Q,$={}){let Z=m($.secret),G=($.now??Date.now())+($.ttlMs??iQ),W=lQ(12).toString("base64url"),Y=p(Z,nQ(Q,W,G)).toString("base64url");return[zQ,oQ(Q.runId),W,G.toString(36),Y].join(".")}function l(Q){return FQ(Q,zQ)}function FQ(Q,$){let Z=Q.split(".");if(Z.length!==5||Z[0]!==$)return null;let J=Number.parseInt(Z[3],36);if(!Number.isFinite(J))return null;try{return{runId:o6(Z[1]),nonce:Z[2],expiresAt:J}}catch{return null}}function tQ(Q,$,Z={}){let J=m(Z.secret),G=l(Q);if(!G)return{ok:!1,reason:"malformed"};let W=Buffer.from(Q.split(".")[4],"base64url"),Y=p(J,nQ($,G.nonce,G.expiresAt));if(W.length!==Y.length||!dQ(W,Y))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>G.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:G.runId,nonce:G.nonce,expiresAt:G.expiresAt}}var d="agn1";function aQ(Q,$,Z){return[d,Q.runId,q(Q.path),Q.nestedRunId,$,String(Z),q([...Q.open].sort()),q(Q.input)]}function rQ(Q,$={}){let Z=m($.secret),G=($.now??Date.now())+($.ttlMs??iQ),W=lQ(12).toString("base64url"),Y=p(Z,aQ(Q,W,G)).toString("base64url");return[d,oQ(Q.runId),W,G.toString(36),Y].join(".")}function eQ(Q,$,Z={}){let J=m(Z.secret),G=FQ(Q,d);if(!G)return{ok:!1,reason:"malformed"};let W=Buffer.from(Q.split(".")[4],"base64url"),Y=p(J,aQ({...$,runId:G.runId},G.nonce,G.expiresAt));if(W.length!==Y.length||!dQ(W,Y))return{ok:!1,reason:"forged"};if((Z.now??Date.now())>G.expiresAt)return{ok:!1,reason:"expired"};return{ok:!0,runId:G.runId,nonce:G.nonce,expiresAt:G.expiresAt}}var E=new Map,Q6=1024;function s6(Q){for(let[$,Z]of E)if(Z<=Q)E.delete($);Q6=Math.max(1024,E.size*2)}function $6(Q,$={}){return J6(l(Q),$)}function Z6(Q,$={}){return J6(FQ(Q,d),$)}function J6(Q,$){if(!Q)return!1;let Z=$.now??Date.now();if(E.size>=Q6)s6(Z);let J=E.get(Q.nonce);if(J!==void 0&&J>Z)return!1;return E.set(Q.nonce,Q.expiresAt),!0}class v extends Error{id;code="attachment_not_found";constructor(Q){super(`No attachment ${Q}.`);this.id=Q;this.name="AttachmentNotFoundError"}}class A extends Error{code="invalid_attachment_scope";constructor(Q){super(Q);this.name="InvalidAttachmentScopeError"}}function LQ(Q){if(!Q||typeof Q.key!=="string"||Q.key.length===0)throw new A("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 N="gemi_att_";function CQ(){return`${N}${crypto.randomUUID()}`}class f{store;storage;scope;constructor(Q,$,Z){this.store=Q;this.storage=$;this.scope=Z;LQ(Z)}async get(Q){let $=await this.store.find(this.scope,Q);if(!$||$.scopeKey!==this.scope.key)throw new v(Q);return $}async read(Q){return await this.readRecord(Q,await this.get(Q))}async readRecord(Q,$){if(!$.objectName)throw new v(Q);return await this.storage.read({name:$.objectName})}async file(Q){let $=await this.get(Q),J=(await this.readRecord(Q,$)).body,G=J instanceof Blob?J:J?await new Response(J).blob():new Blob([]);return new File([G],$.name,{type:$.mimeType})}async put(Q,$={}){let Z=CQ(),J=$.mimeType??Q.type??"",G=$.name??(Q instanceof File?Q.name:Z),W=await this.storage.put({name:OQ(Z,G),body:Q,contentType:J||void 0}),Y={id:Z,scopeKey:this.scope.key,objectName:W,name:G,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,Y),Y}}function OQ(Q,$){let Z=/\.([A-Za-z0-9]{1,8})$/.exec($);return`attachments/${Q}${Z?`.${Z[1].toLowerCase()}`:""}`}class i{rows=new Map;async put(Q,$){LQ(Q),this.rows.set($.id,{...$,scopeKey:Q.key})}async find(Q,$){LQ(Q);let Z=this.rows.get($);if(!Z||Z.scopeKey!==Q.key)return null;return Z}get size(){return this.rows.size}}var n=new i;var jQ=new TextEncoder;function G6(Q){return`id: ${Q.seq}
|
|
3
3
|
data: ${JSON.stringify(Q.event)}
|
|
4
4
|
|
|
5
|
-
`}var
|
|
5
|
+
`}var t6=5000,a6=`: keepalive
|
|
6
6
|
|
|
7
|
-
`;function
|
|
8
|
-
${await
|
|
7
|
+
`;function NQ(Q,$=t6){let Z=null,J=!1,G=()=>{if(J)return;if(Z!==null)clearTimeout(Z);Z=setTimeout(()=>{if(Z=null,J)return;try{Q.enqueue(jQ.encode(a6))}catch{W();return}G()},$)},W=()=>{if(J=!0,Z!==null)clearTimeout(Z);Z=null};return G(),{touch:G,stop:W}}function r6(){return{"Content-Type":"text/event-stream","Cache-Control":"no-store, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}}function W6(Q,$=200){let Z=Q[Symbol.asyncIterator](),J=-1,G,W=new ReadableStream({start(Y){G=NQ(Y)},async pull(Y){try{let V=await Z.next();if(V.done){G.stop(),Y.close();return}J=V.value.seq,Y.enqueue(jQ.encode(G6(V.value))),G.touch()}catch(V){let X={type:"error",error:e6(V)};G.stop(),Y.enqueue(jQ.encode(G6({seq:J+1,event:X}))),Y.close()}},cancel(Y){G.stop(),Z.return?.(Y)}});return new Response(W,{status:$,headers:r6()})}function e6(Q){return{code:"unknown",message:Q instanceof Error?Q.message:String(Q),retryable:!1}}class S 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 T{name;description;inputSchema;outputSchema;requiresApproval;deferred;answeredBy;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}static create(Q){return new T(Q)}static ask(Q){return T.create({name:Q.name,description:Q.description,inputSchema:MQ,outputSchema:Q.outputSchema,answeredBy:"client"})}}var MQ={toJSONSchema:()=>({type:"object",properties:{question:{type:"string",description:"What to ask the user"}},required:["question"],additionalProperties:!1}),parse(Q){let $=MQ.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 e{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 e(Q)}}class qQ{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 qQ(Q)}}var h="skills",Q9="Instructions this agent can load on demand. Load the relevant one before acting in the area it covers.",F6={type:"object",properties:{},required:[],additionalProperties:!1},$9=8,Z9=3;class SQ{name;tools;skills;provider;output;instructions;maxSteps;maxDepth;reasoning;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??$9,this.maxDepth=Q.maxDepth??Z9,this.reasoning=Q.reasoning;let{registry:$,providerTools:Z}=J9(this.tools,this.skills);this.config={name:this.name,instructions:this.instructions,provider:this.provider,registry:$,providerTools:Z,output:Q.output,maxSteps:this.maxSteps,maxDepth:this.maxDepth,reasoning:this.reasoning,maxOutputTokens:Q.maxOutputTokens,temperature:Q.temperature}}static create(Q){return new SQ(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};return new C6($,Q)}}function Y6(Q){return{name:Q.tool.name,description:Q.tool.description,parameters:Q.tool.inputSchema.toJSONSchema(),strict:r(Q.tool.inputSchema),deferred:Q.deferred}}function J9(Q,$){let Z=new Map,J=[],G=(W)=>{if(Z.has(W.tool.name))throw Error(`Two tools are named "${W.tool.name}". Tool names are global within an agent \u2014 the client discriminates a tool part by name alone.`);Z.set(W.tool.name,W)};for(let W of Q){if(W instanceof e){if(W.name===h)throw Error(`"${h}" 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 X of W.tools){let K={tool:X,namespace:W.name,deferred:W.deferred||X.deferred};G(K),V.push(Y6(K))}J.push({name:W.name,description:W.description,tools:V});continue}let Y={tool:W,deferred:W.deferred};G(Y),J.push(Y6(Y))}if($.length>0){let W=[];for(let Y of $){let V=G9(Y);G({tool:V,namespace:h,deferred:!1}),W.push({name:Y.name,description:Y.description,parameters:F6,strict:!0,deferred:!1})}J.push({name:h,description:Q9,tools:W})}return{registry:Z,providerTools:J}}function G9(Q){return T.create({name:Q.name,description:Q.description,inputSchema:{toJSONSchema:()=>F6,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 W9(J)}`);return Z.join(`
|
|
9
9
|
|
|
10
|
-
`)}})}async function
|
|
11
|
-
data: ${JSON.stringify(
|
|
10
|
+
`)}})}async function W9(Q){try{return await Bun.file(Q).text()}catch($){return`(could not be read: ${$.message})`}}class R extends Error{constructor(){super("The run was stopped");this.name="RunAborted"}}function o(Q,$){if($.aborted)return Promise.reject(new R);return new Promise((Z,J)=>{let G=()=>J(new R);$.addEventListener("abort",G,{once:!0}),Q.then(Z,J).finally(()=>$.removeEventListener("abort",G))})}function s(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function t(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 Y9(Q){return typeof Q==="object"&&Q!==null&&typeof Q.next==="function"&&Symbol.asyncIterator in Q}function _Q(Q){if(!Q.trim())return{};try{return JSON.parse(Q)}catch{}let $=[],Z=!1,J=!1;for(let Y of Q){if(Z){if(J)J=!1;else if(Y==="\\")J=!0;else if(Y==='"')Z=!1;continue}if(Y==='"')Z=!0;else if(Y==="{")$.push("}");else if(Y==="[")$.push("]");else if(Y==="}"||Y==="]")$.pop()}let G=Q;if(Z)G+='"';G=G.replace(/[,:]\s*$/,"");let W=$.reverse().join("");try{return JSON.parse(G+W)}catch{try{return JSON.parse(G.replace(/,?\s*"[^"]*"\s*$/,"")+W)}catch{return{}}}}function X6(Q,$){let Z=[...Q],J=new Map(Z.map((G,W)=>[G.id,W]));for(let G of $){let W=J.get(G.id);if(W===void 0)J.set(G.id,Z.length),Z.push(G);else Z[W]=G}return Z}function a(Q){let $=new Set;for(let J of Q)for(let G of J.content)if(G.type==="tool-result")$.add(G.toolCallId);let Z=new Set;for(let J of Q)for(let G of J.content)if(G.type==="tool-call"&&!$.has(G.toolCallId))Z.add(G.toolCallId);return Z}function V6(Q){for(let $=Q.length-1;$>=0;$--){let Z=Q[$].content;for(let J=Z.length-1;J>=0;J--){let G=Z[J];if(G.type==="output"&&G.partial!==!0)return G.value}}return}function K6(Q,$){return $===void 0?`"${Q}"`:`"${Q}" labelled "${$}"`}function L6(Q){return Q.content.map(($)=>$.type==="text"?$.text:`<${$.type}>`).join("")}function X9(Q){if(Q.prompt!==void 0)return`user:${Q.prompt}`;let $=Q.messages?.[0];return $?`${$.role}:${L6($)}`:null}function H6(Q){let $=new Set;for(let Z of Q)for(let J of Z.content){if(J.type!=="tool-call")continue;for(let G of J.attachments??[])if("shown"in G&&G.shown)$.add(G.shown.messageId)}return $}var B6=1;function V9(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 G=Boolean(Z.showModel);if(G!==Boolean(Q.shown))return G?"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 K9(Q,$,Z){if(Q.agent!==$.name||Q.label!==Z.label)return`was ${K6(Q.agent,Q.label)} on the turn that escalated and is ${K6($.name,Z.label)} on the replay`;let J=X9(Z),G=Q.messages[0],W=G?`${G.role}:${L6(G)}`:null;if(J!==null&&W!==null&&J!==W)return`was started with ${JSON.stringify(W)} on the turn that escalated and with ${JSON.stringify(J)} on the replay`;return null}function D6(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 PQ{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 C6{runId;config;params;controller=new AbortController;buffer=[];waiters=new Set;seq=0;ended=!1;history=[];produced=[];current=null;outputTruncated=!1;amended=new Map;unreported=new Set;usage=s();finishReason="stop";output;stopReason;settled;depth;maxDepth;chain;signingRunId;pathPrefix;onPending;nestedSettling=new Set;shownQueue=new Map;constructor(Q,$){this.config=Q,this.params=$,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});this.settled=this.execute(),$.req?.ctx?.()?.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,G,W=new ReadableStream({start:async(Y)=>{G=NQ(Y);try{for await(let V of $){if(J)break;Y.enqueue(Z.encode(`id: ${V.seq}
|
|
11
|
+
data: ${JSON.stringify(V.event)}
|
|
12
12
|
|
|
13
|
-
`)),
|
|
13
|
+
`)),G.touch()}}catch{}G.stop();try{Y.close()}catch{}},cancel:()=>{J=!0,G.stop()}});return new Response(W,{headers:{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}})}result(){return this.settled}stop(Q){if(this.ended||this.controller.signal.aborted)return;this.stopReason=Q?.reason,this.controller.abort()}async execute(){this.emit({type:"run-start",runId:this.runId,threadId:this.params.threadId});try{let Q=await this.ingestTurn();if(Q.length>0)this.finishReason="awaiting-input",this.emit({type:"awaiting-input",runId:this.runId,pending:Q});else await this.loop()}catch(Q){if(Q instanceof R||this.controller.signal.aborted)await this.finalizeAborted();else{let $=this.config.provider.normalizeError(Q);this.emit({type:"error",error:$}),await this.finalizeMessage("error"),this.finishReason="error"}}return this.emit({type:"usage",usage:this.usage}),this.emit({type:"run-end",runId:this.runId,finishReason:this.finishReason}),this.ended=!0,this.wake(),{runId:this.runId,messages:this.produced,finishReason:this.finishReason,usage:this.usage,output:this.output}}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.emit({type:"error",error:J.error}),await this.finalizeMessage("error"),this.finishReason="error";return}let G=Z.content.filter((Y)=>Y.type==="tool-call");if(G.length===0){this.finishReason=J.reason,await this.finalizeMessage(J.reason);return}let W=await this.runTools(Z,G,$);if(W.length>0){this.finishReason="awaiting-input",await this.finalizeMessage("awaiting-input"),this.emit({type:"awaiting-input",runId:this.runId,pending:W});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=H9(J.text)}this.emit({type:"message-end",messageId:$.id,finishReason:Q,...Z?{outputTruncated:!0}:{}}),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"},G=new Map,W="",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?{name:"output",schema:this.config.output.toJSONSchema(),strict:r(this.config.output)}:void 0,reasoning:this.config.reasoning,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature,signal:$})[Symbol.asyncIterator]();for(;;){let K=await o(Promise.resolve(V.next()),$);if(K.done)break;let H=K.value;switch(H.type){case"text-delta":{B9(Q,"text",H.delta),this.emit({type:"text-delta",messageId:Q.id,delta:H.delta});break}case"reasoning-delta":{D9(Q,H.id,H.delta),this.emit({type:"reasoning-delta",messageId:Q.id,delta:H.delta,id:H.id});break}case"output-delta":{W+=H.delta,this.emit({type:"output-delta",messageId:Q.id,delta:H.delta,snapshot:_Q(W)});break}case"tool-search":{this.emit({type:"tool-search",loaded:H.loaded});break}case"tool-call-delta":{let B=G.get(H.toolCallId)??{name:H.name,args:""};B.args+=H.argsDelta,B.name=H.name||B.name,G.set(H.toolCallId,B),this.emit({type:"tool-call",messageId:Q.id,part:{type:"tool-call",toolCallId:H.toolCallId,name:B.name,input:_Q(B.args),partial:!0}});break}case"tool-call":{G.delete(H.toolCallId);let B={type:"tool-call",toolCallId:H.toolCallId,name:H.name,input:z6(H.args)};Q.content.push(B),this.emit({type:"tool-call",messageId:Q.id,part:B});break}case"finish":{if(this.usage=t(this.usage,H.usage),!J.error)J={reason:H.reason};break}case"error":{J={reason:"error",error:H.error};break}}}for(let[K,H]of G){let B={type:"tool-call",toolCallId:K,name:H.name,input:z6(H.args)};Q.content.push(B),this.emit({type:"tool-call",messageId:Q.id,part:B})}let X=J.reason==="length";if(X)this.outputTruncated=!0;if(this.config.output&&W&&!J.error&&!X){let K=this.config.output.safeParse(_Q(W));if(K.ok===!0)this.output=K.value,Q.content.push({type:"output",value:K.value});else this.emit({type:"error",error:{code:"unknown",message:`The model's structured answer did not match the output schema: ${K.errors.join(", ")}`,retryable:!0}})}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 G=[],J=[];for(let W of $){let Y=this.config.registry.get(String(W.name));if(!Y){this.addResult(Q,{type:"tool-result",toolCallId:W.toolCallId,name:W.name,status:"error",error:{code:"tool_error",message:`There is no tool named "${String(W.name)}".`,toolCallId:W.toolCallId,retryable:!0}});continue}let X=Y.tool.inputSchema.safeParse(W.input);if(X.ok===!1){this.addResult(Q,{type:"tool-result",toolCallId:W.toolCallId,name:W.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${String(W.name)}": ${X.errors.join(", ")}`,toolCallId:W.toolCallId,retryable:!0}});continue}W.input=X.value;let V=G2(Y.tool);if(V){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(W));continue}G.push({toolCallId:W.toolCallId,name:W.name,input:X.value,kind:V,signature:gQ(this.claimsFor(W.toolCallId,String(W.name),V,X.value)),...this.pathPrefix.length>0?{path:[...this.pathPrefix]}:{}});continue}J.push(this.executeTool(Y,Q.id,W,X.value,Z).then(async(B)=>{this.addResult(Q,B),await this.settleShown(W.toolCallId)}).catch((B)=>{if(B instanceof q){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(W));return}G.push(...B.pending);return}}))}return await n(Promise.all(J).then(()=>{return}),this.controller.signal),G}claimsFor(Q,$,Z,G){return{runId:this.signingRunId,toolCallId:Q,name:$,kind:Z,input:G,path:this.pathPrefix.length>0?[...this.pathPrefix]:void 0}}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,G,J,W){let Y={req:this.params.req,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,toolCallId:Z.toolCallId,signal:this.controller.signal,step:J,depth:this.depth,resumed:W!==void 0,attachments:this.toolAttachments(Z),turn:this.toolTurn($),runAgent:this.nestedRunner($,Z,W)};try{let X=Q.tool.execute(G,Y),V;if(l2(X)){let B=await X.next();while(!B.done)this.emit({type:"tool-progress",toolCallId:Z.toolCallId,data:B.value}),B=await X.next();V=B.value}else V=await X;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"ok",output:V}}catch(X){if(X instanceof S||this.controller.signal.aborted)throw new S;if(X instanceof q)throw X;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:{code:"tool_error",message:X instanceof Error?X.message:String(X),toolCallId:Z.toolCallId,retryable:!0}}}}nestedRunner(Q,$,Z){let G=new FQ(()=>$.nested,()=>$.nested=[]);return async(J,W={})=>{let{at:Y,recorded:X,write:V}=G.next();if(X){let B=o2(X,J,W);if(B)throw Error(`Nested run ${Y} of "${String($.name)}" ${B}. `+"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(X.finishReason!=="awaiting-input")return{runId:X.runId,agent:X.agent,messages:X.messages,finishReason:X.finishReason??"stop",usage:X.usage??o(),output:rQ(X.messages),nested:X}}return this.runNested(Q,$,J,W,V,X,Z?.answers??[])}}async runNested(Q,$,Z,G,J,W,Y){let X=[...this.chain,Z.name];if(this.chain.includes(Z.name))throw Error(`"${Z.name}" is already running further up this chain: ${X.join(" -> ")}. An agent cannot run itself, directly or through another agent.`);let V=this.depth+1;if(V>this.maxDepth)throw Error(`Nested agent runs are ${this.maxDepth} deep at most and this one would be ${V}: ${X.join(" -> ")}. Raise maxDepth on the agent at the root of the run if the tree is meant to be this deep.`);let B=G.label,K=[...this.pathPrefix,$.toolCallId],H=this.onPending==="deny"?"deny":G.onPending??"escalate",z=W!==void 0,O=z?s(W.messages):new Set,D=z?Y.filter((F)=>{let x=Z2(F.path,K);if(x===null)return!1;return O.has(x.length>0?x[0]:F.toolCallId)}):[],U=Z.stream({messages:z?W.messages:G.messages??[],turn:z?{toolResults:D}:G.prompt?{text:G.prompt}:void 0,req:this.params.req,attachments:this.params.attachments,body:this.params.body,signal:this.controller.signal,threadId:this.params.threadId,instructions:G.instructions,maxOutputTokens:G.maxOutputTokens,temperature:G.temperature,runId:z?W.runId:void 0,nesting:{depth:V,maxDepth:this.maxDepth,chain:X,signingRunId:this.signingRunId,signingPath:K,onPending:H}}),j=[],_=(async()=>{for await(let F of U){if(F.type==="awaiting-input")j=F.pending;this.emit({type:"nested-event",toolCallId:$.toolCallId,runId:U.runId,agent:Z.name,label:B,event:F})}})(),L=(async()=>{let F=await U.result();await _;let x=z?aQ(W.messages,F.messages):aQ(G.messages??[],F.messages),wQ={runId:U.runId,agent:Z.name,label:B,messages:x,finishReason:F.finishReason,usage:z?OQ(W.usage??o(),F.usage):F.usage,...F.finishReason==="awaiting-input"?{signature:mQ({runId:this.signingRunId,path:K,nestedRunId:U.runId,open:[...s(x)],input:$.input})}:{}};return J(wQ),this.usage=OQ(this.usage,F.usage),{result:F,record:wQ}})(),b=L.then(()=>{return},()=>{return});this.nestedSettling.add(b);let u,P;try{({result:u,record:P}=await L)}finally{this.nestedSettling.delete(b)}if(this.controller.signal.aborted)throw new S;if(u.finishReason==="awaiting-input"){if(j.length===0)throw Error(`"${Z.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 q({pending:j,path:K,nested:P})}return{runId:P.runId,agent:Z.name,messages:P.messages,finishReason:u.finishReason,usage:P.usage??o(),output:u.output??rQ(P.messages),nested:P}}addResult(Q,$){Q.content.push($),this.emit({type:"tool-result",messageId:Q.id,part:$})}toolAttachments(Q){let $=this.params.attachments??null,Z=new FQ(()=>Q.attachments,()=>Q.attachments=[],()=>({failed:!0})),G=()=>{if(!$)throw new A("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 $};return{get:(J)=>G().get(J),read:(J)=>G().read(J),file:(J)=>G().file(J),put:async(J,W={})=>{let{at:Y,recorded:X,write:V}=Z.next();if(X&&"attachment"in X){let U=n2(X,J,W);if(U)throw Error(`Attachment ${Y} 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(X.shown)this.queueShown(Q.toolCallId,X);return X.attachment}let B=G(),K=W.mimeType||J.type||"",H=W.name??(J instanceof File?J.name:"attachment"),z;if(W.showModel){let U=this.config.provider;if(!U.capabilities.fileInput)throw Error(`"${String(Q.name)}" asked to show a file to ${U.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.`);z=await U.upload(new File([J],H,{type:K||void 0}))}let O=await B.put(J,{name:H,mimeType:K,fileId:z}),D={attachment:O,...z?{shown:{fileId:z,messageId:`msg_${crypto.randomUUID()}`,createdAt:new Date().toISOString()}}:{}};if(V(D),D.shown)this.queueShown(Q.toolCallId,D);return O}}}toolTurn(Q){let $=this.history.findIndex((W)=>W.id===Q),Z=Q2(this.history),G;for(let W=$-1;W>=0;W--){let Y=this.history[W];if(Y.role!=="user"||Z.has(Y.id))continue;G=Y;break}let J=[];for(let W of G?.content??[]){if(W.type!=="file")continue;let Y=W.attachmentId;if(typeof Y!=="string"||!Y.startsWith(C))continue;if(!J.includes(Y))J.push(Y)}return Object.freeze({attachments:Object.freeze(J)})}queueShown(Q,$){let Z=$.shown;if(!Z)return;let G=this.shownQueue.get(Q)??[];if(G.some((J)=>J.id===Z.messageId))return;G.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,G)}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((G)=>G.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((W)=>W!==Q),Z=Q2($),G=[];for(let W of $){if(!Z.has(W.id))continue;for(let Y of W.content)if(Y.type==="file")G.push(Y)}if(G.length<=$2)return $;let J=new Set(G.slice(0,G.length-$2));return $.map((W)=>{if(!W.content.some((Y)=>Y.type==="file"&&J.has(Y)))return W;return{...W,content:W.content.map((Y)=>Y.type==="file"&&J.has(Y)?{type:"text",text:`[A ${Y.mimeType||"file"} produced by a tool (attachment ${Y.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.]`}:Y)}})}async ingestTurn(){let Q=this.params.turn,$=this.openCalls(),Z=[];if($.length>0){let G=new Set,J=new Set,W=new Map;for(let Y of Q?.toolResults??[]){let X=`${(Y.path??[]).join("/")}#${Y.toolCallId}`;if(J.has(X))continue;J.add(X);let V=(z)=>this.emit({type:"error",error:{code:"invalid_tool_result",message:z,toolCallId:Y.toolCallId,retryable:!1}}),B=Z2(Y.path,this.pathPrefix);if(B===null){V(`The answer for "${Y.toolCallId}" is addressed to a tool call this run is not inside.`);continue}if(B.length>0){let z=B[0],O=$.find((j)=>j.call.toolCallId===z);if(!O){V(`No pending tool call with id "${z}" to deliver a nested answer to.`);continue}let D=this.parkedBelow(O.call,B,Y.toolCallId);if(D.ok===!1){let j=`The answer for "${Y.toolCallId}" is addressed under "${z}", which`;V(D.reason==="unparked"?`${j} has no sub-agent run waiting on that question.`:D.reason==="expired"?`${j} parked a sub-agent run that has since expired. Ask again.`:`${j} carries a record of a parked sub-agent run the server did not sign.`);continue}let U=W.get(z);if(!U){if(!dQ(D.signature)){V(`The answer for "${Y.toolCallId}" is addressed under "${z}", which has already been re-entered on that record. Ask again.`);continue}U=[],W.set(z,U),G.add(z)}U.push(Y);continue}let K=$.find((z)=>z.call.toolCallId===Y.toolCallId);if(!K){V(`No pending tool call with id "${Y.toolCallId}".`);continue}let H=await this.resolveAnswer(K,Y,Z);if(H===null)continue;if(G.add(Y.toolCallId),H!=="open")this.attachToHistory(K,H),await this.settleShown(Y.toolCallId)}for(let[Y,X]of W){let V=$.find((K)=>K.call.toolCallId===Y),B=await this.reenter(V,X,Z);if(B)this.attachToHistory(V,B),await this.settleShown(Y)}for(let Y of $){if(G.has(Y.call.toolCallId))continue;this.attachToHistory(Y,{type:"tool-result",toolCallId:Y.call.toolCallId,name:Y.call.name,status:"denied",cause:"refused"})}await this.reportDeferred()}if(Q&&(Q.text||Q.files&&Q.files.length>0)){let G={id:`msg_${crypto.randomUUID()}`,role:"user",content:[...Q.text?[{type:"text",text:Q.text}]:[],...(Q.files??[]).map((J)=>({type:"file",...J.fileId?{fileId:J.fileId}:{},name:J.name,mimeType:J.mimeType,...J.attachmentId?{attachmentId:J.attachmentId}:{}}))],createdAt:new Date().toISOString(),finishReason:"stop"};this.history.push(G),this.produced.push(G),await this.report(G)}return Z}parkedBelow(Q,$,Z){let G=$.length>1?$[1]:Z,J=[...this.pathPrefix,Q.toolCallId],W=(Q.nested??[]).find((X)=>X.finishReason==="awaiting-input"&&s(X.messages).has(G));if(!W)return{ok:!1,reason:"unparked"};if(typeof W.signature!=="string")return{ok:!1,reason:"unsigned"};let Y=pQ(W.signature,{path:J,nestedRunId:W.runId,open:[...s(W.messages)],input:Q.input});if(Y.ok===!1)return{ok:!1,reason:Y.reason==="expired"?"expired":"unsigned"};return{ok:!0,signature:W.signature}}async reenter(Q,$,Z){let G=String(Q.call.name),J=this.config.registry.get(G);if(!J||!J.tool.execute)return{type:"tool-result",toolCallId:Q.call.toolCallId,name:Q.call.name,status:"error",error:{code:"invalid_tool_result",message:`The tool "${G}" no longer exists, so the sub-agent's question cannot be delivered.`,toolCallId:Q.call.toolCallId,retryable:!1}};let W=J.tool.inputSchema.safeParse(Q.call.input);if(W.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 "${G}": ${W.errors.join(", ")}`,toolCallId:Q.call.toolCallId,retryable:!0}};let Y=this.amendCall(Q);Y.input=W.value;try{return await n(this.executeTool(J,Q.message.id,Y,W.value,0,{answers:$}),this.controller.signal)}catch(X){if(X instanceof q)return Z.push(...X.pending),null;throw X}}amendCall(Q){let $=this.amend(Q.message),Z=$.content.indexOf(Q.call),G={...Q.call,nested:(Q.call.nested??[]).map((J)=>({...J})),...Q.call.attachments?{attachments:Q.call.attachments.map((J)=>({...J}))}:{}};if(Z>=0)$.content[Z]=G;return this.unreported.add($),G}openCalls(){let Q=new Set;for(let Z of this.history)for(let G of Z.content)if(G.type==="tool-result")Q.add(G.toolCallId);let $=[];for(let Z of this.history)for(let G of Z.content)if(G.type==="tool-call"&&!Q.has(G.toolCallId))$.push({message:Z,call:G});return $}async resolveAnswer(Q,$,Z){let G=Q.call,J=String(G.name),W=this.config.registry.get(J),Y=(K)=>{return this.emit({type:"error",error:{code:"invalid_tool_result",message:K,toolCallId:G.toolCallId,retryable:!1}}),null};if(!W)return Y(`The tool "${J}" no longer exists, so its answer cannot be checked.`);let X=G2(W.tool);if(!X)return Y(`"${J}" is a server tool with no pending question.`);if(typeof $.signature!=="string"||$.signature.length===0)return Y(`The answer for "${J}" carried no signature.`);let V=p($.signature);if(!V)return Y(`The signature for "${J}" is malformed.`);let B=uQ($.signature,{...this.claimsFor(G.toolCallId,J,X,G.input),runId:V.runId});if(B.ok===!1)return Y(B.reason==="expired"?`The approval for "${J}" has expired. Ask again.`:`The answer for "${J}" does not match the call the server made.`);if(!lQ($.signature))return Y(`The answer for "${J}" has already been used. Ask again.`);if("approve"in $){if(X!=="approval")return Y(`"${J}" is answered by the client, not approved.`);if($.approve===!0){let K=this.amendCall(Q);try{return await n(this.executeTool(W,Q.message.id,K,K.input,0),this.controller.signal)}catch(H){if(H instanceof q)return Z.push(...H.pending),"open";throw H}}return{type:"tool-result",toolCallId:G.toolCallId,name:G.name,status:"denied",cause:"refused",reason:$.reason}}if("output"in $){if(X==="approval")return Y(`"${J}" is approved, not answered: the server produces its result.`);let K=W.tool.outputSchema,H=K?K.safeParse($.output):{ok:!0,value:$.output};if(H.ok===!1)return{type:"tool-result",toolCallId:G.toolCallId,name:G.name,status:"error",error:{code:"invalid_tool_result",message:`The answer for "${J}" did not match its output schema: ${H.errors.join(", ")}`,toolCallId:G.toolCallId,retryable:!0}};return{type:"tool-result",toolCallId:G.toolCallId,name:G.name,status:"ok",output:H.value}}return Y(`The answer for "${J}" 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:$})}amend(Q){let $=this.amended.get(Q.id);if($)return $;let Z={...Q,content:[...Q.content]},G=this.history.indexOf(Q);if(G>=0)this.history[G]=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})}}this.finishReason="aborted",await this.finalizeMessage("aborted")}}function G2(Q){if(Q.answeredBy==="client")return Q.inputSchema===LQ?"question":"client";return Q.requiresApproval?"approval":null}function J2(Q){if(!Q||!Q.trim())return{};try{return JSON.parse(Q)}catch{return Q}}function s2(Q){if(Q.length>0)Q[0];return Q}function t2(Q,$,Z){let G=Q.content[Q.content.length-1];if(G&&G.type===$){G.text=(G.text??"")+Z;return}Q.content.push($==="text"?{type:"text",text:Z}:{type:"reasoning",text:Z})}function a2(Q,$,Z){let G=Q.content[Q.content.length-1];if(G&&G.type==="reasoning"&&G.id===$){G.text=(G.text??"")+Z;return}Q.content.push($?{type:"reasoning",id:$,text:Z}:{type:"reasoning",text:Z})}function r2(Q,$){return Q.descriptors($).map((Z)=>R.create({name:Z.name,description:Z.description,inputSchema:Z.inputSchema,requiresApproval:Z.requiresApproval,execute:(G,J)=>Q.execute({kind:"local",req:J.req},Z.name,G,J)}))}class r extends Error{status;body;requestId;constructor(Q,$,Z){super(`Provider request failed with status ${Q}: ${e2($)}`);this.name="ProviderHttpError",this.status=Q,this.body=$,this.requestId=Z}}class e extends Error{timeoutMs;constructor(Q){super(`Provider request timed out after ${Q}ms`);this.name="ProviderTimeoutError",this.timeoutMs=Q}}function e2(Q){let $=V2(Q);if($?.message)return $.message;if(typeof Q==="string")return Q.slice(0,500);return"no error body"}function V2(Q){if(!Q||typeof Q!=="object")return null;let $=Q,G=$.error&&typeof $.error==="object"?$.error:Q;if(typeof G.message!=="string"&&typeof G.code!=="string"&&typeof G.type!=="string")return null;let J=G.innererror?.code??G.code;return{message:G.message,type:G.type,code:J,param:G.param}}function k(Q){if(Q instanceof e)return{code:"provider_error",message:Q.message,retryable:!0};if(G5(Q))return{code:"aborted",message:"The request was aborted.",retryable:!1};if(Q instanceof r)return Q5(Q.status,V2(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 Q5(Q,$,Z){let G=$?.message??Z,J=($?.code??"").toLowerCase(),W=($?.type??"").toLowerCase(),Y=`${J} ${W} ${G}`.toLowerCase();if(Q===429){let X=J==="insufficient_quota"||Y.includes("quota");return{code:"rate_limited",message:G,retryable:!X}}if(Q>=500||Q===408||Q===409)return{code:"provider_error",message:G,retryable:!0};if($5(Y))return{code:"context_length_exceeded",message:G,retryable:!1};if(Z5(Y))return{code:"content_filtered",message:G,retryable:!1};if($?.param?.startsWith("tools")||Y.includes("invalid schema for function"))return{code:"invalid_tool_input",message:G,retryable:!1};return{code:"provider_error",message:G,retryable:!1}}function $5(Q){return Q.includes("context_length_exceeded")||Q.includes("maximum context length")||Q.includes("context window")||Q.includes("reduce the length")}function Z5(Q){return Q.includes("content_filter")||Q.includes("content_policy_violation")||Q.includes("responsibleaipolicyviolation")||Q.includes("content management policy")}function G5(Q){if(!Q||typeof Q!=="object")return!1;let $=Q;return $.name==="AbortError"||$.code==="ABORT_ERR"}var J5=500,K2=20000;function W5(Q,$){if(!Q)return;let Z=Q.trim();if(/^\d+(\.\d+)?$/.test(Z))return Math.max(0,Number(Z)*1000);let G=Date.parse(Z);if(Number.isNaN(G))return;return Math.max(0,G-$)}function B2(Q,$){let Z=Math.min(K2,J5*2**Q);return Math.round(Z*(0.5+$()*0.5))}function Y5(Q){return Q===429||Q===408||Q===409||Q>=500}function X5(Q,$){return Y5(Q)&&k($).retryable}function H2(Q){return Q.reason??new DOMException("The operation was aborted.","AbortError")}function V5(Q,$){return new Promise((Z,G)=>{let J=setTimeout(Z,Q);$?.addEventListener("abort",()=>{clearTimeout(J),G(H2($))},{once:!0})})}async function _Q(Q,$,Z){let G=Z.fetchImpl??((K,H)=>fetch(K,H)),J=Z.sleep??V5,W=Z.random??Math.random,Y=Z.now??Date.now,X=Math.max(0,Z.maxRetries),V=async(K)=>{let H=Z.signal;if(!H)return await J(K);H.throwIfAborted();let z;try{await Promise.race([J(K,H),new Promise((O,D)=>{z=()=>D(H2(H)),H.addEventListener("abort",z,{once:!0})})])}finally{if(z)H.removeEventListener("abort",z)}},B;for(let K=0;K<=X;K++){Z.signal?.throwIfAborted();let H=new AbortController,z=()=>H.abort(Z.signal?.reason);Z.signal?.addEventListener("abort",z,{once:!0});let O=!1,D=Z.timeoutMs>0?setTimeout(()=>{O=!0,H.abort()},Z.timeoutMs):void 0,U;try{U=await G(Q,{...$,signal:H.signal})}catch(b){if(D!==void 0)clearTimeout(D);if(Z.signal?.removeEventListener("abort",z),Z.signal?.aborted)throw b;if(B=O?new e(Z.timeoutMs):b,K===X)throw B;await V(B2(K,W));continue}if(D!==void 0)clearTimeout(D);if(U.ok)return U;Z.signal?.removeEventListener("abort",z);let j=await B5(U),_=new r(U.status,j,U.headers.get("x-request-id")??void 0);if(K===X||!X5(U.status,_))throw _;let L=W5(U.headers.get("retry-after"),Y());await V(L===void 0?B2(K,W):Math.min(L,K2)),B=_}throw B??Error("Provider request failed with no response.")}async function B5(Q){let $;try{$=await Q.text()}catch{return null}try{return JSON.parse($)}catch{return $}}async function*K5(Q){let $="",Z="",G=[],J,W=()=>{if(G.length===0&&!Z)return null;let V={event:Z,data:G.join(`
|
|
16
|
-
`),id:
|
|
17
|
-
`);while(
|
|
18
|
-
`)}}if($.length>0){let V=Y($);if(V)yield V}let X=W();if(X)yield X}async function*z2(Q,$={}){let Z=new Map,G=new Set,J=!1;for await(let W of K5(Q)){if(W.data==="[DONE]")break;let Y;try{Y=JSON.parse(W.data)}catch{continue}switch(typeof Y.type==="string"?Y.type:W.event){case"response.output_text.delta":{let V=String(Y.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(Y.delta??"");if(!V)break;yield{type:"reasoning-delta",delta:V,id:Y.item_id};break}case"response.output_item.added":{let V=Y.item;if(!V)break;if(V.type==="function_call"){let B=String(V.id??Y.item_id??V.call_id??"");Z.set(B,{callId:String(V.call_id??B),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(Y.item_id??""));if(!V)break;let B=String(Y.delta??"");if(!B)break;yield{type:"tool-call-delta",toolCallId:V.callId,name:V.name,argsDelta:B,...V.namespace?{namespace:V.namespace}:{}};break}case"response.function_call_arguments.done":{let V=String(Y.item_id??""),B=Z.get(V);if(!B)break;B.done=!0,yield{type:"tool-call",toolCallId:B.callId,name:B.name,args:String(Y.arguments??""),...B.namespace?{namespace:B.namespace}:{}};break}case"response.output_item.done":{let V=Y.item;if(!V)break;if(V.type==="function_call"){let B=String(V.id??Y.item_id??V.call_id??""),K=Z.get(B);if(K?.done)break;let H=(typeof V.namespace==="string"?V.namespace:"")||K?.namespace;if(yield{type:"tool-call",toolCallId:String(V.call_id??B),name:String(V.name??K?.name??""),args:String(V.arguments??""),...H?{namespace:H}:{}},K)K.done=!0;break}if(V.type==="tool_search_call"||V.type==="tool_search_output"){let B=H5(V);if(B.loaded.length===0&&B.namespaces.length===0)break;let K=String(V.tool_search_call_id??V.id??"");if(G.has(K))break;G.add(K),yield{type:"tool-search",...B}}break}case"response.refusal.done":{yield{type:"error",error:{code:"content_filtered",message:String(Y.refusal??"The model refused to answer."),retryable:!1}};break}case"response.completed":{J=!0,yield{type:"finish",reason:"stop",usage:PQ(Y.response?.usage)};break}case"response.incomplete":{J=!0;let V=PQ(Y.response?.usage),B=Y.response?.incomplete_details?.reason;if(B==="content_filter"){yield{type:"error",error:{code:"content_filtered",message:z5(Y.response?.content_filters),retryable:!1}},yield{type:"finish",reason:"error",usage:V};break}yield{type:"finish",reason:B==="max_output_tokens"?"length":"stop",usage:V};break}case"response.failed":case"error":{J=!0;let V=Y.response?.error??Y.error??Y;yield{type:"error",error:U5(V)},yield{type:"finish",reason:"error",usage:PQ(Y.response?.usage)};break}}if(J)return}if(!J)yield{type:"error",error:{code:"provider_error",message:"The provider stream ended without a terminal event.",retryable:!0}},yield{type:"finish",reason:"error",usage:I()}}function H5(Q){let $=[],Z=[];return U2(Q.results??Q.tools??Q.loaded??Q.output,$,Z,0),{loaded:MQ($),namespaces:MQ(Z)}}function U2(Q,$,Z,G){if(!Array.isArray(Q)||G>4)return;for(let J of Q){if(typeof J==="string"){$.push(J);continue}if(!J||typeof J!=="object")continue;let W=J,Y=typeof W.name==="string"?W.name:typeof W.tool_name==="string"?W.tool_name:"",X=W.tools??W.functions;if(Array.isArray(X)){if(Y)Z.push(Y);U2(X,$,Z,G+1);continue}if(Y)$.push(Y)}}function MQ(Q){return Q.filter(($,Z)=>Q.indexOf($)===Z)}function z5(Q){if(!Array.isArray(Q))return"The provider's content filter blocked this request.";let Z=[];for(let G of Q){if(!G||typeof G!=="object")continue;let J=G,W=J.content_filter_results;if(!W||typeof W!=="object")continue;for(let[Y,X]of Object.entries(W))if(X&&typeof X==="object"&&X.filtered===!0)Z.push(`${Y} (${String(J.source_type??"unknown")})`)}return Z.length===0?"The provider's content filter blocked this request.":`The provider's content filter blocked this request. Categories: ${MQ(Z).join(", ")}.`}function U5(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 I(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function PQ(Q){if(!Q)return I();let $=Number(Q.input_tokens??0),Z=Number(Q.output_tokens??0),G={inputTokens:$,outputTokens:Z,totalTokens:Number(Q.total_tokens??$+Z)},J=Q.output_tokens_details?.reasoning_tokens;if(typeof J==="number")G.reasoningTokens=J;let W=Q.input_tokens_details?.cached_tokens;if(typeof W==="number")G.cachedInputTokens=W;return G}async function*D2(Q){if(!Q)return;let $=Q.getReader(),Z=new TextDecoder;try{while(!0){let{done:J,value:W}=await $.read();if(J)break;if(W)yield Z.decode(W,{stream:!0})}let G=Z.decode();if(G)yield G}finally{$.releaseLock()}}async function*qQ(Q,$,Z){let G;try{G=await _Q(Q.responsesUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify($)},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,signal:Z.signal,fetchImpl:Q.fetchImpl})}catch(J){let W=k(J);if(W.code!=="aborted")yield{type:"error",error:W};yield{type:"finish",reason:W.code==="aborted"?"aborted":"error",usage:I()};return}try{yield*z2(D2(G.body),{structuredOutput:Z.structuredOutput})}catch(J){let W=k(J);if(W.code==="aborted"){yield{type:"finish",reason:"aborted",usage:I()};return}yield{type:"error",error:W},yield{type:"finish",reason:"error",usage:I()}}}async function SQ(Q,$){let Z=new FormData;Z.set("purpose","user_data"),Z.set("file",$);let J=await(await _Q(Q.filesUrl,{method:"POST",headers:await Q.headers(),body:Z},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,fetchImpl:Q.fetchImpl})).json();if(!J?.id)throw Error("The provider accepted the upload but returned no file id.");return J.id}function RQ(Q){let $=D5(Q);if($.startsWith("gpt-3.5")||$.startsWith("text-")||$.startsWith("davinci"))return{reasoning:!1,structuredOutput:!1,fileInput:!1,parallelToolCalls:!0,toolSearch:!1};let Z=O5($);if(Z?.kind==="o")return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:Z.major>1,toolSearch:O2(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:O2(Z)};return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:!0,toolSearch:!0}}function O2(Q){if(Q.kind==="o")return Q.major>=5;return Q.major>5||Q.major===5&&Q.minor>=2}function D5(Q){return Q.trim().toLowerCase()}function O5(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 kQ(Q,$){let{capabilities:Z}=$,G={model:$.model,input:j5(Q.messages,Z),stream:!0};if(Q.systemPrompt)G.instructions=Q.systemPrompt;let J=S5(Q.tools,Z);if(J.length>0){if(G.tools=J,!Z.parallelToolCalls)G.parallel_tool_calls=!1}if(Q.output)G.text={format:{type:"json_schema",name:Q.output.name,schema:Q.output.schema,strict:Q.output.strict}};if(Q.reasoning&&Z.reasoning)G.reasoning={effort:Q.reasoning,summary:"auto"};if(typeof Q.temperature==="number")G.temperature=Q.temperature;if(typeof Q.maxOutputTokens==="number")G.max_output_tokens=Q.maxOutputTokens;return G}function j5(Q,$){let Z=[];for(let G of Q){let J=G.role,W=[],Y=()=>{if(W.length===0)return;Z.push({type:"message",role:J,content:W}),W=[]};for(let X of G.content??[])switch(X.type){case"text":{if(!X.text)break;W.push(QQ(J,X.text));break}case"output":{if(X.partial)break;W.push(QQ(J,JSON.stringify(X.value)));break}case"file":{if(J==="assistant")break;let V=C5(X);if(!$.fileInput){if(V)W.push(QQ(J,j2(X,!1)));break}if(X.fileId?.startsWith(C))throw Error(`FilePart.fileId holds a gemi attachment id (${X.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(!X.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(V)W.push(QQ(J,j2(X,!!X.fileId)));if(X.fileId)W.push(N5(X));break}case"reasoning":{Y();let V=M5(X);if(V)Z.push(V);break}case"tool-call":{if(X.partial)break;Y(),Z.push({type:"function_call",call_id:X.toolCallId,name:String(X.name),arguments:JSON.stringify(X.input??{})});break}case"tool-result":{Y(),Z.push({type:"function_call_output",call_id:X.toolCallId,output:q5(X)});break}}Y()}return L5(Z)}var F5="No result was recorded for this tool call. Assume it did not complete.";function L5(Q){let $=new Set,Z=new Set,G=[];for(let W of Q){if(W.type==="function_call"){let Y=String(W.call_id);if($.has(Y))continue;$.add(Y)}else if(W.type==="function_call_output"){let Y=String(W.call_id);if(!$.has(Y)||Z.has(Y))continue;Z.add(Y)}G.push(W)}if(Z.size===$.size)return G;let J=[];for(let W of G){if(J.push(W),W.type!=="function_call")continue;let Y=String(W.call_id);if(Z.has(Y))continue;Z.add(Y),J.push({type:"function_call_output",call_id:Y,output:F5})}return J}function QQ(Q,$){return{type:Q==="assistant"?"output_text":"input_text",text:$}}function C5(Q){let $=Q.attachmentId;return typeof $==="string"&&$.startsWith(C)?$:void 0}function j2(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 G=`attachment ${Z.join(" ")}`;return $?`[${G}]`:`[${G} \u2014 its contents are not shown to you; a tool can read the file by this id]`}function N5(Q){let $=Q.mimeType?.trim().toLowerCase()??"";return{type:($?$.startsWith("image/")&&$!=="image/svg+xml":_5(Q.name))?"input_image":"input_file",file_id:Q.fileId}}function _5(Q){let $=/\.([a-z0-9]+)$/.exec(Q?.trim().toLowerCase()??"");return $?.[1]!==void 0&&P5.has($[1])}var P5=new Set(["jpeg","jpg","png","gif","webp"]);function M5(Q){if(!Q.id)return null;let $={type:"reasoning",id:Q.id};return $.summary=Q.text?[{type:"summary_text",text:Q.text}]:[],$}function q5(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.${$}`;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 F2(Q){return Array.isArray(Q.tools)}function S5(Q,$){if(!Q||Q.length===0)return[];if(!$.toolSearch){let J=[];for(let W of Q)if(F2(W))for(let Y of W.tools)J.push($Q(Y,!1));else J.push($Q(W,!1));return J}let Z=[],G=!1;for(let J of Q)if(F2(J)){let W=J.tools.map((Y)=>{if(Y.deferred)G=!0;return $Q(Y,!0)});Z.push({type:"namespace",name:J.name,description:J.description,tools:W})}else{if(J.deferred)G=!0;Z.push($Q(J,!0))}if(G)Z.push({type:"tool_search"});return Z}function $Q(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}var C2=120000,N2=2;function T(Q){return typeof process>"u"?void 0:process.env?.[Q]}class ZQ{static models(){return[]}normalizeError(Q){return k(Q)}}var _2=["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 TQ extends ZQ{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=RQ(Q),this.config=$}static model(Q,$){return new TQ(Q,$)}static models(){return _2}stream(Q){let $=kQ(Q,{model:this.model,capabilities:this.capabilities});return qQ(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output)})}upload(Q){return SQ(this.endpoint(),Q)}baseURL(){return(this.config.baseURL??T("OPENAI_BASE_URL")??"https://api.openai.com/v1").replace(/\/+$/,"")}endpoint(){let Q=this.baseURL(),$=this.config;return{responsesUrl:`${Q}/responses`,filesUrl:`${Q}/files`,headers:async()=>{let Z=$.apiKey??T("OPENAI_API_KEY");return{...Z?{authorization:`Bearer ${Z}`}:{},...$.headers}},timeoutMs:$.timeoutMs??C2,maxRetries:$.maxRetries??N2}}}var R5="preview";function L2(Q){let $=Q.trim().replace(/\/+$/,"");if(!$)return"";return`${$.replace(/\/openai(?:\/v1)?$/i,"")}/openai`}function k5(Q){return/^\d{4}-\d{2}-\d{2}/.test(Q)?"":"/v1"}class xQ extends ZQ{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=RQ(Q),this.config=$}static model(Q,$){return new xQ(Q,$)}static models(){return _2}stream(Q){let $=kQ(Q,{model:this.deployment(),capabilities:this.capabilities});return qQ(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output)})}upload(Q){return SQ(this.endpoint(),Q)}deployment(){return this.config.deployment??this.model}base(){let Q=this.config,$=Q.baseURL??Q.endpoint??T("AZURE_OPENAI_ENDPOINT");if($)return L2($);let Z=Q.resourceName??T("AZURE_OPENAI_RESOURCE_NAME")??T("AZURE_RESOURCE_NAME");return Z?L2(`https://${Z.trim()}.cognitiveservices.azure.com`):""}endpoint(){let Q=this.config,$=this.base(),Z=Q.apiVersion??T("AZURE_OPENAI_API_VERSION")??R5,G=k5(Z),J=`?api-version=${encodeURIComponent(Z)}`;return{responsesUrl:`${$}${G}/responses${J}`,filesUrl:`${$}${G}/files${J}`,headers:async()=>{if(Q.getToken)return{authorization:`Bearer ${await Q.getToken()}`,...Q.headers};let W=Q.apiKey??T("AZURE_OPENAI_API_KEY");return{...W?{"api-key":W}:{},...Q.headers}},timeoutMs:Q.timeoutMs??C2,maxRetries:Q.maxRetries??N2}}}class w 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 y extends Error{runId;code="live_run_not_found";constructor(Q){super(`No live run ${Q} in this process.`);this.runId=Q}}class GQ{ttlMs;maxFrames;runs=new Map;byThread=new Map;byClientRun=new Map;constructor(Q={}){this.ttlMs=Q.ttlMs??60000,this.maxFrames=Q.maxFrames??4096}register(Q,$={}){let Z={run:Q,threadId:$.threadId,clientRunId:$.clientRunId,frames:[],lastSeq:-1,lostBefore:0,ended:!1,evictAt: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.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}replay(Q,$){let Z=this.runs.get(Q);if(!Z)throw new y(Q);if($!==void 0&&$<Z.lostBefore)throw new w(Q,$,Z.lostBefore);let G=Z.frames[0]?.seq;return this.drain(Z,Q,$??G??Z.lastSeq+1)}clear(){for(let Q of this.runs.values()){if(Q.evictAt)clearTimeout(Q.evictAt);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 G of Q.run.frames()){if(Q.frames.push(G),Q.lastSeq=G.seq,Q.frames.length>this.maxFrames){let W=Q.frames.shift();if(W)Q.lostBefore=W.seq+1}this.notify(Q);let J=$.onEvent;if(J)Z=Z.then(()=>J(G.event)).catch((W)=>P2($,W))}}catch(G){P2($,G)}finally{Q.ended=!0,this.notify(Q),this.scheduleEviction(Q),await Z}}async*drain(Q,$,Z){let G=Z;while(!0){let J=Q.version;for(;;){if(G<Q.lostBefore)throw new w($,G,Q.lostBefore);let W=Q.frames,Y=W[0]?.seq;if(Y===void 0)break;let X=Math.max(0,G-Y);if(X>=W.length)break;let V=W[X];yield V,G=V.seq+1}if(Q.ended&&G>Q.lastSeq)return;await this.wait(Q,J)}}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(this.runs.delete(Z),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=$}}var EQ=new GQ;function P2(Q,$){try{Q.onInternalError?.($)}catch{}}class JQ{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 G of $){let J=Z.messages.findIndex((W)=>W.id===G.id);if(J===-1)Z.messages.push(G);else Z.messages[J]=G}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 AQ=new JQ;var T5=k2,WQ=new Map,M2=new WeakMap,YQ=new Map;class x2 extends T5{static kind="agent-controller";store=AQ;liveRuns=EQ;attachments=d;attachmentStorage=T2;hookHoldMs=30000;instructions(Q,$){}requireThread=!1;authorizeRequest(Q,$){}async stream(Q=new g){let $=await IQ(Q);if($.error)return XQ($);let Z=$.body,G=typeof Z.threadId==="string"?Z.threadId:void 0,J=I5(Z);if(J.error)return XQ({body:{},error:J.error});let W=J.turn,Y=typeof Z.clientRunId==="string"?Z.clientRunId:void 0;if(this.requireThread&&!G)return N(400,{code:"thread_required",message:"This agent takes a turn only on a thread: send a threadId."});let X=Y?{cancelled:!1}:null;if(X)YQ.set(Y,X);let V=async()=>{let B;if(G){let L=await this.store.loadThread(G);if(!L)return N(404,{code:"thread_not_found",message:`Thread ${G} does not exist here, or has expired.`});B=L}else B=Array.isArray(Z.messages)?Z.messages:[];let K=E5(Z),H=await this.instructions(Q,{body:K})||void 0,z=await this.attachmentsFor(Q,G);if(X?.cancelled)return S2();let O=this.agent.stream({messages:B,turn:W,req:Q,threadId:G,instructions:H,attachments:z,body:K}),D={req:Q,runId:O.runId,threadId:G},U=this.liveRuns.register(O,{threadId:G,clientRunId:Y,onEvent:(L)=>this.dispatchEvent(L,D),onInternalError:(L)=>this.reportHookFailure(L)}),{stored:j,hooks:_}=this.persistRun(O,D,U);return M2.set(O,j),Q.ctx?.()?.waitUntil(_),O.toResponse()};try{if(await this.authorizeRequest(Q,{route:"stream",threadId:G}),X?.cancelled)return S2();return G?await this.withThread(G,V):await V()}finally{if(X&&YQ.get(Y)===X)YQ.delete(Y)}}async withThread(Q,$){let Z=WQ.get(Q)??Promise.resolve(),G,J=new Promise((Y)=>{G=Y}),W=Z.then(()=>J);WQ.set(Q,W),await Z;try{let Y=await this.liveRuns.find({threadId:Q}),X=Y?this.liveRuns.get(Y.runId):null;if(X)X.stop({reason:"superseded by a later turn on this thread"}),await M2.get(X);return await $()}finally{if(G(),WQ.get(Q)===W)WQ.delete(Q)}}async attach(Q=new g){let $=await IQ(Q);if($.error)return XQ($);let Z=$.body,G=typeof Z.threadId==="string"?Z.threadId:v5(Q,"threadId");if(!G)return N(400,{code:"invalid_request",message:"attach needs a threadId: it is the handle that survives a refresh."});await this.authorizeRequest(Q,{route:"attach",threadId:G});let J=await this.liveRuns.find({threadId:G});if(!J)return N(404,{code:"no_live_run",message:`No run in progress for thread ${G} in this process.`});let W=typeof Z.runId==="string"?Z.runId:void 0,Y=W&&W!==J.runId?void 0:b5(Q,Z);try{return sQ(this.liveRuns.replay(J.runId,Y))}catch(X){if(X instanceof w)return N(410,{code:X.code,message:X.message,oldestSeq:X.oldest});if(X instanceof y)return N(404,{code:X.code,message:X.message});throw X}}async stop(Q=new g){let $=await IQ(Q);if($.error)return XQ($);let Z=$.body;await this.authorizeRequest(Q,{route:"stop",threadId:typeof Z.threadId==="string"?Z.threadId:void 0});let G=typeof Z.runId==="string"?Z.runId:void 0;if(!G&&typeof Z.clientRunId==="string"){if(G=this.liveRuns.findByClientRunId(Z.clientRunId)??void 0,!G){let W=YQ.get(Z.clientRunId);if(W)return W.cancelled=!0,{stopped:!0}}}if(!G&&typeof Z.threadId==="string")G=(await this.liveRuns.find({threadId:Z.threadId}))?.runId;let J=G?this.liveRuns.get(G):null;if(!J)return{stopped:!1};return J.stop({reason:typeof Z.reason==="string"?Z.reason:void 0}),{stopped:!0}}attachmentScope(Q,$){let Z=Q.ctx()?.user,G=Z?.id??Z?.publicId;if(G!==void 0&&G!==null&&String(G)!=="")return{key:`user:${String(G)}`};if($)return{key:`thread:${$}`};return null}attachmentDestination(Q,$){return"both"}async attachmentsFor(Q,$){let Z=await this.attachmentScope(Q,$);if(!Z)return null;return new f(this.attachments,this.attachmentStorage,Z)}async upload(Q=new g){let $=await Q.rawRequest.formData(),Z=$.get("file");if(!(Z instanceof Blob))throw Error("upload expects a multipart body with a `file` field.");let G=Z instanceof File&&Z.name?Z.name:"upload",J=Z.type||"application/octet-stream",W=$.get("threadId");await this.authorizeRequest(Q,{route:"upload",threadId:typeof W==="string"&&W.length>0?W:void 0});let Y=typeof W==="string"&&W.length>0&&await this.store.loadThread(W)!==null?W:void 0,X=await this.attachmentDestination(Z,Q),V=f5(X,$.get("destination")),B=await this.attachmentScope(Q,Y),K=V!=="provider"&&!B;if(K){if(V==="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()`.');h5()}if(V==="provider"||!B){let j={fileId:await this.agent.provider.upload(Z),name:G,mimeType:J,size:Z.size,destination:"provider"};if(K)j.downgraded="no_scope";return j}let H=HQ(),z=await this.attachmentStorage.put({name:zQ(H,G),body:Z,contentType:J}),O=V==="both"?await this.agent.provider.upload(Z):void 0,D={id:H,scopeKey:B.key,fileId:O,objectName:z,name:G,mimeType:J,size:Z.size,createdAt:new Date().toISOString(),destination:V};return await this.attachments.put(B,D),{fileId:O,attachmentId:H,name:G,mimeType:J,size:Z.size,destination:V}}onMessage(Q,$){}onToolCall(Q,$){}onAwaitingInput(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(Q.error,$);return;default:return}}persistRun(Q,$,Z){let G=Promise.resolve(),J=(async()=>{let Y;try{Y=await Q.result()}catch(V){G=this.safely(()=>this.onError({code:"unknown",message:V instanceof Error?V.message:String(V),retryable:!1},$));return}let X=Y.messages;if($.threadId&&X.length>0)try{await this.store.appendMessages($.threadId,X)}catch(V){this.reportHookFailure(V)}G=this.notifyRun(Y,X,$)})(),W=J.then(()=>g5(Promise.all([G,Z]).then(()=>{}),this.hookHoldMs));return{stored:J,hooks:W}}async notifyRun(Q,$,Z){for(let G of $)await this.safely(()=>this.onMessage(G,Z));await this.safely(()=>this.onStreamComplete(Q,Z))}async safely(Q){try{await Q()}catch($){this.reportHookFailure($)}}}var q2=["turn","clientRunId","threadId","messages"],x5=["text","files","toolResults"];function E5(Q){let $=E2(Q)?q2:[...q2,...x5],Z={};for(let[G,J]of Object.entries(Q)){if($.includes(G))continue;Object.defineProperty(Z,G,{value:J,writable:!0,enumerable:!0,configurable:!0})}return Z}async function IQ(Q){let $=Q?.rawRequest;if(!$||$.method==="GET"||$.method==="HEAD"||!$.body)return{body:{}};if(!A5($.headers.get("Content-Type")))return{body:{},status:415,code:"unsupported_media_type",error:"The request body must be sent as application/json."};let Z;try{Z=await $.text()}catch{return{body:{},error:"The request body could not be read."}}if(!Z.trim())return{body:{}};let G;try{G=JSON.parse(Z)}catch{return{body:{},error:"The request body is not valid JSON."}}if(G===null||typeof G!=="object"||Array.isArray(G))return{body:{},error:"The request body must be a JSON object."};return{body:G}}function A5(Q){if(typeof Q!=="string")return!1;let[$]=Q.split(";",1);return $.trim().toLowerCase()==="application/json"}function XQ(Q){return N(Q.status??400,{code:Q.code??"invalid_request",message:Q.error})}function E2(Q){return Boolean(Q.turn)&&typeof Q.turn==="object"}function I5(Q){let $=E2(Q)?Q.turn:Q,Z={};if(typeof $.text==="string")Z.text=$.text;if(Array.isArray($.files)){let G=w5($.files);if(typeof G==="string")return{error:G};Z.files=G}if(Array.isArray($.toolResults))Z.toolResults=$.toolResults;return Object.keys(Z).length>0?{turn:Z}:{}}function w5(Q){let $=[];for(let[Z,G]of Q.entries()){let J=`turn.files[${Z}]`;if(!G||typeof G!=="object"||Array.isArray(G))return`${J} must be an object.`;let W={};for(let K of["fileId","attachmentId","name","mimeType"]){let H=G[K];if(H===void 0||H===null||H==="")continue;if(typeof H!=="string")return`${J}.${K} must be a string.`;W[K]=H}let{fileId:Y,attachmentId:X,name:V,mimeType:B}=W;if(Y?.startsWith(C))return`${J}.fileId holds a gemi attachment id (${Y}). \`fileId\` is the provider's id from the upload response; put this one in \`attachmentId\`.`;if(X!==void 0&&!X.startsWith(C))return`${J}.attachmentId is not a gemi attachment id: it must start with "${C}".`;if(!Y&&!X)return`${J} has neither a \`fileId\` nor an \`attachmentId\`. Send the ids the upload response answered.`;$.push({...Y?{fileId:Y}:{},...X?{attachmentId:X}:{},...V!==void 0?{name:V}:{},...B!==void 0?{mimeType:B}:{}})}return $}function b5(Q,$){if(typeof $.from==="number"&&Number.isFinite($.from))return Math.max(0,Math.floor($.from));if(typeof $.cursor==="number"&&Number.isFinite($.cursor)){let G=Math.floor($.cursor);if(G>=0)return G+1;return}let Z=Q?.rawRequest?.headers?.get("Last-Event-ID");if(Z){let G=Number.parseInt(Z,10);if(Number.isFinite(G))return Math.max(0,G+1)}return}function v5(Q,$){let Z=Q?.search?.get($);return typeof Z==="string"?Z:void 0}function S2(){return N(409,{code:"stopped",message:"The turn was stopped before it started."})}function N(Q,$){return new Response(JSON.stringify({error:$}),{status:Q,headers:{"Content-Type":"application/json"}})}function f5(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 R2=!1;function h5(){if(R2)return;R2=!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 y5=2147483647;function g5(Q,$){let Z=Q.then(()=>{},()=>{});if(!($<=y5))return Z;let G,J=new Promise((W)=>{G=setTimeout(W,$)});return Promise.race([Z,J]).finally(()=>clearTimeout(G))}export{r2 as toAgentTools,t as supportsStrict,u5 as s,EQ as liveRuns,d as defaultAttachmentStore,AQ as defaultAgentStore,a as ToolNamespace,CQ as Skill,f as ScopedAttachments,h as SKILLS_NAMESPACE,q as PendingEscalation,TQ as OpenAIProvider,GQ as MemoryLiveRuns,l as MemoryAttachmentStore,JQ as MemoryAgentStore,y as LiveRunNotFoundError,A as InvalidAttachmentScopeError,w as FrameCursorEvictedError,xQ as AzureOpenAIProvider,v as AttachmentNotFoundError,R as AgentTool,ZQ as AgentProvider,x2 as AgentController,NQ as Agent};
|
|
15
|
+
`):void 0}async runTools(Q,$,Z){let J=[],G=[];for(let W of $){let Y=this.config.registry.get(String(W.name));if(!Y){this.addResult(Q,{type:"tool-result",toolCallId:W.toolCallId,name:W.name,status:"error",error:{code:"tool_error",message:`There is no tool named "${String(W.name)}".`,toolCallId:W.toolCallId,retryable:!0}});continue}let V=Y.tool.inputSchema.safeParse(W.input);if(V.ok===!1){this.addResult(Q,{type:"tool-result",toolCallId:W.toolCallId,name:W.name,status:"error",error:{code:"invalid_tool_input",message:`Invalid arguments for "${String(W.name)}": ${V.errors.join(", ")}`,toolCallId:W.toolCallId,retryable:!0}});continue}W.input=V.value;let X=U6(Y.tool);if(X){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(W));continue}J.push({toolCallId:W.toolCallId,name:W.name,input:V.value,kind:X,signature:sQ(this.claimsFor(W.toolCallId,String(W.name),X,V.value)),...this.pathPrefix.length>0?{path:[...this.pathPrefix]}:{}});continue}G.push(this.executeTool(Y,Q.id,W,V.value,Z).then(async(K)=>{this.addResult(Q,K),await this.settleShown(W.toolCallId)}).catch((K)=>{if(K instanceof S){if(this.onPending==="deny"){this.addResult(Q,this.deniedByPolicy(W));return}J.push(...K.pending);return}}))}return await o(Promise.all(G).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}}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,G,W){let Y=this.toolFiles(Z),V={req:this.params.req,body:this.params.body??{},runId:this.runId,threadId:this.params.threadId,toolCallId:Z.toolCallId,signal:this.controller.signal,step:G,depth:this.depth,resumed:W!==void 0,attachments:Y.attachments,generateImage:Y.generateImage,editImage:Y.editImage,turn:this.toolTurn($),runAgent:this.nestedRunner($,Z,W)};try{let X=Q.tool.execute(J,V),K;if(Y9(X)){let H=await X.next();while(!H.done)this.emit({type:"tool-progress",toolCallId:Z.toolCallId,data:H.value}),H=await X.next();K=H.value}else K=await X;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"ok",output:K}}catch(X){if(X instanceof R||this.controller.signal.aborted)throw new R;if(X instanceof S)throw X;return{type:"tool-result",toolCallId:Z.toolCallId,name:Z.name,status:"error",error:{code:"tool_error",message:X instanceof Error?X.message:String(X),toolCallId:Z.toolCallId,retryable:!0}}}}nestedRunner(Q,$,Z){let J=new PQ(()=>$.nested,()=>$.nested=[]);return async(G,W={})=>{let{at:Y,recorded:V,write:X}=J.next();if(V){let K=K9(V,G,W);if(K)throw Error(`Nested run ${Y} 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??s(),output:V6(V.messages),nested:V}}return this.runNested(Q,$,G,W,X,V,Z?.answers??[])}}async runNested(Q,$,Z,J,G,W,Y){let V=[...this.chain,Z.name];if(this.chain.includes(Z.name))throw Error(`"${Z.name}" is already running further up this chain: ${V.join(" -> ")}. An agent cannot run itself, directly or through another agent.`);let X=this.depth+1;if(X>this.maxDepth)throw Error(`Nested agent runs are ${this.maxDepth} deep at most and this one would be ${X}: ${V.join(" -> ")}. Raise maxDepth on the agent at the root of the run if the tree is meant to be this deep.`);let K=J.label,H=[...this.pathPrefix,$.toolCallId],B=this.onPending==="deny"?"deny":J.onPending??"escalate",D=W!==void 0,z=D?a(W.messages):new Set,U=D?Y.filter((C)=>{let x=D6(C.path,H);if(x===null)return!1;return z.has(x.length>0?x[0]:C.toolCallId)}):[],F=Z.stream({messages:D?W.messages:J.messages??[],turn:D?{toolResults:U}:J.prompt?{text:J.prompt}:void 0,req:this.params.req,attachments:this.params.attachments,body:this.params.body,signal:this.controller.signal,threadId:this.params.threadId,instructions:J.instructions,maxOutputTokens:J.maxOutputTokens,temperature:J.temperature,runId:D?W.runId:void 0,nesting:{depth:X,maxDepth:this.maxDepth,chain:V,signingRunId:this.signingRunId,signingPath:H,onPending:B}}),L=[],P=(async()=>{for await(let C of F){if(C.type==="awaiting-input")L=C.pending;this.emit({type:"nested-event",toolCallId:$.toolCallId,runId:F.runId,agent:Z.name,label:K,event:C})}})(),O=(async()=>{let C=await F.result();await P;let x=D?X6(W.messages,C.messages):X6(J.messages??[],C.messages),pQ={runId:F.runId,agent:Z.name,label:K,messages:x,finishReason:C.finishReason,usage:D?t(W.usage??s(),C.usage):C.usage,...C.finishReason==="awaiting-input"?{signature:rQ({runId:this.signingRunId,path:H,nestedRunId:F.runId,open:[...a(x)],input:$.input})}:{}};return G(pQ),this.usage=t(this.usage,C.usage),{result:C,record:pQ}})(),b=O.then(()=>{return},()=>{return});this.nestedSettling.add(b);let c,M;try{({result:c,record:M}=await O)}finally{this.nestedSettling.delete(b)}if(this.controller.signal.aborted)throw new R;if(c.finishReason==="awaiting-input"){if(L.length===0)throw Error(`"${Z.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 S({pending:L,path:H,nested:M})}return{runId:M.runId,agent:Z.name,messages:M.messages,finishReason:c.finishReason,usage:M.usage??s(),output:c.output??V6(M.messages),nested:M}}addResult(Q,$){Q.content.push($),this.emit({type:"tool-result",messageId:Q.id,part:$})}toolFiles(Q){let $=this.params.attachments??null,Z=new PQ(()=>Q.attachments,()=>Q.attachments=[],()=>({failed:!0})),J=()=>{if(!$)throw new A("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 $},G=async(X,K,H)=>{let B=J(),D=K.mimeType||X.type||"",z=K.name??(X instanceof File?X.name:"attachment"),U;if(K.showModel){let L=this.config.provider;if(!L.capabilities.fileInput)throw Error(`"${String(Q.name)}" asked to show a file to ${L.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 L.upload(new File([X],z,{type:D||void 0}))}return{attachment:await B.put(X,{name:z,mimeType:D,fileId:U}),...H?{generated:H}:{},...U?{shown:{fileId:U,messageId:`msg_${crypto.randomUUID()}`,createdAt:new Date().toISOString()}}:{}}},W=(X,K,H)=>{let B=X.generated?"image":"put";if(B===K)return;throw Error(`Attachment ${H} 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.`)},Y=async(X,K,H)=>{let{at:B,recorded:D,write:z}=Z.next();if(D&&"attachment"in D){if(W(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 H();this.usage=t(this.usage,U.usage);let F=U.mimeType==="image/jpeg"?"jpg":"png",L=await G(U.image,{name:K.name??`${X.name}.${F}`,mimeType:U.mimeType,...K.showModel?{showModel:!0}:{}},{size:U.size,usage:U.usage});if(z(L),L.shown)this.queueShown(Q.toolCallId,L);return{attachment:L.attachment,size:U.size,mimeType:U.mimeType,usage:U.usage}},V=async(X)=>typeof X==="string"?await J().file(X):X;return{generateImage:(X,K)=>Y(X,K,()=>X.generate({...K,signal:this.controller.signal})),editImage:(X,K)=>Y(X,K,async()=>{let{images:H,mask:B,...D}=K;return await X.edit({...D,images:await Promise.all(H.map(V)),...B?{mask:await V(B)}:{},signal:this.controller.signal})}),attachments:{get:(X)=>J().get(X),read:(X)=>J().read(X),file:(X)=>J().file(X),put:async(X,K={})=>{let{at:H,recorded:B,write:D}=Z.next();if(B&&"attachment"in B){W(B,"put",H);let U=V9(B,X,K);if(U)throw Error(`Attachment ${H} 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 z=await G(X,K);if(D(z),z.shown)this.queueShown(Q.toolCallId,z);return z.attachment}}}}toolTurn(Q){let $=this.history.findIndex((W)=>W.id===Q),Z=H6(this.history),J;for(let W=$-1;W>=0;W--){let Y=this.history[W];if(Y.role!=="user"||Z.has(Y.id))continue;J=Y;break}let G=[];for(let W of J?.content??[]){if(W.type!=="file")continue;let Y=W.attachmentId;if(typeof Y!=="string"||!Y.startsWith(N))continue;if(!G.includes(Y))G.push(Y)}return Object.freeze({attachments:Object.freeze(G)})}queueShown(Q,$){let Z=$.shown;if(!Z)return;let J=this.shownQueue.get(Q)??[];if(J.some((G)=>G.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((W)=>W!==Q),Z=H6($),J=[];for(let W of $){if(!Z.has(W.id))continue;for(let Y of W.content)if(Y.type==="file")J.push(Y)}if(J.length<=B6)return $;let G=new Set(J.slice(0,J.length-B6));return $.map((W)=>{if(!W.content.some((Y)=>Y.type==="file"&&G.has(Y)))return W;return{...W,content:W.content.map((Y)=>Y.type==="file"&&G.has(Y)?{type:"text",text:`[A ${Y.mimeType||"file"} produced by a tool (attachment ${Y.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.]`}:Y)}})}async ingestTurn(){let Q=this.params.turn,$=this.openCalls(),Z=[];if($.length>0){let J=new Set,G=new Set,W=new Map;for(let Y of Q?.toolResults??[]){let V=`${(Y.path??[]).join("/")}#${Y.toolCallId}`;if(G.has(V))continue;G.add(V);let X=(D)=>this.emit({type:"error",error:{code:"invalid_tool_result",message:D,toolCallId:Y.toolCallId,retryable:!1}}),K=D6(Y.path,this.pathPrefix);if(K===null){X(`The answer for "${Y.toolCallId}" is addressed to a tool call this run is not inside.`);continue}if(K.length>0){let D=K[0],z=$.find((L)=>L.call.toolCallId===D);if(!z){X(`No pending tool call with id "${D}" to deliver a nested answer to.`);continue}let U=this.parkedBelow(z.call,K,Y.toolCallId);if(U.ok===!1){let L=`The answer for "${Y.toolCallId}" is addressed under "${D}", which`;X(U.reason==="unparked"?`${L} has no sub-agent run waiting on that question.`:U.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 F=W.get(D);if(!F){if(!Z6(U.signature)){X(`The answer for "${Y.toolCallId}" is addressed under "${D}", which has already been re-entered on that record. Ask again.`);continue}F=[],W.set(D,F),J.add(D)}F.push(Y);continue}let H=$.find((D)=>D.call.toolCallId===Y.toolCallId);if(!H){X(`No pending tool call with id "${Y.toolCallId}".`);continue}let B=await this.resolveAnswer(H,Y,Z);if(B===null)continue;if(J.add(Y.toolCallId),B!=="open")this.attachToHistory(H,B),await this.settleShown(Y.toolCallId)}for(let[Y,V]of W){let X=$.find((H)=>H.call.toolCallId===Y),K=await this.reenter(X,V,Z);if(K)this.attachToHistory(X,K),await this.settleShown(Y)}for(let Y of $){if(J.has(Y.call.toolCallId))continue;this.attachToHistory(Y,{type:"tool-result",toolCallId:Y.call.toolCallId,name:Y.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((G)=>({type:"file",...G.fileId?{fileId:G.fileId}:{},name:G.name,mimeType:G.mimeType,...G.attachmentId?{attachmentId:G.attachmentId}:{}}))],createdAt:new Date().toISOString(),finishReason:"stop"};this.history.push(J),this.produced.push(J),await this.report(J)}return Z}parkedBelow(Q,$,Z){let J=$.length>1?$[1]:Z,G=[...this.pathPrefix,Q.toolCallId],W=(Q.nested??[]).find((V)=>V.finishReason==="awaiting-input"&&a(V.messages).has(J));if(!W)return{ok:!1,reason:"unparked"};if(typeof W.signature!=="string")return{ok:!1,reason:"unsigned"};let Y=eQ(W.signature,{path:G,nestedRunId:W.runId,open:[...a(W.messages)],input:Q.input});if(Y.ok===!1)return{ok:!1,reason:Y.reason==="expired"?"expired":"unsigned"};return{ok:!0,signature:W.signature}}async reenter(Q,$,Z){let J=String(Q.call.name),G=this.config.registry.get(J);if(!G||!G.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 W=G.tool.inputSchema.safeParse(Q.call.input);if(W.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}": ${W.errors.join(", ")}`,toolCallId:Q.call.toolCallId,retryable:!0}};let Y=this.amendCall(Q);Y.input=W.value;try{return await o(this.executeTool(G,Q.message.id,Y,W.value,0,{answers:$}),this.controller.signal)}catch(V){if(V instanceof S)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((G)=>({...G})),...Q.call.attachments?{attachments:Q.call.attachments.map((G)=>({...G}))}:{}};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 resolveAnswer(Q,$,Z){let J=Q.call,G=String(J.name),W=this.config.registry.get(G),Y=(H)=>{return this.emit({type:"error",error:{code:"invalid_tool_result",message:H,toolCallId:J.toolCallId,retryable:!1}}),null};if(!W)return Y(`The tool "${G}" no longer exists, so its answer cannot be checked.`);let V=U6(W.tool);if(!V)return Y(`"${G}" is a server tool with no pending question.`);if(typeof $.signature!=="string"||$.signature.length===0)return Y(`The answer for "${G}" carried no signature.`);let X=l($.signature);if(!X)return Y(`The signature for "${G}" is malformed.`);let K=tQ($.signature,{...this.claimsFor(J.toolCallId,G,V,J.input),runId:X.runId});if(K.ok===!1)return Y(K.reason==="expired"?`The approval for "${G}" has expired. Ask again.`:`The answer for "${G}" does not match the call the server made.`);if(!$6($.signature))return Y(`The answer for "${G}" has already been used. Ask again.`);if("approve"in $){if(V!=="approval")return Y(`"${G}" is answered by the client, not approved.`);if($.approve===!0){let H=this.amendCall(Q);try{return await o(this.executeTool(W,Q.message.id,H,H.input,0),this.controller.signal)}catch(B){if(B instanceof S)return Z.push(...B.pending),"open";throw B}}return{type:"tool-result",toolCallId:J.toolCallId,name:J.name,status:"denied",cause:"refused",reason:$.reason}}if("output"in $){if(V==="approval")return Y(`"${G}" is approved, not answered: the server produces its result.`);let H=W.tool.outputSchema,B=H?H.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 "${G}" 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 Y(`The answer for "${G}" 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:$})}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})}}this.finishReason="aborted",await this.finalizeMessage("aborted")}}function U6(Q){if(Q.answeredBy==="client")return Q.inputSchema===MQ?"question":"client";return Q.requiresApproval?"approval":null}function z6(Q){if(!Q||!Q.trim())return{};try{return JSON.parse(Q)}catch{return Q}}function H9(Q){if(Q.length>0)Q[0];return Q}function B9(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 D9(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 U9(Q,$){return Q.descriptors($).map((Z)=>T.create({name:Z.name,description:Z.description,inputSchema:Z.inputSchema,requiresApproval:Z.requiresApproval,execute:(J,G)=>Q.execute({kind:"local",req:G.req},Z.name,J,G)}))}function z9(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 O6(Q,$){if(Q.size!==void 0)try{z9(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 j6(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 RQ{name;provider;settings;constructor(Q){let{name:$,provider:Z,...J}=Q;O6(J,`ImageModel "${$}"`),this.name=$,this.provider=Z,this.settings=J}static create(Q){return new RQ(Q)}async generate(Q){let $=this.merge(Q);return N6(await this.provider.generate({prompt:Q.prompt,...$,signal:Q.signal}))}async edit(Q){let $=this.merge(Q);return N6(await this.provider.edit({prompt:Q.prompt,...$,images:Q.images.map((Z,J)=>j6(Z,`image-${J}`)),...Q.mask?{mask:j6(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 O6($,`ImageModel "${this.name}"`),$}}function N6(Q){return{image:new Blob([Q.bytes],{type:Q.mimeType}),mimeType:Q.mimeType,size:Q.size,usage:Q.usage}}function k(Q){return typeof process>"u"?void 0:process.env?.[Q]}var F9="preview";function _6(Q){let $=Q.trim().replace(/\/+$/,"");if(!$)return"";return`${$.replace(/\/openai(?:\/v1)?$/i,"")}/openai`}function L9(Q){return/^\d{4}-\d{2}-\d{2}/.test(Q)?"":"/v1"}function QQ(Q,$={}){return{base:(Q.baseURL??k("OPENAI_BASE_URL")??"https://api.openai.com/v1").replace(/\/+$/,""),query:"",headers:async()=>{let J=Q.apiKey??k("OPENAI_API_KEY");return{...J?{authorization:`Bearer ${J}`}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}function C9(Q){let $=Q.baseURL??Q.endpoint??k("AZURE_OPENAI_ENDPOINT");if($)return _6($);let Z=Q.resourceName??k("AZURE_OPENAI_RESOURCE_NAME")??k("AZURE_RESOURCE_NAME");return Z?_6(`https://${Z.trim()}.cognitiveservices.azure.com`):""}function $Q(Q,$={}){let Z=Q.apiVersion??k("AZURE_OPENAI_API_VERSION")??F9;return{base:`${C9(Q)}${L9(Z)}`,query:`?api-version=${encodeURIComponent(Z)}`,headers:async()=>{if(Q.getToken)return{authorization:`Bearer ${await Q.getToken()}`,...Q.headers};let J=Q.apiKey??k("AZURE_OPENAI_API_KEY");return{...J?{"api-key":J}:{},...Q.headers}},timeoutMs:Q.timeoutMs??$.timeoutMs??120000,maxRetries:Q.maxRetries??2}}class ZQ extends Error{status;body;requestId;constructor(Q,$,Z){super(`Provider request failed with status ${Q}: ${O9($)}`);this.name="ProviderHttpError",this.status=Q,this.body=$,this.requestId=Z}}class JQ extends Error{timeoutMs;constructor(Q){super(`Provider request timed out after ${Q}ms`);this.name="ProviderTimeoutError",this.timeoutMs=Q}}function O9(Q){let $=P6(Q);if($?.message)return $.message;if(typeof Q==="string")return Q.slice(0,500);return"no error body"}function P6(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 G=J.innererror?.code??J.code;return{message:J.message,type:J.type,code:G,param:J.param}}function j(Q){if(Q instanceof JQ)return{code:"provider_error",message:Q.message,retryable:!0};if(P9(Q))return{code:"aborted",message:"The request was aborted.",retryable:!1};if(Q instanceof ZQ)return j9(Q.status,P6(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 j9(Q,$,Z){let J=$?.message??Z,G=($?.code??"").toLowerCase(),W=($?.type??"").toLowerCase(),Y=`${G} ${W} ${J}`.toLowerCase();if(Q===429){let V=G==="insufficient_quota"||Y.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(N9(Y))return{code:"context_length_exceeded",message:J,retryable:!1};if(_9(Y))return{code:"content_filtered",message:J,retryable:!1};if($?.param?.startsWith("tools")||Y.includes("invalid schema for function"))return{code:"invalid_tool_input",message:J,retryable:!1};return{code:"provider_error",message:J,retryable:!1}}function N9(Q){return Q.includes("context_length_exceeded")||Q.includes("maximum context length")||Q.includes("context window")||Q.includes("reduce the length")}function _9(Q){return Q.includes("content_filter")||Q.includes("content_policy_violation")||Q.includes("responsibleaipolicyviolation")||Q.includes("content management policy")}function P9(Q){if(!Q||typeof Q!=="object")return!1;let $=Q;return $.name==="AbortError"||$.code==="ABORT_ERR"}var M9=500,q6=20000;function q9(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 M6(Q,$){let Z=Math.min(q6,M9*2**Q);return Math.round(Z*(0.5+$()*0.5))}function S9(Q){return Q===429||Q===408||Q===409||Q>=500}function R9(Q,$){return S9(Q)&&j($).retryable}function S6(Q){return Q.reason??new DOMException("The operation was aborted.","AbortError")}function T9(Q,$){return new Promise((Z,J)=>{let G=setTimeout(Z,Q);$?.addEventListener("abort",()=>{clearTimeout(G),J(S6($))},{once:!0})})}async function y(Q,$,Z){let J=Z.fetchImpl??((H,B)=>fetch(H,B)),G=Z.sleep??T9,W=Z.random??Math.random,Y=Z.now??Date.now,V=Math.max(0,Z.maxRetries),X=async(H)=>{let B=Z.signal;if(!B)return await G(H);B.throwIfAborted();let D;try{await Promise.race([G(H,B),new Promise((z,U)=>{D=()=>U(S6(B)),B.addEventListener("abort",D,{once:!0})})])}finally{if(D)B.removeEventListener("abort",D)}},K;for(let H=0;H<=V;H++){Z.signal?.throwIfAborted();let B=new AbortController,D=()=>B.abort(Z.signal?.reason);Z.signal?.addEventListener("abort",D,{once:!0});let z=!1,U=Z.timeoutMs>0?setTimeout(()=>{z=!0,B.abort()},Z.timeoutMs):void 0,F;try{F=await J(Q,{...$,signal:B.signal})}catch(b){if(U!==void 0)clearTimeout(U);if(Z.signal?.removeEventListener("abort",D),Z.signal?.aborted)throw b;if(K=z?new JQ(Z.timeoutMs):b,z&&Z.retryTimeouts===!1)throw K;if(H===V)throw K;await X(M6(H,W));continue}if(U!==void 0)clearTimeout(U);if(F.ok)return F;Z.signal?.removeEventListener("abort",D);let L=await k9(F),P=new ZQ(F.status,L,F.headers.get("x-request-id")??void 0);if(H===V||!R9(F.status,P))throw P;let O=q9(F.headers.get("retry-after"),Y());await X(O===void 0?M6(H,W):Math.min(O,q6)),K=P}throw K??Error("Provider request failed with no response.")}async function k9(Q){let $;try{$=await Q.text()}catch{return null}try{return JSON.parse($)}catch{return $}}var TQ=300000;function kQ(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 GQ extends Error{code;retryable;constructor(Q,$={}){super(Q.message,$);this.name="ImageRequestError",this.code=Q.code,this.retryable=Q.retryable}}var x9={png:"image/png",jpeg:"image/jpeg"};function E9(Q){let $=Number(Q?.input_tokens??0),Z=Number(Q?.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q?.total_tokens??$+Z)},G=Q?.input_tokens_details?.image_tokens;if(typeof G==="number")J.imageInputTokens=G;let W=Q?.output_tokens_details?.image_tokens;if(typeof W==="number")J.imageOutputTokens=W;return J}function A9(Q){let $=atob(Q),Z=new Uint8Array($.length);for(let J=0;J<$.length;J++)Z[J]=$.charCodeAt(J);return Z}function I9(Q){let Z=Q?.data?.[0]?.b64_json;if(typeof Z!=="string"||Z.length===0)throw new GQ({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:A9(Z),mimeType:x9[J]??`image/${J}`,size:typeof Q.size==="string"?Q.size:"",...typeof Q.background==="string"?{background:Q.background}:{},usage:E9(Q.usage)}}async function R6(Q,$,Z,J){let G;try{G=await y(Q,$,{maxRetries:Z.maxRetries,timeoutMs:Z.timeoutMs,retryTimeouts:!1,signal:J.signal,fetchImpl:Z.fetchImpl})}catch(W){if(J.signal?.aborted)throw W;throw new GQ(j(W),{cause:W})}return I9(await G.json())}async function T6(Q,$,Z={}){return await R6(Q.generationsUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify($)},Q,Z)}async function k6(Q,$,Z={}){return await R6(Q.editsUrl,{method:"POST",headers:await Q.headers(),body:$},Q,Z)}class WQ{static models(){return[]}modelName(){return this.model}async generate(Q){return await T6(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 k6(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 j(Q)}}var x6=["gpt-image-2","gpt-image-1.5","gpt-image-1"];class xQ extends WQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new xQ(Q,$)}static models(){return x6}endpoint(){return kQ(QQ(this.config,{timeoutMs:TQ}))}}class EQ extends WQ{model;config;constructor(Q,$={}){super();this.model=Q,this.config=$}static model(Q,$){return new EQ(Q,$)}static models(){return x6}modelName(){return this.config.deployment??this.model}endpoint(){return kQ($Q(this.config,{timeoutMs:TQ}))}}async function*w9(Q){let $="",Z="",J=[],G,W=()=>{if(J.length===0&&!Z)return null;let X={event:Z,data:J.join(`
|
|
16
|
+
`),id:G};return Z="",J=[],G=void 0,X.data?X:null},Y=(X)=>{let K=X.endsWith("\r")?X.slice(0,-1):X;if(K==="")return W();if(K.startsWith(":"))return null;let H=K.indexOf(":"),B=H===-1?K:K.slice(0,H),D=H===-1?"":K.slice(H+1);if(D.startsWith(" "))D=D.slice(1);if(B==="event")Z=D;else if(B==="data")J.push(D);else if(B==="id")G=D;return null};for await(let X of Q){$+=X;let K=$.indexOf(`
|
|
17
|
+
`);while(K!==-1){let H=$.slice(0,K);$=$.slice(K+1);let B=Y(H);if(B)yield B;K=$.indexOf(`
|
|
18
|
+
`)}}if($.length>0){let X=Y($);if(X)yield X}let V=W();if(V)yield V}async function*E6(Q,$={}){let Z=new Map,J=new Set,G=!1;for await(let W of w9(Q)){if(W.data==="[DONE]")break;let Y;try{Y=JSON.parse(W.data)}catch{continue}switch(typeof Y.type==="string"?Y.type:W.event){case"response.output_text.delta":{let X=String(Y.delta??"");if(!X)break;yield $.structuredOutput?{type:"output-delta",delta:X}:{type:"text-delta",delta:X};break}case"response.reasoning_summary_text.delta":case"response.reasoning_text.delta":{let X=String(Y.delta??"");if(!X)break;yield{type:"reasoning-delta",delta:X,id:Y.item_id};break}case"response.output_item.added":{let X=Y.item;if(!X)break;if(X.type==="function_call"){let K=String(X.id??Y.item_id??X.call_id??"");Z.set(K,{callId:String(X.call_id??K),name:String(X.name??""),namespace:typeof X.namespace==="string"&&X.namespace?X.namespace:void 0,done:!1})}break}case"response.function_call_arguments.delta":{let X=Z.get(String(Y.item_id??""));if(!X)break;let K=String(Y.delta??"");if(!K)break;yield{type:"tool-call-delta",toolCallId:X.callId,name:X.name,argsDelta:K,...X.namespace?{namespace:X.namespace}:{}};break}case"response.function_call_arguments.done":{let X=String(Y.item_id??""),K=Z.get(X);if(!K)break;K.done=!0,yield{type:"tool-call",toolCallId:K.callId,name:K.name,args:String(Y.arguments??""),...K.namespace?{namespace:K.namespace}:{}};break}case"response.output_item.done":{let X=Y.item;if(!X)break;if(X.type==="function_call"){let K=String(X.id??Y.item_id??X.call_id??""),H=Z.get(K);if(H?.done)break;let B=(typeof X.namespace==="string"?X.namespace:"")||H?.namespace;if(yield{type:"tool-call",toolCallId:String(X.call_id??K),name:String(X.name??H?.name??""),args:String(X.arguments??""),...B?{namespace:B}:{}},H)H.done=!0;break}if(X.type==="tool_search_call"||X.type==="tool_search_output"){let K=b9(X);if(K.loaded.length===0&&K.namespaces.length===0)break;let H=String(X.tool_search_call_id??X.id??"");if(J.has(H))break;J.add(H),yield{type:"tool-search",...K}}break}case"response.refusal.done":{yield{type:"error",error:{code:"content_filtered",message:String(Y.refusal??"The model refused to answer."),retryable:!1}};break}case"response.completed":{G=!0,yield{type:"finish",reason:"stop",usage:AQ(Y.response?.usage)};break}case"response.incomplete":{G=!0;let X=AQ(Y.response?.usage),K=Y.response?.incomplete_details?.reason;if(K==="content_filter"){yield{type:"error",error:{code:"content_filtered",message:v9(Y.response?.content_filters),retryable:!1}},yield{type:"finish",reason:"error",usage:X};break}yield{type:"finish",reason:K==="max_output_tokens"?"length":"stop",usage:X};break}case"response.failed":case"error":{G=!0;let X=Y.response?.error??Y.error??Y;yield{type:"error",error:f9(X)},yield{type:"finish",reason:"error",usage:AQ(Y.response?.usage)};break}}if(G)return}if(!G)yield{type:"error",error:{code:"provider_error",message:"The provider stream ended without a terminal event.",retryable:!0}},yield{type:"finish",reason:"error",usage:I()}}function b9(Q){let $=[],Z=[];return A6(Q.results??Q.tools??Q.loaded??Q.output,$,Z,0),{loaded:IQ($),namespaces:IQ(Z)}}function A6(Q,$,Z,J){if(!Array.isArray(Q)||J>4)return;for(let G of Q){if(typeof G==="string"){$.push(G);continue}if(!G||typeof G!=="object")continue;let W=G,Y=typeof W.name==="string"?W.name:typeof W.tool_name==="string"?W.tool_name:"",V=W.tools??W.functions;if(Array.isArray(V)){if(Y)Z.push(Y);A6(V,$,Z,J+1);continue}if(Y)$.push(Y)}}function IQ(Q){return Q.filter(($,Z)=>Q.indexOf($)===Z)}function v9(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 G=J,W=G.content_filter_results;if(!W||typeof W!=="object")continue;for(let[Y,V]of Object.entries(W))if(V&&typeof V==="object"&&V.filtered===!0)Z.push(`${Y} (${String(G.source_type??"unknown")})`)}return Z.length===0?"The provider's content filter blocked this request.":`The provider's content filter blocked this request. Categories: ${IQ(Z).join(", ")}.`}function f9(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 I(){return{inputTokens:0,outputTokens:0,totalTokens:0}}function AQ(Q){if(!Q)return I();let $=Number(Q.input_tokens??0),Z=Number(Q.output_tokens??0),J={inputTokens:$,outputTokens:Z,totalTokens:Number(Q.total_tokens??$+Z)},G=Q.output_tokens_details?.reasoning_tokens;if(typeof G==="number")J.reasoningTokens=G;let W=Q.input_tokens_details?.cached_tokens;if(typeof W==="number")J.cachedInputTokens=W;return J}async function*I6(Q){if(!Q)return;let $=Q.getReader(),Z=new TextDecoder;try{while(!0){let{done:G,value:W}=await $.read();if(G)break;if(W)yield Z.decode(W,{stream:!0})}let J=Z.decode();if(J)yield J}finally{$.releaseLock()}}function wQ(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*bQ(Q,$,Z){let J;try{J=await y(Q.responsesUrl,{method:"POST",headers:{...await Q.headers(),"content-type":"application/json"},body:JSON.stringify($)},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,signal:Z.signal,fetchImpl:Q.fetchImpl})}catch(G){let W=j(G);if(W.code!=="aborted")yield{type:"error",error:W};yield{type:"finish",reason:W.code==="aborted"?"aborted":"error",usage:I()};return}try{yield*E6(I6(J.body),{structuredOutput:Z.structuredOutput})}catch(G){let W=j(G);if(W.code==="aborted"){yield{type:"finish",reason:"aborted",usage:I()};return}yield{type:"error",error:W},yield{type:"finish",reason:"error",usage:I()}}}async function vQ(Q,$){let Z=new FormData;Z.set("purpose","user_data"),Z.set("file",$);let G=await(await y(Q.filesUrl,{method:"POST",headers:await Q.headers(),body:Z},{maxRetries:Q.maxRetries,timeoutMs:Q.timeoutMs,fetchImpl:Q.fetchImpl})).json();if(!G?.id)throw Error("The provider accepted the upload but returned no file id.");return G.id}function fQ(Q){let $=h9(Q);if($.startsWith("gpt-3.5")||$.startsWith("text-")||$.startsWith("davinci"))return{reasoning:!1,structuredOutput:!1,fileInput:!1,parallelToolCalls:!0,toolSearch:!1};let Z=y9($);if(Z?.kind==="o")return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:Z.major>1,toolSearch:w6(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:w6(Z)};return{reasoning:!0,structuredOutput:!0,fileInput:!0,parallelToolCalls:!0,toolSearch:!0}}function w6(Q){if(Q.kind==="o")return Q.major>=5;return Q.major>5||Q.major===5&&Q.minor>=2}function h9(Q){return Q.trim().toLowerCase()}function y9(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 hQ(Q,$){let{capabilities:Z}=$,J={model:$.model,input:u9(Q.messages,Z),stream:!0};if(Q.systemPrompt)J.instructions=Q.systemPrompt;let G=o9(Q.tools,Z);if(G.length>0){if(J.tools=G,!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={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 u9(Q,$){let Z=[];for(let J of Q){let G=J.role,W=[],Y=()=>{if(W.length===0)return;Z.push({type:"message",role:G,content:W}),W=[]};for(let V of J.content??[])switch(V.type){case"text":{if(!V.text)break;W.push(YQ(G,V.text));break}case"output":{if(V.partial)break;W.push(YQ(G,JSON.stringify(V.value)));break}case"file":{if(G==="assistant")break;let X=m9(V);if(!$.fileInput){if(X)W.push(YQ(G,b6(V,!1)));break}if(V.fileId?.startsWith(N))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&&!X)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(X)W.push(YQ(G,b6(V,!!V.fileId)));if(V.fileId)W.push(p9(V));break}case"reasoning":{Y();let X=i9(V);if(X)Z.push(X);break}case"tool-call":{if(V.partial)break;Y(),Z.push({type:"function_call",call_id:V.toolCallId,name:String(V.name),arguments:JSON.stringify(V.input??{})});break}case"tool-result":{Y(),Z.push({type:"function_call_output",call_id:V.toolCallId,output:n9(V)});break}}Y()}return c9(Z)}var g9="No result was recorded for this tool call. Assume it did not complete.";function c9(Q){let $=new Set,Z=new Set,J=[];for(let W of Q){if(W.type==="function_call"){let Y=String(W.call_id);if($.has(Y))continue;$.add(Y)}else if(W.type==="function_call_output"){let Y=String(W.call_id);if(!$.has(Y)||Z.has(Y))continue;Z.add(Y)}J.push(W)}if(Z.size===$.size)return J;let G=[];for(let W of J){if(G.push(W),W.type!=="function_call")continue;let Y=String(W.call_id);if(Z.has(Y))continue;Z.add(Y),G.push({type:"function_call_output",call_id:Y,output:g9})}return G}function YQ(Q,$){return{type:Q==="assistant"?"output_text":"input_text",text:$}}function m9(Q){let $=Q.attachmentId;return typeof $==="string"&&$.startsWith(N)?$:void 0}function b6(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 p9(Q){let $=Q.mimeType?.trim().toLowerCase()??"";return{type:($?$.startsWith("image/")&&$!=="image/svg+xml":l9(Q.name))?"input_image":"input_file",file_id:Q.fileId}}function l9(Q){let $=/\.([a-z0-9]+)$/.exec(Q?.trim().toLowerCase()??"");return $?.[1]!==void 0&&d9.has($[1])}var d9=new Set(["jpeg","jpg","png","gif","webp"]);function i9(Q){if(!Q.id)return null;let $={type:"reasoning",id:Q.id};return $.summary=Q.text?[{type:"summary_text",text:Q.text}]:[],$}function n9(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.${$}`;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 v6(Q){return Array.isArray(Q.tools)}function o9(Q,$){if(!Q||Q.length===0)return[];if(!$.toolSearch){let G=[];for(let W of Q)if(v6(W))for(let Y of W.tools)G.push(XQ(Y,!1));else G.push(XQ(W,!1));return G}let Z=[],J=!1;for(let G of Q)if(v6(G)){let W=G.tools.map((Y)=>{if(Y.deferred)J=!0;return XQ(Y,!0)});Z.push({type:"namespace",name:G.name,description:G.description,tools:W})}else{if(G.deferred)J=!0;Z.push(XQ(G,!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 VQ{static models(){return[]}normalizeError(Q){return j(Q)}}var f6=["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 yQ extends VQ{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=fQ(Q),this.config=$}static model(Q,$){return new yQ(Q,$)}static models(){return f6}stream(Q){let $=hQ(Q,{model:this.model,capabilities:this.capabilities});return bQ(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output)})}upload(Q){return vQ(this.endpoint(),Q)}endpoint(){return wQ(QQ(this.config))}}class uQ extends VQ{model;capabilities;config;constructor(Q,$={}){super();this.model=Q,this.capabilities=fQ(Q),this.config=$}static model(Q,$){return new uQ(Q,$)}static models(){return f6}stream(Q){let $=hQ(Q,{model:this.deployment(),capabilities:this.capabilities});return bQ(this.endpoint(),$,{signal:Q.signal,structuredOutput:Boolean(Q.output)})}upload(Q){return vQ(this.endpoint(),Q)}deployment(){return this.config.deployment??this.model}endpoint(){return wQ($Q(this.config))}}class w 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 u extends Error{runId;code="live_run_not_found";constructor(Q){super(`No live run ${Q} in this process.`);this.runId=Q}}class KQ{ttlMs;maxFrames;runs=new Map;byThread=new Map;byClientRun=new Map;constructor(Q={}){this.ttlMs=Q.ttlMs??60000,this.maxFrames=Q.maxFrames??4096}register(Q,$={}){let Z={run:Q,threadId:$.threadId,clientRunId:$.clientRunId,frames:[],lastSeq:-1,lostBefore:0,ended:!1,evictAt: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.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}replay(Q,$){let Z=this.runs.get(Q);if(!Z)throw new u(Q);if($!==void 0&&$<Z.lostBefore)throw new w(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);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.frames.push(J),Q.lastSeq=J.seq,Q.frames.length>this.maxFrames){let W=Q.frames.shift();if(W)Q.lostBefore=W.seq+1}this.notify(Q);let G=$.onEvent;if(G)Z=Z.then(()=>G(J.event)).catch((W)=>h6($,W))}}catch(J){h6($,J)}finally{Q.ended=!0,this.notify(Q),this.scheduleEviction(Q),await Z}}async*drain(Q,$,Z){let J=Z;while(!0){let G=Q.version;for(;;){if(J<Q.lostBefore)throw new w($,J,Q.lostBefore);let W=Q.frames,Y=W[0]?.seq;if(Y===void 0)break;let V=Math.max(0,J-Y);if(V>=W.length)break;let X=W[V];yield X,J=X.seq+1}if(Q.ended&&J>Q.lastSeq)return;await this.wait(Q,G)}}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(this.runs.delete(Z),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=$}}var gQ=new KQ;function h6(Q,$){try{Q.onInternalError?.($)}catch{}}class HQ{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 G=Z.messages.findIndex((W)=>W.id===J.id);if(G===-1)Z.messages.push(J);else Z.messages[G]=J}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 cQ=new HQ;var s9=m6,BQ=new Map,y6=new WeakMap,DQ=new Map;class l6 extends s9{static kind="agent-controller";store=cQ;liveRuns=gQ;attachments=n;attachmentStorage=p6;hookHoldMs=30000;instructions(Q,$){}requireThread=!1;authorizeRequest(Q,$){}async stream(Q=new g){let $=await mQ(Q);if($.error)return UQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:void 0,G=e9(Z);if(G.error)return UQ({body:{},error:G.error});let W=G.turn,Y=typeof Z.clientRunId==="string"?Z.clientRunId:void 0;if(this.requireThread&&!J)return _(400,{code:"thread_required",message:"This agent takes a turn only on a thread: send a threadId."});let V=Y?{cancelled:!1}:null;if(V)DQ.set(Y,V);let X=async()=>{let K;if(J){let O=await this.store.loadThread(J);if(!O)return _(404,{code:"thread_not_found",message:`Thread ${J} does not exist here, or has expired.`});K=O}else K=Array.isArray(Z.messages)?Z.messages:[];let H=a9(Z),B=await this.instructions(Q,{body:H})||void 0,D=await this.attachmentsFor(Q,J);if(V?.cancelled)return g6();let z=this.agent.stream({messages:K,turn:W,req:Q,threadId:J,instructions:B,attachments:D,body:H}),U={req:Q,runId:z.runId,threadId:J},F=this.liveRuns.register(z,{threadId:J,clientRunId:Y,onEvent:(O)=>this.dispatchEvent(O,U),onInternalError:(O)=>this.reportHookFailure(O)}),{stored:L,hooks:P}=this.persistRun(z,U,F);return y6.set(z,L),Q.ctx?.()?.waitUntil(P),z.toResponse()};try{if(await this.authorizeRequest(Q,{route:"stream",threadId:J}),V?.cancelled)return g6();return J?await this.withThread(J,X):await X()}finally{if(V&&DQ.get(Y)===V)DQ.delete(Y)}}async withThread(Q,$){let Z=BQ.get(Q)??Promise.resolve(),J,G=new Promise((Y)=>{J=Y}),W=Z.then(()=>G);BQ.set(Q,W),await Z;try{let Y=await this.liveRuns.find({threadId:Q}),V=Y?this.liveRuns.get(Y.runId):null;if(V)V.stop({reason:"superseded by a later turn on this thread"}),await y6.get(V);return await $()}finally{if(J(),BQ.get(Q)===W)BQ.delete(Q)}}async attach(Q=new g){let $=await mQ(Q);if($.error)return UQ($);let Z=$.body,J=typeof Z.threadId==="string"?Z.threadId:Z$(Q,"threadId");if(!J)return _(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 G=await this.liveRuns.find({threadId:J});if(!G)return _(404,{code:"no_live_run",message:`No run in progress for thread ${J} in this process.`});let W=typeof Z.runId==="string"?Z.runId:void 0,Y=W&&W!==G.runId?void 0:$$(Q,Z);try{return W6(this.liveRuns.replay(G.runId,Y))}catch(V){if(V instanceof w)return _(410,{code:V.code,message:V.message,oldestSeq:V.oldest});if(V instanceof u)return _(404,{code:V.code,message:V.message});throw V}}async stop(Q=new g){let $=await mQ(Q);if($.error)return UQ($);let Z=$.body;await this.authorizeRequest(Q,{route:"stop",threadId:typeof Z.threadId==="string"?Z.threadId:void 0});let J=typeof Z.runId==="string"?Z.runId:void 0;if(!J&&typeof Z.clientRunId==="string"){if(J=this.liveRuns.findByClientRunId(Z.clientRunId)??void 0,!J){let W=DQ.get(Z.clientRunId);if(W)return W.cancelled=!0,{stopped:!0}}}if(!J&&typeof Z.threadId==="string")J=(await this.liveRuns.find({threadId:Z.threadId}))?.runId;let G=J?this.liveRuns.get(J):null;if(!G)return{stopped:!1};return G.stop({reason:typeof Z.reason==="string"?Z.reason:void 0}),{stopped:!0}}attachmentScope(Q,$){let Z=Q.ctx()?.user,J=Z?.id??Z?.publicId;if(J!==void 0&&J!==null&&String(J)!=="")return{key:`user:${String(J)}`};if($)return{key:`thread:${$}`};return null}attachmentDestination(Q,$){return"both"}async attachmentsFor(Q,$){let Z=await this.attachmentScope(Q,$);if(!Z)return null;return new f(this.attachments,this.attachmentStorage,Z)}async upload(Q=new g){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",G=Z.type||"application/octet-stream",W=$.get("threadId");await this.authorizeRequest(Q,{route:"upload",threadId:typeof W==="string"&&W.length>0?W:void 0});let Y=typeof W==="string"&&W.length>0&&await this.store.loadThread(W)!==null?W:void 0,V=await this.attachmentDestination(Z,Q),X=J$(V,$.get("destination")),K=await this.attachmentScope(Q,Y),H=X!=="provider"&&!K;if(H){if(X==="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()`.');G$()}if(X==="provider"||!K){let L={fileId:await this.agent.provider.upload(Z),name:J,mimeType:G,size:Z.size,destination:"provider"};if(H)L.downgraded="no_scope";return L}let B=CQ(),D=await this.attachmentStorage.put({name:OQ(B,J),body:Z,contentType:G}),z=X==="both"?await this.agent.provider.upload(Z):void 0,U={id:B,scopeKey:K.key,fileId:z,objectName:D,name:J,mimeType:G,size:Z.size,createdAt:new Date().toISOString(),destination:X};return await this.attachments.put(K,U),{fileId:z,attachmentId:B,name:J,mimeType:G,size:Z.size,destination:X}}onMessage(Q,$){}onToolCall(Q,$){}onAwaitingInput(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(Q.error,$);return;default:return}}persistRun(Q,$,Z){let J=Promise.resolve(),G=(async()=>{let Y;try{Y=await Q.result()}catch(X){J=this.safely(()=>this.onError({code:"unknown",message:X instanceof Error?X.message:String(X),retryable:!1},$));return}let V=Y.messages;if($.threadId&&V.length>0)try{await this.store.appendMessages($.threadId,V)}catch(X){this.reportHookFailure(X)}J=this.notifyRun(Y,V,$)})(),W=G.then(()=>Y$(Promise.all([J,Z]).then(()=>{}),this.hookHoldMs));return{stored:G,hooks:W}}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 u6=["turn","clientRunId","threadId","messages"],t9=["text","files","toolResults"];function a9(Q){let $=d6(Q)?u6:[...u6,...t9],Z={};for(let[J,G]of Object.entries(Q)){if($.includes(J))continue;Object.defineProperty(Z,J,{value:G,writable:!0,enumerable:!0,configurable:!0})}return Z}async function mQ(Q){let $=Q?.rawRequest;if(!$||$.method==="GET"||$.method==="HEAD"||!$.body)return{body:{}};if(!r9($.headers.get("Content-Type")))return{body:{},status:415,code:"unsupported_media_type",error:"The request body must be sent as application/json."};let Z;try{Z=await $.text()}catch{return{body:{},error:"The request body could not be read."}}if(!Z.trim())return{body:{}};let J;try{J=JSON.parse(Z)}catch{return{body:{},error:"The request body is not valid JSON."}}if(J===null||typeof J!=="object"||Array.isArray(J))return{body:{},error:"The request body must be a JSON object."};return{body:J}}function r9(Q){if(typeof Q!=="string")return!1;let[$]=Q.split(";",1);return $.trim().toLowerCase()==="application/json"}function UQ(Q){return _(Q.status??400,{code:Q.code??"invalid_request",message:Q.error})}function d6(Q){return Boolean(Q.turn)&&typeof Q.turn==="object"}function e9(Q){let $=d6(Q)?Q.turn:Q,Z={};if(typeof $.text==="string")Z.text=$.text;if(Array.isArray($.files)){let J=Q$($.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 Q$(Q){let $=[];for(let[Z,J]of Q.entries()){let G=`turn.files[${Z}]`;if(!J||typeof J!=="object"||Array.isArray(J))return`${G} must be an object.`;let W={};for(let H of["fileId","attachmentId","name","mimeType"]){let B=J[H];if(B===void 0||B===null||B==="")continue;if(typeof B!=="string")return`${G}.${H} must be a string.`;W[H]=B}let{fileId:Y,attachmentId:V,name:X,mimeType:K}=W;if(Y?.startsWith(N))return`${G}.fileId holds a gemi attachment id (${Y}). \`fileId\` is the provider's id from the upload response; put this one in \`attachmentId\`.`;if(V!==void 0&&!V.startsWith(N))return`${G}.attachmentId is not a gemi attachment id: it must start with "${N}".`;if(!Y&&!V)return`${G} has neither a \`fileId\` nor an \`attachmentId\`. Send the ids the upload response answered.`;$.push({...Y?{fileId:Y}:{},...V?{attachmentId:V}:{},...X!==void 0?{name:X}:{},...K!==void 0?{mimeType:K}:{}})}return $}function $$(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 Z$(Q,$){let Z=Q?.search?.get($);return typeof Z==="string"?Z:void 0}function g6(){return _(409,{code:"stopped",message:"The turn was stopped before it started."})}function _(Q,$){return new Response(JSON.stringify({error:$}),{status:Q,headers:{"Content-Type":"application/json"}})}function J$(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 c6=!1;function G$(){if(c6)return;c6=!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 W$=2147483647;function Y$(Q,$){let Z=Q.then(()=>{},()=>{});if(!($<=W$))return Z;let J,G=new Promise((W)=>{J=setTimeout(W,$)});return Promise.race([Z,G]).finally(()=>clearTimeout(J))}export{U9 as toAgentTools,r as supportsStrict,X$ as s,gQ as liveRuns,n as defaultAttachmentStore,cQ as defaultAgentStore,e as ToolNamespace,qQ as Skill,f as ScopedAttachments,h as SKILLS_NAMESPACE,S as PendingEscalation,yQ as OpenAIProvider,xQ as OpenAIImageProvider,KQ as MemoryLiveRuns,i as MemoryAttachmentStore,HQ as MemoryAgentStore,u as LiveRunNotFoundError,A as InvalidAttachmentScopeError,GQ as ImageRequestError,WQ as ImageProvider,RQ as ImageModel,w as FrameCursorEvictedError,uQ as AzureOpenAIProvider,EQ as AzureOpenAIImageProvider,v as AttachmentNotFoundError,T as AgentTool,VQ as AgentProvider,l6 as AgentController,SQ as Agent};
|
|
19
19
|
|
|
20
|
-
//# debugId=
|
|
20
|
+
//# debugId=17ABCDE313E1DC1364756E2164756E21
|