Skip to content

Commit

Permalink
fix for OpenAI Assistant where it returns multiple content after one …
Browse files Browse the repository at this point in the history
…request prompt
  • Loading branch information
OvidijusParsiunas committed Apr 6, 2024
1 parent 49599bf commit 64bb3f4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
15 changes: 6 additions & 9 deletions component/src/services/openAI/openAIAssistantIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {MessageLimitUtils} from '../utils/messageLimitUtils';
import {MessageContentI} from '../../types/messagesInternal';
import {Messages} from '../../views/chat/messages/messages';
import {Response as ResponseI} from '../../types/response';
import {Response as ResponseT} from '../../types/response';
import {HTTPRequest} from '../../utils/HTTP/HTTPRequest';
import {DirectServiceIO} from '../utils/directServiceIO';
import {OpenAIUtils} from './utils/openAIUtils';
Expand Down Expand Up @@ -139,7 +138,7 @@ export class OpenAIAssistantIO extends DirectServiceIO {

// prettier-ignore
override async extractResultData(result: OpenAIAssistantInitReqResult):
Promise<ResponseT | {makingAnotherRequest: true}> {
Promise<ResponseI | {makingAnotherRequest: true}> {
if (this.waitingForStreamResponse || (this.isSSEStream && this.sessionId)) {
return await this.handleStream(result);
}
Expand Down Expand Up @@ -173,20 +172,18 @@ export class OpenAIAssistantIO extends DirectServiceIO {
if (!isHistory && this.deepChat.responseInterceptor) {
threadMessages = (await this.deepChat.responseInterceptor?.(threadMessages)) as OpenAIAssistantMessagesResult;
}
const messages = isHistory ? threadMessages.data : [threadMessages.data[0]];
const parsedMessages = messages.map(async (data) => {
const content = data.content.find((content) => !!content.text || !!content.image_file);
return await OpenAIAssistantFiles.getFilesAndText(this, data, content);
});
return Promise.all(parsedMessages);
return OpenAIAssistantFiles.processAPIMessages(this, threadMessages, isHistory);
}

async extractPollResultData(result: OpenAIRunResult): PollResult {
const {status, required_action} = result;
if (status === 'queued' || status === 'in_progress') return {timeoutMS: OpenAIAssistantIO.POLLING_TIMEOUT_MS};
if (status === 'completed' && this.messages) {
const threadMessages = await this.getThreadMessages(result.thread_id);
const {text, files} = threadMessages[0];
const {text, files} = threadMessages.pop() as ResponseI;
setTimeout(() => {
threadMessages.forEach((message) => this.deepChat.addMessage(message));
});
return {text, _sessionId: this.sessionId, files};
}
const toolCalls = required_action?.submit_tool_outputs?.tool_calls;
Expand Down
45 changes: 44 additions & 1 deletion component/src/services/openAI/utils/openAIAssistantFiles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {OpenAIAssistantData, OpenAIAssistantContent} from '../../../types/openAIResult';
import {OpenAIAssistantData, OpenAIAssistantContent, OpenAIAssistantMessagesResult} from '../../../types/openAIResult';
import {MessageFileType, MessageFile} from '../../../types/messageFile';
import {Messages} from '../../../views/chat/messages/messages';
import {RequestUtils} from '../../../utils/HTTP/requestUtils';
import {DirectServiceIO} from '../../utils/directServiceIO';
import {OpenAIUtils} from './openAIUtils';
import {ServiceIO} from '../../serviceIO';

Expand Down Expand Up @@ -119,4 +120,46 @@ export class OpenAIAssistantFiles {
// gets files and replaces hyperlinks with base64 file encodings
return await OpenAIAssistantFiles.getFilesAndNewText(io, fileDetails, message.role, content);
}

private static parseMesages(result: OpenAIAssistantMessagesResult, isHistory: boolean) {
let messages = [];
if (isHistory) {
messages = result.data;
} else {
for (let i = 0; i < result.data.length; i += 1) {
const message = result.data[i];
if (message.role === 'assistant') {
messages.push(message);
} else {
break;
}
}
}
return messages;
}

// test this using this prompt and it should give 2 text mesages and a file:
// "give example data for a csv and create a suitable bar chart"
private static parseContent(io: DirectServiceIO, messages: OpenAIAssistantData[]) {
const parsedContent: Promise<{text?: string; files?: MessageFile[]}>[] = [];
messages.forEach(async (data) => {
data.content
.filter((content) => !!content.text || !!content.image_file)
.sort((content) => {
if (content.text) return -1;
if (content.image_file) return 1;
return 0;
})
.forEach(async (content) => {
parsedContent.push(OpenAIAssistantFiles.getFilesAndText(io, data, content));
});
});
return parsedContent;
}

public static async processAPIMessages(io: DirectServiceIO, result: OpenAIAssistantMessagesResult, isHistory: boolean) {
const messages = OpenAIAssistantFiles.parseMesages(result, isHistory);
const parsedContent = OpenAIAssistantFiles.parseContent(io, messages);
return Promise.all(parsedContent);
}
}

0 comments on commit 64bb3f4

Please sign in to comment.