opencode-auth-load-balancer 0.4.0 → 0.4.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 +5 -1
- package/dist/index.js +1538 -1496
- package/dist/providers/anthropic/constants.d.ts +27 -0
- package/dist/providers/anthropic/version.d.ts +21 -0
- package/dist/providers/types.d.ts +20 -0
- package/package.json +1 -1
|
@@ -83,6 +83,33 @@ export declare const FALLBACK_CLAUDE_CODE_VERSION = "2.1.258";
|
|
|
83
83
|
* `cch` fingerprint algorithm and the newest version starts 400ing).
|
|
84
84
|
*/
|
|
85
85
|
export declare const CLAUDE_CODE_VERSION_ENV = "OPENCODE_AUTH_LB_ANTHROPIC_CLAUDE_CODE_VERSION";
|
|
86
|
+
/**
|
|
87
|
+
* The structured error code Anthropic answers a version-gated model with:
|
|
88
|
+
*
|
|
89
|
+
* ```json
|
|
90
|
+
* {"type":"error","error":{"type":"invalid_request_error",
|
|
91
|
+
* "message":"Claude Code 2.1.278 does not support this model; version 2.1.280 or newer is required.",
|
|
92
|
+
* "details":{"error_code":"claude_code_version_too_old"}}}
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* Matched as a SUBSTRING of the raw body rather than through a parsed path
|
|
96
|
+
* (`error.details.error_code`): the envelope's shape is Anthropic's to change,
|
|
97
|
+
* and this string appearing anywhere in a rejection is both sufficient — no
|
|
98
|
+
* other error carries it — and immune to a reshuffle that would silently break
|
|
99
|
+
* a path lookup. See `recoverClaudeCodeVersion` in version.ts.
|
|
100
|
+
*/
|
|
101
|
+
export declare const CLAUDE_CODE_VERSION_GATE_CODE = "claude_code_version_too_old";
|
|
102
|
+
/**
|
|
103
|
+
* The MINIMUM version that rejection's human-readable message demands.
|
|
104
|
+
*
|
|
105
|
+
* Anchored on the `or newer is required` tail rather than the first version in
|
|
106
|
+
* the string, because the message names TWO: the one we just sent ("Claude
|
|
107
|
+
* Code 2.1.278 does not support this model") and the one being asked for
|
|
108
|
+
* ("version 2.1.280 or newer is required"). Capturing the leading one would
|
|
109
|
+
* adopt the version that just failed — a no-op the recovery would correctly
|
|
110
|
+
* refuse to retry, i.e. a silent regression to the old stuck behavior.
|
|
111
|
+
*/
|
|
112
|
+
export declare const CLAUDE_CODE_REQUIRED_VERSION_RE: RegExp;
|
|
86
113
|
/**
|
|
87
114
|
* npm dist-tags for the Claude Code CLI — `{"latest":"2.1.258",…}`, ~56 bytes.
|
|
88
115
|
* Deliberately NOT `/@anthropic-ai/claude-code/latest`, which returns the whole
|
|
@@ -20,6 +20,27 @@ export declare function usageUserAgent(): string;
|
|
|
20
20
|
* usable answer, so a failure does NOT refresh the TTL).
|
|
21
21
|
*/
|
|
22
22
|
export declare function refreshClaudeCodeVersion(now: number): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* REACTIVE recovery, driven by the gate's own rejection.
|
|
25
|
+
*
|
|
26
|
+
* `primeClaudeCodeVersion` resolves once at startup and then trusts the cache
|
|
27
|
+
* for `CLAUDE_CODE_VERSION_TTL_MS`. A model that launches INSIDE that window is
|
|
28
|
+
* therefore rejected for as long as the TTL has left to run — up to a full day
|
|
29
|
+
* of hard failures — even when npm already tags the version Anthropic is asking
|
|
30
|
+
* for, and even though the rejection itself NAMES that version. No polling
|
|
31
|
+
* cadence fixes this in general either: Anthropic can gate a model before npm
|
|
32
|
+
* tags the release, which is why the env pin exists as a manual escape hatch.
|
|
33
|
+
*
|
|
34
|
+
* So learn from the rejection instead. Adopt the minimum it demands, then ask
|
|
35
|
+
* npm for the real `latest` in the same breath — the minimum only clears the
|
|
36
|
+
* model that just failed, whereas `latest` is what the NEXT launch will want.
|
|
37
|
+
*
|
|
38
|
+
* Returns whether the reported version actually MOVED, which is precisely the
|
|
39
|
+
* condition under which a retry can succeed; the caller spends a second
|
|
40
|
+
* round-trip on true and passes the rejection through untouched on false.
|
|
41
|
+
* `res` is consumed, so callers that still need the body must pass a clone.
|
|
42
|
+
*/
|
|
43
|
+
export declare function recoverClaudeCodeVersion(res: Response, now: number): Promise<boolean>;
|
|
23
44
|
/**
|
|
24
45
|
* Startup hook. Awaits only the LOCAL cache read — cheap, and enough to have
|
|
25
46
|
* the right version in hand before the loader returns the fetch — then leaves
|
|
@@ -136,4 +136,24 @@ export interface ProviderAdapter {
|
|
|
136
136
|
* downgraded body. null = treat the 429 as a normal account rotation.
|
|
137
137
|
*/
|
|
138
138
|
planReactiveFallback?(res: Response, body: string, now: number, models: readonly string[]): ReactiveModelFallback | null;
|
|
139
|
+
/**
|
|
140
|
+
* REACTIVE recovery from a CLIENT-VERSION gate: a provider may reject an
|
|
141
|
+
* otherwise-valid request until the plugin claims to be a newer client
|
|
142
|
+
* (Anthropic answers a too-new model with 400 `claude_code_version_too_old`,
|
|
143
|
+
* naming the minimum it wants). Such a status classifies as `ok` — the fetch
|
|
144
|
+
* loop is one statement away from handing it to the caller — so this is the
|
|
145
|
+
* last point at which it can become a recoverable event instead of a failed
|
|
146
|
+
* turn.
|
|
147
|
+
*
|
|
148
|
+
* Return true ONLY when the version the adapter will now report actually
|
|
149
|
+
* changed: the fetch loop reads that as "a retry can succeed" and restarts
|
|
150
|
+
* the request once. Returning true without a change would buy a second,
|
|
151
|
+
* byte-identical round-trip and the same rejection.
|
|
152
|
+
*
|
|
153
|
+
* `res` is a CLONE the implementation may consume freely; the original is
|
|
154
|
+
* still returned to the caller when this resolves false. Absent on providers
|
|
155
|
+
* with no such gate (OpenAI) — the fetch loop treats that as "nothing to
|
|
156
|
+
* recover".
|
|
157
|
+
*/
|
|
158
|
+
recoverClientVersion?(res: Response, now: number): Promise<boolean>;
|
|
139
159
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-auth-load-balancer",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Load-balance opencode requests across multiple Anthropic (Claude) and OpenAI (Codex) OAuth accounts, weighted primarily by weekly usage with drain-before-reset scheduling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|