ghc-tunnel 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,8 +40,9 @@ ghc-tunnel [options]
40
40
 
41
41
  -s, --setup Interactive setup wizard (configure models + Claude Code)
42
42
  --claudecode Update Claude Code settings only (use with --setup)
43
+ -d, --default Use defaults for setup and Codex config prompts
43
44
  -p, --port <port> Port to listen on (default: 8314)
44
- -a, --address <addr> Address to listen on (default: localhost)
45
+ -a, --address <addr> Address to listen on (default: 127.0.0.1)
45
46
  -c, --config Generate default config file
46
47
  -v, --version Show version
47
48
  -h, --help Show help
@@ -54,10 +55,10 @@ Run `ghc-tunnel --setup --claudecode` or manually configure `~/.claude/settings.
54
55
  ```json
55
56
  {
56
57
  "env": {
57
- "ANTHROPIC_BASE_URL": "http://localhost:8314/",
58
+ "ANTHROPIC_BASE_URL": "http://127.0.0.1:8314/",
58
59
  "ANTHROPIC_AUTH_TOKEN": "dummy",
59
- "ANTHROPIC_MODEL": "claude-opus-4-7[1m]",
60
- "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-opus-4-7[1m]"
60
+ "ANTHROPIC_MODEL": "claude-opus-4-8[1m]",
61
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-opus-4-8[1m]"
61
62
  }
62
63
  }
63
64
  ```
@@ -66,9 +67,9 @@ Run `ghc-tunnel --setup --claudecode` or manually configure `~/.claude/settings.
66
67
 
67
68
  `ghc-tunnel` exposes the OpenAI Responses API (`/v1/responses`) with Codex-specific adapters so the Codex CLI can drive Copilot models directly.
68
69
 
69
- On startup ghc-tunnel automatically repairs `~/.codex/config.toml` — if any of `model`, `model_reasoning_effort`, `personality`, `model_provider`, or the `[model_providers.ghc-tunnel]` block is missing (or the block is partial), the missing pieces are filled in. When `model` or `model_reasoning_effort` is absent it prompts interactively (defaults: `gpt-5.5` / `high`, `xhigh` also valid).
70
+ On startup ghc-tunnel automatically repairs `~/.codex/config.toml` — if any of `model`, `model_reasoning_effort`, `personality`, `model_provider`, or the `[model_providers.ghc-tunnel]` block is missing (or the block is partial), the missing pieces are filled in. When `model` or `model_reasoning_effort` is absent it prompts interactively (defaults: `gpt-5.5` / `high`, `xhigh` also valid). Use `-d` / `--default` to skip prompts and accept defaults.
70
71
 
71
- `ghc-tunnel --setup` forces a full rewrite of those keys (still prompting for model + reasoning).
72
+ `ghc-tunnel --setup` forces a full rewrite of those keys (still prompting for model + reasoning unless `-d` / `--default` is passed).
72
73
 
73
74
  Resulting config:
74
75
 
@@ -80,7 +81,7 @@ model_provider = "ghc-tunnel"
80
81
 
81
82
  [model_providers.ghc-tunnel]
82
83
  name = "GHC TUNNEL"
83
- base_url = "http://localhost:8314/v1"
84
+ base_url = "http://127.0.0.1:8314/v1"
84
85
  wire_api = "responses"
85
86
  ```
86
87
 
@@ -196,7 +197,7 @@ Recent working directories are persisted to `workdirs.json` in the same location
196
197
  from openai import OpenAI
197
198
 
198
199
  client = OpenAI(
199
- base_url="http://localhost:8314/v1",
200
+ base_url="http://127.0.0.1:8314/v1",
200
201
  api_key="not-needed"
201
202
  )
202
203
 
@@ -212,7 +213,7 @@ response = client.chat.completions.create(
212
213
  import anthropic
213
214
 
214
215
  client = anthropic.Anthropic(
215
- base_url="http://localhost:8314",
216
+ base_url="http://127.0.0.1:8314",
216
217
  api_key="not-needed"
217
218
  )
218
219
 
@@ -226,7 +227,7 @@ message = client.messages.create(
226
227
  ### cURL
227
228
 
228
229
  ```bash
229
- curl http://localhost:8314/v1/chat/completions \
230
+ curl http://127.0.0.1:8314/v1/chat/completions \
230
231
  -H "Content-Type: application/json" \
231
232
  -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello!"}]}'
