mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 11:55:47 -06:00
fix(plugins): reuse current metadata snapshots for tool loads
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user