






















@@ -312,6 +312,43 @@ const runDefaultEmbeddedTurn = async (sessionFile: string, prompt: string, sessi
312312});
313313};
314314315+const addAnthropicProvider = (
316+cfg: ReturnType<typeof createEmbeddedAgentRunnerOpenAiConfig>,
317+modelIds: string[],
318+) => ({
319+ ...cfg,
320+models: {
321+providers: {
322+ ...cfg.models?.providers,
323+anthropic: {
324+api: "anthropic-messages" as const,
325+apiKey: "sk-test",
326+baseUrl: "https://example.com",
327+models: modelIds.map((id) => ({
328+ id,
329+name: `Mock ${id}`,
330+reasoning: false,
331+input: ["text" as const],
332+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
333+contextWindow: 16_000,
334+maxTokens: 2048,
335+})),
336+},
337+},
338+},
339+});
340+341+const mockSuccessfulEmbeddedAttempt = () => {
342+runEmbeddedAttemptMock.mockResolvedValueOnce(
343+makeEmbeddedRunnerAttempt({
344+assistantTexts: ["ok"],
345+lastAssistant: buildEmbeddedRunnerAssistant({
346+content: [{ type: "text", text: "ok" }],
347+}),
348+}),
349+);
350+};
351+315352function firstMockCall(mock: { mock: { calls: unknown[][] } }, label: string): unknown[] {
316353const call = mock.mock.calls[0];
317354if (!call) {
@@ -338,14 +375,7 @@ describe("runEmbeddedAgent", () => {
338375list: [{ id: "research", model: "openrouter/research-default" }],
339376},
340377};
341-runEmbeddedAttemptMock.mockResolvedValueOnce(
342-makeEmbeddedRunnerAttempt({
343-assistantTexts: ["ok"],
344-lastAssistant: buildEmbeddedRunnerAssistant({
345-content: [{ type: "text", text: "ok" }],
346-}),
347-}),
348-);
378+mockSuccessfulEmbeddedAttempt();
349379350380await runEmbeddedAgent({
351381sessionId: "configured-default-model",
@@ -383,14 +413,7 @@ describe("runEmbeddedAgent", () => {
383413},
384414};
385415setRuntimeConfigSnapshot(cfg);
386-runEmbeddedAttemptMock.mockResolvedValueOnce(
387-makeEmbeddedRunnerAttempt({
388-assistantTexts: ["ok"],
389-lastAssistant: buildEmbeddedRunnerAssistant({
390-content: [{ type: "text", text: "ok" }],
391-}),
392-}),
393-);
416+mockSuccessfulEmbeddedAttempt();
394417395418await runEmbeddedAgent({
396419sessionId: "runtime-config-default-model",
@@ -415,6 +438,85 @@ describe("runEmbeddedAgent", () => {
415438);
416439});
417440441+it("uses the session-key agent default when agentId is inferred", async () => {
442+const sessionFile = nextSessionFile();
443+const cfg = {
444+ ...addAnthropicProvider(createEmbeddedAgentRunnerOpenAiConfig(["mock-1"]), [
445+"claude-opus-4-7",
446+]),
447+agents: {
448+defaults: {
449+model: { primary: "openai/mock-1" },
450+},
451+list: [
452+{
453+id: "research",
454+model: { primary: "anthropic/claude-opus-4-7" },
455+},
456+],
457+},
458+};
459+mockSuccessfulEmbeddedAttempt();
460+461+await runEmbeddedAgent({
462+sessionId: "session-key-agent-default",
463+sessionKey: "agent:research:embedded:session-key-agent-default",
464+ sessionFile,
465+ workspaceDir,
466+config: cfg,
467+prompt: "hello",
468+timeoutMs: 5_000,
469+ agentDir,
470+runId: nextRunId("session-key-agent-default"),
471+enqueue: immediateEnqueue,
472+});
473+474+expect(resolveModelAsyncMock).toHaveBeenNthCalledWith(
475+1,
476+"anthropic",
477+"claude-opus-4-7",
478+agentDir,
479+cfg,
480+expect.objectContaining({ skipAgentDiscovery: true }),
481+);
482+expect(
483+(firstRunEmbeddedAttemptParams() as { model?: { provider?: string; id?: string } }).model,
484+).toEqual(expect.objectContaining({ provider: "anthropic", id: "claude-opus-4-7" }));
485+});
486+487+it("resolves model-only provider refs instead of prefixing the default provider", async () => {
488+const sessionFile = nextSessionFile();
489+const cfg = addAnthropicProvider(createEmbeddedAgentRunnerOpenAiConfig(["mock-1"]), [
490+"claude-sonnet-4-6",
491+]);
492+mockSuccessfulEmbeddedAttempt();
493+494+await runEmbeddedAgent({
495+sessionId: "model-only-provider-ref",
496+ sessionFile,
497+ workspaceDir,
498+config: cfg,
499+prompt: "hello",
500+model: "anthropic/claude-sonnet-4-6",
501+timeoutMs: 5_000,
502+ agentDir,
503+runId: nextRunId("model-only-provider-ref"),
504+enqueue: immediateEnqueue,
505+});
506+507+expect(resolveModelAsyncMock).toHaveBeenNthCalledWith(
508+1,
509+"anthropic",
510+"claude-sonnet-4-6",
511+agentDir,
512+cfg,
513+expect.objectContaining({ skipAgentDiscovery: true }),
514+);
515+expect(
516+(firstRunEmbeddedAttemptParams() as { model?: { provider?: string; id?: string } }).model,
517+).toEqual(expect.objectContaining({ provider: "anthropic", id: "claude-sonnet-4-6" }));
518+});
519+418520it("skips models.json generation when dynamic model resolution succeeds", async () => {
419521const sessionFile = nextSessionFile();
420522const cfg = createEmbeddedAgentRunnerOpenAiConfig([]);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。