232
233
  ```
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Ct=Object.create;var Ve=Object.defineProperty;var At=Object.getOwnPropertyDescriptor;var Ot=Object.getOwnPropertyNames;var Tt=Object.getPrototypeOf,Et=Object.prototype.hasOwnProperty;var Pt=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ot(e))!Et.call(t,s)&&s!==o&&Ve(t,s,{get:()=>e[s],enumerable:!(n=At(e,s))||n.enumerable});return t};var v=(t,e,o)=>(o=t!=null?Ct(Tt(t)):{},Pt(e||!t||!t.__esModule?Ve(o,"default",{value:t,enumerable:!0}):o,t));var me=v(require("fs")),Ce=v(require("path")),ve=v(require("express"));var ie=v(require("fs")),_e=v(require("path")),Ae=v(require("os")),Ge=v(require("js-yaml")),We=parseInt(process.env.PORT||"8314",10),Xe=process.env.HOST||"localhost",Ke="https://api.github.com",ce="0.26.7",ae="2025-04-01",le="1.93.0",h="claude-opus-4.7-1m",G="claude-haiku-4.5",z="claude-opus-4-7[1m]",Te={exact:{opus:h,sonnet:h,"opus4-7":h,"4-7[1m]":h,haiku:G},prefix:{"claude-sonnet-4-":h,"claude-opus-4.5-":h,"claude-opus-4.6-":h,"claude-opus-4.7-":h,"claude-opus-4-5-":h,"claude-opus-4-6-":h,"claude-opus-4-7-":h,"claude-opus-4.5":h,"claude-opus-4.6":h,"claude-opus-4.7":h,"claude-opus-4-6":h,"claude-opus-4-7":h,"claude-opus-4-6[1m]":h,"claude-opus-4-7[1m]":h,"claude-sonnet-4-7":h,"claude-sonnet-4-6":h,"claude-sonnet-4-5":h,"claude-haiku-4.5-":G,"claude-haiku-4-5-":G}},Ee="01ab8ac9400c4e429b23",Oe=class{exactMappings={};prefixMappings={};translate(e){if(e in this.exactMappings)return this.exactMappings[e];for(let[o,n]of Object.entries(this.prefixMappings))if(e.startsWith(o))return n;return e}loadFromConfig(e){let o=e.model_mappings;this.exactMappings=o?.exact??{},this.prefixMappings=o?.prefix??{}}},J=new Oe;function E(){return process.platform==="win32"?_e.default.join(process.env.APPDATA||Ae.default.homedir(),"ghc-tunnel"):_e.default.join(Ae.default.homedir(),".ghc-tunnel")}function Ye(t){let e=ie.default.readFileSync(t,"utf-8");return Ge.default.load(e)||{}}function Pe(){let t=E();ie.default.mkdirSync(t,{recursive:!0});let e=_e.default.join(t,"config.yaml");if(ie.default.existsSync(e)){console.log(`Configuration file already exists at: ${e}`);return}let o=`# GitHub Copilot API Proxy Configuration
2
+ "use strict";var Et=Object.create;var Ke=Object.defineProperty;var Dt=Object.getOwnPropertyDescriptor;var Pt=Object.getOwnPropertyNames;var qt=Object.getPrototypeOf,Nt=Object.prototype.hasOwnProperty;var Lt=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Pt(e))!Nt.call(t,s)&&s!==o&&Ke(t,s,{get:()=>e[s],enumerable:!(n=Dt(e,s))||n.enumerable});return t};var v=(t,e,o)=>(o=t!=null?Et(qt(t)):{},Lt(e||!t||!t.__esModule?Ke(o,"default",{value:t,enumerable:!0}):o,t));var Re=v(require("fs")),Pe=v(require("path")),De=v(require("express"));var le=v(require("fs")),ke=v(require("path")),qe=v(require("os")),Ye=v(require("js-yaml")),Qe=parseInt(process.env.PORT||"8314",10),ee="127.0.0.1",Ze=process.env.HOST||ee,et="https://api.github.com",pe="0.26.7",de="2025-04-01",ge="1.93.0",m="claude-opus-4.8-1m",X="claude-haiku-4.5",V="claude-opus-4-8[1m]",Le={exact:{opus:m,sonnet:m,"opus4-8":m,"opus4-7":m,"4-8[1m]":m,"4-7[1m]":m,haiku:X},prefix:{"claude-sonnet-4-":m,"claude-opus-4.5-":m,"claude-opus-4.6-":m,"claude-opus-4.7-":m,"claude-opus-4.8-":m,"claude-opus-4-5-":m,"claude-opus-4-6-":m,"claude-opus-4-7-":m,"claude-opus-4-8-":m,"claude-opus-4.5":m,"claude-opus-4.6":m,"claude-opus-4.7":m,"claude-opus-4.8":m,"claude-opus-4-6":m,"claude-opus-4-7":m,"claude-opus-4-8":m,"claude-opus-4-6[1m]":m,"claude-opus-4-7[1m]":m,"claude-opus-4-8[1m]":m,"claude-sonnet-4-7":m,"claude-sonnet-4-6":m,"claude-sonnet-4-5":m,"claude-haiku-4.5-":X,"claude-haiku-4-5-":X}},Ie="01ab8ac9400c4e429b23",Ne=class{exactMappings={};prefixMappings={};translate(e){if(e in this.exactMappings)return this.exactMappings[e];for(let[o,n]of Object.entries(this.prefixMappings))if(e.startsWith(o))return n;return e}loadFromConfig(e){let o=e.model_mappings;this.exactMappings=o?.exact??{},this.prefixMappings=o?.prefix??{}}},G=new Ne;function D(){return process.platform==="win32"?ke.default.join(process.env.APPDATA||qe.default.homedir(),"ghc-tunnel"):ke.default.join(qe.default.homedir(),".ghc-tunnel")}function tt(t){let e=le.default.readFileSync(t,"utf-8");return Ye.default.load(e)||{}}function Ue(){let t=D();le.default.mkdirSync(t,{recursive:!0});let e=ke.default.join(t,"config.yaml");if(le.default.existsSync(e)){console.log(`Configuration file already exists at: ${e}`);return}let o=`# GitHub Copilot API Proxy Configuration
3
3
  # ========================================
4
4
 
5
5
  # Server Settings
6
- address: localhost
6
+ address: ${ee}
7
7
  port: 8314
8
8
  debug: false
9
9
 
@@ -12,39 +12,46 @@ debug: false
12
12
  account_type: individual
13
13
 
14
14
  # Header version strings (only affect request headers to Copilot API)
15
- vscode_version: "${le}"
16
- api_version: "${ae}"
17
- copilot_version: "${ce}"
15
+ vscode_version: "${ge}"
16
+ api_version: "${de}"
17
+ copilot_version: "${pe}"
18
18
 
19
19
  # Model Name Mappings
20
20
  # Two types: exact (full name match) and prefix (starts-with match)
21
21
  model_mappings:
22
22
  exact:
23
- opus: ${h}
24
- sonnet: ${h}
25
- opus4-7: ${h}
26
- "4-7[1m]": ${h}
27
- haiku: ${G}
23
+ opus: ${m}
24
+ sonnet: ${m}
25
+ opus4-8: ${m}
26
+ opus4-7: ${m}
27
+ "4-8[1m]": ${m}
28
+ "4-7[1m]": ${m}
29
+ haiku: ${X}
28
30
  prefix:
29
- claude-sonnet-4-: ${h}
30
- claude-opus-4.5-: ${h}
31
- claude-opus-4.6-: ${h}
32
- claude-opus-4.7-: ${h}
33
- claude-opus-4-5-: ${h}
34
- claude-opus-4-6-: ${h}
35
- claude-opus-4-7-: ${h}
36
- "claude-opus-4.5": ${h}
37
- "claude-opus-4.6": ${h}
38
- "claude-opus-4.7": ${h}
39
- "claude-opus-4-6": ${h}
40
- "claude-opus-4-7": ${h}
41
- "claude-opus-4-6[1m]": ${h}
42
- "claude-opus-4-7[1m]": ${h}
43
- claude-sonnet-4-7: ${h}
44
- claude-sonnet-4-6: ${h}
45
- claude-sonnet-4-5: ${h}
46
- claude-haiku-4.5-: ${G}
47
- claude-haiku-4-5-: ${G}
31
+ claude-sonnet-4-: ${m}
32
+ claude-opus-4.5-: ${m}
33
+ claude-opus-4.6-: ${m}
34
+ claude-opus-4.7-: ${m}
35
+ claude-opus-4.8-: ${m}
36
+ claude-opus-4-5-: ${m}
37
+ claude-opus-4-6-: ${m}
38
+ claude-opus-4-7-: ${m}
39
+ claude-opus-4-8-: ${m}
40
+ "claude-opus-4.5": ${m}
41
+ "claude-opus-4.6": ${m}
42
+ "claude-opus-4.7": ${m}
43
+ "claude-opus-4.8": ${m}
44
+ "claude-opus-4-6": ${m}
45
+ "claude-opus-4-7": ${m}
46
+ "claude-opus-4-8": ${m}
47
+ "claude-opus-4-6[1m]": ${m}
48
+ "claude-opus-4-7[1m]": ${m}
49
+ "claude-opus-4-8[1m]": ${m}
50
+ claude-sonnet-4-7: ${m}
51
+ claude-sonnet-4-6: ${m}
52
+ claude-sonnet-4-5: ${m}
53
+ claude-haiku-4.5-: ${X}
54
+ claude-haiku-4-5-: ${X}
48
55
 
49
56
  # Content Filtering
50
57
  # system_prompt_remove: strings to strip from system prompts
@@ -57,79 +64,79 @@ tool_result_suffix_remove: []
57
64
  # Retry Settings
58
65
  # Max retries for upstream connection errors (0 = no retries)
59
66
  max_connection_retries: 3
60
- `;ie.default.writeFileSync(e,o,"utf-8"),console.log(`Configuration file generated at: ${e}`)}var De=class{githubToken="";copilotToken=null;models=null;accountType="individual";tokenExpiresAt=0;vscodeVersion=le;copilotVersion=ce;apiVersion=ae;systemPromptRemove=[];systemPromptAdd=[];toolResultSuffixRemove=[];redirectAnthropic=!1;maxConnectionRetries=3;get editorPluginVersion(){return`copilot-chat/${this.copilotVersion}`}get userAgent(){return`GitHubCopilotChat/${this.copilotVersion}`}},f=new De;var ue=v(require("fs")),Qe=require("child_process"),Ze=v(require("path"));function et(){let t=E();return ue.default.mkdirSync(t,{recursive:!0}),Ze.default.join(t,"github_token.txt")}function Dt(){let t=et();if(!ue.default.existsSync(t))return null;try{let e=ue.default.readFileSync(t,"utf-8").trim();if(e)return console.log(`Loaded GitHub token from ${t}`),e}catch(e){console.log(`Failed to read token file: ${e}`)}return null}function qt(t){try{let e=et();ue.default.writeFileSync(e,t,"utf-8"),console.log(`Saved GitHub token to ${e}`)}catch(e){console.log(`Failed to save token file: ${e}`)}}function It(t){let e=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";(0,Qe.exec)(`${e} ${t}`,()=>{})}function Nt(t){return new Promise(e=>setTimeout(e,t))}async function Lt(){console.log(`
61
- `+"=".repeat(60)),console.log("GitHub Device Flow Authentication"),console.log("=".repeat(60));let t=await fetch("https://github.com/login/device/code",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:Ee,scope:"read:user copilot"})});if(!t.ok)return console.log(`Failed to get device code: ${t.status} ${await t.text()}`),null;let e=await t.json(),{device_code:o,user_code:n,verification_uri:s,expires_in:r=900}=e,i=e.interval??5;console.log(`
67
+ `;le.default.writeFileSync(e,o,"utf-8"),console.log(`Configuration file generated at: ${e}`)}var je=class{githubToken="";copilotToken=null;models=null;accountType="individual";tokenExpiresAt=0;vscodeVersion=ge;copilotVersion=pe;apiVersion=de;systemPromptRemove=[];systemPromptAdd=[];toolResultSuffixRemove=[];redirectAnthropic=!1;maxConnectionRetries=3;get editorPluginVersion(){return`copilot-chat/${this.copilotVersion}`}get userAgent(){return`GitHubCopilotChat/${this.copilotVersion}`}},_=new je;var fe=v(require("fs")),nt=require("child_process"),ot=v(require("path"));function st(){let t=D();return fe.default.mkdirSync(t,{recursive:!0}),ot.default.join(t,"github_token.txt")}function It(){let t=st();if(!fe.default.existsSync(t))return null;try{let e=fe.default.readFileSync(t,"utf-8").trim();if(e)return console.log(`Loaded GitHub token from ${t}`),e}catch(e){console.log(`Failed to read token file: ${e}`)}return null}function Ut(t){try{let e=st();fe.default.writeFileSync(e,t,"utf-8"),console.log(`Saved GitHub token to ${e}`)}catch(e){console.log(`Failed to save token file: ${e}`)}}function jt(t){let e=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";(0,nt.exec)(`${e} ${t}`,()=>{})}function Ft(t){return new Promise(e=>setTimeout(e,t))}async function Mt(){console.log(`
68
+ `+"=".repeat(60)),console.log("GitHub Device Flow Authentication"),console.log("=".repeat(60));let t=await fetch("https://github.com/login/device/code",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:Ie,scope:"read:user copilot"})});if(!t.ok)return console.log(`Failed to get device code: ${t.status} ${await t.text()}`),null;let e=await t.json(),{device_code:o,user_code:n,verification_uri:s,expires_in:r=900}=e,i=e.interval??5;console.log(`
62
69
  Please visit: ${s}`),console.log(`And enter the code: ${n}`),console.log(`
63
- Waiting for authorization (expires in ${r} seconds)...`),It(s),console.log("(Browser opened automatically)");let c=Date.now()+r*1e3;for(;Date.now()<c;){await Nt(i*1e3);let a=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:Ee,device_code:o,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})});if(!a.ok)continue;let l=await a.json();if(l.error==="authorization_pending"){process.stdout.write(".");continue}if(l.error==="slow_down"){i+=5;continue}if(l.error==="expired_token")return console.log(`
64
- Authorization expired. Please try again.`),null;if(l.error==="access_denied")return console.log(`
65
- Authorization denied by user.`),null;if(l.error)return console.log(`
66
- Error: ${l.error_description||l.error}`),null;if(l.access_token)return console.log(`
67
-
68
- Authorization successful!`),l.access_token}return console.log(`
69
- Authorization timed out. Please try again.`),null}async function he(){let t=(process.env.GITHUB_TOKEN||"").trim();if(t)return console.log("Using GitHub token from GITHUB_TOKEN environment variable"),t;let e=Dt();if(e)return e;console.log(`
70
- No GitHub token found. Starting GitHub Device Flow authentication...`);let o=await Lt();return o?(qt(o),o):null}function N(){return f.accountType==="individual"?"https://api.githubcopilot.com":`https://api.${f.accountType}.githubcopilot.com`}function Ut(){return{"Content-Type":"application/json",Accept:"application/json",Authorization:`token ${f.githubToken}`,"Editor-Version":`vscode/${f.vscodeVersion}`,"Editor-Plugin-Version":f.editorPluginVersion,"User-Agent":f.userAgent,"X-GitHub-Api-Version":f.apiVersion,"X-VSCode-User-Agent-Library-Version":"electron-fetch"}}function Y(t=!1){let e={Authorization:`Bearer ${f.copilotToken}`,"Content-Type":"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":`vscode/${f.vscodeVersion}`,"Editor-Plugin-Version":f.editorPluginVersion,"User-Agent":f.userAgent,"OpenAI-Intent":"conversation-panel","X-GitHub-Api-Version":f.apiVersion,"X-Request-Id":crypto.randomUUID(),"X-VSCode-User-Agent-Library-Version":"electron-fetch"};return t&&(e["Copilot-Vision-Request"]="true"),e}async function pe(){if(f.copilotToken&&Date.now()/1e3<f.tokenExpiresAt-60)return;console.log("Refreshing Copilot token...");let t=await fetch(`${Ke}/copilot_internal/v2/token`,{headers:Ut()});if(!t.ok)throw new Error(`Failed to get Copilot token: ${t.status} ${await t.text()}`);let e=await t.json();f.copilotToken=e.token,f.tokenExpiresAt=Date.now()/1e3+(e.refresh_in??1800),console.log("Copilot token refreshed successfully")}async function U(){(!f.copilotToken||Date.now()/1e3>=f.tokenExpiresAt-60)&&await pe()}async function te(){await U();let t=await fetch(`${N()}/models`,{headers:Y()});t.ok?(f.models=await t.json(),console.log(`Loaded ${f.models.data?.length??0} models`)):console.log(`Failed to fetch models: ${t.status}`)}function tt(t){return f.redirectAnthropic?!1:f.models?.data?.find(o=>o.id===t)?.supported_endpoints?.includes("/v1/messages")??!1}function nt(t){return f.models?.data?.find(o=>o.id===t)?.supported_endpoints?.includes("/responses")??!1}function j(t){return Math.ceil(t.length/4)}var Q=v(require("fs")),ye=v(require("path"));function Z(t,e,o,n){let s=E();Q.default.mkdirSync(s,{recursive:!0});let r=ye.default.join(s,"error.log"),i={timestamp:new Date().toISOString(),endpoint:t,status_code:n,request:e,response:o};Q.default.appendFileSync(r,JSON.stringify(i)+`
71
- `,"utf-8")}function Re(t,e,o,n,s){try{let r=E();Q.default.mkdirSync(r,{recursive:!0});let i=ye.default.join(r,"connection_retry.jl"),c={timestamp:new Date().toISOString(),request_id:t,endpoint:e,attempt:o+1,max_attempts:n+1,error_type:s.constructor.name,error_message:s.message};Q.default.appendFileSync(i,JSON.stringify(c)+`
72
- `,"utf-8")}catch{}}function ke(t){try{let e=E();Q.default.mkdirSync(e,{recursive:!0});let o=ye.default.join(e,"tool_result_cleanup.jl");t.timestamp=new Date().toISOString(),Q.default.appendFileSync(o,JSON.stringify(t)+`
73
- `,"utf-8")}catch{}}function qe(t){let e=[],o="unexpected `tool_use_id` found in `tool_result` blocks: ",n=t.indexOf(o);if(n!==-1){let s=n+o.length,r=s;for(;r<t.length&&!/[. "'\\\n]/.test(t[r]);)r++;let i=t.slice(s,r).trim();i&&e.push(i)}if(e.length===0){let s=t;for(;s.includes("toolu_");){let r=s.indexOf("toolu_"),i=r+6;for(;i<s.length&&/[\w-]/.test(s[i]);)i++;let c=s.slice(r,i);c&&!e.includes(c)&&e.push(c),s=s.slice(i)}}return e}function Ie(t,e){if(!e.length)return t;let o=new Set(e),n=[];for(let s of t){if(s.role!=="user"){n.push(s);continue}let r=s.content;if(!Array.isArray(r)){n.push(s);continue}let i=r.filter(c=>c.type==="tool_result"&&o.has(c.tool_use_id)?(console.log(`[Tool Result Cleanup] Removing orphaned tool_result: ${c.tool_use_id}`),!1):!0);i.length>0&&n.push({...s,content:i})}return n}function Ne(t,e){return t===400&&e.includes("tool_use_id")&&e.includes("tool_result")}function Le(){console.log(`
74
- `+"=".repeat(60)),console.log("Model Name Mappings"),console.log("=".repeat(60));let t=Object.entries(J.exactMappings);if(t.length){console.log(`
70
+ Waiting for authorization (expires in ${r} seconds)...`),jt(s),console.log("(Browser opened automatically)");let c=Date.now()+r*1e3;for(;Date.now()<c;){await Ft(i*1e3);let a=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:Ie,device_code:o,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})});if(!a.ok)continue;let u=await a.json();if(u.error==="authorization_pending"){process.stdout.write(".");continue}if(u.error==="slow_down"){i+=5;continue}if(u.error==="expired_token")return console.log(`
71
+ Authorization expired. Please try again.`),null;if(u.error==="access_denied")return console.log(`
72
+ Authorization denied by user.`),null;if(u.error)return console.log(`
73
+ Error: ${u.error_description||u.error}`),null;if(u.access_token)return console.log(`
74
+
75
+ Authorization successful!`),u.access_token}return console.log(`
76
+ Authorization timed out. Please try again.`),null}async function $e(){let t=(process.env.GITHUB_TOKEN||"").trim();if(t)return console.log("Using GitHub token from GITHUB_TOKEN environment variable"),t;let e=It();if(e)return e;console.log(`
77
+ No GitHub token found. Starting GitHub Device Flow authentication...`);let o=await Mt();return o?(Ut(o),o):null}function I(){return _.accountType==="individual"?"https://api.githubcopilot.com":`https://api.${_.accountType}.githubcopilot.com`}function Ht(){return{"Content-Type":"application/json",Accept:"application/json",Authorization:`token ${_.githubToken}`,"Editor-Version":`vscode/${_.vscodeVersion}`,"Editor-Plugin-Version":_.editorPluginVersion,"User-Agent":_.userAgent,"X-GitHub-Api-Version":_.apiVersion,"X-VSCode-User-Agent-Library-Version":"electron-fetch"}}function te(t=!1){let e={Authorization:`Bearer ${_.copilotToken}`,"Content-Type":"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":`vscode/${_.vscodeVersion}`,"Editor-Plugin-Version":_.editorPluginVersion,"User-Agent":_.userAgent,"OpenAI-Intent":"conversation-panel","X-GitHub-Api-Version":_.apiVersion,"X-Request-Id":crypto.randomUUID(),"X-VSCode-User-Agent-Library-Version":"electron-fetch"};return t&&(e["Copilot-Vision-Request"]="true"),e}async function me(){if(_.copilotToken&&Date.now()/1e3<_.tokenExpiresAt-60)return;console.log("Refreshing Copilot token...");let t=await fetch(`${et}/copilot_internal/v2/token`,{headers:Ht()});if(!t.ok)throw new Error(`Failed to get Copilot token: ${t.status} ${await t.text()}`);let e=await t.json();_.copilotToken=e.token,_.tokenExpiresAt=Date.now()/1e3+(e.refresh_in??1800),console.log("Copilot token refreshed successfully")}async function F(){(!_.copilotToken||Date.now()/1e3>=_.tokenExpiresAt-60)&&await me()}async function se(){await F();let t=await fetch(`${I()}/models`,{headers:te()});t.ok?(_.models=await t.json(),console.log(`Loaded ${_.models.data?.length??0} models`)):console.log(`Failed to fetch models: ${t.status}`)}function rt(t){return _.redirectAnthropic?!1:_.models?.data?.find(o=>o.id===t)?.supported_endpoints?.includes("/v1/messages")??!1}function it(t){return _.models?.data?.find(o=>o.id===t)?.supported_endpoints?.includes("/responses")??!1}function M(t){return Math.ceil(t.length/4)}var ne=v(require("fs")),Se=v(require("path"));function oe(t,e,o,n){let s=D();ne.default.mkdirSync(s,{recursive:!0});let r=Se.default.join(s,"error.log"),i={timestamp:new Date().toISOString(),endpoint:t,status_code:n,request:e,response:o};ne.default.appendFileSync(r,JSON.stringify(i)+`
78
+ `,"utf-8")}function be(t,e,o,n,s){try{let r=D();ne.default.mkdirSync(r,{recursive:!0});let i=Se.default.join(r,"connection_retry.jl"),c={timestamp:new Date().toISOString(),request_id:t,endpoint:e,attempt:o+1,max_attempts:n+1,error_type:s.constructor.name,error_message:s.message};ne.default.appendFileSync(i,JSON.stringify(c)+`
79
+ `,"utf-8")}catch{}}function xe(t){try{let e=D();ne.default.mkdirSync(e,{recursive:!0});let o=Se.default.join(e,"tool_result_cleanup.jl");t.timestamp=new Date().toISOString(),ne.default.appendFileSync(o,JSON.stringify(t)+`
80
+ `,"utf-8")}catch{}}function Fe(t){let e=[],o="unexpected `tool_use_id` found in `tool_result` blocks: ",n=t.indexOf(o);if(n!==-1){let s=n+o.length,r=s;for(;r<t.length&&!/[. "'\\\n]/.test(t[r]);)r++;let i=t.slice(s,r).trim();i&&e.push(i)}if(e.length===0){let s=t;for(;s.includes("toolu_");){let r=s.indexOf("toolu_"),i=r+6;for(;i<s.length&&/[\w-]/.test(s[i]);)i++;let c=s.slice(r,i);c&&!e.includes(c)&&e.push(c),s=s.slice(i)}}return e}function Me(t,e){if(!e.length)return t;let o=new Set(e),n=[];for(let s of t){if(s.role!=="user"){n.push(s);continue}let r=s.content;if(!Array.isArray(r)){n.push(s);continue}let i=r.filter(c=>c.type==="tool_result"&&o.has(c.tool_use_id)?(console.log(`[Tool Result Cleanup] Removing orphaned tool_result: ${c.tool_use_id}`),!1):!0);i.length>0&&n.push({...s,content:i})}return n}function He(t,e){return t===400&&e.includes("tool_use_id")&&e.includes("tool_result")}function Be(){console.log(`
81
+ `+"=".repeat(60)),console.log("Model Name Mappings"),console.log("=".repeat(60));let t=Object.entries(G.exactMappings);if(t.length){console.log(`
75
82
  Exact Mappings:`);for(let[o,n]of t)console.log(` ${o} -> ${n}`)}else console.log(`
76
- Exact Mappings: (none)`);let e=Object.entries(J.prefixMappings);if(e.length){console.log(`
83
+ Exact Mappings: (none)`);let e=Object.entries(G.prefixMappings);if(e.length){console.log(`
77
84
  Prefix Mappings:`);for(let[o,n]of e)console.log(` ${o}* -> ${n}`)}else console.log(`
78
85
  Prefix Mappings: (none)`);console.log("=".repeat(60)+`
79
- `)}function Ue(){if(!f.models?.data?.length){console.log("No models available yet.");return}console.log(`
80
- `+"=".repeat(60)),console.log("Available Models"),console.log("=".repeat(60));for(let t of f.models.data){let e=t.capabilities,o=c=>c&&c>=1e3?`${Math.floor(c/1e3)}K`:String(c??"N/A"),n=o(e?.limits?.max_context_window_tokens),s=o(e?.limits?.max_prompt_tokens),r=o(e?.limits?.max_output_tokens),i=[];e?.supports?.vision&&i.push("Vision"),e?.supports?.tool_calls&&i.push("Tool"),t.supported_endpoints?.includes("/v1/messages")&&i.push("Anthropic"),t.preview&&i.push("Preview"),console.log(`${t.id.padEnd(30)} ctx: ${n} in: ${s} out: ${r} [${t.vendor??"unknown"}] (${i.join(",")})`)}console.log(`
86
+ `)}function ze(){if(!_.models?.data?.length){console.log("No models available yet.");return}console.log(`
87
+ `+"=".repeat(60)),console.log("Available Models"),console.log("=".repeat(60));for(let t of _.models.data){let e=t.capabilities,o=c=>c&&c>=1e3?`${Math.floor(c/1e3)}K`:String(c??"N/A"),n=o(e?.limits?.max_context_window_tokens),s=o(e?.limits?.max_prompt_tokens),r=o(e?.limits?.max_output_tokens),i=[];e?.supports?.vision&&i.push("Vision"),e?.supports?.tool_calls&&i.push("Tool"),t.supported_endpoints?.includes("/v1/messages")&&i.push("Anthropic"),t.preview&&i.push("Preview"),console.log(`${t.id.padEnd(30)} ctx: ${n} in: ${s} out: ${r} [${t.vendor??"unknown"}] (${i.join(",")})`)}console.log(`
81
88
  `+"=".repeat(60)+`
82
- `)}var rt=require("express");var je=class{cache=new Map;maxEntries;requestCount=0;bytesSent=0;bytesReceived=0;modelStats={};endpointStats={};constructor(e=1e3){this.maxEntries=e}startRequest(e,o){this.evictIfFull(),this.cache.set(e,{id:e,timestamp:new Date().toISOString(),original_request_body:o.original_request_body??null,request_body:o.request_body??null,response_body:null,model:o.model??"unknown",translated_model:o.translated_model??null,endpoint:o.endpoint??"unknown",status_code:null,request_size:o.request_size??0,response_size:0,input_tokens:0,output_tokens:0,duration:0,state:"pending"})}updateRequestState(e,o,n){let s=this.cache.get(e);s&&(s.state=o,n&&Object.assign(s,n))}completeRequest(e,o){let n=this.cache.get(e);n?Object.assign(n,{response_body:o.response_body,status_code:o.status_code??200,response_size:o.response_size??0,input_tokens:o.input_tokens??0,output_tokens:o.output_tokens??0,duration:o.duration??0,state:(o.status_code??200)<400?"completed":"error"}):(this.evictIfFull(),n={id:e,timestamp:new Date().toISOString(),original_request_body:o.original_request_body??null,request_body:o.request_body??null,response_body:o.response_body??null,model:o.model??"unknown",translated_model:o.translated_model??null,endpoint:o.endpoint??"unknown",status_code:o.status_code??200,request_size:o.request_size??0,response_size:o.response_size??0,input_tokens:o.input_tokens??0,output_tokens:o.output_tokens??0,duration:o.duration??0,state:(o.status_code??200)<400?"completed":"error"},this.cache.set(e,n)),this.requestCount++,this.bytesSent+=o.request_size??0,this.bytesReceived+=o.response_size??0,this.updateModelStats(o),this.updateEndpointStats(o)}addRequest(e,o){this.cache.has(e)?this.completeRequest(e,o):(this.startRequest(e,o),this.completeRequest(e,o))}getRequest(e){return this.cache.get(e)}getRecentRequests(e=50,o=0){return[...this.cache.values()].reverse().slice(o,o+e)}getTotalCount(){return this.cache.size}getStats(){return{total_requests:this.requestCount,cached_requests:this.cache.size,bytes_sent:this.bytesSent,bytes_received:this.bytesReceived,model_stats:{...this.modelStats},endpoint_stats:{...this.endpointStats}}}searchRequests(e,o=50,n=0){let s=e.toLowerCase(),r=[];for(let i of[...this.cache.values()].reverse())(i.model.toLowerCase().includes(s)||i.endpoint.toLowerCase().includes(s)||JSON.stringify(i.request_body).toLowerCase().includes(s))&&r.push(i);return r.slice(n,n+o)}fulltextSearch(e,o=50,n=0){let s=e.toLowerCase(),r=[];for(let i of[...this.cache.values()].reverse()){let c=JSON.stringify(i.request_body).toLowerCase(),a=JSON.stringify(i.response_body).toLowerCase();(c.includes(s)||a.includes(s))&&r.push(i)}return[r.slice(n,n+o),r.length]}getAllRequests(){return[...this.cache.values()]}importRequest(e){let o=e.id||crypto.randomUUID();this.evictIfFull();let n={id:o,timestamp:e.timestamp||new Date().toISOString(),original_request_body:e.original_request_body??null,request_body:e.request_body??null,response_body:e.response_body??null,model:e.model||"unknown",translated_model:e.translated_model||null,endpoint:e.endpoint||"unknown",status_code:e.status_code??200,request_size:e.request_size??0,response_size:e.response_size??0,input_tokens:e.input_tokens??0,output_tokens:e.output_tokens??0,duration:e.duration??0,state:e.state||"completed"};this.cache.set(o,n),this.requestCount++,this.bytesSent+=n.request_size,this.bytesReceived+=n.response_size,this.updateModelStats(n),this.updateEndpointStats(n)}evictIfFull(){if(this.cache.size>=this.maxEntries){let e=this.cache.keys().next().value;this.cache.delete(e)}}updateModelStats(e){let o=e.model??"unknown";this.modelStats[o]||(this.modelStats[o]={request_count:0,input_tokens:0,output_tokens:0,bytes_sent:0,bytes_received:0});let n=this.modelStats[o];n.request_count++,n.input_tokens+=e.input_tokens??0,n.output_tokens+=e.output_tokens??0,n.bytes_sent+=e.request_size??0,n.bytes_received+=e.response_size??0}updateEndpointStats(e){let o=e.endpoint??"unknown";this.endpointStats[o]||(this.endpointStats[o]={request_count:0,bytes_sent:0,bytes_received:0});let n=this.endpointStats[o];n.request_count++,n.bytes_sent+=e.request_size??0,n.bytes_received+=e.response_size??0}},$=new je;function ne(t){return J.translate(t)}function $e(t){for(let e of f.systemPromptRemove)t.includes(e)&&(t=t.replaceAll(e,""),console.log(`[Content Filter] Removed from system prompt: ${e.slice(0,50)}${e.length>50?"...":""}`));return t}function Fe(t){for(let e of f.toolResultSuffixRemove)t.endsWith(e)&&(t=t.slice(0,-e.length),console.log(`[Content Filter] Removed suffix from tool result: ${e.slice(0,50)}${e.length>50?"...":""}`));return t}function ot(t){let e=[],o=t.system;if(o){if(typeof o=="string")e.push({role:"system",content:$e(o)});else if(Array.isArray(o)){let r=o.filter(i=>i.type==="text"&&!(i.text||"").includes("x-anthropic-billing-header")).map(i=>i.text);r.length&&e.push({role:"system",content:$e(r.join(`
89
+ `)}var ut=require("express");var Je=class{cache=new Map;maxEntries;requestCount=0;bytesSent=0;bytesReceived=0;modelStats={};endpointStats={};constructor(e=1e3){this.maxEntries=e}startRequest(e,o){this.evictIfFull(),this.cache.set(e,{id:e,timestamp:new Date().toISOString(),original_request_body:o.original_request_body??null,request_body:o.request_body??null,response_body:null,model:o.model??"unknown",translated_model:o.translated_model??null,endpoint:o.endpoint??"unknown",status_code:null,request_size:o.request_size??0,response_size:0,input_tokens:0,output_tokens:0,duration:0,state:"pending"})}updateRequestState(e,o,n){let s=this.cache.get(e);s&&(s.state=o,n&&Object.assign(s,n))}completeRequest(e,o){let n=this.cache.get(e);n?Object.assign(n,{response_body:o.response_body,status_code:o.status_code??200,response_size:o.response_size??0,input_tokens:o.input_tokens??0,output_tokens:o.output_tokens??0,duration:o.duration??0,state:(o.status_code??200)<400?"completed":"error"}):(this.evictIfFull(),n={id:e,timestamp:new Date().toISOString(),original_request_body:o.original_request_body??null,request_body:o.request_body??null,response_body:o.response_body??null,model:o.model??"unknown",translated_model:o.translated_model??null,endpoint:o.endpoint??"unknown",status_code:o.status_code??200,request_size:o.request_size??0,response_size:o.response_size??0,input_tokens:o.input_tokens??0,output_tokens:o.output_tokens??0,duration:o.duration??0,state:(o.status_code??200)<400?"completed":"error"},this.cache.set(e,n)),this.requestCount++,this.bytesSent+=o.request_size??0,this.bytesReceived+=o.response_size??0,this.updateModelStats(o),this.updateEndpointStats(o)}addRequest(e,o){this.cache.has(e)?this.completeRequest(e,o):(this.startRequest(e,o),this.completeRequest(e,o))}getRequest(e){return this.cache.get(e)}getRecentRequests(e=50,o=0){return[...this.cache.values()].reverse().slice(o,o+e)}getTotalCount(){return this.cache.size}getStats(){return{total_requests:this.requestCount,cached_requests:this.cache.size,bytes_sent:this.bytesSent,bytes_received:this.bytesReceived,model_stats:{...this.modelStats},endpoint_stats:{...this.endpointStats}}}searchRequests(e,o=50,n=0){let s=e.toLowerCase(),r=[];for(let i of[...this.cache.values()].reverse())(i.model.toLowerCase().includes(s)||i.endpoint.toLowerCase().includes(s)||JSON.stringify(i.request_body).toLowerCase().includes(s))&&r.push(i);return r.slice(n,n+o)}fulltextSearch(e,o=50,n=0){let s=e.toLowerCase(),r=[];for(let i of[...this.cache.values()].reverse()){let c=JSON.stringify(i.request_body).toLowerCase(),a=JSON.stringify(i.response_body).toLowerCase();(c.includes(s)||a.includes(s))&&r.push(i)}return[r.slice(n,n+o),r.length]}getAllRequests(){return[...this.cache.values()]}importRequest(e){let o=e.id||crypto.randomUUID();this.evictIfFull();let n={id:o,timestamp:e.timestamp||new Date().toISOString(),original_request_body:e.original_request_body??null,request_body:e.request_body??null,response_body:e.response_body??null,model:e.model||"unknown",translated_model:e.translated_model||null,endpoint:e.endpoint||"unknown",status_code:e.status_code??200,request_size:e.request_size??0,response_size:e.response_size??0,input_tokens:e.input_tokens??0,output_tokens:e.output_tokens??0,duration:e.duration??0,state:e.state||"completed"};this.cache.set(o,n),this.requestCount++,this.bytesSent+=n.request_size,this.bytesReceived+=n.response_size,this.updateModelStats(n),this.updateEndpointStats(n)}evictIfFull(){if(this.cache.size>=this.maxEntries){let e=this.cache.keys().next().value;this.cache.delete(e)}}updateModelStats(e){let o=e.model??"unknown";this.modelStats[o]||(this.modelStats[o]={request_count:0,input_tokens:0,output_tokens:0,bytes_sent:0,bytes_received:0});let n=this.modelStats[o];n.request_count++,n.input_tokens+=e.input_tokens??0,n.output_tokens+=e.output_tokens??0,n.bytes_sent+=e.request_size??0,n.bytes_received+=e.response_size??0}updateEndpointStats(e){let o=e.endpoint??"unknown";this.endpointStats[o]||(this.endpointStats[o]={request_count:0,bytes_sent:0,bytes_received:0});let n=this.endpointStats[o];n.request_count++,n.bytes_sent+=e.request_size??0,n.bytes_received+=e.response_size??0}},$=new Je;function re(t){return t.clientDisconnected&&!t.streamCompleted?499:t.upstreamStatusCode}function ie(t){return G.translate(t)}function we(t){for(let e of _.systemPromptRemove)t.includes(e)&&(t=t.replaceAll(e,""),console.log(`[Content Filter] Removed from system prompt: ${e.slice(0,50)}${e.length>50?"...":""}`));return t}function Ve(t){for(let e of _.toolResultSuffixRemove)t.endsWith(e)&&(t=t.slice(0,-e.length),console.log(`[Content Filter] Removed suffix from tool result: ${e.slice(0,50)}${e.length>50?"...":""}`));return t}function ct(t){let e=[],o=t.system;if(o){if(typeof o=="string")e.push({role:"system",content:we(o)});else if(Array.isArray(o)){let r=o.filter(i=>i.type==="text"&&!(i.text||"").includes("x-anthropic-billing-header")).map(i=>i.text);r.length&&e.push({role:"system",content:we(r.join(`
83
90
 
84
- `))})}}for(let r of t.messages||[]){let i=r.role,c=r.content;if(i==="user")if(Array.isArray(c)){let a=c.filter(p=>p.type==="tool_result"),l=c.filter(p=>p.type!=="tool_result");for(let p of a){let u=p.content??"";typeof u=="string"&&(u=Fe(u)),e.push({role:"tool",tool_call_id:p.tool_use_id,content:u})}if(l.length){let p=jt(l);p!=null&&e.push({role:"user",content:p})}}else e.push({role:"user",content:c});else if(i==="assistant")if(Array.isArray(c)){let a=c.filter(u=>u.type==="tool_use"),p=c.filter(u=>u.type==="text"||u.type==="thinking").map(u=>(u.type==="text"?u.text:u.thinking)??"").join(`
91
+ `))})}}for(let r of t.messages||[]){let i=r.role,c=r.content;if(i==="user")if(Array.isArray(c)){let a=c.filter(p=>p.type==="tool_result"),u=c.filter(p=>p.type!=="tool_result");for(let p of a){let l=p.content??"";typeof l=="string"&&(l=Ve(l)),e.push({role:"tool",tool_call_id:p.tool_use_id,content:l})}if(u.length){let p=Bt(u);p!=null&&e.push({role:"user",content:p})}}else e.push({role:"user",content:c});else if(i==="assistant")if(Array.isArray(c)){let a=c.filter(l=>l.type==="tool_use"),p=c.filter(l=>l.type==="text"||l.type==="thinking").map(l=>(l.type==="text"?l.text:l.thinking)??"").join(`
85
92
 
86
- `);a.length?e.push({role:"assistant",content:p||null,tool_calls:a.map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.input??{})}}))}):e.push({role:"assistant",content:p})}else e.push({role:"assistant",content:c})}let n={model:ne(t.model??""),messages:e,max_tokens:t.max_tokens,stream:t.stream??!1};t.temperature!=null&&(n.temperature=t.temperature),t.top_p!=null&&(n.top_p=t.top_p),t.stop_sequences&&(n.stop=t.stop_sequences),Array.isArray(t.tools)&&(n.tools=t.tools.map(r=>({type:"function",function:{name:r.name,description:r.description,parameters:r.input_schema??{}}})));let s=t.tool_choice;if(s){let r=s.type;r==="auto"?n.tool_choice="auto":r==="any"?n.tool_choice="required":r==="none"?n.tool_choice="none":r==="tool"&&s.name&&(n.tool_choice={type:"function",function:{name:s.name}})}return n}function jt(t){if(!t.some(n=>n.type==="image")){let n=[];for(let s of t)s.type==="text"?n.push(s.text??""):s.type==="thinking"&&n.push(s.thinking??"");return n.length?n.join(`
93
+ `);a.length?e.push({role:"assistant",content:p||null,tool_calls:a.map(l=>({id:l.id,type:"function",function:{name:l.name,arguments:JSON.stringify(l.input??{})}}))}):e.push({role:"assistant",content:p})}else e.push({role:"assistant",content:c})}let n={model:ie(t.model??""),messages:e,max_tokens:t.max_tokens,stream:t.stream??!1};t.temperature!=null&&(n.temperature=t.temperature),t.top_p!=null&&(n.top_p=t.top_p),t.stop_sequences&&(n.stop=t.stop_sequences),Array.isArray(t.tools)&&(n.tools=t.tools.map(r=>({type:"function",function:{name:r.name,description:r.description,parameters:r.input_schema??{}}})));let s=t.tool_choice;if(s){let r=s.type;r==="auto"?n.tool_choice="auto":r==="any"?n.tool_choice="required":r==="none"?n.tool_choice="none":r==="tool"&&s.name&&(n.tool_choice={type:"function",function:{name:s.name}})}return n}function Bt(t){if(!t.some(n=>n.type==="image")){let n=[];for(let s of t)s.type==="text"?n.push(s.text??""):s.type==="thinking"&&n.push(s.thinking??"");return n.length?n.join(`
87
94
 
88
- `):null}let o=[];for(let n of t)if(n.type==="text")o.push({type:"text",text:n.text});else if(n.type==="thinking")o.push({type:"text",text:n.thinking});else if(n.type==="image"){let s=n.source;o.push({type:"image_url",image_url:{url:`data:${s?.media_type};base64,${s?.data}`}})}return o.length?o:null}var Ft={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"refusal"};function Me(t){return t?Ft[t]??null:null}function He(t){let e=[],o=null;for(let i of t.choices||[]){let c=i.message;if(c){if(c.content&&e.push({type:"text",text:c.content}),Array.isArray(c.tool_calls))for(let a of c.tool_calls){let l=a.function,p;try{p=JSON.parse(l.arguments||"{}")}catch{p={_raw_arguments:l.arguments}}e.push({type:"tool_use",id:a.id,name:l.name,input:p})}i.finish_reason&&(o=i.finish_reason)}}let n=t.usage??{},s=n.prompt_tokens_details?.cached_tokens??0,r=(n.prompt_tokens??0)-s;return{id:t.id??crypto.randomUUID(),type:"message",role:"assistant",content:e,model:t.model??"",stop_reason:Me(o),stop_sequence:null,usage:{input_tokens:r,output_tokens:n.completion_tokens??0,...s?{cache_read_input_tokens:s}:{}}}}var be=class{messageStartSent=!1;contentBlockIndex=0;contentBlockOpen=!1;toolCalls={}};function st(t,e){let o=[];if(!t.choices?.length)return o;let n=t.choices[0],s=n.delta??{};if(!e.messageStartSent){let r=t.usage??{},i=r.prompt_tokens_details?.cached_tokens??0;o.push({type:"message_start",message:{id:t.id??crypto.randomUUID(),type:"message",role:"assistant",content:[],model:t.model??"",stop_reason:null,stop_sequence:null,usage:{input_tokens:(r.prompt_tokens??0)-i,output_tokens:0,...i?{cache_read_input_tokens:i}:{}}}}),e.messageStartSent=!0}if(s.content&&(e.contentBlockOpen&&Object.values(e.toolCalls).some(r=>r.anthropicBlockIndex===e.contentBlockIndex)&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.contentBlockOpen=!1),e.contentBlockOpen||(o.push({type:"content_block_start",index:e.contentBlockIndex,content_block:{type:"text",text:""}}),e.contentBlockOpen=!0),o.push({type:"content_block_delta",index:e.contentBlockIndex,delta:{type:"text_delta",text:s.content}})),s.tool_calls)for(let r of s.tool_calls){let i=r.index??0;if(r.id&&r.function?.name){e.contentBlockOpen&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.contentBlockOpen=!1);let c=e.contentBlockIndex;e.toolCalls[i]={id:r.id,name:r.function.name,anthropicBlockIndex:c},o.push({type:"content_block_start",index:c,content_block:{type:"tool_use",id:r.id,name:r.function.name,input:{}}}),e.contentBlockOpen=!0}if(r.function?.arguments){let c=e.toolCalls[i];c&&o.push({type:"content_block_delta",index:c.anthropicBlockIndex,delta:{type:"input_json_delta",partial_json:r.function.arguments}})}}if(n.finish_reason){e.contentBlockOpen&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockOpen=!1);let r=t.usage??{},i=r.prompt_tokens_details?.cached_tokens??0;o.push({type:"message_delta",delta:{stop_reason:Me(n.finish_reason),stop_sequence:null},usage:{input_tokens:(r.prompt_tokens??0)-i,output_tokens:r.completion_tokens??0,...i?{cache_read_input_tokens:i}:{}}}),o.push({type:"message_stop"})}return o}function xe(t){if(!t.length)return{};let e=t[0],o=[],n={},s=null,r={};for(let a of t){a.usage&&(r=a.usage);for(let l of a.choices??[]){let p=l.delta;if(p?.content&&o.push(p.content),p?.tool_calls)for(let u of p.tool_calls){let m=u.index??0;n[m]||(n[m]={id:"",type:"function",function:{name:"",arguments:""}}),u.id&&(n[m].id=u.id),u.function?.name&&(n[m].function.name=u.function.name),u.function?.arguments&&(n[m].function.arguments+=u.function.arguments)}l.finish_reason&&(s=l.finish_reason)}}let i={role:"assistant",content:o.length?o.join(""):null},c=Object.keys(n).map(Number).sort((a,l)=>a-l);return c.length&&(i.tool_calls=c.map(a=>n[a])),{id:e.id??"",object:"chat.completion",created:e.created??0,model:e.model??"",choices:[{index:0,message:i,finish_reason:s}],usage:r}}var oe=(0,rt.Router)();oe.get(["/v1/models","/models"],async(t,e)=>{try{await U(),f.models||await te();let o=(f.models?.data??[]).map(n=>({id:n.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:n.vendor??"unknown",display_name:n.name??n.id}));e.json({object:"list",data:o,has_more:!1})}catch(o){e.status(500).json({error:String(o)})}});oe.get(["/v1/models/full/","/models/full/"],(t,e)=>{e.json(f.models)});oe.post(["/v1/chat/completions","/chat/completions"],async(t,e)=>{try{let o=Date.now();await U();let n=t.body,s=crypto.randomUUID(),r=n.model??"unknown",i=ne(r);i!==r&&(n={...n,model:i}),console.log(`[Chat Completions API] Using OpenAI Chat Completions path for: ${i}`);let c=(n.messages??[]).some(d=>Array.isArray(d.content)&&d.content.some(y=>y.type==="image_url")),a=(n.messages??[]).some(d=>d.role==="assistant"||d.role==="tool"),l=Y(c);l["X-Initiator"]=a?"agent":"user";let p=JSON.stringify(n).length;if(n.stream)return Mt(e,n,l,s,p,o,r,i);let u=await it(`${N()}/chat/completions`,{method:"POST",headers:l,body:JSON.stringify(n)},s,"/v1/chat/completions"),m=Math.round((Date.now()-o)/1e3*100)/100;if(!u)return e.status(504).json({error:`Upstream connection error after ${f.maxConnectionRetries+1} attempts`});let _=await u.text(),R=_.length;if(u.ok){let d=JSON.parse(_),y=d.usage??{};$.addRequest(s,{request_body:n,response_body:d,model:r,translated_model:i!==r?i:null,endpoint:"/v1/chat/completions",status_code:u.status,request_size:p,response_size:R,input_tokens:y.prompt_tokens??0,output_tokens:y.completion_tokens??0,duration:m}),e.json(d)}else Z("/v1/chat/completions",n,_,u.status),e.status(u.status).type("json").send(_)}catch(o){e.status(500).json({error:String(o)})}});async function Mt(t,e,o,n,s,r,i,c){$.startRequest(n,{request_body:e,model:i,translated_model:c!==i?c:null,endpoint:"/v1/chat/completions",request_size:s}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let a=[],l=0,p=0,u=200,m=!1;t.on("close",()=>{m=!0});try{$.updateRequestState(n,"sending");let d=await fetch(`${N()}/chat/completions`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});u=d.status;let y=d.body.getReader(),b=new TextDecoder,k="";for($.updateRequestState(n,"receiving");;){let{done:x,value:T}=await y.read();if(x)break;if(m){y.cancel();break}k+=b.decode(T,{stream:!0});let q=k.split(`
89
- `);k=q.pop();for(let C of q)if(C.trim()&&C.startsWith("data: ")){let H=C.slice(6);if(H==="[DONE]"){m||t.write(`data: [DONE]
95
+ `):null}let o=[];for(let n of t)if(n.type==="text")o.push({type:"text",text:n.text});else if(n.type==="thinking")o.push({type:"text",text:n.thinking});else if(n.type==="image"){let s=n.source;o.push({type:"image_url",image_url:{url:`data:${s?.media_type};base64,${s?.data}`}})}return o.length?o:null}var zt={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",content_filter:"refusal"};function Ge(t){return t?zt[t]??null:null}function We(t){let e=[],o=null;for(let i of t.choices||[]){let c=i.message;if(c){if(c.content&&e.push({type:"text",text:c.content}),Array.isArray(c.tool_calls))for(let a of c.tool_calls){let u=a.function,p;try{p=JSON.parse(u.arguments||"{}")}catch{p={_raw_arguments:u.arguments}}e.push({type:"tool_use",id:a.id,name:u.name,input:p})}i.finish_reason&&(o=i.finish_reason)}}let n=t.usage??{},s=n.prompt_tokens_details?.cached_tokens??0,r=(n.prompt_tokens??0)-s;return{id:t.id??crypto.randomUUID(),type:"message",role:"assistant",content:e,model:t.model??"",stop_reason:Ge(o),stop_sequence:null,usage:{input_tokens:r,output_tokens:n.completion_tokens??0,...s?{cache_read_input_tokens:s}:{}}}}var ve=class{messageStartSent=!1;contentBlockIndex=0;contentBlockOpen=!1;toolCalls={}};function at(t,e){let o=[];if(!t.choices?.length)return o;let n=t.choices[0],s=n.delta??{};if(!e.messageStartSent){let r=t.usage??{},i=r.prompt_tokens_details?.cached_tokens??0;o.push({type:"message_start",message:{id:t.id??crypto.randomUUID(),type:"message",role:"assistant",content:[],model:t.model??"",stop_reason:null,stop_sequence:null,usage:{input_tokens:(r.prompt_tokens??0)-i,output_tokens:0,...i?{cache_read_input_tokens:i}:{}}}}),e.messageStartSent=!0}if(s.content&&(e.contentBlockOpen&&Object.values(e.toolCalls).some(r=>r.anthropicBlockIndex===e.contentBlockIndex)&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.contentBlockOpen=!1),e.contentBlockOpen||(o.push({type:"content_block_start",index:e.contentBlockIndex,content_block:{type:"text",text:""}}),e.contentBlockOpen=!0),o.push({type:"content_block_delta",index:e.contentBlockIndex,delta:{type:"text_delta",text:s.content}})),s.tool_calls)for(let r of s.tool_calls){let i=r.index??0;if(r.id&&r.function?.name){e.contentBlockOpen&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockIndex++,e.contentBlockOpen=!1);let c=e.contentBlockIndex;e.toolCalls[i]={id:r.id,name:r.function.name,anthropicBlockIndex:c},o.push({type:"content_block_start",index:c,content_block:{type:"tool_use",id:r.id,name:r.function.name,input:{}}}),e.contentBlockOpen=!0}if(r.function?.arguments){let c=e.toolCalls[i];c&&o.push({type:"content_block_delta",index:c.anthropicBlockIndex,delta:{type:"input_json_delta",partial_json:r.function.arguments}})}}if(n.finish_reason){e.contentBlockOpen&&(o.push({type:"content_block_stop",index:e.contentBlockIndex}),e.contentBlockOpen=!1);let r=t.usage??{},i=r.prompt_tokens_details?.cached_tokens??0;o.push({type:"message_delta",delta:{stop_reason:Ge(n.finish_reason),stop_sequence:null},usage:{input_tokens:(r.prompt_tokens??0)-i,output_tokens:r.completion_tokens??0,...i?{cache_read_input_tokens:i}:{}}}),o.push({type:"message_stop"})}return o}function Ce(t){if(!t.length)return{};let e=t[0],o=[],n={},s=null,r={};for(let a of t){a.usage&&(r=a.usage);for(let u of a.choices??[]){let p=u.delta;if(p?.content&&o.push(p.content),p?.tool_calls)for(let l of p.tool_calls){let d=l.index??0;n[d]||(n[d]={id:"",type:"function",function:{name:"",arguments:""}}),l.id&&(n[d].id=l.id),l.function?.name&&(n[d].function.name=l.function.name),l.function?.arguments&&(n[d].function.arguments+=l.function.arguments)}u.finish_reason&&(s=u.finish_reason)}}let i={role:"assistant",content:o.length?o.join(""):null},c=Object.keys(n).map(Number).sort((a,u)=>a-u);return c.length&&(i.tool_calls=c.map(a=>n[a])),{id:e.id??"",object:"chat.completion",created:e.created??0,model:e.model??"",choices:[{index:0,message:i,finish_reason:s}],usage:r}}var ce=(0,ut.Router)();ce.get(["/v1/models","/models"],async(t,e)=>{try{await F(),_.models||await se();let o=(_.models?.data??[]).map(n=>({id:n.id,object:"model",type:"model",created:0,created_at:new Date(0).toISOString(),owned_by:n.vendor??"unknown",display_name:n.name??n.id}));e.json({object:"list",data:o,has_more:!1})}catch(o){e.status(500).json({error:String(o)})}});ce.get(["/v1/models/full/","/models/full/"],(t,e)=>{e.json(_.models)});ce.post(["/v1/chat/completions","/chat/completions"],async(t,e)=>{try{let o=Date.now();await F();let n=t.body,s=crypto.randomUUID(),r=n.model??"unknown",i=ie(r);i!==r&&(n={...n,model:i}),console.log(`[Chat Completions API] Using OpenAI Chat Completions path for: ${i}`);let c=(n.messages??[]).some(f=>Array.isArray(f.content)&&f.content.some(S=>S.type==="image_url")),a=(n.messages??[]).some(f=>f.role==="assistant"||f.role==="tool"),u=te(c);u["X-Initiator"]=a?"agent":"user";let p=JSON.stringify(n).length;if(n.stream)return Jt(e,n,u,s,p,o,r,i);let l=await lt(`${I()}/chat/completions`,{method:"POST",headers:u,body:JSON.stringify(n)},s,"/v1/chat/completions"),d=Math.round((Date.now()-o)/1e3*100)/100;if(!l)return e.status(504).json({error:`Upstream connection error after ${_.maxConnectionRetries+1} attempts`});let h=await l.text(),k=h.length;if(l.ok){let f=JSON.parse(h),S=f.usage??{};$.addRequest(s,{request_body:n,response_body:f,model:r,translated_model:i!==r?i:null,endpoint:"/v1/chat/completions",status_code:l.status,request_size:p,response_size:k,input_tokens:S.prompt_tokens??0,output_tokens:S.completion_tokens??0,duration:d}),e.json(f)}else oe("/v1/chat/completions",n,h,l.status),e.status(l.status).type("json").send(h)}catch(o){e.status(500).json({error:String(o)})}});async function Jt(t,e,o,n,s,r,i,c){$.startRequest(n,{request_body:e,model:i,translated_model:c!==i?c:null,endpoint:"/v1/chat/completions",request_size:s}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let a=[],u=0,p=0,l=200,d=!1,h=!1;t.on("close",()=>{d=!0});try{$.updateRequestState(n,"sending");let y=await fetch(`${I()}/chat/completions`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});l=y.status;let R=y.body.getReader(),b=new TextDecoder,C="";for($.updateRequestState(n,"receiving");;){let{done:A,value:j}=await R.read();if(A)break;if(d){R.cancel();break}C+=b.decode(j,{stream:!0});let N=C.split(`
96
+ `);C=N.pop();for(let O of N)if(O.trim()&&O.startsWith("data: ")){let z=O.slice(6);if(z==="[DONE]"){h=!0,d||t.write(`data: [DONE]
90
97
 
91
- `);continue}try{let I=JSON.parse(H);a.push(I),I.usage&&(l=I.usage.prompt_tokens??0,p=I.usage.completion_tokens??0),m||t.write(`data: ${H}
98
+ `);continue}try{let L=JSON.parse(z);a.push(L),L.usage&&(u=L.usage.prompt_tokens??0,p=L.usage.completion_tokens??0),d||t.write(`data: ${z}
92
99
 
93
- `)}catch{}}}}catch(d){u=504,console.log(`[Stream] Error for ${n}: ${d}`)}m?$.updateRequestState(n,"error",{status_code:499}):t.end();let _=Math.round((Date.now()-r)/1e3*100)/100,R=xe(a);$.completeRequest(n,{request_body:e,response_body:R,model:i,translated_model:c!==i?c:null,endpoint:"/v1/chat/completions",status_code:m?499:u,request_size:s,response_size:a.reduce((d,y)=>d+JSON.stringify(y).length,0),input_tokens:l,output_tokens:p,duration:_})}oe.post(["/v1/responses","/responses"],async(t,e)=>{try{let o=Date.now();await U();let n=t.body,s=crypto.randomUUID(),r=n.model??"unknown",i=ne(r);if(i!==r&&(n={...n,model:i}),!nt(i))return e.status(400).json({error:{message:`Model '${r}' does not support the /v1/responses endpoint.`,type:"invalid_request_error",code:"unsupported_model"}});if(console.log(`[Responses API] Using OpenAI Responses API path for: ${i}`),Array.isArray(n.tools)&&(n={...n,tools:n.tools.map(_=>_.type==="custom"&&_.name==="apply_patch"?{type:"function",name:"apply_patch",description:"Use the `apply_patch` tool to edit files",parameters:{type:"object",properties:{input:{type:"string",description:"The entire contents of the apply_patch command"}},required:["input"]},strict:!1}:_)}),Array.isArray(n.tools)){let _=new Set(["image_generation"]);n={...n,tools:n.tools.filter(R=>!(typeof R.type=="string"&&_.has(R.type)))}}if(Array.isArray(n.input)){let _=zt(n.input);_!==n.input&&(n={...n,input:_})}n={...n,service_tier:null};let c=Jt(n.input),a=Y(c);a["X-Initiator"]=Bt(n.input)?"agent":"user";let l=JSON.stringify(n).length;if(n.stream)return Ht(e,n,a,s,l,o,r,i);let p=await it(`${N()}/responses`,{method:"POST",headers:a,body:JSON.stringify(n)},s,"/v1/responses"),u=Math.round((Date.now()-o)/1e3*100)/100;if(!p)return e.status(504).json({error:`Upstream connection error after ${f.maxConnectionRetries+1} attempts`});let m=await p.text();if(p.ok){let _=JSON.parse(m),R=_.usage??{};$.addRequest(s,{request_body:n,response_body:_,model:r,translated_model:i!==r?i:null,endpoint:"/v1/responses",status_code:p.status,request_size:l,response_size:m.length,input_tokens:R.input_tokens??0,output_tokens:R.output_tokens??0,duration:u}),e.json(_)}else Z("/v1/responses",n,m,p.status),e.status(p.status).type("json").send(m)}catch(o){e.status(500).json({error:String(o)})}});async function Ht(t,e,o,n,s,r,i,c){$.startRequest(n,{request_body:e,model:i,translated_model:c!==i?c:null,endpoint:"/v1/responses",request_size:s}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let a=0,l=0,p=200,u={},m=[],_=!1;t.on("close",()=>{_=!0});try{$.updateRequestState(n,"sending");let y=await fetch(`${N()}/responses`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});if(p=y.status,y.ok){let b=y.body.getReader(),k=new TextDecoder,x="";for($.updateRequestState(n,"receiving");;){let{done:T,value:q}=await b.read();if(T)break;if(_){b.cancel();break}_||t.write(q),x+=k.decode(q,{stream:!0});let C=x.split(`
94
- `);x=C.pop();for(let H of C){let I=H.replace(/\r$/,"");if(!I.startsWith("data: "))continue;let V=I.slice(6);if(V!=="[DONE]")try{let A=JSON.parse(V);if(A.type==="response.completed"){let B=A.response??{};u=B;let O=B.usage??{};a=O.input_tokens??0,l=O.output_tokens??0}else A.type==="response.output_text.delta"&&m.push(A.delta??"")}catch{}}}}else{let b=await y.text();Z("/v1/responses",e,b,p),_||t.write(`event: error
100
+ `)}catch{}}}}catch(y){l=504,console.log(`[Stream] Error for ${n}: ${y}`)}let k=re({clientDisconnected:d,streamCompleted:h,upstreamStatusCode:l});k===499?$.updateRequestState(n,"error",{status_code:499}):d||t.end();let f=Math.round((Date.now()-r)/1e3*100)/100,S=Ce(a);$.completeRequest(n,{request_body:e,response_body:S,model:i,translated_model:c!==i?c:null,endpoint:"/v1/chat/completions",status_code:k,request_size:s,response_size:a.reduce((y,R)=>y+JSON.stringify(R).length,0),input_tokens:u,output_tokens:p,duration:f})}ce.post(["/v1/responses","/responses"],async(t,e)=>{try{let o=Date.now();await F();let n=t.body,s=crypto.randomUUID(),r=n.model??"unknown",i=ie(r);if(i!==r&&(n={...n,model:i}),!it(i))return e.status(400).json({error:{message:`Model '${r}' does not support the /v1/responses endpoint.`,type:"invalid_request_error",code:"unsupported_model"}});if(console.log(`[Responses API] Using OpenAI Responses API path for: ${i}`),Array.isArray(n.tools)&&(n={...n,tools:n.tools.map(h=>h.type==="custom"&&h.name==="apply_patch"?{type:"function",name:"apply_patch",description:"Use the `apply_patch` tool to edit files",parameters:{type:"object",properties:{input:{type:"string",description:"The entire contents of the apply_patch command"}},required:["input"]},strict:!1}:h)}),Array.isArray(n.tools)){let h=new Set(["image_generation"]);n={...n,tools:n.tools.filter(k=>!(typeof k.type=="string"&&h.has(k.type)))}}if(Array.isArray(n.input)){let h=Wt(n.input);h!==n.input&&(n={...n,input:h})}n={...n,service_tier:null};let c=Xt(n.input),a=te(c);a["X-Initiator"]=Gt(n.input)?"agent":"user";let u=JSON.stringify(n).length;if(n.stream)return Vt(e,n,a,s,u,o,r,i);let p=await lt(`${I()}/responses`,{method:"POST",headers:a,body:JSON.stringify(n)},s,"/v1/responses"),l=Math.round((Date.now()-o)/1e3*100)/100;if(!p)return e.status(504).json({error:`Upstream connection error after ${_.maxConnectionRetries+1} attempts`});let d=await p.text();if(p.ok){let h=JSON.parse(d),k=h.usage??{};$.addRequest(s,{request_body:n,response_body:h,model:r,translated_model:i!==r?i:null,endpoint:"/v1/responses",status_code:p.status,request_size:u,response_size:d.length,input_tokens:k.input_tokens??0,output_tokens:k.output_tokens??0,duration:l}),e.json(h)}else oe("/v1/responses",n,d,p.status),e.status(p.status).type("json").send(d)}catch(o){e.status(500).json({error:String(o)})}});async function Vt(t,e,o,n,s,r,i,c){$.startRequest(n,{request_body:e,model:i,translated_model:c!==i?c:null,endpoint:"/v1/responses",request_size:s}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let a=0,u=0,p=200,l={},d=[],h=!1,k=!1;t.on("close",()=>{h=!0});try{$.updateRequestState(n,"sending");let R=await fetch(`${I()}/responses`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});if(p=R.status,R.ok){let b=R.body.getReader(),C=new TextDecoder,A="";for($.updateRequestState(n,"receiving");;){let{done:j,value:N}=await b.read();if(j)break;if(h){b.cancel();break}h||t.write(N),A+=C.decode(N,{stream:!0});let O=A.split(`
101
+ `);A=O.pop();for(let z of O){let L=z.replace(/\r$/,"");if(!L.startsWith("data: "))continue;let W=L.slice(6);if(W!=="[DONE]")try{let T=JSON.parse(W);if(T.type==="response.completed"){k=!0;let J=T.response??{};l=J;let E=J.usage??{};a=E.input_tokens??0,u=E.output_tokens??0}else T.type==="response.output_text.delta"&&d.push(T.delta??"")}catch{}}}}else{let b=await R.text();oe("/v1/responses",e,b,p),h||t.write(`event: error
95
102
  data: ${JSON.stringify({status:p,body:b})}
96
103
 
97
- `)}}catch(y){p=504,console.log(`[Stream Responses] Error for ${n}: ${y}`)}_?$.updateRequestState(n,"error",{status_code:499}):t.end();let R=Math.round((Date.now()-r)/1e3*100)/100,d=Object.keys(u).length?u:null;!d&&m.length&&(d={output:[{type:"message",content:[{type:"output_text",text:m.join("")}]}]}),$.completeRequest(n,{request_body:e,response_body:d??{error:"Stream interrupted"},model:i,translated_model:c!==i?c:null,endpoint:"/v1/responses",status_code:_?499:p,request_size:s,response_size:JSON.stringify(d??{}).length,input_tokens:a,output_tokens:l,duration:R})}function Bt(t){if(!Array.isArray(t)||t.length===0)return!1;let e=t[t.length-1];if(typeof e!="object"||!e)return!1;let o=e.role;return o?typeof o=="string"&&o.toLowerCase()==="assistant":!0}function zt(t){for(let e=t.length-1;e>=0;e--){let o=t[e];if(o&&typeof o=="object"&&o.type==="compaction")return e===0?t:t.slice(e)}return t}function Jt(t){if(!Array.isArray(t))return!1;for(let e of t){if(typeof e!="object"||!e)continue;let o=e.content;if(Array.isArray(o)&&o.some(n=>n.type==="input_image")||e.type==="input_image")return!0}return!1}async function it(t,e,o,n){let s=f.maxConnectionRetries;for(let r=0;r<=s;r++)try{return await fetch(t,{...e,signal:AbortSignal.timeout(12e5)})}catch(i){let c=i;if(Re(o,n,r,s,c),await U(),r<s){let a=Math.min(2**r,8)*1e3;console.log(`[${n}] Connection error (attempt ${r+1}/${s+1}): ${c.message}`),await new Promise(l=>setTimeout(l,a))}else console.log(`[${n}] Connection error (final attempt): ${c.message}`)}return null}var ct=require("express");var we=(0,ct.Router)(),Vt=new Set(["model","messages","max_tokens","system","metadata","stop_sequences","stream","temperature","top_p","top_k","tools","tool_choice","thinking","service_tier"]);function Gt(t){let e=o=>{let n=o?.cache_control;n?.type==="ephemeral"&&"scope"in n&&delete n.scope};for(let o of t.tools??[])e(o);if(Array.isArray(t.system))for(let o of t.system)e(o);for(let o of t.messages??[])if(Array.isArray(o.content))for(let n of o.content)e(n)}function Wt(t){let e={};for(let[o,n]of Object.entries(t))Vt.has(o)&&(e[o]=n);return Gt(e),e}function Xt(t){let e=t.thinking;if(!e?.budget_tokens)return t;let o=e.budget_tokens,n=t.max_tokens??0;if(n<=o){let s=o+Math.min(16384,o);return console.log(`[DirectAnthropic] Adjusted max_tokens: ${n} \u2192 ${s} (thinking.budget_tokens=${o})`),{...t,max_tokens:s}}return t}function Kt(t){let e=t.system;if(!e)return f.systemPromptAdd.length?{...t,system:f.systemPromptAdd.map(o=>({type:"text",text:o}))}:t;if(typeof e=="string"){let o=$e(e);for(let n of f.systemPromptAdd)o.includes(n)||(o+=`
104
+ `)}}catch(R){p=504,console.log(`[Stream Responses] Error for ${n}: ${R}`)}let f=re({clientDisconnected:h,streamCompleted:k,upstreamStatusCode:p});f===499?$.updateRequestState(n,"error",{status_code:499}):h||t.end();let S=Math.round((Date.now()-r)/1e3*100)/100,y=Object.keys(l).length?l:null;!y&&d.length&&(y={output:[{type:"message",content:[{type:"output_text",text:d.join("")}]}]}),$.completeRequest(n,{request_body:e,response_body:y??{error:"Stream interrupted"},model:i,translated_model:c!==i?c:null,endpoint:"/v1/responses",status_code:f,request_size:s,response_size:JSON.stringify(y??{}).length,input_tokens:a,output_tokens:u,duration:S})}function Gt(t){if(!Array.isArray(t)||t.length===0)return!1;let e=t[t.length-1];if(typeof e!="object"||!e)return!1;let o=e.role;return o?typeof o=="string"&&o.toLowerCase()==="assistant":!0}function Wt(t){for(let e=t.length-1;e>=0;e--){let o=t[e];if(o&&typeof o=="object"&&o.type==="compaction")return e===0?t:t.slice(e)}return t}function Xt(t){if(!Array.isArray(t))return!1;for(let e of t){if(typeof e!="object"||!e)continue;let o=e.content;if(Array.isArray(o)&&o.some(n=>n.type==="input_image")||e.type==="input_image")return!0}return!1}async function lt(t,e,o,n){let s=_.maxConnectionRetries;for(let r=0;r<=s;r++)try{return await fetch(t,{...e,signal:AbortSignal.timeout(12e5)})}catch(i){let c=i;if(be(o,n,r,s,c),await F(),r<s){let a=Math.min(2**r,8)*1e3;console.log(`[${n}] Connection error (attempt ${r+1}/${s+1}): ${c.message}`),await new Promise(u=>setTimeout(u,a))}else console.log(`[${n}] Connection error (final attempt): ${c.message}`)}return null}var pt=require("express");var Ae=(0,pt.Router)(),Kt=new Set(["model","messages","max_tokens","system","metadata","stop_sequences","stream","temperature","top_p","top_k","tools","tool_choice","thinking","service_tier"]);function Yt(t){let e=o=>{let n=o?.cache_control;n?.type==="ephemeral"&&"scope"in n&&delete n.scope};for(let o of t.tools??[])e(o);if(Array.isArray(t.system))for(let o of t.system)e(o);for(let o of t.messages??[])if(Array.isArray(o.content))for(let n of o.content)e(n)}function Qt(t){let e={};for(let[o,n]of Object.entries(t))Kt.has(o)&&(e[o]=n);return Yt(e),e}function Zt(t){let e=t.thinking;if(!e?.budget_tokens)return t;let o=e.budget_tokens,n=t.max_tokens??0;if(n<=o){let s=o+Math.min(16384,o);return console.log(`[DirectAnthropic] Adjusted max_tokens: ${n} \u2192 ${s} (thinking.budget_tokens=${o})`),{...t,max_tokens:s}}return t}function en(t){let e=t.system;if(!e)return _.systemPromptAdd.length?{...t,system:_.systemPromptAdd.map(o=>({type:"text",text:o}))}:t;if(typeof e=="string"){let o=we(e);for(let n of _.systemPromptAdd)o.includes(n)||(o+=`
98
105
 
99
106
  `+n);return{...t,system:o}}if(Array.isArray(e)){let o=e,n=o.filter(i=>i.type==="text").map(i=>i.text).join(`
100
- `),s=!1,r=[];for(let i of o)if(i.type==="text"){let c=i.text;if(c.startsWith("x-anthropic-billing-header:")){s=!0;continue}let a=c;for(let l of f.systemPromptRemove)a.includes(l)&&(a=a.replaceAll(l,""),s=!0);r.push(a!==c?{...i,text:a}:i)}else r.push(i);for(let i of f.systemPromptAdd)n.includes(i)||(r.push({type:"text",text:i}),s=!0);return s?{...t,system:r}:t}return t}function Yt(t){let e=t.messages;if(!e?.length)return t;let o=!1,n=e.map(s=>{if(!Array.isArray(s.content))return s;let r=!1,i=s.content.map(c=>{if(c.type!=="tool_result"||typeof c.content!="string")return c;let a=Fe(c.content);return a!==c.content?(r=!0,{...c,content:a}):c});return r?(o=!0,{...s,content:i}):s});return o?{...t,messages:n}:t}we.post("/v1/messages/count_tokens",async(t,e)=>{try{await U();let o=t.body,n=o.model??"",s=f.models?.data?.find(c=>c.id===n);if(!s)return e.json({input_tokens:1});let r=0,i=o.system;if(typeof i=="string")r+=j(i);else if(Array.isArray(i))for(let c of i)c.type==="text"&&(r+=j(c.text??""));for(let c of o.messages??[]){let a=c.content;if(typeof a=="string")r+=j(a);else if(Array.isArray(a))for(let l of a)l.type==="text"?r+=j(l.text??""):l.type==="tool_result"&&typeof l.content=="string"?r+=j(l.content):l.type==="tool_use"&&(r+=j(JSON.stringify(l.input??{})))}if(o.tools?.length){r+=n.startsWith("claude")?346:n.startsWith("grok")?480:346;for(let c of o.tools)r+=j(c.name??""),r+=j(c.description??""),r+=j(JSON.stringify(c.input_schema??{}))}s.vendor!=="Anthropic"&&(r=Math.ceil(r*(n.startsWith("grok")?1.03:1.05))),e.json({input_tokens:r})}catch(o){console.log(`[count_tokens] Error: ${o}`),e.json({input_tokens:1})}});we.post("/v1/messages",async(t,e)=>{let o=Date.now();await U();let n=t.body,s=crypto.randomUUID(),r=n,i=n.model??"unknown",c=ne(i);return c!==i&&(console.log(`[Anthropic API] Model name translated: ${i} -> ${c}`),n={...n,model:c}),n=Kt(n),n=Yt(n),tt(c)?(console.log(`[Anthropic API] Using direct Anthropic API path for: ${c}`),Qt(e,n,s,o,i,c,r)):(console.log(`[Anthropic API] Using OpenAI translation path for: ${c}`),en(e,n,s,o,i,c,r))});async function Qt(t,e,o,n,s,r,i){let c=JSON.stringify(e).length,a=at(e),l=(e.messages??[]).some(_=>_.role==="assistant"),p=Y(a);p["anthropic-version"]="2023-06-01",p["X-Initiator"]=l?"agent":"user";let u=e,m=null;for(let _=0;_<=3;_++){let R=Wt(u);if(R=Xt(R),R.stream)return Zt(t,R,p,o,u,c,n,s,r,i);let d=await lt(`${N()}/v1/messages`,{method:"POST",headers:p,body:JSON.stringify(R)},o,"/v1/messages");if(!d)return void t.status(504).json({type:"error",error:{type:"api_error",message:"Upstream connection error"}});let y=Math.round((Date.now()-n)/1e3*100)/100;if(d.ok){let k=await d.json(),x=k.usage;return $.addRequest(o,{original_request_body:i,request_body:u,response_body:k,model:s,translated_model:r!==s?r:null,endpoint:"/v1/messages",status_code:d.status,request_size:c,response_size:JSON.stringify(k).length,input_tokens:x?.input_tokens??0,output_tokens:x?.output_tokens??0,duration:y}),m&&ke({...m,modified_request:u,final_status_code:d.status,final_response:k}),void t.json(k)}let b=await d.text();if(Z("/v1/messages",u,b,d.status),Ne(d.status,b)){let k=qe(b);if(k.length){console.log(`[Direct Anthropic] Attempt ${_+1}: orphaned IDs: ${k}`),m?m.orphaned_ids.push(...k):m={request_id:o,original_request:e,error_response:b,error_status_code:d.status,orphaned_ids:k},u={...u,messages:Ie(u.messages,k)};continue}}return m&&ke({...m,modified_request:u,final_status_code:d.status,final_response:b}),void t.status(d.status).type("json").send(b)}}async function Zt(t,e,o,n,s,r,i,c,a,l){$.startRequest(n,{original_request_body:l,request_body:s,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",request_size:r}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let p=0,u=0,m=200,_=c,R=[],d=!1;t.on("close",()=>{d=!0});try{$.updateRequestState(n,"sending");let k=await fetch(`${N()}/v1/messages`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});m=k.status,$.updateRequestState(n,"receiving");let x=k.body.getReader(),T=new TextDecoder,q="",C="";for(;;){let{done:H,value:I}=await x.read();if(H)break;if(d){x.cancel();break}q+=T.decode(I,{stream:!0});let V=q.split(`
101
- `);q=V.pop();for(let A of V){if(!A.trim())continue;if(A.startsWith("event: ")){C=A.slice(7);continue}if(!A.startsWith("data: "))continue;let B=A.slice(6);if(B==="[DONE]")break;try{let O=JSON.parse(B),ee=C||O.type||"";if(C="",ee==="message_start"){let re=O.message??{};_=re.model??c,p=re.usage?.input_tokens??0}else ee==="message_delta"?u=O.usage?.output_tokens??0:ee==="content_block_delta"&&O.delta?.type==="text_delta"&&R.push(O.delta.text??"");d||t.write(`event: ${ee}
102
- data: ${B}
107
+ `),s=!1,r=[];for(let i of o)if(i.type==="text"){let c=i.text;if(c.startsWith("x-anthropic-billing-header:")){s=!0;continue}let a=c;for(let u of _.systemPromptRemove)a.includes(u)&&(a=a.replaceAll(u,""),s=!0);r.push(a!==c?{...i,text:a}:i)}else r.push(i);for(let i of _.systemPromptAdd)n.includes(i)||(r.push({type:"text",text:i}),s=!0);return s?{...t,system:r}:t}return t}function tn(t){let e=t.messages;if(!e?.length)return t;let o=!1,n=e.map(s=>{if(!Array.isArray(s.content))return s;let r=!1,i=s.content.map(c=>{if(c.type!=="tool_result"||typeof c.content!="string")return c;let a=Ve(c.content);return a!==c.content?(r=!0,{...c,content:a}):c});return r?(o=!0,{...s,content:i}):s});return o?{...t,messages:n}:t}Ae.post("/v1/messages/count_tokens",async(t,e)=>{try{await F();let o=t.body,n=o.model??"",s=_.models?.data?.find(c=>c.id===n);if(!s)return e.json({input_tokens:1});let r=0,i=o.system;if(typeof i=="string")r+=M(i);else if(Array.isArray(i))for(let c of i)c.type==="text"&&(r+=M(c.text??""));for(let c of o.messages??[]){let a=c.content;if(typeof a=="string")r+=M(a);else if(Array.isArray(a))for(let u of a)u.type==="text"?r+=M(u.text??""):u.type==="tool_result"&&typeof u.content=="string"?r+=M(u.content):u.type==="tool_use"&&(r+=M(JSON.stringify(u.input??{})))}if(o.tools?.length){r+=n.startsWith("claude")?346:n.startsWith("grok")?480:346;for(let c of o.tools)r+=M(c.name??""),r+=M(c.description??""),r+=M(JSON.stringify(c.input_schema??{}))}s.vendor!=="Anthropic"&&(r=Math.ceil(r*(n.startsWith("grok")?1.03:1.05))),e.json({input_tokens:r})}catch(o){console.log(`[count_tokens] Error: ${o}`),e.json({input_tokens:1})}});Ae.post("/v1/messages",async(t,e)=>{let o=Date.now();await F();let n=t.body,s=crypto.randomUUID(),r=n,i=n.model??"unknown",c=ie(i);return c!==i&&(console.log(`[Anthropic API] Model name translated: ${i} -> ${c}`),n={...n,model:c}),n=en(n),n=tn(n),rt(c)?(console.log(`[Anthropic API] Using direct Anthropic API path for: ${c}`),nn(e,n,s,o,i,c,r)):(console.log(`[Anthropic API] Using OpenAI translation path for: ${c}`),sn(e,n,s,o,i,c,r))});async function nn(t,e,o,n,s,r,i){let c=JSON.stringify(e).length,a=dt(e),u=(e.messages??[]).some(h=>h.role==="assistant"),p=te(a);p["anthropic-version"]="2023-06-01",p["X-Initiator"]=u?"agent":"user";let l=e,d=null;for(let h=0;h<=3;h++){let k=Qt(l);if(k=Zt(k),k.stream)return on(t,k,p,o,l,c,n,s,r,i);let f=await gt(`${I()}/v1/messages`,{method:"POST",headers:p,body:JSON.stringify(k)},o,"/v1/messages");if(!f)return void t.status(504).json({type:"error",error:{type:"api_error",message:"Upstream connection error"}});let S=Math.round((Date.now()-n)/1e3*100)/100;if(f.ok){let R=await f.json(),b=R.usage;return $.addRequest(o,{original_request_body:i,request_body:l,response_body:R,model:s,translated_model:r!==s?r:null,endpoint:"/v1/messages",status_code:f.status,request_size:c,response_size:JSON.stringify(R).length,input_tokens:b?.input_tokens??0,output_tokens:b?.output_tokens??0,duration:S}),d&&xe({...d,modified_request:l,final_status_code:f.status,final_response:R}),void t.json(R)}let y=await f.text();if(oe("/v1/messages",l,y,f.status),He(f.status,y)){let R=Fe(y);if(R.length){console.log(`[Direct Anthropic] Attempt ${h+1}: orphaned IDs: ${R}`),d?d.orphaned_ids.push(...R):d={request_id:o,original_request:e,error_response:y,error_status_code:f.status,orphaned_ids:R},l={...l,messages:Me(l.messages,R)};continue}}return d&&xe({...d,modified_request:l,final_status_code:f.status,final_response:y}),void t.status(f.status).type("json").send(y)}}async function on(t,e,o,n,s,r,i,c,a,u){$.startRequest(n,{original_request_body:u,request_body:s,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",request_size:r}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let p=0,l=0,d=200,h=c,k=[],f=!1,S=!1;t.on("close",()=>{f=!0});try{$.updateRequestState(n,"sending");let C=await fetch(`${I()}/v1/messages`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});d=C.status,$.updateRequestState(n,"receiving");let A=C.body.getReader(),j=new TextDecoder,N="",O="";for(;;){let{done:z,value:L}=await A.read();if(z)break;if(f){A.cancel();break}N+=j.decode(L,{stream:!0});let W=N.split(`
108
+ `);N=W.pop();for(let T of W){if(!T.trim())continue;if(T.startsWith("event: ")){O=T.slice(7);continue}if(!T.startsWith("data: "))continue;let J=T.slice(6);if(J==="[DONE]"){S=!0;break}try{let E=JSON.parse(J),Z=O||E.type||"";if(O="",Z==="message_start"){let ue=E.message??{};h=ue.model??c,p=ue.usage?.input_tokens??0}else Z==="message_delta"?l=E.usage?.output_tokens??0:Z==="message_stop"?S=!0:Z==="content_block_delta"&&E.delta?.type==="text_delta"&&k.push(E.delta.text??"");f||t.write(`event: ${Z}
109
+ data: ${J}
103
110
 
104
- `)}catch{}}}}catch(k){m=504,console.log(`[Stream Direct Anthropic] Error for ${n}: ${k}`)}d?$.updateRequestState(n,"error",{status_code:499}):t.end();let y=Math.round((Date.now()-i)/1e3*100)/100,b=R.length?{id:n,type:"message",role:"assistant",content:[{type:"text",text:R.join("")}],model:_,usage:{input_tokens:p,output_tokens:u}}:{error:{type:"api_error",message:"Stream interrupted"}};$.completeRequest(n,{request_body:s,response_body:b,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",status_code:d?499:m,request_size:r,response_size:JSON.stringify(b).length,input_tokens:p,output_tokens:u,duration:y})}async function en(t,e,o,n,s,r,i){let c=at(e),a=JSON.stringify(e).length,l=e,p=null;for(let u=0;u<=3;u++){let m=ot(l),_=(m.messages??[]).some(k=>k.role==="assistant"||k.role==="tool"),R=Y(c);if(R["X-Initiator"]=_?"agent":"user",e.stream)return tn(t,m,R,o,l,a,n,s,r,i);let d=await lt(`${N()}/chat/completions`,{method:"POST",headers:R,body:JSON.stringify(m)},o,"/v1/messages (translated)");if(!d)return void t.status(504).json({type:"error",error:{type:"api_error",message:"Upstream connection error"}});let y=Math.round((Date.now()-n)/1e3*100)/100;if(d.ok){let k=await d.json(),x=He(k),T=k.usage;return $.addRequest(o,{original_request_body:i,request_body:l,response_body:x,model:s,translated_model:r!==s?r:null,endpoint:"/v1/messages",status_code:d.status,request_size:a,response_size:JSON.stringify(x).length,input_tokens:T?.prompt_tokens??0,output_tokens:T?.completion_tokens??0,duration:y}),void t.json(x)}let b=await d.text();if(Z("/v1/messages",l,b,d.status),Ne(d.status,b)){let k=qe(b);if(k.length){p?p.orphaned_ids.push(...k):p={request_id:o,original_request:e,error_response:b,error_status_code:d.status,orphaned_ids:k},l={...l,messages:Ie(l.messages,k)};continue}}return p&&ke({...p,modified_request:l,final_status_code:d.status,final_response:b}),void t.status(d.status).type("json").send(b)}}async function tn(t,e,o,n,s,r,i,c,a,l){$.startRequest(n,{original_request_body:l,request_body:s,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",request_size:r}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let p=new be,u=[],m=0,_=0,R=200,d=!1;t.on("close",()=>{d=!0});try{$.updateRequestState(n,"sending");let x=await fetch(`${N()}/chat/completions`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});R=x.status,$.updateRequestState(n,"receiving");let T=x.body.getReader(),q=new TextDecoder,C="";for(;;){let{done:H,value:I}=await T.read();if(H)break;if(d){T.cancel();break}C+=q.decode(I,{stream:!0});let V=C.split(`
105
- `);C=V.pop();for(let A of V){if(!A.trim()||!A.startsWith("data: "))continue;let B=A.slice(6);if(B==="[DONE]")break;try{let O=JSON.parse(B);u.push(O),O.usage&&(m=O.usage.prompt_tokens??0,_=O.usage.completion_tokens??0);let ee=st(O,p);for(let re of ee)d||t.write(`event: ${re.type}
106
- data: ${JSON.stringify(re)}
111
+ `)}catch{}}}}catch(C){d=504,console.log(`[Stream Direct Anthropic] Error for ${n}: ${C}`)}let y=re({clientDisconnected:f,streamCompleted:S,upstreamStatusCode:d});y===499?$.updateRequestState(n,"error",{status_code:499}):f||t.end();let R=Math.round((Date.now()-i)/1e3*100)/100,b=k.length?{id:n,type:"message",role:"assistant",content:[{type:"text",text:k.join("")}],model:h,usage:{input_tokens:p,output_tokens:l}}:{error:{type:"api_error",message:"Stream interrupted"}};$.completeRequest(n,{request_body:s,response_body:b,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",status_code:y,request_size:r,response_size:JSON.stringify(b).length,input_tokens:p,output_tokens:l,duration:R})}async function sn(t,e,o,n,s,r,i){let c=dt(e),a=JSON.stringify(e).length,u=e,p=null;for(let l=0;l<=3;l++){let d=ct(u),h=(d.messages??[]).some(R=>R.role==="assistant"||R.role==="tool"),k=te(c);if(k["X-Initiator"]=h?"agent":"user",e.stream)return rn(t,d,k,o,u,a,n,s,r,i);let f=await gt(`${I()}/chat/completions`,{method:"POST",headers:k,body:JSON.stringify(d)},o,"/v1/messages (translated)");if(!f)return void t.status(504).json({type:"error",error:{type:"api_error",message:"Upstream connection error"}});let S=Math.round((Date.now()-n)/1e3*100)/100;if(f.ok){let R=await f.json(),b=We(R),C=R.usage;return $.addRequest(o,{original_request_body:i,request_body:u,response_body:b,model:s,translated_model:r!==s?r:null,endpoint:"/v1/messages",status_code:f.status,request_size:a,response_size:JSON.stringify(b).length,input_tokens:C?.prompt_tokens??0,output_tokens:C?.completion_tokens??0,duration:S}),void t.json(b)}let y=await f.text();if(oe("/v1/messages",u,y,f.status),He(f.status,y)){let R=Fe(y);if(R.length){p?p.orphaned_ids.push(...R):p={request_id:o,original_request:e,error_response:y,error_status_code:f.status,orphaned_ids:R},u={...u,messages:Me(u.messages,R)};continue}}return p&&xe({...p,modified_request:u,final_status_code:f.status,final_response:y}),void t.status(f.status).type("json").send(y)}}async function rn(t,e,o,n,s,r,i,c,a,u){$.startRequest(n,{original_request_body:u,request_body:s,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",request_size:r}),t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let p=new ve,l=[],d=0,h=0,k=200,f=!1,S=!1;t.on("close",()=>{f=!0});try{$.updateRequestState(n,"sending");let A=await fetch(`${I()}/chat/completions`,{method:"POST",headers:o,body:JSON.stringify(e),signal:AbortSignal.timeout(12e5)});k=A.status,$.updateRequestState(n,"receiving");let j=A.body.getReader(),N=new TextDecoder,O="";for(;;){let{done:z,value:L}=await j.read();if(z)break;if(f){j.cancel();break}O+=N.decode(L,{stream:!0});let W=O.split(`
112
+ `);O=W.pop();for(let T of W){if(!T.trim()||!T.startsWith("data: "))continue;let J=T.slice(6);if(J==="[DONE]"){S=!0;break}try{let E=JSON.parse(J);l.push(E),E.usage&&(d=E.usage.prompt_tokens??0,h=E.usage.completion_tokens??0);let Z=at(E,p);for(let ue of Z)f||t.write(`event: ${ue.type}
113
+ data: ${JSON.stringify(ue)}
107
114
 
108
- `)}catch{}}}}catch(x){R=504,console.log(`[Stream Anthropic] Error for ${n}: ${x}`)}d?$.updateRequestState(n,"error",{status_code:499}):t.end();let y=Math.round((Date.now()-i)/1e3*100)/100,b=xe(u),k=Object.keys(b).length?He(b):{error:{type:"api_error",message:"Stream interrupted"}};$.completeRequest(n,{request_body:s,response_body:k,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",status_code:d?499:R,request_size:r,response_size:u.reduce((x,T)=>x+JSON.stringify(T).length,0),input_tokens:m,output_tokens:_,duration:y})}function at(t){return(t.messages??[]).some(e=>Array.isArray(e.content)&&e.content.some(o=>o.type==="image"))}async function lt(t,e,o,n){let s=f.maxConnectionRetries;for(let r=0;r<=s;r++)try{return await fetch(t,{...e,signal:AbortSignal.timeout(12e5)})}catch(i){let c=i;Re(o,n,r,s,c),await U(),r<s&&(console.log(`[${n}] Connection error (attempt ${r+1}/${s+1}): ${c.message}`),await new Promise(a=>setTimeout(a,Math.min(2**r,8)*1e3)))}return null}var ut=require("express"),de=v(require("path")),pt=v(require("fs"));var P=(0,ut.Router)();function dt(){let t=de.default.join(__dirname,"..","public");return pt.default.existsSync(t)?t:de.default.join(__dirname,"..","..","public")}P.get("/",(t,e)=>{e.sendFile(de.default.join(dt(),"dashboard.html"))});P.get("/requests",(t,e)=>{e.sendFile(de.default.join(dt(),"requests.html"))});P.get("/api/stats",(t,e)=>{e.json($.getStats())});P.get("/api/requests",(t,e)=>{let o=parseInt(t.query.page)||1,n=parseInt(t.query.per_page)||50,s=t.query.search||"",r=(o-1)*n,i,c;s?(i=$.searchRequests(s,n,r),c=$.searchRequests(s,1e4,0).length):(i=$.getRecentRequests(n,r),c=$.getTotalCount());let a=i.map(l=>({...l,request_body:null,response_body:null}));e.json({items:a,total:c,page:o,per_page:n,total_pages:Math.ceil(c/n)})});P.get("/api/request/:id",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o)});P.get("/api/request/:id/request-body",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o.request_body)});P.get("/api/request/:id/response-body",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o.response_body)});P.get("/api/requests/search",(t,e)=>{let o=parseInt(t.query.page)||1,n=parseInt(t.query.per_page)||50,s=t.query.q||"",r=(o-1)*n;if(!s)return e.json({items:[],total:0,page:o,per_page:n,total_pages:0});let[i,c]=$.fulltextSearch(s,n,r),a=i.map(l=>({...l,request_body:null,response_body:null}));e.json({items:a,total:c,page:o,per_page:n,total_pages:c>0?Math.ceil(c/n):0})});P.get("/api/requests/export",(t,e)=>{let o=new Date().toISOString().replace(/[:.]/g,"").slice(0,15);e.setHeader("Content-Type","application/x-jsonlines"),e.setHeader("Content-Disposition",`attachment; filename=requests_${o}.jl`);for(let n of $.getAllRequests())e.write(JSON.stringify(n)+`
115
+ `)}catch{}}}}catch(A){k=504,console.log(`[Stream Anthropic] Error for ${n}: ${A}`)}let y=re({clientDisconnected:f,streamCompleted:S,upstreamStatusCode:k});y===499?$.updateRequestState(n,"error",{status_code:499}):f||t.end();let R=Math.round((Date.now()-i)/1e3*100)/100,b=Ce(l),C=Object.keys(b).length?We(b):{error:{type:"api_error",message:"Stream interrupted"}};$.completeRequest(n,{request_body:s,response_body:C,model:c,translated_model:a!==c?a:null,endpoint:"/v1/messages",status_code:y,request_size:r,response_size:l.reduce((A,j)=>A+JSON.stringify(j).length,0),input_tokens:d,output_tokens:h,duration:R})}function dt(t){return(t.messages??[]).some(e=>Array.isArray(e.content)&&e.content.some(o=>o.type==="image"))}async function gt(t,e,o,n){let s=_.maxConnectionRetries;for(let r=0;r<=s;r++)try{return await fetch(t,{...e,signal:AbortSignal.timeout(12e5)})}catch(i){let c=i;be(o,n,r,s,c),await F(),r<s&&(console.log(`[${n}] Connection error (attempt ${r+1}/${s+1}): ${c.message}`),await new Promise(a=>setTimeout(a,Math.min(2**r,8)*1e3)))}return null}var ft=require("express"),_e=v(require("path")),mt=v(require("fs"));var P=(0,ft.Router)();function _t(){let t=_e.default.join(__dirname,"..","public");return mt.default.existsSync(t)?t:_e.default.join(__dirname,"..","..","public")}P.get("/",(t,e)=>{e.sendFile(_e.default.join(_t(),"dashboard.html"))});P.get("/requests",(t,e)=>{e.sendFile(_e.default.join(_t(),"requests.html"))});P.get("/api/stats",(t,e)=>{e.json($.getStats())});P.get("/api/requests",(t,e)=>{let o=parseInt(t.query.page)||1,n=parseInt(t.query.per_page)||50,s=t.query.search||"",r=(o-1)*n,i,c;s?(i=$.searchRequests(s,n,r),c=$.searchRequests(s,1e4,0).length):(i=$.getRecentRequests(n,r),c=$.getTotalCount());let a=i.map(u=>({...u,request_body:null,response_body:null}));e.json({items:a,total:c,page:o,per_page:n,total_pages:Math.ceil(c/n)})});P.get("/api/request/:id",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o)});P.get("/api/request/:id/request-body",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o.request_body)});P.get("/api/request/:id/response-body",(t,e)=>{let o=$.getRequest(t.params.id);if(!o)return e.status(404).json({error:"Request not found"});e.json(o.response_body)});P.get("/api/requests/search",(t,e)=>{let o=parseInt(t.query.page)||1,n=parseInt(t.query.per_page)||50,s=t.query.q||"",r=(o-1)*n;if(!s)return e.json({items:[],total:0,page:o,per_page:n,total_pages:0});let[i,c]=$.fulltextSearch(s,n,r),a=i.map(u=>({...u,request_body:null,response_body:null}));e.json({items:a,total:c,page:o,per_page:n,total_pages:c>0?Math.ceil(c/n):0})});P.get("/api/requests/export",(t,e)=>{let o=new Date().toISOString().replace(/[:.]/g,"").slice(0,15);e.setHeader("Content-Type","application/x-jsonlines"),e.setHeader("Content-Disposition",`attachment; filename=requests_${o}.jl`);for(let n of $.getAllRequests())e.write(JSON.stringify(n)+`
109
116
  `);e.end()});P.post("/api/requests/import",(t,e)=>{let n=(typeof t.body=="string"?t.body:JSON.stringify(t.body)).split(`
110
- `).filter(i=>i.trim()),s=0,r=[];for(let i=0;i<n.length;i++)try{let c=JSON.parse(n[i]);$.importRequest(c),s++}catch(c){r.push(`Line ${i+1}: ${c}`)}e.json({imported:s,errors:r.slice(0,10),total_errors:r.length})});var S=v(require("fs")),M=v(require("path")),ft=v(require("readline"));var L="\x1B[1m",w="\x1B[2m",g="\x1B[0m",K="\x1B[36m",D="\x1B[32m",se="\x1B[33m",W="\x1B[35m",Se="localhost";function nn(){console.log(`
111
- ${W}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${g}
112
- ${W}\u2551${g} ${L}ghc-tunnel Setup Wizard${g} ${W}\u2551${g}
113
- ${W}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${g}
114
- `)}function Be(){return ft.default.createInterface({input:process.stdin,output:process.stdout})}function fe(t,e){return new Promise(o=>t.question(e,o))}async function mt(){nn(),console.log(`${L}Step 1: GitHub Authentication${g}`),console.log(`${w}Checking for GitHub token...${g}
115
- `);let t=await he();t||(console.error("Failed to get GitHub token. Cannot continue setup."),process.exit(1)),f.githubToken=t,await pe(),await te();let e=f.models?.data??[];e.length||(console.error("No models available. Check your Copilot subscription."),process.exit(1)),console.log(`
116
- ${L}Step 2: Configure Models${g}
117
- `),console.log(`${w}Available Copilot models:${g}
118
- `);for(let R=0;R<e.length;R++){let d=e[R],y=[];d.capabilities?.supports?.vision&&y.push("Vision"),d.capabilities?.supports?.tool_calls&&y.push("Tools"),d.supported_endpoints?.includes("/v1/messages")&&y.push("Anthropic"),d.preview&&y.push("Preview");let b=y.length?` ${w}(${y.join(", ")})${g}`:"";console.log(` ${K}${String(R+1).padStart(2)}.${g} ${d.id}${b}`)}let o=Be();console.log(`
119
- ${se}Pick models by number. Press Enter to accept the default.${g}
120
- `);let n=on(e,[h,"claude-opus-4.7","claude-opus-4.6-1m","claude-opus-4.6"])??0,s=await gt(o,e,'Primary model (mapped to "opus", "sonnet" aliases)',n),r=e[s],i=_t(e,G)??0,c=await gt(o,e,'Small/fast model (mapped to "haiku" alias)',i),a=e[c];console.log(`
121
- ${D}Primary: ${r.id}${g}`),console.log(`${D}Small: ${a.id}${g}
122
- `),console.log(`${L}Step 3: Server Settings${g}
123
- `);let l=await fe(o,` Port ${w}[8314]${g}: `),p=l.trim()?parseInt(l.trim(),10):8314,u=Se;console.log(`${D}Host: ${u}${g}
117
+ `).filter(i=>i.trim()),s=0,r=[];for(let i=0;i<n.length;i++)try{let c=JSON.parse(n[i]);$.importRequest(c),s++}catch(c){r.push(`Line ${i+1}: ${c}`)}e.json({imported:s,errors:r.slice(0,10),total_errors:r.length})});var w=v(require("fs")),B=v(require("path")),yt=v(require("readline"));var U="\x1B[1m",x="\x1B[2m",g="\x1B[0m",Q="\x1B[36m",q="\x1B[32m",ae="\x1B[33m",K="\x1B[35m",Oe=ee;function cn(){console.log(`
118
+ ${K}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${g}
119
+ ${K}\u2551${g} ${U}ghc-tunnel Setup Wizard${g} ${K}\u2551${g}
120
+ ${K}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${g}
121
+ `)}function Xe(){return yt.default.createInterface({input:process.stdin,output:process.stdout})}function ye(t,e){return new Promise(o=>t.question(e,o))}async function Rt(t={}){cn(),console.log(`${U}Step 1: GitHub Authentication${g}`),console.log(`${x}Checking for GitHub token...${g}
122
+ `);let e=await $e();e||(console.error("Failed to get GitHub token. Cannot continue setup."),process.exit(1)),_.githubToken=e,await me(),await se();let o=_.models?.data??[];o.length||(console.error("No models available. Check your Copilot subscription."),process.exit(1)),console.log(`
123
+ ${U}Step 2: Configure Models${g}
124
+ `),console.log(`${x}Available Copilot models:${g}
125
+ `);for(let f=0;f<o.length;f++){let S=o[f],y=[];S.capabilities?.supports?.vision&&y.push("Vision"),S.capabilities?.supports?.tool_calls&&y.push("Tools"),S.supported_endpoints?.includes("/v1/messages")&&y.push("Anthropic"),S.preview&&y.push("Preview");let R=y.length?` ${x}(${y.join(", ")})${g}`:"";console.log(` ${Q}${String(f+1).padStart(2)}.${g} ${S.id}${R}`)}let n=t.useDefaults?void 0:Xe();console.log(`
126
+ ${ae}Pick models by number. Press Enter to accept the default.${g}
127
+ `);let s=an(o,[m,"claude-opus-4.8","claude-opus-4.7-1m","claude-opus-4.7","claude-opus-4.6-1m","claude-opus-4.6"])??0,r=t.useDefaults?s:await ht(n,o,'Primary model (mapped to "opus", "sonnet" aliases)',s),i=o[r],c=kt(o,X)??0,a=t.useDefaults?c:await ht(n,o,'Small/fast model (mapped to "haiku" alias)',c),u=o[a];console.log(`
128
+ ${q}Primary: ${i.id}${g}`),console.log(`${q}Small: ${u.id}${g}
129
+ `),console.log(`${U}Step 3: Server Settings${g}
130
+ `);let p=t.useDefaults?"":await ye(n,` Port ${x}[8314]${g}: `),l=p.trim()?parseInt(p.trim(),10):8314,d=Oe;console.log(`${q}Host: ${d}${g}
124
131
  `),console.log(`
125
- ${L}Step 4: Claude Code Model Settings${g}`),console.log(`${w}Using the same Claude Code model identifier for both primary and fallback model settings.${g}
126
- `),console.log(`${D}ANTHROPIC_MODEL: ${z}${g}`),console.log(`${D}ANTHROPIC_DEFAULT_HAIKU_MODEL: ${z}${g}
127
- `),console.log(`${L}Step 4b: Codex Model${g}
128
- `);let{model:m,reasoning:_}=await $t(o,{model:ze,reasoning:Je});return console.log(`${D}Codex model: ${m} (reasoning: ${_})${g}
129
- `),o.close(),console.log(`${L}Step 5: Saving Configuration${g}
130
- `),sn(r.id,a.id,p,u),ht(p,u),an(p,u,m,_),console.log(`
131
- ${D}${L}Setup complete!${g}
132
- `),{port:p,host:u}}async function gt(t,e,o,n){let s=e[n]?.id??"?";for(;;){let r=await fe(t,` ${o} ${w}[${n+1}: ${s}]${g}: `);if(!r.trim())return n;let i=parseInt(r.trim(),10);if(i>=1&&i<=e.length)return i-1;let c=e.findIndex(a=>a.id===r.trim());if(c!==-1)return c;console.log(` ${se}Invalid choice. Enter a number 1-${e.length} or a model name.${g}`)}}function _t(t,e){let o=t.findIndex(n=>n.id===e);return o>=0?o:void 0}function on(t,e){for(let o of e){let n=_t(t,o);if(n!==void 0)return n}}function sn(t,e,o,n){let s=E();S.default.mkdirSync(s,{recursive:!0});let r=M.default.join(s,"config.yaml"),i=`# ghc-tunnel Configuration (generated by --setup)
132
+ ${U}Step 4: Claude Code Model Settings${g}`),console.log(`${x}Using the same Claude Code model identifier for both primary and fallback model settings.${g}
133
+ `),console.log(`${q}ANTHROPIC_MODEL: ${V}${g}`),console.log(`${q}ANTHROPIC_DEFAULT_HAIKU_MODEL: ${V}${g}
134
+ `),console.log(`${U}Step 4b: Codex Model${g}
135
+ `);let{model:h,reasoning:k}=t.useDefaults?{model:Te,reasoning:Ee}:await wt(n,{model:Te,reasoning:Ee});return console.log(`${q}Codex model: ${h} (reasoning: ${k})${g}
136
+ `),n?.close(),console.log(`${U}Step 5: Saving Configuration${g}
137
+ `),un(i.id,u.id,l,d),$t(l,d),dn(l,d,h,k),console.log(`
138
+ ${q}${U}Setup complete!${g}
139
+ `),{port:l,host:d}}async function ht(t,e,o,n){let s=e[n]?.id??"?";for(;;){let r=await ye(t,` ${o} ${x}[${n+1}: ${s}]${g}: `);if(!r.trim())return n;let i=parseInt(r.trim(),10);if(i>=1&&i<=e.length)return i-1;let c=e.findIndex(a=>a.id===r.trim());if(c!==-1)return c;console.log(` ${ae}Invalid choice. Enter a number 1-${e.length} or a model name.${g}`)}}function kt(t,e){let o=t.findIndex(n=>n.id===e);return o>=0?o:void 0}function an(t,e){for(let o of e){let n=kt(t,o);if(n!==void 0)return n}}function un(t,e,o,n){let s=D();w.default.mkdirSync(s,{recursive:!0});let r=B.default.join(s,"config.yaml"),i=`# ghc-tunnel Configuration (generated by --setup)
133
140
  # ================================================
134
141
 
135
142
  address: ${n}
@@ -138,34 +145,42 @@ debug: false
138
145
 
139
146
  account_type: individual
140
147
 
141
- vscode_version: "${le}"
142
- api_version: "${ae}"
143
- copilot_version: "${ce}"
148
+ vscode_version: "${ge}"
149
+ api_version: "${de}"
150
+ copilot_version: "${pe}"
144
151
 
145
152
  model_mappings:
146
153
  exact:
147
154
  opus: ${t}
148
- sonnet: claude-sonnet-4.6
155
+ sonnet: ${t}
156
+ opus4-8: ${t}
149
157
  opus4-7: ${t}
158
+ "4-8[1m]": ${t}
150
159
  "4-7[1m]": ${t}
151
160
  haiku: ${e}
152
161
  prefix:
153
- claude-opus-4.5-: claude-opus-4.6
154
- claude-opus-4.6-: claude-opus-4.6
155
- claude-opus-4.7-: claude-opus-4.7
156
- claude-opus-4-5-: claude-opus-4.6
157
- claude-opus-4-6-: claude-opus-4.6
158
- claude-opus-4-7-: claude-opus-4.7
159
- "claude-opus-4.5": claude-opus-4.6
160
- "claude-opus-4.6": claude-opus-4.6
161
- "claude-opus-4.7": claude-opus-4.7
162
- "claude-opus-4-6": claude-opus-4.6
163
- "claude-opus-4-7": claude-opus-4.7
164
- "claude-opus-4-6[1m]": claude-opus-4.6
165
- "claude-opus-4-7[1m]": claude-opus-4.7
166
- claude-sonnet-4-7: claude-sonnet-4.7
167
- claude-sonnet-4-6: claude-sonnet-4.6
168
- claude-sonnet-4-5: claude-sonnet-4.6
162
+ claude-sonnet-4-: ${t}
163
+ claude-opus-4.5-: ${t}
164
+ claude-opus-4.6-: ${t}
165
+ claude-opus-4.7-: ${t}
166
+ claude-opus-4.8-: ${t}
167
+ claude-opus-4-5-: ${t}
168
+ claude-opus-4-6-: ${t}
169
+ claude-opus-4-7-: ${t}
170
+ claude-opus-4-8-: ${t}
171
+ "claude-opus-4.5": ${t}
172
+ "claude-opus-4.6": ${t}
173
+ "claude-opus-4.7": ${t}
174
+ "claude-opus-4.8": ${t}
175
+ "claude-opus-4-6": ${t}
176
+ "claude-opus-4-7": ${t}
177
+ "claude-opus-4-8": ${t}
178
+ "claude-opus-4-6[1m]": ${t}
179
+ "claude-opus-4-7[1m]": ${t}
180
+ "claude-opus-4-8[1m]": ${t}
181
+ claude-sonnet-4-7: ${t}
182
+ claude-sonnet-4-6: ${t}
183
+ claude-sonnet-4-5: ${t}
169
184
  claude-haiku-4.5-: ${e}
170
185
  claude-haiku-4-5-: ${e}
171
186
 
@@ -174,51 +189,52 @@ system_prompt_add: []
174
189
  tool_result_suffix_remove: []
175
190
 
176
191
  max_connection_retries: 3
177
- `;S.default.writeFileSync(r,i,"utf-8"),console.log(` ${D}\u2713${g} Config saved to ${K}${r}${g}`)}function ht(t,e){let o=M.default.join(process.env.HOME||"~",".claude"),n=M.default.join(o,"settings.json"),s={};if(S.default.existsSync(n))try{s=JSON.parse(S.default.readFileSync(n,"utf-8"))}catch{console.log(` ${se}\u26A0${g} Could not parse existing settings.json, creating new one`)}let r=`http://${e}:${t}/`,i=s.env??{};i.ANTHROPIC_BASE_URL=r,i.ANTHROPIC_AUTH_TOKEN="dummy",i.ANTHROPIC_MODEL=z,i.ANTHROPIC_DEFAULT_HAIKU_MODEL=z,i.DISABLE_NON_ESSENTIAL_MODEL_CALLS="1",i.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1",delete i.ANTHROPIC_SMALL_FAST_MODEL,s.env=i,S.default.mkdirSync(o,{recursive:!0}),S.default.writeFileSync(n,JSON.stringify(s,null,2)+`
178
- `,"utf-8"),console.log(` ${D}\u2713${g} Claude Code settings updated at ${K}${n}${g}`),console.log(` ${w}ANTHROPIC_BASE_URL = ${r}${g}`),console.log(` ${w}ANTHROPIC_MODEL = ${z}${g}`),console.log(` ${w}ANTHROPIC_DEFAULT_HAIKU_MODEL = ${z}${g}`)}var ze="gpt-5.5",F="ghc-tunnel",yt="GHC TUNNEL",Je="high",Rt="pragmatic";function X(t,e,o){let n=t.search(/(^|\n)\[/),s=n===-1?t:t.slice(0,n),r=n===-1?"":t.slice(n),i=`${e} = ${o}`,c=new RegExp(`^${e}\\s*=.*$`,"m");if(c.test(s))return s.replace(c,i)+r;let a=s.length===0||s.endsWith(`
192
+ `;w.default.writeFileSync(r,i,"utf-8"),console.log(` ${q}\u2713${g} Config saved to ${Q}${r}${g}`)}function $t(t,e){let o=B.default.join(process.env.HOME||"~",".claude"),n=B.default.join(o,"settings.json"),s={};if(w.default.existsSync(n))try{s=JSON.parse(w.default.readFileSync(n,"utf-8"))}catch{console.log(` ${ae}\u26A0${g} Could not parse existing settings.json, creating new one`)}let r=`http://${e}:${t}/`,i=s.env??{};i.ANTHROPIC_BASE_URL=r,i.ANTHROPIC_AUTH_TOKEN="dummy",i.ANTHROPIC_MODEL=V,i.ANTHROPIC_DEFAULT_HAIKU_MODEL=V,i.DISABLE_NON_ESSENTIAL_MODEL_CALLS="1",i.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1",delete i.ANTHROPIC_SMALL_FAST_MODEL,s.env=i,w.default.mkdirSync(o,{recursive:!0}),w.default.writeFileSync(n,JSON.stringify(s,null,2)+`
193
+ `,"utf-8"),console.log(` ${q}\u2713${g} Claude Code settings updated at ${Q}${n}${g}`),console.log(` ${x}ANTHROPIC_BASE_URL = ${r}${g}`),console.log(` ${x}ANTHROPIC_MODEL = ${V}${g}`),console.log(` ${x}ANTHROPIC_DEFAULT_HAIKU_MODEL = ${V}${g}`)}var Te="gpt-5.5",H="ghc-tunnel",St="GHC TUNNEL",Ee="high",bt="pragmatic";function Y(t,e,o){let n=t.search(/(^|\n)\[/),s=n===-1?t:t.slice(0,n),r=n===-1?"":t.slice(n),i=`${e} = ${o}`,c=new RegExp(`^${e}\\s*=.*$`,"m");if(c.test(s))return s.replace(c,i)+r;let a=s.length===0||s.endsWith(`
179
194
  `)?"":`
180
195
  `;return`${s}${a}${i}
181
- ${r}`}function kt(t,e,o,n){let s=e.replace(/[.[\]]/g,a=>`\\${a}`),r=new RegExp(`(^|\\n)\\[${s}\\][^\\[]*?(?=\\n\\[|$)`),i=`[${e}]
196
+ ${r}`}function xt(t,e,o,n){let s=e.replace(/[.[\]]/g,a=>`\\${a}`),r=new RegExp(`(^|\\n)\\[${s}\\][^\\[]*?(?=\\n\\[|$)`),i=`[${e}]
182
197
  ${o.trim()}
183
- `;if(r.test(t))return t.replace(r,(a,l)=>`${l}${i}`);if(n){let a=n.replace(/\./g,"\\."),l=new RegExp(`\\[${a}[^\\]]*\\][^\\[]*`,"g"),p=-1,u;for(;(u=l.exec(t))!==null;)p=u.index+u[0].length;if(p!==-1){let m=t.slice(0,p),_=t.slice(p),R=m.endsWith(`
198
+ `;if(r.test(t))return t.replace(r,(a,u)=>`${u}${i}`);if(n){let a=n.replace(/\./g,"\\."),u=new RegExp(`\\[${a}[^\\]]*\\][^\\[]*`,"g"),p=-1,l;for(;(l=u.exec(t))!==null;)p=l.index+l[0].length;if(p!==-1){let d=t.slice(0,p),h=t.slice(p),k=d.endsWith(`
184
199
 
185
- `)?"":m.endsWith(`
200
+ `)?"":d.endsWith(`
186
201
  `)?`
187
202
  `:`
188
203
 
189
- `,d=_.startsWith(`
204
+ `,f=h.startsWith(`
190
205
  `)?"":`
191
- `;return`${m}${R}${i}${d}${_}`}}let c=t.length===0||t.endsWith(`
206
+ `;return`${d}${k}${i}${f}${h}`}}let c=t.length===0||t.endsWith(`
192
207
 
193
208
  `)?"":t.endsWith(`
194
209
  `)?`
195
210
  `:`
196
211
 
197
- `;return`${t}${c}${i}`}function ge(t,e){let o=t.search(/(^|\n)\[/),n=o===-1?t:t.slice(0,o),s=new RegExp(`^${e}\\s*=\\s*"([^"]*)"`,"m"),r=n.match(s);return r?r[1]:void 0}function rn(t,e){let o=e.replace(/[.[\]]/g,r=>`\\${r}`),n=new RegExp(`(?:^|\\n)\\[${o}\\]\\n([\\s\\S]*?)(?=\\n\\[|$)`),s=t.match(n);return s?s[1]:void 0}function cn(t){let e=rn(t,`model_providers.${F}`);return e===void 0?!1:/^\s*name\s*=/m.test(e)&&/^\s*base_url\s*=/m.test(e)&&/^\s*wire_api\s*=/m.test(e)}async function $t(t,e){let o=(await fe(t,` Codex model ${w}[${e.model}]${g}: `)).trim(),n=(await fe(t,` Reasoning effort ${w}[${e.reasoning}] (low | medium | high | xhigh)${g}: `)).trim();return{model:o||e.model,reasoning:n||e.reasoning}}function an(t,e,o=ze,n=Je){let s=M.default.join(process.env.HOME||"~",".codex"),r=M.default.join(s,"config.toml"),i=`http://${e}:${t}/v1`,c="";if(S.default.existsSync(r))try{c=S.default.readFileSync(r,"utf-8")}catch{console.log(` ${se}\u26A0${g} Could not read existing config.toml, creating new one`)}let a=ge(c,"model_provider"),l=c;l=X(l,"model",JSON.stringify(o)),l=X(l,"model_reasoning_effort",JSON.stringify(n)),l=X(l,"personality",JSON.stringify(Rt)),l=X(l,"model_provider",JSON.stringify(F));let p=[`name = ${JSON.stringify(yt)}`,`base_url = ${JSON.stringify(i)}`,'wire_api = "responses"'].join(`
198
- `);l=kt(l,`model_providers.${F}`,p,"model_providers."),S.default.mkdirSync(s,{recursive:!0}),S.default.writeFileSync(r,l,"utf-8");let u=a&&a!==F?` ${w}(was '${a}')${g}`:"";console.log(` ${D}\u2713${g} Codex config updated at ${K}${r}${g}${u}`),console.log(` ${w}model = ${o}, reasoning = ${n}${g}`),console.log(` ${w}model_provider = ${F} (base_url = ${i})${g}`)}async function bt(t,e){let o=M.default.join(process.env.HOME||"~",".codex"),n=M.default.join(o,"config.toml"),s=`http://${e}:${t}/v1`,r="";if(S.default.existsSync(n))try{r=S.default.readFileSync(n,"utf-8")}catch{return}let i=ge(r,"model"),c=ge(r,"model_reasoning_effort"),a=ge(r,"personality"),l=ge(r,"model_provider"),p=cn(r),u=[];if(i||u.push("model"),c||u.push("model_reasoning_effort"),a||u.push("personality"),l!==F&&u.push("model_provider"),p||u.push(`[model_providers.${F}]`),u.length===0)return;console.log(`
199
- ${se}Codex config is incomplete (${u.join(", ")}). Filling in:${g}`);let m=i||ze,_=c||Je,R=!i,d=!c;if((R||d)&&process.stdin.isTTY){let b=Be();try{let k=await $t(b,{model:m,reasoning:_});R&&(m=k.model),d&&(_=k.reasoning)}finally{b.close()}}let y=r;if(i||(y=X(y,"model",JSON.stringify(m))),c||(y=X(y,"model_reasoning_effort",JSON.stringify(_))),a||(y=X(y,"personality",JSON.stringify(Rt))),l!==F&&(y=X(y,"model_provider",JSON.stringify(F))),!p){let b=[`name = ${JSON.stringify(yt)}`,`base_url = ${JSON.stringify(s)}`,'wire_api = "responses"'].join(`
200
- `);y=kt(y,`model_providers.${F}`,b,"model_providers.")}try{S.default.mkdirSync(o,{recursive:!0}),S.default.writeFileSync(n,y,"utf-8"),console.log(` ${D}\u2713${g} Codex config patched at ${K}${n}${g}`)}catch(b){console.log(` ${se}\u26A0${g} Could not write Codex config: ${b}`)}}async function xt(){console.log(`
201
- ${W}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${g}
202
- ${W}\u2551${g} ${L}Claude Code Settings${g} ${W}\u2551${g}
203
- ${W}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${g}
204
- `);let t=M.default.join(process.env.HOME||"~",".claude"),e=M.default.join(t,"settings.json"),o={},n={};if(S.default.existsSync(e))try{o=JSON.parse(S.default.readFileSync(e,"utf-8")),n=o.env??{}}catch{}(n.ANTHROPIC_BASE_URL||n.ANTHROPIC_MODEL||n.ANTHROPIC_DEFAULT_HAIKU_MODEL)&&(console.log(`${L}Current configuration:${g}`),n.ANTHROPIC_BASE_URL&&console.log(` ANTHROPIC_BASE_URL: ${K}${n.ANTHROPIC_BASE_URL}${g}`),n.ANTHROPIC_MODEL&&console.log(` ANTHROPIC_MODEL: ${K}${n.ANTHROPIC_MODEL}${g}`),n.ANTHROPIC_DEFAULT_HAIKU_MODEL&&console.log(` ANTHROPIC_DEFAULT_HAIKU_MODEL: ${K}${n.ANTHROPIC_DEFAULT_HAIKU_MODEL}${g}`),console.log(`
205
- ${w}Press Enter to keep the current port. Host and model identifiers will be reset to ${Se} and ${z}.${g}
206
- `));let r=8314,i=r;if(n.ANTHROPIC_BASE_URL)try{let p=new URL(n.ANTHROPIC_BASE_URL);i=parseInt(p.port,10)||r}catch{}let c=Be(),a=await fe(c,` Port ${w}[${i}]${g}: `),l=a.trim()?parseInt(a.trim(),10):i;c.close(),console.log(`
207
- ${w}Writing ANTHROPIC_BASE_URL as http://${Se}:${l}/ and both model identifiers as ${z}.${g}
208
- `),ht(l,Se),console.log(`
209
- ${D}${L}Claude Code settings updated!${g}
210
- `)}var wt="1.0.2";function ln(){let t=process.argv.slice(2),e={};for(let o=0;o<t.length;o++){let n=t[o];n==="-p"||n==="--port"?e.port=parseInt(t[++o],10):n==="-a"||n==="--address"?e.address=t[++o]:n==="-c"||n==="--config"?e.config=!0:n==="-s"||n==="--setup"?e.setup=!0:n==="--claudecode"?e.claudecode=!0:n==="-v"||n==="--version"?e.version=!0:(n==="-h"||n==="--help")&&(e.help=!0)}return e}function St(t,e){let o=(0,ve.default)();o.use(ve.default.json({limit:"50mb"})),o.use(ve.default.text({limit:"50mb"})),o.use(we),o.use(oe),o.use(P),o.use((n,s)=>s.status(404).json({error:"Not found"})),o.listen(e,t,()=>{console.log(`
211
- Starting GitHub Copilot API Proxy on ${t}:${e}`),console.log(`Dashboard: http://${t}:${e}/`),console.log(`OpenAI API: http://${t}:${e}/v1/chat/completions`),console.log(`Responses API: http://${t}:${e}/v1/responses`),console.log(`Anthropic API: http://${t}:${e}/v1/messages`)})}function vt(t,e){let o=E(),n=Ce.default.join(o,"config.yaml");me.default.existsSync(n)||(console.log(`No config file found at ${n}, generating one.`),Pe());try{let s=Ye(n);t=s.address??t,e=s.port??e,s.account_type&&(f.accountType=s.account_type),s.vscode_version&&(f.vscodeVersion=s.vscode_version),s.api_version&&(f.apiVersion=s.api_version),s.copilot_version&&(f.copilotVersion=s.copilot_version),s.system_prompt_remove&&(f.systemPromptRemove=s.system_prompt_remove),s.system_prompt_add&&(f.systemPromptAdd=s.system_prompt_add),s.tool_result_suffix_remove&&(f.toolResultSuffixRemove=s.tool_result_suffix_remove),s.max_connection_retries!=null&&(f.maxConnectionRetries=s.max_connection_retries),s.model_mappings?J.loadFromConfig(s):J.loadFromConfig({model_mappings:Te}),console.log(`Loaded configuration from: ${n}`)}catch(s){console.log(`Error loading config: ${s}`),J.loadFromConfig({model_mappings:Te})}return{host:t,port:e}}function un(){let t=E(),e=Ce.default.join(t,"config.yaml");if(!me.default.existsSync(e))return!0;let o=Ce.default.join(process.env.HOME||"~",".claude","settings.json");if(!me.default.existsSync(o))return!0;try{let s=JSON.parse(me.default.readFileSync(o,"utf-8"))?.env;if(!s?.ANTHROPIC_BASE_URL||!s.ANTHROPIC_BASE_URL.includes("localhost"))return!0}catch{return!0}return!1}async function pn(){let t=ln();if(t.help&&(console.log(`ghc-tunnel v${wt} \u2013 GitHub Copilot API Proxy
212
+ `;return`${t}${c}${i}`}function he(t,e){let o=t.search(/(^|\n)\[/),n=o===-1?t:t.slice(0,o),s=new RegExp(`^${e}\\s*=\\s*"([^"]*)"`,"m"),r=n.match(s);return r?r[1]:void 0}function ln(t,e){let o=e.replace(/[.[\]]/g,r=>`\\${r}`),n=new RegExp(`(?:^|\\n)\\[${o}\\]\\n([\\s\\S]*?)(?=\\n\\[|$)`),s=t.match(n);return s?s[1]:void 0}function pn(t){let e=ln(t,`model_providers.${H}`);return e===void 0?!1:/^\s*name\s*=/m.test(e)&&/^\s*base_url\s*=/m.test(e)&&/^\s*wire_api\s*=/m.test(e)}async function wt(t,e){let o=(await ye(t,` Codex model ${x}[${e.model}]${g}: `)).trim(),n=(await ye(t,` Reasoning effort ${x}[${e.reasoning}] (low | medium | high | xhigh)${g}: `)).trim();return{model:o||e.model,reasoning:n||e.reasoning}}function dn(t,e,o=Te,n=Ee){let s=B.default.join(process.env.HOME||"~",".codex"),r=B.default.join(s,"config.toml"),i=`http://${e}:${t}/v1`,c="";if(w.default.existsSync(r))try{c=w.default.readFileSync(r,"utf-8")}catch{console.log(` ${ae}\u26A0${g} Could not read existing config.toml, creating new one`)}let a=he(c,"model_provider"),u=c;u=Y(u,"model",JSON.stringify(o)),u=Y(u,"model_reasoning_effort",JSON.stringify(n)),u=Y(u,"personality",JSON.stringify(bt)),u=Y(u,"model_provider",JSON.stringify(H));let p=[`name = ${JSON.stringify(St)}`,`base_url = ${JSON.stringify(i)}`,'wire_api = "responses"'].join(`
213
+ `);u=xt(u,`model_providers.${H}`,p,"model_providers."),w.default.mkdirSync(s,{recursive:!0}),w.default.writeFileSync(r,u,"utf-8");let l=a&&a!==H?` ${x}(was '${a}')${g}`:"";console.log(` ${q}\u2713${g} Codex config updated at ${Q}${r}${g}${l}`),console.log(` ${x}model = ${o}, reasoning = ${n}${g}`),console.log(` ${x}model_provider = ${H} (base_url = ${i})${g}`)}async function vt(t,e,o={}){let n=B.default.join(process.env.HOME||"~",".codex"),s=B.default.join(n,"config.toml"),r=`http://${e}:${t}/v1`,i="";if(w.default.existsSync(s))try{i=w.default.readFileSync(s,"utf-8")}catch{return}let c=he(i,"model"),a=he(i,"model_reasoning_effort"),u=he(i,"personality"),p=he(i,"model_provider"),l=pn(i),d=[];if(c||d.push("model"),a||d.push("model_reasoning_effort"),u||d.push("personality"),p!==H&&d.push("model_provider"),l||d.push(`[model_providers.${H}]`),d.length===0)return;console.log(`
214
+ ${ae}Codex config is incomplete (${d.join(", ")}). Filling in:${g}`);let h=c||Te,k=a||Ee,f=!c,S=!a;if((f||S)&&process.stdin.isTTY&&!o.useDefaults){let R=Xe();try{let b=await wt(R,{model:h,reasoning:k});f&&(h=b.model),S&&(k=b.reasoning)}finally{R.close()}}let y=i;if(c||(y=Y(y,"model",JSON.stringify(h))),a||(y=Y(y,"model_reasoning_effort",JSON.stringify(k))),u||(y=Y(y,"personality",JSON.stringify(bt))),p!==H&&(y=Y(y,"model_provider",JSON.stringify(H))),!l){let R=[`name = ${JSON.stringify(St)}`,`base_url = ${JSON.stringify(r)}`,'wire_api = "responses"'].join(`
215
+ `);y=xt(y,`model_providers.${H}`,R,"model_providers.")}try{w.default.mkdirSync(n,{recursive:!0}),w.default.writeFileSync(s,y,"utf-8"),console.log(` ${q}\u2713${g} Codex config patched at ${Q}${s}${g}`)}catch(R){console.log(` ${ae}\u26A0${g} Could not write Codex config: ${R}`)}}async function Ct(t={}){console.log(`
216
+ ${K}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${g}
217
+ ${K}\u2551${g} ${U}Claude Code Settings${g} ${K}\u2551${g}
218
+ ${K}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${g}
219
+ `);let e=B.default.join(process.env.HOME||"~",".claude"),o=B.default.join(e,"settings.json"),n={},s={};if(w.default.existsSync(o))try{n=JSON.parse(w.default.readFileSync(o,"utf-8")),s=n.env??{}}catch{}(s.ANTHROPIC_BASE_URL||s.ANTHROPIC_MODEL||s.ANTHROPIC_DEFAULT_HAIKU_MODEL)&&(console.log(`${U}Current configuration:${g}`),s.ANTHROPIC_BASE_URL&&console.log(` ANTHROPIC_BASE_URL: ${Q}${s.ANTHROPIC_BASE_URL}${g}`),s.ANTHROPIC_MODEL&&console.log(` ANTHROPIC_MODEL: ${Q}${s.ANTHROPIC_MODEL}${g}`),s.ANTHROPIC_DEFAULT_HAIKU_MODEL&&console.log(` ANTHROPIC_DEFAULT_HAIKU_MODEL: ${Q}${s.ANTHROPIC_DEFAULT_HAIKU_MODEL}${g}`),console.log(`
220
+ ${x}Press Enter to keep the current port. Host and model identifiers will be reset to ${Oe} and ${V}.${g}
221
+ `));let i=8314,c=i;if(s.ANTHROPIC_BASE_URL)try{let l=new URL(s.ANTHROPIC_BASE_URL);c=parseInt(l.port,10)||i}catch{}let a=t.useDefaults?void 0:Xe(),u=t.useDefaults?"":await ye(a,` Port ${x}[${c}]${g}: `),p=u.trim()?parseInt(u.trim(),10):c;a?.close(),console.log(`
222
+ ${x}Writing ANTHROPIC_BASE_URL as http://${Oe}:${p}/ and both model identifiers as ${V}.${g}
223
+ `),$t(p,Oe),console.log(`
224
+ ${q}${U}Claude Code settings updated!${g}
225
+ `)}var At="1.0.6";function gn(){let t=process.argv.slice(2),e={};for(let o=0;o<t.length;o++){let n=t[o];n==="-p"||n==="--port"?e.port=parseInt(t[++o],10):n==="-a"||n==="--address"?e.address=t[++o]:n==="-c"||n==="--config"?e.config=!0:n==="-s"||n==="--setup"?e.setup=!0:n==="-d"||n==="--default"?e.defaults=!0:n==="--claudecode"?e.claudecode=!0:n==="-v"||n==="--version"?e.version=!0:(n==="-h"||n==="--help")&&(e.help=!0)}return e}function Ot(t,e){let o=(0,De.default)();o.use(De.default.json({limit:"50mb"})),o.use(De.default.text({limit:"50mb"})),o.use(Ae),o.use(ce),o.use(P),o.use((n,s)=>s.status(404).json({error:"Not found"})),o.listen(e,t,()=>{console.log(`
226
+ Starting GitHub Copilot API Proxy on ${t}:${e}`),console.log(`Dashboard: http://${t}:${e}/`),console.log(`OpenAI API: http://${t}:${e}/v1/chat/completions`),console.log(`Responses API: http://${t}:${e}/v1/responses`),console.log(`Anthropic API: http://${t}:${e}/v1/messages`)})}function Tt(t,e){let o=D(),n=Pe.default.join(o,"config.yaml");Re.default.existsSync(n)||(console.log(`No config file found at ${n}, generating one.`),Ue());try{let s=tt(n);t=s.address??t,e=s.port??e,s.account_type&&(_.accountType=s.account_type),s.vscode_version&&(_.vscodeVersion=s.vscode_version),s.api_version&&(_.apiVersion=s.api_version),s.copilot_version&&(_.copilotVersion=s.copilot_version),s.system_prompt_remove&&(_.systemPromptRemove=s.system_prompt_remove),s.system_prompt_add&&(_.systemPromptAdd=s.system_prompt_add),s.tool_result_suffix_remove&&(_.toolResultSuffixRemove=s.tool_result_suffix_remove),s.max_connection_retries!=null&&(_.maxConnectionRetries=s.max_connection_retries),s.model_mappings?G.loadFromConfig(s):G.loadFromConfig({model_mappings:Le}),console.log(`Loaded configuration from: ${n}`)}catch(s){console.log(`Error loading config: ${s}`),G.loadFromConfig({model_mappings:Le})}return{host:t,port:e}}function fn(){let t=D(),e=Pe.default.join(t,"config.yaml");if(!Re.default.existsSync(e))return!0;let o=Pe.default.join(process.env.HOME||"~",".claude","settings.json");if(!Re.default.existsSync(o))return!0;try{let s=JSON.parse(Re.default.readFileSync(o,"utf-8"))?.env;if(!s?.ANTHROPIC_BASE_URL||!mn(s.ANTHROPIC_BASE_URL))return!0}catch{return!0}return!1}function mn(t){try{let e=new URL(t);return e.hostname==="localhost"||e.hostname===ee}catch{return!1}}async function _n(){let t=gn();if(t.help&&(console.log(`ghc-tunnel v${At} \u2013 GitHub Copilot API Proxy
212
227
 
213
228
  Usage: ghc-tunnel [options]
214
229
 
215
230
  Options:
216
231
  -s, --setup Interactive setup wizard (configure models + Claude Code)
217
232
  --claudecode Update Claude Code settings only (skip model/config setup)
233
+ -d, --default Use defaults for setup and Codex config prompts
218
234
  -p, --port <port> Port to listen on (default: 8314)
219
- -a, --address <addr> Address to listen on (default: localhost)
235
+ -a, --address <addr> Address to listen on (default: ${ee})
220
236
  -c, --config Generate default config file
221
237
  -v, --version Show version
222
- -h, --help Show this help`),process.exit(0)),t.version&&(console.log(`ghc-tunnel ${wt}`),process.exit(0)),t.config&&(Pe(),process.exit(0)),t.setup&&t.claudecode&&(await xt(),process.exit(0)),t.setup||un()){t.setup||console.log(`First run detected \u2014 launching setup wizard.
223
- `);let{port:r,host:i}=await mt(),{host:c,port:a}=vt(i,r);Ue(),Le(),St(c,a);return}let{host:o,port:n}=vt(Xe,We);t.address!=null&&(o=t.address),t.port!=null&&(n=t.port);let s=await he();s||(console.error(`
224
- `+"=".repeat(60)),console.error("ERROR: No GitHub token available!"),console.error("Options:"),console.error(" 1. Set GITHUB_TOKEN environment variable"),console.error(" 2. Create github_token.txt in "+E()),console.error(" 3. Run again for interactive Device Flow auth"),console.error("=".repeat(60)),process.exit(1)),f.githubToken=s,await pe(),await te(),await bt(n,o),Ue(),Le(),St(o,n)}pn().catch(t=>{console.error("Fatal error:",t),process.exit(1)});
238
+ -h, --help Show this help`),process.exit(0)),t.version&&(console.log(`ghc-tunnel ${At}`),process.exit(0)),t.config&&(Ue(),process.exit(0)),t.setup&&t.claudecode&&(await Ct({useDefaults:t.defaults}),process.exit(0)),t.setup||fn()){t.setup||console.log(`First run detected \u2014 launching setup wizard.
239
+ `);let{port:r,host:i}=await Rt({useDefaults:t.defaults}),{host:c,port:a}=Tt(i,r);ze(),Be(),Ot(c,a);return}let{host:o,port:n}=Tt(Ze,Qe);t.address!=null&&(o=t.address),t.port!=null&&(n=t.port);let s=await $e();s||(console.error(`
240
+ `+"=".repeat(60)),console.error("ERROR: No GitHub token available!"),console.error("Options:"),console.error(" 1. Set GITHUB_TOKEN environment variable"),console.error(" 2. Create github_token.txt in "+D()),console.error(" 3. Run again for interactive Device Flow auth"),console.error("=".repeat(60)),process.exit(1)),_.githubToken=s,await me(),await se(),await vt(n,o,{useDefaults:t.defaults}),ze(),Be(),Ot(o,n)}_n().catch(t=>{console.error("Fatal error:",t),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghc-tunnel",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "GitHub Copilot API Proxy - Provides OpenAI and Anthropic compatible endpoints via GitHub Copilot",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "public"
12
12
  ],
13
13
  "scripts": {
14
+ "test": "node --import tsx --test tests/*.test.ts",
14
15
  "typecheck": "tsc",
15
16
  "build": "tsc && node esbuild.config.mjs",
16
17
  "start": "node dist/index.js",
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>GHC Proxy - Dashboard</title>
6
+ <title>GHC Tunnel - Dashboard</title>
7
7
  <style>
8
8
  * { box-sizing: border-box; margin: 0; padding: 0; }
9
9
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; color: #333; line-height: 1.6; }
@@ -61,7 +61,7 @@
61
61
  </head>
62
62
  <body>
63
63
  <nav class="navbar">
64
- <h1>GHC Proxy Dashboard</h1>
64
+ <h1>GHC Tunnel Dashboard</h1>
65
65
  <div class="navbar-actions">
66
66
  <a href="/requests">Request Browser</a>
67
67
  <a href="/api/stats">API Stats</a>