Conversation List Contain Duplicate User Message

so now i use response api streaming with conversation, all work fine, but when i try fetch conversation items the user message seem duplicated, here is my code

let input = [{ role: "user", content: message }];
    let previousResponseId = null;
    while (true) {
      const payload = {
        conversationId,
        input,
      };
      if (previousResponseId) {
        payload.previousResponseId = previousResponseId;
      }
      const responseStream = await createResponseRepository(payload);
      let toolCalls = [];
      for await (const chunk of responseStream) {
        if (chunk.type === "response.in_progress") {
          const message = "🤖 **Agent is thinking**";
         console.log(message)
        } else if (chunk.type === "response.output_text.delta") {
          const text = chunk.delta;
         console.log(text)
        } else if (chunk.type === "response.output_text.done") {
          const message = chunk.text;
          console.log(text)
        } else if (chunk.type === "response.function_call_arguments.done") {
          const message = chunk.arguments;
          console.log(message)
        } else if (
          chunk.type === "response.output_item.done" &&
          chunk.item.type === "function_call"
        ) {
          const functionName = chunk.item.name;
          const call = chunk.item;
          let message = `🖥️ **Agent is executing a function call**`;
          switch (functionName) {
            case "funcA": {
              message = `🖥️ **Agent is executing a funcA**`;
              const args = JSON.parse(call.arguments || "{}");
              const output = await callFunctions(
                "funcA",
                callArgs,
              );
              toolCalls.push({
                type: "function_call_output",
                call_id: call.call_id,
                output:
                  typeof output === "string" ? output : JSON.stringify(output),
              });
              break;
            }
        } else if (chunk.type === "response.completed") {
          previousResponseId = chunk.response.id;
        }
      }

      if (toolCalls.length > 0) {
        const nextInputs = toolCalls.map((t) => ({
          type: t.type,
          call_id: t.call_id,
          output: t.output,
        }));
        input.splice(0, input.length, ...nextInputs);
      } else {
        sendEvent(res, "completed", {
          message: `🤖 **Processing completed**`,
        });
        break;
      }

this code work, but the problem is when i listing the conversation items, here is the results


the problem is when the agent doing multiple turn, see the user message is duplicated 5 times, i have tried to set empty array for next turn but i got error

400 No tool output found for function call call_Ua2BsTzGZPR1EhN7SmUSwnFq

any clue? cause its hard to mapping the conversation list into UI if there is a duplicate part

You don’t show the payload being sent to the API.

You don’t show if you are manually placing messages on the conversation stack as input.

You display different message IDs.

That doesn’t let anybody understand if you are making an error, such reusing a conversation, or not using the “store”:true parameter to properly populate an AI model response (which is unexpectedly required).

I see you handle function calls, but they are of no use if the assistant has no record of them being emitted but gets called again.

A possible reference:

(I don’t persist conversation IDs any longer than an experimentation script runs, and immediately delete the returned unwanted response ID being stored.)

okay here is the function createResponseRepository that called

import OpenAI from "openai";
import ResponseError from "../../errors/response.js";
import { structuredLog } from "../../loggers/logger.js";

const createRunRepository = async ({
  conversationId,
  input,
  previousResponseId,
}) => {
  try {
    const openai = new OpenAI({ apiKey: process.env.OPEN_AI_KEY });
    const newRun = await openai.responses.create({
      prompt: {
        id: process.env.PROMPT_ID,
      },
      input,
      conversation: conversationId,
      stream: true,
      parallel_tool_calls: true,
      previous_response_id: previousResponseId,
      store: true,
    });
    return newRun;
  } catch (error) {
    structuredLog(
      traceId || "",
      "repositories",
      "createRunRepository",
      "error",
      error.message || error
    );
    throw new ResponseError(500, "internal server error");
  }
};

export default createRunRepository;

yes i showed i manually placing user messages on the conversation stack as input, you can check the input variable, then its modified on here input.splice(0, input.length, …nextInputs);

so the user input will be still there for next turn

the problem is, if i dont put user message on next turn conversation, its say erorr

400 No tool output found for function call call_Ua2BsTzGZPR1EhN7SmUSwnFq

but if i put user message on next turn its duplicated as much the agent turn the conversation

You have both a conversation ID and a previous response ID configured.

That is an untolerated conflict, which the SDK may be masking but the API will error-out on.

You need to completely remove the previous_response_id parameter if using “conversation”.

See if that is the fault with a new conversation ID instantiated.

you are right, tried remove the previous_response_id, and its no duplicate again, thanks

1 Like