Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/chat/runs/__tests__/handleStartChatRun.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,11 @@ describe("handleStartChatRun", () => {
expect(mintEphemeralAccountKey).not.toHaveBeenCalled();
expect(deleteApiKey).not.toHaveBeenCalled();
});

it("passes the resolved modelId to provisionRunSession so chats.model_id is accurate (chat#1918)", async () => {
await handleStartChatRun(req());
expect(provisionRunSession).toHaveBeenCalledWith(
expect.objectContaining({ modelId: expect.any(String) }),
);
});
});
11 changes: 11 additions & 0 deletions lib/chat/runs/__tests__/provisionRunSession.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,15 @@ describe("provisionRunSession", () => {
expect(result.session).toEqual(updated);
expect(discoverSkills).toHaveBeenCalled();
});

it("forwards modelId to createSessionWithInitialChat (chat#1918)", async () => {
await provisionRunSession({
accountId: "acc-1",
title: "T",
modelId: "anthropic/claude-sonnet-5",
});
expect(createSessionWithInitialChat).toHaveBeenCalledWith(
expect.objectContaining({ modelId: "anthropic/claude-sonnet-5" }),
);
});
});
1 change: 1 addition & 0 deletions lib/chat/runs/handleStartChatRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export async function handleStartChatRun(request: NextRequest): Promise<Response
accountId,
title: DEFAULT_RUN_SESSION_TITLE,
artistId,
modelId,
});

const { rawKey, keyId } = await mintEphemeralAccountKey(accountId);
Expand Down
4 changes: 4 additions & 0 deletions lib/chat/runs/provisionRunSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,20 @@ export async function provisionRunSession({
accountId,
title,
artistId,
modelId,
}: {
accountId: string;
title: string;
artistId?: string;
/** Resolved model for this run; persisted onto the chat row (chat#1918). */
modelId?: string;
}): Promise<ProvisionedRunSession> {
const created = await createSessionWithInitialChat({
accountId,
title,
chatTitle: "Scheduled generation",
artistId,
modelId,
});
if (created.ok === false) {
throw new Error(
Expand Down
13 changes: 13 additions & 0 deletions lib/sessions/__tests__/createSessionWithInitialChat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ describe("createSessionWithInitialChat", () => {
expect(r).toEqual({ ok: false, reason: "insert" });
expect(deleteSessionById).toHaveBeenCalledWith("sess-1");
});

it("persists modelId onto the chat row so the run's model is recorded (chat#1918)", async () => {
await createSessionWithInitialChat({ ...args, modelId: "moonshotai/kimi-k3" });
expect(insertChat).toHaveBeenCalledWith(
expect.objectContaining({ model_id: "moonshotai/kimi-k3" }),
);
});

it("omits model_id when no modelId is supplied", async () => {
await createSessionWithInitialChat(args);
const row = vi.mocked(insertChat).mock.calls[0]![0] as Record<string, unknown>;
expect(row.model_id).toBeUndefined();
});
});
15 changes: 14 additions & 1 deletion lib/sessions/createSessionWithInitialChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@ export async function createSessionWithInitialChat({
title,
chatTitle,
artistId,
modelId,
}: {
accountId: string;
workspaceAccountId?: string;
title: string;
chatTitle: string;
artistId?: string;
/**
* Model the run will execute on. Persisted onto the chat so `chats.model_id`
* reflects reality — the generation path reads the model from the chat row,
* so leaving it unset made every headless run record the default regardless
* of what the task configured (chat#1918).
*/
modelId?: string;
}): Promise<CreateSessionWithChatResult> {
const cloneUrl = await ensurePersonalRepo({ accountId: workspaceAccountId ?? accountId });
if (!cloneUrl) return { ok: false, reason: "repo" };
Expand All @@ -50,7 +58,12 @@ export async function createSessionWithInitialChat({
);
if (!session) return { ok: false, reason: "insert" };

const chat = await insertChat({ id: generateUUID(), session_id: session.id, title: chatTitle });
const chat = await insertChat({
id: generateUUID(),
session_id: session.id,
title: chatTitle,
...(modelId ? { model_id: modelId } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: An explicitly supplied modelId: "" is treated as absent, despite the stated undefined-only fallback. Check for undefined rather than truthiness so supplied values are forwarded consistently (or reject empty IDs at validation).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/sessions/createSessionWithInitialChat.ts, line 65:

<comment>An explicitly supplied `modelId: ""` is treated as absent, despite the stated undefined-only fallback. Check for `undefined` rather than truthiness so supplied values are forwarded consistently (or reject empty IDs at validation).</comment>

<file context>
@@ -50,7 +58,12 @@ export async function createSessionWithInitialChat({
+    id: generateUUID(),
+    session_id: session.id,
+    title: chatTitle,
+    ...(modelId ? { model_id: modelId } : {}),
+  });
   if (!chat) {
</file context>
Suggested change
...(modelId ? { model_id: modelId } : {}),
...(modelId !== undefined ? { model_id: modelId } : {}),

});
if (!chat) {
const rolledBack = await deleteSessionById(session.id);
if (!rolledBack) {
Expand Down
Loading