
























@@ -37,21 +37,145 @@ function readBudgetEnv(name, fallback) {
3737return parsed;
3838}
393940+function readEntrypointBudgetEnv(name, fallback) {
41+const raw = process.env[name];
42+if (raw === undefined) {
43+return fallback;
44+}
45+let parsed;
46+try {
47+parsed = JSON.parse(raw);
48+} catch {
49+throw new Error(`${name} must be a JSON object of entrypoint integer budgets`);
50+}
51+if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
52+throw new Error(`${name} must be a JSON object of entrypoint integer budgets`);
53+}
54+55+const overrides = {};
56+for (const [entrypoint, value] of Object.entries(parsed)) {
57+if (!Number.isSafeInteger(value) || value < 0) {
58+throw new Error(`${name}.${entrypoint} must be a safe non-negative integer`);
59+}
60+overrides[entrypoint] = value;
61+}
62+return Object.freeze({ ...fallback, ...overrides });
63+}
64+65+const defaultPublicDeprecatedExportsByEntrypointBudget = Object.freeze({
66+core: 2,
67+lmstudio: 1,
68+"provider-setup": 1,
69+"self-hosted-provider-setup": 14,
70+routing: 1,
71+runtime: 3,
72+"runtime-logger": 3,
73+"runtime-secret-resolution": 5,
74+"setup-adapter-runtime": 1,
75+"channel-streaming": 47,
76+"approval-reply-runtime": 1,
77+"config-runtime": 123,
78+"config-contracts": 1,
79+"config-types": 415,
80+"config-schema": 3,
81+"reply-dedupe": 1,
82+"inbound-reply-dispatch": 33,
83+"channel-reply-pipeline": 12,
84+"channel-reply-options-runtime": 2,
85+"channel-runtime": 144,
86+"interactive-runtime": 13,
87+"outbound-send-deps": 4,
88+"outbound-runtime": 16,
89+"file-access-runtime": 2,
90+"infra-runtime": 570,
91+"ssrf-policy": 1,
92+"ssrf-runtime": 1,
93+"media-runtime": 2,
94+"text-runtime": 188,
95+"agent-runtime": 7,
96+"plugin-runtime": 13,
97+"channel-secret-runtime": 23,
98+"secret-file-runtime": 1,
99+"security-runtime": 7,
100+"agent-harness": 7,
101+"agent-harness-runtime": 7,
102+types: 6,
103+"agent-config-primitives": 2,
104+"command-auth": 81,
105+compat: 152,
106+"direct-dm": 9,
107+"direct-dm-access": 5,
108+discord: 48,
109+mattermost: 7,
110+matrix: 1,
111+"channel-config-schema-legacy": 22,
112+"channel-actions": 2,
113+"channel-envelope": 3,
114+"channel-inbound": 21,
115+"channel-inbound-roots": 1,
116+"channel-logging": 4,
117+"channel-location": 4,
118+"channel-mention-gating": 7,
119+"channel-lifecycle": 23,
120+"channel-ingress": 8,
121+"channel-message": 228,
122+"channel-message-runtime": 225,
123+"channel-pairing-paths": 1,
124+"channel-policy": 8,
125+"channel-route": 5,
126+"session-store-runtime": 1,
127+"group-access": 13,
128+"media-generation-runtime-shared": 3,
129+"music-generation-core": 20,
130+"reply-history": 8,
131+"messaging-targets": 12,
132+"memory-core": 45,
133+"memory-core-engine-runtime": 15,
134+"memory-core-host-multimodal": 3,
135+"memory-core-host-query": 2,
136+"memory-core-host-events": 11,
137+"memory-core-host-status": 1,
138+"memory-core-host-runtime-core": 1,
139+"memory-host-core": 1,
140+"memory-host-files": 7,
141+"memory-host-status": 72,
142+"provider-auth": 20,
143+"provider-oauth-runtime": 2,
144+"provider-auth-login": 3,
145+"provider-model-shared": 29,
146+"provider-stream-family": 40,
147+"provider-stream-shared": 28,
148+"provider-stream": 40,
149+"provider-web-search": 1,
150+"provider-zai-endpoint": 3,
151+"telegram-account": 3,
152+"telegram-command-config": 7,
153+"webhook-ingress": 2,
154+"webhook-path": 2,
155+zalouser: 5,
156+zod: 282,
157+});
158+40159let budgets;
160+let publicDeprecatedExportsByEntrypointBudget;
41161try {
42162budgets = {
43-publicEntrypoints: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_ENTRYPOINTS", 308),
44-publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 9920),
45-publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5031),
163+publicEntrypoints: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_ENTRYPOINTS", 319),
164+publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 10269),
165+publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5159),
46166publicDeprecatedExports: readBudgetEnv(
47167"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_DEPRECATED_EXPORTS",
48-3143,
168+3230,
49169),
50170publicWildcardReexports: readBudgetEnv(
51171"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_WILDCARD_REEXPORTS",
52172215,
53173),
54174};
175+publicDeprecatedExportsByEntrypointBudget = readEntrypointBudgetEnv(
176+"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_DEPRECATED_EXPORTS_BY_ENTRYPOINT",
177+defaultPublicDeprecatedExportsByEntrypointBudget,
178+);
55179} catch (error) {
56180console.error(error instanceof Error ? error.message : String(error));
57181process.exit(1);
@@ -194,6 +318,19 @@ function formatStats(label, stats) {
194318].join("\n");
195319}
196320321+function collectDeprecatedEntrypointBudgetFailures(byEntrypoint) {
322+const failures = [];
323+for (const [entrypoint, stats] of byEntrypoint) {
324+const budget = publicDeprecatedExportsByEntrypointBudget[entrypoint] ?? 0;
325+if (stats.deprecatedExports > budget) {
326+failures.push(
327+`public deprecated exports in ${entrypoint} ${stats.deprecatedExports} > ${budget}`,
328+);
329+}
330+}
331+return failures;
332+}
333+197334const allStats = collectExportStats(pluginSdkEntrypoints);
198335const publicStats = collectExportStats(publicPluginSdkEntrypoints);
199336const localOnlyStats = collectExportStats(privateLocalOnlyPluginSdkEntrypoints);
@@ -246,6 +383,7 @@ if (publicStats.totals.deprecatedExports > budgets.publicDeprecatedExports) {
246383`public deprecated exports ${publicStats.totals.deprecatedExports} > ${budgets.publicDeprecatedExports}`,
247384);
248385}
386+failures.push(...collectDeprecatedEntrypointBudgetFailures(publicStats.byEntrypoint));
249387if (publicWildcards.count > budgets.publicWildcardReexports) {
250388failures.push(
251389`public wildcard reexports ${publicWildcards.count} > ${budgets.publicWildcardReexports}`,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。