diff --git a/src/components/__tests__/GenerationComposer.test.tsx b/src/components/__tests__/GenerationComposer.test.tsx
index ce2edb0b..3fcb9463 100644
--- a/src/components/__tests__/GenerationComposer.test.tsx
+++ b/src/components/__tests__/GenerationComposer.test.tsx
@@ -332,6 +332,30 @@ describe("GenerationComposer", () => {
expect(screen.getByDisplayValue("visible prompt")).toBeInTheDocument();
});
+ it("opens model selection from the collapsed model label without expanding", () => {
+ useWorkflowStore.setState({ nodes: [imageNode("img-1", true, { inputPrompt: "visible prompt" })] });
+ render();
+
+ fireEvent.click(screen.getByLabelText("Collapse composer"));
+ fireEvent.click(screen.getByLabelText("Select model"));
+
+ expect(screen.getByTestId("model-dialog")).toHaveAttribute("data-filter", "image");
+ expect(screen.queryByDisplayValue("visible prompt")).not.toBeInTheDocument();
+ });
+
+ it("submits from the collapsed generate button without expanding", async () => {
+ useWorkflowStore.setState({ nodes: [imageNode("img-1", true, { inputPrompt: "visible prompt" })] });
+ render();
+
+ fireEvent.click(screen.getByLabelText("Collapse composer"));
+ fireEvent.click(screen.getByLabelText("Generate"));
+
+ await waitFor(() => {
+ expect(useWorkflowStore.getState().regenerateNode).toHaveBeenCalledWith("img-1");
+ });
+ expect(screen.queryByDisplayValue("visible prompt")).not.toBeInTheDocument();
+ });
+
it("uses the video model filter and reruns the selected video node", async () => {
useWorkflowStore.setState({ nodes: [videoNode("vid-1", true)] });
render();
diff --git a/src/components/composer/GenerationComposer.tsx b/src/components/composer/GenerationComposer.tsx
index f8f054f4..2cf192c8 100644
--- a/src/components/composer/GenerationComposer.tsx
+++ b/src/components/composer/GenerationComposer.tsx
@@ -985,31 +985,50 @@ export function GenerationComposer() {
/>
{isComposerCollapsed ? (
-