@tormentalabs/claude-code-wire-compat 0.1.0-rc.10

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +312 -0
  2. package/LICENSE +674 -0
  3. package/NOTICE +16 -0
  4. package/README.md +39 -0
  5. package/dist/anti-verbosity.d.ts +58 -0
  6. package/dist/anti-verbosity.d.ts.map +1 -0
  7. package/dist/anti-verbosity.js +174 -0
  8. package/dist/anti-verbosity.js.map +1 -0
  9. package/dist/beta-registry.d.ts +119 -0
  10. package/dist/beta-registry.d.ts.map +1 -0
  11. package/dist/beta-registry.js +125 -0
  12. package/dist/beta-registry.js.map +1 -0
  13. package/dist/betas.d.ts +11 -0
  14. package/dist/betas.d.ts.map +1 -0
  15. package/dist/betas.js +68 -0
  16. package/dist/betas.js.map +1 -0
  17. package/dist/build-request.d.ts +24 -0
  18. package/dist/build-request.d.ts.map +1 -0
  19. package/dist/build-request.js +1008 -0
  20. package/dist/build-request.js.map +1 -0
  21. package/dist/contracts.d.ts +717 -0
  22. package/dist/contracts.d.ts.map +1 -0
  23. package/dist/contracts.js +36 -0
  24. package/dist/contracts.js.map +1 -0
  25. package/dist/count-tokens.d.ts +42 -0
  26. package/dist/count-tokens.d.ts.map +1 -0
  27. package/dist/count-tokens.js +61 -0
  28. package/dist/count-tokens.js.map +1 -0
  29. package/dist/fingerprint.d.ts +4 -0
  30. package/dist/fingerprint.d.ts.map +1 -0
  31. package/dist/fingerprint.js +59 -0
  32. package/dist/fingerprint.js.map +1 -0
  33. package/dist/headers.d.ts +4 -0
  34. package/dist/headers.d.ts.map +1 -0
  35. package/dist/headers.js +255 -0
  36. package/dist/headers.js.map +1 -0
  37. package/dist/index.d.ts +17 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +6 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/metadata.d.ts +4 -0
  42. package/dist/metadata.d.ts.map +1 -0
  43. package/dist/metadata.js +192 -0
  44. package/dist/metadata.js.map +1 -0
  45. package/dist/model-capabilities.d.ts +103 -0
  46. package/dist/model-capabilities.d.ts.map +1 -0
  47. package/dist/model-capabilities.js +263 -0
  48. package/dist/model-capabilities.js.map +1 -0
  49. package/dist/model-identity.d.ts +11 -0
  50. package/dist/model-identity.d.ts.map +1 -0
  51. package/dist/model-identity.js +64 -0
  52. package/dist/model-identity.js.map +1 -0
  53. package/dist/models.d.ts +9 -0
  54. package/dist/models.d.ts.map +1 -0
  55. package/dist/models.js +25 -0
  56. package/dist/models.js.map +1 -0
  57. package/dist/profiles/claude-code-2.1.195.d.ts +3 -0
  58. package/dist/profiles/claude-code-2.1.195.d.ts.map +1 -0
  59. package/dist/profiles/claude-code-2.1.195.js +150 -0
  60. package/dist/profiles/claude-code-2.1.195.js.map +1 -0
  61. package/dist/redaction.d.ts +16 -0
  62. package/dist/redaction.d.ts.map +1 -0
  63. package/dist/redaction.js +364 -0
  64. package/dist/redaction.js.map +1 -0
  65. package/dist/request-body.d.ts +19 -0
  66. package/dist/request-body.d.ts.map +1 -0
  67. package/dist/request-body.js +1658 -0
  68. package/dist/request-body.js.map +1 -0
  69. package/dist/sha256.d.ts +9 -0
  70. package/dist/sha256.d.ts.map +1 -0
  71. package/dist/sha256.js +104 -0
  72. package/dist/sha256.js.map +1 -0
  73. package/dist/system-prompt.d.ts +4 -0
  74. package/dist/system-prompt.d.ts.map +1 -0
  75. package/dist/system-prompt.js +157 -0
  76. package/dist/system-prompt.js.map +1 -0
  77. package/dist/thinking.d.ts +91 -0
  78. package/dist/thinking.d.ts.map +1 -0
  79. package/dist/thinking.js +132 -0
  80. package/dist/thinking.js.map +1 -0
  81. package/dist/unicode.d.ts +10 -0
  82. package/dist/unicode.d.ts.map +1 -0
  83. package/dist/unicode.js +19 -0
  84. package/dist/unicode.js.map +1 -0
  85. package/package.json +72 -0
