@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);