copilot-api-node20 0.21.2 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -9
- package/dist/main.mjs +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|

|
|
8
8
|
[](./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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 T,_ as A,a as $,b as S,c as O,d as I,f as q,g as N,h as j,i as E,j as P,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 K,w as G,x as z,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{Client as ie}from"undici";import se from"clipboardy";import le from"node:process";import{serve as ue}from"srvx";import ce from"tiny-invariant";import{execSync as pe}from"node:child_process";import{Hono as de}from"hono";import{cors as me}from"hono/cors";import{streamSSE as fe}from"hono/streaming";import{events as _e}from"fetch-event-stream";import{Tokenizer as ge,models as he}from"ai-tokenizer";import*as ye from"ai-tokenizer/encoding/claude";const ke=async()=>{let e=`${E}/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 be=e=>new Promise(t=>{setTimeout(t,e)}),we=e=>null==e;async function xe(){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)}})()}let ve,Te,Ae,$e=!1;const Se=async()=>{let{token:e,refresh_in:n}=await ke();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(!$e)return $e=!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 ke();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 z(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 z(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(),$e=!1}});Z.debug("Refresh already in progress, skipping")};ve=setInterval(()=>{o(5,1e3,"scheduled").catch(e=>{Z.error("Unexpected error in scheduled token refresh:",e)})},1e3*(n-60)),F.start(),Te=()=>{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)})},Ae=()=>{Z.debug("Network connectivity lost")},F.on("online",Te),F.on("offline",Ae)};async function Oe(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 Ie();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}" in ${n.verification_uri}`);let o=await async function(e){let t=1e3*(e.interval+1);for(Z.debug(`Polling access token with interval of ${t}ms`);;){let n=new AbortController,o=v.timeoutMs,r=setTimeout(()=>{n.abort()},o);try{let o=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:n.signal});if(!o.ok){await be(t),Z.error("Failed to poll access token:",await o.text());continue}let r=await o.json();Z.debug("Polling access token response:",r);let{access_token:a}=r;if(a)return a;await be(t)}catch(e){if(e instanceof Error&&"AbortError"===e.name){Z.error("Access token polling timed out"),await be(t);continue}throw e}finally{clearTimeout(r)}}}(n);await(e=>ee.writeFile(x.GITHUB_TOKEN_PATH,e))(o),v._t2=o,v.showToken&&Z.info("Auth token:",o),await Ie()}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 Ie(){let e=await L();Z.debug(`Authenticated as ${e.login}`)}const qe=Q({meta:{name:"auth",description:"Run authentication flow"},args:{verbose:{alias:"v",type:"boolean",default:!1,description:"Enable verbose logging"},"show-token":{type:"boolean",default:!1,description:"Show token on auth"}},run:({args:e})=>async function(e){e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),v.showToken=e.showToken,await T(),await Oe({force:!0}),Z.success("Auth token written to",x.GITHUB_TOKEN_PATH)}({verbose:e.verbose,showToken:e["show-token"]})}),Ne=async()=>{let e=`${E}/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)}},je=Q({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await T(),await Oe();try{let e=await Ne(),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 Ee(){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 Pe(){let e=typeof Bun<"u";return{name:e?"bun":"node",version:e?Bun.version:process.version.slice(1),platform:te.platform(),arch:te.arch()}}async function Ce(){try{return!!(await ee.stat(x.GITHUB_TOKEN_PATH)).isFile()&&(await ee.readFile(x.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function Re(e){let t=await async function(){let[e,t]=await Promise.all([Ee(),Ce()]);return{version:e,runtime:Pe(),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 Be=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})=>Re({json:e.json})}),De="copilot-api-node20",Me=`https://registry.npmjs.org/${De}/latest`,Fe=e=>`[1m${e}[0m`,He=e=>`[33m${e}[0m`;async function Je(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);try{let t=await fetch(Me,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function Ue(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 Le=new Map,We=new Map,Ke=new Set;let Ge,ze,Ye;function Ve(e){return!e.closed&&!e.destroyed}function Qe(e){Z.debug(`Creating HTTP/2 client for ${e}`);let t=new ie(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return Le.set(t,Date.now()),G.add(1,{event:"created",origin:e}),z(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),G.add(1,{event:"goaway",origin:e}),z(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}),We.delete(t),Ke.delete(t),Le.delete(t),Ve(t)&&t.close().catch(e=>{Z.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function Xe(e){if(!v.connectivity.h2)return;Ge&&Ge!==e&&function(){for(let e of[...We.keys(),...Ke])Ve(e)&&e.close().catch(e=>{Z.debug("Error closing HTTP/2 pool entry:",e)});We.clear(),Ke.clear(),Le.clear()}(),Ge=e;let t=Date.now();for(let[n]of We)if(t-(Le.get(n)??0)>=6e5)We.delete(n),Le.delete(n),Ve(n)&&n.close().catch(e=>{Z.debug("Error closing rotated HTTP/2 client:",e)}),G.add(1,{event:"rotated",origin:e}),z(j.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(Ve(n))return We.delete(n),Ke.add(n),n;We.delete(n),Le.delete(n)}let n=Qe(e);return Ke.add(n),n}function Ze(e){e&&Ke.delete(e)&&(Ve(e)?We.set(e,Date.now()):Le.delete(e))}function et(){Ye||(Ye=setInterval(()=>{!function(){let e=Date.now(),t=v.connectivity.h2Keepalive,n=We.size;for(let[o,r]of We)e-r<6e4||t&&n<=1||(We.delete(o),Le.delete(o),n--,Ve(o)&&o.close().catch(e=>{Z.debug("Error closing idle HTTP/2 client:",e)}),G.add(1,{event:"idle_reaped",origin:Ge??""}),z(j.INFO,"INFO",`HTTP/2 idle connection reaped for ${Ge}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":Ge??""}))}()},3e4),Ye.unref())}function tt(){ze||(Z.debug("Starting HTTP/2 keepalive (every 45s)"),ze=setInterval(()=>{(async function(){if(0===We.size&&0===Ke.size){if(Ge){let e=Qe(Ge);We.set(e,Date.now())}return}let e=[...We.keys()];await Promise.allSettled(e.map(async e=>{if(!Ve(e))return We.delete(e),void Le.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}`),We.set(e,Date.now())}catch(t){y.add(1,{result:"error"}),Z.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),G.add(1,{event:"error",origin:Ge??""}),We.delete(e),Le.delete(e),Ve(e)&&e.close().catch(e=>{Z.debug("Error closing broken HTTP/2 client:",e)})}}))})().catch(e=>{Z.debug("Unexpected error in HTTP/2 keepalive:",e)})},45e3),ze.unref(),et())}function nt(e,t=""){let n,o=function(){let{platform:e,ppid:t,env:n}=le;if("win32"===e){try{if(pe(`wmic process get ParentProcessId,Name | findstr "${t}"`,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}{let e=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 ot=e=>`[1m${e}[0m`,rt=e=>`[2m${e}[0m`,at=e=>`[36m${e}[0m`,it=e=>`[32m${e}[0m`,st=e=>`[33m${e}[0m`,lt=e=>`[4m${e}[0m`,ut=(e,t)=>`]8;;${e}\\${t}]8;;\\`,ct="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",pt=rt(" ─────────────────────────────────────────────────────────────");function dt(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const mt=[{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 ft(e){if(0===e.length)return[];let t=["",pt,` ${ot("BARAZANY.DEV")} ${rt("— Recent Posts")}`,pt,""];for(let[n,o]of e.entries()){let e=ut(`${o.url}${ct}`,ot(lt(`[${n+1}]`)));t.push(` ${e} ${at(o.title)}`,` ${rt("→")} ${rt(o.teaser)}`,"")}return t.push(pt,` ${ut(`https://barazany.dev/blog${ct}`,"barazany.dev/blog")}`,pt),t}function _t(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 ${it("✓")}`:rt("off"),o=["",` ${ot("COPILOT-API")} ${rt(`v${e.version}`)}`,pt,` ${rt("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${rt("User")} ${e.user} ${rt("·")} ${e.accountType}`];return v._v1&&o.push(` ${rt("Client")} VSCode ${v._v1}`),o.push(` ${rt("Network")} ${t.join(rt(" · "))}`,` ${rt("Search")} ${n}`),e.clipboardCopied&&o.push(` ${rt("Clipboard")} Claude Code command ${it("✓")}`),o.push(pt),o}function gt(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${ot("Active")}`];if(e.model){let n=v.models?.data.find(t=>t.id===e.model),o=dt(n?.capabilities.limits?.max_context_window_tokens);t.push(` ${at(e.model.padEnd(32))} ${rt("ctx")} ${ot(o.padStart(5))} ${st("← main")}`)}if(e.smallModel){let n=v.models?.data.find(t=>t.id===e.smallModel),o=dt(n?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${rt("ctx")} ${o.padStart(5)} ${st("← small")}`)}return t}function ht(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("",` ${ot(n)}`);for(let n of o){let o=n.id===e.model||n.id===e.smallModel,r=o?at("●"):rt("·"),a=o?at(n.id.padEnd(34)):n.id.padEnd(34),i=n.ctx?dt(n.ctx).padStart(5):"";t.push(` ${r} ${a} ${rt(i)}`)}}return t}function yt(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 kt(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&&(P.add(e.outputTokens,t),d.record(e.outputTokens,t)),e.cachedTokens&&K.add(e.cachedTokens,{model:_})}!g&&p?.tokenUsage&&H.executeCompletion(u)}(e)}const bt=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),A.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()}}),wt=3e-6,xt=15e-6;function vt(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*wt+n*xt,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function Tt(e,t){void 0!==t.prompt_tokens&&e.setAttribute("copilot_api.input_tokens",t.prompt_tokens),void 0!==t.completion_tokens&&e.setAttribute("copilot_api.output_tokens",t.completion_tokens),void 0!==t.total_tokens&&e.setAttribute("copilot_api.total_tokens",t.total_tokens)}const At=[{pattern:/haiku/i,family:"haiku"},{pattern:/sonnet[.-]?4[.-]6/i,family:"sonnet-4.6"},{pattern:/(sonnet-4[.-]5|[.-]?3[.-]5[.-]?sonnet|[.-]?3[.-]7[.-]?sonnet)/i,family:"sonnet-4.5"},{pattern:/sonnet-4(?![.-]5|[.-]6|[.-]1)/i,family:"sonnet-4"},{pattern:/opus[.-]?4[.-]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"}],$t={haiku:"claude-haiku-4.5","sonnet-4.6":"claude-sonnet-4.6","sonnet-4.5":"claude-sonnet-4.5","sonnet-4":"claude-sonnet-4","opus-4.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 St(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 At)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=$t[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 Ot=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function It(t){if(!t||"string"!=typeof t)throw new Ot("Model name is required and must be a string");if(!v.models?.data)throw new Ot("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=St(t,n);if(!o)throw e.add(1,{requested_model:t}),new Ot(`Invalid model: '${t}'. Available services: ${n.join(", ")}`);return o}async function qt(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 be(i),e.lastRequestTimestamp=o,Z.info("Rate limit wait completed, proceeding with request")}finally{n.end()}})}function Nt(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 jt(e,t,n){return Math.min(Math.max(e,t),n)}function Et(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 Et(JSON.parse(r),t+1)}catch{return null}}function Pt(e,t){let n=e?.data.find(e=>e.id===t);if(!n)return null;let o=Nt(n.capabilities.supports.min_thinking_budget),r=Nt(n.capabilities.supports.max_thinking_budget);return!o||!r||r<=o?null:{bounds:{min:o,max:r-1},maxOutputTokens:Nt(n.capabilities.limits?.max_output_tokens)??void 0}}function Ct(e){let{config:t}=e,n=t.bounds.min,o=t.bounds.max,r=jt(Nt(e.requestedBudget)??n,n,o),a=Nt(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 Rt(e,t,n){if(we(e.thinking_budget))return e;if(!1===n?.enabled)return{...e,thinking_budget:void 0};let o=Pt(t,e.model);if(!o)return{...e,thinking_budget:void 0};let r=Ct({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 Bt(e){return"invalid_thinking_budget"===Et(e)}async function Dt(e){let{payload:t,error:n,models:o,errorBodyText:r}=e;if(we(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(!Bt(i))return null;let l=Pt(o,t.model);return l?function(e,t){let n=Ct({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=Nt(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 Mt(e){if(!(e instanceof Error))return!1;let t=e.code;return(!t||"UND_ERR_SOCKET"===t)&&/GOAWAY/i.test(e.message)}async function Ft(){return new Promise(e=>setTimeout(e,100))}function Ht(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=>Ht(e));if(e&&"object"==typeof e){let t={};for(let[n,o]of Object.entries(e))t[n]=Ht(o);return"object"===t.type&&!("properties"in t)&&(t.properties={}),t}return e}const Jt=async e=>{let t=Ht(e);try{return await Ut(t)}catch(e){let n;if(e instanceof D)try{n=await e.response.clone().text()}catch{n=void 0}let o=await Dt({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 Ut(Ht(o));throw e}},Ut=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=Xe(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:_e(m),span:d,release:()=>Ze(n)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&Tt(d,f.usage),d.end(),Ze(n),f}catch(e){if(Ze(n),Mt(e)&&t<1){Z.warn(`HTTP/2 GOAWAY during chat completions, retrying (attempt ${t+1})`),await Ft();continue}throw e}finally{clearTimeout(c)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function Lt(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=It(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 Wt(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 Kt=e=>Object.hasOwn(e,"choices"),Gt=new de;Gt.post("/",async e=>{try{return await async function(e){await qt(v);let t=await e.req.json();Z.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=Lt(t)}catch(t){if(t instanceof Ot)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 bt(),we(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=Rt(t,v.models,{enabled:v.thinkingEnabled}),we(t.thinking_budget)||Z.debug("Normalized thinking_budget to:",JSON.stringify(t.thinking_budget));let n=performance.now(),o=await Jt(t),r=performance.now()-n;if(S.record(r,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),Kt(o)){let t=e.get("requestData")||{};return o.usage&&(t.tokenUsage=vt(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 fe(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=Wt(i,t=>{o.value=t;let n=e.get("requestData")||{};n.tokenUsage=vt(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=vt(o.value),t._d1=r,e.set("requestData",t))}}finally{o.value&&Tt(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 zt=new de;zt.post("/",async e=>{try{let t=await e.req.json();try{It(t.model)}catch(t){if(t instanceof Ot)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=vt(o.usage),a._d1=r,e.set("requestData",a),e.json(o)}catch(t){return await J(e,t)}});const Yt=new ge(ye),Vt={...he["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function Qt(e){return Yt.encode(e).length}function Xt(e){let t=0;for(let n of e)switch(n.type){case"text":t+=Qt(n.text)*Vt.contentMultiplier;break;case"tool_use":t+=Qt(n.name+JSON.stringify(n.input))*Vt.contentMultiplier;break;case"tool_result":n.content&&(t+=Qt("string"==typeof n.content?n.content:JSON.stringify(n.content))*Vt.contentMultiplier);break;case"thinking":t+=Qt(n.thinking)*Vt.contentMultiplier;break;case"image":t+=1600}return t}function Zt(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?Vt.perFirstProp:Vt.perAdditionalProp,t+=Qt(n),r.description&&(t+=Vt.perPropDesc+Qt(r.description)),r.enum&&Array.isArray(r.enum)){t+=Vt.perEnum;for(let e of r.enum)t+=Qt(String(e))}if("object"===r.type&&r.properties&&(t+=Vt.perNestedObject,t+=Zt(r)),"array"===r.type&&r.items){let e=r.items;"object"===e.type&&e.properties&&(t+=Vt.perArrayOfObjects,t+=Zt(e))}}return t}const en=async e=>{if(!v._t1)throw Error("Service token not found");let t=Ht(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=Xe(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:_e(m),span:d,release:()=>Ze(l)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&Tt(d,{prompt_tokens:f.usage.input_tokens,completion_tokens:f.usage.output_tokens,total_tokens:f.usage.total_tokens}),d.end(),Ze(l),f}catch(t){if(Ze(l),Mt(t)&&e<1){Z.warn(`HTTP/2 GOAWAY during responses, retrying (attempt ${e+1})`),await Ft();continue}throw t}finally{clearTimeout(c)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function tn(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function nn(e,t){let n={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:un(e.tools),tool_choice:cn(e.tool_choice)},o=e.thinking;if("enabled"===o?.type||"adaptive"===o?.type){let r=Pt(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=Nt(t),a=r&&r>1?r-1:n.min;return jt(Math.min(o,a),n.min,n.max)}(e.output_config?.effort??"high",n.max_tokens,r.bounds);n=Rt({...n,thinking_budget:a},t)}}return n}function on(e,t){let n=function(e){return e?"string"==typeof e?[{role:"system",content:rn(e)}]:[{role:"system",content:rn(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:ln(e.content)});o.length>0&&t.push({role:"user",content:ln(o)})}else t.push({role:"user",content:ln(e.content)});return t}(e):function(e){let t=function(e){return{reasoning_text:sn(e.reasoning_text),reasoning_opaque:sn(e.reasoning_opaque)}}(e);if(!Array.isArray(e.content))return[{role:"assistant",content:ln(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:ln(e.content),...t}]}(e));return[...n,...o]}function rn(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}const an=32768;function sn(e){if("string"==typeof e)return e.length<=an?e:e.slice(0,an)}function ln(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 un(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function cn(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 pn(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:gn(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:_n(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 _n(e){switch(e){case"low":return"low";case"medium":return"medium";case"max":return"xhigh";default:return"high"}}function gn(e){let t=[];for(let n of e)"user"===n.role?t.push(...hn(n)):t.push(...kn(n));return t}function hn(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(yn(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 yn(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 kn(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 bn(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 wn(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function xn(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 vn(e,t){let n=[];switch(e.type){case"response.created":xn(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){xn(t,n),wn(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":xn(t,n),wn(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":wn(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":{wn(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:bn(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":{xn(t,n),wn(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":xn(t,n),wn(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":xn(t,n),wn(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":xn(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 Tn(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 An(e,t){e.thinkingBlockOpen&&(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.thinkingBlockOpen=!1,e.contentBlockOpen=!1)}function $n(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&&(Tn(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&&(Tn(t,n),n.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"signature_delta",signature:r.reasoning_opaque}}),An(t,n)),r.content&&(An(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){An(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&&(An(t,n),t.contentBlockOpen&&=(n.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),n.push({type:"message_delta",delta:{stop_reason:tn(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 Sn(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 On(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function In(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 Sn(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_${On()}`,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_${On()}`,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_${On()}`,a=`msg_tavily_${On()}`,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 fe(e,async e=>{for(let t of i)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}function qn(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 Nn(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 In(e,t);await qt(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=It(t.model);n.setAttribute("copilot_api.model.normalized",o);let r=qn(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 Ot)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),fn(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 bt();let r=performance.now(),a=await en(o),s=performance.now()-r;if(S.record(s,{model:o.model,target:"responses",streaming:String(!!o.stream)}),Pn(a)){let t=e.get("requestData")||{};if(a.usage&&(t.tokenUsage=vt({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:bn(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 fe(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=jn(l);if(u){n=u;let t=e.get("requestData")||{};t.tokenUsage=vt(n),t._d1=s,e.set("requestData",t)}let c=vn(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&&Tt(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),nn(t,v.models)}finally{e.end()}});c.record(performance.now()-a,{direction:"anthropic_to_openai"}),s=Rt(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 bt();let u=await Jt(s),p=performance.now()-l;if(S.record(p,{model:s.model,target:"chat_completions",streaming:String(!!s.stream)}),En(u)){let t=e.get("requestData")||{};u.usage&&(t.tokenUsage=vt(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=dn(a.message),i=pn(a.message.content),s=mn(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:tn(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 fe(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=vt(n),t._d1=p,e.set("requestData",t)}let l=$n(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=vt(n),t._d1=p,e.set("requestData",t))}}finally{n&&Tt(m,n),m.end(),f()}let i=e.get("requestId");i&&H.executeCompletion(i)}finally{e.get("resolveStreamComplete")?.()}})}function jn(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 En=e=>Object.hasOwn(e,"choices"),Pn=e=>Object.hasOwn(e,"output");const Cn=new de;Cn.post("/",async e=>{try{return await Nn(e)}catch(t){return await J(e,t)}});const Rn=new de;function Bn(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let n=It(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 Dn(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=vt(n),o._d1=t._d1,t.c.set("requestData",o)}Rn.get("/",async e=>{try{v.models||await xe();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 Mn=new Set(["message","function_call","function_call_output"]),Fn=new Set(["type","name","description","parameters"]);async function Hn(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 Sn(v.tavilyApiKey,n,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function Jn(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 Hn(e.action))return JSON.stringify(t)}}catch(e){Z.error("Failed to enrich web search:",e)}return e}function Un(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 Ln(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&&Un(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)Un(e,t)&&(r=!0);if(r)return JSON.stringify(n)}}catch{}return e}function Wn(e){return null!=e}function Kn(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 Mn.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"])Wn(e[t])&&(o[t]=e[t]);let r=new Set;if(Wn(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))Fn.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(Wn(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;o.reasoning={},Wn(t.effort)&&(o.reasoning.effort=t.effort),Wn(t.summary)&&(o.reasoning.summary=t.summary)}if(Wn(e.text)&&"object"==typeof e.text){let t=e.text;Wn(t.format)&&(o.text={format:t.format})}return{payload:o,customToolNames:r}}async function Gn(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 Hn(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=vt({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 zn=e=>Object.hasOwn(e,"output"),Yn=new de;Yn.post("/",async e=>{try{return await async function(e){await qt(v);let{payload:t,customToolNames:n}=Kn(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=Bn(o)}catch(t){if(t instanceof Ot)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 bt();let r=performance.now(),a=await en(o),i=performance.now()-r;if(S.record(i,{model:o.model,target:"responses",streaming:String(!!o.stream)}),zn(a))return Gn(e,a,i);let{events:s,span:l,release:u}=a;return fe(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=Ln(l.data,n);s=await Jn(s);let u=s===l.data?l:{...l,data:s};g.add(1,{model:o.model,endpoint_type:"responses"}),Dn(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&&Tt(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 Vn=new de;Vn.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 Qn=new de;Qn.get("/",async e=>{try{let t=await Ne();return e.json(t)}catch(t){return Z.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const Xn=new de;Xn.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(()=>kt(m)).catch(e=>{Z.debug("Error finalizing streaming request:",e),l.end()}):kt(m)}),Xn.use(me()),Xn.get("/",e=>e.text("Server running")),Xn.route("/chat/completions",Gt),Xn.route("/models",Rn),Xn.route("/embeddings",zt),Xn.route("/usage",Qn),Xn.route("/token",Vn),Xn.route("/v1/chat/completions",Gt),Xn.route("/v1/models",Rn),Xn.route("/v1/embeddings",zt),Xn.route("/v1/messages",Cn),Xn.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=Vt.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");n+=Vt.perMessage+Qt(e)*Vt.contentMultiplier}for(let e of t.messages)n+=Vt.perMessage,n+=Qt(e.role),"string"==typeof e.content?n+=Qt(e.content)*Vt.contentMultiplier:Array.isArray(e.content)&&(n+=Xt(e.content));return t.tools&&t.tools.length>0&&(n+=function(e){let t=Vt.toolsExist;for(let[n,o]of e.entries())n>0&&(t+=Vt.perTool),t+=Qt(o.name),o.description&&(t+=Vt.perDesc+Qt(o.description)),t+=Zt(o.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(n)})}),Xn.route("/v1/responses",Yn),Xn.route("/responses",Yn);const Zn=[],eo=Date.now();let to="";function no(){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()-eo)/1e3}});for(let t of Zn)try{await t()}catch(e){Z.error("Error during cleanup:",e)}n.end(),function(e,t){let n=ut("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),o=["",pt,` ${ot("COPILOT-API")} ${rt(`v${e}`)} ${rt("·")} ${yt(t)} uptime`,pt,""," Check in from time to time on",` ${at(n)}`,"",pt,""];console.log(o.join("\n"))}(to,Date.now()-eo),le.exit(t)};le.on("SIGINT",()=>e("SIGINT")),le.on("SIGTERM",()=>e("SIGTERM")),le.on("uncaughtException",t=>{Z.error("Uncaught exception:",t),e("uncaughtException",1)}),le.on("unhandledRejection",(t,n)=>{Z.error("Unhandled promise rejection at:",n,"reason:",t),e("unhandledRejection",1)})}function oo(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()-eo},"copilot_api")});if(v.models?.data)for(let e of v.models.data)s.addEvent("copilot_api.model.available",n(e,"model"));s.end(),z(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()-eo},"copilot_api"))}async function ro(e){no(),Zn.push(()=>{Z.debug("Cleaning up connectivity monitor"),F.stop()},()=>{Z.debug("Cleaning up token management"),Z.debug("Cleaning up token management"),ve&&=void clearInterval(ve),Te&&=void F.off("online",Te),Ae&&=void F.off("offline",Ae)},async()=>{Z.debug("Cleaning up HTTP/2 client"),await async function(){Z.debug("Stopping HTTP/2 pool"),ze&&=void clearInterval(ze),Ye&&=void clearInterval(Ye);let e=[...We.keys(),...Ke];We.clear(),Ke.clear(),Le.clear(),Ge=void 0;for(let t of e)Ve(t)&&(G.add(1,{event:"closed"}),await t.close())}()},async()=>{Z.debug("Shutting down OTel SDK"),await p()}),e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),e._cc1&&e.codex&&(Z.error("Cannot use --claude-code and --codex together"),le.exit(1)),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"===le.env.COPILOT_H2_KEEPALIVE||"true"===le.env.COPILOT_H2_KEEPALIVE,t=e||"1"===le.env.COPILOT_H2||"true"===le.env.COPILOT_H2;v.connectivity.h2=t,v.connectivity.h2Keepalive=e}(),await T(),v._v1="1.116.0-insider";let t=await Ee();to=t;let n,o=Pe();r(t,eo),e._t2?(v._t2=e._t2,Z.info("Using provided Auth token")):await Oe();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"),le.exit(1)}await Se(),await xe();let a=function(e=18e5){let t=setInterval(()=>{xe().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)}}();Zn.push(()=>{Z.debug("Cleaning up model refresh interval"),a()}),v.connectivity.h2&&(Ze(Xe(O(v))),v.connectivity.h2Keepalive&&tt()),oo({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(ce(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")}`),le.exit(1)),t.includes(e.smallModel)||(Z.error(`Invalid small model: ${e.smallModel}`),Z.info(`Available services: \n${t.join("\n")}`),le.exit(1)),n=e.model,o=e.smallModel}else e.model||e.smallModel?(Z.error("Both --model and --small-model must be specified for model selection"),le.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=nt({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:n,ANTHROPIC_SMALL_FAST_MODEL:o},"claude");try{return se.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(ce(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")}`),le.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=nt({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy"},`codex --model ${n}`);try{return se.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=[..._t(e),...gt(e),...ht(e),"",...ft(mt),""];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}),ue({fetch:Xn.fetch,port:e.port,bun:{idleTimeout:255}})}const ao=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 ro({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"]||le.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([Ee(),Je()]);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 ${De}@latest`,o=He("│"),r=` ${Fe("Update available!")} ${(e=>`[2m${e}[0m`)(e)} → ${(e=>`[32m${e}[0m`)(t)}`,a=` Run ${Fe(n)} to update`,i=" ".repeat(54),s=He(`╭${"─".repeat(54)}╮`),l=He(`╰${"─".repeat(54)}╯`),u=["",s,`${o}${i}${o}`,`${o}${Ue(r,54)}${o}`,`${o}${i}${o}`,`${o}${Ue(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:qe,start:ao,"check-usage":je,debug:Be}}));export{};
|
|
2
|
+
import{A as e,B as t,C as o,D as n,E as a,F as r,G as i,H as s,I as l,J as c,K as u,L as p,M as d,N as m,O as f,P as g,R as h,S as _,T as y,U as k,V as w,W as b,X as v,Y as $,Z as x,_ as T,a as A,b as S,c as O,d as I,f as P,g as C,h as N,i as E,j,k as q,l as R,m as D,n as B,o as M,p as F,q as H,r as L,s as U,t as J,u as K,v as G,w as W,x as z,y as Y,z as V}from"./get-user-CEqqH34r.mjs";import{defineCommand as X,runMain as Q}from"citty";import Z from"consola";import ee from"node:fs/promises";import te from"node:os";import oe from"node:path";import{SpanKind as ne,SpanStatusCode as ae,context as re,trace as ie}from"@opentelemetry/api";import se from"clipboardy";import{execFile as le,execSync as ce}from"node:child_process";import ue from"node:process";import{Client as pe}from"undici";import{promisify as de}from"node:util";import{accessSync as me}from"node:fs";import{serve as fe}from"srvx";import ge from"tiny-invariant";import{isIP as he}from"node:net";import{generate as _e}from"selfsigned";import{Hono as ye}from"hono";import{cors as ke}from"hono/cors";import{streamSSE as we}from"hono/streaming";import{events as be}from"fetch-event-stream";import{Tokenizer as ve,models as $e}from"ai-tokenizer";import*as xe from"ai-tokenizer/encoding/claude";const Te=async()=>{let e=`${E}/copilot_internal/v2/token`,t=$.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await k({spanName:"github GET /copilot_internal/v2/token",url:e,target:"copilot_token",headers:K($),signal:o.signal});if(!t.ok)throw n.end(),new B("Failed to get Service token",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}};const Ae=e=>new Promise(t=>{setTimeout(t,e)}),Se=e=>null==e;async function Oe(){$.models=await(async()=>{let e=`${O($)}/models`,t=R($),o=$.timeoutMs,n=new AbortController,a=setTimeout(()=>n.abort(),o);try{let{response:o,span:a}=await k({spanName:"copilot GET /models",url:e,target:"models",headers:t,signal:n.signal});if(!o.ok)throw a.end(),new B("Failed to get models",o);let r=await o.json();return a.setAttribute("copilot_api.models_count",r.data.length),a.end(),r}finally{clearTimeout(a)}})()}var Ie=class extends Error{constructor(e){super(e),this.name="AuthorizationError"}};let Pe,Ce,Ne,Ee=!1;const je=async()=>{let{token:e,refresh_in:o}=await Te();$._t1=e,Z.debug("Service token fetched successfully!"),$.showToken&&Z.info("Service token:",e);let n=async(e=5,o=1e3,n="scheduled")=>{if(!Ee)return Ee=!0,i.startActiveSpan("copilot_api.token.refresh",async a=>{let r=performance.now();a.setAttribute("copilot_api.token_refresh.reason",n),a.setAttribute("copilot_api.token_refresh.max_retries",e);try{for(let i=1;i<=e;i++)try{a.setAttribute("copilot_api.token_refresh.attempt",i),Z.debug(`Refreshing Service token (${n}, attempt ${i}/${e})`);let{token:o}=await Te();return $._t1=o,Z.debug("Service token refreshed successfully"),$.showToken&&Z.info("Refreshed Service token:",o),a.setAttribute("copilot_api.token_refresh.success",!0),t.add(1,{reason:n,success:"true"}),w.record(performance.now()-r,{reason:n}),void z(N.INFO,"INFO",`Token refreshed successfully (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempt":i})}catch(l){let c=i===e;if(Z.error(`Failed to refresh Service token (attempt ${i}/${e}):`,l),t.add(1,{reason:n,success:"false"}),c){Z.error("All refresh attempts failed. May be unavailable until next scheduled refresh.");let t=l instanceof Error?l:Error(String(l));return a.setAttribute("copilot_api.token_refresh.success",!1),a.setStatus({code:ae.ERROR,message:t.message}),a.recordException(t),s.add(1,{reason:n}),w.record(performance.now()-r,{reason:n}),void z(N.ERROR,"ERROR",`Token refresh failed after ${e} attempts (${n})`,{"copilot_api.token_refresh.reason":n,"copilot_api.token_refresh.attempts":e})}let u=o*2**(i-1);Z.debug(`Retrying token refresh in ${u}ms...`),await new Promise(e=>setTimeout(e,u))}}finally{a.end(),Ee=!1}});Z.debug("Refresh already in progress, skipping")};Pe=setInterval(()=>{n(5,1e3,"scheduled").catch(e=>{Z.error("Unexpected error in scheduled token refresh:",e)})},1e3*(o-60)),F.start(),Ce=()=>{Z.debug("Network connectivity restored, attempting immediate token refresh"),n(3,500,"network-restored").catch(e=>{Z.error("Unexpected error in network-restored token refresh:",e)})},Ne=()=>{Z.debug("Network connectivity lost")},F.on("online",Ce),F.on("offline",Ne)};async function qe(e){try{let t=await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8");if(t&&!e?.force)return $._t2=t,$.showToken&&Z.info("Auth token:",t),void await Re();Z.info("Authentication required");let o=await async function(){let e=new AbortController,t=$.timeoutMs,o=setTimeout(()=>{e.abort()},t);try{let t=await fetch(`${M}/login/device/code`,{method:"POST",headers:P(),body:JSON.stringify({client_id:U,scope:A}),signal:e.signal});if(!t.ok)throw new B("Failed to get device code",t);return await t.json()}finally{clearTimeout(o)}}();Z.debug("Device code response:",o),Z.info(`Please enter the code "${o.user_code}" at ${o.verification_uri}`);try{se.writeSync(o.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,o=ue.platform;t="darwin"===o?"open":"win32"===o?"start":"xdg-open",le(t,[e],()=>{})}catch{}}(o.verification_uri);let n=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 o=Date.now(),n=1e3*e.expires_in;for(;;){if(Date.now()-o>=n)throw new Ie("Authorization timed out — the code expired. Please run the command again.");let a=new AbortController,r=$.timeoutMs,i=setTimeout(()=>{a.abort()},r);try{let o=await fetch(`${M}/login/oauth/access_token`,{method:"POST",headers:P(),body:JSON.stringify({client_id:U,device_code:e.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"}),signal:a.signal});if(!o.ok){await Ae(t),Z.error("Failed to poll access token:",await o.text());continue}let n=await o.json();if(Z.debug("Polling access token response:",n),n.error){if("expired_token"===n.error)throw new Ie("Authorization timed out — the code expired. Please run the command again.");if("access_denied"===n.error)throw new Ie("Authorization was denied. Please run the command again and approve the request.");"authorization_pending"!==n.error&&"slow_down"!==n.error&&Z.warn(`Unexpected auth error: ${n.error}`),await Ae(t);continue}if(n.access_token)return n.access_token;await Ae(t)}catch(e){if(e instanceof Ie)throw e;if(e instanceof Error&&"AbortError"===e.name){Z.error("Access token polling timed out"),await Ae(t);continue}throw e}finally{clearTimeout(i)}}}(o);await(e=>ee.writeFile(v.GITHUB_TOKEN_PATH,e))(n),$._t2=n,$.showToken&&Z.info("Auth token:",n),await Re()}catch(e){throw e instanceof B?(Z.error("Failed to get Auth token:",await e.response.json()),e):(Z.error("Failed to get Auth token:",e),e)}}async function Re(){let e=await J();Z.success(`Authenticated as ${e.login}`)}async function De(e){e.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),$.showToken=e.showToken,await x(),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 Be=X({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})=>De({verbose:e.verbose,showToken:e["show-token"]})}),Me=async()=>{let e=`${E}/copilot_internal/user`,t=$.timeoutMs,o=new AbortController,n=setTimeout(()=>o.abort(),t);try{let{response:t,span:n}=await k({spanName:"github GET /copilot_internal/user",url:e,target:"usage",headers:K($),signal:o.signal});if(!t.ok)throw n.end(),new B("Failed to get usage",t);let a=await t.json();return n.end(),a}finally{clearTimeout(n)}},Fe=X({meta:{name:"check-usage",description:"Show current usage/quota information"},async run(){await x(),await qe();try{let e=await Me(),t=e.quota_snapshots.premium_interactions,o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;function i(e,t){if(!t)return`${e}: N/A`;let o=t.entitlement,n=o-t.remaining,a=o>0?n/o*100:0,r=t.percent_remaining;return`${e}: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`}let s=`Premium: ${n}/${o} used (${a.toFixed(1)}% used, ${r.toFixed(1)}% remaining)`,l=i("Chat",e.quota_snapshots.chat),c=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 ${c}`)}catch(u){Z.error("Failed to fetch usage:",u),process.exit(1)}}}),He=de(le);async function Le(){let e="win32"===ue.platform?"where.exe":"which";try{return await He(e,["tailscale"]),!0}catch{return!1}}async function Ue(){try{let{stdout:e}=await He("tailscale",["status","--self","--json"]);return JSON.parse(e).Self}catch{return}}function Je(e){return e.replace(/\.$/,"")}async function Ke(){let e=await Ue();if(e?.Online)return Je(e.DNSName)}const Ge=de(le),We=e=>`[1m${e}[0m`,ze=e=>`[2m${e}[0m`,Ye=e=>`[36m${e}[0m`,Ve=e=>`[32m${e}[0m`,Xe=e=>`[31m${e}[0m`,Qe=e=>`[33m${e}[0m`,Ze=ze(" ─────────────────────────────────────────────────────────────"),et=oe.join(v.APP_DIR,"certs","tailscale"),tt=oe.join(et,"cert.pem"),ot=oe.join(et,"key.pem"),nt={certDir:et,certPath:tt,keyPath:ot};function at(){switch(ue.platform){case"darwin":return[` ${ze("Install Tailscale for macOS:")}`,` ${Ye("https://tailscale.com/download/mac")}`,` ${ze("(Use the Mac App Store or .pkg download — not brew)")}`,"",` ${ze("After installing, open the Tailscale app and sign in.")}`,` ${ze("Then re-run this command.")}`].join("\n");case"linux":return[` ${ze("Install Tailscale for Linux:")}`,` ${Ye("curl -fsSL https://tailscale.com/install.sh | sh")}`,` ${Ye("sudo tailscale up")}`,` ${ze("or")} ${Ye("https://tailscale.com/download/linux")}`].join("\n");case"win32":return[` ${ze("Install Tailscale for Windows:")}`,` ${Ye("https://tailscale.com/download/windows")}`,"",` ${ze("After installing, open the Tailscale app and sign in.")}`].join("\n");default:return` ${ze("Install Tailscale:")} ${Ye("https://tailscale.com/download")}`}}function rt(){let e=[` ${Xe("Tailscale is not running.")}`];return"darwin"===ue.platform?e.push(` ${ze("Open the Tailscale app from Applications and sign in.")}`,` ${ze("Download:")} ${Ye("https://tailscale.com/download/mac")}`):"win32"===ue.platform?e.push(` ${ze("Open the Tailscale app and sign in.")}`,` ${ze("Download:")} ${Ye("https://tailscale.com/download/windows")}`):e.push(` ${ze("Connect with:")} ${Ye("sudo tailscale up")}`),e.push("",` ${ze("Then re-run this command.")}`),e.join("\n")}async function it(){try{return await ee.access(tt),await ee.access(ot),!0}catch{return!1}}function st(e){console.log(""),console.log(Ze),console.log(` ${We("Claude Cowork Setup")} ${ze("— Diagnostic")}`),console.log(Ze),console.log("");for(let t of function(e){let t=[];for(let[o,n]of Object.entries(e)){let e;e="ok"===n.status?Ve("✅"):"missing"===n.status?Xe("❌"):Qe("❓");let a=n.detail?ze(` ${n.detail}`):"";t.push(` ${e} ${o}${a}`)}return t}(e))console.log(t);console.log("");let t=Object.values(e).filter(e=>"missing"===e.status);0===t.length?console.log(` ${Ve("All checks passed.")}`):console.log(` ${Xe(`${t.length} issue(s).`)} Run ${Ye("copilot-api cowork-setup install")} to fix.`),console.log("")}const lt={alias:"y",type:"boolean",default:!1,description:"Skip confirmation prompts (non-interactive mode)"},ct=X({meta:{name:"cowork-setup",description:"Set up Tailscale-based HTTPS for Claude Cowork to reach the proxy."},subCommands:{doctor:X({meta:{name:"doctor",description:"Diagnose Tailscale + cert status"},async run(){await async function(){let e={},t=await Le();if(e["tailscale-installed"]=t?{status:"ok"}:{status:"missing",detail:"tailscale not found in PATH"},!t)return st(e),console.log(""),console.log(at()),void console.log("");let o=await Ue();if(!o||!o.Online)return e["tailscale-running"]={status:"missing",detail:"not connected"},st(e),console.log(rt()),void console.log("");let n=Je(o.DNSName);e["tailscale-running"]={status:"ok",detail:n};let a=await it();e["tailscale-cert"]=a?{status:"ok",detail:tt}:{status:"missing",detail:'Run "copilot-api cowork-setup install" to generate'},a&&(e.ready={status:"ok",detail:`https://${n}:<port>`}),st(e)}(),ue.exit(0)}}),install:X({meta:{name:"install",description:"Generate a Tailscale TLS certificate for Cowork (interactive, or pass --yes)"},args:{yes:lt},async run({args:e}){await async function(e){if(console.log(""),console.log(Ze),console.log(` ${We("Claude Cowork Setup")} ${ze("— Install")}`),console.log(Ze),console.log(""),!await Le())return console.log(` ${Xe("Tailscale is not installed.")}`),console.log(""),console.log(at()),console.log(""),console.log(` ${ze("After installing, run")} ${Ye("tailscale up")} ${ze("to connect, then re-run this command.")}`),void console.log("");let t=await Ue();if(!t||!t.Online)return console.log(rt()),void console.log("");let o=Je(t.DNSName);if(console.log(` ${ze("Tailscale hostname:")} ${We(o)}`),console.log(""),console.log(` ${We("Generating TLS certificate via Tailscale…")}`),console.log(` ${ze("This requests a real Let's Encrypt cert for your Tailscale hostname.")}`),console.log(` ${Ye(`$ tailscale cert --cert-file ${tt} --key-file ${ot} ${o}`)}`),console.log(""),e||await Z.prompt("Generate the certificate?",{type:"confirm",initial:!0})){try{await ee.mkdir(et,{recursive:!0}),Z.start("Generating certificate (this may take a few seconds)…"),await Ge("tailscale",["cert","--cert-file",tt,"--key-file",ot,o]),console.log(` ${Ve("✓ Certificate generated")}`)}catch(e){let t=e instanceof Error?e.message:String(e);return void Z.error(`Failed to generate cert: ${t}`)}console.log(""),console.log(Ze),console.log(` ${We("Next steps")}`),console.log(Ze),console.log(""),console.log(` ${We("1.")} Start the proxy:`),console.log(` ${Ye("copilot-api start --claude-cowork")}`),console.log(""),console.log(` ${We("2.")} In Cowork ${ze("→")} Settings ${ze("→")} Inference Provider, set:`),console.log(` ${We("inferenceGatewayBaseUrl")} = ${Ye(`https://${o}:<port>`)}`),console.log(` ${ze("(replace <port> with the port you start the proxy on, default 4141)")}`),console.log(""),console.log(` ${We("3.")} Restart Cowork ${ze("(Cmd+Q and reopen)")}`),console.log(""),console.log(` ${ze("For Cowork's own configuration docs, see:")}`),console.log(` ${Ye("https://claude.com/docs/cowork/3p/installation")}`),console.log("")}else Z.info("Skipped.")}(e.yes),ue.exit(0)}}),revert:X({meta:{name:"revert",description:"Remove the generated Tailscale cert files"},args:{yes:lt},async run({args:e}){await async function(e){if(console.log(""),console.log(Ze),console.log(` ${We("Claude Cowork Setup")} ${ze("— Revert")}`),console.log(Ze),console.log(""),!await it())return console.log(` ${ze("No Tailscale cert found. Nothing to revert.")}`),void console.log("");if(console.log(` ${We("Remove Tailscale cert files:")}`),console.log(` ${ze(tt)}`),console.log(` ${ze(ot)}`),console.log(""),e||await Z.prompt("Delete these files?",{type:"confirm",initial:!0})){try{await ee.rm(et,{recursive:!0}),console.log(` ${Ve("✓ Cert files removed.")}`)}catch(e){let t=e instanceof Error?e.message:String(e);Z.warn(`Could not remove: ${t}`)}console.log(""),console.log(` ${ze("Don't forget to update Cowork's inferenceGatewayBaseUrl setting.")}`),console.log("")}else Z.info("Skipped.")}(e.yes),ue.exit(0)}})}});async function ut(){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 pt(){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 dt(){try{return!!(await ee.stat(v.GITHUB_TOKEN_PATH)).isFile()&&(await ee.readFile(v.GITHUB_TOKEN_PATH,"utf8")).trim().length>0}catch{return!1}}async function mt(e){let t=await async function(){let[e,t]=await Promise.all([ut(),dt()]);return{version:e,runtime:pt(),paths:{APP_DIR:v.APP_DIR,GITHUB_TOKEN_PATH:v.GITHUB_TOKEN_PATH},tokenExists:t}}();e.json?function(e){console.log(JSON.stringify(e,null,2))}(t):function(e){Z.info(`service debug\n\nVersion: ${e.version}\nRuntime: ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform} ${e.runtime.arch})\n\nPaths:\n- APP_DIR: ${e.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${e.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${e.tokenExists?"Yes":"No"}`)}(t)}const ft=X({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})=>mt({json:e.json})}),gt="copilot-api-node20",ht=`https://registry.npmjs.org/${gt}/latest`,_t=e=>`[1m${e}[0m`,yt=e=>`[33m${e}[0m`;async function kt(){let e=new AbortController,t=setTimeout(()=>e.abort(),5e3);"object"==typeof t&&"unref"in t&&t.unref();try{let t=await fetch(ht,{signal:e.signal});return t.ok?(await t.json()).version??null:null}catch{return null}finally{clearTimeout(t)}}function wt(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 bt=new Map,vt=new Map,$t=new Set;let xt,Tt,At;function St(e){return!e.closed&&!e.destroyed}function Ot(e){Z.debug(`Creating HTTP/2 client for ${e}`);let t=new pe(e,{allowH2:!0,pipelining:0,keepAliveTimeout:6e4,initialWindowSize:4194304,connectionWindowSize:16777216});return bt.set(t,Date.now()),W.add(1,{event:"created",origin:e}),z(N.INFO,"INFO",`HTTP/2 client created for ${e}`,{"copilot_api.h2.event":"created","copilot_api.h2.origin":e}),t.on("connect",()=>{Z.debug(`HTTP/2 client connected to ${e}`)}),t.on("error",t=>{Z.debug(`HTTP/2 client error for ${e}:`,t.message)}),t.on("disconnect",(o,n,a)=>{Z.debug(`HTTP/2 client disconnected from ${e}:`,a.message),W.add(1,{event:"goaway",origin:e}),z(N.WARN,"WARN",`HTTP/2 client disconnected from ${e}: ${a.message}`,{"copilot_api.h2.event":"goaway","copilot_api.h2.origin":e,"copilot_api.h2.error":a.message}),vt.delete(t),$t.delete(t),bt.delete(t),St(t)&&t.close().catch(e=>{Z.debug("Error closing GOAWAY'd HTTP/2 client:",e)})}),t}function It(e){if(!$.connectivity.h2)return;xt&&xt!==e&&function(){for(let e of[...vt.keys(),...$t])St(e)&&e.close().catch(e=>{Z.debug("Error closing HTTP/2 pool entry:",e)});vt.clear(),$t.clear(),bt.clear()}(),xt=e;let t=Date.now();for(let[o]of vt)if(t-(bt.get(o)??0)>=6e5)vt.delete(o),bt.delete(o),St(o)&&o.close().catch(e=>{Z.debug("Error closing rotated HTTP/2 client:",e)}),W.add(1,{event:"rotated",origin:e}),z(N.INFO,"INFO",`HTTP/2 client rotated for ${e} (max lifetime reached)`,{"copilot_api.h2.event":"rotated","copilot_api.h2.origin":e});else{if(St(o))return vt.delete(o),$t.add(o),o;vt.delete(o),bt.delete(o)}let o=Ot(e);return $t.add(o),o}function Pt(e){e&&$t.delete(e)&&(St(e)?vt.set(e,Date.now()):bt.delete(e))}function Ct(){At||(At=setInterval(()=>{!function(){let e=Date.now(),t=$.connectivity.h2Keepalive,o=vt.size;for(let[n,a]of vt)e-a<6e4||t&&o<=1||(vt.delete(n),bt.delete(n),o--,St(n)&&n.close().catch(e=>{Z.debug("Error closing idle HTTP/2 client:",e)}),W.add(1,{event:"idle_reaped",origin:xt??""}),z(N.INFO,"INFO",`HTTP/2 idle connection reaped for ${xt}`,{"copilot_api.h2.event":"idle_reaped","copilot_api.h2.origin":xt??""}))}()},3e4),At.unref())}function Nt(){Tt||(Z.debug("Starting HTTP/2 keepalive (every 45s)"),Tt=setInterval(()=>{(async function(){if(0===vt.size&&0===$t.size){if(xt){let e=Ot(xt);vt.set(e,Date.now())}return}let e=[...vt.keys()];await Promise.allSettled(e.map(async e=>{if(!St(e))return vt.delete(e),void bt.delete(e);try{let{statusCode:t,body:o}=await e.request({path:"/models",method:"GET",headers:R($)});await o.dump(),y.add(1,{result:"success"}),Z.debug(`HTTP/2 keepalive: GET /models → ${t}`),vt.set(e,Date.now())}catch(t){y.add(1,{result:"error"}),Z.warn("HTTP/2 keepalive failed:",t instanceof Error?t.message:t),W.add(1,{event:"error",origin:xt??""}),vt.delete(e),bt.delete(e),St(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),Tt.unref(),Ct())}function Et(e,t=""){let o,n=function(){let{platform:e,ppid:t,env:o}=ue;if("win32"===e){try{if(ce(`wmic process get ParentProcessId,Name | findstr "${t}"`,{stdio:"pipe"}).toString().toLowerCase().includes("powershell.exe"))return"powershell"}catch{return"cmd"}return"cmd"}{let e=o.SHELL;if(e){if(e.endsWith("zsh"))return"zsh";if(e.endsWith("fish"))return"fish";if(e.endsWith("bash"))return"bash"}return"sh"}}(),a=Object.entries(e).filter(([,e])=>void 0!==e);switch(n){case"powershell":o=a.map(([e,t])=>`$env:${e} = ${t}`).join("; ");break;case"cmd":o=a.map(([e,t])=>`set ${e}=${t}`).join(" & ");break;case"fish":o=a.map(([e,t])=>`set -gx ${e} ${t}`).join("; ");break;default:{let e=a.map(([e,t])=>`${e}=${t}`).join(" ");o=a.length>0?`export ${e}`:"";break}}return o&&t?`${o}${"cmd"===n?" & ":" && "}${t}`:o||t}const jt=e=>`[1m${e}[0m`,qt=e=>`[2m${e}[0m`,Rt=e=>`[36m${e}[0m`,Dt=e=>`[32m${e}[0m`,Bt=e=>`[33m${e}[0m`,Mt=e=>`[4m${e}[0m`,Ft=(e,t)=>`]8;;${e}\\${t}]8;;\\`,Ht="?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=startup_banner",Lt=qt(" ─────────────────────────────────────────────────────────────");function Ut(e){return void 0===e?"":e>=1e6?`${(e/1e6).toFixed(0)}M`:`${(e/1e3).toFixed(0)}K`}const Jt=[{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 Kt(e){if(0===e.length)return[];let t=["",Lt,` ${jt("BARAZANY.DEV")} ${qt("— Recent Posts")}`,Lt,""];for(let[o,n]of e.entries()){let e=Ft(`${n.url}${Ht}`,jt(Mt(`[${o+1}]`)));t.push(` ${e} ${Rt(n.title)}`,` ${qt("→")} ${qt(n.teaser)}`,"")}return t.push(Lt,` ${Ft(`https://barazany.dev/blog${Ht}`,"barazany.dev/blog")}`,Lt),t}function Gt(e){let t=[];$.connectivity.h2Keepalive?t.push("HTTP/2 keepalive"):$.connectivity.h2&&t.push("HTTP/2"),t.push(`timeout ${e.timeout/1e3}s`);let o=e.webSearch?`Tavily ${Dt("✓")}`:qt("off"),n=["",` ${jt("COPILOT-API")} ${qt(`v${e.version}`)}`,Lt,` ${qt("Runtime")} ${e.runtime.name} ${e.runtime.version} (${e.runtime.platform}-${e.runtime.arch})`,` ${qt("User")} ${e.user} ${qt("·")} ${e.accountType}`];return $._v1&&n.push(` ${qt("Client")} VSCode ${$._v1}`),n.push(` ${qt("Network")} ${t.join(qt(" · "))}`,` ${qt("Search")} ${o}`),e.clipboardCopied&&n.push(` ${qt("Clipboard")} Claude Code command ${Dt("✓")}`),n.push(Lt),n}function Wt(e){if(!e.model&&!e.smallModel)return[];let t=["",` ${jt("Active")}`];if(e.model){let o=$.models?.data.find(t=>t.id===e.model),n=Ut(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${Rt(e.model.padEnd(32))} ${qt("ctx")} ${jt(n.padStart(5))} ${Bt("← main")}`)}if(e.smallModel){let o=$.models?.data.find(t=>t.id===e.smallModel),n=Ut(o?.capabilities.limits?.max_context_window_tokens);t.push(` ${e.smallModel.padEnd(32)} ${qt("ctx")} ${n.padStart(5)} ${Bt("← small")}`)}return t}function zt(e){let t=[];for(let[o,n]of function(){let e=[],t=[],o=[],n=[];for(let a of $.models?.data??[]){let r=a.capabilities.limits?.max_context_window_tokens,i={id:a.id,ctx:r};a.id.startsWith("text-embedding")?n.push(i):"Anthropic"===a.vendor?e.push(i):"Google"===a.vendor?o.push(i):t.push(i)}return[["Claude",e],["OpenAI",t],["Gemini",o],["Embedding",n]]}())if(0!==n.length){t.push("",` ${jt(o)}`);for(let o of n){let n=o.id===e.model||o.id===e.smallModel,a=n?Rt("●"):qt("·"),r=n?Rt(o.id.padEnd(34)):o.id.padEnd(34),i=o.ctx?Ut(o.ctx).padStart(5):"";t.push(` ${a} ${r} ${qt(i)}`)}}return t}function Yt(e){if(!e.endpoints)return[];let{scheme:t,port:o,hostname:n}=e.endpoints,a=n?`${t}://${n}:${o}`:`${t}://<your-tailscale-hostname>:${o}`,r=["",Lt,` ${jt("Claude Cowork")} ${qt("— Settings → Inference Provider")}`,Lt,"",` ${qt("Paste into")} ${jt("inferenceGatewayBaseUrl")}${qt(":")}`,` ${jt(Rt(a))}`];return n||r.push("",` ${qt("Your Tailscale hostname is shown by:")} ${Rt("tailscale status --self")}`),r.push("",` ${qt("Docs:")} ${Rt("https://claude.com/docs/cowork/3p/installation")}`),r}function Vt(e){if(!e.https||!e.https.selfSigned)return[];let{certPath:t}=e.https,o=["",Lt,` ${jt("HTTPS")} ${qt("— self-signed cert")}`,Lt,"",` ${qt("Cert")} ${t}`];switch(o.push("",` ${jt("Trust this cert")} ${qt("(one-time setup)")}`),ue.platform){case"darwin":o.push(` ${qt("macOS:")}`,` ${Rt("sudo security add-trusted-cert -d -r trustRoot \\")}`,` ${Rt(`-k /Library/Keychains/System.keychain "${t}"`)}`);break;case"win32":o.push(` ${qt("Windows (PowerShell as Administrator):")}`,` ${Rt(`Import-Certificate -FilePath "${t}" \``)}`,` ${Rt("-CertStoreLocation Cert:\\LocalMachine\\Root")}`);break;case"linux":o.push(` ${qt("Linux (Debian/Ubuntu):")}`,` ${Rt(`sudo cp "${t}" /usr/local/share/ca-certificates/copilot-api.crt`)}`,` ${Rt("sudo update-ca-certificates")}`,` ${qt("Linux (Fedora/RHEL/Arch):")}`,` ${Rt(`sudo cp "${t}" /etc/pki/ca-trust/source/anchors/copilot-api.crt`)}`,` ${Rt("sudo update-ca-trust")}`);break;default:o.push(` ${qt("(Unknown platform — see Node fallback below.)")}`)}return o.push("",` ${qt("Or, for Node CLIs only (no admin needed):")}`,` ${Rt(`export NODE_EXTRA_CA_CERTS="${t}"`)}`,Lt),o}function Xt(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 Qt=oe.join(v.APP_DIR,"certs"),Zt=oe.join(Qt,"cert.pem"),eo=oe.join(Qt,"key.pem"),to=oe.join(Qt,"cert.meta.json");async function oo(e){try{return await ee.readFile(e,"utf8")}catch{return}}async function no(e){let t=await oo(Zt),o=await oo(eo),n=await async function(){let e=await oo(to);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 a=new Set(n.hosts);for(let t of e)if(!a.has(t))return!1;let r=Date.parse(n.notAfter);return!Number.isNaN(r)&&r-Date.now()>2592e6}function ao(e){return 0!==he(e)}async function ro(e){await ee.mkdir(Qt,{recursive:!0});let t=new Date,o=new Date;o.setDate(o.getDate()+825);let n=["127.0.0.1","::1"],a=new Set(["localhost"]),r=new Set(n);for(let t of e)ao(t)?r.add(t):a.add(t);let i=await _e([{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:[...[...a].map(e=>({type:2,value:e})),...[...r].map(e=>({type:7,ip:e}))]}]});return await ee.writeFile(Zt,i.cert,{mode:420}),await ee.writeFile(eo,i.private,{mode:384}),await async function(e){await ee.writeFile(to,JSON.stringify(e,null,2),{mode:420})}({hosts:[...a,...r].sort(),notAfter:o.toISOString()}),{cert:i.cert,key:i.private,certPath:Zt,keyPath:eo,generated:!0}}function io(e){(function(e){let{c:t,start:o,span:n}=e,a=t.get("requestData"),r=t.res.status,i=a?.model??"unknown",s=a?.streaming??!1,l=Date.now()-o;if(n.setAttribute("http.status_code",r),n.setAttribute("copilot_api.model",i),n.setAttribute("copilot_api.streaming",s),n.setAttribute("copilot_api.duration_ms",l),a?._d1&&n.setAttribute("copilot_api.copilot_duration_ms",a._d1),a?.tokenUsage){let e=a.tokenUsage;n.setAttribute("copilot_api.input_tokens",e.inputTokens),n.setAttribute("copilot_api.output_tokens",e.outputTokens),n.setAttribute("copilot_api.total_tokens",e.totalTokens),e.cachedTokens&&n.setAttribute("copilot_api.cached_tokens",e.cachedTokens),e.estimatedCost&&n.setAttribute("copilot_api.estimated_cost",e.estimatedCost)}t.res.headers.forEach((e,t)=>{let o=t.toLowerCase();D.has(o)||n.setAttribute(`http.response.header.${o}`,e)}),r>=400&&n.setStatus({code:ae.ERROR,message:`HTTP ${r}`}),n.end()})(e),function(e){let{c:t,start:o,method:a,path:i,endpointType:s,requestId:c}=e,u=Date.now()-o,p=t.get("requestData"),m=t.res.status,g=p?.model??"unknown",h=p?.streaming??!1,y={method:a,path:i,status_code:String(m),model:g,streaming:String(h),endpoint_type:s};if(l.add(1,y),r.record(u,y),m>=400&&_.add(1,{method:a,path:i,status_code:String(m),error_type:m>=500?"server_error":"client_error"}),p?.tokenUsage){let e=p.tokenUsage,t={model:g,endpoint_type:s};e.inputTokens&&(n.add(e.inputTokens,t),f.record(e.inputTokens,t)),e.outputTokens&&(j.add(e.outputTokens,t),d.record(e.outputTokens,t)),e.cachedTokens&&G.add(e.cachedTokens,{model:g})}!h&&p?.tokenUsage&&H.executeCompletion(c)}(e)}const so=async()=>i.startActiveSpan("copilot_api.approval.await",async e=>{let t=performance.now();try{let o=await Z.prompt("Accept incoming request?",{type:"confirm"}),n=performance.now()-t;if(e.setAttribute("copilot_api.approval.wait_duration_ms",n),T.record(n),!o)throw e.setAttribute("copilot_api.approval.result","rejected"),C.add(1,{result:"rejected"}),new B("Request rejected",Response.json({message:"Request rejected"},{status:403}));e.setAttribute("copilot_api.approval.result","approved"),C.add(1,{result:"approved"})}finally{e.end()}}),lo=3e-6,co=15e-6;function uo(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*lo+o*co,cachedTokens:e.prompt_tokens_details?.cached_tokens,acceptedPredictionTokens:e.completion_tokens_details?.accepted_prediction_tokens,rejectedPredictionTokens:e.completion_tokens_details?.rejected_prediction_tokens}}function po(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 mo=[{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"}],fo={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 go(e,t){let o=function(e){return e.startsWith("anthropic/")?e.slice(10):e}(e),[n,a]=function(e){let t=e.lastIndexOf("["),o=e.lastIndexOf("]");return-1!==t&&o===e.length-1&&o>t?[e.slice(0,t),e.slice(t+1,o)]:[e,null]}(o);if(t.includes(o))return o;if(a){let e=`${n}-${a}`.replaceAll(/(\d)-(\d)\b/g,"$1.$2");if(t.includes(e))return e}let r=function(e){for(let t of mo)if(t.pattern.test(e))return t.family;return null}(n);if(!r)return null;let i=n.replace(/-\d{8}(?::.*)?$/,""),s=a?`-${a}`:"";for(let e of t){let t=e.replace(/-\d{8}(?::.*)?$/,""),o=`${i}${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=fo[e];if(!n)return null;if(o){let e=`${n}-${o}`;if(t.includes(e))return e}if(t.includes(n))return n;if("sonnet-4.5"===e)for(let e of["claude-3.5-sonnet"]){let n=o?`${e}-${o}`:e;if(t.includes(n))return n}return null}(r,t,a)}var ho=class extends Error{statusCode;constructor(e,t=400){super(e),this.name="ModelValidationError",this.statusCode=t}};function _o(t){if(!t||"string"!=typeof t)throw new ho("Model name is required and must be a string");if(!$.models?.data)throw new ho("Models not available. Please try again later.",503);let o=$.models.data.map(e=>e.id);if(o.includes(t))return t;let n=go(t,o);if(!n)throw e.add(1,{requested_model:t}),new ho(`Invalid model: '${t}'. Available services: ${o.join(", ")}`);return n}async function yo(e){if(void 0===e.rateLimitSeconds)return;let t=e.rateLimitSeconds;return i.startActiveSpan("copilot_api.rate_limit.check",async o=>{try{let n=Date.now();if(o.setAttribute("copilot_api.rate_limit.configured_seconds",t),!e.lastRequestTimestamp)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let a=(n-e.lastRequestTimestamp)/1e3;if(o.setAttribute("copilot_api.rate_limit.elapsed_seconds",a),a>t)return e.lastRequestTimestamp=n,void o.setAttribute("copilot_api.rate_limit.action","allowed");let r=Math.ceil(t-a);if(o.setAttribute("copilot_api.rate_limit.wait_seconds",r),!e.rateLimitWait)throw o.setAttribute("copilot_api.rate_limit.action","rejected"),m.add(1,{action:"rejected",source:"local"}),Z.warn(`Rate limit exceeded. Need to wait ${r} more seconds.`),new B("Rate limit exceeded",Response.json({message:"Rate limit exceeded"},{status:429}));let i=1e3*r;o.setAttribute("copilot_api.rate_limit.action","waited"),m.add(1,{action:"waited",source:"local"}),g.record(i,{source:"local"}),Z.warn(`Rate limit reached. Waiting ${r} seconds before proceeding...`),await Ae(i),e.lastRequestTimestamp=n,Z.info("Rate limit wait completed, proceeding with request")}finally{o.end()}})}function ko(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 wo(e,t,o){return Math.min(Math.max(e,t),o)}function bo(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 a=o.message;if("string"!=typeof a)return null;try{return bo(JSON.parse(a),t+1)}catch{return null}}function vo(e,t){let o=e?.data.find(e=>e.id===t);if(!o)return null;let n=ko(o.capabilities.supports.min_thinking_budget),a=ko(o.capabilities.supports.max_thinking_budget);return!n||!a||a<=n?null:{bounds:{min:n,max:a-1},maxOutputTokens:ko(o.capabilities.limits?.max_output_tokens)??void 0}}function $o(e){let{config:t}=e,o=t.bounds.min,n=t.bounds.max,a=wo(ko(e.requestedBudget)??o,o,n),r=ko(e.maxTokens);if(r||=a+1,t.maxOutputTokens&&r>t.maxOutputTokens&&(r=t.maxOutputTokens),r<=a){let e=Math.min(a,r-1);if(e>=o)a=e;else{let e=o+1;if(t.maxOutputTokens&&e>t.maxOutputTokens)return{thinkingBudget:null,maxTokens:r};r=e,a=o}}return r<=a?{thinkingBudget:null,maxTokens:r}:{thinkingBudget:a,maxTokens:r}}function xo(e,t,o){if(Se(e.thinking_budget))return e;if(!1===o?.enabled)return{...e,thinking_budget:void 0};let n=vo(t,e.model);if(!n)return{...e,thinking_budget:void 0};let a=$o({requestedBudget:e.thinking_budget,maxTokens:e.max_tokens,config:n});return null===a.thinkingBudget?{...e,max_tokens:a.maxTokens,thinking_budget:void 0}:{...e,max_tokens:a.maxTokens,thinking_budget:a.thinkingBudget}}function To(e){return"invalid_thinking_budget"===bo(e)}async function Ao(e){let{payload:t,error:o,models:n,errorBodyText:a}=e;if(Se(t.thinking_budget)||!(o instanceof Error))return null;let r,i,s=o;if(!(s.response instanceof Response)||400!==s.response.status)return null;if(void 0!==a)r=a;else try{r=await s.response.clone().text()}catch{return null}try{i=JSON.parse(r)}catch{return null}if(!To(i))return null;let l=vo(n,t.model);return l?function(e,t){let o=$o({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,a=ko(e.thinking_budget);if(a&&a===o.thinkingBudget){let e=n+1;e<=t.bounds.max&&(!o.maxTokens||e<o.maxTokens)&&(n=e)}let r=o.maxTokens;if((!r||r<=n)&&(r=n+1),t.maxOutputTokens&&r>t.maxOutputTokens){if(!(t.maxOutputTokens>n))return{...e,max_tokens:t.maxOutputTokens,thinking_budget:void 0};r=t.maxOutputTokens}return{...e,max_tokens:r,thinking_budget:n}}(t,l):{...t,thinking_budget:void 0}}function So(e){if(!(e instanceof Error))return!1;let t=e.code;return(!t||"UND_ERR_SOCKET"===t)&&/GOAWAY/i.test(e.message)}async function Oo(){return new Promise(e=>setTimeout(e,100))}function Io(e){if("string"==typeof e)return function(e){let t=e,o=String.fromCodePoint(27),n=t.split(o);if(n.length>1){t=n[0];for(let e=1;e<n.length;e++){let a=n[e],r=a.match(/^\[[0-9;]*[a-z]/i);t+=r?a.slice(r[0].length):o+a}}return t.replaceAll(/[\u200B-\u200D\uFEFF]/g,"").replaceAll(/[\u2060-\u2064]/g,"").replaceAll(/[\u206A-\u206F]/g,"").replaceAll(/[\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/g,"").replaceAll(/[\uFFF0-\uFFFF]/g,"").replaceAll(/[\x00-\x08\v\f\x0E-\x1F]/g,"")}(e);if(Array.isArray(e))return e.map(e=>Io(e));if(e&&"object"==typeof e){let t={};for(let[o,n]of Object.entries(e))t[o]=Io(n);return"object"===t.type&&!("properties"in t)&&(t.properties={}),t}return e}const Po=async e=>{let t=Io(e);try{return await Co(t)}catch(e){let o;if(e instanceof B)try{o=await e.response.clone().text()}catch{o=void 0}let n=await Ao({payload:t,error:e,models:$.models,errorBodyText:o});if(n)return e instanceof B&&void 0!==o&&Z.warn(`Upstream rejected thinking_budget (status ${e.response.status}): ${o.slice(0,500)}`),Z.warn("Adjusting thinking_budget payload and retrying once..."),await Co(Io(n));throw e}},Co=async e=>{if(!$._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)),o=e.messages.some(e=>["assistant","tool"].includes(e.role)),n={...R($,t),"X-Initiator":o?"agent":"user"},a=O($),r=`${a}/chat/completions`,i=$.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":o?"agent":"user"};for(let t=0;t<=1;t++){let o=It(a),c=new AbortController,u=setTimeout(()=>c.abort(),i);try{let{statusCode:a,headers:u,body:p,span:d}=await b({spanName:"copilot POST /chat/completions",url:r,target:"chat_completions",headers:n,body:s,signal:c.signal,headersTimeout:i,bodyTimeout:3*i,extraAttributes:{...l,"copilot_api.h2.retry_attempt":t},dispatcher:o}),m=new Response(p,{status:a,headers:u});if(!m.ok)throw d.end(),new B("Failed to create chat completions",m);if(e.stream)return{events:be(m),span:d,release:()=>Pt(o)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&po(d,f.usage),d.end(),Pt(o),f}catch(e){if(Pt(o),So(e)&&t<1){Z.warn(`HTTP/2 GOAWAY during chat completions, retrying (attempt ${t+1})`),await Oo();continue}throw e}finally{clearTimeout(u)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function No(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=_o(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),q.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function Eo(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){Z.warn("Failed to parse streaming chunk:",e.data.slice(0,200),t)}return e}const jo=e=>Object.hasOwn(e,"choices"),qo=new ye;qo.post("/",async e=>{try{return await async function(e){await yo($);let t=await e.req.json();Z.debug("Request payload:",JSON.stringify(t).slice(-400));try{t=No(t)}catch(t){if(t instanceof ho)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}),$.manualApprove&&await so(),Se(t.max_tokens)){let e=$.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=xo(t,$.models,{enabled:$.thinkingEnabled}),Se(t.thinking_budget)||Z.debug("Normalized thinking_budget to:",JSON.stringify(t.thinking_budget));let o=performance.now(),n=await Po(t),a=performance.now()-o;if(S.record(a,{model:t.model,target:"chat_completions",streaming:String(!!t.stream)}),jo(n)){let t=e.get("requestData")||{};return n.usage&&(t.tokenUsage=uo(n.usage)),t._d1=a,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(n)),e.json(n)}let{events:r,span:i,release:s}=n;return we(e,async o=>{let n={value:null},l=0,c=performance.now();try{try{for await(let i of r){let r=i;i.data&&"[DONE]"!==i.data&&(l++,h.add(1,{model:t.model,endpoint_type:"openai"}),r=Eo(i,t=>{n.value=t;let o=e.get("requestData")||{};o.tokenUsage=uo(t),o._d1=a,e.set("requestData",o)})),await o.writeSSE(r)}let i=performance.now()-c,s={model:t.model,endpoint_type:"openai"};if(V.record(i,s),Y.record(l,s),n.value){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=uo(n.value),t._d1=a,e.set("requestData",t))}}finally{n.value&&po(i,n.value),i.end(),s()}let u=e.get("requestId");u&&H.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await L(e,t)}});const Ro=new ye;Ro.post("/",async e=>{try{let t=await e.req.json();try{_o(t.model)}catch(t){if(t instanceof ho)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(!$._t1)throw Error("Service token not found");let t=`${O($)}/embeddings`,o=R($),n=$.timeoutMs,a=new AbortController,r=setTimeout(()=>a.abort(),n);try{let{response:n,span:r}=await k({spanName:"copilot POST /embeddings",url:t,target:"embeddings",method:"POST",headers:o,body:JSON.stringify(e),signal:a.signal,extraAttributes:{"copilot_api.model":e.model,"copilot_api.input_count":Array.isArray(e.input)?e.input.length:1}});if(!n.ok)throw r.end(),new B("Failed to create embeddings",n);let i=await n.json();return r.end(),i}finally{clearTimeout(r)}})(t),a=performance.now()-o;S.record(a,{model:t.model,target:"embeddings",streaming:"false"});let r=e.get("requestData")||{};return r.tokenUsage=uo(n.usage),r._d1=a,e.set("requestData",r),e.json(n)}catch(t){return await L(e,t)}});const Do=new ve(xe),Bo={...$e["anthropic/claude-sonnet-4"].tokens,baseOverhead:4,perTool:27};function Mo(e){return Do.encode(e).length}function Fo(e){let t=0;for(let o of e)switch(o.type){case"text":t+=Mo(o.text)*Bo.contentMultiplier;break;case"tool_use":t+=Mo(o.name+JSON.stringify(o.input))*Bo.contentMultiplier;break;case"tool_result":o.content&&(t+=Mo("string"==typeof o.content?o.content:JSON.stringify(o.content))*Bo.contentMultiplier);break;case"thinking":t+=Mo(o.thinking)*Bo.contentMultiplier;break;case"image":t+=1600}return t}function Ho(e){let t=0,o=e.properties;if(!o)return t;let n=Object.entries(o);for(let[e,[o,a]]of n.entries()){if(t+=0===e?Bo.perFirstProp:Bo.perAdditionalProp,t+=Mo(o),a.description&&(t+=Bo.perPropDesc+Mo(a.description)),a.enum&&Array.isArray(a.enum)){t+=Bo.perEnum;for(let e of a.enum)t+=Mo(String(e))}if("object"===a.type&&a.properties&&(t+=Bo.perNestedObject,t+=Ho(a)),"array"===a.type&&a.items){let e=a.items;"object"===e.type&&e.properties&&(t+=Bo.perArrayOfObjects,t+=Ho(e))}}return t}const Lo=async e=>{if(!$._t1)throw Error("Service token not found");let t=Io(e),o={...R($),"X-Initiator":"agent"},n=O($),a=`${n}/responses`,r=$.timeoutMs,i=JSON.stringify(t),s={"copilot_api.model":t.model,"copilot_api.streaming":!!t.stream,"copilot_api.timeout_ms":r,"copilot_api.has_tools":!!t.tools?.length,"copilot_api.tool_count":t.tools?.length??0,"copilot_api.max_output_tokens":t.max_output_tokens??0,"copilot_api.api_type":"responses"};for(let e=0;e<=1;e++){let l=It(n),c=new AbortController,u=setTimeout(()=>c.abort(),r);try{let{statusCode:n,headers:u,body:p,span:d}=await b({spanName:"copilot POST /responses",url:a,target:"responses",headers:o,body:i,signal:c.signal,headersTimeout:r,bodyTimeout:3*r,extraAttributes:{...s,"copilot_api.h2.retry_attempt":e},dispatcher:l}),m=new Response(p,{status:n,headers:u});if(!m.ok)throw d.end(),new B("Failed to create responses",m);if(t.stream)return{events:be(m),span:d,release:()=>Pt(l)};let f=await m.json();return f.id&&d.setAttribute("copilot_api.response.id",f.id),f.usage&&po(d,{prompt_tokens:f.usage.input_tokens,completion_tokens:f.usage.output_tokens,total_tokens:f.usage.total_tokens}),d.end(),Pt(l),f}catch(t){if(Pt(l),So(t)&&e<1){Z.warn(`HTTP/2 GOAWAY during responses, retrying (attempt ${e+1})`),await Oo();continue}throw t}finally{clearTimeout(u)}}throw Error("Unexpected: exhausted GOAWAY retries without result")};function Uo(e){return null===e?null:{stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"end_turn"}[e]}function Jo(e,t){let o={model:e.model,messages:Ko(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:Vo(e.tools),tool_choice:Xo(e.tool_choice)},n=e.thinking;if("enabled"===n?.type||"adaptive"===n?.type){let a=vo(t,o.model);if(a){let r="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),a=ko(t),r=a&&a>1?a-1:o.min;return wo(Math.min(n,r),o.min,o.max)}(e.output_config?.effort??"high",o.max_tokens,a.bounds);o=xo({...o,thinking_budget:r},t)}}return o}function Ko(e,t){let o=function(e){return e?"string"==typeof e?[{role:"system",content:Go(e)}]:[{role:"system",content:Go(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:Yo(e.content)});n.length>0&&t.push({role:"user",content:Yo(n)})}else t.push({role:"user",content:Yo(e.content)});return t}(e):function(e){let t=function(e){return{reasoning_text:zo(e.reasoning_text),reasoning_opaque:zo(e.reasoning_opaque)}}(e);if(!Array.isArray(e.content))return[{role:"assistant",content:Yo(e.content),...t}];let o=e.content.filter(e=>"tool_use"===e.type),n=e.content.filter(e=>"text"===e.type),a=e.content.filter(e=>"thinking"===e.type),r=[...n.map(e=>e.text),...a.map(e=>e.thinking)].join("\n\n");return o.length>0?[{role:"assistant",content:r||null,...t,tool_calls:o.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.input)}}))}]:[{role:"assistant",content:Yo(e.content),...t}]}(e));return[...o,...n]}function Go(e){return e.startsWith("x-anthropic-billing-header")?e.replace(/^x-_an1-billing-header:[^\n]*\n+/,""):e}const Wo=32768;function zo(e){if("string"==typeof e)return e.length<=Wo?e:e.slice(0,Wo)}function Yo(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 Vo(e){if(e)return e.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.input_schema}}))}function Xo(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 Qo(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 Zo(e){return e.reasoning_text?[{type:"thinking",thinking:e.reasoning_text}]:[]}function en(e){return e?e.map(e=>({type:"tool_use",id:e.id,name:e.function.name,input:JSON.parse(e.function.arguments)})):[]}function tn(e){let t={model:e.model,input:nn(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:on(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 on(e){switch(e){case"low":return"low";case"medium":return"medium";case"max":return"xhigh";default:return"high"}}function nn(e){let t=[];for(let o of e)"user"===o.role?t.push(...an(o)):t.push(...sn(o));return t}function an(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(rn(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 rn(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 sn(e){if("string"==typeof e.content)return[{type:"message",role:"assistant",content:e.content}];let t=[],o=e.content.filter(e=>"text"===e.type),n=e.content.filter(e=>"thinking"===e.type),a=e.content.filter(e=>"tool_use"===e.type),r=[...o.map(e=>e.text),...n.map(e=>e.thinking)].join("\n\n");r&&t.push({type:"message",role:"assistant",content:r});for(let e of a)t.push({type:"function_call",call_id:e.id,name:e.name,arguments:JSON.stringify(e.input)});return t}function ln(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 cn(e,t){e.contentBlockOpen&&=(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,!1)}function un(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 pn(e,t){let o=[];switch(e.type){case"response.created":un(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){un(t,o),cn(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":un(t,o),cn(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":cn(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":{cn(t,o);let n=e.response.output.some(e=>"function_call"===e.type),a=e.response.usage;o.push({type:"message_delta",delta:{stop_reason:ln(e.response.status,n),stop_sequence:null},usage:{input_tokens:a?.input_tokens??0,output_tokens:a?.output_tokens??0}},{type:"message_stop"});break}case"response.incomplete":{un(t,o),cn(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":un(t,o),cn(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":un(t,o),cn(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":un(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 dn(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 mn(e,t){e.thinkingBlockOpen&&(t.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.thinkingBlockOpen=!1,e.contentBlockOpen=!1)}function fn(e,t){let o=[];if(0===e.choices.length)return o;let n=e.choices[0],{delta:a}=n;if(t.messageStartSent||=(o.push({type:"message_start",message:{id:e.id,type:"message",role:"assistant",content:[],model:e.model,stop_reason:null,stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:0}}}),!0),"string"==typeof a.reasoning_text&&""!==a.reasoning_text&&(dn(t,o),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"thinking_delta",thinking:a.reasoning_text}})),"string"==typeof a.reasoning_opaque&&""!==a.reasoning_opaque&&(dn(t,o),o.push({type:"content_block_delta",index:t.contentBlockIndex,delta:{type:"signature_delta",signature:a.reasoning_opaque}}),mn(t,o)),a.content&&(mn(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:a.content}})),a.tool_calls){mn(t,o);for(let e of a.tool_calls){if(e.id&&e.function?.name){t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),t.contentBlockIndex++,!1);let n=t.contentBlockIndex;t.toolCalls[e.index]={id:e.id,name:e.function.name,_bi1:n},o.push({type:"content_block_start",index:n,content_block:{type:"tool_use",id:e.id,name:e.function.name,input:{}}}),t.contentBlockOpen=!0}if(e.function?.arguments){let n=t.toolCalls[e.index];n&&o.push({type:"content_block_delta",index:n._bi1,delta:{type:"input_json_delta",partial_json:e.function.arguments}})}}}return n.finish_reason&&(mn(t,o),t.contentBlockOpen&&=(o.push({type:"content_block_stop",index:t.contentBlockIndex}),!1),o.push({type:"message_delta",delta:{stop_reason:Uo(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 gn(e,t,o){let n={query:t,max_results:o?.maxResults??5};o?.includeDomains?.length&&(n.include_domains=o.includeDomains),o?.excludeDomains?.length&&(n.exclude_domains=o.excludeDomains),Z.debug("Tavily search request:",JSON.stringify(n));let a=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)});if(!a.ok){let e=await a.text();throw Z.error(`Tavily API error (${a.status}):`,e),Error(`Tavily API error: ${a.status} ${e}`)}let r=await a.json();return Z.debug(`Tavily returned ${r.results.length} results`),r.results}function hn(){let e="";for(let t=0;t<24;t++)e+="abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())];return e}async function _n(e,t){let o=function(e){let t,o=e.messages[0];if(!o||"user"!==o.role)return null;if("string"==typeof o.content)t=o.content;else{if(!Array.isArray(o.content))return null;{let e=o.content.find(e=>"text"===e.type);if(!e)return null;t=e.text}}return t.startsWith("Perform a web search for the query: ")?t.slice(36).trim():t.trim()||null}(t);if(!o)return e.json({type:"error",error:{type:"invalid_request_error",message:"Could not extract search query from web search request"}},400);let n=function(e){let t=e.tools?.[0];return{maxResults:"number"==typeof t?.max_uses?t.max_uses:5,allowedDomains:t?.allowed_domains,blockedDomains:t?.blocked_domains}}(t);Z.info(`Web search intercepted: "${o}"`);let a=[];try{let e=$.tavilyApiKey;if(!e)throw Error("No Tavily API key configured");a=(await gn(e,o,{maxResults:Math.min(n.maxResults,10),includeDomains:n.allowedDomains,excludeDomains:n.blockedDomains})).map(e=>({type:"web_search_result",url:e.url,title:e.title,encrypted_content:Buffer.from(e.content).toString("base64"),page_age:null}))}catch(e){Z.error("Tavily search failed:",e)}let r={query:o,results:a,model:t.model};if(!t.stream)return e.json(function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${hn()}`,r=[{type:"text",text:"I'll search for that."},{type:"server_tool_use",id:a,name:"web_search",input:{query:t}},{type:"web_search_tool_result",tool_use_id:a,content:o}];return{id:`msg_tavily_${hn()}`,type:"message",role:"assistant",model:n,content:r,stop_reason:"end_turn",stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}}(r));let i=function(e){let{query:t,results:o,model:n}=e,a=`srvtoolu_${hn()}`,r=`msg_tavily_${hn()}`,i=[];return i.push({type:"message_start",message:{id:r,type:"message",role:"assistant",content:[],model:n,stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}},{type:"content_block_start",index:0,content_block:{type:"text",text:""}},{type:"content_block_delta",index:0,delta:{type:"text_delta",text:"I'll search for that."}},{type:"content_block_stop",index:0},{type:"content_block_start",index:1,content_block:{type:"server_tool_use",id:a,name:"web_search",input:{}}},{type:"content_block_delta",index:1,delta:{type:"input_json_delta",partial_json:JSON.stringify({query:t})}},{type:"content_block_stop",index:1},{type:"content_block_start",index:2,content_block:{type:"web_search_tool_result",tool_use_id:a,content:o}},{type:"content_block_stop",index:2},{type:"message_delta",delta:{stop_reason:"end_turn",stop_sequence:null},usage:{output_tokens:0}},{type:"message_stop"}),i}(r);return we(e,async e=>{for(let t of i)await e.writeSSE({event:t.type,data:JSON.stringify(t)})})}function yn(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 kn(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 _n(e,t);await yo($),Z.debug("Anthropic request payload:",JSON.stringify(t));let o=e.req.header("anthropic-beta")??"",n=/context-1m/i.test(o);if(n&&/\u0063\u006c\u0061\u0075\u0064\u0065/i.test(t.model)){let e=t.model;t={...t,model:`${t.model}-1m`},Z.debug(`Detected context-1m beta flag, rewriting model: '${e}' → '${t.model}'`)}let a=function(e,t){return i.startActiveSpan("copilot_api.model.validate",o=>{try{o.setAttribute("copilot_api.model.requested",t.model);let n=_o(t.model);o.setAttribute("copilot_api.model.normalized",n);let a=yn(t);return a?{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:a}},400)}:n===t.model?(o.setAttribute("copilot_api.model.was_mapped",!1),{ok:!0,payload:t}):(o.setAttribute("copilot_api.model.was_mapped",!0),q.add(1,{from_model:t.model,to_model:n}),Z.debug(`Model mapping: '${t.model}' → '${n}'`),{ok:!0,payload:{...t,model:n}})}catch(t){if(t instanceof ho)return{ok:!1,response:e.json({type:"error",error:{type:"invalid_request_error",message:t.message}},t.statusCode)};throw t}finally{o.end()}})}(e,t);if(!a.ok)return a.response;if(t=a.payload,function(e){return/gpt-[\d.]+-codex/i.test(e)}(t.model))return async function(e,t){let o=performance.now(),n=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),tn(t)}finally{e.end()}});u.record(performance.now()-o,{direction:"anthropic_to_responses"}),Z.debug("Translated Responses API payload:",JSON.stringify(n)),e.set("requestData",{model:n.model,streaming:!!n.stream}),$.manualApprove&&await so();let a=performance.now(),r=await Lo(n),s=performance.now()-a;if(S.record(s,{model:n.model,target:"responses",streaming:String(!!n.stream)}),vn(r)){let t=e.get("requestData")||{};if(r.usage&&(t.tokenUsage=uo({prompt_tokens:r.usage.input_tokens,completion_tokens:r.usage.output_tokens,total_tokens:r.usage.total_tokens})),t._d1=s,e.set("requestData",t),Z.debug("Non-streaming Responses API response:",JSON.stringify(r).slice(-400)),"failed"===r.status)return e.json({type:"error",error:{type:r.error?.code??"api_error",message:r.error?.message??"Response generation failed"}},500);let o=performance.now(),n=i.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:ln(e.status,o),stop_sequence:null,usage:{input_tokens:e.usage?.input_tokens??0,output_tokens:e.usage?.output_tokens??0}}}(r)}finally{e.end()}});return u.record(performance.now()-o,{direction:"responses_to_anthropic"}),e.json(n)}Z.debug("Streaming Responses API response");let{events:l,span:c,release:p}=r;return we(e,async t=>{let o=null,a=0,r=performance.now(),i={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,responseId:"",model:"",toolCalls:{}};try{try{for await(let r of l){if(Z.debug("Responses API raw stream event:",JSON.stringify(r)),!r.data)continue;let l;try{l=JSON.parse(r.data)}catch(e){Z.warn("Failed to parse streaming chunk:",r.data.slice(0,200),e);continue}a++,h.add(1,{model:n.model,endpoint_type:"responses"});let c=wn(l);if(c){o=c;let t=e.get("requestData")||{};t.tokenUsage=uo(o),t._d1=s,e.set("requestData",t)}let u=pn(l,i);for(let e of u)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let c=performance.now()-r,u={model:n.model,endpoint_type:"responses"};V.record(c,u),Y.record(a,u)}finally{o&&po(c,o),c.end(),p()}let u=e.get("requestId");u&&H.executeCompletion(u)}finally{e.get("resolveStreamComplete")?.()}})}(e,t);let r=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",n);let o=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"===e.type)),a=t.messages.some(e=>Array.isArray(e.content)&&e.content.some(e=>"thinking"===e.type));return e.setAttribute("copilot_api.translation.has_images",o),e.setAttribute("copilot_api.translation.has_thinking",a),Jo(t,$.models)}finally{e.end()}});u.record(performance.now()-r,{direction:"anthropic_to_openai"}),s=xo(s,$.models,{enabled:$.thinkingEnabled}),Z.debug("Translated OpenAI request payload:",JSON.stringify(s)),e.set("requestData",{model:s.model,streaming:!!s.stream});let l=performance.now();$.manualApprove&&await so();let c=await Po(s),p=performance.now()-l;if(S.record(p,{model:s.model,target:"chat_completions",streaming:String(!!s.stream)}),bn(c)){let t=e.get("requestData")||{};c.usage&&(t.tokenUsage=uo(c.usage)),t._d1=p,e.set("requestData",t),Z.debug("Non-streaming response:",JSON.stringify(c).slice(-400));let o=performance.now(),n=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=[],o=[],n=[],a=null;a=e.choices[0]?.finish_reason??a;for(let r of e.choices){let e=Zo(r.message),i=Qo(r.message.content),s=en(r.message.tool_calls);t.push(...e),o.push(...i),n.push(...s),("tool_calls"===r.finish_reason||"stop"===a)&&(a=r.finish_reason)}return{id:e.id,type:"message",role:"assistant",model:e.model,content:[...t,...o,...n],stop_reason:Uo(a),stop_sequence:null,usage:{input_tokens:e.usage?.prompt_tokens??0,output_tokens:e.usage?.completion_tokens??0}}}(c);return e.setAttribute("copilot_api.translation.content_blocks",t.content.length),e.setAttribute("copilot_api.translation.stop_reason",t.stop_reason??"null"),e.setAttribute("copilot_api.translation.has_tool_use",t.content.some(e=>"tool_use"===e.type)),t}finally{e.end()}});return u.record(performance.now()-o,{direction:"openai_to_anthropic"}),Z.debug("Translated Anthropic response:",JSON.stringify(n)),e.json(n)}Z.debug("Streaming response from service");let{events:d,span:m,release:f}=c;return we(e,async t=>{let o=null,n=0,a=performance.now(),r={messageStartSent:!1,contentBlockIndex:0,contentBlockOpen:!1,thinkingBlockOpen:!1,toolCalls:{}};try{try{for await(let a of d){if(Z.debug("Raw stream event:",JSON.stringify(a)),"[DONE]"===a.data)break;if(!a.data)continue;let i;try{i=JSON.parse(a.data)}catch(e){Z.warn("Failed to parse streaming chunk:",a.data.slice(0,200),e);continue}if(n++,h.add(1,{model:s.model,endpoint_type:"anthropic"}),i.usage){o=i.usage;let t=e.get("requestData")||{};t.tokenUsage=uo(o),t._d1=p,e.set("requestData",t)}let l=fn(i,r);for(let e of l)Z.debug("Translated Anthropic event:",JSON.stringify(e)),await t.writeSSE({event:e.type,data:JSON.stringify(e)})}let i=performance.now()-a,l={model:s.model,endpoint_type:"anthropic"};if(V.record(i,l),Y.record(n,l),o){let t=e.get("requestData")||{};t.tokenUsage||(t.tokenUsage=uo(o),t._d1=p,e.set("requestData",t))}}finally{o&&po(m,o),m.end(),f()}let i=e.get("requestId");i&&H.executeCompletion(i)}finally{e.get("resolveStreamComplete")?.()}})}function wn(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 bn=e=>Object.hasOwn(e,"choices"),vn=e=>Object.hasOwn(e,"output");const $n=new ye;$n.post("/",async e=>{try{return await kn(e)}catch(t){return await L(e,t)}});const xn=new ye;function Tn(e){return i.startActiveSpan("copilot_api.model.validate",t=>{try{t.setAttribute("copilot_api.model.requested",e.model);let o=_o(e.model);return t.setAttribute("copilot_api.model.normalized",o),o===e.model?(t.setAttribute("copilot_api.model.was_mapped",!1),e):(t.setAttribute("copilot_api.model.was_mapped",!0),q.add(1,{from_model:e.model,to_model:o}),Z.debug(`Normalized model from '${e.model}' to '${o}'`),{...e,model:o})}finally{t.end()}})}function An(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=uo(o),n._d1=t._d1,t.c.set("requestData",n)}xn.get("/",async e=>{try{$.models||await Oe();let t=$.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 L(e,t)}});const Sn=new Set(["message","function_call","function_call_output"]),On=new Set(["type","name","description","parameters"]);async function In(e){if(!e)return!1;let t=e.sources;if(t&&t.length>0)return!1;let o=e.query??e.queries?.[0];return!(!o||!$.tavilyApiKey)&&(Z.info(`Enriching web search: "${o}"`),e.sources=(await gn($.tavilyApiKey,o,{maxResults:5})).map(e=>({type:"url",url:e.url,title:e.title,content:e.content})),!0)}async function Pn(e){if(!$.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 In(e.action))return JSON.stringify(t)}}catch(e){Z.error("Failed to enrich web search:",e)}return e}function Cn(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 Nn(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&&Cn(e,t))return JSON.stringify(o)}if("response.completed"===n){let n=o.response?.output;if(!n)return e;let a=!1;for(let e of n)Cn(e,t)&&(a=!0);if(a)return JSON.stringify(o)}}catch{}return e}function En(e){return null!=e}function jn(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 Sn.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"])En(e[t])&&(n[t]=e[t]);let a=new Set;if(En(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))On.has(t)&&(n[t]=e[t]);return"custom"===n.type&&(n.type="function",t.add(n.name),n.parameters||={type:"object",properties:{input:{type:"string",description:"The freeform tool input content"}},required:["input"],additionalProperties:!1}),n}),customToolNames:t}}(e.tools);n.tools=t.tools,a=t.customToolNames}if(En(e.reasoning)&&"object"==typeof e.reasoning){let t=e.reasoning;n.reasoning={},En(t.effort)&&(n.reasoning.effort=t.effort),En(t.summary)&&(n.reasoning.summary=t.summary)}if(En(e.text)&&"object"==typeof e.text){let t=e.text;En(t.format)&&(n.text={format:t.format})}return{payload:n,customToolNames:a}}async function qn(e,t,o){await async function(e){if($.tavilyApiKey)try{for(let t of e.output){let e=t;"web_search_call"===e.type&&await In(e.action)}}catch(e){Z.error("Failed to enrich non-streaming web search:",e)}}(t);let n=e.get("requestData")||{};return t.usage&&(n.tokenUsage=uo({prompt_tokens:t.usage.input_tokens,completion_tokens:t.usage.output_tokens,total_tokens:t.usage.total_tokens})),n._d1=o,e.set("requestData",n),e.json(t)}const Rn=e=>Object.hasOwn(e,"output"),Dn=new ye;Dn.post("/",async e=>{try{return await async function(e){await yo($);let{payload:t,customToolNames:o}=jn(await e.req.json()),n=t;Z.debug(`Responses API [${Array.isArray(n.input)?n.input.length:1} items]`),o.size>0&&Z.debug(`Custom tools detected: ${[...o].join(", ")}`);try{n=Tn(n)}catch(t){if(t instanceof ho)return e.json({error:{message:t.message,type:"invalid_request_error",code:"invalid_model"}},t.statusCode);throw t}e.set("requestData",{model:n.model,streaming:!!n.stream}),$.manualApprove&&await so();let a=performance.now(),r=await Lo(n),i=performance.now()-a;if(S.record(i,{model:n.model,target:"responses",streaming:String(!!n.stream)}),Rn(r))return qn(e,r,i);let{events:s,span:l,release:c}=r;return we(e,async t=>{let a={value:null},r=0,u=performance.now();try{try{for await(let l of s)if(l.data&&"[DONE]"!==l.data){r++;let s=Nn(l.data,o);s=await Pn(s);let c=s===l.data?l:{...l,data:s};h.add(1,{model:n.model,endpoint_type:"responses"}),An(s,{usageRef:a,c:e,_d1:i}),await t.writeSSE(c)}else await t.writeSSE(l);let l=performance.now()-u,c={model:n.model,endpoint_type:"responses"};V.record(l,c),Y.record(r,c)}finally{a.value&&po(l,a.value),l.end(),c()}let p=e.get("requestId");p&&H.executeCompletion(p)}finally{e.get("resolveStreamComplete")?.()}})}(e)}catch(t){return await L(e,t)}});const Bn=new ye;Bn.get("/",e=>{try{return e.json({token:$._t1})}catch(t){return Z.error("Error fetching token:",t),e.json({error:"Failed to fetch token",token:null},500)}});const Mn=new ye;Mn.get("/",async e=>{try{let t=await Me();return e.json(t)}catch(t){return Z.error("Error fetching usage:",t),e.json({error:"Failed to fetch usage"},500)}});const Fn=new ye;Fn.use(async(e,t)=>{let o=Date.now(),n=`req_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,a=e.req.method,r=e.req.path,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"}(r);e.set("requestId",n),e.header("x-request-id",n);let l=i.startSpan("copilot_api.handle_request",{kind:ne.SERVER,attributes:{"http.method":a,"http.url":e.req.url,"http.route":r,"copilot_api.request_id":n,"copilot_api.endpoint_type":s}});for(let[t,o]of Object.entries(e.req.header())){let e=t.toLowerCase();D.has(e)||l.setAttribute(`http.request.header.${e}`,o)}let c,u=new Promise(e=>{c=e});e.set("streamComplete",u),e.set("resolveStreamComplete",c);let p=ie.setSpan(re.active(),l);await re.with(p,async()=>{H.registerCompletion(n,e,o);try{await t()}catch(e){let t=e instanceof Error?e:Error(String(e));throw l.setStatus({code:ae.ERROR,message:t.message}),l.recordException(t),e}});let d=e.get("requestData"),m={c:e,start:o,method:a,path:r,endpointType:s,requestId:n,span:l};d?.streaming?u.then(()=>io(m)).catch(e=>{Z.debug("Error finalizing streaming request:",e),l.end()}):io(m)}),Fn.use(ke()),Fn.get("/",e=>e.text("Server running")),Fn.route("/chat/completions",qo),Fn.route("/models",xn),Fn.route("/embeddings",Ro),Fn.route("/usage",Mn),Fn.route("/token",Bn),Fn.route("/v1/chat/completions",qo),Fn.route("/v1/models",xn),Fn.route("/v1/embeddings",Ro),Fn.route("/v1/messages",$n),Fn.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=Bo.baseOverhead;if(t.system){let e="string"==typeof t.system?t.system:t.system.map(e=>e.text).join("\n\n");o+=Bo.perMessage+Mo(e)*Bo.contentMultiplier}for(let e of t.messages)o+=Bo.perMessage,o+=Mo(e.role),"string"==typeof e.content?o+=Mo(e.content)*Bo.contentMultiplier:Array.isArray(e.content)&&(o+=Fo(e.content));return t.tools&&t.tools.length>0&&(o+=function(e){let t=Bo.toolsExist;for(let[o,n]of e.entries())o>0&&(t+=Bo.perTool),t+=Mo(n.name),n.description&&(t+=Bo.perDesc+Mo(n.description)),t+=Ho(n.input_schema);return t}(t.tools)),e.json({input_tokens:Math.round(o)})}),Fn.route("/v1/responses",Dn),Fn.route("/responses",Dn);const Hn=[],Ln=Date.now();let Un="";function Jn(){let e=async(e,t=0)=>{let o=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()-Ln)/1e3}});for(let t of Hn)try{await t()}catch(e){Z.error("Error during cleanup:",e)}o.end(),function(e,t){let o=Ft("https://barazany.dev?utm_source=copilot-cli&utm_medium=terminal&utm_campaign=goodbye_banner","barazany.dev"),n=["",Lt,` ${jt("COPILOT-API")} ${qt(`v${e}`)} ${qt("·")} ${Xt(t)} uptime`,Lt,""," Check in from time to time on",` ${Rt(o)}`,"",Lt,""];console.log(n.join("\n"))}(Un,Date.now()-Ln),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,o)=>{Z.error("Unhandled promise rejection at:",o,"reason:",t),e("unhandledRejection",1)})}function Kn(e){let{options:t,version:n,runtime:a,_u1:r}=e,s=i.startSpan("copilot_api.server.startup",{kind:ne.INTERNAL,attributes:o({config:{version:n,port:t.port,accountType:t.accountType,verbose:t.verbose,manualApprove:t.manual,rateLimitSeconds:t.rateLimit??0,rateLimitWait:t.rateLimitWait,timeoutMs:t.timeout,showToken:t.showToken,_cc1:t._cc1,model:t.model,smallModel:t.smallModel,_t3:t._t2?"cli_arg":"stored",enableThinking:t.enableThinking},runtime:a,identity:{_u1:r.login,machineId:$.machineId,sessionId:$.sessionId,_v1:$._v1},connectivity:$.connectivity,modelsCount:$.models?.data.length??0,startupDurationMs:Date.now()-Ln},"copilot_api")});if($.models?.data)for(let e of $.models.data)s.addEvent("copilot_api.model.available",o(e,"model"));s.end(),z(N.INFO,"INFO","Server started",o({version:n,port:t.port,accountType:t.accountType,_u1:r.login,modelsCount:$.models?.data.length??0,startupDurationMs:Date.now()-Ln},"copilot_api"))}async function Gn(e){if(e.https){if(e.httpsCert&&e.httpsKey)return async function(e,t){let[o,n]=await Promise.all([ee.readFile(e,"utf8"),ee.readFile(t,"utf8")]);return{cert:o,key:n,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 no(e)){let e=await oo(Zt),t=await oo(eo);if(e&&t)return{cert:e,key:t,certPath:Zt,keyPath:eo,generated:!1}}return Z.info("Generating new self-signed TLS certificate…"),ro(e)}(e.httpsHosts)}}async function Wn(e){let t=function(e){if(!e.claudeCowork)return e;if(e.httpsCert&&e.httpsKey)return{...e,https:!0};let{certPath:t,keyPath:o}=nt;try{me(t),me(o)}catch{throw Z.error("Tailscale cert not found. Run `copilot-api cowork-setup install` first."),Error("Tailscale cert not found")}return{...e,https:!0,httpsCert:t,httpsKey:o}}(e);if(Jn(),Hn.push(()=>{Z.debug("Cleaning up connectivity monitor"),F.stop()},()=>{Z.debug("Cleaning up token management"),Z.debug("Cleaning up token management"),Pe&&=void clearInterval(Pe),Ce&&=void F.off("online",Ce),Ne&&=void F.off("offline",Ne)},async()=>{Z.debug("Cleaning up HTTP/2 client"),await async function(){Z.debug("Stopping HTTP/2 pool"),Tt&&=void clearInterval(Tt),At&&=void clearInterval(At);let e=[...vt.keys(),...$t];vt.clear(),$t.clear(),bt.clear(),xt=void 0;for(let t of e)St(t)&&(W.add(1,{event:"closed"}),await t.close())}()},async()=>{Z.debug("Shutting down OTel SDK"),await p()}),t.verbose&&(Z.level=5,Z.info("Verbose logging enabled")),t._cc1&&t.codex)throw Error("Cannot use --claude-code and --codex together");$.accountType=t.accountType,$.manualApprove=t.manual,$.rateLimitSeconds=t.rateLimit,$.rateLimitWait=t.rateLimitWait,$.showToken=t.showToken,$.timeoutMs=t.timeout,$.thinkingEnabled=t.enableThinking,t.tavilyApiKey&&($.tavilyApiKey=t.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;$.connectivity.h2=t,$.connectivity.h2Keepalive=e}(),await x(),$._v1="1.116.0-insider";let o=await ut();Un=o;let n,r=pt();a(o,Ln),t._t2?($._t2=t._t2,Z.info("Using provided Auth token")):await qe();try{let{getGitHubUser:e}=await import("./get-user-O49GxhnU.mjs");n=await e(),await I($,n.login)}catch(e){throw Z.error("Failed to get user info for machine ID generation:",e),Error("Cannot proceed without user information",{cause:e})}await je(),await Oe();let i=function(e=18e5){let t=setInterval(()=>{Oe().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)}}();Hn.push(()=>{Z.debug("Cleaning up model refresh interval"),i()}),$.connectivity.h2&&(Pt(It(O($))),$.connectivity.h2Keepalive&&Nt()),Kn({options:t,version:o,runtime:r,_u1:n});let s=await Gn(t),l=`${s?"https":"http"}://localhost:${t.port}`,c=await async function(e,t,o){if(!e._cc1)return!1;let n,a;if(ge($.models,"Models should be loaded by now"),e.model&&e.smallModel){let t=$.models.data.map(e=>e.id);if(!t.includes(e.model))throw Z.info(`Available services: \n${t.join("\n")}`),Error(`Invalid model: ${e.model}`);if(!t.includes(e.smallModel))throw Z.info(`Available services: \n${t.join("\n")}`),Error(`Invalid small model: ${e.smallModel}`);n=e.model,a=e.smallModel}else{if(e.model||e.smallModel)throw Error("Both --model and --small-model must be specified for model selection");n=await Z.prompt("Select a model to use",{type:"select",options:$.models.data.map(e=>e.id)}),a=await Z.prompt("Select a small model to use",{type:"select",options:$.models.data.map(e=>e.id)})}let r=Et({ANTHROPIC_BASE_URL:t,ANTHROPIC_AUTH_TOKEN:"dummy",ANTHROPIC_MODEL:n,ANTHROPIC_SMALL_FAST_MODEL:a,NODE_EXTRA_CA_CERTS:o?.certPath},"claude");try{return se.writeSync(r),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the command:"),Z.log(r),!1}}(t,l,s)||await async function(e,t,o){if(!e.codex)return!1;let n;if(ge($.models,"Models should be loaded by now"),e.model){let t=$.models.data.map(e=>e.id);if(!t.includes(e.model))throw Z.info(`Available services: \n${t.join("\n")}`),Error(`Invalid model: ${e.model}`);n=e.model}else n=await Z.prompt("Select a model to use with Codex CLI",{type:"select",options:$.models.data.map(e=>e.id)});let a=Et({OPENAI_BASE_URL:t,OPENAI_API_KEY:"dummy",NODE_EXTRA_CA_CERTS:o?.certPath},`codex --model ${n}`);try{return se.writeSync(a),!0}catch{return Z.warn("Failed to copy to clipboard. Here is the Codex CLI command:"),Z.log(a),!1}}(t,l,s);(function(e){let t=[...Gt(e),...Wt(e),...zt(e),"",...Kt(Jt),...Yt(e),...Vt(e),""];console.log(t.join("\n"))})(await async function(e){let{options:t,version:o,runtime:n,user:a,clipboardCopied:r,tls:i}=e,s=i?"https":"http";return{version:o,runtime:n,user:a,accountType:t.accountType,port:t.port,timeout:t.timeout,webSearch:!!t.tavilyApiKey,model:t.model,smallModel:t.smallModel,clipboardCopied:r,https:i?{certPath:i.certPath,keyPath:i.keyPath,generated:i.generated,selfSigned:!t.httpsCert}:void 0,endpoints:t.claudeCowork?{scheme:s,port:t.port,hostname:await Ke()}:void 0}}({options:t,version:o,runtime:r,user:n.login,clipboardCopied:c,tls:s})),fe({fetch:Fn.fetch,port:t.port,tls:s?{cert:s.cert,key:s.key}:void 0,bun:{idleTimeout:255}})}function zn(e,t){let o=Number.parseInt(e,10);if(Number.isNaN(o))throw Error(`${t} must be a number, got: "${e}"`);return o}const Yn=X({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:zn(t,"--rate-limit"),n=e.timeout,a=void 0===n?c:zn(n,"--timeout"),r=e["https-hosts"],i=r?r.split(",").map(e=>e.trim()).filter(Boolean):[];return Wn({port:zn(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:a,tavilyApiKey:e["tavily-api-key"]||ue.env.TAVILY_API_KEY,enableThinking:e["enable-thinking"],https:e.https,httpsCert:e["https-cert"],httpsKey:e["https-key"],httpsHosts:i,claudeCowork:e["claude-cowork"]})}});await async function(){try{if("1"===process.env.COPILOT_API_SKIP_UPDATE_CHECK)return;let[e,t]=await Promise.all([ut(),kt()]);if("unknown"===e||!t||!function(e,t){let o=e.split(".").map(Number),n=t.split(".").map(Number),a=Math.max(o.length,n.length);for(let e=0;e<a;e++){let t=o[e]??0,a=n[e]??0;if(t<a)return!0;if(t>a)return!1}return!1}(e,t))return;!function(e,t){let o=`npx ${gt}@latest`,n=yt("│"),a=` ${_t("Update available!")} ${(e=>`[2m${e}[0m`)(e)} → ${(e=>`[32m${e}[0m`)(t)}`,r=` Run ${_t(o)} to update`,i=" ".repeat(54),s=yt(`╭${"─".repeat(54)}╮`),l=yt(`╰${"─".repeat(54)}╯`),c=["",s,`${n}${i}${n}`,`${n}${wt(a,54)}${n}`,`${n}${i}${n}`,`${n}${wt(r,54)}${n}`,`${n}${i}${n}`,l,""];console.log(c.join("\n"))}(e,t)}catch{}}(),await Q(X({meta:{name:"copilot-api",description:"API proxy server for tool integration."},subCommands:{auth:Be,start:Yn,"check-usage":Fe,debug:ft,"cowork-setup":ct}}));export{};
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copilot-api-node20",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
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"
|