copilot-api-node20 0.21.3 → 0.22.1

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
@@ -7,19 +7,19 @@
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
- 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.
10
+ A proxy server that turns a GitHub Copilot subscription into fully compatible OpenAI and Anthropic API endpoints. Use Claude Code, Claude Cowork, 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
12
  ```
13
13
  Clients Proxy Backends
14
14
  ─────── ───── ────────
15
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
16
+ Claude Code ─┐ ┌─▶ GitHub Copilot API
17
+ Claude Cowork─┤ Anthropic ┌────────────┐ │ Chat Completions
18
+ Codex CLI ─┤─────or───────▶│ copilot-api │───┤ Responses API
19
+ OpenAI SDK ─┤ OpenAI └────────────┘ │ Embeddings
20
+ curl ─┤ format │
21
+ Any tool ─┘ └─▶ Tavily
22
+ Web Search
23
23
  ```
24
24
 
25
25
  ---
@@ -31,10 +31,12 @@ A proxy server that turns a GitHub Copilot subscription into fully compatible Op
31
31
  - [Claude Code](#claude-code)
32
32
  - [Codex CLI](#codex-cli)
33
33
  - [Web Search](#web-search)
34
+ - [Claude Cowork](#claude-cowork)
34
35
  - [API Endpoints](#api-endpoints)
35
36
  - [CLI Reference](#cli-reference)
36
37
  - [Commands](#commands)
37
38
  - [start Flags](#start-flags)
39
+ - [cowork-setup](#cowork-setup)
38
40
  - [Telemetry](#telemetry)
39
41
  - [Closed Source](#closed-source)
40
42
  - [Notices](#notices)
@@ -48,9 +50,11 @@ A proxy server that turns a GitHub Copilot subscription into fully compatible Op
48
50
  | Feature | Description |
49
51
  |:--|:--|
50
52
  | **Full Claude Code support** | All Claude models, streaming, extended thinking, and the complete **1M token context window** |
53
+ | **Claude Cowork support** | Run Claude's desktop app through Copilot — **one-command setup** via [Tailscale](https://tailscale.com) for zero-trust-hassle HTTPS |
51
54
  | **Full Codex CLI support** | Complete **OpenAI Responses API** implementation purpose-built for Codex CLI |
52
55
  | **Web search** | Optional **Tavily-powered web search** available to both Claude Code and Codex sessions |
53
56
  | **Dual API compatibility** | OpenAI Chat Completions, Anthropic Messages, and OpenAI Responses APIs side by side |
57
+ | **HTTPS with auto-generated certs** | Self-signed TLS certs with configurable SANs -- works across VMs, containers, and LAN |
54
58
  | **Zero configuration** | Single command to start -- authenticates via GitHub device-code OAuth |
55
59
 
56
60
  ---
@@ -118,11 +122,34 @@ npx copilot-api-node20@latest start --claude-code --tavily-api-key <key>
118
122
 
119
123
  Alternatively, set `TAVILY_API_KEY` as an environment variable. The proxy operates normally when no key is provided -- web search is simply unavailable.
120
124
 
125
+ ### Claude Cowork
126
+
127
+ Use Claude's desktop app ([Cowork](https://claude.ai/desktop)) with your Copilot subscription. Requires [Tailscale](https://tailscale.com) (free for personal use) for a real Let's Encrypt TLS certificate — no self-signed cert headaches.
128
+
129
+ **1. Install [Tailscale](https://tailscale.com/download)** and sign in. On macOS, use the [App Store or .pkg download](https://tailscale.com/download/mac) (not brew). See [docs/claude-cowork.md](./docs/claude-cowork.md) for Linux/Windows.
130
+
131
+ **2. Generate a TLS cert and configure the proxy:**
132
+
133
+ ```bash
134
+ npx copilot-api-node20@latest cowork-setup install
135
+ npx copilot-api-node20@latest start --claude-cowork
136
+ ```
137
+
138
+ **3.** Follow Anthropic's [Cowork 3P Installation guide](https://claude.com/docs/cowork/3p/installation). When prompted for the gateway URL, paste the Tailscale hostname from the startup banner (e.g. `https://your-machine.tail12345.ts.net:4141`), then **restart Cowork**.
139
+
140
+ Run `cowork-setup doctor` at any time to diagnose issues:
141
+
142
+ ```bash
143
+ npx copilot-api-node20@latest cowork-setup doctor
144
+ ```
145
+
146
+ See **[docs/claude-cowork.md](./docs/claude-cowork.md)** for the full setup guide and troubleshooting. For Cowork's own configuration docs, see [Claude Cowork 3P Installation](https://claude.com/docs/cowork/3p/installation).
147
+
121
148
  ---
122
149
 
123
150
  ## API Endpoints
124
151
 
125
- All endpoints are served at `http://localhost:4141` by default.
152
+ All endpoints are served at `http://localhost:4141` by default (`https://` when `--https` or `--claude-cowork` is used).
126
153
 
127
154
  | Method | Path | Compatibility |
128
155
  |:--|:--|:--|
@@ -146,6 +173,7 @@ All OpenAI-compatible routes are also available without the `/v1/` prefix.
146
173
  | `copilot-api auth` | Authenticate with GitHub |
147
174
  | `copilot-api check-usage` | Display Copilot usage quota |
148
175
  | `copilot-api debug` | Print diagnostic information |
176
+ | `copilot-api cowork-setup` | Manage Claude Cowork OS-level setup |
149
177
 
150
178
  ### `start` Flags
151
179
 
@@ -170,9 +198,28 @@ All OpenAI-compatible routes are also available without the `/v1/` prefix.
170
198
  | `--show-token` | | | Display tokens on fetch and refresh |
171
199
  | `--tavily-api-key` | | | Tavily API key for web search |
172
200
  | `--verbose` | `-v` | | Enable debug-level logging |
201
+ | `--https` | | | Serve over HTTPS using a self-signed cert |
202
+ | `--https-cert` | | | Path to a PEM-encoded TLS certificate (use with `--https-key`) |
203
+ | `--https-key` | | | Path to a PEM-encoded TLS private key (use with `--https-cert`) |
204
+ | `--https-hosts` | | | Extra hostnames or IPs to include in the cert's SANs (comma-separated) |
205
+ | `--claude-cowork` | | | Auto-detect Tailscale cert and enable HTTPS for Cowork. Run `cowork-setup install` first. See [docs/claude-cowork.md](./docs/claude-cowork.md) |
173
206
 
174
207
  </details>
175
208
 
209
+ ### `cowork-setup`
210
+
211
+ Manage [Tailscale](https://tailscale.com)-based HTTPS for Claude Cowork.
212
+
213
+ | Subcommand | Description |
214
+ |:--|:--|
215
+ | `cowork-setup doctor` | Diagnose Tailscale + cert status |
216
+ | `cowork-setup install` | Generate a Tailscale TLS certificate for Cowork |
217
+ | `cowork-setup revert` | Remove the generated cert files |
218
+
219
+ Requires Tailscale installed and connected (`tailscale up`). See [docs/claude-cowork.md](./docs/claude-cowork.md).
220
+
221
+ Platform support: **macOS**, **Linux**, **Windows** — anywhere Tailscale runs.
222
+
176
223
  ---
177
224
 
178
225
  ## Telemetry
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 n,D as o,E as r,F as a,G as i,H as s,I as l,J as u,K as c,L as p,M as d,N as m,O as f,P as _,R as g,S as h,T as y,U as k,V as b,W as w,X as x,Y as v,Z as A,_ as T,a as $,b as S,c as O,d as I,f as q,g as N,h as j,i as P,j as E,k as C,l as R,m as B,n as D,o as M,p as F,q as H,r as J,s as U,t as L,u as W,v as z,w as K,x as G,y as Y,z as V}from"./get-user-CEqqH34r.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 ne,SpanStatusCode as oe,context as re,trace as ae}from"@opentelemetry/api";import ie from"clipboardy";import{execFile as se,execSync as le}from"node:child_process";import ue from"node:process";import{Client as ce}from"undici";import{serve as pe}from"srvx";import de from"tiny-invariant";import{Hono as me}from"hono";import{cors as fe}from"hono/cors";import{streamSSE as _e}from"hono/streaming";import{events as ge}from"fetch-event-stream";import{Tokenizer as he,models as ye}from"ai-tokenizer";import*as ke from"ai-tokenizer/encoding/claude";const be=async()=>{let e=`${P}/copilot_internal/v2/token`,t=v.timeoutMs,n=new AbortController,o=setTimeout(()=>n.abort(),t);try{let{response:t,span:o}=await k({spanName:"github GET /copilot_internal/v2/token",url:e,target:"copilot_token",headers:W(v),signal:n.signal});if(!t.ok)throw o.end(),new D("Failed to get Service token",t);let r=await t.json();return o.end(),r}finally{clearTimeout(o)}};const we=e=>new Promise(t=>{setTimeout(t,e)}),xe=e=>null==e;async function ve(){v.models=await(async()=>{let e=`${O(v)}/models`,t=R(v),n=v.timeoutMs,o=new AbortController,r=setTimeout(()=>o.abort(),n);try{let{response:n,span:r}=await k({spanName:"copilot GET /models",url:e,target:"models",headers:t,signal:o.signal});if(!n.ok)throw r.end(),new D("Failed to get models",n);let a=await n.json();return r.setAttribute("copilot_api.models_count",a.data.length),r.end(),a}finally{clearTimeout(r)}})()}var Ae=class extends Error{constructor(e){super(e),this.name="AuthorizationError"}};let Te,$e,Se,Oe=!1;const Ie=async()=>{let{token:e,refresh_in:n}=await be();v._t1=e,Z.debug("Service token fetched successfully!"),v.showToken&&Z.info("Service token:",e);let o=async(e=5,n=1e3,o="scheduled")=>{if(!Oe)return Oe=!0,i.startActiveSpan("copilot_api.token.refresh",async r=>{let a=performance.now();r.setAttribute("copilot_api.token_refresh.reason",o),r.setAttribute("copilot_api.token_refresh.max_retries",e);try{for(let i=1;i<=e;i++)try{r.setAttribute("copilot_api.token_refresh.attempt",i),Z.debug(`Refreshing Service token (${o}, attempt ${i}/${e})`);let{token:n}=await be();return v._t1=n,Z.debug("Service token refreshed successfully"),v.showToken&&Z.info("Refreshed Service token:",n),r.setAttribute("copilot_api.token_refresh.success",!0),t.add(1,{reason:o,success:"true"}),b.record(performance.now()-a,{reason:o}),void G(j.INFO,"INFO",`Token refreshed successfully (${o})`,{"copilot_api.token_refresh.reason":o,"copilot_api.token_refresh.attempt":i})}catch(l){let u=i===e;if(Z.error(`Failed to refresh Service token (attempt ${i}/${e}):`,l),t.add(1,{reason:o,success:"false"}),u){Z.error("All refresh attempts failed. May be unavailable until next scheduled refresh.");let t=l instanceof Error?l:Error(String(l));return r.setAttribute("copilot_api.token_refresh.success",!1),r.setStatus({code:oe.ERROR,message:t.message}),r.recordException(t),s.add(1,{reason:o}),b.record(performance.now()-a,{reason:o}),void G(j.ERROR,"ERROR",`Token refresh failed after ${e} attempts (${o})`,{"copilot_api.token_refresh.reason":o,"copilot_api.token_refresh.attempts":e})}let c=n*2**(i-1);Z.debug(`Retrying token refresh in ${c}ms...`),await new Promise(e=>setTimeout(e,c))}}finally{r.end(),Oe=!1}});Z.debug("Refresh already in progress, skipping")};Te=setInterval(()=>{o(5,1e3,"scheduled").catch(e=>{Z.error("Unexpected error in scheduled token refresh:",e)})},1e3*(n-60)),F.start(),$e=()=>{Z.debug("Network connectivity restored, attempting immediate token refresh"),o(3,500,"network-restored").catch(e=>{Z.error("Unexpected error in network-restored token refresh:",e)})},Se=()=>{Z.debug("Network connectivity lost")},F.on("online",$e),F.on("offline",Se)};async function qe(e){try{let t=await ee.readFile(x.GITHUB_TOKEN_PATH,"utf8");if(t&&!e?.force)return v._t2=t,v.showToken&&Z.info("Auth token:",t),void await Ne();Z.info("Authentication required");let n=await async function(){let e=new AbortController,t=v.timeoutMs,n=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${M}/login/device/code`,{method:"POST",headers:q(),body:JSON.stringify({client_id:U,scope:$}),signal:e.signal});if(!t.ok)throw new D("Failed to get device code",t);return await t.json()}finally{clearTimeout(n)}}();Z.debug("Device code response:",n),Z.info(`Please enter the code "${n.user_code}" at ${n.verification_uri}`);try{ie.writeSync(n.user_code),Z.success("Code copied to clipboard — opening browser...")}catch{Z.info("Open the link above and enter the code to authenticate")}!function(e){try{let t,n=ue.platform;t="darwin"===n?"open":"win32"===n?"start":"xdg-open",se(t,[e],()=>{})}catch{}}(n.verification_uri);let o=await async function(e){let t=1e3*(e.interval+1);Z.debug(`Polling access token with interval of ${t}ms`),Z.start("Waiting for authorization...");let n=Date.now(),o=1e3*e.expires_in;for(;;){if(Date.now()-n>=o)throw new Ae("Authorization timed out — the code expired. Please run the command again.");let r=new AbortController,a=v.timeoutMs,i=setTimeout(()=>{r.abort()},a);try{let n=await fetch(`${M}/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:r.signal});if(!n.ok){await we(t),Z.error("Failed to poll access token:",await n.text());continue}let o=await n.json();if(Z.debug("Polling access token response:",o),o.error){if("expired_token"===o.error)throw new Ae("Authorization timed out — the code expired. Please run the command again.");if("access_denied"===o.error)throw new Ae("Authorization was denied. Please run the command again and approve the request.");"authorization_pending"!==o.error&&"slow_down"!==o.error&&Z.warn(`Unexpected auth error: ${o.error}`),await we(t);continue}if(o.access_token)return o.access_token;await we(t)}catch(e){if(e instanceof Ae)throw e;if(e instanceof Error&&"AbortError"===e.name){Z.error("Access token polling timed out"),await we(t);continue}throw e}finally{clearTimeout(i)}}}(n);await(e=>ee.writeFile(x.GITHUB_TOKEN_PATH,e))(o),v._t2=o,v.showToken&&Z.info("Auth token:",o),await Ne()}catch(e){throw e instanceof D?(Z.error("Failed to get Auth token:",await e.response.json()),e):(Z.error("Failed to get Auth token:",e),e)}}async function Ne(){let e=await L();Z.success(`Authenticated as ${e.login}`)}async function je(e){e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),v.showToken=e.showToken,await A(),await qe({force:!0}),console.log([""," Get started:",""," $ npx copilot-api-node20@latest start --claude-code"," $ npx copilot-api-node20@latest start --codex",""," Full docs: https://www.npmjs.com/package/copilot-api-node20",""].join("\n")),process.exit(0)}const Pe=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})=>je({verbose:e.verbose,showToken:e["show-token"]})}),Ee=async()=>{let e=`${P}/copilot_internal/user`,t=v.timeoutMs,n=new AbortController,o=setTimeout(()=>n.abort(),t);try{let{response:t,span:o}=await k({spanName:"github GET /copilot_internal/user",url:e,target:"usage",headers:W(v),signal:n.signal});if(!t.ok)throw o.end(),new D("Failed to get usage",t);let r=await t.json();return o.end(),r}finally{clearTimeout(o)}},Ce=Q({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await A(),await qe();try{let e=await Ee(),t=e.quota_snapshots.premium_interactions,n=t.entitlement,o=n-t.remaining,r=n>0?o/n*100:0,a=t.percent_remaining;function i(e,t){if(!t)return`${e}: N/A`;let n=t.entitlement,o=n-t.remaining,r=n>0?o/n*100:0,a=t.percent_remaining;return`${e}: ${o}/${n} used (${r.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`}let s=`Premium: ${o}/${n} used (${r.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`,l=i("Chat",e.quota_snapshots.chat),u=i("Completions",e.quota_snapshots.completions);Z.box(`Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${s}\n ${l}\n ${u}`)}catch(c){Z.error("Failed to fetch usage:",c),process.exit(1)}}});async function Re(){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 Be(){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 De(){try{return!!(await ee.stat(x.GITHUB_TOKEN_PATH)).isFile()&&(await ee.readFile(x.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function Me(e){let t=await async function(){let[e,t]=await Promise.all([Re(),De()]);return{version:e,runtime:Be(),paths:{APP_DIR:x.APP_DIR,GITHUB_TOKEN_PATH:x.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 Fe=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})=>Me({json:e.json})}),He="copilot-api-node20",Je=`https://registry.npmjs.org/${He}/latest`,Ue=e=>`${e}`,Le=e=>`${e}`;async function We(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);try{let t=await fetch(Je,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function ze(e,t){let n=Math.max(0,t-function(e){return e.replaceAll(/\x1b\[[0-9;]*m/g,"").length}(e));return e+" ".repeat(n)}const Ke=new Map,Ge=new Map,Ye=new Set;let Ve,Qe,Xe;function Ze(e){return!e.closed&&!e.destroyed}function et(e){Z.debug(`Creating HTTP/2 client for ${e}`);let t=new ce(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return Ke.set(t,Date.now()),K.add(1,{event:"created",origin:e}),G(j.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",(n,o,r)=>{Z.debug(`HTTP/2 client disconnected from ${e}:`,r.message),K.add(1,{event:"goaway",origin:e}),G(j.WARN,"WARN",`HTTP/2 client disconnected from ${e}: ${r.message}`,{"copilot_api.h2.event":"goaway","copilot_api.h2.origin":e,"copilot_api.h2.error":r.message}),Ge.delete(t),Ye.delete(t),Ke.delete(t),Ze(t)&&t.close().catch(e=>{Z.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function tt(e){if(!v.connectivity.h2)return;Ve&&Ve!==e&&function(){for(let e of[...Ge.keys(),...Ye])Ze(e)&&e.close().catch(e=>{Z.debug("Error closing HTTP/2 pool entry:",e)});Ge.clear(),Ye.clear(),Ke.clear()}(),Ve=e;let t=Date.now();for(let[n]of Ge)if(t-(Ke.get(n)??0)>=6e5)Ge.delete(n),Ke.delete(n),Ze(n)&&n.close().catch(e=>{Z.debug("Error closing rotated HTTP/2 client:",e)}),K.add(1,{event:"rotated",origin:e}),G(j.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(Ze(n))return Ge.delete(n),Ye.add(n),n;Ge.delete(n),Ke.delete(n)}let n=et(e);return Ye.add(n),n}function nt(e){e&&Ye.delete(e)&&(Ze(e)?Ge.set(e,Date.now()):Ke.delete(e))}function ot(){Xe||(Xe=setInterval(()=>{!function(){let e=Date.now(),t=v.connectivity.h2Keepalive,n=Ge.size;for(let[o,r]of Ge)e-r<6e4||t&&n<=1||(Ge.delete(o),Ke.delete(o),n--,Ze(o)&&o.close().catch(e=>{Z.debug("Error closing idle HTTP/2 client:",e)}),K.add(1,{event:"idle_reaped",origin:Ve??""}),G(j.INFO,"INFO",`HTTP/2 idle connection reaped for ${Ve}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":Ve??""}))}()},3e4),Xe.unref())}function rt(){Qe||(Z.debug("Starting HTTP/2 keepalive (every 45s)"),Qe=setInterval(()=>{(async function(){if(0===Ge.size&&0===Ye.size){if(Ve){let e=et(Ve);Ge.set(e,Date.now())}return}let e=[...Ge.keys()];await Promise.allSettled(e.map(async e=>{if(!Ze(e))return Ge.delete(e),void Ke.delete(e);try{let{statusCode:t,body:n}=await e.request({path:"/models",method:"GET",headers:R(v)});await n.dump(),y.add(1,{result:"success"}),Z.debug(`HTTP/2 keepalive: GET /models → ${t}`),Ge.set(e,Date.now())}catch(t){y.add(1,{result:"error"}),Z.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),K.add(1,{event:"error",origin:Ve??""}),Ge.delete(e),Ke.delete(e),Ze(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),Qe.unref(),ot())}function at(e,t=""){let n,o=function(){let{platform:e,ppid:t,env:n}=ue;if("win32"===e){try{if(le(`wmic process get ParentProcessId,Name | findstr "${t}"`,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}{let e=n.SHELL;if(e){if(e.endsWith("zsh"))return"zsh";if(e.endsWith("fish"))return"fish";if(e.endsWith("bash"))return"bash"}return"sh"}}(),r=Object.entries(e).filter(([,e])=>void 0!==e);switch(o){case"powershell":n=r.map(([e,t])=>`$env:${e} = ${t}`).join("; ");break;case"cmd":n=r.map(([e,t])=>`set ${e}=${t}`).join(" & ");break;case"fish":n=r.map(([e,t])=>`set -gx ${e} ${t}`).join("; ");break;default:{let e=r.map(([e,t])=>`${e}=${t}`).join(" ");n=r.length>0?`export ${e}`:"";break}}return n&&t?`${n}${"cmd"===o?" & ":" && "}${t}`:n||t}const it=e=>`${e}`,st=e=>`${e}`,lt=e=>`${e}`,ut=e=>`${e}`,ct=e=>`${e}`,pt=e=>`${e}`,dt=(e,t)=>`]8;;${e}\\${t}]8;;\\`,mt="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",ft=st(" ─────────────────────────────────────────────────────────────");function _t(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const gt=[{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 ht(e){if(0===e.length)return[];let t=["",ft,` ${it("BARAZANY.DEV")} ${st("— Recent Posts")}`,ft,""];for(let[n,o]of e.entries()){let e=dt(`${o.url}${mt}`,it(pt(`[${n+1}]`)));t.push(` ${e} ${lt(o.title)}`,` ${st("→")} ${st(o.teaser)}`,"")}return t.push(ft,` ${dt(`https://barazany.dev/blog${mt}`,"barazany.dev/blog")}`,ft),t}function yt(e){let t=[];v.connectivity.h2Keepalive?t.push("HTTP/2 keepalive"):v.connectivity.h2&&t.push("HTTP/2"),t.push(`timeout ${e.timeout/1e3}s`);let n=e.webSearch?`Tavily ${ut("✓")}`:st("off"),o=["",` ${it("COPILOT-API")} ${st(`v${e.version}`)}`,ft,` ${st("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${st("User")} ${e.user} ${st("·")} ${e.accountType}`];return v._v1&&o.push(` ${st("Client")} VSCode ${v._v1}`),o.push(` ${st("Network")} ${t.join(st(" · "))}`,` ${st("Search")} ${n}`),e.clipboardCopied&&o.push(` ${st("Clipboard")} Claude Code command ${ut("✓")}`),o.push(ft),o}function kt(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${it("Active")}`];if(e.model){let n=v.models?.data.find(t=>t.id===e.model),o=_t(n?.capabilities.limits?.max_context_window_tokens);t.push(` ${lt(e.model.padEnd(32))} ${st("ctx")} ${it(o.padStart(5))} ${ct("← main")}`)}if(e.smallModel){let n=v.models?.data.find(t=>t.id===e.smallModel),o=_t(n?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${st("ctx")} ${o.padStart(5)} ${ct("← small")}`)}return t}function bt(e){let t=[];for(let[n,o]of function(){let e=[],t=[],n=[],o=[];for(let r of v.models?.data??[]){let a=r.capabilities.limits?.max_context_window_tokens,i={id:r.id,ctx:a};r.id.startsWith("text-embedding")?o.push(i):"Anthropic"===r.vendor?e.push(i):"Google"===r.vendor?n.push(i):t.push(i)}return[["Claude",e],["OpenAI",t],["Gemini",n],["Embedding",o]]}())if(0!==o.length){t.push("",` ${it(n)}`);for(let n of o){let o=n.id===e.model||n.id===e.smallModel,r=o?lt("●"):st("·"),a=o?lt(n.id.padEnd(34)):n.id.padEnd(34),i=n.ctx?_t(n.ctx).padStart(5):"";t.push(` ${r} ${a} ${st(i)}`)}}return t}function wt(e){let t=Math.floor(e/1e3),n=Math.floor(t/3600),o=Math.floor(t%3600/60);return n>0?`${n}h ${o}m`:o>0?`${o}m`:`${t}s`}function xt(e){(function(e){let{c:t,start:n,span:o}=e,r=t.get("requestData"),a=t.res.status,i=r?.model??"unknown",s=r?.streaming??!1,l=Date.now()-n;if(o.setAttribute("http.status_code",a),o.setAttribute("copilot_api.model",i),o.setAttribute("copilot_api.streaming",s),o.setAttribute("copilot_api.duration_ms",l),r?._d1&&o.setAttribute("copilot_api.copilot_duration_ms",r._d1),r?.tokenUsage){let e=r.tokenUsage;o.setAttribute("copilot_api.input_tokens",e.inputTokens),o.setAttribute("copilot_api.output_tokens",e.outputTokens),o.setAttribute("copilot_api.total_tokens",e.totalTokens),e.cachedTokens&&o.setAttribute("copilot_api.cached_tokens",e.cachedTokens),e.estimatedCost&&o.setAttribute("copilot_api.estimated_cost",e.estimatedCost)}t.res.headers.forEach((e,t)=>{let n=t.toLowerCase();B.has(n)||o.setAttribute(`http.response.header.${n}`,e)}),a>=400&&o.setStatus({code:oe.ERROR,message:`HTTP ${a}`}),o.end()})(e),function(e){let{c:t,start:n,method:r,path:i,endpointType:s,requestId:u}=e,c=Date.now()-n,p=t.get("requestData"),m=t.res.status,_=p?.model??"unknown",g=p?.streaming??!1,y={method:r,path:i,status_code:String(m),model:_,streaming:String(g),endpoint_type:s};if(l.add(1,y),a.record(c,y),m>=400&&h.add(1,{method:r,path:i,status_code:String(m),error_type:m>=500?"server_error":"client_error"}),p?.tokenUsage){let e=p.tokenUsage,t={model:_,endpoint_type:s};e.inputTokens&&(o.add(e.inputTokens,t),f.record(e.inputTokens,t)),e.outputTokens&&(E.add(e.outputTokens,t),d.record(e.outputTokens,t)),e.cachedTokens&&z.add(e.cachedTokens,{model:_})}!g&&p?.tokenUsage&&H.executeCompletion(u)}(e)}const vt=async()=>i.startActiveSpan("copilot_api.approval.await",async e=>{let t=performance.now();try{let n=await Z.prompt("Accept incoming request?",{type:"confirm"}),o=performance.now()-t;if(e.setAttribute("copilot_api.approval.wait_duration_ms",o),T.record(o),!n)throw e.setAttribute("copilot_api.approval.result","rejected"),N.add(1,{result:"rejected"}),new D("Request rejected",Response.json({message:"Request rejected"},{status:403}));e.setAttribute("copilot_api.approval.result","approved"),N.add(1,{result:"approved"})}finally{e.end()}}),At=3e-6,Tt=15e-6;function $t(e){let t=e.prompt_tokens||0,n=e.completion_tokens||0;return{inputTokens:t,outputTokens:n,totalTokens:e.total_tokens||t+n,estimatedCost:t*At+n*Tt,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function St(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 Ot=[{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[.-]7/i,family:"opus-4.7"},{pattern:/opus[.-]?4[.-]6/i,family:"opus-4.6"},{pattern:/opus[.-]?4[.-]5/i,family:"opus-4.5"},{pattern:/opus/i,family:"opus"}],It={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.7":"claude-opus-4.7","opus-4.6":"claude-opus-4.6","opus-4.5":"claude-opus-4.5",opus:"claude-opus-4.5"};function qt(e,t){let n=function(e){return e.startsWith("anthropic/")?e.slice(10):e}(e),[o,r]=function(e){let t=e.lastIndexOf("["),n=e.lastIndexOf("]");return-1!==t&&n===e.length-1&&n>t?[e.slice(0,t),e.slice(t+1,n)]:[e,null]}(n);if(t.includes(n))return n;if(r){let e=`${o}-${r}`.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(e))return e}let a=function(e){for(let t of Ot)if(t.pattern.test(e))return t.family;return null}(o);if(!a)return null;let i=o.replace(/-\d{8}(?::.*)?$/,""),s=r?`-${r}`:"";for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,""),n=`${i}${s}`.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.toLowerCase().replaceAll(/(\d)-(\d)\b/g,"$1.$2")===n)return e}return function(e,t,n=null){let o=It[e];if(!o)return null;if(n){let e=`${o}-${n}`;if(t.includes(e))return e}if(t.includes(o))return o;if("sonnet-4.5"===e)for(let e of["claude-3.5-sonnet"]){let o=n?`${e}-${n}`:e;if(t.includes(o))return o}return null}(a,t,r)}var Nt=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function jt(t){if(!t||"string"!=typeof t)throw new Nt("Model name is required and must be a string");if(!v.models?.data)throw new Nt("Models not available. Please try again later.",503);let n=v.models.data.map(e=>e.id);if(n.includes(t))return t;let o=qt(t,n);if(!o)throw e.add(1,{requested_model:t}),new Nt(`Invalid model: '${t}'. Available services: ${n.join(", ")}`);return o}async function Pt(e){if(void 0===e.rateLimitSeconds)return;let t=e.rateLimitSeconds;return i.startActiveSpan("copilot_api.rate_limit.check",async n=>{try{let o=Date.now();if(n.setAttribute("copilot_api.rate_limit.configured_seconds",t),!e.lastRequestTimestamp)return e.lastRequestTimestamp=o,void n.setAttribute("copilot_api.rate_limit.action","allowed");let r=(o-e.lastRequestTimestamp)/1e3;if(n.setAttribute("copilot_api.rate_limit.elapsed_seconds",r),r>t)return e.lastRequestTimestamp=o,void n.setAttribute("copilot_api.rate_limit.action","allowed");let a=Math.ceil(t-r);if(n.setAttribute("copilot_api.rate_limit.wait_seconds",a),!e.rateLimitWait)throw n.setAttribute("copilot_api.rate_limit.action","rejected"),m.add(1,{action:"rejected",source:"local"}),Z.warn(`Rate limit exceeded. Need to wait ${a} more seconds.`),new D("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let i=1e3*a;n.setAttribute("copilot_api.rate_limit.action","waited"),m.add(1,{action:"waited",source:"local"}),_.record(i,{source:"local"}),Z.warn(`Rate limit reached. Waiting ${a} seconds before proceeding...`),await we(i),e.lastRequestTimestamp=o,Z.info("Rate limit wait completed, proceeding with request")}finally{n.end()}})}function Et(e){if("number"==typeof e){if(!Number.isFinite(e))return null;let t=Math.floor(e);return t>0?t:null}if("string"==typeof e){let t=e.trim();if(!t)return null;let n=Number(t);if(!Number.isFinite(n))return null;let o=Math.floor(n);return o>0?o:null}return null}function Ct(e,t,n){return Math.min(Math.max(e,t),n)}function Rt(e,t=0){if(t>5||!e||"object"!=typeof e)return null;let n=e.error;if(!n||"object"!=typeof n)return null;let o=n.code;if("string"==typeof o)return o;let r=n.message;if("string"!=typeof r)return null;try{return Rt(JSON.parse(r),t+1)}catch{return null}}function Bt(e,t){let n=e?.data.find(e=>e.id===t);if(!n)return null;let o=Et(n.capabilities.supports.min_thinking_budget),r=Et(n.capabilities.supports.max_thinking_budget);return!o||!r||r<=o?null:{bounds:{min:o,max:r-1},maxOutputTokens:Et(n.capabilities.limits?.max_output_tokens)??void 0}}function Dt(e){let{config:t}=e,n=t.bounds.min,o=t.bounds.max,r=Ct(Et(e.requestedBudget)??n,n,o),a=Et(e.maxTokens);if(a||=r+1,t.maxOutputTokens&&a>t.maxOutputTokens&&(a=t.maxOutputTokens),a<=r){let e=Math.min(r,a-1);if(e>=n)r=e;else{let e=n+1;if(t.maxOutputTokens&&e>t.maxOutputTokens)return{thinkingBudget:null,maxTokens:a};a=e,r=n}}return a<=r?{thinkingBudget:null,maxTokens:a}:{thinkingBudget:r,maxTokens:a}}function Mt(e,t,n){if(xe(e.thinking_budget))return e;if(!1===n?.enabled)return{...e,thinking_budget:void 0};let o=Bt(t,e.model);if(!o)return{...e,thinking_budget:void 0};let r=Dt({requestedBudget:e.thinking_budget,maxTokens:e.max_tokens,config:o});return null===r.thinkingBudget?{...e,max_tokens:r.maxTokens,thinking_budget:void 0}:{...e,max_tokens:r.maxTokens,thinking_budget:r.thinkingBudget}}function Ft(e){return"invalid_thinking_budget"===Rt(e)}async function Ht(e){let{payload:t,error:n,models:o,errorBodyText:r}=e;if(xe(t.thinking_budget)||!(n instanceof Error))return null;let a,i,s=n;if(!(s.response instanceof Response)||400!==s.response.status)return null;if(void 0!==r)a=r;else try{a=await s.response.clone().text()}catch{return null}try{i=JSON.parse(a)}catch{return null}if(!Ft(i))return null;let l=Bt(o,t.model);return l?function(e,t){let n=Dt({requestedBudget:e.thinking_budget,maxTokens:e.max_tokens,config:t});if(null===n.thinkingBudget)return{...e,max_tokens:n.maxTokens,thinking_budget:void 0};let o=n.thinkingBudget,r=Et(e.thinking_budget);if(r&&r===n.thinkingBudget){let e=o+1;e<=t.bounds.max&&(!n.maxTokens||e<n.maxTokens)&&(o=e)}let a=n.maxTokens;if((!a||a<=o)&&(a=o+1),t.maxOutputTokens&&a>t.maxOutputTokens){if(!(t.maxOutputTokens>o))return{...e,max_tokens:t.maxOutputTokens,thinking_budget:void 0};a=t.maxOutputTokens}return{...e,max_tokens:a,thinking_budget:o}}(t,l):{...t,thinking_budget:void 0}}function Jt(e){if(!(e instanceof Error))return!1;let t=e.code;return(!t||"UND_ERR_SOCKET"===t)&&/GOAWAY/i.test(e.message)}async function Ut(){return new Promise(e=>setTimeout(e,100))}function Lt(e){if("string"==typeof e)return function(e){let t=e,n=String.fromCodePoint(27),o=t.split(n);if(o.length>1){t=o[0];for(let e=1;e<o.length;e++){let r=o[e],a=r.match(/^\[[0-9;]*[a-z]/i);t+=a?r.slice(a[0].length):n+r}}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=>Lt(e));if(e&&"object"==typeof e){let t={};for(let[n,o]of Object.entries(e))t[n]=Lt(o);return"object"===t.type&&!("properties"in t)&&(t.properties={}),t}return e}const Wt=async e=>{let t=Lt(e);try{return await zt(t)}catch(e){let n;if(e instanceof D)try{n=await e.response.clone().text()}catch{n=void 0}let o=await Ht({payload:t,error:e,models:v.models,errorBodyText:n});if(o)return e instanceof D&&void 0!==n&&Z.warn(`Upstream rejected thinking_budget (status ${e.response.status}): ${n.slice(0,500)}`),Z.warn("Adjusting thinking_budget payload and retrying once..."),await zt(Lt(o));throw e}},zt=async e=>{if(!v._t1)throw Error("Service token not found");let t=e.messages.some(e=>"string"!=typeof e.content&&e.content?.some(e=>"image_url"===e.type)),n=e.messages.some(e=>["assistant","tool"].includes(e.role)),o={...R(v,t),"X-Initiator":n?"agent":"user"},r=O(v),a=`${r}/chat/completions`,i=v.timeoutMs,s=JSON.stringify(e),l={"copilot_api.model":e.model,"copilot_api.streaming":!!e.stream,"copilot_api.timeout_ms":i,"copilot_api.has_tools":!!e.tools?.length,"copilot_api.tool_count":e.tools?.length??0,"copilot_api.message_count":e.messages.length,"copilot_api.max_tokens":e.max_tokens??0,"copilot_api.vision_enabled":t,"copilot_api.initiator":n?"agent":"user"};for(let t=0;t<=1;t++){let n=tt(r),u=new AbortController,c=setTimeout(()=>u.abort(),i);try{let{statusCode:r,headers:c,body:p,span:d}=await w({spanName:"copilot POST /chat/completions",url:a,target:"chat_completions",headers:o,body:s,signal:u.signal,headersTimeout:i,bodyTimeout:3*i,extraAttributes:{...l,"copilot_api.h2.retry_attempt":t},dispatcher:n}),m=new Response(p,{status:r,headers:c});if(!m.ok)throw d.end(),new D("Failed to create chat completions",m);if(e.stream)return{events:ge(m),span:d,release:()=>nt(n)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&St(d,f.usage),d.end(),nt(n),f}catch(e){if(nt(n),Jt(e)&&t<1){Z.warn(`HTTP/2 GOAWAY during chat completions, retrying (attempt ${t+1})`),await Ut();continue}throw e}finally{clearTimeout(c)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function Kt(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=jt(e.model);return t.setAttribute("copilot_api.model.normalized",n),n===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:n}),Z.debug(`Normalized model from '${e.model}' to '${n}'`),{...e,model:n})}finally{t.end()}})}function Gt(e,t){if(!e.data)return e;try{let n=JSON.parse(e.data);if(n.usage&&t(n.usage),void 0!==n.usage?.prompt_tokens_details?.cached_tokens)return{...e,data:JSON.stringify({...n,usage:{...n.usage,prompt_tokens_details:void 0}})}}catch(t){Z.warn("Failed to parse streaming chunk:",e.data.slice(0,200),t)}return e}const Yt=e=>Object.hasOwn(e,"choices"),Vt=new me;Vt.post("/",async e=>{try{return await async function(e){await Pt(v);let t=await e.req.json();Z.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=Kt(t)}catch(t){if(t instanceof Nt)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}),v.manualApprove&&await vt(),xe(t.max_tokens)){let e=v.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))}t=Mt(t,v.models,{enabled:v.thinkingEnabled}),xe(t.thinking_budget)||Z.debug("Normalized thinking_budget to:",JSON.stringify(t.thinking_budget));let n=performance.now(),o=await Wt(t),r=performance.now()-n;if(S.record(r,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),Yt(o)){let t=e.get("requestData")||{};return o.usage&&(t.tokenUsage=$t(o.usage)),t._d1=r,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(o)),e.json(o)}let{events:a,span:i,release:s}=o;return _e(e,async n=>{let o={value:null},l=0,u=performance.now();try{try{for await(let i of a){let a=i;i.data&&"[DONE]"!==i.data&&(l++,g.add(1,{model:t.model,endpoint_type:"openai"}),a=Gt(i,t=>{o.value=t;let n=e.get("requestData")||{};n.tokenUsage=$t(t),n._d1=r,e.set("requestData",n)})),await n.writeSSE(a)}let i=performance.now()-u,s={model:t.model,endpoint_type:"openai"};if(V.record(i,s),Y.record(l,s),o.value){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=$t(o.value),t._d1=r,e.set("requestData",t))}}finally{o.value&&St(i,o.value),i.end(),s()}let c=e.get("requestId");c&&H.executeCompletion(c)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const Qt=new me;Qt.post("/",async e=>{try{let t=await e.req.json();try{jt(t.model)}catch(t){if(t instanceof Nt)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 n=performance.now(),o=await(async e=>{if(!v._t1)throw Error("Service token not found");let t=`${O(v)}/embeddings`,n=R(v),o=v.timeoutMs,r=new AbortController,a=setTimeout(()=>r.abort(),o);try{let{response:o,span:a}=await k({spanName:"copilot POST /embeddings",url:t,target:"embeddings",method:"POST",headers:n,body:JSON.stringify(e),signal:r.signal,extraAttributes:{"copilot_api.model":e.model,"copilot_api.input_count":Array.isArray(e.input)?e.input.length:1}});if(!o.ok)throw a.end(),new D("Failed to create embeddings",o);let i=await o.json();return a.end(),i}finally{clearTimeout(a)}})(t),r=performance.now()-n;S.record(r,{model:t.model,target:"embeddings",streaming:"false"});let a=e.get("requestData")||{};return a.tokenUsage=$t(o.usage),a._d1=r,e.set("requestData",a),e.json(o)}catch(t){return await J(e,t)}});const Xt=new he(ke),Zt={...ye["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function en(e){return Xt.encode(e).length}function tn(e){let t=0;for(let n of e)switch(n.type){case"text":t+=en(n.text)*Zt.contentMultiplier;break;case"tool_use":t+=en(n.name+JSON.stringify(n.input))*Zt.contentMultiplier;break;case"tool_result":n.content&&(t+=en("string"==typeof n.content?n.content:JSON.stringify(n.content))*Zt.contentMultiplier);break;case"thinking":t+=en(n.thinking)*Zt.contentMultiplier;break;case"image":t+=1600}return t}function nn(e){let t=0,n=e.properties;if(!n)return t;let o=Object.entries(n);for(let[e,[n,r]]of o.entries()){if(t+=0===e?Zt.perFirstProp:Zt.perAdditionalProp,t+=en(n),r.description&&(t+=Zt.perPropDesc+en(r.description)),r.enum&&Array.isArray(r.enum)){t+=Zt.perEnum;for(let e of r.enum)t+=en(String(e))}if("object"===r.type&&r.properties&&(t+=Zt.perNestedObject,t+=nn(r)),"array"===r.type&&r.items){let e=r.items;"object"===e.type&&e.properties&&(t+=Zt.perArrayOfObjects,t+=nn(e))}}return t}const on=async e=>{if(!v._t1)throw Error("Service token not found");let t=Lt(e),n={...R(v),"X-Initiator":"agent"},o=O(v),r=`${o}/responses`,a=v.timeoutMs,i=JSON.stringify(t),s={"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":a,"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=tt(o),u=new AbortController,c=setTimeout(()=>u.abort(),a);try{let{statusCode:o,headers:c,body:p,span:d}=await w({spanName:"copilot POST /responses",url:r,target:"responses",headers:n,body:i,signal:u.signal,headersTimeout:a,bodyTimeout:3*a,extraAttributes:{...s,"copilot_api.h2.retry_attempt":e},dispatcher:l}),m=new Response(p,{status:o,headers:c});if(!m.ok)throw d.end(),new D("Failed to create responses",m);if(t.stream)return{events:ge(m),span:d,release:()=>nt(l)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&St(d,{prompt_tokens:f.usage.input_tokens,completion_tokens:f.usage.output_tokens,total_tokens:f.usage.total_tokens}),d.end(),nt(l),f}catch(t){if(nt(l),Jt(t)&&e<1){Z.warn(`HTTP/2 GOAWAY during responses, retrying (attempt ${e+1})`),await Ut();continue}throw t}finally{clearTimeout(c)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function rn(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function an(e,t){let n={model:e.model,messages:sn(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:dn(e.tools),tool_choice:mn(e.tool_choice)},o=e.thinking;if("enabled"===o?.type||"adaptive"===o?.type){let r=Bt(t,n.model);if(r){let a="enabled"===o.type&&"number"==typeof o.budget_tokens?o.budget_tokens:function(e,t,n){let o=function(e,t){return"max"===e?t:"high"===e?16e3:"medium"===e?8e3:1024}(e,n.max),r=Et(t),a=r&&r>1?r-1:n.min;return Ct(Math.min(o,a),n.min,n.max)}(e.output_config?.effort??"high",n.max_tokens,r.bounds);n=Mt({...n,thinking_budget:a},t)}}return n}function sn(e,t){let n=function(e){return e?"string"==typeof e?[{role:"system",content:ln(e)}]:[{role:"system",content:ln(e.map(e=>e.text).join("\n\n"))}]:[]}(t),o=e.flatMap(e=>"user"===e.role?function(e){let t=[];if(Array.isArray(e.content)){let n=e.content.filter(e=>"tool_result"===e.type),o=e.content.filter(e=>"tool_result"!==e.type);for(let e of n)t.push({role:"tool",tool_call_id:e.tool_use_id,content:pn(e.content)});o.length>0&&t.push({role:"user",content:pn(o)})}else t.push({role:"user",content:pn(e.content)});return t}(e):function(e){let t=function(e){return{reasoning_text:cn(e.reasoning_text),reasoning_opaque:cn(e.reasoning_opaque)}}(e);if(!Array.isArray(e.content))return[{role:"assistant",content:pn(e.content),...t}];let n=e.content.filter(e=>"tool_use"===e.type),o=e.content.filter(e=>"text"===e.type),r=e.content.filter(e=>"thinking"===e.type),a=[...o.map(e=>e.text),...r.map(e=>e.thinking)].join("\n\n");return n.length>0?[{role:"assistant",content:a||null,...t,tool_calls:n.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:"assistant",content:pn(e.content),...t}]}(e));return[...n,...o]}function ln(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}const un=32768;function cn(e){if("string"==typeof e)return e.length<=un?e:e.slice(0,un)}function pn(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 n of e)switch(n.type){case"text":t.push({type:"text",text:n.text});break;case"thinking":t.push({type:"text",text:n.thinking});break;case"image":t.push({type:"image_url",image_url:{url:`data:${n.source.media_type};base64,${n.source.data}`}})}return t}function dn(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function mn(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 fn(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 _n(e){return e.reasoning_text?[{type:"thinking",thinking:e.reasoning_text}]:[]}function gn(e){return e?e.map(e=>({type:"tool_use",id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function hn(e){let t={model:e.model,input:kn(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)},n=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);return n&&(t.instructions=n),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)),"adaptive"===e.thinking?.type?t.reasoning={effort:yn(e.output_config?.effort??"high")}:"enabled"===e.thinking?.type&&e.thinking.budget_tokens&&(t.reasoning=function(e){return e<5e3?{effort:"low"}:e<2e4?{effort:"medium"}:e<32e3?{effort:"high"}:{effort:"xhigh"}}(e.thinking.budget_tokens)),t}function yn(e){switch(e){case"low":return"low";case"medium":return"medium";case"max":return"xhigh";default:return"high"}}function kn(e){let t=[];for(let n of e)"user"===n.role?t.push(...bn(n)):t.push(...xn(n));return t}function bn(e){if("string"==typeof e.content)return[{type:"message",role:"user",content:e.content}];let t=[],n=e.content.filter(e=>"tool_result"===e.type),o=e.content.filter(e=>"tool_result"!==e.type);for(let e of n)t.push(wn(e));if(o.length>0)if(o.some(e=>"image"===e.type)){let e=[];for(let t of o)"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=o.filter(e=>"text"===e.type).map(e=>e.text).join("\n\n");e&&t.push({type:"message",role:"user",content:e})}return t}function wn(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 xn(e){if("string"==typeof e.content)return[{type:"message",role:"assistant",content:e.content}];let t=[],n=e.content.filter(e=>"text"===e.type),o=e.content.filter(e=>"thinking"===e.type),r=e.content.filter(e=>"tool_use"===e.type),a=[...n.map(e=>e.text),...o.map(e=>e.thinking)].join("\n\n");a&&t.push({type:"message",role:"assistant",content:a});for(let e of r)t.push({type:"function_call",call_id:e.id,name:e.name,arguments:JSON.stringify(e.input)});return t}function vn(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 An(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function Tn(e,t,n){e.messageStartSent||=(e.responseId=n?.responseId??e.responseId,e.model=n?.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 $n(e,t){let n=[];switch(e.type){case"response.created":Tn(t,n,{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){Tn(t,n),An(t,n);let o=e.item;t.toolCalls[e.output_index]={call_id:o.call_id,name:o.name,_bi1:t.contentBlockIndex},n.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"tool_use",id:o.call_id,name:o.name,input:{}}}),t.contentBlockOpen=!0}break;case"response.content_part.added":Tn(t,n),An(t,n),n.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),t.contentBlockOpen=!0;break;case"response.output_text.delta":n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}});break;case"response.content_part.done":An(t,n);break;case"response.function_call_arguments.delta":{let o=t.toolCalls[e.output_index];o&&n.push({type:"content_block_delta",index:o._bi1,delta:{type:"input_json_delta",partial_json:e.delta}});break}case"response.output_item.done":if("function_call"===e.item.type){let o=t.toolCalls[e.output_index];o&&t.contentBlockOpen&&(n.push({type:"content_block_stop",index:o._bi1}),t.contentBlockIndex++,t.contentBlockOpen=!1)}break;case"response.completed":{An(t,n);let o=e.response.output.some(e=>"function_call"===e.type),r=e.response.usage;n.push({type:"message_delta",delta:{stop_reason:vn(e.response.status,o),stop_sequence:null},usage:{input_tokens:r?.input_tokens??0,output_tokens:r?.output_tokens??0}},{type:"message_stop"});break}case"response.incomplete":{Tn(t,n),An(t,n);let o=e.response.usage;n.push({type:"message_delta",delta:{stop_reason:"max_tokens",stop_sequence:null},usage:{input_tokens:o?.input_tokens??0,output_tokens:o?.output_tokens??0}},{type:"message_stop"});break}case"response.failed":Tn(t,n),An(t,n),n.push({type:"error",error:{type:e.response.error?.code??"api_error",message:e.response.error?.message??"Response generation failed"}});break;case"response.cancelled":Tn(t,n),An(t,n),n.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":Tn(t,n),t.contentBlockOpen||=(n.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:e.delta}})}return n}function Sn(e,t){e.thinkingBlockOpen||(e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1),t.push({type:"content_block_start",index:e.contentBlockIndex,content_block:{type:"thinking",thinking:""}}),e.thinkingBlockOpen=!0,e.contentBlockOpen=!0)}function On(e,t){e.thinkingBlockOpen&&(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.thinkingBlockOpen=!1,e.contentBlockOpen=!1)}function In(e,t){let n=[];if(0===e.choices.length)return n;let o=e.choices[0],{delta:r}=o;if(t.messageStartSent||=(n.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),"string"==typeof r.reasoning_text&&""!==r.reasoning_text&&(Sn(t,n),n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"thinking_delta",thinking:r.reasoning_text}})),"string"==typeof r.reasoning_opaque&&""!==r.reasoning_opaque&&(Sn(t,n),n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"signature_delta",signature:r.reasoning_opaque}}),On(t,n)),r.content&&(On(t,n),function(e){return!!e.contentBlockOpen&&Object.values(e.toolCalls).some(t=>t._bi1===e.contentBlockIndex)}(t)&&(n.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,t.contentBlockOpen=!1),t.contentBlockOpen||=(n.push({type:"content_block_start",index:t.contentBlockIndex,content_block:{type:"text",text:""}}),!0),n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"text_delta",text:r.content}})),r.tool_calls){On(t,n);for(let e of r.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(n.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let o=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,_bi1:o},n.push({type:"content_block_start",index:o,content_block:{type:"tool_use",id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let o=t.toolCalls[e.index];o&&n.push({type:"content_block_delta",index:o._bi1,delta:{type:"input_json_delta",partial_json:e.function.arguments}})}}}return o.finish_reason&&(On(t,n),t.contentBlockOpen&&=(n.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),n.push({type:"message_delta",delta:{stop_reason:rn(o.finish_reason),stop_sequence:null},usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}},{type:"message_stop"})),n}async function qn(e,t,n){let o={query:t,max_results:n?.maxResults??5};n?.includeDomains?.length&&(o.include_domains=n.includeDomains),n?.excludeDomains?.length&&(o.exclude_domains=n.excludeDomains),Z.debug("Tavily search request:",JSON.stringify(o));let r=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!r.ok){let e=await r.text();throw Z.error(`Tavily API error (${r.status}):`,e),Error(`Tavily API error: ${r.status} ${e}`)}let a=await r.json();return Z.debug(`Tavily returned ${a.results.length} results`),a.results}function Nn(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function jn(e,t){let n=function(e){let t,n=e.messages[0];if(!n||"user"!==n.role)return null;if("string"==typeof n.content)t=n.content;else{if(!Array.isArray(n.content))return null;{let e=n.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(!n)return e.json({type:"error",error:{type:"invalid_request_error",message:"Could not extract search query from web search request"}},400);let o=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: "${n}"`);let r=[];try{let e=v.tavilyApiKey;if(!e)throw Error("No Tavily API key configured");r=(await qn(e,n,{maxResults:Math.min(o.maxResults,10),includeDomains:o.allowedDomains,excludeDomains:o.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 a={query:n,results:r,model:t.model};if(!t.stream)return e.json(function(e){let{query:t,results:n,model:o}=e,r=`srvtoolu_${Nn()}`,a=[{type:"text",text:"I'll search for that."},{type:"server_tool_use",id:r,name:"web_search",input:{query:t}},{type:"web_search_tool_result",tool_use_id:r,content:n}];return{id:`msg_tavily_${Nn()}`,type:"message",role:"assistant",model:o,content:a,stop_reason:"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}(a));let i=function(e){let{query:t,results:n,model:o}=e,r=`srvtoolu_${Nn()}`,a=`msg_tavily_${Nn()}`,i=[];return i.push({type:"message_start",message:{id:a,type:"message",role:"assistant",content:[],model:o,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:r,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:r,content:n}},{type:"content_block_stop",index:2},{type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{output_tokens:0}},{type:"message_stop"}),i}(a);return _e(e,async e=>{for(let t of i)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}function Pn(e){return function(e){let t=e.thinking;if(null==t)return null;if("object"!=typeof t)return"thinking must be an object";let n=t,o=new Set(["enabled","adaptive","disabled"]);return"string"==typeof n.type&&o.has(n.type)?"enabled"!==n.type||void 0===n.budget_tokens||"number"==typeof n.budget_tokens&&Number.isFinite(n.budget_tokens)&&!(n.budget_tokens<=0)&&Number.isInteger(n.budget_tokens)?null:"thinking.budget_tokens must be a positive integer":"thinking.type must be one of: enabled, adaptive, disabled"}(e)??function(e){let t=e.output_config;if(null==t)return null;if("object"!=typeof t)return"output_config must be an object";let n=t;if(void 0===n.effort)return null;let o=new Set(["low","medium","high","max"]);return"string"==typeof n.effort&&o.has(n.effort)?null:"output_config.effort must be one of: low, medium, high, max"}(e)}async function En(e){let t=await e.req.json();if(function(e){let t=e.tools;if(!t||1!==t.length)return!1;let n=t[0].type;return"string"==typeof n&&n.startsWith("web_search")}(t))return jn(e,t);await Pt(v),Z.debug("Anthropic request payload:",JSON.stringify(t));let n=e.req.header("anthropic-beta")??"",o=/context-1m/i.test(n);if(o&&/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 r=function(e,t){return i.startActiveSpan("copilot_api.model.validate",n=>{try{n.setAttribute("copilot_api.model.requested",t.model);let o=jt(t.model);n.setAttribute("copilot_api.model.normalized",o);let r=Pn(t);return r?{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:r}},400)}:o===t.model?(n.setAttribute("copilot_api.model.was_mapped",!1),{ok:!0,payload:t}):(n.setAttribute("copilot_api.model.was_mapped",!0),C.add(1,{from_model:t.model,to_model:o}),Z.debug(`Model mapping: '${t.model}' → '${o}'`),{ok:!0,payload:{...t,model:o}})}catch(t){if(t instanceof Nt)return{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:t.message}},t.statusCode)};throw t}finally{n.end()}})}(e,t);if(!r.ok)return r.response;if(t=r.payload,function(e){return/gpt-[\d.]+-codex/i.test(e)}(t.model))return async function(e,t){let n=performance.now(),o=i.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),hn(t)}finally{e.end()}});c.record(performance.now()-n,{direction:"anthropic_to_responses"}),Z.debug("Translated Responses API payload:",JSON.stringify(o)),e.set("requestData",{model:o.model,streaming:!!o.stream}),v.manualApprove&&await vt();let r=performance.now(),a=await on(o),s=performance.now()-r;if(S.record(s,{model:o.model,target:"responses",streaming:String(!!o.stream)}),Bn(a)){let t=e.get("requestData")||{};if(a.usage&&(t.tokenUsage=$t({prompt_tokens:a.usage.input_tokens,completion_tokens:a.usage.output_tokens,total_tokens:a.usage.total_tokens})),t._d1=s,e.set("requestData",t),Z.debug("Non-streaming Responses API response:",JSON.stringify(a).slice(-400)),"failed"===a.status)return e.json({type:"error",error:{type:a.error?.code??"api_error",message:a.error?.message??"Response generation failed"}},500);let n=performance.now(),o=i.startActiveSpan("copilot_api.translate.responses_to_anthropic",e=>{try{return e.setAttribute("copilot_api.translation.direction","responses_to_anthropic"),function(e){let t=[],n=!1;for(let o of e.output)if("message"===o.type)for(let e of o.content)e.text&&t.push({type:"text",text:e.text});else if("function_call"===o.type){n=!0;let e={};try{e=JSON.parse(o.arguments)}catch{}t.push({type:"tool_use",id:o.call_id,name:o.name,input:e})}return{id:e.id,type:"message",role:"assistant",model:e.model,content:t,stop_reason:vn(e.status,n),stop_sequence:null,usage:{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}}(a)}finally{e.end()}});return c.record(performance.now()-n,{direction:"responses_to_anthropic"}),e.json(o)}Z.debug("Streaming Responses API response");let{events:l,span:u,release:p}=a;return _e(e,async t=>{let n=null,r=0,a=performance.now(),i={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,responseId:"",model:"",toolCalls:{}};try{try{for await(let a of l){if(Z.debug("Responses API raw stream event:",JSON.stringify(a)),!a.data)continue;let l;try{l=JSON.parse(a.data)}catch(e){Z.warn("Failed to parse streaming chunk:",a.data.slice(0,200),e);continue}r++,g.add(1,{model:o.model,endpoint_type:"responses"});let u=Cn(l);if(u){n=u;let t=e.get("requestData")||{};t.tokenUsage=$t(n),t._d1=s,e.set("requestData",t)}let c=$n(l,i);for(let e of c)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let u=performance.now()-a,c={model:o.model,endpoint_type:"responses"};V.record(u,c),Y.record(r,c)}finally{n&&St(u,n),u.end(),p()}let c=e.get("requestId");c&&H.executeCompletion(c)}finally{e.get("resolveStreamComplete")?.()}})}(e,t);let a=performance.now(),s=i.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",o);let n=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"===e.type)),r=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"thinking"===e.type));return e.setAttribute("copilot_api.translation.has_images",n),e.setAttribute("copilot_api.translation.has_thinking",r),an(t,v.models)}finally{e.end()}});c.record(performance.now()-a,{direction:"anthropic_to_openai"}),s=Mt(s,v.models,{enabled:v.thinkingEnabled}),Z.debug("Translated OpenAI request payload:",JSON.stringify(s)),e.set("requestData",{model:s.model,streaming:!!s.stream});let l=performance.now();v.manualApprove&&await vt();let u=await Wt(s),p=performance.now()-l;if(S.record(p,{model:s.model,target:"chat_completions",streaming:String(!!s.stream)}),Rn(u)){let t=e.get("requestData")||{};u.usage&&(t.tokenUsage=$t(u.usage)),t._d1=p,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(u).slice(-400));let n=performance.now(),o=i.startActiveSpan("copilot_api.translate.openai_to_anthropic",e=>{try{e.setAttribute("copilot_api.translation.direction","openai_to_anthropic");let t=function(e){let t=[],n=[],o=[],r=null;r=e.choices[0]?.finish_reason??r;for(let a of e.choices){let e=_n(a.message),i=fn(a.message.content),s=gn(a.message.tool_calls);t.push(...e),n.push(...i),o.push(...s),("tool_calls"===a.finish_reason||"stop"===r)&&(r=a.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...n,...o],stop_reason:rn(r),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}(u);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 c.record(performance.now()-n,{direction:"openai_to_anthropic"}),Z.debug("Translated Anthropic response:",JSON.stringify(o)),e.json(o)}Z.debug("Streaming response from service");let{events:d,span:m,release:f}=u;return _e(e,async t=>{let n=null,o=0,r=performance.now(),a={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,thinkingBlockOpen:!1,toolCalls:{}};try{try{for await(let r of d){if(Z.debug("Raw stream event:",JSON.stringify(r)),"[DONE]"===r.data)break;if(!r.data)continue;let i;try{i=JSON.parse(r.data)}catch(e){Z.warn("Failed to parse streaming chunk:",r.data.slice(0,200),e);continue}if(o++,g.add(1,{model:s.model,endpoint_type:"anthropic"}),i.usage){n=i.usage;let t=e.get("requestData")||{};t.tokenUsage=$t(n),t._d1=p,e.set("requestData",t)}let l=In(i,a);for(let e of l)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let i=performance.now()-r,l={model:s.model,endpoint_type:"anthropic"};if(V.record(i,l),Y.record(o,l),n){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=$t(n),t._d1=p,e.set("requestData",t))}}finally{n&&St(m,n),m.end(),f()}let i=e.get("requestId");i&&H.executeCompletion(i)}finally{e.get("resolveStreamComplete")?.()}})}function Cn(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 Rn=e=>Object.hasOwn(e,"choices"),Bn=e=>Object.hasOwn(e,"output");const Dn=new me;Dn.post("/",async e=>{try{return await En(e)}catch(t){return await J(e,t)}});const Mn=new me;function Fn(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=jt(e.model);return t.setAttribute("copilot_api.model.normalized",n),n===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:n}),Z.debug(`Normalized model from '${e.model}' to '${n}'`),{...e,model:n})}finally{t.end()}})}function Hn(e,t){let n=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(!n)return;t.usageRef.value=n;let o=t.c.get("requestData")||{};o.tokenUsage=$t(n),o._d1=t._d1,t.c.set("requestData",o)}Mn.get("/",async e=>{try{v.models||await ve();let t=v.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 Jn=new Set(["message","function_call","function_call_output"]),Un=new Set(["type","name","description","parameters"]);async function Ln(e){if(!e)return!1;let t=e.sources;if(t&&t.length>0)return!1;let n=e.query??e.queries?.[0];return!(!n||!v.tavilyApiKey)&&(Z.info(`Enriching web search: "${n}"`),e.sources=(await qn(v.tavilyApiKey,n,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function Wn(e){if(!v.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 Ln(e.action))return JSON.stringify(t)}}catch(e){Z.error("Failed to enrich web search:",e)}return e}function zn(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 Kn(e,t){if(0===t.size)return e;try{let n=JSON.parse(e),o=n.type;if("response.output_item.added"===o||"response.output_item.done"===o){let e=n.item;if(e&&zn(e,t))return JSON.stringify(n)}if("response.completed"===o){let o=n.response?.output;if(!o)return e;let r=!1;for(let e of o)zn(e,t)&&(r=!0);if(r)return JSON.stringify(n)}}catch{}return e}function Gn(e){return null!=e}function Yn(e){let t=e.input,n="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 Jn.has(e.type)||"web_search_call"===e.type?e:null}}(e)).filter(e=>null!==e),o={model:e.model,input:n};for(let t of["instructions","max_output_tokens","temperature","top_p","stream","store","tool_choice","parallel_tool_calls","user"])Gn(e[t])&&(o[t]=e[t]);let r=new Set;if(Gn(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 n=e.type;if("web_search"===n||n.startsWith("web_search_"))return{type:e.type};let o={};for(let t of Object.keys(e))Un.has(t)&&(o[t]=e[t]);return"custom"===o.type&&(o.type="function",t.add(o.name),o.parameters||={type:"object",properties:{input:{type:"string",description:"The freeform tool input content"}},required:["input"],additionalProperties:!1}),o}),customToolNames:t}}(e.tools);o.tools=t.tools,r=t.customToolNames}if(Gn(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;o.reasoning={},Gn(t.effort)&&(o.reasoning.effort=t.effort),Gn(t.summary)&&(o.reasoning.summary=t.summary)}if(Gn(e.text)&&"object"==typeof e.text){let t=e.text;Gn(t.format)&&(o.text={format:t.format})}return{payload:o,customToolNames:r}}async function Vn(e,t,n){await async function(e){if(v.tavilyApiKey)try{for(let t of e.output){let e=t;"web_search_call"===e.type&&await Ln(e.action)}}catch(e){Z.error("Failed to enrich non-streaming web search:",e)}}(t);let o=e.get("requestData")||{};return t.usage&&(o.tokenUsage=$t({prompt_tokens:t.usage.input_tokens,completion_tokens:t.usage.output_tokens,total_tokens:t.usage.total_tokens})),o._d1=n,e.set("requestData",o),e.json(t)}const Qn=e=>Object.hasOwn(e,"output"),Xn=new me;Xn.post("/",async e=>{try{return await async function(e){await Pt(v);let{payload:t,customToolNames:n}=Yn(await e.req.json()),o=t;Z.debug(`Responses API [${Array.isArray(o.input)?o.input.length:1} items]`),n.size>0&&Z.debug(`Custom tools detected: ${[...n].join(", ")}`);try{o=Fn(o)}catch(t){if(t instanceof Nt)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:o.model,streaming:!!o.stream}),v.manualApprove&&await vt();let r=performance.now(),a=await on(o),i=performance.now()-r;if(S.record(i,{model:o.model,target:"responses",streaming:String(!!o.stream)}),Qn(a))return Vn(e,a,i);let{events:s,span:l,release:u}=a;return _e(e,async t=>{let r={value:null},a=0,c=performance.now();try{try{for await(let l of s)if(l.data&&"[DONE]"!==l.data){a++;let s=Kn(l.data,n);s=await Wn(s);let u=s===l.data?l:{...l,data:s};g.add(1,{model:o.model,endpoint_type:"responses"}),Hn(s,{usageRef:r,c:e,_d1:i}),await t.writeSSE(u)}else await t.writeSSE(l);let l=performance.now()-c,u={model:o.model,endpoint_type:"responses"};V.record(l,u),Y.record(a,u)}finally{r.value&&St(l,r.value),l.end(),u()}let p=e.get("requestId");p&&H.executeCompletion(p)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await J(e,t)}});const Zn=new me;Zn.get("/",e=>{try{return e.json({token:v._t1})}catch(t){return Z.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const eo=new me;eo.get("/",async e=>{try{let t=await Ee();return e.json(t)}catch(t){return Z.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const to=new me;to.use(async(e,t)=>{let n=Date.now(),o=`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,r=e.req.method,a=e.req.path,s=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"}(a);e.set("requestId",o),e.header("x-request-id",o);let l=i.startSpan("copilot_api.handle_request",{kind:ne.SERVER,attributes:{"http.method":r,"http.url":e.req.url,"http.route":a,"copilot_api.request_id":o,"copilot_api.endpoint_type":s}});for(let[t,n]of Object.entries(e.req.header())){let e=t.toLowerCase();B.has(e)||l.setAttribute(`http.request.header.${e}`,n)}let u,c=new Promise(e=>{u=e});e.set("streamComplete",c),e.set("resolveStreamComplete",u);let p=ae.setSpan(re.active(),l);await re.with(p,async()=>{H.registerCompletion(o,e,n);try{await t()}catch(e){let t=e instanceof Error?e:Error(String(e));throw l.setStatus({code:oe.ERROR,message:t.message}),l.recordException(t),e}});let d=e.get("requestData"),m={c:e,start:n,method:r,path:a,endpointType:s,requestId:o,span:l};d?.streaming?c.then(()=>xt(m)).catch(e=>{Z.debug("Error finalizing streaming request:",e),l.end()}):xt(m)}),to.use(fe()),to.get("/",e=>e.text("Server running")),to.route("/chat/completions",Vt),to.route("/models",Mn),to.route("/embeddings",Qt),to.route("/usage",eo),to.route("/token",Zn),to.route("/v1/chat/completions",Vt),to.route("/v1/models",Mn),to.route("/v1/embeddings",Qt),to.route("/v1/messages",Dn),to.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 n=Zt.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");n+=Zt.perMessage+en(e)*Zt.contentMultiplier}for(let e of t.messages)n+=Zt.perMessage,n+=en(e.role),"string"==typeof e.content?n+=en(e.content)*Zt.contentMultiplier:Array.isArray(e.content)&&(n+=tn(e.content));return t.tools&&t.tools.length>0&&(n+=function(e){let t=Zt.toolsExist;for(let[n,o]of e.entries())n>0&&(t+=Zt.perTool),t+=en(o.name),o.description&&(t+=Zt.perDesc+en(o.description)),t+=nn(o.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(n)})}),to.route("/v1/responses",Xn),to.route("/responses",Xn);const no=[],oo=Date.now();let ro="";function ao(){let e=async(e,t=0)=>{let n=i.startSpan("copilot_api.server.shutdown",{kind:ne.INTERNAL,attributes:{"copilot_api.shutdown.reason":e,"copilot_api.shutdown.exit_code":t,"copilot_api.uptime_seconds":(Date.now()-oo)/1e3}});for(let t of no)try{await t()}catch(e){Z.error("Error during cleanup:",e)}n.end(),function(e,t){let n=dt("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),o=["",ft,` ${it("COPILOT-API")} ${st(`v${e}`)} ${st("·")} ${wt(t)} uptime`,ft,""," Check in from time to time on",` ${lt(n)}`,"",ft,""];console.log(o.join("\n"))}(ro,Date.now()-oo),ue.exit(t)};ue.on("SIGINT",()=>e("SIGINT")),ue.on("SIGTERM",()=>e("SIGTERM")),ue.on("uncaughtException",t=>{Z.error("Uncaught exception:",t),e("uncaughtException",1)}),ue.on("unhandledRejection",(t,n)=>{Z.error("Unhandled promise rejection at:",n,"reason:",t),e("unhandledRejection",1)})}function io(e){let{options:t,version:o,runtime:r,_u1:a}=e,s=i.startSpan("copilot_api.server.startup",{kind:ne.INTERNAL,attributes:n({config:{version:o,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",enableThinking:t.enableThinking},runtime:r,identity:{_u1:a.login,machineId:v.machineId,sessionId:v.sessionId,_v1:v._v1},connectivity:v.connectivity,modelsCount:v.models?.data.length??0,startupDurationMs:Date.now()-oo},"copilot_api")});if(v.models?.data)for(let e of v.models.data)s.addEvent("copilot_api.model.available",n(e,"model"));s.end(),G(j.INFO,"INFO","Server started",n({version:o,port:t.port,accountType:t.accountType,_u1:a.login,modelsCount:v.models?.data.length??0,startupDurationMs:Date.now()-oo},"copilot_api"))}async function so(e){ao(),no.push(()=>{Z.debug("Cleaning up connectivity monitor"),F.stop()},()=>{Z.debug("Cleaning up token management"),Z.debug("Cleaning up token management"),Te&&=void clearInterval(Te),$e&&=void F.off("online",$e),Se&&=void F.off("offline",Se)},async()=>{Z.debug("Cleaning up HTTP/2 client"),await async function(){Z.debug("Stopping HTTP/2 pool"),Qe&&=void clearInterval(Qe),Xe&&=void clearInterval(Xe);let e=[...Ge.keys(),...Ye];Ge.clear(),Ye.clear(),Ke.clear(),Ve=void 0;for(let t of e)Ze(t)&&(K.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"),ue.exit(1)),v.accountType=e.accountType,v.manualApprove=e.manual,v.rateLimitSeconds=e.rateLimit,v.rateLimitWait=e.rateLimitWait,v.showToken=e.showToken,v.timeoutMs=e.timeout,v.thinkingEnabled=e.enableThinking,e.tavilyApiKey&&(v.tavilyApiKey=e.tavilyApiKey),function(){let e="1"===ue.env.COPILOT_H2_KEEPALIVE||"true"===ue.env.COPILOT_H2_KEEPALIVE,t=e||"1"===ue.env.COPILOT_H2||"true"===ue.env.COPILOT_H2;v.connectivity.h2=t,v.connectivity.h2Keepalive=e}(),await A(),v._v1="1.116.0-insider";let t=await Re();ro=t;let n,o=Be();r(t,oo),e._t2?(v._t2=e._t2,Z.info("Using provided Auth token")):await qe();try{let{_s4:e}=await import("./get-user-O49GxhnU.mjs");n=await e(),await I(v,n.login)}catch(e){Z.error("Failed to get user info for machine ID generation:",e),Z.error("Cannot proceed without user information"),ue.exit(1)}await Ie(),await ve();let a=function(e=18e5){let t=setInterval(()=>{ve().then(()=>Z.debug("Model list refreshed successfully")).catch(e=>{Z.warn("Failed to refresh model list; keeping existing cache:",e)})},e);return t.unref(),()=>{clearInterval(t)}}();no.push(()=>{Z.debug("Cleaning up model refresh interval"),a()}),v.connectivity.h2&&(nt(tt(O(v))),v.connectivity.h2Keepalive&&rt()),io({options:e,version:t,runtime:o,_u1:n});let i=`http://localhost:${e.port}`,s=await async function(e,t){if(!e._cc1)return!1;let n,o;if(de(v.models,"Models should be loaded by now"),e.model&&e.smallModel){let t=v.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),ue.exit(1)),t.includes(e.smallModel)||(Z.error(`Invalid small model: ${e.smallModel}`),Z.info(`Available services: \n${t.join("\n")}`),ue.exit(1)),n=e.model,o=e.smallModel}else e.model||e.smallModel?(Z.error("Both --model and --small-model must be specified for model selection"),ue.exit(1)):(n=await Z.prompt("Select a model to use",{type:"select",options:v.models.data.map(e=>e.id)}),o=await Z.prompt("Select a small model to use",{type:"select",options:v.models.data.map(e=>e.id)}));let r=at({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:n,ANTHROPIC_SMALL_FAST_MODEL:o},"claude");try{return ie.writeSync(r),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the command:"),Z.log(r),!1}}(e,i)||await async function(e,t){if(!e.codex)return!1;let n;if(de(v.models,"Models should be loaded by now"),e.model){let t=v.models.data.map(e=>e.id);t.includes(e.model)||(Z.error(`Invalid model: ${e.model}`),Z.info(`Available services: \n${t.join("\n")}`),ue.exit(1)),n=e.model}else n=await Z.prompt("Select a model to use with Codex CLI",{type:"select",options:v.models.data.map(e=>e.id)});let o=at({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy"},`codex --model ${n}`);try{return ie.writeSync(o),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the Codex CLI command:"),Z.log(o),!1}}(e,i);(function(e){let t=[...yt(e),...kt(e),...bt(e),"",...ht(gt),""];console.log(t.join("\n"))})({version:t,runtime:o,user:n.login,accountType:e.accountType,port:e.port,timeout:e.timeout,webSearch:!!e.tavilyApiKey,model:e.model,smallModel:e.smallModel,clipboardCopied:s}),pe({fetch:to.fetch,port:e.port,bun:{idleTimeout:255}})}const lo=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)"},"enable-thinking":{type:"boolean",default:!1,description:"Enable forwarding of thinking_budget / Anthropic thinking config to upstream. Off by default to avoid accidentally triggering reasoning behaviour."}},run({args:e}){let t=e["rate-limit"],n=void 0===t?void 0:Number.parseInt(t,10),o=e.timeout,r=void 0===o?u:Number.parseInt(o,10);return so({port:Number.parseInt(e.port,10),verbose:e.verbose,accountType:e["account-type"],manual:e.manual,rateLimit:n,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:r,tavilyApiKey:e["tavily-api-key"]||ue.env.TAVILY_API_KEY,enableThinking:e["enable-thinking"]})}});await async function(){try{if("1"===process.env.COPILOT_API_SKIP_UPDATE_CHECK)return;let[e,t]=await Promise.all([Re(),We()]);if("unknown"===e||!t||!function(e,t){let n=e.split(".").map(Number),o=t.split(".").map(Number),r=Math.max(n.length,o.length);for(let e=0;e<r;e++){let t=n[e]??0,r=o[e]??0;if(t<r)return!0;if(t>r)return!1}return!1}(e,t))return;!function(e,t){let n=`npx ${He}@latest`,o=Le("│"),r=` ${Ue("Update available!")} ${(e=>`${e}`)(e)} → ${(e=>`${e}`)(t)}`,a=` Run ${Ue(n)} to update`,i=" ".repeat(54),s=Le(`╭${"─".repeat(54)}╮`),l=Le(`╰${"─".repeat(54)}╯`),u=["",s,`${o}${i}${o}`,`${o}${ze(r,54)}${o}`,`${o}${i}${o}`,`${o}${ze(a,54)}${o}`,`${o}${i}${o}`,l,""];console.log(u.join("\n"))}(e,t)}catch{}}(),await X(Q({meta:{name:"copilot-api",description:"API proxy server for tool integration."},subCommands:{auth:Pe,start:lo,"check-usage":Ce,debug:Fe}}));export{};
2
+ import{defineCommand as e,runMain as t}from"citty";import o from"consola";import n from"node:fs/promises";import r from"node:os";import i from"node:path";import{SpanKind as a,SpanStatusCode as s,context as l,metrics as c,trace as u}from"@opentelemetry/api";import p from"clipboardy";import{execFile as d,execSync as m}from"node:child_process";import f from"node:process";import{SeverityNumber as h,logs as g}from"@opentelemetry/api-logs";import{OTLPLogExporter as _}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as y}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as k}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as b}from"@opentelemetry/resources";import{BatchLogRecordProcessor as w}from"@opentelemetry/sdk-logs";import{PeriodicExportingMetricReader as v}from"@opentelemetry/sdk-metrics";import{NodeSDK as $}from"@opentelemetry/sdk-node";import{ATTR_SERVICE_INSTANCE_ID as x,ATTR_SERVICE_NAME as T,ATTR_SERVICE_VERSION as A}from"@opentelemetry/semantic-conventions";import{Client as S,request as C}from"undici";import{createHash as O,randomBytes as E,randomUUID as I}from"node:crypto";import{promisify as P}from"node:util";import{accessSync as N}from"node:fs";import{serve as j}from"srvx";import R from"tiny-invariant";import{isIP as q}from"node:net";import{generate as D}from"selfsigned";import{Hono as M}from"hono";import{cors as F}from"hono/cors";import{streamSSE as H}from"hono/streaming";import{events as B}from"fetch-event-stream";import{Tokenizer as L,models as U}from"ai-tokenizer";import*as J from"ai-tokenizer/encoding/claude";const G=i.join(r.homedir(),".local","share","copilot-api"),z={APP_DIR:G,GITHUB_TOKEN_PATH:i.join(G,"github_token"),MACHINE_ID_PATH:i.join(G,"machine_id"),SESSION_ID_PATH:i.join(G,"session_id")};async function K(){await n.mkdir(z.APP_DIR,{recursive:!0}),await W(z.GITHUB_TOKEN_PATH),await W(z.SESSION_ID_PATH)}async function W(e){try{await n.access(e,n.constants.W_OK)}catch{await n.writeFile(e,""),await n.chmod(e,384)}}const V=6e5,Y={accountType:"individual",manualApprove:!1,rateLimitWait:!1,showToken:!1,thinkingEnabled:!1,timeoutMs:V,connectivity:{probeEndpoints:["https://api.github.com","https://www.google.com","https://1.1.1.1"],fastProbeInterval:5e3,slowProbeInterval:1e4,timeoutMs:5e3,jitterMaxMs:1e3,connectionPooling:!0,dnsCache:!0,h2:!1,h2Keepalive:!1}},X=e=>e>=1e5||e>=1e4?`${Math.round(e/1e3)}K`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toString(),Q=(e,t)=>e.padEnd(t),Z=e=>{let t=[];if(e.model){let o=Q(e.model,18);t.push(o)}if(e.tokenUsage){let o=e.tokenUsage,n=(o.inputTokens||0)+(o.outputTokens||0),r=e.model?((e,t)=>{if(!Y.models)return"";let o=Y.models.data.find(e=>e.id===t);if(!o)return"";let n=o.capabilities.limits?.max_context_window_tokens;return n?` (${(e/n*100).toFixed(1)}%)`:""})(n,e.model):"",i=Q(`↑${X(o.inputTokens||0).padStart(5)} │ ↓${X(o.outputTokens||0).padStart(5)}`,18),a=X(n),s=r?`${a}${r.padStart(15-a.length)}`:a.padEnd(15);t.push(`Tokens: ${i} | Context: ${s}`)}else if(e.model){let e=Q("N/A",18),o="N/A".padEnd(15);t.push(`Tokens: ${e} | Context: ${o}`)}if(e._d1){let o=Q(`${Math.round(e._d1)}ms`,8);t.push(`API: ${o}`)}return t.length>0?` | ${t.join(" | ")}`:""},ee={completionCallbacks:new Map,registerCompletion(e,t,o){this.completionCallbacks.set(e,{context:t,startTime:o,requestId:e})},executeCompletion(e){let t=this.completionCallbacks.get(e);t&&(this.logCompletion(t),this.completionCallbacks.delete(e))},logCompletion(e){let{context:t,startTime:n}=e,r=Date.now()-n,i=t.get("requestData"),a=` --\x3e ${Q(t.req.method,4)}${Q(t.req.path,21)}${Q(t.res.status.toString(),3)} ${Q(`${r}ms`,8)}`;i&&(a+=Z(i)),o.info(a),De(h.INFO,"INFO","Request completed",{"http.method":t.req.method,"http.path":t.req.path,"http.status_code":t.res.status,"copilot_api.duration_ms":r,...i?.model&&{"copilot_api.model":i.model},...i?._d1&&{"copilot_api.copilot_duration_ms":Math.round(i._d1)},...i?.tokenUsage?.inputTokens&&{"copilot_api.input_tokens":i.tokenUsage.inputTokens},...i?.tokenUsage?.outputTokens&&{"copilot_api.output_tokens":i.tokenUsage.outputTokens}})},logRateLimit(e,t){let{context:n,startTime:r}=e,i=Date.now()-r,a=(t.headers.get("x-ratelimit-exceeded")||"").split(":")[1]||"unknown",s=t.headers.get("retry-after")||t.headers.get("x-ratelimit-user-retry-after")||"?",l=`⚠ --\x3e ${Q(n.req.method,4)}${Q(n.req.path,21)}${Q("429",3)} ${Q(`${i}ms`,8)}`;l+=` | Rate limited (${s}s retry) | ${a}`;let c=n.get("requestData");if(c?._d1){l+=` | API: ${Q(`${Math.round(c._d1)}ms`,8)}`}o.info(l)},cleanup(){let e=Date.now()-3e5;for(let[t,o]of this.completionCallbacks)o.startTime<e&&this.completionCallbacks.delete(t);if(this.completionCallbacks.size>1e3){let e=Array.from(this.completionCallbacks.entries()).sort(([,e],[,t])=>e.startTime-t.startTime),t=e.slice(0,e.length-1e3);for(let[e]of t)this.completionCallbacks.delete(e)}}};setInterval(()=>ee.cleanup(),6e4);let te,oe,ne=Date.now();const re="https://api.honeycomb.io",ie={"x-honeycomb-team":"hcaik_01km2y7yf1rrn70xvxce5kx9dyz936dwm21b9bgvnwf3pxq0cmqkcwha8n"};const ae=u.getTracer("copilot-api"),se=c.getMeter("copilot-api"),le=g.getLogger("copilot-api"),ce=se.createCounter("copilot_api.requests.total",{unit:"{request}",description:"Total requests received"}),ue=se.createCounter("copilot_api.requests.errors",{unit:"{error}",description:"Total error responses"}),pe=se.createCounter("copilot_api.tokens.input",{unit:"{token}",description:"Total input tokens consumed"}),de=se.createCounter("copilot_api.tokens.output",{unit:"{token}",description:"Total output tokens generated"}),me=se.createCounter("copilot_api.tokens.cached",{unit:"{token}",description:"Total cached prompt tokens"}),fe=se.createCounter("copilot_api.rate_limit.triggers",{unit:"{trigger}",description:"Rate limit trigger count"}),he=se.createCounter("copilot_api.model_validation.errors",{unit:"{error}",description:"Model validation failures"}),ge=se.createCounter("copilot_api.model_mapping.mappings",{unit:"{mapping}",description:"Model name normalizations"}),_e=se.createCounter("copilot_api.token_refresh.attempts",{unit:"{attempt}",description:"Token refresh attempts"}),ye=se.createCounter("copilot_api.token_refresh.failures",{unit:"{failure}",description:"Token refresh final failures"}),ke=se.createCounter("copilot_api.connectivity.checks",{unit:"{check}",description:"Connectivity probe results"}),be=se.createCounter("copilot_api.connectivity.transitions",{unit:"{transition}",description:"Connectivity state transitions"}),we=se.createCounter("copilot_api.upstream.requests",{unit:"{request}",description:"Upstream API calls"}),ve=se.createCounter("copilot_api.stream.chunks",{unit:"{chunk}",description:"Total SSE chunks sent"}),$e=se.createCounter("copilot_api.approval.decisions",{unit:"{decision}",description:"Manual approval decisions"}),xe=se.createCounter("copilot_api.h2_keepalive.pings",{unit:"{ping}",description:"HTTP/2 keepalive pings sent"}),Te=se.createCounter("copilot_api.h2.connections",{unit:"{connection}",description:"HTTP/2 connection lifecycle events"}),Ae=se.createHistogram("copilot_api.request.duration",{unit:"ms",description:"Total request duration"}),Se=se.createHistogram("copilot_api.copilot.duration",{unit:"ms",description:"Upstream Copilot API call duration"}),Ce=se.createHistogram("copilot_api.stream.duration",{unit:"ms",description:"Duration of SSE streaming phase"}),Oe=se.createHistogram("copilot_api.rate_limit.wait_duration",{unit:"ms",description:"Duration of rate limit waits"}),Ee=se.createHistogram("copilot_api.translation.duration",{unit:"ms",description:"Translation layer processing time"}),Ie=se.createHistogram("copilot_api.token_refresh.duration",{unit:"ms",description:"Token refresh duration"}),Pe=se.createHistogram("copilot_api.connectivity.probe_duration",{unit:"ms",description:"Individual connectivity probe duration"}),Ne=se.createHistogram("copilot_api.tokens.per_request.input",{unit:"{token}",description:"Input tokens per request distribution"}),je=se.createHistogram("copilot_api.tokens.per_request.output",{unit:"{token}",description:"Output tokens per request distribution"}),Re=se.createHistogram("copilot_api.stream.chunks_per_request",{unit:"{chunk}",description:"Chunks per streaming request"}),qe=se.createHistogram("copilot_api.approval.wait_duration",{unit:"ms",description:"Time waiting for manual approval"});function De(e,t,o,n){let r=u.getActiveSpan()?.spanContext();le.emit({severityNumber:e,severityText:t,body:o,attributes:{...n,...r&&{"trace.id":r.traceId,"span.id":r.spanId}}})}function Me(e,t=""){let o={};if(null==e)return o;if("object"!=typeof e)return("string"==typeof e||"number"==typeof e||"boolean"==typeof e)&&t&&(o[t]=e),o;if(Array.isArray(e))return t&&(o[t]=JSON.stringify(e)),o;for(let[n,r]of Object.entries(e)){let e=t?`${t}.${n}`:n;void 0===r||"function"==typeof r||(null===r?o[e]="null":"object"!=typeof r||Array.isArray(r)?Array.isArray(r)?o[e]=JSON.stringify(r):("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(o[e]=r):Object.assign(o,Me(r,e)))}return o}se.createObservableGauge("copilot_api.connectivity.status",{unit:"{status}",description:"1 = online, 0 = offline"}).addCallback(e=>{e.observe(Ue.getConnectivityStats().isOnline?1:0)}),se.createObservableGauge("copilot_api.connectivity.consecutive_failures",{unit:"{failure}",description:"Current consecutive connectivity failure count"}).addCallback(e=>{e.observe(Ue.getConnectivityStats().consecutiveFailures)}),se.createObservableGauge("copilot_api.models.available",{unit:"{model}",description:"Number of available models"}).addCallback(e=>{e.observe(Y.models?.data.length??0)}),se.createObservableGauge("copilot_api.completion_logger.pending",{unit:"{callback}",description:"Number of pending completion callbacks"}).addCallback(e=>{e.observe(ee.completionCallbacks.size)}),se.createObservableGauge("copilot_api.uptime",{unit:"s",description:"Server uptime in seconds"}).addCallback(e=>{e.observe((Date.now()-ne)/1e3)});const Fe=new Set(["authorization","cookie","set-cookie","x-honeycomb-team","x-api-key","proxy-authorization"]);function He(e,t,o){for(let[n,r]of Object.entries(o)){let o=n.toLowerCase();Fe.has(o)||e.setAttribute(`http.${t}.header.${o}`,r)}}async function Be(e){let{spanName:t,url:o,target:n,method:r="GET",headers:i,body:l,signal:c,extraAttributes:u}=e,p=ae.startSpan(t,{kind:a.CLIENT,attributes:{"http.method":r,"url.full":o,"copilot_api.target":n,...u}});i&&He(p,"request",i);try{let e=await fetch(o,{method:r,headers:i,body:l,signal:c});return p.setAttribute("http.response.status_code",e.status),function(e,t){t.headers.forEach((t,o)=>{let n=o.toLowerCase();Fe.has(n)||e.setAttribute(`http.response.header.${n}`,t)})}(p,e),we.add(1,{target:n,status_code:String(e.status)}),e.ok||p.setStatus({code:s.ERROR,message:`HTTP ${e.status}`}),{response:e,span:p}}catch(e){let t=e instanceof Error?e:Error(String(e));throw p.setStatus({code:s.ERROR,message:t.message}),p.recordException(t),p.end(),e}}async function Le(e){let{spanName:t,url:o,target:n,method:r="POST",headers:i,body:l,signal:c,headersTimeout:u,bodyTimeout:p,extraAttributes:d,dispatcher:m}=e,f=ae.startSpan(t,{kind:a.CLIENT,attributes:{"http.method":r,"url.full":o,"copilot_api.target":n,"copilot_api.h2.enabled":void 0!==m,...d}});He(f,"request",i);try{let{statusCode:e,headers:t,body:a}=await C(o,{method:r,headers:i,body:l,signal:c,headersTimeout:u,bodyTimeout:p,dispatcher:m});f.setAttribute("http.response.status_code",e);for(let[e,o]of Object.entries(t)){let t=e.toLowerCase();void 0!==o&&!Fe.has(t)&&f.setAttribute(`http.response.header.${t}`,Array.isArray(o)?o.join(", "):o)}return we.add(1,{target:n,status_code:String(e)}),e>=400&&f.setStatus({code:s.ERROR,message:`HTTP ${e}`}),{statusCode:e,headers:t,body:a,span:f}}catch(e){let t=e instanceof Error?e:Error(String(e));throw f.setStatus({code:s.ERROR,message:t.message}),f.recordException(t),f.end(),e}}const Ue=new class extends EventTarget{isOnline=!0;lastChecked=(new Date).toISOString();consecutiveFailures=0;lastErrorType;lastErrorMessage;lastSuccessfulEndpoint;endpointFailureStats={};checkInterval;abortController;on(e,t){return this.addEventListener(e,t),this}off(e,t){return this.removeEventListener(e,t),this}start(){o.debug("Starting connectivity monitor",{probeEndpoints:Y.connectivity.probeEndpoints,fastInterval:Y.connectivity.fastProbeInterval}),this.scheduleNextCheck()}stop(){o.debug("Stopping connectivity monitor"),this.checkInterval&&=void clearTimeout(this.checkInterval),this.abortController&&=void this.abortController.abort()}scheduleNextCheck(){this.checkInterval&&clearTimeout(this.checkInterval);let e=(this.isOnline?Y.connectivity.slowProbeInterval:Y.connectivity.fastProbeInterval)+Math.random()*Y.connectivity.jitterMaxMs;this.checkInterval=setTimeout(()=>{this.performConnectivityCheck().catch(e=>{o.error("Connectivity check failed:",e)})},e)}async performConnectivityCheck(){let e=ae.startSpan("copilot_api.connectivity.probe");this.abortController=new AbortController;let t=setTimeout(()=>this.abortController?.abort(),Y.connectivity.timeoutMs);try{let n=!1;for(let e of Y.connectivity.probeEndpoints)try{let t=performance.now(),o=await fetch(e,{method:"HEAD",signal:this.abortController.signal,headers:{"User-Agent":"copilot-api-connectivity-monitor/1.0",...Y.connectivity.dnsCache&&{"Cache-Control":"max-age=300"}}}),r=performance.now()-t;if(o.ok){n=!0,this.lastSuccessfulEndpoint=e,Pe.record(r,{endpoint:e,result:"success"});break}Pe.record(r,{endpoint:e,result:"failed"})}catch(t){this.endpointFailureStats[e]=(this.endpointFailureStats[e]||0)+1,o.debug(`Probe failed for ${e}:`,t)}this.updateConnectivityState(n);let r=n?"online":"offline";e.setAttribute("copilot_api.connectivity.result",r),e.setAttribute("copilot_api.connectivity.consecutive_failures",this.consecutiveFailures),this.lastSuccessfulEndpoint&&e.setAttribute("copilot_api.connectivity.successful_endpoint",this.lastSuccessfulEndpoint),ke.add(1,{result:n?"online":"offline"})}catch(e){this.handleConnectivityError(e)}finally{clearTimeout(t),e.end(),this.scheduleNextCheck()}}updateConnectivityState(e){let t=this.isOnline;if(this.isOnline=e,this.lastChecked=(new Date).toISOString(),e){let e=this.consecutiveFailures;this.consecutiveFailures>0&&o.info(`Connectivity restored after ${this.consecutiveFailures} failures`),this.consecutiveFailures=0,this.lastErrorType=void 0,this.lastErrorMessage=void 0,t||(this.dispatchEvent(new CustomEvent("online")),be.add(1,{from:"offline",to:"online"}),De(h.INFO,"INFO","Connectivity restored",{"copilot_api.connectivity.consecutive_failures_before_recovery":e}))}else this.consecutiveFailures++,t&&(o.warn("Connectivity lost"),this.dispatchEvent(new CustomEvent("offline")),be.add(1,{from:"online",to:"offline"}),De(h.WARN,"WARN","Connectivity lost",{"copilot_api.connectivity.consecutive_failures":this.consecutiveFailures}))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,o.error("Connectivity check failed:",e),this.updateConnectivityState(!1)}getConnectivityStats(){return{isOnline:this.isOnline,lastChecked:this.lastChecked,consecutiveFailures:this.consecutiveFailures,lastErrorType:this.lastErrorType,lastErrorMessage:this.lastErrorMessage}}getPerformanceStats(){let e=this.isOnline?Y.connectivity.slowProbeInterval:Y.connectivity.fastProbeInterval;return{currentInterval:e,nextCheckEstimate:new Date(Date.now()+e+Math.random()*Y.connectivity.jitterMaxMs).toISOString(),lastSuccessfulEndpoint:this.lastSuccessfulEndpoint,endpointFailureStats:{...this.endpointFailureStats},jitterEnabled:Y.connectivity.jitterMaxMs>0,connectionPooling:Y.connectivity.connectionPooling,dnsCache:Y.connectivity.dnsCache}}},Je=()=>({"content-type":"application/json",accept:"application/json"}),Ge="0.43.2026040705",ze=`copilot-chat/${Ge}`,Ke=`GitHubCopilotChat/${Ge}`,We=async e=>{let t=(e=>{let t=e.replaceAll(/[^\w.-]/g,"_").trim();if(0===t.length||"."===t||".."===t||/^[_.]+$/.test(t))throw Error("Invalid GitHub username: cannot be empty or consist only of special characters after sanitization");return`${z.MACHINE_ID_PATH}_${t}`})(e);try{let e=await n.readFile(t,"utf8");if(e.trim())return e.trim()}catch{}let o=(e=>{let t=O("sha256");return t.update(process.platform),t.update(process.arch),t.update(process.env.USER||process.env.USERNAME||"anonymous"),t.update(r.hostname()),t.update(e),t.update(Date.now().toString()),t.update(E(16)),t.digest("hex")})(e);return await n.writeFile(t,o),await n.chmod(t,384),o},Ve=async(e,t)=>{e.machineId||=await We(t),e.sessionId||=await(async()=>{try{let e=await n.readFile(z.SESSION_ID_PATH,"utf8");if(e.trim())return e.trim()}catch{}let e=I();return await n.writeFile(z.SESSION_ID_PATH,e),await n.chmod(z.SESSION_ID_PATH,384),e})()},Ye=e=>"individual"===e.accountType?"https://api.githubcopilot.com":`https://api.${e.accountType}.githubcopilot.com`,Xe=(e,t=!1)=>{if(!e.machineId||!e.sessionId)throw Error("VSCode identifiers not initialized. Call initializeVSCodeIdentifiers() during startup.");let o=I(),n={Authorization:`Bearer ${e._t1}`,"Content-Type":"application/json",accept:"*/*","accept-encoding":"br, gzip, deflate","accept-language":"*","sec-fetch-mode":"cors","Copilot-Integration-Id":"vscode-chat","Editor-Version":`vscode/${e._v1}`,"Editor-Plugin-Version":ze,"User-Agent":Ke,"VScode-MachineId":e.machineId,"VScode-SessionId":e.sessionId,"OpenAI-Intent":"conversation-agent","X-Interaction-Type":"conversation-agent","X-Agent-Task-Id":o,"X-VSCode-User-Agent-Library-Version":"node-fetch","X-GitHub-Api-Version":"2025-05-01","X-Interaction-Id":I(),"X-Request-Id":o};return t&&(n["copilot-vision-request"]="true"),n},Qe="https://api.github.com",Ze=e=>({"content-type":"application/json",accept:"application/json",authorization:`token ${e._t2}`,"editor-version":`vscode/${e._v1}`,"editor-plugin-version":ze,"user-agent":Ke,"x-github-api-version":"2025-04-01","x-vscode-user-agent-library-version":"node-fetch"}),et="https://github.com",tt="01ab8ac9400c4e429b23",ot=["user:email"].join(" ");var nt=class extends Error{response;constructor(e,t){super(e),this.response=t}};async function rt(e,t){let n=u.getActiveSpan();if(t instanceof nt&&429===t.response.status){let o=e.get("requestId"),r=ee.completionCallbacks.get(o);r&&(ee.logRateLimit(r,t.response),ee.completionCallbacks.delete(o)),fe.add(1,{action:"rejected",source:"upstream"});let i,a=await t.response.text();try{i=JSON.parse(a)}catch{i={error:{message:a,type:"error"}}}return n?.setStatus({code:s.ERROR,message:"Rate limited by upstream"}),n?.setAttribute("copilot_api.error_type","rate_limit_upstream"),De(h.WARN,"WARN","Upstream rate limit hit",{"copilot_api.status_code":429,"http.path":e.req.path,"copilot_api.error_type":"rate_limit_upstream"}),e.json(i,429)}if(o.error("Error occurred:",t),t instanceof nt){let r,i=await t.response.text();try{r=JSON.parse(i)}catch{r=i}return o.error("HTTP error:",r),n?.setStatus({code:s.ERROR,message:t.message}),n?.recordException(t),n?.setAttribute("copilot_api.error_type","HTTPError"),De(h.ERROR,"ERROR",`HTTP error: ${t.message}`,{"copilot_api.status_code":t.response.status,"http.path":e.req.path,"copilot_api.error_type":"HTTPError"}),e.json({error:{message:i,type:"error"}},t.response.status)}let r=t instanceof Error?t:Error(String(t));return n?.setStatus({code:s.ERROR,message:r.message}),n?.recordException(r),n?.setAttribute("copilot_api.error_type",r.name),De(h.ERROR,"ERROR",`Unhandled error: ${r.message}`,{"copilot_api.status_code":500,"http.path":e.req.path,"copilot_api.error_type":r.name}),e.json({error:{message:r.message,type:"error"}},500)}const it=async()=>{let e=`${Qe}/copilot_internal/v2/token`,t=Y.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await Be({spanName:"github GET /copilot_internal/v2/token",url:e,target:"copilot_token",headers:Ze(Y),signal:o.signal});if(!t.ok)throw n.end(),new nt("Failed to get Service token",t);let r=await t.json();return n.end(),r}finally{clearTimeout(n)}};async function at(){let e=`${Qe}/user`,t=Y.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await Be({spanName:"github GET /user",url:e,target:"github_user",headers:{authorization:`token ${Y._t2}`,"content-type":"application/json",accept:"application/json"},signal:o.signal});if(!t.ok)throw n.end(),new nt("Failed to get GitHub user",t);let r=await t.json();return n.end(),r}finally{clearTimeout(n)}}const st=e=>new Promise(t=>{setTimeout(t,e)}),lt=e=>null==e;async function ct(){Y.models=await(async()=>{let e=`${Ye(Y)}/models`,t=Xe(Y),o=Y.timeoutMs,n=new AbortController,r=setTimeout(()=>n.abort(),o);try{let{response:o,span:r}=await Be({spanName:"copilot GET /models",url:e,target:"models",headers:t,signal:n.signal});if(!o.ok)throw r.end(),new nt("Failed to get models",o);let i=await o.json();return r.setAttribute("copilot_api.models_count",i.data.length),r.end(),i}finally{clearTimeout(r)}})()}var ut=class extends Error{constructor(e){super(e),this.name="AuthorizationError"}};let pt,dt,mt,ft=!1;const ht=()=>n.readFile(z.GITHUB_TOKEN_PATH,"utf8"),gt=e=>n.writeFile(z.GITHUB_TOKEN_PATH,e);const _t=async()=>{let{token:e,refresh_in:t}=await it();Y._t1=e,o.debug("Service token fetched successfully!"),Y.showToken&&o.info("Service token:",e);let n=async(e=5,t=1e3,n="scheduled")=>{if(!ft)return ft=!0,ae.startActiveSpan("copilot_api.token.refresh",async r=>{let i=performance.now();r.setAttribute("copilot_api.token_refresh.reason",n),r.setAttribute("copilot_api.token_refresh.max_retries",e);try{for(let a=1;a<=e;a++)try{r.setAttribute("copilot_api.token_refresh.attempt",a),o.debug(`Refreshing Service token (${n}, attempt ${a}/${e})`);let{token:t}=await it();return Y._t1=t,o.debug("Service token refreshed successfully"),Y.showToken&&o.info("Refreshed Service token:",t),r.setAttribute("copilot_api.token_refresh.success",!0),_e.add(1,{reason:n,success:"true"}),Ie.record(performance.now()-i,{reason:n}),void De(h.INFO,"INFO",`Token refreshed successfully (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempt":a})}catch(l){let c=a===e;if(o.error(`Failed to refresh Service token (attempt ${a}/${e}):`,l),_e.add(1,{reason:n,success:"false"}),c){o.error("All refresh attempts failed. May be unavailable until next scheduled refresh.");let t=l instanceof Error?l:Error(String(l));return r.setAttribute("copilot_api.token_refresh.success",!1),r.setStatus({code:s.ERROR,message:t.message}),r.recordException(t),ye.add(1,{reason:n}),Ie.record(performance.now()-i,{reason:n}),void De(h.ERROR,"ERROR",`Token refresh failed after ${e} attempts (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempts":e})}let u=t*2**(a-1);o.debug(`Retrying token refresh in ${u}ms...`),await new Promise(e=>setTimeout(e,u))}}finally{r.end(),ft=!1}});o.debug("Refresh already in progress, skipping")};pt=setInterval(()=>{n(5,1e3,"scheduled").catch(e=>{o.error("Unexpected error in scheduled token refresh:",e)})},1e3*(t-60)),Ue.start(),dt=()=>{o.debug("Network connectivity restored, attempting immediate token refresh"),n(3,500,"network-restored").catch(e=>{o.error("Unexpected error in network-restored token refresh:",e)})},mt=()=>{o.debug("Network connectivity lost")},Ue.on("online",dt),Ue.on("offline",mt)};async function yt(e){try{let t=await ht();if(t&&!e?.force)return Y._t2=t,Y.showToken&&o.info("Auth token:",t),void await kt();o.info("Authentication required");let n=await async function(){let e=new AbortController,t=Y.timeoutMs,o=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${et}/login/device/code`,{method:"POST",headers:{"content-type":"application/json",accept:"application/json"},body:JSON.stringify({client_id:tt,scope:ot}),signal:e.signal});if(!t.ok)throw new nt("Failed to get device code",t);return await t.json()}finally{clearTimeout(o)}}();o.debug("Device code response:",n),o.info(`Please enter the code "${n.user_code}" at ${n.verification_uri}`);try{p.writeSync(n.user_code),o.success("Code copied to clipboard — opening browser...")}catch{o.info("Open the link above and enter the code to authenticate")}!function(e){try{let t,o=f.platform;t="darwin"===o?"open":"win32"===o?"start":"xdg-open",d(t,[e],()=>{})}catch{}}(n.verification_uri);let r=await async function(e){let t=1e3*(e.interval+1);o.debug(`Polling access token with interval of ${t}ms`),o.start("Waiting for authorization...");let n=Date.now(),r=1e3*e.expires_in;for(;;){if(Date.now()-n>=r)throw new ut("Authorization timed out — the code expired. Please run the command again.");let i=new AbortController,a=Y.timeoutMs,s=setTimeout(()=>{i.abort()},a);try{let n=await fetch(`${et}/login/oauth/access_token`,{method:"POST",headers:Je(),body:JSON.stringify({client_id:tt,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:i.signal});if(!n.ok){await st(t),o.error("Failed to poll access token:",await n.text());continue}let r=await n.json();if(o.debug("Polling access token response:",r),r.error){if("expired_token"===r.error)throw new ut("Authorization timed out — the code expired. Please run the command again.");if("access_denied"===r.error)throw new ut("Authorization was denied. Please run the command again and approve the request.");"authorization_pending"!==r.error&&"slow_down"!==r.error&&o.warn(`Unexpected auth error: ${r.error}`),await st(t);continue}if(r.access_token)return r.access_token;await st(t)}catch(e){if(e instanceof ut)throw e;if(e instanceof Error&&"AbortError"===e.name){o.error("Access token polling timed out"),await st(t);continue}throw e}finally{clearTimeout(s)}}}(n);await gt(r),Y._t2=r,Y.showToken&&o.info("Auth token:",r),await kt()}catch(e){throw e instanceof nt?(o.error("Failed to get Auth token:",await e.response.json()),e):(o.error("Failed to get Auth token:",e),e)}}async function kt(){let e=await at();o.success(`Authenticated as ${e.login}`)}async function bt(e){e.verbose&&(o.level=5,o.info("Verbose logging enabled")),Y.showToken=e.showToken,await K(),await yt({force:!0}),console.log([""," Get started:",""," $ npx copilot-api-node20@latest start --claude-code"," $ npx copilot-api-node20@latest start --codex",""," Full docs: https://www.npmjs.com/package/copilot-api-node20",""].join("\n")),process.exit(0)}const wt=e({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})=>bt({verbose:e.verbose,showToken:e["show-token"]})}),vt=async()=>{let e=`${Qe}/copilot_internal/user`,t=Y.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await Be({spanName:"github GET /copilot_internal/user",url:e,target:"usage",headers:Ze(Y),signal:o.signal});if(!t.ok)throw n.end(),new nt("Failed to get usage",t);let r=await t.json();return n.end(),r}finally{clearTimeout(n)}},$t=e({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await K(),await yt();try{let e=await vt(),t=e.quota_snapshots.premium_interactions,n=t.entitlement,r=n-t.remaining,i=n>0?r/n*100:0,a=t.percent_remaining;function s(e,t){if(!t)return`${e}: N/A`;let o=t.entitlement,n=o-t.remaining,r=o>0?n/o*100:0,i=t.percent_remaining;return`${e}: ${n}/${o} used (${r.toFixed(1)}% used, ${i.toFixed(1)}% remaining)`}let l=`Premium: ${r}/${n} used (${i.toFixed(1)}% used, ${a.toFixed(1)}% remaining)`,c=s("Chat",e.quota_snapshots.chat),u=s("Completions",e.quota_snapshots.completions);o.box(`Usage (plan: ${e.copilot_plan})\nQuota resets: ${e.quota_reset_date}\n\nQuotas:\n ${l}\n ${c}\n ${u}`)}catch(p){o.error("Failed to fetch usage:",p),process.exit(1)}}}),xt=P(d);async function Tt(){let e="win32"===f.platform?"where.exe":"which";try{return await xt(e,["tailscale"]),!0}catch{return!1}}async function At(){try{let{stdout:e}=await xt("tailscale",["status","--self","--json"]);return JSON.parse(e).Self}catch{return}}function St(e){return e.replace(/\.$/,"")}async function Ct(){let e=await At();if(e?.Online)return St(e.DNSName)}const Ot=P(d),Et=e=>`${e}`,It=e=>`${e}`,Pt=e=>`${e}`,Nt=e=>`${e}`,jt=e=>`${e}`,Rt=e=>`${e}`,qt=It(" ─────────────────────────────────────────────────────────────"),Dt=i.join(z.APP_DIR,"certs","tailscale"),Mt=i.join(Dt,"cert.pem"),Ft=i.join(Dt,"key.pem"),Ht={certDir:Dt,certPath:Mt,keyPath:Ft};function Bt(){switch(f.platform){case"darwin":return[` ${It("Install Tailscale for macOS:")}`,` ${Pt("https://tailscale.com/download/mac")}`,` ${It("(Use the Mac App Store or .pkg download — not brew)")}`,"",` ${It("After installing, open the Tailscale app and sign in.")}`,` ${It("Then re-run this command.")}`].join("\n");case"linux":return[` ${It("Install Tailscale for Linux:")}`,` ${Pt("curl -fsSL https://tailscale.com/install.sh | sh")}`,` ${Pt("sudo tailscale up")}`,` ${It("or")} ${Pt("https://tailscale.com/download/linux")}`].join("\n");case"win32":return[` ${It("Install Tailscale for Windows:")}`,` ${Pt("https://tailscale.com/download/windows")}`,"",` ${It("After installing, open the Tailscale app and sign in.")}`].join("\n");default:return` ${It("Install Tailscale:")} ${Pt("https://tailscale.com/download")}`}}function Lt(){let e=[` ${jt("Tailscale is not running.")}`];return"darwin"===f.platform?e.push(` ${It("Open the Tailscale app from Applications and sign in.")}`,` ${It("Download:")} ${Pt("https://tailscale.com/download/mac")}`):"win32"===f.platform?e.push(` ${It("Open the Tailscale app and sign in.")}`,` ${It("Download:")} ${Pt("https://tailscale.com/download/windows")}`):e.push(` ${It("Connect with:")} ${Pt("sudo tailscale up")}`),e.push("",` ${It("Then re-run this command.")}`),e.join("\n")}async function Ut(){try{return await n.access(Mt),await n.access(Ft),!0}catch{return!1}}function Jt(e){console.log(""),console.log(qt),console.log(` ${Et("Claude Cowork Setup")} ${It("— Diagnostic")}`),console.log(qt),console.log("");for(let t of function(e){let t=[];for(let[o,n]of Object.entries(e)){let e;e="ok"===n.status?Nt("✅"):"missing"===n.status?jt("❌"):Rt("❓");let r=n.detail?It(` ${n.detail}`):"";t.push(` ${e} ${o}${r}`)}return t}(e))console.log(t);console.log("");let t=Object.values(e).filter(e=>"missing"===e.status);0===t.length?console.log(` ${Nt("All checks passed.")}`):console.log(` ${jt(`${t.length} issue(s).`)} Run ${Pt("copilot-api cowork-setup install")} to fix.`),console.log("")}const Gt={alias:"y",type:"boolean",default:!1,description:"Skip confirmation prompts (non-interactive mode)"},zt=e({meta:{name:"cowork-setup",description:"Set up Tailscale-based HTTPS for Claude Cowork to reach the proxy."},subCommands:{doctor:e({meta:{name:"doctor",description:"Diagnose Tailscale + cert status"},async run(){await async function(){let e={},t=await Tt();if(e["tailscale-installed"]=t?{status:"ok"}:{status:"missing",detail:"tailscale not found in PATH"},!t)return Jt(e),console.log(""),console.log(Bt()),void console.log("");let o=await At();if(!o||!o.Online)return e["tailscale-running"]={status:"missing",detail:"not connected"},Jt(e),console.log(Lt()),void console.log("");let n=St(o.DNSName);e["tailscale-running"]={status:"ok",detail:n};let r=await Ut();e["tailscale-cert"]=r?{status:"ok",detail:Mt}:{status:"missing",detail:'Run "copilot-api cowork-setup install" to generate'},r&&(e.ready={status:"ok",detail:`https://${n}:<port>`}),Jt(e)}(),f.exit(0)}}),install:e({meta:{name:"install",description:"Generate a Tailscale TLS certificate for Cowork (interactive, or pass --yes)"},args:{yes:Gt},async run({args:e}){await async function(e){if(console.log(""),console.log(qt),console.log(` ${Et("Claude Cowork Setup")} ${It("— Install")}`),console.log(qt),console.log(""),!await Tt())return console.log(` ${jt("Tailscale is not installed.")}`),console.log(""),console.log(Bt()),console.log(""),console.log(` ${It("After installing, run")} ${Pt("tailscale up")} ${It("to connect, then re-run this command.")}`),void console.log("");let t=await At();if(!t||!t.Online)return console.log(Lt()),void console.log("");let r=St(t.DNSName);if(console.log(` ${It("Tailscale hostname:")} ${Et(r)}`),console.log(""),console.log(` ${Et("Generating TLS certificate via Tailscale…")}`),console.log(` ${It("This requests a real Let's Encrypt cert for your Tailscale hostname.")}`),console.log(` ${Pt(`$ tailscale cert --cert-file ${Mt} --key-file ${Ft} ${r}`)}`),console.log(""),e||await o.prompt("Generate the certificate?",{type:"confirm",initial:!0})){try{await n.mkdir(Dt,{recursive:!0}),o.start("Generating certificate (this may take a few seconds)…"),await Ot("tailscale",["cert","--cert-file",Mt,"--key-file",Ft,r]),console.log(` ${Nt("✓ Certificate generated")}`)}catch(e){let t=e instanceof Error?e.message:String(e);return void o.error(`Failed to generate cert: ${t}`)}console.log(""),console.log(qt),console.log(` ${Et("Next steps")}`),console.log(qt),console.log(""),console.log(` ${Et("1.")} Start the proxy:`),console.log(` ${Pt("copilot-api start --claude-cowork")}`),console.log(""),console.log(` ${Et("2.")} In Cowork ${It("→")} Settings ${It("→")} Inference Provider, set:`),console.log(` ${Et("inferenceGatewayBaseUrl")} = ${Pt(`https://${r}:<port>`)}`),console.log(` ${It("(replace <port> with the port you start the proxy on, default 4141)")}`),console.log(""),console.log(` ${Et("3.")} Restart Cowork ${It("(Cmd+Q and reopen)")}`),console.log(""),console.log(` ${It("For Cowork's own configuration docs, see:")}`),console.log(` ${Pt("https://claude.com/docs/cowork/3p/installation")}`),console.log("")}else o.info("Skipped.")}(e.yes),f.exit(0)}}),revert:e({meta:{name:"revert",description:"Remove the generated Tailscale cert files"},args:{yes:Gt},async run({args:e}){await async function(e){if(console.log(""),console.log(qt),console.log(` ${Et("Claude Cowork Setup")} ${It("— Revert")}`),console.log(qt),console.log(""),!await Ut())return console.log(` ${It("No Tailscale cert found. Nothing to revert.")}`),void console.log("");if(console.log(` ${Et("Remove Tailscale cert files:")}`),console.log(` ${It(Mt)}`),console.log(` ${It(Ft)}`),console.log(""),e||await o.prompt("Delete these files?",{type:"confirm",initial:!0})){try{await n.rm(Dt,{recursive:!0}),console.log(` ${Nt("✓ Cert files removed.")}`)}catch(e){let t=e instanceof Error?e.message:String(e);o.warn(`Could not remove: ${t}`)}console.log(""),console.log(` ${It("Don't forget to update Cowork's inferenceGatewayBaseUrl setting.")}`),console.log("")}else o.info("Skipped.")}(e.yes),f.exit(0)}})}});async function Kt(){try{let e=new URL("../package.json",import.meta.url).pathname,t=await n.readFile(e);return JSON.parse(t.toString()).version}catch{return"unknown"}}function Wt(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:r.platform(),arch:r.arch()}}async function Vt(){try{return!!(await n.stat(z.GITHUB_TOKEN_PATH)).isFile()&&(await n.readFile(z.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function Yt(e){let t=await async function(){let[e,t]=await Promise.all([Kt(),Vt()]);return{version:e,runtime:Wt(),paths:{APP_DIR:z.APP_DIR,GITHUB_TOKEN_PATH:z.GITHUB_TOKEN_PATH},tokenExists:t}}();e.json?function(e){console.log(JSON.stringify(e,null,2))}(t):function(e){o.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 Xt=e({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})=>Yt({json:e.json})}),Qt="copilot-api-node20",Zt=`https://registry.npmjs.org/${Qt}/latest`,eo=e=>`${e}`,to=e=>`${e}`;async function oo(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);"object"==typeof t&&"unref"in t&&t.unref();try{let t=await fetch(Zt,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function no(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 ro=new Map,io=new Map,ao=new Set;let so,lo,co;function uo(e){return!e.closed&&!e.destroyed}function po(e){o.debug(`Creating HTTP/2 client for ${e}`);let t=new S(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return ro.set(t,Date.now()),Te.add(1,{event:"created",origin:e}),De(h.INFO,"INFO",`HTTP/2 client created for ${e}`,{"copilot_api.h2.event":"created","copilot_api.h2.origin":e}),t.on("connect",()=>{o.debug(`HTTP/2 client connected to ${e}`)}),t.on("error",t=>{o.debug(`HTTP/2 client error for ${e}:`,t.message)}),t.on("disconnect",(n,r,i)=>{o.debug(`HTTP/2 client disconnected from ${e}:`,i.message),Te.add(1,{event:"goaway",origin:e}),De(h.WARN,"WARN",`HTTP/2 client disconnected from ${e}: ${i.message}`,{"copilot_api.h2.event":"goaway","copilot_api.h2.origin":e,"copilot_api.h2.error":i.message}),io.delete(t),ao.delete(t),ro.delete(t),uo(t)&&t.close().catch(e=>{o.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function mo(e){if(!Y.connectivity.h2)return;so&&so!==e&&function(){for(let e of[...io.keys(),...ao])uo(e)&&e.close().catch(e=>{o.debug("Error closing HTTP/2 pool entry:",e)});io.clear(),ao.clear(),ro.clear()}(),so=e;let t=Date.now();for(let[n]of io)if(t-(ro.get(n)??0)>=6e5)io.delete(n),ro.delete(n),uo(n)&&n.close().catch(e=>{o.debug("Error closing rotated HTTP/2 client:",e)}),Te.add(1,{event:"rotated",origin:e}),De(h.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(uo(n))return io.delete(n),ao.add(n),n;io.delete(n),ro.delete(n)}let n=po(e);return ao.add(n),n}function fo(e){e&&ao.delete(e)&&(uo(e)?io.set(e,Date.now()):ro.delete(e))}function ho(){co||(co=setInterval(()=>{!function(){let e=Date.now(),t=Y.connectivity.h2Keepalive,n=io.size;for(let[r,i]of io)e-i<6e4||t&&n<=1||(io.delete(r),ro.delete(r),n--,uo(r)&&r.close().catch(e=>{o.debug("Error closing idle HTTP/2 client:",e)}),Te.add(1,{event:"idle_reaped",origin:so??""}),De(h.INFO,"INFO",`HTTP/2 idle connection reaped for ${so}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":so??""}))}()},3e4),co.unref())}function go(){lo||(o.debug("Starting HTTP/2 keepalive (every 45s)"),lo=setInterval(()=>{(async function(){if(0===io.size&&0===ao.size){if(so){let e=po(so);io.set(e,Date.now())}return}let e=[...io.keys()];await Promise.allSettled(e.map(async e=>{if(!uo(e))return io.delete(e),void ro.delete(e);try{let{statusCode:t,body:n}=await e.request({path:"/models",method:"GET",headers:Xe(Y)});await n.dump(),xe.add(1,{result:"success"}),o.debug(`HTTP/2 keepalive: GET /models → ${t}`),io.set(e,Date.now())}catch(t){xe.add(1,{result:"error"}),o.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),Te.add(1,{event:"error",origin:so??""}),io.delete(e),ro.delete(e),uo(e)&&e.close().catch(e=>{o.debug("Error closing broken HTTP/2 client:",e)})}}))})().catch(e=>{o.debug("Unexpected error in HTTP/2 keepalive:",e)})},45e3),lo.unref(),ho())}function _o(e,t=""){let o,n=function(){let{platform:e,ppid:t,env:o}=f;if("win32"===e){try{if(m(`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"}}(),r=Object.entries(e).filter(([,e])=>void 0!==e);switch(n){case"powershell":o=r.map(([e,t])=>`$env:${e} = ${t}`).join("; ");break;case"cmd":o=r.map(([e,t])=>`set ${e}=${t}`).join(" & ");break;case"fish":o=r.map(([e,t])=>`set -gx ${e} ${t}`).join("; ");break;default:{let e=r.map(([e,t])=>`${e}=${t}`).join(" ");o=r.length>0?`export ${e}`:"";break}}return o&&t?`${o}${"cmd"===n?" & ":" && "}${t}`:o||t}const yo=e=>`${e}`,ko=e=>`${e}`,bo=e=>`${e}`,wo=e=>`${e}`,vo=e=>`${e}`,$o=e=>`${e}`,xo=(e,t)=>`]8;;${e}\\${t}]8;;\\`,To="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",Ao=ko(" ─────────────────────────────────────────────────────────────");function So(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const Co=[{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 Oo(e){if(0===e.length)return[];let t=["",Ao,` ${yo("BARAZANY.DEV")} ${ko("— Recent Posts")}`,Ao,""];for(let[o,n]of e.entries()){let e=xo(`${n.url}${To}`,yo($o(`[${o+1}]`)));t.push(` ${e} ${bo(n.title)}`,` ${ko("→")} ${ko(n.teaser)}`,"")}return t.push(Ao,` ${xo(`https://barazany.dev/blog${To}`,"barazany.dev/blog")}`,Ao),t}function Eo(e){let t=[];Y.connectivity.h2Keepalive?t.push("HTTP/2 keepalive"):Y.connectivity.h2&&t.push("HTTP/2"),t.push(`timeout ${e.timeout/1e3}s`);let o=e.webSearch?`Tavily ${wo("✓")}`:ko("off"),n=["",` ${yo("COPILOT-API")} ${ko(`v${e.version}`)}`,Ao,` ${ko("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${ko("User")} ${e.user} ${ko("·")} ${e.accountType}`];return Y._v1&&n.push(` ${ko("Client")} VSCode ${Y._v1}`),n.push(` ${ko("Network")} ${t.join(ko(" · "))}`,` ${ko("Search")} ${o}`),e.clipboardCopied&&n.push(` ${ko("Clipboard")} Claude Code command ${wo("✓")}`),n.push(Ao),n}function Io(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${yo("Active")}`];if(e.model){let o=Y.models?.data.find(t=>t.id===e.model),n=So(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${bo(e.model.padEnd(32))} ${ko("ctx")} ${yo(n.padStart(5))} ${vo("← main")}`)}if(e.smallModel){let o=Y.models?.data.find(t=>t.id===e.smallModel),n=So(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${ko("ctx")} ${n.padStart(5)} ${vo("← small")}`)}return t}function Po(e){let t=[];for(let[o,n]of function(){let e=[],t=[],o=[],n=[];for(let r of Y.models?.data??[]){let i=r.capabilities.limits?.max_context_window_tokens,a={id:r.id,ctx:i};r.id.startsWith("text-embedding")?n.push(a):"Anthropic"===r.vendor?e.push(a):"Google"===r.vendor?o.push(a):t.push(a)}return[["Claude",e],["OpenAI",t],["Gemini",o],["Embedding",n]]}())if(0!==n.length){t.push("",` ${yo(o)}`);for(let o of n){let n=o.id===e.model||o.id===e.smallModel,r=n?bo("●"):ko("·"),i=n?bo(o.id.padEnd(34)):o.id.padEnd(34),a=o.ctx?So(o.ctx).padStart(5):"";t.push(` ${r} ${i} ${ko(a)}`)}}return t}function No(e){if(!e.endpoints)return[];let{scheme:t,port:o,hostname:n}=e.endpoints,r=n?`${t}://${n}:${o}`:`${t}://<your-tailscale-hostname>:${o}`,i=["",Ao,` ${yo("Claude Cowork")} ${ko("— Settings → Inference Provider")}`,Ao,"",` ${ko("Paste into")} ${yo("inferenceGatewayBaseUrl")}${ko(":")}`,` ${yo(bo(r))}`];return n||i.push("",` ${ko("Your Tailscale hostname is shown by:")} ${bo("tailscale status --self")}`),i.push("",` ${ko("Docs:")} ${bo("https://claude.com/docs/cowork/3p/installation")}`),i}function jo(e){if(!e.https||!e.https.selfSigned)return[];let{certPath:t}=e.https,o=["",Ao,` ${yo("HTTPS")} ${ko("— self-signed cert")}`,Ao,"",` ${ko("Cert")} ${t}`];switch(o.push("",` ${yo("Trust this cert")} ${ko("(one-time setup)")}`),f.platform){case"darwin":o.push(` ${ko("macOS:")}`,` ${bo("sudo security add-trusted-cert -d -r trustRoot \\")}`,` ${bo(`-k /Library/Keychains/System.keychain "${t}"`)}`);break;case"win32":o.push(` ${ko("Windows (PowerShell as Administrator):")}`,` ${bo(`Import-Certificate -FilePath "${t}" \``)}`,` ${bo("-CertStoreLocation Cert:\\LocalMachine\\Root")}`);break;case"linux":o.push(` ${ko("Linux (Debian/Ubuntu):")}`,` ${bo(`sudo cp "${t}" /usr/local/share/ca-certificates/copilot-api.crt`)}`,` ${bo("sudo update-ca-certificates")}`,` ${ko("Linux (Fedora/RHEL/Arch):")}`,` ${bo(`sudo cp "${t}" /etc/pki/ca-trust/source/anchors/copilot-api.crt`)}`,` ${bo("sudo update-ca-trust")}`);break;default:o.push(` ${ko("(Unknown platform — see Node fallback below.)")}`)}return o.push("",` ${ko("Or, for Node CLIs only (no admin needed):")}`,` ${bo(`export NODE_EXTRA_CA_CERTS="${t}"`)}`,Ao),o}function Ro(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`}const qo=i.join(z.APP_DIR,"certs"),Do=i.join(qo,"cert.pem"),Mo=i.join(qo,"key.pem"),Fo=i.join(qo,"cert.meta.json");async function Ho(e){try{return await n.readFile(e,"utf8")}catch{return}}async function Bo(e){let t=await Ho(Do),o=await Ho(Mo),n=await async function(){let e=await Ho(Fo);if(e)try{let t=JSON.parse(e);return Array.isArray(t.hosts)&&"string"==typeof t.notAfter?t:void 0}catch{return}}();if(!t||!o||!n)return!1;let r=new Set(n.hosts);for(let t of e)if(!r.has(t))return!1;let i=Date.parse(n.notAfter);return!Number.isNaN(i)&&i-Date.now()>2592e6}function Lo(e){return 0!==q(e)}async function Uo(e){await n.mkdir(qo,{recursive:!0});let t=new Date,o=new Date;o.setDate(o.getDate()+825);let r=["127.0.0.1","::1"],i=new Set(["localhost"]),a=new Set(r);for(let t of e)Lo(t)?a.add(t):i.add(t);let s=await D([{name:"commonName",value:"localhost"},{name:"organizationName",value:"copilot-api"}],{keyType:"ec",curve:"P-256",algorithm:"sha256",notBeforeDate:t,notAfterDate:o,extensions:[{name:"basicConstraints",cA:!1},{name:"keyUsage",digitalSignature:!0,keyEncipherment:!0,critical:!0},{name:"extKeyUsage",serverAuth:!0,clientAuth:!0},{name:"subjectAltName",altNames:[...[...i].map(e=>({type:2,value:e})),...[...a].map(e=>({type:7,ip:e}))]}]});return await n.writeFile(Do,s.cert,{mode:420}),await n.writeFile(Mo,s.private,{mode:384}),await async function(e){await n.writeFile(Fo,JSON.stringify(e,null,2),{mode:420})}({hosts:[...i,...a].sort(),notAfter:o.toISOString()}),{cert:s.cert,key:s.private,certPath:Do,keyPath:Mo,generated:!0}}function Jo(e){(function(e){let{c:t,start:o,span:n}=e,r=t.get("requestData"),i=t.res.status,a=r?.model??"unknown",l=r?.streaming??!1,c=Date.now()-o;if(n.setAttribute("http.status_code",i),n.setAttribute("copilot_api.model",a),n.setAttribute("copilot_api.streaming",l),n.setAttribute("copilot_api.duration_ms",c),r?._d1&&n.setAttribute("copilot_api.copilot_duration_ms",r._d1),r?.tokenUsage){let e=r.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();Fe.has(o)||n.setAttribute(`http.response.header.${o}`,e)}),i>=400&&n.setStatus({code:s.ERROR,message:`HTTP ${i}`}),n.end()})(e),function(e){let{c:t,start:o,method:n,path:r,endpointType:i,requestId:a}=e,s=Date.now()-o,l=t.get("requestData"),c=t.res.status,u=l?.model??"unknown",p=l?.streaming??!1,d={method:n,path:r,status_code:String(c),model:u,streaming:String(p),endpoint_type:i};if(ce.add(1,d),Ae.record(s,d),c>=400&&ue.add(1,{method:n,path:r,status_code:String(c),error_type:c>=500?"server_error":"client_error"}),l?.tokenUsage){let e=l.tokenUsage,t={model:u,endpoint_type:i};e.inputTokens&&(pe.add(e.inputTokens,t),Ne.record(e.inputTokens,t)),e.outputTokens&&(de.add(e.outputTokens,t),je.record(e.outputTokens,t)),e.cachedTokens&&me.add(e.cachedTokens,{model:u})}!p&&l?.tokenUsage&&ee.executeCompletion(a)}(e)}const Go=async()=>ae.startActiveSpan("copilot_api.approval.await",async e=>{let t=performance.now();try{let n=await o.prompt("Accept incoming request?",{type:"confirm"}),r=performance.now()-t;if(e.setAttribute("copilot_api.approval.wait_duration_ms",r),qe.record(r),!n)throw e.setAttribute("copilot_api.approval.result","rejected"),$e.add(1,{result:"rejected"}),new nt("Request rejected",Response.json({message:"Request rejected"},{status:403}));e.setAttribute("copilot_api.approval.result","approved"),$e.add(1,{result:"approved"})}finally{e.end()}}),zo=3e-6,Ko=15e-6;function Wo(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*zo+o*Ko,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function Vo(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 Yo=[{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[.-]7/i,family:"opus-4.7"},{pattern:/opus[.-]?4[.-]6/i,family:"opus-4.6"},{pattern:/opus[.-]?4[.-]5/i,family:"opus-4.5"},{pattern:/opus/i,family:"opus"}],Xo={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.7":"claude-opus-4.7","opus-4.6":"claude-opus-4.6","opus-4.5":"claude-opus-4.5",opus:"claude-opus-4.5"};function Qo(e,t){let o=function(e){return e.startsWith("anthropic/")?e.slice(10):e}(e),[n,r]=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(r){let e=`${n}-${r}`.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(e))return e}let i=function(e){for(let t of Yo)if(t.pattern.test(e))return t.family;return null}(n);if(!i)return null;let a=n.replace(/-\d{8}(?::.*)?$/,""),s=r?`-${r}`:"";for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,""),o=`${a}${s}`.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=Xo[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}(i,t,r)}var Zo=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function en(e){if(!e||"string"!=typeof e)throw new Zo("Model name is required and must be a string");if(!Y.models?.data)throw new Zo("Models not available. Please try again later.",503);let t=Y.models.data.map(e=>e.id);if(t.includes(e))return e;let o=Qo(e,t);if(!o)throw he.add(1,{requested_model:e}),new Zo(`Invalid model: '${e}'. Available services: ${t.join(", ")}`);return o}async function tn(e){if(void 0===e.rateLimitSeconds)return;let t=e.rateLimitSeconds;return ae.startActiveSpan("copilot_api.rate_limit.check",async n=>{try{let r=Date.now();if(n.setAttribute("copilot_api.rate_limit.configured_seconds",t),!e.lastRequestTimestamp)return e.lastRequestTimestamp=r,void n.setAttribute("copilot_api.rate_limit.action","allowed");let i=(r-e.lastRequestTimestamp)/1e3;if(n.setAttribute("copilot_api.rate_limit.elapsed_seconds",i),i>t)return e.lastRequestTimestamp=r,void n.setAttribute("copilot_api.rate_limit.action","allowed");let a=Math.ceil(t-i);if(n.setAttribute("copilot_api.rate_limit.wait_seconds",a),!e.rateLimitWait)throw n.setAttribute("copilot_api.rate_limit.action","rejected"),fe.add(1,{action:"rejected",source:"local"}),o.warn(`Rate limit exceeded. Need to wait ${a} more seconds.`),new nt("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let s=1e3*a;n.setAttribute("copilot_api.rate_limit.action","waited"),fe.add(1,{action:"waited",source:"local"}),Oe.record(s,{source:"local"}),o.warn(`Rate limit reached. Waiting ${a} seconds before proceeding...`),await st(s),e.lastRequestTimestamp=r,o.info("Rate limit wait completed, proceeding with request")}finally{n.end()}})}function on(e){if("number"==typeof e){if(!Number.isFinite(e))return null;let t=Math.floor(e);return t>0?t:null}if("string"==typeof e){let t=e.trim();if(!t)return null;let o=Number(t);if(!Number.isFinite(o))return null;let n=Math.floor(o);return n>0?n:null}return null}function nn(e,t,o){return Math.min(Math.max(e,t),o)}function rn(e,t=0){if(t>5||!e||"object"!=typeof e)return null;let o=e.error;if(!o||"object"!=typeof o)return null;let n=o.code;if("string"==typeof n)return n;let r=o.message;if("string"!=typeof r)return null;try{return rn(JSON.parse(r),t+1)}catch{return null}}function an(e,t){let o=e?.data.find(e=>e.id===t);if(!o)return null;let n=on(o.capabilities.supports.min_thinking_budget),r=on(o.capabilities.supports.max_thinking_budget);return!n||!r||r<=n?null:{bounds:{min:n,max:r-1},maxOutputTokens:on(o.capabilities.limits?.max_output_tokens)??void 0}}function sn(e){let{config:t}=e,o=t.bounds.min,n=t.bounds.max,r=nn(on(e.requestedBudget)??o,o,n),i=on(e.maxTokens);if(i||=r+1,t.maxOutputTokens&&i>t.maxOutputTokens&&(i=t.maxOutputTokens),i<=r){let e=Math.min(r,i-1);if(e>=o)r=e;else{let e=o+1;if(t.maxOutputTokens&&e>t.maxOutputTokens)return{thinkingBudget:null,maxTokens:i};i=e,r=o}}return i<=r?{thinkingBudget:null,maxTokens:i}:{thinkingBudget:r,maxTokens:i}}function ln(e,t,o){if(lt(e.thinking_budget))return e;if(!1===o?.enabled)return{...e,thinking_budget:void 0};let n=an(t,e.model);if(!n)return{...e,thinking_budget:void 0};let r=sn({requestedBudget:e.thinking_budget,maxTokens:e.max_tokens,config:n});return null===r.thinkingBudget?{...e,max_tokens:r.maxTokens,thinking_budget:void 0}:{...e,max_tokens:r.maxTokens,thinking_budget:r.thinkingBudget}}function cn(e){return"invalid_thinking_budget"===rn(e)}async function un(e){let{payload:t,error:o,models:n,errorBodyText:r}=e;if(lt(t.thinking_budget)||!(o instanceof Error))return null;let i,a,s=o;if(!(s.response instanceof Response)||400!==s.response.status)return null;if(void 0!==r)i=r;else try{i=await s.response.clone().text()}catch{return null}try{a=JSON.parse(i)}catch{return null}if(!cn(a))return null;let l=an(n,t.model);return l?function(e,t){let o=sn({requestedBudget:e.thinking_budget,maxTokens:e.max_tokens,config:t});if(null===o.thinkingBudget)return{...e,max_tokens:o.maxTokens,thinking_budget:void 0};let n=o.thinkingBudget,r=on(e.thinking_budget);if(r&&r===o.thinkingBudget){let e=n+1;e<=t.bounds.max&&(!o.maxTokens||e<o.maxTokens)&&(n=e)}let i=o.maxTokens;if((!i||i<=n)&&(i=n+1),t.maxOutputTokens&&i>t.maxOutputTokens){if(!(t.maxOutputTokens>n))return{...e,max_tokens:t.maxOutputTokens,thinking_budget:void 0};i=t.maxOutputTokens}return{...e,max_tokens:i,thinking_budget:n}}(t,l):{...t,thinking_budget:void 0}}function pn(e){if(!(e instanceof Error))return!1;let t=e.code;return(!t||"UND_ERR_SOCKET"===t)&&/GOAWAY/i.test(e.message)}async function dn(){return new Promise(e=>setTimeout(e,100))}function mn(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 r=n[e],i=r.match(/^\[[0-9;]*[a-z]/i);t+=i?r.slice(i[0].length):o+r}}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=>mn(e));if(e&&"object"==typeof e){let t={};for(let[o,n]of Object.entries(e))t[o]=mn(n);return"object"===t.type&&!("properties"in t)&&(t.properties={}),t}return e}const fn=async e=>{let t=mn(e);try{return await hn(t)}catch(e){let n;if(e instanceof nt)try{n=await e.response.clone().text()}catch{n=void 0}let r=await un({payload:t,error:e,models:Y.models,errorBodyText:n});if(r)return e instanceof nt&&void 0!==n&&o.warn(`Upstream rejected thinking_budget (status ${e.response.status}): ${n.slice(0,500)}`),o.warn("Adjusting thinking_budget payload and retrying once..."),await hn(mn(r));throw e}},hn=async e=>{if(!Y._t1)throw Error("Service token not found");let t=e.messages.some(e=>"string"!=typeof e.content&&e.content?.some(e=>"image_url"===e.type)),n=e.messages.some(e=>["assistant","tool"].includes(e.role)),r={...Xe(Y,t),"X-Initiator":n?"agent":"user"},i=Ye(Y),a=`${i}/chat/completions`,s=Y.timeoutMs,l=JSON.stringify(e),c={"copilot_api.model":e.model,"copilot_api.streaming":!!e.stream,"copilot_api.timeout_ms":s,"copilot_api.has_tools":!!e.tools?.length,"copilot_api.tool_count":e.tools?.length??0,"copilot_api.message_count":e.messages.length,"copilot_api.max_tokens":e.max_tokens??0,"copilot_api.vision_enabled":t,"copilot_api.initiator":n?"agent":"user"};for(let t=0;t<=1;t++){let n=mo(i),u=new AbortController,p=setTimeout(()=>u.abort(),s);try{let{statusCode:o,headers:i,body:p,span:d}=await Le({spanName:"copilot POST /chat/completions",url:a,target:"chat_completions",headers:r,body:l,signal:u.signal,headersTimeout:s,bodyTimeout:3*s,extraAttributes:{...c,"copilot_api.h2.retry_attempt":t},dispatcher:n}),m=new Response(p,{status:o,headers:i});if(!m.ok)throw d.end(),new nt("Failed to create chat completions",m);if(e.stream)return{events:B(m),span:d,release:()=>fo(n)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&Vo(d,f.usage),d.end(),fo(n),f}catch(e){if(fo(n),pn(e)&&t<1){o.warn(`HTTP/2 GOAWAY during chat completions, retrying (attempt ${t+1})`),await dn();continue}throw e}finally{clearTimeout(p)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function gn(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(t){o.warn("Failed to parse streaming chunk:",e.data.slice(0,200),t)}return e}async function _n(e){await tn(Y);let t=await e.req.json();o.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=function(e){return ae.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=en(e.model);return t.setAttribute("copilot_api.model.normalized",n),n===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),ge.add(1,{from_model:e.model,to_model:n}),o.debug(`Normalized model from '${e.model}' to '${n}'`),{...e,model:n})}finally{t.end()}})}(t)}catch(t){if(t instanceof Zo)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}),Y.manualApprove&&await Go(),lt(t.max_tokens)){let e=Y.models?.data.find(e=>e.id===t.model);t={...t,max_tokens:e?.capabilities.limits?.max_output_tokens},o.debug("Set max_tokens to:",JSON.stringify(t.max_tokens))}t=ln(t,Y.models,{enabled:Y.thinkingEnabled}),lt(t.thinking_budget)||o.debug("Normalized thinking_budget to:",JSON.stringify(t.thinking_budget));let n=performance.now(),r=await fn(t),i=performance.now()-n;if(Se.record(i,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),yn(r)){let t=e.get("requestData")||{};return r.usage&&(t.tokenUsage=Wo(r.usage)),t._d1=i,e.set("requestData",t),o.debug("Non-streaming response:",JSON.stringify(r)),e.json(r)}let{events:a,span:s,release:l}=r;return H(e,async o=>{let n={value:null},r=0,c=performance.now();try{try{for await(let s of a){let a=s;s.data&&"[DONE]"!==s.data&&(r++,ve.add(1,{model:t.model,endpoint_type:"openai"}),a=gn(s,t=>{n.value=t;let o=e.get("requestData")||{};o.tokenUsage=Wo(t),o._d1=i,e.set("requestData",o)})),await o.writeSSE(a)}let s=performance.now()-c,l={model:t.model,endpoint_type:"openai"};if(Ce.record(s,l),Re.record(r,l),n.value){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=Wo(n.value),t._d1=i,e.set("requestData",t))}}finally{n.value&&Vo(s,n.value),s.end(),l()}let u=e.get("requestId");u&&ee.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}const yn=e=>Object.hasOwn(e,"choices"),kn=new M;kn.post("/",async e=>{try{return await _n(e)}catch(t){return await rt(e,t)}});const bn=new M;bn.post("/",async e=>{try{let t=await e.req.json();try{en(t.model)}catch(t){if(t instanceof Zo)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(!Y._t1)throw Error("Service token not found");let t=`${Ye(Y)}/embeddings`,o=Xe(Y),n=Y.timeoutMs,r=new AbortController,i=setTimeout(()=>r.abort(),n);try{let{response:n,span:i}=await Be({spanName:"copilot POST /embeddings",url:t,target:"embeddings",method:"POST",headers:o,body:JSON.stringify(e),signal:r.signal,extraAttributes:{"copilot_api.model":e.model,"copilot_api.input_count":Array.isArray(e.input)?e.input.length:1}});if(!n.ok)throw i.end(),new nt("Failed to create embeddings",n);let a=await n.json();return i.end(),a}finally{clearTimeout(i)}})(t),r=performance.now()-o;Se.record(r,{model:t.model,target:"embeddings",streaming:"false"});let i=e.get("requestData")||{};return i.tokenUsage=Wo(n.usage),i._d1=r,e.set("requestData",i),e.json(n)}catch(t){return await rt(e,t)}});const wn=new L(J),vn={...U["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function $n(e){return wn.encode(e).length}function xn(e){let t=0;for(let o of e)switch(o.type){case"text":t+=$n(o.text)*vn.contentMultiplier;break;case"tool_use":t+=$n(o.name+JSON.stringify(o.input))*vn.contentMultiplier;break;case"tool_result":o.content&&(t+=$n("string"==typeof o.content?o.content:JSON.stringify(o.content))*vn.contentMultiplier);break;case"thinking":t+=$n(o.thinking)*vn.contentMultiplier;break;case"image":t+=1600}return t}function Tn(e){let t=0,o=e.properties;if(!o)return t;let n=Object.entries(o);for(let[e,[o,r]]of n.entries()){if(t+=0===e?vn.perFirstProp:vn.perAdditionalProp,t+=$n(o),r.description&&(t+=vn.perPropDesc+$n(r.description)),r.enum&&Array.isArray(r.enum)){t+=vn.perEnum;for(let e of r.enum)t+=$n(String(e))}if("object"===r.type&&r.properties&&(t+=vn.perNestedObject,t+=Tn(r)),"array"===r.type&&r.items){let e=r.items;"object"===e.type&&e.properties&&(t+=vn.perArrayOfObjects,t+=Tn(e))}}return t}const An=async e=>{if(!Y._t1)throw Error("Service token not found");let t=mn(e),n={...Xe(Y),"X-Initiator":"agent"},r=Ye(Y),i=`${r}/responses`,a=Y.timeoutMs,s=JSON.stringify(t),l={"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":a,"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 c=mo(r),u=new AbortController,p=setTimeout(()=>u.abort(),a);try{let{statusCode:o,headers:r,body:p,span:d}=await Le({spanName:"copilot POST /responses",url:i,target:"responses",headers:n,body:s,signal:u.signal,headersTimeout:a,bodyTimeout:3*a,extraAttributes:{...l,"copilot_api.h2.retry_attempt":e},dispatcher:c}),m=new Response(p,{status:o,headers:r});if(!m.ok)throw d.end(),new nt("Failed to create responses",m);if(t.stream)return{events:B(m),span:d,release:()=>fo(c)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&Vo(d,{prompt_tokens:f.usage.input_tokens,completion_tokens:f.usage.output_tokens,total_tokens:f.usage.total_tokens}),d.end(),fo(c),f}catch(t){if(fo(c),pn(t)&&e<1){o.warn(`HTTP/2 GOAWAY during responses, retrying (attempt ${e+1})`),await dn();continue}throw t}finally{clearTimeout(p)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function Sn(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function Cn(e,t){let o={model:e.model,messages:On(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:jn(e.tools),tool_choice:Rn(e.tool_choice)},n=e.thinking;if("enabled"===n?.type||"adaptive"===n?.type){let r=an(t,o.model);if(r){let i="enabled"===n.type&&"number"==typeof n.budget_tokens?n.budget_tokens:function(e,t,o){let n=function(e,t){return"max"===e?t:"high"===e?16e3:"medium"===e?8e3:1024}(e,o.max),r=on(t),i=r&&r>1?r-1:o.min;return nn(Math.min(n,i),o.min,o.max)}(e.output_config?.effort??"high",o.max_tokens,r.bounds);o=ln({...o,thinking_budget:i},t)}}return o}function On(e,t){let o=function(e){return e?"string"==typeof e?[{role:"system",content:En(e)}]:[{role:"system",content:En(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:Nn(e.content)});n.length>0&&t.push({role:"user",content:Nn(n)})}else t.push({role:"user",content:Nn(e.content)});return t}(e):function(e){let t=function(e){return{reasoning_text:Pn(e.reasoning_text),reasoning_opaque:Pn(e.reasoning_opaque)}}(e);if(!Array.isArray(e.content))return[{role:"assistant",content:Nn(e.content),...t}];let o=e.content.filter(e=>"tool_use"===e.type),n=e.content.filter(e=>"text"===e.type),r=e.content.filter(e=>"thinking"===e.type),i=[...n.map(e=>e.text),...r.map(e=>e.thinking)].join("\n\n");return o.length>0?[{role:"assistant",content:i||null,...t,tool_calls:o.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:"assistant",content:Nn(e.content),...t}]}(e));return[...o,...n]}function En(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}const In=32768;function Pn(e){if("string"==typeof e)return e.length<=In?e:e.slice(0,In)}function Nn(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 jn(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Rn(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 qn(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 Dn(e){return e.reasoning_text?[{type:"thinking",thinking:e.reasoning_text}]:[]}function Mn(e){return e?e.map(e=>({type:"tool_use",id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function Fn(e){let t={model:e.model,input:Bn(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);return 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)),"adaptive"===e.thinking?.type?t.reasoning={effort:Hn(e.output_config?.effort??"high")}:"enabled"===e.thinking?.type&&e.thinking.budget_tokens&&(t.reasoning=function(e){return e<5e3?{effort:"low"}:e<2e4?{effort:"medium"}:e<32e3?{effort:"high"}:{effort:"xhigh"}}(e.thinking.budget_tokens)),t}function Hn(e){switch(e){case"low":return"low";case"medium":return"medium";case"max":return"xhigh";default:return"high"}}function Bn(e){let t=[];for(let o of e)"user"===o.role?t.push(...Ln(o)):t.push(...Jn(o));return t}function Ln(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(Un(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 Un(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 Jn(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),r=e.content.filter(e=>"tool_use"===e.type),i=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");i&&t.push({type:"message",role:"assistant",content:i});for(let e of r)t.push({type:"function_call",call_id:e.id,name:e.name,arguments:JSON.stringify(e.input)});return t}function Gn(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 zn(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function Kn(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 Wn(e,t){let o=[];switch(e.type){case"response.created":Kn(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){Kn(t,o),zn(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":Kn(t,o),zn(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":zn(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":{zn(t,o);let n=e.response.output.some(e=>"function_call"===e.type),r=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:Gn(e.response.status,n),stop_sequence:null},usage:{input_tokens:r?.input_tokens??0,output_tokens:r?.output_tokens??0}},{type:"message_stop"});break}case"response.incomplete":{Kn(t,o),zn(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":Kn(t,o),zn(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":Kn(t,o),zn(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":Kn(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 Vn(e,t){e.thinkingBlockOpen||(e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1),t.push({type:"content_block_start",index:e.contentBlockIndex,content_block:{type:"thinking",thinking:""}}),e.thinkingBlockOpen=!0,e.contentBlockOpen=!0)}function Yn(e,t){e.thinkingBlockOpen&&(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.thinkingBlockOpen=!1,e.contentBlockOpen=!1)}function Xn(e,t){let o=[];if(0===e.choices.length)return o;let n=e.choices[0],{delta:r}=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),"string"==typeof r.reasoning_text&&""!==r.reasoning_text&&(Vn(t,o),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"thinking_delta",thinking:r.reasoning_text}})),"string"==typeof r.reasoning_opaque&&""!==r.reasoning_opaque&&(Vn(t,o),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"signature_delta",signature:r.reasoning_opaque}}),Yn(t,o)),r.content&&(Yn(t,o),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:r.content}})),r.tool_calls){Yn(t,o);for(let e of r.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&&(Yn(t,o),t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:Sn(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 Qn(e,t,n){let r={query:t,max_results:n?.maxResults??5};n?.includeDomains?.length&&(r.include_domains=n.includeDomains),n?.excludeDomains?.length&&(r.exclude_domains=n.excludeDomains),o.debug("Tavily search request:",JSON.stringify(r));let i=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(r)});if(!i.ok){let e=await i.text();throw o.error(`Tavily API error (${i.status}):`,e),Error(`Tavily API error: ${i.status} ${e}`)}let a=await i.json();return o.debug(`Tavily returned ${a.results.length} results`),a.results}function Zn(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function er(e,t){let n=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(!n)return e.json({type:"error",error:{type:"invalid_request_error",message:"Could not extract search query from web search request"}},400);let r=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);o.info(`Web search intercepted: "${n}"`);let i=[];try{let e=Y.tavilyApiKey;if(!e)throw Error("No Tavily API key configured");i=(await Qn(e,n,{maxResults:Math.min(r.maxResults,10),includeDomains:r.allowedDomains,excludeDomains:r.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){o.error("Tavily search failed:",e)}let a={query:n,results:i,model:t.model};if(!t.stream)return e.json(function(e){let{query:t,results:o,model:n}=e,r=`srvtoolu_${Zn()}`,i=[{type:"text",text:"I'll search for that."},{type:"server_tool_use",id:r,name:"web_search",input:{query:t}},{type:"web_search_tool_result",tool_use_id:r,content:o}];return{id:`msg_tavily_${Zn()}`,type:"message",role:"assistant",model:n,content:i,stop_reason:"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}(a));let s=function(e){let{query:t,results:o,model:n}=e,r=`srvtoolu_${Zn()}`,i=`msg_tavily_${Zn()}`,a=[];return a.push({type:"message_start",message:{id:i,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:r,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:r,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"}),a}(a);return H(e,async e=>{for(let t of s)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}function tr(e){return function(e){let t=e.thinking;if(null==t)return null;if("object"!=typeof t)return"thinking must be an object";let o=t,n=new Set(["enabled","adaptive","disabled"]);return"string"==typeof o.type&&n.has(o.type)?"enabled"!==o.type||void 0===o.budget_tokens||"number"==typeof o.budget_tokens&&Number.isFinite(o.budget_tokens)&&!(o.budget_tokens<=0)&&Number.isInteger(o.budget_tokens)?null:"thinking.budget_tokens must be a positive integer":"thinking.type must be one of: enabled, adaptive, disabled"}(e)??function(e){let t=e.output_config;if(null==t)return null;if("object"!=typeof t)return"output_config must be an object";let o=t;if(void 0===o.effort)return null;let n=new Set(["low","medium","high","max"]);return"string"==typeof o.effort&&n.has(o.effort)?null:"output_config.effort must be one of: low, medium, high, max"}(e)}async function or(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 er(e,t);await tn(Y),o.debug("Anthropic request payload:",JSON.stringify(t));let n=e.req.header("anthropic-beta")??"",r=/context-1m/i.test(n);if(r&&/\u0063\u006c\u0061\u0075\u0064\u0065/i.test(t.model)){let e=t.model;t={...t,model:`${t.model}-1m`},o.debug(`Detected context-1m beta flag, rewriting model: '${e}' → '${t.model}'`)}let i=function(e,t){return ae.startActiveSpan("copilot_api.model.validate",n=>{try{n.setAttribute("copilot_api.model.requested",t.model);let r=en(t.model);n.setAttribute("copilot_api.model.normalized",r);let i=tr(t);return i?{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:i}},400)}:r===t.model?(n.setAttribute("copilot_api.model.was_mapped",!1),{ok:!0,payload:t}):(n.setAttribute("copilot_api.model.was_mapped",!0),ge.add(1,{from_model:t.model,to_model:r}),o.debug(`Model mapping: '${t.model}' → '${r}'`),{ok:!0,payload:{...t,model:r}})}catch(t){if(t instanceof Zo)return{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:t.message}},t.statusCode)};throw t}finally{n.end()}})}(e,t);if(!i.ok)return i.response;if(t=i.payload,function(e){return/gpt-[\d.]+-codex/i.test(e)}(t.model))return async function(e,t){let n=performance.now(),r=ae.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),Fn(t)}finally{e.end()}});Ee.record(performance.now()-n,{direction:"anthropic_to_responses"}),o.debug("Translated Responses API payload:",JSON.stringify(r)),e.set("requestData",{model:r.model,streaming:!!r.stream}),Y.manualApprove&&await Go();let i=performance.now(),a=await An(r),s=performance.now()-i;if(Se.record(s,{model:r.model,target:"responses",streaming:String(!!r.stream)}),ir(a)){let t=e.get("requestData")||{};if(a.usage&&(t.tokenUsage=Wo({prompt_tokens:a.usage.input_tokens,completion_tokens:a.usage.output_tokens,total_tokens:a.usage.total_tokens})),t._d1=s,e.set("requestData",t),o.debug("Non-streaming Responses API response:",JSON.stringify(a).slice(-400)),"failed"===a.status)return e.json({type:"error",error:{type:a.error?.code??"api_error",message:a.error?.message??"Response generation failed"}},500);let n=performance.now(),r=ae.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:Gn(e.status,o),stop_sequence:null,usage:{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}}(a)}finally{e.end()}});return Ee.record(performance.now()-n,{direction:"responses_to_anthropic"}),e.json(r)}o.debug("Streaming Responses API response");let{events:l,span:c,release:u}=a;return H(e,async t=>{let n=null,i=0,a=performance.now(),p={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,responseId:"",model:"",toolCalls:{}};try{try{for await(let a of l){if(o.debug("Responses API raw stream event:",JSON.stringify(a)),!a.data)continue;let l;try{l=JSON.parse(a.data)}catch(e){o.warn("Failed to parse streaming chunk:",a.data.slice(0,200),e);continue}i++,ve.add(1,{model:r.model,endpoint_type:"responses"});let c=nr(l);if(c){n=c;let t=e.get("requestData")||{};t.tokenUsage=Wo(n),t._d1=s,e.set("requestData",t)}let u=Wn(l,p);for(let e of u)o.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let c=performance.now()-a,u={model:r.model,endpoint_type:"responses"};Ce.record(c,u),Re.record(i,u)}finally{n&&Vo(c,n),c.end(),u()}let d=e.get("requestId");d&&ee.executeCompletion(d)}finally{e.get("resolveStreamComplete")?.()}})}(e,t);let a=performance.now(),s=ae.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",r);let o=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"===e.type)),n=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",n),Cn(t,Y.models)}finally{e.end()}});Ee.record(performance.now()-a,{direction:"anthropic_to_openai"}),s=ln(s,Y.models,{enabled:Y.thinkingEnabled}),o.debug("Translated OpenAI request payload:",JSON.stringify(s)),e.set("requestData",{model:s.model,streaming:!!s.stream});let l=performance.now();Y.manualApprove&&await Go();let c=await fn(s),u=performance.now()-l;if(Se.record(u,{model:s.model,target:"chat_completions",streaming:String(!!s.stream)}),rr(c)){let t=e.get("requestData")||{};c.usage&&(t.tokenUsage=Wo(c.usage)),t._d1=u,e.set("requestData",t),o.debug("Non-streaming response:",JSON.stringify(c).slice(-400));let n=performance.now(),r=ae.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=[],r=null;r=e.choices[0]?.finish_reason??r;for(let i of e.choices){let e=Dn(i.message),a=qn(i.message.content),s=Mn(i.message.tool_calls);t.push(...e),o.push(...a),n.push(...s),("tool_calls"===i.finish_reason||"stop"===r)&&(r=i.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o,...n],stop_reason:Sn(r),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 Ee.record(performance.now()-n,{direction:"openai_to_anthropic"}),o.debug("Translated Anthropic response:",JSON.stringify(r)),e.json(r)}o.debug("Streaming response from service");let{events:p,span:d,release:m}=c;return H(e,async t=>{let n=null,r=0,i=performance.now(),a={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,thinkingBlockOpen:!1,toolCalls:{}};try{try{for await(let i of p){if(o.debug("Raw stream event:",JSON.stringify(i)),"[DONE]"===i.data)break;if(!i.data)continue;let l;try{l=JSON.parse(i.data)}catch(e){o.warn("Failed to parse streaming chunk:",i.data.slice(0,200),e);continue}if(r++,ve.add(1,{model:s.model,endpoint_type:"anthropic"}),l.usage){n=l.usage;let t=e.get("requestData")||{};t.tokenUsage=Wo(n),t._d1=u,e.set("requestData",t)}let c=Xn(l,a);for(let e of c)o.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let l=performance.now()-i,c={model:s.model,endpoint_type:"anthropic"};if(Ce.record(l,c),Re.record(r,c),n){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=Wo(n),t._d1=u,e.set("requestData",t))}}finally{n&&Vo(d,n),d.end(),m()}let l=e.get("requestId");l&&ee.executeCompletion(l)}finally{e.get("resolveStreamComplete")?.()}})}function nr(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 rr=e=>Object.hasOwn(e,"choices"),ir=e=>Object.hasOwn(e,"output");const ar=new M;ar.post("/",async e=>{try{return await or(e)}catch(t){return await rt(e,t)}});const sr=new M;function lr(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=Wo(o),n._d1=t._d1,t.c.set("requestData",n)}sr.get("/",async e=>{try{Y.models||await ct();let t=Y.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 rt(e,t)}});const cr=new Set(["message","function_call","function_call_output"]),ur=new Set(["type","name","description","parameters"]);async function pr(e){if(!e)return!1;let t=e.sources;if(t&&t.length>0)return!1;let n=e.query??e.queries?.[0];return!(!n||!Y.tavilyApiKey)&&(o.info(`Enriching web search: "${n}"`),e.sources=(await Qn(Y.tavilyApiKey,n,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function dr(e){if(Y.tavilyApiKey)try{for(let t of e.output){let e=t;"web_search_call"===e.type&&await pr(e.action)}}catch(e){o.error("Failed to enrich non-streaming web search:",e)}}async function mr(e){if(!Y.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 pr(e.action))return JSON.stringify(t)}}catch(e){o.error("Failed to enrich web search:",e)}return e}function fr(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 hr(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&&fr(e,t))return JSON.stringify(o)}if("response.completed"===n){let n=o.response?.output;if(!n)return e;let r=!1;for(let e of n)fr(e,t)&&(r=!0);if(r)return JSON.stringify(o)}}catch{}return e}function gr(e){return null!=e}function _r(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 cr.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"])gr(e[t])&&(n[t]=e[t]);let r=new Set;if(gr(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))ur.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,r=t.customToolNames}if(gr(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;n.reasoning={},gr(t.effort)&&(n.reasoning.effort=t.effort),gr(t.summary)&&(n.reasoning.summary=t.summary)}if(gr(e.text)&&"object"==typeof e.text){let t=e.text;gr(t.format)&&(n.text={format:t.format})}return{payload:n,customToolNames:r}}async function yr(e){await tn(Y);let{payload:t,customToolNames:n}=_r(await e.req.json()),r=t;o.debug(`Responses API [${Array.isArray(r.input)?r.input.length:1} items]`),n.size>0&&o.debug(`Custom tools detected: ${[...n].join(", ")}`);try{r=function(e){return ae.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=en(e.model);return t.setAttribute("copilot_api.model.normalized",n),n===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),ge.add(1,{from_model:e.model,to_model:n}),o.debug(`Normalized model from '${e.model}' to '${n}'`),{...e,model:n})}finally{t.end()}})}(r)}catch(t){if(t instanceof Zo)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:r.model,streaming:!!r.stream}),Y.manualApprove&&await Go();let i=performance.now(),a=await An(r),s=performance.now()-i;if(Se.record(s,{model:r.model,target:"responses",streaming:String(!!r.stream)}),kr(a))return async function(e,t,o){await dr(t);let n=e.get("requestData")||{};return t.usage&&(n.tokenUsage=Wo({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)}(e,a,s);let{events:l,span:c,release:u}=a;return H(e,async t=>{let o={value:null},i=0,a=performance.now();try{try{for await(let a of l)if(a.data&&"[DONE]"!==a.data){i++;let l=hr(a.data,n);l=await mr(l);let c=l===a.data?a:{...a,data:l};ve.add(1,{model:r.model,endpoint_type:"responses"}),lr(l,{usageRef:o,c:e,_d1:s}),await t.writeSSE(c)}else await t.writeSSE(a);let c=performance.now()-a,u={model:r.model,endpoint_type:"responses"};Ce.record(c,u),Re.record(i,u)}finally{o.value&&Vo(c,o.value),c.end(),u()}let p=e.get("requestId");p&&ee.executeCompletion(p)}finally{e.get("resolveStreamComplete")?.()}})}const kr=e=>Object.hasOwn(e,"output"),br=new M;br.post("/",async e=>{try{return await yr(e)}catch(t){return await rt(e,t)}});const wr=new M;wr.get("/",e=>{try{return e.json({token:Y._t1})}catch(t){return o.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const vr=new M;vr.get("/",async e=>{try{let t=await vt();return e.json(t)}catch(t){return o.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const $r=new M;$r.use(async(e,t)=>{let n=Date.now(),r=`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,i=e.req.method,c=e.req.path,p=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"}(c);e.set("requestId",r),e.header("x-request-id",r);let d=ae.startSpan("copilot_api.handle_request",{kind:a.SERVER,attributes:{"http.method":i,"http.url":e.req.url,"http.route":c,"copilot_api.request_id":r,"copilot_api.endpoint_type":p}});for(let[t,o]of Object.entries(e.req.header())){let e=t.toLowerCase();Fe.has(e)||d.setAttribute(`http.request.header.${e}`,o)}let m,f=new Promise(e=>{m=e});e.set("streamComplete",f),e.set("resolveStreamComplete",m);let h=u.setSpan(l.active(),d);await l.with(h,async()=>{ee.registerCompletion(r,e,n);try{await t()}catch(e){let t=e instanceof Error?e:Error(String(e));throw d.setStatus({code:s.ERROR,message:t.message}),d.recordException(t),e}});let g=e.get("requestData"),_={c:e,start:n,method:i,path:c,endpointType:p,requestId:r,span:d};g?.streaming?f.then(()=>Jo(_)).catch(e=>{o.debug("Error finalizing streaming request:",e),d.end()}):Jo(_)}),$r.use(F()),$r.get("/",e=>e.text("Server running")),$r.route("/chat/completions",kn),$r.route("/models",sr),$r.route("/embeddings",bn),$r.route("/usage",vr),$r.route("/token",wr),$r.route("/v1/chat/completions",kn),$r.route("/v1/models",sr),$r.route("/v1/embeddings",bn),$r.route("/v1/messages",ar),$r.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=vn.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");o+=vn.perMessage+$n(e)*vn.contentMultiplier}for(let e of t.messages)o+=vn.perMessage,o+=$n(e.role),"string"==typeof e.content?o+=$n(e.content)*vn.contentMultiplier:Array.isArray(e.content)&&(o+=xn(e.content));return t.tools&&t.tools.length>0&&(o+=function(e){let t=vn.toolsExist;for(let[o,n]of e.entries())o>0&&(t+=vn.perTool),t+=$n(n.name),n.description&&(t+=vn.perDesc+$n(n.description)),t+=Tn(n.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(o)})}),$r.route("/v1/responses",br),$r.route("/responses",br);const xr=[],Tr=Date.now();let Ar="";function Sr(){let e=async(e,t=0)=>{let n=ae.startSpan("copilot_api.server.shutdown",{kind:a.INTERNAL,attributes:{"copilot_api.shutdown.reason":e,"copilot_api.shutdown.exit_code":t,"copilot_api.uptime_seconds":(Date.now()-Tr)/1e3}});for(let t of xr)try{await t()}catch(e){o.error("Error during cleanup:",e)}n.end(),function(e,t){let o=xo("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),n=["",Ao,` ${yo("COPILOT-API")} ${ko(`v${e}`)} ${ko("·")} ${Ro(t)} uptime`,Ao,""," Check in from time to time on",` ${bo(o)}`,"",Ao,""];console.log(n.join("\n"))}(Ar,Date.now()-Tr),f.exit(t)};f.on("SIGINT",()=>e("SIGINT")),f.on("SIGTERM",()=>e("SIGTERM")),f.on("uncaughtException",t=>{o.error("Uncaught exception:",t),e("uncaughtException",1)}),f.on("unhandledRejection",(t,n)=>{o.error("Unhandled promise rejection at:",n,"reason:",t),e("unhandledRejection",1)})}function Cr(e){let{options:t,version:o,runtime:n,_u1:r}=e,i=ae.startSpan("copilot_api.server.startup",{kind:a.INTERNAL,attributes:Me({config:{version:o,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",enableThinking:t.enableThinking},runtime:n,identity:{_u1:r.login,machineId:Y.machineId,sessionId:Y.sessionId,_v1:Y._v1},connectivity:Y.connectivity,modelsCount:Y.models?.data.length??0,startupDurationMs:Date.now()-Tr},"copilot_api")});if(Y.models?.data)for(let e of Y.models.data)i.addEvent("copilot_api.model.available",Me(e,"model"));i.end(),De(h.INFO,"INFO","Server started",Me({version:o,port:t.port,accountType:t.accountType,_u1:r.login,modelsCount:Y.models?.data.length??0,startupDurationMs:Date.now()-Tr},"copilot_api"))}async function Or(e){if(e.https){if(e.httpsCert&&e.httpsKey)return async function(e,t){let[o,r]=await Promise.all([n.readFile(e,"utf8"),n.readFile(t,"utf8")]);return{cert:o,key:r,certPath:e,keyPath:t,generated:!1}}(e.httpsCert,e.httpsKey);if(e.httpsCert||e.httpsKey)throw Error("Both --https-cert and --https-key must be provided together");return async function(e=[]){if(await Bo(e)){let e=await Ho(Do),t=await Ho(Mo);if(e&&t)return{cert:e,key:t,certPath:Do,keyPath:Mo,generated:!1}}return o.info("Generating new self-signed TLS certificate…"),Uo(e)}(e.httpsHosts)}}async function Er(e){let t=function(e){if(!e.claudeCowork)return e;if(e.httpsCert&&e.httpsKey)return{...e,https:!0};let{certPath:t,keyPath:n}=Ht;try{N(t),N(n)}catch{throw o.error("Tailscale cert not found. Run `copilot-api cowork-setup install` first."),Error("Tailscale cert not found")}return{...e,https:!0,httpsCert:t,httpsKey:n}}(e);if(Sr(),xr.push(()=>{o.debug("Cleaning up connectivity monitor"),Ue.stop()},()=>{o.debug("Cleaning up token management"),o.debug("Cleaning up token management"),pt&&=void clearInterval(pt),dt&&=void Ue.off("online",dt),mt&&=void Ue.off("offline",mt)},async()=>{o.debug("Cleaning up HTTP/2 client"),await async function(){o.debug("Stopping HTTP/2 pool"),lo&&=void clearInterval(lo),co&&=void clearInterval(co);let e=[...io.keys(),...ao];io.clear(),ao.clear(),ro.clear(),so=void 0;for(let t of e)uo(t)&&(Te.add(1,{event:"closed"}),await t.close())}()},async()=>{o.debug("Shutting down OTel SDK"),await async function(){te&&await te.shutdown()}()}),t.verbose&&(o.level=5,o.info("Verbose logging enabled")),t._cc1&&t.codex)throw Error("Cannot use --claude-code and --codex together");Y.accountType=t.accountType,Y.manualApprove=t.manual,Y.rateLimitSeconds=t.rateLimit,Y.rateLimitWait=t.rateLimitWait,Y.showToken=t.showToken,Y.timeoutMs=t.timeout,Y.thinkingEnabled=t.enableThinking,t.tavilyApiKey&&(Y.tavilyApiKey=t.tavilyApiKey),function(){let e="1"===f.env.COPILOT_H2_KEEPALIVE||"true"===f.env.COPILOT_H2_KEEPALIVE,t=e||"1"===f.env.COPILOT_H2||"true"===f.env.COPILOT_H2;Y.connectivity.h2=t,Y.connectivity.h2Keepalive=e}(),await K(),Y._v1="1.116.0-insider";let n=await Kt();Ar=n;let r,i=Wt();(function(e,t){t&&(ne=t),oe=crypto.randomUUID(),te=new $({resource:b({[T]:"copilot-api",[A]:e,[x]:oe}),traceExporter:new k({url:`${re}/v1/traces`,headers:ie}),metricReader:new v({exporter:new y({url:`${re}/v1/metrics`,headers:ie}),exportIntervalMillis:15e3}),logRecordProcessors:[new w(new _({url:`${re}/v1/logs`,headers:ie}))],instrumentations:[]}),te.start()})(n,Tr),t._t2?(Y._t2=t._t2,o.info("Using provided Auth token")):await yt();try{r=await at(),await Ve(Y,r.login)}catch(e){throw o.error("Failed to get user info for machine ID generation:",e),Error("Cannot proceed without user information",{cause:e})}await _t(),await ct();let a=function(e=18e5){let t=setInterval(()=>{ct().then(()=>o.debug("Model list refreshed successfully")).catch(e=>{o.warn("Failed to refresh model list; keeping existing cache:",e)})},e);return t.unref(),()=>{clearInterval(t)}}();xr.push(()=>{o.debug("Cleaning up model refresh interval"),a()}),Y.connectivity.h2&&(fo(mo(Ye(Y))),Y.connectivity.h2Keepalive&&go()),Cr({options:t,version:n,runtime:i,_u1:r});let s=await Or(t),l=`${s?"https":"http"}://localhost:${t.port}`,c=await async function(e,t,n){if(!e._cc1)return!1;let r,i;if(R(Y.models,"Models should be loaded by now"),e.model&&e.smallModel){let t=Y.models.data.map(e=>e.id);if(!t.includes(e.model))throw o.info(`Available services: \n${t.join("\n")}`),Error(`Invalid model: ${e.model}`);if(!t.includes(e.smallModel))throw o.info(`Available services: \n${t.join("\n")}`),Error(`Invalid small model: ${e.smallModel}`);r=e.model,i=e.smallModel}else{if(e.model||e.smallModel)throw Error("Both --model and --small-model must be specified for model selection");r=await o.prompt("Select a model to use",{type:"select",options:Y.models.data.map(e=>e.id)}),i=await o.prompt("Select a small model to use",{type:"select",options:Y.models.data.map(e=>e.id)})}let a=_o({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:r,ANTHROPIC_SMALL_FAST_MODEL:i,NODE_EXTRA_CA_CERTS:n?.certPath},"claude");try{return p.writeSync(a),!0}catch{return o.warn("Failed to copy to clipboard. Here is the command:"),o.log(a),!1}}(t,l,s)||await async function(e,t,n){if(!e.codex)return!1;let r;if(R(Y.models,"Models should be loaded by now"),e.model){let t=Y.models.data.map(e=>e.id);if(!t.includes(e.model))throw o.info(`Available services: \n${t.join("\n")}`),Error(`Invalid model: ${e.model}`);r=e.model}else r=await o.prompt("Select a model to use with Codex CLI",{type:"select",options:Y.models.data.map(e=>e.id)});let i=_o({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy",NODE_EXTRA_CA_CERTS:n?.certPath},`codex --model ${r}`);try{return p.writeSync(i),!0}catch{return o.warn("Failed to copy to clipboard. Here is the Codex CLI command:"),o.log(i),!1}}(t,l,s);(function(e){let t=[...Eo(e),...Io(e),...Po(e),"",...Oo(Co),...No(e),...jo(e),""];console.log(t.join("\n"))})(await async function(e){let{options:t,version:o,runtime:n,user:r,clipboardCopied:i,tls:a}=e,s=a?"https":"http";return{version:o,runtime:n,user:r,accountType:t.accountType,port:t.port,timeout:t.timeout,webSearch:!!t.tavilyApiKey,model:t.model,smallModel:t.smallModel,clipboardCopied:i,https:a?{certPath:a.certPath,keyPath:a.keyPath,generated:a.generated,selfSigned:!t.httpsCert}:void 0,endpoints:t.claudeCowork?{scheme:s,port:t.port,hostname:await Ct()}:void 0}}({options:t,version:n,runtime:i,user:r.login,clipboardCopied:c,tls:s})),j({fetch:$r.fetch,port:t.port,tls:s?{cert:s.cert,key:s.key}:void 0,bun:{idleTimeout:255}})}function Ir(e,t){let o=Number.parseInt(e,10);if(Number.isNaN(o))throw Error(`${t} must be a number, got: "${e}"`);return o}const Pr=e({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)"},"enable-thinking":{type:"boolean",default:!1,description:"Enable forwarding of thinking_budget / Anthropic thinking config to upstream. Off by default to avoid accidentally triggering reasoning behaviour."},https:{type:"boolean",default:!1,description:"Serve over HTTPS using a self-signed certificate (auto-generated and persisted)"},"https-cert":{type:"string",description:"Path to a PEM-encoded TLS certificate (use with --https-key to bring your own cert)"},"https-key":{type:"string",description:"Path to a PEM-encoded TLS private key (use with --https-cert to bring your own cert)"},"https-hosts":{type:"string",description:"Extra hostnames or IPs to include in the self-signed cert's SANs (comma-separated). Example: --https-hosts host.docker.internal,192.168.1.42"},"claude-cowork":{type:"boolean",default:!1,description:"Print Claude Cowork-specific setup hints (inference endpoint URLs to paste into Cowork's apiHost setting)"}},run({args:e}){let t=e["rate-limit"],o=void 0===t?void 0:Ir(t,"--rate-limit"),n=e.timeout,r=void 0===n?V:Ir(n,"--timeout"),i=e["https-hosts"],a=i?i.split(",").map(e=>e.trim()).filter(Boolean):[];return Er({port:Ir(e.port,"--port"),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:r,tavilyApiKey:e["tavily-api-key"]||f.env.TAVILY_API_KEY,enableThinking:e["enable-thinking"],https:e.https,httpsCert:e["https-cert"],httpsKey:e["https-key"],httpsHosts:a,claudeCowork:e["claude-cowork"]})}});await async function(){try{if("1"===process.env.COPILOT_API_SKIP_UPDATE_CHECK)return;let[e,t]=await Promise.all([Kt(),oo()]);if("unknown"===e||!t||!function(e,t){let o=e.split(".").map(Number),n=t.split(".").map(Number),r=Math.max(o.length,n.length);for(let e=0;e<r;e++){let t=o[e]??0,r=n[e]??0;if(t<r)return!0;if(t>r)return!1}return!1}(e,t))return;!function(e,t){let o=`npx ${Qt}@latest`,n=to("│"),r=` ${eo("Update available!")} ${(e=>`${e}`)(e)} → ${(e=>`${e}`)(t)}`,i=` Run ${eo(o)} to update`,a=" ".repeat(54),s=to(`╭${"─".repeat(54)}╮`),l=to(`╰${"─".repeat(54)}╯`),c=["",s,`${n}${a}${n}`,`${n}${no(r,54)}${n}`,`${n}${a}${n}`,`${n}${no(i,54)}${n}`,`${n}${a}${n}`,l,""];console.log(c.join("\n"))}(e,t)}catch{}}(),await t(e({meta:{name:"copilot-api",description:"API proxy server for tool integration."},subCommands:{auth:wt,start:Pr,"check-usage":$t,debug:Xt,"cowork-setup":zt}}));export{};
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "copilot-api-node20",
3
- "version": "0.21.3",
3
+ "version": "0.22.1",
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",
7
7
  "github-copilot",
8
8
  "openai-compatible",
9
+ "anthropic-compatible",
10
+ "claude-code",
11
+ "claude-cowork",
12
+ "codex-cli",
9
13
  "node20",
10
14
  "fork"
11
15
  ],
@@ -77,6 +81,7 @@
77
81
  "consola": "^3.4.2",
78
82
  "fetch-event-stream": "^0.1.5",
79
83
  "hono": "^4.12.7",
84
+ "selfsigned": "^5.5.0",
80
85
  "srvx": "^0.11.13",
81
86
  "tiny-invariant": "^1.3.3",
82
87
  "undici": "^7.24.0"
@@ -1 +0,0 @@
1
- import t from"consola";import e from"node:fs/promises";import o from"node:os";import i from"node:path";import{SpanKind as r,SpanStatusCode as a,metrics as s,trace as n}from"@opentelemetry/api";import{SeverityNumber as c,logs as l}from"@opentelemetry/api-logs";import{OTLPLogExporter as p}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as u}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as d}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as m}from"@opentelemetry/resources";import{BatchLogRecordProcessor as h}from"@opentelemetry/sdk-logs";import{PeriodicExportingMetricReader as g}from"@opentelemetry/sdk-metrics";import{NodeSDK as f}from"@opentelemetry/sdk-node";import{ATTR_SERVICE_INSTANCE_ID as y,ATTR_SERVICE_NAME as v,ATTR_SERVICE_VERSION as _}from"@opentelemetry/semantic-conventions";import{request as b}from"undici";import{createHash as k,randomBytes as C,randomUUID as T}from"node:crypto";const E=i.join(o.homedir(),".local","share","copilot-api"),S={APP_DIR:E,GITHUB_TOKEN_PATH:i.join(E,"github_token"),MACHINE_ID_PATH:i.join(E,"machine_id"),SESSION_ID_PATH:i.join(E,"session_id")};async function I(){await e.mkdir(S.APP_DIR,{recursive:!0}),await w(S.GITHUB_TOKEN_PATH),await w(S.SESSION_ID_PATH)}async function w(t){try{await e.access(t,e.constants.W_OK)}catch{await e.writeFile(t,""),await e.chmod(t,384)}}const A=6e5,R={accountType:"individual",manualApprove:!1,rateLimitWait:!1,showToken:!1,thinkingEnabled:!1,timeoutMs:A,connectivity:{probeEndpoints:["https://api.github.com","https://www.google.com","https://1.1.1.1"],fastProbeInterval:5e3,slowProbeInterval:1e4,timeoutMs:5e3,jitterMaxMs:1e3,connectionPooling:!0,dnsCache:!0,h2:!1,h2Keepalive:!1}},x=t=>t>=1e5||t>=1e4?`${Math.round(t/1e3)}K`:t>=1e3?`${(t/1e3).toFixed(1)}K`:t.toString(),O=(t,e)=>t.padEnd(e),$=t=>{let e=[];if(t.model){let o=O(t.model,18);e.push(o)}if(t.tokenUsage){let o=t.tokenUsage,i=(o.inputTokens||0)+(o.outputTokens||0),r=t.model?((t,e)=>{if(!R.models)return"";let o=R.models.data.find(t=>t.id===e);if(!o)return"";let i=o.capabilities.limits?.max_context_window_tokens;return i?` (${(t/i*100).toFixed(1)}%)`:""})(i,t.model):"",a=O(`↑${x(o.inputTokens||0).padStart(5)} │ ↓${x(o.outputTokens||0).padStart(5)}`,18),s=x(i),n=r?`${s}${r.padStart(15-s.length)}`:s.padEnd(15);e.push(`Tokens: ${a} | Context: ${n}`)}else if(t.model){let t=O("N/A",18),o="N/A".padEnd(15);e.push(`Tokens: ${t} | Context: ${o}`)}if(t._d1){let o=O(`${Math.round(t._d1)}ms`,8);e.push(`API: ${o}`)}return e.length>0?` | ${e.join(" | ")}`:""},P={completionCallbacks:new Map,registerCompletion(t,e,o){this.completionCallbacks.set(t,{context:e,startTime:o,requestId:t})},executeCompletion(t){let e=this.completionCallbacks.get(t);e&&(this.logCompletion(e),this.completionCallbacks.delete(t))},logCompletion(e){let{context:o,startTime:i}=e,r=Date.now()-i,a=o.get("requestData"),s=` --\x3e ${O(o.req.method,4)}${O(o.req.path,21)}${O(o.res.status.toString(),3)} ${O(`${r}ms`,8)}`;a&&(s+=$(a)),t.info(s),vt(c.INFO,"INFO","Request completed",{"http.method":o.req.method,"http.path":o.req.path,"http.status_code":o.res.status,"copilot_api.duration_ms":r,...a?.model&&{"copilot_api.model":a.model},...a?._d1&&{"copilot_api.copilot_duration_ms":Math.round(a._d1)},...a?.tokenUsage?.inputTokens&&{"copilot_api.input_tokens":a.tokenUsage.inputTokens},...a?.tokenUsage?.outputTokens&&{"copilot_api.output_tokens":a.tokenUsage.outputTokens}})},logRateLimit(e,o){let{context:i,startTime:r}=e,a=Date.now()-r,s=(o.headers.get("x-ratelimit-exceeded")||"").split(":")[1]||"unknown",n=o.headers.get("retry-after")||o.headers.get("x-ratelimit-user-retry-after")||"?",c=`⚠ --\x3e ${O(i.req.method,4)}${O(i.req.path,21)}${O("429",3)} ${O(`${a}ms`,8)}`;c+=` | Rate limited (${n}s retry) | ${s}`;let l=i.get("requestData");if(l?._d1){c+=` | API: ${O(`${Math.round(l._d1)}ms`,8)}`}t.info(c)},cleanup(){let t=Date.now()-3e5;for(let[e,o]of this.completionCallbacks)o.startTime<t&&this.completionCallbacks.delete(e);if(this.completionCallbacks.size>1e3){let t=Array.from(this.completionCallbacks.entries()).sort(([,t],[,e])=>t.startTime-e.startTime),e=t.slice(0,t.length-1e3);for(let[t]of e)this.completionCallbacks.delete(t)}}};setInterval(()=>P.cleanup(),6e4);let N,H,M=Date.now();const q="https://api.honeycomb.io",j={"x-honeycomb-team":"hcaik_01km2y7yf1rrn70xvxce5kx9dyz936dwm21b9bgvnwf3pxq0cmqkcwha8n"};function F(t,e){e&&(M=e),H=crypto.randomUUID(),N=new f({resource:m({[v]:"copilot-api",[_]:t,[y]:H}),traceExporter:new d({url:`${q}/v1/traces`,headers:j}),metricReader:new g({exporter:new u({url:`${q}/v1/metrics`,headers:j}),exportIntervalMillis:15e3}),logRecordProcessors:[new h(new p({url:`${q}/v1/logs`,headers:j}))],instrumentations:[]}),N.start()}async function D(){N&&await N.shutdown()}const U=n.getTracer("copilot-api"),L=s.getMeter("copilot-api"),z=l.getLogger("copilot-api"),G=L.createCounter("copilot_api.requests.total",{unit:"{request}",description:"Total requests received"}),V=L.createCounter("copilot_api.requests.errors",{unit:"{error}",description:"Total error responses"}),K=L.createCounter("copilot_api.tokens.input",{unit:"{token}",description:"Total input tokens consumed"}),W=L.createCounter("copilot_api.tokens.output",{unit:"{token}",description:"Total output tokens generated"}),X=L.createCounter("copilot_api.tokens.cached",{unit:"{token}",description:"Total cached prompt tokens"}),B=L.createCounter("copilot_api.rate_limit.triggers",{unit:"{trigger}",description:"Rate limit trigger count"}),J=L.createCounter("copilot_api.model_validation.errors",{unit:"{error}",description:"Model validation failures"}),Y=L.createCounter("copilot_api.model_mapping.mappings",{unit:"{mapping}",description:"Model name normalizations"}),Z=L.createCounter("copilot_api.token_refresh.attempts",{unit:"{attempt}",description:"Token refresh attempts"}),Q=L.createCounter("copilot_api.token_refresh.failures",{unit:"{failure}",description:"Token refresh final failures"}),tt=L.createCounter("copilot_api.connectivity.checks",{unit:"{check}",description:"Connectivity probe results"}),et=L.createCounter("copilot_api.connectivity.transitions",{unit:"{transition}",description:"Connectivity state transitions"}),ot=L.createCounter("copilot_api.upstream.requests",{unit:"{request}",description:"Upstream API calls"}),it=L.createCounter("copilot_api.stream.chunks",{unit:"{chunk}",description:"Total SSE chunks sent"}),rt=L.createCounter("copilot_api.approval.decisions",{unit:"{decision}",description:"Manual approval decisions"}),at=L.createCounter("copilot_api.h2_keepalive.pings",{unit:"{ping}",description:"HTTP/2 keepalive pings sent"}),st=L.createCounter("copilot_api.h2.connections",{unit:"{connection}",description:"HTTP/2 connection lifecycle events"}),nt=L.createHistogram("copilot_api.request.duration",{unit:"ms",description:"Total request duration"}),ct=L.createHistogram("copilot_api.copilot.duration",{unit:"ms",description:"Upstream Copilot API call duration"}),lt=L.createHistogram("copilot_api.stream.duration",{unit:"ms",description:"Duration of SSE streaming phase"}),pt=L.createHistogram("copilot_api.rate_limit.wait_duration",{unit:"ms",description:"Duration of rate limit waits"}),ut=L.createHistogram("copilot_api.translation.duration",{unit:"ms",description:"Translation layer processing time"}),dt=L.createHistogram("copilot_api.token_refresh.duration",{unit:"ms",description:"Token refresh duration"}),mt=L.createHistogram("copilot_api.connectivity.probe_duration",{unit:"ms",description:"Individual connectivity probe duration"}),ht=L.createHistogram("copilot_api.tokens.per_request.input",{unit:"{token}",description:"Input tokens per request distribution"}),gt=L.createHistogram("copilot_api.tokens.per_request.output",{unit:"{token}",description:"Output tokens per request distribution"}),ft=L.createHistogram("copilot_api.stream.chunks_per_request",{unit:"{chunk}",description:"Chunks per streaming request"}),yt=L.createHistogram("copilot_api.approval.wait_duration",{unit:"ms",description:"Time waiting for manual approval"});function vt(t,e,o,i){let r=n.getActiveSpan()?.spanContext();z.emit({severityNumber:t,severityText:e,body:o,attributes:{...i,...r&&{"trace.id":r.traceId,"span.id":r.spanId}}})}function _t(t,e=""){let o={};if(null==t)return o;if("object"!=typeof t)return("string"==typeof t||"number"==typeof t||"boolean"==typeof t)&&e&&(o[e]=t),o;if(Array.isArray(t))return e&&(o[e]=JSON.stringify(t)),o;for(let[i,r]of Object.entries(t)){let t=e?`${e}.${i}`:i;void 0===r||"function"==typeof r||(null===r?o[t]="null":"object"!=typeof r||Array.isArray(r)?Array.isArray(r)?o[t]=JSON.stringify(r):("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(o[t]=r):Object.assign(o,_t(r,t)))}return o}L.createObservableGauge("copilot_api.connectivity.status",{unit:"{status}",description:"1 = online, 0 = offline"}).addCallback(t=>{t.observe(Et.getConnectivityStats().isOnline?1:0)}),L.createObservableGauge("copilot_api.connectivity.consecutive_failures",{unit:"{failure}",description:"Current consecutive connectivity failure count"}).addCallback(t=>{t.observe(Et.getConnectivityStats().consecutiveFailures)}),L.createObservableGauge("copilot_api.models.available",{unit:"{model}",description:"Number of available models"}).addCallback(t=>{t.observe(R.models?.data.length??0)}),L.createObservableGauge("copilot_api.completion_logger.pending",{unit:"{callback}",description:"Number of pending completion callbacks"}).addCallback(t=>{t.observe(P.completionCallbacks.size)}),L.createObservableGauge("copilot_api.uptime",{unit:"s",description:"Server uptime in seconds"}).addCallback(t=>{t.observe((Date.now()-M)/1e3)});const bt=new Set(["authorization","cookie","set-cookie","x-honeycomb-team","x-api-key","proxy-authorization"]);function kt(t,e,o){for(let[i,r]of Object.entries(o)){let o=i.toLowerCase();bt.has(o)||t.setAttribute(`http.${e}.header.${o}`,r)}}async function Ct(t){let{spanName:e,url:o,target:i,method:s="GET",headers:n,body:c,signal:l,extraAttributes:p}=t,u=U.startSpan(e,{kind:r.CLIENT,attributes:{"http.method":s,"url.full":o,"copilot_api.target":i,...p}});n&&kt(u,"request",n);try{let t=await fetch(o,{method:s,headers:n,body:c,signal:l});return u.setAttribute("http.response.status_code",t.status),function(t,e){e.headers.forEach((e,o)=>{let i=o.toLowerCase();bt.has(i)||t.setAttribute(`http.response.header.${i}`,e)})}(u,t),ot.add(1,{target:i,status_code:String(t.status)}),t.ok||u.setStatus({code:a.ERROR,message:`HTTP ${t.status}`}),{response:t,span:u}}catch(t){let e=t instanceof Error?t:Error(String(t));throw u.setStatus({code:a.ERROR,message:e.message}),u.recordException(e),u.end(),t}}async function Tt(t){let{spanName:e,url:o,target:i,method:s="POST",headers:n,body:c,signal:l,headersTimeout:p,bodyTimeout:u,extraAttributes:d,dispatcher:m}=t,h=U.startSpan(e,{kind:r.CLIENT,attributes:{"http.method":s,"url.full":o,"copilot_api.target":i,"copilot_api.h2.enabled":void 0!==m,...d}});kt(h,"request",n);try{let{statusCode:t,headers:e,body:r}=await b(o,{method:s,headers:n,body:c,signal:l,headersTimeout:p,bodyTimeout:u,dispatcher:m});h.setAttribute("http.response.status_code",t);for(let[t,o]of Object.entries(e)){let e=t.toLowerCase();void 0!==o&&!bt.has(e)&&h.setAttribute(`http.response.header.${e}`,Array.isArray(o)?o.join(", "):o)}return ot.add(1,{target:i,status_code:String(t)}),t>=400&&h.setStatus({code:a.ERROR,message:`HTTP ${t}`}),{statusCode:t,headers:e,body:r,span:h}}catch(t){let e=t instanceof Error?t:Error(String(t));throw h.setStatus({code:a.ERROR,message:e.message}),h.recordException(e),h.end(),t}}const Et=new class extends EventTarget{isOnline=!0;lastChecked=(new Date).toISOString();consecutiveFailures=0;lastErrorType;lastErrorMessage;lastSuccessfulEndpoint;endpointFailureStats={};checkInterval;abortController;on(t,e){return this.addEventListener(t,e),this}off(t,e){return this.removeEventListener(t,e),this}start(){t.debug("Starting connectivity monitor",{probeEndpoints:R.connectivity.probeEndpoints,fastInterval:R.connectivity.fastProbeInterval}),this.scheduleNextCheck()}stop(){t.debug("Stopping connectivity monitor"),this.checkInterval&&=void clearTimeout(this.checkInterval),this.abortController&&=void this.abortController.abort()}scheduleNextCheck(){this.checkInterval&&clearTimeout(this.checkInterval);let e=(this.isOnline?R.connectivity.slowProbeInterval:R.connectivity.fastProbeInterval)+Math.random()*R.connectivity.jitterMaxMs;this.checkInterval=setTimeout(()=>{this.performConnectivityCheck().catch(e=>{t.error("Connectivity check failed:",e)})},e)}async performConnectivityCheck(){let e=U.startSpan("copilot_api.connectivity.probe");this.abortController=new AbortController;let o=setTimeout(()=>this.abortController?.abort(),R.connectivity.timeoutMs);try{let i=!1;for(let e of R.connectivity.probeEndpoints)try{let t=performance.now(),o=await fetch(e,{method:"HEAD",signal:this.abortController.signal,headers:{"User-Agent":"copilot-api-connectivity-monitor/1.0",...R.connectivity.dnsCache&&{"Cache-Control":"max-age=300"}}}),r=performance.now()-t;if(o.ok){i=!0,this.lastSuccessfulEndpoint=e,mt.record(r,{endpoint:e,result:"success"});break}mt.record(r,{endpoint:e,result:"failed"})}catch(o){this.endpointFailureStats[e]=(this.endpointFailureStats[e]||0)+1,t.debug(`Probe failed for ${e}:`,o)}this.updateConnectivityState(i);let r=i?"online":"offline";e.setAttribute("copilot_api.connectivity.result",r),e.setAttribute("copilot_api.connectivity.consecutive_failures",this.consecutiveFailures),this.lastSuccessfulEndpoint&&e.setAttribute("copilot_api.connectivity.successful_endpoint",this.lastSuccessfulEndpoint),tt.add(1,{result:i?"online":"offline"})}catch(t){this.handleConnectivityError(t)}finally{clearTimeout(o),e.end(),this.scheduleNextCheck()}}updateConnectivityState(e){let o=this.isOnline;if(this.isOnline=e,this.lastChecked=(new Date).toISOString(),e){let e=this.consecutiveFailures;this.consecutiveFailures>0&&t.info(`Connectivity restored after ${this.consecutiveFailures} failures`),this.consecutiveFailures=0,this.lastErrorType=void 0,this.lastErrorMessage=void 0,o||(this.dispatchEvent(new CustomEvent("online")),et.add(1,{from:"offline",to:"online"}),vt(c.INFO,"INFO","Connectivity restored",{"copilot_api.connectivity.consecutive_failures_before_recovery":e}))}else this.consecutiveFailures++,o&&(t.warn("Connectivity lost"),this.dispatchEvent(new CustomEvent("offline")),et.add(1,{from:"online",to:"offline"}),vt(c.WARN,"WARN","Connectivity lost",{"copilot_api.connectivity.consecutive_failures":this.consecutiveFailures}))}handleConnectivityError(e){this.lastErrorType=e.name,this.lastErrorMessage=e.message,t.error("Connectivity check failed:",e),this.updateConnectivityState(!1)}getConnectivityStats(){return{isOnline:this.isOnline,lastChecked:this.lastChecked,consecutiveFailures:this.consecutiveFailures,lastErrorType:this.lastErrorType,lastErrorMessage:this.lastErrorMessage}}getPerformanceStats(){let t=this.isOnline?R.connectivity.slowProbeInterval:R.connectivity.fastProbeInterval;return{currentInterval:t,nextCheckEstimate:new Date(Date.now()+t+Math.random()*R.connectivity.jitterMaxMs).toISOString(),lastSuccessfulEndpoint:this.lastSuccessfulEndpoint,endpointFailureStats:{...this.endpointFailureStats},jitterEnabled:R.connectivity.jitterMaxMs>0,connectionPooling:R.connectivity.connectionPooling,dnsCache:R.connectivity.dnsCache}}},St=()=>({"content-type":"application/json",accept:"application/json"}),It="0.43.2026040705",wt=`copilot-chat/${It}`,At=`GitHubCopilotChat/${It}`,Rt=t=>{let e=k("sha256");return e.update(process.platform),e.update(process.arch),e.update(process.env.USER||process.env.USERNAME||"anonymous"),e.update(o.hostname()),e.update(t),e.update(Date.now().toString()),e.update(C(16)),e.digest("hex")},xt=async t=>{let o=(t=>{let e=t.replaceAll(/[^\w.-]/g,"_").trim();if(0===e.length||"."===e||".."===e||/^[_.]+$/.test(e))throw Error("Invalid GitHub username: cannot be empty or consist only of special characters after sanitization");return`${S.MACHINE_ID_PATH}_${e}`})(t);try{let t=await e.readFile(o,"utf8");if(t.trim())return t.trim()}catch{}let i=Rt(t);return await e.writeFile(o,i),await e.chmod(o,384),i},Ot=async()=>{try{let t=await e.readFile(S.SESSION_ID_PATH,"utf8");if(t.trim())return t.trim()}catch{}let t=T();return await e.writeFile(S.SESSION_ID_PATH,t),await e.chmod(S.SESSION_ID_PATH,384),t},$t=async(t,e)=>{t.machineId||=await xt(e),t.sessionId||=await Ot()},Pt=t=>"individual"===t.accountType?"https://api.githubcopilot.com":`https://api.${t.accountType}.githubcopilot.com`,Nt=(t,e=!1)=>{if(!t.machineId||!t.sessionId)throw Error("VSCode identifiers not initialized. Call initializeVSCodeIdentifiers() during startup.");let o=T(),i={Authorization:`Bearer ${t._t1}`,"Content-Type":"application/json",accept:"*/*","accept-encoding":"br, gzip, deflate","accept-language":"*","sec-fetch-mode":"cors","Copilot-Integration-Id":"vscode-chat","Editor-Version":`vscode/${t._v1}`,"Editor-Plugin-Version":wt,"User-Agent":At,"VScode-MachineId":t.machineId,"VScode-SessionId":t.sessionId,"OpenAI-Intent":"conversation-agent","X-Interaction-Type":"conversation-agent","X-Agent-Task-Id":o,"X-VSCode-User-Agent-Library-Version":"node-fetch","X-GitHub-Api-Version":"2025-05-01","X-Interaction-Id":T(),"X-Request-Id":o};return e&&(i["copilot-vision-request"]="true"),i},Ht="https://api.github.com",Mt=t=>({"content-type":"application/json",accept:"application/json",authorization:`token ${t._t2}`,"editor-version":`vscode/${t._v1}`,"editor-plugin-version":wt,"user-agent":At,"x-github-api-version":"2025-04-01","x-vscode-user-agent-library-version":"node-fetch"}),qt="https://github.com",jt="01ab8ac9400c4e429b23",Ft=["user:email"].join(" ");var Dt=class extends Error{response;constructor(t,e){super(t),this.response=e}};async function Ut(e,o){let i=n.getActiveSpan();if(o instanceof Dt&&429===o.response.status){let t=e.get("requestId"),r=P.completionCallbacks.get(t);r&&(P.logRateLimit(r,o.response),P.completionCallbacks.delete(t)),B.add(1,{action:"rejected",source:"upstream"});let s,n=await o.response.text();try{s=JSON.parse(n)}catch{s={error:{message:n,type:"error"}}}return i?.setStatus({code:a.ERROR,message:"Rate limited by upstream"}),i?.setAttribute("copilot_api.error_type","rate_limit_upstream"),vt(c.WARN,"WARN","Upstream rate limit hit",{"copilot_api.status_code":429,"http.path":e.req.path,"copilot_api.error_type":"rate_limit_upstream"}),e.json(s,429)}if(t.error("Error occurred:",o),o instanceof Dt){let r,s=await o.response.text();try{r=JSON.parse(s)}catch{r=s}return t.error("HTTP error:",r),i?.setStatus({code:a.ERROR,message:o.message}),i?.recordException(o),i?.setAttribute("copilot_api.error_type","HTTPError"),vt(c.ERROR,"ERROR",`HTTP error: ${o.message}`,{"copilot_api.status_code":o.response.status,"http.path":e.req.path,"copilot_api.error_type":"HTTPError"}),e.json({error:{message:s,type:"error"}},o.response.status)}let r=o instanceof Error?o:Error(String(o));return i?.setStatus({code:a.ERROR,message:r.message}),i?.recordException(r),i?.setAttribute("copilot_api.error_type",r.name),vt(c.ERROR,"ERROR",`Unhandled error: ${r.message}`,{"copilot_api.status_code":500,"http.path":e.req.path,"copilot_api.error_type":r.name}),e.json({error:{message:r.message,type:"error"}},500)}async function Lt(){let t=`${Ht}/user`,e=R.timeoutMs,o=new AbortController,i=setTimeout(()=>o.abort(),e);try{let{response:e,span:i}=await Ct({spanName:"github GET /user",url:t,target:"github_user",headers:{authorization:`token ${R._t2}`,"content-type":"application/json",accept:"application/json"},signal:o.signal});if(!e.ok)throw i.end(),new Dt("Failed to get GitHub user",e);let r=await e.json();return i.end(),r}finally{clearTimeout(i)}}export{J as A,Z as B,_t as C,K as D,F as E,nt as F,U as G,Q as H,G as I,A as J,ut as K,D as L,gt as M,B as N,ht as O,pt as P,it as R,V as S,at as T,Ct as U,dt as V,Tt as W,S as X,R as Y,I as Z,yt as _,Ft as a,ct as b,Pt as c,$t as d,St as f,rt as g,c as h,Ht as i,W as j,Y as k,Nt as l,bt as m,Dt as n,qt as o,Et as p,P as q,Ut as r,jt as s,Lt as t,Mt as u,X as v,st as w,vt as x,ft as y,lt as z};
@@ -1 +0,0 @@
1
- import{t as r}from"./get-user-CEqqH34r.mjs";export{r as _s4};