feat(FN-2598): merge fusion/fn-2598 (auto-resolved)
- test(FN-2598): complete Step 3 — update collapsed model header coverage - fix(FN-2598): normalize expand button spacing token - feat(FN-2598): complete Step 2 — style compact model header - feat(FN-2598): complete Step 1 — compact model header structure
This commit is contained in:
@@ -7,7 +7,10 @@ import type { AgentLogEntry } from "@fusion/core";
|
||||
vi.mock("lucide-react", () => ({
|
||||
Maximize2: () => null,
|
||||
Minimize2: () => null,
|
||||
Loader2: () => null,
|
||||
Cpu: () => null,
|
||||
ChevronDown: () => null,
|
||||
ChevronRight: () => null,
|
||||
}));
|
||||
|
||||
function makeEntry(overrides: Partial<AgentLogEntry> = {}): AgentLogEntry {
|
||||
@@ -275,38 +278,34 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-sonnet-4-5" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(header!.textContent).not.toContain("Executor:");
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
// Verify ProviderIcon is rendered for executor
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders 'Using default' when no executor model override is set", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} executorModel={null} />
|
||||
<AgentLogViewer entries={entries} loading={false} executorModel={null} />,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders 'Using default' when executorModel is undefined", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} />
|
||||
);
|
||||
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders model info header with validator model when set", () => {
|
||||
@@ -316,27 +315,26 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
validatorModel={{ provider: "openai", modelId: "gpt-4o" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="openai"]')).toBeTruthy();
|
||||
expect(header!.textContent).not.toContain("Validator:");
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
// Verify ProviderIcon is rendered for validator
|
||||
expect(container.querySelector('[data-provider="openai"]')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders 'Using default' when no validator model override is set", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} validatorModel={null} />
|
||||
<AgentLogViewer entries={entries} loading={false} validatorModel={null} />,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders both models when both are configured", () => {
|
||||
@@ -347,30 +345,26 @@ describe("AgentLogViewer", () => {
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-opus-4" }}
|
||||
validatorModel={{ provider: "openai", modelId: "gpt-4o" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
// Verify both ProviderIcons are rendered
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="openai"]')).toBeTruthy();
|
||||
expect(header!.textContent).not.toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).not.toContain("openai/gpt-4o");
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
});
|
||||
|
||||
it("renders header with 'Using default' for both models when both are null/undefined", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} />
|
||||
);
|
||||
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("shows 'Using default' when executorModel has only provider but no modelId", () => {
|
||||
@@ -380,12 +374,11 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("shows 'Using default' when executorModel has only modelId but no provider", () => {
|
||||
@@ -395,12 +388,11 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ modelId: "claude-sonnet-4-5" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders model info header with planning model when set", () => {
|
||||
@@ -410,36 +402,34 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
planningModel={{ provider: "anthropic", modelId: "claude-opus-4" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
// Verify ProviderIcon is rendered for planning
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(header!.textContent).not.toContain("Planning/Triage:");
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(header!.textContent).toContain("Planning/Triage:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
});
|
||||
|
||||
it("renders 'Using default' for planning when no planning model is set", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} planningModel={null} />
|
||||
<AgentLogViewer entries={entries} loading={false} planningModel={null} />,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders 'Using default' for planning when planningModel is undefined", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer entries={entries} loading={false} />
|
||||
);
|
||||
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
|
||||
it("renders all three models when all are configured", () => {
|
||||
@@ -451,20 +441,21 @@ describe("AgentLogViewer", () => {
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-opus-4" }}
|
||||
validatorModel={{ provider: "openai", modelId: "gpt-4o" }}
|
||||
planningModel={{ provider: "google", modelId: "gemini-pro" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Executor:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).toContain("Validator:");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
// Verify all three ProviderIcons are rendered
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="openai"]')).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="google"]')).toBeTruthy();
|
||||
expect(header!.textContent).not.toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).not.toContain("openai/gpt-4o");
|
||||
expect(header!.textContent).not.toContain("google/gemini-pro");
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(header!.textContent).toContain("anthropic/claude-opus-4");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
});
|
||||
|
||||
it("shows 'Using default' for planning when planningModel has only provider but no modelId", () => {
|
||||
@@ -474,12 +465,101 @@ describe("AgentLogViewer", () => {
|
||||
entries={entries}
|
||||
loading={false}
|
||||
planningModel={{ provider: "anthropic" }}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("Using default");
|
||||
expect(header!.textContent).not.toContain("Using default");
|
||||
});
|
||||
});
|
||||
|
||||
describe("model header expand/collapse", () => {
|
||||
it("shows only provider icons in collapsed state, hides model text", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-sonnet-4-5" }}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(screen.getByTestId("agent-log-model-expand")).toBeTruthy();
|
||||
expect(container.textContent).not.toContain("Executor:");
|
||||
expect(container.textContent).not.toContain("claude-sonnet-4-5");
|
||||
});
|
||||
|
||||
it("shows model details when expand button is clicked", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-sonnet-4-5" }}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByTestId("agent-log-model-expand"));
|
||||
expect(container.textContent).toContain("Executor:");
|
||||
expect(container.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
|
||||
it("collapses model details when expand button is clicked again", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-sonnet-4-5" }}
|
||||
/>,
|
||||
);
|
||||
|
||||
const button = screen.getByTestId("agent-log-model-expand");
|
||||
fireEvent.click(button);
|
||||
expect(container.textContent).toContain("Executor:");
|
||||
fireEvent.click(button);
|
||||
expect(container.textContent).not.toContain("Executor:");
|
||||
});
|
||||
|
||||
it("shows no provider icons when no model overrides are set", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(<AgentLogViewer entries={entries} loading={false} />);
|
||||
|
||||
expect(container.querySelector("[data-provider]")).toBeNull();
|
||||
});
|
||||
|
||||
it("has aria-expanded=false when collapsed and aria-expanded=true when expanded", () => {
|
||||
const entries = [makeEntry()];
|
||||
render(
|
||||
<AgentLogViewer
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-sonnet-4-5" }}
|
||||
/>,
|
||||
);
|
||||
|
||||
const button = screen.getByTestId("agent-log-model-expand");
|
||||
expect(button.getAttribute("aria-expanded")).toBe("false");
|
||||
fireEvent.click(button);
|
||||
expect(button.getAttribute("aria-expanded")).toBe("true");
|
||||
});
|
||||
|
||||
it("renders multiple provider icons for multiple overrides", () => {
|
||||
const entries = [makeEntry()];
|
||||
const { container } = render(
|
||||
<AgentLogViewer
|
||||
entries={entries}
|
||||
loading={false}
|
||||
executorModel={{ provider: "anthropic", modelId: "claude-opus-4" }}
|
||||
validatorModel={{ provider: "openai", modelId: "gpt-4o" }}
|
||||
planningModel={{ provider: "google", modelId: "gemini-pro" }}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(container.querySelector('[data-provider="anthropic"]')).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="openai"]')).toBeTruthy();
|
||||
expect(container.querySelector('[data-provider="google"]')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -48,9 +48,11 @@ vi.mock("lucide-react", () => ({
|
||||
MessageSquare: () => null,
|
||||
ChevronUp: () => null,
|
||||
ChevronDown: () => null,
|
||||
ChevronRight: () => null,
|
||||
X: () => null,
|
||||
Maximize2: () => null,
|
||||
Minimize2: () => null,
|
||||
Loader2: () => null,
|
||||
Bot: () => null,
|
||||
CircleDot: () => null,
|
||||
XCircle: () => null,
|
||||
@@ -1706,23 +1708,32 @@ describe("TaskDetailModal", () => {
|
||||
);
|
||||
}
|
||||
|
||||
it("shows resolved executor from settings when task has no explicit executor override", async () => {
|
||||
const { container } = await setupModelTest({
|
||||
defaultProvider: "anthropic",
|
||||
defaultModelId: "claude-sonnet-4-5",
|
||||
});
|
||||
|
||||
async function openAgentLogAndExpandModelDetails(container: HTMLElement) {
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
|
||||
const expandButton = screen.getByTestId("agent-log-model-expand") as HTMLButtonElement;
|
||||
if (expandButton.getAttribute("aria-expanded") !== "true") {
|
||||
fireEvent.click(expandButton);
|
||||
}
|
||||
|
||||
return container.querySelector("[data-testid='agent-log-model-header']") as HTMLElement;
|
||||
}
|
||||
|
||||
it("shows resolved executor from settings when task has no explicit executor override", async () => {
|
||||
const { container } = await setupModelTest({
|
||||
defaultProvider: "anthropic",
|
||||
defaultModelId: "claude-sonnet-4-5",
|
||||
});
|
||||
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
// Validator should also fall back to the default
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
|
||||
@@ -1734,16 +1745,7 @@ describe("TaskDetailModal", () => {
|
||||
validatorModelId: "gpt-4o",
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
// Executor falls back to default
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
// Validator uses the validator-specific setting
|
||||
@@ -1757,18 +1759,9 @@ describe("TaskDetailModal", () => {
|
||||
// No validatorProvider or validatorModelId
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Both executor and validator should resolve to the default
|
||||
expect(header!.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
// Count occurrences - should appear three times (once for executor, once for validator, once for planning)
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const matches = header.textContent!.match(/anthropic\/claude-sonnet-4-5/g);
|
||||
expect(matches).toHaveLength(3);
|
||||
});
|
||||
@@ -1779,18 +1772,9 @@ describe("TaskDetailModal", () => {
|
||||
{ defaultProvider: "anthropic", defaultModelId: "claude-sonnet-4-5" },
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Task override should win
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
});
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
// Default model should not appear for executor
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
expect(header.textContent).toContain("openai/gpt-4o");
|
||||
// Validator falls back to default
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
@@ -1802,17 +1786,7 @@ describe("TaskDetailModal", () => {
|
||||
{ defaultProvider: "anthropic", defaultModelId: "claude-sonnet-4-5", validatorProvider: "openai", validatorModelId: "gpt-4o" },
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Task validator override should win
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
// Executor falls back to default
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
// Settings validator should not appear (task override wins)
|
||||
@@ -1824,15 +1798,7 @@ describe("TaskDetailModal", () => {
|
||||
// No defaultProvider/defaultModelId
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
expect(header.textContent).toContain("Using default");
|
||||
// Should show "Using default" for executor, validator, and planning
|
||||
const defaultBadges = header.querySelectorAll(".model-badge-default");
|
||||
@@ -1862,16 +1828,8 @@ describe("TaskDetailModal", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
// Wait for the failed fetch to settle
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
expect(header.textContent).toContain("Using default");
|
||||
const defaultBadges = header.querySelectorAll(".model-badge-default");
|
||||
expect(defaultBadges).toHaveLength(3);
|
||||
@@ -1892,16 +1850,7 @@ describe("TaskDetailModal", () => {
|
||||
},
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
// Executor uses task override
|
||||
expect(header.textContent).toContain("google/gemini-pro");
|
||||
// Validator uses settings-specific validator
|
||||
@@ -1943,19 +1892,11 @@ describe("TaskDetailModal", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Planning should show the runtime triage marker, not settings default
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
// Planning should show the runtime triage marker, not settings default
|
||||
expect(header.textContent).toContain("Planning/Triage:");
|
||||
expect(header.textContent).toContain("google/gemini-pro");
|
||||
// Executor/Validator should still show settings default
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
@@ -1992,19 +1933,11 @@ describe("TaskDetailModal", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Planning should use planningProvider/planningModelId from settings
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("openai/gpt-4o");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
// Planning should use planningProvider/planningModelId from settings
|
||||
expect(header.textContent).toContain("Planning/Triage:");
|
||||
expect(header.textContent).toContain("openai/gpt-4o");
|
||||
// Executor/Validator should show default
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
// Planning should NOT show the default
|
||||
@@ -2017,19 +1950,12 @@ describe("TaskDetailModal", () => {
|
||||
defaultModelId: "claude-sonnet-4-5",
|
||||
});
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
});
|
||||
expect(header.textContent).toContain("Planning/Triage:");
|
||||
expect(header.textContent).toContain("anthropic/claude-sonnet-4-5");
|
||||
|
||||
// Planning falls back to default - same as executor/validator
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const matches = header.textContent!.match(/anthropic\/claude-sonnet-4-5/g);
|
||||
expect(matches).toHaveLength(3); // executor, validator, planning
|
||||
});
|
||||
@@ -2039,17 +1965,8 @@ describe("TaskDetailModal", () => {
|
||||
// No defaultProvider/defaultModelId
|
||||
});
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
expect(header.textContent).toContain("Planning:");
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
expect(header.textContent).toContain("Planning/Triage:");
|
||||
const defaultBadges = header.querySelectorAll(".model-badge-default");
|
||||
// 3 default badges: executor, validator, planning
|
||||
expect(defaultBadges).toHaveLength(3);
|
||||
@@ -2091,19 +2008,10 @@ describe("TaskDetailModal", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Per-task override should take precedence over settings
|
||||
expect(header!.textContent).toContain("Planning:");
|
||||
expect(header!.textContent).toContain("google/gemini-2.5-pro");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
// Per-task override should take precedence over settings
|
||||
expect(header.textContent).toContain("Planning/Triage:");
|
||||
expect(header.textContent).toContain("google/gemini-2.5-pro");
|
||||
// Should NOT show the settings planning model
|
||||
expect(header.textContent).not.toContain("openai/gpt-4o");
|
||||
});
|
||||
@@ -2143,18 +2051,9 @@ describe("TaskDetailModal", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// Navigate to Agent Log subview
|
||||
fireEvent.click(screen.getByText("Logs"));
|
||||
fireEvent.click(screen.getByText("Agent Log"));
|
||||
|
||||
await waitFor(() => {
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']");
|
||||
expect(header).toBeTruthy();
|
||||
// Runtime marker should win over planning settings
|
||||
expect(header!.textContent).toContain("google/gemini-pro");
|
||||
});
|
||||
|
||||
const header = container.querySelector("[data-testid='agent-log-model-header']")!;
|
||||
const header = await openAgentLogAndExpandModelDetails(container);
|
||||
// Runtime marker should win over planning settings
|
||||
expect(header.textContent).toContain("google/gemini-pro");
|
||||
// Should NOT show the planning settings model
|
||||
expect(header.textContent).not.toContain("openai/gpt-4o");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user