@dylanrussell/agent-router 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +77 -3
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/plugin.js +580 -243
- package/dist/plugin.js.map +1 -1
- package/dist/tui.js +2 -3
- package/dist/tui.js.map +1 -1
- package/package.json +2 -1
package/dist/plugin.js
CHANGED
|
@@ -729,9 +729,9 @@ function floatSafeRemainder(val, step) {
|
|
|
729
729
|
return ratio - roundedRatio;
|
|
730
730
|
}
|
|
731
731
|
var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
|
|
732
|
-
function defineLazy(object2,
|
|
732
|
+
function defineLazy(object2, key3, getter) {
|
|
733
733
|
let value = void 0;
|
|
734
|
-
Object.defineProperty(object2,
|
|
734
|
+
Object.defineProperty(object2, key3, {
|
|
735
735
|
get() {
|
|
736
736
|
if (value === EVALUATING) {
|
|
737
737
|
return void 0;
|
|
@@ -743,7 +743,7 @@ function defineLazy(object2, key2, getter) {
|
|
|
743
743
|
return value;
|
|
744
744
|
},
|
|
745
745
|
set(v) {
|
|
746
|
-
Object.defineProperty(object2,
|
|
746
|
+
Object.defineProperty(object2, key3, {
|
|
747
747
|
value: v
|
|
748
748
|
// configurable: true,
|
|
749
749
|
});
|
|
@@ -776,11 +776,11 @@ function cloneDef(schema) {
|
|
|
776
776
|
function getElementAtPath(obj, path8) {
|
|
777
777
|
if (!path8)
|
|
778
778
|
return obj;
|
|
779
|
-
return path8.reduce((acc,
|
|
779
|
+
return path8.reduce((acc, key3) => acc?.[key3], obj);
|
|
780
780
|
}
|
|
781
781
|
function promiseAllObject(promisesObj) {
|
|
782
782
|
const keys = Object.keys(promisesObj);
|
|
783
|
-
const promises = keys.map((
|
|
783
|
+
const promises = keys.map((key3) => promisesObj[key3]);
|
|
784
784
|
return Promise.all(promises).then((results) => {
|
|
785
785
|
const resolvedObj = {};
|
|
786
786
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -852,8 +852,8 @@ function shallowClone(o) {
|
|
|
852
852
|
}
|
|
853
853
|
function numKeys(data) {
|
|
854
854
|
let keyCount = 0;
|
|
855
|
-
for (const
|
|
856
|
-
if (Object.prototype.hasOwnProperty.call(data,
|
|
855
|
+
for (const key3 in data) {
|
|
856
|
+
if (Object.prototype.hasOwnProperty.call(data, key3)) {
|
|
857
857
|
keyCount++;
|
|
858
858
|
}
|
|
859
859
|
}
|
|
@@ -1003,13 +1003,13 @@ function pick(schema, mask) {
|
|
|
1003
1003
|
const def = mergeDefs(schema._zod.def, {
|
|
1004
1004
|
get shape() {
|
|
1005
1005
|
const newShape = {};
|
|
1006
|
-
for (const
|
|
1007
|
-
if (!(
|
|
1008
|
-
throw new Error(`Unrecognized key: "${
|
|
1006
|
+
for (const key3 in mask) {
|
|
1007
|
+
if (!(key3 in currDef.shape)) {
|
|
1008
|
+
throw new Error(`Unrecognized key: "${key3}"`);
|
|
1009
1009
|
}
|
|
1010
|
-
if (!mask[
|
|
1010
|
+
if (!mask[key3])
|
|
1011
1011
|
continue;
|
|
1012
|
-
newShape[
|
|
1012
|
+
newShape[key3] = currDef.shape[key3];
|
|
1013
1013
|
}
|
|
1014
1014
|
assignProp(this, "shape", newShape);
|
|
1015
1015
|
return newShape;
|
|
@@ -1028,13 +1028,13 @@ function omit(schema, mask) {
|
|
|
1028
1028
|
const def = mergeDefs(schema._zod.def, {
|
|
1029
1029
|
get shape() {
|
|
1030
1030
|
const newShape = { ...schema._zod.def.shape };
|
|
1031
|
-
for (const
|
|
1032
|
-
if (!(
|
|
1033
|
-
throw new Error(`Unrecognized key: "${
|
|
1031
|
+
for (const key3 in mask) {
|
|
1032
|
+
if (!(key3 in currDef.shape)) {
|
|
1033
|
+
throw new Error(`Unrecognized key: "${key3}"`);
|
|
1034
1034
|
}
|
|
1035
|
-
if (!mask[
|
|
1035
|
+
if (!mask[key3])
|
|
1036
1036
|
continue;
|
|
1037
|
-
delete newShape[
|
|
1037
|
+
delete newShape[key3];
|
|
1038
1038
|
}
|
|
1039
1039
|
assignProp(this, "shape", newShape);
|
|
1040
1040
|
return newShape;
|
|
@@ -1051,8 +1051,8 @@ function extend(schema, shape) {
|
|
|
1051
1051
|
const hasChecks = checks && checks.length > 0;
|
|
1052
1052
|
if (hasChecks) {
|
|
1053
1053
|
const existingShape = schema._zod.def.shape;
|
|
1054
|
-
for (const
|
|
1055
|
-
if (Object.getOwnPropertyDescriptor(existingShape,
|
|
1054
|
+
for (const key3 in shape) {
|
|
1055
|
+
if (Object.getOwnPropertyDescriptor(existingShape, key3) !== void 0) {
|
|
1056
1056
|
throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
|
|
1057
1057
|
}
|
|
1058
1058
|
}
|
|
@@ -1108,23 +1108,23 @@ function partial(Class2, schema, mask) {
|
|
|
1108
1108
|
const oldShape = schema._zod.def.shape;
|
|
1109
1109
|
const shape = { ...oldShape };
|
|
1110
1110
|
if (mask) {
|
|
1111
|
-
for (const
|
|
1112
|
-
if (!(
|
|
1113
|
-
throw new Error(`Unrecognized key: "${
|
|
1111
|
+
for (const key3 in mask) {
|
|
1112
|
+
if (!(key3 in oldShape)) {
|
|
1113
|
+
throw new Error(`Unrecognized key: "${key3}"`);
|
|
1114
1114
|
}
|
|
1115
|
-
if (!mask[
|
|
1115
|
+
if (!mask[key3])
|
|
1116
1116
|
continue;
|
|
1117
|
-
shape[
|
|
1117
|
+
shape[key3] = Class2 ? new Class2({
|
|
1118
1118
|
type: "optional",
|
|
1119
|
-
innerType: oldShape[
|
|
1120
|
-
}) : oldShape[
|
|
1119
|
+
innerType: oldShape[key3]
|
|
1120
|
+
}) : oldShape[key3];
|
|
1121
1121
|
}
|
|
1122
1122
|
} else {
|
|
1123
|
-
for (const
|
|
1124
|
-
shape[
|
|
1123
|
+
for (const key3 in oldShape) {
|
|
1124
|
+
shape[key3] = Class2 ? new Class2({
|
|
1125
1125
|
type: "optional",
|
|
1126
|
-
innerType: oldShape[
|
|
1127
|
-
}) : oldShape[
|
|
1126
|
+
innerType: oldShape[key3]
|
|
1127
|
+
}) : oldShape[key3];
|
|
1128
1128
|
}
|
|
1129
1129
|
}
|
|
1130
1130
|
assignProp(this, "shape", shape);
|
|
@@ -1140,22 +1140,22 @@ function required(Class2, schema, mask) {
|
|
|
1140
1140
|
const oldShape = schema._zod.def.shape;
|
|
1141
1141
|
const shape = { ...oldShape };
|
|
1142
1142
|
if (mask) {
|
|
1143
|
-
for (const
|
|
1144
|
-
if (!(
|
|
1145
|
-
throw new Error(`Unrecognized key: "${
|
|
1143
|
+
for (const key3 in mask) {
|
|
1144
|
+
if (!(key3 in shape)) {
|
|
1145
|
+
throw new Error(`Unrecognized key: "${key3}"`);
|
|
1146
1146
|
}
|
|
1147
|
-
if (!mask[
|
|
1147
|
+
if (!mask[key3])
|
|
1148
1148
|
continue;
|
|
1149
|
-
shape[
|
|
1149
|
+
shape[key3] = new Class2({
|
|
1150
1150
|
type: "nonoptional",
|
|
1151
|
-
innerType: oldShape[
|
|
1151
|
+
innerType: oldShape[key3]
|
|
1152
1152
|
});
|
|
1153
1153
|
}
|
|
1154
1154
|
} else {
|
|
1155
|
-
for (const
|
|
1156
|
-
shape[
|
|
1155
|
+
for (const key3 in oldShape) {
|
|
1156
|
+
shape[key3] = new Class2({
|
|
1157
1157
|
type: "nonoptional",
|
|
1158
|
-
innerType: oldShape[
|
|
1158
|
+
innerType: oldShape[key3]
|
|
1159
1159
|
});
|
|
1160
1160
|
}
|
|
1161
1161
|
}
|
|
@@ -2936,13 +2936,13 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
|
2936
2936
|
return payload;
|
|
2937
2937
|
};
|
|
2938
2938
|
});
|
|
2939
|
-
function handlePropertyResult(result, final,
|
|
2940
|
-
const isPresent =
|
|
2939
|
+
function handlePropertyResult(result, final, key3, input, isOptionalIn, isOptionalOut) {
|
|
2940
|
+
const isPresent = key3 in input;
|
|
2941
2941
|
if (result.issues.length) {
|
|
2942
2942
|
if (isOptionalIn && isOptionalOut && !isPresent) {
|
|
2943
2943
|
return;
|
|
2944
2944
|
}
|
|
2945
|
-
final.issues.push(...prefixIssues(
|
|
2945
|
+
final.issues.push(...prefixIssues(key3, result.issues));
|
|
2946
2946
|
}
|
|
2947
2947
|
if (!isPresent && !isOptionalIn) {
|
|
2948
2948
|
if (!result.issues.length) {
|
|
@@ -2950,17 +2950,17 @@ function handlePropertyResult(result, final, key2, input, isOptionalIn, isOption
|
|
|
2950
2950
|
code: "invalid_type",
|
|
2951
2951
|
expected: "nonoptional",
|
|
2952
2952
|
input: void 0,
|
|
2953
|
-
path: [
|
|
2953
|
+
path: [key3]
|
|
2954
2954
|
});
|
|
2955
2955
|
}
|
|
2956
2956
|
return;
|
|
2957
2957
|
}
|
|
2958
2958
|
if (result.value === void 0) {
|
|
2959
2959
|
if (isPresent) {
|
|
2960
|
-
final.value[
|
|
2960
|
+
final.value[key3] = void 0;
|
|
2961
2961
|
}
|
|
2962
2962
|
} else {
|
|
2963
|
-
final.value[
|
|
2963
|
+
final.value[key3] = result.value;
|
|
2964
2964
|
}
|
|
2965
2965
|
}
|
|
2966
2966
|
function normalizeDef(def) {
|
|
@@ -2986,20 +2986,20 @@ function handleCatchall(proms, input, payload, ctx, def, inst) {
|
|
|
2986
2986
|
const t = _catchall.def.type;
|
|
2987
2987
|
const isOptionalIn = _catchall.optin === "optional";
|
|
2988
2988
|
const isOptionalOut = _catchall.optout === "optional";
|
|
2989
|
-
for (const
|
|
2990
|
-
if (
|
|
2989
|
+
for (const key3 in input) {
|
|
2990
|
+
if (key3 === "__proto__")
|
|
2991
2991
|
continue;
|
|
2992
|
-
if (keySet.has(
|
|
2992
|
+
if (keySet.has(key3))
|
|
2993
2993
|
continue;
|
|
2994
2994
|
if (t === "never") {
|
|
2995
|
-
unrecognized.push(
|
|
2995
|
+
unrecognized.push(key3);
|
|
2996
2996
|
continue;
|
|
2997
2997
|
}
|
|
2998
|
-
const r = _catchall.run({ value: input[
|
|
2998
|
+
const r = _catchall.run({ value: input[key3], issues: [] }, ctx);
|
|
2999
2999
|
if (r instanceof Promise) {
|
|
3000
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload,
|
|
3000
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key3, input, isOptionalIn, isOptionalOut)));
|
|
3001
3001
|
} else {
|
|
3002
|
-
handlePropertyResult(r, payload,
|
|
3002
|
+
handlePropertyResult(r, payload, key3, input, isOptionalIn, isOptionalOut);
|
|
3003
3003
|
}
|
|
3004
3004
|
}
|
|
3005
3005
|
if (unrecognized.length) {
|
|
@@ -3035,12 +3035,12 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3035
3035
|
defineLazy(inst._zod, "propValues", () => {
|
|
3036
3036
|
const shape = def.shape;
|
|
3037
3037
|
const propValues = {};
|
|
3038
|
-
for (const
|
|
3039
|
-
const field = shape[
|
|
3038
|
+
for (const key3 in shape) {
|
|
3039
|
+
const field = shape[key3]._zod;
|
|
3040
3040
|
if (field.values) {
|
|
3041
|
-
propValues[
|
|
3041
|
+
propValues[key3] ?? (propValues[key3] = /* @__PURE__ */ new Set());
|
|
3042
3042
|
for (const v of field.values)
|
|
3043
|
-
propValues[
|
|
3043
|
+
propValues[key3].add(v);
|
|
3044
3044
|
}
|
|
3045
3045
|
}
|
|
3046
3046
|
return propValues;
|
|
@@ -3063,15 +3063,15 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3063
3063
|
payload.value = {};
|
|
3064
3064
|
const proms = [];
|
|
3065
3065
|
const shape = value.shape;
|
|
3066
|
-
for (const
|
|
3067
|
-
const el = shape[
|
|
3066
|
+
for (const key3 of value.keys) {
|
|
3067
|
+
const el = shape[key3];
|
|
3068
3068
|
const isOptionalIn = el._zod.optin === "optional";
|
|
3069
3069
|
const isOptionalOut = el._zod.optout === "optional";
|
|
3070
|
-
const r = el._zod.run({ value: input[
|
|
3070
|
+
const r = el._zod.run({ value: input[key3], issues: [] }, ctx);
|
|
3071
3071
|
if (r instanceof Promise) {
|
|
3072
|
-
proms.push(r.then((r2) => handlePropertyResult(r2, payload,
|
|
3072
|
+
proms.push(r.then((r2) => handlePropertyResult(r2, payload, key3, input, isOptionalIn, isOptionalOut)));
|
|
3073
3073
|
} else {
|
|
3074
|
-
handlePropertyResult(r, payload,
|
|
3074
|
+
handlePropertyResult(r, payload, key3, input, isOptionalIn, isOptionalOut);
|
|
3075
3075
|
}
|
|
3076
3076
|
}
|
|
3077
3077
|
if (!catchall) {
|
|
@@ -3087,24 +3087,24 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
3087
3087
|
const generateFastpass = (shape) => {
|
|
3088
3088
|
const doc = new Doc(["shape", "payload", "ctx"]);
|
|
3089
3089
|
const normalized = _normalized.value;
|
|
3090
|
-
const parseStr = (
|
|
3091
|
-
const k = esc(
|
|
3090
|
+
const parseStr = (key3) => {
|
|
3091
|
+
const k = esc(key3);
|
|
3092
3092
|
return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
3093
3093
|
};
|
|
3094
3094
|
doc.write(`const input = payload.value;`);
|
|
3095
3095
|
const ids = /* @__PURE__ */ Object.create(null);
|
|
3096
3096
|
let counter = 0;
|
|
3097
|
-
for (const
|
|
3098
|
-
ids[
|
|
3097
|
+
for (const key3 of normalized.keys) {
|
|
3098
|
+
ids[key3] = `key_${counter++}`;
|
|
3099
3099
|
}
|
|
3100
3100
|
doc.write(`const newResult = {};`);
|
|
3101
|
-
for (const
|
|
3102
|
-
const id = ids[
|
|
3103
|
-
const k = esc(
|
|
3104
|
-
const schema = shape[
|
|
3101
|
+
for (const key3 of normalized.keys) {
|
|
3102
|
+
const id = ids[key3];
|
|
3103
|
+
const k = esc(key3);
|
|
3104
|
+
const schema = shape[key3];
|
|
3105
3105
|
const isOptionalIn = schema?._zod?.optin === "optional";
|
|
3106
3106
|
const isOptionalOut = schema?._zod?.optout === "optional";
|
|
3107
|
-
doc.write(`const ${id} = ${parseStr(
|
|
3107
|
+
doc.write(`const ${id} = ${parseStr(key3)};`);
|
|
3108
3108
|
if (isOptionalIn && isOptionalOut) {
|
|
3109
3109
|
doc.write(`
|
|
3110
3110
|
if (${id}.issues.length) {
|
|
@@ -3416,17 +3416,17 @@ function mergeValues(a, b) {
|
|
|
3416
3416
|
}
|
|
3417
3417
|
if (isPlainObject(a) && isPlainObject(b)) {
|
|
3418
3418
|
const bKeys = Object.keys(b);
|
|
3419
|
-
const sharedKeys = Object.keys(a).filter((
|
|
3419
|
+
const sharedKeys = Object.keys(a).filter((key3) => bKeys.indexOf(key3) !== -1);
|
|
3420
3420
|
const newObj = { ...a, ...b };
|
|
3421
|
-
for (const
|
|
3422
|
-
const sharedValue = mergeValues(a[
|
|
3421
|
+
for (const key3 of sharedKeys) {
|
|
3422
|
+
const sharedValue = mergeValues(a[key3], b[key3]);
|
|
3423
3423
|
if (!sharedValue.valid) {
|
|
3424
3424
|
return {
|
|
3425
3425
|
valid: false,
|
|
3426
|
-
mergeErrorPath: [
|
|
3426
|
+
mergeErrorPath: [key3, ...sharedValue.mergeErrorPath]
|
|
3427
3427
|
};
|
|
3428
3428
|
}
|
|
3429
|
-
newObj[
|
|
3429
|
+
newObj[key3] = sharedValue.data;
|
|
3430
3430
|
}
|
|
3431
3431
|
return { valid: true, data: newObj };
|
|
3432
3432
|
}
|
|
@@ -3561,9 +3561,9 @@ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
|
|
|
3561
3561
|
return handleTupleResults(itemResults, payload, items, input, optoutStart);
|
|
3562
3562
|
};
|
|
3563
3563
|
});
|
|
3564
|
-
function getTupleOptStart(items,
|
|
3564
|
+
function getTupleOptStart(items, key3) {
|
|
3565
3565
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
3566
|
-
if (items[i]._zod[
|
|
3566
|
+
if (items[i]._zod[key3] !== "optional")
|
|
3567
3567
|
return i + 1;
|
|
3568
3568
|
}
|
|
3569
3569
|
return 0;
|
|
@@ -3614,10 +3614,10 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
3614
3614
|
if (values) {
|
|
3615
3615
|
payload.value = {};
|
|
3616
3616
|
const recordKeys = /* @__PURE__ */ new Set();
|
|
3617
|
-
for (const
|
|
3618
|
-
if (typeof
|
|
3619
|
-
recordKeys.add(typeof
|
|
3620
|
-
const keyResult = def.keyType._zod.run({ value:
|
|
3617
|
+
for (const key3 of values) {
|
|
3618
|
+
if (typeof key3 === "string" || typeof key3 === "number" || typeof key3 === "symbol") {
|
|
3619
|
+
recordKeys.add(typeof key3 === "number" ? key3.toString() : key3);
|
|
3620
|
+
const keyResult = def.keyType._zod.run({ value: key3, issues: [] }, ctx);
|
|
3621
3621
|
if (keyResult instanceof Promise) {
|
|
3622
3622
|
throw new Error("Async schemas not supported in object keys currently");
|
|
3623
3623
|
}
|
|
@@ -3626,34 +3626,34 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
3626
3626
|
code: "invalid_key",
|
|
3627
3627
|
origin: "record",
|
|
3628
3628
|
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
3629
|
-
input:
|
|
3630
|
-
path: [
|
|
3629
|
+
input: key3,
|
|
3630
|
+
path: [key3],
|
|
3631
3631
|
inst
|
|
3632
3632
|
});
|
|
3633
3633
|
continue;
|
|
3634
3634
|
}
|
|
3635
3635
|
const outKey = keyResult.value;
|
|
3636
|
-
const result = def.valueType._zod.run({ value: input[
|
|
3636
|
+
const result = def.valueType._zod.run({ value: input[key3], issues: [] }, ctx);
|
|
3637
3637
|
if (result instanceof Promise) {
|
|
3638
3638
|
proms.push(result.then((result2) => {
|
|
3639
3639
|
if (result2.issues.length) {
|
|
3640
|
-
payload.issues.push(...prefixIssues(
|
|
3640
|
+
payload.issues.push(...prefixIssues(key3, result2.issues));
|
|
3641
3641
|
}
|
|
3642
3642
|
payload.value[outKey] = result2.value;
|
|
3643
3643
|
}));
|
|
3644
3644
|
} else {
|
|
3645
3645
|
if (result.issues.length) {
|
|
3646
|
-
payload.issues.push(...prefixIssues(
|
|
3646
|
+
payload.issues.push(...prefixIssues(key3, result.issues));
|
|
3647
3647
|
}
|
|
3648
3648
|
payload.value[outKey] = result.value;
|
|
3649
3649
|
}
|
|
3650
3650
|
}
|
|
3651
3651
|
}
|
|
3652
3652
|
let unrecognized;
|
|
3653
|
-
for (const
|
|
3654
|
-
if (!recordKeys.has(
|
|
3653
|
+
for (const key3 in input) {
|
|
3654
|
+
if (!recordKeys.has(key3)) {
|
|
3655
3655
|
unrecognized = unrecognized ?? [];
|
|
3656
|
-
unrecognized.push(
|
|
3656
|
+
unrecognized.push(key3);
|
|
3657
3657
|
}
|
|
3658
3658
|
}
|
|
3659
3659
|
if (unrecognized && unrecognized.length > 0) {
|
|
@@ -3666,18 +3666,18 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
3666
3666
|
}
|
|
3667
3667
|
} else {
|
|
3668
3668
|
payload.value = {};
|
|
3669
|
-
for (const
|
|
3670
|
-
if (
|
|
3669
|
+
for (const key3 of Reflect.ownKeys(input)) {
|
|
3670
|
+
if (key3 === "__proto__")
|
|
3671
3671
|
continue;
|
|
3672
|
-
if (!Object.prototype.propertyIsEnumerable.call(input,
|
|
3672
|
+
if (!Object.prototype.propertyIsEnumerable.call(input, key3))
|
|
3673
3673
|
continue;
|
|
3674
|
-
let keyResult = def.keyType._zod.run({ value:
|
|
3674
|
+
let keyResult = def.keyType._zod.run({ value: key3, issues: [] }, ctx);
|
|
3675
3675
|
if (keyResult instanceof Promise) {
|
|
3676
3676
|
throw new Error("Async schemas not supported in object keys currently");
|
|
3677
3677
|
}
|
|
3678
|
-
const checkNumericKey = typeof
|
|
3678
|
+
const checkNumericKey = typeof key3 === "string" && number.test(key3) && keyResult.issues.length;
|
|
3679
3679
|
if (checkNumericKey) {
|
|
3680
|
-
const retryResult = def.keyType._zod.run({ value: Number(
|
|
3680
|
+
const retryResult = def.keyType._zod.run({ value: Number(key3), issues: [] }, ctx);
|
|
3681
3681
|
if (retryResult instanceof Promise) {
|
|
3682
3682
|
throw new Error("Async schemas not supported in object keys currently");
|
|
3683
3683
|
}
|
|
@@ -3687,30 +3687,30 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
3687
3687
|
}
|
|
3688
3688
|
if (keyResult.issues.length) {
|
|
3689
3689
|
if (def.mode === "loose") {
|
|
3690
|
-
payload.value[
|
|
3690
|
+
payload.value[key3] = input[key3];
|
|
3691
3691
|
} else {
|
|
3692
3692
|
payload.issues.push({
|
|
3693
3693
|
code: "invalid_key",
|
|
3694
3694
|
origin: "record",
|
|
3695
3695
|
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
3696
|
-
input:
|
|
3697
|
-
path: [
|
|
3696
|
+
input: key3,
|
|
3697
|
+
path: [key3],
|
|
3698
3698
|
inst
|
|
3699
3699
|
});
|
|
3700
3700
|
}
|
|
3701
3701
|
continue;
|
|
3702
3702
|
}
|
|
3703
|
-
const result = def.valueType._zod.run({ value: input[
|
|
3703
|
+
const result = def.valueType._zod.run({ value: input[key3], issues: [] }, ctx);
|
|
3704
3704
|
if (result instanceof Promise) {
|
|
3705
3705
|
proms.push(result.then((result2) => {
|
|
3706
3706
|
if (result2.issues.length) {
|
|
3707
|
-
payload.issues.push(...prefixIssues(
|
|
3707
|
+
payload.issues.push(...prefixIssues(key3, result2.issues));
|
|
3708
3708
|
}
|
|
3709
3709
|
payload.value[keyResult.value] = result2.value;
|
|
3710
3710
|
}));
|
|
3711
3711
|
} else {
|
|
3712
3712
|
if (result.issues.length) {
|
|
3713
|
-
payload.issues.push(...prefixIssues(
|
|
3713
|
+
payload.issues.push(...prefixIssues(key3, result.issues));
|
|
3714
3714
|
}
|
|
3715
3715
|
payload.value[keyResult.value] = result.value;
|
|
3716
3716
|
}
|
|
@@ -3737,15 +3737,15 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
|
3737
3737
|
}
|
|
3738
3738
|
const proms = [];
|
|
3739
3739
|
payload.value = /* @__PURE__ */ new Map();
|
|
3740
|
-
for (const [
|
|
3741
|
-
const keyResult = def.keyType._zod.run({ value:
|
|
3740
|
+
for (const [key3, value] of input) {
|
|
3741
|
+
const keyResult = def.keyType._zod.run({ value: key3, issues: [] }, ctx);
|
|
3742
3742
|
const valueResult = def.valueType._zod.run({ value, issues: [] }, ctx);
|
|
3743
3743
|
if (keyResult instanceof Promise || valueResult instanceof Promise) {
|
|
3744
3744
|
proms.push(Promise.all([keyResult, valueResult]).then(([keyResult2, valueResult2]) => {
|
|
3745
|
-
handleMapResult(keyResult2, valueResult2, payload,
|
|
3745
|
+
handleMapResult(keyResult2, valueResult2, payload, key3, input, inst, ctx);
|
|
3746
3746
|
}));
|
|
3747
3747
|
} else {
|
|
3748
|
-
handleMapResult(keyResult, valueResult, payload,
|
|
3748
|
+
handleMapResult(keyResult, valueResult, payload, key3, input, inst, ctx);
|
|
3749
3749
|
}
|
|
3750
3750
|
}
|
|
3751
3751
|
if (proms.length)
|
|
@@ -3753,10 +3753,10 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
|
|
|
3753
3753
|
return payload;
|
|
3754
3754
|
};
|
|
3755
3755
|
});
|
|
3756
|
-
function handleMapResult(keyResult, valueResult, final,
|
|
3756
|
+
function handleMapResult(keyResult, valueResult, final, key3, input, inst, ctx) {
|
|
3757
3757
|
if (keyResult.issues.length) {
|
|
3758
|
-
if (propertyKeyTypes.has(typeof
|
|
3759
|
-
final.issues.push(...prefixIssues(
|
|
3758
|
+
if (propertyKeyTypes.has(typeof key3)) {
|
|
3759
|
+
final.issues.push(...prefixIssues(key3, keyResult.issues));
|
|
3760
3760
|
} else {
|
|
3761
3761
|
final.issues.push({
|
|
3762
3762
|
code: "invalid_key",
|
|
@@ -3768,15 +3768,15 @@ function handleMapResult(keyResult, valueResult, final, key2, input, inst, ctx)
|
|
|
3768
3768
|
}
|
|
3769
3769
|
}
|
|
3770
3770
|
if (valueResult.issues.length) {
|
|
3771
|
-
if (propertyKeyTypes.has(typeof
|
|
3772
|
-
final.issues.push(...prefixIssues(
|
|
3771
|
+
if (propertyKeyTypes.has(typeof key3)) {
|
|
3772
|
+
final.issues.push(...prefixIssues(key3, valueResult.issues));
|
|
3773
3773
|
} else {
|
|
3774
3774
|
final.issues.push({
|
|
3775
3775
|
origin: "map",
|
|
3776
3776
|
code: "invalid_element",
|
|
3777
3777
|
input,
|
|
3778
3778
|
inst,
|
|
3779
|
-
key:
|
|
3779
|
+
key: key3,
|
|
3780
3780
|
issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
|
|
3781
3781
|
});
|
|
3782
3782
|
}
|
|
@@ -11532,15 +11532,15 @@ function extractDefs(ctx, schema) {
|
|
|
11532
11532
|
return;
|
|
11533
11533
|
}
|
|
11534
11534
|
const seen = entry[1];
|
|
11535
|
-
const { ref, defId } = makeURI(entry);
|
|
11535
|
+
const { ref: ref2, defId } = makeURI(entry);
|
|
11536
11536
|
seen.def = { ...seen.schema };
|
|
11537
11537
|
if (defId)
|
|
11538
11538
|
seen.defId = defId;
|
|
11539
11539
|
const schema2 = seen.schema;
|
|
11540
|
-
for (const
|
|
11541
|
-
delete schema2[
|
|
11540
|
+
for (const key3 in schema2) {
|
|
11541
|
+
delete schema2[key3];
|
|
11542
11542
|
}
|
|
11543
|
-
schema2.$ref =
|
|
11543
|
+
schema2.$ref = ref2;
|
|
11544
11544
|
};
|
|
11545
11545
|
if (ctx.cycles === "throw") {
|
|
11546
11546
|
for (const entry of ctx.seen.entries()) {
|
|
@@ -11592,11 +11592,11 @@ function finalize(ctx, schema) {
|
|
|
11592
11592
|
return;
|
|
11593
11593
|
const schema2 = seen.def ?? seen.schema;
|
|
11594
11594
|
const _cached = { ...schema2 };
|
|
11595
|
-
const
|
|
11595
|
+
const ref2 = seen.ref;
|
|
11596
11596
|
seen.ref = null;
|
|
11597
|
-
if (
|
|
11598
|
-
flattenRef(
|
|
11599
|
-
const refSeen = ctx.seen.get(
|
|
11597
|
+
if (ref2) {
|
|
11598
|
+
flattenRef(ref2);
|
|
11599
|
+
const refSeen = ctx.seen.get(ref2);
|
|
11600
11600
|
const refSchema = refSeen.schema;
|
|
11601
11601
|
if (refSchema.$ref && (ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0")) {
|
|
11602
11602
|
schema2.allOf = schema2.allOf ?? [];
|
|
@@ -11605,38 +11605,38 @@ function finalize(ctx, schema) {
|
|
|
11605
11605
|
Object.assign(schema2, refSchema);
|
|
11606
11606
|
}
|
|
11607
11607
|
Object.assign(schema2, _cached);
|
|
11608
|
-
const isParentRef = zodSchema._zod.parent ===
|
|
11608
|
+
const isParentRef = zodSchema._zod.parent === ref2;
|
|
11609
11609
|
if (isParentRef) {
|
|
11610
|
-
for (const
|
|
11611
|
-
if (
|
|
11610
|
+
for (const key3 in schema2) {
|
|
11611
|
+
if (key3 === "$ref" || key3 === "allOf")
|
|
11612
11612
|
continue;
|
|
11613
|
-
if (!(
|
|
11614
|
-
delete schema2[
|
|
11613
|
+
if (!(key3 in _cached)) {
|
|
11614
|
+
delete schema2[key3];
|
|
11615
11615
|
}
|
|
11616
11616
|
}
|
|
11617
11617
|
}
|
|
11618
11618
|
if (refSchema.$ref && refSeen.def) {
|
|
11619
|
-
for (const
|
|
11620
|
-
if (
|
|
11619
|
+
for (const key3 in schema2) {
|
|
11620
|
+
if (key3 === "$ref" || key3 === "allOf")
|
|
11621
11621
|
continue;
|
|
11622
|
-
if (
|
|
11623
|
-
delete schema2[
|
|
11622
|
+
if (key3 in refSeen.def && JSON.stringify(schema2[key3]) === JSON.stringify(refSeen.def[key3])) {
|
|
11623
|
+
delete schema2[key3];
|
|
11624
11624
|
}
|
|
11625
11625
|
}
|
|
11626
11626
|
}
|
|
11627
11627
|
}
|
|
11628
11628
|
const parent = zodSchema._zod.parent;
|
|
11629
|
-
if (parent && parent !==
|
|
11629
|
+
if (parent && parent !== ref2) {
|
|
11630
11630
|
flattenRef(parent);
|
|
11631
11631
|
const parentSeen = ctx.seen.get(parent);
|
|
11632
11632
|
if (parentSeen?.schema.$ref) {
|
|
11633
11633
|
schema2.$ref = parentSeen.schema.$ref;
|
|
11634
11634
|
if (parentSeen.def) {
|
|
11635
|
-
for (const
|
|
11636
|
-
if (
|
|
11635
|
+
for (const key3 in schema2) {
|
|
11636
|
+
if (key3 === "$ref" || key3 === "allOf")
|
|
11637
11637
|
continue;
|
|
11638
|
-
if (
|
|
11639
|
-
delete schema2[
|
|
11638
|
+
if (key3 in parentSeen.def && JSON.stringify(schema2[key3]) === JSON.stringify(parentSeen.def[key3])) {
|
|
11639
|
+
delete schema2[key3];
|
|
11640
11640
|
}
|
|
11641
11641
|
}
|
|
11642
11642
|
}
|
|
@@ -11737,8 +11737,8 @@ function isTransforming(_schema, _ctx) {
|
|
|
11737
11737
|
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
11738
11738
|
}
|
|
11739
11739
|
if (def.type === "object") {
|
|
11740
|
-
for (const
|
|
11741
|
-
if (isTransforming(def.shape[
|
|
11740
|
+
for (const key3 in def.shape) {
|
|
11741
|
+
if (isTransforming(def.shape[key3], ctx))
|
|
11742
11742
|
return true;
|
|
11743
11743
|
}
|
|
11744
11744
|
return false;
|
|
@@ -12027,15 +12027,15 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
12027
12027
|
json2.type = "object";
|
|
12028
12028
|
json2.properties = {};
|
|
12029
12029
|
const shape = def.shape;
|
|
12030
|
-
for (const
|
|
12031
|
-
json2.properties[
|
|
12030
|
+
for (const key3 in shape) {
|
|
12031
|
+
json2.properties[key3] = process2(shape[key3], ctx, {
|
|
12032
12032
|
...params,
|
|
12033
|
-
path: [...params.path, "properties",
|
|
12033
|
+
path: [...params.path, "properties", key3]
|
|
12034
12034
|
});
|
|
12035
12035
|
}
|
|
12036
12036
|
const allKeys = new Set(Object.keys(shape));
|
|
12037
|
-
const requiredKeys = new Set([...allKeys].filter((
|
|
12038
|
-
const v = def.shape[
|
|
12037
|
+
const requiredKeys = new Set([...allKeys].filter((key3) => {
|
|
12038
|
+
const v = def.shape[key3]._zod;
|
|
12039
12039
|
if (ctx.io === "input") {
|
|
12040
12040
|
return v.optin === void 0;
|
|
12041
12041
|
} else {
|
|
@@ -12301,9 +12301,9 @@ function toJSONSchema(input, params) {
|
|
|
12301
12301
|
};
|
|
12302
12302
|
ctx2.external = external;
|
|
12303
12303
|
for (const entry of registry2._idmap.entries()) {
|
|
12304
|
-
const [
|
|
12304
|
+
const [key3, schema] = entry;
|
|
12305
12305
|
extractDefs(ctx2, schema);
|
|
12306
|
-
schemas[
|
|
12306
|
+
schemas[key3] = finalize(ctx2, schema);
|
|
12307
12307
|
}
|
|
12308
12308
|
if (Object.keys(defs).length > 0) {
|
|
12309
12309
|
const defsSegment = ctx2.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
@@ -12709,14 +12709,14 @@ function _installLazyMethods(inst, group, methods) {
|
|
|
12709
12709
|
if (installed.has(group))
|
|
12710
12710
|
return;
|
|
12711
12711
|
installed.add(group);
|
|
12712
|
-
for (const
|
|
12713
|
-
const fn = methods[
|
|
12714
|
-
Object.defineProperty(proto,
|
|
12712
|
+
for (const key3 in methods) {
|
|
12713
|
+
const fn = methods[key3];
|
|
12714
|
+
Object.defineProperty(proto, key3, {
|
|
12715
12715
|
configurable: true,
|
|
12716
12716
|
enumerable: false,
|
|
12717
12717
|
get() {
|
|
12718
12718
|
const bound = fn.bind(this);
|
|
12719
|
-
Object.defineProperty(this,
|
|
12719
|
+
Object.defineProperty(this, key3, {
|
|
12720
12720
|
configurable: true,
|
|
12721
12721
|
writable: true,
|
|
12722
12722
|
enumerable: true,
|
|
@@ -12725,7 +12725,7 @@ function _installLazyMethods(inst, group, methods) {
|
|
|
12725
12725
|
return bound;
|
|
12726
12726
|
},
|
|
12727
12727
|
set(v) {
|
|
12728
|
-
Object.defineProperty(this,
|
|
12728
|
+
Object.defineProperty(this, key3, {
|
|
12729
12729
|
configurable: true,
|
|
12730
12730
|
writable: true,
|
|
12731
12731
|
enumerable: true,
|
|
@@ -14103,23 +14103,23 @@ function detectVersion(schema, defaultTarget) {
|
|
|
14103
14103
|
}
|
|
14104
14104
|
return defaultTarget ?? "draft-2020-12";
|
|
14105
14105
|
}
|
|
14106
|
-
function resolveRef(
|
|
14107
|
-
if (!
|
|
14106
|
+
function resolveRef(ref2, ctx) {
|
|
14107
|
+
if (!ref2.startsWith("#")) {
|
|
14108
14108
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14109
14109
|
}
|
|
14110
|
-
const path8 =
|
|
14110
|
+
const path8 = ref2.slice(1).split("/").filter(Boolean);
|
|
14111
14111
|
if (path8.length === 0) {
|
|
14112
14112
|
return ctx.rootSchema;
|
|
14113
14113
|
}
|
|
14114
14114
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14115
14115
|
if (path8[0] === defsKey) {
|
|
14116
|
-
const
|
|
14117
|
-
if (!
|
|
14118
|
-
throw new Error(`Reference not found: ${
|
|
14116
|
+
const key3 = path8[1];
|
|
14117
|
+
if (!key3 || !ctx.defs[key3]) {
|
|
14118
|
+
throw new Error(`Reference not found: ${ref2}`);
|
|
14119
14119
|
}
|
|
14120
|
-
return ctx.defs[
|
|
14120
|
+
return ctx.defs[key3];
|
|
14121
14121
|
}
|
|
14122
|
-
throw new Error(`Reference not found: ${
|
|
14122
|
+
throw new Error(`Reference not found: ${ref2}`);
|
|
14123
14123
|
}
|
|
14124
14124
|
function convertBaseSchema(schema, ctx) {
|
|
14125
14125
|
if (schema.not !== void 0) {
|
|
@@ -14303,9 +14303,9 @@ function convertBaseSchema(schema, ctx) {
|
|
|
14303
14303
|
const shape = {};
|
|
14304
14304
|
const properties = schema.properties || {};
|
|
14305
14305
|
const requiredSet = new Set(schema.required || []);
|
|
14306
|
-
for (const [
|
|
14306
|
+
for (const [key3, propSchema] of Object.entries(properties)) {
|
|
14307
14307
|
const propZodSchema = convertSchema(propSchema, ctx);
|
|
14308
|
-
shape[
|
|
14308
|
+
shape[key3] = requiredSet.has(key3) ? propZodSchema : propZodSchema.optional();
|
|
14309
14309
|
}
|
|
14310
14310
|
if (schema.propertyNames) {
|
|
14311
14311
|
const keySchema = convertSchema(schema.propertyNames, ctx);
|
|
@@ -14446,20 +14446,20 @@ function convertSchema(schema, ctx) {
|
|
|
14446
14446
|
}
|
|
14447
14447
|
const extraMeta = {};
|
|
14448
14448
|
const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
|
|
14449
|
-
for (const
|
|
14450
|
-
if (
|
|
14451
|
-
extraMeta[
|
|
14449
|
+
for (const key3 of coreMetadataKeys) {
|
|
14450
|
+
if (key3 in schema) {
|
|
14451
|
+
extraMeta[key3] = schema[key3];
|
|
14452
14452
|
}
|
|
14453
14453
|
}
|
|
14454
14454
|
const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
|
|
14455
|
-
for (const
|
|
14456
|
-
if (
|
|
14457
|
-
extraMeta[
|
|
14455
|
+
for (const key3 of contentMetadataKeys) {
|
|
14456
|
+
if (key3 in schema) {
|
|
14457
|
+
extraMeta[key3] = schema[key3];
|
|
14458
14458
|
}
|
|
14459
14459
|
}
|
|
14460
|
-
for (const
|
|
14461
|
-
if (!RECOGNIZED_KEYS.has(
|
|
14462
|
-
extraMeta[
|
|
14460
|
+
for (const key3 of Object.keys(schema)) {
|
|
14461
|
+
if (!RECOGNIZED_KEYS.has(key3)) {
|
|
14462
|
+
extraMeta[key3] = schema[key3];
|
|
14463
14463
|
}
|
|
14464
14464
|
}
|
|
14465
14465
|
if (Object.keys(extraMeta).length > 0) {
|
|
@@ -15164,29 +15164,29 @@ function parseMapping(lines, startIdx, indent) {
|
|
|
15164
15164
|
i++;
|
|
15165
15165
|
continue;
|
|
15166
15166
|
}
|
|
15167
|
-
const
|
|
15168
|
-
if (
|
|
15167
|
+
const key3 = stripKeyQuotes(line.text.slice(0, colon).trim());
|
|
15168
|
+
if (key3 === "") {
|
|
15169
15169
|
i++;
|
|
15170
15170
|
continue;
|
|
15171
15171
|
}
|
|
15172
15172
|
const rest = line.text.slice(colon + 1).trim();
|
|
15173
15173
|
if (rest !== "") {
|
|
15174
|
-
out[
|
|
15174
|
+
out[key3] = parseFlowValue(rest);
|
|
15175
15175
|
i++;
|
|
15176
15176
|
} else {
|
|
15177
15177
|
const childIndent = lines[i + 1]?.indent ?? line.indent + 1;
|
|
15178
15178
|
let j = i + 1;
|
|
15179
15179
|
while (j < lines.length && (lines[j]?.indent ?? -1) >= childIndent) j++;
|
|
15180
15180
|
if (j === i + 1) {
|
|
15181
|
-
out[
|
|
15181
|
+
out[key3] = null;
|
|
15182
15182
|
i++;
|
|
15183
15183
|
} else {
|
|
15184
15184
|
const childBlock = lines.slice(i + 1, j);
|
|
15185
15185
|
const firstChild = childBlock[0];
|
|
15186
15186
|
if (firstChild?.text.trimStart().startsWith("- ")) {
|
|
15187
|
-
out[
|
|
15187
|
+
out[key3] = parseSequence(childBlock, childIndent);
|
|
15188
15188
|
} else {
|
|
15189
|
-
out[
|
|
15189
|
+
out[key3] = parseMapping(childBlock, 0, childIndent).value;
|
|
15190
15190
|
}
|
|
15191
15191
|
i = j;
|
|
15192
15192
|
}
|
|
@@ -15298,24 +15298,24 @@ function setFrontmatterOptions(content, options) {
|
|
|
15298
15298
|
for (let i = 0; i < lines.length; i++) {
|
|
15299
15299
|
const m = /^([A-Za-z0-9_-]+):[ \t]*(.*)$/.exec(lines[i] ?? "");
|
|
15300
15300
|
if (!m) continue;
|
|
15301
|
-
const
|
|
15302
|
-
if (!(
|
|
15303
|
-
handled.add(
|
|
15301
|
+
const key3 = m[1] ?? "";
|
|
15302
|
+
if (!(key3 in options)) continue;
|
|
15303
|
+
handled.add(key3);
|
|
15304
15304
|
let end = i + 1;
|
|
15305
15305
|
while (end < lines.length && /^[ \t]+/.test(lines[end] ?? "")) end++;
|
|
15306
|
-
const value = options[
|
|
15306
|
+
const value = options[key3];
|
|
15307
15307
|
if (value === null || value === void 0) {
|
|
15308
15308
|
lines.splice(i, end - i);
|
|
15309
15309
|
i--;
|
|
15310
15310
|
} else {
|
|
15311
|
-
lines.splice(i, end - i, `${
|
|
15311
|
+
lines.splice(i, end - i, `${key3}: ${serializeOptionValue(value)}`);
|
|
15312
15312
|
}
|
|
15313
15313
|
}
|
|
15314
15314
|
const appended = [];
|
|
15315
|
-
for (const [
|
|
15316
|
-
if (handled.has(
|
|
15315
|
+
for (const [key3, value] of Object.entries(options)) {
|
|
15316
|
+
if (handled.has(key3)) continue;
|
|
15317
15317
|
if (value === null || value === void 0) continue;
|
|
15318
|
-
appended.push(`${
|
|
15318
|
+
appended.push(`${key3}: ${serializeOptionValue(value)}`);
|
|
15319
15319
|
}
|
|
15320
15320
|
const nextBlock = appended.length > 0 ? lines.join(eol) + eol + appended.join(eol) : lines.join(eol);
|
|
15321
15321
|
if (nextBlock === block) return content;
|
|
@@ -15753,49 +15753,8 @@ async function captureStack(paths, name, options = {}) {
|
|
|
15753
15753
|
return { name, path: dest, agents: Object.keys(agents).length };
|
|
15754
15754
|
}
|
|
15755
15755
|
|
|
15756
|
-
// src/
|
|
15757
|
-
|
|
15758
|
-
var PIN_STORE_KEY = "quota-pins-v1";
|
|
15759
|
-
function createPinStore(storage) {
|
|
15760
|
-
let lane = Promise.resolve();
|
|
15761
|
-
let pending = 0;
|
|
15762
|
-
const read = async () => {
|
|
15763
|
-
const value = await storage.get(PIN_STORE_KEY);
|
|
15764
|
-
return new Set(value === void 0 ? [] : Pins.parse(value).sessionIDs);
|
|
15765
|
-
};
|
|
15766
|
-
const mutate = (sessionID, add, valid) => {
|
|
15767
|
-
if (pending >= 65) return Promise.reject(new Error("Session pin storage is busy; try again."));
|
|
15768
|
-
pending++;
|
|
15769
|
-
const operation = lane.then(async () => {
|
|
15770
|
-
const pins = await read();
|
|
15771
|
-
if (!valid()) throw new Error("Session pin operation was cancelled.");
|
|
15772
|
-
if (add) {
|
|
15773
|
-
if (!pins.has(sessionID) && pins.size >= 1024)
|
|
15774
|
-
throw new Error("Session pin capacity reached.");
|
|
15775
|
-
pins.add(sessionID);
|
|
15776
|
-
} else if (!pins.delete(sessionID)) return;
|
|
15777
|
-
await storage.set(PIN_STORE_KEY, { version: 1, sessionIDs: [...pins] });
|
|
15778
|
-
});
|
|
15779
|
-
lane = operation.then(
|
|
15780
|
-
() => {
|
|
15781
|
-
pending--;
|
|
15782
|
-
},
|
|
15783
|
-
() => {
|
|
15784
|
-
pending--;
|
|
15785
|
-
}
|
|
15786
|
-
);
|
|
15787
|
-
return operation;
|
|
15788
|
-
};
|
|
15789
|
-
return {
|
|
15790
|
-
async has(sessionID) {
|
|
15791
|
-
await lane;
|
|
15792
|
-
return (await read()).has(sessionID);
|
|
15793
|
-
},
|
|
15794
|
-
add: (sessionID, valid) => mutate(sessionID, true, valid),
|
|
15795
|
-
remove: (sessionID, valid = () => true) => mutate(sessionID, false, valid),
|
|
15796
|
-
drain: () => lane
|
|
15797
|
-
};
|
|
15798
|
-
}
|
|
15756
|
+
// src/quota-fallback-v2.ts
|
|
15757
|
+
import { createHash } from "crypto";
|
|
15799
15758
|
|
|
15800
15759
|
// src/core/quota-preflight.ts
|
|
15801
15760
|
import { Rpc } from "@opencode/plugin/rpc";
|
|
@@ -15876,12 +15835,301 @@ function createQuotaQuery(query, deadlineMs = 3e3, capacity = 16) {
|
|
|
15876
15835
|
};
|
|
15877
15836
|
}
|
|
15878
15837
|
|
|
15838
|
+
// src/quota-fallback-v2.ts
|
|
15839
|
+
var QuotaFallbackOptions = external_exports.object({
|
|
15840
|
+
enabled: external_exports.boolean().default(false),
|
|
15841
|
+
allowPaidFallbacks: external_exports.boolean().default(false),
|
|
15842
|
+
maxSwitches: external_exports.number().int().min(1).max(8).default(8)
|
|
15843
|
+
}).strict();
|
|
15844
|
+
var key = (m) => `${m.providerID}/${m.id}#${m.variant === "default" ? "" : m.variant ?? ""}`;
|
|
15845
|
+
var ref = (m) => ({
|
|
15846
|
+
...quotaCandidate(m),
|
|
15847
|
+
...m.variant && m.variant !== "default" ? { variant: m.variant } : {}
|
|
15848
|
+
});
|
|
15849
|
+
var TTL = 5e3;
|
|
15850
|
+
var clock = () => performance.now();
|
|
15851
|
+
var CAP = 1024;
|
|
15852
|
+
var digest = (text) => createHash("sha256").update(text).digest("hex");
|
|
15853
|
+
function createQuotaFallback(ctx, routes, admission, current, selected = () => {
|
|
15854
|
+
}) {
|
|
15855
|
+
const parsed = QuotaFallbackOptions.safeParse(ctx.options?.quotaFallback ?? {});
|
|
15856
|
+
if (!parsed.success || !parsed.data.enabled) return void 0;
|
|
15857
|
+
const options = parsed.data;
|
|
15858
|
+
const query = createQuotaQuery((input, request) => ctx.rpc(UsageQuota).query(input, request));
|
|
15859
|
+
const turns = /* @__PURE__ */ new Map();
|
|
15860
|
+
const observations = /* @__PURE__ */ new Map();
|
|
15861
|
+
const requests = /* @__PURE__ */ new WeakMap();
|
|
15862
|
+
const poisoned = /* @__PURE__ */ new Set();
|
|
15863
|
+
const busy = /* @__PURE__ */ new Set();
|
|
15864
|
+
const tickets = /* @__PURE__ */ new Map();
|
|
15865
|
+
const claiming = /* @__PURE__ */ new Map();
|
|
15866
|
+
let disposed = false;
|
|
15867
|
+
let saturated = false;
|
|
15868
|
+
let childSaturated = false;
|
|
15869
|
+
const poison = (id) => {
|
|
15870
|
+
if (poisoned.has(id) || poisoned.size < CAP) poisoned.add(id);
|
|
15871
|
+
else saturated = true;
|
|
15872
|
+
};
|
|
15873
|
+
const prune = () => {
|
|
15874
|
+
const cutoff = clock() - TTL;
|
|
15875
|
+
for (const [id, value] of observations) {
|
|
15876
|
+
if (value.at >= cutoff) continue;
|
|
15877
|
+
if (value.ambiguous || value.status === void 0 || value.status >= 400) poison(id);
|
|
15878
|
+
observations.delete(id);
|
|
15879
|
+
}
|
|
15880
|
+
for (const [id, value] of tickets) if (value.at < cutoff) tickets.delete(id);
|
|
15881
|
+
};
|
|
15882
|
+
const timer = setInterval(prune, TTL);
|
|
15883
|
+
timer.unref();
|
|
15884
|
+
const stop = (id) => {
|
|
15885
|
+
turns.delete(id);
|
|
15886
|
+
observations.delete(id);
|
|
15887
|
+
poisoned.delete(id);
|
|
15888
|
+
claiming.delete(id);
|
|
15889
|
+
};
|
|
15890
|
+
return {
|
|
15891
|
+
stop,
|
|
15892
|
+
admit(id, agent, model) {
|
|
15893
|
+
stop(id);
|
|
15894
|
+
if (turns.size < CAP)
|
|
15895
|
+
turns.set(id, { agent, model, switches: 0, selected: false, generation: 0 });
|
|
15896
|
+
},
|
|
15897
|
+
// Keep only a digest of the automatic admission, never prompt text.
|
|
15898
|
+
ticket(id, parent, agent, model, prompt) {
|
|
15899
|
+
prune();
|
|
15900
|
+
if (tickets.size < CAP)
|
|
15901
|
+
tickets.set(`${parent}/${id}`, {
|
|
15902
|
+
parent,
|
|
15903
|
+
agent,
|
|
15904
|
+
model,
|
|
15905
|
+
callID: id,
|
|
15906
|
+
promptHash: prompt === void 0 ? void 0 : digest(`You are a subagent spawned by another session.
|
|
15907
|
+
${prompt}`),
|
|
15908
|
+
at: clock()
|
|
15909
|
+
});
|
|
15910
|
+
else childSaturated = true;
|
|
15911
|
+
},
|
|
15912
|
+
async child(id, agent, model) {
|
|
15913
|
+
if (childSaturated || turns.has(id) || claiming.has(id) || claiming.size >= 64 || disposed || !current())
|
|
15914
|
+
return;
|
|
15915
|
+
prune();
|
|
15916
|
+
const claim = {};
|
|
15917
|
+
claiming.set(id, claim);
|
|
15918
|
+
try {
|
|
15919
|
+
const session = await ctx.session.get({ sessionID: id });
|
|
15920
|
+
if (!session.parentID || session.agent !== agent || !session.model || key(session.model) !== key(model))
|
|
15921
|
+
return;
|
|
15922
|
+
const candidates = [...tickets].filter(([, t]) => t.parent === session.parentID);
|
|
15923
|
+
if (candidates.length !== 1 || await admission.isPinned(id)) return;
|
|
15924
|
+
const messages = await ctx.session.context({ sessionID: session.parentID });
|
|
15925
|
+
const calls = messages.flatMap((m) => "content" in m ? m.content : []);
|
|
15926
|
+
const childMessages = await ctx.session.context({ sessionID: id });
|
|
15927
|
+
const users = childMessages.filter((m) => m.type === "user");
|
|
15928
|
+
const user = users.length === 1 ? users[0] : void 0;
|
|
15929
|
+
if (!user) return;
|
|
15930
|
+
const matched = candidates.filter(
|
|
15931
|
+
([, t]) => t.agent === agent && t.promptHash && digest(user.text) === t.promptHash && // Positive native association beats a matching automatic prompt fingerprint.
|
|
15932
|
+
!calls.some(
|
|
15933
|
+
(call) => call.name === "subagent" && call.id !== t.callID && call.state?.metadata?.sessionID === id
|
|
15934
|
+
) && calls.some(
|
|
15935
|
+
(call) => call.id === t.callID && call.name === "subagent" && call.state?.status === "running" && (!call.state.metadata?.sessionID || call.state.metadata.sessionID === id)
|
|
15936
|
+
) && (!t.model || t.model === `${model.providerID}/${model.id}${model.variant && model.variant !== "default" ? `#${model.variant}` : ""}`)
|
|
15937
|
+
);
|
|
15938
|
+
const match = matched.length === 1 ? matched[0] : void 0;
|
|
15939
|
+
if (!match) return;
|
|
15940
|
+
const latest = await ctx.session.get({ sessionID: id });
|
|
15941
|
+
if (disposed || childSaturated || !current() || claiming.get(id) !== claim || latest.agent !== agent || !latest.model || key(latest.model) !== key(model) || await admission.isPinned(id) || claiming.get(id) !== claim || childSaturated || clock() - match[1].at > TTL)
|
|
15942
|
+
return;
|
|
15943
|
+
tickets.delete(match[0]);
|
|
15944
|
+
if (admission.claim(id, agent, model) && turns.size < CAP) {
|
|
15945
|
+
turns.set(id, { agent, model, switches: 0, selected: false, generation: 0 });
|
|
15946
|
+
selected(id, agent, model, user.id);
|
|
15947
|
+
}
|
|
15948
|
+
} finally {
|
|
15949
|
+
if (claiming.get(id) === claim) claiming.delete(id);
|
|
15950
|
+
}
|
|
15951
|
+
},
|
|
15952
|
+
model(event) {
|
|
15953
|
+
prune();
|
|
15954
|
+
const turn = turns.get(event.sessionID);
|
|
15955
|
+
if (turn) turn.generation++;
|
|
15956
|
+
const previous = observations.get(event.sessionID);
|
|
15957
|
+
if (!previous && observations.size >= CAP) {
|
|
15958
|
+
poison(event.sessionID);
|
|
15959
|
+
return;
|
|
15960
|
+
}
|
|
15961
|
+
if (event.kind !== "primary" || previous?.ambiguous || previous && (previous.status === void 0 || previous.status >= 400)) {
|
|
15962
|
+
poison(event.sessionID);
|
|
15963
|
+
}
|
|
15964
|
+
const observed = {
|
|
15965
|
+
model: key(event.model),
|
|
15966
|
+
agent: event.agent,
|
|
15967
|
+
kind: event.kind,
|
|
15968
|
+
at: clock(),
|
|
15969
|
+
ambiguous: event.kind !== "primary" || poisoned.has(event.sessionID)
|
|
15970
|
+
};
|
|
15971
|
+
try {
|
|
15972
|
+
const url2 = new URL(event.baseURL ?? "");
|
|
15973
|
+
if (!["http:", "https:"].includes(url2.protocol) || url2.username || url2.password || url2.search || url2.hash)
|
|
15974
|
+
observed.ambiguous = true;
|
|
15975
|
+
else {
|
|
15976
|
+
observed.origin = url2.origin;
|
|
15977
|
+
const base = url2.pathname.replace(/\/$/, "");
|
|
15978
|
+
observed.paths = ["/chat/completions", "/responses", "/messages"].map((p) => base + p);
|
|
15979
|
+
}
|
|
15980
|
+
} catch {
|
|
15981
|
+
observed.ambiguous = true;
|
|
15982
|
+
}
|
|
15983
|
+
observations.set(event.sessionID, observed);
|
|
15984
|
+
},
|
|
15985
|
+
request(event) {
|
|
15986
|
+
prune();
|
|
15987
|
+
const observed = observations.get(event.sessionID);
|
|
15988
|
+
if (!observed) return;
|
|
15989
|
+
const url2 = new URL(event.request.url);
|
|
15990
|
+
if (observed.sent || observed.model !== key(event.model) || observed.agent !== event.agent || observed.kind !== event.kind || url2.username || url2.password || url2.search || url2.hash || url2.origin !== observed.origin || !observed.paths?.includes(url2.pathname))
|
|
15991
|
+
observed.ambiguous = true;
|
|
15992
|
+
observed.sent = true;
|
|
15993
|
+
requests.set(event.request, observed);
|
|
15994
|
+
const turn = turns.get(event.sessionID);
|
|
15995
|
+
if (turn?.selected && event.kind === "primary" && key(turn.model) === key(event.model)) {
|
|
15996
|
+
turn.selected = false;
|
|
15997
|
+
admission.reason(event.sessionID, "quota_fallback_attempt_dispatched", event.model);
|
|
15998
|
+
}
|
|
15999
|
+
},
|
|
16000
|
+
response(event) {
|
|
16001
|
+
const observed = observations.get(event.sessionID);
|
|
16002
|
+
if (!observed) return;
|
|
16003
|
+
if (requests.get(event.request) !== observed || observed.model !== key(event.model) || observed.agent !== event.agent || observed.kind !== event.kind)
|
|
16004
|
+
observed.ambiguous = true;
|
|
16005
|
+
else observed.status = event.response.status;
|
|
16006
|
+
},
|
|
16007
|
+
unsupported(id) {
|
|
16008
|
+
const observed = observations.get(id);
|
|
16009
|
+
poison(id);
|
|
16010
|
+
if (observed) observed.ambiguous = true;
|
|
16011
|
+
},
|
|
16012
|
+
async retry(event) {
|
|
16013
|
+
const id = event.sessionID;
|
|
16014
|
+
prune();
|
|
16015
|
+
const observed = observations.get(id);
|
|
16016
|
+
if (observed && (observed.ambiguous || observed.status === void 0)) poison(id);
|
|
16017
|
+
observations.delete(id);
|
|
16018
|
+
const turn = turns.get(id);
|
|
16019
|
+
const generation = turn?.generation;
|
|
16020
|
+
const live = () => !disposed && current() && turns.get(id) === turn && turn?.generation === generation && !!observed && clock() - observed.at <= TTL;
|
|
16021
|
+
if (disposed || saturated || !current() || busy.has(id) || busy.size >= 64 || !turn || !observed || observed.ambiguous || poisoned.has(id) || observed.kind !== "primary" || observed.agent !== event.agent || observed.model !== key(event.model) || turn.agent !== event.agent || key(turn.model) !== key(event.model) || event.error.type !== "provider.quota" || ![402, 429].includes(observed.status ?? 0) || event.error.status !== observed.status)
|
|
16022
|
+
return false;
|
|
16023
|
+
if (!options.allowPaidFallbacks || turn.switches >= options.maxSwitches) return true;
|
|
16024
|
+
const route = routes[turn.agent];
|
|
16025
|
+
if (!route) return true;
|
|
16026
|
+
const chain = [route, ...route.fallbacks ?? []].map(ref);
|
|
16027
|
+
const index = chain.findIndex((m) => key(m) === key(event.model));
|
|
16028
|
+
if (index < 0) return true;
|
|
16029
|
+
busy.add(id);
|
|
16030
|
+
try {
|
|
16031
|
+
const before = await ctx.session.get({ sessionID: id });
|
|
16032
|
+
if (before.agent !== turn.agent || !admission.owns(id, before) || before.model && key(before.model) !== key(event.model) || await admission.isPinned(id) || !live())
|
|
16033
|
+
return true;
|
|
16034
|
+
const results = await query.read(
|
|
16035
|
+
chain.slice(index + 1).map(({ providerID, id: id2 }) => ({ providerID, id: id2 }))
|
|
16036
|
+
);
|
|
16037
|
+
const next = chain.slice(index + 1).find(
|
|
16038
|
+
(m) => (
|
|
16039
|
+
// Do not revisit a model, even if it occurs twice in the configured chain.
|
|
16040
|
+
!chain.slice(0, index + 1).some((old) => key(old) === key(m)) && effectiveQuotaStatus(m, results).status !== "exhausted"
|
|
16041
|
+
)
|
|
16042
|
+
);
|
|
16043
|
+
if (!next) return true;
|
|
16044
|
+
const latest = await ctx.session.get({ sessionID: id });
|
|
16045
|
+
if (!live() || clock() - observed.at > TTL || !admission.owns(id, latest) || await admission.isPinned(id) || latest.agent !== before.agent || (latest.model ? key(latest.model) : "") !== (before.model ? key(before.model) : "") || !live())
|
|
16046
|
+
return true;
|
|
16047
|
+
if (!await admission.select(id, turn.agent, next, live)) return true;
|
|
16048
|
+
turn.model = next;
|
|
16049
|
+
turn.switches++;
|
|
16050
|
+
turn.selected = true;
|
|
16051
|
+
admission.reason(
|
|
16052
|
+
id,
|
|
16053
|
+
live() ? "quota_fallback_selected_retry_requested_not_confirmed" : "quota_fallback_selected_retry_not_requested_control_changed",
|
|
16054
|
+
next
|
|
16055
|
+
);
|
|
16056
|
+
if (live()) {
|
|
16057
|
+
selected(id, turn.agent, next);
|
|
16058
|
+
event.decision = { retry: true, delay: 0 };
|
|
16059
|
+
}
|
|
16060
|
+
return true;
|
|
16061
|
+
} catch {
|
|
16062
|
+
admission.reason(id, "quota_fallback_selection_failed_retry_not_requested");
|
|
16063
|
+
return true;
|
|
16064
|
+
} finally {
|
|
16065
|
+
busy.delete(id);
|
|
16066
|
+
}
|
|
16067
|
+
},
|
|
16068
|
+
dispose() {
|
|
16069
|
+
disposed = true;
|
|
16070
|
+
clearInterval(timer);
|
|
16071
|
+
query.dispose();
|
|
16072
|
+
turns.clear();
|
|
16073
|
+
observations.clear();
|
|
16074
|
+
tickets.clear();
|
|
16075
|
+
poisoned.clear();
|
|
16076
|
+
claiming.clear();
|
|
16077
|
+
}
|
|
16078
|
+
};
|
|
16079
|
+
}
|
|
16080
|
+
|
|
16081
|
+
// src/core/pin-store.ts
|
|
16082
|
+
var Pins = external_exports.object({ version: external_exports.literal(1), sessionIDs: external_exports.array(external_exports.string().min(1)).max(1024) }).strict();
|
|
16083
|
+
var PIN_STORE_KEY = "quota-pins-v1";
|
|
16084
|
+
function createPinStore(storage) {
|
|
16085
|
+
let lane = Promise.resolve();
|
|
16086
|
+
let pending = 0;
|
|
16087
|
+
const read = async () => {
|
|
16088
|
+
const value = await storage.get(PIN_STORE_KEY);
|
|
16089
|
+
return new Set(value === void 0 ? [] : Pins.parse(value).sessionIDs);
|
|
16090
|
+
};
|
|
16091
|
+
const mutate = (sessionID, add, valid) => {
|
|
16092
|
+
if (pending >= 65) return Promise.reject(new Error("Session pin storage is busy; try again."));
|
|
16093
|
+
pending++;
|
|
16094
|
+
const operation = lane.then(async () => {
|
|
16095
|
+
const pins = await read();
|
|
16096
|
+
if (!valid()) throw new Error("Session pin operation was cancelled.");
|
|
16097
|
+
if (add) {
|
|
16098
|
+
if (!pins.has(sessionID) && pins.size >= 1024)
|
|
16099
|
+
throw new Error("Session pin capacity reached.");
|
|
16100
|
+
pins.add(sessionID);
|
|
16101
|
+
} else if (!pins.delete(sessionID)) return;
|
|
16102
|
+
await storage.set(PIN_STORE_KEY, { version: 1, sessionIDs: [...pins] });
|
|
16103
|
+
});
|
|
16104
|
+
lane = operation.then(
|
|
16105
|
+
() => {
|
|
16106
|
+
pending--;
|
|
16107
|
+
},
|
|
16108
|
+
() => {
|
|
16109
|
+
pending--;
|
|
16110
|
+
}
|
|
16111
|
+
);
|
|
16112
|
+
return operation;
|
|
16113
|
+
};
|
|
16114
|
+
return {
|
|
16115
|
+
async has(sessionID) {
|
|
16116
|
+
await lane;
|
|
16117
|
+
return (await read()).has(sessionID);
|
|
16118
|
+
},
|
|
16119
|
+
add: (sessionID, valid) => mutate(sessionID, true, valid),
|
|
16120
|
+
remove: (sessionID, valid = () => true) => mutate(sessionID, false, valid),
|
|
16121
|
+
drain: () => lane
|
|
16122
|
+
};
|
|
16123
|
+
}
|
|
16124
|
+
|
|
15879
16125
|
// src/quota-v2.ts
|
|
15880
|
-
var
|
|
16126
|
+
var key2 = (model) => model ? `${model.providerID}/${model.id}#${model.variant === "default" ? "" : model.variant ?? ""}` : "";
|
|
15881
16127
|
function createQuotaAdmission(ctx, routes, current) {
|
|
15882
16128
|
const parsed = QuotaOptions.safeParse(ctx.options?.quotaPreflight ?? {});
|
|
15883
|
-
|
|
15884
|
-
|
|
16129
|
+
const fallback = QuotaFallbackOptions.safeParse(ctx.options?.quotaFallback ?? {});
|
|
16130
|
+
if ((!parsed.success || !parsed.data.enabled) && (!fallback.success || !fallback.data.enabled))
|
|
16131
|
+
return void 0;
|
|
16132
|
+
const options = parsed.success ? parsed.data : { enabled: false, allowPaidFallbacks: false };
|
|
15885
16133
|
const query = createQuotaQuery((input, request) => ctx.rpc(UsageQuota).query(input, request));
|
|
15886
16134
|
const owned = /* @__PURE__ */ new Map();
|
|
15887
16135
|
const expected = /* @__PURE__ */ new Map();
|
|
@@ -15899,7 +16147,7 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
15899
16147
|
const reason = (sessionID, value, model) => {
|
|
15900
16148
|
if (disposed) return;
|
|
15901
16149
|
if (reasons.has(sessionID) || reasons.size < 1024) reasons.set(sessionID, value);
|
|
15902
|
-
console.info(`agent-router: [${sessionID}] ${value}${model ? ` ${
|
|
16150
|
+
console.info(`agent-router: [${sessionID}] ${value}${model ? ` ${key2(model)}` : ""}`);
|
|
15903
16151
|
};
|
|
15904
16152
|
const isPinned = async (sessionID) => {
|
|
15905
16153
|
if (pinned.has(sessionID)) return true;
|
|
@@ -15915,19 +16163,19 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
15915
16163
|
(other) => other.providerID === entry.providerID && other.id === entry.id
|
|
15916
16164
|
) === index
|
|
15917
16165
|
);
|
|
15918
|
-
const results = await query.read(candidates);
|
|
16166
|
+
const results = options.enabled ? await query.read(candidates) : [];
|
|
15919
16167
|
return () => {
|
|
15920
16168
|
const now = Date.now();
|
|
15921
16169
|
const startIndex = pending ? Math.max(
|
|
15922
16170
|
0,
|
|
15923
16171
|
[route, ...route.fallbacks ?? []].findIndex(
|
|
15924
|
-
(entry) =>
|
|
16172
|
+
(entry) => key2({
|
|
15925
16173
|
...quotaCandidate(entry),
|
|
15926
16174
|
...entry.variant ? { variant: entry.variant } : {}
|
|
15927
|
-
}) ===
|
|
16175
|
+
}) === key2(pending)
|
|
15928
16176
|
)
|
|
15929
16177
|
) : 0;
|
|
15930
|
-
const choice = chooseQuotaRoute(route, results, options.allowPaidFallbacks, now, startIndex);
|
|
16178
|
+
const choice = options.enabled ? chooseQuotaRoute(route, results, options.allowPaidFallbacks, now, startIndex) : pending ? [route, ...route.fallbacks ?? []][startIndex] : route;
|
|
15931
16179
|
return {
|
|
15932
16180
|
choice,
|
|
15933
16181
|
reason: !choice ? "no_eligible_fallback" : pending ? "staged_reactive_fallback" : choice.model !== route.model ? "known_exhaustion_fallback" : effectiveQuotaStatus(quotaCandidate(route), results, now).status === "available" ? "primary_available" : "primary_unknown"
|
|
@@ -15936,10 +16184,39 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
15936
16184
|
};
|
|
15937
16185
|
return {
|
|
15938
16186
|
isPinned,
|
|
16187
|
+
reason,
|
|
16188
|
+
owns(sessionID, session) {
|
|
16189
|
+
return !disposed && current() && !controls.has(sessionID) && !pinned.has(sessionID) && !!session.agent && (!session.model || owned.get(sessionID)?.agent === session.agent && owned.get(sessionID)?.model === key2(session.model));
|
|
16190
|
+
},
|
|
16191
|
+
claim(sessionID, agent, model) {
|
|
16192
|
+
if (disposed || !current() || controls.has(sessionID) || pinned.has(sessionID)) return false;
|
|
16193
|
+
if (!owned.has(sessionID) && owned.size >= 1024) return false;
|
|
16194
|
+
owned.set(sessionID, { agent, model: key2(model) });
|
|
16195
|
+
return true;
|
|
16196
|
+
},
|
|
16197
|
+
async select(sessionID, agent, model, live) {
|
|
16198
|
+
if (!live()) return false;
|
|
16199
|
+
expected.set(sessionID, key2(model));
|
|
16200
|
+
try {
|
|
16201
|
+
await ctx.session.switchModel({
|
|
16202
|
+
sessionID,
|
|
16203
|
+
model: {
|
|
16204
|
+
providerID: model.providerID,
|
|
16205
|
+
id: model.id,
|
|
16206
|
+
...model.variant ? { variant: model.variant } : {}
|
|
16207
|
+
}
|
|
16208
|
+
});
|
|
16209
|
+
if (live()) owned.set(sessionID, { agent, model: key2(model) });
|
|
16210
|
+
return true;
|
|
16211
|
+
} catch (error51) {
|
|
16212
|
+
expected.delete(sessionID);
|
|
16213
|
+
throw error51;
|
|
16214
|
+
}
|
|
16215
|
+
},
|
|
15939
16216
|
async status(sessionID) {
|
|
15940
16217
|
const session = await ctx.session.get({ sessionID });
|
|
15941
16218
|
const explicit = await isPinned(sessionID);
|
|
15942
|
-
const automatic = !explicit && (!session.model || owned.get(sessionID)?.model ===
|
|
16219
|
+
const automatic = !explicit && (!session.model || owned.get(sessionID)?.model === key2(session.model));
|
|
15943
16220
|
const resolved = session.model ?? (session.agent ? (await ctx.agent.get({ agentID: session.agent })).data.model : void 0) ?? (await ctx.model.default()).data;
|
|
15944
16221
|
return {
|
|
15945
16222
|
sessionID,
|
|
@@ -15981,7 +16258,7 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
15981
16258
|
if (!resolved) throw new Error("No native model is resolved; routing remains pinned.");
|
|
15982
16259
|
const latest = await ctx.session.get({ sessionID });
|
|
15983
16260
|
if (!live()) throw new Error("Router stopped or session deleted during pinning.");
|
|
15984
|
-
if (latest.agent !== session.agent ||
|
|
16261
|
+
if (latest.agent !== session.agent || key2(latest.model) !== key2(session.model))
|
|
15985
16262
|
throw new Error(
|
|
15986
16263
|
"Session selection changed while pinning; current selection remains pinned."
|
|
15987
16264
|
);
|
|
@@ -16000,7 +16277,7 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
16000
16277
|
await pinStore.remove(sessionID, live);
|
|
16001
16278
|
if (!live()) throw new Error("Router stopped; automatic routing was not resumed.");
|
|
16002
16279
|
pinned.delete(sessionID);
|
|
16003
|
-
owned.set(sessionID, { agent: session.agent, model:
|
|
16280
|
+
owned.set(sessionID, { agent: session.agent, model: key2(session.model) });
|
|
16004
16281
|
reason(sessionID, "automatic_next_explicit_turn", session.model);
|
|
16005
16282
|
}
|
|
16006
16283
|
} finally {
|
|
@@ -16010,7 +16287,7 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
16010
16287
|
},
|
|
16011
16288
|
/** Called for every selection event, including before the first prompt. */
|
|
16012
16289
|
event(sessionID, type, model) {
|
|
16013
|
-
if (type === "session.model.selected" && expected.get(sessionID) ===
|
|
16290
|
+
if (type === "session.model.selected" && expected.get(sessionID) === key2(model)) {
|
|
16014
16291
|
expected.delete(sessionID);
|
|
16015
16292
|
return true;
|
|
16016
16293
|
}
|
|
@@ -16045,13 +16322,13 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
16045
16322
|
const route = routes[session.agent];
|
|
16046
16323
|
if (!route) return;
|
|
16047
16324
|
const previous = owned.get(sessionID);
|
|
16048
|
-
if (session.model && (!previous || previous.agent !== session.agent || previous.model !==
|
|
16325
|
+
if (session.model && (!previous || previous.agent !== session.agent || previous.model !== key2(session.model)))
|
|
16049
16326
|
return;
|
|
16050
16327
|
if (!owned.has(sessionID) && owned.size >= 1024) return;
|
|
16051
16328
|
const choose = await evaluate(route, pending);
|
|
16052
16329
|
if (disposed || !current() || (versions.get(sessionID) ?? 0) !== generation) return;
|
|
16053
16330
|
const latest = await ctx.session.get({ sessionID });
|
|
16054
|
-
if (disposed || controls.has(sessionID) || pinned.has(sessionID) || latest.agent !== session.agent ||
|
|
16331
|
+
if (disposed || controls.has(sessionID) || pinned.has(sessionID) || latest.agent !== session.agent || key2(latest.model) !== key2(session.model) || (versions.get(sessionID) ?? 0) !== generation || !current())
|
|
16055
16332
|
return;
|
|
16056
16333
|
const decision = choose();
|
|
16057
16334
|
const { choice } = decision;
|
|
@@ -16063,8 +16340,8 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
16063
16340
|
...quotaCandidate(choice),
|
|
16064
16341
|
...choice.variant && choice.variant !== "default" ? { variant: choice.variant } : {}
|
|
16065
16342
|
};
|
|
16066
|
-
if (
|
|
16067
|
-
expected.set(sessionID,
|
|
16343
|
+
if (key2(model) !== key2(session.model) && (session.model || choice.model !== route.model || choice.variant !== route.variant)) {
|
|
16344
|
+
expected.set(sessionID, key2(model));
|
|
16068
16345
|
try {
|
|
16069
16346
|
await ctx.session.switchModel({ sessionID, model });
|
|
16070
16347
|
} catch {
|
|
@@ -16074,7 +16351,7 @@ function createQuotaAdmission(ctx, routes, current) {
|
|
|
16074
16351
|
}
|
|
16075
16352
|
if (disposed || controls.has(sessionID) || pinned.has(sessionID) || (versions.get(sessionID) ?? 0) !== generation)
|
|
16076
16353
|
return;
|
|
16077
|
-
owned.set(sessionID, { agent: session.agent, model:
|
|
16354
|
+
owned.set(sessionID, { agent: session.agent, model: key2(model) });
|
|
16078
16355
|
reason(sessionID, decision.reason, model);
|
|
16079
16356
|
return model;
|
|
16080
16357
|
} finally {
|
|
@@ -16174,6 +16451,28 @@ async function setupV2(ctx) {
|
|
|
16174
16451
|
const kinds = /* @__PURE__ */ new Map();
|
|
16175
16452
|
const ownSelections = /* @__PURE__ */ new Map();
|
|
16176
16453
|
const quota = createQuotaAdmission(ctx, routes, () => state() === initial);
|
|
16454
|
+
const quotaFallback = quota && createQuotaFallback(
|
|
16455
|
+
ctx,
|
|
16456
|
+
routes,
|
|
16457
|
+
quota,
|
|
16458
|
+
() => state() === initial,
|
|
16459
|
+
(sessionID, agent, model, messageID) => {
|
|
16460
|
+
const id = messageID ?? turns.get(sessionID)?.id;
|
|
16461
|
+
if (!id) return;
|
|
16462
|
+
const message = {
|
|
16463
|
+
id,
|
|
16464
|
+
agent,
|
|
16465
|
+
model: {
|
|
16466
|
+
providerID: model.providerID,
|
|
16467
|
+
modelID: model.id,
|
|
16468
|
+
variant: variant(model.variant)
|
|
16469
|
+
}
|
|
16470
|
+
};
|
|
16471
|
+
failover.admit(sessionID, message);
|
|
16472
|
+
turns.set(sessionID, message);
|
|
16473
|
+
kinds.set(sessionID, "primary");
|
|
16474
|
+
}
|
|
16475
|
+
);
|
|
16177
16476
|
if (quota) {
|
|
16178
16477
|
await ctx.tool.transform((editor) => {
|
|
16179
16478
|
const input = { type: "object", properties: {}, additionalProperties: false };
|
|
@@ -16184,6 +16483,7 @@ async function setupV2(ctx) {
|
|
|
16184
16483
|
input,
|
|
16185
16484
|
async execute(_input, context) {
|
|
16186
16485
|
await quota.control(context.sessionID, action, async () => {
|
|
16486
|
+
quotaFallback?.stop(context.sessionID);
|
|
16187
16487
|
turns.delete(context.sessionID);
|
|
16188
16488
|
kinds.delete(context.sessionID);
|
|
16189
16489
|
await failover.event({
|
|
@@ -16217,6 +16517,15 @@ async function setupV2(ctx) {
|
|
|
16217
16517
|
event.type === "session.model.selected" ? event.data.model : void 0
|
|
16218
16518
|
))
|
|
16219
16519
|
continue;
|
|
16520
|
+
if ([
|
|
16521
|
+
"session.model.selected",
|
|
16522
|
+
"session.agent.selected",
|
|
16523
|
+
"session.execution.interrupted",
|
|
16524
|
+
"session.deleted",
|
|
16525
|
+
"session.execution.succeeded",
|
|
16526
|
+
"session.execution.failed"
|
|
16527
|
+
].includes(event.type))
|
|
16528
|
+
quotaFallback?.stop(sessionID);
|
|
16220
16529
|
if (!turns.has(sessionID)) continue;
|
|
16221
16530
|
if (event.type === "session.model.selected") {
|
|
16222
16531
|
const model = event.data.model;
|
|
@@ -16241,12 +16550,37 @@ async function setupV2(ctx) {
|
|
|
16241
16550
|
})().catch((error51) => {
|
|
16242
16551
|
if (!controller.signal.aborted) console.warn("agent-router event subscription failed", error51);
|
|
16243
16552
|
});
|
|
16244
|
-
await ctx.session.hook("model.request", (event) => {
|
|
16553
|
+
await ctx.session.hook("model.request", async (event) => {
|
|
16554
|
+
quotaFallback?.model(event);
|
|
16555
|
+
if (event.kind === "primary")
|
|
16556
|
+
await quotaFallback?.child(event.sessionID, event.agent, event.model);
|
|
16245
16557
|
if (turns.has(event.sessionID)) kinds.set(event.sessionID, event.kind);
|
|
16246
16558
|
});
|
|
16247
|
-
if (quota)
|
|
16559
|
+
if (quota)
|
|
16560
|
+
await ctx.tool.hook("execute.before", async (event) => {
|
|
16561
|
+
const input = event.input;
|
|
16562
|
+
const automatic = event.tool === "subagent" && input && typeof input === "object" && !["model", "sessionID", "session_id", "task_id"].some((key3) => key3 in input) && typeof input.agent === "string";
|
|
16563
|
+
await quota.child(event);
|
|
16564
|
+
if (event.tool === "subagent" && input && typeof input.agent === "string")
|
|
16565
|
+
quotaFallback?.ticket(
|
|
16566
|
+
event.id,
|
|
16567
|
+
event.sessionID,
|
|
16568
|
+
input.agent,
|
|
16569
|
+
typeof input.model === "string" ? input.model : void 0,
|
|
16570
|
+
automatic && typeof input.prompt === "string" ? input.prompt : void 0
|
|
16571
|
+
);
|
|
16572
|
+
});
|
|
16573
|
+
if (quotaFallback) {
|
|
16574
|
+
await ctx.session.hook("http.request", (event) => quotaFallback.request(event));
|
|
16575
|
+
await ctx.session.hook("http.response", (event) => quotaFallback.response(event));
|
|
16576
|
+
await ctx.session.hook(
|
|
16577
|
+
"experimental.ws.handshake",
|
|
16578
|
+
(event) => quotaFallback.unsupported(event.sessionID)
|
|
16579
|
+
);
|
|
16580
|
+
}
|
|
16248
16581
|
await ctx.session.hook("prompt", async (event) => {
|
|
16249
16582
|
if (turns.get(event.sessionID)?.id === event.messageID) return;
|
|
16583
|
+
quotaFallback?.stop(event.sessionID);
|
|
16250
16584
|
if (state() !== initial) {
|
|
16251
16585
|
failover.disable();
|
|
16252
16586
|
turns.clear();
|
|
@@ -16285,6 +16619,7 @@ async function setupV2(ctx) {
|
|
|
16285
16619
|
failover.admit(event.sessionID, message2);
|
|
16286
16620
|
if (!failover.active(event.sessionID)) return;
|
|
16287
16621
|
turns.set(event.sessionID, message2);
|
|
16622
|
+
if (!session.parentID) quotaFallback?.admit(event.sessionID, session.agent, selected);
|
|
16288
16623
|
return;
|
|
16289
16624
|
}
|
|
16290
16625
|
if (!session.agent || !session.model || !routes[session.agent]) return;
|
|
@@ -16336,6 +16671,7 @@ async function setupV2(ctx) {
|
|
|
16336
16671
|
turns.set(event.sessionID, message);
|
|
16337
16672
|
});
|
|
16338
16673
|
await ctx.session.hook("retry", async (event) => {
|
|
16674
|
+
if (await quotaFallback?.retry(event)) return;
|
|
16339
16675
|
const turn = turns.get(event.sessionID);
|
|
16340
16676
|
if (!turn || kinds.get(event.sessionID) !== "primary" || turn.agent !== event.agent || turn.model.providerID !== event.model.providerID || turn.model.modelID !== event.model.id)
|
|
16341
16677
|
return;
|
|
@@ -16363,6 +16699,7 @@ async function setupV2(ctx) {
|
|
|
16363
16699
|
});
|
|
16364
16700
|
return async () => {
|
|
16365
16701
|
controller.abort();
|
|
16702
|
+
quotaFallback?.dispose();
|
|
16366
16703
|
await quota?.dispose();
|
|
16367
16704
|
failover.disable();
|
|
16368
16705
|
turns.clear();
|
|
@@ -16373,7 +16710,7 @@ async function setupV2(ctx) {
|
|
|
16373
16710
|
}
|
|
16374
16711
|
|
|
16375
16712
|
// src/version.ts
|
|
16376
|
-
var VERSION = "2.
|
|
16713
|
+
var VERSION = "2.2.0";
|
|
16377
16714
|
|
|
16378
16715
|
// src/plugin.ts
|
|
16379
16716
|
var tool = Object.assign(
|