@jeffusion/bungee-core 5.10.0 → 5.12.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/dist/main.js +31436 -17327
- package/dist/plugins/ai-transformer/index.js.map +2 -2
- package/dist/plugins/anthropic-request-sanitizer/index.js.map +2 -2
- package/dist/plugins/anthropic-tool-name-transformer/index.js.map +2 -2
- package/dist/plugins/chatgpt-oauth/control.js +850 -47
- package/dist/plugins/chatgpt-oauth/control.js.map +16 -7
- package/dist/plugins/chatgpt-oauth/index.js +691 -16
- package/dist/plugins/chatgpt-oauth/index.js.map +15 -7
- package/dist/plugins/chatgpt-oauth/manifest.json +117 -7
- package/dist/plugins/chatgpt-oauth/ui/AccountsPage.svelte +25 -15
- package/dist/plugins/chatgpt-oauth/ui/ChatgptQuotaWidget.svelte +7 -4
- package/dist/plugins/chatgpt-oauth/ui/account-model.js +16 -7
- package/dist/plugins/deepseek-reasoning-fix/index.js.map +2 -2
- package/dist/plugins/key-access/index.js.map +2 -2
- package/dist/plugins/key-rate-limit/index.js.map +2 -2
- package/dist/plugins/local-accounts/control.js.map +2 -2
- package/dist/plugins/local-accounts/index.js.map +2 -2
- package/dist/plugins/model-mapping/control.js +72 -17741
- package/dist/plugins/model-mapping/control.js.map +6 -58
- package/dist/plugins/model-mapping/index.js +32 -17433
- package/dist/plugins/model-mapping/index.js.map +6 -58
- package/dist/plugins/model-mapping/manifest.json +30 -14
- package/dist/plugins/models-dev/control.js +1042 -0
- package/dist/plugins/models-dev/control.js.map +16 -0
- package/dist/plugins/models-dev/index.js +15418 -0
- package/dist/plugins/models-dev/index.js.map +134 -0
- package/dist/plugins/models-dev/manifest.json +199 -0
- package/dist/plugins/models-dev/ui/ModelsDevSettings.svelte +120 -0
- package/dist/plugins/openai-messages-to-chat/index.js.map +2 -2
- package/dist/plugins/signature-repair/index.js.map +2 -2
- package/dist/plugins/token-budget/control.js +524 -9
- package/dist/plugins/token-budget/control.js.map +12 -4
- package/dist/plugins/token-budget/index.js +519 -12
- package/dist/plugins/token-budget/index.js.map +13 -6
- package/dist/plugins/token-budget/manifest.json +16 -2
- package/dist/plugins/token-metering/index.js +93 -2
- package/dist/plugins/token-metering/index.js.map +12 -6
- package/dist/plugins/token-stats/control.js +174 -312
- package/dist/plugins/token-stats/control.js.map +7 -7
- package/dist/plugins/token-stats/index.js +283 -486
- package/dist/plugins/token-stats/index.js.map +16 -12
- package/dist/plugins/token-stats/manifest.json +99 -12
- package/dist/plugins/token-stats/ui/ClientModelPicker.svelte +76 -0
- package/dist/plugins/token-stats/ui/PriceModelPicker.svelte +87 -0
- package/dist/plugins/token-stats/ui/TokenStatsSettings.svelte +136 -80
- package/dist/plugins/token-stats/ui/client-model-search.test.ts +58 -0
- package/dist/plugins/token-stats/ui/client-model-search.ts +16 -0
- package/dist/plugins/token-stats/ui/model-search.ts +45 -0
- package/dist/plugins/token-stats/ui/pricing-catalog.test.ts +114 -0
- package/dist/plugins/token-stats/ui/pricing-catalog.ts +17 -0
- package/package.json +2 -2
|
@@ -14770,6 +14770,518 @@ var require_winston_daily_rotate_file = __commonJS(function(exports, module) {
|
|
|
14770
14770
|
module.exports = DailyRotateFile;
|
|
14771
14771
|
});
|
|
14772
14772
|
|
|
14773
|
+
// packages/core/src/plugin-services/host-rpc.ts
|
|
14774
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
14775
|
+
|
|
14776
|
+
// packages/core/src/plugin-services/wire-contract.ts
|
|
14777
|
+
import { isProxy } from "util/types";
|
|
14778
|
+
var RPC_JSON_MAX_BYTES = 64 * 1024;
|
|
14779
|
+
var RPC_CONTRACT_MAX_BYTES = 256 * 1024;
|
|
14780
|
+
var JSON_MAX_DEPTH = 64;
|
|
14781
|
+
var SCHEMA_MAX_DEPTH = 64;
|
|
14782
|
+
var RPC_MAX_TIMEOUT_MS = 300000;
|
|
14783
|
+
var RPC_MAX_METHODS = 128;
|
|
14784
|
+
var RPC_SERVICE_ID = /^[a-z][a-z0-9.-]{0,127}$/;
|
|
14785
|
+
var RPC_METHOD_NAME = /^[A-Za-z_][A-Za-z0-9_.-]{0,127}$/;
|
|
14786
|
+
var RPC_CALL_PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
14787
|
+
var RPC_COMMAND_DEDUPLICATION = new Set(["local-transaction", "external-contract", "none"]);
|
|
14788
|
+
var RPC_COMMAND_POLICY_KEYS = new Set(["deduplication", "resultRetentionMs", "quotaBytes", "maxResultBytes"]);
|
|
14789
|
+
var CONTRACT_KEYS = ["id", "version", "methods"];
|
|
14790
|
+
var METHOD_KEYS = [
|
|
14791
|
+
"kind",
|
|
14792
|
+
"input",
|
|
14793
|
+
"output",
|
|
14794
|
+
"purposes",
|
|
14795
|
+
"timeoutMs",
|
|
14796
|
+
"maxInputBytes",
|
|
14797
|
+
"maxOutputBytes",
|
|
14798
|
+
"command"
|
|
14799
|
+
];
|
|
14800
|
+
|
|
14801
|
+
class RpcProtocolError extends Error {
|
|
14802
|
+
code;
|
|
14803
|
+
name = "RpcProtocolError";
|
|
14804
|
+
constructor(code, message) {
|
|
14805
|
+
super(message);
|
|
14806
|
+
this.code = code;
|
|
14807
|
+
}
|
|
14808
|
+
}
|
|
14809
|
+
function failData(category) {
|
|
14810
|
+
throw new RpcProtocolError("invalid_data", `invalid_data in ${category}`);
|
|
14811
|
+
}
|
|
14812
|
+
function failSize() {
|
|
14813
|
+
throw new RpcProtocolError("size_limit", "size_limit: JSON value exceeds the byte limit");
|
|
14814
|
+
}
|
|
14815
|
+
function failContract(reason) {
|
|
14816
|
+
throw new RpcProtocolError("invalid_contract", `invalid_contract: ${reason}`);
|
|
14817
|
+
}
|
|
14818
|
+
function isPlainObject(value) {
|
|
14819
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
14820
|
+
return false;
|
|
14821
|
+
if (isProxy(value))
|
|
14822
|
+
return false;
|
|
14823
|
+
const prototype = Object.getPrototypeOf(value);
|
|
14824
|
+
return prototype === Object.prototype || prototype === null;
|
|
14825
|
+
}
|
|
14826
|
+
function isPositiveSafeInteger(value) {
|
|
14827
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
14828
|
+
}
|
|
14829
|
+
function isNonNegativeSafeInteger(value) {
|
|
14830
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
14831
|
+
}
|
|
14832
|
+
function hasLoneSurrogate(value) {
|
|
14833
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
14834
|
+
const code = value.charCodeAt(index);
|
|
14835
|
+
if (code >= 55296 && code <= 56319) {
|
|
14836
|
+
if (index + 1 >= value.length)
|
|
14837
|
+
return true;
|
|
14838
|
+
const next = value.charCodeAt(index + 1);
|
|
14839
|
+
if (next < 56320 || next > 57343)
|
|
14840
|
+
return true;
|
|
14841
|
+
index += 1;
|
|
14842
|
+
} else if (code >= 56320 && code <= 57343) {
|
|
14843
|
+
return true;
|
|
14844
|
+
}
|
|
14845
|
+
}
|
|
14846
|
+
return false;
|
|
14847
|
+
}
|
|
14848
|
+
function isArrayIndex(key, length) {
|
|
14849
|
+
if (!/^(?:0|[1-9]\d*)$/.test(key))
|
|
14850
|
+
return false;
|
|
14851
|
+
const index = Number(key);
|
|
14852
|
+
return Number.isSafeInteger(index) && index >= 0 && index < length;
|
|
14853
|
+
}
|
|
14854
|
+
function assertKnownKeys(input, allowed, category) {
|
|
14855
|
+
for (const key of Object.keys(input)) {
|
|
14856
|
+
if (!allowed.includes(key))
|
|
14857
|
+
failContract(`unknown ${category} field`);
|
|
14858
|
+
}
|
|
14859
|
+
}
|
|
14860
|
+
function spend(budget, bytes) {
|
|
14861
|
+
budget.left -= bytes;
|
|
14862
|
+
if (budget.left < 0)
|
|
14863
|
+
failSize();
|
|
14864
|
+
}
|
|
14865
|
+
function snapshot(value, depth, ancestors, budget) {
|
|
14866
|
+
if (value === null) {
|
|
14867
|
+
spend(budget, 4);
|
|
14868
|
+
return null;
|
|
14869
|
+
}
|
|
14870
|
+
if (typeof value === "boolean") {
|
|
14871
|
+
spend(budget, value ? 4 : 5);
|
|
14872
|
+
return value;
|
|
14873
|
+
}
|
|
14874
|
+
if (typeof value === "string") {
|
|
14875
|
+
if (hasLoneSurrogate(value))
|
|
14876
|
+
failData("string");
|
|
14877
|
+
spend(budget, Buffer.byteLength(value, "utf8") + 2);
|
|
14878
|
+
return value;
|
|
14879
|
+
}
|
|
14880
|
+
if (typeof value === "number") {
|
|
14881
|
+
if (!Number.isFinite(value))
|
|
14882
|
+
failData("number");
|
|
14883
|
+
spend(budget, 1);
|
|
14884
|
+
return value;
|
|
14885
|
+
}
|
|
14886
|
+
if (typeof value !== "object")
|
|
14887
|
+
failData("json");
|
|
14888
|
+
const object = value;
|
|
14889
|
+
if (isProxy(object))
|
|
14890
|
+
failData("json");
|
|
14891
|
+
if (ancestors.has(object))
|
|
14892
|
+
failData("json");
|
|
14893
|
+
const nextDepth = depth + 1;
|
|
14894
|
+
if (nextDepth > JSON_MAX_DEPTH)
|
|
14895
|
+
failData("json");
|
|
14896
|
+
if (Array.isArray(object)) {
|
|
14897
|
+
if (Object.getPrototypeOf(object) !== Array.prototype)
|
|
14898
|
+
failData("array");
|
|
14899
|
+
const lengthDescriptor = Object.getOwnPropertyDescriptor(object, "length");
|
|
14900
|
+
if (!lengthDescriptor || !("value" in lengthDescriptor) || typeof lengthDescriptor.value !== "number") {
|
|
14901
|
+
failData("array");
|
|
14902
|
+
}
|
|
14903
|
+
const length = lengthDescriptor.value;
|
|
14904
|
+
if (!Number.isSafeInteger(length) || length < 0)
|
|
14905
|
+
failData("array");
|
|
14906
|
+
if (length > budget.left)
|
|
14907
|
+
failSize();
|
|
14908
|
+
spend(budget, 2);
|
|
14909
|
+
if (length > 1)
|
|
14910
|
+
spend(budget, length - 1);
|
|
14911
|
+
ancestors.add(object);
|
|
14912
|
+
const items = new Array(length);
|
|
14913
|
+
let count = 0;
|
|
14914
|
+
for (const key of Reflect.ownKeys(object)) {
|
|
14915
|
+
if (key === "length")
|
|
14916
|
+
continue;
|
|
14917
|
+
if (typeof key !== "string" || !isArrayIndex(key, length))
|
|
14918
|
+
failData("array");
|
|
14919
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
14920
|
+
if (!descriptor || !descriptor.enumerable || !("value" in descriptor))
|
|
14921
|
+
failData("array");
|
|
14922
|
+
items[Number(key)] = snapshot(descriptor.value, nextDepth, ancestors, budget);
|
|
14923
|
+
count += 1;
|
|
14924
|
+
}
|
|
14925
|
+
if (count !== length)
|
|
14926
|
+
failData("array");
|
|
14927
|
+
ancestors.delete(object);
|
|
14928
|
+
return items;
|
|
14929
|
+
}
|
|
14930
|
+
const prototype = Object.getPrototypeOf(object);
|
|
14931
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
14932
|
+
failData("object");
|
|
14933
|
+
const keys = Reflect.ownKeys(object);
|
|
14934
|
+
if (keys.length > budget.left)
|
|
14935
|
+
failSize();
|
|
14936
|
+
spend(budget, 2);
|
|
14937
|
+
if (keys.length > 1)
|
|
14938
|
+
spend(budget, keys.length - 1);
|
|
14939
|
+
ancestors.add(object);
|
|
14940
|
+
const result = {};
|
|
14941
|
+
for (const key of keys) {
|
|
14942
|
+
if (typeof key !== "string")
|
|
14943
|
+
failData("object");
|
|
14944
|
+
if (hasLoneSurrogate(key))
|
|
14945
|
+
failData("object");
|
|
14946
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
14947
|
+
if (!descriptor || !descriptor.enumerable || !("value" in descriptor))
|
|
14948
|
+
failData("object");
|
|
14949
|
+
spend(budget, Buffer.byteLength(key, "utf8") + 3);
|
|
14950
|
+
Object.defineProperty(result, key, {
|
|
14951
|
+
value: snapshot(descriptor.value, nextDepth, ancestors, budget),
|
|
14952
|
+
enumerable: true,
|
|
14953
|
+
writable: true,
|
|
14954
|
+
configurable: true
|
|
14955
|
+
});
|
|
14956
|
+
}
|
|
14957
|
+
ancestors.delete(object);
|
|
14958
|
+
return result;
|
|
14959
|
+
}
|
|
14960
|
+
function snapshotPureInput(input) {
|
|
14961
|
+
try {
|
|
14962
|
+
const pure = snapshot(input, 0, new Set, { left: RPC_CONTRACT_MAX_BYTES });
|
|
14963
|
+
if (Buffer.byteLength(JSON.stringify(pure), "utf8") > RPC_CONTRACT_MAX_BYTES)
|
|
14964
|
+
failContract("input must be bounded pure JSON data");
|
|
14965
|
+
return pure;
|
|
14966
|
+
} catch (error) {
|
|
14967
|
+
if (error instanceof RpcProtocolError && (error.code === "invalid_data" || error.code === "size_limit")) {
|
|
14968
|
+
failContract("input must be bounded pure JSON data");
|
|
14969
|
+
}
|
|
14970
|
+
throw error;
|
|
14971
|
+
}
|
|
14972
|
+
}
|
|
14973
|
+
function checkOptionalNonNegative(value, field) {
|
|
14974
|
+
if (value === undefined)
|
|
14975
|
+
return;
|
|
14976
|
+
if (!isNonNegativeSafeInteger(value))
|
|
14977
|
+
failContract(`${field} must be a non-negative safe integer`);
|
|
14978
|
+
return value;
|
|
14979
|
+
}
|
|
14980
|
+
function checkOptionalFinite(value, field) {
|
|
14981
|
+
if (value === undefined)
|
|
14982
|
+
return;
|
|
14983
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
14984
|
+
failContract(`${field} must be a finite number`);
|
|
14985
|
+
return value;
|
|
14986
|
+
}
|
|
14987
|
+
function checkSchema(input, depth, seen) {
|
|
14988
|
+
if (depth > SCHEMA_MAX_DEPTH)
|
|
14989
|
+
failContract("schema nesting exceeds the limit");
|
|
14990
|
+
if (!isPlainObject(input))
|
|
14991
|
+
failContract("schema must be a plain object");
|
|
14992
|
+
if (seen.has(input))
|
|
14993
|
+
failContract("schema must not contain cycles");
|
|
14994
|
+
seen.add(input);
|
|
14995
|
+
const type = input.type;
|
|
14996
|
+
if (type === "string") {
|
|
14997
|
+
assertKnownKeys(input, ["type", "minLength", "maxLength"], "schema");
|
|
14998
|
+
const min = checkOptionalNonNegative(input.minLength, "minLength");
|
|
14999
|
+
const max = checkOptionalNonNegative(input.maxLength, "maxLength");
|
|
15000
|
+
if (min !== undefined && max !== undefined && min > max)
|
|
15001
|
+
failContract("string minLength must not exceed maxLength");
|
|
15002
|
+
} else if (type === "number") {
|
|
15003
|
+
assertKnownKeys(input, ["type", "integer", "minimum", "maximum"], "schema");
|
|
15004
|
+
if (input.integer !== undefined && typeof input.integer !== "boolean")
|
|
15005
|
+
failContract("number integer flag must be boolean");
|
|
15006
|
+
const min = checkOptionalFinite(input.minimum, "minimum");
|
|
15007
|
+
const max = checkOptionalFinite(input.maximum, "maximum");
|
|
15008
|
+
if (min !== undefined && max !== undefined && min > max)
|
|
15009
|
+
failContract("number minimum must not exceed maximum");
|
|
15010
|
+
} else if (type === "boolean") {
|
|
15011
|
+
assertKnownKeys(input, ["type"], "schema");
|
|
15012
|
+
} else if (type === "null") {
|
|
15013
|
+
assertKnownKeys(input, ["type"], "schema");
|
|
15014
|
+
} else if (type === "literal") {
|
|
15015
|
+
assertKnownKeys(input, ["type", "value"], "schema");
|
|
15016
|
+
if (!Object.prototype.hasOwnProperty.call(input, "value"))
|
|
15017
|
+
failContract("literal schema requires a value");
|
|
15018
|
+
try {
|
|
15019
|
+
snapshot(input.value, 0, new Set, { left: Infinity });
|
|
15020
|
+
} catch (error) {
|
|
15021
|
+
if (error instanceof RpcProtocolError && error.code === "invalid_data") {
|
|
15022
|
+
failContract("literal value must be pure JSON");
|
|
15023
|
+
}
|
|
15024
|
+
throw error;
|
|
15025
|
+
}
|
|
15026
|
+
} else if (type === "array") {
|
|
15027
|
+
assertKnownKeys(input, ["type", "items", "maxItems"], "schema");
|
|
15028
|
+
if (!Object.prototype.hasOwnProperty.call(input, "items"))
|
|
15029
|
+
failContract("array schema requires items");
|
|
15030
|
+
checkSchema(input.items, depth + 1, seen);
|
|
15031
|
+
checkOptionalNonNegative(input.maxItems, "maxItems");
|
|
15032
|
+
} else if (type === "object") {
|
|
15033
|
+
assertKnownKeys(input, ["type", "properties", "optional"], "schema");
|
|
15034
|
+
const properties = input.properties;
|
|
15035
|
+
if (!isPlainObject(properties))
|
|
15036
|
+
failContract("object schema requires a properties record");
|
|
15037
|
+
for (const key of Object.keys(properties))
|
|
15038
|
+
checkSchema(properties[key], depth + 1, seen);
|
|
15039
|
+
const optional = input.optional;
|
|
15040
|
+
if (optional !== undefined) {
|
|
15041
|
+
if (!Array.isArray(optional))
|
|
15042
|
+
failContract("object optional must be an array of field names");
|
|
15043
|
+
const names = new Set;
|
|
15044
|
+
for (const name of optional) {
|
|
15045
|
+
if (typeof name !== "string")
|
|
15046
|
+
failContract("object optional entries must be strings");
|
|
15047
|
+
if (names.has(name))
|
|
15048
|
+
failContract("object optional entries must be unique");
|
|
15049
|
+
names.add(name);
|
|
15050
|
+
if (!Object.prototype.hasOwnProperty.call(properties, name)) {
|
|
15051
|
+
failContract("object optional names must exist in properties");
|
|
15052
|
+
}
|
|
15053
|
+
}
|
|
15054
|
+
}
|
|
15055
|
+
} else if (type === "record") {
|
|
15056
|
+
assertKnownKeys(input, ["type", "values", "maxEntries"], "schema");
|
|
15057
|
+
if (!Object.prototype.hasOwnProperty.call(input, "values"))
|
|
15058
|
+
failContract("record schema requires values");
|
|
15059
|
+
checkSchema(input.values, depth + 1, seen);
|
|
15060
|
+
checkOptionalNonNegative(input.maxEntries, "maxEntries");
|
|
15061
|
+
} else if (type === "union") {
|
|
15062
|
+
assertKnownKeys(input, ["type", "variants"], "schema");
|
|
15063
|
+
const variants = input.variants;
|
|
15064
|
+
if (!Array.isArray(variants) || variants.length === 0) {
|
|
15065
|
+
failContract("union schema requires a non-empty variants array");
|
|
15066
|
+
}
|
|
15067
|
+
for (const variant of variants)
|
|
15068
|
+
checkSchema(variant, depth + 1, seen);
|
|
15069
|
+
} else if (type === "json") {
|
|
15070
|
+
assertKnownKeys(input, ["type", "maxBytes"], "schema");
|
|
15071
|
+
if (input.maxBytes !== undefined && !isPositiveSafeInteger(input.maxBytes)) {
|
|
15072
|
+
failContract("json schema maxBytes must be a positive safe integer");
|
|
15073
|
+
}
|
|
15074
|
+
} else {
|
|
15075
|
+
failContract("unknown schema type");
|
|
15076
|
+
}
|
|
15077
|
+
seen.delete(input);
|
|
15078
|
+
}
|
|
15079
|
+
function checkByteLimit(value, field) {
|
|
15080
|
+
if (value === undefined)
|
|
15081
|
+
return;
|
|
15082
|
+
if (!isPositiveSafeInteger(value) || value > RPC_JSON_MAX_BYTES) {
|
|
15083
|
+
failContract(`${field} must be a positive integer no larger than the RPC envelope`);
|
|
15084
|
+
}
|
|
15085
|
+
return value;
|
|
15086
|
+
}
|
|
15087
|
+
function checkCommandPolicy(policy, maxOutputBytes) {
|
|
15088
|
+
const keys = Object.keys(policy);
|
|
15089
|
+
if (keys.length !== RPC_COMMAND_POLICY_KEYS.size || keys.some((key) => !RPC_COMMAND_POLICY_KEYS.has(key))) {
|
|
15090
|
+
failContract("command policy fields are fixed");
|
|
15091
|
+
}
|
|
15092
|
+
const deduplication = policy.deduplication;
|
|
15093
|
+
if (typeof deduplication !== "string" || !RPC_COMMAND_DEDUPLICATION.has(deduplication)) {
|
|
15094
|
+
failContract("invalid command deduplication");
|
|
15095
|
+
}
|
|
15096
|
+
const retention = policy.resultRetentionMs;
|
|
15097
|
+
if (retention !== null && !isPositiveSafeInteger(retention)) {
|
|
15098
|
+
failContract("resultRetentionMs must be a positive integer or null");
|
|
15099
|
+
}
|
|
15100
|
+
const maxResultBytes = policy.maxResultBytes;
|
|
15101
|
+
if (!isPositiveSafeInteger(maxResultBytes))
|
|
15102
|
+
failContract("maxResultBytes must be a positive safe integer");
|
|
15103
|
+
if (maxResultBytes > maxOutputBytes)
|
|
15104
|
+
failContract("maxResultBytes must not exceed maxOutputBytes");
|
|
15105
|
+
const quotaBytes = policy.quotaBytes;
|
|
15106
|
+
if (!isPositiveSafeInteger(quotaBytes))
|
|
15107
|
+
failContract("quotaBytes must be a positive safe integer");
|
|
15108
|
+
if (quotaBytes < maxResultBytes)
|
|
15109
|
+
failContract("quotaBytes must be able to hold maxResultBytes");
|
|
15110
|
+
}
|
|
15111
|
+
function checkMethod(definition) {
|
|
15112
|
+
assertKnownKeys(definition, METHOD_KEYS, "method");
|
|
15113
|
+
const kind = definition.kind;
|
|
15114
|
+
if (kind !== "query" && kind !== "command")
|
|
15115
|
+
failContract("method kind must be query or command");
|
|
15116
|
+
checkSchema(definition.input, 0, new Set);
|
|
15117
|
+
checkSchema(definition.output, 0, new Set);
|
|
15118
|
+
const purposes = definition.purposes;
|
|
15119
|
+
if (!Array.isArray(purposes) || purposes.length === 0)
|
|
15120
|
+
failContract("purposes must be a non-empty array");
|
|
15121
|
+
const seenPurposes = new Set;
|
|
15122
|
+
for (const purpose of purposes) {
|
|
15123
|
+
if (typeof purpose !== "string" || !RPC_CALL_PURPOSES.has(purpose))
|
|
15124
|
+
failContract("invalid purpose");
|
|
15125
|
+
if (seenPurposes.has(purpose))
|
|
15126
|
+
failContract("purposes must be unique");
|
|
15127
|
+
seenPurposes.add(purpose);
|
|
15128
|
+
}
|
|
15129
|
+
if (definition.timeoutMs !== undefined) {
|
|
15130
|
+
if (!isPositiveSafeInteger(definition.timeoutMs) || definition.timeoutMs > RPC_MAX_TIMEOUT_MS) {
|
|
15131
|
+
failContract("timeoutMs must be a positive integer no larger than the timeout bound");
|
|
15132
|
+
}
|
|
15133
|
+
}
|
|
15134
|
+
checkByteLimit(definition.maxInputBytes, "maxInputBytes");
|
|
15135
|
+
const maxOutputBytes = checkByteLimit(definition.maxOutputBytes, "maxOutputBytes");
|
|
15136
|
+
const command = definition.command;
|
|
15137
|
+
if (kind === "command") {
|
|
15138
|
+
if (!isPlainObject(command))
|
|
15139
|
+
failContract("command methods require an explicit command policy");
|
|
15140
|
+
checkCommandPolicy(command, maxOutputBytes ?? RPC_JSON_MAX_BYTES);
|
|
15141
|
+
} else if (command !== undefined) {
|
|
15142
|
+
failContract("query methods must not declare a command policy");
|
|
15143
|
+
}
|
|
15144
|
+
}
|
|
15145
|
+
function checkContract(contract) {
|
|
15146
|
+
if (!isPlainObject(contract))
|
|
15147
|
+
failContract("contract must be a plain object");
|
|
15148
|
+
assertKnownKeys(contract, CONTRACT_KEYS, "contract");
|
|
15149
|
+
if (typeof contract.id !== "string" || !RPC_SERVICE_ID.test(contract.id))
|
|
15150
|
+
failContract("invalid service id");
|
|
15151
|
+
if (!isPositiveSafeInteger(contract.version))
|
|
15152
|
+
failContract("service version must be a positive safe integer");
|
|
15153
|
+
const methods = contract.methods;
|
|
15154
|
+
if (!isPlainObject(methods))
|
|
15155
|
+
failContract("methods must be a plain object");
|
|
15156
|
+
const names = Object.keys(methods);
|
|
15157
|
+
if (names.length === 0)
|
|
15158
|
+
failContract("service must declare at least one method");
|
|
15159
|
+
if (names.length > RPC_MAX_METHODS)
|
|
15160
|
+
failContract("service declares too many methods");
|
|
15161
|
+
for (const name of names) {
|
|
15162
|
+
if (!RPC_METHOD_NAME.test(name))
|
|
15163
|
+
failContract("invalid method name");
|
|
15164
|
+
const definition = methods[name];
|
|
15165
|
+
if (!isPlainObject(definition))
|
|
15166
|
+
failContract("method definition must be a plain object");
|
|
15167
|
+
checkMethod(definition);
|
|
15168
|
+
}
|
|
15169
|
+
}
|
|
15170
|
+
function deepFreeze(value) {
|
|
15171
|
+
if (Array.isArray(value)) {
|
|
15172
|
+
for (const item of value)
|
|
15173
|
+
deepFreeze(item);
|
|
15174
|
+
return Object.freeze(value);
|
|
15175
|
+
}
|
|
15176
|
+
if (isPlainObject(value)) {
|
|
15177
|
+
for (const key of Object.keys(value))
|
|
15178
|
+
deepFreeze(value[key]);
|
|
15179
|
+
return Object.freeze(value);
|
|
15180
|
+
}
|
|
15181
|
+
return value;
|
|
15182
|
+
}
|
|
15183
|
+
function defineRpcService(contract) {
|
|
15184
|
+
const pure = snapshotPureInput(contract);
|
|
15185
|
+
checkContract(pure);
|
|
15186
|
+
return deepFreeze(pure);
|
|
15187
|
+
}
|
|
15188
|
+
|
|
15189
|
+
// packages/core/src/plugin-services/rpc-runtime.ts
|
|
15190
|
+
var PROCESSES = new Set(["control", "worker", "ingress"]);
|
|
15191
|
+
var SCOPES = new Set(["global", "binding"]);
|
|
15192
|
+
var PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
15193
|
+
var ENDPOINTS = new WeakMap;
|
|
15194
|
+
var REVOKED = new WeakMap;
|
|
15195
|
+
|
|
15196
|
+
// packages/core/src/plugin-services/host-rpc.ts
|
|
15197
|
+
var SERVICE_ERROR_MESSAGES = {
|
|
15198
|
+
unauthorized: "RPC call is not authorized",
|
|
15199
|
+
not_ready: "RPC endpoint is not ready",
|
|
15200
|
+
retired: "RPC endpoint is retiring",
|
|
15201
|
+
revoked: "RPC endpoint generation was revoked",
|
|
15202
|
+
unsupported_method: "RPC method is not published",
|
|
15203
|
+
wrong_purpose: "RPC method is not published for this purpose",
|
|
15204
|
+
invalid_input: "RPC input is not valid",
|
|
15205
|
+
invalid_output: "RPC output is not valid",
|
|
15206
|
+
invalid_operation_id: "RPC command operation id is invalid",
|
|
15207
|
+
overloaded: "RPC runtime is at capacity",
|
|
15208
|
+
cancelled: "RPC call was cancelled",
|
|
15209
|
+
timeout: "RPC call deadline exceeded",
|
|
15210
|
+
unknown: "RPC command outcome is unknown",
|
|
15211
|
+
capability_unavailable: "RPC command execution is unavailable",
|
|
15212
|
+
closed: "RPC runtime is closed",
|
|
15213
|
+
failed: "RPC call failed",
|
|
15214
|
+
conflict: "RPC command identity conflicts with an existing record",
|
|
15215
|
+
expired: "RPC command result has expired",
|
|
15216
|
+
pending: "RPC command is still pending",
|
|
15217
|
+
rejected: "RPC command was rejected",
|
|
15218
|
+
missing: "RPC command has no stored result",
|
|
15219
|
+
storage_failure: "RPC command storage failed",
|
|
15220
|
+
deadlock: "RPC call chain would deadlock",
|
|
15221
|
+
call_depth_exceeded: "RPC call depth exceeded",
|
|
15222
|
+
undeclared: "RPC service is not declared by the manifest",
|
|
15223
|
+
unavailable: "RPC service is unavailable",
|
|
15224
|
+
ambiguous_placement: "RPC service placement is ambiguous",
|
|
15225
|
+
invalid_registration: "RPC registration is invalid"
|
|
15226
|
+
};
|
|
15227
|
+
var SERVICE_ERROR_CODES = new Set(Object.keys(SERVICE_ERROR_MESSAGES));
|
|
15228
|
+
var EMPTY_OPTIONS = Object.freeze({});
|
|
15229
|
+
var FRAME_STORE = new AsyncLocalStorage;
|
|
15230
|
+
var CALLEE_INFO = new WeakMap;
|
|
15231
|
+
// packages/core/src/plugin-services/peer-channel-protocol.ts
|
|
15232
|
+
var CHANNEL_REQUEST_MAX_BYTES = 4 * 1024;
|
|
15233
|
+
var CHANNEL_RESULT_MAX_BYTES = 60 * 1024;
|
|
15234
|
+
var CHANNEL_MAX_CHUNK_BYTES = 60 * 1024;
|
|
15235
|
+
var PLUGIN_CHANNEL_LANES = Object.freeze(["event", "snapshot", "stream"]);
|
|
15236
|
+
var ERROR_CODES = new Set([
|
|
15237
|
+
"unavailable",
|
|
15238
|
+
"ambiguous",
|
|
15239
|
+
"unauthorized",
|
|
15240
|
+
"invalid",
|
|
15241
|
+
"overloaded",
|
|
15242
|
+
"expired",
|
|
15243
|
+
"conflict",
|
|
15244
|
+
"gap",
|
|
15245
|
+
"truncated",
|
|
15246
|
+
"rejected",
|
|
15247
|
+
"cancelled",
|
|
15248
|
+
"closed",
|
|
15249
|
+
"unknown",
|
|
15250
|
+
"failed"
|
|
15251
|
+
]);
|
|
15252
|
+
var RPC_CALL_PURPOSES2 = new Set(["bootstrap", "background", "management", "request", "attempt"]);
|
|
15253
|
+
|
|
15254
|
+
// packages/core/src/plugin-services/peer-channel-hub.ts
|
|
15255
|
+
var CHANNEL_MAX_TRANSFER_BUFFER_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
|
|
15256
|
+
var CHANNEL_MAX_TOTAL_BUFFER_BYTES = 16 * CHANNEL_MAX_CHUNK_BYTES;
|
|
15257
|
+
var CHANNEL_STREAM_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
15258
|
+
var CHANNEL_STREAM_MAX_CREDIT_BYTES = 8 * CHANNEL_MAX_CHUNK_BYTES;
|
|
15259
|
+
var CHANNEL_STREAM_DEFAULT_CREDIT_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
|
|
15260
|
+
var CHANNEL_SNAPSHOT_MAX_BYTES = 64 * 1024 * 1024;
|
|
15261
|
+
var CHANNEL_EVENT_MAX_PAYLOAD_BYTES = 60 * 1024;
|
|
15262
|
+
var EMPTY = new Uint8Array(0);
|
|
15263
|
+
var HANDLE_REGISTRATIONS = new WeakMap;
|
|
15264
|
+
|
|
15265
|
+
// packages/core/src/plugin-services/snapshot-store.ts
|
|
15266
|
+
var DEFAULT_CHUNK_BYTES = 60 * 1024;
|
|
15267
|
+
var SNAPSHOT_FAMILY_REFS = new Map;
|
|
15268
|
+
|
|
15269
|
+
// packages/core/src/plugin-services.ts
|
|
15270
|
+
var CHANNEL_KINDS = new Set(["events", "snapshot", "stream"]);
|
|
15271
|
+
var TOKEN_METERING_SERVICE_ID = "token-metering.v1";
|
|
15272
|
+
var TOKEN_METERING_CONTRACT_VERSION = 1;
|
|
15273
|
+
var TOKEN_PRICING_SERVICE_ID = "token-stats.pricing.v1";
|
|
15274
|
+
var TOKEN_PRICING_CONTRACT_VERSION = 1;
|
|
15275
|
+
|
|
15276
|
+
// plugins/token-budget/server/rpc.ts
|
|
15277
|
+
var command = { deduplication: "none", resultRetentionMs: null, quotaBytes: 65536, maxResultBytes: 65536 };
|
|
15278
|
+
var businessRpc = defineRpcService({ id: "token-budget.admission.v1", version: 1, methods: {
|
|
15279
|
+
prepare: { kind: "command", input: { type: "object", properties: { snapshot: { type: "json" } } }, output: { type: "json" }, purposes: ["attempt"], command, timeoutMs: 15000 },
|
|
15280
|
+
status: { kind: "query", input: { type: "null" }, output: { type: "json" }, purposes: ["attempt"], timeoutMs: 15000 },
|
|
15281
|
+
cancel: { kind: "command", input: { type: "object", properties: { sent: { type: "literal", value: false } } }, output: { type: "json" }, purposes: ["attempt"], command, timeoutMs: 15000 },
|
|
15282
|
+
settle: { kind: "command", input: { type: "object", properties: { result: { type: "json" }, costNanoUsd: { type: "union", variants: [{ type: "null" }, { type: "number", integer: true, minimum: 0 }] } }, optional: ["costNanoUsd"] }, output: { type: "json" }, purposes: ["attempt"], command, timeoutMs: 15000 }
|
|
15283
|
+
} });
|
|
15284
|
+
|
|
14773
15285
|
// packages/core/src/logger.ts
|
|
14774
15286
|
var import_winston = __toESM(require_winston());
|
|
14775
15287
|
var import_winston_daily_rotate_file = __toESM(require_winston_daily_rotate_file());
|
|
@@ -14823,12 +15335,6 @@ function definePlugin(plugin) {
|
|
|
14823
15335
|
return plugin;
|
|
14824
15336
|
}
|
|
14825
15337
|
|
|
14826
|
-
// packages/core/src/plugin-services.ts
|
|
14827
|
-
var TOKEN_METERING_SERVICE_ID = "token-metering.v1";
|
|
14828
|
-
var TOKEN_METERING_CONTRACT_VERSION = 1;
|
|
14829
|
-
var TOKEN_PRICING_SERVICE_ID = "token-stats.pricing.v1";
|
|
14830
|
-
var TOKEN_PRICING_CONTRACT_VERSION = 1;
|
|
14831
|
-
|
|
14832
15338
|
// plugins/token-budget/server/policy.ts
|
|
14833
15339
|
function usdToNanoUsd(value) {
|
|
14834
15340
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || Number(value.toFixed(6)) !== value)
|
|
@@ -14907,7 +15413,7 @@ function createIngress() {
|
|
|
14907
15413
|
function createBudgetConsumer(service, pricing) {
|
|
14908
15414
|
return {
|
|
14909
15415
|
async prepareAdmissionAttempt(input) {
|
|
14910
|
-
const { target, snapshot,
|
|
15416
|
+
const { target, snapshot, callBudget } = input;
|
|
14911
15417
|
if (!snapshot)
|
|
14912
15418
|
return {};
|
|
14913
15419
|
if (snapshot.keyId !== target.principal.keyId || snapshot.requestId !== target.requestId)
|
|
@@ -14922,7 +15428,7 @@ function createBudgetConsumer(service, pricing) {
|
|
|
14922
15428
|
if (price && Number.isSafeInteger(price.costNanoUsd) && price.costNanoUsd >= 0)
|
|
14923
15429
|
costNanoUsd = price.costNanoUsd;
|
|
14924
15430
|
} catch {}
|
|
14925
|
-
await
|
|
15431
|
+
await callBudget("settle", { result: JSON.parse(JSON.stringify(result)), costNanoUsd });
|
|
14926
15432
|
settled = true;
|
|
14927
15433
|
unsubscribe();
|
|
14928
15434
|
} });
|
|
@@ -14939,13 +15445,13 @@ function createBudgetConsumer(service, pricing) {
|
|
|
14939
15445
|
return { denial: { error: "token-budget.unpriceable", status: 422 } };
|
|
14940
15446
|
}
|
|
14941
15447
|
}
|
|
14942
|
-
await
|
|
15448
|
+
await callBudget("prepare", { snapshot });
|
|
14943
15449
|
} catch {
|
|
14944
15450
|
unsubscribe();
|
|
14945
15451
|
return { denial: { error: "token-budget.prepare_failed", status: 503 } };
|
|
14946
15452
|
}
|
|
14947
15453
|
const cancel = async () => {
|
|
14948
|
-
await
|
|
15454
|
+
await callBudget("cancel", { sent: false });
|
|
14949
15455
|
unsubscribe();
|
|
14950
15456
|
};
|
|
14951
15457
|
return { cancel, async onResult(result) {
|
|
@@ -14955,7 +15461,7 @@ function createBudgetConsumer(service, pricing) {
|
|
|
14955
15461
|
}
|
|
14956
15462
|
await service.drainRequest(target.requestId);
|
|
14957
15463
|
if (!settled) {
|
|
14958
|
-
await
|
|
15464
|
+
await callBudget("settle", { result: { requestId: target.requestId, attemptId: target.attemptId, routeId: target.routeId, upstreamId: target.upstreamId, provider: "unknown", inputSource: "none", outputSource: "none", inputAuthority: "none", outputAuthority: "none", complete: false, observationIncomplete: true, outcome: "failed", finishedAtMs: Date.now(), settlementVersion: 1 }, costNanoUsd: null });
|
|
14959
15465
|
unsubscribe();
|
|
14960
15466
|
}
|
|
14961
15467
|
} };
|
|
@@ -14963,6 +15469,7 @@ function createBudgetConsumer(service, pricing) {
|
|
|
14963
15469
|
};
|
|
14964
15470
|
}
|
|
14965
15471
|
var server_default = definePlugin(class {
|
|
15472
|
+
static admissionRpcContract = businessRpc;
|
|
14966
15473
|
static name = "token-budget";
|
|
14967
15474
|
static version = "1.0.0";
|
|
14968
15475
|
consumer;
|
|
@@ -14986,4 +15493,4 @@ export {
|
|
|
14986
15493
|
server_default as default
|
|
14987
15494
|
};
|
|
14988
15495
|
|
|
14989
|
-
//# debugId=
|
|
15496
|
+
//# debugId=D3B8F2328107322464756E2164756E21
|