@veryfront/ext-llm-anthropic 0.1.1237 → 0.1.1239
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-request-builder.d.ts","sourceRoot":"","sources":["../src/anthropic-request-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"anthropic-request-builder.d.ts","sourceRoot":"","sources":["../src/anthropic-request-builder.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,uBAAuB,EAEvB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACL,KAAK,iCAAiC,EAUvC,MAAM,+BAA+B,CAAC;AAEvC,KAAK,gBAAgB,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;AA2E9C,KAAK,0BAA0B,GAAG;IAChC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,+BAAgC,SAAQ,uBAAuB;IAC9E,YAAY,CAAC,EAAE,0BAA0B,CAAC;IAC1C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACjD;AAED,gGAAgG;AAChG,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,CAAC;AAE/D,KAAK,gBAAgB,GAAG;IACtB,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,KAAK,IAAI,KAAK,CAAC;QACb,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzC,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AA8lEF,wBAAgB,iDAAiD,CAC/D,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB;IACD,IAAI,EAAE,0BAA0B,CAAC;IACjC,qBAAqB,EAAE,iCAAiC,CAAC;CAC1D,CAgLA;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,+BAA+B,EACxC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,gBAAgB,GACzB,0BAA0B,CAQ5B"}
|
|
@@ -1,6 +1,70 @@
|
|
|
1
|
-
import { jsonValuesEqual, readProviderOptions, readRecord, stringifyToolResultValue, unwrapToolInputSchema, } from "veryfront/provider/shared";
|
|
1
|
+
import { canIdentifyProxyWithoutHooks, isProxyWithoutHooks, jsonValuesEqual, readProviderOptions, readRecord, snapshotProviderJsonValue, stringifyToolResultValue, unwrapToolInputSchema, } from "veryfront/provider/shared";
|
|
2
2
|
import { assertAnthropicMcpRequestContract, normalizeAnthropicMcpServers, normalizeAnthropicMcpToolsetArgs, } from "./anthropic-mcp-request.js";
|
|
3
3
|
import { isAnthropicProviderToolResultBlockType, MAX_ANTHROPIC_RAW_ASSISTANT_BLOCKS, MAX_ANTHROPIC_RAW_ASSISTANT_MESSAGES, parseAnthropicProviderToolUse, parseAnthropicServerToolResult, snapshotAnthropicRawAssistantMetadata, validateAnthropicRawAssistantMessages, } from "./anthropic-native-content.js";
|
|
4
|
+
const apply = Reflect.apply;
|
|
5
|
+
const NativeArray = Array;
|
|
6
|
+
const ArrayIsArray = Array.isArray;
|
|
7
|
+
const booleanValueOf = Boolean.prototype.valueOf;
|
|
8
|
+
const NativeSet = Set;
|
|
9
|
+
const numberValueOf = Number.prototype.valueOf;
|
|
10
|
+
const objectAssign = Object.assign;
|
|
11
|
+
const objectDefineProperty = Object.defineProperty;
|
|
12
|
+
const objectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
13
|
+
const objectGetPrototypeOf = Object.getPrototypeOf;
|
|
14
|
+
const objectHasOwn = Object.hasOwn;
|
|
15
|
+
const objectKeys = Object.keys;
|
|
16
|
+
const reflectDeleteProperty = Reflect.deleteProperty;
|
|
17
|
+
const reflectOwnKeys = Reflect.ownKeys;
|
|
18
|
+
const setAdd = Set.prototype.add;
|
|
19
|
+
const setDelete = Set.prototype.delete;
|
|
20
|
+
const setHas = Set.prototype.has;
|
|
21
|
+
const stringValueOf = String.prototype.valueOf;
|
|
22
|
+
function hasSetValue(set, value) {
|
|
23
|
+
return apply(setHas, set, [value]);
|
|
24
|
+
}
|
|
25
|
+
function addSetValue(set, value) {
|
|
26
|
+
apply(setAdd, set, [value]);
|
|
27
|
+
}
|
|
28
|
+
function deleteSetValue(set, value) {
|
|
29
|
+
apply(setDelete, set, [value]);
|
|
30
|
+
}
|
|
31
|
+
function defineOwnEnumerableDataProperty(target, key, value) {
|
|
32
|
+
apply(objectDefineProperty, Object, [target, key, {
|
|
33
|
+
configurable: true,
|
|
34
|
+
enumerable: true,
|
|
35
|
+
value,
|
|
36
|
+
writable: true,
|
|
37
|
+
}]);
|
|
38
|
+
}
|
|
39
|
+
function boxedPrimitiveKind(value) {
|
|
40
|
+
try {
|
|
41
|
+
apply(booleanValueOf, value, []);
|
|
42
|
+
return "boolean";
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Continue with the other intrinsic brand checks.
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
apply(numberValueOf, value, []);
|
|
49
|
+
return "number";
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Continue with the other intrinsic brand checks.
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
apply(stringValueOf, value, []);
|
|
56
|
+
return "string";
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function isBoxedPrimitive(value) {
|
|
63
|
+
return boxedPrimitiveKind(value) !== undefined;
|
|
64
|
+
}
|
|
65
|
+
function isBoxedString(value) {
|
|
66
|
+
return boxedPrimitiveKind(value) === "string";
|
|
67
|
+
}
|
|
4
68
|
function normalizeAnthropicToolChoice(toolChoice) {
|
|
5
69
|
if (typeof toolChoice === "string") {
|
|
6
70
|
return { type: toolChoice };
|
|
@@ -30,14 +94,14 @@ function pushAnthropicUserContent(messages, content) {
|
|
|
30
94
|
function readOwnAnthropicMetadataProperty(value, key, malformedMessage) {
|
|
31
95
|
let descriptor;
|
|
32
96
|
try {
|
|
33
|
-
descriptor =
|
|
97
|
+
descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
34
98
|
}
|
|
35
99
|
catch {
|
|
36
100
|
throw new TypeError(malformedMessage);
|
|
37
101
|
}
|
|
38
102
|
if (descriptor === undefined)
|
|
39
103
|
return undefined;
|
|
40
|
-
if (!
|
|
104
|
+
if (!objectHasOwn(descriptor, "value") || descriptor.enumerable !== true) {
|
|
41
105
|
throw new TypeError(malformedMessage);
|
|
42
106
|
}
|
|
43
107
|
return descriptor.value;
|
|
@@ -141,10 +205,10 @@ const ANTHROPIC_SERVER_TOOL_RESULT_ERROR_FIELDS = new Set([
|
|
|
141
205
|
]);
|
|
142
206
|
function readOwnEnumerableDataProperty(value, key) {
|
|
143
207
|
try {
|
|
144
|
-
const descriptor =
|
|
208
|
+
const descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
145
209
|
if (descriptor === undefined)
|
|
146
210
|
return { present: false };
|
|
147
|
-
if (!
|
|
211
|
+
if (!objectHasOwn(descriptor, "value") || descriptor.enumerable !== true) {
|
|
148
212
|
return undefined;
|
|
149
213
|
}
|
|
150
214
|
return { present: true, value: descriptor.value };
|
|
@@ -158,7 +222,7 @@ function readAnthropicServerToolResultErrorFields(value) {
|
|
|
158
222
|
return undefined;
|
|
159
223
|
}
|
|
160
224
|
try {
|
|
161
|
-
if (
|
|
225
|
+
if (objectKeys(value).some((key) => !ANTHROPIC_SERVER_TOOL_RESULT_ERROR_FIELDS.has(key))) {
|
|
162
226
|
return undefined;
|
|
163
227
|
}
|
|
164
228
|
}
|
|
@@ -524,6 +588,75 @@ function resolveAnthropicCacheControlBlock(ttl) {
|
|
|
524
588
|
}
|
|
525
589
|
return { type: "ephemeral" };
|
|
526
590
|
}
|
|
591
|
+
function resolveAnthropicSystemMessageCacheControl(message, providerName) {
|
|
592
|
+
const providerOptions = readOwnEnumerableDataProperty(message, "providerOptions");
|
|
593
|
+
if (!providerOptions) {
|
|
594
|
+
throw new TypeError("Anthropic system message providerOptions must be an own enumerable data property");
|
|
595
|
+
}
|
|
596
|
+
if (!providerOptions.present || providerOptions.value === undefined) {
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
if (!providerOptions.value || typeof providerOptions.value !== "object" ||
|
|
600
|
+
Array.isArray(providerOptions.value)) {
|
|
601
|
+
throw new TypeError("Anthropic system message providerOptions must be an object");
|
|
602
|
+
}
|
|
603
|
+
let rawCacheControl;
|
|
604
|
+
let hasCacheControl = false;
|
|
605
|
+
for (const key of ["anthropic", providerName]) {
|
|
606
|
+
const providerBucket = readOwnEnumerableDataProperty(providerOptions.value, key);
|
|
607
|
+
if (!providerBucket) {
|
|
608
|
+
throw new TypeError("Anthropic system message provider bucket must be an own enumerable data property");
|
|
609
|
+
}
|
|
610
|
+
if (!providerBucket.present || !providerBucket.value ||
|
|
611
|
+
typeof providerBucket.value !== "object" || Array.isArray(providerBucket.value)) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
const cacheControl = readOwnEnumerableDataProperty(providerBucket.value, "cacheControl");
|
|
615
|
+
if (!cacheControl) {
|
|
616
|
+
throw new TypeError("Anthropic system message cacheControl must be an own enumerable data property");
|
|
617
|
+
}
|
|
618
|
+
if (cacheControl.present && cacheControl.value !== undefined) {
|
|
619
|
+
hasCacheControl = true;
|
|
620
|
+
rawCacheControl = cacheControl.value;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (!hasCacheControl || rawCacheControl === undefined) {
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
if (!rawCacheControl || typeof rawCacheControl !== "object" || Array.isArray(rawCacheControl)) {
|
|
627
|
+
throw new TypeError("Anthropic system message cacheControl must be an object");
|
|
628
|
+
}
|
|
629
|
+
let unsupportedFields;
|
|
630
|
+
try {
|
|
631
|
+
const keys = objectKeys(rawCacheControl);
|
|
632
|
+
unsupportedFields = [];
|
|
633
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
634
|
+
const key = keys[index];
|
|
635
|
+
if (key !== "type" && key !== "ttl") {
|
|
636
|
+
unsupportedFields.push(key);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
throw new TypeError("Anthropic system message cacheControl could not be inspected");
|
|
642
|
+
}
|
|
643
|
+
if (unsupportedFields.length > 0) {
|
|
644
|
+
throw new TypeError("Anthropic system message cacheControl contains unsupported fields");
|
|
645
|
+
}
|
|
646
|
+
const type = readOwnEnumerableDataProperty(rawCacheControl, "type");
|
|
647
|
+
const ttl = readOwnEnumerableDataProperty(rawCacheControl, "ttl");
|
|
648
|
+
if (!type || !ttl) {
|
|
649
|
+
throw new TypeError("Anthropic system message cacheControl must contain only enumerable data properties");
|
|
650
|
+
}
|
|
651
|
+
if (!type.present || type.value !== "ephemeral") {
|
|
652
|
+
throw new TypeError('Anthropic system message cacheControl.type must be "ephemeral"');
|
|
653
|
+
}
|
|
654
|
+
if (ttl.present && ttl.value !== undefined && ttl.value !== "5m" &&
|
|
655
|
+
ttl.value !== "1h") {
|
|
656
|
+
throw new TypeError('Anthropic system message cacheControl.ttl must be "5m" or "1h"');
|
|
657
|
+
}
|
|
658
|
+
return ttl.value === "1h" ? { type: "ephemeral", ttl: "1h" } : { type: "ephemeral" };
|
|
659
|
+
}
|
|
527
660
|
function createValidatedAnthropicProviderToolCorrelationState(canonicalProviderToolNamesById, rawProviderToolNamesById) {
|
|
528
661
|
assertBoundedAnthropicProviderToolState(canonicalProviderToolNamesById);
|
|
529
662
|
assertBoundedAnthropicProviderToolState(rawProviderToolNamesById);
|
|
@@ -535,7 +668,7 @@ function createValidatedAnthropicProviderToolCorrelationState(canonicalProviderT
|
|
|
535
668
|
}
|
|
536
669
|
return correlated;
|
|
537
670
|
}
|
|
538
|
-
function toAnthropicMessages(prompt, systemCacheControl) {
|
|
671
|
+
function toAnthropicMessages(prompt, systemCacheControl, providerName = "anthropic") {
|
|
539
672
|
const systemParts = [];
|
|
540
673
|
const messages = [];
|
|
541
674
|
const lastUserIndex = prompt.findLastIndex((message) => message.role === "user");
|
|
@@ -564,7 +697,11 @@ function toAnthropicMessages(prompt, systemCacheControl) {
|
|
|
564
697
|
rawProviderToolNamesById = new Map();
|
|
565
698
|
canonicalProviderToolNamesById = new Map();
|
|
566
699
|
if (message.content.length > 0) {
|
|
567
|
-
|
|
700
|
+
const cacheControl = resolveAnthropicSystemMessageCacheControl(message, providerName);
|
|
701
|
+
systemParts.push({
|
|
702
|
+
text: message.content,
|
|
703
|
+
...(cacheControl === undefined ? {} : { cacheControl }),
|
|
704
|
+
});
|
|
568
705
|
}
|
|
569
706
|
break;
|
|
570
707
|
case "user":
|
|
@@ -664,7 +801,23 @@ function toAnthropicMessages(prompt, systemCacheControl) {
|
|
|
664
801
|
providerToolNamesById: createValidatedAnthropicProviderToolCorrelationState(canonicalProviderToolNamesById, rawProviderToolNamesById),
|
|
665
802
|
};
|
|
666
803
|
}
|
|
667
|
-
|
|
804
|
+
if (systemParts.some((part) => part.cacheControl !== undefined)) {
|
|
805
|
+
const system = systemParts.map((part) => ({
|
|
806
|
+
type: "text",
|
|
807
|
+
text: part.text,
|
|
808
|
+
...(part.cacheControl === undefined ? {} : { cache_control: part.cacheControl }),
|
|
809
|
+
}));
|
|
810
|
+
const lastSystemBlock = system.at(-1);
|
|
811
|
+
if (systemCacheControl && lastSystemBlock) {
|
|
812
|
+
lastSystemBlock.cache_control = systemCacheControl;
|
|
813
|
+
}
|
|
814
|
+
return {
|
|
815
|
+
system,
|
|
816
|
+
messages,
|
|
817
|
+
providerToolNamesById: createValidatedAnthropicProviderToolCorrelationState(canonicalProviderToolNamesById, rawProviderToolNamesById),
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
const joined = systemParts.map((part) => part.text).join("\n\n");
|
|
668
821
|
if (systemCacheControl) {
|
|
669
822
|
return {
|
|
670
823
|
system: [{
|
|
@@ -763,6 +916,660 @@ function applyAnthropicToolsCacheControl(tools, cacheControl) {
|
|
|
763
916
|
const lastIndex = tools.length - 1;
|
|
764
917
|
return tools.map((tool, index) => index === lastIndex ? { ...tool, cache_control: cacheControl } : tool);
|
|
765
918
|
}
|
|
919
|
+
function isOmittedJsonObjectPropertyValue(value) {
|
|
920
|
+
return value === undefined || typeof value === "function" || typeof value === "symbol";
|
|
921
|
+
}
|
|
922
|
+
function assertNoAnthropicCacheJsonHook(value) {
|
|
923
|
+
const visited = new NativeSet();
|
|
924
|
+
let candidate = value;
|
|
925
|
+
let depth = 0;
|
|
926
|
+
while (candidate !== null && !hasSetValue(visited, candidate) && depth < 64) {
|
|
927
|
+
if (isProxyWithoutHooks(candidate)) {
|
|
928
|
+
throw new TypeError("Anthropic cache inputs must not contain Proxy values");
|
|
929
|
+
}
|
|
930
|
+
addSetValue(visited, candidate);
|
|
931
|
+
depth += 1;
|
|
932
|
+
let descriptor;
|
|
933
|
+
try {
|
|
934
|
+
descriptor = objectGetOwnPropertyDescriptor(candidate, "toJSON");
|
|
935
|
+
}
|
|
936
|
+
catch {
|
|
937
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
938
|
+
}
|
|
939
|
+
if (descriptor !== undefined) {
|
|
940
|
+
if (!objectHasOwn(descriptor, "value") || typeof descriptor.value === "function") {
|
|
941
|
+
throw new TypeError("Anthropic cache inputs must not define toJSON hooks");
|
|
942
|
+
}
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
try {
|
|
946
|
+
candidate = objectGetPrototypeOf(candidate);
|
|
947
|
+
}
|
|
948
|
+
catch {
|
|
949
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
if (candidate !== null) {
|
|
953
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function assertNoNestedAnthropicCacheJsonHooks(value, label = "Anthropic cache_control", ancestors = new NativeSet(), depth = 0) {
|
|
957
|
+
if (depth >= 64 || hasSetValue(ancestors, value)) {
|
|
958
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
959
|
+
}
|
|
960
|
+
if (isBoxedPrimitive(value)) {
|
|
961
|
+
throw new TypeError(`${label} must not contain boxed primitive values`);
|
|
962
|
+
}
|
|
963
|
+
assertNoAnthropicCacheJsonHook(value);
|
|
964
|
+
addSetValue(ancestors, value);
|
|
965
|
+
try {
|
|
966
|
+
if (ArrayIsArray(value)) {
|
|
967
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
968
|
+
const key = `${index}`;
|
|
969
|
+
let descriptor;
|
|
970
|
+
try {
|
|
971
|
+
descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
972
|
+
}
|
|
973
|
+
catch {
|
|
974
|
+
throw new TypeError(`${label} could not be inspected`);
|
|
975
|
+
}
|
|
976
|
+
if (descriptor === undefined) {
|
|
977
|
+
assertNoInheritedAnthropicArrayElement(value, index, label);
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
981
|
+
throw new TypeError(`${label} must contain only indexed data properties`);
|
|
982
|
+
}
|
|
983
|
+
const nested = descriptor.value;
|
|
984
|
+
if (nested !== null &&
|
|
985
|
+
(typeof nested === "object" || typeof nested === "function")) {
|
|
986
|
+
assertNoNestedAnthropicCacheJsonHooks(nested, label === "Anthropic message content" ? "Anthropic cache records" : label, ancestors, depth + 1);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
let keys;
|
|
992
|
+
try {
|
|
993
|
+
keys = objectKeys(value);
|
|
994
|
+
}
|
|
995
|
+
catch {
|
|
996
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
997
|
+
}
|
|
998
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
999
|
+
const key = keys[index];
|
|
1000
|
+
let descriptor;
|
|
1001
|
+
try {
|
|
1002
|
+
descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
1003
|
+
}
|
|
1004
|
+
catch {
|
|
1005
|
+
throw new TypeError("Anthropic cache input toJSON hooks could not be inspected");
|
|
1006
|
+
}
|
|
1007
|
+
if (!descriptor || !objectHasOwn(descriptor, "value")) {
|
|
1008
|
+
throw new TypeError(`${label} must contain only enumerable data properties`);
|
|
1009
|
+
}
|
|
1010
|
+
const nested = descriptor.value;
|
|
1011
|
+
if (nested !== null &&
|
|
1012
|
+
(typeof nested === "object" || typeof nested === "function")) {
|
|
1013
|
+
const nestedLabel = key === "cache_control" ? "Anthropic cache_control" : label;
|
|
1014
|
+
if (nestedLabel === "Anthropic cache_control" &&
|
|
1015
|
+
(key === "type" || key === "ttl") &&
|
|
1016
|
+
isBoxedString(nested)) {
|
|
1017
|
+
assertNoAnthropicCacheJsonHook(nested);
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
assertNoNestedAnthropicCacheJsonHooks(nested, nestedLabel, ancestors, depth + 1);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
finally {
|
|
1025
|
+
deleteSetValue(ancestors, value);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
function assertNoAnthropicCacheRecordSerializationHooks(value) {
|
|
1029
|
+
if (isBoxedPrimitive(value)) {
|
|
1030
|
+
throw new TypeError("Anthropic cache records must not contain boxed primitive values");
|
|
1031
|
+
}
|
|
1032
|
+
assertNoAnthropicCacheJsonHook(value);
|
|
1033
|
+
let keys;
|
|
1034
|
+
try {
|
|
1035
|
+
keys = objectKeys(value);
|
|
1036
|
+
}
|
|
1037
|
+
catch {
|
|
1038
|
+
throw new TypeError("Anthropic cache records could not be inspected");
|
|
1039
|
+
}
|
|
1040
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
1041
|
+
const key = keys[index];
|
|
1042
|
+
let descriptor;
|
|
1043
|
+
try {
|
|
1044
|
+
descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
1045
|
+
}
|
|
1046
|
+
catch {
|
|
1047
|
+
throw new TypeError("Anthropic cache records could not be inspected");
|
|
1048
|
+
}
|
|
1049
|
+
if (!descriptor || !objectHasOwn(descriptor, "value")) {
|
|
1050
|
+
if (key === "cache_control") {
|
|
1051
|
+
throw new TypeError("Anthropic cache_control must be an own enumerable data property");
|
|
1052
|
+
}
|
|
1053
|
+
throw new TypeError("Anthropic cache records must contain only enumerable data properties");
|
|
1054
|
+
}
|
|
1055
|
+
const nested = descriptor.value;
|
|
1056
|
+
if (nested !== null &&
|
|
1057
|
+
(typeof nested === "object" || typeof nested === "function")) {
|
|
1058
|
+
const nestedLabel = key === "cache_control"
|
|
1059
|
+
? "Anthropic cache_control"
|
|
1060
|
+
: key === "content" && ArrayIsArray(nested)
|
|
1061
|
+
? "Anthropic message content"
|
|
1062
|
+
: "Anthropic cache records";
|
|
1063
|
+
assertNoNestedAnthropicCacheJsonHooks(nested, nestedLabel);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function cloneAnthropicCacheRecord(value) {
|
|
1068
|
+
assertNoAnthropicCacheRecordSerializationHooks(value);
|
|
1069
|
+
const clone = {};
|
|
1070
|
+
const keys = objectKeys(value);
|
|
1071
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
1072
|
+
const key = keys[index];
|
|
1073
|
+
const descriptor = objectGetOwnPropertyDescriptor(value, key);
|
|
1074
|
+
if (!descriptor || !objectHasOwn(descriptor, "value")) {
|
|
1075
|
+
throw new TypeError("Anthropic cache records must contain only enumerable data properties");
|
|
1076
|
+
}
|
|
1077
|
+
defineOwnEnumerableDataProperty(clone, key, descriptor.value);
|
|
1078
|
+
}
|
|
1079
|
+
return clone;
|
|
1080
|
+
}
|
|
1081
|
+
const ANTHROPIC_MAX_CACHE_BREAKPOINTS = 4;
|
|
1082
|
+
function assertNoInheritedAnthropicArrayElement(value, index, label) {
|
|
1083
|
+
const key = `${index}`;
|
|
1084
|
+
const visited = new NativeSet();
|
|
1085
|
+
let candidate;
|
|
1086
|
+
try {
|
|
1087
|
+
candidate = objectGetPrototypeOf(value);
|
|
1088
|
+
}
|
|
1089
|
+
catch {
|
|
1090
|
+
throw new TypeError(`${label} inherited indexed properties could not be inspected`);
|
|
1091
|
+
}
|
|
1092
|
+
let depth = 0;
|
|
1093
|
+
while (candidate !== null && !hasSetValue(visited, candidate) && depth < 64) {
|
|
1094
|
+
if (isProxyWithoutHooks(candidate)) {
|
|
1095
|
+
throw new TypeError(`${label} inherited indexed properties could not be inspected`);
|
|
1096
|
+
}
|
|
1097
|
+
addSetValue(visited, candidate);
|
|
1098
|
+
depth += 1;
|
|
1099
|
+
let descriptor;
|
|
1100
|
+
try {
|
|
1101
|
+
descriptor = objectGetOwnPropertyDescriptor(candidate, key);
|
|
1102
|
+
}
|
|
1103
|
+
catch {
|
|
1104
|
+
throw new TypeError(`${label} inherited indexed properties could not be inspected`);
|
|
1105
|
+
}
|
|
1106
|
+
if (descriptor !== undefined) {
|
|
1107
|
+
throw new TypeError(`${label} must not contain inherited indexed properties`);
|
|
1108
|
+
}
|
|
1109
|
+
try {
|
|
1110
|
+
candidate = objectGetPrototypeOf(candidate);
|
|
1111
|
+
}
|
|
1112
|
+
catch {
|
|
1113
|
+
throw new TypeError(`${label} inherited indexed properties could not be inspected`);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
if (candidate !== null) {
|
|
1117
|
+
throw new TypeError(`${label} inherited indexed properties could not be inspected`);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
function snapshotAnthropicCacheArray(value, label) {
|
|
1121
|
+
assertNoAnthropicCacheJsonHook(value);
|
|
1122
|
+
const snapshot = new NativeArray(value.length);
|
|
1123
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1124
|
+
let descriptor;
|
|
1125
|
+
try {
|
|
1126
|
+
descriptor = objectGetOwnPropertyDescriptor(value, `${index}`);
|
|
1127
|
+
}
|
|
1128
|
+
catch {
|
|
1129
|
+
throw new TypeError(`${label} could not be inspected`);
|
|
1130
|
+
}
|
|
1131
|
+
if (descriptor === undefined) {
|
|
1132
|
+
assertNoInheritedAnthropicArrayElement(value, index, label);
|
|
1133
|
+
continue;
|
|
1134
|
+
}
|
|
1135
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1136
|
+
throw new TypeError(`${label} must contain only indexed data properties`);
|
|
1137
|
+
}
|
|
1138
|
+
defineOwnEnumerableDataProperty(snapshot, `${index}`, descriptor.value);
|
|
1139
|
+
}
|
|
1140
|
+
return snapshot;
|
|
1141
|
+
}
|
|
1142
|
+
function hasEmittedAnthropicCacheBreakpoint(value) {
|
|
1143
|
+
assertNoAnthropicCacheRecordSerializationHooks(value);
|
|
1144
|
+
let descriptor;
|
|
1145
|
+
try {
|
|
1146
|
+
descriptor = objectGetOwnPropertyDescriptor(value, "cache_control");
|
|
1147
|
+
}
|
|
1148
|
+
catch {
|
|
1149
|
+
throw new TypeError("Anthropic cache_control could not be inspected");
|
|
1150
|
+
}
|
|
1151
|
+
if (descriptor === undefined || descriptor.enumerable !== true) {
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1155
|
+
throw new TypeError("Anthropic cache_control must be an own enumerable data property");
|
|
1156
|
+
}
|
|
1157
|
+
if (typeof descriptor.value === "function" ||
|
|
1158
|
+
(typeof descriptor.value === "object" && descriptor.value !== null)) {
|
|
1159
|
+
assertNoAnthropicCacheJsonHook(descriptor.value);
|
|
1160
|
+
}
|
|
1161
|
+
return !isOmittedJsonObjectPropertyValue(descriptor.value);
|
|
1162
|
+
}
|
|
1163
|
+
function isAnthropicMessageCacheBlock(value) {
|
|
1164
|
+
if (typeof value === "function" || ArrayIsArray(value)) {
|
|
1165
|
+
assertNoAnthropicCacheJsonHook(value);
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
return typeof value === "object" && value !== null;
|
|
1169
|
+
}
|
|
1170
|
+
function readEmittedAnthropicMessageContent(message) {
|
|
1171
|
+
assertNoAnthropicCacheRecordSerializationHooks(message);
|
|
1172
|
+
let descriptor;
|
|
1173
|
+
try {
|
|
1174
|
+
descriptor = objectGetOwnPropertyDescriptor(message, "content");
|
|
1175
|
+
}
|
|
1176
|
+
catch {
|
|
1177
|
+
throw new TypeError("Anthropic message content could not be inspected");
|
|
1178
|
+
}
|
|
1179
|
+
if (descriptor === undefined || descriptor.enumerable !== true) {
|
|
1180
|
+
return [];
|
|
1181
|
+
}
|
|
1182
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1183
|
+
throw new TypeError("Anthropic message content must be an own enumerable data property");
|
|
1184
|
+
}
|
|
1185
|
+
const content = descriptor.value;
|
|
1186
|
+
if (!ArrayIsArray(content)) {
|
|
1187
|
+
if ((typeof content === "object" && content !== null) ||
|
|
1188
|
+
typeof content === "function") {
|
|
1189
|
+
assertNoAnthropicCacheJsonHook(content);
|
|
1190
|
+
}
|
|
1191
|
+
return [];
|
|
1192
|
+
}
|
|
1193
|
+
return snapshotAnthropicCacheArray(content, "Anthropic message content");
|
|
1194
|
+
}
|
|
1195
|
+
function readAnthropicArrayDataElement(value, index, label) {
|
|
1196
|
+
let descriptor;
|
|
1197
|
+
try {
|
|
1198
|
+
descriptor = objectGetOwnPropertyDescriptor(value, `${index}`);
|
|
1199
|
+
}
|
|
1200
|
+
catch {
|
|
1201
|
+
throw new TypeError(`${label} could not be inspected`);
|
|
1202
|
+
}
|
|
1203
|
+
if (descriptor === undefined) {
|
|
1204
|
+
return undefined;
|
|
1205
|
+
}
|
|
1206
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1207
|
+
throw new TypeError(`${label} must contain only indexed data properties`);
|
|
1208
|
+
}
|
|
1209
|
+
return descriptor.value;
|
|
1210
|
+
}
|
|
1211
|
+
function retainLatestAnthropicMessageCacheBreakpoints(messages, maximum) {
|
|
1212
|
+
const breakpointCount = countAnthropicMessageCacheBreakpoints(messages);
|
|
1213
|
+
let remainingToRemove = breakpointCount > maximum ? breakpointCount - maximum : 0;
|
|
1214
|
+
if (remainingToRemove === 0) {
|
|
1215
|
+
return messages;
|
|
1216
|
+
}
|
|
1217
|
+
const normalizedMessages = new NativeArray(messages.length);
|
|
1218
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
1219
|
+
const message = readAnthropicArrayDataElement(messages, messageIndex, "Anthropic messages");
|
|
1220
|
+
if (message === undefined) {
|
|
1221
|
+
continue;
|
|
1222
|
+
}
|
|
1223
|
+
const originalContent = readEmittedAnthropicMessageContent(message);
|
|
1224
|
+
let content = originalContent;
|
|
1225
|
+
for (let contentIndex = 0; remainingToRemove > 0 && contentIndex < originalContent.length; contentIndex += 1) {
|
|
1226
|
+
const block = readAnthropicArrayDataElement(originalContent, contentIndex, "Anthropic message content");
|
|
1227
|
+
if (!isAnthropicMessageCacheBlock(block) ||
|
|
1228
|
+
!hasEmittedAnthropicCacheBreakpoint(block)) {
|
|
1229
|
+
continue;
|
|
1230
|
+
}
|
|
1231
|
+
if (content === originalContent) {
|
|
1232
|
+
content = snapshotAnthropicCacheArray(originalContent, "Anthropic message content");
|
|
1233
|
+
}
|
|
1234
|
+
const next = cloneAnthropicCacheRecord(block);
|
|
1235
|
+
reflectDeleteProperty(next, "cache_control");
|
|
1236
|
+
defineOwnEnumerableDataProperty(content, `${contentIndex}`, next);
|
|
1237
|
+
remainingToRemove -= 1;
|
|
1238
|
+
}
|
|
1239
|
+
if (content === originalContent) {
|
|
1240
|
+
defineOwnEnumerableDataProperty(normalizedMessages, `${messageIndex}`, message);
|
|
1241
|
+
}
|
|
1242
|
+
else {
|
|
1243
|
+
const nextMessage = cloneAnthropicCacheRecord(message);
|
|
1244
|
+
defineOwnEnumerableDataProperty(nextMessage, "content", content);
|
|
1245
|
+
defineOwnEnumerableDataProperty(normalizedMessages, `${messageIndex}`, nextMessage);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
return normalizedMessages;
|
|
1249
|
+
}
|
|
1250
|
+
function countAnthropicMessageCacheBreakpoints(messages) {
|
|
1251
|
+
let count = 0;
|
|
1252
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
1253
|
+
const message = readAnthropicArrayDataElement(messages, messageIndex, "Anthropic messages");
|
|
1254
|
+
if (message === undefined) {
|
|
1255
|
+
continue;
|
|
1256
|
+
}
|
|
1257
|
+
const content = readEmittedAnthropicMessageContent(message);
|
|
1258
|
+
for (let contentIndex = 0; contentIndex < content.length; contentIndex += 1) {
|
|
1259
|
+
const block = readAnthropicArrayDataElement(content, contentIndex, "Anthropic message content");
|
|
1260
|
+
if (isAnthropicMessageCacheBlock(block) &&
|
|
1261
|
+
hasEmittedAnthropicCacheBreakpoint(block)) {
|
|
1262
|
+
count += 1;
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return count;
|
|
1267
|
+
}
|
|
1268
|
+
function readJsonSerializedAnthropicString(value) {
|
|
1269
|
+
if (typeof value === "string")
|
|
1270
|
+
return value;
|
|
1271
|
+
if (typeof value !== "object" || value === null)
|
|
1272
|
+
return undefined;
|
|
1273
|
+
assertNoAnthropicCacheJsonHook(value);
|
|
1274
|
+
try {
|
|
1275
|
+
apply(stringValueOf, value, []);
|
|
1276
|
+
}
|
|
1277
|
+
catch {
|
|
1278
|
+
return undefined;
|
|
1279
|
+
}
|
|
1280
|
+
throw new TypeError("Anthropic cache strings must use primitive string values");
|
|
1281
|
+
}
|
|
1282
|
+
function snapshotAnthropicProviderBucket(bucket) {
|
|
1283
|
+
if (isProxyWithoutHooks(bucket)) {
|
|
1284
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1285
|
+
}
|
|
1286
|
+
const snapshot = {};
|
|
1287
|
+
let keys;
|
|
1288
|
+
try {
|
|
1289
|
+
keys = apply(reflectOwnKeys, Reflect, [bucket]);
|
|
1290
|
+
}
|
|
1291
|
+
catch {
|
|
1292
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1293
|
+
}
|
|
1294
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
1295
|
+
const key = keys[index];
|
|
1296
|
+
if (typeof key !== "string")
|
|
1297
|
+
continue;
|
|
1298
|
+
let descriptor;
|
|
1299
|
+
try {
|
|
1300
|
+
descriptor = objectGetOwnPropertyDescriptor(bucket, key);
|
|
1301
|
+
}
|
|
1302
|
+
catch {
|
|
1303
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1304
|
+
}
|
|
1305
|
+
if (descriptor?.enumerable !== true)
|
|
1306
|
+
continue;
|
|
1307
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1308
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1309
|
+
}
|
|
1310
|
+
defineOwnEnumerableDataProperty(snapshot, key, descriptor.value);
|
|
1311
|
+
}
|
|
1312
|
+
return snapshot;
|
|
1313
|
+
}
|
|
1314
|
+
function prepareAnthropicProviderOptions(providerOptions, ...providerNames) {
|
|
1315
|
+
if (providerOptions === undefined)
|
|
1316
|
+
return undefined;
|
|
1317
|
+
try {
|
|
1318
|
+
if (canIdentifyProxyWithoutHooks) {
|
|
1319
|
+
if (isProxyWithoutHooks(providerOptions)) {
|
|
1320
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1321
|
+
}
|
|
1322
|
+
const snapshot = {};
|
|
1323
|
+
for (let index = 0; index < providerNames.length; index += 1) {
|
|
1324
|
+
const providerName = providerNames[index];
|
|
1325
|
+
const descriptor = objectGetOwnPropertyDescriptor(providerOptions, providerName);
|
|
1326
|
+
if (descriptor === undefined)
|
|
1327
|
+
continue;
|
|
1328
|
+
if (!objectHasOwn(descriptor, "value")) {
|
|
1329
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1330
|
+
}
|
|
1331
|
+
const value = descriptor.value;
|
|
1332
|
+
defineOwnEnumerableDataProperty(snapshot, providerName, value !== null && typeof value === "object" && !ArrayIsArray(value)
|
|
1333
|
+
? snapshotAnthropicProviderBucket(value)
|
|
1334
|
+
: value);
|
|
1335
|
+
}
|
|
1336
|
+
return snapshot;
|
|
1337
|
+
}
|
|
1338
|
+
const snapshot = snapshotProviderJsonValue(providerOptions, {
|
|
1339
|
+
dropUndefinedMembers: true,
|
|
1340
|
+
sortObjectKeys: false,
|
|
1341
|
+
});
|
|
1342
|
+
if (snapshot === null || typeof snapshot !== "object" || ArrayIsArray(snapshot)) {
|
|
1343
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1344
|
+
}
|
|
1345
|
+
return snapshot;
|
|
1346
|
+
}
|
|
1347
|
+
catch {
|
|
1348
|
+
throw new TypeError("Anthropic provider options could not be inspected");
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
function readEmittedAnthropicCacheTtl(value) {
|
|
1352
|
+
let descriptor;
|
|
1353
|
+
try {
|
|
1354
|
+
descriptor = objectGetOwnPropertyDescriptor(value, "cache_control");
|
|
1355
|
+
}
|
|
1356
|
+
catch {
|
|
1357
|
+
return undefined;
|
|
1358
|
+
}
|
|
1359
|
+
if (descriptor === undefined || descriptor.enumerable !== true ||
|
|
1360
|
+
!objectHasOwn(descriptor, "value")) {
|
|
1361
|
+
return undefined;
|
|
1362
|
+
}
|
|
1363
|
+
const cacheControl = descriptor.value;
|
|
1364
|
+
if (typeof cacheControl !== "object" || cacheControl === null ||
|
|
1365
|
+
ArrayIsArray(cacheControl)) {
|
|
1366
|
+
return undefined;
|
|
1367
|
+
}
|
|
1368
|
+
assertNoNestedAnthropicCacheJsonHooks(cacheControl);
|
|
1369
|
+
let keys;
|
|
1370
|
+
try {
|
|
1371
|
+
keys = objectKeys(cacheControl);
|
|
1372
|
+
}
|
|
1373
|
+
catch {
|
|
1374
|
+
return undefined;
|
|
1375
|
+
}
|
|
1376
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
1377
|
+
const key = keys[index];
|
|
1378
|
+
const property = readOwnEnumerableDataProperty(cacheControl, key);
|
|
1379
|
+
if (!property) {
|
|
1380
|
+
throw new TypeError("Anthropic cache_control must contain only enumerable data properties");
|
|
1381
|
+
}
|
|
1382
|
+
if (!isOmittedJsonObjectPropertyValue(property.value) && key !== "type" && key !== "ttl") {
|
|
1383
|
+
return undefined;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
const type = readOwnEnumerableDataProperty(cacheControl, "type");
|
|
1387
|
+
const ttl = readOwnEnumerableDataProperty(cacheControl, "ttl");
|
|
1388
|
+
const typeValue = type?.present ? readJsonSerializedAnthropicString(type.value) : undefined;
|
|
1389
|
+
const ttlValue = ttl?.present ? readJsonSerializedAnthropicString(ttl.value) : undefined;
|
|
1390
|
+
if (!type?.present || isOmittedJsonObjectPropertyValue(type.value) ||
|
|
1391
|
+
typeValue !== "ephemeral" || !ttl) {
|
|
1392
|
+
return undefined;
|
|
1393
|
+
}
|
|
1394
|
+
if (ttl.present && ttlValue === "1h") {
|
|
1395
|
+
return "1h";
|
|
1396
|
+
}
|
|
1397
|
+
return !ttl.present || isOmittedJsonObjectPropertyValue(ttl.value) || ttlValue === "5m"
|
|
1398
|
+
? "5m"
|
|
1399
|
+
: undefined;
|
|
1400
|
+
}
|
|
1401
|
+
function upgradeEmittedAnthropicCacheTtl(value) {
|
|
1402
|
+
const upgraded = cloneAnthropicCacheRecord(value);
|
|
1403
|
+
defineOwnEnumerableDataProperty(upgraded, "cache_control", { type: "ephemeral", ttl: "1h" });
|
|
1404
|
+
return upgraded;
|
|
1405
|
+
}
|
|
1406
|
+
function normalizeAnthropicCacheTtls(values, requiresOneHourPrefix) {
|
|
1407
|
+
let normalized = values;
|
|
1408
|
+
for (let index = values.length - 1; index >= 0; index -= 1) {
|
|
1409
|
+
const value = values[index];
|
|
1410
|
+
if (!value || !hasEmittedAnthropicCacheBreakpoint(value)) {
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
const ttl = readEmittedAnthropicCacheTtl(value);
|
|
1414
|
+
if (ttl === "1h") {
|
|
1415
|
+
requiresOneHourPrefix = true;
|
|
1416
|
+
}
|
|
1417
|
+
else if (ttl === "5m" && requiresOneHourPrefix) {
|
|
1418
|
+
if (normalized === values) {
|
|
1419
|
+
normalized = snapshotAnthropicCacheArray(values, "Anthropic cache blocks");
|
|
1420
|
+
}
|
|
1421
|
+
defineOwnEnumerableDataProperty(normalized, `${index}`, upgradeEmittedAnthropicCacheTtl(value));
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return { values: normalized, requiresOneHourPrefix };
|
|
1425
|
+
}
|
|
1426
|
+
function normalizeAnthropicMessageCacheTtls(messages) {
|
|
1427
|
+
let normalizedMessages = messages;
|
|
1428
|
+
let requiresOneHourPrefix = false;
|
|
1429
|
+
for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {
|
|
1430
|
+
const message = messages[messageIndex];
|
|
1431
|
+
if (!message) {
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
const content = readEmittedAnthropicMessageContent(message);
|
|
1435
|
+
let normalizedContent = content;
|
|
1436
|
+
for (let contentIndex = content.length - 1; contentIndex >= 0; contentIndex -= 1) {
|
|
1437
|
+
const block = content[contentIndex];
|
|
1438
|
+
if (!isAnthropicMessageCacheBlock(block) ||
|
|
1439
|
+
!hasEmittedAnthropicCacheBreakpoint(block)) {
|
|
1440
|
+
continue;
|
|
1441
|
+
}
|
|
1442
|
+
const ttl = readEmittedAnthropicCacheTtl(block);
|
|
1443
|
+
if (ttl === "1h") {
|
|
1444
|
+
requiresOneHourPrefix = true;
|
|
1445
|
+
}
|
|
1446
|
+
else if (ttl === "5m" && requiresOneHourPrefix) {
|
|
1447
|
+
if (normalizedContent === content) {
|
|
1448
|
+
normalizedContent = snapshotAnthropicCacheArray(content, "Anthropic message content");
|
|
1449
|
+
}
|
|
1450
|
+
defineOwnEnumerableDataProperty(normalizedContent, `${contentIndex}`, upgradeEmittedAnthropicCacheTtl(block));
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
if (normalizedContent !== content) {
|
|
1454
|
+
if (normalizedMessages === messages) {
|
|
1455
|
+
normalizedMessages = snapshotAnthropicCacheArray(messages, "Anthropic messages");
|
|
1456
|
+
}
|
|
1457
|
+
const nextMessage = cloneAnthropicCacheRecord(message);
|
|
1458
|
+
defineOwnEnumerableDataProperty(nextMessage, "content", normalizedContent);
|
|
1459
|
+
defineOwnEnumerableDataProperty(normalizedMessages, `${messageIndex}`, nextMessage);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
return { messages: normalizedMessages, requiresOneHourPrefix };
|
|
1463
|
+
}
|
|
1464
|
+
function retainLatestAnthropicCacheBreakpoints(values, maximum) {
|
|
1465
|
+
const breakpointIndexes = new NativeArray(values.length);
|
|
1466
|
+
let breakpointCount = 0;
|
|
1467
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
1468
|
+
const descriptor = objectGetOwnPropertyDescriptor(values, `${index}`);
|
|
1469
|
+
if (descriptor !== undefined &&
|
|
1470
|
+
hasEmittedAnthropicCacheBreakpoint(descriptor.value)) {
|
|
1471
|
+
defineOwnEnumerableDataProperty(breakpointIndexes, `${breakpointCount}`, index);
|
|
1472
|
+
breakpointCount += 1;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
const removalCount = breakpointCount > maximum ? breakpointCount - maximum : 0;
|
|
1476
|
+
if (removalCount === 0) {
|
|
1477
|
+
return values;
|
|
1478
|
+
}
|
|
1479
|
+
const retained = new NativeArray(values.length);
|
|
1480
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
1481
|
+
const descriptor = objectGetOwnPropertyDescriptor(values, `${index}`);
|
|
1482
|
+
if (descriptor !== undefined) {
|
|
1483
|
+
defineOwnEnumerableDataProperty(retained, `${index}`, descriptor.value);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
for (let position = 0; position < removalCount; position += 1) {
|
|
1487
|
+
const index = breakpointIndexes[position];
|
|
1488
|
+
const next = cloneAnthropicCacheRecord(retained[index]);
|
|
1489
|
+
reflectDeleteProperty(next, "cache_control");
|
|
1490
|
+
defineOwnEnumerableDataProperty(retained, `${index}`, next);
|
|
1491
|
+
}
|
|
1492
|
+
return retained;
|
|
1493
|
+
}
|
|
1494
|
+
function countAnthropicCacheBreakpoints(values) {
|
|
1495
|
+
let count = 0;
|
|
1496
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
1497
|
+
const value = readAnthropicArrayDataElement(values, index, "Anthropic cache blocks");
|
|
1498
|
+
if (value !== undefined && hasEmittedAnthropicCacheBreakpoint(value)) {
|
|
1499
|
+
count += 1;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
return count;
|
|
1503
|
+
}
|
|
1504
|
+
function limitAnthropicCacheBreakpoints(system, tools, messages) {
|
|
1505
|
+
const inspectedMessages = snapshotAnthropicCacheArray(messages, "Anthropic messages");
|
|
1506
|
+
const inspectedSystem = ArrayIsArray(system)
|
|
1507
|
+
? snapshotAnthropicCacheArray(system, "Anthropic system")
|
|
1508
|
+
: system;
|
|
1509
|
+
const inspectedTools = tools ? snapshotAnthropicCacheArray(tools, "Anthropic tools") : undefined;
|
|
1510
|
+
const boundedMessages = retainLatestAnthropicMessageCacheBreakpoints(inspectedMessages, ANTHROPIC_MAX_CACHE_BREAKPOINTS);
|
|
1511
|
+
const messageBreakpointCount = countAnthropicMessageCacheBreakpoints(boundedMessages);
|
|
1512
|
+
const boundedSystem = ArrayIsArray(inspectedSystem)
|
|
1513
|
+
? retainLatestAnthropicCacheBreakpoints(inspectedSystem, ANTHROPIC_MAX_CACHE_BREAKPOINTS - messageBreakpointCount)
|
|
1514
|
+
: inspectedSystem;
|
|
1515
|
+
const systemBreakpointCount = ArrayIsArray(boundedSystem)
|
|
1516
|
+
? countAnthropicCacheBreakpoints(boundedSystem)
|
|
1517
|
+
: 0;
|
|
1518
|
+
const boundedTools = inspectedTools
|
|
1519
|
+
? retainLatestAnthropicCacheBreakpoints(inspectedTools, ANTHROPIC_MAX_CACHE_BREAKPOINTS - messageBreakpointCount - systemBreakpointCount)
|
|
1520
|
+
: undefined;
|
|
1521
|
+
const normalizedMessages = normalizeAnthropicMessageCacheTtls(boundedMessages);
|
|
1522
|
+
const normalizedSystem = ArrayIsArray(boundedSystem)
|
|
1523
|
+
? normalizeAnthropicCacheTtls(boundedSystem, normalizedMessages.requiresOneHourPrefix)
|
|
1524
|
+
: {
|
|
1525
|
+
values: boundedSystem,
|
|
1526
|
+
requiresOneHourPrefix: normalizedMessages.requiresOneHourPrefix,
|
|
1527
|
+
};
|
|
1528
|
+
const normalizedTools = boundedTools
|
|
1529
|
+
? normalizeAnthropicCacheTtls(boundedTools, normalizedSystem.requiresOneHourPrefix).values
|
|
1530
|
+
: undefined;
|
|
1531
|
+
return {
|
|
1532
|
+
system: normalizedSystem.values,
|
|
1533
|
+
tools: normalizedTools,
|
|
1534
|
+
messages: normalizedMessages.messages,
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function assertAnthropicCacheableRequestFields(body) {
|
|
1538
|
+
assertNoAnthropicCacheJsonHook(body);
|
|
1539
|
+
if (!ArrayIsArray(body.messages)) {
|
|
1540
|
+
throw new TypeError("Anthropic messages must be an array");
|
|
1541
|
+
}
|
|
1542
|
+
if (body.system !== undefined && typeof body.system !== "string" &&
|
|
1543
|
+
!ArrayIsArray(body.system)) {
|
|
1544
|
+
throw new TypeError("Anthropic system must be a string or an array");
|
|
1545
|
+
}
|
|
1546
|
+
if (body.tools !== undefined && !ArrayIsArray(body.tools)) {
|
|
1547
|
+
throw new TypeError("Anthropic tools must be an array");
|
|
1548
|
+
}
|
|
1549
|
+
const keys = objectKeys(body);
|
|
1550
|
+
let lastCacheFieldIndex = -1;
|
|
1551
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
1552
|
+
const key = keys[index];
|
|
1553
|
+
if (key === "messages" || key === "system" || key === "tools") {
|
|
1554
|
+
lastCacheFieldIndex = index;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
for (let index = 0; index <= lastCacheFieldIndex; index += 1) {
|
|
1558
|
+
const key = keys[index];
|
|
1559
|
+
if (key === "messages" || key === "system" || key === "tools") {
|
|
1560
|
+
continue;
|
|
1561
|
+
}
|
|
1562
|
+
const descriptor = objectGetOwnPropertyDescriptor(body, key);
|
|
1563
|
+
if (!descriptor || !objectHasOwn(descriptor, "value")) {
|
|
1564
|
+
throw new TypeError("Anthropic request fields must use enumerable data properties");
|
|
1565
|
+
}
|
|
1566
|
+
const value = descriptor.value;
|
|
1567
|
+
if (value !== null &&
|
|
1568
|
+
(typeof value === "object" || typeof value === "function")) {
|
|
1569
|
+
assertNoNestedAnthropicCacheJsonHooks(value, "Anthropic request fields");
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
766
1573
|
function containsAnthropicMcpToolset(tools) {
|
|
767
1574
|
return tools?.some((tool) => tool.type === "mcp_toolset") ?? false;
|
|
768
1575
|
}
|
|
@@ -825,23 +1632,32 @@ function resolveAnthropicThinkingBudget(option) {
|
|
|
825
1632
|
}
|
|
826
1633
|
}
|
|
827
1634
|
function resolveAnthropicProviderThinkingBudget(options) {
|
|
828
|
-
const
|
|
1635
|
+
const thinkingProperty = readOwnEnumerableDataProperty(options, "thinking");
|
|
1636
|
+
if (!thinkingProperty) {
|
|
1637
|
+
throw new TypeError("Anthropic provider thinking must be an object");
|
|
1638
|
+
}
|
|
1639
|
+
const thinking = thinkingProperty.present ? thinkingProperty.value : undefined;
|
|
829
1640
|
if (thinking === undefined) {
|
|
830
1641
|
return undefined;
|
|
831
1642
|
}
|
|
832
|
-
if (thinking === null || typeof thinking !== "object" ||
|
|
1643
|
+
if (thinking === null || typeof thinking !== "object" || ArrayIsArray(thinking) ||
|
|
1644
|
+
isProxyWithoutHooks(thinking)) {
|
|
833
1645
|
throw new TypeError("Anthropic provider thinking must be an object");
|
|
834
1646
|
}
|
|
835
|
-
const
|
|
836
|
-
if (typeof
|
|
1647
|
+
const type = readOwnEnumerableDataProperty(thinking, "type");
|
|
1648
|
+
if (!type?.present || typeof type.value !== "string" || type.value.length === 0) {
|
|
837
1649
|
throw new TypeError("Anthropic provider thinking.type must be a non-empty string");
|
|
838
1650
|
}
|
|
839
|
-
const
|
|
1651
|
+
const budgetTokensProperty = readOwnEnumerableDataProperty(thinking, "budget_tokens");
|
|
1652
|
+
if (!budgetTokensProperty) {
|
|
1653
|
+
throw new TypeError("Anthropic provider thinking.budget_tokens must be a safe integer of at least 1024");
|
|
1654
|
+
}
|
|
1655
|
+
const budgetTokens = budgetTokensProperty.present ? budgetTokensProperty.value : undefined;
|
|
840
1656
|
if (budgetTokens !== undefined &&
|
|
841
1657
|
(!Number.isSafeInteger(budgetTokens) || budgetTokens < 1024)) {
|
|
842
1658
|
throw new TypeError("Anthropic provider thinking.budget_tokens must be a safe integer of at least 1024");
|
|
843
1659
|
}
|
|
844
|
-
if (
|
|
1660
|
+
if (type.value !== "enabled") {
|
|
845
1661
|
return undefined;
|
|
846
1662
|
}
|
|
847
1663
|
if (budgetTokens === undefined) {
|
|
@@ -852,17 +1668,17 @@ function resolveAnthropicProviderThinkingBudget(options) {
|
|
|
852
1668
|
export function buildAnthropicMessagesRequestWithCorrelationState(modelId, providerName, options, stream, warnings) {
|
|
853
1669
|
const systemCacheControl = resolveAnthropicCacheControlBlock(options.cacheControl?.system);
|
|
854
1670
|
const toolsCacheControl = resolveAnthropicCacheControlBlock(options.cacheControl?.tools);
|
|
855
|
-
const { system, messages, providerToolNamesById } = toAnthropicMessages(options.prompt, systemCacheControl);
|
|
1671
|
+
const { system, messages, providerToolNamesById } = toAnthropicMessages(options.prompt, systemCacheControl, providerName);
|
|
856
1672
|
const mcpConfiguration = normalizeAnthropicMcpServers(options.mcpServers);
|
|
857
1673
|
const callerTools = toAnthropicTools(options.tools);
|
|
858
1674
|
const anthropicTools = applyAnthropicToolsCacheControl(mergeAnthropicMcpToolsets(callerTools, mcpConfiguration), toolsCacheControl);
|
|
859
|
-
const rawProviderOptions = readProviderOptions(options.providerOptions, "anthropic", providerName);
|
|
1675
|
+
const rawProviderOptions = readProviderOptions(prepareAnthropicProviderOptions(options.providerOptions, "anthropic", providerName), "anthropic", providerName);
|
|
860
1676
|
if (mcpConfiguration &&
|
|
861
|
-
(
|
|
862
|
-
|
|
1677
|
+
(objectHasOwn(rawProviderOptions, "mcp_servers") ||
|
|
1678
|
+
objectHasOwn(rawProviderOptions, "tools"))) {
|
|
863
1679
|
throw new TypeError("Anthropic MCP configuration must not be split between mcpServers and providerOptions");
|
|
864
1680
|
}
|
|
865
|
-
if (
|
|
1681
|
+
if (objectHasOwn(rawProviderOptions, "tools") &&
|
|
866
1682
|
containsAnthropicMcpToolset(callerTools)) {
|
|
867
1683
|
throw new TypeError("Anthropic MCP toolsets must not be defined in both tools and providerOptions");
|
|
868
1684
|
}
|
|
@@ -964,10 +1780,25 @@ export function buildAnthropicMessagesRequestWithCorrelationState(modelId, provi
|
|
|
964
1780
|
...(mcpConfiguration ? { mcp_servers: mcpConfiguration.servers } : {}),
|
|
965
1781
|
...(options.anthropicContainer !== undefined ? { container: options.anthropicContainer } : {}),
|
|
966
1782
|
};
|
|
967
|
-
Object
|
|
1783
|
+
apply(objectAssign, Object, [body, rawProviderOptions]);
|
|
968
1784
|
if (thinkingBudget !== undefined || providerThinkingBudget !== undefined) {
|
|
969
1785
|
body.thinking = { type: "enabled", budget_tokens: effectiveThinkingBudget };
|
|
970
1786
|
}
|
|
1787
|
+
assertAnthropicCacheableRequestFields(body);
|
|
1788
|
+
const boundedCacheBreakpoints = limitAnthropicCacheBreakpoints(body.system, body.tools, body.messages);
|
|
1789
|
+
if (boundedCacheBreakpoints.system === undefined) {
|
|
1790
|
+
reflectDeleteProperty(body, "system");
|
|
1791
|
+
}
|
|
1792
|
+
else {
|
|
1793
|
+
body.system = boundedCacheBreakpoints.system;
|
|
1794
|
+
}
|
|
1795
|
+
if (boundedCacheBreakpoints.tools === undefined) {
|
|
1796
|
+
reflectDeleteProperty(body, "tools");
|
|
1797
|
+
}
|
|
1798
|
+
else {
|
|
1799
|
+
body.tools = boundedCacheBreakpoints.tools;
|
|
1800
|
+
}
|
|
1801
|
+
body.messages = boundedCacheBreakpoints.messages;
|
|
971
1802
|
assertAnthropicMcpRequestContract(body);
|
|
972
1803
|
return {
|
|
973
1804
|
body,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veryfront/ext-llm-anthropic",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1239",
|
|
4
4
|
"description": "Veryfront first-party extension package for ext-llm-anthropic",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"veryfront",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@deno/shim-timers": "~0.1.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"veryfront": "^0.1.
|
|
53
|
+
"veryfront": "^0.1.1239"
|
|
54
54
|
},
|
|
55
55
|
"type": "module",
|
|
56
56
|
"types": "./esm/index.d.ts",
|