Skip to content

Commit 085d3cb

Browse files
committed
refac
1 parent 116eb7f commit 085d3cb

1 file changed

Lines changed: 43 additions & 18 deletions

File tree

src/lib/utils/index.ts

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,9 @@ export const calculateSHA256 = async (file) => {
677677

678678
export const getImportOrigin = (_chats) => {
679679
// Check what external service chat imports are from
680-
if ('mapping' in _chats[0]) {
680+
// ChatGPT exports may include folder/project metadata entries without 'mapping',
681+
// so we check if ANY item has a 'mapping' key instead of only the first one.
682+
if (_chats.some((chat) => 'mapping' in chat)) {
681683
return 'openai';
682684
}
683685
return 'webui';
@@ -706,6 +708,21 @@ export const getUserPosition = async (raw = false) => {
706708
}
707709
};
708710

711+
const extractOpenAIMessageContent = (message): string => {
712+
// Extract text content from a ChatGPT message, handling various content formats
713+
// (string parts, object parts like DALL-E images, text field fallback)
714+
try {
715+
const parts = message?.['content']?.['parts'];
716+
if (Array.isArray(parts)) {
717+
const textParts = parts.filter((p) => typeof p === 'string');
718+
if (textParts.length > 0) return textParts.join('\n');
719+
}
720+
return message?.['content']?.['text'] || '';
721+
} catch {
722+
return '';
723+
}
724+
};
725+
709726
const convertOpenAIMessages = (convo) => {
710727
// Parse OpenAI chat messages and create chat dictionary for creating new chats
711728
const mapping = convo['mapping'];
@@ -726,15 +743,18 @@ const convertOpenAIMessages = (convo) => {
726743
// Skip chat messages with no content
727744
continue;
728745
} else {
746+
const role = message['message']?.['author']?.['role'];
747+
// Skip system and tool messages — they don't map to user/assistant
748+
if (role === 'system' || role === 'tool') {
749+
continue;
750+
}
751+
729752
const new_chat = {
730753
id: message_id,
731754
parentId: lastId,
732755
childrenIds: message['children'] || [],
733-
role: message['message']?.['author']?.['role'] !== 'user' ? 'assistant' : 'user',
734-
content:
735-
message['message']?.['content']?.['parts']?.[0] ||
736-
message['message']?.['content']?.['text'] ||
737-
'',
756+
role: role !== 'user' ? 'assistant' : 'user',
757+
content: extractOpenAIMessageContent(message['message']),
738758
model: 'gpt-3.5-turbo',
739759
done: true,
740760
context: null
@@ -747,6 +767,12 @@ const convertOpenAIMessages = (convo) => {
747767
}
748768
}
749769

770+
// Fix up the last message's childrenIds to be empty (it's the leaf node in our
771+
// linear chain regardless of what the original tree structure had)
772+
if (messages.length > 0) {
773+
messages[messages.length - 1].childrenIds = [];
774+
}
775+
750776
const history: Record<PropertyKey, (typeof messages)[number]> = {};
751777
messages.forEach((obj) => (history[obj.id] = obj));
752778

@@ -773,18 +799,6 @@ const validateChat = (chat) => {
773799
return false;
774800
}
775801

776-
// Last message's children should be an empty array
777-
const lastMessage = messages[messages.length - 1];
778-
if (lastMessage.childrenIds.length !== 0) {
779-
return false;
780-
}
781-
782-
// First message's parent should be null
783-
const firstMessage = messages[0];
784-
if (firstMessage.parentId !== null) {
785-
return false;
786-
}
787-
788802
// Every message's content should be a string
789803
for (const message of messages) {
790804
if (typeof message.content !== 'string') {
@@ -799,7 +813,15 @@ export const convertOpenAIChats = (_chats) => {
799813
// Create a list of dictionaries with each conversation from import
800814
const chats = [];
801815
let failed = 0;
816+
let skipped = 0;
802817
for (const convo of _chats) {
818+
// Skip folder/project metadata entries that lack a 'mapping' key
819+
if (!('mapping' in convo)) {
820+
skipped++;
821+
console.log('Skipping non-conversation entry (folder/project):', convo['title'] ?? convo['id']);
822+
continue;
823+
}
824+
803825
const chat = convertOpenAIMessages(convo);
804826

805827
if (validateChat(chat)) {
@@ -815,6 +837,9 @@ export const convertOpenAIChats = (_chats) => {
815837
}
816838
}
817839
console.log(failed, 'Conversations could not be imported');
840+
if (skipped > 0) {
841+
console.log(skipped, 'Non-conversation entries (folders/projects) were skipped');
842+
}
818843
return chats;
819844
};
820845

0 commit comments

Comments
 (0)