diff --git a/packages/app/src/components/prompt-input/submit.test.ts b/packages/app/src/components/prompt-input/submit.test.ts index 54f33a3d4f7..0cfa52d80d0 100644 --- a/packages/app/src/components/prompt-input/submit.test.ts +++ b/packages/app/src/components/prompt-input/submit.test.ts @@ -31,6 +31,12 @@ const promotedDrafts: Array<{ draftID: string; server: string; sessionId: string const sentPrompts: string[] = [] const promptInputs: unknown[] = [] const sentCommands: unknown[] = [] +const switchedAgents: Array<{ sessionID: string; agent: string }> = [] +const switchedModels: Array<{ + sessionID: string + model: { id: string; providerID: string; variant?: string } +}> = [] +const sessionRequestOrder: string[] = [] const commands: Array<{ name: string }> = [] let serverSessionSyncs = 0 @@ -93,10 +99,22 @@ const clientFor = (directory: string) => { } }, prompt: async (input: unknown) => { + sessionRequestOrder.push("prompt") sentPrompts.push(directory) promptInputs.push(input) return { data: undefined } }, + switchAgent: async (input: { sessionID: string; agent: string }) => { + sessionRequestOrder.push("agent") + switchedAgents.push(input) + }, + switchModel: async (input: { + sessionID: string + model: { id: string; providerID: string; variant?: string } + }) => { + sessionRequestOrder.push("model") + switchedModels.push(input) + }, command: async (input: unknown) => { sentCommands.push(input) }, @@ -279,6 +297,9 @@ beforeEach(() => { sentPrompts.length = 0 promptInputs.length = 0 sentCommands.length = 0 + switchedAgents.length = 0 + switchedModels.length = 0 + sessionRequestOrder.length = 0 commands.length = 0 promptValue = [{ type: "text", content: "ls", start: 0, end: 2 }] params = {} @@ -436,13 +457,17 @@ describe("prompt submit worktree selection", () => { expect(promotedDrafts).toEqual([{ draftID: "draft-1", server: "project-server", sessionId: "session-1" }]) }) - test("includes the selected variant on optimistic prompts", async () => { + test("switches the selected agent and model before prompting", async () => { params = { id: "session-1" } variant = "high" const submit = createPromptSubmit({ prompt, - info: () => ({ id: "session-1" }), + info: () => ({ + id: "session-1", + agent: "old-agent", + model: { id: "old-model", providerID: "old-provider" }, + }), imageAttachments: () => [], commentCount: () => 0, autoAccept: () => false, @@ -471,6 +496,14 @@ describe("prompt submit worktree selection", () => { }, }) expect(sentPrompts).toEqual(["/repo/main"]) + expect(switchedAgents).toEqual([{ sessionID: "session-1", agent: "agent" }]) + expect(switchedModels).toEqual([ + { + sessionID: "session-1", + model: { id: "model", providerID: "provider", variant: "high" }, + }, + ]) + expect(sessionRequestOrder).toEqual(["agent", "model", "prompt"]) expect(promptInputs[0]).toMatchObject({ sessionID: "session-1", text: "ls", diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index bc421ed58fc..56f81acf58f 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -45,6 +45,7 @@ type FollowupSendInput = { api: DirectorySDK["api"]["session"] serverSync: ServerSync sync: DirectorySync + session: Accessor<{ agent?: string; model?: { id: string; providerID: string; variant?: string } } | undefined> draft: FollowupDraft messageID?: string optimisticBusy?: boolean @@ -157,6 +158,25 @@ export async function sendFollowupDraft(input: FollowupSendInput) { return false } + const session = input.session() + if (session?.agent !== input.draft.agent) { + await input.api.switchAgent({ sessionID: input.draft.sessionID, agent: input.draft.agent }) + } + if ( + session?.model?.providerID !== input.draft.model.providerID || + session.model.id !== input.draft.model.modelID || + (session.model.variant ?? "default") !== (input.draft.variant ?? "default") + ) { + await input.api.switchModel({ + sessionID: input.draft.sessionID, + model: { + id: input.draft.model.modelID, + providerID: input.draft.model.providerID, + variant: input.draft.variant, + }, + }) + } + await input.api.prompt({ sessionID: input.draft.sessionID, id: messageID, @@ -197,7 +217,9 @@ export async function sendFollowupDraft(input: FollowupSendInput) { type PromptSubmitInput = { prompt: ReturnType - info: Accessor<{ id: string } | undefined> + info: Accessor< + { id: string; agent?: string; model?: { id: string; providerID: string; variant?: string } } | undefined + > imageAttachments: Accessor commentCount: Accessor autoAccept: Accessor @@ -595,6 +617,7 @@ export function createPromptSubmit(input: PromptSubmitInput) { api: sdk().api.session, sync: sync(), serverSync: serverSync(), + session: () => input.info() ?? session, draft, messageID, optimisticBusy: sessionDirectory === projectDirectory, diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 0009b1ae4bc..cf7d60af9e3 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1721,6 +1721,7 @@ export default function Page() { api: sdk().api.session, sync: sync(), serverSync: serverSync(), + session: () => sync().session.get(input.sessionID), draft: item, optimisticBusy: item.sessionDirectory === sdk().directory, }).catch((err) => {