diff --git a/packages/api/src/import/chatgpt/convert.spec.ts b/packages/api/src/import/chatgpt/convert.spec.ts index 8823f803bd..4ef4ef8823 100644 --- a/packages/api/src/import/chatgpt/convert.spec.ts +++ b/packages/api/src/import/chatgpt/convert.spec.ts @@ -25,7 +25,7 @@ const OPTIONS = { }; describe('convertConversation', () => { - it('carries archive, pin, model, and external id onto the conversation', () => { + it('carries archive, pin, and external id onto the conversation, on the configured model', () => { const result = convertConversation( conversation({ root: { id: 'root', message: null, parent: null, children: ['a'] }, @@ -46,7 +46,10 @@ describe('convertConversation', () => { expect(result.isArchived).toBe(true); expect(result.pinned).toBe(true); - expect(result.model).toBe('gpt-5-thinking'); + /** Not `default_model_slug` ('gpt-5-thinking'): the conversation's model is + * what its next prompt is sent with, and a historical ChatGPT slug is not a + * model any endpoint serves. */ + expect(result.model).toBe('gpt-4o'); expect(result.externalId).toBe('ext-1'); expect(result.title).toBe('Trip planning'); }); diff --git a/packages/api/src/import/chatgpt/convert.ts b/packages/api/src/import/chatgpt/convert.ts index 138209d237..24631980f9 100644 --- a/packages/api/src/import/chatgpt/convert.ts +++ b/packages/api/src/import/chatgpt/convert.ts @@ -210,8 +210,6 @@ export function convertConversation( orderTree(messages); - const { model } = resolveModel(conv.default_model_slug ?? undefined, options.defaultModel); - return { conversationId: uuidv4(), externalId: conv.conversation_id, @@ -219,7 +217,15 @@ export function convertConversation( createdAt: new Date(fallbackTime), isArchived: conv.is_archived === true, pinned: conv.is_starred === true || conv.pinned_time != null, - model, + /** The conversation's model is what its *next* prompt is sent with, so it + * has to be a model this deployment actually serves. `default_model_slug` + * is a historical ChatGPT identifier — `auto`, `research`, `gpt-5-t` — that + * no endpoint accepts, and setting it here would leave every imported + * conversation unusable until the user picked a model by hand. The + * per-message `model` keeps the historical slug for display, which is + * where it belongs; the Claude and Grok converters resolve this field the + * same way. */ + model: options.defaultModel, messages, }; }