await openai.beta.threads.messages.create({
thread_id: threadsCache[chatId],
role: "user",
content: [{ text: { value: userText } }]
});
Good request, no error:
user_input = input("prompt> ") # Get input first
thread_message = client.beta.threads.messages.create(
thread.id,
role="user",
content=user_input,
)
print(f"Added message ID: {thread_message.id}")
You seem to be jamming some JSON-like object in instead of using positional and keyword parameters the function accepts.
Add await
only if using the ascyncio client in a function.
the code was written in js(node.js), what should I do? In the regular 3.5 model, it worked perfectly.
async function chatWithOpenAI(chatId, userText) {
try {
console.log(`Отправляем в ChatGPT для диалога ${chatId}: ${userText}`);
if (!threadsCache[chatId]) {
const thread = await openai.beta.threads.create();
threadsCache[chatId] = thread.id;
console.log(`Создан поток ${thread.id} для диалога ${chatId}`);
}
await openai.beta.threads.messages.create({
thread_id: threadsCache[chatId],
role: "user",
content: userText
});
const run = await openai.beta.threads.runs.create({
thread_id: threadsCache[chatId],
assistant_id: ASSISTANT_ID
});
while (true) {
const runStatus = await openai.beta.threads.runs.retrieve({
thread_id: threadsCache[chatId],
run_id: run.id
});
const status = runStatus.status;
if (["completed", "expired", "cancelled", "failed"].includes(status)) {
console.log(`Статус выполнения для диалога ${chatId}: ${status}`);
break;
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
const messagesResponse = await openai.beta.threads.messages.list({
thread_id: threadsCache[chatId],
before: threadAfter[threadsCache[chatId]] || undefined
});
for (const message of messagesResponse.data) {
if (message.role === "assistant") {
threadAfter[threadsCache[chatId]] = message.id;
console.log(`Получен ответ для диалога ${chatId}: ${message.content[0].text.value}`);
return message.content[0].text.value;
}
}
console.log(`Ответ не получен для диалога ${chatId}`);
return "Нет ответа от ассистента.";
} catch (e) {
console.error(`Ошибка при обращении к OpenAI для диалога ${chatId}:`, e);
return `Ошибка: ${e}`;
}
}
The error you’re encountering:
BadRequestError: 400 Missing required parameter: ‘role’.
is happening because the method call to create a message in the thread is incorrect. Specifically, the method:
openai.beta.threads.messages.create()
requires two parameters:
- The thread ID (as the first argument)
- An object containing the message details (as the second argument)
As I detailed previously, in your current code, you are incorrectly passing a single object with thread_id
inside it. The correct usage is to pass the thread ID as the first argument, and then the message details object as the second argument.
Step-by-step walkthrough of the mistake:
Incorrect code snippet:
await openai.beta.threads.messages.create({
thread_id: threadsCache[chatId],
role: "user",
content: userText
});
Why this is incorrect:
- The method
openai.beta.threads.messages.create()
expects the first parameter to be the thread ID directly, not an object containingthread_id
. - The second parameter should be an object containing the message details (
role
andcontent
).
Corrected code snippet:
await openai.beta.threads.messages.create(
threadsCache[chatId], // thread ID as first argument
{
role: "user", // role as second argument object property
content: userText // content as second argument object property
}
);
Additional improvements:
- Your current implementation manually polls the run status, expecting only the statuses you show. OpenAI provides a convenient helper method
createAndPoll()
that simplifies this process, and new updates to the SDK library could track Assistants endpoint improvements. - You can simplify your code by using this helper method instead of manually polling the run status.
Final corrected and improved implementation (in your original language):
Here’s a complete, corrected, and improved version of your function:
async function chatWithOpenAI(chatId, userText) {
try {
console.log(`Отправляем в ChatGPT для диалога ${chatId}: ${userText}`);
// Создаем поток, если его еще нет
if (!threadsCache[chatId]) {
const thread = await openai.beta.threads.create();
threadsCache[chatId] = thread.id;
console.log(`Создан поток ${thread.id} для диалога ${chatId}`);
}
// Правильно добавляем сообщение пользователя в поток
await openai.beta.threads.messages.create(
threadsCache[chatId], // thread ID первым аргументом
{
role: "user",
content: userText
}
);
// Запускаем ассистента и ждем завершения выполнения с помощью createAndPoll
const run = await openai.beta.threads.runs.createAndPoll(
threadsCache[chatId],
{ assistant_id: ASSISTANT_ID }
);
if (run.status !== 'completed') {
console.log(`Статус выполнения для диалога ${chatId}: ${run.status}`);
return `Ассистент не смог завершить выполнение: ${run.status}`;
}
// Получаем список сообщений после завершения выполнения
const messagesResponse = await openai.beta.threads.messages.list(
threadsCache[chatId],
{ before: threadAfter[threadsCache[chatId]] || undefined }
);
// Ищем последнее сообщение от ассистента
for (const message of messagesResponse.data) {
if (message.role === "assistant") {
threadAfter[threadsCache[chatId]] = message.id;
const assistantReply = message.content[0].text.value;
console.log(`Получен ответ для диалога ${chatId}: ${assistantReply}`);
return assistantReply;
}
}
console.log(`Ответ не получен для диалога ${chatId}`);
return "Нет ответа от ассистента.";
} catch (e) {
console.error(`Ошибка при обращении к OpenAI для диалога ${chatId}:`, e);
return `Ошибка: ${e}`;
}
}
Summary of corrections made:
- Fixed the incorrect usage of
openai.beta.threads.messages.create()
by passing the thread ID as the first argument and the message details as the second argument. - Simplified the run polling logic by using the built-in helper method
createAndPoll()
provided by OpenAI’s SDK.
This corrected implementation should resolve your error and provide a cleaner, more reliable interaction with the OpenAI Assistants API.
(gpt-4.5-preview with 15k input tokens to make it a node.js Assistants expert…)
Thanks, it worked, I thought the problem would remain:heart_eyes: