mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor: burn wrapper shadowing baseline entries (#122040)
* refactor: burn wrapper shadowing entries * chore: refresh wrapper shadowing baselines * test: update secrets runtime state mocks * fix(ci): absorb Control UI build identity variance
This commit is contained in:
committed by
GitHub
parent
b30e0dc4c6
commit
db73b59c04
+20
-20
@@ -3,12 +3,12 @@
|
||||
{"contentHash":"0d6827cdd7180482c49dc67aacc2b512e587d3453536081c15d3febaea2f1492","entrypoint":"account-id","importSpecifier":"openclaw/plugin-sdk/account-id"}
|
||||
{"contentHash":"0b4930a77ab3e63bed21a9651a23fb7130f623baf6ce153166cb80a965b0a004","entrypoint":"account-resolution","importSpecifier":"openclaw/plugin-sdk/account-resolution"}
|
||||
{"contentHash":"0349da0a93dadbdcff03ae8064b5066c5f2e1c28ee298bfa9ab3f1f8563300eb","entrypoint":"agent-config-primitives","importSpecifier":"openclaw/plugin-sdk/agent-config-primitives"}
|
||||
{"contentHash":"b6c5507d2fc6a0467480a468d1131efba94faef5284b78d2dd3e7b8cb2fd3105","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"}
|
||||
{"contentHash":"ec417e2b535f930d1c9d52e4a64375327913b9b92022c583a2e7f7a1ea7a4b25","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"}
|
||||
{"contentHash":"bf900891a3c6ee746fdf5033882e8ca88bc03ae0b2c971bb5977c0f0db506506","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"}
|
||||
{"contentHash":"4f8b570b60781e746c19cd370d5c5967ad68047b255e81fd29d0dff95bfc9f3e","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"}
|
||||
{"contentHash":"4387e74b1261f632a0e140276c0f8cbbbe848a11f7ad287325538ebbee3b09da","entrypoint":"agent-media-payload","importSpecifier":"openclaw/plugin-sdk/agent-media-payload"}
|
||||
{"contentHash":"b065a946eca85d03276bc0f6b1c04af1e44ee4ce441e5a5477f13d13aa3de17b","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"}
|
||||
{"contentHash":"6fe3155f10712bc5d001f1f69e502f3e1a0b4179bb5ed7100d0ca7df933085be","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"}
|
||||
{"contentHash":"1f0e51c8b1a58fff13ab7d19806d97bf07fca61a5c7edeb3437cd805775a8320","entrypoint":"agent-scope-runtime","importSpecifier":"openclaw/plugin-sdk/agent-scope-runtime"}
|
||||
{"contentHash":"ce460dee97b375e50944f4da2ac95fe4c7a3f7be6b435550f54088b16369ed49","entrypoint":"allow-from","importSpecifier":"openclaw/plugin-sdk/allow-from"}
|
||||
{"contentHash":"1f45bc7ea08bd3029e9a6bfd723f930324df2e7da79e1bd81bfb02f50c57362a","entrypoint":"allow-from","importSpecifier":"openclaw/plugin-sdk/allow-from"}
|
||||
{"contentHash":"c19f8658d0db60b1d3eddfeae9639ca6558592d7d69c6905ab2994b4a572f25b","entrypoint":"allowlist-config-edit","importSpecifier":"openclaw/plugin-sdk/allowlist-config-edit"}
|
||||
{"contentHash":"2800815b9a0dac84fccd0b946bc938ba31ba3915990b899b0ebce3b80744ed47","entrypoint":"approval-auth-runtime","importSpecifier":"openclaw/plugin-sdk/approval-auth-runtime"}
|
||||
{"contentHash":"6fef2bb5627a1f9de6bad01c0ba0d15a4fb64a0f3310c26f1c2cbce67088516c","entrypoint":"approval-client-runtime","importSpecifier":"openclaw/plugin-sdk/approval-client-runtime"}
|
||||
@@ -26,19 +26,19 @@
|
||||
{"contentHash":"222019df4c06aca4e9bbede0fdea4b946f9b024a1524e3837c3c13be6d3d9e6a","entrypoint":"channel-config-primitives","importSpecifier":"openclaw/plugin-sdk/channel-config-primitives"}
|
||||
{"contentHash":"645ec473e40a04e4cc627d05c9156f66d835eb67dab32166f745f66eadc98880","entrypoint":"channel-config-schema","importSpecifier":"openclaw/plugin-sdk/channel-config-schema"}
|
||||
{"contentHash":"75935c1d837265d191436d43bbfe24c6328b35a45a68cad250c157923badf857","entrypoint":"channel-contract","importSpecifier":"openclaw/plugin-sdk/channel-contract"}
|
||||
{"contentHash":"d1d17e04a95ebb93d4213caa49e214b9da55163465474c33a42cfab27dd855ee","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"}
|
||||
{"contentHash":"28666b0cf5d0bdf28648baffffcf1239e4d27727408c785fa06f5c271fc0843a","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"}
|
||||
{"contentHash":"b2d90f161ca88ef2d5ff35f87f160c772bd784a4ebda91b2ab33bf16b6abd843","entrypoint":"channel-dm-policy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy"}
|
||||
{"contentHash":"571b88343e5e7028d2dc8a414d3c7c6cfc26c4fe72c296258e615a308fc1b6d5","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"}
|
||||
{"contentHash":"49a549e6a39d55279ecafe650e7e00496ebd6da5266cb11e486f5ee19f53b4c1","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"}
|
||||
{"contentHash":"8bc8b784c78a70ee58731aae0be9731c9af01705db00acbafa25de9745a23601","entrypoint":"channel-feedback","importSpecifier":"openclaw/plugin-sdk/channel-feedback"}
|
||||
{"contentHash":"6da95ea5bb2850b714f47387e1e970b761ac64d02e40531e797d0584e2c6434d","entrypoint":"channel-inbound","importSpecifier":"openclaw/plugin-sdk/channel-inbound"}
|
||||
{"contentHash":"99cee44d09759fdbb01bc1b50e430933c61c745ec3c7880ea7e2aa63b382c673","entrypoint":"channel-inbound","importSpecifier":"openclaw/plugin-sdk/channel-inbound"}
|
||||
{"contentHash":"87ba6e4e9f2f56621f6d52cc262e8b80fada5e338e841439b4d20983e22dfb82","entrypoint":"channel-inbound-debounce","importSpecifier":"openclaw/plugin-sdk/channel-inbound-debounce"}
|
||||
{"contentHash":"7a69b23fdd7b631ed407d9ae4af55df192d93b61488c81626f041d4199760d95","entrypoint":"channel-ingress-runtime","importSpecifier":"openclaw/plugin-sdk/channel-ingress-runtime"}
|
||||
{"contentHash":"85afc43170761c8d7d6d2d91401b0ad033189636050e8cf85d22132e4aba9f1a","entrypoint":"channel-lifecycle","importSpecifier":"openclaw/plugin-sdk/channel-lifecycle"}
|
||||
{"contentHash":"be803c0341214a8e731f98cb7bf98654410ab1e0254d90f9f1ad9f442f70669f","entrypoint":"channel-logging","importSpecifier":"openclaw/plugin-sdk/channel-logging"}
|
||||
{"contentHash":"97e407fc8124084452fee297707490622f529565f4ca6f7dbc306b189db429ab","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"}
|
||||
{"contentHash":"37a8bcb4eadeb02a4b71ebfa56e0a3d97efd52dd63f066a29766880abcb01146","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"}
|
||||
{"contentHash":"970ba9dd27f5e4d6a09b0ffec37264cdb3f745a5934e2cb8cc53eee78f2c176a","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"}
|
||||
{"contentHash":"574fa42cccdf71a38cb19a0662dacbcbd94486069f01fda496e950384897ddbf","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"}
|
||||
{"contentHash":"fee97710da33e100a8987aed897be17ab3ec4ece9fa09b7eb871a90461c8fca3","entrypoint":"channel-pairing","importSpecifier":"openclaw/plugin-sdk/channel-pairing"}
|
||||
{"contentHash":"1c135098d104d0b73b95b3fc41ba2c27e6eca836cbb16e21601452219d4d8099","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"}
|
||||
{"contentHash":"897b21d2b152cacd699378eabe938caaee71171ec4002a3dd6dd42efabcda0f7","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"}
|
||||
{"contentHash":"350b4986aec115e3674c9dd3712302e7c185dbefc534b65a98a6a84564e65e05","entrypoint":"channel-policy","importSpecifier":"openclaw/plugin-sdk/channel-policy"}
|
||||
{"contentHash":"369721c067caf33fc86e50c7dd5aec3e8371d2e97e2e3c4305751b79da9e7387","entrypoint":"channel-reply-pipeline","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline"}
|
||||
{"contentHash":"5181d3f1c6936e1e13a7d3ab4b904f5ae929a1985480c130915710a9bf8e8a25","entrypoint":"channel-runtime-context","importSpecifier":"openclaw/plugin-sdk/channel-runtime-context"}
|
||||
@@ -60,12 +60,12 @@
|
||||
{"contentHash":"1deb735b023442072fe21294cf4f94af0e44356fd8591ed6a8a9befafc7c3d67","entrypoint":"config-mutation","importSpecifier":"openclaw/plugin-sdk/config-mutation"}
|
||||
{"contentHash":"40df7e972484ae28718fef1095b2b44cb2cc9eadd35464bf28d4ae0d0f0f66b5","entrypoint":"config-runtime","importSpecifier":"openclaw/plugin-sdk/config-runtime"}
|
||||
{"contentHash":"7a5a2f4d3e5e18d211480286d125419ecbf8175bb6f8eeee9a6ee105df03cb3f","entrypoint":"conversation-runtime","importSpecifier":"openclaw/plugin-sdk/conversation-runtime"}
|
||||
{"contentHash":"ace1613bc3d78ac0daeb15bd9c2c048e5916ac2279095813e72b5ddfcfe68e60","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"}
|
||||
{"contentHash":"db165d4f6bdb943dae0cb3015cafcb6d94d2482fff712eda98eb5442d418b095","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"}
|
||||
{"contentHash":"184f6a3849b361adfc9db756699787e934e274f05eeedcda04cd2b7cb4f9fe5e","entrypoint":"dedupe-runtime","importSpecifier":"openclaw/plugin-sdk/dedupe-runtime"}
|
||||
{"contentHash":"8ba476d7f0411071797cd4362f3a71720d9d008d54107b2cb4eccb4a4eb0db0a","entrypoint":"device-bootstrap","importSpecifier":"openclaw/plugin-sdk/device-bootstrap"}
|
||||
{"contentHash":"cb6fbd1612e60755c7528a5243cec69c9123904297d2e16a9c716485785be532","entrypoint":"diagnostic-runtime","importSpecifier":"openclaw/plugin-sdk/diagnostic-runtime"}
|
||||
{"contentHash":"f7b6949b179827646d4e047ce4f181550ca8d67bd4537441405d36fb79438556","entrypoint":"directory-runtime","importSpecifier":"openclaw/plugin-sdk/directory-runtime"}
|
||||
{"contentHash":"ef6120fc7033025caad534b2ab4edbdffde2088e0019654fe8334c9e012917b6","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"}
|
||||
{"contentHash":"4b32922587dab4f465f85b7fea02e3b64d89ebea73a496501aa3c59fa7ef6337","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"}
|
||||
{"contentHash":"e0523b4936d7c7ec043265de9e2a8f6289d32dacba0a28c3999ba3a0975dfc21","entrypoint":"error-runtime","importSpecifier":"openclaw/plugin-sdk/error-runtime"}
|
||||
{"contentHash":"5125d71bf8c4aeca728c4b8c73b2984247ba7bcc088a45ee29692ff64e3ebf90","entrypoint":"extension-shared","importSpecifier":"openclaw/plugin-sdk/extension-shared"}
|
||||
{"contentHash":"cbeb81159a1e558846f3cf9eecf3fd5a84858029cfdd9ccf237af428e35e755c","entrypoint":"gateway-method-runtime","importSpecifier":"openclaw/plugin-sdk/gateway-method-runtime"}
|
||||
@@ -75,7 +75,7 @@
|
||||
{"contentHash":"273ebd4fcac3041e3a136410fa396b9704c73eedb66414723996127ed80db8f3","entrypoint":"hook-runtime","importSpecifier":"openclaw/plugin-sdk/hook-runtime"}
|
||||
{"contentHash":"a6537713e63d101897ef9ddfeaae438a50645e2672be5bdced887c4e8a651b96","entrypoint":"inbound-envelope","importSpecifier":"openclaw/plugin-sdk/inbound-envelope"}
|
||||
{"contentHash":"931a52a774750ab895236a8fa7851781ad0279cb5678b1a78e81af9dd25bb3a4","entrypoint":"inbound-event-delivery","importSpecifier":"openclaw/plugin-sdk/inbound-event-delivery"}
|
||||
{"contentHash":"699bafa75513e6fffb80ecfc0ccc3f0746fdf291f570e128a1ddfa09c2fac97d","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"}
|
||||
{"contentHash":"c1acc4ca962cb62ae6036308b6d90c2e018420cf8b0f12594b2b876f5a5b0ca2","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"}
|
||||
{"contentHash":"b590647f65a2e148ba7a1bc207f70adbd3a57990b41d3bf6b10f61ee8f27ab87","entrypoint":"infra-runtime","importSpecifier":"openclaw/plugin-sdk/infra-runtime"}
|
||||
{"contentHash":"41a1f24a1b745f833d44e622ae1922c9dc66ee5de56f0e967ec1a3f9e03a2d18","entrypoint":"ingress-effect-once","importSpecifier":"openclaw/plugin-sdk/ingress-effect-once"}
|
||||
{"contentHash":"57f79c6e8db72b2806bc8c016066682de71bf690378ccb4403b8da6dd3d38b28","entrypoint":"interactive-runtime","importSpecifier":"openclaw/plugin-sdk/interactive-runtime"}
|
||||
@@ -89,7 +89,7 @@
|
||||
{"contentHash":"0df97720dfd7b1a5892bbf3d46bc64297468af9b8cbb8720ce0d80d42ff2e59d","entrypoint":"media-store","importSpecifier":"openclaw/plugin-sdk/media-store"}
|
||||
{"contentHash":"684c061bb0d1112872c9b2d5a00e258d14b4ff8649a26dd0cc67995352d8ca8b","entrypoint":"media-understanding","importSpecifier":"openclaw/plugin-sdk/media-understanding"}
|
||||
{"contentHash":"f48e34067ab9b25a232af71d8ce17f9cbf9165ebce0832deaae3c1d9c9aeaab7","entrypoint":"media-understanding-runtime","importSpecifier":"openclaw/plugin-sdk/media-understanding-runtime"}
|
||||
{"contentHash":"98583ac36cd86b8533f323c2cdb76deb3803b23e10e2fc2cfc177ed7f47d6522","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"}
|
||||
{"contentHash":"18782530d1c5bb66e086dd0177eb8ee52d152805aa68932a945fbc35178c3b03","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"}
|
||||
{"contentHash":"27509d9bbabc547662a45bf258fa432d1e0c3c3f7c22051858d8a67375486e79","entrypoint":"memory-core-host-engine-foundation","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation"}
|
||||
{"contentHash":"ad875662e95df74808357c234ac36825d1ff729165da941180061591525ff47f","entrypoint":"memory-host-core","importSpecifier":"openclaw/plugin-sdk/memory-host-core"}
|
||||
{"contentHash":"0f140018c2c21965b6a8f7a2ac1882babcaf70e733b477bb693e498641629938","entrypoint":"messaging-targets","importSpecifier":"openclaw/plugin-sdk/messaging-targets"}
|
||||
@@ -101,10 +101,10 @@
|
||||
{"contentHash":"3b2106094ccada38a6736f39abbb5814e776638cdb7f1f6d065576e6f8a2d3b6","entrypoint":"persistent-dedupe","importSpecifier":"openclaw/plugin-sdk/persistent-dedupe"}
|
||||
{"contentHash":"e43fcfe8f88cf8d338c3e3496f3bdd6ec14afc1fcf341e171f7758f5c0190d5b","entrypoint":"plugin-command-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime"}
|
||||
{"contentHash":"756175b7ff16cd8456b3c85a87466f077476a9236e098c5545ea8ef31fcff0d2","entrypoint":"plugin-config-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-config-runtime"}
|
||||
{"contentHash":"e898b4f42be94df7004177ecfe78d9f07eb5ea7156563f9c3d998ce1a9109d67","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"}
|
||||
{"contentHash":"998e819896710d288c7eb70eda60d0b2a6e78ad5a196abd67df6644178f73daf","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"}
|
||||
{"contentHash":"3f92b4ce6954e9bbe85a7675f7ad000e01e6b34049523a9a3e38d23966ad959a","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"}
|
||||
{"contentHash":"60b7d6caebf369d35a367e431f77eb3f7e5437870ef1da5f024ea8c71217b1cb","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"}
|
||||
{"contentHash":"d5d21f2a0883eac72d6642d93306c36e2de0f3851286eb3edbe3a2d9d6122dcc","entrypoint":"provider-auth","importSpecifier":"openclaw/plugin-sdk/provider-auth"}
|
||||
{"contentHash":"62853769aed0937975c704dfef003559b5e9a48ae809cc5f0a1e53632ba17ff7","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"}
|
||||
{"contentHash":"36aad63a3fda1116df864fcdaa3c26d2c0d7af809603d3d4afaf96dcccdd8391","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"}
|
||||
{"contentHash":"aee2a235e7218ed4ba36e80e0a6d67ceb3b5de448f25ebc10d6f70552dc35b8a","entrypoint":"proxy-capture","importSpecifier":"openclaw/plugin-sdk/proxy-capture"}
|
||||
{"contentHash":"55bc0be5ce1d700d8b671efccb69ec14a3c942535c2f77d3ed7ca87809dc1ad9","entrypoint":"question-gateway-runtime","importSpecifier":"openclaw/plugin-sdk/question-gateway-runtime"}
|
||||
{"contentHash":"5263836c817c9391fd5a0efdda50552330dd01e4d6bc9cb4ebba58627c48f098","entrypoint":"reply-chunking","importSpecifier":"openclaw/plugin-sdk/reply-chunking"}
|
||||
@@ -142,11 +142,11 @@
|
||||
{"contentHash":"09957526abf9619fd2ef095119a7195f2bebf2d8e8b1a5605aee0868152f8b5c","entrypoint":"temp-path","importSpecifier":"openclaw/plugin-sdk/temp-path"}
|
||||
{"contentHash":"4519df78f420290da1fd755f7e4a7de7d09dbc934b3e17fc139aaf64896ffa06","entrypoint":"text-chunking","importSpecifier":"openclaw/plugin-sdk/text-chunking"}
|
||||
{"contentHash":"c5f29e3b48cb9a92111bf565f739875a32fc3e19a009dd0bab3c27bbb71f7583","entrypoint":"text-runtime","importSpecifier":"openclaw/plugin-sdk/text-runtime"}
|
||||
{"contentHash":"4ce582ca52fde9a7281dcdd3b4b2d3ade5c248a524ceac6049a5f3868da8d81a","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"}
|
||||
{"contentHash":"39bc2bdca81266a16eab23271664ad8cbffdf2fc9b7f0f1d04c98c2611c53c5d","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"}
|
||||
{"contentHash":"17e58e27b06e2470908acd719f64ec2add1f117c1882adad79eb5a3b5bd74312","entrypoint":"tool-results","importSpecifier":"openclaw/plugin-sdk/tool-results"}
|
||||
{"contentHash":"aabfb4eacce1bd5190b2f92189332abe7bbe3a5cea3655babe66bf1909206984","entrypoint":"tool-send","importSpecifier":"openclaw/plugin-sdk/tool-send"}
|
||||
{"contentHash":"8d432f42395afae27f4a95c897dfca0bf5df6289c0846d326df424ad5f6b491b","entrypoint":"web-media","importSpecifier":"openclaw/plugin-sdk/web-media"}
|
||||
{"contentHash":"e16eaf86f2bc171afd654f94fdfac5a396ef1371109f0c399fe607345e6de1cf","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"}
|
||||
{"contentHash":"fa8effcbdf093c93d07526b1655ed5941fd277e484a55e680ad84874a8323867","entrypoint":"web-media","importSpecifier":"openclaw/plugin-sdk/web-media"}
|
||||
{"contentHash":"1600c91e3364cf9bd9cceaec9403f3c96503a145620e18a30502af3b53571e4c","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"}
|
||||
{"contentHash":"1fe8314d4dfa3d7b536f39ac5622ff688f6a20fa6ae8b8fa4770d4851e85a400","entrypoint":"webhook-request-guards","importSpecifier":"openclaw/plugin-sdk/webhook-request-guards"}
|
||||
{"contentHash":"6091f4048c4464103dfdf659904c6afa6e29c483b9a05c502ab3333df08f942b","entrypoint":"widget-html","importSpecifier":"openclaw/plugin-sdk/widget-html"}
|
||||
{"contentHash":"eafdc7277066acf893bfef9b635689c1a69d6d5af22ad8cee2b47351d9b53ca6","entrypoint":"zod","importSpecifier":"openclaw/plugin-sdk/zod"}
|
||||
|
||||
@@ -23,6 +23,10 @@ const DEFAULT_STARTUP_BUDGET_BASELINE_PATH = path.resolve(
|
||||
// fixed JS ceiling bounds cumulative creep.
|
||||
export const CONTROL_UI_STARTUP_JS_GZIP_TOLERANCE_BYTES = 1024;
|
||||
|
||||
// The startup bundle embeds commit SHA and timestamp identity. Those fixed-length,
|
||||
// high-entropy values move Linux gzip output by tens of bytes between identical builds.
|
||||
export const CONTROL_UI_STARTUP_JS_GZIP_IDENTITY_VARIANCE_BYTES = 64;
|
||||
|
||||
// Small, explicit headroom over the optimized baseline. Budget changes should
|
||||
// accompany an intentional loading or chunking decision.
|
||||
const controlUiPerformanceBudgets = {
|
||||
@@ -146,10 +150,13 @@ export function evaluateControlUiPerformanceBudgets(
|
||||
startupBudgetBaseline: Readonly<ControlUiStartupBudgetBaseline> | null = null,
|
||||
startupJsTolerance = CONTROL_UI_STARTUP_JS_GZIP_TOLERANCE_BYTES,
|
||||
) {
|
||||
const startupJsFixedLimit =
|
||||
budgets.startupJsGzipBytes +
|
||||
(startupBudgetBaseline ? CONTROL_UI_STARTUP_JS_GZIP_IDENTITY_VARIANCE_BYTES : 0);
|
||||
const checks: Array<[string, number, number, "count" | "bytes"]> = [
|
||||
["startup JS requests", metrics.startup.js.requests, budgets.startupJsRequests, "count"],
|
||||
["startup CSS requests", metrics.startup.css.requests, budgets.startupCssRequests, "count"],
|
||||
["startup JS gzip", metrics.startup.js.gzipBytes, budgets.startupJsGzipBytes, "bytes"],
|
||||
["startup JS gzip", metrics.startup.js.gzipBytes, startupJsFixedLimit, "bytes"],
|
||||
["startup CSS gzip", metrics.startup.css.gzipBytes, budgets.startupCssGzipBytes, "bytes"],
|
||||
["largest JS gzip", metrics.largest.js.gzipBytes, budgets.largestJsGzipBytes, "bytes"],
|
||||
["largest CSS gzip", metrics.largest.css.gzipBytes, budgets.largestCssGzipBytes, "bytes"],
|
||||
@@ -226,7 +233,7 @@ export function formatControlUiPerformanceReport(
|
||||
];
|
||||
if (startupBudgetBaseline) {
|
||||
lines.push(
|
||||
` startup JS gzip vs baseline: ${metrics.startup.js.gzipBytes} B (baseline ${startupBudgetBaseline.startupJsGzipBytes} B + tolerance ${startupJsTolerance} B, ceiling ${budgets.startupJsGzipBytes} B)`,
|
||||
` startup JS gzip vs baseline: ${metrics.startup.js.gzipBytes} B (baseline ${startupBudgetBaseline.startupJsGzipBytes} B + tolerance ${startupJsTolerance} B, ceiling ${budgets.startupJsGzipBytes} B + build-identity variance ${CONTROL_UI_STARTUP_JS_GZIP_IDENTITY_VARIANCE_BYTES} B)`,
|
||||
);
|
||||
}
|
||||
lines.push(
|
||||
|
||||
@@ -7,13 +7,6 @@
|
||||
],
|
||||
"sdk": true
|
||||
},
|
||||
{
|
||||
"name": "clearSecretsRuntimeSnapshot",
|
||||
"files": [
|
||||
"src/secrets/runtime-state.ts",
|
||||
"src/secrets/runtime.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "createPluginLoaderLogger",
|
||||
"files": [
|
||||
|
||||
@@ -1,157 +1,4 @@
|
||||
[
|
||||
{
|
||||
"name": "buildConfigSchema",
|
||||
"wrapped": "src/config/schema.ts",
|
||||
"wrapper": "src/config/doc-baseline.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "buildShouldSuppressBuiltInModel",
|
||||
"wrapped": "src/agents/model-suppression.ts",
|
||||
"wrapper": "src/agents/model-suppression.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "clearRuntimeAuthProfileStoreSnapshot",
|
||||
"wrapped": "src/agents/auth-profiles/runtime-snapshots.ts",
|
||||
"wrapper": "src/agents/auth-profiles/store.ts"
|
||||
},
|
||||
{
|
||||
"name": "clearSecretsRuntimeSnapshot",
|
||||
"wrapped": "src/secrets/runtime-state.ts",
|
||||
"wrapper": "src/secrets/runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "collectBundledChannelConfigs",
|
||||
"wrapped": "src/plugins/bundled-channel-config-metadata.ts",
|
||||
"wrapper": "src/config/doc-baseline.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "collectChannelSchemaMetadata",
|
||||
"wrapped": "src/config/channel-config-metadata.ts",
|
||||
"wrapper": "src/config/doc-baseline.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "collectChannelSecurityFindings",
|
||||
"wrapped": "src/security/audit-channel.ts",
|
||||
"wrapper": "src/security/audit-channel.collect.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "collectPluginSchemaMetadata",
|
||||
"wrapped": "src/config/channel-config-metadata.ts",
|
||||
"wrapper": "src/config/doc-baseline.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "createAgentHarnessToolSurfaceRuntime",
|
||||
"wrapped": "src/agents/harness/tool-surface-bridge.ts",
|
||||
"wrapper": "src/plugin-sdk/agent-harness-tool-runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "createChannelPluginBase",
|
||||
"wrapped": "src/plugin-sdk/core.ts",
|
||||
"wrapper": "src/plugin-sdk/channel-core.ts"
|
||||
},
|
||||
{
|
||||
"name": "createDeferred",
|
||||
"wrapped": "src/shared/deferred.ts",
|
||||
"wrapper": "src/plugin-sdk/extension-shared.ts"
|
||||
},
|
||||
{
|
||||
"name": "DEFAULT_PROGRESS_DRAFT_LABELS",
|
||||
"wrapped": "src/shared/progress-labels.ts",
|
||||
"wrapper": "src/channels/streaming.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActivePluginRegistryWorkspaceDirFromState",
|
||||
"wrapped": "src/plugins/runtime-workspace-state.ts",
|
||||
"wrapper": "src/plugins/runtime-state.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActiveRuntimeWebToolsMetadata",
|
||||
"wrapped": "src/secrets/runtime-web-tools-state.ts",
|
||||
"wrapper": "src/secrets/runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActiveSecretsRuntimeEnv",
|
||||
"wrapped": "src/secrets/runtime-state.ts",
|
||||
"wrapper": "src/secrets/runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActiveSecretsRuntimeSnapshotRevision",
|
||||
"wrapped": "src/secrets/runtime-state.ts",
|
||||
"wrapper": "src/secrets/runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActiveSecretsRuntimeSnapshot",
|
||||
"wrapped": "src/secrets/runtime-state.ts",
|
||||
"wrapper": "src/secrets/runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "getActiveSkillEnvKeys",
|
||||
"wrapped": "src/skills/runtime/env-overrides.ts",
|
||||
"wrapper": "src/skills/runtime/env-overrides.runtime.ts"
|
||||
},
|
||||
{
|
||||
"name": "getApiKeyForModel",
|
||||
"wrapped": "src/agents/model-auth-model.ts",
|
||||
"wrapper": "src/plugins/runtime/runtime-model-auth.runtime.ts",
|
||||
"via": "src/agents/model-auth.ts"
|
||||
},
|
||||
{
|
||||
"name": "getCoreCliCommandNames",
|
||||
"wrapped": "src/cli/program/core-command-descriptors.ts",
|
||||
"wrapper": "src/cli/program/command-registry-core.ts"
|
||||
},
|
||||
{
|
||||
"name": "getDefaultLocalRoots",
|
||||
"wrapped": "src/media/local-media-access.ts",
|
||||
"wrapper": "src/plugins/runtime/runtime-web-channel-plugin.ts",
|
||||
"via": "src/media/web-media.ts"
|
||||
},
|
||||
{
|
||||
"name": "getDiagnosticSessionStateCountForTest",
|
||||
"wrapped": "src/logging/diagnostic-session-state.ts",
|
||||
"wrapper": "src/logging/diagnostic.ts"
|
||||
},
|
||||
{
|
||||
"name": "getPreparedRuntimeAuthProfileStoreSnapshot",
|
||||
"wrapped": "src/agents/auth-profiles/runtime-snapshots.ts",
|
||||
"wrapper": "src/agents/auth-profiles/store.ts"
|
||||
},
|
||||
{
|
||||
"name": "getRuntimeAuthProfileStoreSnapshot",
|
||||
"wrapped": "src/agents/auth-profiles/runtime-snapshots.ts",
|
||||
"wrapper": "src/agents/auth-profiles/store.ts"
|
||||
},
|
||||
{
|
||||
"name": "getSubCliEntries",
|
||||
"wrapped": "src/cli/program/subcli-descriptors.ts",
|
||||
"wrapper": "src/cli/program/register.subclis-core.ts"
|
||||
},
|
||||
{
|
||||
"name": "hasExplicitPluginConfig",
|
||||
"wrapped": "src/plugins/config-normalization-shared.ts",
|
||||
"wrapper": "src/plugins/config-state.ts"
|
||||
},
|
||||
{
|
||||
"name": "isAllowedParsedChatSender",
|
||||
"wrapped": "src/channels/plugins/chat-target-prefixes.ts",
|
||||
"wrapper": "src/plugin-sdk/allow-from.ts"
|
||||
},
|
||||
{
|
||||
"name": "isBundledChannelEnabledByChannelConfig",
|
||||
"wrapped": "src/plugins/config-normalization-shared.ts",
|
||||
"wrapper": "src/plugins/config-state.ts"
|
||||
},
|
||||
{
|
||||
"name": "isMissingPathError",
|
||||
"wrapped": "src/infra/errno.ts",
|
||||
"wrapper": "src/plugin-sdk/memory-host-event-export.ts",
|
||||
"via": "src/infra/errors.ts"
|
||||
},
|
||||
{
|
||||
"name": "listAuthProfileStoreAgentDirs",
|
||||
"wrapped": "src/secrets/auth-store-paths.ts",
|
||||
"wrapper": "src/secrets/storage-scan.ts"
|
||||
},
|
||||
{
|
||||
"name": "loadBundledPluginPublicSurfaceModuleSync",
|
||||
"wrapped": "src/plugin-sdk/facade-loader.ts",
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
saveAuthProfileStore,
|
||||
} from "./auth-profiles.js";
|
||||
import { isLiveTestEnabled, readLiveTestConfig } from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { getApiKeyForModelCore, requireApiKey } from "./model-auth.js";
|
||||
import { normalizeProviderId, parseModelRef } from "./model-selection.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
@@ -205,7 +205,7 @@ describeLive("live anthropic setup-token", () => {
|
||||
);
|
||||
}
|
||||
|
||||
const apiKeyInfo = await getApiKeyForModel({
|
||||
const apiKeyInfo = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
profileId: tokenSource.profileId,
|
||||
|
||||
@@ -40,7 +40,7 @@ import { assertNoOAuthSecretRefPolicyViolations } from "./policy.js";
|
||||
import { clearLastGoodProfileWithLock } from "./profiles.js";
|
||||
import { suggestOAuthProfileIdForLegacyDefault } from "./repair.js";
|
||||
import {
|
||||
getRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
hasRuntimeAuthProfileStoreSnapshot,
|
||||
setRuntimeAuthProfileStoreSnapshot,
|
||||
} from "./runtime-snapshots.js";
|
||||
@@ -311,7 +311,7 @@ function resolveRuntimeAuthProfile(params: {
|
||||
profile: AuthProfileCredential;
|
||||
defaults: SecretDefaults | undefined;
|
||||
}): { profile: AuthProfileCredential; published: boolean } {
|
||||
const runtimeProfile = getRuntimeAuthProfileStoreSnapshot(params.agentDir)?.profiles[
|
||||
const runtimeProfile = getRuntimeAuthProfileStoreSnapshotCore(params.agentDir)?.profiles[
|
||||
params.profileId
|
||||
];
|
||||
const inputRefKey = authProfileSecretRefKey(params.profile, params.defaults);
|
||||
@@ -514,7 +514,7 @@ export async function resolveApiKeyForProfile(
|
||||
params.agentDir !== ownerAgentDir &&
|
||||
hasRuntimeAuthProfileStoreSnapshot(params.agentDir)
|
||||
) {
|
||||
const snapshot = getRuntimeAuthProfileStoreSnapshot(params.agentDir);
|
||||
const snapshot = getRuntimeAuthProfileStoreSnapshotCore(params.agentDir);
|
||||
const providerKey = resolveProviderIdForAuth(cred.provider);
|
||||
if (snapshot?.lastGood?.[providerKey] === profileId) {
|
||||
delete snapshot.lastGood[providerKey];
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
} from "./profiles.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
getRuntimeAuthProfileStoreSnapshot as getInternalRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshotCore as getInternalRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreCredentialMutationToken,
|
||||
getRuntimeAuthProfileStoreCredentialsRevision,
|
||||
getRuntimeAuthProfileStoreStateMutationToken,
|
||||
|
||||
@@ -12,10 +12,10 @@ import {
|
||||
revokeRuntimeAuthMaterializations,
|
||||
} from "./runtime-materializations.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshot,
|
||||
clearRuntimeAuthProfileStoreSnapshotCore,
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
getPreparedRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshot,
|
||||
getPreparedRuntimeAuthProfileStoreSnapshotCore,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
getRuntimeAuthProfileStoreCredentialsRevision,
|
||||
noteRuntimeAuthProfileStorePersistedMutation,
|
||||
registerRuntimeAuthProfileStoreMutationListener,
|
||||
@@ -171,7 +171,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
},
|
||||
agentDir,
|
||||
);
|
||||
clearRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
clearRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
|
||||
expect(listener).toHaveBeenCalledTimes(2);
|
||||
expect(listener).toHaveBeenNthCalledWith(1, {
|
||||
@@ -223,7 +223,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
try {
|
||||
setRuntimeAuthProfileStoreSnapshot(emptyStore, agentDir);
|
||||
setRuntimeAuthProfileStoreSnapshot(emptyStore, agentDir);
|
||||
clearRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
clearRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
|
||||
expect(listener).toHaveBeenCalledTimes(2);
|
||||
expect(listener).toHaveBeenNthCalledWith(1, {
|
||||
@@ -268,7 +268,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
).provider = "mutated";
|
||||
expectDefined(stored.order?.openai, "stored OpenAI profile order").push("mutated");
|
||||
|
||||
const first = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const first = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
expectOpenAICodexSnapshotCredential(first, { access: "access-1" });
|
||||
expect(first?.order?.["openai"]).toEqual(["openai:default"]);
|
||||
|
||||
@@ -280,7 +280,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
"first OpenAI usage stats",
|
||||
).lastUsed = 99;
|
||||
|
||||
const second = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const second = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
expectOpenAICodexSnapshotCredential(second, { access: "access-1" });
|
||||
expect(second?.usageStats?.["openai:default"]?.lastUsed).toBe(1);
|
||||
|
||||
@@ -292,7 +292,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
replacementCredential.access = "mutated-replacement";
|
||||
}
|
||||
|
||||
const replaced = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const replaced = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
expectOpenAICodexSnapshotCredential(replaced, {
|
||||
access: "access-2",
|
||||
refresh: "refresh-access-2",
|
||||
@@ -324,7 +324,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
);
|
||||
setRuntimeAuthProfileStoreSnapshot(createStore("agent"), agentDir);
|
||||
|
||||
const prepared = getPreparedRuntimeAuthProfileStoreSnapshot(agentDir, inheritedAuthDir);
|
||||
const prepared = getPreparedRuntimeAuthProfileStoreSnapshotCore(agentDir, inheritedAuthDir);
|
||||
|
||||
expectOpenAICodexSnapshotCredential(prepared, { access: "agent" });
|
||||
expect(prepared?.profiles["anthropic:default"]).toMatchObject({
|
||||
@@ -333,7 +333,7 @@ describe("runtime auth profile snapshots", () => {
|
||||
key: "inherited-key",
|
||||
});
|
||||
expect(
|
||||
getPreparedRuntimeAuthProfileStoreSnapshot(
|
||||
getPreparedRuntimeAuthProfileStoreSnapshotCore(
|
||||
"/tmp/openclaw-auth-runtime-missing",
|
||||
"/tmp/openclaw-auth-runtime-also-missing",
|
||||
),
|
||||
@@ -351,13 +351,15 @@ describe("runtime auth profile snapshots", () => {
|
||||
setRuntimeAuthProfileStoreSnapshot(createStore("first"), firstAgentDir);
|
||||
setRuntimeAuthProfileStoreSnapshot(createStore("second"), secondAgentDir);
|
||||
|
||||
expect(clearRuntimeAuthProfileStoreSnapshot(firstAgentDir)).toBe(true);
|
||||
expect(getRuntimeAuthProfileStoreSnapshot(firstAgentDir)).toBeUndefined();
|
||||
expectOpenAICodexSnapshotCredential(getRuntimeAuthProfileStoreSnapshot(), { access: "main" });
|
||||
expectOpenAICodexSnapshotCredential(getRuntimeAuthProfileStoreSnapshot(secondAgentDir), {
|
||||
expect(clearRuntimeAuthProfileStoreSnapshotCore(firstAgentDir)).toBe(true);
|
||||
expect(getRuntimeAuthProfileStoreSnapshotCore(firstAgentDir)).toBeUndefined();
|
||||
expectOpenAICodexSnapshotCredential(getRuntimeAuthProfileStoreSnapshotCore(), {
|
||||
access: "main",
|
||||
});
|
||||
expectOpenAICodexSnapshotCredential(getRuntimeAuthProfileStoreSnapshotCore(secondAgentDir), {
|
||||
access: "second",
|
||||
});
|
||||
expect(clearRuntimeAuthProfileStoreSnapshot(firstAgentDir)).toBe(false);
|
||||
expect(clearRuntimeAuthProfileStoreSnapshotCore(firstAgentDir)).toBe(false);
|
||||
} finally {
|
||||
clearRuntimeAuthProfileStoreSnapshots();
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ export function registerRuntimeAuthProfileStoreMutationListener(
|
||||
}
|
||||
|
||||
/** Reads a cloned runtime auth profile store snapshot for an agent dir. */
|
||||
export function getRuntimeAuthProfileStoreSnapshot(
|
||||
export function getRuntimeAuthProfileStoreSnapshotCore(
|
||||
agentDir?: string,
|
||||
): RuntimeAuthProfileStore | undefined {
|
||||
const store = runtimeAuthStoreSnapshots.get(resolveRuntimeStoreKey(agentDir));
|
||||
@@ -245,12 +245,12 @@ export function getRuntimeAuthProfileStoreSnapshot(
|
||||
* Reads the effective prepared auth store without falling back to persisted storage.
|
||||
* Lifecycle consumers use this after auth publication so request paths never reopen SQLite.
|
||||
*/
|
||||
export function getPreparedRuntimeAuthProfileStoreSnapshot(
|
||||
export function getPreparedRuntimeAuthProfileStoreSnapshotCore(
|
||||
agentDir?: string,
|
||||
inheritedAuthDir?: string,
|
||||
): AuthProfileStore | undefined {
|
||||
const inherited = getRuntimeAuthProfileStoreSnapshot(inheritedAuthDir);
|
||||
const requested = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const inherited = getRuntimeAuthProfileStoreSnapshotCore(inheritedAuthDir);
|
||||
const requested = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
if (!agentDir || resolveRuntimeStoreKey(agentDir) === resolveRuntimeStoreKey(inheritedAuthDir)) {
|
||||
return requested ?? inherited;
|
||||
}
|
||||
@@ -280,14 +280,14 @@ export function hasRuntimeAuthProfileStoreSnapshot(agentDir?: string): boolean {
|
||||
|
||||
/** Returns true when requested or main runtime snapshots contain profiles. */
|
||||
export function hasAnyRuntimeAuthProfileStoreSource(agentDir?: string): boolean {
|
||||
const requestedStore = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const requestedStore = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
if (requestedStore && Object.keys(requestedStore.profiles).length > 0) {
|
||||
return true;
|
||||
}
|
||||
if (!agentDir) {
|
||||
return false;
|
||||
}
|
||||
const mainStore = getRuntimeAuthProfileStoreSnapshot();
|
||||
const mainStore = getRuntimeAuthProfileStoreSnapshotCore();
|
||||
return Boolean(mainStore && Object.keys(mainStore.profiles).length > 0);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ export function clearRuntimeAuthProfileStoreSnapshots(): void {
|
||||
}
|
||||
|
||||
/** Clears one runtime auth-profile snapshot without disturbing other active agents. */
|
||||
export function clearRuntimeAuthProfileStoreSnapshot(agentDir?: string): boolean {
|
||||
export function clearRuntimeAuthProfileStoreSnapshotCore(agentDir?: string): boolean {
|
||||
const key = resolveRuntimeStoreKey(agentDir);
|
||||
const store = runtimeAuthStoreSnapshots.get(key);
|
||||
if (!store) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { evaluateStoredCredentialEligibility } from "./credential-state.js";
|
||||
import { hasLegacyAuthProfileCredentialSource } from "./legacy-source-diagnostic.js";
|
||||
import { coercePersistedAuthProfileStore } from "./persisted.js";
|
||||
import {
|
||||
getRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
hasAnyRuntimeAuthProfileStoreSource,
|
||||
} from "./runtime-snapshots.js";
|
||||
import {
|
||||
@@ -116,7 +116,7 @@ export function hasAnyAuthProfileStoreSource(agentDir?: string): boolean {
|
||||
|
||||
/** Returns true when the requested agent dir has a local auth profile source. */
|
||||
export function hasLocalAuthProfileStoreSource(agentDir?: string): boolean {
|
||||
const runtimeStore = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const runtimeStore = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
if (runtimeStore && Object.keys(runtimeStore.profiles).length > 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ export function hasAuthProfileStoreSourceForProvider(
|
||||
if (profileIds?.length === 0) {
|
||||
return false;
|
||||
}
|
||||
const localRuntimeStore = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const localRuntimeStore = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
if (runtimeStoreHasProviderProfile(localRuntimeStore, provider, profileIds)) {
|
||||
return true;
|
||||
}
|
||||
@@ -164,7 +164,7 @@ export function hasAuthProfileStoreSourceForProvider(
|
||||
if (!agentDir) {
|
||||
return false;
|
||||
}
|
||||
const mainRuntimeStore = getRuntimeAuthProfileStoreSnapshot();
|
||||
const mainRuntimeStore = getRuntimeAuthProfileStoreSnapshotCore();
|
||||
if (runtimeStoreHasProviderProfile(mainRuntimeStore, provider, profileIds)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ import {
|
||||
mergeAuthProfileStores,
|
||||
} from "./persisted.js";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshot as clearRuntimeAuthProfileStoreSnapshotImpl,
|
||||
clearRuntimeAuthProfileStoreSnapshotCore,
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
getPreparedRuntimeAuthProfileStoreSnapshot as getPreparedRuntimeAuthProfileStoreSnapshotImpl,
|
||||
getRuntimeAuthProfileStoreSnapshot as getRuntimeAuthProfileStoreSnapshotImpl,
|
||||
getPreparedRuntimeAuthProfileStoreSnapshotCore,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
getRuntimeAuthProfileStoreSnapshotRevision,
|
||||
noteRuntimeAuthProfileStorePersistedMutation,
|
||||
listRuntimeAuthProfileStoreSnapshots,
|
||||
@@ -282,8 +282,8 @@ function resolveRuntimeAuthProfileStore(
|
||||
): AuthProfileStore | null {
|
||||
const mainKey = resolveAuthStorePath(options?.inheritedAuthDir);
|
||||
const requestedKey = resolveAuthStorePath(agentDir);
|
||||
const mainStore = getRuntimeAuthProfileStoreSnapshotImpl(options?.inheritedAuthDir);
|
||||
const requestedStore = getRuntimeAuthProfileStoreSnapshotImpl(agentDir);
|
||||
const mainStore = getRuntimeAuthProfileStoreSnapshotCore(options?.inheritedAuthDir);
|
||||
const requestedStore = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
|
||||
if (!agentDir || requestedKey === mainKey) {
|
||||
if (!mainStore) {
|
||||
@@ -1317,7 +1317,7 @@ export {
|
||||
export function getRuntimeAuthProfileStoreSnapshot(
|
||||
agentDir?: string,
|
||||
): AuthProfileStore | undefined {
|
||||
return getRuntimeAuthProfileStoreSnapshotImpl(agentDir);
|
||||
return getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
}
|
||||
|
||||
/** Return the lifecycle-published effective auth store without persisted fallback reads. */
|
||||
@@ -1325,14 +1325,14 @@ export function getPreparedRuntimeAuthProfileStoreSnapshot(
|
||||
agentDir?: string,
|
||||
inheritedAuthDir?: string,
|
||||
): AuthProfileStore | undefined {
|
||||
return getPreparedRuntimeAuthProfileStoreSnapshotImpl(agentDir, inheritedAuthDir);
|
||||
return getPreparedRuntimeAuthProfileStoreSnapshotCore(agentDir, inheritedAuthDir);
|
||||
}
|
||||
|
||||
export { getRuntimeAuthProfileStoreSnapshotRevision };
|
||||
|
||||
/** Clear one runtime auth-profile snapshot. */
|
||||
export function clearRuntimeAuthProfileStoreSnapshot(agentDir?: string): boolean {
|
||||
return clearRuntimeAuthProfileStoreSnapshotImpl(agentDir);
|
||||
return clearRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
}
|
||||
|
||||
function saveAuthProfileStoreInTransaction(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ManagedRun } from "../process/supervisor/index.js";
|
||||
import type { SpawnInput } from "../process/supervisor/types.js";
|
||||
import { createDeferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import type { DeliveryContext } from "../utils/delivery-context.types.js";
|
||||
import { markBackgrounded } from "./bash-process-registry.js";
|
||||
import { runExecProcess } from "./bash-tools.exec-runtime.js";
|
||||
@@ -14,7 +14,7 @@ export async function startDeferredNotifyRun(params: {
|
||||
sessionKey: string;
|
||||
notifyDeliveryContext?: DeliveryContext;
|
||||
}) {
|
||||
const exit = createDeferred<Awaited<ReturnType<ManagedRun["wait"]>>>();
|
||||
const exit = createDeferredCore<Awaited<ReturnType<ManagedRun["wait"]>>>();
|
||||
params.spawn.mockImplementationOnce(async (input) => {
|
||||
input.onStdout?.("producer output\n");
|
||||
return {
|
||||
|
||||
@@ -137,7 +137,7 @@ vi.mock("./model-auth.js", () => ({
|
||||
ensureAuthProfileStore: (...args: unknown[]) => ensureAuthProfileStoreMock(...args),
|
||||
ensureAuthProfileStoreWithoutExternalProfiles: (...args: unknown[]) =>
|
||||
ensureAuthProfileStoreWithoutExternalProfilesMock(...args),
|
||||
getApiKeyForModel: (...args: unknown[]) => getApiKeyForModelMock(...args),
|
||||
getApiKeyForModelCore: (...args: unknown[]) => getApiKeyForModelMock(...args),
|
||||
hasUsableCustomProviderApiKey: (...args: unknown[]) => hasUsableCustomProviderApiKeyMock(...args),
|
||||
requireApiKey: (...args: unknown[]) => requireApiKeyMock(...args),
|
||||
resolveProviderEntryApiKeyProfileReference: (params: unknown) =>
|
||||
|
||||
@@ -781,7 +781,7 @@ export async function loadCompactHooksHarness(): Promise<{
|
||||
(auth: { mode: string; source: string }, provider: string) =>
|
||||
`No API key resolved for provider "${provider}" (auth mode: ${auth.mode}, checked: ${auth.source}).`,
|
||||
),
|
||||
getApiKeyForModel: (params: { profileId?: string; allowAuthProfileFallback?: boolean }) =>
|
||||
getApiKeyForModelCore: (params: { profileId?: string; allowAuthProfileFallback?: boolean }) =>
|
||||
getApiKeyForModelMock(params),
|
||||
hasUsableCustomProviderApiKey: vi.fn(() => false),
|
||||
resolveProviderEntryApiKeyProfileReference: resolveProviderEntryApiKeyProfileReferenceMock,
|
||||
|
||||
@@ -1004,7 +1004,7 @@ export async function loadRunOverflowCompactionHarness(): Promise<{
|
||||
ensureAuthProfileStore: mockedEnsureAuthProfileStore,
|
||||
ensureAuthProfileStoreWithoutExternalProfiles:
|
||||
mockedEnsureAuthProfileStoreWithoutExternalProfiles,
|
||||
getApiKeyForModel: mockedGetApiKeyForModel,
|
||||
getApiKeyForModelCore: mockedGetApiKeyForModel,
|
||||
hasUsableCustomProviderApiKey: mockedHasUsableCustomProviderApiKey,
|
||||
resolveAuthProfileOrder: mockedResolveAuthProfileOrder,
|
||||
resolveAuthProfileOrderWithMetadata: mockedResolveAuthProfileOrderWithMetadata,
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { RuntimeAuthState } from "./helpers.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
prepareProviderRuntimeAuth: vi.fn(),
|
||||
getApiKeyForModel: vi.fn(),
|
||||
getApiKeyForModelCore: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../../../plugins/provider-runtime.js", async () => {
|
||||
@@ -32,7 +32,7 @@ vi.mock("../../model-auth.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../model-auth.js")>("../../model-auth.js");
|
||||
return {
|
||||
...actual,
|
||||
getApiKeyForModel: mocks.getApiKeyForModel,
|
||||
getApiKeyForModelCore: mocks.getApiKeyForModelCore,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -165,7 +165,7 @@ function createMutableEmbeddedRunAuthController(params: {
|
||||
describe("createEmbeddedRunAuthController", () => {
|
||||
beforeEach(() => {
|
||||
mocks.prepareProviderRuntimeAuth.mockReset();
|
||||
mocks.getApiKeyForModel.mockReset();
|
||||
mocks.getApiKeyForModelCore.mockReset();
|
||||
});
|
||||
|
||||
it("commits a prepared route only after its credential resolves", async () => {
|
||||
@@ -176,7 +176,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
baseUrl: "https://chatgpt.com/backend-api/codex",
|
||||
contextWindow: 272_000,
|
||||
};
|
||||
mocks.getApiKeyForModel.mockImplementation(async ({ model }) => {
|
||||
mocks.getApiKeyForModelCore.mockImplementation(async ({ model }) => {
|
||||
expect(model).toBe(selectedModel);
|
||||
expect(harness.runtimeModel).not.toBe(selectedModel);
|
||||
return {
|
||||
@@ -210,7 +210,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
it("rejects credentials whose class does not match the prepared route", async () => {
|
||||
const harness = createMutableAuthControllerHarness();
|
||||
const commit = vi.fn();
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: "platform-key",
|
||||
mode: "api-key",
|
||||
source: "config",
|
||||
@@ -243,7 +243,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const harness = createMutableAuthControllerHarness();
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: "source-api-key",
|
||||
mode: "api-key",
|
||||
profileId: "default",
|
||||
@@ -268,7 +268,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
|
||||
await controller.initializeAuthProfile();
|
||||
|
||||
const apiKeyParams = mocks.getApiKeyForModel.mock.calls.at(0)?.[0] as
|
||||
const apiKeyParams = mocks.getApiKeyForModelCore.mock.calls.at(0)?.[0] as
|
||||
| { agentDir?: string; workspaceDir?: string }
|
||||
| undefined;
|
||||
expect(apiKeyParams?.agentDir).toBe("/tmp/agent");
|
||||
@@ -296,7 +296,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
refKeys: ["env:default:MISSING_OPENAI_KEY"],
|
||||
reason: "secret reference was not found",
|
||||
});
|
||||
mocks.getApiKeyForModel.mockImplementation(async ({ profileId }) => {
|
||||
mocks.getApiKeyForModelCore.mockImplementation(async ({ profileId }) => {
|
||||
if (profileId === "default") {
|
||||
throw unavailable;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
});
|
||||
|
||||
await expect(controller.initializeAuthProfile()).rejects.toBe(unavailable);
|
||||
expect(mocks.getApiKeyForModel).toHaveBeenCalledOnce();
|
||||
expect(mocks.getApiKeyForModelCore).toHaveBeenCalledOnce();
|
||||
expect(mocks.prepareProviderRuntimeAuth).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -328,7 +328,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
harness.effectiveModel = baseModel;
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockImplementation(async ({ profileId }) => ({
|
||||
mocks.getApiKeyForModelCore.mockImplementation(async ({ profileId }) => ({
|
||||
apiKey: `${String(profileId)}-source-key`,
|
||||
mode: "api-key" as const,
|
||||
profileId,
|
||||
@@ -376,7 +376,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
const secret = "runtime-exchange-source-secret";
|
||||
const sentinel = mintSecretSentinel(secret, { label: "model-auth:custom-openai" });
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: sentinel,
|
||||
mode: "api-key",
|
||||
source: "profile:custom-openai:default",
|
||||
@@ -395,7 +395,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const controller = createMutableEmbeddedRunAuthController({ harness, setRuntimeApiKey });
|
||||
await controller.initializeAuthProfile();
|
||||
|
||||
expect(mocks.getApiKeyForModel).toHaveBeenCalledWith(
|
||||
expect(mocks.getApiKeyForModelCore).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ secretSentinels: true }),
|
||||
);
|
||||
expect(mocks.prepareProviderRuntimeAuth).toHaveBeenCalledWith(
|
||||
@@ -415,7 +415,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const sentinel = mintSecretSentinel("runtime-source-secret", {
|
||||
label: "model-auth:custom-openai",
|
||||
});
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: sentinel,
|
||||
mode: "api-key",
|
||||
source: "profile:custom-openai:default",
|
||||
@@ -435,7 +435,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const source = mintSecretSentinel("kill-switch-source-secret", {
|
||||
label: "model-auth:custom-openai",
|
||||
});
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: source,
|
||||
mode: "api-key",
|
||||
source: "profile:custom-openai:default",
|
||||
@@ -456,7 +456,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const harness = createMutableAuthControllerHarness();
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
mode: "api-key",
|
||||
source: "models.providers.custom-openai",
|
||||
});
|
||||
@@ -561,7 +561,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
it("rejects privileged runtime transport overrides on the first auth exchange", async () => {
|
||||
let runtimeModel = createTestModel();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: "source-api-key",
|
||||
mode: "api-key",
|
||||
profileId: "default",
|
||||
@@ -642,7 +642,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
expiresAt: number;
|
||||
}>();
|
||||
|
||||
mocks.getApiKeyForModel.mockImplementation(async ({ profileId }) => {
|
||||
mocks.getApiKeyForModelCore.mockImplementation(async ({ profileId }) => {
|
||||
if (profileId === "backup") {
|
||||
return {
|
||||
apiKey: "backup-source-api-key",
|
||||
@@ -744,7 +744,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const harness = createMutableAuthControllerHarness();
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: undefined,
|
||||
mode: "aws-sdk",
|
||||
source: "aws-sdk default chain",
|
||||
@@ -774,7 +774,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const harness = createMutableAuthControllerHarness();
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: undefined,
|
||||
mode: "aws-sdk",
|
||||
source: "aws-sdk default chain",
|
||||
@@ -806,7 +806,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
refreshTimer: setTimeout(() => undefined, 60_000),
|
||||
};
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: undefined,
|
||||
mode: "aws-sdk",
|
||||
source: "aws-sdk default chain",
|
||||
@@ -834,7 +834,7 @@ describe("createEmbeddedRunAuthController", () => {
|
||||
const setRuntimeApiKey = vi.fn<(provider: string, apiKey: string) => void>();
|
||||
const warn = vi.fn<(message: string) => void>();
|
||||
|
||||
mocks.getApiKeyForModel.mockResolvedValue({
|
||||
mocks.getApiKeyForModelCore.mockResolvedValue({
|
||||
apiKey: undefined,
|
||||
mode: "aws-sdk",
|
||||
source: "aws-sdk default chain",
|
||||
|
||||
@@ -22,7 +22,7 @@ import { FailoverError, resolveFailoverStatus } from "../../failover-error.js";
|
||||
import { shouldUseTransientCooldownProbeSlot } from "../../failover-policy.js";
|
||||
import { renderAuthProfileFailoverCopy } from "../../failover/user-copy.js";
|
||||
import {
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
MissingProviderAuthError,
|
||||
type ResolvedProviderAuth,
|
||||
} from "../../model-auth.js";
|
||||
@@ -449,7 +449,7 @@ export function createEmbeddedRunAuthController(params: {
|
||||
model = params.getRuntimeModel(),
|
||||
allowAuthProfileFallback?: boolean,
|
||||
) => {
|
||||
return getApiKeyForModel({
|
||||
return getApiKeyForModelCore({
|
||||
model,
|
||||
cfg: params.config,
|
||||
profileId: candidate,
|
||||
|
||||
@@ -55,7 +55,7 @@ const agentRunAttempt = vi.fn<AgentHarness["runAttempt"]>(async () =>
|
||||
const compactAuthMocks = vi.hoisted(() => ({
|
||||
ensureAuthProfileStore: vi.fn(),
|
||||
ensureAuthProfileStoreWithoutExternalProfiles: vi.fn(),
|
||||
getApiKeyForModel: vi.fn(),
|
||||
getApiKeyForModelCore: vi.fn(),
|
||||
prepareAgentRuntimeAuth: vi.fn(),
|
||||
resolveModelAsync: vi.fn(),
|
||||
}));
|
||||
@@ -122,7 +122,7 @@ vi.mock("../model-auth.js", async (importOriginal) => ({
|
||||
ensureAuthProfileStore: compactAuthMocks.ensureAuthProfileStore,
|
||||
ensureAuthProfileStoreWithoutExternalProfiles:
|
||||
compactAuthMocks.ensureAuthProfileStoreWithoutExternalProfiles,
|
||||
getApiKeyForModel: compactAuthMocks.getApiKeyForModel,
|
||||
getApiKeyForModelCore: compactAuthMocks.getApiKeyForModelCore,
|
||||
}));
|
||||
vi.mock("../embedded-agent-runner/model.js", () => ({
|
||||
resolveModelAsync: compactAuthMocks.resolveModelAsync,
|
||||
@@ -174,7 +174,7 @@ beforeEach(async () => {
|
||||
compactAuthMocks.resolveModelAsync.mockResolvedValue({
|
||||
model: { id: "gpt-5.5", provider: "openai" },
|
||||
});
|
||||
compactAuthMocks.getApiKeyForModel.mockResolvedValue({ apiKey: "test-key" });
|
||||
compactAuthMocks.getApiKeyForModelCore.mockResolvedValue({ apiKey: "test-key" });
|
||||
providerOwnerMocks.resolveProviderRefOwnership.mockReset();
|
||||
providerOwnerMocks.resolveProviderRefOwnership.mockReturnValue({ status: "unowned" });
|
||||
contextEngineTurnAttemptMocks.drainPendingContextEngineTurnsBeforeRun
|
||||
@@ -214,7 +214,7 @@ afterEach(() => {
|
||||
agentRunAttempt.mockClear();
|
||||
compactAuthMocks.prepareAgentRuntimeAuth.mockClear();
|
||||
compactAuthMocks.resolveModelAsync.mockReset();
|
||||
compactAuthMocks.getApiKeyForModel.mockReset();
|
||||
compactAuthMocks.getApiKeyForModelCore.mockReset();
|
||||
compactAuthMocks.ensureAuthProfileStore.mockReset();
|
||||
compactAuthMocks.ensureAuthProfileStoreWithoutExternalProfiles.mockReset();
|
||||
providerOwnerMocks.resolveProviderRefOwnership.mockReset();
|
||||
@@ -2655,7 +2655,7 @@ describe("selectAgentHarness", () => {
|
||||
).resolves.toEqual({ ok: true, compacted: false });
|
||||
|
||||
expect(compactAuthMocks.resolveModelAsync).not.toHaveBeenCalled();
|
||||
expect(compactAuthMocks.getApiKeyForModel).not.toHaveBeenCalled();
|
||||
expect(compactAuthMocks.getApiKeyForModelCore).not.toHaveBeenCalled();
|
||||
expect(compact).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runtimeAuthPlan: expect.objectContaining({
|
||||
@@ -2881,7 +2881,7 @@ describe("selectAgentHarness", () => {
|
||||
});
|
||||
|
||||
it("keeps compaction recoverable when auth profile lookup fails", async () => {
|
||||
compactAuthMocks.getApiKeyForModel.mockRejectedValue(new Error("missing auth profile"));
|
||||
compactAuthMocks.getApiKeyForModelCore.mockRejectedValue(new Error("missing auth profile"));
|
||||
const compact = vi.fn<NonNullable<AgentHarness["compact"]>>(async () => ({
|
||||
ok: true,
|
||||
compacted: false,
|
||||
@@ -2958,7 +2958,7 @@ describe("selectAgentHarness", () => {
|
||||
}),
|
||||
).resolves.toEqual({ ok: true, compacted: false });
|
||||
|
||||
expect(compactAuthMocks.getApiKeyForModel).not.toHaveBeenCalled();
|
||||
expect(compactAuthMocks.getApiKeyForModelCore).not.toHaveBeenCalled();
|
||||
expect(compact).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resolvedApiKey: "already-resolved",
|
||||
@@ -3069,7 +3069,7 @@ describe("selectAgentHarness", () => {
|
||||
workspaceDir: "/tmp/workspace",
|
||||
}),
|
||||
);
|
||||
expect(compactAuthMocks.getApiKeyForModel).toHaveBeenCalledWith(
|
||||
expect(compactAuthMocks.getApiKeyForModelCore).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agentDir: expect.any(String),
|
||||
model: expect.objectContaining({
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
TOOL_SEARCH_RAW_TOOL_NAME,
|
||||
} from "../tool-search.js";
|
||||
import { testing } from "../tool-search.test-support.js";
|
||||
import { createAgentHarnessToolSurfaceRuntime as createAgentHarnessToolSurfaceRuntimeBase } from "./tool-surface-bridge.js";
|
||||
import { createAgentHarnessToolSurfaceRuntimeCore as createAgentHarnessToolSurfaceRuntimeBase } from "./tool-surface-bridge.js";
|
||||
|
||||
function createAgentHarnessToolSurfaceRuntime(
|
||||
params: Parameters<typeof createAgentHarnessToolSurfaceRuntimeBase>[0],
|
||||
|
||||
@@ -51,7 +51,7 @@ export type AgentHarnessToolSurfaceRuntime = {
|
||||
toolSearchCatalogExecutor: ToolSearchCatalogToolExecutor | undefined;
|
||||
};
|
||||
|
||||
export function createAgentHarnessToolSurfaceRuntime(params: {
|
||||
export function createAgentHarnessToolSurfaceRuntimeCore(params: {
|
||||
abortSignal?: AbortSignal;
|
||||
agentId?: string;
|
||||
config?: OpenClawConfig;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { collectProviderApiKeys } from "./live-auth-keys.js";
|
||||
import { isLiveTestEnabled } from "./live-test-helpers.js";
|
||||
import {
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
isMissingProviderAuthError,
|
||||
isProviderAuthError,
|
||||
requireApiKey,
|
||||
@@ -269,7 +269,7 @@ export async function resolveLiveDirectModelPool(params: {
|
||||
let apiKey: string;
|
||||
try {
|
||||
apiKey = requireApiKey(
|
||||
await getApiKeyForModel({
|
||||
await getApiKeyForModelCore({
|
||||
model: resolvedModel,
|
||||
cfg,
|
||||
agentDir,
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
resolveStoredCredentialReadOnlyAvailability,
|
||||
} from "./auth-profiles/read-only-availability.js";
|
||||
import type { RuntimeAuthMaterialization } from "./auth-profiles/runtime-materializations.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshot } from "./auth-profiles/runtime-snapshots.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshotCore } from "./auth-profiles/runtime-snapshots.js";
|
||||
import type { AuthProfileCredential, AuthProfileStore } from "./auth-profiles/types.js";
|
||||
import {
|
||||
isAuthCooldownBypassedForProvider,
|
||||
@@ -183,7 +183,7 @@ export function createModelAuthAvailabilityResolver(
|
||||
const runtimeStore =
|
||||
params.preparedRuntimeAuthStore ??
|
||||
(params.allowPreparedRuntimeAuth !== false
|
||||
? getRuntimeAuthProfileStoreSnapshot(params.agentDir)
|
||||
? getRuntimeAuthProfileStoreSnapshotCore(params.agentDir)
|
||||
: undefined);
|
||||
const hydratedProfileIds = new Set<string>();
|
||||
const sameSecretRef = (
|
||||
|
||||
@@ -232,7 +232,7 @@ export async function hasAvailableAuthForProvider(params: {
|
||||
}
|
||||
|
||||
/** Resolves request credentials from the provider attached to a model descriptor. */
|
||||
export async function getApiKeyForModel(params: {
|
||||
export async function getApiKeyForModelCore(params: {
|
||||
model: Model;
|
||||
cfg?: OpenClawConfig;
|
||||
profileId?: string;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { resolveInlineProviderApiKeyUsageId } from "./auth-profiles/usage.js";
|
||||
import type { ClaudeCliCredential } from "./cli-credentials.js";
|
||||
import {
|
||||
createRuntimeProviderAuthLookup,
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
hasAvailableAuthForProvider,
|
||||
hasRuntimeAvailableProviderAuth,
|
||||
isConfigBackedInlineProviderApiKey,
|
||||
@@ -403,7 +403,7 @@ async function resolveDemoLocalApiKey(params: {
|
||||
});
|
||||
}
|
||||
|
||||
describe("getApiKeyForModel", () => {
|
||||
describe("getApiKeyForModelCore", () => {
|
||||
it("reads oauth auth-profiles entries from auth-profiles.json via explicit profile", async () => {
|
||||
await withOpenClawTestState(
|
||||
{
|
||||
@@ -432,7 +432,7 @@ describe("getApiKeyForModel", () => {
|
||||
const store = ensureAuthProfileStore(process.env.OPENCLAW_AGENT_DIR, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
const apiKey = await getApiKeyForModel({
|
||||
const apiKey = await getApiKeyForModelCore({
|
||||
model,
|
||||
profileId: "openai:default",
|
||||
store,
|
||||
@@ -460,7 +460,7 @@ describe("getApiKeyForModel", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const directAuth = await getApiKeyForModel({
|
||||
const directAuth = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "chat-latest",
|
||||
provider: "openai",
|
||||
@@ -468,7 +468,7 @@ describe("getApiKeyForModel", () => {
|
||||
} as Model,
|
||||
store,
|
||||
});
|
||||
const codexAuth = await getApiKeyForModel({
|
||||
const codexAuth = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai",
|
||||
@@ -502,7 +502,7 @@ describe("getApiKeyForModel", () => {
|
||||
};
|
||||
|
||||
await expect(
|
||||
getApiKeyForModel({
|
||||
getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "chat-latest",
|
||||
provider: "openai",
|
||||
@@ -528,7 +528,7 @@ describe("getApiKeyForModel", () => {
|
||||
};
|
||||
|
||||
await expect(
|
||||
getApiKeyForModel({
|
||||
getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai",
|
||||
|
||||
@@ -179,7 +179,7 @@ let hasRuntimeAvailableProviderAuth: typeof import("./model-auth.js").hasRuntime
|
||||
let hasUsableCustomProviderApiKey: typeof import("./model-auth.js").hasUsableCustomProviderApiKey;
|
||||
let hasSyntheticLocalProviderAuthConfig: typeof import("./model-auth.js").hasSyntheticLocalProviderAuthConfig;
|
||||
let requireApiKey: typeof import("./model-auth.js").requireApiKey;
|
||||
let getApiKeyForModel: typeof import("./model-auth.js").getApiKeyForModel;
|
||||
let getApiKeyForModelCore: typeof import("./model-auth.js").getApiKeyForModelCore;
|
||||
let resolveApiKeyForProvider: typeof import("./model-auth.js").resolveApiKeyForProvider;
|
||||
let resolveAwsSdkEnvVarName: typeof import("./model-auth.js").resolveAwsSdkEnvVarName;
|
||||
let resolveModelAuthMode: typeof import("./model-auth.js").resolveModelAuthMode;
|
||||
@@ -210,7 +210,7 @@ beforeAll(async () => {
|
||||
hasAvailableAuthForProvider,
|
||||
hasRuntimeAvailableProviderAuth,
|
||||
hasSyntheticLocalProviderAuthConfig,
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
hasUsableCustomProviderApiKey,
|
||||
requireApiKey,
|
||||
resolveApiKeyForProvider,
|
||||
@@ -1586,7 +1586,7 @@ describe("resolveApiKeyForProvider", () => {
|
||||
it("preserves explicit subscription modes for literal provider credentials", async () => {
|
||||
for (const mode of ["oauth", "token"] as const) {
|
||||
const provider = `custom-${mode}`;
|
||||
const resolved = await getApiKeyForModel({
|
||||
const resolved = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "subscription-model",
|
||||
provider,
|
||||
@@ -1617,7 +1617,7 @@ describe("resolveApiKeyForProvider", () => {
|
||||
|
||||
it("does not reinterpret explicit OpenAI oauth material as a Platform API key", async () => {
|
||||
await expect(
|
||||
getApiKeyForModel({
|
||||
getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "platform-model",
|
||||
provider: "openai",
|
||||
@@ -1645,7 +1645,7 @@ describe("resolveApiKeyForProvider", () => {
|
||||
"OPENCLAW_TEST_PROVIDER_SUBSCRIPTION_TOKEN",
|
||||
"env-subscription-credential",
|
||||
async () => {
|
||||
const resolved = await getApiKeyForModel({
|
||||
const resolved = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "subscription-model",
|
||||
provider: "custom-token-env",
|
||||
@@ -1758,7 +1758,7 @@ describe("resolveApiKeyForProvider", () => {
|
||||
sourceConfig,
|
||||
);
|
||||
|
||||
const resolved = await getApiKeyForModel({
|
||||
const resolved = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "subscription-model",
|
||||
provider: "custom-oauth-ref",
|
||||
@@ -2013,7 +2013,7 @@ describe("resolveApiKeyForProvider – synthetic local auth for custom providers
|
||||
});
|
||||
|
||||
it("resolves synthetic auth when model overrides api to ollama within a non-ollama provider", async () => {
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "my-router/local-llama",
|
||||
name: "Local Llama",
|
||||
@@ -2254,7 +2254,7 @@ describe("resolveApiKeyForProvider – synthetic local auth for custom providers
|
||||
});
|
||||
|
||||
it("uses implicit aws-sdk auth for built-in Bedrock Converse models", async () => {
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "us.anthropic.claude-sonnet-4-6-v1",
|
||||
name: "Claude Sonnet",
|
||||
|
||||
@@ -12,7 +12,7 @@ export {
|
||||
applyAuthHeaderOverride,
|
||||
applyLocalNoAuthHeaderOverride,
|
||||
applySecretRefHeaderSentinels,
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
hasAvailableAuthForProvider,
|
||||
resolveModelAuthMode,
|
||||
} from "./model-auth-model.js";
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
* the full suppression implementation at module load.
|
||||
*/
|
||||
import {
|
||||
buildShouldSuppressBuiltInModel as buildShouldSuppressBuiltInModelImpl,
|
||||
buildShouldSuppressBuiltInModelCore,
|
||||
shouldSuppressBuiltInModel as shouldSuppressBuiltInModelImpl,
|
||||
} from "./model-suppression.js";
|
||||
|
||||
type ShouldSuppressBuiltInModel =
|
||||
typeof import("./model-suppression.js").shouldSuppressBuiltInModel;
|
||||
type BuildShouldSuppressBuiltInModel =
|
||||
typeof import("./model-suppression.js").buildShouldSuppressBuiltInModel;
|
||||
typeof import("./model-suppression.js").buildShouldSuppressBuiltInModelCore;
|
||||
|
||||
/** Runtime-forwarded predicate for hiding bundled models. */
|
||||
export function shouldSuppressBuiltInModel(
|
||||
@@ -24,5 +24,5 @@ export function shouldSuppressBuiltInModel(
|
||||
export function buildShouldSuppressBuiltInModel(
|
||||
...args: Parameters<BuildShouldSuppressBuiltInModel>
|
||||
): ReturnType<BuildShouldSuppressBuiltInModel> {
|
||||
return buildShouldSuppressBuiltInModelImpl(...args);
|
||||
return buildShouldSuppressBuiltInModelCore(...args);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ vi.mock("../plugins/manifest-model-suppression.js", () => ({
|
||||
import { setCurrentPluginMetadataSnapshotState } from "../plugins/current-plugin-metadata-state.js";
|
||||
import { clearPluginMetadataLifecycleCaches } from "../plugins/plugin-metadata-lifecycle.js";
|
||||
import {
|
||||
buildShouldSuppressBuiltInModel,
|
||||
buildShouldSuppressBuiltInModelCore,
|
||||
shouldSuppressBuiltInModel,
|
||||
} from "./model-suppression.js";
|
||||
|
||||
@@ -147,7 +147,7 @@ describe("model suppression", () => {
|
||||
expect(secondResolver).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
describe("buildShouldSuppressBuiltInModel", () => {
|
||||
describe("buildShouldSuppressBuiltInModelCore", () => {
|
||||
beforeEach(() => {
|
||||
mocks.buildManifestBuiltInModelSuppressionResolver.mockReset();
|
||||
});
|
||||
@@ -160,7 +160,7 @@ describe("model suppression", () => {
|
||||
const config = {};
|
||||
mocks.buildManifestBuiltInModelSuppressionResolver.mockReturnValueOnce(resolver);
|
||||
|
||||
const shouldSuppress = buildShouldSuppressBuiltInModel({ config });
|
||||
const shouldSuppress = buildShouldSuppressBuiltInModelCore({ config });
|
||||
|
||||
expect(shouldSuppress({ provider: "bedrock", id: "Claude-3" })).toBe(true);
|
||||
expect(shouldSuppress({ provider: "aws-bedrock", id: "claude-4" })).toBe(false);
|
||||
@@ -183,7 +183,7 @@ describe("model suppression", () => {
|
||||
const resolver = vi.fn();
|
||||
mocks.buildManifestBuiltInModelSuppressionResolver.mockReturnValueOnce(resolver);
|
||||
|
||||
const shouldSuppress = buildShouldSuppressBuiltInModel({});
|
||||
const shouldSuppress = buildShouldSuppressBuiltInModelCore({});
|
||||
|
||||
expect(shouldSuppress({ provider: "openai", id: "" })).toBe(false);
|
||||
expect(shouldSuppress({ provider: "", id: "gpt-5.5" })).toBe(false);
|
||||
|
||||
@@ -172,7 +172,7 @@ export function buildSuppressedBuiltInModelError(params: {
|
||||
}
|
||||
|
||||
/** Build a reusable suppression predicate for repeated catalog filtering. */
|
||||
export function buildShouldSuppressBuiltInModel(params: {
|
||||
export function buildShouldSuppressBuiltInModelCore(params: {
|
||||
config?: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
}): (input: { provider?: string | null; id?: string | null; baseUrl?: string | null }) => boolean {
|
||||
|
||||
@@ -49,7 +49,7 @@ import {
|
||||
isLiveRateLimitDrift,
|
||||
} from "./live-test-provider-drift.test-support.js";
|
||||
import {
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
requireApiKey,
|
||||
resolveUsableCustomProviderApiKey,
|
||||
} from "./model-auth.js";
|
||||
@@ -487,7 +487,7 @@ async function resolveLiveModelApiKeyInfo(params: {
|
||||
model: Model;
|
||||
cfg: OpenClawConfig;
|
||||
requireProfileKeys: boolean;
|
||||
}): Promise<Awaited<ReturnType<typeof getApiKeyForModel>>> {
|
||||
}): Promise<Awaited<ReturnType<typeof getApiKeyForModelCore>>> {
|
||||
if (isLiveLocalOllamaModel(params.model, params.cfg)) {
|
||||
const configuredKey = canReuseConfiguredLocalOllamaApiKey(params.model, params.cfg)
|
||||
? resolveUsableCustomProviderApiKey({
|
||||
@@ -508,7 +508,7 @@ async function resolveLiveModelApiKeyInfo(params: {
|
||||
mode: "api-key",
|
||||
};
|
||||
}
|
||||
return await getApiKeyForModel({
|
||||
return await getApiKeyForModelCore({
|
||||
model: params.model,
|
||||
cfg: params.cfg,
|
||||
credentialPrecedence: resolveLiveCredentialPrecedence(
|
||||
@@ -1829,7 +1829,7 @@ describeLive("live models (profile keys)", () => {
|
||||
const skipped: Array<{ model: string; reason: string }> = [];
|
||||
const candidates: Array<{
|
||||
model: Model;
|
||||
apiKeyInfo: Awaited<ReturnType<typeof getApiKeyForModel>>;
|
||||
apiKeyInfo: Awaited<ReturnType<typeof getApiKeyForModelCore>>;
|
||||
}> = [];
|
||||
|
||||
for (const model of models) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
readLiveTestConfig,
|
||||
resolveLiveCredentialPrecedence,
|
||||
} from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { getApiKeyForModelCore, requireApiKey } from "./model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
const LIVE = isLiveTestEnabled();
|
||||
@@ -118,7 +118,7 @@ describeLive("openai reasoning compat live", () => {
|
||||
|
||||
let apiKeyInfo;
|
||||
try {
|
||||
apiKeyInfo = await getApiKeyForModel({
|
||||
apiKeyInfo = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
credentialPrecedence: resolveLiveCredentialPrecedence(
|
||||
@@ -178,7 +178,7 @@ describeLive("openai reasoning compat live", () => {
|
||||
|
||||
let apiKeyInfo;
|
||||
try {
|
||||
apiKeyInfo = await getApiKeyForModel({
|
||||
apiKeyInfo = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
credentialPrecedence: resolveLiveCredentialPrecedence(
|
||||
|
||||
@@ -14,7 +14,7 @@ import { isEmbeddedMode } from "../infra/embedded-mode.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { getActiveSecretsRuntimeConfigSnapshot } from "../secrets/runtime-state.js";
|
||||
import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime-web-tools-state.js";
|
||||
import { getActiveRuntimeWebToolsMetadataFromState } from "../secrets/runtime-web-tools-state.js";
|
||||
import { isCronRunSessionKey } from "../sessions/session-key-utils.js";
|
||||
import type { SkillWorkshopRunOptions } from "../skills/workshop/types.js";
|
||||
import { resolveTranscriptsConfig } from "../transcripts/config.js";
|
||||
@@ -265,7 +265,7 @@ export function createOpenClawTools(
|
||||
// Scheduled turns keep delivery routing live, but Gateway authorization remains bound to the
|
||||
// authenticated creator account captured in the immutable scheduled authority envelope.
|
||||
const gatewayCallerAccountId = options?.gatewayCallerAccountId ?? options?.agentAccountId;
|
||||
const runtimeWebTools = getActiveRuntimeWebToolsMetadata();
|
||||
const runtimeWebTools = getActiveRuntimeWebToolsMetadataFromState();
|
||||
const sandbox =
|
||||
options?.sandboxRoot && options?.sandboxFsBridge
|
||||
? { root: options.sandboxRoot, bridge: options.sandboxFsBridge }
|
||||
|
||||
@@ -181,7 +181,7 @@ vi.mock("./auth-profiles/runtime-materializations.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("./auth-profiles/runtime-snapshots.js", () => ({
|
||||
getPreparedRuntimeAuthProfileStoreSnapshot: () => preparedModelRuntimeMocks.preparedAuthStore,
|
||||
getPreparedRuntimeAuthProfileStoreSnapshotCore: () => preparedModelRuntimeMocks.preparedAuthStore,
|
||||
getRuntimeAuthProfileStoreSnapshot: () => preparedModelRuntimeMocks.preparedAuthStore,
|
||||
getRuntimeAuthProfileStoreSnapshotRevision: () => 0,
|
||||
registerRuntimeAuthProfileStoreMutationListener: (
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { Model } from "../../llm/types.js";
|
||||
import type { AuthProfileStore } from "../auth-profiles.js";
|
||||
import { resolveAgentHarnessPreparedAuthSupport } from "../harness/support.js";
|
||||
import { getApiKeyForModel } from "../model-auth.js";
|
||||
import { getApiKeyForModelCore } from "../model-auth.js";
|
||||
import {
|
||||
agentRuntimeAuthPlanMatchesTarget,
|
||||
canRunPreparedAgentRuntimeAuthAttempt,
|
||||
@@ -1219,7 +1219,7 @@ describe("prepareAgentRuntimeAuthPlan", () => {
|
||||
maxTokens: 128_000,
|
||||
} as Model;
|
||||
const profileAttempt = prepared.attempts[0];
|
||||
const profileResolved = await getApiKeyForModel({
|
||||
const profileResolved = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg: config,
|
||||
profileId: profileAttempt?.profileId,
|
||||
@@ -1417,7 +1417,7 @@ describe("prepareAgentRuntimeAuthPlan", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = await getApiKeyForModel({
|
||||
const resolved = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
name: "GPT-5.5",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SecretSurfaceUnavailableError } from "../../secrets/runtime-degraded-st
|
||||
import { OAuthRefreshFailureError } from "../auth-profiles/oauth-refresh-failure.js";
|
||||
import type { AuthProfileStore } from "../auth-profiles/types.js";
|
||||
import { isProfileInCooldown } from "../auth-profiles/usage-state.js";
|
||||
import { getApiKeyForModel } from "../model-auth.js";
|
||||
import { getApiKeyForModelCore } from "../model-auth.js";
|
||||
import { providerModelRouteAcceptsAuthMode } from "../provider-model-route-auth.js";
|
||||
import { shouldForceDirectAuthFallbackModelResolve } from "./credential-scoped-model.js";
|
||||
import { sameAgentRuntimeAuthModelRoute } from "./model-route.js";
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import type { AgentRuntimeAuthPlan } from "./types.js";
|
||||
|
||||
type PreparedRuntimeModelAuthResolution = Readonly<{
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModel>>;
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModelCore>>;
|
||||
plan: AgentRuntimeAuthPlan;
|
||||
}>;
|
||||
|
||||
@@ -212,7 +212,7 @@ export function scopeAuthProfileStoreToPreparedPlan(
|
||||
|
||||
function applyResolvedAuthToPlan(params: {
|
||||
plan: AgentRuntimeAuthPlan;
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModel>>;
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModelCore>>;
|
||||
candidates: string[];
|
||||
}): AgentRuntimeAuthPlan {
|
||||
const profileId = params.auth.profileId?.trim();
|
||||
@@ -242,7 +242,7 @@ function applyResolvedAuthToPlan(params: {
|
||||
|
||||
function assertResolvedAuthMatchesPreparedRoute(params: {
|
||||
plan: AgentRuntimeAuthPlan;
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModel>>;
|
||||
auth: Awaited<ReturnType<typeof getApiKeyForModelCore>>;
|
||||
}): void {
|
||||
const route = params.plan.modelRoute;
|
||||
if (
|
||||
@@ -261,7 +261,7 @@ function assertResolvedAuthMatchesPreparedRoute(params: {
|
||||
|
||||
/** Resolves prepared same-route candidates without pinning the first unresolved profile. */
|
||||
export async function resolvePreparedRuntimeModelAuth(
|
||||
params: Omit<Parameters<typeof getApiKeyForModel>[0], "profileId"> & {
|
||||
params: Omit<Parameters<typeof getApiKeyForModelCore>[0], "profileId"> & {
|
||||
plan: AgentRuntimeAuthPlan;
|
||||
},
|
||||
): Promise<PreparedRuntimeModelAuthResolution> {
|
||||
@@ -275,7 +275,7 @@ export async function resolvePreparedRuntimeModelAuth(
|
||||
if (candidates.length === 0) {
|
||||
// The planner selected direct auth. Resolve only env/config material so an
|
||||
// unrelated full store cannot replace or pre-reject that immutable source.
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
...authParams,
|
||||
store: { version: 1, profiles: {} },
|
||||
lockedProfile: false,
|
||||
@@ -286,7 +286,7 @@ export async function resolvePreparedRuntimeModelAuth(
|
||||
return { auth, plan: applyResolvedAuthToPlan({ plan, auth, candidates }) };
|
||||
}
|
||||
if (plan.forwardedAuthProfileSource !== "auto") {
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
...authParams,
|
||||
profileId: plan.forwardedAuthProfileId,
|
||||
lockedProfile: Boolean(plan.forwardedAuthProfileId),
|
||||
@@ -314,7 +314,7 @@ export async function resolvePreparedRuntimeModelAuth(
|
||||
let refreshFailure: OAuthRefreshFailureError | undefined;
|
||||
for (const profileId of currentCandidates) {
|
||||
try {
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
...authParams,
|
||||
profileId,
|
||||
// This loop owns fallback order. Pin each lookup so the generic auth
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
} from "../auth-profiles/legacy-source-diagnostic.js";
|
||||
import { resolveOAuthRefreshLockPath } from "../auth-profiles/paths.js";
|
||||
import { loadPersistedAuthProfileStore } from "../auth-profiles/persisted.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshot } from "../auth-profiles/runtime-snapshots.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshotCore } from "../auth-profiles/runtime-snapshots.js";
|
||||
import {
|
||||
inspectPersistedAuthProfileStateRaw,
|
||||
inspectPersistedAuthProfileStoreRaw,
|
||||
@@ -297,7 +297,7 @@ class SqliteAuthStorageBackend implements AuthStorageBackend {
|
||||
) {}
|
||||
|
||||
private resolveMaterializedRuntimeStores(): AuthProfileStore[] {
|
||||
const current = getRuntimeAuthProfileStoreSnapshot(this.agentDir);
|
||||
const current = getRuntimeAuthProfileStoreSnapshotCore(this.agentDir);
|
||||
// A current lifecycle snapshot is authoritative, including an unresolved
|
||||
// ref after failed/revoked secrets reload. Prepared data is bootstrap-only.
|
||||
return current ? [current] : this.preparedStore ? [this.preparedStore] : [];
|
||||
@@ -446,7 +446,7 @@ export class AuthStorage {
|
||||
static forAgent(agentDir: string = getAgentDir()): AuthStorage {
|
||||
assertAuthProfileMigrationReady(agentDir);
|
||||
const preparedStore =
|
||||
getRuntimeAuthProfileStoreSnapshot(agentDir) ??
|
||||
getRuntimeAuthProfileStoreSnapshotCore(agentDir) ??
|
||||
loadAuthProfileStoreForSecretsRuntime(agentDir);
|
||||
assertAuthStorageSecretRefsMaterialized(preparedStore);
|
||||
return new AuthStorage(new SqliteAuthStorageBackend(agentDir, preparedStore), agentDir);
|
||||
|
||||
@@ -70,7 +70,7 @@ vi.mock("./model-auth.js", () => ({
|
||||
(auth: { source: string; mode: string }, provider: string) =>
|
||||
`No API key resolved for provider "${provider}" (auth mode: ${auth.mode}, checked: ${auth.source}).`,
|
||||
),
|
||||
getApiKeyForModel: hoisted.getApiKeyForModelMock,
|
||||
getApiKeyForModelCore: hoisted.getApiKeyForModelMock,
|
||||
resolveApiKeyForProvider: hoisted.getApiKeyForModelMock,
|
||||
applyLocalNoAuthHeaderOverride: hoisted.applyLocalNoAuthHeaderOverrideMock,
|
||||
}));
|
||||
@@ -478,7 +478,7 @@ describe("prepareSimpleCompletionModel", () => {
|
||||
expect(result.model.baseUrl).toBe("https://api.copilot.enterprise.example");
|
||||
});
|
||||
|
||||
it("returns error when getApiKeyForModel throws", async () => {
|
||||
it("returns error when getApiKeyForModelCore throws", async () => {
|
||||
hoisted.getApiKeyForModelMock.mockRejectedValueOnce(new Error("Profile not found: copilot"));
|
||||
|
||||
const result = await prepareSimpleCompletionModel({
|
||||
|
||||
@@ -35,7 +35,7 @@ import {
|
||||
applySecretRefHeaderSentinels,
|
||||
applyLocalNoAuthHeaderOverride,
|
||||
formatMissingAuthError,
|
||||
getApiKeyForModel,
|
||||
getApiKeyForModelCore,
|
||||
resolveApiKeyForProvider,
|
||||
type ResolvedProviderAuth,
|
||||
} from "./model-auth.js";
|
||||
@@ -306,7 +306,7 @@ export async function prepareSimpleCompletionModel(params: {
|
||||
modelId: initialModel.id,
|
||||
secretSentinels: true,
|
||||
})
|
||||
: await getApiKeyForModel({
|
||||
: await getApiKeyForModelCore({
|
||||
model: initialModel,
|
||||
cfg: params.cfg,
|
||||
agentDir: params.agentDir,
|
||||
@@ -396,7 +396,7 @@ export async function prepareSimpleCompletionModel(params: {
|
||||
),
|
||||
})) ?? initialModel;
|
||||
if (resolvesAuthBeforePhysicalRoute) {
|
||||
auth = await getApiKeyForModel({
|
||||
auth = await getApiKeyForModelCore({
|
||||
model: resolvedModel,
|
||||
cfg: params.cfg,
|
||||
agentDir: params.agentDir,
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
resolveLiveCredentialPrecedence,
|
||||
type CompleteSimpleContent,
|
||||
} from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { getApiKeyForModelCore, requireApiKey } from "./model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { transformTransportMessages } from "./transport-message-transform.js";
|
||||
|
||||
@@ -261,7 +261,7 @@ describeLive("tool replay repair live", () => {
|
||||
|
||||
let apiKeyInfo;
|
||||
try {
|
||||
apiKeyInfo = await getApiKeyForModel({
|
||||
apiKeyInfo = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
credentialPrecedence: resolveLiveCredentialPrecedence(
|
||||
@@ -374,7 +374,7 @@ describeLive("tool replay repair live", () => {
|
||||
|
||||
let apiKeyInfo;
|
||||
try {
|
||||
apiKeyInfo = await getApiKeyForModel({
|
||||
apiKeyInfo = await getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
credentialPrecedence: resolveLiveCredentialPrecedence(
|
||||
|
||||
@@ -7,7 +7,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { ModelDefinitionConfig } from "../../config/types.models.js";
|
||||
import type { ImageDescriptionRequest } from "../../plugin-sdk/media-understanding.js";
|
||||
import { getApiKeyForModel, hasUsableCustomProviderApiKey } from "../model-auth.js";
|
||||
import { getApiKeyForModelCore, hasUsableCustomProviderApiKey } from "../model-auth.js";
|
||||
import { resolveImageToolFactoryAvailable } from "../openclaw-tools.media-factory-plan.js";
|
||||
import { createImageTool } from "./image-tool.js";
|
||||
import { resolveImageModelConfigForTool, testing } from "./image-tool.test-support.js";
|
||||
@@ -195,7 +195,7 @@ describe("image custom provider auth regression", () => {
|
||||
// but execution still resolves the config-backed image-model key.
|
||||
await withEmptyAgentDir(async (agentDir) => {
|
||||
const cfg = createUserReportedConfig();
|
||||
const auth = await getApiKeyForModel({
|
||||
const auth = await getApiKeyForModelCore({
|
||||
model: {
|
||||
id: USER_MODEL,
|
||||
name: USER_MODEL,
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { SsrFPolicy } from "../../infra/net/ssrf.js";
|
||||
import type { Model } from "../../llm/types.js";
|
||||
import { resolveChannelInboundAttachmentRootsForChannel } from "../../media/channel-inbound-roots.js";
|
||||
import { getDefaultLocalRoots } from "../../media/local-media-access.js";
|
||||
import { getDefaultLocalRootsCore } from "../../media/local-media-access.js";
|
||||
import { readSnakeCaseParamRaw } from "../../param-key.js";
|
||||
import { loadCapabilityManifestSnapshot } from "../../plugins/capability-provider-runtime.js";
|
||||
import { listAvailableManifestContractValues } from "../../plugins/manifest-contract-eligibility.js";
|
||||
@@ -45,7 +45,11 @@ import {
|
||||
resolveDefaultModelRef,
|
||||
type ToolModelConfig,
|
||||
} from "./model-config.helpers.js";
|
||||
import { getApiKeyForModel, normalizeWorkspaceDir, requireApiKey } from "./tool-runtime.helpers.js";
|
||||
import {
|
||||
getApiKeyForModelCore,
|
||||
normalizeWorkspaceDir,
|
||||
requireApiKey,
|
||||
} from "./tool-runtime.helpers.js";
|
||||
|
||||
type TextToolAttempt = {
|
||||
provider: string;
|
||||
@@ -597,7 +601,7 @@ export function resolveMediaToolLocalRoots(
|
||||
}
|
||||
// Channel inbound attachment roots stay separate: those paths are scoped to inbound media
|
||||
// access, not broad host-local file reads.
|
||||
const roots = getDefaultLocalRoots();
|
||||
const roots = getDefaultLocalRootsCore();
|
||||
return uniqueStrings([...roots, ...(workspaceDir ? [workspaceDir] : [])]);
|
||||
}
|
||||
|
||||
@@ -730,7 +734,7 @@ export async function resolveModelRuntimeApiKey(params: {
|
||||
setRuntimeApiKey: (provider: string, apiKey: string) => void;
|
||||
};
|
||||
}): Promise<string> {
|
||||
const apiKeyInfo = await getApiKeyForModel({
|
||||
const apiKeyInfo = await getApiKeyForModelCore({
|
||||
model: params.model,
|
||||
cfg: params.cfg,
|
||||
agentDir: params.agentDir,
|
||||
|
||||
@@ -110,7 +110,7 @@ export function createPdfToolInfraStub(completeMock: Mock) {
|
||||
wrote: false,
|
||||
});
|
||||
|
||||
vi.spyOn(modelAuth, "getApiKeyForModel").mockResolvedValue({ apiKey: "test-key" } as never);
|
||||
vi.spyOn(modelAuth, "getApiKeyForModelCore").mockResolvedValue({ apiKey: "test-key" } as never);
|
||||
vi.spyOn(modelAuth, "requireApiKey").mockReturnValue("test-key");
|
||||
|
||||
return { loadSpy, release, setRuntimeApiKey };
|
||||
|
||||
@@ -330,7 +330,7 @@ describe("createPdfTool", () => {
|
||||
|
||||
const [, loadOptions] = firstMockCall(loadSpy, "loadWebMediaRaw");
|
||||
expectFields(loadOptions, { maxBytes: 524_288 });
|
||||
expect(modelAuth.getApiKeyForModel).toHaveBeenCalledWith(
|
||||
expect(modelAuth.getApiKeyForModelCore).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ secretSentinels: true }),
|
||||
);
|
||||
});
|
||||
@@ -833,7 +833,7 @@ describe("createPdfTool", () => {
|
||||
api: "bedrock-converse-stream",
|
||||
input: ["text", "image"],
|
||||
});
|
||||
vi.mocked(modelAuth.getApiKeyForModel).mockResolvedValue({
|
||||
vi.mocked(modelAuth.getApiKeyForModelCore).mockResolvedValue({
|
||||
apiKey: "",
|
||||
source: "aws-sdk default chain",
|
||||
mode: "aws-sdk",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Tools import from this module when they need model auth, fallback, discovery,
|
||||
* sandbox media paths, or workspace helpers without depending on broad agent barrels.
|
||||
*/
|
||||
export { getApiKeyForModel, requireApiKey } from "../model-auth.js";
|
||||
export { getApiKeyForModelCore, requireApiKey } from "../model-auth.js";
|
||||
export { runWithImageModelFallback } from "../model-fallback-image.js";
|
||||
export {
|
||||
createSandboxBridgeReadFile,
|
||||
|
||||
@@ -25,7 +25,7 @@ vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
getActiveSecretsRuntimeConfigSnapshot: () => runtimeState.activeSecretsRuntimeSnapshot,
|
||||
}));
|
||||
vi.mock("../../secrets/runtime-web-tools-state.js", () => ({
|
||||
getActiveRuntimeWebToolsMetadata: () => runtimeState.activeRuntimeWebToolsMetadata,
|
||||
getActiveRuntimeWebToolsMetadataFromState: () => runtimeState.activeRuntimeWebToolsMetadata,
|
||||
}));
|
||||
|
||||
describe("web_fetch provider fallback normalization", () => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { createWebSearchTool } from "./web-search.js";
|
||||
const mocks = vi.hoisted(() => ({
|
||||
runWebSearch: vi.fn(),
|
||||
resolveManifestContractOwnerPluginId: vi.fn(),
|
||||
getActiveRuntimeWebToolsMetadata: vi.fn(),
|
||||
getActiveRuntimeWebToolsMetadataFromState: vi.fn(),
|
||||
getActiveSecretsRuntimeConfigSnapshot: vi.fn(),
|
||||
}));
|
||||
|
||||
@@ -21,7 +21,7 @@ vi.mock("../../plugins/plugin-registry.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/runtime-web-tools-state.js", () => ({
|
||||
getActiveRuntimeWebToolsMetadata: mocks.getActiveRuntimeWebToolsMetadata,
|
||||
getActiveRuntimeWebToolsMetadataFromState: mocks.getActiveRuntimeWebToolsMetadataFromState,
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
@@ -49,8 +49,8 @@ describe("web_search late-bound runtime fallback", () => {
|
||||
});
|
||||
mocks.resolveManifestContractOwnerPluginId.mockReset();
|
||||
mocks.resolveManifestContractOwnerPluginId.mockReturnValue(undefined);
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReset();
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue(null);
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReset();
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReturnValue(null);
|
||||
mocks.getActiveSecretsRuntimeConfigSnapshot.mockReset();
|
||||
mocks.getActiveSecretsRuntimeConfigSnapshot.mockReturnValue(null);
|
||||
});
|
||||
@@ -136,7 +136,7 @@ describe("web_search late-bound runtime fallback", () => {
|
||||
it("prefers active runtime metadata over options.runtimeWebSearch when present", async () => {
|
||||
// Active runtime metadata reflects the newest credential snapshot; fallback
|
||||
// options only cover tools created before that state exists.
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue({
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReturnValue({
|
||||
search: {
|
||||
selectedProvider: "perplexity",
|
||||
providerConfigured: "perplexity",
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "./web-tool-runtime-context.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
getActiveRuntimeWebToolsMetadata: vi.fn(),
|
||||
getActiveRuntimeWebToolsMetadataFromState: vi.fn(),
|
||||
getActiveSecretsRuntimeConfigSnapshot: vi.fn(),
|
||||
resolveManifestContractOwnerPluginId: vi.fn(),
|
||||
}));
|
||||
@@ -17,7 +17,7 @@ vi.mock("../../plugins/plugin-registry.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/runtime-web-tools-state.js", () => ({
|
||||
getActiveRuntimeWebToolsMetadata: mocks.getActiveRuntimeWebToolsMetadata,
|
||||
getActiveRuntimeWebToolsMetadataFromState: mocks.getActiveRuntimeWebToolsMetadataFromState,
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
@@ -36,8 +36,8 @@ function latestOwnerLookupParams(): Record<string, unknown> {
|
||||
|
||||
describe("web tool runtime context", () => {
|
||||
beforeEach(() => {
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReset();
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue(null);
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReset();
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReturnValue(null);
|
||||
mocks.getActiveSecretsRuntimeConfigSnapshot.mockReset();
|
||||
mocks.getActiveSecretsRuntimeConfigSnapshot.mockReturnValue(null);
|
||||
mocks.resolveManifestContractOwnerPluginId.mockReset();
|
||||
@@ -49,7 +49,7 @@ describe("web tool runtime context", () => {
|
||||
tools: { web: { search: { provider: "perplexity" } } },
|
||||
};
|
||||
mocks.getActiveSecretsRuntimeConfigSnapshot.mockReturnValue({ config: runtimeConfig });
|
||||
mocks.getActiveRuntimeWebToolsMetadata.mockReturnValue({
|
||||
mocks.getActiveRuntimeWebToolsMetadataFromState.mockReturnValue({
|
||||
search: {
|
||||
providerConfigured: "perplexity",
|
||||
providerSource: "configured",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { resolveManifestContractOwnerPluginId } from "../../plugins/plugin-registry.js";
|
||||
import { getActiveSecretsRuntimeConfigSnapshot } from "../../secrets/runtime-state.js";
|
||||
import { getActiveRuntimeWebToolsMetadata } from "../../secrets/runtime-web-tools-state.js";
|
||||
import { getActiveRuntimeWebToolsMetadataFromState } from "../../secrets/runtime-web-tools-state.js";
|
||||
import type {
|
||||
RuntimeWebFetchMetadata,
|
||||
RuntimeWebSearchMetadata,
|
||||
@@ -61,7 +61,7 @@ function resolveWebToolRuntimeContext<TMetadata extends WebProviderRuntimeMetada
|
||||
lateBindRuntimeConfig?: boolean;
|
||||
}): ResolvedWebToolRuntimeContext<TMetadata> {
|
||||
const activeWebTools =
|
||||
params.lateBindRuntimeConfig === true ? getActiveRuntimeWebToolsMetadata() : null;
|
||||
params.lateBindRuntimeConfig === true ? getActiveRuntimeWebToolsMetadataFromState() : null;
|
||||
// Late-bound metadata wins over constructor-captured metadata for long-lived tool instances.
|
||||
const runtimeMetadata = (activeWebTools?.[params.kind] ?? params.capturedRuntimeMetadata) as
|
||||
| TMetadata
|
||||
|
||||
@@ -47,7 +47,7 @@ vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
|
||||
vi.mock("../../web-search/runtime.js", async () => {
|
||||
const { getActivePluginRegistry } = await import("../../plugins/runtime.js");
|
||||
const { getActiveRuntimeWebToolsMetadata } =
|
||||
const { getActiveRuntimeWebToolsMetadataFromState } =
|
||||
await import("../../secrets/runtime-web-tools-state.js");
|
||||
const resolveRuntimeDefinition = (options?: {
|
||||
config?: unknown;
|
||||
@@ -58,8 +58,8 @@ vi.mock("../../web-search/runtime.js", async () => {
|
||||
const providerId =
|
||||
options?.runtimeWebSearch?.selectedProvider ??
|
||||
options?.runtimeWebSearch?.providerConfigured ??
|
||||
getActiveRuntimeWebToolsMetadata()?.search?.selectedProvider ??
|
||||
getActiveRuntimeWebToolsMetadata()?.search?.providerConfigured ??
|
||||
getActiveRuntimeWebToolsMetadataFromState()?.search?.selectedProvider ??
|
||||
getActiveRuntimeWebToolsMetadataFromState()?.search?.providerConfigured ??
|
||||
readConfiguredSearchProvider(options?.config);
|
||||
const registration = getActivePluginRegistry()?.webSearchProviders.find(
|
||||
(entry) => entry.provider.id === providerId,
|
||||
|
||||
@@ -134,7 +134,7 @@ vi.mock("../../config/runtime-schema.js", async () => {
|
||||
const actual =
|
||||
await vi.importActual<typeof import("../../config/schema.js")>("../../config/schema.js");
|
||||
return {
|
||||
loadGatewayRuntimeConfigSchema: () => actual.buildConfigSchema(),
|
||||
loadGatewayRuntimeConfigSchema: () => actual.buildConfigSchemaCore(),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "../../config/mcp-config.js";
|
||||
import { redactSensitiveArgv } from "../../config/redact-argv.js";
|
||||
import { REDACTED_SENTINEL, redactConfigObject } from "../../config/redact-snapshot.js";
|
||||
import { buildConfigSchema } from "../../config/schema.js";
|
||||
import { buildConfigSchemaCore } from "../../config/schema.js";
|
||||
import type { ExecApprovalRequest } from "../../infra/exec-approvals.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
import {
|
||||
@@ -56,7 +56,7 @@ function redactMcpServersForDisplay(servers: Record<string, unknown>): Record<st
|
||||
);
|
||||
const redactedRoot = redactConfigObject(
|
||||
{ mcp: { servers: argvRedacted } },
|
||||
buildConfigSchema().uiHints,
|
||||
buildConfigSchemaCore().uiHints,
|
||||
) as {
|
||||
mcp?: { servers?: Record<string, unknown> };
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { normalizeOptionalString } from "@openclaw/normalization-core/string-coe
|
||||
import { normalizeChatType } from "../../../channels/chat-type.js";
|
||||
import { logMessageQueuedWithBacklogPolicy } from "../../../logging/diagnostic-runtime.js";
|
||||
import { channelRouteDedupeKey } from "../../../plugin-sdk/channel-route.js";
|
||||
import { createDeferred } from "../../../shared/deferred.js";
|
||||
import { createDeferredCore } from "../../../shared/deferred.js";
|
||||
import {
|
||||
applyQueueDropPolicy,
|
||||
countPendingQueueItems,
|
||||
@@ -159,7 +159,7 @@ export function enqueueFollowupRun(
|
||||
if (!markFollowupRunEnqueued(run)) {
|
||||
return false;
|
||||
}
|
||||
const { promise: acceptance, resolve: settle } = createDeferred<boolean>();
|
||||
const { promise: acceptance, resolve: settle } = createDeferredCore<boolean>();
|
||||
run.steerPending = { predecessor: queue.steerAcceptanceTail, settle };
|
||||
queue.steerAcceptanceTail = acceptance;
|
||||
appendQueueItem({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { normalizeStringifiedEntries } from "@openclaw/normalization-core/string-coerce";
|
||||
import { createDeferred } from "../../shared/deferred.js";
|
||||
import { createDeferredCore } from "../../shared/deferred.js";
|
||||
import { resolveGlobalMap } from "../../shared/global-singleton.js";
|
||||
|
||||
export const REPLY_ADMISSION_TICKET = Symbol("openclaw.replyAdmissionTicket");
|
||||
@@ -21,7 +21,7 @@ export function reserveReplyAdmissionTicket(
|
||||
if (keys.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const { promise: completed, resolve: finish } = createDeferred();
|
||||
const { promise: completed, resolve: finish } = createDeferredCore();
|
||||
const predecessors = keys.map((key) => tails.get(key) ?? Promise.resolve());
|
||||
const owned = keys.map((key, index) => {
|
||||
const tail = predecessors[index]!.then(() => completed);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
|
||||
import { createDeferred } from "../../shared/deferred.js";
|
||||
import { createDeferredCore } from "../../shared/deferred.js";
|
||||
import {
|
||||
replyMessageInjectionTargetOperation,
|
||||
type ReplyBackendHandle,
|
||||
@@ -151,7 +151,7 @@ export function beginReplyMessageInjectionTarget(
|
||||
// sub-10-minute user messages re-arm a wedged run's staleness window forever.
|
||||
// Invoke before the first await. The capability owns the final synchronous
|
||||
// admission check, matching Codex's active-turn lock boundary.
|
||||
const acceptance = createDeferred<boolean>();
|
||||
const acceptance = createDeferredCore<boolean>();
|
||||
let acceptanceSettled = false;
|
||||
const settleAcceptance = (accepted: boolean) => {
|
||||
if (acceptanceSettled) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import { createAbortError } from "../../infra/abort-signal.js";
|
||||
import { getAgentEventLifecycleGeneration } from "../../infra/agent-events.js";
|
||||
import { diagnosticLogger as diag } from "../../logging/diagnostic-runtime.js";
|
||||
import { createDeferred } from "../../shared/deferred.js";
|
||||
import { createDeferredCore } from "../../shared/deferred.js";
|
||||
import type { ReplyFollowupAdmissionBarrierTimeoutPolicy } from "./reply-dispatcher.types.js";
|
||||
import * as replyRunSettle from "./reply-run-finalization-lease.js";
|
||||
import {
|
||||
@@ -94,7 +94,7 @@ export function createReplyOperation(params: {
|
||||
let retainFailureUntilComplete = false;
|
||||
let terminalRecovery = false;
|
||||
let acceptedSteeredInboundAudio = false;
|
||||
const ownerSettlement = createDeferred();
|
||||
const ownerSettlement = createDeferredCore();
|
||||
let ownerSettled = false;
|
||||
const settleOwner = () => {
|
||||
if (ownerSettled) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
markDiagnosticRunProgress,
|
||||
resolveRunStaleThresholdMs,
|
||||
} from "../../logging/diagnostic-run-activity.js";
|
||||
import { createDeferred } from "../../shared/deferred.js";
|
||||
import { createDeferredCore } from "../../shared/deferred.js";
|
||||
import { resolveGlobalSingleton } from "../../shared/global-singleton.js";
|
||||
import { resolveTimerTimeoutMs } from "../../shared/number-coercion.js";
|
||||
import type { ReplyFollowupAdmissionBarrierTimeoutPolicy } from "./reply-dispatcher.types.js";
|
||||
@@ -229,7 +229,7 @@ export function registerReplyOperationSuccessorBarrier(params: {
|
||||
sessionKeys: readonly string[];
|
||||
start: () => PromiseLike<unknown>;
|
||||
}): void {
|
||||
const settlement = createDeferred();
|
||||
const settlement = createDeferredCore();
|
||||
const barriers = new Set<ReplyRunAdmissionBarrier>();
|
||||
for (const sessionKey of new Set(params.sessionKeys.map(normalizeOptionalString))) {
|
||||
if (sessionKey) {
|
||||
|
||||
@@ -18,10 +18,7 @@ import type {
|
||||
StreamingMode,
|
||||
TextChunkMode,
|
||||
} from "../config/types.base.js";
|
||||
import {
|
||||
DEFAULT_PROGRESS_DRAFT_LABELS as SHARED_PROGRESS_DRAFT_LABELS,
|
||||
selectProgressLabel,
|
||||
} from "../shared/progress-labels.js";
|
||||
import { DEFAULT_PROGRESS_DRAFT_LABELS, selectProgressLabel } from "../shared/progress-labels.js";
|
||||
import { asBoolean } from "../utils/boolean.js";
|
||||
import {
|
||||
getChannelStreamingConfigObject,
|
||||
@@ -81,7 +78,7 @@ function asCommandTextMode(value: unknown): ChannelStreamingCommandTextMode | un
|
||||
return value === "raw" || value === "status" ? value : undefined;
|
||||
}
|
||||
|
||||
export const DEFAULT_PROGRESS_DRAFT_LABELS = SHARED_PROGRESS_DRAFT_LABELS;
|
||||
export { DEFAULT_PROGRESS_DRAFT_LABELS } from "../shared/progress-labels.js";
|
||||
|
||||
// Short enough that a multi-tool turn is never silent, long enough that a
|
||||
// quick answer posts no draft at all: the gate only creates the draft when the
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import type { ProgramContext } from "./context.js";
|
||||
import {
|
||||
getCoreCliCommandDescriptors,
|
||||
getCoreCliCommandNames as getCoreDescriptorNames,
|
||||
getCoreCliCommandNamesCore,
|
||||
} from "./core-command-descriptors.js";
|
||||
import {
|
||||
registerCommandGroupByName,
|
||||
@@ -157,7 +157,7 @@ function resolveCoreCommandGroups(ctx: ProgramContext, argv: string[]): CommandG
|
||||
}
|
||||
|
||||
export function getCoreCliCommandNames(): string[] {
|
||||
return getCoreDescriptorNames();
|
||||
return getCoreCliCommandNamesCore();
|
||||
}
|
||||
|
||||
export async function registerCoreCliByName(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { levenshteinDistance } from "../../shared/levenshtein-distance.js";
|
||||
import { formatCliCommand } from "../command-format.js";
|
||||
import { getCoreCliCommandNames } from "./core-command-descriptors.js";
|
||||
import { getSubCliEntries } from "./subcli-descriptors.js";
|
||||
import { getCoreCliCommandNamesCore } from "./core-command-descriptors.js";
|
||||
import { getSubCliEntriesCore } from "./subcli-descriptors.js";
|
||||
|
||||
const EXPLICIT_COMMAND_ALIASES = new Map<string, string>([
|
||||
["upgrade", "update"],
|
||||
@@ -23,8 +23,8 @@ export function formatCliCommandSuggestions(input: string): string | undefined {
|
||||
}
|
||||
|
||||
const knownCommands = uniqueSortedCommandNames([
|
||||
...getCoreCliCommandNames(),
|
||||
...getSubCliEntries().map((entry) => entry.name),
|
||||
...getCoreCliCommandNamesCore(),
|
||||
...getSubCliEntriesCore().map((entry) => entry.name),
|
||||
]);
|
||||
const explicitAlias = EXPLICIT_COMMAND_ALIASES.get(normalizedInput);
|
||||
if (explicitAlias && knownCommands.includes(explicitAlias)) {
|
||||
|
||||
@@ -148,7 +148,7 @@ export function getCoreCliCommandDescriptors(): ReadonlyArray<CoreCliCommandDesc
|
||||
}
|
||||
|
||||
/** Return names for all core root commands. */
|
||||
export function getCoreCliCommandNames(): string[] {
|
||||
export function getCoreCliCommandNamesCore(): string[] {
|
||||
return visibleCoreCliCommandDescriptors().map((descriptor) => descriptor.name);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,7 @@ import {
|
||||
registerCommandGroups,
|
||||
type CommandGroupEntry,
|
||||
} from "./register-command-groups.js";
|
||||
import {
|
||||
getSubCliEntries as getSubCliEntryDescriptors,
|
||||
type SubCliDescriptor,
|
||||
} from "./subcli-descriptors.js";
|
||||
import { getSubCliEntriesCore, type SubCliDescriptor } from "./subcli-descriptors.js";
|
||||
|
||||
export type SubCliRegistrationContext = {
|
||||
purpose?: "runtime" | "completion";
|
||||
@@ -317,7 +314,7 @@ function resolveSubCliCommandGroups(
|
||||
argv: string[],
|
||||
context: SubCliRegistrationContext = {},
|
||||
): CommandGroupEntry[] {
|
||||
const descriptors = getSubCliEntryDescriptors();
|
||||
const descriptors = getSubCliEntriesCore();
|
||||
const descriptorNames = new Set(descriptors.map((descriptor) => descriptor.name));
|
||||
return buildCommandGroupEntries(
|
||||
descriptors,
|
||||
@@ -329,7 +326,7 @@ function resolveSubCliCommandGroups(
|
||||
}
|
||||
|
||||
export function getSubCliEntries(): ReadonlyArray<SubCliDescriptor> {
|
||||
return getSubCliEntryDescriptors();
|
||||
return getSubCliEntriesCore();
|
||||
}
|
||||
|
||||
export async function registerSubCliByNameCore(
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
registerSubCliCommandsCore,
|
||||
type SubCliRegistrationContext,
|
||||
} from "./register.subclis-core.js";
|
||||
import { getSubCliEntries as getSubCliEntryDescriptors } from "./subcli-descriptors.js";
|
||||
import { getSubCliEntriesCore as getSubCliEntryDescriptors } from "./subcli-descriptors.js";
|
||||
|
||||
type SubCliRegistrar = (
|
||||
program: Command,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getCoreCliCommandNames, registerCoreCliByName } from "./command-registr
|
||||
import { createProgramContext } from "./context.js";
|
||||
import { getCoreCliCommandDescriptors } from "./core-command-descriptors.js";
|
||||
import { registerSubCliByName, registerSubCliCommands } from "./register.subclis.js";
|
||||
import { getSubCliEntries } from "./subcli-descriptors.js";
|
||||
import { getSubCliEntriesCore } from "./subcli-descriptors.js";
|
||||
|
||||
const RESERVED_CATALOG_ROOTS = {
|
||||
tool: "reserved so plugin registration cannot claim this unregistered root",
|
||||
@@ -233,7 +233,7 @@ async function registerAllBuiltInCommands(): Promise<Command> {
|
||||
for (const name of getCoreCliCommandNames()) {
|
||||
await registerCoreCliByName(program, ctx, name, argv);
|
||||
}
|
||||
for (const entry of getSubCliEntries()) {
|
||||
for (const entry of getSubCliEntriesCore()) {
|
||||
await registerSubCliByName(program, entry.name, argv, { purpose: "completion" });
|
||||
}
|
||||
return program;
|
||||
@@ -295,7 +295,7 @@ describe("root command descriptions", () => {
|
||||
}
|
||||
}
|
||||
|
||||
const descriptors = [...getCoreCliCommandDescriptors(), ...getSubCliEntries()];
|
||||
const descriptors = [...getCoreCliCommandDescriptors(), ...getSubCliEntriesCore()];
|
||||
const missing: string[] = [];
|
||||
const mismatches: string[] = [];
|
||||
for (const descriptor of descriptors) {
|
||||
|
||||
@@ -38,7 +38,7 @@ vi.mock("./subcli-descriptors.js", () => ({
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
getSubCliEntries: () => [
|
||||
getSubCliEntriesCore: () => [
|
||||
{
|
||||
name: "config",
|
||||
description: "Manage config",
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from "./command-descriptor-utils.js";
|
||||
import { getCoreCliCommandDescriptors } from "./core-command-descriptors.js";
|
||||
import { configureProgramHelp, formatProgramHelpOutput } from "./help.js";
|
||||
import { getSubCliEntries } from "./subcli-descriptors.js";
|
||||
import { getSubCliEntriesCore } from "./subcli-descriptors.js";
|
||||
|
||||
/** Options for rendering root help without fully registering the live CLI. */
|
||||
export type RootHelpRenderOptions = Pick<PluginLoadOptions, "pluginSdkResolution"> & {
|
||||
@@ -48,7 +48,7 @@ async function buildRootHelpProgram(renderOptions?: RootHelpRenderOptions): Prom
|
||||
program,
|
||||
collectUniqueCommandDescriptors([
|
||||
getCoreCliCommandDescriptors(),
|
||||
getSubCliEntries(),
|
||||
getSubCliEntriesCore(),
|
||||
pluginDescriptors,
|
||||
]),
|
||||
);
|
||||
|
||||
@@ -45,10 +45,10 @@ describe("sub-cli descriptors", () => {
|
||||
it("keeps the exported descriptor list aligned with private QA visibility when disabled (#83927)", async () => {
|
||||
delete process.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI;
|
||||
|
||||
const { SUB_CLI_DESCRIPTORS, getSubCliEntries } = await importSubCliDescriptors();
|
||||
const { SUB_CLI_DESCRIPTORS, getSubCliEntriesCore } = await importSubCliDescriptors();
|
||||
const exportedNames = descriptorNames(SUB_CLI_DESCRIPTORS);
|
||||
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntries()));
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntriesCore()));
|
||||
expect(exportedNames).not.toContain("qa");
|
||||
});
|
||||
|
||||
@@ -73,12 +73,12 @@ describe("sub-cli descriptors", () => {
|
||||
const {
|
||||
SUB_CLI_DESCRIPTORS,
|
||||
getSubCliCommandsWithSubcommands,
|
||||
getSubCliEntries,
|
||||
getSubCliEntriesCore,
|
||||
getSubCliParentDefaultHelpCommands,
|
||||
} = await importSubCliDescriptors();
|
||||
const exportedNames = descriptorNames(SUB_CLI_DESCRIPTORS);
|
||||
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntries()));
|
||||
expect(exportedNames).toEqual(descriptorNames(getSubCliEntriesCore()));
|
||||
expect(exportedNames).toContain("qa");
|
||||
expect(getSubCliCommandsWithSubcommands()).toContain("qa");
|
||||
expect(getSubCliParentDefaultHelpCommands()).not.toContain("qa");
|
||||
|
||||
@@ -263,7 +263,7 @@ export const SUB_CLI_DESCRIPTORS = filterPrivateQaItems(
|
||||
);
|
||||
|
||||
/** Return visible sub-CLI descriptors in help/registration order. */
|
||||
export function getSubCliEntries(): ReadonlyArray<SubCliDescriptor> {
|
||||
export function getSubCliEntriesCore(): ReadonlyArray<SubCliDescriptor> {
|
||||
return filterPrivateQaItems(
|
||||
subCliCommandCatalog.getDescriptors(),
|
||||
(descriptor) => descriptor.name,
|
||||
|
||||
+5
-5
@@ -53,9 +53,9 @@ import { applyCliProfileEnv, parseCliProfileArgs } from "./profile.js";
|
||||
import { formatCliCommandSuggestions } from "./program/command-suggestions.js";
|
||||
import {
|
||||
getCoreCliCommandDescriptors,
|
||||
getCoreCliCommandNames,
|
||||
getCoreCliCommandNamesCore,
|
||||
} from "./program/core-command-descriptors.js";
|
||||
import { getSubCliEntries } from "./program/subcli-descriptors.js";
|
||||
import { getSubCliEntriesCore } from "./program/subcli-descriptors.js";
|
||||
import {
|
||||
resolveMissingPluginCommandMessage,
|
||||
rewriteUpdateFlagArgv,
|
||||
@@ -865,8 +865,8 @@ function shouldBootstrapCliProxyBeforeFastPath(env: NodeJS.ProcessEnv = process.
|
||||
|
||||
function isKnownBuiltInCommandRoot(primary: string): boolean {
|
||||
return (
|
||||
getCoreCliCommandNames().includes(primary) ||
|
||||
getSubCliEntries().some((entry) => entry.name === primary)
|
||||
getCoreCliCommandNamesCore().includes(primary) ||
|
||||
getSubCliEntriesCore().some((entry) => entry.name === primary)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -884,7 +884,7 @@ function resolveBuiltInMachineOutput(argv: string[]): boolean {
|
||||
if (!primary) {
|
||||
return false;
|
||||
}
|
||||
const descriptor = [...getCoreCliCommandDescriptors(), ...getSubCliEntries()].find(
|
||||
const descriptor = [...getCoreCliCommandDescriptors(), ...getSubCliEntriesCore()].find(
|
||||
(entry) => entry.name === primary,
|
||||
);
|
||||
return descriptor ? resolvesMachineOutput(descriptor, argv) : false;
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
import { isLikelySensitiveModelProviderHeaderName } from "../secrets/model-provider-header-policy.js";
|
||||
import { hasConfiguredPlaintextSecretValue } from "../secrets/secret-value.js";
|
||||
import { discoverConfigSecretTargets } from "../secrets/target-registry.js";
|
||||
import { collectChannelSecurityFindings } from "../security/audit-channel.js";
|
||||
import { collectChannelSecurityFindingsCore } from "../security/audit-channel.js";
|
||||
import { collectExecFilesystemPolicyDriftHits } from "../security/exec-filesystem-policy.js";
|
||||
|
||||
function collectImplicitHeartbeatDirectPolicyWarnings(cfg: OpenClawConfig): string[] {
|
||||
@@ -340,7 +340,7 @@ export async function collectSecurityWarnings(
|
||||
warnings.push(...tokenConflict.warningLines);
|
||||
}
|
||||
|
||||
const channelFindings = await collectChannelSecurityFindings({
|
||||
const channelFindings = await collectChannelSecurityFindingsCore({
|
||||
cfg,
|
||||
mode: "doctor",
|
||||
plugins: listReadOnlyChannelPluginsForConfig(cfg, {
|
||||
|
||||
@@ -124,7 +124,9 @@ function normalizeCoreOwnedChannelSchema(schema: Record<string, unknown>): Recor
|
||||
}
|
||||
|
||||
/** Collects plugin config UI metadata with deterministic origin precedence and output ordering. */
|
||||
export function collectPluginSchemaMetadata(registry: PluginManifestRegistry): PluginUiMetadata[] {
|
||||
export function collectPluginSchemaMetadataCore(
|
||||
registry: PluginManifestRegistry,
|
||||
): PluginUiMetadata[] {
|
||||
const deduped = new Map<
|
||||
string,
|
||||
PluginUiMetadata & {
|
||||
@@ -217,7 +219,7 @@ export function collectChannelSchemaMetadataWithOwnership(
|
||||
}
|
||||
|
||||
/** Collects public per-channel config UI metadata without internal schema ownership. */
|
||||
export function collectChannelSchemaMetadata(
|
||||
export function collectChannelSchemaMetadataCore(
|
||||
registry: PluginManifestRegistry,
|
||||
): ChannelUiMetadata[] {
|
||||
return collectChannelSchemaMetadataWithOwnership(registry).map(
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// Collects runtime data needed to generate config documentation baselines.
|
||||
import { collectBundledChannelConfigs as collectBundledChannelConfigsImpl } from "../plugins/bundled-channel-config-metadata.js";
|
||||
import { collectBundledChannelConfigsCore } from "../plugins/bundled-channel-config-metadata.js";
|
||||
import { loadPluginManifestRegistry as loadPluginManifestRegistryImpl } from "../plugins/manifest-registry.js";
|
||||
import {
|
||||
collectChannelSchemaMetadata as collectChannelSchemaMetadataImpl,
|
||||
collectPluginSchemaMetadata as collectPluginSchemaMetadataImpl,
|
||||
collectChannelSchemaMetadataCore,
|
||||
collectPluginSchemaMetadataCore,
|
||||
} from "./channel-config-metadata.js";
|
||||
import { buildConfigSchema as buildConfigSchemaImpl } from "./schema.js";
|
||||
import { buildConfigSchemaCore } from "./schema.js";
|
||||
|
||||
/** Runtime facade used by docs baseline generation to keep imports narrow. */
|
||||
export const loadPluginManifestRegistry = loadPluginManifestRegistryImpl;
|
||||
export const collectBundledChannelConfigs = collectBundledChannelConfigsImpl;
|
||||
export const collectChannelSchemaMetadata = collectChannelSchemaMetadataImpl;
|
||||
export const collectPluginSchemaMetadata = collectPluginSchemaMetadataImpl;
|
||||
export const buildConfigSchema = buildConfigSchemaImpl;
|
||||
export const collectBundledChannelConfigs = collectBundledChannelConfigsCore;
|
||||
export const collectChannelSchemaMetadata = collectChannelSchemaMetadataCore;
|
||||
export const collectPluginSchemaMetadata = collectPluginSchemaMetadataCore;
|
||||
export const buildConfigSchema = buildConfigSchemaCore;
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { replaceConfigFile } from "./mutate.js";
|
||||
import { redactSensitiveArgv } from "./redact-argv.js";
|
||||
import { REDACTED_SENTINEL, restoreRedactedValues } from "./redact-snapshot.js";
|
||||
import { buildConfigSchema } from "./schema.js";
|
||||
import { buildConfigSchemaCore } from "./schema.js";
|
||||
import type { OpenClawConfig } from "./types.openclaw.js";
|
||||
import { validateConfigObjectWithPlugins } from "./validation.js";
|
||||
|
||||
@@ -285,7 +285,7 @@ export async function setConfiguredMcpServer(params: {
|
||||
const restored = restoreRedactedValues(
|
||||
{ mcp: { servers: { [name]: argvRestored.server } } },
|
||||
{ mcp: { servers: loaded.mcpServers } },
|
||||
buildConfigSchema().uiHints,
|
||||
buildConfigSchemaCore().uiHints,
|
||||
);
|
||||
if (!restored.ok) {
|
||||
return {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { redactSnapshotTestHints as mainSchemaHints } from "../../test/helpers/config/redact-snapshot-test-hints.js";
|
||||
import { REDACTED_SENTINEL, redactConfigSnapshot } from "./redact-snapshot.js";
|
||||
import { makeSnapshot, restoreRedactedValues } from "./redact-snapshot.test-helpers.js";
|
||||
import { buildConfigSchema } from "./schema.js";
|
||||
import { buildConfigSchemaCore } from "./schema.js";
|
||||
|
||||
describe("realredactConfigSnapshot_real", () => {
|
||||
it("main schema redact works (samples)", () => {
|
||||
@@ -50,7 +50,7 @@ describe("realredactConfigSnapshot_real", () => {
|
||||
});
|
||||
|
||||
it("redacts bundled channel private keys from generated schema hints", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const snapshot = makeSnapshot({
|
||||
channels: {
|
||||
nostr: {
|
||||
@@ -73,7 +73,7 @@ describe("realredactConfigSnapshot_real", () => {
|
||||
});
|
||||
|
||||
it("redacts Discord Activity client secrets registered on plain string schemas", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
expect(hints["channels.discord.activities.clientSecret"]?.sensitive).toBe(true);
|
||||
const snapshot = makeSnapshot({
|
||||
channels: {
|
||||
@@ -93,7 +93,7 @@ describe("realredactConfigSnapshot_real", () => {
|
||||
});
|
||||
|
||||
it("redacts and restores web fetch operator headers from generated schema hints", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
expect(hints["tools.web.fetch.headers.*"]?.sensitive).toBe(true);
|
||||
const snapshot = makeSnapshot({
|
||||
tools: {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
restoreRedactedValues,
|
||||
type TestSnapshot,
|
||||
} from "./redact-snapshot.test-helpers.js";
|
||||
import { buildConfigSchema } from "./schema.js";
|
||||
import { buildConfigSchemaCore } from "./schema.js";
|
||||
import type { ConfigFileSnapshot, OpenClawConfig } from "./types.openclaw.js";
|
||||
|
||||
function expectNestedPairValue(
|
||||
@@ -208,7 +208,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts and restores MCP SSE header values from schema hints", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const snapshot = makeSnapshot({
|
||||
mcp: {
|
||||
servers: {
|
||||
@@ -252,7 +252,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts sensitive auth material from MCP SSE URLs", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
mcp: {
|
||||
servers: {
|
||||
@@ -289,7 +289,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts media request auth and proxy transport secrets from config snapshots", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
tools: {
|
||||
media: {
|
||||
@@ -346,7 +346,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts model provider request auth secrets from config snapshots", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
models: {
|
||||
providers: {
|
||||
@@ -394,7 +394,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts model provider local service env values from config snapshots", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
models: {
|
||||
providers: {
|
||||
@@ -448,7 +448,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts install policy env values from config snapshots", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
security: {
|
||||
installPolicy: {
|
||||
@@ -498,7 +498,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts model provider request proxy URLs from config snapshots", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
models: {
|
||||
providers: {
|
||||
@@ -1413,7 +1413,7 @@ describe("redactConfigSnapshot", () => {
|
||||
});
|
||||
|
||||
it("redacts browser cdpUrl secrets while preserving bare endpoints", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const hints = buildConfigSchemaCore().uiHints;
|
||||
const raw = `{
|
||||
browser: {
|
||||
cdpUrl: "https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { resolvePluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
|
||||
import {
|
||||
collectChannelSchemaMetadata,
|
||||
collectPluginSchemaMetadata,
|
||||
collectChannelSchemaMetadataCore,
|
||||
collectPluginSchemaMetadataCore,
|
||||
} from "./channel-config-metadata.js";
|
||||
import { getRuntimeConfig, readConfigFileSnapshot } from "./config.js";
|
||||
import type { OpenClawConfig } from "./config.js";
|
||||
import { buildConfigSchema, type ConfigSchemaResponse } from "./schema.js";
|
||||
import { buildConfigSchemaCore, type ConfigSchemaResponse } from "./schema.js";
|
||||
|
||||
// Runtime schemas include currently loaded plugin/channel metadata for accurate UI fields.
|
||||
function loadManifestRegistry(config: OpenClawConfig, env?: NodeJS.ProcessEnv) {
|
||||
@@ -24,9 +24,9 @@ function loadManifestRegistry(config: OpenClawConfig, env?: NodeJS.ProcessEnv) {
|
||||
export function loadGatewayRuntimeConfigSchema(): ConfigSchemaResponse {
|
||||
const config = getRuntimeConfig();
|
||||
const registry = loadManifestRegistry(config);
|
||||
return buildConfigSchema({
|
||||
plugins: collectPluginSchemaMetadata(registry),
|
||||
channels: collectChannelSchemaMetadata(registry),
|
||||
return buildConfigSchemaCore({
|
||||
plugins: collectPluginSchemaMetadataCore(registry),
|
||||
channels: collectChannelSchemaMetadataCore(registry),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ export async function readBestEffortRuntimeConfigSchema(): Promise<ConfigSchemaR
|
||||
? snapshot.config
|
||||
: { agents: { list: [{ id: "main", default: true }] }, plugins: { enabled: true } };
|
||||
const registry = loadManifestRegistry(config);
|
||||
return buildConfigSchema({
|
||||
plugins: snapshot.valid ? collectPluginSchemaMetadata(registry) : [],
|
||||
channels: collectChannelSchemaMetadata(registry),
|
||||
return buildConfigSchemaCore({
|
||||
plugins: snapshot.valid ? collectPluginSchemaMetadataCore(registry) : [],
|
||||
channels: collectChannelSchemaMetadataCore(registry),
|
||||
});
|
||||
}
|
||||
|
||||
+13
-13
@@ -2,7 +2,7 @@ import { SENSITIVE_URL_HINT_TAG } from "@openclaw/net-policy/redact-sensitive-ur
|
||||
// Covers canonical config schema defaults, validation, and sensitive redaction.
|
||||
import { expectDefined } from "@openclaw/normalization-core";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { buildConfigSchema, lookupConfigSchema } from "./schema.js";
|
||||
import { buildConfigSchemaCore, lookupConfigSchema } from "./schema.js";
|
||||
import { applyDerivedTags } from "./schema.tags.js";
|
||||
import { applyResolvedConfigTierHints } from "./schema.tiers.js";
|
||||
import { validateConfigObjectRaw } from "./validation.js";
|
||||
@@ -10,8 +10,8 @@ import { ToolsSchema } from "./zod-schema.agent-runtime.js";
|
||||
import { OpenClawSchema } from "./zod-schema.js";
|
||||
|
||||
describe("config schema", () => {
|
||||
type SchemaInput = NonNullable<Parameters<typeof buildConfigSchema>[0]>;
|
||||
let baseSchema: ReturnType<typeof buildConfigSchema>;
|
||||
type SchemaInput = NonNullable<Parameters<typeof buildConfigSchemaCore>[0]>;
|
||||
let baseSchema: ReturnType<typeof buildConfigSchemaCore>;
|
||||
let pluginUiHintInput: SchemaInput;
|
||||
let tokenHintInput: SchemaInput;
|
||||
let mergedSchemaInput: SchemaInput;
|
||||
@@ -19,7 +19,7 @@ describe("config schema", () => {
|
||||
let cachedMergeInput: SchemaInput;
|
||||
|
||||
beforeAll(() => {
|
||||
baseSchema = buildConfigSchema();
|
||||
baseSchema = buildConfigSchemaCore();
|
||||
pluginUiHintInput = {
|
||||
plugins: [
|
||||
{
|
||||
@@ -471,7 +471,7 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("merges plugin ui hints", () => {
|
||||
const res = buildConfigSchema(pluginUiHintInput);
|
||||
const res = buildConfigSchemaCore(pluginUiHintInput);
|
||||
|
||||
expect(res.uiHints["plugins.entries.voice-call"]?.label).toBe("Voice Call");
|
||||
expect(res.uiHints["plugins.entries.voice-call.config"]?.label).toBe("Voice Call Config");
|
||||
@@ -482,13 +482,13 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("does not re-mark existing non-sensitive token-like fields", () => {
|
||||
const res = buildConfigSchema(tokenHintInput);
|
||||
const res = buildConfigSchemaCore(tokenHintInput);
|
||||
|
||||
expect(res.uiHints["plugins.entries.voice-call.config.tokens"]?.sensitive).toBe(false);
|
||||
});
|
||||
|
||||
it("merges plugin + channel schemas", () => {
|
||||
const res = buildConfigSchema(mergedSchemaInput);
|
||||
const res = buildConfigSchemaCore(mergedSchemaInput);
|
||||
|
||||
const schema = res.schema as {
|
||||
properties?: Record<string, unknown>;
|
||||
@@ -544,7 +544,7 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("omits a single oversized plugin schema from the full schema response", () => {
|
||||
const res = buildConfigSchema({
|
||||
const res = buildConfigSchemaCore({
|
||||
cache: false,
|
||||
plugins: [
|
||||
{
|
||||
@@ -572,7 +572,7 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("omits later plugin schemas after the aggregate extension schema budget is exhausted", () => {
|
||||
const res = buildConfigSchema({
|
||||
const res = buildConfigSchemaCore({
|
||||
cache: false,
|
||||
plugins: Array.from({ length: 40 }, (_, index) => ({
|
||||
id: `plugin-${index}`,
|
||||
@@ -597,7 +597,7 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("looks up plugin config paths for slash-delimited plugin ids", () => {
|
||||
const res = buildConfigSchema({
|
||||
const res = buildConfigSchemaCore({
|
||||
plugins: [
|
||||
{
|
||||
id: "pack/one",
|
||||
@@ -622,7 +622,7 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("adds heartbeat target hints with dynamic channels", () => {
|
||||
const res = buildConfigSchema(heartbeatChannelInput);
|
||||
const res = buildConfigSchemaCore(heartbeatChannelInput);
|
||||
|
||||
const defaultsHint = res.uiHints["agents.defaults.heartbeat.target"];
|
||||
const entryHint = res.uiHints["agents.entries.*.heartbeat.target"];
|
||||
@@ -634,10 +634,10 @@ describe("config schema", () => {
|
||||
});
|
||||
|
||||
it("caches merged schemas for identical plugin/channel metadata", () => {
|
||||
const first = buildConfigSchema(cachedMergeInput);
|
||||
const first = buildConfigSchemaCore(cachedMergeInput);
|
||||
const plugin = expectDefined(cachedMergeInput.plugins?.[0], "cached plugin metadata");
|
||||
const channel = expectDefined(cachedMergeInput.channels?.[0], "cached channel metadata");
|
||||
const second = buildConfigSchema({
|
||||
const second = buildConfigSchemaCore({
|
||||
plugins: [{ ...plugin }],
|
||||
channels: [{ ...channel }],
|
||||
});
|
||||
|
||||
@@ -567,7 +567,7 @@ function buildBaseConfigSchema(): ConfigSchemaResponse {
|
||||
return next;
|
||||
}
|
||||
|
||||
export function buildConfigSchema(params?: {
|
||||
export function buildConfigSchemaCore(params?: {
|
||||
plugins?: PluginUiMetadata[];
|
||||
channels?: ChannelUiMetadata[];
|
||||
cache?: boolean;
|
||||
|
||||
@@ -21,7 +21,7 @@ import { openLocalFileSafely, FsSafeError } from "../infra/fs-safe.js";
|
||||
import { safeFileURLToPath } from "../infra/local-file-access.js";
|
||||
import { verifyPairingToken } from "../infra/pairing-token.js";
|
||||
import { isWithinDir } from "../infra/path-safety.js";
|
||||
import { assertLocalMediaAllowed, getDefaultLocalRoots } from "../media/local-media-access.js";
|
||||
import { assertLocalMediaAllowed, getDefaultLocalRootsCore } from "../media/local-media-access.js";
|
||||
import { getAgentScopedMediaLocalRoots } from "../media/local-roots.js";
|
||||
import { probePlaybackMediaFileDescriptor, type MediaProbeResult } from "../media/media-probe.js";
|
||||
import {
|
||||
@@ -699,7 +699,7 @@ export async function handleControlUiAssistantMediaRequest(
|
||||
}
|
||||
const localRoots = opts?.config
|
||||
? getAgentScopedMediaLocalRoots(opts.config, opts.agentId)
|
||||
: getDefaultLocalRoots();
|
||||
: getDefaultLocalRootsCore();
|
||||
|
||||
if (isMetaRequest) {
|
||||
const availability = await resolveAssistantMediaAvailability(source, localRoots);
|
||||
|
||||
@@ -54,7 +54,7 @@ import {
|
||||
isLiveBillingDrift,
|
||||
isLiveRateLimitDrift,
|
||||
} from "../agents/live-test-provider-drift.test-support.js";
|
||||
import { getApiKeyForModel, resolveEnvApiKey } from "../agents/model-auth.js";
|
||||
import { getApiKeyForModelCore, resolveEnvApiKey } from "../agents/model-auth.js";
|
||||
import { normalizeProviderId } from "../agents/model-selection.js";
|
||||
import { shouldSuppressBuiltInModel } from "../agents/model-suppression.js";
|
||||
import { ensureOpenClawModelsJson } from "../agents/models-config.js";
|
||||
@@ -5626,7 +5626,7 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
const modelRef = `${model.provider}/${model.id}`;
|
||||
try {
|
||||
const apiKeyInfo = await withGatewayLiveSetupTimeout(
|
||||
getApiKeyForModel({
|
||||
getApiKeyForModelCore({
|
||||
model,
|
||||
cfg,
|
||||
store: authProfileStore,
|
||||
@@ -5763,12 +5763,12 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await getApiKeyForModel({
|
||||
await getApiKeyForModelCore({
|
||||
model: anthropic,
|
||||
cfg,
|
||||
credentialPrecedence: LIVE_CREDENTIAL_PRECEDENCE,
|
||||
});
|
||||
await getApiKeyForModel({
|
||||
await getApiKeyForModelCore({
|
||||
model: zai,
|
||||
cfg,
|
||||
credentialPrecedence: LIVE_CREDENTIAL_PRECEDENCE,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type RequestNodePairingResult,
|
||||
} from "../infra/device-pairing-node.js";
|
||||
import { KeyedAsyncQueue } from "../plugin-sdk/keyed-async-queue.js";
|
||||
import { createDeferred, type Deferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore, type Deferred } from "../shared/deferred.js";
|
||||
import {
|
||||
AUTH_RATE_LIMIT_SCOPE_NODE_REAPPROVAL,
|
||||
buildRateLimitIdentityKey,
|
||||
@@ -171,7 +171,7 @@ export function createNodeReapprovalCoordinator(
|
||||
const fingerprint = buildRequestFingerprint(params.input);
|
||||
const state = requestStates.get(nodeId);
|
||||
if (!state) {
|
||||
const deferred = createDeferred<RequestNodePairingResult | null>();
|
||||
const deferred = createDeferredCore<RequestNodePairingResult | null>();
|
||||
const nextState: NodeRequestState = { activeFingerprint: fingerprint };
|
||||
requestStates.set(nodeId, nextState);
|
||||
startFirstRequest(nodeId, nextState, {
|
||||
@@ -183,13 +183,13 @@ export function createNodeReapprovalCoordinator(
|
||||
return deferred.promise;
|
||||
}
|
||||
if (state.queued?.fingerprint === fingerprint) {
|
||||
const follower = createDeferred<RequestNodePairingResult | null>();
|
||||
const follower = createDeferredCore<RequestNodePairingResult | null>();
|
||||
state.queued.params = params;
|
||||
state.queued.followers.push(follower);
|
||||
return follower.promise;
|
||||
}
|
||||
|
||||
const deferred = createDeferred<RequestNodePairingResult | null>();
|
||||
const deferred = createDeferredCore<RequestNodePairingResult | null>();
|
||||
if (state.queued) {
|
||||
state.queued.deferred.resolve(null);
|
||||
for (const follower of state.queued.followers) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
} from "../../packages/gateway-protocol/src/client-info.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createDeferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import { resolveGatewayClientBootstrap } from "./client-bootstrap.js";
|
||||
import { startGatewayClientWhenEventLoopReady } from "./client-start-readiness.js";
|
||||
import { GatewayClient, type GatewayClientOptions } from "./client.js";
|
||||
@@ -83,7 +83,7 @@ export async function withOperatorApprovalsGatewayClient<T>(
|
||||
},
|
||||
run: (client: GatewayClient) => Promise<T>,
|
||||
): Promise<T> {
|
||||
const ready = createDeferred();
|
||||
const ready = createDeferredCore();
|
||||
|
||||
const gatewayClient = await createOperatorApprovalsGatewayClient({
|
||||
config: params.config,
|
||||
|
||||
@@ -25,7 +25,7 @@ vi.mock("../secrets/store/secret-store.js", () => {
|
||||
});
|
||||
import {
|
||||
getRuntimeAuthProfileStoreCredentialsRevision,
|
||||
getRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
setRuntimeAuthProfileStoreSnapshot,
|
||||
} from "../agents/auth-profiles/runtime-snapshots.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
@@ -750,7 +750,7 @@ describe("gateway aux handlers", () => {
|
||||
required: "gen-old",
|
||||
});
|
||||
expect(
|
||||
getRuntimeAuthProfileStoreSnapshot(authAgentDir)?.profiles["openai:default"],
|
||||
getRuntimeAuthProfileStoreSnapshotCore(authAgentDir)?.profiles["openai:default"],
|
||||
).toMatchObject({ access: "access-new", refresh: "refresh-new" });
|
||||
});
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
type CommandSecretAssignment,
|
||||
} from "../secrets/runtime-command-secrets.js";
|
||||
import {
|
||||
getActiveSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision,
|
||||
getActiveSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState,
|
||||
type PreparedSecretsRuntimeSnapshot,
|
||||
} from "../secrets/runtime-state.js";
|
||||
import { createLazyPromise } from "../shared/lazy-runtime.js";
|
||||
@@ -381,11 +381,11 @@ export function createGatewayAuxHandlers(params: {
|
||||
const restartedChannels = new Set<ChannelKind>();
|
||||
try {
|
||||
for (;;) {
|
||||
const previousSnapshot = getActiveSecretsRuntimeSnapshot();
|
||||
const previousSnapshot = getActiveSecretsRuntimeSnapshotState();
|
||||
if (!previousSnapshot) {
|
||||
throw new Error("Secrets runtime snapshot is not active.");
|
||||
}
|
||||
const previousSnapshotRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const previousSnapshotRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const previousGenerationOwnership =
|
||||
captureSharedGatewaySessionGenerationOwnership(
|
||||
params.sharedGatewaySessionGenerationState,
|
||||
@@ -404,7 +404,7 @@ export function createGatewayAuxHandlers(params: {
|
||||
publishFailureAsDegraded: true,
|
||||
forceColdRefKeys: reloadOptions?.forceColdRefKeys,
|
||||
canPublishFailureAsDegraded: () =>
|
||||
getActiveSecretsRuntimeSnapshotRevision() === previousSnapshotRevision,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() === previousSnapshotRevision,
|
||||
},
|
||||
);
|
||||
const plan = buildReloadPlan(
|
||||
@@ -425,7 +425,7 @@ export function createGatewayAuxHandlers(params: {
|
||||
activate: true,
|
||||
},
|
||||
async () => {
|
||||
publishedSnapshotRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
publishedSnapshotRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
generationOwnership = claimSharedGatewaySessionGenerationIfOwned(
|
||||
params.sharedGatewaySessionGenerationState,
|
||||
previousGenerationOwnership,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { isNixMode } from "../config/paths.js";
|
||||
import { ensureOpenClawCliOnPath } from "../infra/path-env.js";
|
||||
import { createSubsystemLogger, runtimeForLogger } from "../logging/subsystem.js";
|
||||
import { clearPluginMetadataLifecycleCaches } from "../plugins/plugin-metadata-lifecycle.js";
|
||||
import { clearSecretsRuntimeSnapshot } from "../secrets/runtime-state.js";
|
||||
import { clearSecretsRuntimeSnapshotState } from "../secrets/runtime-state.js";
|
||||
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
|
||||
import { startGatewayCoreRuntime } from "./server-core-runtime.js";
|
||||
import { prepareGatewayKernelRequestRuntime } from "./server-kernel-request-runtime.js";
|
||||
@@ -162,7 +162,7 @@ export async function createGatewayKernel(port = 18789, opts: GatewayServerOptio
|
||||
if (lifecycleRuntime) {
|
||||
await lifecycleRuntime.closeOnStartupFailure();
|
||||
} else {
|
||||
clearSecretsRuntimeSnapshot();
|
||||
clearSecretsRuntimeSnapshotState();
|
||||
clearPluginMetadataLifecycleCaches();
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { upsertPresence } from "../infra/system-presence.js";
|
||||
import { startDiagnosticHeartbeat, stopDiagnosticHeartbeat } from "../logging/diagnostic.js";
|
||||
import type { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { clearPluginMetadataLifecycleCaches } from "../plugins/plugin-metadata-lifecycle.js";
|
||||
import { clearSecretsRuntimeSnapshot } from "../secrets/runtime-state.js";
|
||||
import { clearSecretsRuntimeSnapshotState } from "../secrets/runtime-state.js";
|
||||
import { roleScopesAllow } from "../shared/operator-scope-compat.js";
|
||||
import {
|
||||
recordRemoteNodeInfo,
|
||||
@@ -517,7 +517,7 @@ export async function prepareGatewayLifecycle(params: {
|
||||
await createGatewayCloseHandler({
|
||||
bonjourStop: runtimeState.bonjourStop,
|
||||
tailscaleCleanup: runtimeState.tailscaleCleanup,
|
||||
clearSecretsRuntimeSnapshot,
|
||||
clearSecretsRuntimeSnapshot: clearSecretsRuntimeSnapshotState,
|
||||
channelIds,
|
||||
stopChannel,
|
||||
pluginServices: runtimeState.pluginServices,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { applySessionEntryCanonicalReplacements } from "../config/sessions/sessi
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
|
||||
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { createDeferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import { withOpenClawTestState } from "../test-utils/openclaw-test-state.js";
|
||||
import {
|
||||
createGatewayMethodRegistry,
|
||||
@@ -589,8 +589,8 @@ describe("sessions.patchMany orchestration", () => {
|
||||
cfg,
|
||||
key: conflictingAlias,
|
||||
}).storePath;
|
||||
const writerStarted = createDeferred();
|
||||
const insertConflictingAlias = createDeferred();
|
||||
const writerStarted = createDeferredCore();
|
||||
const insertConflictingAlias = createDeferredCore();
|
||||
const writer = applySessionEntryCanonicalReplacements({
|
||||
agentId: "main",
|
||||
sessionKeys: [conflictingAlias],
|
||||
@@ -612,7 +612,7 @@ describe("sessions.patchMany orchestration", () => {
|
||||
});
|
||||
await writerStarted.promise;
|
||||
|
||||
const preflightCompleted = createDeferred();
|
||||
const preflightCompleted = createDeferredCore();
|
||||
const respond = vi.fn();
|
||||
const request = sessionMutationHandlers["sessions.patchMany"]!({
|
||||
params: {
|
||||
@@ -686,8 +686,8 @@ describe("sessions.patchMany orchestration", () => {
|
||||
cfg,
|
||||
key: conflictingAlias,
|
||||
}).storePath;
|
||||
const writerStarted = createDeferred();
|
||||
const insertConflictingAlias = createDeferred();
|
||||
const writerStarted = createDeferredCore();
|
||||
const insertConflictingAlias = createDeferredCore();
|
||||
const writer = applySessionEntryCanonicalReplacements({
|
||||
agentId: "main",
|
||||
sessionKeys: [conflictingAlias],
|
||||
@@ -709,7 +709,7 @@ describe("sessions.patchMany orchestration", () => {
|
||||
});
|
||||
await writerStarted.promise;
|
||||
|
||||
const preflightCompleted = createDeferred();
|
||||
const preflightCompleted = createDeferredCore();
|
||||
const respond = vi.fn();
|
||||
const request = sessionMutationHandlers["sessions.patch"]!({
|
||||
params: { key: conflictingAlias, pinned: true },
|
||||
|
||||
@@ -6,7 +6,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { getDefaultLocalRoots } from "../../media/local-media-access.js";
|
||||
import { getDefaultLocalRootsCore } from "../../media/local-media-access.js";
|
||||
import { buildWebchatAssistantMessageFromReplyPayloads } from "./chat-webchat-media.js";
|
||||
|
||||
async function buildWebchatAudioBlocks(
|
||||
@@ -211,7 +211,7 @@ describe("webchat audio blocks through assistant messages", () => {
|
||||
});
|
||||
|
||||
it("falls back to default localRoots when explicit roots are omitted", async () => {
|
||||
const [defaultRoot] = getDefaultLocalRoots();
|
||||
const [defaultRoot] = getDefaultLocalRootsCore();
|
||||
if (defaultRoot === undefined) {
|
||||
throw new Error("expected default local media root");
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ vi.mock("../../secrets/runtime-state.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("../../secrets/runtime-state.js")>();
|
||||
return {
|
||||
...actual,
|
||||
getActiveSecretsRuntimeSnapshot: () => secretsMocks.activeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotState: () => secretsMocks.activeSnapshot,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
writeRestartSentinel,
|
||||
} from "../../infra/restart-sentinel.js";
|
||||
import { scheduleGatewaySigusr1Restart } from "../../infra/restart.js";
|
||||
import { getActiveSecretsRuntimeSnapshot } from "../../secrets/runtime-state.js";
|
||||
import { getActiveSecretsRuntimeSnapshotState } from "../../secrets/runtime-state.js";
|
||||
import { isRecord } from "../../utils.js";
|
||||
import { resolveEffectiveSharedGatewayAuth, resolveGatewayAuth } from "../auth.js";
|
||||
import { invalidateConfigGetResponseCache } from "../config-get-response.js";
|
||||
@@ -137,7 +137,7 @@ export function didActiveSharedGatewayAuthChange(params: {
|
||||
fallbackSource?: OpenClawConfig;
|
||||
next: OpenClawConfig;
|
||||
}): boolean {
|
||||
const active = getActiveSecretsRuntimeSnapshot();
|
||||
const active = getActiveSecretsRuntimeSnapshotState();
|
||||
if (!active) {
|
||||
return didSharedGatewayAuthChange(params.fallbackPrev, params.next);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ vi.mock("../../secrets/runtime.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
getActiveSecretsRuntimeSnapshot: () => null,
|
||||
getActiveSecretsRuntimeSnapshotState: () => null,
|
||||
}));
|
||||
|
||||
vi.mock("../../infra/restart.js", () => ({
|
||||
|
||||
@@ -16,7 +16,7 @@ const storeMocks = vi.hoisted(() => ({
|
||||
|
||||
vi.mock("../../secrets/runtime-state.js", () => ({
|
||||
collectSecretStoreRefKeysInConfig: storeMocks.collectRefKeys,
|
||||
getActiveSecretsRuntimeSnapshot: storeMocks.getSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotState: storeMocks.getSnapshot,
|
||||
}));
|
||||
|
||||
vi.mock("../../secrets/store/secret-store.js", () => {
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { formatErrorMessage as errorMessage } from "../../infra/errors.js";
|
||||
import {
|
||||
collectSecretStoreRefKeysInConfig,
|
||||
getActiveSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotState,
|
||||
} from "../../secrets/runtime-state.js";
|
||||
import {
|
||||
deleteSecretStoreEntry,
|
||||
@@ -136,7 +136,7 @@ export function createSecretsHandlers(params: {
|
||||
const reloadStoreReference = async (
|
||||
name: string,
|
||||
): Promise<{ reloaded: boolean; warningCount?: number }> => {
|
||||
const snapshot = getActiveSecretsRuntimeSnapshot();
|
||||
const snapshot = getActiveSecretsRuntimeSnapshotState();
|
||||
const refKeys = snapshot
|
||||
? collectSecretStoreRefKeysInConfig(snapshot.sourceConfig, name)
|
||||
: new Set<string>();
|
||||
|
||||
@@ -6,9 +6,9 @@ import {
|
||||
} from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import {
|
||||
clearSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision,
|
||||
clearSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState,
|
||||
hasActiveSecretsRuntimeSnapshotLineage,
|
||||
hasSameSecretReloadContract,
|
||||
restoreSecretsRuntimeSourceSnapshotIfLineageCurrent,
|
||||
@@ -43,7 +43,7 @@ import { publishRuntimeSecretsStateTransition } from "./server-startup-config.js
|
||||
export function isRuntimeSecretsPreparationCurrent(
|
||||
preparation: CurrentRuntimeSecretsPreparation,
|
||||
): boolean {
|
||||
return getActiveSecretsRuntimeSnapshotRevision() === preparation.expectedRevision;
|
||||
return getActiveSecretsRuntimeSnapshotRevisionState() === preparation.expectedRevision;
|
||||
}
|
||||
|
||||
async function activateSecretsRuntimeSnapshotIfCurrent(
|
||||
@@ -124,8 +124,8 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
const previousRuntimeSourceConfig = getRuntimeConfigSourceSnapshot();
|
||||
const previousSecretsSnapshot = getActiveSecretsRuntimeSnapshot();
|
||||
const previousSecretsRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const previousSecretsSnapshot = getActiveSecretsRuntimeSnapshotState();
|
||||
const previousSecretsRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const previousRuntimeMetadata = getRuntimeConfigSnapshotMetadata();
|
||||
const nextSecretsSourceConfig = prepareRuntimeCandidate(
|
||||
nextConfig,
|
||||
@@ -158,7 +158,7 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const committedSecretsRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const committedSecretsRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const rollbackPublishedSource = async () => {
|
||||
if (
|
||||
!restoreSecretsRuntimeSourceSnapshotIfLineageCurrent({
|
||||
@@ -246,7 +246,7 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
if (!activated) {
|
||||
continue;
|
||||
}
|
||||
const committedSecretsRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const committedSecretsRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const rollbackPublishedSource = async () => {
|
||||
if (
|
||||
!(await restoreSecretsRuntimeSnapshotIfCurrent(
|
||||
@@ -334,8 +334,8 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
if (!transactionOwnership.isCurrent()) {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
const previousSnapshot = getActiveSecretsRuntimeSnapshot();
|
||||
const previousSnapshotRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const previousSnapshot = getActiveSecretsRuntimeSnapshotState();
|
||||
const previousSnapshotRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const previousGenerationOwnership = captureSharedGatewaySessionGenerationOwnership(
|
||||
params.sharedGatewaySessionGenerationState,
|
||||
);
|
||||
@@ -361,7 +361,7 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
if (!transactionOwnership.isCurrent()) {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
if (getActiveSecretsRuntimeSnapshotRevision() !== previousSnapshotRevision) {
|
||||
if (getActiveSecretsRuntimeSnapshotRevisionState() !== previousSnapshotRevision) {
|
||||
continue;
|
||||
}
|
||||
const nextSharedGatewaySessionGeneration =
|
||||
@@ -416,7 +416,7 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
};
|
||||
const publishRuntime = async () => {
|
||||
runtimeSecretsPublished = true;
|
||||
publishedSnapshotRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
publishedSnapshotRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
// Claim the generation at the snapshot activation edge, but keep
|
||||
// `required` until the runtime commit succeeds.
|
||||
claimGenerationOwnership();
|
||||
@@ -461,9 +461,9 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
);
|
||||
} else if (
|
||||
publishedSnapshotRevision !== null &&
|
||||
getActiveSecretsRuntimeSnapshotRevision() === publishedSnapshotRevision
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() === publishedSnapshotRevision
|
||||
) {
|
||||
clearSecretsRuntimeSnapshot();
|
||||
clearSecretsRuntimeSnapshotState();
|
||||
snapshotRestored = true;
|
||||
if (generationOwnership) {
|
||||
generationRestored = restoreOwnedCurrentSharedGatewaySessionGeneration(
|
||||
@@ -572,9 +572,9 @@ export function createManagedReloadSecretHandlers(options: {
|
||||
} else if (
|
||||
publishedSnapshotRevision !== null &&
|
||||
generationOwnership &&
|
||||
getActiveSecretsRuntimeSnapshotRevision() === publishedSnapshotRevision
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() === publishedSnapshotRevision
|
||||
) {
|
||||
clearSecretsRuntimeSnapshot();
|
||||
clearSecretsRuntimeSnapshotState();
|
||||
snapshotRestored = true;
|
||||
generationRestored = restoreOwnedCurrentSharedGatewaySessionGeneration(
|
||||
params.sharedGatewaySessionGenerationState,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { runWithGatewayIndependentRootWorkAdmission } from "../process/gateway-work-admission.js";
|
||||
import { getActiveSecretsRuntimeSnapshotRevision } from "../secrets/runtime-state.js";
|
||||
import { getActiveSecretsRuntimeSnapshotRevisionState } from "../secrets/runtime-state.js";
|
||||
import { resetSkillSnapshotConfigFingerprintCache } from "../skills/runtime/snapshot-config-fingerprint.js";
|
||||
import { invalidateConfigGetResponseCache } from "./config-get-response.js";
|
||||
import {
|
||||
@@ -71,26 +71,26 @@ export function startManagedGatewayConfigReloader(
|
||||
if (!transactionOwnership.isCurrent()) {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
try {
|
||||
const snapshot = await params.activateRuntimeSecrets(config, {
|
||||
...activationParams,
|
||||
activate: false,
|
||||
canPublishFailureAsDegraded: () =>
|
||||
transactionOwnership.isCurrent() &&
|
||||
getActiveSecretsRuntimeSnapshotRevision() === expectedRevision,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() === expectedRevision,
|
||||
});
|
||||
if (!transactionOwnership.isCurrent()) {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
return getActiveSecretsRuntimeSnapshotRevision() === expectedRevision
|
||||
return getActiveSecretsRuntimeSnapshotRevisionState() === expectedRevision
|
||||
? { snapshot, expectedRevision }
|
||||
: null;
|
||||
} catch (error) {
|
||||
if (!transactionOwnership.isCurrent()) {
|
||||
throw new GatewayConfigReloadSupersededError();
|
||||
}
|
||||
if (getActiveSecretsRuntimeSnapshotRevision() !== expectedRevision) {
|
||||
if (getActiveSecretsRuntimeSnapshotRevisionState() !== expectedRevision) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { loadAuthProfileStoreWithoutExternalProfiles } from "../agents/auth-profiles.js";
|
||||
import {
|
||||
getRuntimeAuthProfileStoreCredentialsRevision,
|
||||
getRuntimeAuthProfileStoreSnapshot,
|
||||
getRuntimeAuthProfileStoreSnapshotCore,
|
||||
setRuntimeAuthProfileStoreSnapshot,
|
||||
} from "../agents/auth-profiles/runtime-snapshots.js";
|
||||
import { writePersistedAuthProfileStoreRaw } from "../agents/auth-profiles/sqlite.js";
|
||||
@@ -20,9 +20,9 @@ import { activateProviderAuthRuntimeSnapshot } from "../secrets/runtime-provider
|
||||
import {
|
||||
activateSecretsRuntimeSnapshotState,
|
||||
activateSecretsRuntimeSnapshotStateIfCurrent,
|
||||
clearSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision,
|
||||
clearSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState,
|
||||
} from "../secrets/runtime-state.js";
|
||||
import type { PreparedSecretsRuntimeSnapshot, SecretResolverWarning } from "../secrets/runtime.js";
|
||||
import { withEnvAsync } from "../test-utils/env.js";
|
||||
@@ -427,7 +427,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
const previousSkipProviders = process.env.OPENCLAW_SKIP_PROVIDERS;
|
||||
|
||||
afterEach(() => {
|
||||
clearSecretsRuntimeSnapshot();
|
||||
clearSecretsRuntimeSnapshotState();
|
||||
if (previousSkipChannels === undefined) {
|
||||
delete process.env.OPENCLAW_SKIP_CHANNELS;
|
||||
} else {
|
||||
@@ -452,9 +452,9 @@ describe("gateway startup config secret preflight", () => {
|
||||
activateRuntimeSecretsSnapshot,
|
||||
});
|
||||
activateSecretsRuntimeSnapshotForTest(initial);
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
activateSecretsRuntimeSnapshotForTest(refreshed);
|
||||
const refreshedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const refreshedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(candidate, initialRevision, {
|
||||
@@ -514,7 +514,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
logSecrets,
|
||||
});
|
||||
activateSecretsRuntimeSnapshotForTest(initial);
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const activateSnapshotIfCurrent = vi.fn(() => {
|
||||
activateSecretsRuntimeSnapshotForTest(candidate);
|
||||
return true;
|
||||
@@ -576,7 +576,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
publishFailureAsDegraded: true,
|
||||
}),
|
||||
).rejects.toThrow(failure.message);
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const expectedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
await expect(
|
||||
activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: candidate,
|
||||
@@ -636,7 +636,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
|
||||
await activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: providerDegraded,
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevision(),
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
activateSnapshotIfCurrent: () => {
|
||||
activateSecretsRuntimeSnapshotForTest(providerDegraded);
|
||||
return true;
|
||||
@@ -652,7 +652,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
const recovered = preparedSnapshot(config);
|
||||
await activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: recovered,
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevision(),
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
activateSnapshotIfCurrent: () => {
|
||||
activateSecretsRuntimeSnapshotForTest(recovered);
|
||||
return true;
|
||||
@@ -689,7 +689,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: candidate,
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevision(),
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
activateSnapshotIfCurrent: () => true,
|
||||
}),
|
||||
).resolves.toBe(true);
|
||||
@@ -728,7 +728,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
const recovered = preparedSnapshot(config);
|
||||
await activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: recovered,
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevision(),
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
activateSnapshotIfCurrent: () => {
|
||||
activateSecretsRuntimeSnapshotForTest(recovered);
|
||||
return true;
|
||||
@@ -797,7 +797,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
const recovered = preparedSnapshot(config);
|
||||
await activateProviderAuthRuntimeSnapshot({
|
||||
snapshot: recovered,
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevision(),
|
||||
expectedRevision: getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
activateSnapshotIfCurrent: () => {
|
||||
activateSecretsRuntimeSnapshotForTest(recovered);
|
||||
return true;
|
||||
@@ -848,7 +848,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
rolledBackCandidate,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(rolledBackCandidate);
|
||||
@@ -859,7 +859,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
committedCandidate,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(committedCandidate);
|
||||
@@ -918,11 +918,11 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
degraded,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(degraded);
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const descendant: PreparedSecretsRuntimeSnapshot = structuredClone(degraded);
|
||||
descendant.degradedOwners?.push({
|
||||
ownerKind: "provider",
|
||||
@@ -985,11 +985,11 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
degraded,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(degraded);
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const recovered = preparedSnapshot(config);
|
||||
|
||||
await expect(
|
||||
@@ -1060,11 +1060,11 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
providerDegraded,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(providerDegraded);
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const recovered = preparedSnapshot(config);
|
||||
|
||||
await expect(
|
||||
@@ -1126,11 +1126,11 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
recovered,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(recovered);
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const outerRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const descendant = structuredClone(recovered);
|
||||
|
||||
await expect(
|
||||
@@ -1208,7 +1208,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
|
||||
const sourceOnly = preparedSnapshot(stableConfig);
|
||||
activateSecretsRuntimeSnapshotForTest(sourceOnly);
|
||||
const committedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const committedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const descendant = structuredClone(sourceOnly);
|
||||
expect(
|
||||
activateSecretsRuntimeSnapshotStateIfCurrent({
|
||||
@@ -1259,7 +1259,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
activateRuntimeSecretsSnapshot,
|
||||
});
|
||||
activateSecretsRuntimeSnapshotForTest(initial);
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
setRuntimeAuthProfileStoreSnapshot(
|
||||
{
|
||||
version: 1,
|
||||
@@ -1283,7 +1283,9 @@ describe("gateway startup config secret preflight", () => {
|
||||
}),
|
||||
).resolves.toBeNull();
|
||||
expect(activateRuntimeSecretsSnapshot).not.toHaveBeenCalled();
|
||||
expect(getRuntimeAuthProfileStoreSnapshot(agentDir)?.profiles["openai:default"]).toMatchObject({
|
||||
expect(
|
||||
getRuntimeAuthProfileStoreSnapshotCore(agentDir)?.profiles["openai:default"],
|
||||
).toMatchObject({
|
||||
access: "access-new",
|
||||
refresh: "refresh-new",
|
||||
});
|
||||
@@ -1298,7 +1300,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
activateRuntimeSecretsSnapshot: vi.fn(activateSecretsRuntimeSnapshotForTest),
|
||||
});
|
||||
activateSecretsRuntimeSnapshotForTest(initial);
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const initialRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
let releasePublication: (() => void) | undefined;
|
||||
const publicationBlocked = new Promise<void>((resolve) => {
|
||||
releasePublication = resolve;
|
||||
@@ -1330,7 +1332,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
releasePublication?.();
|
||||
await candidateActivation;
|
||||
await laterActivation;
|
||||
expect(getActiveSecretsRuntimeSnapshot()?.config.gateway?.auth?.token).toBe("later-token");
|
||||
expect(getActiveSecretsRuntimeSnapshotState()?.config.gateway?.auth?.token).toBe("later-token");
|
||||
});
|
||||
|
||||
it("measures startup auth subphases", async () => {
|
||||
@@ -2092,7 +2094,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
}),
|
||||
).rejects.toThrow(missingSecretError.message);
|
||||
shouldResolve = true;
|
||||
const activeRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const activeRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const prepared = await activateRuntimeSecrets(sourceConfig, {
|
||||
reason: "restart-check",
|
||||
activate: false,
|
||||
@@ -2140,7 +2142,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
}),
|
||||
).rejects.toThrow(missingSecretError.message);
|
||||
shouldResolve = true;
|
||||
const sourceOnlyRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const sourceOnlyRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const sourceOnly = await activateRuntimeSecrets(sourceConfig, {
|
||||
reason: "reload",
|
||||
activate: false,
|
||||
@@ -2173,7 +2175,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
"SECRETS_RELOADER_DEGRADED",
|
||||
]);
|
||||
shouldResolve = true;
|
||||
const newerRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const newerRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
const newerPrepared = await activateRuntimeSecrets(sourceConfig, {
|
||||
reason: "reload",
|
||||
activate: false,
|
||||
@@ -2218,8 +2220,8 @@ describe("gateway startup config secret preflight", () => {
|
||||
publishFailureAsDegraded: true,
|
||||
}),
|
||||
).rejects.toThrow(missingSecretError.message);
|
||||
const revertedSnapshot = getActiveSecretsRuntimeSnapshot()!;
|
||||
const revertedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const revertedSnapshot = getActiveSecretsRuntimeSnapshotState()!;
|
||||
const revertedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
revertedSnapshot,
|
||||
@@ -2267,11 +2269,11 @@ describe("gateway startup config secret preflight", () => {
|
||||
publishFailureAsDegraded: true,
|
||||
}),
|
||||
).rejects.toThrow(missingSecretError.message);
|
||||
const unrelatedRevertedSnapshot = getActiveSecretsRuntimeSnapshot()!;
|
||||
const unrelatedRevertedSnapshot = getActiveSecretsRuntimeSnapshotState()!;
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
unrelatedRevertedSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toMatchObject({ sourceConfig });
|
||||
@@ -2290,8 +2292,8 @@ describe("gateway startup config secret preflight", () => {
|
||||
publishFailureAsDegraded: true,
|
||||
}),
|
||||
).rejects.toThrow(missingSecretError.message);
|
||||
const unchangedSnapshot = getActiveSecretsRuntimeSnapshot()!;
|
||||
const unchangedRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const unchangedSnapshot = getActiveSecretsRuntimeSnapshotState()!;
|
||||
const unchangedRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
unchangedSnapshot,
|
||||
@@ -2389,7 +2391,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
revertedSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(revertedSnapshot);
|
||||
@@ -2402,7 +2404,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
fullyResolvedSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(fullyResolvedSnapshot);
|
||||
@@ -2433,7 +2435,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
await expect(
|
||||
activateRuntimeSecrets.activatePreparedSnapshotIfCurrent?.(
|
||||
secondRevertedSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision(),
|
||||
getActiveSecretsRuntimeSnapshotRevisionState(),
|
||||
{ reason: "reload", activate: true, deferStatePublication: true },
|
||||
),
|
||||
).resolves.toBe(secondRevertedSnapshot);
|
||||
@@ -2689,8 +2691,8 @@ describe("gateway startup config secret preflight", () => {
|
||||
|
||||
try {
|
||||
const {
|
||||
clearSecretsRuntimeSnapshot: clearImportedSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshot: getImportedSecretsRuntimeSnapshot,
|
||||
clearSecretsRuntimeSnapshotState: clearImportedSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotState: getImportedSecretsRuntimeSnapshot,
|
||||
} = await import("../secrets/runtime-state.js");
|
||||
const { getRuntimeConfigSnapshotRefreshHandler } =
|
||||
await import("../config/runtime-snapshot.js");
|
||||
@@ -2858,7 +2860,7 @@ describe("gateway startup config secret preflight", () => {
|
||||
activate: true,
|
||||
includeAuthStoreRefs: false,
|
||||
});
|
||||
expect(getRuntimeAuthProfileStoreSnapshot(agentDir)?.profiles["openai:default"]).toEqual(
|
||||
expect(getRuntimeAuthProfileStoreSnapshotCore(agentDir)?.profiles["openai:default"]).toEqual(
|
||||
credential,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -27,8 +27,8 @@ import {
|
||||
import {
|
||||
activateSecretsRuntimeSnapshotState,
|
||||
graftActiveSecretsRuntimeAuthState,
|
||||
getActiveSecretsRuntimeSnapshot,
|
||||
getActiveSecretsRuntimeSnapshotRevision,
|
||||
getActiveSecretsRuntimeSnapshotState,
|
||||
getActiveSecretsRuntimeSnapshotRevisionState,
|
||||
hasActiveSecretsRuntimeSnapshotLineage,
|
||||
hasSameSecretReloadContract,
|
||||
hasCurrentAuthStoreCredentialsRevision,
|
||||
@@ -268,7 +268,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
const activationScope = options?.stateScope ?? "full";
|
||||
if (activationParams.activate && (statePrepared.degradedOwners?.length ?? 0) > 0) {
|
||||
if (activationParams.deferStatePublication === true) {
|
||||
const activationRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const activationRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
deferredStateTransitions.set(prepared, {
|
||||
kind: "degraded",
|
||||
activationRevision,
|
||||
@@ -282,7 +282,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
} else if (activationParams.activate && secretsDegraded) {
|
||||
if (activationParams.deferStatePublication === true) {
|
||||
if (activeDegradationGeneration !== null) {
|
||||
const activationRevision = getActiveSecretsRuntimeSnapshotRevision();
|
||||
const activationRevision = getActiveSecretsRuntimeSnapshotRevisionState();
|
||||
deferredStateTransitions.set(prepared, {
|
||||
kind: "recovered",
|
||||
activationRevision,
|
||||
@@ -415,7 +415,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
const prepareRuntimeSecretsSnapshot =
|
||||
params.prepareRuntimeSecretsSnapshot ?? secretsRuntime!.prepareSecretsRuntimeSnapshot;
|
||||
const allowUnavailableSecretOwners =
|
||||
activationParams.reason !== "startup" || getActiveSecretsRuntimeSnapshot() === null;
|
||||
activationParams.reason !== "startup" || getActiveSecretsRuntimeSnapshotState() === null;
|
||||
const prepared = await measureDiagnosticsTimelineSpan(
|
||||
"secrets.prepare",
|
||||
() =>
|
||||
@@ -485,7 +485,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
: undefined;
|
||||
return await runWithSecretsActivationLock(async () => {
|
||||
if (
|
||||
getActiveSecretsRuntimeSnapshotRevision() !== expectedRevision ||
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() !== expectedRevision ||
|
||||
!hasCurrentAuthStoreCredentialsRevision(snapshot) ||
|
||||
(canActivate && !canActivate())
|
||||
) {
|
||||
@@ -522,7 +522,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
registerProviderAuthRuntimeSnapshotActivationOwner({
|
||||
runExclusive: runWithSecretsActivationLock,
|
||||
isCurrent: (snapshot, expectedRevision) =>
|
||||
getActiveSecretsRuntimeSnapshotRevision() === expectedRevision &&
|
||||
getActiveSecretsRuntimeSnapshotRevisionState() === expectedRevision &&
|
||||
hasCurrentAuthStoreCredentialsRevision(snapshot),
|
||||
assertValid: (snapshot) => assertRuntimeGatewayAuthNotKnownWeak(snapshot.config),
|
||||
publish: async (snapshot) => {
|
||||
@@ -553,7 +553,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
options?.sourceOnly === true &&
|
||||
options.expectedRevision !== undefined &&
|
||||
hasActiveSecretsRuntimeSnapshotLineage(options.expectedRevision);
|
||||
const activeSnapshot = sourceOnlyOwnsLineage ? getActiveSecretsRuntimeSnapshot() : null;
|
||||
const activeSnapshot = sourceOnlyOwnsLineage ? getActiveSecretsRuntimeSnapshotState() : null;
|
||||
const sourceOnlyDegradationGeneration = activeDegradationGeneration;
|
||||
const sourceOnlyContractRecovered =
|
||||
activeSnapshot !== null &&
|
||||
@@ -574,7 +574,7 @@ export function createRuntimeSecretsActivator(params: {
|
||||
if (!hasActiveSecretsRuntimeSnapshotLineage(transition.activationRevision)) {
|
||||
return;
|
||||
}
|
||||
const activeSnapshot = getActiveSecretsRuntimeSnapshot();
|
||||
const activeSnapshot = getActiveSecretsRuntimeSnapshotState();
|
||||
if (!activeSnapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from "node:path";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshot } from "../agents/auth-profiles/runtime-snapshots.js";
|
||||
import { getRuntimeAuthProfileStoreSnapshotCore } from "../agents/auth-profiles/runtime-snapshots.js";
|
||||
import { saveAuthProfileStore } from "../agents/auth-profiles/store.js";
|
||||
import { resolveMemorySearchConfig } from "../agents/memory-search.js";
|
||||
import { resolveApiKeyForProvider } from "../agents/model-auth.js";
|
||||
@@ -591,7 +591,7 @@ describe("Gateway startup SecretRef owner isolation", () => {
|
||||
expect(active?.degradedOwners).toMatchObject([
|
||||
{ ownerKind: "account", ownerId, state: "unavailable" },
|
||||
]);
|
||||
const store = getRuntimeAuthProfileStoreSnapshot(agentDir);
|
||||
const store = getRuntimeAuthProfileStoreSnapshotCore(agentDir);
|
||||
if (!store || !active) {
|
||||
throw new Error("Expected activated Gateway auth profile snapshot");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getRuntimeConfig } from "../config/config.js";
|
||||
import type { PluginRegistry } from "../plugins/registry-types.js";
|
||||
import {
|
||||
getActiveSecretsRuntimeConfigSnapshot,
|
||||
getActiveSecretsRuntimeEnv,
|
||||
getActiveSecretsRuntimeEnvState,
|
||||
} from "../secrets/runtime-state.js";
|
||||
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
|
||||
import type { WorkerBundleProducer, WorkerNpmArtifact } from "./worker-environments/bundle.js";
|
||||
@@ -180,7 +180,7 @@ export async function createGatewayWorkerEnvironmentRuntime(params: {
|
||||
kind: "material",
|
||||
contents: await workerRuntime.resolveSecretRefString(genericKeyRef, {
|
||||
config: getActiveSecretsRuntimeConfigSnapshot()?.sourceConfig ?? getRuntimeConfig(),
|
||||
env: getActiveSecretsRuntimeEnv(),
|
||||
env: getActiveSecretsRuntimeEnvState(),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { createDeferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import {
|
||||
coordinateWorkerPlacementDispatch,
|
||||
type GatewayWorkerPlacementRuntime,
|
||||
@@ -33,8 +33,8 @@ describe("worker placement dispatch coordinator", () => {
|
||||
});
|
||||
|
||||
it("coalesces an identical dispatch and rejects a conflicting in-flight request", async () => {
|
||||
const dispatchStarted = createDeferred();
|
||||
const releaseDispatch = createDeferred();
|
||||
const dispatchStarted = createDeferredCore();
|
||||
const releaseDispatch = createDeferredCore();
|
||||
const active = { state: "active" };
|
||||
const dispatch = vi.fn(async () => {
|
||||
dispatchStarted.resolve();
|
||||
@@ -76,8 +76,8 @@ describe("worker placement dispatch coordinator", () => {
|
||||
});
|
||||
|
||||
it("joins a retry before a queued reconciliation after dispatch failure", async () => {
|
||||
const dispatchStarted = createDeferred();
|
||||
const releaseDispatch = createDeferred();
|
||||
const dispatchStarted = createDeferredCore();
|
||||
const releaseDispatch = createDeferredCore();
|
||||
const dispatchError = new Error("provision failed");
|
||||
const dispatch = vi.fn(async () => {
|
||||
dispatchStarted.resolve();
|
||||
@@ -116,8 +116,8 @@ describe("worker placement dispatch coordinator", () => {
|
||||
});
|
||||
|
||||
it("coalesces full sweeps but runs a fresh targeted pass with its environment id", async () => {
|
||||
const fullSweepStarted = createDeferred();
|
||||
const releaseFullSweep = createDeferred();
|
||||
const fullSweepStarted = createDeferredCore();
|
||||
const releaseFullSweep = createDeferredCore();
|
||||
const reconcileActive = vi.fn(async (environmentId?: string) => {
|
||||
if (environmentId === undefined) {
|
||||
fullSweepStarted.resolve();
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
isSessionLifecycleMutationActive,
|
||||
runExclusiveSessionLifecycleMutation,
|
||||
} from "../sessions/session-lifecycle-admission.js";
|
||||
import { createDeferred } from "../shared/deferred.js";
|
||||
import { createDeferredCore } from "../shared/deferred.js";
|
||||
import { closeOpenClawStateDatabaseForTest } from "../state/openclaw-state-db.js";
|
||||
import { markChatAbortTerminalPersistenceError } from "./chat-abort-lifecycle-internal.js";
|
||||
import { registerChatAbortController, removeChatAbortControllerEntry } from "./chat-abort.js";
|
||||
@@ -65,7 +65,7 @@ function activeRunContext(params: {
|
||||
runId: string;
|
||||
sessionId: string;
|
||||
sessionKey: string;
|
||||
persistence: ReturnType<typeof createDeferred<void>>;
|
||||
persistence: ReturnType<typeof createDeferredCore<void>>;
|
||||
ownerConnId?: string;
|
||||
}) {
|
||||
const chatAbortControllers = new Map();
|
||||
@@ -306,7 +306,7 @@ test("sessions.patch cancels active work and commits only after admission and te
|
||||
interrupted = true;
|
||||
},
|
||||
});
|
||||
const persistence = createDeferred();
|
||||
const persistence = createDeferredCore();
|
||||
const active = activeRunContext({
|
||||
runId,
|
||||
sessionId,
|
||||
@@ -385,7 +385,7 @@ test("sharing revocation fences archive before cancellation and forces fresh aut
|
||||
interrupted = true;
|
||||
},
|
||||
});
|
||||
const persistence = createDeferred();
|
||||
const persistence = createDeferredCore();
|
||||
const active = activeRunContext({ runId, sessionId, sessionKey, persistence });
|
||||
const requestContext = await archiveLifecycleRequestContext(active.context);
|
||||
const placement = workerPlacement({ sessionId, sessionKey, state: "active" });
|
||||
@@ -410,7 +410,7 @@ test("sharing revocation fences archive before cancellation and forces fresh aut
|
||||
throw new Error("expected resolved sharing target");
|
||||
}
|
||||
|
||||
const releaseAudit = createDeferred();
|
||||
const releaseAudit = createDeferredCore();
|
||||
sessionAuditGate.entered.mockClear();
|
||||
sessionAuditGate.wait = releaseAudit.promise;
|
||||
let sharing: Promise<LifecycleHandlerResponse> | undefined;
|
||||
@@ -492,11 +492,11 @@ test("archive retains the lifecycle fence until drain and commit before sharing
|
||||
identities: [sessionKey, sessionId],
|
||||
assertAllowed: () => {},
|
||||
});
|
||||
const persistence = createDeferred();
|
||||
const persistence = createDeferredCore();
|
||||
const active = activeRunContext({ runId, sessionId, sessionKey, persistence });
|
||||
const requestContext = await archiveLifecycleRequestContext(active.context);
|
||||
let placement = workerPlacement({ sessionId, sessionKey, state: "active" });
|
||||
const reclaimGate = createDeferred();
|
||||
const reclaimGate = createDeferredCore();
|
||||
const reclaim = vi.fn(async () => {
|
||||
await reclaimGate.promise;
|
||||
placement = workerPlacement({ sessionId, sessionKey, state: "reclaimed" });
|
||||
@@ -569,9 +569,9 @@ test("alias archive lets the canonical cloud reclaim barrier reenter without dea
|
||||
const sessionId = "session-archive-cloud-alias";
|
||||
await writeSessionStore({ entries: { [sessionKey]: sessionStoreEntry(sessionId) } });
|
||||
let placement = workerPlacement({ sessionId, sessionKey, state: "active" });
|
||||
const reclaimEntered = createDeferred();
|
||||
const allowNestedReclaim = createDeferred();
|
||||
const contenderRelease = createDeferred();
|
||||
const reclaimEntered = createDeferredCore();
|
||||
const allowNestedReclaim = createDeferredCore();
|
||||
const contenderRelease = createDeferredCore();
|
||||
const reclaim = vi.fn(async () => {
|
||||
reclaimEntered.resolve();
|
||||
await allowNestedReclaim.promise;
|
||||
@@ -752,7 +752,7 @@ test("sessions.patch returns UNAVAILABLE when terminal persistence fails", async
|
||||
const sessionId = "session-archive-persistence-failure";
|
||||
const runId = "run-archive-persistence-failure";
|
||||
await writeSessionStore({ entries: { [sessionKey]: sessionStoreEntry(sessionId) } });
|
||||
const persistence = createDeferred();
|
||||
const persistence = createDeferredCore();
|
||||
const active = activeRunContext({ runId, sessionId, sessionKey, persistence });
|
||||
try {
|
||||
const archive = directSessionReq(
|
||||
@@ -862,7 +862,7 @@ test("sessions.patchMany prepares independent archive drains concurrently and re
|
||||
[secondKey]: sessionStoreEntry(secondSessionId),
|
||||
},
|
||||
});
|
||||
const firstDrained = createDeferred();
|
||||
const firstDrained = createDeferredCore();
|
||||
const firstRelease = vi.fn();
|
||||
const secondRelease = vi.fn();
|
||||
const beginInferenceSessionDrain = vi.fn((sessionId: string) => ({
|
||||
@@ -1012,7 +1012,7 @@ test("sessions.patch rejects a generation replaced after the exact preparation r
|
||||
const sessionId = "session-archive-generation-race";
|
||||
const runId = "run-archive-generation-race";
|
||||
await writeSessionStore({ entries: { [sessionKey]: sessionStoreEntry(sessionId) } });
|
||||
const persistence = createDeferred();
|
||||
const persistence = createDeferredCore();
|
||||
const active = activeRunContext({ runId, sessionId, sessionKey, persistence });
|
||||
let placement = workerPlacement({ sessionId, sessionKey, state: "active" });
|
||||
const dispatch = vi.fn();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user