@cortexkit/opencode-openai-auth 1.5.0 → 1.6.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/bin.js +2 -2
- package/dist/{codex-request-BjGT9yWg.d.ts → codex-request-D_In8uaR.d.ts} +43 -26
- package/dist/{index-gmmakhbt.js → index-1qxz4s8a.js} +2 -2
- package/dist/{index-2rw81dtm.js → index-79y7w9bz.js} +1 -1
- package/dist/{index-2yszc75z.js → index-7nmdsmpp.js} +2 -2
- package/dist/{index-3y453wg4.js → index-8xq099qf.js} +2 -2
- package/dist/index-agaatt62.js +65 -0
- package/dist/{index-mhfja8yr.js → index-b0ty9qam.js} +2 -2
- package/dist/index-ge60xry3.js +90 -0
- package/dist/{index-krcqvyqf.js → index-jkpg9d1p.js} +1 -1
- package/dist/index-k5anexvs.js +69 -0
- package/dist/{index-e416r885.js → index-rf0ht3gc.js} +2 -2
- package/dist/{index-4w0nsq5s.js → index-x9nffaye.js} +1 -1
- package/dist/{index-7vkn2e46.js → index-ya9c5e4m.js} +1 -1
- package/dist/{index-djnfq652.js → index-z8bptbrk.js} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{model-BMq5SCUB.d.ts → model-D22uj0OB.d.ts} +1 -1
- package/dist/{port-file-CjMFUWcX.d.ts → port-file-8ElfwDcq.d.ts} +1 -1
- package/dist/{protocol-BC3ndToM.d.ts → protocol-CK9guiFy.d.ts} +1 -1
- package/dist/rpc/port-file.d.ts +1 -1
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +1 -1
- package/dist/rpc/protocol.js +1 -1
- package/dist/rpc/rpc-client.d.ts +3 -3
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/{sidebar-state-DfYyqiOH.d.ts → sidebar-state-Bb9L9oPq.d.ts} +4 -4
- package/dist/sidebar-state.d.ts +1 -1
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-nyvn9866.js +1 -0
- package/dist/{token-ycw7dyev.js → token-xtq3457d.js} +1 -1
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +2 -2
- package/dist/v2/server.d.ts +2 -2
- package/dist/v2/server.js +2 -2
- package/package.json +2 -2
- package/src/tui-compiled/raw/shared/81dddd203f1b92a3-quota-writer.js +4 -54
- package/src/tui-compiled/raw/shared/a62a27a204266acd-attribution.js +39 -25
- package/src/tui-compiled/raw/shared/a910277ac43a8626-pull.js +3 -1
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +18 -3
- package/src/tui-compiled/raw/shared/c911dbb64c9d85c7-quota-writer.js +298 -0
- package/src/tui-compiled/raw/shared/e1c5e56df0ba4053-pending.js +48 -0
- package/src/tui-compiled/runtime/shared/81dddd203f1b92a3-quota-writer.js +4 -54
- package/src/tui-compiled/runtime/shared/a62a27a204266acd-attribution.js +39 -25
- package/src/tui-compiled/runtime/shared/a910277ac43a8626-pull.js +3 -1
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +18 -3
- package/src/tui-compiled/runtime/shared/c911dbb64c9d85c7-quota-writer.js +298 -0
- package/src/tui-compiled/runtime/shared/e1c5e56df0ba4053-pending.js +48 -0
- package/dist/index-2p3gcjsa.js +0 -69
- package/dist/index-6fdmqk6p.js +0 -90
- package/dist/index-fztcacjr.js +0 -65
- package/dist/token-util-ed4az5gg.js +0 -1
package/dist/v2/server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{c as
|
|
1
|
+
import{c as sZ}from"../index-79y7w9bz.js";import{A as u2,B as _$,C as M$,D as cZ,E as dZ,F as C1,G as iZ,H as aZ,I as B$,J as MZ,K as CZ,L as nZ,M as oZ,N as l$,O as u$,P as v2,Q as U$,T as ZZ,U as JZ,aa as QZ,ba as jZ,d as S$,e as vZ,f as GZ,fa as rZ,g as n2,h as C2,i as l2,j as uZ,k as pZ,l as d2,la as f1,m as P2,ma as I1,o as w1,p as y1,pa as tZ,q as D1,r as y2,s as x$,t as q$,u as b$,v as h$,w as m$,x as g$,y as t$,z as e$}from"../index-agaatt62.js";import{Aa as $$,Ra as i$,Ya as g2,gb as i2,hb as yZ,ib as fZ,jb as IZ,lb as hZ,mb as a$,vb as mZ,wa as wZ,wb as gZ,xb as lZ,yb as n$,za as e1}from"../index-k5anexvs.js";import{Ob as KZ,bc as LZ,cc as PZ,ec as TZ,ic as _Z}from"../index-1qxz4s8a.js";import{Hd as B2,Md as s1,Od as T$,Pd as t1,Vd as c2,Wc as h2,Xc as m2,Yc as DZ,ae as YZ,be as S2,ce as Z$,dd as M1,de as J$,ed as a1,ee as z$,fd as n1,gd as o1,ge as G$,he as X$,je as Y$,ke as Q$,le as V1,me as j$,ne as V$,od as c$,ud as d$,wd as kZ,xd as XZ,yc as i1,yd as r1}from"../index-ge60xry3.js";import{te as R$}from"../index-8xq099qf.js";import{Ce as I$}from"../index-z8bptbrk.js";import"../index-rf0ht3gc.js";import{Me as bZ,Oe as N2}from"../index-b0ty9qam.js";import"../index-7nmdsmpp.js";import{if as v$}from"../index-x9nffaye.js";import{mf as a2,nf as qZ}from"../index-ya9c5e4m.js";import{AsyncLocalStorage as $4}from"node:async_hooks";import{randomUUID as Z4}from"node:crypto";class J2 extends Error{kind;providerID;sessionID;requestKind;constructor($){super($.message??`${$.providerID} ${$.requestKind} request refused (${$.kind})`);this.name="OpenCode2AuthError",this.kind=$.kind,this.providerID=$.providerID,this.sessionID=$.sessionID,this.requestKind=$.requestKind}}function Q2($){return`common-auth-placeholder.${$}`}function S1($){let Z=Q2($.integrationID);return{type:"oauth",methodID:$.methodID,access:Z,refresh:Z,expires:$.now+31536000000,metadata:{["commonAuthPlaceholder"]:!0}}}function O2($,Z){if($?.type!=="oauth")return!1;let J=Z===void 0?void 0:Q2(Z),z=(X)=>J===void 0?X.startsWith("common-auth-placeholder."):X===J;return z($.access)&&z($.refresh)}var x1="No browser sign-in: this connects the plugin to the accounts in its vault.";async function t2($,Z){let J=Z.now??Date.now,{integrationID:z}=Z,X=(N)=>S1({integrationID:z,methodID:N,now:J()}),Y=async(N,U)=>{return await Z.onLogin(N,{integrationID:z,methodID:U}),X(U)},F=(N)=>async(U)=>{let j=N.method.id,B=await N.authorize(U),L={url:B.url,instructions:B.instructions,...B.expiresAt===void 0?{}:{expiresAt:B.expiresAt}};if(B.mode==="auto")return{...L,mode:"auto",callback:B.callback.then((_)=>Y(_,j))};let S=B.callback;return{...L,mode:"code",callback:async(_)=>Y(await S(_),j)}};return $.integration.transform((N)=>{let U=Z.label===void 0?{}:{label:()=>Z.label};for(let L of Z.methods)N.method.update({integrationID:z,method:L.method,authorize:F(L),refresh:async(S)=>{if(!O2(S,z))throw Error("This login method refreshes only its pool placeholder; sign in again with the plugin's login method.");return X(S.methodID)},...U});let j=Z.vault;if(j===void 0)return;let B=j.method.id;N.method.update({integrationID:z,method:j.method,authorize:async()=>({url:"",instructions:j.instructions??x1,mode:"auto",callback:Promise.resolve().then(()=>j.activate({integrationID:z,methodID:B})).then(()=>X(B))}),refresh:async(L)=>{if(!O2(L,z)||L.methodID!==B)throw Error("This login method refreshes only its vault placeholder; choose the plugin's vault login method again.");return X(B)},...U})})}function Z0($){let Z=[],J;for(let z of $.split(/\r?\n/))if(z.startsWith("data:"))Z.push(z.slice(5).replace(/^ /,""));else if(z.startsWith("event:"))J=z.slice(6).trim();if(Z.length===0)return;return J===void 0?{data:Z.join(`
|
|
2
2
|
`)}:{event:J,data:Z.join(`
|
|
3
|
-
`)}}function e2($,Z){let J=new TextDecoder,z="",X=(F)=>{let N=$0(F);if(!N)return;try{$(N)}catch(U){Z(U)}},Y=()=>{for(;;){let F=/\r?\n\r?\n/.exec(z);if(!F)return;let N=z.slice(0,F.index);z=z.slice(F.index+F[0].length),X(N)}};return new TransformStream({transform(F,N){N.enqueue(F),z+=J.decode(F,{stream:!0}),Y()},flush(){if(z+=J.decode(),Y(),z.trim()!=="")X(z);z=""}})}var q1=512,M2="x-common-auth-attempt",L2=($,Z)=>JSON.stringify([$,Z]),j2=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function Z0($){let Z=$.headers;return typeof Z==="object"&&Z!==null}function J0($,Z){let J=$.getReader();return new ReadableStream({async pull(z){let X;try{X=await J.read()}catch(Y){Z({reason:"failed",message:Y instanceof Error?Y.message:String(Y)}),z.error(Y);return}if(X.done)Z(),z.close();else z.enqueue(X.value)},async cancel(z){Z({reason:"cancelled",...z===void 0?{}:{message:String(z)}}),await J.cancel(z)}})}function $1($,Z){for(let[J,z]of Object.entries(Z)){let X=J.toLowerCase();for(let Y of Object.keys($))if(Y.toLowerCase()===X)delete $[Y];if(z!==null)$[J]=z}}function z0($,Z){for(let[J,z]of Object.entries(Z))if(z===null)$.delete(J);else $.set(J,z)}async function Z1($,Z,J={}){let{providerID:z}=Z,X=J.gateOnPlaceholder,Y=(G)=>X===void 0||X.credential(G)===Q2(z),F=J.logger,N=Math.max(1,J.maxRecords??q1),U=[...J.hostCredentials??[Q2(z)],...X?[Q2(z)]:[]].filter((G)=>G!==""),j=new Map,B=new WeakMap,L=new Map,S=new Set,_=new Map,u=!1,o=!1,R=new Map,k=0,z2=!1,w=new Map,h=(G,Q)=>{try{F?.warn(G,Q)}catch{}},v=(G)=>G instanceof Error?G.message:String(G),V=new Map,P=(G,Q)=>{let W=(V.get(G)??Promise.resolve()).then(Q),H=W.then(()=>{},()=>{});return V.set(G,H),H.then(()=>{if(V.get(G)===H)V.delete(G)}),W},E=(G,Q)=>{let W=V.get(G);return W?W.then(()=>E(G,Q)):Q()},K=async(G)=>{try{await Z.dropChoice?.({...G.input,accountId:G.accountId})}catch(Q){h("opencode2 auth dropChoice threw; the request is unaffected",{sessionID:G.input.sessionID,error:v(Q)})}},A=(G)=>{let Q=L.get(G);if(L.delete(G),Q?.next){let W=Q.next;P(Q.sessionID,()=>K(W))}},T=async(G,Q)=>{let W=R.get(G);if(!W||W.size===0)return;await Promise.all([...W].map(async(H)=>{try{await H(Q)}catch(x){h("opencode2 auth listener threw; the request is unaffected",{event:G,error:v(x)})}}))},C=async(G,Q)=>{try{await Z.onAttemptEnd?.(G,Q)}catch(W){h("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:G.attemptId,error:v(W)})}},y=(G,Q)=>{if(G.ended||!G.attempt)return;let W={...G.status===void 0?{}:{status:G.status},outputStarted:G.outputStarted,...G.limit?{limit:G.limit.signal}:{},...Q?{error:Q}:{}};if(Q)G.endError=Q;G.ended=C(G.attempt,W)},b=(G,Q)=>y(G,{reason:"abandoned",message:Q}),m=(G)=>[...j.values()].filter((Q)=>Q.key===G),g=(G)=>m(G).at(-1),r=(G)=>{if(j.delete(G.id),L.get(G.key)?.attemptId===G.id||!m(G.key).length)A(G.key)},e=(G)=>{j.set(G.id,G);while(j.size>N){let Q=j.values().next().value;if(Q===void 0)break;b(Q,"dropped to keep the record bound"),r(Q)}},c=(G)=>G.accountId===void 0?void 0:{...G.scope,accountId:G.accountId},s=(G,Q)=>new J2({kind:"no-account",providerID:z,sessionID:G.sessionID,requestKind:G.kind,...Q===void 0?{}:{message:Q}}),l=(G)=>{w.get(G)?.clear(),w.delete(G)},f=async(G,Q)=>{let W=()=>s(G,`${z} ${G.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(z2)throw W();let H=w.get(G.sessionID);if(!H)H=new Set,w.set(G.sessionID,H);let x={};H.add(x);let q=()=>{if(!H.has(x))throw W()};try{return await Q(q)}finally{if(H.delete(x),H.size===0&&w.get(G.sessionID)===H)w.delete(G.sessionID)}},I=(G,Q)=>{for(let[W,H]of Q)if(U.some((x)=>H.includes(x)))throw new J2({kind:"host-credential-on-wire",providerID:z,sessionID:G.sessionID,requestKind:G.kind,message:`${z} ${G.kind} request still carries the host's placeholder credential in ${W}; the adapter's account headers must replace it`})},$2=(G)=>{for(let Q of m(G))if(Q.ended||!Q.attempt)r(Q);else if(Q.transport==="ws"||Q.judged)b(Q,"a newer attempt of its session and kind began"),r(Q)},p=async(G,Q,W,H)=>{let x=L2(G.sessionID,G.kind),{input:q,accountId:O}=await E(G.sessionID,async()=>{W();let n=L.get(x);L.delete(x);let _2=n?.accountId??g(x)?.accountId;$2(x);let t=n?.next,O2=t!==void 0&&t.input.modelID===G.modelID&&t.input.agent===G.agent,H2={...G,phase:"request",..._2===void 0?{}:{previousAccountId:_2},...n?.rerouteFrom?{rerouteFrom:n.rerouteFrom}:{}};if(t&&!O2)await P(G.sessionID,()=>K(t)),W();let w2=O2?t.accountId:await Z.chooseAccount(H2);return{input:H2,accountId:w2}});W();let D={},i;if(O!==void 0){let n=await Z.accountHeaders({...G,accountId:O});if(W(),Z0(n))D=n.headers,i=n.attempt;else D=n}let G2=`attempt-${++k}`,Z2={id:G2,key:x,scope:G,accountId:O,headers:D,attempt:O===void 0?void 0:{...G,accountId:O,attemptId:G2,transport:H,data:i},...H===void 0?{}:{transport:H},outputStarted:!1};if(e(Z2),Z2.attempt)T("select",{...G,accountId:Z2.attempt.accountId,hook:Q,...q.previousAccountId===void 0?{}:{previousAccountId:q.previousAccountId},...q.rerouteFrom===void 0?{}:{rerouteFrom:q.rerouteFrom},handle:Z2.attempt});return Z2},a=async(G,Q,W,H,x)=>{let q=L2(G.sessionID,G.kind),O=H===void 0?void 0:j.get(H);if(O?.key!==q)O=void 0;if(!O){if(O=g(q),m(q).filter((i)=>i.transport===void 0&&!i.ended).length>1&&!o)o=!0,h("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:G.sessionID,kind:G.kind})}if(!O||O.transport!==void 0||O.ended)O=await p(G,Q,x,W);else if(O.transport=W,O.attempt)O.attempt.transport=W;if(W==="ws"){for(let D of m(q))if(D!==O&&D.transport==="ws")b(D,"a newer attempt of its session and kind went out over WebSocket")}return O},U2=async(G,Q)=>{try{return await Q()}catch(W){throw y(G,{reason:"failed",message:v(W)}),W}},T2=(G,Q)=>{let W=m(L2(G,Q)).filter((H)=>H.transport==="ws").at(-1);return W?.attempt!==void 0&&!W.ended?W:void 0},F2=(G,Q,W)=>{let H=c(G);if(!H||!G.attempt||G.limit)return;G.limit={signal:Q,delivered:T("limit",{...H,via:W,limit:Q,outputStarted:G.outputStarted,handle:G.attempt})}},M=(G,Q,W,H)=>{let x=c(G);if(!x||!G.attempt)return;T("quota",{...x,transport:Q,...H===void 0?{}:{status:H},quota:W,handle:G.attempt})},d=(G,Q,W,H)=>{let x=G.attempt;if(!x)return;let q=Z.inspectEvent?.(H===void 0?{transport:Q,data:W,attempt:x}:{transport:Q,data:W,event:H,attempt:x});if(!q)return;if(q.quota!==void 0)M(G,Q,q.quota);if(q.outputStarted)G.outputStarted=!0;if(q.limit)F2(G,q.limit,Q);if(q.error!==void 0)y(G,{reason:"failed",message:q.error});else if(q.done)y(G)},Y2=(G,Q)=>{let W=G.attempt;if(!W||Q.accountId===G.accountId)return;if(W.reboundFrom??=W.accountId,W.accountId=Q.accountId,"data"in Q)W.data=Q.data;G.accountId=Q.accountId},tZ=(G)=>!G.attempt||G.endError!==void 0||G.status!==void 0&&G.status>=400,eZ=(G)=>{let Q=[...j.values()].filter((D)=>D.scope.sessionID===G),W=Q.filter((D)=>D.limit&&!D.rerouted).at(-1);if(W)return W;let H=Q.filter((D)=>D.scope.kind==="primary"),x=H.length>0?H:Q;if(x.length<=1)return x[0];let q=x.filter((D)=>!D.judged&&tZ(D)).at(-1);if(q)return q;let O=x.filter((D)=>D.attempt&&!D.ended);if(O.length>1)return"ambiguous";return O[0]??x.at(-1)},K2={providerID:z},W2=[];W2.push(await $.session.hook("model.request",(G)=>{if(X)return;return f(j2(G),async(Q)=>{let W=await p(j2(G),"model.request",Q);if(Q(),W.accountId===void 0)throw s(W.scope);$1(G.headers,{...W.headers,[M2]:W.id})})},K2)),W2.push(await $.session.hook("http.request",(G)=>{if(X){let Q=Y(G.request.headers);if(_.set(G.sessionID,Q),!Q)return}return f(j2(G),async(Q)=>{let W=G.request.headers.get(M2)??void 0,H=X?await p(j2(G),"http.request",Q,"http"):await a(j2(G),"http.request","http",W,Q);Q();let x=c(H),q=H.attempt;if(!x||!q)throw s(H.scope);await U2(H,async()=>{let O=G.request;if(Z.rewriteRequest){if(W!==void 0){let G2=new Headers(O.headers);G2.delete(M2),O=new Request(O,{headers:G2})}O=await Z.rewriteRequest({...x,request:O,attempt:q})??O,Q()}let D=new Headers(O.headers);D.delete(M2),z0(D,H.headers),I(H.scope,D.entries());let i=new Request(O,{headers:D});B.set(i,H),G.request=i})})},K2)),W2.push(await $.session.hook("http.response",async(G)=>{let Q=B.get(G.request);if(!Q){if(X)return;if(!u)u=!0,h("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:G.sessionID,kind:G.kind});return}let W=G.response;if(Z.answeredBy&&Q.attempt){let D=Q.attempt,i=await U2(Q,async()=>Z.answeredBy?.({request:G.request,response:W,attempt:D}));if(i)Y2(Q,i)}let H=c(Q),x=Q.attempt;if(!H||!x)return;Q.status=W.status;let q=Z.quotaFromHeaders?.(W.headers,W.status,x);if(q!==void 0)M(Q,"http",q,W.status);if(!W.ok&&Z.limitFromResponse){let D=await Z.limitFromResponse({status:W.status,headers:W.headers,body:()=>W.clone().text(),attempt:x});if(D)F2(Q,D,"http")}if(!W.ok||!W.body)y(Q);let O=W;if(W.body&&(Z.inspectEvent||Z.onAttemptEnd)){let D=W.body;if(Z.inspectEvent)D=D.pipeThrough(e2((i)=>d(Q,"http",i.data,i.event),(i)=>h("opencode2 auth event inspection threw",{error:v(i)})));O=new Response(J0(D,(i)=>y(Q,i)),{status:W.status,statusText:W.statusText,headers:W.headers})}if(Z.rewriteResponse)O=await Z.rewriteResponse({...H,request:G.request,response:O,attempt:x})??O;if(O!==W)G.response=O},K2)),W2.push(await $.session.hook("experimental.ws.handshake",(G)=>{if(X){let Q=Y(new Headers(G.headers)),W=L2(G.sessionID,G.kind);if(_.set(G.sessionID,Q),S.delete(W),!Q)return}return f(j2(G),async(Q)=>{let W;for(let O of Object.keys(G.headers)){if(O.toLowerCase()!==M2)continue;W??=G.headers[O],delete G.headers[O]}let H=X?await p(j2(G),"experimental.ws.handshake",Q,"ws"):await a(j2(G),"experimental.ws.handshake","ws",W,Q);Q();let x=c(H),q=H.attempt;if(!x||!q)throw s(H.scope);await U2(H,async()=>{$1(G.headers,H.headers);let O=Z.rewriteHandshakeURL?.({...x,url:G.url,attempt:q});if(O!==void 0)G.url=O;if(I(H.scope,Object.entries(G.headers)),X)S.add(H.key)})})},K2));let O1=Z.rewriteWebSocketFrame?.bind(Z);if(O1)W2.push(await $.session.hook("experimental.ws.send",async(G)=>{let Q=j2(G);if(X&&!S.has(L2(Q.sessionID,Q.kind)))return;let W=T2(Q.sessionID,Q.kind),H=await O1({...Q,attempt:W?.attempt,frame:G.frame});if(H!==void 0)G.frame=H},K2));W2.push(await $.session.hook("experimental.ws.receive",(G)=>{if(X&&!S.has(L2(G.sessionID,G.kind)))return;let Q=T2(G.sessionID,G.kind);if(!Q)return;try{d(Q,"ws",G.frame)}catch(W){h("opencode2 auth frame inspection threw",{error:v(W)})}},K2)),W2.push(await $.session.hook("retry",async(G)=>{if(X&&_.get(G.sessionID)!==!0)return;let Q=eZ(G.sessionID);if(!Q)return;let W=G.decision;if(Q==="ambiguous"){await T("retry",{sessionID:G.sessionID,attempt:G.attempt,reason:"host-decides",hostDecision:W,decision:W});return}let H=Q;await f(H.scope,async(x)=>{let q=x;H.judged=!0;let O=H.attempt;if(O&&!H.outputStarted){if(!H.limit){let G2=Z.limitFromError?.(G.error,O);if(G2)F2(H,G2,"error")}if(H.ended)await H.ended;if(H.limit)await H.limit.delivered}q();let{decision:D,reason:i}=await P(H.scope.sessionID,async()=>{q();let G2=L.get(H.key);if(L.delete(H.key),G2?.next)await K(G2.next);q();let Z2=W,n,_2,t;if(H.accountId===void 0||!O)Z2={retry:!1},n="no-account";else if(H.outputStarted)Z2={retry:!1},n="output-started";else if(H.limit){let O2={accountId:H.accountId,limit:H.limit.signal},H2,w2={...H.scope,phase:"retry",previousAccountId:H.accountId,rerouteFrom:O2};try{H2=await Z.chooseAccount(w2)}catch(s2){h("opencode2 auth chooseAccount threw while the retry hook looked for another account; the host decides the retry",{sessionID:H.scope.sessionID,error:v(s2)})}if(H2!==void 0)t={accountId:H2,input:w2};try{q()}catch(s2){if(t)await K(t);throw s2}if(H2!==void 0&&H2!==H.accountId)H.rerouted=!0,_2=O2,Z2={retry:!0,delay:0},n="reroute";else n="host-decides-last-account"}else n="host-decides";if(G.decision=Z2,Z2.retry&&H.accountId!==void 0&&j.has(H.id))L.set(H.key,{attemptId:H.id,sessionID:H.scope.sessionID,accountId:H.accountId,..._2===void 0?{}:{rerouteFrom:_2},...t===void 0?{}:{next:t}});else if(t)await K(t);return{decision:Z2,reason:n}});q(),await T("retry",{sessionID:G.sessionID,...H.accountId===void 0?{}:{accountId:H.accountId},kind:H.scope.kind,attempt:G.attempt,reason:i,hostDecision:W,decision:D,...O===void 0?{}:{handle:O}})})},K2));let A1=(G)=>{l(G),_.delete(G);for(let Q of S)if(JSON.parse(Q)[0]===G)S.delete(Q);for(let Q of[...j.values()]){if(Q.scope.sessionID!==G)continue;b(Q,"its session was forgotten"),j.delete(Q.id)}for(let[Q,W]of L)if(W.sessionID===G)A(Q)},r2=new AbortController,R1=$.event;if(R1)(async()=>{try{for await(let G of R1.subscribe({signal:r2.signal}))if(G.type==="session.deleted")A1(G.data.sessionID)}catch(G){if(!r2.signal.aborted)h("opencode2 auth stopped listening for session deletion",{error:v(G)})}})();return{on(G,Q){let W=R.get(G);if(!W)W=new Set,R.set(G,W);let H=Q;return W.add(H),()=>{W.delete(H)}},accountFor(G,Q){return g(L2(G,Q))?.accountId},forgetSession:A1,get size(){return j.size},async dispose(){if(z2)return;z2=!0;for(let G of w.keys())l(G);r2.abort();for(let G of j.values())b(G,"the installation was disposed");j.clear();for(let G of L.keys())A(G);S.clear(),_.clear(),R.clear(),await Promise.all(V.values()),await Promise.all(W2.map(async(G)=>{try{await G.dispose()}catch(Q){h("opencode2 auth hook did not dispose cleanly",{error:v(Q)})}}))}}}import{createHash as G0}from"node:crypto";var X0=1024,Y0=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),b1=($)=>D1($,"user"),Q0=($)=>Y0($)&&($.role==="assistant"||typeof $.type==="string"&&$.type!=="message"&&$.type!=="configuration_update");function j0($){return G0("sha256").update(JSON.stringify($)).digest("hex")}class R2{runtime;maxSessions;#$=new Map;constructor($,Z=X0){this.runtime=$;this.maxSessions=Z}advance($,Z,J=this.runtime){let z=this.#$.get($),X=Array.isArray(Z.input)?Z.input:[],Y=X.filter(b1),F=X.findLastIndex(b1),N=F<0?void 0:j0(X[F]),U=typeof Z.previous_response_id==="string"&&Z.previous_response_id.length>0,j,B,L;if(U)j=Y.length>0,B=N??z?.fingerprint,L=z?.userCount===void 0?void 0:z.userCount+Y.length;else{B=N,L=Y.length;let _=F>=0&&F>X.findLastIndex(Q0),u=z!==void 0&&!z.completed&&z.fingerprint===B&&z.userCount===L;j=_&&!u}let S=j||!z?{turnID:(J?.uuid??P2)(),turnStartedAt:(J?.now??Date.now)()}:{turnID:z.turnID,turnStartedAt:z.turnStartedAt};return this.#Z($,{...S,completed:!1,fingerprint:B,userCount:L}),S}completed($){let Z=this.#$.get($);if(Z)this.#Z($,{...Z,completed:!0})}get($){return this.#$.get($)}forget($){this.#$.delete($)}#Z($,Z){this.#$.delete($),this.#$.set($,Z);while(this.#$.size>this.maxSessions){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function J1($,Z){return{threadID:$.threadID,windowID:$.windowID,turnID:Z.turnID,turnStartedAt:Z.turnStartedAt}}var k1=Symbol.for("@cortexkit/openai-auth/opencode2/codex-installation");function V0(){let $=globalThis;return $[k1]??=crypto.randomUUID(),$[k1]}class S2{runtime;store;sessions;frameTurns;installationID;constructor($,Z,J){this.runtime=$;this.store=J;this.installationID=Z??V0(),this.sessions=J?.sessions??new Map,this.frameTurns=J?.frameTurns??new R2}get($){let Z=this.runtime?.uuid??P2;if(this.store)return this.store.get($,Z);let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J)}return J}advanceFrame($,Z){return this.frameTurns.advance($,Z,this.runtime)}frameReceived($,Z){if(!Z.includes("response.completed"))return;if(y2(Z)?.type==="response.completed")this.frameTurns.completed($)}forget($){if(this.store)this.store.delete($);else this.sessions.delete($),this.frameTurns.forget($)}}var z1={version:w1,"user-agent":y1,originator:"codex_exec"};var B0=1024,U0=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,I2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),v1=($)=>I2($)&&($.type==="message"||("role"in $))&&$.role==="user",h1=($)=>I2($)&&$.type==="configuration_update";class G1{http;#$=new Map;constructor($=new S2){this.http=$}apply($,Z,J){if(Z.kind!=="primary")return!1;let z=typeof $.model==="string"?$.model:"";if(!f1.has(z))return!1;if(U0.test(z))return!1;let X=I2($.reasoning)?$.reasoning:void 0,Y=typeof X?.effort==="string"?X.effort:void 0;if(!Y)return!1;let F=this.#$.get(Z.sessionID);if(F===void 0)return this.#Z(Z.sessionID,Y),!1;if(Y===F)return!1;let N=Array.isArray($.input)?$.input:void 0;if(!N||N.length===0)return!1;let U=N.findLastIndex(v1);if(U<0){if(J==="http")return!1;return $.reasoning={...X,effort:F},!0}if($.reasoning={...X,effort:F},!h1(N[U-1]))N.splice(U,0,{type:"configuration_update",reasoning:{effort:Y}});return!0}forget($){this.#$.delete($),this.http.forget($)}#Z($,Z){this.#$.set($,Z);while(this.#$.size>B0){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function y2($){try{let Z=JSON.parse($);return I2(Z)?Z:void 0}catch{return}}async function m1($,Z,J,z,X=J.http){if($.method.toUpperCase()!=="POST")return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let Y=await $.clone().text(),F=y2(Y);if(F)delete F.max_output_tokens;let N=new Headers($.headers),U=f2({rewriteLite:I1,init:{body:F?JSON.stringify(F):$.body===null?void 0:Y},headers:N,metadata:X.get(Z.sessionID),installationID:X.installationID,runtime:X.runtime,websocket:!1,responsesLite:z,applyEffort:(j)=>{J.apply(j,Z,"http")}});return new Request($,{headers:N,body:U.init?.body})}function g1($,Z,J,z){let X=z.sessions.get($.sessionID),Y=z.frameTurns.get($.sessionID);if(!X||!Y)return;let F=J1(X,Y),N=new Headers({"content-type":"application/json"});for(let j of["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"]){let B=J.get(j);if(B!==null)N.set(j,B)}f2({init:{body:$.bodyText},headers:N,metadata:F,installationID:z.installationID,runtime:z.runtime,websocket:!1,skipTurnUpdate:!0,responsesLite:!1,rewriteLite:()=>{}});let U=new URL(Z);if(U.protocol==="wss:")U.protocol="https:";if(U.protocol==="ws:")U.protocol="http:";return new Request(U,{method:"POST",headers:N,body:$.bodyText})}function W0($,Z){if(JSON.stringify($)===JSON.stringify(Z))return!0;if(!Array.isArray($)||!Array.isArray(Z)||Z.length!==$.length+1)return!1;let J=Z.findIndex((z,X)=>JSON.stringify(z)!==JSON.stringify($[X]));return J>=0&&h1(Z[J])&&v1(Z[J+1])&&JSON.stringify(Z.slice(J+1))===JSON.stringify($.slice(J))}function l1($,Z,J){let z=y2($);if(z?.type!=="response.create")return;let X=J.http.advanceFrame(Z.sessionID,z),Y=J.http.get(Z.sessionID);delete z.max_output_tokens;let F=f2({rewriteLite:()=>{},init:{body:JSON.stringify(z)},headers:new Headers,metadata:J1(Y,X),installationID:J.http.installationID,runtime:J.http.runtime,websocket:!0,responsesLite:!1,applyEffort:(U)=>{J.apply(U,Z,"ws")}}),N=y2(String(F.init?.body));if(!N)return;if(!W0(z.input,N.input)){if("input"in z)N.input=z.input;else delete N.input;return JSON.stringify(N)}return String(F.init?.body)}function H0($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function X1($,Z){let J=new URL($);if(J.origin!=="https://api.openai.com"&&J.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(J.pathname))return $;let z=new URL(`${H0(Z)}/responses`);if(z.search=J.search,J.protocol==="ws:"||J.protocol==="wss:")z.protocol=z.protocol==="https:"?"wss:":"ws:";return z.href}import{resolve as u1}from"node:path";var N0=1024;class v2{accounts=new Map;limit;constructor($=N0){this.limit=Math.max(1,$)}record($,Z){this.accounts.delete($),this.accounts.set($,Z);while(this.accounts.size>this.limit){let J=this.accounts.keys().next().value;if(J===void 0)break;this.accounts.delete(J)}}activeAccount($){return this.accounts.get($)}forget($){this.accounts.delete($)}get size(){return this.accounts.size}}var p1=Symbol.for("@cortexkit/openai-auth/opencode2-session-accounts"),c1=globalThis,Y1=c1[p1]??new Map;c1[p1]=Y1;function Q1($){let Z=JSON.stringify([u1($.configPath),u1($.statePath)]),J=Y1.get(Z);if(!J)J=new v2,Y1.set(Z,J);return J}var X2="openai",F0=60000,j1=1,K0="request refused: no account with a usable credential",V2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function L0($){let Z=V2($)?$.counters:void 0,J=V2(Z)?Z.resetCredits:void 0,z=V2(J)?J.value:void 0;return typeof z==="number"&&Number.isFinite(z)?z:void 0}function B1($){try{return JSON.parse($)}catch{return}}function d1($){let Z=m2($);return Z?g2(Z):void 0}var P0=new Set(["usage_limit_reached","rate_limit_exceeded"]);function U1($,Z,J){return{reason:$.window,...J!==void 0?{status:J}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-Z)}:{}}}function T0($,Z){let J=h2($);if(J){let Y=typeof $.status==="number"?$.status:void 0;return U1(J,Z,Y)}if($.type!=="response.failed"||!V2($.response))return;let z=$.response.failed;if(V2(z)&&typeof z.rate_limit_reached_type==="string")return{reason:z.rate_limit_reached_type};let X=$.response.error;if(V2(X)){let Y=typeof X.code==="string"?X.code:typeof X.type==="string"?X.type:void 0;if(Y&&P0.has(Y))return{reason:Y}}return}function _0($,Z){let J=B1($);if(!V2(J))return;let z=typeof J.type==="string"?J.type:void 0;if(z==="codex.rate_limits")return{quota:{snapshot:o1(J),complete:!0}};let X=T0(J,Z);if(X)return{limit:X};if(z===void 0||z==="error")return;return U$(z)?void 0:{outputStarted:!0}}function M0($){let Z=!1;for(let J of $.keys())if(J.toLowerCase().startsWith("x-codex-")){Z=!0;break}if(!Z)return;return{snapshot:a1($),complete:n1($)}}function C0($){let Z=$.get("retry-after");if(Z===null)return;let J=Number(Z);return Number.isFinite(J)&&J>=0?J*1000:void 0}function W$($){let{source:Z,pins:J}=$,z=$.now??Date.now,X=$.log,Y=$.vault,F=new G1($.codex),N=new Map,U=new Map,j=(V)=>`${V.sessionID}\x00${V.kind}\x00${V.accountId}`,B=new Map,L=$.sessionAccounts??new v2,S=new Y$,_=(V,P,E)=>{let K=E?[]:B$(Z.peek().rows,V,P,Y?.identities()??new Set),A=(Y?.routes()??[]).filter((T)=>T.kind==="oauth"&&s1(x2(T.quota),V,P));return[...K.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota,row:T})),...A.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota}))]},u=(V,P,E)=>{let K=z$(V,P,E),A=V.map((b)=>({id:b.id,kind:"oauth",...i1(b.quota)?{quota:b.quota}:{}})),T=V.flatMap((b)=>b.row?[b.row]:[]),C=new Set(V.filter((b)=>!b.row).map((b)=>b.id)),y=Z.rateLimitMarks(T);for(let b of C){let m=B.get(b);if(m===void 0)continue;if(m<=E)B.delete(b);else y.set(b,m)}return{rows:A,now:E,rateLimitMarks:y,refreshBackoff:Z.refreshBackoffFor(T),killswitch:K,requestPull:(b)=>C.has(b)?Y?.requestReading(b):Z.requestReading(b)}},o=(V,P,E,K,A)=>{let T=Q$({...V,placement:G$(P),mainId:A});if(T.kind==="block"){X?.debug("pool admission refused the request",{reason:T.block.reason});return}let C=T.order.filter((y)=>!E.has(y));if(K!==void 0&&C.includes(K))return K;return C[0]},R=(V,P,E,K,A,T,C)=>{let y=new Map(P.map((l)=>[l.id,l.quota])),b={requestBytes:j1,reservePercent:(l)=>t1(E,l===Z$?void 0:l),resetCredits:(l)=>L0(y.get(l))},m=V1(V),g=(l,f)=>l2(C,{sessionId:K,requestBytes:j1,validPinnedAccountIds:V.rows.map((I)=>I.id).filter((I)=>!m.excluded.has(I)),excludeAccountIds:l,quotaCheckedAtByAccount:Object.fromEntries(V.rows.map((I)=>[I.id,m.projections.get(I.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(P.map((I)=>[I.id,I.identity])),select:(I)=>j$(V,b,new Set(l),I),persist:f},(I,$2)=>C.set(I,$2)),r=[...A],e=g(r,T);if(!e)return;let c=e.accountId,s=V$(V,b,c);if(s.kind==="none")return;if(s.kind==="move"){let l=g([...r,c],T);if(l)return l.accountId;return s.reason==="killswitch"?void 0:c}if(s.kind==="detour")return g([...r,c],!1)?.accountId;return c},w={providerID:X2,dropChoice(V){let P=j(V);U.get(P)?.drop(),U.delete(P),N.delete(P)},chooseAccount:async(V)=>{let P=await Y?.authority(),E=await $.storage(),K=P!==void 0&&P!=="local",A=()=>{throw new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:u2})};if(K)await $.awaitVaultRoster?.();else{if(!(await Z.current()).active){if(await $.slotPlaceholderWithoutMain?.())A();X?.warn("the account pool does not serve requests yet; refusing the request",{kind:V.kind});return}await Z.prepareTokens(Z.peek().rows,E)}let T=z(),C=_(E,T,K),y=X$(u(C.filter((I)=>I.id!==V.rerouteFrom?.accountId),E,T));if(y)await y,T=z(),C=_(E,T,K);let b=new Map(C.map((I)=>[I.id,I])),m=u(C,E,T),g=new Set(V.rerouteFrom?[V.rerouteFrom.accountId]:[]),r=E?.routing?.mode??"main-first",e=V.kind==="primary",c=new Set,s,l,f;try{for(;;){let I=new Set([...g,...c]);if(f=void 0,s=void 0,r==="sticky-balanced"){let p=new Map(J.placementSnapshot(V.sessionID)),a=p.get(V.sessionID);if(f=R(m,C,E,V.sessionID,I,e&&c.size===0,p),f!==void 0&&p.get(V.sessionID)!==a)s=p.get(V.sessionID)}if(f??=o(m,r,I,e?void 0:L.activeAccount(V.sessionID),K?r==="sticky-balanced"?null:J$(Y?.routes()??[]):void 0),f===void 0||c.has(f)){if(g.size>0){let p=new Map(m.rateLimitMarks);for(let a of g)p.delete(a);m={...m,rateLimitMarks:p},g.clear();continue}f=void 0;break}if(e&&r==="sticky-balanced"){let p=V1(m).projections.get(f)?.checkedAt,a=b.get(f)?.identity;l=J.reserve(V.sessionID,{accountId:f,inputBytes:j1,...p!==void 0?{quotaCheckedAt:p}:{},...a!==void 0?{wireIdentity:a}:{}})}let $2=b.get(f)?.row;if($2){if(Z.usableToken($2)!==void 0)break;X?.debug("pool row holds no usable token; choosing again",{accountId:f})}else{if(!Y)break;let p=await Y.authorize(f);if(p){N.set(j({...V,accountId:f}),p);break}X?.debug("the vault refused to serve an account; choosing again",{accountId:f})}if(l)J.rollback(l);l=void 0,c.add(f)}if(f===void 0&&!K&&C.length===0&&await $.slotPlaceholderWithoutMain?.())A();if(f===void 0&&K&&Y&&(C.length===0||c.size>0)){let I=c.size>0?"vault-refused":$$(Y);throw X?.warn("vault mode: no vault account can serve; refusing the request",{cause:I}),new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:e1(I,Y.name)})}if(f!==void 0){let I=f,$2=l,p=s,a=()=>{if($2)J.finish($2,p);if(e)L.record(V.sessionID,I),$.onRoute?.(V.sessionID,I,r)};if(V.phase==="retry")U.set(j({...V,accountId:f}),{commit:a,drop:()=>{if($2)J.rollback($2)}}),l=void 0;else a();let U2=X?.info;S.served(m,f,X&&U2?{info:(T2,F2)=>U2.call(X,T2,F2)}:void 0)}return X?.debug("pool account chosen",{kind:V.kind,accountId:f,mode:r,...V.rerouteFrom?{rerouteFrom:V.rerouteFrom.accountId}:{}}),f}finally{if(l)J.rollback(l)}},accountHeaders:async(V)=>{let{accountId:P}=V,E=j(V),K=U.get(E);U.delete(E);let A=()=>{K?.commit()};try{let T=()=>new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:K0}),C=Y&&await Y.authority()!=="local"?void 0:Z.peek().rows.find((m)=>m.id===P);if(!C&&Y){let m=j(V),g=N.get(m)??await Y.authorize(P);if(N.delete(m),!g)throw X?.warn("the vault refused to serve an account; refusing the request",{accountId:P}),T();return A(),{headers:{...z1,"session-id":V.sessionID,authorization:`Bearer ${g.accessToken}`,"chatgpt-account-id":g.accountIdentity??d1(g.accessToken)??null},attempt:{kind:"vault",routeId:P,receipt:g}}}let y=C?Z.usableToken(C):void 0;if(!C||!y)throw X?.warn("pool row holds no usable token; refusing the request",{accountId:P}),T();let b=C.identity??d1(y);return A(),{headers:{...z1,"session-id":V.sessionID,authorization:`Bearer ${y}`,"chatgpt-account-id":b??null},attempt:{kind:"pool",token:y,credentialEpoch:C.credentialEpoch}}}finally{K?.drop()}},async rewriteRequest({request:V,sessionID:P,kind:E}){let K=$.codexEndpoint?X1(V.url,$.codexEndpoint()):V.url,A=K===V.url?V:new Request(K,V);return await m1(A,{sessionID:P,kind:E},F,$.responsesLite?.()??!1)??A},rewriteHandshakeURL:({url:V})=>$.codexEndpoint?X1(V,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:V,sessionID:P,kind:E})=>l1(V,{sessionID:P,kind:E},F),quotaFromHeaders:(V)=>M0(V),async limitFromResponse({status:V,headers:P,body:E}){if(V<400)return;let K=B1(await E().catch(()=>"")),A=h2({...V2(K)?K:{},status:V});if(!A)return;let T=z(),C=U1(A,T,V);if(C.retryAfterMs!==void 0)return C;let y=C0(P);return y===void 0?C:{...C,retryAfterMs:y}},inspectEvent:({data:V})=>_0(V,z()),limitFromError(V){let P=B1(V.message),E=h2({...V2(P)?P:{},...V.status!==void 0?{status:V.status}:{}})??(V.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return E?U1(E,z(),V.status):void 0},async onAttemptEnd(V,P){let E=V.data;if(E?.kind!=="vault"||P.status!==401)return;X?.warn("a vault account answered 401; reporting it to the vault",{accountId:V.accountId}),await Y?.reportFailure(E.receipt,401)}},h=(V,P,E)=>{let K=E.data;if(K?.kind==="vault"){Y?.recordSnapshot(V,P.snapshot,P.complete,K.receipt);return}if(K?.kind!=="pool")return;if(Z.peek().rows.find((T)=>T.id===V)?.credentialEpoch!==K.credentialEpoch){X?.debug("quota reading dropped: the row holds another credential",{accountId:V});return}Z.recordSnapshot(V,P.snapshot,K.token,P.complete)},v=(V,P,E)=>{let K=z(),A=E.data?.kind==="vault",T=A?Y?.routes().find((b)=>b.id===V)?.quota:Z.peek().rows.find((b)=>b.id===V)?.quota,C=r1(x2(T),P.reason,K,F0,P.retryAfterMs!==void 0?K+P.retryAfterMs:void 0);if(!A){Z.markRateLimited(V,C);return}let y=B.get(V);if(y===void 0||y<C)B.set(V,C)};return{adapter:w,attach(V){V.on("quota",(P)=>h(P.accountId,P.quota,P.handle)),V.on("limit",(P)=>{v(P.accountId,P.limit,P.handle),X?.debug("pool row refused the request",{accountId:P.accountId,via:P.via,reason:P.limit.reason,outputStarted:P.outputStarted})})},forgetSession(V){J.forget(V),L.forget(V),F.forget(V)},activeAccount:(V)=>L.activeAccount(V)}}import{resolve as P$}from"node:path";import{Buffer as E0}from"node:buffer";import{resolve as H$}from"node:path";function q2($){return E0.byteLength(JSON.stringify($))}function O0($){return $.reduce((Z,J)=>Z+q2(J),0)}function W1($,Z){return 2+$+Math.max(0,Z-1)}function A0($){let{head:Z,pending:J}=$;return 10+$.fieldsBytes+1+(Z?22+Z.responseIDBytes+9+W1(Z.inputBytes,Z.input.length)+1:0)+(J?20+W1(J.inputBytes,J.input.length)+10+W1(J.outputBytes,J.output.length)+(J.responseID===void 0?0:14+J.responseIDBytes)+1:0)}function N$($){try{let Z=JSON.parse($);if(Z&&typeof Z==="object"&&!Array.isArray(Z))return Z}catch{}return}class F${enabled;caps=p2;entries=new Map;bytes=0;constructor($=!1){this.enabled=$}setEnabled($){if(this.enabled=$,!$)this.entries.clear(),this.bytes=0}send($,Z){if(!this.enabled)return;let J=N$(Z);if(J?.type!=="response.create")return;if(!Array.isArray(J.input)){this.forget($);return}let z=J.previous_response_id,X=this.entries.get($),Y=X?.head;if(z&&z!==Y?.responseID){this.forget($);return}let{type:F,previous_response_id:N,input:U,...j}=J;this.keep($,{fields:z&&X?X.fields:j,fieldsBytes:z&&X?X.fieldsBytes:q2(j),...z&&Y?{head:Y}:{},pending:{input:U,inputBytes:O0(U),output:[],outputBytes:0,responseIDBytes:0},bytes:0})}receive($,Z,J){if(!this.enabled||!Z.includes("response.created")&&!Z.includes("response.output_item.done")&&!Z.includes("response.completed"))return;let z=this.entries.get($);if(!z?.pending)return;let X=N$(Z);if(!X)return;let Y=z.pending,F=X.response;if(X.type==="response.created"&&typeof F?.id==="string")Y.responseID=F.id,Y.responseIDBytes=q2(F.id),this.keep($,z);else if(X.type==="response.output_item.done"&&X.item){if(typeof X.response_id==="string"&&Y.responseID!==void 0&&X.response_id!==Y.responseID)return;Y.output.push(X.item),Y.outputBytes+=q2(X.item),this.keep($,z)}else if(X.type==="response.completed"&&typeof F?.id==="string"){if(F.id===z.head?.responseID||Y.responseID!==void 0&&F.id!==Y.responseID)return;let N={responseID:F.id,responseIDBytes:Y.responseID===F.id?Y.responseIDBytes:q2(F.id),input:[...z.head?.input??[],...Y.input,...Y.output],inputBytes:(z.head?.inputBytes??0)+Y.inputBytes+Y.outputBytes},U={...z,head:N,pending:void 0};if(!this.keep($,U))return;J?.({sessionID:$,responseID:N.responseID,bodyText:this.body(z.fields,N)})}}replay($){let Z=this.entries.get($);if(!Z?.head)return;return this.entries.delete($),this.entries.set($,Z),this.body(Z.fields,Z.head)}forget($){let Z=this.entries.get($);if(Z)this.bytes-=Z.bytes;this.entries.delete($)}status(){return{bytes:this.bytes,sessions:[...this.entries].map(([$,Z])=>({sessionID:$,bytes:Z.bytes,responseID:Z.head?.responseID,pending:Z.pending!==void 0}))}}body($,Z){return JSON.stringify({...$,input:Z.input,stream:!0})}keep($,Z){let J=A0(Z);if(this.forget($),J>this.caps.maxBytes)return!1;Z.bytes=J,this.entries.set($,Z),this.bytes+=J;while(this.entries.size>this.caps.maxTargets||this.bytes>this.caps.maxBytes){let z=this.entries.keys().next().value;if(z===void 0)break;this.forget(z)}return this.entries.has($)}}var K$=Symbol.for("@cortexkit/openai-auth/opencode2-frame-mirror"),L$=globalThis,H1=L$[K$]??new Map;L$[K$]=H1;function c2($){let Z=JSON.stringify([H$($.configPath),H$($.statePath)]),J=H1.get(Z);if(!J)J=new F$,H1.set(Z,J);return J}var R0=5000,S0=["accept","originator","session-id","thread-id","user-agent","version","x-client-request-id","x-codex-beta-features","x-codex-turn-metadata","x-codex-window-id","x-openai-internal-codex-responses-lite","x-opencode-parent-session-id","x-parent-session-id"],x0=["x-opencode-parent-session-id","x-parent-session-id"];function C$($){let Z=T$($);return{enabled:Z?.enabled===!0,subagents:Z?.subagents===!0,sustain:Z?.sustain===!0,window:_$($?{...$,cachekeep:Z}:$)}}var E$=Symbol.for("@cortexkit/openai-auth/opencode2-cache-keep"),O$=globalThis,b2=O$[E$]??new Map;O$[E$]=b2;function q0($,Z){let J=[],z=()=>J.at(-1)?.location,X=()=>{let U=z();if(!U)throw Error("no location holds keep-warm");return U},Y=(U,j)=>{N.remove(U),z()?.log?.debug(`cachekeep dropped target (${j})`,{sessionKey:U})},F=async(U)=>{if(U.meta.credentialMode!=="local")throw Error("a target captured in vault mode is not warmed with a local credential");let j=U.accountId??"main",B=X(),L=await B.source.accessFor(j,await B.storage());if(!L)throw Error(`pool row ${j} has no usable token`);return{token:L.token,identity:L.row.identity}},N=M$({...p2,now:$.now,...$.setIntervalImpl?{setIntervalImpl:$.setIntervalImpl}:{},...$.clearIntervalImpl?{clearIntervalImpl:$.clearIntervalImpl}:{},codexResponsesUrl:$.codexResponsesUrl,fetchImpl:(U,j)=>X().fetch(U,j),logger:{debug:(U,j)=>z()?.log?.debug(U,j),warn:(U,j)=>z()?.log?.warn(U,j)},getWindow:()=>z()?.settings().window,getSustain:()=>z()?.settings().sustain===!0,resolveLocal:F,vault:{owns:(U)=>z()?.vault.owns(U)===!0,authority:()=>X().vault.authority(),send:async(U,j,B)=>{let L=X();if(await L.vault.authority()!=="vault")return;return L.vault.send(U,j,B)}},activeAccount:(U)=>{if(U===void 0)throw Error("target has no session");let j=z(),B=j?.settings();if(!j||!B?.enabled){Y(U,"keep-warm is off");return}if(!B.subagents&&N.status().targets.some((S)=>S.sessionKey===U&&S.isSubagent)){Y(U,"subagent warming is off");return}let L=j.accounts.activeAccount(U);if(L===void 0){Y(U,"no account recorded for the session");return}return L},verifyCredential:({target:U,mode:j,identity:B})=>{if(U.meta.credentialMode!==j)throw Error(`a target captured in ${U.meta.credentialMode??"an unknown"} mode is not warmed with a ${j} credential`);if(B!==U.meta.chatgptAccountId)throw Y(U.sessionKey,"the account signs in as another login now"),Error("the account signs in as another login now")}});return{manager:N,settings:Z,holders:J,joinTimeoutMs:$.joinTimeoutMs??R0}}function b0($){try{let Z=JSON.parse($),J=Array.isArray(Z.input)?Z.input.at(-1):void 0;if(J?.role!=="user")return!1;return(typeof J.content==="string"?J.content:Array.isArray(J.content)?J.content.map((X)=>typeof X?.text==="string"?X.text:"").join(""):"").startsWith("This is a keep-alive request.")}catch{return!1}}function D0($){let Z={};for(let J of S0){let z=$.get(J);if(z)Z[J]=z}return Z}function A$($,Z,J){let z=JSON.stringify([P$($.configPath),P$($.statePath)]),X=b2.get(z);if(!X)X=q0(J,Z.settings()),b2.set(z,X);let Y=X,F=c2($);F.setEnabled(Y.settings.enabled);let N={location:{...Z,settings:()=>Y.settings}};Y.holders.push(N);let U=!1,j=async(B)=>{try{let L=N.location.settings();if(U||!L.enabled)return;if(B.kind!=="primary"){if(B.kind==="generate"&&b0(await B.request.clone().text())){if(U)return;Y.manager.remove(B.sessionID)}return}let S=B.attempt.data,_=S?.kind==="pool"?"local":S?.kind==="vault"?"vault":void 0;if(!_)return;let u=B.request.headers,o=x0.some((z2)=>u.has(z2))||Z.parentOf!==void 0&&await Z.parentOf(B.sessionID)!==void 0;if(o&&!L.subagents)return;let R=await B.request.clone().text();if(U)return;let k=u.get("chatgpt-account-id")??void 0;Y.manager.track({sessionKey:B.sessionID,bodyText:R,accountId:B.attempt.accountId,isSubagent:o,meta:{replayHeaders:D0(u),...k?{chatgptAccountId:k}:{},routingSessionId:B.sessionID,url:B.request.url,credentialMode:_}})}catch(L){Z.log?.warn("cachekeep capture failed",{error:L instanceof Error?L.message:String(L)})}};return{manager:Y.manager,configure:(B)=>{Object.assign(Y.settings,B),F.setEnabled(Y.settings.enabled)},capture:j,forget:(B)=>Y.manager.remove(B),async release(){if(U)return;U=!0;let B=Y.holders.indexOf(N);if(B>=0)Y.holders.splice(B,1);if(Y.holders.length>0)return;if(b2.get(z)===Y)b2.delete(z);Y.manager.stop();let L;try{await Promise.race([Y.manager.tick().catch(()=>{}),new Promise((S)=>{L=setTimeout(S,Y.joinTimeoutMs),L.unref?.()})])}finally{clearTimeout(L)}}}}import{mkdirSync as k0}from"node:fs";import{dirname as w0,join as y0,resolve as f0}from"node:path";var I0="openai-auth-sessions-opencode2.json";function v0(){return y0(S$(),I0)}var h0="sessions",m0=1e4,g0=5000,l0=25;class D${path;options;sessions;frameTurns=new R2;#$=new Set;#Z=new Set;#J=Promise.resolve();#z=!1;constructor($,Z={}){this.path=$;this.options=Z;this.sessions=q$($,Z.uuid??P2)}get($,Z=P2){let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J),this.#Z.delete($),this.#$.add($),this.save()}return J}delete($){this.sessions.delete($),this.frameTurns.forget($),this.#$.delete($),this.#Z.add($),this.save()}save(){if(!this.#z)this.#z=!0,this.#J=this.#J.then(()=>{return this.#z=!1,this.#G()});return this.#J}settled(){return this.#J}async#G(){if(this.#$.size===0&&this.#Z.size===0)return;let $=[...this.#$].flatMap((z)=>{let X=this.sessions.get(z);return X?[[z,X]]:[]}),Z=[...this.#Z],J=null;try{if(k0(w0(this.path),{recursive:!0}),J=await this.#X(),!J)return;let z;try{z=x$(this.path)}catch{z=new Map}await this.options.afterRead?.();for(let X of Z)z.delete(X);for(let[X,Y]of $)z.set(X,Y.threadID);b$(this.path,z)}catch{return}finally{await J?.release().catch(()=>{})}for(let[z,X]of $)if(this.sessions.get(z)===X)this.#$.delete(z);for(let z of Z)if(!this.sessions.has(z))this.#Z.delete(z)}async#X(){let $=performance.now()+(this.options.lockWaitMs??g0);for(;;){let Z=await R$({name:h0,path:this.path,ttlMs:m0});if(Z||performance.now()>=$)return Z;await new Promise((J)=>setTimeout(J,l0))}}}var k$=Symbol.for("@cortexkit/openai-auth/opencode2-codex-sessions"),w$=globalThis,N1=w$[k$]??new Map;w$[k$]=N1;function y$($=v0()){let Z=f0($),J=N1.get(Z);if(!J)J=new D$(Z),N1.set(Z,J);return J}var f$=Symbol.for("cortexkit.openai-auth.v2.commands");function u0(){let $=globalThis;return $[f$]??={locations:new Map},$[f$]}async function p$($,Z){let J=u0(),z=$.location.directory,X={menu:Z,session:$.session},Y=await v$(z),F=await I$(l$,Y.dir,()=>u$({...Y,drain:m$,apply:(B)=>{let L=J.locations.get(z);if(!L)throw Error("The OpenAI menu location was closed");return L.menu.apply(B)}})),N=J.locations.get(z);J.locations.set(z,X),await N?.registration?.dispose(),J.command??={name:"openai",description:"OpenAI account menu",async execute(B){let L=J.locations.values().next().value?.session;if(!L)return;let S=await L.get({sessionID:B.sessionID}),_=J.locations.get(S.location.directory);if(!_||!g$(B.sessionID))return;let u=await _.menu.open(B.sessionID);h$(u,B.sessionID)}};let U=J.command;try{X.registration=await $.command.transform((B)=>{B.add(U)})}catch(B){if(J.locations.get(z)===X)J.locations.delete(z);throw await F.release(),B}let j=!1;return async()=>{if(j)return;if(j=!0,J.locations.get(z)===X)J.locations.delete(z);await F.release(),await X.registration?.dispose()}}var p0="openai-auth-pool-browser",c0="openai-auth-pool-headless",d0="openai-auth-vault",i0="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function D2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function o$($){return{method:{id:d0,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await c$($.paths,$.name)!=="vault")throw Error(i0)}}}function r$($){let Z=(J,z,X)=>({method:{id:J,type:"oauth",label:z},async authorize(){if($.vault)await D2($.vault);let Y=await $.beginLogin({version:$.version,headless:X});return{url:Y.url,instructions:Y.instructions,mode:"auto",callback:Y.completion}}});return[Z(p0,"ChatGPT (openai-auth pool, browser)",!1),Z(c0,"ChatGPT (openai-auth pool, headless)",!0)]}function F1($){let Z=(J)=>typeof J==="string"?J:"";return A2({type:"oauth",access:Z($.access),refresh:Z($.refresh)})||$.refresh===a$||d$($)}function a0($){if($.accountId)return $.accountId;let Z=$.access?m2($.access):void 0;return Z?g2(Z):void 0}async function s$($,Z,J,z={}){if(z.vault)await D2(z.vault);if(F1(J))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let X=i$($,{rowLocks:(_)=>n$(Z,_)}),Y=await X.read();if(Y.status!=="ready")throw Error(`the account pool cannot be read (${Y.status}); the login was not stored`);let F={type:"oauth",refresh:J.refresh,...J.access!==void 0?{access:J.access}:{},...J.expires!==void 0?{expires:J.expires}:{}},N=a0(J);if(z.vault)await D2(z.vault);let U=N!==void 0?{identity:N}:{};if(z.origin==="import"){let _=Y.rows.find((u)=>N!==void 0&&u.identity===N||u.credential?.type==="oauth"&&u.credential.refresh===J.refresh);if(_)return{id:_.id,operation:"kept"}}let j=Y.rows.filter((_)=>_.type==="oauth"&&!_.invalid),B=N?j.find((_)=>_.identity===N):void 0,L=Y.rows.find((_)=>_.id===d2);if(B)return{id:(await X.replace(B.id,F,U)).id,operation:"replaced"};if(!L){let _=await X.add({id:d2,credential:F,...U,...J.label!==void 0?{label:J.label}:{}});return{id:_.id,operation:_.outcome==="added-disabled"?"added-disabled":"added"}}if(!L.invalid&&!L.credential)return{id:(await X.replace(d2,F,U)).id,operation:"replaced"};let S=await X.add({id:J.id,credential:F,...U,...J.label!==void 0?{label:J.label}:{}});return{id:S.id,operation:S.outcome==="added-disabled"?"added-disabled":S.outcome==="rotated"?"replaced":"added"}}function n0($){let Z=$.itemId!==void 0;switch($.sectionId){case"accounts":return Z?["enable","disable","remove","move"].includes($.actionId):$.actionId==="add";case"routing":return!Z&&["order","mode"].includes($.actionId);case"quota":return $.actionId==="check";case"limits":return Z?$.actionId==="floors":$.actionId==="killswitch";case"session":return!Z&&$.actionId==="clear-pin";case"diagnostics":return!Z&&["logging","dump"].includes($.actionId);case"cache":return!Z&&["enabled","subagents","sustain","window"].includes($.actionId);case"reset":return Z&&["preview","spend","retry"].includes($.actionId);default:return!1}}function $Z($){let Z={...$,allowAction:n0,unavailableSections:[]};return{open:(J)=>t$(Z,J),apply:(J)=>{let z=J!==null&&typeof J==="object"?J:{},X=z.values&&typeof z.values==="object"&&!Array.isArray(z.values)?Object.fromEntries(Object.entries(z.values).filter(([,Y])=>Y===null||["string","number","boolean"].includes(typeof Y))):void 0;return e$(Z,{command:"openai",sectionId:typeof z.sectionId==="string"?z.sectionId:"",actionId:typeof z.actionId==="string"?z.actionId:"",...X?{values:X}:{},...z.confirmed===!0?{confirmed:!0}:{},...typeof z.itemId==="string"?{itemId:z.itemId}:{},...typeof z.sessionId==="string"?{sessionId:z.sessionId}:{}})}}}function o0($){if(!ZZ($.modelID??$.id)){$.enabled=!1;return}let Z=JZ($.id);if(Z)$.limit={...Z}}function zZ($){return $.model.transform((Z)=>{for(let J of Z.list(X2))Z.update(X2,String(J.id),(z)=>o0(z))})}class K1{log;pending=new Map;requests=new Map;writing=new Set;constructor($){this.log=$}async safely($){let Z=(async()=>{try{await $()}catch{this.log.warn("request dump failed")}})();this.writing.add(Z);try{await Z}finally{this.writing.delete(Z)}}async captureHttp($,Z){await this.safely(async()=>{if(!C2().dump)return;let J={sessionID:Z.sessionID,accountId:Z.accountId,transport:"http",phase:"http",url:$.url,method:$.method,headers:new Headers($.headers),bodyText:await $.clone().text()};if(this.pending.set($,{attemptId:Z.attemptId,input:J}),this.requests.set(Z.attemptId,$),this.pending.size>512){let z=this.pending.keys().next().value;if(z)this.take(z)}})}take($){let Z=this.pending.get($);if(Z)this.pending.delete($),this.requests.delete(Z.attemptId);return Z?.input}async response($,Z){let J=this.take($);if(J)await this.safely(()=>i2({...J,status:Z}))}async end($,Z){if(Z.status!==void 0||!Z.error)return;let J=this.requests.get($.attemptId),z=J&&this.take(J);if(!z)return;let{reason:X,message:Y}=Z.error,F=Y?`${X}: ${Y}`:X;await this.safely(()=>i2({...z,error:a2(F,J?.headers.get("authorization")?.replace(/^Bearer /,""))}))}async frame($,Z){await this.safely(()=>i2({sessionID:Z.sessionID,accountId:Z.accountId,transport:"websocket",phase:"observed",bodyText:$}))}clear(){this.pending.clear(),this.requests.clear()}async settle(){await Promise.all(this.writing)}}class L1{counts=new Map;record($,Z){let J=Z.resetCreditsApplicable;this.counts.set($.id,{credentialEpoch:$.credentialEpoch,identity:$.identity,applicable:typeof J==="number"&&Number.isFinite(J)?J:void 0})}applicable($){let Z=this.counts.get($.id);if(!Z||Z.credentialEpoch!==$.credentialEpoch||Z.identity!==$.identity)return;return Z.applicable}}function jZ($){return async(Z)=>{let J=Z.credential;if(J.type!=="oauth"||!J.access)throw Error("the row holds no access token to poll with");let z=await GZ({accessToken:J.access,fetchImpl:$.fetchImpl,now:$.now,...Z.identity?{accountId:Z.identity}:{},accountKey:Z.id,...$.logger?{logger:$.logger}:{}});return $.counts.record(Z,z),XZ(z,$.now(),!0)}}function VZ($){let{source:Z,counts:J,now:z}=$,X=async(j)=>{let B=await Z.rowAccess(j,await $.storage());if(!B?.row)throw new YZ("unknown_account",`${j==="main"?"Main":"Fallback"} account ${j} was not found.`);return QZ(j,B)},Y=async(j)=>{if($.authority&&await $.authority()!=="local")return{account:j,ok:!1,error:"local accounts are not polled while this host is connected to the vault"};let[B]=await Z.pollRows(await $.storage(),{ids:[j]});if(!B)return{account:j,ok:!1,error:"targeted quota refresh returned no result"};return{account:B.id,ok:B.ok,...B.error!==void 0?{error:B.error}:{}}},F=(j)=>Z.peek().rows.find((B)=>B.id===j),N=(j)=>{let B=F(j);if(!B)return null;let L=x2(B.quota)??{},S=J.applicable(B),_=Math.max(0,...[L.primary?.checkedAt,L.secondary?.checkedAt].filter((u)=>typeof u==="number"));return{quota:{...L,...S!==void 0?{resetCreditsApplicable:S}:{}},checkedAt:_,refreshAfter:_,...B.identity!==void 0?{accountId:B.identity}:{}}};return{resolveResetTarget:X,refreshResetTargetQuota:Y,quotaManager:{isRateLimited:(j)=>{let B=F(j);if(!B)return!1;let L=Z.rateLimitMarks([B]).get(B.id);return L!==void 0&&L>z()},getMain:()=>N("main"),getFallback:(j)=>N(j)}}}import{resolve as BZ}from"node:path";var r0=1024;class P1{pins=new Map;reservations=new Map;listeners=new Set;limit;constructor($=r0){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.reservations.delete($),this.pins.delete($);for(let Z of this.listeners)Z($)}subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}snapshot(){return new Map(this.pins)}placementSnapshot($){let Z=new Map(this.pins);for(let J of this.reservations.values())if(J.sessionId!==$)Z.set(J.sessionId,J.pin);return Z}reserve($,Z){let J={sessionId:$,previous:this.pins.get($),pin:Z};return this.reservations.set($,J),J}rollback($){if(this.reservations.get($.sessionId)===$)this.reservations.delete($.sessionId)}finish($,Z){if(this.reservations.get($.sessionId)!==$)return;if(this.rollback($),Z&&this.pins.get($.sessionId)===$.previous)this.set($.sessionId,Z)}get size(){return this.pins.size}set($,Z){this.reservations.delete($),this.pins.delete($),this.pins.set($,Z);for(let J of this.listeners)J($,Z);while(this.pins.size>this.limit){let J=this.pins.keys().next().value;if(J===void 0)break;this.forget(J)}}place($){return l2(this.placementSnapshot($.sessionId),$,(Z,J)=>this.set(Z,J))}}var UZ=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),WZ=globalThis,T1=WZ[UZ]??new Map;WZ[UZ]=T1;function HZ($){let Z=JSON.stringify([BZ($.configPath),BZ($.statePath)]),J=T1.get(Z);if(!J)J=new P1,T1.set(Z,J);return J}import{statSync as s0}from"node:fs";import{resolve as t0}from"node:path";function CZ($){return $.map((Z)=>{try{let J=s0(Z);return`${J.ino}:${J.size}:${J.mtimeMs}:${J.ctimeMs}`}catch{return"?"}}).join("|")}function _1($){return CZ([$.vault.paths.tokenPath,$.vault.paths.statePath])}function NZ($){return CZ([$.paths.configPath,$.paths.statePath,$.vault.paths.rosterPath])+_1($)}class EZ{file;observationIntervalMs;producers=new Set;subscriptions=new Map;observations=new Map;chain=Promise.resolve();timer;constructor($,Z){this.file=$;this.observationIntervalMs=Z}add($){this.producers.add($),this.observations.set($,{stamp:NZ($),roster:$.vault.snapshot()});let Z=$.source.subscribe(()=>{this.publish($)}),J=this.subscriptions.get($.pins);if(!J){let z=new Set;J={producers:z,stop:$.pins.subscribe((X,Y)=>{let F=z.values().next().value;if(F)this.publish(F,{sessionId:X,pin:Y,accountId:Y?.accountId,route:"sticky-balanced"})})},this.subscriptions.set($.pins,J)}return J.producers.add($),this.timer??=setInterval(()=>{for(let z of this.producers){let X={stamp:NZ(z),roster:z.vault.snapshot()},Y=this.observations.get(z);if(X.stamp!==Y?.stamp||X.roster!==Y?.roster)this.observations.set(z,X),this.publish(z)}},this.observationIntervalMs),this.timer.unref?.(),()=>{if(Z(),this.producers.delete($),this.observations.delete($),J.producers.delete($),!J.producers.size)J.stop(),this.subscriptions.delete($.pins);if(!this.producers.size)clearInterval(this.timer),this.timer=void 0}}publish($,Z){return this.chain=this.chain.then(async()=>{if(!this.producers.has($))return;let z=await $.vault.authority()!=="local",X=_1($),Y=()=>this.producers.has($)&&$.vault.enrolled()===z&&_1($)===X,F=await B2($.paths),N=z?_Z($.vault.snapshot()?.rows??[],new Set($.vault.routes().map((j)=>j.id)),F,Date.now()):MZ((await $.source.sidebarView()).rows,F,Date.now());if(await KZ(N,this.file,{canWrite:Y}),!Y()||!Z)return;let U=N.vaultAccounts??N.fallbacks;if(Z.accountId===void 0){await PZ(Z.sessionId,U,this.file,{canWrite:Y});return}if(Z.pin){let j=Date.now();await TZ({sessionId:Z.sessionId,assignment:{accountId:Z.pin.accountId,wireAccountId:Z.pin.wireIdentity,inputBytes:Z.pin.inputBytes??0,quotaCheckedAt:Z.pin.quotaCheckedAt,assignedAt:j,lastSeenAt:j},validPinnedAccountIds:[...z?[]:["main"],...U.filter((B)=>B.enabled).map((B)=>B.id)]},this.file)}await LZ({sessionId:Z.sessionId,activeId:Z.accountId,route:Z.route??N.route,updatedAt:Date.now()},U,this.file,{canWrite:Y})}).catch(()=>{N2("opencode2").warn("sidebar publication failed")}),this.chain}settled(){return this.chain}get empty(){return this.producers.size===0}}var OZ=Symbol.for("@cortexkit/openai-auth/opencode2-sidebar-publishers"),AZ=globalThis,k2=AZ[OZ]??new Map;AZ[OZ]=k2;function RZ($,Z=FZ(),J=2000){let z=t0(Z),X=k2.get(z);if(!X)X=new EZ(z,J),k2.set(z,X);let Y=X,F=Y.add($),N=!1;for(let[U,j]of $.pins.snapshot())Y.publish($,{sessionId:U,pin:j,accountId:j.accountId,route:"sticky-balanced"});return{publish:()=>Y.publish($),route:(U,j,B)=>{Y.publish($,{sessionId:U,accountId:j,route:B})},async release(){if(N)return;if(N=!0,F(),await Y.settled(),Y.empty&&k2.get(z)===Y)k2.delete(z)}}}var o2="cortexkit-openai-auth",Z4=5000;async function SZ($,Z,J,z=new S2,X,Y,F){let N=new K1(J),U=new e0,j=new Map,B=new Map,L=(R)=>{B.delete(R);for(let k of j.keys())if(k.startsWith(`${R}:`))j.delete(k)},S=(R)=>{F?.(R.sessionID),Y?.send(R.sessionID,R.frame)},u=await Z1({session:{hook:(R,k,z2)=>$.session.hook(R,async(w)=>{let h=R==="http.request"?w:void 0,v=R==="experimental.ws.handshake"?w:void 0,P=(h?h.request.headers:v?new Headers(v.headers):void 0)?.get("authorization")===`Bearer ${Q2(Z.providerID)}`,E={};if(v)j.delete(`${v.sessionID}:${v.kind}`);try{await U.run(E,()=>k(w))}catch(K){if(P&&!(K instanceof J2))throw wZ(K);throw K}if(h&&P&&E.attempt){let K=h.request.headers.get("thread-id");if(K)h.request.headers.set("session-id",K)}if(h&&P&&E.attempt)await N.captureHttp(h.request,E.attempt);if(h&&P&&E.attempt)await X?.({sessionID:h.sessionID,kind:h.kind,request:h.request,attempt:E.attempt});if(v&&P&&E.attempt)v.headers["session-id"]=z.get(v.sessionID).threadID;if(R==="experimental.ws.send"){let K=w,A=j.get(`${K.sessionID}:${K.kind}`);if(A)await N.frame(K.frame,A.attempt);if(A&&K.kind==="primary")S(K)}if(h||v){let K=h??v;if(!K)return;let T=(h?h.request.headers:new Headers(K.headers)).get("authorization")?.replace(/^Bearer /,"");if(P&&T)B.set(K.sessionID,T);else B.delete(K.sessionID);if(v){let C=`${v.sessionID}:${v.kind}`;if(P&&T&&E.attempt)j.set(C,{bearer:T,attempt:E.attempt,url:v.url,headers:new Headers(Object.entries(v.headers).filter(([y])=>["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"].includes(y.toLowerCase())))});else j.delete(C)}if(B.size>512){let C=B.keys().next().value;if(C)B.delete(C)}if(j.size>512){let C=j.keys().next().value;if(C)j.delete(C)}}else if(R==="experimental.ws.receive"){let K=w,A=j.get(`${K.sessionID}:${K.kind}`);if(A){if(z.frameReceived(K.sessionID,K.frame),K.kind==="primary"){let T;if(Y?.receive(K.sessionID,K.frame,(C)=>{T=C}),T)try{let C=g1(T,A.url,A.headers,z);if(C)await X?.({sessionID:K.sessionID,kind:"primary",request:C,attempt:A.attempt})}catch(C){J.warn("cachekeep WebSocket capture failed",{error:C instanceof Error?C.message:String(C)})}}K.frame=yZ(K.frame,A.bearer)}}else if(R==="retry"){let K=w,A=B.get(K.sessionID);if(A)Object.assign(K.error,{message:a2(K.error.message,A)})}},z2)},event:{subscribe:(R)=>async function*(){for await(let k of $.event.subscribe(R)){if(k.type==="session.deleted")L(k.data.sessionID);yield k}}()}},{...Z,rewriteRequest:async(R)=>{let k=U.getStore();if(k)k.attempt=R.attempt;return Z.rewriteRequest?.(R)},rewriteHandshakeURL:(R)=>{let k=U.getStore();if(k)k.attempt=R.attempt;return Z.rewriteHandshakeURL?.(R)},onAttemptEnd:async(R,k)=>{await N.end(R,k),await Z.onAttemptEnd?.(R,k)},rewriteResponse:async(R)=>{await N.response(R.request,R.response.status);let k=await Z.rewriteResponse?.(R)??R.response;return fZ(k,R.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(R)=>{let k=R.get("authorization");return k?.startsWith("Bearer ")?k.slice(7):void 0}},logger:{warn:(R,k)=>J.warn(R,{data:k})}}),o=u.dispose;return{...u,dispose:async()=>{B.clear(),j.clear(),await o(),await N.settle(),N.clear()}}}function E1($={}){return{id:o2,setup:(Z)=>J4(Z,$)}}async function J4($,Z={}){let a=[];try{let J=N2("opencode2");let z=N2("quota");let X=Z.paths??(()=>vZ(IZ()));let Y=await B2(X());let F=Y?.logging?.level;if(F&&typeof F==="string")qZ(F);let N=Z.fetch??fetch;let U=Z.now??Date.now;let j=Z.version??uZ;let B=Z.poolMigration??oZ;if(!B&&!E2(X().configPath)){J.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let M=(Y2)=>{throw new J2({kind:"no-account",providerID:X2,sessionID:Y2.sessionID,requestKind:Y2.kind,message:u2})},d=await SZ($,{providerID:X2,chooseAccount:M,accountHeaders:M},J);return()=>d.dispose()}let L=Z.vault?.firstRosterWaitMs??cZ;let S=nZ({host:"opencode",stateDir:Z.vault?.stateDir??kZ(X().statePath),reservedRouteIds:()=>w.peek().rows.map((M)=>M.id),...Z.vault?.connectionFile?{connectionFile:Z.vault.connectionFile}:{},...Z.vault?.connectScoped?{connectScoped:Z.vault.connectScoped}:{},...Z.vault?.connectEnrollment?{connectEnrollment:Z.vault.connectEnrollment}:{},...Z.vault?.pollIntervalMs!==void 0?{pollIntervalMs:Z.vault.pollIntervalMs}:{},fetchImpl:()=>N},X());let _=S.vault;let u=!1;let o=!1;const R=n2(a,{[Symbol.dispose](){if(!u)S.release()}},0);await _.authority();let k=S.firstRoster;let z2=new L1;let w=new dZ({paths:X,refreshProvider:async(M)=>{let d=await DZ({refreshToken:M.refresh,fetchImpl:N,now:U}),Y2=bZ({id_token:"",access_token:d.access,refresh_token:d.refresh});return{...d,...Y2?{identity:Y2}:{}}},pullQuota:jZ({fetchImpl:N,now:U,counts:z2,logger:z}),now:U,vaultIdentities:()=>_.identities(),vaultMode:()=>_.enrolled(),vaultAuthority:()=>_.authority(),vaultFirstRoster:k,vaultFirstRosterBackgroundWaitMs:L,log:N2("pool")});await w.load();let h=Z.heartbeat===!1?void 0:await aZ({version:j,logger:N2("heartbeat")});let v=Z.fence??(()=>lZ({currentVersion:j}));let V=Z.slot??rZ();let P=async()=>hZ(X(),await V.get({path:{id:"openai"}}));let E=!1;let K=B?iZ({paths:X,slot:V,version:j,fence:v,runDeps:{vaultServes:()=>_.serves()},paused:async()=>await _.authority()!=="local",migrate:async(M)=>{let d=await mZ(M);if(E=d.status==="refused",!o)await w.load();return d},adopt:async(M)=>{if(o)return{status:"retry",reason:"unsettled"};if(!await C1(k,L))return{status:"retry",reason:"vault-roster-pending"};if(o)return{status:"retry",reason:"unsettled"};let d=await gZ(M);if(!o)await w.load();return d}}):void 0;K?.start();S.start();let A=HZ(X());let T=RZ({paths:X(),source:w,pins:A,vault:_},Z.sidebarStateFile,Z.sidebarObservationIntervalMs);const C=n2(a,{[Symbol.dispose](){if(!u)T.release()}},0);T.publish();let y=Z.codex??new S2(void 0,void 0,y$());let b=C$(Y);let m=c2(X());let g=A$(X(),{source:w,storage:()=>B2(X()),vault:_,accounts:Q1(X()),settings:()=>b,parentOf:async(M)=>(await $.session.get({sessionID:M}))?.parentID??void 0,fetch:N,log:N2("cachekeep")},{now:U,codexResponsesUrl:C2().codexApiEndpoint,...Z.cacheKeep});const r=n2(a,{[Symbol.dispose](){if(!u)g.release()}},0);let e=W$({codex:y,onRoute:T.route,source:w,slotPlaceholderWithoutMain:P,storage:()=>B2(X()),pins:A,sessionAccounts:Q1(X()),vault:_,awaitVaultRoster:async()=>{await C1(_.awaitRequestRoster(),pZ)},responsesLite:()=>C2().responsesLite,codexEndpoint:()=>C2().codexApiEndpoint,now:U,log:J});let c=await SZ($,e.adapter,J,y,(M)=>g.capture(M),m,(M)=>g.forget(M));e.attach(c);let s=async(M)=>{if(await D2(_),E2(X().configPath))return;if(await K?.idle(),E2(X().configPath))return;if(E&&!F1(M)&&(await v()).open){await w.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let l=async(M)=>{await s(M);let d=await s$(w.poolStore(),X(),M,{vault:_});if(!E2(X().configPath))await K?.requestAdoption();await w.load(),J.info("ChatGPT login stored in the account pool",d)};let f=await t2($,{integrationID:X2,methods:r$({beginLogin:Z.beginLogin??M1,version:j,vault:_}),onLogin:(M)=>l(M),label:"ChatGPT (openai-auth account pool)",vault:o$(_)});let I=await zZ($);if(Z.controlPlane&&(!$.command||!$.location))throw Error("OpenCode 2 control plane requires command and location APIs");let $2=$.command&&$.location?await p$({session:$.session,command:$.command,location:$.location},Z.controlPlane??$Z({...VZ({source:w,storage:()=>B2(X()),counts:z2,now:U,authority:()=>_.authority()}),fetchImpl:N,now:U,randomUUID:$4,accountStoragePath:X().configPath,accountStatePath:X().statePath,packageVersion:j,loadAccounts:B2,store:()=>w.poolStore(),migration:async()=>{if(E2(X().configPath))return{migrated:!0};let M=await v();return{migrated:!1,blockers:M.open?[]:M.blockers}},beginAccountLogin:Z.beginLogin??M1,refreshAllQuota:async()=>(await w.pollRows(await B2(X()))).map((M)=>({...M,account:M.id})),getStickyRouting:async(M)=>A.get(M),cacheKeepManager:g.manager,setCacheKeepEnabled:(M)=>g.configure({enabled:M}),setCacheKeepSubagents:(M)=>g.configure({subagents:M}),setCacheKeepSustain:(M)=>g.configure({sustain:M}),setCacheKeepWindow:(M)=>g.configure({window:M}),afterWrite:()=>w.load(),refreshSidebar:()=>T.publish(),clearStickyRouting:async(M)=>{let d=A.get(M)!==void 0;return A.forget(M),d},vault:_})):void 0;let p=new AbortController;(async()=>{try{for await(let M of $.event.subscribe({signal:p.signal}))if(M.type==="session.deleted")e.forgetSession(M.data.sessionID),g.forget(M.data.sessionID),m.forget(M.data.sessionID)}catch(M){if(!p.signal.aborted)J.warn("stopped listening for session deletion",{error:M instanceof Error?M.message:String(M)})}})();u=!0;return async()=>{o=!0,p.abort();let M=g.release();await $2?.(),K?.dispose(),w.dispose(),await T.release(),await Promise.allSettled([c.dispose(),f.dispose(),I.dispose()]);let d;try{await Promise.race([Promise.all([K?.idle(),w.settled(),y.store?.settled(),M]),new Promise((Y2)=>{d=setTimeout(Y2,Z4),d.unref?.()})])}finally{clearTimeout(d),S.release(),await h?.release()}}}catch(U2){var T2=U2,F2=1}finally{xZ(a,T2,F2)}}var z4=E1(),A6={id:o2,setup:z4.setup,server:sZ.server};export{A6 as default,E1 as createOpenAIAuthPlugin,o2 as OPENAI_AUTH_PLUGIN_ID};
|
|
3
|
+
`)}}function e2($,Z){let J=new TextDecoder,z="",X=(F)=>{let N=Z0(F);if(!N)return;try{$(N)}catch(U){Z(U)}},Y=()=>{for(;;){let F=/\r?\n\r?\n/.exec(z);if(!F)return;let N=z.slice(0,F.index);z=z.slice(F.index+F[0].length),X(N)}};return new TransformStream({transform(F,N){N.enqueue(F),z+=J.decode(F,{stream:!0}),Y()},flush(){if(z+=J.decode(),Y(),z.trim()!=="")X(z);z=""}})}var q1=512,M2="x-common-auth-attempt",L2=($,Z)=>JSON.stringify([$,Z]),j2=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function J0($){let Z=$.headers;return typeof Z==="object"&&Z!==null}function z0($,Z){let J=$.getReader();return new ReadableStream({async pull(z){let X;try{X=await J.read()}catch(Y){Z({reason:"failed",message:Y instanceof Error?Y.message:String(Y)}),z.error(Y);return}if(X.done)Z(),z.close();else z.enqueue(X.value)},async cancel(z){Z({reason:"cancelled",...z===void 0?{}:{message:String(z)}}),await J.cancel(z)}})}function $1($,Z){for(let[J,z]of Object.entries(Z)){let X=J.toLowerCase();for(let Y of Object.keys($))if(Y.toLowerCase()===X)delete $[Y];if(z!==null)$[J]=z}}function G0($,Z){for(let[J,z]of Object.entries(Z))if(z===null)$.delete(J);else $.set(J,z)}async function Z1($,Z,J={}){let{providerID:z}=Z,X=J.gateOnPlaceholder,Y=(G)=>X===void 0||X.credential(G)===Q2(z),F=J.logger,N=Math.max(1,J.maxRecords??q1),U=[...J.hostCredentials??[Q2(z)],...X?[Q2(z)]:[]].filter((G)=>G!==""),j=new Map,B=new WeakMap,L=new Map,S=new Set,_=new Map,u=!1,o=!1,R=new Map,k=0,z2=!1,w=new Map,h=(G,Q)=>{try{F?.warn(G,Q)}catch{}},v=(G)=>G instanceof Error?G.message:String(G),V=new Map,P=(G,Q)=>{let W=(V.get(G)??Promise.resolve()).then(Q),H=W.then(()=>{},()=>{});return V.set(G,H),H.then(()=>{if(V.get(G)===H)V.delete(G)}),W},E=(G,Q)=>{let W=V.get(G);return W?W.then(()=>E(G,Q)):Q()},K=async(G)=>{try{await Z.dropChoice?.({...G.input,accountId:G.accountId})}catch(Q){h("opencode2 auth dropChoice threw; the request is unaffected",{sessionID:G.input.sessionID,error:v(Q)})}},A=(G)=>{let Q=L.get(G);if(L.delete(G),Q?.next){let W=Q.next;P(Q.sessionID,()=>K(W))}},T=async(G,Q)=>{let W=R.get(G);if(!W||W.size===0)return;await Promise.all([...W].map(async(H)=>{try{await H(Q)}catch(x){h("opencode2 auth listener threw; the request is unaffected",{event:G,error:v(x)})}}))},C=async(G,Q)=>{try{await Z.onAttemptEnd?.(G,Q)}catch(W){h("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:G.attemptId,error:v(W)})}},y=(G,Q)=>{if(G.ended||!G.attempt)return;let W={...G.status===void 0?{}:{status:G.status},outputStarted:G.outputStarted,...G.limit?{limit:G.limit.signal}:{},...Q?{error:Q}:{}};if(Q)G.endError=Q;G.ended=C(G.attempt,W)},b=(G,Q)=>y(G,{reason:"abandoned",message:Q}),m=(G)=>[...j.values()].filter((Q)=>Q.key===G),g=(G)=>m(G).at(-1),r=(G)=>{if(j.delete(G.id),L.get(G.key)?.attemptId===G.id||!m(G.key).length)A(G.key)},e=(G)=>{j.set(G.id,G);while(j.size>N){let Q=j.values().next().value;if(Q===void 0)break;b(Q,"dropped to keep the record bound"),r(Q)}},c=(G)=>G.accountId===void 0?void 0:{...G.scope,accountId:G.accountId},s=(G,Q)=>new J2({kind:"no-account",providerID:z,sessionID:G.sessionID,requestKind:G.kind,...Q===void 0?{}:{message:Q}}),l=(G)=>{w.get(G)?.clear(),w.delete(G)},f=async(G,Q)=>{let W=()=>s(G,`${z} ${G.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(z2)throw W();let H=w.get(G.sessionID);if(!H)H=new Set,w.set(G.sessionID,H);let x={};H.add(x);let q=()=>{if(!H.has(x))throw W()};try{return await Q(q)}finally{if(H.delete(x),H.size===0&&w.get(G.sessionID)===H)w.delete(G.sessionID)}},I=(G,Q)=>{for(let[W,H]of Q)if(U.some((x)=>H.includes(x)))throw new J2({kind:"host-credential-on-wire",providerID:z,sessionID:G.sessionID,requestKind:G.kind,message:`${z} ${G.kind} request still carries the host's placeholder credential in ${W}; the adapter's account headers must replace it`})},$2=(G)=>{for(let Q of m(G))if(Q.ended||!Q.attempt)r(Q);else if(Q.transport==="ws"||Q.judged)b(Q,"a newer attempt of its session and kind began"),r(Q)},p=async(G,Q,W,H)=>{let x=L2(G.sessionID,G.kind),{input:q,accountId:O}=await E(G.sessionID,async()=>{W();let n=L.get(x);L.delete(x);let _2=n?.accountId??g(x)?.accountId;$2(x);let t=n?.next,E2=t!==void 0&&t.input.modelID===G.modelID&&t.input.agent===G.agent,H2={...G,phase:"request",..._2===void 0?{}:{previousAccountId:_2},...n?.rerouteFrom?{rerouteFrom:n.rerouteFrom}:{}};if(t&&!E2)await P(G.sessionID,()=>K(t)),W();let k2=E2?t.accountId:await Z.chooseAccount(H2);return{input:H2,accountId:k2}});W();let D={},i;if(O!==void 0){let n=await Z.accountHeaders({...G,accountId:O});if(W(),J0(n))D=n.headers,i=n.attempt;else D=n}let G2=`attempt-${++k}`,Z2={id:G2,key:x,scope:G,accountId:O,headers:D,attempt:O===void 0?void 0:{...G,accountId:O,attemptId:G2,transport:H,data:i},...H===void 0?{}:{transport:H},outputStarted:!1};if(e(Z2),Z2.attempt)T("select",{...G,accountId:Z2.attempt.accountId,hook:Q,...q.previousAccountId===void 0?{}:{previousAccountId:q.previousAccountId},...q.rerouteFrom===void 0?{}:{rerouteFrom:q.rerouteFrom},handle:Z2.attempt});return Z2},a=async(G,Q,W,H,x)=>{let q=L2(G.sessionID,G.kind),O=H===void 0?void 0:j.get(H);if(O?.key!==q)O=void 0;if(!O){if(O=g(q),m(q).filter((i)=>i.transport===void 0&&!i.ended).length>1&&!o)o=!0,h("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:G.sessionID,kind:G.kind})}if(!O||O.transport!==void 0||O.ended)O=await p(G,Q,x,W);else if(O.transport=W,O.attempt)O.attempt.transport=W;if(W==="ws"){for(let D of m(q))if(D!==O&&D.transport==="ws")b(D,"a newer attempt of its session and kind went out over WebSocket")}return O},U2=async(G,Q)=>{try{return await Q()}catch(W){throw y(G,{reason:"failed",message:v(W)}),W}},T2=(G,Q)=>{let W=m(L2(G,Q)).filter((H)=>H.transport==="ws").at(-1);return W?.attempt!==void 0&&!W.ended?W:void 0},F2=(G,Q,W)=>{let H=c(G);if(!H||!G.attempt||G.limit)return;G.limit={signal:Q,delivered:T("limit",{...H,via:W,limit:Q,outputStarted:G.outputStarted,handle:G.attempt})}},M=(G,Q,W,H)=>{let x=c(G);if(!x||!G.attempt)return;T("quota",{...x,transport:Q,...H===void 0?{}:{status:H},quota:W,handle:G.attempt})},d=(G,Q,W,H)=>{let x=G.attempt;if(!x)return;let q=Z.inspectEvent?.(H===void 0?{transport:Q,data:W,attempt:x}:{transport:Q,data:W,event:H,attempt:x});if(!q)return;if(q.quota!==void 0)M(G,Q,q.quota);if(q.outputStarted)G.outputStarted=!0;if(q.limit)F2(G,q.limit,Q);if(q.error!==void 0)y(G,{reason:"failed",message:q.error});else if(q.done)y(G)},Y2=(G,Q)=>{let W=G.attempt;if(!W||Q.accountId===G.accountId)return;if(W.reboundFrom??=W.accountId,W.accountId=Q.accountId,"data"in Q)W.data=Q.data;G.accountId=Q.accountId},eZ=(G)=>!G.attempt||G.endError!==void 0||G.status!==void 0&&G.status>=400,$0=(G)=>{let Q=[...j.values()].filter((D)=>D.scope.sessionID===G),W=Q.filter((D)=>D.limit&&!D.rerouted).at(-1);if(W)return W;let H=Q.filter((D)=>D.scope.kind==="primary"),x=H.length>0?H:Q;if(x.length<=1)return x[0];let q=x.filter((D)=>!D.judged&&eZ(D)).at(-1);if(q)return q;let O=x.filter((D)=>D.attempt&&!D.ended);if(O.length>1)return"ambiguous";return O[0]??x.at(-1)},K2={providerID:z},W2=[];W2.push(await $.session.hook("model.request",(G)=>{if(X)return;return f(j2(G),async(Q)=>{let W=await p(j2(G),"model.request",Q);if(Q(),W.accountId===void 0)throw s(W.scope);$1(G.headers,{...W.headers,[M2]:W.id})})},K2)),W2.push(await $.session.hook("http.request",(G)=>{if(X){let Q=Y(G.request.headers);if(_.set(G.sessionID,Q),!Q)return}return f(j2(G),async(Q)=>{let W=G.request.headers.get(M2)??void 0,H=X?await p(j2(G),"http.request",Q,"http"):await a(j2(G),"http.request","http",W,Q);Q();let x=c(H),q=H.attempt;if(!x||!q)throw s(H.scope);await U2(H,async()=>{let O=G.request;if(Z.rewriteRequest){if(W!==void 0){let G2=new Headers(O.headers);G2.delete(M2),O=new Request(O,{headers:G2})}O=await Z.rewriteRequest({...x,request:O,attempt:q})??O,Q()}let D=new Headers(O.headers);D.delete(M2),G0(D,H.headers),I(H.scope,D.entries());let i=new Request(O,{headers:D});B.set(i,H),G.request=i})})},K2)),W2.push(await $.session.hook("http.response",async(G)=>{let Q=B.get(G.request);if(!Q){if(X)return;if(!u)u=!0,h("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:G.sessionID,kind:G.kind});return}let W=G.response;if(Z.answeredBy&&Q.attempt){let D=Q.attempt,i=await U2(Q,async()=>Z.answeredBy?.({request:G.request,response:W,attempt:D}));if(i)Y2(Q,i)}let H=c(Q),x=Q.attempt;if(!H||!x)return;Q.status=W.status;let q=Z.quotaFromHeaders?.(W.headers,W.status,x);if(q!==void 0)M(Q,"http",q,W.status);if(!W.ok&&Z.limitFromResponse){let D=await Z.limitFromResponse({status:W.status,headers:W.headers,body:()=>W.clone().text(),attempt:x});if(D)F2(Q,D,"http")}if(!W.ok||!W.body)y(Q);let O=W;if(W.body&&(Z.inspectEvent||Z.onAttemptEnd)){let D=W.body;if(Z.inspectEvent)D=D.pipeThrough(e2((i)=>d(Q,"http",i.data,i.event),(i)=>h("opencode2 auth event inspection threw",{error:v(i)})));O=new Response(z0(D,(i)=>y(Q,i)),{status:W.status,statusText:W.statusText,headers:W.headers})}if(Z.rewriteResponse)O=await Z.rewriteResponse({...H,request:G.request,response:O,attempt:x})??O;if(O!==W)G.response=O},K2)),W2.push(await $.session.hook("experimental.ws.handshake",(G)=>{if(X){let Q=Y(new Headers(G.headers)),W=L2(G.sessionID,G.kind);if(_.set(G.sessionID,Q),S.delete(W),!Q)return}return f(j2(G),async(Q)=>{let W;for(let O of Object.keys(G.headers)){if(O.toLowerCase()!==M2)continue;W??=G.headers[O],delete G.headers[O]}let H=X?await p(j2(G),"experimental.ws.handshake",Q,"ws"):await a(j2(G),"experimental.ws.handshake","ws",W,Q);Q();let x=c(H),q=H.attempt;if(!x||!q)throw s(H.scope);await U2(H,async()=>{$1(G.headers,H.headers);let O=Z.rewriteHandshakeURL?.({...x,url:G.url,attempt:q});if(O!==void 0)G.url=O;if(I(H.scope,Object.entries(G.headers)),X)S.add(H.key)})})},K2));let O1=Z.rewriteWebSocketFrame?.bind(Z);if(O1)W2.push(await $.session.hook("experimental.ws.send",async(G)=>{let Q=j2(G);if(X&&!S.has(L2(Q.sessionID,Q.kind)))return;let W=T2(Q.sessionID,Q.kind),H=await O1({...Q,attempt:W?.attempt,frame:G.frame});if(H!==void 0)G.frame=H},K2));W2.push(await $.session.hook("experimental.ws.receive",(G)=>{if(X&&!S.has(L2(G.sessionID,G.kind)))return;let Q=T2(G.sessionID,G.kind);if(!Q)return;try{d(Q,"ws",G.frame)}catch(W){h("opencode2 auth frame inspection threw",{error:v(W)})}},K2)),W2.push(await $.session.hook("retry",async(G)=>{if(X&&_.get(G.sessionID)!==!0)return;let Q=$0(G.sessionID);if(!Q)return;let W=G.decision;if(Q==="ambiguous"){await T("retry",{sessionID:G.sessionID,attempt:G.attempt,reason:"host-decides",hostDecision:W,decision:W});return}let H=Q;await f(H.scope,async(x)=>{let q=x;H.judged=!0;let O=H.attempt;if(O&&!H.outputStarted){if(!H.limit){let G2=Z.limitFromError?.(G.error,O);if(G2)F2(H,G2,"error")}if(H.ended)await H.ended;if(H.limit)await H.limit.delivered}q();let{decision:D,reason:i}=await P(H.scope.sessionID,async()=>{q();let G2=L.get(H.key);if(L.delete(H.key),G2?.next)await K(G2.next);q();let Z2=W,n,_2,t;if(H.accountId===void 0||!O)Z2={retry:!1},n="no-account";else if(H.outputStarted)Z2={retry:!1},n="output-started";else if(H.limit){let E2={accountId:H.accountId,limit:H.limit.signal},H2,k2={...H.scope,phase:"retry",previousAccountId:H.accountId,rerouteFrom:E2};try{H2=await Z.chooseAccount(k2)}catch(s2){h("opencode2 auth chooseAccount threw while the retry hook looked for another account; the host decides the retry",{sessionID:H.scope.sessionID,error:v(s2)})}if(H2!==void 0)t={accountId:H2,input:k2};try{q()}catch(s2){if(t)await K(t);throw s2}if(H2!==void 0&&H2!==H.accountId)H.rerouted=!0,_2=E2,Z2={retry:!0,delay:0},n="reroute";else n="host-decides-last-account"}else n="host-decides";if(G.decision=Z2,Z2.retry&&H.accountId!==void 0&&j.has(H.id))L.set(H.key,{attemptId:H.id,sessionID:H.scope.sessionID,accountId:H.accountId,..._2===void 0?{}:{rerouteFrom:_2},...t===void 0?{}:{next:t}});else if(t)await K(t);return{decision:Z2,reason:n}});q(),await T("retry",{sessionID:G.sessionID,...H.accountId===void 0?{}:{accountId:H.accountId},kind:H.scope.kind,attempt:G.attempt,reason:i,hostDecision:W,decision:D,...O===void 0?{}:{handle:O}})})},K2));let A1=(G)=>{l(G),_.delete(G);for(let Q of S)if(JSON.parse(Q)[0]===G)S.delete(Q);for(let Q of[...j.values()]){if(Q.scope.sessionID!==G)continue;b(Q,"its session was forgotten"),j.delete(Q.id)}for(let[Q,W]of L)if(W.sessionID===G)A(Q)},r2=new AbortController,R1=$.event;if(R1)(async()=>{try{for await(let G of R1.subscribe({signal:r2.signal}))if(G.type==="session.deleted")A1(G.data.sessionID)}catch(G){if(!r2.signal.aborted)h("opencode2 auth stopped listening for session deletion",{error:v(G)})}})();return{on(G,Q){let W=R.get(G);if(!W)W=new Set,R.set(G,W);let H=Q;return W.add(H),()=>{W.delete(H)}},accountFor(G,Q){return g(L2(G,Q))?.accountId},forgetSession:A1,get size(){return j.size},async dispose(){if(z2)return;z2=!0;for(let G of w.keys())l(G);r2.abort();for(let G of j.values())b(G,"the installation was disposed");j.clear();for(let G of L.keys())A(G);S.clear(),_.clear(),R.clear(),await Promise.all(V.values()),await Promise.all(W2.map(async(G)=>{try{await G.dispose()}catch(Q){h("opencode2 auth hook did not dispose cleanly",{error:v(Q)})}}))}}}import{createHash as X0}from"node:crypto";var Y0=1024,Q0=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),b1=($)=>D1($,"user"),j0=($)=>Q0($)&&($.role==="assistant"||typeof $.type==="string"&&$.type!=="message"&&$.type!=="configuration_update");function V0($){return X0("sha256").update(JSON.stringify($)).digest("hex")}class A2{runtime;maxSessions;#$=new Map;constructor($,Z=Y0){this.runtime=$;this.maxSessions=Z}advance($,Z,J=this.runtime){let z=this.#$.get($),X=Array.isArray(Z.input)?Z.input:[],Y=X.filter(b1),F=X.findLastIndex(b1),N=F<0?void 0:V0(X[F]),U=typeof Z.previous_response_id==="string"&&Z.previous_response_id.length>0,j,B,L;if(U)j=Y.length>0,B=N??z?.fingerprint,L=z?.userCount===void 0?void 0:z.userCount+Y.length;else{B=N,L=Y.length;let _=F>=0&&F>X.findLastIndex(j0),u=z!==void 0&&!z.completed&&z.fingerprint===B&&z.userCount===L;j=_&&!u}let S=j||!z?{turnID:(J?.uuid??P2)(),turnStartedAt:(J?.now??Date.now)()}:{turnID:z.turnID,turnStartedAt:z.turnStartedAt};return this.#Z($,{...S,completed:!1,fingerprint:B,userCount:L}),S}completed($){let Z=this.#$.get($);if(Z)this.#Z($,{...Z,completed:!0})}get($){return this.#$.get($)}forget($){this.#$.delete($)}#Z($,Z){this.#$.delete($),this.#$.set($,Z);while(this.#$.size>this.maxSessions){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function J1($,Z){return{threadID:$.threadID,windowID:$.windowID,turnID:Z.turnID,turnStartedAt:Z.turnStartedAt}}var k1=Symbol.for("@cortexkit/openai-auth/opencode2/codex-installation");function B0(){let $=globalThis;return $[k1]??=crypto.randomUUID(),$[k1]}class R2{runtime;store;sessions;frameTurns;installationID;constructor($,Z,J){this.runtime=$;this.store=J;this.installationID=Z??B0(),this.sessions=J?.sessions??new Map,this.frameTurns=J?.frameTurns??new A2}get($){let Z=this.runtime?.uuid??P2;if(this.store)return this.store.get($,Z);let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J)}return J}advanceFrame($,Z){return this.frameTurns.advance($,Z,this.runtime)}frameReceived($,Z){if(!Z.includes("response.completed"))return;if(w2(Z)?.type==="response.completed")this.frameTurns.completed($)}forget($){if(this.store)this.store.delete($);else this.sessions.delete($),this.frameTurns.forget($)}}var z1={version:w1,"user-agent":y1,originator:"codex_exec"};var U0=1024,W0=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,f2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),v1=($)=>f2($)&&($.type==="message"||("role"in $))&&$.role==="user",h1=($)=>f2($)&&$.type==="configuration_update";class G1{http;#$=new Map;constructor($=new R2){this.http=$}apply($,Z,J){if(Z.kind!=="primary")return!1;let z=typeof $.model==="string"?$.model:"";if(!f1.has(z))return!1;if(W0.test(z))return!1;let X=f2($.reasoning)?$.reasoning:void 0,Y=typeof X?.effort==="string"?X.effort:void 0;if(!Y)return!1;let F=this.#$.get(Z.sessionID);if(F===void 0)return this.#Z(Z.sessionID,Y),!1;if(Y===F)return!1;let N=Array.isArray($.input)?$.input:void 0;if(!N||N.length===0)return!1;let U=N.findLastIndex(v1);if(U<0){if(J==="http")return!1;return $.reasoning={...X,effort:F},!0}if($.reasoning={...X,effort:F},!h1(N[U-1]))N.splice(U,0,{type:"configuration_update",reasoning:{effort:Y}});return!0}forget($){this.#$.delete($),this.http.forget($)}#Z($,Z){this.#$.set($,Z);while(this.#$.size>U0){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function w2($){try{let Z=JSON.parse($);return f2(Z)?Z:void 0}catch{return}}async function m1($,Z,J,z,X=J.http){if($.method.toUpperCase()!=="POST")return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let Y=await $.clone().text(),F=w2(Y);if(F)delete F.max_output_tokens;let N=new Headers($.headers),U=y2({rewriteLite:I1,init:{body:F?JSON.stringify(F):$.body===null?void 0:Y},headers:N,metadata:X.get(Z.sessionID),installationID:X.installationID,runtime:X.runtime,websocket:!1,responsesLite:z,applyEffort:(j)=>{J.apply(j,Z,"http")}});return new Request($,{headers:N,body:U.init?.body})}function g1($,Z,J,z){let X=z.sessions.get($.sessionID),Y=z.frameTurns.get($.sessionID);if(!X||!Y)return;let F=J1(X,Y),N=new Headers({"content-type":"application/json"});for(let j of["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"]){let B=J.get(j);if(B!==null)N.set(j,B)}y2({init:{body:$.bodyText},headers:N,metadata:F,installationID:z.installationID,runtime:z.runtime,websocket:!1,skipTurnUpdate:!0,responsesLite:!1,rewriteLite:()=>{}});let U=new URL(Z);if(U.protocol==="wss:")U.protocol="https:";if(U.protocol==="ws:")U.protocol="http:";return new Request(U,{method:"POST",headers:N,body:$.bodyText})}function H0($,Z){if(JSON.stringify($)===JSON.stringify(Z))return!0;if(!Array.isArray($)||!Array.isArray(Z)||Z.length!==$.length+1)return!1;let J=Z.findIndex((z,X)=>JSON.stringify(z)!==JSON.stringify($[X]));return J>=0&&h1(Z[J])&&v1(Z[J+1])&&JSON.stringify(Z.slice(J+1))===JSON.stringify($.slice(J))}function l1($,Z,J){let z=w2($);if(z?.type!=="response.create")return;let X=J.http.advanceFrame(Z.sessionID,z),Y=J.http.get(Z.sessionID);delete z.max_output_tokens;let F=y2({rewriteLite:()=>{},init:{body:JSON.stringify(z)},headers:new Headers,metadata:J1(Y,X),installationID:J.http.installationID,runtime:J.http.runtime,websocket:!0,responsesLite:!1,applyEffort:(U)=>{J.apply(U,Z,"ws")}}),N=w2(String(F.init?.body));if(!N)return;if(!H0(z.input,N.input)){if("input"in z)N.input=z.input;else delete N.input;return JSON.stringify(N)}return String(F.init?.body)}function N0($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function X1($,Z){let J=new URL($);if(J.origin!=="https://api.openai.com"&&J.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(J.pathname))return $;let z=new URL(`${N0(Z)}/responses`);if(z.search=J.search,J.protocol==="ws:"||J.protocol==="wss:")z.protocol=z.protocol==="https:"?"wss:":"ws:";return z.href}import{resolve as u1}from"node:path";var F0=1024;class I2{accounts=new Map;limit;constructor($=F0){this.limit=Math.max(1,$)}record($,Z){this.accounts.delete($),this.accounts.set($,Z);while(this.accounts.size>this.limit){let J=this.accounts.keys().next().value;if(J===void 0)break;this.accounts.delete(J)}}activeAccount($){return this.accounts.get($)}forget($){this.accounts.delete($)}get size(){return this.accounts.size}}var p1=Symbol.for("@cortexkit/openai-auth/opencode2-session-accounts"),c1=globalThis,Y1=c1[p1]??new Map;c1[p1]=Y1;function Q1($){let Z=JSON.stringify([u1($.configPath),u1($.statePath)]),J=Y1.get(Z);if(!J)J=new I2,Y1.set(Z,J);return J}var X2="openai",K0=60000,j1=1,L0="request refused: no account with a usable credential",V2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function P0($){let Z=V2($)?$.counters:void 0,J=V2(Z)?Z.resetCredits:void 0,z=V2(J)?J.value:void 0;return typeof z==="number"&&Number.isFinite(z)?z:void 0}function B1($){try{return JSON.parse($)}catch{return}}function d1($){let Z=h2($);return Z?m2(Z):void 0}var T0=new Set(["usage_limit_reached","rate_limit_exceeded"]);function U1($,Z,J){return{reason:$.window,...J!==void 0?{status:J}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-Z)}:{}}}function _0($,Z){let J=v2($);if(J){let Y=typeof $.status==="number"?$.status:void 0;return U1(J,Z,Y)}if($.type!=="response.failed"||!V2($.response))return;let z=$.response.failed;if(V2(z)&&typeof z.rate_limit_reached_type==="string")return{reason:z.rate_limit_reached_type};let X=$.response.error;if(V2(X)){let Y=typeof X.code==="string"?X.code:typeof X.type==="string"?X.type:void 0;if(Y&&T0.has(Y))return{reason:Y}}return}function M0($,Z){let J=B1($);if(!V2(J))return;let z=typeof J.type==="string"?J.type:void 0;if(z==="codex.rate_limits")return{quota:{snapshot:o1(J),complete:!0}};let X=_0(J,Z);if(X)return{limit:X};if(z===void 0||z==="error")return;return U$(z)?void 0:{outputStarted:!0}}function C0($){let Z=!1;for(let J of $.keys())if(J.toLowerCase().startsWith("x-codex-")){Z=!0;break}if(!Z)return;return{snapshot:a1($),complete:n1($)}}function E0($){let Z=$.get("retry-after");if(Z===null)return;let J=Number(Z);return Number.isFinite(J)&&J>=0?J*1000:void 0}function W$($){let{source:Z,pins:J}=$,z=$.now??Date.now,X=$.log,Y=$.vault,F=new G1($.codex),N=new Map,U=new Map,j=(V)=>`${V.sessionID}\x00${V.kind}\x00${V.accountId}`,B=new Map,L=$.sessionAccounts??new I2,S=new Y$,_=(V,P,E)=>{let K=E?[]:B$(Z.peek().rows,V,P,Y?.identities()??new Set),A=(Y?.routes()??[]).filter((T)=>T.kind==="oauth"&&s1(S2(T.quota),V,P));return[...K.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota,row:T})),...A.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota}))]},u=(V,P,E)=>{let K=z$(V,P,E),A=V.map((b)=>({id:b.id,kind:"oauth",...i1(b.quota)?{quota:b.quota}:{}})),T=V.flatMap((b)=>b.row?[b.row]:[]),C=new Set(V.filter((b)=>!b.row).map((b)=>b.id)),y=Z.rateLimitMarks(T);for(let b of C){let m=B.get(b);if(m===void 0)continue;if(m<=E)B.delete(b);else y.set(b,m)}return{rows:A,now:E,rateLimitMarks:y,refreshBackoff:Z.refreshBackoffFor(T),killswitch:K,requestPull:(b)=>C.has(b)?Y?.requestReading(b):Z.requestReading(b)}},o=(V,P,E,K,A)=>{let T=Q$({...V,placement:G$(P),mainId:A});if(T.kind==="block"){X?.debug("pool admission refused the request",{reason:T.block.reason});return}let C=T.order.filter((y)=>!E.has(y));if(K!==void 0&&C.includes(K))return K;return C[0]},R=(V,P,E,K,A,T,C)=>{let y=new Map(P.map((l)=>[l.id,l.quota])),b={requestBytes:j1,reservePercent:(l)=>t1(E,l===Z$?void 0:l),resetCredits:(l)=>P0(y.get(l))},m=V1(V),g=(l,f)=>g2(C,{sessionId:K,requestBytes:j1,validPinnedAccountIds:V.rows.map((I)=>I.id).filter((I)=>!m.excluded.has(I)),excludeAccountIds:l,quotaCheckedAtByAccount:Object.fromEntries(V.rows.map((I)=>[I.id,m.projections.get(I.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(P.map((I)=>[I.id,I.identity])),select:(I)=>j$(V,b,new Set(l),I),persist:f},(I,$2)=>C.set(I,$2)),r=[...A],e=g(r,T);if(!e)return;let c=e.accountId,s=V$(V,b,c);if(s.kind==="none")return;if(s.kind==="move"){let l=g([...r,c],T);if(l)return l.accountId;return s.reason==="killswitch"?void 0:c}if(s.kind==="detour")return g([...r,c],!1)?.accountId;return c},w={providerID:X2,dropChoice(V){let P=j(V);U.get(P)?.drop(),U.delete(P),N.delete(P)},chooseAccount:async(V)=>{let P=await Y?.authority(),E=await $.storage(),K=P!==void 0&&P!=="local",A=()=>{throw new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:l2})};if(K)await $.awaitVaultRoster?.();else{if(!(await Z.current()).active){if(await $.slotPlaceholderWithoutMain?.())A();X?.warn("the account pool does not serve requests yet; refusing the request",{kind:V.kind});return}await Z.prepareTokens(Z.peek().rows,E)}let T=z(),C=_(E,T,K),y=X$(u(C.filter((I)=>I.id!==V.rerouteFrom?.accountId),E,T));if(y)await y,T=z(),C=_(E,T,K);let b=new Map(C.map((I)=>[I.id,I])),m=u(C,E,T),g=new Set(V.rerouteFrom?[V.rerouteFrom.accountId]:[]),r=E?.routing?.mode??"main-first",e=V.kind==="primary",c=new Set,s,l,f;try{for(;;){let I=new Set([...g,...c]);if(f=void 0,s=void 0,r==="sticky-balanced"){let p=new Map(J.placementSnapshot(V.sessionID)),a=p.get(V.sessionID);if(f=R(m,C,E,V.sessionID,I,e&&c.size===0,p),f!==void 0&&p.get(V.sessionID)!==a)s=p.get(V.sessionID)}if(f??=o(m,r,I,e?void 0:L.activeAccount(V.sessionID),K?r==="sticky-balanced"?null:J$(Y?.routes()??[]):void 0),f===void 0||c.has(f)){if(g.size>0){let p=new Map(m.rateLimitMarks);for(let a of g)p.delete(a);m={...m,rateLimitMarks:p},g.clear();continue}f=void 0;break}if(e&&r==="sticky-balanced"){let p=V1(m).projections.get(f)?.checkedAt,a=b.get(f)?.identity;l=J.reserve(V.sessionID,{accountId:f,inputBytes:j1,...p!==void 0?{quotaCheckedAt:p}:{},...a!==void 0?{wireIdentity:a}:{}})}let $2=b.get(f)?.row;if($2){if(Z.usableToken($2)!==void 0)break;X?.debug("pool row holds no usable token; choosing again",{accountId:f})}else{if(!Y)break;let p=await Y.authorize(f);if(p){N.set(j({...V,accountId:f}),p);break}X?.debug("the vault refused to serve an account; choosing again",{accountId:f})}if(l)J.rollback(l);l=void 0,c.add(f)}if(f===void 0&&!K&&C.length===0&&await $.slotPlaceholderWithoutMain?.())A();if(f===void 0&&K&&Y&&(C.length===0||c.size>0)){let I=c.size>0?"vault-refused":$$(Y);throw X?.warn("vault mode: no vault account can serve; refusing the request",{cause:I}),new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:e1(I,Y.name)})}if(f!==void 0){let I=f,$2=l,p=s,a=()=>{if($2)J.finish($2,p);if(e)L.record(V.sessionID,I),$.onRoute?.(V.sessionID,I,r)};if(V.phase==="retry")U.set(j({...V,accountId:f}),{commit:a,drop:()=>{if($2)J.rollback($2)}}),l=void 0;else a();let U2=X?.info;S.served(m,f,X&&U2?{info:(T2,F2)=>U2.call(X,T2,F2)}:void 0)}return X?.debug("pool account chosen",{kind:V.kind,accountId:f,mode:r,...V.rerouteFrom?{rerouteFrom:V.rerouteFrom.accountId}:{}}),f}finally{if(l)J.rollback(l)}},accountHeaders:async(V)=>{let{accountId:P}=V,E=j(V),K=U.get(E);U.delete(E);let A=()=>{K?.commit()};try{let T=()=>new J2({kind:"no-account",providerID:X2,sessionID:V.sessionID,requestKind:V.kind,message:L0}),C=Y&&await Y.authority()!=="local"?void 0:Z.peek().rows.find((m)=>m.id===P);if(!C&&Y){let m=j(V),g=N.get(m)??await Y.authorize(P);if(N.delete(m),!g)throw X?.warn("the vault refused to serve an account; refusing the request",{accountId:P}),T();return A(),{headers:{...z1,"session-id":V.sessionID,authorization:`Bearer ${g.accessToken}`,"chatgpt-account-id":g.accountIdentity??d1(g.accessToken)??null},attempt:{kind:"vault",routeId:P,receipt:g}}}let y=C?Z.usableToken(C):void 0;if(!C||!y)throw X?.warn("pool row holds no usable token; refusing the request",{accountId:P}),T();let b=C.identity??d1(y);return A(),{headers:{...z1,"session-id":V.sessionID,authorization:`Bearer ${y}`,"chatgpt-account-id":b??null},attempt:{kind:"pool",token:y,credentialEpoch:C.credentialEpoch}}}finally{K?.drop()}},async rewriteRequest({request:V,sessionID:P,kind:E}){let K=$.codexEndpoint?X1(V.url,$.codexEndpoint()):V.url,A=K===V.url?V:new Request(K,V);return await m1(A,{sessionID:P,kind:E},F,$.responsesLite?.()??!1)??A},rewriteHandshakeURL:({url:V})=>$.codexEndpoint?X1(V,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:V,sessionID:P,kind:E})=>l1(V,{sessionID:P,kind:E},F),quotaFromHeaders:(V)=>C0(V),async limitFromResponse({status:V,headers:P,body:E}){if(V<400)return;let K=B1(await E().catch(()=>"")),A=v2({...V2(K)?K:{},status:V});if(!A)return;let T=z(),C=U1(A,T,V);if(C.retryAfterMs!==void 0)return C;let y=E0(P);return y===void 0?C:{...C,retryAfterMs:y}},inspectEvent:({data:V})=>M0(V,z()),limitFromError(V){let P=B1(V.message),E=v2({...V2(P)?P:{},...V.status!==void 0?{status:V.status}:{}})??(V.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return E?U1(E,z(),V.status):void 0},async onAttemptEnd(V,P){let E=V.data;if(E?.kind!=="vault"||P.status!==401)return;X?.warn("a vault account answered 401; reporting it to the vault",{accountId:V.accountId}),await Y?.reportFailure(E.receipt,401)}},h=(V,P,E)=>{let K=E.data;if(K?.kind==="vault"){Y?.recordSnapshot(V,P.snapshot,P.complete,K.receipt);return}if(K?.kind!=="pool")return;if(Z.peek().rows.find((T)=>T.id===V)?.credentialEpoch!==K.credentialEpoch){X?.debug("quota reading dropped: the row holds another credential",{accountId:V});return}Z.recordSnapshot(V,P.snapshot,K.token,P.complete)},v=(V,P,E)=>{let K=z(),A=E.data?.kind==="vault",T=A?Y?.routes().find((b)=>b.id===V)?.quota:Z.peek().rows.find((b)=>b.id===V)?.quota,C=r1(S2(T),P.reason,K,K0,P.retryAfterMs!==void 0?K+P.retryAfterMs:void 0);if(!A){Z.markRateLimited(V,C);return}let y=B.get(V);if(y===void 0||y<C)B.set(V,C)};return{adapter:w,attach(V){V.on("quota",(P)=>h(P.accountId,P.quota,P.handle)),V.on("limit",(P)=>{v(P.accountId,P.limit,P.handle),X?.debug("pool row refused the request",{accountId:P.accountId,via:P.via,reason:P.limit.reason,outputStarted:P.outputStarted})})},forgetSession(V){J.forget(V),L.forget(V),F.forget(V)},activeAccount:(V)=>L.activeAccount(V)}}import{resolve as P$}from"node:path";import{Buffer as O0}from"node:buffer";import{resolve as H$}from"node:path";function x2($){return O0.byteLength(JSON.stringify($))}function A0($){return $.reduce((Z,J)=>Z+x2(J),0)}function W1($,Z){return 2+$+Math.max(0,Z-1)}function R0($){let{head:Z,pending:J}=$;return 10+$.fieldsBytes+1+(Z?22+Z.responseIDBytes+9+W1(Z.inputBytes,Z.input.length)+1:0)+(J?20+W1(J.inputBytes,J.input.length)+10+W1(J.outputBytes,J.output.length)+(J.responseID===void 0?0:14+J.responseIDBytes)+1:0)}function N$($){try{let Z=JSON.parse($);if(Z&&typeof Z==="object"&&!Array.isArray(Z))return Z}catch{}return}class F${enabled;caps=u2;entries=new Map;bytes=0;constructor($=!1){this.enabled=$}setEnabled($){if(this.enabled=$,!$)this.entries.clear(),this.bytes=0}send($,Z){if(!this.enabled)return;let J=N$(Z);if(J?.type!=="response.create")return;if(!Array.isArray(J.input)){this.forget($);return}let z=J.previous_response_id,X=this.entries.get($),Y=X?.head;if(z&&z!==Y?.responseID){this.forget($);return}let{type:F,previous_response_id:N,input:U,...j}=J;this.keep($,{fields:z&&X?X.fields:j,fieldsBytes:z&&X?X.fieldsBytes:x2(j),...z&&Y?{head:Y}:{},pending:{input:U,inputBytes:A0(U),output:[],outputBytes:0,responseIDBytes:0},bytes:0})}receive($,Z,J){if(!this.enabled||!Z.includes("response.created")&&!Z.includes("response.output_item.done")&&!Z.includes("response.completed"))return;let z=this.entries.get($);if(!z?.pending)return;let X=N$(Z);if(!X)return;let Y=z.pending,F=X.response;if(X.type==="response.created"&&typeof F?.id==="string")Y.responseID=F.id,Y.responseIDBytes=x2(F.id),this.keep($,z);else if(X.type==="response.output_item.done"&&X.item){if(typeof X.response_id==="string"&&Y.responseID!==void 0&&X.response_id!==Y.responseID)return;Y.output.push(X.item),Y.outputBytes+=x2(X.item),this.keep($,z)}else if(X.type==="response.completed"&&typeof F?.id==="string"){if(F.id===z.head?.responseID||Y.responseID!==void 0&&F.id!==Y.responseID)return;let N={responseID:F.id,responseIDBytes:Y.responseID===F.id?Y.responseIDBytes:x2(F.id),input:[...z.head?.input??[],...Y.input,...Y.output],inputBytes:(z.head?.inputBytes??0)+Y.inputBytes+Y.outputBytes},U={...z,head:N,pending:void 0};if(!this.keep($,U))return;J?.({sessionID:$,responseID:N.responseID,bodyText:this.body(z.fields,N)})}}replay($){let Z=this.entries.get($);if(!Z?.head)return;return this.entries.delete($),this.entries.set($,Z),this.body(Z.fields,Z.head)}forget($){let Z=this.entries.get($);if(Z)this.bytes-=Z.bytes;this.entries.delete($)}status(){return{bytes:this.bytes,sessions:[...this.entries].map(([$,Z])=>({sessionID:$,bytes:Z.bytes,responseID:Z.head?.responseID,pending:Z.pending!==void 0}))}}body($,Z){return JSON.stringify({...$,input:Z.input,stream:!0})}keep($,Z){let J=R0(Z);if(this.forget($),J>this.caps.maxBytes)return!1;Z.bytes=J,this.entries.set($,Z),this.bytes+=J;while(this.entries.size>this.caps.maxTargets||this.bytes>this.caps.maxBytes){let z=this.entries.keys().next().value;if(z===void 0)break;this.forget(z)}return this.entries.has($)}}var K$=Symbol.for("@cortexkit/openai-auth/opencode2-frame-mirror"),L$=globalThis,H1=L$[K$]??new Map;L$[K$]=H1;function p2($){let Z=JSON.stringify([H$($.configPath),H$($.statePath)]),J=H1.get(Z);if(!J)J=new F$,H1.set(Z,J);return J}var S0=5000,x0=["accept","originator","session-id","thread-id","user-agent","version","x-client-request-id","x-codex-beta-features","x-codex-turn-metadata","x-codex-window-id","x-openai-internal-codex-responses-lite","x-opencode-parent-session-id","x-parent-session-id"],q0=["x-opencode-parent-session-id","x-parent-session-id"];function C$($){let Z=T$($);return{enabled:Z?.enabled===!0,subagents:Z?.subagents===!0,sustain:Z?.sustain===!0,window:_$($?{...$,cachekeep:Z}:$)}}var E$=Symbol.for("@cortexkit/openai-auth/opencode2-cache-keep"),O$=globalThis,q2=O$[E$]??new Map;O$[E$]=q2;function b0($,Z){let J=[],z=()=>J.at(-1)?.location,X=()=>{let U=z();if(!U)throw Error("no location holds keep-warm");return U},Y=(U,j)=>{N.remove(U),z()?.log?.debug(`cachekeep dropped target (${j})`,{sessionKey:U})},F=async(U)=>{if(U.meta.credentialMode!=="local")throw Error("a target captured in vault mode is not warmed with a local credential");let j=U.accountId??"main",B=X(),L=await B.source.accessFor(j,await B.storage());if(!L)throw Error(`pool row ${j} has no usable token`);return{token:L.token,identity:L.row.identity}},N=M$({...u2,now:$.now,...$.setIntervalImpl?{setIntervalImpl:$.setIntervalImpl}:{},...$.clearIntervalImpl?{clearIntervalImpl:$.clearIntervalImpl}:{},codexResponsesUrl:$.codexResponsesUrl,fetchImpl:(U,j)=>X().fetch(U,j),logger:{debug:(U,j)=>z()?.log?.debug(U,j),warn:(U,j)=>z()?.log?.warn(U,j)},getWindow:()=>z()?.settings().window,getSustain:()=>z()?.settings().sustain===!0,resolveLocal:F,vault:{owns:(U)=>z()?.vault.owns(U)===!0,authority:()=>X().vault.authority(),send:async(U,j,B)=>{let L=X();if(await L.vault.authority()!=="vault")return;return L.vault.send(U,j,B)}},activeAccount:(U)=>{if(U===void 0)throw Error("target has no session");let j=z(),B=j?.settings();if(!j||!B?.enabled){Y(U,"keep-warm is off");return}if(!B.subagents&&N.status().targets.some((S)=>S.sessionKey===U&&S.isSubagent)){Y(U,"subagent warming is off");return}let L=j.accounts.activeAccount(U);if(L===void 0){Y(U,"no account recorded for the session");return}return L},verifyCredential:({target:U,mode:j,identity:B})=>{if(U.meta.credentialMode!==j)throw Error(`a target captured in ${U.meta.credentialMode??"an unknown"} mode is not warmed with a ${j} credential`);if(B!==U.meta.chatgptAccountId)throw Y(U.sessionKey,"the account signs in as another login now"),Error("the account signs in as another login now")}});return{manager:N,settings:Z,holders:J,joinTimeoutMs:$.joinTimeoutMs??S0}}function D0($){try{let Z=JSON.parse($),J=Array.isArray(Z.input)?Z.input.at(-1):void 0;if(J?.role!=="user")return!1;return(typeof J.content==="string"?J.content:Array.isArray(J.content)?J.content.map((X)=>typeof X?.text==="string"?X.text:"").join(""):"").startsWith("This is a keep-alive request.")}catch{return!1}}function k0($){let Z={};for(let J of x0){let z=$.get(J);if(z)Z[J]=z}return Z}function A$($,Z,J){let z=JSON.stringify([P$($.configPath),P$($.statePath)]),X=q2.get(z);if(!X)X=b0(J,Z.settings()),q2.set(z,X);let Y=X,F=p2($);F.setEnabled(Y.settings.enabled);let N={location:{...Z,settings:()=>Y.settings}};Y.holders.push(N);let U=!1,j=async(B)=>{try{let L=N.location.settings();if(U||!L.enabled)return;if(B.kind!=="primary"){if(B.kind==="generate"&&D0(await B.request.clone().text())){if(U)return;Y.manager.remove(B.sessionID)}return}let S=B.attempt.data,_=S?.kind==="pool"?"local":S?.kind==="vault"?"vault":void 0;if(!_)return;let u=B.request.headers,o=q0.some((z2)=>u.has(z2))||Z.parentOf!==void 0&&await Z.parentOf(B.sessionID)!==void 0;if(o&&!L.subagents)return;let R=await B.request.clone().text();if(U)return;let k=u.get("chatgpt-account-id")??void 0;Y.manager.track({sessionKey:B.sessionID,bodyText:R,accountId:B.attempt.accountId,isSubagent:o,meta:{replayHeaders:k0(u),...k?{chatgptAccountId:k}:{},routingSessionId:B.sessionID,url:B.request.url,credentialMode:_}})}catch(L){Z.log?.warn("cachekeep capture failed",{error:L instanceof Error?L.message:String(L)})}};return{manager:Y.manager,configure:(B)=>{Object.assign(Y.settings,B),F.setEnabled(Y.settings.enabled)},capture:j,forget:(B)=>Y.manager.remove(B),async release(){if(U)return;U=!0;let B=Y.holders.indexOf(N);if(B>=0)Y.holders.splice(B,1);if(Y.holders.length>0)return;if(q2.get(z)===Y)q2.delete(z);Y.manager.stop();let L;try{await Promise.race([Y.manager.tick().catch(()=>{}),new Promise((S)=>{L=setTimeout(S,Y.joinTimeoutMs),L.unref?.()})])}finally{clearTimeout(L)}}}}import{mkdirSync as w0}from"node:fs";import{dirname as y0,join as f0,resolve as I0}from"node:path";var v0="openai-auth-sessions-opencode2.json";function h0(){return f0(S$(),v0)}var m0="sessions",g0=1e4,l0=5000,u0=25;class D${path;options;sessions;frameTurns=new A2;#$=new Set;#Z=new Set;#J=Promise.resolve();#z=!1;constructor($,Z={}){this.path=$;this.options=Z;this.sessions=q$($,Z.uuid??P2)}get($,Z=P2){let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J),this.#Z.delete($),this.#$.add($),this.save()}return J}delete($){this.sessions.delete($),this.frameTurns.forget($),this.#$.delete($),this.#Z.add($),this.save()}save(){if(!this.#z)this.#z=!0,this.#J=this.#J.then(()=>{return this.#z=!1,this.#G()});return this.#J}settled(){return this.#J}async#G(){if(this.#$.size===0&&this.#Z.size===0)return;let $=[...this.#$].flatMap((z)=>{let X=this.sessions.get(z);return X?[[z,X]]:[]}),Z=[...this.#Z],J=null;try{if(w0(y0(this.path),{recursive:!0}),J=await this.#X(),!J)return;let z;try{z=x$(this.path)}catch{z=new Map}await this.options.afterRead?.();for(let X of Z)z.delete(X);for(let[X,Y]of $)z.set(X,Y.threadID);b$(this.path,z)}catch{return}finally{await J?.release().catch(()=>{})}for(let[z,X]of $)if(this.sessions.get(z)===X)this.#$.delete(z);for(let z of Z)if(!this.sessions.has(z))this.#Z.delete(z)}async#X(){let $=performance.now()+(this.options.lockWaitMs??l0);for(;;){let Z=await R$({name:m0,path:this.path,ttlMs:g0});if(Z||performance.now()>=$)return Z;await new Promise((J)=>setTimeout(J,u0))}}}var k$=Symbol.for("@cortexkit/openai-auth/opencode2-codex-sessions"),w$=globalThis,N1=w$[k$]??new Map;w$[k$]=N1;function y$($=h0()){let Z=I0($),J=N1.get(Z);if(!J)J=new D$(Z),N1.set(Z,J);return J}var f$=Symbol.for("cortexkit.openai-auth.v2.commands");function p0(){let $=globalThis;return $[f$]??={locations:new Map},$[f$]}async function p$($,Z){let J=p0(),z=$.location.directory,X={menu:Z,session:$.session},Y=await v$(z),F=await I$(l$,Y.dir,()=>u$({...Y,drain:m$,apply:(B)=>{let L=J.locations.get(z);if(!L)throw Error("The OpenAI menu location was closed");return L.menu.apply(B)}})),N=J.locations.get(z);J.locations.set(z,X),await N?.registration?.dispose(),J.command??={name:"openai",description:"OpenAI account menu",async execute(B){let L=J.locations.values().next().value?.session;if(!L)return;let S=await L.get({sessionID:B.sessionID}),_=J.locations.get(S.location.directory);if(!_||!g$(B.sessionID))return;let u=await _.menu.open(B.sessionID);h$(u,B.sessionID)}};let U=J.command;try{X.registration=await $.command.transform((B)=>{B.add(U)})}catch(B){if(J.locations.get(z)===X)J.locations.delete(z);throw await F.release(),B}let j=!1;return async()=>{if(j)return;if(j=!0,J.locations.get(z)===X)J.locations.delete(z);await F.release(),await X.registration?.dispose()}}var c0="openai-auth-pool-browser",d0="openai-auth-pool-headless",i0="openai-auth-vault",a0="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function b2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function o$($){return{method:{id:i0,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await c$($.paths,$.name)!=="vault")throw Error(a0)}}}function r$($){let Z=(J,z,X)=>({method:{id:J,type:"oauth",label:z},async authorize(){if($.vault)await b2($.vault);let Y=await $.beginLogin({version:$.version,headless:X});return{url:Y.url,instructions:Y.instructions,mode:"auto",callback:Y.completion}}});return[Z(c0,"ChatGPT (openai-auth pool, browser)",!1),Z(d0,"ChatGPT (openai-auth pool, headless)",!0)]}function F1($){let Z=(J)=>typeof J==="string"?J:"";return O2({type:"oauth",access:Z($.access),refresh:Z($.refresh)})||$.refresh===a$||d$($)}function n0($){if($.accountId)return $.accountId;let Z=$.access?h2($.access):void 0;return Z?m2(Z):void 0}async function s$($,Z,J,z={}){if(z.vault)await b2(z.vault);if(F1(J))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let X=i$($,{rowLocks:(_)=>n$(Z,_)}),Y=await X.read();if(Y.status!=="ready")throw Error(`the account pool cannot be read (${Y.status}); the login was not stored`);let F={type:"oauth",refresh:J.refresh,...J.access!==void 0?{access:J.access}:{},...J.expires!==void 0?{expires:J.expires}:{}},N=n0(J);if(z.vault)await b2(z.vault);let U=N!==void 0?{identity:N}:{};if(z.origin==="import"){let _=Y.rows.find((u)=>N!==void 0&&u.identity===N||u.credential?.type==="oauth"&&u.credential.refresh===J.refresh);if(_)return{id:_.id,operation:"kept"}}let j=Y.rows.filter((_)=>_.type==="oauth"&&!_.invalid),B=N?j.find((_)=>_.identity===N):void 0,L=Y.rows.find((_)=>_.id===c2);if(B)return{id:(await X.replace(B.id,F,U)).id,operation:"replaced"};if(!L){let _=await X.add({id:c2,credential:F,...U,...J.label!==void 0?{label:J.label}:{}});return{id:_.id,operation:_.outcome==="added-disabled"?"added-disabled":"added"}}if(!L.invalid&&!L.credential)return{id:(await X.replace(c2,F,U)).id,operation:"replaced"};let S=await X.add({id:J.id,credential:F,...U,...J.label!==void 0?{label:J.label}:{}});return{id:S.id,operation:S.outcome==="added-disabled"?"added-disabled":S.outcome==="rotated"?"replaced":"added"}}function o0($){let Z=$.itemId!==void 0;switch($.sectionId){case"accounts":return Z?["enable","disable","remove","move"].includes($.actionId):$.actionId==="add";case"routing":return!Z&&["order","mode"].includes($.actionId);case"quota":return $.actionId==="check";case"limits":return Z?$.actionId==="floors":$.actionId==="killswitch";case"session":return!Z&&$.actionId==="clear-pin";case"diagnostics":return!Z&&["logging","dump"].includes($.actionId);case"cache":return!Z&&["enabled","subagents","sustain","window"].includes($.actionId);case"reset":return Z&&["preview","spend","retry"].includes($.actionId);default:return!1}}function $Z($){let Z={...$,allowAction:o0,unavailableSections:[]};return{open:(J)=>t$(Z,J),apply:(J)=>{let z=J!==null&&typeof J==="object"?J:{},X=z.values&&typeof z.values==="object"&&!Array.isArray(z.values)?Object.fromEntries(Object.entries(z.values).filter(([,Y])=>Y===null||["string","number","boolean"].includes(typeof Y))):void 0;return e$(Z,{command:"openai",sectionId:typeof z.sectionId==="string"?z.sectionId:"",actionId:typeof z.actionId==="string"?z.actionId:"",...X?{values:X}:{},...z.confirmed===!0?{confirmed:!0}:{},...typeof z.itemId==="string"?{itemId:z.itemId}:{},...typeof z.sessionId==="string"?{sessionId:z.sessionId}:{}})}}}function r0($){if(!ZZ($.modelID??$.id)){$.enabled=!1;return}let Z=JZ($.id);if(Z)$.limit={...Z}}function zZ($){return $.model.transform((Z)=>{for(let J of Z.list(X2))Z.update(X2,String(J.id),(z)=>r0(z))})}class K1{log;pending=new Map;requests=new Map;writing=new Set;constructor($){this.log=$}async safely($){let Z=(async()=>{try{await $()}catch{this.log.warn("request dump failed")}})();this.writing.add(Z);try{await Z}finally{this.writing.delete(Z)}}async captureHttp($,Z){if(!GZ())return;await this.safely(async()=>{let J={sessionID:Z.sessionID,accountId:Z.accountId,transport:"http",phase:"http",url:$.url,method:$.method,headers:new Headers($.headers),bodyText:await $.clone().text()};if(this.pending.set($,{attemptId:Z.attemptId,input:J}),this.requests.set(Z.attemptId,$),this.pending.size>512){let z=this.pending.keys().next().value;if(z)this.take(z)}})}take($){let Z=this.pending.get($);if(Z)this.pending.delete($),this.requests.delete(Z.attemptId);return Z?.input}async response($,Z){let J=this.take($);if(J)await this.safely(()=>d2({...J,status:Z}))}async end($,Z){if(Z.status!==void 0||!Z.error)return;let J=this.requests.get($.attemptId),z=J&&this.take(J);if(!z)return;let{reason:X,message:Y}=Z.error,F=Y?`${X}: ${Y}`:X;await this.safely(()=>d2({...z,error:i2(F,J?.headers.get("authorization")?.replace(/^Bearer /,""))}))}async frame($,Z){await this.safely(()=>d2({sessionID:Z.sessionID,accountId:Z.accountId,transport:"websocket",phase:"observed",bodyText:$}))}clear(){this.pending.clear(),this.requests.clear()}async settle(){await Promise.all(this.writing)}}class L1{counts=new Map;record($,Z){let J=Z.resetCreditsApplicable;this.counts.set($.id,{credentialEpoch:$.credentialEpoch,identity:$.identity,applicable:typeof J==="number"&&Number.isFinite(J)?J:void 0})}applicable($){let Z=this.counts.get($.id);if(!Z||Z.credentialEpoch!==$.credentialEpoch||Z.identity!==$.identity)return;return Z.applicable}}function VZ($){return async(Z)=>{let J=Z.credential;if(J.type!=="oauth"||!J.access)throw Error("the row holds no access token to poll with");let z=await XZ({accessToken:J.access,fetchImpl:$.fetchImpl,now:$.now,...Z.identity?{accountId:Z.identity}:{},accountKey:Z.id,...$.logger?{logger:$.logger}:{}});return $.counts.record(Z,z),YZ(z,$.now(),!0)}}function BZ($){let{source:Z,counts:J,now:z}=$,X=async(j)=>{let B=await Z.rowAccess(j,await $.storage());if(!B?.row)throw new QZ("unknown_account",`${j==="main"?"Main":"Fallback"} account ${j} was not found.`);return jZ(j,B)},Y=async(j)=>{if($.authority&&await $.authority()!=="local")return{account:j,ok:!1,error:"local accounts are not polled while this host is connected to the vault"};let[B]=await Z.pollRows(await $.storage(),{ids:[j]});if(!B)return{account:j,ok:!1,error:"targeted quota refresh returned no result"};return{account:B.id,ok:B.ok,...B.error!==void 0?{error:B.error}:{}}},F=(j)=>Z.peek().rows.find((B)=>B.id===j),N=(j)=>{let B=F(j);if(!B)return null;let L=S2(B.quota)??{},S=J.applicable(B),_=Math.max(0,...[L.primary?.checkedAt,L.secondary?.checkedAt].filter((u)=>typeof u==="number"));return{quota:{...L,...S!==void 0?{resetCreditsApplicable:S}:{}},checkedAt:_,refreshAfter:_,...B.identity!==void 0?{accountId:B.identity}:{}}};return{resolveResetTarget:X,refreshResetTargetQuota:Y,quotaManager:{isRateLimited:(j)=>{let B=F(j);if(!B)return!1;let L=Z.rateLimitMarks([B]).get(B.id);return L!==void 0&&L>z()},getMain:()=>N("main"),getFallback:(j)=>N(j)}}}import{resolve as UZ}from"node:path";var s0=1024;class P1{pins=new Map;reservations=new Map;listeners=new Set;limit;constructor($=s0){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.reservations.delete($),this.pins.delete($);for(let Z of this.listeners)Z($)}subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}snapshot(){return new Map(this.pins)}placementSnapshot($){let Z=new Map(this.pins);for(let J of this.reservations.values())if(J.sessionId!==$)Z.set(J.sessionId,J.pin);return Z}reserve($,Z){let J={sessionId:$,previous:this.pins.get($),pin:Z};return this.reservations.set($,J),J}rollback($){if(this.reservations.get($.sessionId)===$)this.reservations.delete($.sessionId)}finish($,Z){if(this.reservations.get($.sessionId)!==$)return;if(this.rollback($),Z&&this.pins.get($.sessionId)===$.previous)this.set($.sessionId,Z)}get size(){return this.pins.size}set($,Z){this.reservations.delete($),this.pins.delete($),this.pins.set($,Z);for(let J of this.listeners)J($,Z);while(this.pins.size>this.limit){let J=this.pins.keys().next().value;if(J===void 0)break;this.forget(J)}}place($){return g2(this.placementSnapshot($.sessionId),$,(Z,J)=>this.set(Z,J))}}var WZ=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),HZ=globalThis,T1=HZ[WZ]??new Map;HZ[WZ]=T1;function NZ($){let Z=JSON.stringify([UZ($.configPath),UZ($.statePath)]),J=T1.get(Z);if(!J)J=new P1,T1.set(Z,J);return J}import{statSync as t0}from"node:fs";import{resolve as e0}from"node:path";function EZ($){return $.map((Z)=>{try{let J=t0(Z);return`${J.ino}:${J.size}:${J.mtimeMs}:${J.ctimeMs}`}catch{return"?"}}).join("|")}function _1($){return EZ([$.vault.paths.tokenPath,$.vault.paths.statePath])}function FZ($){return EZ([$.paths.configPath,$.paths.statePath,$.vault.paths.rosterPath])+_1($)}class OZ{file;observationIntervalMs;producers=new Set;subscriptions=new Map;observations=new Map;chain=Promise.resolve();timer;constructor($,Z){this.file=$;this.observationIntervalMs=Z}add($){this.producers.add($),this.observations.set($,{stamp:FZ($),roster:$.vault.snapshot()});let Z=$.source.subscribe(()=>{this.publish($)}),J=this.subscriptions.get($.pins);if(!J){let z=new Set;J={producers:z,stop:$.pins.subscribe((X,Y)=>{let F=z.values().next().value;if(F)this.publish(F,{sessionId:X,pin:Y,accountId:Y?.accountId,route:"sticky-balanced"})})},this.subscriptions.set($.pins,J)}return J.producers.add($),this.timer??=setInterval(()=>{for(let z of this.producers){let X={stamp:FZ(z),roster:z.vault.snapshot()},Y=this.observations.get(z);if(X.stamp!==Y?.stamp||X.roster!==Y?.roster)this.observations.set(z,X),this.publish(z)}},this.observationIntervalMs),this.timer.unref?.(),()=>{if(Z(),this.producers.delete($),this.observations.delete($),J.producers.delete($),!J.producers.size)J.stop(),this.subscriptions.delete($.pins);if(!this.producers.size)clearInterval(this.timer),this.timer=void 0}}publish($,Z){return this.chain=this.chain.then(async()=>{if(!this.producers.has($))return;let z=await $.vault.authority()!=="local",X=_1($),Y=()=>this.producers.has($)&&$.vault.enrolled()===z&&_1($)===X,F=await B2($.paths),N=z?MZ($.vault.snapshot()?.rows??[],new Set($.vault.routes().map((j)=>j.id)),F,Date.now()):CZ((await $.source.sidebarView()).rows,F,Date.now());if(await LZ(N,this.file,{canWrite:Y}),!Y()||!Z)return;let U=N.vaultAccounts??N.fallbacks;if(Z.accountId===void 0){await TZ(Z.sessionId,U,this.file,{canWrite:Y});return}if(Z.pin){let j=Date.now();await _Z({sessionId:Z.sessionId,assignment:{accountId:Z.pin.accountId,wireAccountId:Z.pin.wireIdentity,inputBytes:Z.pin.inputBytes??0,quotaCheckedAt:Z.pin.quotaCheckedAt,assignedAt:j,lastSeenAt:j},validPinnedAccountIds:[...z?[]:["main"],...U.filter((B)=>B.enabled).map((B)=>B.id)]},this.file)}await PZ({sessionId:Z.sessionId,activeId:Z.accountId,route:Z.route??N.route,updatedAt:Date.now()},U,this.file,{canWrite:Y})}).catch(()=>{N2("opencode2").warn("sidebar publication failed")}),this.chain}settled(){return this.chain}get empty(){return this.producers.size===0}}var AZ=Symbol.for("@cortexkit/openai-auth/opencode2-sidebar-publishers"),RZ=globalThis,D2=RZ[AZ]??new Map;RZ[AZ]=D2;function SZ($,Z=KZ(),J=2000){let z=e0(Z),X=D2.get(z);if(!X)X=new OZ(z,J),D2.set(z,X);let Y=X,F=Y.add($),N=!1;for(let[U,j]of $.pins.snapshot())Y.publish($,{sessionId:U,pin:j,accountId:j.accountId,route:"sticky-balanced"});return{publish:()=>Y.publish($),route:(U,j,B)=>{Y.publish($,{sessionId:U,accountId:j,route:B})},async release(){if(N)return;if(N=!0,F(),await Y.settled(),Y.empty&&D2.get(z)===Y)D2.delete(z)}}}var o2="cortexkit-openai-auth",J4=5000;async function xZ($,Z,J,z=new R2,X,Y,F){let N=new K1(J),U=new $4,j=new Map,B=new Map,L=(R)=>{B.delete(R);for(let k of j.keys())if(k.startsWith(`${R}:`))j.delete(k)},S=(R)=>{F?.(R.sessionID),Y?.send(R.sessionID,R.frame)},u=await Z1({session:{hook:(R,k,z2)=>$.session.hook(R,async(w)=>{let h=R==="http.request"?w:void 0,v=R==="experimental.ws.handshake"?w:void 0,P=(h?h.request.headers:v?new Headers(v.headers):void 0)?.get("authorization")===`Bearer ${Q2(Z.providerID)}`,E={};if(v)j.delete(`${v.sessionID}:${v.kind}`);try{await U.run(E,()=>k(w))}catch(K){if(P&&!(K instanceof J2))throw yZ(K);throw K}if(h&&P&&E.attempt){let K=h.request.headers.get("thread-id");if(K)h.request.headers.set("session-id",K)}if(h&&P&&E.attempt)await N.captureHttp(h.request,E.attempt);if(h&&P&&E.attempt)await X?.({sessionID:h.sessionID,kind:h.kind,request:h.request,attempt:E.attempt});if(v&&P&&E.attempt)v.headers["session-id"]=z.get(v.sessionID).threadID;if(R==="experimental.ws.send"){let K=w,A=j.get(`${K.sessionID}:${K.kind}`);if(A)await N.frame(K.frame,A.attempt);if(A&&K.kind==="primary")S(K)}if(h||v){let K=h??v;if(!K)return;let T=(h?h.request.headers:new Headers(K.headers)).get("authorization")?.replace(/^Bearer /,"");if(P&&T)B.set(K.sessionID,T);else B.delete(K.sessionID);if(v){let C=`${v.sessionID}:${v.kind}`;if(P&&T&&E.attempt)j.set(C,{bearer:T,attempt:E.attempt,url:v.url,headers:new Headers(Object.entries(v.headers).filter(([y])=>["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"].includes(y.toLowerCase())))});else j.delete(C)}if(B.size>512){let C=B.keys().next().value;if(C)B.delete(C)}if(j.size>512){let C=j.keys().next().value;if(C)j.delete(C)}}else if(R==="experimental.ws.receive"){let K=w,A=j.get(`${K.sessionID}:${K.kind}`);if(A){if(z.frameReceived(K.sessionID,K.frame),K.kind==="primary"){let T;if(Y?.receive(K.sessionID,K.frame,(C)=>{T=C}),T)try{let C=g1(T,A.url,A.headers,z);if(C)await X?.({sessionID:K.sessionID,kind:"primary",request:C,attempt:A.attempt})}catch(C){J.warn("cachekeep WebSocket capture failed",{error:C instanceof Error?C.message:String(C)})}}K.frame=fZ(K.frame,A.bearer)}}else if(R==="retry"){let K=w,A=B.get(K.sessionID);if(A)Object.assign(K.error,{message:i2(K.error.message,A)})}},z2)},event:{subscribe:(R)=>async function*(){for await(let k of $.event.subscribe(R)){if(k.type==="session.deleted")L(k.data.sessionID);yield k}}()}},{...Z,rewriteRequest:async(R)=>{let k=U.getStore();if(k)k.attempt=R.attempt;return Z.rewriteRequest?.(R)},rewriteHandshakeURL:(R)=>{let k=U.getStore();if(k)k.attempt=R.attempt;return Z.rewriteHandshakeURL?.(R)},onAttemptEnd:async(R,k)=>{await N.end(R,k),await Z.onAttemptEnd?.(R,k)},rewriteResponse:async(R)=>{await N.response(R.request,R.response.status);let k=await Z.rewriteResponse?.(R)??R.response;return IZ(k,R.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(R)=>{let k=R.get("authorization");return k?.startsWith("Bearer ")?k.slice(7):void 0}},logger:{warn:(R,k)=>J.warn(R,{data:k})}}),o=u.dispose;return{...u,dispose:async()=>{B.clear(),j.clear(),await o(),await N.settle(),N.clear()}}}function E1($={}){return{id:o2,setup:(Z)=>z4(Z,$)}}async function z4($,Z={}){let a=[];try{let J=N2("opencode2");let z=N2("quota");let X=Z.paths??(()=>hZ(vZ()));let Y=await B2(X());let F=Y?.logging?.level;if(F&&typeof F==="string")bZ(F);let N=Z.fetch??fetch;let U=Z.now??Date.now;let j=Z.version??pZ;let B=Z.poolMigration??rZ;if(!B&&!C2(X().configPath)){J.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let M=(Y2)=>{throw new J2({kind:"no-account",providerID:X2,sessionID:Y2.sessionID,requestKind:Y2.kind,message:l2})},d=await xZ($,{providerID:X2,chooseAccount:M,accountHeaders:M},J);return()=>d.dispose()}let L=Z.vault?.firstRosterWaitMs??dZ;let S=oZ({host:"opencode",stateDir:Z.vault?.stateDir??wZ(X().statePath),reservedRouteIds:()=>w.peek().rows.map((M)=>M.id),...Z.vault?.connectionFile?{connectionFile:Z.vault.connectionFile}:{},...Z.vault?.connectScoped?{connectScoped:Z.vault.connectScoped}:{},...Z.vault?.connectEnrollment?{connectEnrollment:Z.vault.connectEnrollment}:{},...Z.vault?.pollIntervalMs!==void 0?{pollIntervalMs:Z.vault.pollIntervalMs}:{},fetchImpl:()=>N},X());let _=S.vault;let u=!1;let o=!1;const R=a2(a,{[Symbol.dispose](){if(!u)S.release()}},0);await _.authority();let k=S.firstRoster;let z2=new L1;let w=new iZ({paths:X,refreshProvider:async(M)=>{let d=await kZ({refreshToken:M.refresh,fetchImpl:N,now:U}),Y2=DZ({id_token:"",access_token:d.access,refresh_token:d.refresh});return{...d,...Y2?{identity:Y2}:{}}},pullQuota:VZ({fetchImpl:N,now:U,counts:z2,logger:z}),now:U,vaultIdentities:()=>_.identities(),vaultMode:()=>_.enrolled(),vaultAuthority:()=>_.authority(),vaultFirstRoster:k,vaultFirstRosterBackgroundWaitMs:L,log:N2("pool")});await w.load();let h=Z.heartbeat===!1?void 0:await nZ({version:j,logger:N2("heartbeat")});let v=Z.fence??(()=>uZ({currentVersion:j}));let V=Z.slot??sZ();let P=async()=>mZ(X(),await V.get({path:{id:"openai"}}));let E=!1;let K=B?aZ({paths:X,slot:V,version:j,fence:v,runDeps:{vaultServes:()=>_.serves()},paused:async()=>await _.authority()!=="local",migrate:async(M)=>{let d=await gZ(M);if(E=d.status==="refused",!o)await w.load();return d},adopt:async(M)=>{if(o)return{status:"retry",reason:"unsettled"};if(!await C1(k,L))return{status:"retry",reason:"vault-roster-pending"};if(o)return{status:"retry",reason:"unsettled"};let d=await lZ(M);if(!o)await w.load();return d}}):void 0;K?.start();S.start();let A=NZ(X());let T=SZ({paths:X(),source:w,pins:A,vault:_},Z.sidebarStateFile,Z.sidebarObservationIntervalMs);const C=a2(a,{[Symbol.dispose](){if(!u)T.release()}},0);T.publish();let y=Z.codex??new R2(void 0,void 0,y$());let b=C$(Y);let m=p2(X());let g=A$(X(),{source:w,storage:()=>B2(X()),vault:_,accounts:Q1(X()),settings:()=>b,parentOf:async(M)=>(await $.session.get({sessionID:M}))?.parentID??void 0,fetch:N,log:N2("cachekeep")},{now:U,codexResponsesUrl:n2().codexApiEndpoint,...Z.cacheKeep});const r=a2(a,{[Symbol.dispose](){if(!u)g.release()}},0);let e=W$({codex:y,onRoute:T.route,source:w,slotPlaceholderWithoutMain:P,storage:()=>B2(X()),pins:A,sessionAccounts:Q1(X()),vault:_,awaitVaultRoster:async()=>{await C1(_.awaitRequestRoster(),cZ)},responsesLite:()=>n2().responsesLite,codexEndpoint:()=>n2().codexApiEndpoint,now:U,log:J});let c=await xZ($,e.adapter,J,y,(M)=>g.capture(M),m,(M)=>g.forget(M));e.attach(c);let s=async(M)=>{if(await b2(_),C2(X().configPath))return;if(await K?.idle(),C2(X().configPath))return;if(E&&!F1(M)&&(await v()).open){await w.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let l=async(M)=>{await s(M);let d=await s$(w.poolStore(),X(),M,{vault:_});if(!C2(X().configPath))await K?.requestAdoption();await w.load(),J.info("ChatGPT login stored in the account pool",d)};let f=await t2($,{integrationID:X2,methods:r$({beginLogin:Z.beginLogin??M1,version:j,vault:_}),onLogin:(M)=>l(M),label:"ChatGPT (openai-auth account pool)",vault:o$(_)});let I=await zZ($);if(Z.controlPlane&&(!$.command||!$.location))throw Error("OpenCode 2 control plane requires command and location APIs");let $2=$.command&&$.location?await p$({session:$.session,command:$.command,location:$.location},Z.controlPlane??$Z({...BZ({source:w,storage:()=>B2(X()),counts:z2,now:U,authority:()=>_.authority()}),fetchImpl:N,now:U,randomUUID:Z4,accountStoragePath:X().configPath,accountStatePath:X().statePath,packageVersion:j,loadAccounts:B2,store:()=>w.poolStore(),migration:async()=>{if(C2(X().configPath))return{migrated:!0};let M=await v();return{migrated:!1,blockers:M.open?[]:M.blockers}},beginAccountLogin:Z.beginLogin??M1,refreshAllQuota:async()=>(await w.pollRows(await B2(X()))).map((M)=>({...M,account:M.id})),getStickyRouting:async(M)=>A.get(M),cacheKeepManager:g.manager,setCacheKeepEnabled:(M)=>g.configure({enabled:M}),setCacheKeepSubagents:(M)=>g.configure({subagents:M}),setCacheKeepSustain:(M)=>g.configure({sustain:M}),setCacheKeepWindow:(M)=>g.configure({window:M}),afterWrite:()=>w.load(),refreshSidebar:()=>T.publish(),clearStickyRouting:async(M)=>{let d=A.get(M)!==void 0;return A.forget(M),d},vault:_})):void 0;let p=new AbortController;(async()=>{try{for await(let M of $.event.subscribe({signal:p.signal}))if(M.type==="session.deleted")e.forgetSession(M.data.sessionID),g.forget(M.data.sessionID),m.forget(M.data.sessionID)}catch(M){if(!p.signal.aborted)J.warn("stopped listening for session deletion",{error:M instanceof Error?M.message:String(M)})}})();u=!0;return async()=>{o=!0,p.abort();let M=g.release();await $2?.(),K?.dispose(),await w.dispose(),await T.release(),await Promise.allSettled([c.dispose(),f.dispose(),I.dispose()]);let d;try{await Promise.race([Promise.all([K?.idle(),w.settled(),y.store?.settled(),M]),new Promise((Y2)=>{d=setTimeout(Y2,J4),d.unref?.()})])}finally{clearTimeout(d),S.release(),await h?.release()}}}catch(U2){var T2=U2,F2=1}finally{qZ(a,T2,F2)}}var G4=E1(),R6={id:o2,setup:G4.setup,server:tZ.server};export{R6 as default,E1 as createOpenAIAuthPlugin,o2 as OPENAI_AUTH_PLUGIN_ID};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/opencode-openai-auth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@ai-sdk/openai": "3.0.88",
|
|
69
|
-
"@cortexkit/common-auth": "^0.
|
|
69
|
+
"@cortexkit/common-auth": "^0.26.0",
|
|
70
70
|
"@cortexkit/openai-auth-core": "workspace:*",
|
|
71
71
|
"@opencode/plugin": "2.0.32"
|
|
72
72
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { createLogger } from "./cc9e0702a752cea7-index.js";
|
|
3
3
|
import { isQuotaObservation } from "./d5a8f1061ee2f114-index.js";
|
|
4
|
+
import { quotaFields } from "./e1c5e56df0ba4053-pending.js";
|
|
4
5
|
import { applyVaultQuota, mutateVaultRoster, } from "./30f5bc480f31f51c-roster.js";
|
|
5
6
|
// Every consumer of the same file shares one mailbox and one lock waiter.
|
|
6
7
|
const writers = new Map();
|
|
@@ -34,65 +35,14 @@ export function retainVaultQuotaWriter(path, listener) {
|
|
|
34
35
|
return writer.listeners.size ? Promise.resolve() : drainVaultQuota(path);
|
|
35
36
|
})());
|
|
36
37
|
}
|
|
37
|
-
//
|
|
38
|
-
// window (scope and label), each covered-but-unread window, the budget, each
|
|
39
|
-
// counter and the credits record. The mailbox keeps the newest of each part on
|
|
40
|
-
// its own, so a later observation that carries only some parts can't erase an
|
|
41
|
-
// older but still newest reading of another part, which is how
|
|
42
|
-
// mergeQuotaObservation treats them on disk. Each key also carries the
|
|
43
|
-
// receipt's identity, so the identity fence still applies to every part.
|
|
38
|
+
// Each field retains the receipt fence as well as its independent timestamp.
|
|
44
39
|
function fields(publication) {
|
|
45
|
-
|
|
46
|
-
const { observation } = publication;
|
|
47
|
-
const witness = JSON.stringify([
|
|
40
|
+
return quotaFields(publication, JSON.stringify([
|
|
48
41
|
publication.routeId,
|
|
49
42
|
publication.receipt?.credentialId,
|
|
50
43
|
publication.receipt?.accountIdentitySource,
|
|
51
44
|
publication.receipt?.expectedAccountIdentity,
|
|
52
|
-
]);
|
|
53
|
-
const add = (key, at, part) => result.set(`${witness}:${key}`, {
|
|
54
|
-
at,
|
|
55
|
-
order: 0,
|
|
56
|
-
publication: { ...publication, observation: part },
|
|
57
|
-
});
|
|
58
|
-
const keyFor = (scope, label) => JSON.stringify([scope ?? 'all', label]);
|
|
59
|
-
const read = new Set();
|
|
60
|
-
for (const reading of observation.readings ?? []) {
|
|
61
|
-
const key = keyFor(reading.scope, reading.label);
|
|
62
|
-
read.add(key);
|
|
63
|
-
add(key, observation.checkedAt, {
|
|
64
|
-
checkedAt: observation.checkedAt,
|
|
65
|
-
readings: [{ ...reading }],
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
for (const pair of observation.coverage ?? []) {
|
|
69
|
-
const key = keyFor(pair.scope, pair.label);
|
|
70
|
-
if (!read.has(key))
|
|
71
|
-
add(key, observation.checkedAt, {
|
|
72
|
-
checkedAt: observation.checkedAt,
|
|
73
|
-
coverage: [{ ...pair }],
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
if (observation.budget)
|
|
77
|
-
add('budget', observation.checkedAt, {
|
|
78
|
-
checkedAt: observation.checkedAt,
|
|
79
|
-
budget: { ...observation.budget },
|
|
80
|
-
});
|
|
81
|
-
for (const [name, counter] of Object.entries(observation.counters ?? {})) {
|
|
82
|
-
add(`counter:${name}`, counter.checkedAt, {
|
|
83
|
-
checkedAt: observation.checkedAt,
|
|
84
|
-
counters: { [name]: { ...counter } },
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
if (observation.credits)
|
|
88
|
-
add('credits', observation.credits.checkedAt, {
|
|
89
|
-
checkedAt: observation.checkedAt,
|
|
90
|
-
credits: { ...observation.credits },
|
|
91
|
-
});
|
|
92
|
-
// Even an empty observation can bind an account proved by its receipt.
|
|
93
|
-
if (!result.size)
|
|
94
|
-
add('empty', observation.checkedAt, { checkedAt: observation.checkedAt });
|
|
95
|
-
return result;
|
|
45
|
+
]));
|
|
96
46
|
}
|
|
97
47
|
/** Enqueue without filesystem work; each quota field retains its own receipt fence. */
|
|
98
48
|
export function enqueueVaultQuota(path, publication) {
|
|
@@ -1,8 +1,41 @@
|
|
|
1
1
|
import { PoolOperationError } from "./04a6357627de5ed0-errors.js";
|
|
2
|
-
import { toFailure, withTransaction } from "./458b934e92490331-mutate.js";
|
|
2
|
+
import { toFailure, withTransaction, } from "./458b934e92490331-mutate.js";
|
|
3
3
|
import { LockStack } from "./43fc9e6b994519c7-refresh-lock.js";
|
|
4
4
|
import { refusal, requireBound, unknownRow, } from "./83bc3ba9d0fe2761-runtime.js";
|
|
5
5
|
import { isCredentialEpoch } from "./cd94316a888b0a8e-schema.js";
|
|
6
|
+
export function assertQuotaEpoch(id, attribution) {
|
|
7
|
+
if (!isCredentialEpoch(attribution?.credentialEpoch))
|
|
8
|
+
throw refusal('pull', id, 'invalid-input', 'the credential epoch the reading was issued for must be a positive safe integer');
|
|
9
|
+
}
|
|
10
|
+
// Shared by preflight and the locked commit: accepting into memory must never
|
|
11
|
+
// hide a refusal the immediate writer would have returned to its caller.
|
|
12
|
+
export function assertQuotaRow(id, attribution, row) {
|
|
13
|
+
if (!row)
|
|
14
|
+
throw unknownRow('pull', id);
|
|
15
|
+
if (row.invalid)
|
|
16
|
+
throw refusal('pull', id, 'invalid-row', `row ${id} is invalid`);
|
|
17
|
+
if (!row.credential)
|
|
18
|
+
throw refusal('pull', id, 'no-credential', `row ${id} holds no credential`);
|
|
19
|
+
requireBound('pull', row);
|
|
20
|
+
if (row.torn ||
|
|
21
|
+
!row.hasEntry ||
|
|
22
|
+
row.credentialEpoch !== attribution.credentialEpoch ||
|
|
23
|
+
row.identity !== attribution.identity)
|
|
24
|
+
throw new PoolOperationError({
|
|
25
|
+
operation: 'pull',
|
|
26
|
+
rowId: id,
|
|
27
|
+
phase: 'pull',
|
|
28
|
+
retryable: true,
|
|
29
|
+
kind: 'attribution',
|
|
30
|
+
message: `quota for ${id} was issued for a credential the row no longer holds`,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function mergedQuota(ctx, id, stored, observation) {
|
|
34
|
+
const merged = ctx.codec.merge(stored, observation);
|
|
35
|
+
if (!ctx.codec.validate(merged))
|
|
36
|
+
throw refusal('pull', id, 'invalid-quota', 'the quota codec rejected the merged map');
|
|
37
|
+
return merged;
|
|
38
|
+
}
|
|
6
39
|
/**
|
|
7
40
|
* Merges a quota observation into a row's stored map under the store locks,
|
|
8
41
|
* after attribution passes. Needs no row lock, so it is permitted from
|
|
@@ -13,37 +46,18 @@ export async function recordQuota(rt, id, attribution, observation) {
|
|
|
13
46
|
const locks = new LockStack(ctx.lockDefaults, ctx.lockEnv);
|
|
14
47
|
const progress = { writes: 0 };
|
|
15
48
|
try {
|
|
16
|
-
|
|
17
|
-
throw refusal('pull', id, 'invalid-input', 'the credential epoch the reading was issued for must be a positive safe integer');
|
|
49
|
+
assertQuotaEpoch(id, attribution);
|
|
18
50
|
await withTransaction(ctx, locks, progress, { operation: 'pull', rowId: id }, async (tx) => {
|
|
19
51
|
tx.assertNotStaged(id);
|
|
20
52
|
const row = tx.row(id);
|
|
21
|
-
if (!row)
|
|
22
|
-
throw unknownRow('pull', id);
|
|
23
|
-
if (row.invalid)
|
|
24
|
-
throw refusal('pull', id, 'invalid-row', `row ${id} is invalid`);
|
|
25
53
|
// A reading belongs to one (epoch, identity, credential). A row
|
|
26
54
|
// holding no credential, or torn between the writes of a replace,
|
|
27
55
|
// has no such triple on disk, so no reading is recorded for it.
|
|
28
|
-
|
|
29
|
-
throw refusal('pull', id, 'no-credential', `row ${id} holds no credential`);
|
|
30
|
-
requireBound('pull', row);
|
|
56
|
+
assertQuotaRow(id, attribution, row);
|
|
31
57
|
const entry = tx.entry(id);
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
row.identity !== attribution.identity)
|
|
36
|
-
throw new PoolOperationError({
|
|
37
|
-
operation: 'pull',
|
|
38
|
-
rowId: id,
|
|
39
|
-
phase: 'pull',
|
|
40
|
-
retryable: true,
|
|
41
|
-
kind: 'attribution',
|
|
42
|
-
message: `quota for ${id} was issued for a credential the row no longer holds`,
|
|
43
|
-
});
|
|
44
|
-
const merged = ctx.codec.merge(entry.quota, observation);
|
|
45
|
-
if (!ctx.codec.validate(merged))
|
|
46
|
-
throw refusal('pull', id, 'invalid-quota', 'the quota codec rejected the merged map');
|
|
58
|
+
if (!entry)
|
|
59
|
+
throw unknownRow('pull', id);
|
|
60
|
+
const merged = mergedQuota(ctx, id, entry.quota, observation);
|
|
47
61
|
tx.setEntry(id, { ...entry, quota: merged, needsFirstReading: false });
|
|
48
62
|
await tx.commitConfig();
|
|
49
63
|
},
|
|
@@ -105,7 +105,9 @@ export class PullScheduler {
|
|
|
105
105
|
cause,
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
|
-
|
|
108
|
+
const publish = rt.publishQuota ??
|
|
109
|
+
((rowId, attribution, value) => recordQuota(rt, rowId, attribution, value));
|
|
110
|
+
await publish(id, {
|
|
109
111
|
credentialEpoch: request.credentialEpoch,
|
|
110
112
|
...(request.identity !== undefined
|
|
111
113
|
? { identity: request.identity }
|
|
@@ -3,6 +3,7 @@ import { initializePool, readPool, } from "./458b934e92490331-mutate.js";
|
|
|
3
3
|
import { updateProviderStateRow, } from "./97484d9bb98c705b-provider-state.js";
|
|
4
4
|
import { publication, publishRoster, } from "./83068c0dbe8a6f13-publication.js";
|
|
5
5
|
import { PullScheduler } from "./a910277ac43a8626-pull.js";
|
|
6
|
+
import { PoolQuotaWriter } from "./c911dbb64c9d85c7-quota-writer.js";
|
|
6
7
|
import { refreshRow, } from "./9d3fc9e37456504e-refresh.js";
|
|
7
8
|
import { POOL_LOCK_DEFAULTS, } from "./43fc9e6b994519c7-refresh-lock.js";
|
|
8
9
|
import { addRow, disableRow, enableRow, recordRowIdentity, removeRow, reorderRows, replaceRow, rotateRow, } from "./fe02abeadc535f77-rows.js";
|
|
@@ -80,9 +81,21 @@ export function openPoolStore(options) {
|
|
|
80
81
|
rowLockOptions: options.rowLockOptions ?? {},
|
|
81
82
|
firePull: (id, reason) => pulls.fire(id, reason),
|
|
82
83
|
};
|
|
84
|
+
const quotaWriter = options.coalesceQuota
|
|
85
|
+
? new PoolQuotaWriter(rt, options.quotaDrainTimeoutMs)
|
|
86
|
+
: undefined;
|
|
87
|
+
const record = (id, attribution, observation) => quotaWriter
|
|
88
|
+
? quotaWriter.record(id, attribution, observation)
|
|
89
|
+
: recordQuota(rt, id, attribution, observation);
|
|
90
|
+
rt.publishQuota = record;
|
|
91
|
+
const overlay = (result) => {
|
|
92
|
+
if (result.status === 'ready' && quotaWriter)
|
|
93
|
+
return { ...result, rows: quotaWriter.overlay(result.rows) };
|
|
94
|
+
return result;
|
|
95
|
+
};
|
|
83
96
|
return {
|
|
84
97
|
async load() {
|
|
85
|
-
const result = await readPool(ctx);
|
|
98
|
+
const result = overlay(await readPool(ctx));
|
|
86
99
|
if (result.status === 'ready') {
|
|
87
100
|
// A torn row is no candidate, but its pull is fired too: the pull
|
|
88
101
|
// completes the row on disk before reading it, so an interrupted
|
|
@@ -96,7 +109,7 @@ export function openPoolStore(options) {
|
|
|
96
109
|
return toLoad(result);
|
|
97
110
|
},
|
|
98
111
|
async read() {
|
|
99
|
-
return toLoad(await readPool(ctx));
|
|
112
|
+
return toLoad(overlay(await readPool(ctx)));
|
|
100
113
|
},
|
|
101
114
|
async initialize(input = {}) {
|
|
102
115
|
return { status: await initializePool(ctx, input.dropKeys ?? []) };
|
|
@@ -115,7 +128,9 @@ export function openPoolStore(options) {
|
|
|
115
128
|
updateSettings: (mutator, callOptions) => updatePoolSettings(rt, mutator, callOptions),
|
|
116
129
|
recordIdentity: (id, identity, attribution, callOptions) => recordRowIdentity(rt, id, identity, attribution, callOptions),
|
|
117
130
|
refresh: (id, provider, callOptions) => refreshRow(rt, id, provider, callOptions),
|
|
118
|
-
recordQuota:
|
|
131
|
+
recordQuota: record,
|
|
132
|
+
close: () => quotaWriter?.close() ?? Promise.resolve(),
|
|
133
|
+
dispose: () => quotaWriter?.close() ?? Promise.resolve(),
|
|
119
134
|
requestReading: (id) => pulls.fire(id, 'admission'),
|
|
120
135
|
pullsSettled: () => pulls.settled(),
|
|
121
136
|
};
|