ghc-proxy 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/main.mjs +39 -18
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -121,9 +121,9 @@ bunx ghc-proxy@latest selfcheck # Probe the packaged bundle (loads every to
|
|
|
121
121
|
| `--idle-timeout` | -- | `120` | Bun server idle timeout in seconds (`0` disables; Bun max is `255`; streaming routes disable idle timeout automatically) |
|
|
122
122
|
| `--upstream-timeout` | -- | `1800` | Upstream request timeout in seconds (0 to disable) |
|
|
123
123
|
| `--upstream-queue-concurrency` | -- | `10` | Maximum concurrent Copilot upstream requests |
|
|
124
|
-
| `--upstream-queue-retries` | -- | `5` | Maximum retries for upstream 429
|
|
125
|
-
| `--upstream-queue-base-delay` | -- | `2` | Base delay in seconds for upstream
|
|
126
|
-
| `--upstream-queue-max-delay` | -- | `60` | Maximum delay in seconds for upstream
|
|
124
|
+
| `--upstream-queue-retries` | -- | `5` | Maximum retries for transient upstream responses (`408`, `429`, `500`, `502`, `503`, `504`, `529`) |
|
|
125
|
+
| `--upstream-queue-base-delay` | -- | `2` | Base delay in seconds for upstream retry backoff when `Retry-After` is absent |
|
|
126
|
+
| `--upstream-queue-max-delay` | -- | `60` | Maximum delay in seconds for upstream retry backoff |
|
|
127
127
|
| `--ghe-domain` | `--ghe` | -- | GitHub Enterprise Cloud company domain (e.g. `company.ghe.com`). Required for GHE.com device login on first run; persisted automatically for later runs. |
|
|
128
128
|
|
|
129
129
|
## Rate Limiting
|
|
@@ -206,9 +206,9 @@ All fields are optional. The full schema:
|
|
|
206
206
|
| `responsesOfficialEmulatorTtlSeconds` | `number` | `14400` | In-memory TTL for locally emulated Responses state |
|
|
207
207
|
| `modelReasoningEfforts` | `Record<string, string>` | -- | Per-model reasoning effort defaults for Anthropic-to-Responses translation. Each value must be one of `none`, `minimal`, `low`, `medium`, `high`, or `xhigh` |
|
|
208
208
|
| `upstreamQueueConcurrency` | `number` | `10` | Maximum concurrent Copilot upstream requests |
|
|
209
|
-
| `upstreamQueueMaxRetries` | `number` | `5` | Maximum retries for upstream 429
|
|
210
|
-
| `upstreamQueueBaseDelaySeconds` | `number` | `2` | Base delay (seconds) for upstream
|
|
211
|
-
| `upstreamQueueMaxDelaySeconds` | `number` | `60` | Maximum delay (seconds) for upstream
|
|
209
|
+
| `upstreamQueueMaxRetries` | `number` | `5` | Maximum retries for transient upstream responses (`408`, `429`, `500`, `502`, `503`, `504`, `529`) |
|
|
210
|
+
| `upstreamQueueBaseDelaySeconds` | `number` | `2` | Base delay (seconds) for upstream retry backoff when `Retry-After` is absent |
|
|
211
|
+
| `upstreamQueueMaxDelaySeconds` | `number` | `60` | Maximum delay (seconds) for upstream retry backoff |
|
|
212
212
|
| `gheDomain` | `string` | -- | GitHub Enterprise Cloud company domain (persisted automatically after GHE.com auth) |
|
|
213
213
|
|
|
214
214
|
Example:
|
package/dist/main.mjs
CHANGED
|
@@ -5980,6 +5980,31 @@ var HTTPError = class extends Error {
|
|
|
5980
5980
|
return Response.json(this.body, { status: this.status });
|
|
5981
5981
|
}
|
|
5982
5982
|
};
|
|
5983
|
+
const TRANSIENT_UPSTREAM_STATUSES = new Set([
|
|
5984
|
+
408,
|
|
5985
|
+
429,
|
|
5986
|
+
500,
|
|
5987
|
+
502,
|
|
5988
|
+
503,
|
|
5989
|
+
504,
|
|
5990
|
+
529
|
|
5991
|
+
]);
|
|
5992
|
+
/**
|
|
5993
|
+
* Upstream statuses worth retrying: request-scoped faults (timeouts, gateway
|
|
5994
|
+
* errors) plus capacity limits. Shared by `UpstreamRequestQueue` and the
|
|
5995
|
+
* Copilot token refresh so both agree on what "transient" means.
|
|
5996
|
+
*/
|
|
5997
|
+
function isTransientUpstreamStatus(status) {
|
|
5998
|
+
return TRANSIENT_UPSTREAM_STATUSES.has(status);
|
|
5999
|
+
}
|
|
6000
|
+
/**
|
|
6001
|
+
* Capacity signals that apply to the whole account or service rather than one
|
|
6002
|
+
* request. Only these warrant global back-pressure — applying a queue-wide
|
|
6003
|
+
* cooldown to a request-scoped 5xx turns one bad request into a proxy stall.
|
|
6004
|
+
*/
|
|
6005
|
+
function isCapacityLimitStatus(status) {
|
|
6006
|
+
return status === 429 || status === 529;
|
|
6007
|
+
}
|
|
5983
6008
|
function throwInvalidRequestError(message, param, code) {
|
|
5984
6009
|
throw new HTTPError(400, { error: {
|
|
5985
6010
|
message,
|
|
@@ -6014,7 +6039,9 @@ function isStructuredErrorPayload(value) {
|
|
|
6014
6039
|
return typeof value === "object" && value !== null && "error" in value && typeof value.error === "object" && value.error !== null;
|
|
6015
6040
|
}
|
|
6016
6041
|
function upstreamErrorType(status) {
|
|
6017
|
-
|
|
6042
|
+
if (status === 429) return "rate_limit_error";
|
|
6043
|
+
if (status === 529) return "overloaded_error";
|
|
6044
|
+
return "upstream_error";
|
|
6018
6045
|
}
|
|
6019
6046
|
function createFallbackUpstreamError(message, response, rawText) {
|
|
6020
6047
|
return { error: {
|
|
@@ -6957,8 +6984,10 @@ var UpstreamRequestQueue = class {
|
|
|
6957
6984
|
lease.release();
|
|
6958
6985
|
throw error;
|
|
6959
6986
|
}
|
|
6960
|
-
|
|
6961
|
-
|
|
6987
|
+
const { status } = response;
|
|
6988
|
+
const isCapacityLimit = isCapacityLimitStatus(status);
|
|
6989
|
+
if (!(isTransientUpstreamStatus(status) && context.retryable === true && attempt < this.options.maxRetries)) {
|
|
6990
|
+
if (isCapacityLimit) this.applyCooldown(this.getRetryDelayMs(response, 0));
|
|
6962
6991
|
return {
|
|
6963
6992
|
response,
|
|
6964
6993
|
release: lease.release
|
|
@@ -6966,10 +6995,10 @@ var UpstreamRequestQueue = class {
|
|
|
6966
6995
|
}
|
|
6967
6996
|
const delayMs = this.getRetryDelayMs(response, attempt);
|
|
6968
6997
|
await discardResponse(response);
|
|
6998
|
+
if (isCapacityLimit) this.applyCooldown(delayMs);
|
|
6969
6999
|
lease.release();
|
|
6970
|
-
this.applyCooldown(delayMs);
|
|
6971
7000
|
this.logger.warn([
|
|
6972
|
-
|
|
7001
|
+
`Upstream ${status};`,
|
|
6973
7002
|
`retrying ${formatRequestContext(context)}`,
|
|
6974
7003
|
`in ${formatDurationMs(delayMs)}`,
|
|
6975
7004
|
`(attempt ${attempt + 1}/${this.options.maxRetries})`
|
|
@@ -7244,16 +7273,8 @@ async function setupGitHubToken(options) {
|
|
|
7244
7273
|
function isAuthError(error) {
|
|
7245
7274
|
return error instanceof HTTPError && (error.status === 401 || error.status === 403);
|
|
7246
7275
|
}
|
|
7247
|
-
const TRANSIENT_HTTP_STATUSES = new Set([
|
|
7248
|
-
408,
|
|
7249
|
-
429,
|
|
7250
|
-
500,
|
|
7251
|
-
502,
|
|
7252
|
-
503,
|
|
7253
|
-
504
|
|
7254
|
-
]);
|
|
7255
7276
|
function isTransientHttpError(error) {
|
|
7256
|
-
return
|
|
7277
|
+
return isTransientUpstreamStatus(error.status);
|
|
7257
7278
|
}
|
|
7258
7279
|
async function logUser() {
|
|
7259
7280
|
const user = await createGitHubClient().getGitHubUser();
|
|
@@ -7364,7 +7385,7 @@ const checkUsage = defineCommand({
|
|
|
7364
7385
|
});
|
|
7365
7386
|
//#endregion
|
|
7366
7387
|
//#region src/util/version.ts
|
|
7367
|
-
const VERSION = "0.8.
|
|
7388
|
+
const VERSION = "0.8.1";
|
|
7368
7389
|
//#endregion
|
|
7369
7390
|
//#region src/debug.ts
|
|
7370
7391
|
function getRuntimeInfo() {
|
|
@@ -53194,15 +53215,15 @@ const start = defineCommand({
|
|
|
53194
53215
|
},
|
|
53195
53216
|
"upstream-queue-retries": {
|
|
53196
53217
|
type: "string",
|
|
53197
|
-
description: "Maximum retries for upstream
|
|
53218
|
+
description: "Maximum retries for transient upstream responses (default: 5)"
|
|
53198
53219
|
},
|
|
53199
53220
|
"upstream-queue-base-delay": {
|
|
53200
53221
|
type: "string",
|
|
53201
|
-
description: "Base delay in seconds for upstream
|
|
53222
|
+
description: "Base delay in seconds for upstream retry backoff when Retry-After is absent (default: 2)"
|
|
53202
53223
|
},
|
|
53203
53224
|
"upstream-queue-max-delay": {
|
|
53204
53225
|
type: "string",
|
|
53205
|
-
description: "Maximum delay in seconds for upstream
|
|
53226
|
+
description: "Maximum delay in seconds for upstream retry backoff (default: 60)"
|
|
53206
53227
|
},
|
|
53207
53228
|
"ghe-domain": {
|
|
53208
53229
|
alias: "ghe",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghc-proxy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.1",
|
|
5
5
|
"description": "GitHub Copilot to OpenAI/Anthropic API proxy - Use Copilot with Claude Code, Cursor, and more",
|
|
6
6
|
"author": "wxxb789 <wxxb789@outlook.com>",
|
|
7
7
|
"homepage": "https://github.com/wxxb789/ghc-proxy",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"smoke:cache": "bun run scripts/smoke/cache-control.ts",
|
|
42
42
|
"smoke:packaged": "bun run scripts/smoke/packaged-cli.ts",
|
|
43
43
|
"smoke:translation": "bun run scripts/smoke/translation.ts",
|
|
44
|
+
"serve": "NODE_ENV=production bun run ./src/main.ts start --wait --idle-timeout=255 --upstream-timeout=1800",
|
|
44
45
|
"start": "NODE_ENV=production bun run ./src/main.ts",
|
|
45
46
|
"typecheck": "npx tsc --project tsconfig.json"
|
|
46
47
|
},
|