@tormentalabs/claude-code-wire-compat 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/README.md +32 -0
- package/dist/build-request.d.ts.map +1 -1
- package/dist/build-request.js +15 -2
- package/dist/build-request.js.map +1 -1
- package/dist/contracts.d.ts +10 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/model-identity.d.ts.map +1 -1
- package/dist/model-identity.js +14 -1
- package/dist/model-identity.js.map +1 -1
- package/dist/model-queries.d.ts +77 -0
- package/dist/model-queries.d.ts.map +1 -0
- package/dist/model-queries.js +205 -0
- package/dist/model-queries.js.map +1 -0
- package/package.json +4 -5
- package/src/build-request.ts +30 -16
- package/src/contracts.ts +10 -1
- package/src/index.ts +26 -3
- package/src/model-identity.ts +15 -1
- package/src/model-queries.ts +241 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-identity.d.ts","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;
|
|
1
|
+
{"version":3,"file":"model-identity.d.ts","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAgBD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqBtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,qBAAqB,CAOzE"}
|
package/dist/model-identity.js
CHANGED
|
@@ -3,9 +3,22 @@
|
|
|
3
3
|
export function stripModelMarkers(model) {
|
|
4
4
|
return model.replace(/\[(1|2)m\]/gi, "");
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Rewrites dotted version separators to the hyphenated form upstream uses on
|
|
8
|
+
* the wire (`claude-opus-4.7` -> `claude-opus-4-7`). Only a digit-dot-digit
|
|
9
|
+
* run is rewritten, so ids with no dotted version (`gpt-4o`, `""`) and
|
|
10
|
+
* unrelated dots are left byte-identical.
|
|
11
|
+
*
|
|
12
|
+
* The plugin performs the same rewrite at its wire seam
|
|
13
|
+
* (`lib/mimicry/wire-compat.mjs`); the plugin's own family predicates accept
|
|
14
|
+
* `[._-]` interchangeably, so this keeps package classification in parity.
|
|
15
|
+
*/
|
|
16
|
+
function dottedToDashedVersion(model) {
|
|
17
|
+
return model.replace(/(\d)\.(\d)/g, "$1-$2");
|
|
18
|
+
}
|
|
6
19
|
/** Ports upstream `$_` (binary offset 226639025). */
|
|
7
20
|
export function normalizeModelId(model) {
|
|
8
|
-
model = model.toLowerCase();
|
|
21
|
+
model = dottedToDashedVersion(model.toLowerCase());
|
|
9
22
|
if (model.includes("claude-fable-5"))
|
|
10
23
|
return "claude-fable-5";
|
|
11
24
|
if (model.includes("claude-mythos-5"))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-identity.js","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAI5C,qDAAqD;AACrD,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"model-identity.js","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAI5C,qDAAqD;AACrD,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACnD,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAC9D,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,iBAAiB,CAAC;IACvE,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACpE,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACpE,IAAI,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAC3E,IAAI,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACpE,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACpE,IAAI,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,eAAe,CAAC;IAC5D,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAChE,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAC9D,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,YAAoB;IAChD,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ClaudeCodeProtocolProfile } from "./contracts.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether the active profile's catalogue records `capability` for `model`.
|
|
4
|
+
*
|
|
5
|
+
* `capability` is a verbatim upstream capability string. Ids the profile does
|
|
6
|
+
* not catalogue answer `false` for every capability: the catalogue is the only
|
|
7
|
+
* evidence this query consults, and absence of evidence is reported as
|
|
8
|
+
* absence. Callers wanting the derived nine-boolean view -- which falls back
|
|
9
|
+
* to the ported predicates for uncatalogued ids -- want `resolveModel`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function modelCapability(model: string, capability: string, profile?: ClaudeCodeProtocolProfile): boolean;
|
|
12
|
+
/** Whether `model` normalizes to `claude-opus-4-6`. */
|
|
13
|
+
export declare function isOpus46Model(model: string): boolean;
|
|
14
|
+
/** Whether `model` normalizes to `claude-opus-4-7`. */
|
|
15
|
+
export declare function isOpus47Model(model: string): boolean;
|
|
16
|
+
/** Whether `model` normalizes to `claude-opus-4-8`. */
|
|
17
|
+
export declare function isOpus48Model(model: string): boolean;
|
|
18
|
+
/** Whether `model` normalizes to `claude-sonnet-4-6`. */
|
|
19
|
+
export declare function isSonnet46Model(model: string): boolean;
|
|
20
|
+
/** Whether `model` normalizes to `claude-fable-5`. */
|
|
21
|
+
export declare function isFable5Model(model: string): boolean;
|
|
22
|
+
/** Whether `model` normalizes to `claude-mythos-5`. */
|
|
23
|
+
export declare function isMythos5Model(model: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether `model` belongs to the haiku family.
|
|
26
|
+
*
|
|
27
|
+
* Reuses `modelFamilyOf`, the package's one family classifier, so a new haiku
|
|
28
|
+
* id is classified in exactly one place.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isHaikuModel(model: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Whether `model` is a Claude 3 generation id.
|
|
33
|
+
*
|
|
34
|
+
* The `claude-3-` substring test is the same one the ported capability
|
|
35
|
+
* predicates open with (`model-capabilities.ts`), applied to the normalized
|
|
36
|
+
* id, so a Claude 3 id spelled with a dotted version (`claude-3.5-sonnet`)
|
|
37
|
+
* classifies with its hyphenated spelling.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isClaude3Model(model: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether `model` may receive the 1M-context beta.
|
|
42
|
+
*
|
|
43
|
+
* Three sources, in order: an explicit 1M marker in the id, the active
|
|
44
|
+
* profile's `context.supports1mBeta`, and -- for ids the profile does not
|
|
45
|
+
* catalogue -- the ported family set (`claude-sonnet-4*`, Opus 4.6/4.7/4.8).
|
|
46
|
+
*/
|
|
47
|
+
export declare function isEligibleFor1MContext(model: string, profile?: ClaudeCodeProtocolProfile): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Whether `model` names 1M context explicitly and therefore always uses it.
|
|
50
|
+
*
|
|
51
|
+
* Marker-only by design. The catalogue's `context.native1m` is a DIFFERENT
|
|
52
|
+
* question -- the model's native window -- and consulting it here would make
|
|
53
|
+
* every natively-1M id answer true, which is not what a static "always send
|
|
54
|
+
* 1M" gate means. Use `modelContextWindow`-shaped catalogue reads for that.
|
|
55
|
+
*/
|
|
56
|
+
export declare function hasOneMillionContext(model: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Whether `model` supports the structured-outputs beta.
|
|
59
|
+
*
|
|
60
|
+
* Delegates to the predicate ported from the genuine client (`j4e`), which is
|
|
61
|
+
* narrower and better evidenced than a family-shaped heuristic.
|
|
62
|
+
*/
|
|
63
|
+
export declare function supportsStructuredOutputs(model: string): boolean;
|
|
64
|
+
/** Whether `model` supports the web-search tool. */
|
|
65
|
+
export declare function supportsWebSearch(model: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Whether `model` uses adaptive thinking (`{type: "adaptive"}`) instead of a
|
|
68
|
+
* manual `budget_tokens`.
|
|
69
|
+
*
|
|
70
|
+
* The union of the named family predicates, not a catalogue read: this gates
|
|
71
|
+
* the shape of the emitted `thinking` block, and an uncatalogued id must not
|
|
72
|
+
* inherit adaptive thinking from the permissive capability fallback. Ask
|
|
73
|
+
* `modelCapability(model, "adaptive_thinking", profile)` for the catalogue's
|
|
74
|
+
* answer.
|
|
75
|
+
*/
|
|
76
|
+
export declare function isAdaptiveThinkingModel(model: string): boolean;
|
|
77
|
+
//# sourceMappingURL=model-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-queries.d.ts","sourceRoot":"","sources":["../src/model-queries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AA4EhE;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,yBAAuD,GAC/D,OAAO,CAcT;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,yBAAuD,GAC/D,OAAO,CAkBT;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED,oDAAoD;AACpD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAS9D"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
import { supportsStructuredOutputs as portedStructuredOutputs } from "./model-capabilities.js";
|
|
3
|
+
import { modelFamilyOf, normalizeModelId } from "./model-identity.js";
|
|
4
|
+
import { CLAUDE_CODE_2_1_195_PROFILE } from "./profiles/claude-code-2.1.195.js";
|
|
5
|
+
/*
|
|
6
|
+
* Read-only model queries.
|
|
7
|
+
*
|
|
8
|
+
* DESIGN DECISION (Phase 1.1). Two surfaces, deliberately separate:
|
|
9
|
+
*
|
|
10
|
+
* 1. `modelCapability(model, capability, profile)` -- the GENERIC query. The
|
|
11
|
+
* catalogue is the source of truth: it normalizes the id, looks the entry
|
|
12
|
+
* up in `profile.supportedModels` and asks whether the verbatim upstream
|
|
13
|
+
* capability string is present. It invents nothing, maps nothing, and
|
|
14
|
+
* therefore answers for capability strings this package does not model as
|
|
15
|
+
* a `ClaudeCodeCapabilities` field (`fast_mode`, `lean_prompt`,
|
|
16
|
+
* `fable_5_mitigations`, `mid_conv_system`, ...) as readily as for the
|
|
17
|
+
* six that it does.
|
|
18
|
+
*
|
|
19
|
+
* 2. The NAMED family/version predicates below -- `isOpus47Model` and
|
|
20
|
+
* friends. A family is not a catalogue capability; it is an identity
|
|
21
|
+
* question. They are therefore written over `normalizeModelId` and
|
|
22
|
+
* `modelFamilyOf`, NOT over a new family regex and NOT over the
|
|
23
|
+
* catalogue. Consequence, and it is intended: an id normalizing to
|
|
24
|
+
* `claude-opus-4-7` answers `isOpus47Model` true whether or not the
|
|
25
|
+
* active profile catalogues it.
|
|
26
|
+
*
|
|
27
|
+
* Do not fold (2) into (1). Asking `modelCapability(model, "adaptive_thinking")`
|
|
28
|
+
* and asking `isAdaptiveThinkingModel(model)` are different questions with
|
|
29
|
+
* different answers for ids the active profile does not catalogue, and both
|
|
30
|
+
* questions have callers.
|
|
31
|
+
*
|
|
32
|
+
* INVALID INPUT. Every predicate here returns `false` for a non-string or an
|
|
33
|
+
* empty id rather than throwing. This departs from `resolveModel`
|
|
34
|
+
* (`ClaudeCodeWireError("INVALID_INPUT")`) on purpose: these are predicates,
|
|
35
|
+
* their upstream counterparts are total functions returning `false` on a
|
|
36
|
+
* falsy model, and a predicate that throws cannot be used in the boolean
|
|
37
|
+
* position its callers put it in.
|
|
38
|
+
*
|
|
39
|
+
* RUNTIME NEUTRALITY. No builtins, no clock, no randomness, no I/O.
|
|
40
|
+
*/
|
|
41
|
+
/** Lowercased + dotted-to-dashed id, or `null` for input no predicate can answer for. */
|
|
42
|
+
function normalizedOrNull(model) {
|
|
43
|
+
if (typeof model !== "string" || model.length === 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return normalizeModelId(model);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Explicit 1M markers a caller can spell into the model id.
|
|
50
|
+
*
|
|
51
|
+
* `\[1m\]` is deliberately absent: it marks a request-time context selection,
|
|
52
|
+
* not an always-1M id, and the upstream marker check does not accept it.
|
|
53
|
+
*/
|
|
54
|
+
const ONE_MILLION_MARKER_RE = /(^|[-_ ])1m($|[-_ ])|context[-_]?1m/iu;
|
|
55
|
+
/** As `ONE_MILLION_MARKER_RE`, plus the bracketed request-time marker. */
|
|
56
|
+
const ONE_MILLION_ELIGIBLE_MARKER_RE = /(^|[-_ ])1m($|[-_ ])|context[-_]?1m|\[1m\]/iu;
|
|
57
|
+
/**
|
|
58
|
+
* Vendor tokens the upstream web-search gate accepts. Transcribed as a token
|
|
59
|
+
* list rather than a regex so it stays a data question, not a pattern-matching
|
|
60
|
+
* one.
|
|
61
|
+
*/
|
|
62
|
+
const WEB_SEARCH_VENDOR_TOKENS = Object.freeze([
|
|
63
|
+
"claude",
|
|
64
|
+
"sonnet",
|
|
65
|
+
"opus",
|
|
66
|
+
"haiku",
|
|
67
|
+
"gpt",
|
|
68
|
+
"gemini",
|
|
69
|
+
]);
|
|
70
|
+
/**
|
|
71
|
+
* Whether the active profile's catalogue records `capability` for `model`.
|
|
72
|
+
*
|
|
73
|
+
* `capability` is a verbatim upstream capability string. Ids the profile does
|
|
74
|
+
* not catalogue answer `false` for every capability: the catalogue is the only
|
|
75
|
+
* evidence this query consults, and absence of evidence is reported as
|
|
76
|
+
* absence. Callers wanting the derived nine-boolean view -- which falls back
|
|
77
|
+
* to the ported predicates for uncatalogued ids -- want `resolveModel`.
|
|
78
|
+
*/
|
|
79
|
+
export function modelCapability(model, capability, profile = CLAUDE_CODE_2_1_195_PROFILE) {
|
|
80
|
+
const id = normalizedOrNull(model);
|
|
81
|
+
if (id === null ||
|
|
82
|
+
typeof capability !== "string" ||
|
|
83
|
+
capability.length === 0) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const entry = profile.supportedModels[id];
|
|
87
|
+
if (entry === undefined) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return entry.capabilities.includes(capability);
|
|
91
|
+
}
|
|
92
|
+
/** Whether `model` normalizes to `claude-opus-4-6`. */
|
|
93
|
+
export function isOpus46Model(model) {
|
|
94
|
+
return normalizedOrNull(model) === "claude-opus-4-6";
|
|
95
|
+
}
|
|
96
|
+
/** Whether `model` normalizes to `claude-opus-4-7`. */
|
|
97
|
+
export function isOpus47Model(model) {
|
|
98
|
+
return normalizedOrNull(model) === "claude-opus-4-7";
|
|
99
|
+
}
|
|
100
|
+
/** Whether `model` normalizes to `claude-opus-4-8`. */
|
|
101
|
+
export function isOpus48Model(model) {
|
|
102
|
+
return normalizedOrNull(model) === "claude-opus-4-8";
|
|
103
|
+
}
|
|
104
|
+
/** Whether `model` normalizes to `claude-sonnet-4-6`. */
|
|
105
|
+
export function isSonnet46Model(model) {
|
|
106
|
+
return normalizedOrNull(model) === "claude-sonnet-4-6";
|
|
107
|
+
}
|
|
108
|
+
/** Whether `model` normalizes to `claude-fable-5`. */
|
|
109
|
+
export function isFable5Model(model) {
|
|
110
|
+
return normalizedOrNull(model) === "claude-fable-5";
|
|
111
|
+
}
|
|
112
|
+
/** Whether `model` normalizes to `claude-mythos-5`. */
|
|
113
|
+
export function isMythos5Model(model) {
|
|
114
|
+
return normalizedOrNull(model) === "claude-mythos-5";
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Whether `model` belongs to the haiku family.
|
|
118
|
+
*
|
|
119
|
+
* Reuses `modelFamilyOf`, the package's one family classifier, so a new haiku
|
|
120
|
+
* id is classified in exactly one place.
|
|
121
|
+
*/
|
|
122
|
+
export function isHaikuModel(model) {
|
|
123
|
+
const id = normalizedOrNull(model);
|
|
124
|
+
return id !== null && modelFamilyOf(id) === "haiku";
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Whether `model` is a Claude 3 generation id.
|
|
128
|
+
*
|
|
129
|
+
* The `claude-3-` substring test is the same one the ported capability
|
|
130
|
+
* predicates open with (`model-capabilities.ts`), applied to the normalized
|
|
131
|
+
* id, so a Claude 3 id spelled with a dotted version (`claude-3.5-sonnet`)
|
|
132
|
+
* classifies with its hyphenated spelling.
|
|
133
|
+
*/
|
|
134
|
+
export function isClaude3Model(model) {
|
|
135
|
+
return normalizedOrNull(model)?.includes("claude-3-") ?? false;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Whether `model` may receive the 1M-context beta.
|
|
139
|
+
*
|
|
140
|
+
* Three sources, in order: an explicit 1M marker in the id, the active
|
|
141
|
+
* profile's `context.supports1mBeta`, and -- for ids the profile does not
|
|
142
|
+
* catalogue -- the ported family set (`claude-sonnet-4*`, Opus 4.6/4.7/4.8).
|
|
143
|
+
*/
|
|
144
|
+
export function isEligibleFor1MContext(model, profile = CLAUDE_CODE_2_1_195_PROFILE) {
|
|
145
|
+
const id = normalizedOrNull(model);
|
|
146
|
+
if (id === null) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
if (ONE_MILLION_ELIGIBLE_MARKER_RE.test(model)) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
const entry = profile.supportedModels[id];
|
|
153
|
+
if (entry !== undefined) {
|
|
154
|
+
return entry.context?.supports1mBeta === true;
|
|
155
|
+
}
|
|
156
|
+
return (id.startsWith("claude-sonnet-4") ||
|
|
157
|
+
id === "claude-opus-4-6" ||
|
|
158
|
+
id === "claude-opus-4-7" ||
|
|
159
|
+
id === "claude-opus-4-8");
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Whether `model` names 1M context explicitly and therefore always uses it.
|
|
163
|
+
*
|
|
164
|
+
* Marker-only by design. The catalogue's `context.native1m` is a DIFFERENT
|
|
165
|
+
* question -- the model's native window -- and consulting it here would make
|
|
166
|
+
* every natively-1M id answer true, which is not what a static "always send
|
|
167
|
+
* 1M" gate means. Use `modelContextWindow`-shaped catalogue reads for that.
|
|
168
|
+
*/
|
|
169
|
+
export function hasOneMillionContext(model) {
|
|
170
|
+
return normalizedOrNull(model) !== null && ONE_MILLION_MARKER_RE.test(model);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Whether `model` supports the structured-outputs beta.
|
|
174
|
+
*
|
|
175
|
+
* Delegates to the predicate ported from the genuine client (`j4e`), which is
|
|
176
|
+
* narrower and better evidenced than a family-shaped heuristic.
|
|
177
|
+
*/
|
|
178
|
+
export function supportsStructuredOutputs(model) {
|
|
179
|
+
const id = normalizedOrNull(model);
|
|
180
|
+
return id !== null && portedStructuredOutputs(id);
|
|
181
|
+
}
|
|
182
|
+
/** Whether `model` supports the web-search tool. */
|
|
183
|
+
export function supportsWebSearch(model) {
|
|
184
|
+
const id = normalizedOrNull(model);
|
|
185
|
+
return (id !== null && WEB_SEARCH_VENDOR_TOKENS.some((token) => id.includes(token)));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Whether `model` uses adaptive thinking (`{type: "adaptive"}`) instead of a
|
|
189
|
+
* manual `budget_tokens`.
|
|
190
|
+
*
|
|
191
|
+
* The union of the named family predicates, not a catalogue read: this gates
|
|
192
|
+
* the shape of the emitted `thinking` block, and an uncatalogued id must not
|
|
193
|
+
* inherit adaptive thinking from the permissive capability fallback. Ask
|
|
194
|
+
* `modelCapability(model, "adaptive_thinking", profile)` for the catalogue's
|
|
195
|
+
* answer.
|
|
196
|
+
*/
|
|
197
|
+
export function isAdaptiveThinkingModel(model) {
|
|
198
|
+
return (isOpus46Model(model) ||
|
|
199
|
+
isOpus47Model(model) ||
|
|
200
|
+
isOpus48Model(model) ||
|
|
201
|
+
isSonnet46Model(model) ||
|
|
202
|
+
isFable5Model(model) ||
|
|
203
|
+
isMythos5Model(model));
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=model-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-queries.js","sourceRoot":"","sources":["../src/model-queries.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tormentalabs/claude-code-wire-compat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Runtime-neutral Claude Code Messages wire compatibility primitives",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"test:coverage": "vitest run --coverage",
|
|
54
54
|
"test:pack": "node scripts/verify-packed-consumers.mjs",
|
|
55
55
|
"pack:check": "npm pack --dry-run && publint && attw --pack . --profile esm-only",
|
|
56
|
-
"drift:check": "node scripts/verify-drift.mjs",
|
|
57
56
|
"fixtures:check": "node scripts/seal-golden-fixtures.mjs --check",
|
|
58
57
|
"fixtures:seal": "node scripts/seal-golden-fixtures.mjs --write",
|
|
59
58
|
"extract:profile": "node scripts/extract-upstream-profile.mjs"
|
|
@@ -61,18 +60,18 @@
|
|
|
61
60
|
"devDependencies": {
|
|
62
61
|
"@arethetypeswrong/cli": "0.18.5",
|
|
63
62
|
"@eslint/js": "10.0.1",
|
|
64
|
-
"@types/node": "26.
|
|
63
|
+
"@types/node": "26.2.0",
|
|
65
64
|
"@vitest/coverage-v8": "4.1.10",
|
|
66
65
|
"@vitest/eslint-plugin": "1.6.24",
|
|
67
66
|
"eslint": "10.8.0",
|
|
68
67
|
"fast-check": "4.9.0",
|
|
69
|
-
"globals": "17.
|
|
68
|
+
"globals": "17.11.0",
|
|
70
69
|
"license-checker-rseidelsohn": "5.0.1",
|
|
71
70
|
"miniflare": "4.20260722.0",
|
|
72
71
|
"prettier": "3.9.6",
|
|
73
72
|
"publint": "0.3.22",
|
|
74
73
|
"typescript": "6.0.3",
|
|
75
|
-
"typescript-eslint": "8.
|
|
74
|
+
"typescript-eslint": "8.67.0",
|
|
76
75
|
"vitest": "4.1.10"
|
|
77
76
|
},
|
|
78
77
|
"overrides": {
|
package/src/build-request.ts
CHANGED
|
@@ -111,6 +111,7 @@ const COUNT_TOKENS_INPUT_KEYS = new Set([
|
|
|
111
111
|
"clientApp",
|
|
112
112
|
"anthropicAdditionalProtection",
|
|
113
113
|
"extraHeaders",
|
|
114
|
+
"extraHeaderPolicy",
|
|
114
115
|
]);
|
|
115
116
|
const BUILT_KEYS = new Set(["url", "method", "headers", "body", "evidence"]);
|
|
116
117
|
/**
|
|
@@ -873,6 +874,7 @@ function validateCountTokensInput(input: ClaudeCodeCountTokensInput): {
|
|
|
873
874
|
readonly clientRequestId: string;
|
|
874
875
|
readonly crypto: Pick<Crypto, "subtle"> | undefined;
|
|
875
876
|
readonly profileOverride: ClaudeCodeProfileOverride | undefined;
|
|
877
|
+
readonly extraHeaderPolicy: ClaudeCodeExtraHeaderPolicy | undefined;
|
|
876
878
|
} {
|
|
877
879
|
if (!isRecord(input)) fail();
|
|
878
880
|
assertExactKeys(input, COUNT_TOKENS_INPUT_KEYS);
|
|
@@ -915,11 +917,15 @@ function validateCountTokensInput(input: ClaudeCodeCountTokensInput): {
|
|
|
915
917
|
const profileOverride = Object.hasOwn(input, "profileOverride")
|
|
916
918
|
? validateProfileOverride(ownValue(input, "profileOverride"))
|
|
917
919
|
: undefined;
|
|
920
|
+
const extraHeaderPolicy = Object.hasOwn(input, "extraHeaderPolicy")
|
|
921
|
+
? validateExtraHeaderPolicy(ownValue(input, "extraHeaderPolicy"))
|
|
922
|
+
: undefined;
|
|
918
923
|
return {
|
|
919
924
|
source: input,
|
|
920
925
|
clientRequestId,
|
|
921
926
|
crypto: cryptoValue,
|
|
922
927
|
profileOverride,
|
|
928
|
+
extraHeaderPolicy,
|
|
923
929
|
};
|
|
924
930
|
}
|
|
925
931
|
|
|
@@ -1441,23 +1447,25 @@ export async function buildClaudeCodeCountTokensRequest(
|
|
|
1441
1447
|
),
|
|
1442
1448
|
);
|
|
1443
1449
|
const betas = Object.freeze([...countTokensBetas, TOKEN_COUNTING_BETA]);
|
|
1450
|
+
const headerPlan = buildOrderedHeaderPlan({
|
|
1451
|
+
accessToken: validated.source.accessToken,
|
|
1452
|
+
runtime: identity,
|
|
1453
|
+
clientRequestId: validated.clientRequestId,
|
|
1454
|
+
betaFeatures: betas,
|
|
1455
|
+
app: validated.source.app ?? effectiveProfile.entrypoint,
|
|
1456
|
+
stainlessRetryCount: validated.source.stainlessRetryCount ?? 0,
|
|
1457
|
+
stainlessHelper: validated.source.stainlessHelper,
|
|
1458
|
+
claudeRemoteContainerId: validated.source.claudeRemoteContainerId,
|
|
1459
|
+
claudeRemoteSessionId: validated.source.claudeRemoteSessionId,
|
|
1460
|
+
clientApp: validated.source.clientApp,
|
|
1461
|
+
anthropicAdditionalProtection:
|
|
1462
|
+
validated.source.anthropicAdditionalProtection,
|
|
1463
|
+
extraHeaders: validated.source.extraHeaders ?? [],
|
|
1464
|
+
extraHeaderPolicy: validated.extraHeaderPolicy ?? "strict",
|
|
1465
|
+
profile: pinnedProfile,
|
|
1466
|
+
});
|
|
1444
1467
|
const headers = applyEffectiveProfileHeaders(
|
|
1445
|
-
|
|
1446
|
-
accessToken: validated.source.accessToken,
|
|
1447
|
-
runtime: identity,
|
|
1448
|
-
clientRequestId: validated.clientRequestId,
|
|
1449
|
-
betaFeatures: betas,
|
|
1450
|
-
app: validated.source.app ?? effectiveProfile.entrypoint,
|
|
1451
|
-
stainlessRetryCount: validated.source.stainlessRetryCount ?? 0,
|
|
1452
|
-
stainlessHelper: validated.source.stainlessHelper,
|
|
1453
|
-
claudeRemoteContainerId: validated.source.claudeRemoteContainerId,
|
|
1454
|
-
claudeRemoteSessionId: validated.source.claudeRemoteSessionId,
|
|
1455
|
-
clientApp: validated.source.clientApp,
|
|
1456
|
-
anthropicAdditionalProtection:
|
|
1457
|
-
validated.source.anthropicAdditionalProtection,
|
|
1458
|
-
extraHeaders: validated.source.extraHeaders ?? [],
|
|
1459
|
-
profile: pinnedProfile,
|
|
1460
|
-
}),
|
|
1468
|
+
headerPlan.headers,
|
|
1461
1469
|
effectiveProfile,
|
|
1462
1470
|
);
|
|
1463
1471
|
const canonical = canonicalCountTokensLists(
|
|
@@ -1484,6 +1492,12 @@ export async function buildClaudeCodeCountTokensRequest(
|
|
|
1484
1492
|
logicalHeaders: headers,
|
|
1485
1493
|
betaFeatures: betas,
|
|
1486
1494
|
body,
|
|
1495
|
+
// Emitted only for the opted-in policy, exactly as the main path does,
|
|
1496
|
+
// so count-tokens evidence for every other request keeps the shape it
|
|
1497
|
+
// had before the seam reached this surface.
|
|
1498
|
+
...(validated.extraHeaderPolicy === "dropConflicting"
|
|
1499
|
+
? { droppedExtraHeaderNames: headerPlan.droppedExtraHeaderNames }
|
|
1500
|
+
: {}),
|
|
1487
1501
|
},
|
|
1488
1502
|
validated.crypto,
|
|
1489
1503
|
);
|
package/src/contracts.ts
CHANGED
|
@@ -1067,7 +1067,15 @@ export interface ClaudeCodeRequestInput {
|
|
|
1067
1067
|
* Narrower than `ClaudeCodeRequestInput` by design. Upstream `P5e` derives the
|
|
1068
1068
|
* beta set from the model alone, so there is deliberately no `capabilities`
|
|
1069
1069
|
* field, and the count-tokens body carries no `system`, `metadata`, or
|
|
1070
|
-
* `maxTokens`.
|
|
1070
|
+
* `maxTokens`. Those four omissions are fidelity to upstream and stay out.
|
|
1071
|
+
*
|
|
1072
|
+
* `extraHeaderPolicy` is deliberately IN, on the other hand: it is a PACKAGE
|
|
1073
|
+
* EXTENSION over the transport, not a claim about the count-tokens body, and
|
|
1074
|
+
* `buildOrderedHeaders` is the same code path on both surfaces. Leaving it out
|
|
1075
|
+
* forced consumers to re-implement conflict dropping client-side against a
|
|
1076
|
+
* mirrored list of the header names this package owns. Omitting the field, or
|
|
1077
|
+
* passing `"strict"`, leaves the emitted count-tokens request byte-identical,
|
|
1078
|
+
* evidence included.
|
|
1071
1079
|
*/
|
|
1072
1080
|
export type ClaudeCodeCountTokensInput = Pick<
|
|
1073
1081
|
ClaudeCodeRequestInput,
|
|
@@ -1087,6 +1095,7 @@ export type ClaudeCodeCountTokensInput = Pick<
|
|
|
1087
1095
|
| "clientApp"
|
|
1088
1096
|
| "anthropicAdditionalProtection"
|
|
1089
1097
|
| "extraHeaders"
|
|
1098
|
+
| "extraHeaderPolicy"
|
|
1090
1099
|
>;
|
|
1091
1100
|
|
|
1092
1101
|
export interface BuiltClaudeCodeCountTokensRequest extends Omit<
|
package/src/index.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Public entry point for the Claude Code wire compatibility package.
|
|
5
5
|
*
|
|
6
|
-
* Only the surfaces listed below are public.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Only the surfaces listed below are public. Internal protocol modules remain
|
|
7
|
+
* private; the documented builder, parser, anti-verbosity helpers, read-only
|
|
8
|
+
* model queries and the transcribed beta registries are exported here, and
|
|
9
|
+
* nothing else.
|
|
9
10
|
*
|
|
10
11
|
* Importing this module has no side effects. It reads no environment, opens
|
|
11
12
|
* no network connection, touches no clock or random source, and holds no
|
|
@@ -53,11 +54,33 @@ export {
|
|
|
53
54
|
selectAntiVerbositySection,
|
|
54
55
|
} from "./anti-verbosity.js";
|
|
55
56
|
|
|
57
|
+
export { BETA_REGISTRY } from "./beta-registry.js";
|
|
58
|
+
|
|
56
59
|
export {
|
|
57
60
|
buildClaudeCodeCountTokensRequest,
|
|
58
61
|
buildClaudeCodeRequest,
|
|
59
62
|
parseBuiltClaudeCodeRequest,
|
|
60
63
|
} from "./build-request.js";
|
|
61
64
|
|
|
65
|
+
export { TOKEN_COUNTING_BETA } from "./count-tokens.js";
|
|
66
|
+
|
|
67
|
+
export {
|
|
68
|
+
hasOneMillionContext,
|
|
69
|
+
isAdaptiveThinkingModel,
|
|
70
|
+
isClaude3Model,
|
|
71
|
+
isEligibleFor1MContext,
|
|
72
|
+
isFable5Model,
|
|
73
|
+
isHaikuModel,
|
|
74
|
+
isMythos5Model,
|
|
75
|
+
isOpus46Model,
|
|
76
|
+
isOpus47Model,
|
|
77
|
+
isOpus48Model,
|
|
78
|
+
isSonnet46Model,
|
|
79
|
+
modelCapability,
|
|
80
|
+
supportsStructuredOutputs,
|
|
81
|
+
supportsWebSearch,
|
|
82
|
+
} from "./model-queries.js";
|
|
83
|
+
|
|
84
|
+
export { BETA_REGISTRY_2_1_233 } from "./profiles/beta-registry-2.1.233.js";
|
|
62
85
|
export { CLAUDE_CODE_2_1_195_PROFILE } from "./profiles/claude-code-2.1.195.js";
|
|
63
86
|
export { CLAUDE_CODE_2_1_233_PROFILE } from "./profiles/claude-code-2.1.233.js";
|
package/src/model-identity.ts
CHANGED
|
@@ -7,9 +7,23 @@ export function stripModelMarkers(model: string): string {
|
|
|
7
7
|
return model.replace(/\[(1|2)m\]/gi, "");
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Rewrites dotted version separators to the hyphenated form upstream uses on
|
|
12
|
+
* the wire (`claude-opus-4.7` -> `claude-opus-4-7`). Only a digit-dot-digit
|
|
13
|
+
* run is rewritten, so ids with no dotted version (`gpt-4o`, `""`) and
|
|
14
|
+
* unrelated dots are left byte-identical.
|
|
15
|
+
*
|
|
16
|
+
* The plugin performs the same rewrite at its wire seam
|
|
17
|
+
* (`lib/mimicry/wire-compat.mjs`); the plugin's own family predicates accept
|
|
18
|
+
* `[._-]` interchangeably, so this keeps package classification in parity.
|
|
19
|
+
*/
|
|
20
|
+
function dottedToDashedVersion(model: string): string {
|
|
21
|
+
return model.replace(/(\d)\.(\d)/g, "$1-$2");
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
/** Ports upstream `$_` (binary offset 226639025). */
|
|
11
25
|
export function normalizeModelId(model: string): string {
|
|
12
|
-
model = model.toLowerCase();
|
|
26
|
+
model = dottedToDashedVersion(model.toLowerCase());
|
|
13
27
|
if (model.includes("claude-fable-5")) return "claude-fable-5";
|
|
14
28
|
if (model.includes("claude-mythos-5")) return "claude-mythos-5";
|
|
15
29
|
if (model.includes("claude-opus-4-8")) return "claude-opus-4-8";
|