@@ -0,0 +1,1008 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ import { composeBetas } from "./betas.js";
3
+ import { ClaudeCodeWireError } from "./contracts.js";
4
+ import { buildCountTokensBody, filterCountTokensBetas, TOKEN_COUNTING_BETA, } from "./count-tokens.js";
5
+ import { createBillingBlock } from "./fingerprint.js";
6
+ import { buildOrderedHeaders } from "./headers.js";
7
+ import { buildCorrelatedMetadata, validateRuntimeIdentity, } from "./metadata.js";
8
+ import { resolveModel } from "./models.js";
9
+ import { CLAUDE_CODE_2_1_195_PROFILE } from "./profiles/claude-code-2.1.195.js";
10
+ import { buildRedactedEvidence, toSafeErrorDetails } from "./redaction.js";
11
+ import { buildCanonicalBody, canonicalCountTokensLists, } from "./request-body.js";
12
+ import { sha256Hex } from "./sha256.js";
13
+ import { buildCanonicalSystem } from "./system-prompt.js";
14
+ import { isThinkingDisplayActive } from "./thinking.js";
15
+ import { classifySurrogateAt } from "./unicode.js";
16
+ const METHOD = "POST";
17
+ const MAX_INPUT_DEPTH = 100;
18
+ const MAX_INPUT_SIZE = 1_000_000;
19
+ const FORBIDDEN_KEYS = new Set(["__proto__", "prototype", "constructor"]);
20
+ const INPUT_KEYS = new Set([
21
+ "accessToken",
22
+ "model",
23
+ "maxTokens",
24
+ "messages",
25
+ "system",
26
+ "tools",
27
+ "cacheControl",
28
+ "runtime",
29
+ "capabilities",
30
+ "profileOverride",
31
+ "thinking",
32
+ "effort",
33
+ "metadata",
34
+ "experimentalBodyFields",
35
+ "contextManagement",
36
+ "outputConfig",
37
+ "speed",
38
+ "serviceTier",
39
+ "outputFormat",
40
+ "toolChoice",
41
+ "topP",
42
+ "topK",
43
+ "stopSequences",
44
+ "stream",
45
+ "temperature",
46
+ "clientRequestId",
47
+ "app",
48
+ "stainlessRetryCount",
49
+ "stainlessHelper",
50
+ "claudeRemoteContainerId",
51
+ "claudeRemoteSessionId",
52
+ "clientApp",
53
+ "anthropicAdditionalProtection",
54
+ "extraHeaders",
55
+ "crypto",
56
+ ]);
57
+ const COUNT_TOKENS_INPUT_KEYS = new Set([
58
+ "accessToken",
59
+ "model",
60
+ "messages",
61
+ "tools",
62
+ "runtime",
63
+ "clientRequestId",
64
+ "profileOverride",
65
+ "crypto",
66
+ "app",
67
+ "stainlessRetryCount",
68
+ "stainlessHelper",
69
+ "claudeRemoteContainerId",
70
+ "claudeRemoteSessionId",
71
+ "clientApp",
72
+ "anthropicAdditionalProtection",
73
+ "extraHeaders",
74
+ ]);
75
+ const BUILT_KEYS = new Set(["url", "method", "headers", "body", "evidence"]);
76
+ const EVIDENCE_KEYS = new Set([
77
+ "profileId",
78
+ "url",
79
+ "method",
80
+ "modelFamily",
81
+ "logicalHeaderNames",
82
+ "betaFeatures",
83
+ "bodySha256",
84
+ "bodyByteLength",
85
+ "messageCount",
86
+ "systemBlockCount",
87
+ "capabilityDecisions",
88
+ ]);
89
+ const CAPABILITY_KEYS = [
90
+ "thinking",
91
+ "adaptiveThinking",
92
+ "interleavedThinking",
93
+ "effort",
94
+ "maxEffort",
95
+ "xhighEffort",
96
+ "contextManagement",
97
+ "temperature",
98
+ "rejectsDisabledThinking",
99
+ ];
100
+ const CAPABILITY_KEY_SET = new Set(CAPABILITY_KEYS);
101
+ const OVERRIDE_KEYS = new Set([
102
+ "id",
103
+ "cliVersion",
104
+ "sdkVersion",
105
+ "entrypoint",
106
+ "userAgent",
107
+ "buildTime",
108
+ "gitSha",
109
+ "attributionHeaderEnabled",
110
+ "contextHintEnabled",
111
+ "betaPolicy",
112
+ "supportedModels",
113
+ ]);
114
+ const MODEL_KEYS = new Set([
115
+ "family",
116
+ "context",
117
+ "capabilities",
118
+ "defaultEffort",
119
+ ]);
120
+ const BETA_POLICY_KEYS = new Set([
121
+ "oauthAuthenticated",
122
+ "experimentalBetasEnabled",
123
+ "oneMillionContextEnabled",
124
+ "interleavedThinkingEnabled",
125
+ "interactive",
126
+ "thinkingSummariesShown",
127
+ "thinkingTokenCountEnabled",
128
+ "narrationSummariesEnabled",
129
+ "structuredOutputsEnabled",
130
+ "afkModeEnabled",
131
+ "cacheDiagnosisEnabled",
132
+ ]);
133
+ function fail(code = "INVALID_INPUT") {
134
+ throw new ClaudeCodeWireError(code);
135
+ }
136
+ function isRecord(value) {
137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
138
+ }
139
+ function ownValue(value, key) {
140
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
141
+ if (descriptor === undefined || !("value" in descriptor))
142
+ fail();
143
+ return descriptor.value;
144
+ }
145
+ function present(value) {
146
+ if (value === undefined)
147
+ fail();
148
+ return value;
149
+ }
150
+ function assertExactKeys(value, allowed) {
151
+ for (const key of Reflect.ownKeys(value)) {
152
+ if (typeof key !== "string" || !allowed.has(key))
153
+ fail("INVALID_INPUT");
154
+ }
155
+ }
156
+ function inspectString(value) {
157
+ for (let index = 0; index < value.length; index += 1) {
158
+ const unit = value.charCodeAt(index);
159
+ if (unit <= 0x1f || unit === 0x7f)
160
+ fail("INVALID_UNICODE");
161
+ const classification = classifySurrogateAt(value, index);
162
+ if (classification === "loneSurrogate")
163
+ fail("INVALID_UNICODE");
164
+ if (classification === "surrogatePair")
165
+ index += 1;
166
+ }
167
+ return new TextEncoder().encode(value).byteLength;
168
+ }
169
+ function inspectGraph(value) {
170
+ const active = new WeakSet();
171
+ let size = 0;
172
+ function visit(current, depth) {
173
+ if (depth > MAX_INPUT_DEPTH)
174
+ fail("INPUT_TOO_DEEP");
175
+ if (typeof current === "string") {
176
+ size += inspectString(current);
177
+ }
178
+ else if (current === null ||
179
+ typeof current === "boolean" ||
180
+ typeof current === "number") {
181
+ if (typeof current === "number" && !Number.isFinite(current))
182
+ fail();
183
+ size += 1;
184
+ }
185
+ else if (typeof current !== "object") {
186
+ fail();
187
+ }
188
+ else {
189
+ const prototype = Reflect.getPrototypeOf(current);
190
+ if (prototype !== null &&
191
+ prototype !== Object.prototype &&
192
+ prototype !== Array.prototype) {
193
+ fail();
194
+ }
195
+ if (active.has(current))
196
+ fail("CYCLIC_INPUT");
197
+ active.add(current);
198
+ const keys = Reflect.ownKeys(current);
199
+ size += keys.length;
200
+ for (const key of keys) {
201
+ if (typeof key !== "string" || FORBIDDEN_KEYS.has(key))
202
+ fail();
203
+ size += inspectString(key);
204
+ visit(ownValue(current, key), depth + 1);
205
+ }
206
+ active.delete(current);
207
+ }
208
+ if (size > MAX_INPUT_SIZE)
209
+ fail("INPUT_TOO_LARGE");
210
+ }
211
+ visit(value, 0);
212
+ }
213
+ function containsString(value, target) {
214
+ if (typeof value === "string")
215
+ return value === target;
216
+ if (value === null || typeof value !== "object")
217
+ return false;
218
+ return Reflect.ownKeys(value).some((key) => typeof key === "string"
219
+ ? containsString(ownValue(value, key), target)
220
+ : false);
221
+ }
222
+ function validateProfile(profile) {
223
+ if (profile !== CLAUDE_CODE_2_1_195_PROFILE)
224
+ fail();
225
+ return profile;
226
+ }
227
+ function isCryptoProvider(value) {
228
+ if (!isRecord(value))
229
+ return false;
230
+ const subtleDescriptor = Object.getOwnPropertyDescriptor(value, "subtle");
231
+ if (subtleDescriptor === undefined ||
232
+ !("value" in subtleDescriptor) ||
233
+ !isRecord(subtleDescriptor.value)) {
234
+ return false;
235
+ }
236
+ const digestDescriptor = Object.getOwnPropertyDescriptor(subtleDescriptor.value, "digest");
237
+ return (digestDescriptor !== undefined &&
238
+ "value" in digestDescriptor &&
239
+ typeof digestDescriptor.value === "function");
240
+ }
241
+ function validateCrypto(value) {
242
+ if (value === undefined)
243
+ return undefined;
244
+ if (!isCryptoProvider(value))
245
+ fail("CRYPTO_UNAVAILABLE");
246
+ return value;
247
+ }
248
+ function requireNonEmptyString(value) {
249
+ if (typeof value !== "string" || value.length === 0)
250
+ fail();
251
+ return value;
252
+ }
253
+ function parseCatalogueCapabilities(value) {
254
+ if (!Array.isArray(value) ||
255
+ !value.every((item) => typeof item === "string")) {
256
+ throw new ClaudeCodeWireError("INVALID_INPUT");
257
+ }
258
+ return Object.freeze([...value]);
259
+ }
260
+ function parseCatalogueContext(value) {
261
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
262
+ throw new ClaudeCodeWireError("INVALID_INPUT");
263
+ }
264
+ const keys = Reflect.ownKeys(value);
265
+ if (keys.some((key) => typeof key !== "string" ||
266
+ (key !== "window" && key !== "native1m" && key !== "supports1mBeta"))) {
267
+ throw new ClaudeCodeWireError("INVALID_INPUT");
268
+ }
269
+ const window = Reflect.get(value, "window");
270
+ const native1m = Reflect.get(value, "native1m");
271
+ const supports1mBeta = Reflect.get(value, "supports1mBeta");
272
+ if (typeof window !== "number" ||
273
+ !Number.isFinite(window) ||
274
+ window <= 0 ||
275
+ (native1m !== undefined && typeof native1m !== "boolean") ||
276
+ (supports1mBeta !== undefined && typeof supports1mBeta !== "boolean")) {
277
+ throw new ClaudeCodeWireError("INVALID_INPUT");
278
+ }
279
+ return Object.freeze({
280
+ window,
281
+ ...(native1m === undefined ? {} : { native1m }),
282
+ ...(supports1mBeta === undefined ? {} : { supports1mBeta }),
283
+ });
284
+ }
285
+ function parseDefaultEffort(value) {
286
+ if (value !== "low" &&
287
+ value !== "medium" &&
288
+ value !== "high" &&
289
+ value !== "xhigh" &&
290
+ value !== "max") {
291
+ throw new ClaudeCodeWireError("INVALID_INPUT");
292
+ }
293
+ return value;
294
+ }
295
+ function parseBoolean(value) {
296
+ if (typeof value !== "boolean") {
297
+ throw new ClaudeCodeWireError("INVALID_INPUT");
298
+ }
299
+ return value;
300
+ }
301
+ function parseBetaPolicy(value) {
302
+ if (!isRecord(value))
303
+ fail();
304
+ assertExactKeys(value, BETA_POLICY_KEYS);
305
+ if (Reflect.ownKeys(value).length !== BETA_POLICY_KEYS.size)
306
+ fail();
307
+ return Object.freeze({
308
+ oauthAuthenticated: parseBoolean(ownValue(value, "oauthAuthenticated")),
309
+ experimentalBetasEnabled: parseBoolean(ownValue(value, "experimentalBetasEnabled")),
310
+ oneMillionContextEnabled: parseBoolean(ownValue(value, "oneMillionContextEnabled")),
311
+ interleavedThinkingEnabled: parseBoolean(ownValue(value, "interleavedThinkingEnabled")),
312
+ interactive: parseBoolean(ownValue(value, "interactive")),
313
+ thinkingSummariesShown: parseBoolean(ownValue(value, "thinkingSummariesShown")),
314
+ thinkingTokenCountEnabled: parseBoolean(ownValue(value, "thinkingTokenCountEnabled")),
315
+ narrationSummariesEnabled: parseBoolean(ownValue(value, "narrationSummariesEnabled")),
316
+ structuredOutputsEnabled: parseBoolean(ownValue(value, "structuredOutputsEnabled")),
317
+ afkModeEnabled: parseBoolean(ownValue(value, "afkModeEnabled")),
318
+ cacheDiagnosisEnabled: parseBoolean(ownValue(value, "cacheDiagnosisEnabled")),
319
+ });
320
+ }
321
+ function parseSupportedModels(value) {
322
+ if (!isRecord(value) || Reflect.ownKeys(value).length === 0)
323
+ fail();
324
+ const result = {};
325
+ for (const key of Reflect.ownKeys(value)) {
326
+ if (typeof key !== "string" || key.length === 0)
327
+ fail();
328
+ const model = ownValue(value, key);
329
+ if (!isRecord(model))
330
+ fail();
331
+ assertExactKeys(model, MODEL_KEYS);
332
+ const family = ownValue(model, "family");
333
+ if (family !== "haiku" &&
334
+ family !== "sonnet" &&
335
+ family !== "opus" &&
336
+ family !== "fable" &&
337
+ family !== "mythos" &&
338
+ family !== "unknown")
339
+ fail();
340
+ result[key] = Object.freeze({
341
+ family,
342
+ ...(Object.hasOwn(model, "context")
343
+ ? { context: parseCatalogueContext(ownValue(model, "context")) }
344
+ : {}),
345
+ capabilities: parseCatalogueCapabilities(ownValue(model, "capabilities")),
346
+ ...(Object.hasOwn(model, "defaultEffort")
347
+ ? {
348
+ defaultEffort: parseDefaultEffort(ownValue(model, "defaultEffort")),
349
+ }
350
+ : {}),
351
+ });
352
+ }
353
+ return Object.freeze(result);
354
+ }
355
+ function validateProfileOverride(value) {
356
+ if (!isRecord(value))
357
+ fail();
358
+ assertExactKeys(value, OVERRIDE_KEYS);
359
+ if (Reflect.ownKeys(value).length === 0)
360
+ fail();
361
+ const cliVersion = Object.hasOwn(value, "cliVersion")
362
+ ? requireNonEmptyString(ownValue(value, "cliVersion"))
363
+ : undefined;
364
+ const userAgent = Object.hasOwn(value, "userAgent")
365
+ ? requireNonEmptyString(ownValue(value, "userAgent"))
366
+ : undefined;
367
+ // `cc_version` in the billing header derives from `cliVersion` while the
368
+ // user agent is separate. Overriding one alone would emit a self-inconsistent
369
+ // client signature, precisely the fingerprint mismatch this package prevents.
370
+ if (cliVersion !== undefined && !userAgent?.includes(cliVersion)) {
371
+ fail();
372
+ }
373
+ const attributionHeaderEnabled = Object.hasOwn(value, "attributionHeaderEnabled")
374
+ ? ownValue(value, "attributionHeaderEnabled")
375
+ : undefined;
376
+ if (attributionHeaderEnabled !== undefined &&
377
+ typeof attributionHeaderEnabled !== "boolean") {
378
+ fail();
379
+ }
380
+ return Object.freeze({
381
+ ...(Object.hasOwn(value, "id")
382
+ ? { id: requireNonEmptyString(ownValue(value, "id")) }
383
+ : {}),
384
+ ...(cliVersion === undefined ? {} : { cliVersion }),
385
+ ...(Object.hasOwn(value, "sdkVersion")
386
+ ? { sdkVersion: requireNonEmptyString(ownValue(value, "sdkVersion")) }
387
+ : {}),
388
+ ...(Object.hasOwn(value, "entrypoint")
389
+ ? { entrypoint: requireNonEmptyString(ownValue(value, "entrypoint")) }
390
+ : {}),
391
+ ...(userAgent === undefined ? {} : { userAgent }),
392
+ ...(Object.hasOwn(value, "buildTime")
393
+ ? { buildTime: requireNonEmptyString(ownValue(value, "buildTime")) }
394
+ : {}),
395
+ ...(Object.hasOwn(value, "gitSha")
396
+ ? { gitSha: requireNonEmptyString(ownValue(value, "gitSha")) }
397
+ : {}),
398
+ ...(attributionHeaderEnabled === undefined
399
+ ? {}
400
+ : { attributionHeaderEnabled }),
401
+ ...(Object.hasOwn(value, "contextHintEnabled")
402
+ ? {
403
+ contextHintEnabled: parseBoolean(ownValue(value, "contextHintEnabled")),
404
+ }
405
+ : {}),
406
+ ...(Object.hasOwn(value, "betaPolicy")
407
+ ? { betaPolicy: parseBetaPolicy(ownValue(value, "betaPolicy")) }
408
+ : {}),
409
+ ...(Object.hasOwn(value, "supportedModels")
410
+ ? {
411
+ supportedModels: parseSupportedModels(ownValue(value, "supportedModels")),
412
+ }
413
+ : {}),
414
+ });
415
+ }
416
+ function createEffectiveProfile(pinnedProfile, override) {
417
+ if (override === undefined)
418
+ return pinnedProfile;
419
+ return deepFreeze({ ...pinnedProfile, ...override });
420
+ }
421
+ function applyEffectiveProfileHeaders(headers, profile) {
422
+ return Object.freeze(headers.map(([name, value]) => {
423
+ if (name === "user-agent") {
424
+ return Object.freeze([name, profile.userAgent]);
425
+ }
426
+ if (name === "x-stainless-package-version") {
427
+ return Object.freeze([name, profile.sdkVersion]);
428
+ }
429
+ return Object.freeze([name, value]);
430
+ }));
431
+ }
432
+ function validateInput(input) {
433
+ if (!isRecord(input))
434
+ fail();
435
+ assertExactKeys(input, INPUT_KEYS);
436
+ const graph = {};
437
+ for (const key of Reflect.ownKeys(input)) {
438
+ if (key !== "crypto" && typeof key === "string") {
439
+ graph[key] = ownValue(input, key);
440
+ }
441
+ }
442
+ inspectGraph(graph);
443
+ const accessToken = ownValue(input, "accessToken");
444
+ if (typeof accessToken !== "string" ||
445
+ typeof ownValue(input, "model") !== "string" ||
446
+ !Array.isArray(ownValue(input, "messages"))) {
447
+ fail();
448
+ }
449
+ for (const key of Reflect.ownKeys(input)) {
450
+ if (typeof key === "string" &&
451
+ key !== "accessToken" &&
452
+ key !== "crypto" &&
453
+ containsString(ownValue(input, key), accessToken)) {
454
+ fail();
455
+ }
456
+ }
457
+ const clientRequestId = ownValue(input, "clientRequestId");
458
+ if (typeof clientRequestId !== "string" || clientRequestId.length === 0)
459
+ fail();
460
+ const cryptoValue = Object.hasOwn(input, "crypto")
461
+ ? validateCrypto(ownValue(input, "crypto"))
462
+ : undefined;
463
+ const profileOverride = Object.hasOwn(input, "profileOverride")
464
+ ? validateProfileOverride(ownValue(input, "profileOverride"))
465
+ : undefined;
466
+ return {
467
+ source: input,
468
+ clientRequestId,
469
+ crypto: cryptoValue,
470
+ profileOverride,
471
+ };
472
+ }
473
+ function validateCountTokensInput(input) {
474
+ if (!isRecord(input))
475
+ fail();
476
+ assertExactKeys(input, COUNT_TOKENS_INPUT_KEYS);
477
+ const graph = {};
478
+ for (const key of Reflect.ownKeys(input)) {
479
+ if (key !== "crypto" && typeof key === "string") {
480
+ graph[key] = ownValue(input, key);
481
+ }
482
+ }
483
+ inspectGraph(graph);
484
+ const accessToken = ownValue(input, "accessToken");
485
+ const tools = Object.hasOwn(input, "tools")
486
+ ? ownValue(input, "tools")
487
+ : undefined;
488
+ if (typeof accessToken !== "string" ||
489
+ typeof ownValue(input, "model") !== "string" ||
490
+ !Array.isArray(ownValue(input, "messages")) ||
491
+ (tools !== undefined && !Array.isArray(tools))) {
492
+ fail();
493
+ }
494
+ for (const key of Reflect.ownKeys(input)) {
495
+ if (typeof key === "string" &&
496
+ key !== "accessToken" &&
497
+ key !== "crypto" &&
498
+ containsString(ownValue(input, key), accessToken)) {
499
+ fail();
500
+ }
501
+ }
502
+ const clientRequestId = ownValue(input, "clientRequestId");
503
+ if (typeof clientRequestId !== "string" || clientRequestId.length === 0) {
504
+ fail();
505
+ }
506
+ const cryptoValue = Object.hasOwn(input, "crypto")
507
+ ? validateCrypto(ownValue(input, "crypto"))
508
+ : undefined;
509
+ const profileOverride = Object.hasOwn(input, "profileOverride")
510
+ ? validateProfileOverride(ownValue(input, "profileOverride"))
511
+ : undefined;
512
+ return {
513
+ source: input,
514
+ clientRequestId,
515
+ crypto: cryptoValue,
516
+ profileOverride,
517
+ };
518
+ }
519
+ function requestedCapabilities(input, supported) {
520
+ const raw = input.capabilities;
521
+ if (raw !== undefined) {
522
+ if (!isRecord(raw))
523
+ fail("UNSUPPORTED_CAPABILITY");
524
+ assertExactKeys(raw, CAPABILITY_KEY_SET);
525
+ }
526
+ const result = {
527
+ thinking: raw?.thinking ?? supported.thinking,
528
+ adaptiveThinking: raw?.adaptiveThinking ?? supported.adaptiveThinking,
529
+ interleavedThinking: raw?.interleavedThinking ?? supported.interleavedThinking,
530
+ effort: raw?.effort ?? supported.effort,
531
+ maxEffort: raw?.maxEffort ?? supported.maxEffort,
532
+ xhighEffort: raw?.xhighEffort ?? supported.xhighEffort,
533
+ contextManagement: raw?.contextManagement ?? supported.contextManagement,
534
+ temperature: raw?.temperature ?? supported.temperature,
535
+ rejectsDisabledThinking: raw?.rejectsDisabledThinking ?? supported.rejectsDisabledThinking,
536
+ };
537
+ for (const key of CAPABILITY_KEYS) {
538
+ if (typeof result[key] !== "boolean")
539
+ fail("UNSUPPORTED_CAPABILITY");
540
+ if (result[key] && !supported[key]) {
541
+ throw new ClaudeCodeWireError("UNSUPPORTED_CAPABILITY", {
542
+ capability: key,
543
+ });
544
+ }
545
+ }
546
+ return Object.freeze(result);
547
+ }
548
+ /**
549
+ * Selects the text that seeds the billing fingerprint.
550
+ *
551
+ * The source is the FIRST USER MESSAGE, and nothing else. Upstream
552
+ * `lib/mimicry/system-prompt.mjs:134,143` calls
553
+ * `buildAnthropicBillingHeader(version, firstUserMessage, ...)`, which forwards
554
+ * that message to `computeBillingCacheHash(firstUserMessage || "", version)`.
555
+ * The system prompt never contributes.
556
+ *
557
+ * This is protocol-critical: seeding the fingerprint from system text instead
558
+ * would emit a `cc_version` suffix that does not match the pinned wire profile,
559
+ * silently breaking parity while every local test still looked plausible.
560
+ * The committed goldens are the ground truth here — `outgoing-foreground.json`
561
+ * pairs first user text `hello wire compat` with `cc_version=2.1.195.0f6`.
562
+ */
563
+ function fingerprintText(input) {
564
+ for (const message of input.messages) {
565
+ if (message.role !== "user")
566
+ continue;
567
+ if (typeof message.content === "string")
568
+ return message.content;
569
+ for (const block of message.content) {
570
+ if (block.type === "text")
571
+ return block.text;
572
+ }
573
+ // The first user message exists but carries no text block. Upstream's
574
+ // `firstUserMessage || ""` fallback applies; later messages never substitute.
575
+ return "";
576
+ }
577
+ return "";
578
+ }
579
+ function sanitizeError(error) {
580
+ if (error instanceof ClaudeCodeWireError) {
581
+ const details = toSafeErrorDetails(error);
582
+ const safeDetails = Object.fromEntries(Object.entries(details).filter(([key]) => key !== "code"));
583
+ throw new ClaudeCodeWireError(error.code, safeDetails);
584
+ }
585
+ throw new ClaudeCodeWireError("INVALID_INPUT");
586
+ }
587
+ function deepFreeze(value) {
588
+ if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
589
+ for (const key of Reflect.ownKeys(value))
590
+ deepFreeze(Reflect.get(value, key));
591
+ Object.freeze(value);
592
+ }
593
+ return value;
594
+ }
595
+ function parseStringArray(value) {
596
+ if (!Array.isArray(value))
597
+ fail();
598
+ return value.map((entry) => {
599
+ if (typeof entry !== "string")
600
+ fail();
601
+ return entry;
602
+ });
603
+ }
604
+ function parseHeaders(value) {
605
+ if (!Array.isArray(value))
606
+ fail();
607
+ return value.map((entry) => {
608
+ if (!Array.isArray(entry) ||
609
+ entry.length !== 2 ||
610
+ typeof entry[0] !== "string" ||
611
+ typeof entry[1] !== "string") {
612
+ fail();
613
+ }
614
+ return [entry[0], entry[1]];
615
+ });
616
+ }
617
+ function parseCapabilities(value) {
618
+ if (!isRecord(value))
619
+ fail();
620
+ assertExactKeys(value, CAPABILITY_KEY_SET);
621
+ // Read each key through a narrowing helper rather than building a record and
622
+ // re-checking it afterwards. The re-check was unreachable -- every value was
623
+ // already proven boolean -- which cost coverage and produced mutants that
624
+ // could not be killed.
625
+ const readBoolean = (key) => {
626
+ const entry = ownValue(value, key);
627
+ if (typeof entry !== "boolean")
628
+ fail();
629
+ return entry;
630
+ };
631
+ return {
632
+ thinking: readBoolean("thinking"),
633
+ adaptiveThinking: readBoolean("adaptiveThinking"),
634
+ interleavedThinking: readBoolean("interleavedThinking"),
635
+ effort: readBoolean("effort"),
636
+ maxEffort: readBoolean("maxEffort"),
637
+ xhighEffort: readBoolean("xhighEffort"),
638
+ contextManagement: readBoolean("contextManagement"),
639
+ temperature: readBoolean("temperature"),
640
+ rejectsDisabledThinking: readBoolean("rejectsDisabledThinking"),
641
+ };
642
+ }
643
+ function parseEvidence(value) {
644
+ if (!isRecord(value))
645
+ fail();
646
+ assertExactKeys(value, EVIDENCE_KEYS);
647
+ const modelFamily = ownValue(value, "modelFamily");
648
+ if (modelFamily !== "haiku" &&
649
+ modelFamily !== "sonnet" &&
650
+ modelFamily !== "opus" &&
651
+ modelFamily !== "fable" &&
652
+ modelFamily !== "mythos" &&
653
+ modelFamily !== "unknown") {
654
+ fail();
655
+ }
656
+ const bodySha256 = ownValue(value, "bodySha256");
657
+ const bodyByteLength = ownValue(value, "bodyByteLength");
658
+ const messageCount = ownValue(value, "messageCount");
659
+ const systemBlockCount = ownValue(value, "systemBlockCount");
660
+ if (ownValue(value, "profileId") !== CLAUDE_CODE_2_1_195_PROFILE.id ||
661
+ ownValue(value, "url") !== CLAUDE_CODE_2_1_195_PROFILE.endpoint ||
662
+ ownValue(value, "method") !== METHOD ||
663
+ typeof bodySha256 !== "string" ||
664
+ !/^[0-9a-f]{64}$/u.test(bodySha256) ||
665
+ typeof bodyByteLength !== "number" ||
666
+ !Number.isSafeInteger(bodyByteLength) ||
667
+ typeof messageCount !== "number" ||
668
+ !Number.isSafeInteger(messageCount) ||
669
+ typeof systemBlockCount !== "number" ||
670
+ !Number.isSafeInteger(systemBlockCount)) {
671
+ fail();
672
+ }
673
+ return {
674
+ profileId: CLAUDE_CODE_2_1_195_PROFILE.id,
675
+ url: CLAUDE_CODE_2_1_195_PROFILE.endpoint,
676
+ method: METHOD,
677
+ modelFamily,
678
+ logicalHeaderNames: parseStringArray(ownValue(value, "logicalHeaderNames")),
679
+ betaFeatures: parseStringArray(ownValue(value, "betaFeatures")),
680
+ bodySha256,
681
+ bodyByteLength,
682
+ messageCount,
683
+ systemBlockCount,
684
+ capabilityDecisions: parseCapabilities(ownValue(value, "capabilityDecisions")),
685
+ };
686
+ }
687
+ function parseBody(value) {
688
+ let parsed;
689
+ try {
690
+ parsed = JSON.parse(value);
691
+ }
692
+ catch {
693
+ fail();
694
+ }
695
+ if (!isRecord(parsed))
696
+ fail();
697
+ return parsed;
698
+ }
699
+ function parsedBodySessionId(body) {
700
+ const metadata = body["metadata"];
701
+ if (!isRecord(metadata) || typeof metadata["user_id"] !== "string")
702
+ fail();
703
+ const identity = parseBody(metadata["user_id"]);
704
+ const sessionId = identity["session_id"];
705
+ if (typeof sessionId !== "string")
706
+ fail();
707
+ return sessionId;
708
+ }
709
+ function headerValue(headers, name) {
710
+ const matches = headers.filter(([candidate]) => candidate === name);
711
+ if (matches.length !== 1)
712
+ fail();
713
+ const match = matches[0];
714
+ if (match === undefined)
715
+ fail();
716
+ return match[1];
717
+ }
718
+ function splitDynamicAndExtraHeaders(headers) {
719
+ const timeoutIndex = headers.findIndex(([name]) => name === "x-stainless-timeout");
720
+ if (timeoutIndex < 0)
721
+ fail();
722
+ let cursor = timeoutIndex + 1;
723
+ function consume(name) {
724
+ const pair = headers[cursor];
725
+ if (pair?.[0] !== name)
726
+ return undefined;
727
+ cursor += 1;
728
+ return pair[1];
729
+ }
730
+ return {
731
+ stainlessHelper: consume("x-stainless-helper"),
732
+ claudeRemoteContainerId: consume("x-claude-remote-container-id"),
733
+ claudeRemoteSessionId: consume("x-claude-remote-session-id"),
734
+ clientApp: consume("x-client-app"),
735
+ anthropicAdditionalProtection: consume("x-anthropic-additional-protection"),
736
+ extraHeaders: headers.slice(cursor),
737
+ };
738
+ }
739
+ function evidenceRequest(input, callerModel) {
740
+ const request = {
741
+ accessToken: input.accessToken,
742
+ model: callerModel,
743
+ maxTokens: input.maxTokens,
744
+ messages: input.messages,
745
+ runtime: input.runtime,
746
+ };
747
+ if (input.system !== undefined)
748
+ request.system = input.system;
749
+ if (input.tools !== undefined)
750
+ request.tools = input.tools;
751
+ if (Object.hasOwn(input, "cacheControl"))
752
+ request.cacheControl = present(input.cacheControl);
753
+ if (input.capabilities !== undefined)
754
+ request.capabilities = input.capabilities;
755
+ if (input.thinking !== undefined)
756
+ request.thinking = input.thinking;
757
+ if (input.effort !== undefined)
758
+ request.effort = input.effort;
759
+ if (input.metadata !== undefined)
760
+ request.metadata = input.metadata;
761
+ if (input.experimentalBodyFields !== undefined)
762
+ request.experimentalBodyFields = input.experimentalBodyFields;
763
+ if (Object.hasOwn(input, "contextManagement"))
764
+ request.contextManagement = present(input.contextManagement);
765
+ if (Object.hasOwn(input, "outputConfig"))
766
+ request.outputConfig = present(input.outputConfig);
767
+ if (Object.hasOwn(input, "speed"))
768
+ request.speed = present(input.speed);
769
+ if (Object.hasOwn(input, "serviceTier"))
770
+ request.serviceTier = present(input.serviceTier);
771
+ if (Object.hasOwn(input, "outputFormat"))
772
+ request.outputFormat = present(input.outputFormat);
773
+ if (Object.hasOwn(input, "toolChoice"))
774
+ request.toolChoice = present(input.toolChoice);
775
+ if (Object.hasOwn(input, "topP"))
776
+ request.topP = present(input.topP);
777
+ if (Object.hasOwn(input, "topK"))
778
+ request.topK = present(input.topK);
779
+ if (Object.hasOwn(input, "stopSequences"))
780
+ request.stopSequences = present(input.stopSequences);
781
+ if (Object.hasOwn(input, "stream"))
782
+ request.stream = present(input.stream);
783
+ if (Object.hasOwn(input, "temperature"))
784
+ request.temperature = present(input.temperature);
785
+ return request;
786
+ }
787
+ function countTokensEvidenceRequest(input, capabilities) {
788
+ return {
789
+ accessToken: input.accessToken,
790
+ model: input.model,
791
+ maxTokens: 1,
792
+ messages: input.messages,
793
+ ...(input.tools === undefined ? {} : { tools: input.tools }),
794
+ runtime: input.runtime,
795
+ capabilities,
796
+ };
797
+ }
798
+ /** Builds a canonical Claude Code count-tokens request. */
799
+ export async function buildClaudeCodeCountTokensRequest(input, profile = CLAUDE_CODE_2_1_195_PROFILE) {
800
+ try {
801
+ const pinnedProfile = validateProfile(profile);
802
+ const validated = validateCountTokensInput(input);
803
+ const effectiveProfile = createEffectiveProfile(pinnedProfile, validated.profileOverride);
804
+ const identity = validateRuntimeIdentity(validated.source.runtime);
805
+ const resolvedModel = resolveModel(validated.source.model, effectiveProfile);
806
+ const countTokensBetas = filterCountTokensBetas(composeBetas({
807
+ rawModel: validated.source.model,
808
+ normalizedId: resolvedModel.id,
809
+ capabilities: resolvedModel.capabilities,
810
+ thinkingDisplayActive: false,
811
+ }, effectiveProfile));
812
+ const betas = Object.freeze([...countTokensBetas, TOKEN_COUNTING_BETA]);
813
+ const headers = applyEffectiveProfileHeaders(buildOrderedHeaders({
814
+ accessToken: validated.source.accessToken,
815
+ runtime: identity,
816
+ clientRequestId: validated.clientRequestId,
817
+ betaFeatures: betas,
818
+ app: validated.source.app ?? effectiveProfile.entrypoint,
819
+ stainlessRetryCount: validated.source.stainlessRetryCount ?? 0,
820
+ stainlessHelper: validated.source.stainlessHelper,
821
+ claudeRemoteContainerId: validated.source.claudeRemoteContainerId,
822
+ claudeRemoteSessionId: validated.source.claudeRemoteSessionId,
823
+ clientApp: validated.source.clientApp,
824
+ anthropicAdditionalProtection: validated.source.anthropicAdditionalProtection,
825
+ extraHeaders: validated.source.extraHeaders ?? [],
826
+ profile: pinnedProfile,
827
+ }), effectiveProfile);
828
+ const canonical = canonicalCountTokensLists(validated.source.messages, validated.source.tools);
829
+ const body = JSON.stringify(buildCountTokensBody(resolvedModel.wireId, canonical.messages, canonical.tools));
830
+ const evidenceRequestInput = countTokensEvidenceRequest(validated.source, resolvedModel.capabilities);
831
+ const evidence = await buildRedactedEvidence({
832
+ profile: pinnedProfile,
833
+ effectiveProfile,
834
+ request: evidenceRequestInput,
835
+ modelFamily: resolvedModel.family,
836
+ logicalHeaders: headers,
837
+ betaFeatures: betas,
838
+ body,
839
+ }, validated.crypto);
840
+ return deepFreeze({
841
+ url: effectiveProfile.countTokensEndpoint,
842
+ method: METHOD,
843
+ headers,
844
+ body,
845
+ evidence,
846
+ });
847
+ }
848
+ catch (error) {
849
+ return sanitizeError(error);
850
+ }
851
+ }
852
+ /**
853
+ * Builds one canonical request for the pinned Claude Code wire profile.
854
+ *
855
+ * @param profile - The only accepted value is the exported
856
+ * `CLAUDE_CODE_2_1_195_PROFILE` singleton. Any other object, even a
857
+ * structurally identical clone, is rejected with `ClaudeCodeWireError` code
858
+ * `INVALID_INPUT`. This deliberate fail-closed behaviour prevents callers from
859
+ * substituting an unpinned protocol profile.
860
+ */
861
+ export async function buildClaudeCodeRequest(input, profile = CLAUDE_CODE_2_1_195_PROFILE) {
862
+ try {
863
+ const pinnedProfile = validateProfile(profile);
864
+ const validated = validateInput(input);
865
+ const effectiveProfile = createEffectiveProfile(pinnedProfile, validated.profileOverride);
866
+ const identity = validateRuntimeIdentity(validated.source.runtime);
867
+ const resolvedModel = resolveModel(validated.source.model, effectiveProfile);
868
+ const capabilities = requestedCapabilities(validated.source, resolvedModel.capabilities);
869
+ const effectiveModel = Object.freeze({
870
+ ...resolvedModel,
871
+ capabilities,
872
+ });
873
+ const billing = await createBillingBlock(fingerprintText(validated.source), effectiveProfile.cliVersion, validated.crypto);
874
+ const metadata = buildCorrelatedMetadata(identity, validated.source.metadata);
875
+ const system = buildCanonicalSystem(validated.source.system, billing, identity);
876
+ const canonicalBody = buildCanonicalBody(evidenceRequest(validated.source, validated.source.model), effectiveModel, system, metadata, effectiveProfile);
877
+ const betas = composeBetas({
878
+ rawModel: validated.source.model,
879
+ normalizedId: resolvedModel.id,
880
+ capabilities,
881
+ thinkingDisplayActive: isThinkingDisplayActive(validated.source.thinking, capabilities, effectiveProfile.betaPolicy),
882
+ ...(validated.source.cacheControl?.ttl === undefined
883
+ ? {}
884
+ : { cacheTtl: validated.source.cacheControl.ttl }),
885
+ ...(validated.source.speed === undefined
886
+ ? {}
887
+ : { speed: validated.source.speed }),
888
+ }, effectiveProfile);
889
+ const headers = applyEffectiveProfileHeaders(buildOrderedHeaders({
890
+ accessToken: validated.source.accessToken,
891
+ runtime: identity,
892
+ clientRequestId: validated.clientRequestId,
893
+ betaFeatures: betas,
894
+ app: validated.source.app ?? effectiveProfile.entrypoint,
895
+ stainlessRetryCount: validated.source.stainlessRetryCount ?? 0,
896
+ stainlessHelper: validated.source.stainlessHelper,
897
+ claudeRemoteContainerId: validated.source.claudeRemoteContainerId,
898
+ claudeRemoteSessionId: validated.source.claudeRemoteSessionId,
899
+ clientApp: validated.source.clientApp,
900
+ anthropicAdditionalProtection: validated.source.anthropicAdditionalProtection,
901
+ extraHeaders: validated.source.extraHeaders ?? [],
902
+ profile: pinnedProfile,
903
+ }), effectiveProfile);
904
+ const body = JSON.stringify(canonicalBody);
905
+ const evidence = await buildRedactedEvidence({
906
+ profile: pinnedProfile,
907
+ effectiveProfile,
908
+ request: evidenceRequest(validated.source, validated.source.model),
909
+ modelFamily: resolvedModel.family,
910
+ logicalHeaders: headers,
911
+ betaFeatures: betas,
912
+ body,
913
+ }, validated.crypto);
914
+ return deepFreeze({
915
+ url: effectiveProfile.endpoint,
916
+ method: METHOD,
917
+ headers,
918
+ body,
919
+ evidence,
920
+ });
921
+ }
922
+ catch (error) {
923
+ return sanitizeError(error);
924
+ }
925
+ }
926
+ /**
927
+ * Validates and clones a previously built request into a deeply frozen value.
928
+ *
929
+ * @param profile - The only accepted value is the exported
930
+ * `CLAUDE_CODE_2_1_195_PROFILE` singleton. Any other object, even a
931
+ * structurally identical clone, is rejected with `ClaudeCodeWireError` code
932
+ * `INVALID_INPUT`. This deliberate fail-closed behaviour prevents callers from
933
+ * substituting an unpinned protocol profile.
934
+ */
935
+ export function parseBuiltClaudeCodeRequest(value, profile = CLAUDE_CODE_2_1_195_PROFILE) {
936
+ try {
937
+ const pinnedProfile = validateProfile(profile);
938
+ inspectGraph(value);
939
+ if (!isRecord(value))
940
+ fail();
941
+ assertExactKeys(value, BUILT_KEYS);
942
+ if (ownValue(value, "url") !== pinnedProfile.endpoint ||
943
+ ownValue(value, "method") !== METHOD) {
944
+ fail();
945
+ }
946
+ const body = ownValue(value, "body");
947
+ if (typeof body !== "string")
948
+ fail();
949
+ const parsedBody = parseBody(body);
950
+ const headers = parseHeaders(ownValue(value, "headers"));
951
+ const evidence = parseEvidence(ownValue(value, "evidence"));
952
+ const sessionId = headerValue(headers, "x-claude-code-session-id");
953
+ const additionalHeaders = splitDynamicAndExtraHeaders(headers);
954
+ const expectedHeaders = buildOrderedHeaders({
955
+ accessToken: headerValue(headers, "authorization").replace(/^Bearer /u, ""),
956
+ runtime: {
957
+ sessionId,
958
+ runtime: headerValue(headers, "x-stainless-runtime"),
959
+ runtimeVersion: headerValue(headers, "x-stainless-runtime-version"),
960
+ os: headerValue(headers, "x-stainless-os"),
961
+ arch: headerValue(headers, "x-stainless-arch"),
962
+ },
963
+ clientRequestId: headerValue(headers, "x-client-request-id"),
964
+ betaFeatures: evidence.betaFeatures,
965
+ app: headerValue(headers, "x-app"),
966
+ stainlessRetryCount: Number(headerValue(headers, "x-stainless-retry-count")),
967
+ stainlessHelper: additionalHeaders.stainlessHelper,
968
+ claudeRemoteContainerId: additionalHeaders.claudeRemoteContainerId,
969
+ claudeRemoteSessionId: additionalHeaders.claudeRemoteSessionId,
970
+ clientApp: additionalHeaders.clientApp,
971
+ anthropicAdditionalProtection: additionalHeaders.anthropicAdditionalProtection,
972
+ extraHeaders: additionalHeaders.extraHeaders,
973
+ profile: pinnedProfile,
974
+ });
975
+ if (JSON.stringify(headers) !== JSON.stringify(expectedHeaders))
976
+ fail();
977
+ if (evidence.logicalHeaderNames.length !== headers.length ||
978
+ evidence.logicalHeaderNames.some((name, index) => name !== headers[index]?.[0]) ||
979
+ parsedBodySessionId(parsedBody) !== sessionId ||
980
+ headerValue(headers, "anthropic-beta") !==
981
+ evidence.betaFeatures.join(",") ||
982
+ evidence.bodyByteLength !== new TextEncoder().encode(body).byteLength ||
983
+ evidence.messageCount !==
984
+ (Array.isArray(parsedBody["messages"])
985
+ ? parsedBody["messages"].length
986
+ : -1) ||
987
+ evidence.systemBlockCount !==
988
+ (Array.isArray(parsedBody["system"])
989
+ ? parsedBody["system"].length - 2
990
+ : -1)) {
991
+ fail();
992
+ }
993
+ const result = {
994
+ url: pinnedProfile.endpoint,
995
+ method: METHOD,
996
+ headers,
997
+ body,
998
+ evidence,
999
+ };
1000
+ if (sha256Hex(body) !== evidence.bodySha256)
1001
+ fail();
1002
+ return deepFreeze(result);
1003
+ }
1004
+ catch (error) {
1005
+ return sanitizeError(error);
1006
+ }
1007
+ }
1008
+ //# sourceMappingURL=build-request.js.map