@ex-machina/opencode-anthropic-auth 2.0.0-next.1 → 2.0.0-next.3
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 +2 -2
- package/dist/auth.d.ts +3 -3
- package/dist/auth.js +161 -82
- package/dist/bounded.d.ts +8 -0
- package/dist/bounded.js +59 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +25 -15
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +575 -57
- package/dist/json-response-stream.d.ts +10 -0
- package/dist/json-response-stream.js +638 -0
- package/dist/rate-limit.d.ts +18 -0
- package/dist/rate-limit.js +354 -0
- package/dist/transform.d.ts +41 -19
- package/dist/transform.js +592 -329
- package/dist/version-rejection.d.ts +17 -0
- package/dist/version-rejection.js +75 -0
- package/package.json +3 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ClaudeCodeVersionRejection {
|
|
2
|
+
readonly rejectedVersion: string;
|
|
3
|
+
readonly requiredVersion: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Parse only Anthropic's structured minimum-version rejection.
|
|
7
|
+
*
|
|
8
|
+
* The error code is authoritative; the bounded message supplies the versions.
|
|
9
|
+
* Requiring the rejected version to equal what this setup actually sent keeps
|
|
10
|
+
* an unrelated or stale response from changing later requests.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseClaudeCodeVersionRejection(body: string, reportedVersion: string): ClaudeCodeVersionRejection | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Inspect a clone so the provider still receives the original response body.
|
|
15
|
+
* Any malformed, oversized, non-JSON, or non-400 response is ignored.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectClaudeCodeVersionRejection(response: Response, reportedVersion: string): Promise<ClaudeCodeVersionRejection | undefined>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { contentLength, readBoundedText } from "./bounded.js";
|
|
2
|
+
import { compareClaudeCodeVersions, isValidClaudeCodeVersion, } from "./config.js";
|
|
3
|
+
const VERSION_TOO_OLD_CODE = 'claude_code_version_too_old';
|
|
4
|
+
const MAX_REJECTION_BODY_BYTES = 16 * 1024;
|
|
5
|
+
const MAX_REJECTION_MESSAGE_LENGTH = 1024;
|
|
6
|
+
const VERSION_REJECTION_PATTERN = /^Claude Code ([0-9.]{1,64}) does not support this model; version ([0-9.]{1,64}) or newer is required\./;
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return typeof value === 'object' && value !== null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse only Anthropic's structured minimum-version rejection.
|
|
12
|
+
*
|
|
13
|
+
* The error code is authoritative; the bounded message supplies the versions.
|
|
14
|
+
* Requiring the rejected version to equal what this setup actually sent keeps
|
|
15
|
+
* an unrelated or stale response from changing later requests.
|
|
16
|
+
*/
|
|
17
|
+
export function parseClaudeCodeVersionRejection(body, reportedVersion) {
|
|
18
|
+
if (body.length > MAX_REJECTION_BODY_BYTES)
|
|
19
|
+
return undefined;
|
|
20
|
+
let decoded;
|
|
21
|
+
try {
|
|
22
|
+
decoded = JSON.parse(body);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
if (!isRecord(decoded) || decoded.type !== 'error')
|
|
28
|
+
return undefined;
|
|
29
|
+
const error = decoded.error;
|
|
30
|
+
if (!isRecord(error) || error.type !== 'invalid_request_error') {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const details = error.details;
|
|
34
|
+
if (!isRecord(details) || details.error_code !== VERSION_TOO_OLD_CODE) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
if (typeof error.message !== 'string' ||
|
|
38
|
+
error.message.length > MAX_REJECTION_MESSAGE_LENGTH) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const match = VERSION_REJECTION_PATTERN.exec(error.message);
|
|
42
|
+
if (!match)
|
|
43
|
+
return undefined;
|
|
44
|
+
const rejectedVersion = match[1];
|
|
45
|
+
const requiredVersion = match[2];
|
|
46
|
+
if (!rejectedVersion ||
|
|
47
|
+
!requiredVersion ||
|
|
48
|
+
!isValidClaudeCodeVersion(rejectedVersion) ||
|
|
49
|
+
!isValidClaudeCodeVersion(requiredVersion) ||
|
|
50
|
+
rejectedVersion !== reportedVersion ||
|
|
51
|
+
compareClaudeCodeVersions(requiredVersion, reportedVersion) !== 1) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return { rejectedVersion, requiredVersion };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Inspect a clone so the provider still receives the original response body.
|
|
58
|
+
* Any malformed, oversized, non-JSON, or non-400 response is ignored.
|
|
59
|
+
*/
|
|
60
|
+
export async function detectClaudeCodeVersionRejection(response, reportedVersion) {
|
|
61
|
+
if (response.status !== 400)
|
|
62
|
+
return undefined;
|
|
63
|
+
const declaredLength = contentLength(response.headers);
|
|
64
|
+
if (declaredLength !== undefined &&
|
|
65
|
+
declaredLength > MAX_REJECTION_BODY_BYTES) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const body = await readBoundedText(response.clone().body, MAX_REJECTION_BODY_BYTES, 'Anthropic version rejection');
|
|
70
|
+
return parseClaudeCodeVersionRejection(body, reportedVersion);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ex-machina/opencode-anthropic-auth",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"release:next": "bun scripts/validate-next-release.ts && bun run release"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@opencode
|
|
36
|
+
"@opencode/plugin": "2.0.4",
|
|
37
|
+
"@streamparser/json": "0.0.26"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@biomejs/biome": "2.5.2",
|