fix(plugins): reuse current metadata snapshots for tool loads

This commit is contained in:
luoyanglang
2026-05-17 10:11:52 +00:00
committed by Vincent Koc
parent 6c37a20465
commit 5bf22d2a49
3 changed files with 43 additions and 15 deletions
+1
View File
@@ -3110,6 +3110,7 @@ This audited record covers the complete v2026.5.28..v2026.5.31-beta.4 history: 4
- CLI/context engines: bootstrap and finalize non-legacy context engines for CLI turns while preserving transcript snapshots and deferred maintenance ownership. (#81869) Thanks @sahilsatralkar.
- Telegram: persist polling updates through restart replay so queued same-topic messages resume in order instead of losing context after a gateway restart. (#82256) Thanks @VACInc.
- Gateway/Gmail: abort in-flight Gmail watcher startup and hot-reload restarts before shutdown so reloads cannot spawn `gog serve` after the Gateway is closing. Thanks @frankekn.
- Plugins: reuse compatible current metadata snapshots during runtime load-context resolution, so plugin tool discovery does not discard gateway-provided manifests before auto-enable settles.
- Agents/Codex: fall back to the embedded PI runner when OpenAI's implicit Codex harness preference cannot find a registered Codex plugin, preventing OpenAI-compatible gateway requests from failing with an unregistered harness error. Fixes #82437.
- Agents/OpenAI: honor `openai-codex:*` entries placed ahead of API-key backups in `auth.order.openai` for explicit OpenAI PI runs, and accept `models auth login --provider openai-codex --device-code` for headless sign-in. Fixes #82521. (#82605)
- CLI/channels: install missing externalized same-id channel plugins during `channels add --channel <id>`, so recovery for WhatsApp and other externalized stock channels does not require a separate `plugins enable` step. Fixes #82533.
+4
View File
@@ -21,6 +21,7 @@ const metadataSnapshot = {
workspaceDir: "/resolved-workspace",
};
const loadPluginMetadataSnapshotMock = vi.fn(() => metadataSnapshot);
const isPluginMetadataSnapshotCompatibleMock = vi.fn(() => true);
const getCurrentPluginMetadataSnapshotMock = vi.fn(() => undefined);
const setCurrentPluginMetadataSnapshotMock = vi.fn();
const clearCurrentPluginMetadataSnapshotMock = vi.fn();
@@ -45,6 +46,7 @@ vi.mock("../../agents/agent-scope.js", () => ({
}));
vi.mock("../plugin-metadata-snapshot.js", () => ({
isPluginMetadataSnapshotCompatible: isPluginMetadataSnapshotCompatibleMock,
loadPluginMetadataSnapshot: loadPluginMetadataSnapshotMock,
resolvePluginMetadataSnapshot: loadPluginMetadataSnapshotMock,
}));
@@ -69,6 +71,8 @@ describe("resolvePluginRuntimeLoadContext", () => {
applyPluginAutoEnableMock.mockReset();
getCurrentPluginMetadataSnapshotMock.mockReset();
getCurrentPluginMetadataSnapshotMock.mockReturnValue(undefined);
isPluginMetadataSnapshotCompatibleMock.mockReset();
isPluginMetadataSnapshotCompatibleMock.mockReturnValue(true);
loadPluginMetadataSnapshotMock.mockClear();
getCurrentPluginMetadataSnapshotMock.mockClear();
setCurrentPluginMetadataSnapshotMock.mockClear();
+38 -15
View File
@@ -14,7 +14,10 @@ import {
import { extractPluginInstallRecordsFromInstalledPluginIndex } from "../installed-plugin-index-install-records.js";
import type { PluginLoadOptions } from "../loader.js";
import type { PluginManifestRegistry } from "../manifest-registry.js";
import { resolvePluginMetadataSnapshot } from "../plugin-metadata-snapshot.js";
import {
isPluginMetadataSnapshotCompatible,
resolvePluginMetadataSnapshot,
} from "../plugin-metadata-snapshot.js";
import type { PluginLogger } from "../types.js";
const log = createSubsystemLogger("plugins");
@@ -73,18 +76,16 @@ export function resolvePluginRuntimeLoadContext(
const rawConfig = options?.config ?? getRuntimeConfig();
const rawWorkspaceDir =
options?.workspaceDir ?? resolveAgentWorkspaceDir(rawConfig, resolveDefaultAgentId(rawConfig));
const metadataSnapshot = options?.manifestRegistry
? undefined
: resolvePluginMetadataSnapshot({
config: rawConfig,
env,
workspaceDir: rawWorkspaceDir,
allowWorkspaceScopedCurrent: true,
});
const manifestRegistry = options?.manifestRegistry ?? metadataSnapshot?.manifestRegistry;
const installRecords = metadataSnapshot
? extractPluginInstallRecordsFromInstalledPluginIndex(metadataSnapshot.index)
: undefined;
const initialMetadataSnapshot =
options?.manifestRegistry === undefined
? resolvePluginMetadataSnapshot({
config: rawConfig,
env,
workspaceDir: rawWorkspaceDir,
allowWorkspaceScopedCurrent: true,
})
: undefined;
const manifestRegistry = options?.manifestRegistry ?? initialMetadataSnapshot?.manifestRegistry;
const activationSourceConfig = resolvePluginActivationSourceConfig({
config: rawConfig,
activationSourceConfig: options?.activationSourceConfig,
@@ -93,11 +94,33 @@ export function resolvePluginRuntimeLoadContext(
config: rawConfig,
env,
manifestRegistry,
discovery: metadataSnapshot?.discovery,
discovery: initialMetadataSnapshot?.discovery,
});
const config = autoEnabled.config;
const workspaceDir =
options?.workspaceDir ?? resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
const metadataSnapshot =
options?.manifestRegistry !== undefined
? undefined
: initialMetadataSnapshot &&
isPluginMetadataSnapshotCompatible({
snapshot: initialMetadataSnapshot,
config,
env,
workspaceDir,
})
? initialMetadataSnapshot
: resolvePluginMetadataSnapshot({
config,
env,
workspaceDir,
allowWorkspaceScopedCurrent: true,
...(initialMetadataSnapshot ? { index: initialMetadataSnapshot.index } : {}),
});
const finalManifestRegistry = options?.manifestRegistry ?? metadataSnapshot?.manifestRegistry;
const installRecords = metadataSnapshot
? extractPluginInstallRecordsFromInstalledPluginIndex(metadataSnapshot.index)
: undefined;
if (metadataSnapshot) {
// Reusable snapshots stay available to later manifest-policy lookups for this runtime load.
if (isReusableCurrentPluginMetadataSnapshot(metadataSnapshot)) {
@@ -119,7 +142,7 @@ export function resolvePluginRuntimeLoadContext(
workspaceDir,
env,
logger: options?.logger ?? createPluginRuntimeLoaderLogger(),
manifestRegistry,
...(finalManifestRegistry ? { manifestRegistry: finalManifestRegistry } : {}),
installRecords,
};
}