mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:10:44 +00:00
fix: avoid default workspace metadata for agent models
This commit is contained in:
@@ -151,21 +151,29 @@ export async function ensureOpenClawModelsJson(
|
||||
agentDirOverride?: string,
|
||||
options: {
|
||||
pluginMetadataSnapshot?: Pick<PluginMetadataSnapshot, "index" | "manifestRegistry" | "owners">;
|
||||
workspaceDir?: string;
|
||||
} = {},
|
||||
): Promise<{ agentDir: string; wrote: boolean }> {
|
||||
const resolved = resolveModelsConfigInput(config);
|
||||
const cfg = resolved.config;
|
||||
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
||||
const workspaceDir =
|
||||
options.workspaceDir ??
|
||||
(agentDirOverride?.trim()
|
||||
? undefined
|
||||
: resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)));
|
||||
const pluginMetadataSnapshot =
|
||||
options.pluginMetadataSnapshot ??
|
||||
getCurrentPluginMetadataSnapshot({ config: cfg, workspaceDir });
|
||||
getCurrentPluginMetadataSnapshot({
|
||||
config: cfg,
|
||||
...(workspaceDir ? { 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,
|
||||
...(workspaceDir ? { workspaceDir } : {}),
|
||||
...(pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}),
|
||||
});
|
||||
const cached = MODELS_JSON_STATE.readyCache.get(targetPath);
|
||||
@@ -187,7 +195,7 @@ export async function ensureOpenClawModelsJson(
|
||||
sourceConfigForSecrets: resolved.sourceConfigForSecrets,
|
||||
agentDir,
|
||||
env,
|
||||
workspaceDir,
|
||||
...(workspaceDir ? { workspaceDir } : {}),
|
||||
existingRaw: existingModelsFile.raw,
|
||||
existingParsed: existingModelsFile.parsed,
|
||||
...(pluginMetadataSnapshot ? { pluginMetadataSnapshot } : {}),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveInstalledPluginIndexPolicyHash } from "../plugins/installed-plugin-index-policy.js";
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
|
||||
import {
|
||||
CUSTOM_PROXY_MODELS_CONFIG,
|
||||
installModelsConfigTestHooks,
|
||||
@@ -13,15 +15,63 @@ const planOpenClawModelsJsonMock = vi.fn();
|
||||
installModelsConfigTestHooks();
|
||||
|
||||
let ensureOpenClawModelsJson: typeof import("./models-config.js").ensureOpenClawModelsJson;
|
||||
let clearCurrentPluginMetadataSnapshot: typeof import("../plugins/current-plugin-metadata-snapshot.js").clearCurrentPluginMetadataSnapshot;
|
||||
let setCurrentPluginMetadataSnapshot: typeof import("../plugins/current-plugin-metadata-snapshot.js").setCurrentPluginMetadataSnapshot;
|
||||
|
||||
function createPluginMetadataSnapshot(workspaceDir: string): PluginMetadataSnapshot {
|
||||
const policyHash = resolveInstalledPluginIndexPolicyHash({});
|
||||
return {
|
||||
policyHash,
|
||||
workspaceDir,
|
||||
index: {
|
||||
version: 1,
|
||||
hostContractVersion: "test",
|
||||
compatRegistryVersion: "test",
|
||||
migrationVersion: 1,
|
||||
policyHash,
|
||||
generatedAtMs: 1,
|
||||
installRecords: {},
|
||||
plugins: [],
|
||||
diagnostics: [],
|
||||
},
|
||||
registryDiagnostics: [],
|
||||
manifestRegistry: { plugins: [], diagnostics: [] },
|
||||
plugins: [],
|
||||
diagnostics: [],
|
||||
byPluginId: new Map(),
|
||||
normalizePluginId: (pluginId) => pluginId,
|
||||
owners: {
|
||||
channels: new Map(),
|
||||
channelConfigs: new Map(),
|
||||
providers: new Map(),
|
||||
modelCatalogProviders: new Map(),
|
||||
cliBackends: new Map(),
|
||||
setupProviders: new Map(),
|
||||
commandAliases: new Map(),
|
||||
contracts: new Map(),
|
||||
},
|
||||
metrics: {
|
||||
registrySnapshotMs: 0,
|
||||
manifestRegistryMs: 0,
|
||||
ownerMapsMs: 0,
|
||||
totalMs: 0,
|
||||
indexPluginCount: 0,
|
||||
manifestPluginCount: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.doMock("./models-config.plan.js", () => ({
|
||||
planOpenClawModelsJson: (...args: unknown[]) => planOpenClawModelsJsonMock(...args),
|
||||
}));
|
||||
({ ensureOpenClawModelsJson } = await import("./models-config.js"));
|
||||
({ clearCurrentPluginMetadataSnapshot, setCurrentPluginMetadataSnapshot } =
|
||||
await import("../plugins/current-plugin-metadata-snapshot.js"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
clearCurrentPluginMetadataSnapshot();
|
||||
planOpenClawModelsJsonMock
|
||||
.mockReset()
|
||||
.mockImplementation(async (params: { cfg?: typeof CUSTOM_PROXY_MODELS_CONFIG }) => ({
|
||||
@@ -31,6 +81,38 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
describe("models-config write serialization", () => {
|
||||
it("does not reuse default workspace plugin metadata for explicit agent dirs without workspace", async () => {
|
||||
await withModelsTempHome(async (home) => {
|
||||
const snapshot = createPluginMetadataSnapshot(path.join(home, "default-workspace"));
|
||||
setCurrentPluginMetadataSnapshot(snapshot, { config: {} });
|
||||
const agentDir = path.join(home, "agent-non-default");
|
||||
|
||||
await ensureOpenClawModelsJson({}, agentDir);
|
||||
|
||||
expect(planOpenClawModelsJsonMock).toHaveBeenCalledWith(
|
||||
expect.not.objectContaining({ pluginMetadataSnapshot: snapshot }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("reuses current plugin metadata for explicit agent dirs with matching workspace", async () => {
|
||||
await withModelsTempHome(async (home) => {
|
||||
const workspaceDir = path.join(home, "agent-workspace");
|
||||
const snapshot = createPluginMetadataSnapshot(workspaceDir);
|
||||
setCurrentPluginMetadataSnapshot(snapshot, { config: {} });
|
||||
const agentDir = path.join(home, "agent-non-default");
|
||||
|
||||
await ensureOpenClawModelsJson({}, agentDir, { workspaceDir });
|
||||
|
||||
expect(planOpenClawModelsJsonMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
workspaceDir,
|
||||
pluginMetadataSnapshot: snapshot,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("serializes concurrent models.json writes to avoid overlap", async () => {
|
||||
await withModelsTempHome(async () => {
|
||||
const first = structuredClone(CUSTOM_PROXY_MODELS_CONFIG);
|
||||
|
||||
Reference in New Issue
Block a user