mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
fix: scope model provider discovery metadata to workspace
This commit is contained in:
@@ -151,7 +151,7 @@ Gateway startup builds one `PluginMetadataSnapshot` for the current config snaps
|
||||
|
||||
Plugin-aware config validation, startup auto-enable, and Gateway plugin bootstrap consume that snapshot instead of rebuilding manifest/index metadata independently. `PluginLookUpTable` is derived from the same snapshot and adds the startup plugin plan for the current runtime config.
|
||||
|
||||
After startup, Gateway keeps the current metadata snapshot as a replaceable runtime product. Repeated runtime provider discovery can borrow that snapshot instead of reconstructing the installed index and manifest registry for each provider-catalog pass. The snapshot is cleared or replaced on Gateway shutdown, config/plugin inventory changes, and installed index writes; callers fall back to the cold manifest/index path when no compatible current snapshot exists.
|
||||
After startup, Gateway keeps the current metadata snapshot as a replaceable runtime product. Repeated runtime provider discovery can borrow that snapshot instead of reconstructing the installed index and manifest registry for each provider-catalog pass. The snapshot is cleared or replaced on Gateway shutdown, config/plugin inventory changes, and installed index writes; callers fall back to the cold manifest/index path when no compatible current snapshot exists. Compatibility checks must include plugin discovery roots such as `plugins.load.paths` and the default agent workspace, because workspace plugins are part of the metadata scope.
|
||||
|
||||
The snapshot and lookup table keep repeated startup decisions on the fast path:
|
||||
|
||||
|
||||
@@ -104,6 +104,27 @@ describe("models-config", () => {
|
||||
expect(observedSnapshot).toBe(pluginMetadataSnapshot);
|
||||
});
|
||||
|
||||
it("threads workspace scope into implicit provider discovery", async () => {
|
||||
let observedWorkspaceDir: string | undefined;
|
||||
|
||||
await resolveProvidersForModelsJsonWithDeps(
|
||||
{
|
||||
cfg: { models: { providers: {} } },
|
||||
agentDir: "/tmp/openclaw-models-config-env-vars-test",
|
||||
env: {},
|
||||
workspaceDir: "/tmp/openclaw-workspace",
|
||||
},
|
||||
{
|
||||
resolveImplicitProviders: async ({ workspaceDir }) => {
|
||||
observedWorkspaceDir = workspaceDir;
|
||||
return {};
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(observedWorkspaceDir).toBe("/tmp/openclaw-workspace");
|
||||
});
|
||||
|
||||
it("threads plugin metadata snapshots through models.json planning", async () => {
|
||||
const pluginMetadataSnapshot = {
|
||||
index: { plugins: [] },
|
||||
|
||||
@@ -19,6 +19,7 @@ export type ResolveImplicitProvidersForModelsJson = (params: {
|
||||
agentDir: string;
|
||||
config: OpenClawConfig;
|
||||
env: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
explicitProviders: Record<string, ProviderConfig>;
|
||||
pluginMetadataSnapshot?: Pick<PluginMetadataSnapshot, "index" | "manifestRegistry" | "owners">;
|
||||
}) => Promise<Record<string, ProviderConfig>>;
|
||||
@@ -40,6 +41,7 @@ export async function resolveProvidersForModelsJsonWithDeps(
|
||||
cfg: OpenClawConfig;
|
||||
agentDir: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
pluginMetadataSnapshot?: Pick<PluginMetadataSnapshot, "index" | "manifestRegistry" | "owners">;
|
||||
},
|
||||
deps?: {
|
||||
@@ -53,6 +55,7 @@ export async function resolveProvidersForModelsJsonWithDeps(
|
||||
agentDir,
|
||||
config: cfg,
|
||||
env,
|
||||
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
||||
explicitProviders,
|
||||
...(params.pluginMetadataSnapshot
|
||||
? { pluginMetadataSnapshot: params.pluginMetadataSnapshot }
|
||||
@@ -94,6 +97,7 @@ export async function planOpenClawModelsJsonWithDeps(
|
||||
sourceConfigForSecrets?: OpenClawConfig;
|
||||
agentDir: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
existingRaw: string;
|
||||
existingParsed: unknown;
|
||||
pluginMetadataSnapshot?: Pick<PluginMetadataSnapshot, "index" | "manifestRegistry" | "owners">;
|
||||
@@ -108,6 +112,7 @@ export async function planOpenClawModelsJsonWithDeps(
|
||||
cfg,
|
||||
agentDir,
|
||||
env,
|
||||
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
||||
...(params.pluginMetadataSnapshot
|
||||
? { pluginMetadataSnapshot: params.pluginMetadataSnapshot }
|
||||
: {}),
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-meta
|
||||
import { resolveInstalledManifestRegistryIndexFingerprint } from "../plugins/manifest-registry-installed.js";
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "./agent-scope.js";
|
||||
import { MODELS_JSON_STATE } from "./models-config-state.js";
|
||||
import { planOpenClawModelsJson } from "./models-config.plan.js";
|
||||
|
||||
@@ -44,6 +45,7 @@ async function buildModelsJsonFingerprint(params: {
|
||||
config: OpenClawConfig;
|
||||
sourceConfigForSecrets: OpenClawConfig;
|
||||
agentDir: string;
|
||||
workspaceDir?: string;
|
||||
pluginMetadataSnapshot?: Pick<PluginMetadataSnapshot, "index">;
|
||||
}): Promise<string> {
|
||||
const authProfilesMtimeMs = await readFileMtimeMs(
|
||||
@@ -60,6 +62,7 @@ async function buildModelsJsonFingerprint(params: {
|
||||
envShape,
|
||||
authProfilesMtimeMs,
|
||||
modelsFileMtimeMs,
|
||||
workspaceDir: params.workspaceDir,
|
||||
pluginMetadataSnapshotIndexFingerprint,
|
||||
});
|
||||
}
|
||||
@@ -152,14 +155,17 @@ export async function ensureOpenClawModelsJson(
|
||||
): Promise<{ agentDir: string; wrote: boolean }> {
|
||||
const resolved = resolveModelsConfigInput(config);
|
||||
const cfg = resolved.config;
|
||||
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
||||
const pluginMetadataSnapshot =
|
||||
options.pluginMetadataSnapshot ?? getCurrentPluginMetadataSnapshot({ config: cfg });
|
||||
options.pluginMetadataSnapshot ??
|
||||
getCurrentPluginMetadataSnapshot({ config: cfg, workspaceDir });
|
||||
const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveOpenClawAgentDir();
|
||||
const targetPath = path.join(agentDir, "models.json");
|
||||
const fingerprint = await buildModelsJsonFingerprint({
|
||||
config: cfg,
|
||||
sourceConfigForSecrets: resolved.sourceConfigForSecrets,
|
||||
agentDir,
|
||||
workspaceDir,
|
||||
...(pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}),
|
||||
});
|
||||
const cached = MODELS_JSON_STATE.readyCache.get(targetPath);
|
||||
@@ -181,6 +187,7 @@ export async function ensureOpenClawModelsJson(
|
||||
sourceConfigForSecrets: resolved.sourceConfigForSecrets,
|
||||
agentDir,
|
||||
env,
|
||||
workspaceDir,
|
||||
existingRaw: existingModelsFile.raw,
|
||||
existingParsed: existingModelsFile.parsed,
|
||||
...(pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}),
|
||||
|
||||
Reference in New Issue
Block a user