openai / openai-node

Official JavaScript / TypeScript library for the OpenAI API
https://www.npmjs.com/package/openai
Apache License 2.0
7.93k stars 863 forks source link

README run streaming example has incorrect & unhelpful event examples #860

Open 10xchs opened 5 months ago

10xchs commented 5 months ago

Confirm this is a feature request for the Node library and not the underlying OpenAI API.

Describe the feature or improvement you're requesting

Look at this code from the docs:

const run = openai.beta.threads.runs.stream(thread.id, {
    assistant_id: assistant.id
  })
    .on('textCreated', (text) => process.stdout.write('\nassistant > '))
    .on('textDelta', (textDelta, snapshot) => process.stdout.write(textDelta.value))
    .on('toolCallCreated', (toolCall) => process.stdout.write(`\nassistant > ${toolCall.type}\n\n`))
    .on('toolCallDelta', (toolCallDelta, snapshot) => {
      if (toolCallDelta.type === 'code_interpreter') {
        if (toolCallDelta.code_interpreter.input) {
          process.stdout.write(toolCallDelta.code_interpreter.input);
        }
        if (toolCallDelta.code_interpreter.outputs) {
          process.stdout.write("\noutput >\n");
          toolCallDelta.code_interpreter.outputs.forEach(output => {
            if (output.type === "logs") {
              process.stdout.write(`\n${output.logs}\n`);
            }
          });
        }
      }
    });

Here it listens for events with on.

I'm assuming these are just example events, although I have no clue why you wouldn't include an obviously useful event like "completed" in this list.

Below this is this quote: "See the full list of Assistants streaming events in our API reference here."

The link goes here: https://platform.openai.com/docs/api-reference/assistants-streaming/events

It contains this information:

Assistant stream eventsBeta
Represents an event emitted when streaming a Run.

Each event in a server-sent events stream has an event and data property:

event: thread.created
data: {"id": "thread_123", "object": "thread", ...}
We emit events whenever a new object is created, transitions to a new state, or is being streamed in parts (deltas). For example, we emit thread.run.created when a new run is created, thread.run.completed when a run completes, and so on. When an Assistant chooses to create a message during a run, we emit a thread.message.created event, a thread.message.in_progress event, many thread.message.delta events, and finally a thread.message.completed event.

We may add additional events over time, so we recommend handling unknown events gracefully in your code. See the Assistants API quickstart to learn how to integrate the Assistants API with streaming.

thread.created
data is a thread

Occurs when a new thread is created.

thread.run.created
data is a run

Occurs when a new run is created.

thread.run.queued
data is a run

Occurs when a run moves to a queued status.

thread.run.in_progress
data is a run

Occurs when a run moves to an in_progress status.

thread.run.requires_action
data is a run

Occurs when a run moves to a requires_action status.

thread.run.completed
data is a run

Occurs when a run is completed.

thread.run.incomplete
data is a run

Occurs when a run ends with status incomplete.

thread.run.failed
data is a run

Occurs when a run fails.

thread.run.cancelling
data is a run

Occurs when a run moves to a cancelling status.

thread.run.cancelled
data is a run

Occurs when a run is cancelled.

thread.run.expired
data is a run

Occurs when a run expires.

thread.run.step.created
data is a run step

Occurs when a run step is created.

thread.run.step.in_progress
data is a run step

Occurs when a run step moves to an in_progress state.

thread.run.step.delta
data is a run step delta

Occurs when parts of a run step are being streamed.

thread.run.step.completed
data is a run step

Occurs when a run step is completed.

thread.run.step.failed
data is a run step

Occurs when a run step fails.

thread.run.step.cancelled
data is a run step

Occurs when a run step is cancelled.

thread.run.step.expired
data is a run step

Occurs when a run step expires.

thread.message.created
data is a message

Occurs when a message is created.

thread.message.in_progress
data is a message

Occurs when a message moves to an in_progress state.

thread.message.delta
data is a message delta

Occurs when parts of a Message are being streamed.

thread.message.completed
data is a message

Occurs when a message is completed.

thread.message.incomplete
data is a message

Occurs when a message ends before it is completed.

error
data is an error

Occurs when an error occurs. This can happen due to an internal server error or a timeout.

done
data is [DONE]

Now aren't those COMPLETELY different from the ones we just saw? And indeed I can't write any of them, for example this:

const stream = openai.beta.threads.runs
    .stream(threadId, {
      assistant_id: assistantId,
      instructions,
      stream: true,
    })
    .on("thread.run.completed", (data) => {
      console.log("hey");
    })

So now I have to work out this on my own. This is the case with literally every piece of available information in the documentation. Why not make it useful? Is it really THAT difficult? I guess so since no one can do it, but still.

Additional context

No response

AAR072 commented 4 months ago

Is there any update to this? So much development time is getting wasted because this documentation doesn't make anything clear. I can't find any reference to these events anywhere. Ex: .on('textCreated')

rattrayalex commented 4 months ago

Sorry about this.

It sounds like the assistants streaming helper docs specifically are the most unhelpful, is that so?

I'll reword the title of this issue assuming that's the case, but if you have other specific suggestions or documentation problems to make, I can expand (or you can file a separate issue).

10xchs commented 3 months ago

The fix is in, boys. They removed literally all documentation for streaming now. Great?

awHamer commented 3 months ago

Yeah, it's unclear in docs... I used to solve it this way, may be it will be helpful for someone else:

const stream = openai.beta.threads.runs.stream(threadId, {
      assistant_id: assistantId,
      instructions,
      // ...
    })
    .on('event', ({ event, data }) => {
      console.log('Received', event, data);
    });
heisaduvan commented 4 days ago

I'm also encountering the same error when trying to use the thread running service in my Flutter project. When the event is thread.run.requires_action, the data is not a complete JSON object, so I face issues parsing it. I can listen to each step in the stream to obtain the JSON object, but why should I have to do this? Has it really been so difficult to fix this issue that has been ongoing for months?