























@@ -41,6 +41,8 @@ const resolveModelAsyncMock = vi.fn(
4141const ensureOpenClawModelsJsonMock = vi.fn(async () => ({ wrote: false }));
4242const loggerWarnMock = vi.fn();
4343let refreshRuntimeAuthOnFirstPromptError = false;
44+let clearRuntimeConfigSnapshot: typeof import("../config/config.js").clearRuntimeConfigSnapshot;
45+let setRuntimeConfigSnapshot: typeof import("../config/config.js").setRuntimeConfigSnapshot;
44464547vi.mock("openclaw/plugin-sdk/llm", async () => {
4648const actual =
@@ -178,6 +180,7 @@ beforeAll(async () => {
178180vi.useRealTimers();
179181vi.resetModules();
180182installRunEmbeddedMocks();
183+({ clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } = await import("../config/config.js"));
181184({ runEmbeddedAgent } = await import("./embedded-agent-runner/run.js"));
182185({ SessionManager } = await import("openclaw/plugin-sdk/agent-sessions"));
183186e2eWorkspace = await createEmbeddedAgentRunnerTestWorkspace("openclaw-embedded-agent-");
@@ -190,6 +193,7 @@ afterAll(async () => {
190193});
191194192195beforeEach(() => {
196+clearRuntimeConfigSnapshot();
193197vi.useRealTimers();
194198runEmbeddedAttemptMock.mockReset();
195199disposeSessionMcpRuntimeMock.mockReset();
@@ -321,6 +325,96 @@ function firstRunEmbeddedAttemptParams(): { sessionKey?: string } {
321325}
322326323327describe("runEmbeddedAgent", () => {
328+it("uses the configured default model when the caller omits provider and model", async () => {
329+const sessionFile = nextSessionFile();
330+const cfg = {
331+ ...createEmbeddedAgentRunnerOpenAiConfig([]),
332+agents: {
333+defaults: {
334+model: {
335+primary: "openrouter/global-default",
336+},
337+},
338+list: [{ id: "research", model: "openrouter/research-default" }],
339+},
340+};
341+runEmbeddedAttemptMock.mockResolvedValueOnce(
342+makeEmbeddedRunnerAttempt({
343+assistantTexts: ["ok"],
344+lastAssistant: buildEmbeddedRunnerAssistant({
345+content: [{ type: "text", text: "ok" }],
346+}),
347+}),
348+);
349+350+await runEmbeddedAgent({
351+sessionId: "configured-default-model",
352+ sessionFile,
353+ workspaceDir,
354+config: cfg,
355+agentId: "research",
356+prompt: "hello",
357+timeoutMs: 5_000,
358+ agentDir,
359+runId: nextRunId("configured-default-model"),
360+enqueue: immediateEnqueue,
361+});
362+363+expect(resolveModelAsyncMock).toHaveBeenNthCalledWith(
364+1,
365+"openrouter",
366+"openrouter/research-default",
367+agentDir,
368+cfg,
369+expect.objectContaining({ skipAgentDiscovery: true }),
370+);
371+});
372+373+it("uses runtime config for blank public runtime model overrides", async () => {
374+const sessionFile = nextSessionFile();
375+const cfg = {
376+ ...createEmbeddedAgentRunnerOpenAiConfig([]),
377+agents: {
378+defaults: {
379+model: {
380+primary: "openrouter/runtime-default",
381+},
382+},
383+},
384+};
385+setRuntimeConfigSnapshot(cfg);
386+runEmbeddedAttemptMock.mockResolvedValueOnce(
387+makeEmbeddedRunnerAttempt({
388+assistantTexts: ["ok"],
389+lastAssistant: buildEmbeddedRunnerAssistant({
390+content: [{ type: "text", text: "ok" }],
391+}),
392+}),
393+);
394+395+await runEmbeddedAgent({
396+sessionId: "runtime-config-default-model",
397+ sessionFile,
398+ workspaceDir,
399+prompt: "hello",
400+provider: " ",
401+model: "",
402+timeoutMs: 5_000,
403+ agentDir,
404+runId: nextRunId("runtime-config-default-model"),
405+enqueue: immediateEnqueue,
406+});
407+408+expect(resolveModelAsyncMock).toHaveBeenNthCalledWith(
409+1,
410+"openrouter",
411+"openrouter/runtime-default",
412+agentDir,
413+cfg,
414+expect.objectContaining({ skipAgentDiscovery: true }),
415+);
416+});
417+324418it("skips models.json generation when dynamic model resolution succeeds", async () => {
325419const sessionFile = nextSessionFile();
326420const cfg = createEmbeddedAgentRunnerOpenAiConfig([]);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。