How to Retrieve Run Steps Logs and Messages of OpenaAI Assistant Using JavaScript API

Su Myat Hlaing 160 Reputation points
2024-06-20T05:01:14.08+00:00

Hello,

I'm currently working with the Assistant feature in Azure OpenAI Studio and I've noticed that when using the Assistant, it shows run steps logs and messages between interactions before providing the final answer. These logs and messages are very useful for understanding the process and debugging purposes.

I want to achieve the same functionality using the JavaScript API. Specifically, I would like to:

  1. Retrieve the run steps logs.
  2. Capture the intermediary messages exchanged before the final answer is provided.

https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/openai/openai-assistants/samples-dev/codeAssistant.ts
While this code successfully generates a completion, it does not provide the run steps logs or the intermediary messages.

Could someone guide me on how to properly retrieve these logs and messages using the JavaScript API? Are there specific endpoints or configurations required to achieve this?

Any help or pointers would be greatly appreciated!

Thank you!
User's image

Azure OpenAI Service
Azure OpenAI Service
An Azure service that provides access to OpenAI’s GPT-3 models with enterprise capabilities.
3,268 questions
{count} votes

Accepted answer
  1. navba-MSFT 25,325 Reputation points Microsoft Employee
    2024-07-12T05:14:23.52+00:00

    @Su Myat Hlaing I'm glad to see you were able to resolve your issue. Thanks for posting your solution so that others experiencing the same thing can easily reference this. Since the Microsoft Q&A community has a policy that the question author cannot accept their own answer, they can only accept answers by others, I'll repost your solution in case you'd like to Accept the answer.

    . Issue:

    You would like to know, How to Retrieve Run Steps Logs and Messages of OpenaAI Assistant Using JavaScript API?

    . Resolution:

    You have updated the sample code as below which is solving the issue:

    // Create a run
    
        let runResponse = await assistantsClient.createRun(assistantThread, { assistantId });
    
        // Poll for run completion
    
        async function logRunStepsData(assistantThread, runSteps, loggedSteps) {
    
            const logFilePath = path.join(__dirname, 'runSteps.log');
    
            const logEntries = []; // Accumulate log entries
    
        
    
            try {
    
                const date = new Date().toISOString();
    
        
    
                for (const [index, step] of runSteps.data.entries()) {
    
                    // Collect log messages for message content
    
                    if (step.stepDetails.messageCreation && step.stepDetails.messageCreation.message_id) {
    
                        try {
    
                            const message = await assistantsClient.getMessage(assistantThread, step.stepDetails.messageCreation.message_id);
    
        
    
                            if (message.content && message.content.length > 0) {
    
                                message.content.forEach((contentItem, contentIndex) => {
    
                                    if (contentItem.type === 'text' && contentItem.text) {
    
                                        if (!loggedSteps.has(`message-${index}-${contentIndex}`)) {
    
                                            logEntries.push(`[${date}] Runstep ${index + 1} message content ${contentIndex + 1}: ${JSON.stringify(contentItem.text)}`);
    
                                            loggedSteps.add(`message-${index}-${contentIndex}`);
    
                                        }
    
                                    }
    
                                });
    
                            }
    
                        } catch (error) {
    
                            console.error(`Error retrieving message with ID ${step.stepDetails.messageCreation.message_id}: ${error.message}`);
    
                        }
    
                    }
    
        
    
                    // Collect log messages for toolCall details
    
                    if (step.stepDetails.toolCalls && step.stepDetails.toolCalls.length > 0) {
    
                        for (const [toolIndex, toolCall] of step.stepDetails.toolCalls.entries()) {
    
                            if (toolCall.type === 'code_interpreter' && toolCall.codeInterpreter) {
    
                                if (!loggedSteps.has(`toolCall-${index}-${toolIndex}`)) {
    
                                    logEntries.push(`[${date}] Runstep ${index + 1} toolCall ${toolIndex + 1} codeInterpreter details: ${JSON.stringify(toolCall.codeInterpreter)}`);
    
                                    loggedSteps.add(`toolCall-${index}-${toolIndex}`);
    
                                }
    
                            }
    
                        }
    
                    }
    
                }
    
        
    
            } catch (error) {
    
                console.error(`Error logging run steps data: ${error.message}`);
    
            } finally {
    
                // Write log entries in reverse order
    
                const logStream = fs.createWriteStream(logFilePath, { flags: 'a' });
    
                logEntries.reverse().forEach(entry => logStream.write(`${entry}\n`));
    
                logStream.end();
    
            }
    
        }
    
        
    
        // Main function to handle run steps and logging
    
        async function logRunSteps(assistantThread, runResponse) {
    
            const loggedSteps = new Set(); // Track logged steps
    
        
    
            try {
    
                // Polling loop to check runResponse status
    
                while (runResponse.status === "queued" || runResponse.status === "in_progress") {
    
                    await new Promise((r) => setTimeout(r, 500));
    
        
    
                    // Fetch updated run response status
    
                    runResponse = await assistantsClient.getRun(assistantThread, runResponse.id);
    
                }
    
        
    
                // Fetch run steps data after exiting the loop
    
                let runSteps = await assistantsClient.listRunSteps(assistantThread, runResponse.id);
    
        
    
                // Log run steps data after fetching
    
                await logRunStepsData(assistantThread, runSteps, loggedSteps);
    
        
    
            } catch (error) {
    
                console.error(`Error processing run steps: ${error.message}`);
    
            }
    
        }
    
        
    
        // Call the async function
    
        await logRunSteps(assistantThread, runResponse);
    
    
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.