copilot-api-node20 0.20.3 → 0.20.5

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/README.md CHANGED
@@ -3,12 +3,25 @@
3
3
  [![npm version](https://img.shields.io/npm/v/copilot-api-node20?color=0969da&label=npm&logo=npm&logoColor=white)](https://www.npmjs.com/package/copilot-api-node20)
4
4
  [![downloads](https://img.shields.io/npm/dm/copilot-api-node20?color=0969da&logo=npm&logoColor=white)](https://www.npmjs.com/package/copilot-api-node20)
5
5
  ![Node.js](https://img.shields.io/badge/node-%E2%89%A5%2020-339933?logo=nodedotjs&logoColor=white)
6
- [![GitHub](https://img.shields.io/badge/github-johnib%2Fcopilot--api-24292e?logo=github&logoColor=white)](https://github.com/johnib/copilot-api)
6
+ [![GitHub](https://img.shields.io/badge/github-johnib%2Fcopilot--api--issues-24292e?logo=github&logoColor=white)](https://github.com/johnib/copilot-api-issues)
7
7
  ![Closed Source](https://img.shields.io/badge/source-closed-6c737a)
8
8
  [![License: MIT](https://img.shields.io/badge/license-MIT-22863a)](./LICENSE)
9
9
 
10
10
  A proxy server that turns a GitHub Copilot subscription into fully compatible OpenAI and Anthropic API endpoints. Use Claude Code, Codex CLI, and any tool that speaks the API -- all through the Copilot plan you already pay for, no separate API keys required.
11
11
 
12
+ ```
13
+ Clients Proxy Backends
14
+ ─────── ───── ────────
15
+
16
+ Claude Code ─┐ ┌─▶ GitHub Copilot API
17
+ Codex CLI ─┤ Anthropic ┌────────────┐ │ Chat Completions
18
+ OpenAI SDK ─┼──────or───────▶│ copilot-api │───┤ Responses API
19
+ curl ─┤ OpenAI └────────────┘ │ Embeddings
20
+ Any tool ─┘ format │
21
+ └─▶ Tavily
22
+ Web Search
23
+ ```
24
+
12
25
  ---
13
26
 
14
27
  ## Table of Contents
package/dist/main.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{A as e,B as t,C as o,D as n,E as a,F as r,G as s,H as i,I as l,J as c,K as u,L as p,M as d,N as m,O as _,P as f,R as g,S as y,T as h,U as b,V as k,W as w,X as v,Y as x,Z as A,_ as $,a as T,b as S,c as O,d as I,f as q,g as N,h as P,i as j,j as C,k as E,l as R,m as D,n as M,o as H,p as F,q as B,r as J,s as L,t as U,u as K,v as W,w as z,x as G,y as V,z as Y}from"./get-user-BfOVRifT.mjs";import{defineCommand as Q,runMain as X}from"citty";import Z from"consola";import ee from"node:fs/promises";import te from"node:os";import{SpanKind as oe,SpanStatusCode as ne,context as ae,trace as re}from"@opentelemetry/api";import{Client as se}from"undici";import ie from"clipboardy";import le from"node:process";import{serve as ce}from"srvx";import ue from"tiny-invariant";import{execSync as pe}from"node:child_process";import{Hono as de}from"hono";import{cors as me}from"hono/cors";import{streamSSE as _e}from"hono/streaming";import{events as fe}from"fetch-event-stream";import{Tokenizer as ge,models as ye}from"ai-tokenizer";import*as he from"ai-tokenizer/encoding/claude";const be=async()=>{let e=`${j}/copilot_internal/v2/token`,t=x.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await b({spanName:"github GET /copilot_internal/v2/token",url:e,target:"copilot_token",headers:K(x),signal:o.signal});if(!t.ok)throw n.end(),new M("Failed to get Service token",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}};const ke=e=>new Promise(t=>{setTimeout(t,e)});async function we(){x.models=await(async()=>{let e=`${O(x)}/models`,t=R(x),o=x.timeoutMs,n=new AbortController,a=setTimeout(()=>n.abort(),o);try{let{response:o,span:a}=await b({spanName:"copilot GET /models",url:e,target:"models",headers:t,signal:n.signal});if(!o.ok)throw a.end(),new M("Failed to get models",o);let r=await o.json();return a.setAttribute("copilot_api.models_count",r.data.length),a.end(),r}finally{clearTimeout(a)}})()}let ve,xe,Ae,$e=!1;const Te=async()=>{let{token:e,refresh_in:o}=await be();x._t1=e,Z.debug("Service token fetched successfully!"),x.showToken&&Z.info("Service token:",e);let n=async(e=5,o=1e3,n="scheduled")=>{if(!$e)return $e=!0,s.startActiveSpan("copilot_api.token.refresh",async a=>{let r=performance.now();a.setAttribute("copilot_api.token_refresh.reason",n),a.setAttribute("copilot_api.token_refresh.max_retries",e);try{for(let s=1;s<=e;s++)try{a.setAttribute("copilot_api.token_refresh.attempt",s),Z.debug(`Refreshing Service token (${n}, attempt ${s}/${e})`);let{token:o}=await be();return x._t1=o,Z.debug("Service token refreshed successfully"),x.showToken&&Z.info("Refreshed Service token:",o),a.setAttribute("copilot_api.token_refresh.success",!0),t.add(1,{reason:n,success:"true"}),k.record(performance.now()-r,{reason:n}),void G(P.INFO,"INFO",`Token refreshed successfully (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempt":s})}catch(l){let c=s===e;if(Z.error(`Failed to refresh Service token (attempt ${s}/${e}):`,l),t.add(1,{reason:n,success:"false"}),c){Z.error("All refresh attempts failed. May be unavailable until next scheduled refresh.");let t=l instanceof Error?l:Error(String(l));return a.setAttribute("copilot_api.token_refresh.success",!1),a.setStatus({code:ne.ERROR,message:t.message}),a.recordException(t),i.add(1,{reason:n}),k.record(performance.now()-r,{reason:n}),void G(P.ERROR,"ERROR",`Token refresh failed after ${e} attempts (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempts":e})}let u=o*2**(s-1);Z.debug(`Retrying token refresh in ${u}ms...`),await new Promise(e=>setTimeout(e,u))}}finally{a.end(),$e=!1}});Z.debug("Refresh already in progress, skipping")};ve=setInterval(()=>{n(5,1e3,"scheduled").catch(e=>{Z.error("Unexpected error in scheduled token refresh:",e)})},1e3*(o-60)),F.start(),xe=()=>{Z.debug("Network connectivity restored, attempting immediate token refresh"),n(3,500,"network-restored").catch(e=>{Z.error("Unexpected error in network-restored token refresh:",e)})},Ae=()=>{Z.debug("Network connectivity lost")},F.on("online",xe),F.on("offline",Ae)};async function Se(e){try{let t=await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8");if(t&&!e?.force)return x._t2=t,x.showToken&&Z.info("Auth token:",t),void await Oe();Z.info("Authentication required");let o=await async function(){let e=new AbortController,t=x.timeoutMs,o=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${H}/login/device/code`,{method:"POST",headers:q(),body:JSON.stringify({client_id:L,scope:T}),signal:e.signal});if(!t.ok)throw new M("Failed to get device code",t);return await t.json()}finally{clearTimeout(o)}}();Z.debug("Device code response:",o),Z.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await async function(e){let t=1e3*(e.interval+1);for(Z.debug(`Polling access token with interval of ${t}ms`);;){let o=new AbortController,n=x.timeoutMs,a=setTimeout(()=>{o.abort()},n);try{let n=await fetch(`${H}/login/oauth/access_token`,{method:"POST",headers:q(),body:JSON.stringify({client_id:L,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:o.signal});if(!n.ok){await ke(t),Z.error("Failed to poll access token:",await n.text());continue}let a=await n.json();Z.debug("Polling access token response:",a);let{access_token:r}=a;if(r)return r;await ke(t)}catch(e){if(e instanceof Error&&"AbortError"===e.name){Z.error("Access token polling timed out"),await ke(t);continue}throw e}finally{clearTimeout(a)}}}(o);await(e=>ee.writeFile(v.GITHUB_TOKEN_PATH,e))(n),x._t2=n,x.showToken&&Z.info("Auth token:",n),await Oe()}catch(e){throw e instanceof M?(Z.error("Failed to get Auth token:",await e.response.json()),e):(Z.error("Failed to get Auth token:",e),e)}}async function Oe(){let e=await U();Z.debug(`Authenticated as ${e.login}`)}const Ie=Q({meta:{name:"auth",description:"Run authentication flow"},args:{verbose:{alias:"v",type:"boolean",default:!1,description:"Enable verbose logging"},"show-token":{type:"boolean",default:!1,description:"Show token on auth"}},run:({args:e})=>async function(e){e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),x.showToken=e.showToken,await A(),await Se({force:!0}),Z.success("Auth token written to",v.GITHUB_TOKEN_PATH)}({verbose:e.verbose,showToken:e["show-token"]})}),qe=async()=>{let e=`${j}/copilot_internal/user`,t=x.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await b({spanName:"github GET /copilot_internal/user",url:e,target:"usage",headers:K(x),signal:o.signal});if(!t.ok)throw n.end(),new M("Failed to get usage",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}},Ne=Q({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await A(),await Se();try{let e=await qe(),t=e.quota_snapshots.premium_interactions,o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;function s(e,t){if(!t)return`${e}: N/A`;let o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;return`${e}: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`}let i=`Premium: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`,l=s("Chat",e.quota_snapshots.chat),c=s("Completions",e.quota_snapshots.completions);Z.box(`Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${i}\n ${l}\n ${c}`)}catch(u){Z.error("Failed to fetch usage:",u),process.exit(1)}}});async function Pe(){try{let e=new URL("../package.json",import.meta.url).pathname,t=await ee.readFile(e);return JSON.parse(t.toString()).version}catch{return"unknown"}}function je(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:te.platform(),arch:te.arch()}}async function Ce(){try{return!!(await ee.stat(v.GITHUB_TOKEN_PATH)).isFile()&&(await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function Ee(e){let t=await async function(){let[e,t]=await Promise.all([Pe(),Ce()]);return{version:e,runtime:je(),paths:{APP_DIR:v.APP_DIR,GITHUB_TOKEN_PATH:v.GITHUB_TOKEN_PATH},tokenExists:t}}();e.json?function(e){console.log(JSON.stringify(e,null,2))}(t):function(e){Z.info(`service debug\n\nVersion: ${e.version}\nRuntime: ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})\n\nPaths:\n- APP_DIR: ${e.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${e.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${e.tokenExists?"Yes":"No"}`)}(t)}const Re=Q({meta:{name:"debug",description:"Print debug information about the application"},args:{json:{type:"boolean",default:!1,description:"Output debug information as JSON"}},run:({args:e})=>Ee({json:e.json})}),De="copilot-api-node20",Me=`https://registry.npmjs.org/${De}/latest`,He=e=>`${e}`,Fe=e=>`${e}`;async function Be(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);try{let t=await fetch(Me,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function Je(e,t){let o=Math.max(0,t-function(e){return e.replaceAll(/\x1b\[[0-9;]*m/g,"").length}(e));return e+" ".repeat(o)}const Le=new Map,Ue=new Map,Ke=new Set;let We,ze,Ge;function Ve(e){return!e.closed&&!e.destroyed}function Ye(e){Z.debug(`Creating HTTP/2 client for ${e}`);let t=new se(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return Le.set(t,Date.now()),z.add(1,{event:"created",origin:e}),G(P.INFO,"INFO",`HTTP/2 client created for ${e}`,{"copilot_api.h2.event":"created","copilot_api.h2.origin":e}),t.on("connect",()=>{Z.debug(`HTTP/2 client connected to ${e}`)}),t.on("error",t=>{Z.debug(`HTTP/2 client error for ${e}:`,t.message)}),t.on("disconnect",(o,n,a)=>{Z.debug(`HTTP/2 client disconnected from ${e}:`,a.message),z.add(1,{event:"goaway",origin:e}),G(P.WARN,"WARN",`HTTP/2 client disconnected from ${e}: ${a.message}`,{"copilot_api.h2.event":"goaway","copilot_api.h2.origin":e,"copilot_api.h2.error":a.message}),Ue.delete(t),Ke.delete(t),Le.delete(t),Ve(t)&&t.close().catch(e=>{Z.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function Qe(e){if(!x.connectivity.h2)return;We&&We!==e&&function(){for(let e of[...Ue.keys(),...Ke])Ve(e)&&e.close().catch(e=>{Z.debug("Error closing HTTP/2 pool entry:",e)});Ue.clear(),Ke.clear(),Le.clear()}(),We=e;let t=Date.now();for(let[o]of Ue)if(t-(Le.get(o)??0)>=6e5)Ue.delete(o),Le.delete(o),Ve(o)&&o.close().catch(e=>{Z.debug("Error closing rotated HTTP/2 client:",e)}),z.add(1,{event:"rotated",origin:e}),G(P.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(Ve(o))return Ue.delete(o),Ke.add(o),o;Ue.delete(o),Le.delete(o)}let o=Ye(e);return Ke.add(o),o}function Xe(e){e&&Ke.delete(e)&&(Ve(e)?Ue.set(e,Date.now()):Le.delete(e))}function Ze(){Ge||(Ge=setInterval(()=>{!function(){let e=Date.now(),t=x.connectivity.h2Keepalive,o=Ue.size;for(let[n,a]of Ue)e-a<6e4||t&&o<=1||(Ue.delete(n),Le.delete(n),o--,Ve(n)&&n.close().catch(e=>{Z.debug("Error closing idle HTTP/2 client:",e)}),z.add(1,{event:"idle_reaped",origin:We??""}),G(P.INFO,"INFO",`HTTP/2 idle connection reaped for ${We}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":We??""}))}()},3e4),Ge.unref())}function et(){ze||(Z.debug("Starting HTTP/2 keepalive (every 45s)"),ze=setInterval(()=>{(async function(){if(0===Ue.size&&0===Ke.size){if(We){let e=Ye(We);Ue.set(e,Date.now())}return}let e=[...Ue.keys()];await Promise.allSettled(e.map(async e=>{if(!Ve(e))return Ue.delete(e),void Le.delete(e);try{let{statusCode:t,body:o}=await e.request({path:"/models",method:"GET",headers:R(x)});await o.dump(),h.add(1,{result:"success"}),Z.debug(`HTTP/2 keepalive: GET /models → ${t}`),Ue.set(e,Date.now())}catch(t){h.add(1,{result:"error"}),Z.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),z.add(1,{event:"error",origin:We??""}),Ue.delete(e),Le.delete(e),Ve(e)&&e.close().catch(e=>{Z.debug("Error closing broken HTTP/2 client:",e)})}}))})().catch(e=>{Z.debug("Unexpected error in HTTP/2 keepalive:",e)})},45e3),ze.unref(),Ze())}function tt(e,t=""){let o,n=function(){let{platform:e,ppid:t,env:o}=le;if("win32"===e){try{if(pe(`wmic process get ParentProcessId,Name | findstr "${t}"`,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}{let e=o.SHELL;if(e){if(e.endsWith("zsh"))return"zsh";if(e.endsWith("fish"))return"fish";if(e.endsWith("bash"))return"bash"}return"sh"}}(),a=Object.entries(e).filter(([,e])=>void 0!==e);switch(n){case"powershell":o=a.map(([e,t])=>`$env:${e} = ${t}`).join("; ");break;case"cmd":o=a.map(([e,t])=>`set ${e}=${t}`).join(" & ");break;case"fish":o=a.map(([e,t])=>`set -gx ${e} ${t}`).join("; ");break;default:{let e=a.map(([e,t])=>`${e}=${t}`).join(" ");o=a.length>0?`export ${e}`:"";break}}return o&&t?`${o}${"cmd"===n?" & ":" && "}${t}`:o||t}const ot=e=>`${e}`,nt=e=>`${e}`,at=e=>`${e}`,rt=e=>`${e}`,st=e=>`${e}`,it=e=>`${e}`,lt=(e,t)=>`]8;;${e}\\${t}]8;;\\`,ct="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",ut=nt(" ─────────────────────────────────────────────────────────────");function pt(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const dt=[{title:"The 5-Hour Quota, Boris's Tweet, and What the Source Code Actually Reveals",teaser:"Claude Code's caching story — decoded from the source.",url:"https://barazany.dev/blog/claude-code-token-caching"},{title:"Claude Code's Compaction Engine: What the Source Code Actually Reveals",teaser:"What's actually running beneath every long session.",url:"https://barazany.dev/blog/claude-codes-compaction-engine"},{title:"We Were About to Buy an Automation Platform. We Already Had One.",teaser:"Governance spirals over n8n. The answer was already deployed.",url:"https://barazany.dev/blog/we-already-had-the-automation-platform"}];function mt(e){if(0===e.length)return[];let t=["",ut,` ${ot("BARAZANY.DEV")} ${nt("— Recent Posts")}`,ut,""];for(let[o,n]of e.entries()){let e=lt(`${n.url}${ct}`,ot(it(`[${o+1}]`)));t.push(` ${e} ${at(n.title)}`,` ${nt("→")} ${nt(n.teaser)}`,"")}return t.push(ut,` ${lt(`https://barazany.dev/blog${ct}`,"barazany.dev/blog")}`,ut),t}function _t(e){let t=[];x.connectivity.h2Keepalive?t.push("HTTP/2 keepalive"):x.connectivity.h2&&t.push("HTTP/2"),t.push(`timeout ${e.timeout/1e3}s`);let o=e.webSearch?`Tavily ${rt("✓")}`:nt("off"),n=["",` ${ot("COPILOT-API")} ${nt(`v${e.version}`)}`,ut,` ${nt("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${nt("User")} ${e.user} ${nt("·")} ${e.accountType}`];return x._v1&&n.push(` ${nt("Client")} VSCode ${x._v1}`),n.push(` ${nt("Network")} ${t.join(nt(" · "))}`,` ${nt("Search")} ${o}`),e.clipboardCopied&&n.push(` ${nt("Clipboard")} Claude Code command ${rt("✓")}`),n.push(ut),n}function ft(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${ot("Active")}`];if(e.model){let o=x.models?.data.find(t=>t.id===e.model),n=pt(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${at(e.model.padEnd(32))} ${nt("ctx")} ${ot(n.padStart(5))} ${st("← main")}`)}if(e.smallModel){let o=x.models?.data.find(t=>t.id===e.smallModel),n=pt(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${nt("ctx")} ${n.padStart(5)} ${st("← small")}`)}return t}function gt(e){let t=[];for(let[o,n]of function(){let e=[],t=[],o=[],n=[];for(let a of x.models?.data??[]){let r=a.capabilities.limits?.max_context_window_tokens,s={id:a.id,ctx:r};a.id.startsWith("text-embedding")?n.push(s):"Anthropic"===a.vendor?e.push(s):"Google"===a.vendor?o.push(s):t.push(s)}return[["Claude",e],["OpenAI",t],["Gemini",o],["Embedding",n]]}())if(0!==n.length){t.push("",` ${ot(o)}`);for(let o of n){let n=o.id===e.model||o.id===e.smallModel,a=n?at("●"):nt("·"),r=n?at(o.id.padEnd(34)):o.id.padEnd(34),s=o.ctx?pt(o.ctx).padStart(5):"";t.push(` ${a} ${r} ${nt(s)}`)}}return t}function yt(e){let t=Math.floor(e/1e3),o=Math.floor(t/3600),n=Math.floor(t%3600/60);return o>0?`${o}h ${n}m`:n>0?`${n}m`:`${t}s`}function ht(e){(function(e){let{c:t,start:o,span:n}=e,a=t.get("requestData"),r=t.res.status,s=a?.model??"unknown",i=a?.streaming??!1,l=Date.now()-o;if(n.setAttribute("http.status_code",r),n.setAttribute("copilot_api.model",s),n.setAttribute("copilot_api.streaming",i),n.setAttribute("copilot_api.duration_ms",l),a?._d1&&n.setAttribute("copilot_api.copilot_duration_ms",a._d1),a?.tokenUsage){let e=a.tokenUsage;n.setAttribute("copilot_api.input_tokens",e.inputTokens),n.setAttribute("copilot_api.output_tokens",e.outputTokens),n.setAttribute("copilot_api.total_tokens",e.totalTokens),e.cachedTokens&&n.setAttribute("copilot_api.cached_tokens",e.cachedTokens),e.estimatedCost&&n.setAttribute("copilot_api.estimated_cost",e.estimatedCost)}t.res.headers.forEach((e,t)=>{let o=t.toLowerCase();D.has(o)||n.setAttribute(`http.response.header.${o}`,e)}),r>=400&&n.setStatus({code:ne.ERROR,message:`HTTP ${r}`}),n.end()})(e),function(e){let{c:t,start:o,method:a,path:s,endpointType:i,requestId:c}=e,u=Date.now()-o,p=t.get("requestData"),m=t.res.status,f=p?.model??"unknown",g=p?.streaming??!1,h={method:a,path:s,status_code:String(m),model:f,streaming:String(g),endpoint_type:i};if(l.add(1,h),r.record(u,h),m>=400&&y.add(1,{method:a,path:s,status_code:String(m),error_type:m>=500?"server_error":"client_error"}),p?.tokenUsage){let e=p.tokenUsage,t={model:f,endpoint_type:i};e.inputTokens&&(n.add(e.inputTokens,t),_.record(e.inputTokens,t)),e.outputTokens&&(C.add(e.outputTokens,t),d.record(e.outputTokens,t)),e.cachedTokens&&W.add(e.cachedTokens,{model:f})}!g&&p?.tokenUsage&&B.executeCompletion(c)}(e)}const bt=async()=>s.startActiveSpan("copilot_api.approval.await",async e=>{let t=performance.now();try{let o=await Z.prompt("Accept incoming request?",{type:"confirm"}),n=performance.now()-t;if(e.setAttribute("copilot_api.approval.wait_duration_ms",n),$.record(n),!o)throw e.setAttribute("copilot_api.approval.result","rejected"),N.add(1,{result:"rejected"}),new M("Request rejected",Response.json({message:"Request rejected"},{status:403}));e.setAttribute("copilot_api.approval.result","approved"),N.add(1,{result:"approved"})}finally{e.end()}}),kt=3e-6,wt=15e-6;function vt(e){let t=e.prompt_tokens||0,o=e.completion_tokens||0;return{inputTokens:t,outputTokens:o,totalTokens:e.total_tokens||t+o,estimatedCost:t*kt+o*wt,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function xt(e,t){void 0!==t.prompt_tokens&&e.setAttribute("copilot_api.input_tokens",t.prompt_tokens),void 0!==t.completion_tokens&&e.setAttribute("copilot_api.output_tokens",t.completion_tokens),void 0!==t.total_tokens&&e.setAttribute("copilot_api.total_tokens",t.total_tokens)}const At=[{pattern:/haiku/i,family:"haiku"},{pattern:/sonnet[.-]?4[.-]6/i,family:"sonnet-4.6"},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:"sonnet-4.5"},{pattern:/sonnet-4(?![.-]5|[.-]6|[.-]1)/i,family:"sonnet-4"},{pattern:/opus[.-]?4[.-]6/i,family:"opus-4.6"},{pattern:/opus[.-]?4[.-]5/i,family:"opus-4.5"},{pattern:/opus/i,family:"opus"}],$t={haiku:"claude-haiku-4.5","sonnet-4.6":"claude-sonnet-4.6","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4","opus-4.6":"claude-opus-4.6","opus-4.5":"claude-opus-4.5",opus:"claude-opus-4.5"};function Tt(e,t){let o=function(e){return e.startsWith("anthropic/")?e.slice(10):e}(e),[n,a]=function(e){let t=e.lastIndexOf("["),o=e.lastIndexOf("]");return-1!==t&&o===e.length-1&&o>t?[e.slice(0,t),e.slice(t+1,o)]:[e,null]}(o);if(t.includes(o))return o;if(a){let e=`${n}-${a}`.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(e))return e}let r=function(e){for(let t of At)if(t.pattern.test(e))return t.family;return null}(n);if(!r)return null;let s=n.replace(/-\d{8}(?::.*)?$/,""),i=a?`-${a}`:"";for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,""),o=`${s}${i}`.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2")===o)return e}return function(e,t,o=null){let n=$t[e];if(!n)return null;if(o){let e=`${n}-${o}`;if(t.includes(e))return e}if(t.includes(n))return n;if("sonnet-4.5"===e)for(let e of["claude-3.5-sonnet"]){let n=o?`${e}-${o}`:e;if(t.includes(n))return n}return null}(r,t,a)}var St=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function Ot(t){if(!t||"string"!=typeof t)throw new St("Model name is required and must be a string");if(!x.models?.data)throw new St("Models not available. Please try again later.",503);let o=x.models.data.map(e=>e.id);if(o.includes(t))return t;let n=Tt(t,o);if(!n)throw e.add(1,{requested_model:t}),new St(`Invalid model: '${t}'. Available services: ${o.join(", ")}`);return n}async function It(e){if(void 0===e.rateLimitSeconds)return;let t=e.rateLimitSeconds;return s.startActiveSpan("copilot_api.rate_limit.check",async o=>{try{let n=Date.now();if(o.setAttribute("copilot_api.rate_limit.configured_seconds",t),!e.lastRequestTimestamp)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let a=(n-e.lastRequestTimestamp)/1e3;if(o.setAttribute("copilot_api.rate_limit.elapsed_seconds",a),a>t)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let r=Math.ceil(t-a);if(o.setAttribute("copilot_api.rate_limit.wait_seconds",r),!e.rateLimitWait)throw o.setAttribute("copilot_api.rate_limit.action","rejected"),m.add(1,{action:"rejected",source:"local"}),Z.warn(`Rate limit exceeded. Need to wait ${r} more seconds.`),new M("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let s=1e3*r;o.setAttribute("copilot_api.rate_limit.action","waited"),m.add(1,{action:"waited",source:"local"}),f.record(s,{source:"local"}),Z.warn(`Rate limit reached. Waiting ${r} seconds before proceeding...`),await ke(s),e.lastRequestTimestamp=n,Z.info("Rate limit wait completed, proceeding with request")}finally{o.end()}})}function qt(e){if("string"==typeof e)return function(e){let t=e,o=String.fromCodePoint(27),n=t.split(o);if(n.length>1){t=n[0];for(let e=1;e<n.length;e++){let a=n[e],r=a.match(/^\[[0-9;]*[a-z]/i);t+=r?a.slice(r[0].length):o+a}}return t.replaceAll(/[\u200B-\u200D\uFEFF]/g,"").replaceAll(/[\u2060-\u2064]/g,"").replaceAll(/[\u206A-\u206F]/g,"").replaceAll(/[\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/g,"").replaceAll(/[\uFFF0-\uFFFF]/g,"").replaceAll(/[\x00-\x08\v\f\x0E-\x1F]/g,"")}(e);if(Array.isArray(e))return e.map(e=>qt(e));if(e&&"object"==typeof e){let t={};for(let[o,n]of Object.entries(e))t[o]=qt(n);return t}return e}const Nt=async e=>{if(!x._t1)throw Error("Service token not found");let t=qt(e),o=t.messages.some(e=>"string"!=typeof e.content&&e.content?.some(e=>"image_url"===e.type)),n=t.messages.some(e=>["assistant","tool"].includes(e.role)),a={...R(x,o),"X-Initiator":n?"agent":"user"},r=O(x),s=`${r}/chat/completions`,i=Qe(r),l=x.timeoutMs,c=new AbortController,u=setTimeout(()=>c.abort(),l);try{let{statusCode:e,headers:r,body:u,span:p}=await w({spanName:"copilot POST /chat/completions",url:s,target:"chat_completions",headers:a,body:JSON.stringify(t),signal:c.signal,headersTimeout:l,bodyTimeout:3*l,extraAttributes:{"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":l,"copilot_api.has_tools":!!t.tools?.length,"copilot_api.tool_count":t.tools?.length??0,"copilot_api.message_count":t.messages.length,"copilot_api.max_tokens":t.max_tokens??0,"copilot_api.vision_enabled":o,"copilot_api.initiator":n?"agent":"user"},dispatcher:i}),d=new Response(u,{status:e,headers:r});if(!d.ok)throw p.end(),new M("Failed to create chat completions",d);if(t.stream)return{events:fe(d),span:p,release:()=>Xe(i)};let m=await d.json();return m.id&&p.setAttribute("copilot_api.response.id",m.id),m.usage&&xt(p,m.usage),p.end(),Xe(i),m}catch(e){throw Xe(i),e}finally{clearTimeout(u)}};function Pt(e){return s.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=Ot(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),E.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function jt(e,t){if(!e.data)return e;try{let o=JSON.parse(e.data);if(o.usage&&t(o.usage),void 0!==o.usage?.prompt_tokens_details?.cached_tokens)return{...e,data:JSON.stringify({...o,usage:{...o.usage,prompt_tokens_details:void 0}})}}catch{}return e}const Ct=e=>Object.hasOwn(e,"choices"),Et=new de;Et.post("/",async e=>{try{return await async function(e){await It(x);let t=await e.req.json();Z.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=Pt(t)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}if(e.set("requestData",{model:t.model,streaming:!!t.stream}),x.manualApprove&&await bt(),(e=>null==e)(t.max_tokens)){let e=x.models?.data.find(e=>e.id===t.model);t={...t,max_tokens:e?.capabilities.limits?.max_output_tokens},Z.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}let o=performance.now(),n=await Nt(t),a=performance.now()-o;if(S.record(a,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),Ct(n)){let t=e.get("requestData")||{};return n.usage&&(t.tokenUsage=vt(n.usage)),t._d1=a,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(n)),e.json(n)}let{events:r,span:s,release:i}=n;return _e(e,async o=>{let n={value:null},l=0,c=performance.now();try{try{for await(let s of r){let r=s;s.data&&"[DONE]"!==s.data&&(l++,g.add(1,{model:t.model,endpoint_type:"openai"}),r=jt(s,t=>{n.value=t;let o=e.get("requestData")||{};o.tokenUsage=vt(t),o._d1=a,e.set("requestData",o)})),await o.writeSSE(r)}let s=performance.now()-c,i={model:t.model,endpoint_type:"openai"};if(Y.record(s,i),V.record(l,i),n.value){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=vt(n.value),t._d1=a,e.set("requestData",t))}}finally{n.value&&xt(s,n.value),s.end(),i()}let u=e.get("requestId");u&&B.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const Rt=new de;Rt.post("/",async e=>{try{let t=await e.req.json();try{Ot(t.model)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:t.model});let o=performance.now(),n=await(async e=>{if(!x._t1)throw Error("Service token not found");let t=`${O(x)}/embeddings`,o=R(x),n=x.timeoutMs,a=new AbortController,r=setTimeout(()=>a.abort(),n);try{let{response:n,span:r}=await b({spanName:"copilot POST /embeddings",url:t,target:"embeddings",method:"POST",headers:o,body:JSON.stringify(e),signal:a.signal,extraAttributes:{"copilot_api.model":e.model,"copilot_api.input_count":Array.isArray(e.input)?e.input.length:1}});if(!n.ok)throw r.end(),new M("Failed to create embeddings",n);let s=await n.json();return r.end(),s}finally{clearTimeout(r)}})(t),a=performance.now()-o;S.record(a,{model:t.model,target:"embeddings",streaming:"false"});let r=e.get("requestData")||{};return r.tokenUsage=vt(n.usage),r._d1=a,e.set("requestData",r),e.json(n)}catch(t){return await J(e,t)}});const Dt=new ge(he),Mt={...ye["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function Ht(e){return Dt.encode(e).length}function Ft(e){let t=0;for(let o of e)switch(o.type){case"text":t+=Ht(o.text)*Mt.contentMultiplier;break;case"tool_use":t+=Ht(o.name+JSON.stringify(o.input))*Mt.contentMultiplier;break;case"tool_result":o.content&&(t+=Ht("string"==typeof o.content?o.content:JSON.stringify(o.content))*Mt.contentMultiplier);break;case"thinking":t+=Ht(o.thinking)*Mt.contentMultiplier;break;case"image":t+=1600}return t}function Bt(e){let t=0,o=e.properties;if(!o)return t;let n=Object.entries(o);for(let[e,[o,a]]of n.entries()){if(t+=0===e?Mt.perFirstProp:Mt.perAdditionalProp,t+=Ht(o),a.description&&(t+=Mt.perPropDesc+Ht(a.description)),a.enum&&Array.isArray(a.enum)){t+=Mt.perEnum;for(let e of a.enum)t+=Ht(String(e))}if("object"===a.type&&a.properties&&(t+=Mt.perNestedObject,t+=Bt(a)),"array"===a.type&&a.items){let e=a.items;"object"===e.type&&e.properties&&(t+=Mt.perArrayOfObjects,t+=Bt(e))}}return t}const Jt=async e=>{if(!x._t1)throw Error("Service token not found");let t=qt(e),o={...R(x),"X-Initiator":"agent"},n=O(x),a=`${n}/responses`,r=Qe(n),s=x.timeoutMs,i=new AbortController,l=setTimeout(()=>i.abort(),s);try{let{statusCode:e,headers:n,body:l,span:c}=await w({spanName:"copilot POST /responses",url:a,target:"responses",headers:o,body:JSON.stringify(t),signal:i.signal,headersTimeout:s,bodyTimeout:3*s,extraAttributes:{"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":s,"copilot_api.has_tools":!!t.tools?.length,"copilot_api.tool_count":t.tools?.length??0,"copilot_api.max_output_tokens":t.max_output_tokens??0,"copilot_api.api_type":"responses"},dispatcher:r}),u=new Response(l,{status:e,headers:n});if(!u.ok)throw c.end(),new M("Failed to create responses",u);if(t.stream)return{events:fe(u),span:c};let p=await u.json();return p.id&&c.setAttribute("copilot_api.response.id",p.id),p.usage&&xt(c,{prompt_tokens:p.usage.input_tokens,completion_tokens:p.usage.output_tokens,total_tokens:p.usage.total_tokens}),c.end(),p}finally{clearTimeout(l)}};function Lt(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function Ut(e,t){let o=function(e){return e?"string"==typeof e?[{role:"system",content:Kt(e)}]:[{role:"system",content:Kt(e.map(e=>e.text).join("\n\n"))}]:[]}(t),n=e.flatMap(e=>"user"===e.role?function(e){let t=[];if(Array.isArray(e.content)){let o=e.content.filter(e=>"tool_result"===e.type),n=e.content.filter(e=>"tool_result"!==e.type);for(let e of o)t.push({role:"tool",tool_call_id:e.tool_use_id,content:Wt(e.content)});n.length>0&&t.push({role:"user",content:Wt(n)})}else t.push({role:"user",content:Wt(e.content)});return t}(e):function(e){if(!Array.isArray(e.content))return[{role:"assistant",content:Wt(e.content)}];let t=e.content.filter(e=>"tool_use"===e.type),o=e.content.filter(e=>"text"===e.type),n=e.content.filter(e=>"thinking"===e.type),a=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");return t.length>0?[{role:"assistant",content:a||null,tool_calls:t.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:"assistant",content:Wt(e.content)}]}(e));return[...o,...n]}function Kt(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}function Wt(e){if("string"==typeof e)return e;if(!Array.isArray(e))return null;if(!e.some(e=>"image"===e.type))return e.filter(e=>"text"===e.type||"thinking"===e.type).map(e=>"text"===e.type?e.text:e.thinking).join("\n\n");let t=[];for(let o of e)switch(o.type){case"text":t.push({type:"text",text:o.text});break;case"thinking":t.push({type:"text",text:o.thinking});break;case"image":t.push({type:"image_url",image_url:{url:`data:${o.source.media_type};base64,${o.source.data}`}})}return t}function zt(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Gt(e){if(e)switch(e.type){case"auto":return"auto";case"any":return"required";case"tool":return e.name?{type:"function",function:{name:e.name}}:void 0;case"none":return"none";default:return}}function Vt(e){return"string"==typeof e?[{type:"text",text:e}]:Array.isArray(e)?e.filter(e=>"text"===e.type).map(e=>({type:"text",text:e.text})):[]}function Yt(e){return e?e.map(e=>({type:"tool_use",id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function Qt(e){let t={model:e.model,input:Xt(e.messages),max_output_tokens:Math.max(e.max_tokens,16),stream:e.stream,temperature:e.temperature,top_p:e.top_p,store:!1,user:e.metadata?.user_id?.slice(0,64)},o=function(e){return e?function(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}("string"==typeof e?e:e.map(e=>e.text).join("\n\n")):null}(e.system);if(o&&(t.instructions=o),e.tools?.length&&(t.tools=e.tools.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.input_schema}))),e.tool_choice&&(t.tool_choice=function(e){switch(e.type){case"auto":return"auto";case"any":return"required";case"none":return"none";case"tool":return e.name?{type:"function",name:e.name}:void 0;default:return}}(e.tool_choice)),"enabled"===e.thinking?.type&&e.thinking.budget_tokens){let o=e.thinking.budget_tokens,n="high";o<5e3?n="low":o<2e4&&(n="medium"),t.reasoning={effort:n}}return t}function Xt(e){let t=[];for(let o of e)"user"===o.role?t.push(...Zt(o)):t.push(...to(o));return t}function Zt(e){if("string"==typeof e.content)return[{type:"message",role:"user",content:e.content}];let t=[],o=e.content.filter(e=>"tool_result"===e.type),n=e.content.filter(e=>"tool_result"!==e.type);for(let e of o)t.push(eo(e));if(n.length>0)if(n.some(e=>"image"===e.type)){let e=[];for(let t of n)"text"===t.type?e.push({type:"input_text",text:t.text}):e.push({type:"input_image",image_url:`data:${t.source.media_type};base64,${t.source.data}`});t.push({type:"message",role:"user",content:e})}else{let e=n.filter(e=>"text"===e.type).map(e=>e.text).join("\n\n");e&&t.push({type:"message",role:"user",content:e})}return t}function eo(e){let t;return t="string"==typeof e.content?e.content:Array.isArray(e.content)?e.content.filter(e=>"text"===e.type).map(e=>e.text).join("\n"):"",e.is_error&&(t=`[ERROR] ${t}`),{type:"function_call_output",call_id:e.tool_use_id,output:t}}function to(e){if("string"==typeof e.content)return[{type:"message",role:"assistant",content:e.content}];let t=[],o=e.content.filter(e=>"text"===e.type),n=e.content.filter(e=>"thinking"===e.type),a=e.content.filter(e=>"tool_use"===e.type),r=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");r&&t.push({type:"message",role:"assistant",content:r});for(let e of a)t.push({type:"function_call",call_id:e.id,name:e.name,arguments:JSON.stringify(e.input)});return t}function oo(e,t){if(t)return"tool_use";switch(e){case"completed":case"cancelled":case"failed":return"end_turn";case"incomplete":return"max_tokens";default:return null}}function no(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function ao(e,t,o){e.messageStartSent||=(e.responseId=o?.responseId??e.responseId,e.model=o?.model??e.model,t.push({type:"message_start",message:{id:e.responseId,type:"message",role:"assistant",content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}),!0)}function ro(e,t){let o=[];switch(e.type){case"response.created":ao(t,o,{responseId:e.response.id,model:e.response.model});break;case"response.in_progress":case"response.output_text.done":case"response.function_call_arguments.done":case"response.refusal.done":case"response.reasoning_summary_text.delta":case"response.reasoning_summary_text.done":default:break;case"response.output_item.added":if("function_call"===e.item.type){ao(t,o),no(t,o);let n=e.item;t.toolCalls[e.output_index]={call_id:n.call_id,name:n.name,_bi1:t.contentBlockIndex},o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"tool_use",id:n.call_id,name:n.name,input:{}}}),t.contentBlockOpen=!0}break;case"response.content_part.added":ao(t,o),no(t,o),o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),t.contentBlockOpen=!0;break;case"response.output_text.delta":o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}});break;case"response.content_part.done":no(t,o);break;case"response.function_call_arguments.delta":{let n=t.toolCalls[e.output_index];n&&o.push({type:"content_block_delta",index:n._bi1,delta:{type:"input_json_delta",partial_json:e.delta}});break}case"response.output_item.done":if("function_call"===e.item.type){let n=t.toolCalls[e.output_index];n&&t.contentBlockOpen&&(o.push({type:"content_block_stop",index:n._bi1}),t.contentBlockIndex++,t.contentBlockOpen=!1)}break;case"response.completed":{no(t,o);let n=e.response.output.some(e=>"function_call"===e.type),a=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:oo(e.response.status,n),stop_sequence:null},usage:{input_tokens:a?.input_tokens??0,output_tokens:a?.output_tokens??0}},{type:"message_stop"});break}case"response.incomplete":{ao(t,o),no(t,o);let n=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:"max_tokens",stop_sequence:null},usage:{input_tokens:n?.input_tokens??0,output_tokens:n?.output_tokens??0}},{type:"message_stop"});break}case"response.failed":ao(t,o),no(t,o),o.push({type:"error",error:{type:e.response.error?.code??"api_error",message:e.response.error?.message??"Response generation failed"}});break;case"response.cancelled":ao(t,o),no(t,o),o.push({type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{input_tokens:0,output_tokens:0}},{type:"message_stop"});break;case"response.refusal.delta":ao(t,o),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}})}return o}function so(e,t){let o=[];if(0===e.choices.length)return o;let n=e.choices[0],{delta:a}=n;if(t.messageStartSent||=(o.push({type:"message_start",message:{id:e.id,type:"message",role:"assistant",content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:0}}}),!0),a.content&&(function(e){return!!e.contentBlockOpen&&Object.values(e.toolCalls).some(t=>t._bi1===e.contentBlockIndex)}(t)&&(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:a.content}})),a.tool_calls)for(let e of a.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let n=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,_bi1:n},o.push({type:"content_block_start",index:n,content_block:{type:"tool_use",id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let n=t.toolCalls[e.index];n&&o.push({type:"content_block_delta",index:n._bi1,delta:{type:"input_json_delta",partial_json:e.function.arguments}})}}return n.finish_reason&&(t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:Lt(n.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:"message_stop"})),o}async function io(e,t,o){let n={query:t,max_results:o?.maxResults??5};o?.includeDomains?.length&&(n.include_domains=o.includeDomains),o?.excludeDomains?.length&&(n.exclude_domains=o.excludeDomains),Z.debug("Tavily search request:",JSON.stringify(n));let a=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)});if(!a.ok){let e=await a.text();throw Z.error(`Tavily API error (${a.status}):`,e),Error(`Tavily API error: ${a.status} ${e}`)}let r=await a.json();return Z.debug(`Tavily returned ${r.results.length} results`),r.results}function lo(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function co(e,t){let o=function(e){let t,o=e.messages[0];if(!o||"user"!==o.role)return null;if("string"==typeof o.content)t=o.content;else{if(!Array.isArray(o.content))return null;{let e=o.content.find(e=>"text"===e.type);if(!e)return null;t=e.text}}return t.startsWith("Perform a web search for the query: ")?t.slice(36).trim():t.trim()||null}(t);if(!o)return e.json({type:"error",error:{type:"invalid_request_error",message:"Could not extract search query from web search request"}},400);let n=function(e){let t=e.tools?.[0];return{maxResults:"number"==typeof t?.max_uses?t.max_uses:5,allowedDomains:t?.allowed_domains,blockedDomains:t?.blocked_domains}}(t);Z.info(`Web search intercepted: "${o}"`);let a=[];try{let e=x.tavilyApiKey;if(!e)throw Error("No Tavily API key configured");a=(await io(e,o,{maxResults:Math.min(n.maxResults,10),includeDomains:n.allowedDomains,excludeDomains:n.blockedDomains})).map(e=>({type:"web_search_result",url:e.url,title:e.title,encrypted_content:Buffer.from(e.content).toString("base64"),page_age:null}))}catch(e){Z.error("Tavily search failed:",e)}let r={query:o,results:a,model:t.model};if(!t.stream)return e.json(function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${lo()}`,r=[{type:"text",text:"I'll search for that."},{type:"server_tool_use",id:a,name:"web_search",input:{query:t}},{type:"web_search_tool_result",tool_use_id:a,content:o}];return{id:`msg_tavily_${lo()}`,type:"message",role:"assistant",model:n,content:r,stop_reason:"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}(r));let s=function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${lo()}`,r=`msg_tavily_${lo()}`,s=[];return s.push({type:"message_start",message:{id:r,type:"message",role:"assistant",content:[],model:n,stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}},{type:"content_block_start",index:0,content_block:{type:"text",text:""}},{type:"content_block_delta",index:0,delta:{type:"text_delta",text:"I'll search for that."}},{type:"content_block_stop",index:0},{type:"content_block_start",index:1,content_block:{type:"server_tool_use",id:a,name:"web_search",input:{}}},{type:"content_block_delta",index:1,delta:{type:"input_json_delta",partial_json:JSON.stringify({query:t})}},{type:"content_block_stop",index:1},{type:"content_block_start",index:2,content_block:{type:"web_search_tool_result",tool_use_id:a,content:o}},{type:"content_block_stop",index:2},{type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{output_tokens:0}},{type:"message_stop"}),s}(r);return _e(e,async e=>{for(let t of s)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}async function uo(e){let t=await e.req.json();if(function(e){let t=e.tools;if(!t||1!==t.length)return!1;let o=t[0].type;return"string"==typeof o&&o.startsWith("web_search")}(t))return co(e,t);await It(x),Z.debug("Anthropic request payload:",JSON.stringify(t));let o=e.req.header("anthropic-beta")??"",n=/context-1m/i.test(o);if(n&&/claude/i.test(t.model)){let e=t.model;t={...t,model:`${t.model}-1m`},Z.debug(`Detected context-1m beta flag, rewriting model: '${e}' → '${t.model}'`)}let a=function(e,t){return s.startActiveSpan("copilot_api.model.validate",o=>{try{o.setAttribute("copilot_api.model.requested",t.model);let e=Ot(t.model);return o.setAttribute("copilot_api.model.normalized",e),e===t.model?(o.setAttribute("copilot_api.model.was_mapped",!1),t):(o.setAttribute("copilot_api.model.was_mapped",!0),E.add(1,{from_model:t.model,to_model:e}),Z.debug(`Model mapping: '${t.model}' → '${e}'`),{...t,model:e})}catch(t){if(t instanceof St)return e.json({type:"error",error:{type:"invalid_request_error",message:t.message}},t.statusCode),null;throw t}finally{o.end()}})}(e,t);if(!a)return;if(t=a,function(e){return/gpt-[\d.]+-codex/i.test(e)}(t.model))return async function(e,t){let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.anthropic_to_responses",e=>{try{return e.setAttribute("copilot_api.translation.direction","anthropic_to_responses"),e.setAttribute("copilot_api.translation.message_count",t.messages.length),Qt(t)}finally{e.end()}});u.record(performance.now()-o,{direction:"anthropic_to_responses"}),Z.debug("Translated Responses API payload:",JSON.stringify(n)),e.set("requestData",{model:n.model,streaming:!!n.stream}),x.manualApprove&&await bt();let a=performance.now(),r=await Jt(n),i=performance.now()-a;if(S.record(i,{model:n.model,target:"responses",streaming:String(!!n.stream)}),_o(r)){let t=e.get("requestData")||{};if(r.usage&&(t.tokenUsage=vt({prompt_tokens:r.usage.input_tokens,completion_tokens:r.usage.output_tokens,total_tokens:r.usage.total_tokens})),t._d1=i,e.set("requestData",t),Z.debug("Non-streaming Responses API response:",JSON.stringify(r).slice(-400)),"failed"===r.status)return e.json({type:"error",error:{type:r.error?.code??"api_error",message:r.error?.message??"Response generation failed"}},500);let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.responses_to_anthropic",e=>{try{return e.setAttribute("copilot_api.translation.direction","responses_to_anthropic"),function(e){let t=[],o=!1;for(let n of e.output)if("message"===n.type)for(let e of n.content)e.text&&t.push({type:"text",text:e.text});else if("function_call"===n.type){o=!0;let e={};try{e=JSON.parse(n.arguments)}catch{}t.push({type:"tool_use",id:n.call_id,name:n.name,input:e})}return{id:e.id,type:"message",role:"assistant",model:e.model,content:t,stop_reason:oo(e.status,o),stop_sequence:null,usage:{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}}(r)}finally{e.end()}});return u.record(performance.now()-o,{direction:"responses_to_anthropic"}),e.json(n)}Z.debug("Streaming Responses API response");let{events:l,span:c}=r;return _e(e,async t=>{let o=null,a=0,r=performance.now(),s={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,responseId:"",model:"",toolCalls:{}};try{try{for await(let r of l){if(Z.debug("Responses API raw stream event:",JSON.stringify(r)),!r.data)continue;let l;try{l=JSON.parse(r.data)}catch{continue}a++,g.add(1,{model:n.model,endpoint_type:"responses"});let c=po(l);if(c){o=c;let t=e.get("requestData")||{};t.tokenUsage=vt(o),t._d1=i,e.set("requestData",t)}let u=ro(l,s);for(let e of u)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let c=performance.now()-r,u={model:n.model,endpoint_type:"responses"};Y.record(c,u),V.record(a,u)}finally{o&&xt(c,o),c.end()}let u=e.get("requestId");u&&B.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e,t);let r=performance.now(),i=s.startActiveSpan("copilot_api.translate.anthropic_to_openai",e=>{try{e.setAttribute("copilot_api.translation.direction","anthropic_to_openai"),e.setAttribute("copilot_api.translation.message_count",t.messages.length),e.setAttribute("copilot_api.translation.has_tools",!!t.tools?.length),e.setAttribute("copilot_api.translation.has_system",!!t.system),e.setAttribute("copilot_api.translation.context_1m_beta",n);let o=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"===e.type)),a=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"thinking"===e.type));return e.setAttribute("copilot_api.translation.has_images",o),e.setAttribute("copilot_api.translation.has_thinking",a),function(e){return{model:e.model,messages:Ut(e.messages,e.system),max_tokens:e.max_tokens,stop:e.stop_sequences,stream:e.stream,temperature:e.temperature,top_p:e.top_p,user:e.metadata?.user_id,tools:zt(e.tools),tool_choice:Gt(e.tool_choice)}}(t)}finally{e.end()}});u.record(performance.now()-r,{direction:"anthropic_to_openai"}),Z.debug("Translated OpenAI request payload:",JSON.stringify(i)),e.set("requestData",{model:i.model,streaming:!!i.stream});let l=performance.now();x.manualApprove&&await bt();let c=await Nt(i),p=performance.now()-l;if(S.record(p,{model:i.model,target:"chat_completions",streaming:String(!!i.stream)}),mo(c)){let t=e.get("requestData")||{};c.usage&&(t.tokenUsage=vt(c.usage)),t._d1=p,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(c).slice(-400));let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.openai_to_anthropic",e=>{try{e.setAttribute("copilot_api.translation.direction","openai_to_anthropic");let t=function(e){let t=[],o=[],n=null;n=e.choices[0]?.finish_reason??n;for(let a of e.choices){let e=Vt(a.message.content),r=Yt(a.message.tool_calls);t.push(...e),o.push(...r),("tool_calls"===a.finish_reason||"stop"===n)&&(n=a.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o],stop_reason:Lt(n),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}(c);return e.setAttribute("copilot_api.translation.content_blocks",t.content.length),e.setAttribute("copilot_api.translation.stop_reason",t.stop_reason??"null"),e.setAttribute("copilot_api.translation.has_tool_use",t.content.some(e=>"tool_use"===e.type)),t}finally{e.end()}});return u.record(performance.now()-o,{direction:"openai_to_anthropic"}),Z.debug("Translated Anthropic response:",JSON.stringify(n)),e.json(n)}Z.debug("Streaming response from service");let{events:d,span:m,release:_}=c;return _e(e,async t=>{let o=null,n=0,a=performance.now(),r={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};try{try{for await(let a of d){if(Z.debug("Raw stream event:",JSON.stringify(a)),"[DONE]"===a.data)break;if(!a.data)continue;let s=JSON.parse(a.data);if(n++,g.add(1,{model:i.model,endpoint_type:"anthropic"}),s.usage){o=s.usage;let t=e.get("requestData")||{};t.tokenUsage=vt(o),t._d1=p,e.set("requestData",t)}let l=so(s,r);for(let e of l)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let s=performance.now()-a,l={model:i.model,endpoint_type:"anthropic"};if(Y.record(s,l),V.record(n,l),o){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=vt(o),t._d1=p,e.set("requestData",t))}}finally{o&&xt(m,o),m.end(),_()}let s=e.get("requestId");s&&B.executeCompletion(s)}finally{e.get("resolveStreamComplete")?.()}})}function po(e){if("response.completed"!==e.type&&"response.incomplete"!==e.type)return null;let t=e.response.usage;return t?{prompt_tokens:t.input_tokens,completion_tokens:t.output_tokens,total_tokens:t.total_tokens}:null}const mo=e=>Object.hasOwn(e,"choices"),_o=e=>Object.hasOwn(e,"output");const fo=new de;fo.post("/",async e=>{try{return await uo(e)}catch(t){return await J(e,t)}});const go=new de;function yo(e){return s.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=Ot(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),E.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function ho(e,t){let o=function(e){try{let t=JSON.parse(e);if(("response.completed"===t.type||"response.incomplete"===t.type)&&t.response?.usage){let e=t.response.usage;return{prompt_tokens:e.input_tokens,completion_tokens:e.output_tokens,total_tokens:e.total_tokens}}}catch{}return null}(e);if(!o)return;t.usageRef.value=o;let n=t.c.get("requestData")||{};n.tokenUsage=vt(o),n._d1=t._d1,t.c.set("requestData",n)}go.get("/",async e=>{try{x.models||await we();let t=x.models?.data.map(e=>({id:e.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:e.vendor,display_name:e.name,context_length:e.capabilities.limits?.max_context_window_tokens}));return e.json({object:"list",data:t,has_more:!1})}catch(t){return await J(e,t)}});const bo=new Set(["message","function_call","function_call_output"]),ko=new Set(["type","name","description","parameters"]);async function wo(e){if(!e)return!1;let t=e.sources;if(t&&t.length>0)return!1;let o=e.query??e.queries?.[0];return!(!o||!x.tavilyApiKey)&&(Z.info(`Enriching web search: "${o}"`),e.sources=(await io(x.tavilyApiKey,o,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function vo(e){if(!x.tavilyApiKey)return e;try{let t=JSON.parse(e);if("response.output_item.done"===t.type){let e=t.item;if("web_search_call"===e?.type&&await wo(e.action))return JSON.stringify(t)}}catch(e){Z.error("Failed to enrich web search:",e)}return e}function xo(e,t){if("function_call"!==e.type||!t.has(e.name))return!1;if(e.type="custom_tool_call","string"==typeof e.arguments){try{e.input=JSON.parse(e.arguments).input??e.arguments}catch{e.input=e.arguments}delete e.arguments}return!0}function Ao(e,t){if(0===t.size)return e;try{let o=JSON.parse(e),n=o.type;if("response.output_item.added"===n||"response.output_item.done"===n){let e=o.item;if(e&&xo(e,t))return JSON.stringify(o)}if("response.completed"===n){let n=o.response?.output;if(!n)return e;let a=!1;for(let e of n)xo(e,t)&&(a=!0);if(a)return JSON.stringify(o)}}catch{}return e}function $o(e){return null!=e}function To(e){let t=e.input,o="string"==typeof t?t:t.map(e=>function(e){switch(e.type){case"custom_tool_call":{let t=e.input;return{type:"function_call",call_id:e.call_id,name:e.name,arguments:JSON.stringify("string"==typeof t?{input:t}:t)}}case"custom_tool_call_output":return{type:"function_call_output",call_id:e.call_id,output:e.output};default:return bo.has(e.type)||"web_search_call"===e.type?e:null}}(e)).filter(e=>null!==e),n={model:e.model,input:o};for(let t of["instructions","max_output_tokens","temperature","top_p","stream","store","tool_choice","parallel_tool_calls","user"])$o(e[t])&&(n[t]=e[t]);let a=new Set;if($o(e.tools)){let t=function(e){let t=new Set;return{tools:e.filter(e=>{let t=e.type;return"function"===t||"custom"===t||"web_search"===t||t.startsWith("web_search_")}).map(e=>{let o=e.type;if("web_search"===o||o.startsWith("web_search_"))return{type:e.type};let n={};for(let t of Object.keys(e))ko.has(t)&&(n[t]=e[t]);return"custom"===n.type&&(n.type="function",t.add(n.name),n.parameters||={type:"object",properties:{input:{type:"string",description:"The freeform tool input content"}},required:["input"],additionalProperties:!1}),n}),customToolNames:t}}(e.tools);n.tools=t.tools,a=t.customToolNames}if($o(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;n.reasoning={},$o(t.effort)&&(n.reasoning.effort=t.effort),$o(t.summary)&&(n.reasoning.summary=t.summary)}if($o(e.text)&&"object"==typeof e.text){let t=e.text;$o(t.format)&&(n.text={format:t.format})}return{payload:n,customToolNames:a}}async function So(e,t,o){await async function(e){if(x.tavilyApiKey)try{for(let t of e.output){let e=t;"web_search_call"===e.type&&await wo(e.action)}}catch(e){Z.error("Failed to enrich non-streaming web search:",e)}}(t);let n=e.get("requestData")||{};return t.usage&&(n.tokenUsage=vt({prompt_tokens:t.usage.input_tokens,completion_tokens:t.usage.output_tokens,total_tokens:t.usage.total_tokens})),n._d1=o,e.set("requestData",n),e.json(t)}const Oo=e=>Object.hasOwn(e,"output"),Io=new de;Io.post("/",async e=>{try{return await async function(e){await It(x);let{payload:t,customToolNames:o}=To(await e.req.json()),n=t;Z.debug(`Responses API [${Array.isArray(n.input)?n.input.length:1} items]`),o.size>0&&Z.debug(`Custom tools detected: ${[...o].join(", ")}`);try{n=yo(n)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:n.model,streaming:!!n.stream}),x.manualApprove&&await bt();let a=performance.now(),r=await Jt(n),s=performance.now()-a;if(S.record(s,{model:n.model,target:"responses",streaming:String(!!n.stream)}),Oo(r))return So(e,r,s);let{events:i,span:l}=r;return _e(e,async t=>{let a={value:null},r=0,c=performance.now();try{try{for await(let l of i)if(l.data&&"[DONE]"!==l.data){r++;let i=Ao(l.data,o);i=await vo(i);let c=i===l.data?l:{...l,data:i};g.add(1,{model:n.model,endpoint_type:"responses"}),ho(i,{usageRef:a,c:e,_d1:s}),await t.writeSSE(c)}else await t.writeSSE(l);let l=performance.now()-c,u={model:n.model,endpoint_type:"responses"};Y.record(l,u),V.record(r,u)}finally{a.value&&xt(l,a.value),l.end()}let u=e.get("requestId");u&&B.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const qo=new de;qo.get("/",e=>{try{return e.json({token:x._t1})}catch(t){return console.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const No=new de;No.get("/",async e=>{try{let t=await qe();return e.json(t)}catch(t){return console.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const Po=new de;Po.use(async(e,t)=>{let o=Date.now(),n=`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,a=e.req.method,r=e.req.path,i=function(e){return e.includes("/messages")?"anthropic":e.includes("/chat/completions")?"openai":e.includes("/embeddings")?"embeddings":e.includes("/models")?"models":e.includes("/usage")?"usage":e.includes("/token")?"token":"unknown"}(r);e.set("requestId",n),e.header("x-request-id",n);let l=s.startSpan("copilot_api.handle_request",{kind:oe.SERVER,attributes:{"http.method":a,"http.url":e.req.url,"http.route":r,"copilot_api.request_id":n,"copilot_api.endpoint_type":i}});for(let[t,o]of Object.entries(e.req.header())){let e=t.toLowerCase();D.has(e)||l.setAttribute(`http.request.header.${e}`,o)}let c,u=new Promise(e=>{c=e});e.set("streamComplete",u),e.set("resolveStreamComplete",c);let p=re.setSpan(ae.active(),l);await ae.with(p,async()=>{B.registerCompletion(n,e,o);try{await t()}catch(e){let t=e instanceof Error?e:Error(String(e));throw l.setStatus({code:ne.ERROR,message:t.message}),l.recordException(t),e}});let d=e.get("requestData"),m={c:e,start:o,method:a,path:r,endpointType:i,requestId:n,span:l};d?.streaming?u.then(()=>ht(m)).catch(e=>{Z.debug("Error finalizing streaming request:",e),l.end()}):ht(m)}),Po.use(me()),Po.get("/",e=>e.text("Server running")),Po.route("/chat/completions",Et),Po.route("/models",go),Po.route("/embeddings",Rt),Po.route("/usage",No),Po.route("/token",qo),Po.route("/v1/chat/completions",Et),Po.route("/v1/models",go),Po.route("/v1/embeddings",Rt),Po.route("/v1/messages",fo),Po.post("/v1/messages/count_tokens",async function(e){let t;try{t=await e.req.json()}catch{return e.json({error:{type:"invalid_request_error",message:"Invalid JSON"}},400)}if(!Array.isArray(t.messages))return e.json({error:{type:"invalid_request_error",message:"messages is required"}},400);let o=Mt.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");o+=Mt.perMessage+Ht(e)*Mt.contentMultiplier}for(let e of t.messages)o+=Mt.perMessage,o+=Ht(e.role),"string"==typeof e.content?o+=Ht(e.content)*Mt.contentMultiplier:Array.isArray(e.content)&&(o+=Ft(e.content));return t.tools&&t.tools.length>0&&(o+=function(e){let t=Mt.toolsExist;for(let[o,n]of e.entries())o>0&&(t+=Mt.perTool),t+=Ht(n.name),n.description&&(t+=Mt.perDesc+Ht(n.description)),t+=Bt(n.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(o)})}),Po.route("/v1/responses",Io),Po.route("/responses",Io);const jo=[],Co=Date.now();let Eo="";function Ro(){let e=async(e,t=0)=>{let o=s.startSpan("copilot_api.server.shutdown",{kind:oe.INTERNAL,attributes:{"copilot_api.shutdown.reason":e,"copilot_api.shutdown.exit_code":t,"copilot_api.uptime_seconds":(Date.now()-Co)/1e3}});for(let t of jo)try{await t()}catch(e){Z.error("Error during cleanup:",e)}o.end(),function(e,t){let o=lt("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),n=["",ut,` ${ot("COPILOT-API")} ${nt(`v${e}`)} ${nt("·")} ${yt(t)} uptime`,ut,""," Check in from time to time on",` ${at(o)}`,"",ut,""];console.log(n.join("\n"))}(Eo,Date.now()-Co),le.exit(t)};le.on("SIGINT",()=>e("SIGINT")),le.on("SIGTERM",()=>e("SIGTERM")),le.on("uncaughtException",t=>{Z.error("Uncaught exception:",t),e("uncaughtException",1)}),le.on("unhandledRejection",(t,o)=>{Z.error("Unhandled promise rejection at:",o,"reason:",t),e("unhandledRejection",1)})}function Do(e){let{options:t,version:n,runtime:a,_u1:r}=e,i=s.startSpan("copilot_api.server.startup",{kind:oe.INTERNAL,attributes:o({config:{version:n,port:t.port,accountType:t.accountType,verbose:t.verbose,manualApprove:t.manual,rateLimitSeconds:t.rateLimit??0,rateLimitWait:t.rateLimitWait,timeoutMs:t.timeout,showToken:t.showToken,_cc1:t._cc1,model:t.model,smallModel:t.smallModel,_t3:t._t2?"cli_arg":"stored"},runtime:a,identity:{_u1:r.login,machineId:x.machineId,sessionId:x.sessionId,_v1:x._v1},connectivity:x.connectivity,modelsCount:x.models?.data.length??0,startupDurationMs:Date.now()-Co},"copilot_api")});if(x.models?.data)for(let e of x.models.data)i.addEvent("copilot_api.model.available",o(e,"model"));i.end(),G(P.INFO,"INFO","Server started",o({version:n,port:t.port,accountType:t.accountType,_u1:r.login,modelsCount:x.models?.data.length??0,startupDurationMs:Date.now()-Co},"copilot_api"))}async function Mo(e){Ro(),jo.push(()=>{Z.debug("Cleaning up connectivity monitor"),F.stop()},()=>{Z.debug("Cleaning up token management"),Z.debug("Cleaning up token management"),ve&&=void clearInterval(ve),xe&&=void F.off("online",xe),Ae&&=void F.off("offline",Ae)},async()=>{Z.debug("Cleaning up HTTP/2 client"),await async function(){Z.debug("Stopping HTTP/2 pool"),ze&&=void clearInterval(ze),Ge&&=void clearInterval(Ge);let e=[...Ue.keys(),...Ke];Ue.clear(),Ke.clear(),Le.clear(),We=void 0;for(let t of e)Ve(t)&&(z.add(1,{event:"closed"}),await t.close())}()},async()=>{Z.debug("Shutting down OTel SDK"),await p()}),e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),e._cc1&&e.codex&&(Z.error("Cannot use --claude-code and --codex together"),le.exit(1)),x.accountType=e.accountType,x.manualApprove=e.manual,x.rateLimitSeconds=e.rateLimit,x.rateLimitWait=e.rateLimitWait,x.showToken=e.showToken,x.timeoutMs=e.timeout,e.tavilyApiKey&&(x.tavilyApiKey=e.tavilyApiKey),function(){let e="1"===le.env.COPILOT_H2_KEEPALIVE||"true"===le.env.COPILOT_H2_KEEPALIVE,t=e||"1"===le.env.COPILOT_H2||"true"===le.env.COPILOT_H2;x.connectivity.h2=t,x.connectivity.h2Keepalive=e}(),await A(),x._v1="1.115.0-insider";let t=await Pe();Eo=t;let o,n=je();a(t,Co),e._t2?(x._t2=e._t2,Z.info("Using provided Auth token")):await Se();try{let{_s4:e}=await import("./get-user-DqCcnRgq.mjs");o=await e(),await I(x,o.login)}catch(e){Z.error("Failed to get user info for machine ID generation:",e),Z.error("Cannot proceed without user information"),le.exit(1)}await Te(),await we(),x.connectivity.h2&&(Xe(Qe(O(x))),x.connectivity.h2Keepalive&&et()),Do({options:e,version:t,runtime:n,_u1:o});let r=`http://localhost:${e.port}`,s=await async function(e,t){if(!e._cc1)return!1;let o,n;if(ue(x.models,"Models should be loaded by now"),e.model&&e.smallModel){let t=x.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),t.includes(e.smallModel)||(Z.error(`Invalid small model: ${e.smallModel}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),o=e.model,n=e.smallModel}else e.model||e.smallModel?(Z.error("Both --model and --small-model must be specified for model selection"),le.exit(1)):(o=await Z.prompt("Select a model to use",{type:"select",options:x.models.data.map(e=>e.id)}),n=await Z.prompt("Select a small model to use",{type:"select",options:x.models.data.map(e=>e.id)}));let a=tt({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:o,ANTHROPIC_SMALL_FAST_MODEL:n},"claude");try{return ie.writeSync(a),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the command:"),Z.log(a),!1}}(e,r)||await async function(e,t){if(!e.codex)return!1;let o;if(ue(x.models,"Models should be loaded by now"),e.model){let t=x.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),o=e.model}else o=await Z.prompt("Select a model to use with Codex CLI",{type:"select",options:x.models.data.map(e=>e.id)});let n=tt({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy"},`codex --model ${o}`);try{return ie.writeSync(n),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the Codex CLI command:"),Z.log(n),!1}}(e,r);(function(e){let t=[..._t(e),...ft(e),...gt(e),"",...mt(dt),""];console.log(t.join("\n"))})({version:t,runtime:n,user:o.login,accountType:e.accountType,port:e.port,timeout:e.timeout,webSearch:!!e.tavilyApiKey,model:e.model,smallModel:e.smallModel,clipboardCopied:s}),ce({fetch:Po.fetch,port:e.port,bun:{idleTimeout:255}})}const Ho=Q({meta:{name:"start",description:"Start the API server"},args:{port:{alias:"p",type:"string",default:"4141",description:"Port to listen on"},verbose:{alias:"v",type:"boolean",default:!1,description:"Enable verbose logging"},"account-type":{alias:"a",type:"string",default:"individual",description:"Account type (individual, business, enterprise)"},manual:{type:"boolean",default:!1,description:"Enable manual request approval"},"rate-limit":{alias:"r",type:"string",description:"Rate limit in seconds between requests"},wait:{alias:"w",type:"boolean",default:!1,description:"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set"},"github-token":{alias:"g",type:"string",description:"Provide auth token directly (must be generated using the `auth` subcommand)"},"claude-code":{alias:"c",type:"boolean",default:!1,description:"Generate a command to launch with API config"},codex:{type:"boolean",default:!1,description:"Generate a command to launch Codex CLI with Copilot API config"},model:{alias:"m",type:"string",description:"Model to use (with --claude-code or --codex)"},"small-model":{alias:"s",type:"string",description:"Small/fast model to use (requires --claude-code)"},"show-token":{type:"boolean",default:!1,description:"Show tokens on fetch and refresh"},timeout:{alias:"t",type:"string",description:"API timeout in milliseconds (default: 600000)"},"tavily-api-key":{type:"string",description:"Tavily API key for web search support (or set TAVILY_API_KEY env var)"}},run({args:e}){let t=e["rate-limit"],o=void 0===t?void 0:Number.parseInt(t,10),n=e.timeout,a=void 0===n?c:Number.parseInt(n,10);return Mo({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e["account-type"],manual:e.manual,rateLimit:o,rateLimitWait:e.wait,_t2:e["github-token"],_cc1:e["claude-code"],codex:e.codex,model:e.model,smallModel:e["small-model"],showToken:e["show-token"],timeout:a,tavilyApiKey:e["tavily-api-key"]||le.env.TAVILY_API_KEY})}});await async function(){try{if("1"===process.env.COPILOT_API_SKIP_UPDATE_CHECK)return;let[e,t]=await Promise.all([Pe(),Be()]);if("unknown"===e||!t||!function(e,t){let o=e.split(".").map(Number),n=t.split(".").map(Number),a=Math.max(o.length,n.length);for(let e=0;e<a;e++){let t=o[e]??0,a=n[e]??0;if(t<a)return!0;if(t>a)return!1}return!1}(e,t))return;!function(e,t){let o=`npx ${De}@latest`,n=Fe("│"),a=` ${He("Update available!")} ${(e=>`${e}`)(e)} → ${(e=>`${e}`)(t)}`,r=` Run ${He(o)} to update`,s=" ".repeat(54),i=Fe(`╭${"─".repeat(54)}╮`),l=Fe(`╰${"─".repeat(54)}╯`),c=["",i,`${n}${s}${n}`,`${n}${Je(a,54)}${n}`,`${n}${s}${n}`,`${n}${Je(r,54)}${n}`,`${n}${s}${n}`,l,""];console.log(c.join("\n"))}(e,t)}catch{}}(),await X(Q({meta:{name:"copilot-api",description:"API proxy server for tool integration."},subCommands:{auth:Ie,start:Ho,"check-usage":Ne,debug:Re}}));export{};
2
+ import{A as e,B as t,C as o,D as n,E as a,F as r,G as s,H as i,I as l,J as c,K as u,L as p,M as d,N as m,O as _,P as f,R as g,S as y,T as h,U as w,V as b,W as k,X as v,Y as x,Z as A,_ as $,a as T,b as S,c as O,d as I,f as q,g as N,h as P,i as E,j,k as C,l as R,m as D,n as M,o as H,p as F,q as B,r as J,s as U,t as L,u as W,v as K,w as G,x as z,y as Y,z as V}from"./get-user-BfOVRifT.mjs";import{defineCommand as Q,runMain as X}from"citty";import Z from"consola";import ee from"node:fs/promises";import te from"node:os";import{SpanKind as oe,SpanStatusCode as ne,context as ae,trace as re}from"@opentelemetry/api";import{Client as se}from"undici";import ie from"clipboardy";import le from"node:process";import{serve as ce}from"srvx";import ue from"tiny-invariant";import{execSync as pe}from"node:child_process";import{Hono as de}from"hono";import{cors as me}from"hono/cors";import{streamSSE as _e}from"hono/streaming";import{events as fe}from"fetch-event-stream";import{Tokenizer as ge,models as ye}from"ai-tokenizer";import*as he from"ai-tokenizer/encoding/claude";const we=async()=>{let e=`${E}/copilot_internal/v2/token`,t=x.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await w({spanName:"github GET /copilot_internal/v2/token",url:e,target:"copilot_token",headers:W(x),signal:o.signal});if(!t.ok)throw n.end(),new M("Failed to get Service token",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}};const be=e=>new Promise(t=>{setTimeout(t,e)});async function ke(){x.models=await(async()=>{let e=`${O(x)}/models`,t=R(x),o=x.timeoutMs,n=new AbortController,a=setTimeout(()=>n.abort(),o);try{let{response:o,span:a}=await w({spanName:"copilot GET /models",url:e,target:"models",headers:t,signal:n.signal});if(!o.ok)throw a.end(),new M("Failed to get models",o);let r=await o.json();return a.setAttribute("copilot_api.models_count",r.data.length),a.end(),r}finally{clearTimeout(a)}})()}let ve,xe,Ae,$e=!1;const Te=async()=>{let{token:e,refresh_in:o}=await we();x._t1=e,Z.debug("Service token fetched successfully!"),x.showToken&&Z.info("Service token:",e);let n=async(e=5,o=1e3,n="scheduled")=>{if(!$e)return $e=!0,s.startActiveSpan("copilot_api.token.refresh",async a=>{let r=performance.now();a.setAttribute("copilot_api.token_refresh.reason",n),a.setAttribute("copilot_api.token_refresh.max_retries",e);try{for(let s=1;s<=e;s++)try{a.setAttribute("copilot_api.token_refresh.attempt",s),Z.debug(`Refreshing Service token (${n}, attempt ${s}/${e})`);let{token:o}=await we();return x._t1=o,Z.debug("Service token refreshed successfully"),x.showToken&&Z.info("Refreshed Service token:",o),a.setAttribute("copilot_api.token_refresh.success",!0),t.add(1,{reason:n,success:"true"}),b.record(performance.now()-r,{reason:n}),void z(P.INFO,"INFO",`Token refreshed successfully (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempt":s})}catch(l){let c=s===e;if(Z.error(`Failed to refresh Service token (attempt ${s}/${e}):`,l),t.add(1,{reason:n,success:"false"}),c){Z.error("All refresh attempts failed. May be unavailable until next scheduled refresh.");let t=l instanceof Error?l:Error(String(l));return a.setAttribute("copilot_api.token_refresh.success",!1),a.setStatus({code:ne.ERROR,message:t.message}),a.recordException(t),i.add(1,{reason:n}),b.record(performance.now()-r,{reason:n}),void z(P.ERROR,"ERROR",`Token refresh failed after ${e} attempts (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempts":e})}let u=o*2**(s-1);Z.debug(`Retrying token refresh in ${u}ms...`),await new Promise(e=>setTimeout(e,u))}}finally{a.end(),$e=!1}});Z.debug("Refresh already in progress, skipping")};ve=setInterval(()=>{n(5,1e3,"scheduled").catch(e=>{Z.error("Unexpected error in scheduled token refresh:",e)})},1e3*(o-60)),F.start(),xe=()=>{Z.debug("Network connectivity restored, attempting immediate token refresh"),n(3,500,"network-restored").catch(e=>{Z.error("Unexpected error in network-restored token refresh:",e)})},Ae=()=>{Z.debug("Network connectivity lost")},F.on("online",xe),F.on("offline",Ae)};async function Se(e){try{let t=await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8");if(t&&!e?.force)return x._t2=t,x.showToken&&Z.info("Auth token:",t),void await Oe();Z.info("Authentication required");let o=await async function(){let e=new AbortController,t=x.timeoutMs,o=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${H}/login/device/code`,{method:"POST",headers:q(),body:JSON.stringify({client_id:U,scope:T}),signal:e.signal});if(!t.ok)throw new M("Failed to get device code",t);return await t.json()}finally{clearTimeout(o)}}();Z.debug("Device code response:",o),Z.info(`Please enter the code "${o.user_code}" in ${o.verification_uri}`);let n=await async function(e){let t=1e3*(e.interval+1);for(Z.debug(`Polling access token with interval of ${t}ms`);;){let o=new AbortController,n=x.timeoutMs,a=setTimeout(()=>{o.abort()},n);try{let n=await fetch(`${H}/login/oauth/access_token`,{method:"POST",headers:q(),body:JSON.stringify({client_id:U,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:o.signal});if(!n.ok){await be(t),Z.error("Failed to poll access token:",await n.text());continue}let a=await n.json();Z.debug("Polling access token response:",a);let{access_token:r}=a;if(r)return r;await be(t)}catch(e){if(e instanceof Error&&"AbortError"===e.name){Z.error("Access token polling timed out"),await be(t);continue}throw e}finally{clearTimeout(a)}}}(o);await(e=>ee.writeFile(v.GITHUB_TOKEN_PATH,e))(n),x._t2=n,x.showToken&&Z.info("Auth token:",n),await Oe()}catch(e){throw e instanceof M?(Z.error("Failed to get Auth token:",await e.response.json()),e):(Z.error("Failed to get Auth token:",e),e)}}async function Oe(){let e=await L();Z.debug(`Authenticated as ${e.login}`)}const Ie=Q({meta:{name:"auth",description:"Run authentication flow"},args:{verbose:{alias:"v",type:"boolean",default:!1,description:"Enable verbose logging"},"show-token":{type:"boolean",default:!1,description:"Show token on auth"}},run:({args:e})=>async function(e){e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),x.showToken=e.showToken,await A(),await Se({force:!0}),Z.success("Auth token written to",v.GITHUB_TOKEN_PATH)}({verbose:e.verbose,showToken:e["show-token"]})}),qe=async()=>{let e=`${E}/copilot_internal/user`,t=x.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await w({spanName:"github GET /copilot_internal/user",url:e,target:"usage",headers:W(x),signal:o.signal});if(!t.ok)throw n.end(),new M("Failed to get usage",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}},Ne=Q({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await A(),await Se();try{let e=await qe(),t=e.quota_snapshots.premium_interactions,o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;function s(e,t){if(!t)return`${e}: N/A`;let o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;return`${e}: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`}let i=`Premium: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`,l=s("Chat",e.quota_snapshots.chat),c=s("Completions",e.quota_snapshots.completions);Z.box(`Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${i}\n ${l}\n ${c}`)}catch(u){Z.error("Failed to fetch usage:",u),process.exit(1)}}});async function Pe(){try{let e=new URL("../package.json",import.meta.url).pathname,t=await ee.readFile(e);return JSON.parse(t.toString()).version}catch{return"unknown"}}function Ee(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:te.platform(),arch:te.arch()}}async function je(){try{return!!(await ee.stat(v.GITHUB_TOKEN_PATH)).isFile()&&(await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function Ce(e){let t=await async function(){let[e,t]=await Promise.all([Pe(),je()]);return{version:e,runtime:Ee(),paths:{APP_DIR:v.APP_DIR,GITHUB_TOKEN_PATH:v.GITHUB_TOKEN_PATH},tokenExists:t}}();e.json?function(e){console.log(JSON.stringify(e,null,2))}(t):function(e){Z.info(`service debug\n\nVersion: ${e.version}\nRuntime: ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})\n\nPaths:\n- APP_DIR: ${e.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${e.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${e.tokenExists?"Yes":"No"}`)}(t)}const Re=Q({meta:{name:"debug",description:"Print debug information about the application"},args:{json:{type:"boolean",default:!1,description:"Output debug information as JSON"}},run:({args:e})=>Ce({json:e.json})}),De="copilot-api-node20",Me=`https://registry.npmjs.org/${De}/latest`,He=e=>`${e}`,Fe=e=>`${e}`;async function Be(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);try{let t=await fetch(Me,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function Je(e,t){let o=Math.max(0,t-function(e){return e.replaceAll(/\x1b\[[0-9;]*m/g,"").length}(e));return e+" ".repeat(o)}const Ue=new Map,Le=new Map,We=new Set;let Ke,Ge,ze;function Ye(e){return!e.closed&&!e.destroyed}function Ve(e){Z.debug(`Creating HTTP/2 client for ${e}`);let t=new se(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return Ue.set(t,Date.now()),G.add(1,{event:"created",origin:e}),z(P.INFO,"INFO",`HTTP/2 client created for ${e}`,{"copilot_api.h2.event":"created","copilot_api.h2.origin":e}),t.on("connect",()=>{Z.debug(`HTTP/2 client connected to ${e}`)}),t.on("error",t=>{Z.debug(`HTTP/2 client error for ${e}:`,t.message)}),t.on("disconnect",(o,n,a)=>{Z.debug(`HTTP/2 client disconnected from ${e}:`,a.message),G.add(1,{event:"goaway",origin:e}),z(P.WARN,"WARN",`HTTP/2 client disconnected from ${e}: ${a.message}`,{"copilot_api.h2.event":"goaway","copilot_api.h2.origin":e,"copilot_api.h2.error":a.message}),Le.delete(t),We.delete(t),Ue.delete(t),Ye(t)&&t.close().catch(e=>{Z.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function Qe(e){if(!x.connectivity.h2)return;Ke&&Ke!==e&&function(){for(let e of[...Le.keys(),...We])Ye(e)&&e.close().catch(e=>{Z.debug("Error closing HTTP/2 pool entry:",e)});Le.clear(),We.clear(),Ue.clear()}(),Ke=e;let t=Date.now();for(let[o]of Le)if(t-(Ue.get(o)??0)>=6e5)Le.delete(o),Ue.delete(o),Ye(o)&&o.close().catch(e=>{Z.debug("Error closing rotated HTTP/2 client:",e)}),G.add(1,{event:"rotated",origin:e}),z(P.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(Ye(o))return Le.delete(o),We.add(o),o;Le.delete(o),Ue.delete(o)}let o=Ve(e);return We.add(o),o}function Xe(e){e&&We.delete(e)&&(Ye(e)?Le.set(e,Date.now()):Ue.delete(e))}function Ze(){ze||(ze=setInterval(()=>{!function(){let e=Date.now(),t=x.connectivity.h2Keepalive,o=Le.size;for(let[n,a]of Le)e-a<6e4||t&&o<=1||(Le.delete(n),Ue.delete(n),o--,Ye(n)&&n.close().catch(e=>{Z.debug("Error closing idle HTTP/2 client:",e)}),G.add(1,{event:"idle_reaped",origin:Ke??""}),z(P.INFO,"INFO",`HTTP/2 idle connection reaped for ${Ke}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":Ke??""}))}()},3e4),ze.unref())}function et(){Ge||(Z.debug("Starting HTTP/2 keepalive (every 45s)"),Ge=setInterval(()=>{(async function(){if(0===Le.size&&0===We.size){if(Ke){let e=Ve(Ke);Le.set(e,Date.now())}return}let e=[...Le.keys()];await Promise.allSettled(e.map(async e=>{if(!Ye(e))return Le.delete(e),void Ue.delete(e);try{let{statusCode:t,body:o}=await e.request({path:"/models",method:"GET",headers:R(x)});await o.dump(),h.add(1,{result:"success"}),Z.debug(`HTTP/2 keepalive: GET /models → ${t}`),Le.set(e,Date.now())}catch(t){h.add(1,{result:"error"}),Z.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),G.add(1,{event:"error",origin:Ke??""}),Le.delete(e),Ue.delete(e),Ye(e)&&e.close().catch(e=>{Z.debug("Error closing broken HTTP/2 client:",e)})}}))})().catch(e=>{Z.debug("Unexpected error in HTTP/2 keepalive:",e)})},45e3),Ge.unref(),Ze())}function tt(e,t=""){let o,n=function(){let{platform:e,ppid:t,env:o}=le;if("win32"===e){try{if(pe(`wmic process get ParentProcessId,Name | findstr "${t}"`,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}{let e=o.SHELL;if(e){if(e.endsWith("zsh"))return"zsh";if(e.endsWith("fish"))return"fish";if(e.endsWith("bash"))return"bash"}return"sh"}}(),a=Object.entries(e).filter(([,e])=>void 0!==e);switch(n){case"powershell":o=a.map(([e,t])=>`$env:${e} = ${t}`).join("; ");break;case"cmd":o=a.map(([e,t])=>`set ${e}=${t}`).join(" & ");break;case"fish":o=a.map(([e,t])=>`set -gx ${e} ${t}`).join("; ");break;default:{let e=a.map(([e,t])=>`${e}=${t}`).join(" ");o=a.length>0?`export ${e}`:"";break}}return o&&t?`${o}${"cmd"===n?" & ":" && "}${t}`:o||t}const ot=e=>`${e}`,nt=e=>`${e}`,at=e=>`${e}`,rt=e=>`${e}`,st=e=>`${e}`,it=e=>`${e}`,lt=(e,t)=>`]8;;${e}\\${t}]8;;\\`,ct="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",ut=nt(" ─────────────────────────────────────────────────────────────");function pt(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const dt=[{title:"The 5-Hour Quota, Boris's Tweet, and What the Source Code Actually Reveals",teaser:"Claude Code's caching story — decoded from the source.",url:"https://barazany.dev/blog/claude-code-token-caching"},{title:"Claude Code's Compaction Engine: What the Source Code Actually Reveals",teaser:"What's actually running beneath every long session.",url:"https://barazany.dev/blog/claude-codes-compaction-engine"},{title:"We Were About to Buy an Automation Platform. We Already Had One.",teaser:"Governance spirals over n8n. The answer was already deployed.",url:"https://barazany.dev/blog/we-already-had-the-automation-platform"}];function mt(e){if(0===e.length)return[];let t=["",ut,` ${ot("BARAZANY.DEV")} ${nt("— Recent Posts")}`,ut,""];for(let[o,n]of e.entries()){let e=lt(`${n.url}${ct}`,ot(it(`[${o+1}]`)));t.push(` ${e} ${at(n.title)}`,` ${nt("→")} ${nt(n.teaser)}`,"")}return t.push(ut,` ${lt(`https://barazany.dev/blog${ct}`,"barazany.dev/blog")}`,ut),t}function _t(e){let t=[];x.connectivity.h2Keepalive?t.push("HTTP/2 keepalive"):x.connectivity.h2&&t.push("HTTP/2"),t.push(`timeout ${e.timeout/1e3}s`);let o=e.webSearch?`Tavily ${rt("✓")}`:nt("off"),n=["",` ${ot("COPILOT-API")} ${nt(`v${e.version}`)}`,ut,` ${nt("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${nt("User")} ${e.user} ${nt("·")} ${e.accountType}`];return x._v1&&n.push(` ${nt("Client")} VSCode ${x._v1}`),n.push(` ${nt("Network")} ${t.join(nt(" · "))}`,` ${nt("Search")} ${o}`),e.clipboardCopied&&n.push(` ${nt("Clipboard")} Claude Code command ${rt("✓")}`),n.push(ut),n}function ft(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${ot("Active")}`];if(e.model){let o=x.models?.data.find(t=>t.id===e.model),n=pt(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${at(e.model.padEnd(32))} ${nt("ctx")} ${ot(n.padStart(5))} ${st("← main")}`)}if(e.smallModel){let o=x.models?.data.find(t=>t.id===e.smallModel),n=pt(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${nt("ctx")} ${n.padStart(5)} ${st("← small")}`)}return t}function gt(e){let t=[];for(let[o,n]of function(){let e=[],t=[],o=[],n=[];for(let a of x.models?.data??[]){let r=a.capabilities.limits?.max_context_window_tokens,s={id:a.id,ctx:r};a.id.startsWith("text-embedding")?n.push(s):"Anthropic"===a.vendor?e.push(s):"Google"===a.vendor?o.push(s):t.push(s)}return[["Claude",e],["OpenAI",t],["Gemini",o],["Embedding",n]]}())if(0!==n.length){t.push("",` ${ot(o)}`);for(let o of n){let n=o.id===e.model||o.id===e.smallModel,a=n?at("●"):nt("·"),r=n?at(o.id.padEnd(34)):o.id.padEnd(34),s=o.ctx?pt(o.ctx).padStart(5):"";t.push(` ${a} ${r} ${nt(s)}`)}}return t}function yt(e){let t=Math.floor(e/1e3),o=Math.floor(t/3600),n=Math.floor(t%3600/60);return o>0?`${o}h ${n}m`:n>0?`${n}m`:`${t}s`}function ht(e){(function(e){let{c:t,start:o,span:n}=e,a=t.get("requestData"),r=t.res.status,s=a?.model??"unknown",i=a?.streaming??!1,l=Date.now()-o;if(n.setAttribute("http.status_code",r),n.setAttribute("copilot_api.model",s),n.setAttribute("copilot_api.streaming",i),n.setAttribute("copilot_api.duration_ms",l),a?._d1&&n.setAttribute("copilot_api.copilot_duration_ms",a._d1),a?.tokenUsage){let e=a.tokenUsage;n.setAttribute("copilot_api.input_tokens",e.inputTokens),n.setAttribute("copilot_api.output_tokens",e.outputTokens),n.setAttribute("copilot_api.total_tokens",e.totalTokens),e.cachedTokens&&n.setAttribute("copilot_api.cached_tokens",e.cachedTokens),e.estimatedCost&&n.setAttribute("copilot_api.estimated_cost",e.estimatedCost)}t.res.headers.forEach((e,t)=>{let o=t.toLowerCase();D.has(o)||n.setAttribute(`http.response.header.${o}`,e)}),r>=400&&n.setStatus({code:ne.ERROR,message:`HTTP ${r}`}),n.end()})(e),function(e){let{c:t,start:o,method:a,path:s,endpointType:i,requestId:c}=e,u=Date.now()-o,p=t.get("requestData"),m=t.res.status,f=p?.model??"unknown",g=p?.streaming??!1,h={method:a,path:s,status_code:String(m),model:f,streaming:String(g),endpoint_type:i};if(l.add(1,h),r.record(u,h),m>=400&&y.add(1,{method:a,path:s,status_code:String(m),error_type:m>=500?"server_error":"client_error"}),p?.tokenUsage){let e=p.tokenUsage,t={model:f,endpoint_type:i};e.inputTokens&&(n.add(e.inputTokens,t),_.record(e.inputTokens,t)),e.outputTokens&&(j.add(e.outputTokens,t),d.record(e.outputTokens,t)),e.cachedTokens&&K.add(e.cachedTokens,{model:f})}!g&&p?.tokenUsage&&B.executeCompletion(c)}(e)}const wt=async()=>s.startActiveSpan("copilot_api.approval.await",async e=>{let t=performance.now();try{let o=await Z.prompt("Accept incoming request?",{type:"confirm"}),n=performance.now()-t;if(e.setAttribute("copilot_api.approval.wait_duration_ms",n),$.record(n),!o)throw e.setAttribute("copilot_api.approval.result","rejected"),N.add(1,{result:"rejected"}),new M("Request rejected",Response.json({message:"Request rejected"},{status:403}));e.setAttribute("copilot_api.approval.result","approved"),N.add(1,{result:"approved"})}finally{e.end()}}),bt=3e-6,kt=15e-6;function vt(e){let t=e.prompt_tokens||0,o=e.completion_tokens||0;return{inputTokens:t,outputTokens:o,totalTokens:e.total_tokens||t+o,estimatedCost:t*bt+o*kt,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function xt(e,t){void 0!==t.prompt_tokens&&e.setAttribute("copilot_api.input_tokens",t.prompt_tokens),void 0!==t.completion_tokens&&e.setAttribute("copilot_api.output_tokens",t.completion_tokens),void 0!==t.total_tokens&&e.setAttribute("copilot_api.total_tokens",t.total_tokens)}const At=[{pattern:/haiku/i,family:"haiku"},{pattern:/sonnet[.-]?4[.-]6/i,family:"sonnet-4.6"},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:"sonnet-4.5"},{pattern:/sonnet-4(?![.-]5|[.-]6|[.-]1)/i,family:"sonnet-4"},{pattern:/opus[.-]?4[.-]6/i,family:"opus-4.6"},{pattern:/opus[.-]?4[.-]5/i,family:"opus-4.5"},{pattern:/opus/i,family:"opus"}],$t={haiku:"claude-haiku-4.5","sonnet-4.6":"claude-sonnet-4.6","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4","opus-4.6":"claude-opus-4.6","opus-4.5":"claude-opus-4.5",opus:"claude-opus-4.5"};function Tt(e,t){let o=function(e){return e.startsWith("anthropic/")?e.slice(10):e}(e),[n,a]=function(e){let t=e.lastIndexOf("["),o=e.lastIndexOf("]");return-1!==t&&o===e.length-1&&o>t?[e.slice(0,t),e.slice(t+1,o)]:[e,null]}(o);if(t.includes(o))return o;if(a){let e=`${n}-${a}`.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(e))return e}let r=function(e){for(let t of At)if(t.pattern.test(e))return t.family;return null}(n);if(!r)return null;let s=n.replace(/-\d{8}(?::.*)?$/,""),i=a?`-${a}`:"";for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,""),o=`${s}${i}`.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2")===o)return e}return function(e,t,o=null){let n=$t[e];if(!n)return null;if(o){let e=`${n}-${o}`;if(t.includes(e))return e}if(t.includes(n))return n;if("sonnet-4.5"===e)for(let e of["claude-3.5-sonnet"]){let n=o?`${e}-${o}`:e;if(t.includes(n))return n}return null}(r,t,a)}var St=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function Ot(t){if(!t||"string"!=typeof t)throw new St("Model name is required and must be a string");if(!x.models?.data)throw new St("Models not available. Please try again later.",503);let o=x.models.data.map(e=>e.id);if(o.includes(t))return t;let n=Tt(t,o);if(!n)throw e.add(1,{requested_model:t}),new St(`Invalid model: '${t}'. Available services: ${o.join(", ")}`);return n}async function It(e){if(void 0===e.rateLimitSeconds)return;let t=e.rateLimitSeconds;return s.startActiveSpan("copilot_api.rate_limit.check",async o=>{try{let n=Date.now();if(o.setAttribute("copilot_api.rate_limit.configured_seconds",t),!e.lastRequestTimestamp)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let a=(n-e.lastRequestTimestamp)/1e3;if(o.setAttribute("copilot_api.rate_limit.elapsed_seconds",a),a>t)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let r=Math.ceil(t-a);if(o.setAttribute("copilot_api.rate_limit.wait_seconds",r),!e.rateLimitWait)throw o.setAttribute("copilot_api.rate_limit.action","rejected"),m.add(1,{action:"rejected",source:"local"}),Z.warn(`Rate limit exceeded. Need to wait ${r} more seconds.`),new M("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let s=1e3*r;o.setAttribute("copilot_api.rate_limit.action","waited"),m.add(1,{action:"waited",source:"local"}),f.record(s,{source:"local"}),Z.warn(`Rate limit reached. Waiting ${r} seconds before proceeding...`),await be(s),e.lastRequestTimestamp=n,Z.info("Rate limit wait completed, proceeding with request")}finally{o.end()}})}function qt(e){if(!(e instanceof Error))return!1;let t=e.code;return(!t||"UND_ERR_SOCKET"===t)&&/GOAWAY/i.test(e.message)}async function Nt(){return new Promise(e=>setTimeout(e,100))}function Pt(e){if("string"==typeof e)return function(e){let t=e,o=String.fromCodePoint(27),n=t.split(o);if(n.length>1){t=n[0];for(let e=1;e<n.length;e++){let a=n[e],r=a.match(/^\[[0-9;]*[a-z]/i);t+=r?a.slice(r[0].length):o+a}}return t.replaceAll(/[\u200B-\u200D\uFEFF]/g,"").replaceAll(/[\u2060-\u2064]/g,"").replaceAll(/[\u206A-\u206F]/g,"").replaceAll(/[\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/g,"").replaceAll(/[\uFFF0-\uFFFF]/g,"").replaceAll(/[\x00-\x08\v\f\x0E-\x1F]/g,"")}(e);if(Array.isArray(e))return e.map(e=>Pt(e));if(e&&"object"==typeof e){let t={};for(let[o,n]of Object.entries(e))t[o]=Pt(n);return t}return e}const Et=async e=>{if(!x._t1)throw Error("Service token not found");let t=Pt(e),o=t.messages.some(e=>"string"!=typeof e.content&&e.content?.some(e=>"image_url"===e.type)),n=t.messages.some(e=>["assistant","tool"].includes(e.role)),a={...R(x,o),"X-Initiator":n?"agent":"user"},r=O(x),s=`${r}/chat/completions`,i=x.timeoutMs,l=JSON.stringify(t),c={"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":i,"copilot_api.has_tools":!!t.tools?.length,"copilot_api.tool_count":t.tools?.length??0,"copilot_api.message_count":t.messages.length,"copilot_api.max_tokens":t.max_tokens??0,"copilot_api.vision_enabled":o,"copilot_api.initiator":n?"agent":"user"};for(let e=0;e<=1;e++){let o=Qe(r),n=new AbortController,u=setTimeout(()=>n.abort(),i);try{let{statusCode:r,headers:u,body:p,span:d}=await k({spanName:"copilot POST /chat/completions",url:s,target:"chat_completions",headers:a,body:l,signal:n.signal,headersTimeout:i,bodyTimeout:3*i,extraAttributes:{...c,"copilot_api.h2.retry_attempt":e},dispatcher:o}),m=new Response(p,{status:r,headers:u});if(!m.ok)throw d.end(),new M("Failed to create chat completions",m);if(t.stream)return{events:fe(m),span:d,release:()=>Xe(o)};let _=await m.json();return _.id&&d.setAttribute("copilot_api.response.id",_.id),_.usage&&xt(d,_.usage),d.end(),Xe(o),_}catch(t){if(Xe(o),qt(t)&&e<1){Z.warn(`HTTP/2 GOAWAY during chat completions, retrying (attempt ${e+1})`),await Nt();continue}throw t}finally{clearTimeout(u)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function jt(e){return s.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=Ot(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),C.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function Ct(e,t){if(!e.data)return e;try{let o=JSON.parse(e.data);if(o.usage&&t(o.usage),void 0!==o.usage?.prompt_tokens_details?.cached_tokens)return{...e,data:JSON.stringify({...o,usage:{...o.usage,prompt_tokens_details:void 0}})}}catch{}return e}const Rt=e=>Object.hasOwn(e,"choices"),Dt=new de;Dt.post("/",async e=>{try{return await async function(e){await It(x);let t=await e.req.json();Z.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=jt(t)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}if(e.set("requestData",{model:t.model,streaming:!!t.stream}),x.manualApprove&&await wt(),(e=>null==e)(t.max_tokens)){let e=x.models?.data.find(e=>e.id===t.model);t={...t,max_tokens:e?.capabilities.limits?.max_output_tokens},Z.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}let o=performance.now(),n=await Et(t),a=performance.now()-o;if(S.record(a,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),Rt(n)){let t=e.get("requestData")||{};return n.usage&&(t.tokenUsage=vt(n.usage)),t._d1=a,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(n)),e.json(n)}let{events:r,span:s,release:i}=n;return _e(e,async o=>{let n={value:null},l=0,c=performance.now();try{try{for await(let s of r){let r=s;s.data&&"[DONE]"!==s.data&&(l++,g.add(1,{model:t.model,endpoint_type:"openai"}),r=Ct(s,t=>{n.value=t;let o=e.get("requestData")||{};o.tokenUsage=vt(t),o._d1=a,e.set("requestData",o)})),await o.writeSSE(r)}let s=performance.now()-c,i={model:t.model,endpoint_type:"openai"};if(V.record(s,i),Y.record(l,i),n.value){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=vt(n.value),t._d1=a,e.set("requestData",t))}}finally{n.value&&xt(s,n.value),s.end(),i()}let u=e.get("requestId");u&&B.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const Mt=new de;Mt.post("/",async e=>{try{let t=await e.req.json();try{Ot(t.model)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:t.model});let o=performance.now(),n=await(async e=>{if(!x._t1)throw Error("Service token not found");let t=`${O(x)}/embeddings`,o=R(x),n=x.timeoutMs,a=new AbortController,r=setTimeout(()=>a.abort(),n);try{let{response:n,span:r}=await w({spanName:"copilot POST /embeddings",url:t,target:"embeddings",method:"POST",headers:o,body:JSON.stringify(e),signal:a.signal,extraAttributes:{"copilot_api.model":e.model,"copilot_api.input_count":Array.isArray(e.input)?e.input.length:1}});if(!n.ok)throw r.end(),new M("Failed to create embeddings",n);let s=await n.json();return r.end(),s}finally{clearTimeout(r)}})(t),a=performance.now()-o;S.record(a,{model:t.model,target:"embeddings",streaming:"false"});let r=e.get("requestData")||{};return r.tokenUsage=vt(n.usage),r._d1=a,e.set("requestData",r),e.json(n)}catch(t){return await J(e,t)}});const Ht=new ge(he),Ft={...ye["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function Bt(e){return Ht.encode(e).length}function Jt(e){let t=0;for(let o of e)switch(o.type){case"text":t+=Bt(o.text)*Ft.contentMultiplier;break;case"tool_use":t+=Bt(o.name+JSON.stringify(o.input))*Ft.contentMultiplier;break;case"tool_result":o.content&&(t+=Bt("string"==typeof o.content?o.content:JSON.stringify(o.content))*Ft.contentMultiplier);break;case"thinking":t+=Bt(o.thinking)*Ft.contentMultiplier;break;case"image":t+=1600}return t}function Ut(e){let t=0,o=e.properties;if(!o)return t;let n=Object.entries(o);for(let[e,[o,a]]of n.entries()){if(t+=0===e?Ft.perFirstProp:Ft.perAdditionalProp,t+=Bt(o),a.description&&(t+=Ft.perPropDesc+Bt(a.description)),a.enum&&Array.isArray(a.enum)){t+=Ft.perEnum;for(let e of a.enum)t+=Bt(String(e))}if("object"===a.type&&a.properties&&(t+=Ft.perNestedObject,t+=Ut(a)),"array"===a.type&&a.items){let e=a.items;"object"===e.type&&e.properties&&(t+=Ft.perArrayOfObjects,t+=Ut(e))}}return t}const Lt=async e=>{if(!x._t1)throw Error("Service token not found");let t=Pt(e),o={...R(x),"X-Initiator":"agent"},n=O(x),a=`${n}/responses`,r=x.timeoutMs,s=JSON.stringify(t),i={"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":r,"copilot_api.has_tools":!!t.tools?.length,"copilot_api.tool_count":t.tools?.length??0,"copilot_api.max_output_tokens":t.max_output_tokens??0,"copilot_api.api_type":"responses"};for(let e=0;e<=1;e++){let l=Qe(n),c=new AbortController,u=setTimeout(()=>c.abort(),r);try{let{statusCode:n,headers:u,body:p,span:d}=await k({spanName:"copilot POST /responses",url:a,target:"responses",headers:o,body:s,signal:c.signal,headersTimeout:r,bodyTimeout:3*r,extraAttributes:{...i,"copilot_api.h2.retry_attempt":e},dispatcher:l}),m=new Response(p,{status:n,headers:u});if(!m.ok)throw d.end(),new M("Failed to create responses",m);if(t.stream)return{events:fe(m),span:d,release:()=>Xe(l)};let _=await m.json();return _.id&&d.setAttribute("copilot_api.response.id",_.id),_.usage&&xt(d,{prompt_tokens:_.usage.input_tokens,completion_tokens:_.usage.output_tokens,total_tokens:_.usage.total_tokens}),d.end(),Xe(l),_}catch(t){if(Xe(l),qt(t)&&e<1){Z.warn(`HTTP/2 GOAWAY during responses, retrying (attempt ${e+1})`),await Nt();continue}throw t}finally{clearTimeout(u)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function Wt(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function Kt(e,t){let o=function(e){return e?"string"==typeof e?[{role:"system",content:Gt(e)}]:[{role:"system",content:Gt(e.map(e=>e.text).join("\n\n"))}]:[]}(t),n=e.flatMap(e=>"user"===e.role?function(e){let t=[];if(Array.isArray(e.content)){let o=e.content.filter(e=>"tool_result"===e.type),n=e.content.filter(e=>"tool_result"!==e.type);for(let e of o)t.push({role:"tool",tool_call_id:e.tool_use_id,content:zt(e.content)});n.length>0&&t.push({role:"user",content:zt(n)})}else t.push({role:"user",content:zt(e.content)});return t}(e):function(e){if(!Array.isArray(e.content))return[{role:"assistant",content:zt(e.content)}];let t=e.content.filter(e=>"tool_use"===e.type),o=e.content.filter(e=>"text"===e.type),n=e.content.filter(e=>"thinking"===e.type),a=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");return t.length>0?[{role:"assistant",content:a||null,tool_calls:t.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:"assistant",content:zt(e.content)}]}(e));return[...o,...n]}function Gt(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}function zt(e){if("string"==typeof e)return e;if(!Array.isArray(e))return null;if(!e.some(e=>"image"===e.type))return e.filter(e=>"text"===e.type||"thinking"===e.type).map(e=>"text"===e.type?e.text:e.thinking).join("\n\n");let t=[];for(let o of e)switch(o.type){case"text":t.push({type:"text",text:o.text});break;case"thinking":t.push({type:"text",text:o.thinking});break;case"image":t.push({type:"image_url",image_url:{url:`data:${o.source.media_type};base64,${o.source.data}`}})}return t}function Yt(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Vt(e){if(e)switch(e.type){case"auto":return"auto";case"any":return"required";case"tool":return e.name?{type:"function",function:{name:e.name}}:void 0;case"none":return"none";default:return}}function Qt(e){return"string"==typeof e?[{type:"text",text:e}]:Array.isArray(e)?e.filter(e=>"text"===e.type).map(e=>({type:"text",text:e.text})):[]}function Xt(e){return e?e.map(e=>({type:"tool_use",id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function Zt(e){let t={model:e.model,input:eo(e.messages),max_output_tokens:Math.max(e.max_tokens,16),stream:e.stream,temperature:e.temperature,top_p:e.top_p,store:!1,user:e.metadata?.user_id?.slice(0,64)},o=function(e){return e?function(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}("string"==typeof e?e:e.map(e=>e.text).join("\n\n")):null}(e.system);if(o&&(t.instructions=o),e.tools?.length&&(t.tools=e.tools.map(e=>({type:"function",name:e.name,description:e.description,parameters:e.input_schema}))),e.tool_choice&&(t.tool_choice=function(e){switch(e.type){case"auto":return"auto";case"any":return"required";case"none":return"none";case"tool":return e.name?{type:"function",name:e.name}:void 0;default:return}}(e.tool_choice)),"enabled"===e.thinking?.type&&e.thinking.budget_tokens){let o=e.thinking.budget_tokens,n="high";o<5e3?n="low":o<2e4&&(n="medium"),t.reasoning={effort:n}}return t}function eo(e){let t=[];for(let o of e)"user"===o.role?t.push(...to(o)):t.push(...no(o));return t}function to(e){if("string"==typeof e.content)return[{type:"message",role:"user",content:e.content}];let t=[],o=e.content.filter(e=>"tool_result"===e.type),n=e.content.filter(e=>"tool_result"!==e.type);for(let e of o)t.push(oo(e));if(n.length>0)if(n.some(e=>"image"===e.type)){let e=[];for(let t of n)"text"===t.type?e.push({type:"input_text",text:t.text}):e.push({type:"input_image",image_url:`data:${t.source.media_type};base64,${t.source.data}`});t.push({type:"message",role:"user",content:e})}else{let e=n.filter(e=>"text"===e.type).map(e=>e.text).join("\n\n");e&&t.push({type:"message",role:"user",content:e})}return t}function oo(e){let t;return t="string"==typeof e.content?e.content:Array.isArray(e.content)?e.content.filter(e=>"text"===e.type).map(e=>e.text).join("\n"):"",e.is_error&&(t=`[ERROR] ${t}`),{type:"function_call_output",call_id:e.tool_use_id,output:t}}function no(e){if("string"==typeof e.content)return[{type:"message",role:"assistant",content:e.content}];let t=[],o=e.content.filter(e=>"text"===e.type),n=e.content.filter(e=>"thinking"===e.type),a=e.content.filter(e=>"tool_use"===e.type),r=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");r&&t.push({type:"message",role:"assistant",content:r});for(let e of a)t.push({type:"function_call",call_id:e.id,name:e.name,arguments:JSON.stringify(e.input)});return t}function ao(e,t){if(t)return"tool_use";switch(e){case"completed":case"cancelled":case"failed":return"end_turn";case"incomplete":return"max_tokens";default:return null}}function ro(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function so(e,t,o){e.messageStartSent||=(e.responseId=o?.responseId??e.responseId,e.model=o?.model??e.model,t.push({type:"message_start",message:{id:e.responseId,type:"message",role:"assistant",content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}),!0)}function io(e,t){let o=[];switch(e.type){case"response.created":so(t,o,{responseId:e.response.id,model:e.response.model});break;case"response.in_progress":case"response.output_text.done":case"response.function_call_arguments.done":case"response.refusal.done":case"response.reasoning_summary_text.delta":case"response.reasoning_summary_text.done":default:break;case"response.output_item.added":if("function_call"===e.item.type){so(t,o),ro(t,o);let n=e.item;t.toolCalls[e.output_index]={call_id:n.call_id,name:n.name,_bi1:t.contentBlockIndex},o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"tool_use",id:n.call_id,name:n.name,input:{}}}),t.contentBlockOpen=!0}break;case"response.content_part.added":so(t,o),ro(t,o),o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),t.contentBlockOpen=!0;break;case"response.output_text.delta":o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}});break;case"response.content_part.done":ro(t,o);break;case"response.function_call_arguments.delta":{let n=t.toolCalls[e.output_index];n&&o.push({type:"content_block_delta",index:n._bi1,delta:{type:"input_json_delta",partial_json:e.delta}});break}case"response.output_item.done":if("function_call"===e.item.type){let n=t.toolCalls[e.output_index];n&&t.contentBlockOpen&&(o.push({type:"content_block_stop",index:n._bi1}),t.contentBlockIndex++,t.contentBlockOpen=!1)}break;case"response.completed":{ro(t,o);let n=e.response.output.some(e=>"function_call"===e.type),a=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:ao(e.response.status,n),stop_sequence:null},usage:{input_tokens:a?.input_tokens??0,output_tokens:a?.output_tokens??0}},{type:"message_stop"});break}case"response.incomplete":{so(t,o),ro(t,o);let n=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:"max_tokens",stop_sequence:null},usage:{input_tokens:n?.input_tokens??0,output_tokens:n?.output_tokens??0}},{type:"message_stop"});break}case"response.failed":so(t,o),ro(t,o),o.push({type:"error",error:{type:e.response.error?.code??"api_error",message:e.response.error?.message??"Response generation failed"}});break;case"response.cancelled":so(t,o),ro(t,o),o.push({type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{input_tokens:0,output_tokens:0}},{type:"message_stop"});break;case"response.refusal.delta":so(t,o),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}})}return o}function lo(e,t){let o=[];if(0===e.choices.length)return o;let n=e.choices[0],{delta:a}=n;if(t.messageStartSent||=(o.push({type:"message_start",message:{id:e.id,type:"message",role:"assistant",content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:0}}}),!0),a.content&&(function(e){return!!e.contentBlockOpen&&Object.values(e.toolCalls).some(t=>t._bi1===e.contentBlockIndex)}(t)&&(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(o.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:a.content}})),a.tool_calls)for(let e of a.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let n=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,_bi1:n},o.push({type:"content_block_start",index:n,content_block:{type:"tool_use",id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let n=t.toolCalls[e.index];n&&o.push({type:"content_block_delta",index:n._bi1,delta:{type:"input_json_delta",partial_json:e.function.arguments}})}}return n.finish_reason&&(t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:Wt(n.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:"message_stop"})),o}async function co(e,t,o){let n={query:t,max_results:o?.maxResults??5};o?.includeDomains?.length&&(n.include_domains=o.includeDomains),o?.excludeDomains?.length&&(n.exclude_domains=o.excludeDomains),Z.debug("Tavily search request:",JSON.stringify(n));let a=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)});if(!a.ok){let e=await a.text();throw Z.error(`Tavily API error (${a.status}):`,e),Error(`Tavily API error: ${a.status} ${e}`)}let r=await a.json();return Z.debug(`Tavily returned ${r.results.length} results`),r.results}function uo(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function po(e,t){let o=function(e){let t,o=e.messages[0];if(!o||"user"!==o.role)return null;if("string"==typeof o.content)t=o.content;else{if(!Array.isArray(o.content))return null;{let e=o.content.find(e=>"text"===e.type);if(!e)return null;t=e.text}}return t.startsWith("Perform a web search for the query: ")?t.slice(36).trim():t.trim()||null}(t);if(!o)return e.json({type:"error",error:{type:"invalid_request_error",message:"Could not extract search query from web search request"}},400);let n=function(e){let t=e.tools?.[0];return{maxResults:"number"==typeof t?.max_uses?t.max_uses:5,allowedDomains:t?.allowed_domains,blockedDomains:t?.blocked_domains}}(t);Z.info(`Web search intercepted: "${o}"`);let a=[];try{let e=x.tavilyApiKey;if(!e)throw Error("No Tavily API key configured");a=(await co(e,o,{maxResults:Math.min(n.maxResults,10),includeDomains:n.allowedDomains,excludeDomains:n.blockedDomains})).map(e=>({type:"web_search_result",url:e.url,title:e.title,encrypted_content:Buffer.from(e.content).toString("base64"),page_age:null}))}catch(e){Z.error("Tavily search failed:",e)}let r={query:o,results:a,model:t.model};if(!t.stream)return e.json(function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${uo()}`,r=[{type:"text",text:"I'll search for that."},{type:"server_tool_use",id:a,name:"web_search",input:{query:t}},{type:"web_search_tool_result",tool_use_id:a,content:o}];return{id:`msg_tavily_${uo()}`,type:"message",role:"assistant",model:n,content:r,stop_reason:"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}(r));let s=function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${uo()}`,r=`msg_tavily_${uo()}`,s=[];return s.push({type:"message_start",message:{id:r,type:"message",role:"assistant",content:[],model:n,stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}},{type:"content_block_start",index:0,content_block:{type:"text",text:""}},{type:"content_block_delta",index:0,delta:{type:"text_delta",text:"I'll search for that."}},{type:"content_block_stop",index:0},{type:"content_block_start",index:1,content_block:{type:"server_tool_use",id:a,name:"web_search",input:{}}},{type:"content_block_delta",index:1,delta:{type:"input_json_delta",partial_json:JSON.stringify({query:t})}},{type:"content_block_stop",index:1},{type:"content_block_start",index:2,content_block:{type:"web_search_tool_result",tool_use_id:a,content:o}},{type:"content_block_stop",index:2},{type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{output_tokens:0}},{type:"message_stop"}),s}(r);return _e(e,async e=>{for(let t of s)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}async function mo(e){let t=await e.req.json();if(function(e){let t=e.tools;if(!t||1!==t.length)return!1;let o=t[0].type;return"string"==typeof o&&o.startsWith("web_search")}(t))return po(e,t);await It(x),Z.debug("Anthropic request payload:",JSON.stringify(t));let o=e.req.header("anthropic-beta")??"",n=/context-1m/i.test(o);if(n&&/claude/i.test(t.model)){let e=t.model;t={...t,model:`${t.model}-1m`},Z.debug(`Detected context-1m beta flag, rewriting model: '${e}' → '${t.model}'`)}let a=function(e,t){return s.startActiveSpan("copilot_api.model.validate",o=>{try{o.setAttribute("copilot_api.model.requested",t.model);let e=Ot(t.model);return o.setAttribute("copilot_api.model.normalized",e),e===t.model?(o.setAttribute("copilot_api.model.was_mapped",!1),t):(o.setAttribute("copilot_api.model.was_mapped",!0),C.add(1,{from_model:t.model,to_model:e}),Z.debug(`Model mapping: '${t.model}' → '${e}'`),{...t,model:e})}catch(t){if(t instanceof St)return e.json({type:"error",error:{type:"invalid_request_error",message:t.message}},t.statusCode),null;throw t}finally{o.end()}})}(e,t);if(!a)return;if(t=a,function(e){return/gpt-[\d.]+-codex/i.test(e)}(t.model))return async function(e,t){let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.anthropic_to_responses",e=>{try{return e.setAttribute("copilot_api.translation.direction","anthropic_to_responses"),e.setAttribute("copilot_api.translation.message_count",t.messages.length),Zt(t)}finally{e.end()}});u.record(performance.now()-o,{direction:"anthropic_to_responses"}),Z.debug("Translated Responses API payload:",JSON.stringify(n)),e.set("requestData",{model:n.model,streaming:!!n.stream}),x.manualApprove&&await wt();let a=performance.now(),r=await Lt(n),i=performance.now()-a;if(S.record(i,{model:n.model,target:"responses",streaming:String(!!n.stream)}),go(r)){let t=e.get("requestData")||{};if(r.usage&&(t.tokenUsage=vt({prompt_tokens:r.usage.input_tokens,completion_tokens:r.usage.output_tokens,total_tokens:r.usage.total_tokens})),t._d1=i,e.set("requestData",t),Z.debug("Non-streaming Responses API response:",JSON.stringify(r).slice(-400)),"failed"===r.status)return e.json({type:"error",error:{type:r.error?.code??"api_error",message:r.error?.message??"Response generation failed"}},500);let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.responses_to_anthropic",e=>{try{return e.setAttribute("copilot_api.translation.direction","responses_to_anthropic"),function(e){let t=[],o=!1;for(let n of e.output)if("message"===n.type)for(let e of n.content)e.text&&t.push({type:"text",text:e.text});else if("function_call"===n.type){o=!0;let e={};try{e=JSON.parse(n.arguments)}catch{}t.push({type:"tool_use",id:n.call_id,name:n.name,input:e})}return{id:e.id,type:"message",role:"assistant",model:e.model,content:t,stop_reason:ao(e.status,o),stop_sequence:null,usage:{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}}(r)}finally{e.end()}});return u.record(performance.now()-o,{direction:"responses_to_anthropic"}),e.json(n)}Z.debug("Streaming Responses API response");let{events:l,span:c,release:p}=r;return _e(e,async t=>{let o=null,a=0,r=performance.now(),s={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,responseId:"",model:"",toolCalls:{}};try{try{for await(let r of l){if(Z.debug("Responses API raw stream event:",JSON.stringify(r)),!r.data)continue;let l;try{l=JSON.parse(r.data)}catch{continue}a++,g.add(1,{model:n.model,endpoint_type:"responses"});let c=_o(l);if(c){o=c;let t=e.get("requestData")||{};t.tokenUsage=vt(o),t._d1=i,e.set("requestData",t)}let u=io(l,s);for(let e of u)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let c=performance.now()-r,u={model:n.model,endpoint_type:"responses"};V.record(c,u),Y.record(a,u)}finally{o&&xt(c,o),c.end(),p()}let u=e.get("requestId");u&&B.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e,t);let r=performance.now(),i=s.startActiveSpan("copilot_api.translate.anthropic_to_openai",e=>{try{e.setAttribute("copilot_api.translation.direction","anthropic_to_openai"),e.setAttribute("copilot_api.translation.message_count",t.messages.length),e.setAttribute("copilot_api.translation.has_tools",!!t.tools?.length),e.setAttribute("copilot_api.translation.has_system",!!t.system),e.setAttribute("copilot_api.translation.context_1m_beta",n);let o=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"===e.type)),a=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"thinking"===e.type));return e.setAttribute("copilot_api.translation.has_images",o),e.setAttribute("copilot_api.translation.has_thinking",a),function(e){return{model:e.model,messages:Kt(e.messages,e.system),max_tokens:e.max_tokens,stop:e.stop_sequences,stream:e.stream,temperature:e.temperature,top_p:e.top_p,user:e.metadata?.user_id,tools:Yt(e.tools),tool_choice:Vt(e.tool_choice)}}(t)}finally{e.end()}});u.record(performance.now()-r,{direction:"anthropic_to_openai"}),Z.debug("Translated OpenAI request payload:",JSON.stringify(i)),e.set("requestData",{model:i.model,streaming:!!i.stream});let l=performance.now();x.manualApprove&&await wt();let c=await Et(i),p=performance.now()-l;if(S.record(p,{model:i.model,target:"chat_completions",streaming:String(!!i.stream)}),fo(c)){let t=e.get("requestData")||{};c.usage&&(t.tokenUsage=vt(c.usage)),t._d1=p,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(c).slice(-400));let o=performance.now(),n=s.startActiveSpan("copilot_api.translate.openai_to_anthropic",e=>{try{e.setAttribute("copilot_api.translation.direction","openai_to_anthropic");let t=function(e){let t=[],o=[],n=null;n=e.choices[0]?.finish_reason??n;for(let a of e.choices){let e=Qt(a.message.content),r=Xt(a.message.tool_calls);t.push(...e),o.push(...r),("tool_calls"===a.finish_reason||"stop"===n)&&(n=a.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o],stop_reason:Wt(n),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}(c);return e.setAttribute("copilot_api.translation.content_blocks",t.content.length),e.setAttribute("copilot_api.translation.stop_reason",t.stop_reason??"null"),e.setAttribute("copilot_api.translation.has_tool_use",t.content.some(e=>"tool_use"===e.type)),t}finally{e.end()}});return u.record(performance.now()-o,{direction:"openai_to_anthropic"}),Z.debug("Translated Anthropic response:",JSON.stringify(n)),e.json(n)}Z.debug("Streaming response from service");let{events:d,span:m,release:_}=c;return _e(e,async t=>{let o=null,n=0,a=performance.now(),r={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,toolCalls:{}};try{try{for await(let a of d){if(Z.debug("Raw stream event:",JSON.stringify(a)),"[DONE]"===a.data)break;if(!a.data)continue;let s=JSON.parse(a.data);if(n++,g.add(1,{model:i.model,endpoint_type:"anthropic"}),s.usage){o=s.usage;let t=e.get("requestData")||{};t.tokenUsage=vt(o),t._d1=p,e.set("requestData",t)}let l=lo(s,r);for(let e of l)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let s=performance.now()-a,l={model:i.model,endpoint_type:"anthropic"};if(V.record(s,l),Y.record(n,l),o){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=vt(o),t._d1=p,e.set("requestData",t))}}finally{o&&xt(m,o),m.end(),_()}let s=e.get("requestId");s&&B.executeCompletion(s)}finally{e.get("resolveStreamComplete")?.()}})}function _o(e){if("response.completed"!==e.type&&"response.incomplete"!==e.type)return null;let t=e.response.usage;return t?{prompt_tokens:t.input_tokens,completion_tokens:t.output_tokens,total_tokens:t.total_tokens}:null}const fo=e=>Object.hasOwn(e,"choices"),go=e=>Object.hasOwn(e,"output");const yo=new de;yo.post("/",async e=>{try{return await mo(e)}catch(t){return await J(e,t)}});const ho=new de;function wo(e){return s.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=Ot(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),C.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function bo(e,t){let o=function(e){try{let t=JSON.parse(e);if(("response.completed"===t.type||"response.incomplete"===t.type)&&t.response?.usage){let e=t.response.usage;return{prompt_tokens:e.input_tokens,completion_tokens:e.output_tokens,total_tokens:e.total_tokens}}}catch{}return null}(e);if(!o)return;t.usageRef.value=o;let n=t.c.get("requestData")||{};n.tokenUsage=vt(o),n._d1=t._d1,t.c.set("requestData",n)}ho.get("/",async e=>{try{x.models||await ke();let t=x.models?.data.map(e=>({id:e.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:e.vendor,display_name:e.name,context_length:e.capabilities.limits?.max_context_window_tokens}));return e.json({object:"list",data:t,has_more:!1})}catch(t){return await J(e,t)}});const ko=new Set(["message","function_call","function_call_output"]),vo=new Set(["type","name","description","parameters"]);async function xo(e){if(!e)return!1;let t=e.sources;if(t&&t.length>0)return!1;let o=e.query??e.queries?.[0];return!(!o||!x.tavilyApiKey)&&(Z.info(`Enriching web search: "${o}"`),e.sources=(await co(x.tavilyApiKey,o,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function Ao(e){if(!x.tavilyApiKey)return e;try{let t=JSON.parse(e);if("response.output_item.done"===t.type){let e=t.item;if("web_search_call"===e?.type&&await xo(e.action))return JSON.stringify(t)}}catch(e){Z.error("Failed to enrich web search:",e)}return e}function $o(e,t){if("function_call"!==e.type||!t.has(e.name))return!1;if(e.type="custom_tool_call","string"==typeof e.arguments){try{e.input=JSON.parse(e.arguments).input??e.arguments}catch{e.input=e.arguments}delete e.arguments}return!0}function To(e,t){if(0===t.size)return e;try{let o=JSON.parse(e),n=o.type;if("response.output_item.added"===n||"response.output_item.done"===n){let e=o.item;if(e&&$o(e,t))return JSON.stringify(o)}if("response.completed"===n){let n=o.response?.output;if(!n)return e;let a=!1;for(let e of n)$o(e,t)&&(a=!0);if(a)return JSON.stringify(o)}}catch{}return e}function So(e){return null!=e}function Oo(e){let t=e.input,o="string"==typeof t?t:t.map(e=>function(e){switch(e.type){case"custom_tool_call":{let t=e.input;return{type:"function_call",call_id:e.call_id,name:e.name,arguments:JSON.stringify("string"==typeof t?{input:t}:t)}}case"custom_tool_call_output":return{type:"function_call_output",call_id:e.call_id,output:e.output};default:return ko.has(e.type)||"web_search_call"===e.type?e:null}}(e)).filter(e=>null!==e),n={model:e.model,input:o};for(let t of["instructions","max_output_tokens","temperature","top_p","stream","store","tool_choice","parallel_tool_calls","user"])So(e[t])&&(n[t]=e[t]);let a=new Set;if(So(e.tools)){let t=function(e){let t=new Set;return{tools:e.filter(e=>{let t=e.type;return"function"===t||"custom"===t||"web_search"===t||t.startsWith("web_search_")}).map(e=>{let o=e.type;if("web_search"===o||o.startsWith("web_search_"))return{type:e.type};let n={};for(let t of Object.keys(e))vo.has(t)&&(n[t]=e[t]);return"custom"===n.type&&(n.type="function",t.add(n.name),n.parameters||={type:"object",properties:{input:{type:"string",description:"The freeform tool input content"}},required:["input"],additionalProperties:!1}),n}),customToolNames:t}}(e.tools);n.tools=t.tools,a=t.customToolNames}if(So(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;n.reasoning={},So(t.effort)&&(n.reasoning.effort=t.effort),So(t.summary)&&(n.reasoning.summary=t.summary)}if(So(e.text)&&"object"==typeof e.text){let t=e.text;So(t.format)&&(n.text={format:t.format})}return{payload:n,customToolNames:a}}async function Io(e,t,o){await async function(e){if(x.tavilyApiKey)try{for(let t of e.output){let e=t;"web_search_call"===e.type&&await xo(e.action)}}catch(e){Z.error("Failed to enrich non-streaming web search:",e)}}(t);let n=e.get("requestData")||{};return t.usage&&(n.tokenUsage=vt({prompt_tokens:t.usage.input_tokens,completion_tokens:t.usage.output_tokens,total_tokens:t.usage.total_tokens})),n._d1=o,e.set("requestData",n),e.json(t)}const qo=e=>Object.hasOwn(e,"output"),No=new de;No.post("/",async e=>{try{return await async function(e){await It(x);let{payload:t,customToolNames:o}=Oo(await e.req.json()),n=t;Z.debug(`Responses API [${Array.isArray(n.input)?n.input.length:1} items]`),o.size>0&&Z.debug(`Custom tools detected: ${[...o].join(", ")}`);try{n=wo(n)}catch(t){if(t instanceof St)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:n.model,streaming:!!n.stream}),x.manualApprove&&await wt();let a=performance.now(),r=await Lt(n),s=performance.now()-a;if(S.record(s,{model:n.model,target:"responses",streaming:String(!!n.stream)}),qo(r))return Io(e,r,s);let{events:i,span:l,release:c}=r;return _e(e,async t=>{let a={value:null},r=0,u=performance.now();try{try{for await(let l of i)if(l.data&&"[DONE]"!==l.data){r++;let i=To(l.data,o);i=await Ao(i);let c=i===l.data?l:{...l,data:i};g.add(1,{model:n.model,endpoint_type:"responses"}),bo(i,{usageRef:a,c:e,_d1:s}),await t.writeSSE(c)}else await t.writeSSE(l);let l=performance.now()-u,c={model:n.model,endpoint_type:"responses"};V.record(l,c),Y.record(r,c)}finally{a.value&&xt(l,a.value),l.end(),c()}let p=e.get("requestId");p&&B.executeCompletion(p)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const Po=new de;Po.get("/",e=>{try{return e.json({token:x._t1})}catch(t){return console.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const Eo=new de;Eo.get("/",async e=>{try{let t=await qe();return e.json(t)}catch(t){return console.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const jo=new de;jo.use(async(e,t)=>{let o=Date.now(),n=`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,a=e.req.method,r=e.req.path,i=function(e){return e.includes("/messages")?"anthropic":e.includes("/chat/completions")?"openai":e.includes("/embeddings")?"embeddings":e.includes("/models")?"models":e.includes("/usage")?"usage":e.includes("/token")?"token":"unknown"}(r);e.set("requestId",n),e.header("x-request-id",n);let l=s.startSpan("copilot_api.handle_request",{kind:oe.SERVER,attributes:{"http.method":a,"http.url":e.req.url,"http.route":r,"copilot_api.request_id":n,"copilot_api.endpoint_type":i}});for(let[t,o]of Object.entries(e.req.header())){let e=t.toLowerCase();D.has(e)||l.setAttribute(`http.request.header.${e}`,o)}let c,u=new Promise(e=>{c=e});e.set("streamComplete",u),e.set("resolveStreamComplete",c);let p=re.setSpan(ae.active(),l);await ae.with(p,async()=>{B.registerCompletion(n,e,o);try{await t()}catch(e){let t=e instanceof Error?e:Error(String(e));throw l.setStatus({code:ne.ERROR,message:t.message}),l.recordException(t),e}});let d=e.get("requestData"),m={c:e,start:o,method:a,path:r,endpointType:i,requestId:n,span:l};d?.streaming?u.then(()=>ht(m)).catch(e=>{Z.debug("Error finalizing streaming request:",e),l.end()}):ht(m)}),jo.use(me()),jo.get("/",e=>e.text("Server running")),jo.route("/chat/completions",Dt),jo.route("/models",ho),jo.route("/embeddings",Mt),jo.route("/usage",Eo),jo.route("/token",Po),jo.route("/v1/chat/completions",Dt),jo.route("/v1/models",ho),jo.route("/v1/embeddings",Mt),jo.route("/v1/messages",yo),jo.post("/v1/messages/count_tokens",async function(e){let t;try{t=await e.req.json()}catch{return e.json({error:{type:"invalid_request_error",message:"Invalid JSON"}},400)}if(!Array.isArray(t.messages))return e.json({error:{type:"invalid_request_error",message:"messages is required"}},400);let o=Ft.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");o+=Ft.perMessage+Bt(e)*Ft.contentMultiplier}for(let e of t.messages)o+=Ft.perMessage,o+=Bt(e.role),"string"==typeof e.content?o+=Bt(e.content)*Ft.contentMultiplier:Array.isArray(e.content)&&(o+=Jt(e.content));return t.tools&&t.tools.length>0&&(o+=function(e){let t=Ft.toolsExist;for(let[o,n]of e.entries())o>0&&(t+=Ft.perTool),t+=Bt(n.name),n.description&&(t+=Ft.perDesc+Bt(n.description)),t+=Ut(n.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(o)})}),jo.route("/v1/responses",No),jo.route("/responses",No);const Co=[],Ro=Date.now();let Do="";function Mo(){let e=async(e,t=0)=>{let o=s.startSpan("copilot_api.server.shutdown",{kind:oe.INTERNAL,attributes:{"copilot_api.shutdown.reason":e,"copilot_api.shutdown.exit_code":t,"copilot_api.uptime_seconds":(Date.now()-Ro)/1e3}});for(let t of Co)try{await t()}catch(e){Z.error("Error during cleanup:",e)}o.end(),function(e,t){let o=lt("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),n=["",ut,` ${ot("COPILOT-API")} ${nt(`v${e}`)} ${nt("·")} ${yt(t)} uptime`,ut,""," Check in from time to time on",` ${at(o)}`,"",ut,""];console.log(n.join("\n"))}(Do,Date.now()-Ro),le.exit(t)};le.on("SIGINT",()=>e("SIGINT")),le.on("SIGTERM",()=>e("SIGTERM")),le.on("uncaughtException",t=>{Z.error("Uncaught exception:",t),e("uncaughtException",1)}),le.on("unhandledRejection",(t,o)=>{Z.error("Unhandled promise rejection at:",o,"reason:",t),e("unhandledRejection",1)})}function Ho(e){let{options:t,version:n,runtime:a,_u1:r}=e,i=s.startSpan("copilot_api.server.startup",{kind:oe.INTERNAL,attributes:o({config:{version:n,port:t.port,accountType:t.accountType,verbose:t.verbose,manualApprove:t.manual,rateLimitSeconds:t.rateLimit??0,rateLimitWait:t.rateLimitWait,timeoutMs:t.timeout,showToken:t.showToken,_cc1:t._cc1,model:t.model,smallModel:t.smallModel,_t3:t._t2?"cli_arg":"stored"},runtime:a,identity:{_u1:r.login,machineId:x.machineId,sessionId:x.sessionId,_v1:x._v1},connectivity:x.connectivity,modelsCount:x.models?.data.length??0,startupDurationMs:Date.now()-Ro},"copilot_api")});if(x.models?.data)for(let e of x.models.data)i.addEvent("copilot_api.model.available",o(e,"model"));i.end(),z(P.INFO,"INFO","Server started",o({version:n,port:t.port,accountType:t.accountType,_u1:r.login,modelsCount:x.models?.data.length??0,startupDurationMs:Date.now()-Ro},"copilot_api"))}async function Fo(e){Mo(),Co.push(()=>{Z.debug("Cleaning up connectivity monitor"),F.stop()},()=>{Z.debug("Cleaning up token management"),Z.debug("Cleaning up token management"),ve&&=void clearInterval(ve),xe&&=void F.off("online",xe),Ae&&=void F.off("offline",Ae)},async()=>{Z.debug("Cleaning up HTTP/2 client"),await async function(){Z.debug("Stopping HTTP/2 pool"),Ge&&=void clearInterval(Ge),ze&&=void clearInterval(ze);let e=[...Le.keys(),...We];Le.clear(),We.clear(),Ue.clear(),Ke=void 0;for(let t of e)Ye(t)&&(G.add(1,{event:"closed"}),await t.close())}()},async()=>{Z.debug("Shutting down OTel SDK"),await p()}),e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),e._cc1&&e.codex&&(Z.error("Cannot use --claude-code and --codex together"),le.exit(1)),x.accountType=e.accountType,x.manualApprove=e.manual,x.rateLimitSeconds=e.rateLimit,x.rateLimitWait=e.rateLimitWait,x.showToken=e.showToken,x.timeoutMs=e.timeout,e.tavilyApiKey&&(x.tavilyApiKey=e.tavilyApiKey),function(){let e="1"===le.env.COPILOT_H2_KEEPALIVE||"true"===le.env.COPILOT_H2_KEEPALIVE,t=e||"1"===le.env.COPILOT_H2||"true"===le.env.COPILOT_H2;x.connectivity.h2=t,x.connectivity.h2Keepalive=e}(),await A(),x._v1="1.115.0-insider";let t=await Pe();Do=t;let o,n=Ee();a(t,Ro),e._t2?(x._t2=e._t2,Z.info("Using provided Auth token")):await Se();try{let{_s4:e}=await import("./get-user-DqCcnRgq.mjs");o=await e(),await I(x,o.login)}catch(e){Z.error("Failed to get user info for machine ID generation:",e),Z.error("Cannot proceed without user information"),le.exit(1)}await Te(),await ke(),x.connectivity.h2&&(Xe(Qe(O(x))),x.connectivity.h2Keepalive&&et()),Ho({options:e,version:t,runtime:n,_u1:o});let r=`http://localhost:${e.port}`,s=await async function(e,t){if(!e._cc1)return!1;let o,n;if(ue(x.models,"Models should be loaded by now"),e.model&&e.smallModel){let t=x.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),t.includes(e.smallModel)||(Z.error(`Invalid small model: ${e.smallModel}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),o=e.model,n=e.smallModel}else e.model||e.smallModel?(Z.error("Both --model and --small-model must be specified for model selection"),le.exit(1)):(o=await Z.prompt("Select a model to use",{type:"select",options:x.models.data.map(e=>e.id)}),n=await Z.prompt("Select a small model to use",{type:"select",options:x.models.data.map(e=>e.id)}));let a=tt({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:o,ANTHROPIC_SMALL_FAST_MODEL:n},"claude");try{return ie.writeSync(a),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the command:"),Z.log(a),!1}}(e,r)||await async function(e,t){if(!e.codex)return!1;let o;if(ue(x.models,"Models should be loaded by now"),e.model){let t=x.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),o=e.model}else o=await Z.prompt("Select a model to use with Codex CLI",{type:"select",options:x.models.data.map(e=>e.id)});let n=tt({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy"},`codex --model ${o}`);try{return ie.writeSync(n),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the Codex CLI command:"),Z.log(n),!1}}(e,r);(function(e){let t=[..._t(e),...ft(e),...gt(e),"",...mt(dt),""];console.log(t.join("\n"))})({version:t,runtime:n,user:o.login,accountType:e.accountType,port:e.port,timeout:e.timeout,webSearch:!!e.tavilyApiKey,model:e.model,smallModel:e.smallModel,clipboardCopied:s}),ce({fetch:jo.fetch,port:e.port,bun:{idleTimeout:255}})}const Bo=Q({meta:{name:"start",description:"Start the API server"},args:{port:{alias:"p",type:"string",default:"4141",description:"Port to listen on"},verbose:{alias:"v",type:"boolean",default:!1,description:"Enable verbose logging"},"account-type":{alias:"a",type:"string",default:"individual",description:"Account type (individual, business, enterprise)"},manual:{type:"boolean",default:!1,description:"Enable manual request approval"},"rate-limit":{alias:"r",type:"string",description:"Rate limit in seconds between requests"},wait:{alias:"w",type:"boolean",default:!1,description:"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set"},"github-token":{alias:"g",type:"string",description:"Provide auth token directly (must be generated using the `auth` subcommand)"},"claude-code":{alias:"c",type:"boolean",default:!1,description:"Generate a command to launch with API config"},codex:{type:"boolean",default:!1,description:"Generate a command to launch Codex CLI with Copilot API config"},model:{alias:"m",type:"string",description:"Model to use (with --claude-code or --codex)"},"small-model":{alias:"s",type:"string",description:"Small/fast model to use (requires --claude-code)"},"show-token":{type:"boolean",default:!1,description:"Show tokens on fetch and refresh"},timeout:{alias:"t",type:"string",description:"API timeout in milliseconds (default: 600000)"},"tavily-api-key":{type:"string",description:"Tavily API key for web search support (or set TAVILY_API_KEY env var)"}},run({args:e}){let t=e["rate-limit"],o=void 0===t?void 0:Number.parseInt(t,10),n=e.timeout,a=void 0===n?c:Number.parseInt(n,10);return Fo({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e["account-type"],manual:e.manual,rateLimit:o,rateLimitWait:e.wait,_t2:e["github-token"],_cc1:e["claude-code"],codex:e.codex,model:e.model,smallModel:e["small-model"],showToken:e["show-token"],timeout:a,tavilyApiKey:e["tavily-api-key"]||le.env.TAVILY_API_KEY})}});await async function(){try{if("1"===process.env.COPILOT_API_SKIP_UPDATE_CHECK)return;let[e,t]=await Promise.all([Pe(),Be()]);if("unknown"===e||!t||!function(e,t){let o=e.split(".").map(Number),n=t.split(".").map(Number),a=Math.max(o.length,n.length);for(let e=0;e<a;e++){let t=o[e]??0,a=n[e]??0;if(t<a)return!0;if(t>a)return!1}return!1}(e,t))return;!function(e,t){let o=`npx ${De}@latest`,n=Fe("│"),a=` ${He("Update available!")} ${(e=>`${e}`)(e)} → ${(e=>`${e}`)(t)}`,r=` Run ${He(o)} to update`,s=" ".repeat(54),i=Fe(`╭${"─".repeat(54)}╮`),l=Fe(`╰${"─".repeat(54)}╯`),c=["",i,`${n}${s}${n}`,`${n}${Je(a,54)}${n}`,`${n}${s}${n}`,`${n}${Je(r,54)}${n}`,`${n}${s}${n}`,l,""];console.log(c.join("\n"))}(e,t)}catch{}}(),await X(Q({meta:{name:"copilot-api",description:"API proxy server for tool integration."},subCommands:{auth:Ie,start:Bo,"check-usage":Ne,debug:Re}}));export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-api-node20",
3
- "version": "0.20.3",
3
+ "version": "0.20.5",
4
4
  "description": "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code! (Node v20+ fork)",
5
5
  "keywords": [
6
6
  "proxy",