From 7d27d286876d0a575d91a4752f401126fe93d2a3 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Wed, 13 Mar 2024 16:30:47 -0400
Subject: [PATCH] feat(assistants): add support for streaming (#714)
See the reference docs for more information:
https://platform.openai.com/docs/api-reference/assistants-streaming
We've also improved some of the names for the types in
the assistants beta, non exhaustive list:
- `CodeToolCall` -> `CodeInterpreterToolCall`
- `MessageContentImageFile` -> `ImageFileContentBlock`
- `MessageContentText` -> `TextContentBlock`
- `ThreadMessage` -> `Message`
- `ThreadMessageDeleted` -> `MessageDeleted`
---
api.md | 58 +-
examples/assistant-stream-raw.ts | 39 +
examples/assistant-stream.ts | 48 +
examples/assistants.ts | 57 ++
src/index.ts | 1 +
src/lib/AbstractAssistantStreamRunner.ts | 340 +++++++
src/lib/AssistantStream.ts | 698 +++++++++++++++
src/resources/beta/assistants/assistants.ts | 844 ++++++++++++++++--
src/resources/beta/assistants/index.ts | 9 +
src/resources/beta/beta.ts | 12 +
src/resources/beta/index.ts | 12 +
src/resources/beta/threads/index.ts | 35 +-
src/resources/beta/threads/messages/index.ts | 26 +-
.../beta/threads/messages/messages.ts | 426 +++++++--
src/resources/beta/threads/runs/index.ts | 19 +-
src/resources/beta/threads/runs/runs.ts | 281 ++++--
src/resources/beta/threads/runs/steps.ts | 259 +++++-
src/resources/beta/threads/threads.ts | 207 ++++-
src/resources/chat/completions.ts | 2 +-
src/resources/completions.ts | 2 +
src/resources/shared.ts | 10 +
src/streaming.ts | 14 +
.../beta/threads/runs/runs.test.ts | 2 +
.../beta/threads/threads.test.ts | 1 +
tests/streaming/assistants/assistant.test.ts | 32 +
25 files changed, 3155 insertions(+), 279 deletions(-)
create mode 100644 examples/assistant-stream-raw.ts
create mode 100644 examples/assistant-stream.ts
create mode 100644 examples/assistants.ts
create mode 100644 src/lib/AbstractAssistantStreamRunner.ts
create mode 100644 src/lib/AssistantStream.ts
create mode 100644 tests/streaming/assistants/assistant.test.ts
diff --git a/api.md b/api.md
index ff3180cba..504a103c7 100644
--- a/api.md
+++ b/api.md
@@ -2,6 +2,7 @@
Types:
+- ErrorObject
- FunctionDefinition
- FunctionParameters
@@ -177,6 +178,15 @@ Types:
- Assistant
- AssistantDeleted
+- AssistantStreamEvent
+- AssistantTool
+- CodeInterpreterTool
+- FunctionTool
+- MessageStreamEvent
+- RetrievalTool
+- RunStepStreamEvent
+- RunStreamEvent
+- ThreadStreamEvent
Methods:
@@ -214,6 +224,7 @@ Methods:
- client.beta.threads.update(threadId, { ...params }) -> Thread
- client.beta.threads.del(threadId) -> ThreadDeleted
- client.beta.threads.createAndRun({ ...params }) -> Run
+- client.beta.threads.createAndRunStream(body, options?) -> AssistantStream
### Runs
@@ -231,16 +242,29 @@ Methods:
- client.beta.threads.runs.list(threadId, { ...params }) -> RunsPage
- client.beta.threads.runs.cancel(threadId, runId) -> Run
- client.beta.threads.runs.submitToolOutputs(threadId, runId, { ...params }) -> Run
+- client.beta.threads.runs.createAndStream(threadId, body, options?) -> AssistantStream
+- client.beta.threads.runs.submitToolOutputsStream(threadId, runId, body, options?) -> AssistantStream
#### Steps
Types:
-- CodeToolCall
+- CodeInterpreterLogs
+- CodeInterpreterOutputImage
+- CodeInterpreterToolCall
+- CodeInterpreterToolCallDelta
- FunctionToolCall
+- FunctionToolCallDelta
- MessageCreationStepDetails
- RetrievalToolCall
+- RetrievalToolCallDelta
- RunStep
+- RunStepDelta
+- RunStepDeltaEvent
+- RunStepDeltaMessageDelta
+- ToolCall
+- ToolCallDelta
+- ToolCallDeltaObject
- ToolCallsStepDetails
Methods:
@@ -252,17 +276,33 @@ Methods:
Types:
-- MessageContentImageFile
-- MessageContentText
-- ThreadMessage
-- ThreadMessageDeleted
+- Annotation
+- AnnotationDelta
+- FileCitationAnnotation
+- FileCitationDeltaAnnotation
+- FilePathAnnotation
+- FilePathDeltaAnnotation
+- ImageFile
+- ImageFileContentBlock
+- ImageFileDelta
+- ImageFileDeltaBlock
+- Message
+- MessageContent
+- MessageContentDelta
+- MessageDeleted
+- MessageDelta
+- MessageDeltaEvent
+- Text
+- TextContentBlock
+- TextDelta
+- TextDeltaBlock
Methods:
-- client.beta.threads.messages.create(threadId, { ...params }) -> ThreadMessage
-- client.beta.threads.messages.retrieve(threadId, messageId) -> ThreadMessage
-- client.beta.threads.messages.update(threadId, messageId, { ...params }) -> ThreadMessage
-- client.beta.threads.messages.list(threadId, { ...params }) -> ThreadMessagesPage
+- client.beta.threads.messages.create(threadId, { ...params }) -> Message
+- client.beta.threads.messages.retrieve(threadId, messageId) -> Message
+- client.beta.threads.messages.update(threadId, messageId, { ...params }) -> Message
+- client.beta.threads.messages.list(threadId, { ...params }) -> MessagesPage
#### Files
diff --git a/examples/assistant-stream-raw.ts b/examples/assistant-stream-raw.ts
new file mode 100644
index 000000000..a882d219a
--- /dev/null
+++ b/examples/assistant-stream-raw.ts
@@ -0,0 +1,39 @@
+import OpenAI from 'openai';
+
+const openai = new OpenAI();
+
+async function main() {
+ const assistant = await openai.beta.assistants.create({
+ model: 'gpt-4-1106-preview',
+ name: 'Math Tutor',
+ instructions: 'You are a personal math tutor. Write and run code to answer math questions.',
+ });
+
+ const thread = await openai.beta.threads.create({
+ messages: [
+ {
+ role: 'user',
+ content: '"I need to solve the equation `3x + 11 = 14`. Can you help me?"',
+ },
+ ],
+ });
+
+ const stream = await openai.beta.threads.runs.create(thread.id, {
+ assistant_id: assistant.id,
+ additional_instructions: 'Please address the user as Jane Doe. The user has a premium account.',
+ stream: true,
+ });
+
+ for await (const event of stream) {
+ if (event.event === 'thread.message.delta') {
+ const chunk = event.data.delta.content?.[0];
+ if (chunk && 'text' in chunk) {
+ process.stdout.write(chunk.text.value);
+ }
+ }
+ }
+
+ console.log();
+}
+
+main();
diff --git a/examples/assistant-stream.ts b/examples/assistant-stream.ts
new file mode 100644
index 000000000..36c4ed152
--- /dev/null
+++ b/examples/assistant-stream.ts
@@ -0,0 +1,48 @@
+#!/usr/bin/env -S npm run tsn -T
+
+import OpenAI from 'openai';
+
+/**
+ * Example of streaming a response from an assistant
+ */
+
+const openai = new OpenAI();
+
+async function main() {
+ const assistant = await openai.beta.assistants.create({
+ model: 'gpt-4-1106-preview',
+ name: 'Math Tutor',
+ instructions: 'You are a personal math tutor. Write and run code to answer math questions.',
+ });
+
+ let assistantId = assistant.id;
+ console.log('Created Assistant with Id: ' + assistantId);
+
+ const thread = await openai.beta.threads.create({
+ messages: [
+ {
+ role: 'user',
+ content: '"I need to solve the equation `3x + 11 = 14`. Can you help me?"',
+ },
+ ],
+ });
+
+ let threadId = thread.id;
+ console.log('Created thread with Id: ' + threadId);
+
+ const run = openai.beta.threads.runs
+ .createAndStream(threadId, {
+ assistant_id: assistantId,
+ })
+ //Subscribe to streaming events and log them
+ .on('event', (event) => console.log(event))
+ .on('textDelta', (delta, snapshot) => console.log(snapshot))
+ .on('messageDelta', (delta, snapshot) => console.log(snapshot))
+ .on('run', (run) => console.log(run))
+ .on('messageDelta', (delta, snapshot) => console.log(snapshot))
+ .on('connect', () => console.log());
+ const result = await run.finalRun();
+ console.log('Run Result' + result);
+}
+
+main();
diff --git a/examples/assistants.ts b/examples/assistants.ts
new file mode 100644
index 000000000..bbc2f80ce
--- /dev/null
+++ b/examples/assistants.ts
@@ -0,0 +1,57 @@
+#!/usr/bin/env -S npm run tsn -T
+
+import OpenAI from 'openai';
+import { sleep } from 'openai/core';
+
+/**
+ * Example of polling for a complete response from an assistant
+ */
+
+const openai = new OpenAI();
+
+async function main() {
+ const assistant = await openai.beta.assistants.create({
+ model: 'gpt-4-1106-preview',
+ name: 'Math Tutor',
+ instructions: 'You are a personal math tutor. Write and run code to answer math questions.',
+ // tools = [],
+ });
+
+ let assistantId = assistant.id;
+ console.log('Created Assistant with Id: ' + assistantId);
+
+ const thread = await openai.beta.threads.create({
+ messages: [
+ {
+ role: 'user',
+ content: '"I need to solve the equation `3x + 11 = 14`. Can you help me?"',
+ },
+ ],
+ });
+
+ let threadId = thread.id;
+ console.log('Created thread with Id: ' + threadId);
+
+ const run = await openai.beta.threads.runs.create(thread.id, {
+ assistant_id: assistantId,
+ additional_instructions: 'Please address the user as Jane Doe. The user has a premium account.',
+ });
+
+ console.log('Created run with Id: ' + run.id);
+
+ while (true) {
+ const result = await openai.beta.threads.runs.retrieve(thread.id, run.id);
+ if (result.status == 'completed') {
+ const messages = await openai.beta.threads.messages.list(thread.id);
+ for (const message of messages.getPaginatedItems()) {
+ console.log(message);
+ }
+ break;
+ } else {
+ console.log('Waiting for completion. Current status: ' + result.status);
+ await sleep(5000);
+ }
+ }
+}
+
+main();
diff --git a/src/index.ts b/src/index.ts
index 80bf95b0d..7b3033fa9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -285,6 +285,7 @@ export namespace OpenAI {
export import Beta = API.Beta;
+ export import ErrorObject = API.ErrorObject;
export import FunctionDefinition = API.FunctionDefinition;
export import FunctionParameters = API.FunctionParameters;
}
diff --git a/src/lib/AbstractAssistantStreamRunner.ts b/src/lib/AbstractAssistantStreamRunner.ts
new file mode 100644
index 000000000..b600f0df3
--- /dev/null
+++ b/src/lib/AbstractAssistantStreamRunner.ts
@@ -0,0 +1,340 @@
+import * as Core from 'openai/core';
+import { APIUserAbortError, OpenAIError } from 'openai/error';
+import { Run, RunSubmitToolOutputsParamsBase } from 'openai/resources/beta/threads/runs/runs';
+import { RunCreateParamsBase, Runs } from 'openai/resources/beta/threads/runs/runs';
+import { ThreadCreateAndRunParamsBase, Threads } from 'openai/resources/beta/threads/threads';
+
+export abstract class AbstractAssistantStreamRunner<
+ Events extends CustomEvents = AbstractAssistantRunnerEvents,
+> {
+ controller: AbortController = new AbortController();
+
+ #connectedPromise: Promise;
+ #resolveConnectedPromise: () => void = () => {};
+ #rejectConnectedPromise: (error: OpenAIError) => void = () => {};
+
+ #endPromise: Promise;
+ #resolveEndPromise: () => void = () => {};
+ #rejectEndPromise: (error: OpenAIError) => void = () => {};
+
+ #listeners: { [Event in keyof Events]?: ListenersForEvent } = {};
+
+ #ended = false;
+ #errored = false;
+ #aborted = false;
+ #catchingPromiseCreated = false;
+
+ constructor() {
+ this.#connectedPromise = new Promise((resolve, reject) => {
+ this.#resolveConnectedPromise = resolve;
+ this.#rejectConnectedPromise = reject;
+ });
+
+ this.#endPromise = new Promise((resolve, reject) => {
+ this.#resolveEndPromise = resolve;
+ this.#rejectEndPromise = reject;
+ });
+
+ // Don't let these promises cause unhandled rejection errors.
+ // we will manually cause an unhandled rejection error later
+ // if the user hasn't registered any error listener or called
+ // any promise-returning method.
+ this.#connectedPromise.catch(() => {});
+ this.#endPromise.catch(() => {});
+ }
+
+ protected _run(executor: () => Promise) {
+ // Unfortunately if we call `executor()` immediately we get runtime errors about
+ // references to `this` before the `super()` constructor call returns.
+ setTimeout(() => {
+ executor().then(() => {
+ // this._emitFinal();
+ this._emit('end');
+ }, this.#handleError);
+ }, 0);
+ }
+
+ protected _addRun(run: Run): Run {
+ return run;
+ }
+
+ protected _connected() {
+ if (this.ended) return;
+ this.#resolveConnectedPromise();
+ this._emit('connect');
+ }
+
+ get ended(): boolean {
+ return this.#ended;
+ }
+
+ get errored(): boolean {
+ return this.#errored;
+ }
+
+ get aborted(): boolean {
+ return this.#aborted;
+ }
+
+ abort() {
+ this.controller.abort();
+ }
+
+ /**
+ * Adds the listener function to the end of the listeners array for the event.
+ * No checks are made to see if the listener has already been added. Multiple calls passing
+ * the same combination of event and listener will result in the listener being added, and
+ * called, multiple times.
+ * @returns this ChatCompletionStream, so that calls can be chained
+ */
+ on(event: Event, listener: ListenerForEvent): this {
+ const listeners: ListenersForEvent =
+ this.#listeners[event] || (this.#listeners[event] = []);
+ listeners.push({ listener });
+ return this;
+ }
+
+ /**
+ * Removes the specified listener from the listener array for the event.
+ * off() will remove, at most, one instance of a listener from the listener array. If any single
+ * listener has been added multiple times to the listener array for the specified event, then
+ * off() must be called multiple times to remove each instance.
+ * @returns this ChatCompletionStream, so that calls can be chained
+ */
+ off(event: Event, listener: ListenerForEvent): this {
+ const listeners = this.#listeners[event];
+ if (!listeners) return this;
+ const index = listeners.findIndex((l) => l.listener === listener);
+ if (index >= 0) listeners.splice(index, 1);
+ return this;
+ }
+
+ /**
+ * Adds a one-time listener function for the event. The next time the event is triggered,
+ * this listener is removed and then invoked.
+ * @returns this ChatCompletionStream, so that calls can be chained
+ */
+ once(event: Event, listener: ListenerForEvent): this {
+ const listeners: ListenersForEvent =
+ this.#listeners[event] || (this.#listeners[event] = []);
+ listeners.push({ listener, once: true });
+ return this;
+ }
+
+ /**
+ * This is similar to `.once()`, but returns a Promise that resolves the next time
+ * the event is triggered, instead of calling a listener callback.
+ * @returns a Promise that resolves the next time given event is triggered,
+ * or rejects if an error is emitted. (If you request the 'error' event,
+ * returns a promise that resolves with the error).
+ *
+ * Example:
+ *
+ * const message = await stream.emitted('message') // rejects if the stream errors
+ */
+ emitted(
+ event: Event,
+ ): Promise<
+ EventParameters extends [infer Param] ? Param
+ : EventParameters extends [] ? void
+ : EventParameters
+ > {
+ return new Promise((resolve, reject) => {
+ this.#catchingPromiseCreated = true;
+ if (event !== 'error') this.once('error', reject);
+ this.once(event, resolve as any);
+ });
+ }
+
+ async done(): Promise {
+ this.#catchingPromiseCreated = true;
+ await this.#endPromise;
+ }
+
+ #handleError = (error: unknown) => {
+ this.#errored = true;
+ if (error instanceof Error && error.name === 'AbortError') {
+ error = new APIUserAbortError();
+ }
+ if (error instanceof APIUserAbortError) {
+ this.#aborted = true;
+ return this._emit('abort', error);
+ }
+ if (error instanceof OpenAIError) {
+ return this._emit('error', error);
+ }
+ if (error instanceof Error) {
+ const openAIError: OpenAIError = new OpenAIError(error.message);
+ // @ts-ignore
+ openAIError.cause = error;
+ return this._emit('error', openAIError);
+ }
+ return this._emit('error', new OpenAIError(String(error)));
+ };
+
+ protected _emit(event: Event, ...args: EventParameters) {
+ // make sure we don't emit any events after end
+ if (this.#ended) {
+ return;
+ }
+
+ if (event === 'end') {
+ this.#ended = true;
+ this.#resolveEndPromise();
+ }
+
+ const listeners: ListenersForEvent | undefined = this.#listeners[event];
+ if (listeners) {
+ this.#listeners[event] = listeners.filter((l) => !l.once) as any;
+ listeners.forEach(({ listener }: any) => listener(...args));
+ }
+
+ if (event === 'abort') {
+ const error = args[0] as APIUserAbortError;
+ if (!this.#catchingPromiseCreated && !listeners?.length) {
+ Promise.reject(error);
+ }
+ this.#rejectConnectedPromise(error);
+ this.#rejectEndPromise(error);
+ this._emit('end');
+ return;
+ }
+
+ if (event === 'error') {
+ // NOTE: _emit('error', error) should only be called from #handleError().
+
+ const error = args[0] as OpenAIError;
+ if (!this.#catchingPromiseCreated && !listeners?.length) {
+ // Trigger an unhandled rejection if the user hasn't registered any error handlers.
+ // If you are seeing stack traces here, make sure to handle errors via either:
+ // - runner.on('error', () => ...)
+ // - await runner.done()
+ // - await runner.finalChatCompletion()
+ // - etc.
+ Promise.reject(error);
+ }
+ this.#rejectConnectedPromise(error);
+ this.#rejectEndPromise(error);
+ this._emit('end');
+ }
+ }
+
+ protected async _threadAssistantStream(
+ body: ThreadCreateAndRunParamsBase,
+ thread: Threads,
+ options?: Core.RequestOptions,
+ ): Promise {
+ return await this._createThreadAssistantStream(thread, body, options);
+ }
+
+ protected async _runAssistantStream(
+ threadId: string,
+ runs: Runs,
+ params: RunCreateParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ return await this._createAssistantStream(runs, threadId, params, options);
+ }
+
+ protected async _runToolAssistantStream(
+ threadId: string,
+ runId: string,
+ runs: Runs,
+ params: RunSubmitToolOutputsParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ return await this._createToolAssistantStream(runs, threadId, runId, params, options);
+ }
+
+ protected async _createThreadAssistantStream(
+ thread: Threads,
+ body: ThreadCreateAndRunParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+ // this.#validateParams(params);
+
+ const runResult = await thread.createAndRun(
+ { ...body, stream: false },
+ { ...options, signal: this.controller.signal },
+ );
+ this._connected();
+ return this._addRun(runResult as Run);
+ }
+
+ protected async _createToolAssistantStream(
+ run: Runs,
+ threadId: string,
+ runId: string,
+ params: RunSubmitToolOutputsParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+
+ const runResult = await run.submitToolOutputs(
+ threadId,
+ runId,
+ { ...params, stream: false },
+ { ...options, signal: this.controller.signal },
+ );
+ this._connected();
+ return this._addRun(runResult as Run);
+ }
+
+ protected async _createAssistantStream(
+ run: Runs,
+ threadId: string,
+ params: RunCreateParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+ // this.#validateParams(params);
+
+ const runResult = await run.create(
+ threadId,
+ { ...params, stream: false },
+ { ...options, signal: this.controller.signal },
+ );
+ this._connected();
+ return this._addRun(runResult as Run);
+ }
+}
+
+type CustomEvents = {
+ [k in Event]: k extends keyof AbstractAssistantRunnerEvents ? AbstractAssistantRunnerEvents[k]
+ : (...args: any[]) => void;
+};
+
+type ListenerForEvent, Event extends keyof Events> = Event extends (
+ keyof AbstractAssistantRunnerEvents
+) ?
+ AbstractAssistantRunnerEvents[Event]
+: Events[Event];
+
+type ListenersForEvent, Event extends keyof Events> = Array<{
+ listener: ListenerForEvent;
+ once?: boolean;
+}>;
+type EventParameters, Event extends keyof Events> = Parameters<
+ ListenerForEvent
+>;
+
+export interface AbstractAssistantRunnerEvents {
+ connect: () => void;
+ run: (run: Run) => void;
+ error: (error: OpenAIError) => void;
+ abort: (error: APIUserAbortError) => void;
+ end: () => void;
+}
diff --git a/src/lib/AssistantStream.ts b/src/lib/AssistantStream.ts
new file mode 100644
index 000000000..d70cb7358
--- /dev/null
+++ b/src/lib/AssistantStream.ts
@@ -0,0 +1,698 @@
+import {
+ TextContentBlock,
+ ImageFileContentBlock,
+ Message,
+ MessageContentDelta,
+ Text,
+ ImageFile,
+ TextDelta,
+ Messages,
+} from 'openai/resources/beta/threads/messages/messages';
+import * as Core from 'openai/core';
+import { RequestOptions } from 'openai/core';
+import {
+ Run,
+ RunCreateParamsBase,
+ RunCreateParamsStreaming,
+ Runs,
+ RunSubmitToolOutputsParamsBase,
+ RunSubmitToolOutputsParamsStreaming,
+} from 'openai/resources/beta/threads/runs/runs';
+import {
+ AbstractAssistantRunnerEvents,
+ AbstractAssistantStreamRunner,
+} from './AbstractAssistantStreamRunner';
+import { type ReadableStream } from 'openai/_shims/index';
+import { Stream } from 'openai/streaming';
+import { APIUserAbortError, OpenAIError } from 'openai/error';
+import {
+ AssistantStreamEvent,
+ MessageStreamEvent,
+ RunStepStreamEvent,
+ RunStreamEvent,
+} from 'openai/resources/beta/assistants/assistants';
+import { RunStep, RunStepDelta, ToolCall, ToolCallDelta } from 'openai/resources/beta/threads/runs/steps';
+import { ThreadCreateAndRunParamsBase, Threads } from 'openai/resources/beta/threads/threads';
+import MessageDelta = Messages.MessageDelta;
+
+export interface AssistantStreamEvents extends AbstractAssistantRunnerEvents {
+ //New event structure
+ messageCreated: (message: Message) => void;
+ messageDelta: (message: MessageDelta, snapshot: Message) => void;
+ messageDone: (message: Message) => void;
+
+ runStepCreated: (runStep: RunStep) => void;
+ runStepDelta: (delta: RunStepDelta, snapshot: Runs.RunStep) => void;
+ runStepDone: (runStep: Runs.RunStep, snapshot: Runs.RunStep) => void;
+
+ toolCallCreated: (toolCall: ToolCall) => void;
+ toolCallDelta: (delta: ToolCallDelta, snapshot: ToolCall) => void;
+ toolCallDone: (toolCall: ToolCall) => void;
+
+ textCreated: (content: Text) => void;
+ textDelta: (delta: TextDelta, snapshot: Text) => void;
+ textDone: (content: Text, snapshot: Message) => void;
+
+ //No created or delta as this is not streamed
+ imageFileDone: (content: ImageFile, snapshot: Message) => void;
+
+ end: () => void;
+
+ event: (event: AssistantStreamEvent) => void;
+}
+
+export type ThreadCreateAndRunParamsBaseStream = Omit & {
+ stream?: true;
+};
+
+export type RunCreateParamsBaseStream = Omit & {
+ stream?: true;
+};
+
+export type RunSubmitToolOutputsParamsStream = Omit & {
+ stream?: true;
+};
+
+export class AssistantStream
+ extends AbstractAssistantStreamRunner
+ implements AsyncIterable
+{
+ //Track all events in a single list for reference
+ #events: AssistantStreamEvent[] = [];
+
+ //Used to accumulate deltas
+ //We are accumulating many types so the value here is not strict
+ #runStepSnapshots: { [id: string]: Runs.RunStep } = {};
+ #messageSnapshots: { [id: string]: Message } = {};
+ #messageSnapshot: Message | undefined;
+ #finalRun: Run | undefined;
+ #currentContentIndex: number | undefined;
+ #currentContent: TextContentBlock | ImageFileContentBlock | undefined;
+ #currentToolCallIndex: number | undefined;
+ #currentToolCall: ToolCall | undefined;
+
+ //For current snapshot methods
+ #currentEvent: AssistantStreamEvent | undefined;
+ #currentRunSnapshot: Run | undefined;
+ #currentRunStepSnapshot: Runs.RunStep | undefined;
+
+ [Symbol.asyncIterator](): AsyncIterator {
+ const pushQueue: AssistantStreamEvent[] = [];
+ const readQueue: {
+ resolve: (chunk: AssistantStreamEvent | undefined) => void;
+ reject: (err: unknown) => void;
+ }[] = [];
+ let done = false;
+
+ //Catch all for passing along all events
+ this.on('event', (event) => {
+ const reader = readQueue.shift();
+ if (reader) {
+ reader.resolve(event);
+ } else {
+ pushQueue.push(event);
+ }
+ });
+
+ this.on('end', () => {
+ done = true;
+ for (const reader of readQueue) {
+ reader.resolve(undefined);
+ }
+ readQueue.length = 0;
+ });
+
+ this.on('abort', (err) => {
+ done = true;
+ for (const reader of readQueue) {
+ reader.reject(err);
+ }
+ readQueue.length = 0;
+ });
+
+ this.on('error', (err) => {
+ done = true;
+ for (const reader of readQueue) {
+ reader.reject(err);
+ }
+ readQueue.length = 0;
+ });
+
+ return {
+ next: async (): Promise> => {
+ if (!pushQueue.length) {
+ if (done) {
+ return { value: undefined, done: true };
+ }
+ return new Promise((resolve, reject) =>
+ readQueue.push({ resolve, reject }),
+ ).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true }));
+ }
+ const chunk = pushQueue.shift()!;
+ return { value: chunk, done: false };
+ },
+ return: async () => {
+ this.abort();
+ return { value: undefined, done: true };
+ },
+ };
+ }
+
+ toReadableStream(): ReadableStream {
+ const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
+ return stream.toReadableStream();
+ }
+
+ static createToolAssistantStream(
+ threadId: string,
+ runId: string,
+ runs: Runs,
+ body: RunSubmitToolOutputsParamsStream,
+ options: RequestOptions | undefined,
+ ) {
+ const runner = new AssistantStream();
+ runner._run(() =>
+ runner._runToolAssistantStream(threadId, runId, runs, body, {
+ ...options,
+ headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' },
+ }),
+ );
+ return runner;
+ }
+
+ protected override async _createToolAssistantStream(
+ run: Runs,
+ threadId: string,
+ runId: string,
+ params: RunSubmitToolOutputsParamsStream,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+
+ const body: RunSubmitToolOutputsParamsStreaming = { ...params, stream: true };
+ const stream = await run.submitToolOutputs(threadId, runId, body, {
+ ...options,
+ signal: this.controller.signal,
+ });
+
+ this._connected();
+
+ for await (const event of stream) {
+ this.#addEvent(event);
+ }
+ if (stream.controller.signal?.aborted) {
+ throw new APIUserAbortError();
+ }
+
+ return this._addRun(this.#endRequest());
+ }
+
+ static createThreadAssistantStream(
+ body: ThreadCreateAndRunParamsBaseStream,
+ thread: Threads,
+ options?: RequestOptions,
+ ) {
+ const runner = new AssistantStream();
+ runner._run(() =>
+ runner._threadAssistantStream(body, thread, {
+ ...options,
+ headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' },
+ }),
+ );
+ return runner;
+ }
+
+ static createAssistantStream(
+ threadId: string,
+ runs: Runs,
+ params: RunCreateParamsBaseStream,
+ options?: RequestOptions,
+ ) {
+ const runner = new AssistantStream();
+ runner._run(() =>
+ runner._runAssistantStream(threadId, runs, params, {
+ ...options,
+ headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' },
+ }),
+ );
+ return runner;
+ }
+
+ currentEvent(): AssistantStreamEvent | undefined {
+ return this.#currentEvent;
+ }
+
+ currentRun(): Run | undefined {
+ return this.#currentRunSnapshot;
+ }
+
+ currentMessageSnapshot(): Message | undefined {
+ return this.#messageSnapshot;
+ }
+
+ currentRunStepSnapshot(): Runs.RunStep | undefined {
+ return this.#currentRunStepSnapshot;
+ }
+
+ async finalRunSteps(): Promise {
+ await this.done();
+
+ return Object.values(this.#runStepSnapshots);
+ }
+
+ async finalMessages(): Promise {
+ await this.done();
+
+ return Object.values(this.#messageSnapshots);
+ }
+
+ async finalRun(): Promise {
+ await this.done();
+ if (!this.#finalRun) throw Error('Final run was not received.');
+
+ return this.#finalRun;
+ }
+
+ protected override async _createThreadAssistantStream(
+ thread: Threads,
+ params: ThreadCreateAndRunParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+
+ const body: RunCreateParamsStreaming = { ...params, stream: true };
+ const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal });
+
+ this._connected();
+
+ for await (const event of stream) {
+ this.#addEvent(event);
+ }
+ if (stream.controller.signal?.aborted) {
+ throw new APIUserAbortError();
+ }
+
+ return this._addRun(this.#endRequest());
+ }
+
+ protected override async _createAssistantStream(
+ run: Runs,
+ threadId: string,
+ params: RunCreateParamsBase,
+ options?: Core.RequestOptions,
+ ): Promise {
+ const signal = options?.signal;
+ if (signal) {
+ if (signal.aborted) this.controller.abort();
+ signal.addEventListener('abort', () => this.controller.abort());
+ }
+
+ const body: RunCreateParamsStreaming = { ...params, stream: true };
+ const stream = await run.create(threadId, body, { ...options, signal: this.controller.signal });
+
+ this._connected();
+
+ for await (const event of stream) {
+ this.#addEvent(event);
+ }
+ if (stream.controller.signal?.aborted) {
+ throw new APIUserAbortError();
+ }
+
+ return this._addRun(this.#endRequest());
+ }
+
+ #addEvent(event: AssistantStreamEvent) {
+ if (this.ended) return;
+
+ this.#currentEvent = event;
+
+ this.#handleEvent(event);
+
+ switch (event.event) {
+ case 'thread.created':
+ //No action on this event.
+ break;
+
+ case 'thread.run.created':
+ case 'thread.run.queued':
+ case 'thread.run.in_progress':
+ case 'thread.run.requires_action':
+ case 'thread.run.completed':
+ case 'thread.run.failed':
+ case 'thread.run.cancelling':
+ case 'thread.run.cancelled':
+ case 'thread.run.expired':
+ this.#handleRun(event);
+ break;
+
+ case 'thread.run.step.created':
+ case 'thread.run.step.in_progress':
+ case 'thread.run.step.delta':
+ case 'thread.run.step.completed':
+ case 'thread.run.step.failed':
+ case 'thread.run.step.cancelled':
+ case 'thread.run.step.expired':
+ this.#handleRunStep(event);
+ break;
+
+ case 'thread.message.created':
+ case 'thread.message.in_progress':
+ case 'thread.message.delta':
+ case 'thread.message.completed':
+ case 'thread.message.incomplete':
+ this.#handleMessage(event);
+ break;
+
+ case 'error':
+ //This is included for completeness, but errors are processed in the SSE event processing so this should not occur
+ throw new Error(
+ 'Encountered an error event in event processing - errors should be processed earlier',
+ );
+ }
+ }
+
+ #endRequest(): Run {
+ if (this.ended) {
+ throw new OpenAIError(`stream has ended, this shouldn't happen`);
+ }
+
+ if (!this.#finalRun) throw Error('Final run has been been received');
+
+ return this.#finalRun;
+ }
+
+ #handleMessage(event: MessageStreamEvent) {
+ const [accumulatedMessage, newContent] = this.#accumulateMessage(event, this.#messageSnapshot);
+ this.#messageSnapshot = accumulatedMessage;
+ this.#messageSnapshots[accumulatedMessage.id] = accumulatedMessage;
+
+ for (const content of newContent) {
+ const snapshotContent = accumulatedMessage.content[content.index];
+ if (snapshotContent?.type == 'text') {
+ this._emit('textCreated', snapshotContent.text);
+ }
+ }
+
+ switch (event.event) {
+ case 'thread.message.created':
+ this._emit('messageCreated', event.data);
+ break;
+
+ case 'thread.message.in_progress':
+ break;
+
+ case 'thread.message.delta':
+ this._emit('messageDelta', event.data.delta, accumulatedMessage);
+
+ if (event.data.delta.content) {
+ for (const content of event.data.delta.content) {
+ //If it is text delta, emit a text delta event
+ if (content.type == 'text' && content.text) {
+ let textDelta = content.text;
+ let snapshot = accumulatedMessage.content[content.index];
+ if (snapshot && snapshot.type == 'text') {
+ this._emit('textDelta', textDelta, snapshot.text);
+ } else {
+ throw Error('The snapshot associated with this text delta is not text or missing');
+ }
+ }
+
+ if (content.index != this.#currentContentIndex) {
+ //See if we have in progress content
+ if (this.#currentContent) {
+ switch (this.#currentContent.type) {
+ case 'text':
+ this._emit('textDone', this.#currentContent.text, this.#messageSnapshot);
+ break;
+ case 'image_file':
+ this._emit('imageFileDone', this.#currentContent.image_file, this.#messageSnapshot);
+ break;
+ }
+ }
+
+ this.#currentContentIndex = content.index;
+ }
+
+ this.#currentContent = accumulatedMessage.content[content.index];
+ }
+ }
+
+ break;
+
+ case 'thread.message.completed':
+ case 'thread.message.incomplete':
+ //We emit the latest content we were working on on completion (including incomplete)
+ if (this.#currentContentIndex !== undefined) {
+ const currentContent = event.data.content[this.#currentContentIndex];
+ if (currentContent) {
+ switch (currentContent.type) {
+ case 'image_file':
+ this._emit('imageFileDone', currentContent.image_file, this.#messageSnapshot);
+ break;
+ case 'text':
+ this._emit('textDone', currentContent.text, this.#messageSnapshot);
+ break;
+ }
+ }
+ }
+
+ if (this.#messageSnapshot) {
+ this._emit('messageDone', event.data);
+ }
+
+ this.#messageSnapshot = undefined;
+ }
+ }
+
+ #handleRunStep(event: RunStepStreamEvent) {
+ const accumulatedRunStep = this.#accumulateRunStep(event);
+ this.#currentRunStepSnapshot = accumulatedRunStep;
+
+ switch (event.event) {
+ case 'thread.run.step.created':
+ this._emit('runStepCreated', event.data);
+ break;
+ case 'thread.run.step.delta':
+ const delta = event.data.delta;
+ if (
+ delta.step_details &&
+ delta.step_details.type == 'tool_calls' &&
+ delta.step_details.tool_calls &&
+ accumulatedRunStep.step_details.type == 'tool_calls'
+ ) {
+ for (const toolCall of delta.step_details.tool_calls) {
+ if (toolCall.index == this.#currentToolCallIndex) {
+ this._emit(
+ 'toolCallDelta',
+ toolCall,
+ accumulatedRunStep.step_details.tool_calls[toolCall.index] as ToolCall,
+ );
+ } else {
+ if (this.#currentToolCall) {
+ this._emit('toolCallDone', this.#currentToolCall);
+ }
+
+ this.#currentToolCallIndex = toolCall.index;
+ this.#currentToolCall = accumulatedRunStep.step_details.tool_calls[toolCall.index];
+ if (this.#currentToolCall) this._emit('toolCallCreated', this.#currentToolCall);
+ }
+ }
+ }
+
+ this._emit('runStepDelta', event.data.delta, accumulatedRunStep);
+ break;
+ case 'thread.run.step.completed':
+ case 'thread.run.step.failed':
+ case 'thread.run.step.cancelled':
+ case 'thread.run.step.expired':
+ this.#currentRunStepSnapshot = undefined;
+ const details = event.data.step_details;
+ if (details.type == 'tool_calls') {
+ if (this.#currentToolCall) {
+ this._emit('toolCallDone', this.#currentToolCall as ToolCall);
+ this.#currentToolCall = undefined;
+ }
+ }
+ this._emit('runStepDone', event.data, accumulatedRunStep);
+ break;
+ case 'thread.run.step.in_progress':
+ break;
+ }
+ }
+
+ #handleEvent(event: AssistantStreamEvent) {
+ this.#events.push(event);
+ this._emit('event', event);
+ }
+
+ #accumulateRunStep(event: RunStepStreamEvent): Runs.RunStep {
+ switch (event.event) {
+ case 'thread.run.step.created':
+ this.#runStepSnapshots[event.data.id] = event.data;
+ return event.data;
+
+ case 'thread.run.step.delta':
+ let snapshot = this.#runStepSnapshots[event.data.id] as Runs.RunStep;
+ if (!snapshot) {
+ throw Error('Received a RunStepDelta before creation of a snapshot');
+ }
+
+ let data = event.data;
+
+ if (data.delta) {
+ const accumulated = AssistantStream.accumulateDelta(snapshot, data.delta) as Runs.RunStep;
+ this.#runStepSnapshots[event.data.id] = accumulated;
+ }
+
+ return this.#runStepSnapshots[event.data.id] as Runs.RunStep;
+
+ case 'thread.run.step.completed':
+ case 'thread.run.step.failed':
+ case 'thread.run.step.cancelled':
+ case 'thread.run.step.expired':
+ case 'thread.run.step.in_progress':
+ this.#runStepSnapshots[event.data.id] = event.data;
+ break;
+ }
+
+ if (this.#runStepSnapshots[event.data.id]) return this.#runStepSnapshots[event.data.id] as Runs.RunStep;
+ throw new Error('No snapshot available');
+ }
+
+ #accumulateMessage(
+ event: AssistantStreamEvent,
+ snapshot: Message | undefined,
+ ): [Message, MessageContentDelta[]] {
+ let newContent: MessageContentDelta[] = [];
+
+ switch (event.event) {
+ case 'thread.message.created':
+ //On creation the snapshot is just the initial message
+ return [event.data, newContent];
+
+ case 'thread.message.delta':
+ if (!snapshot) {
+ throw Error(
+ 'Received a delta with no existing snapshot (there should be one from message creation)',
+ );
+ }
+
+ let data = event.data;
+
+ //If this delta does not have content, nothing to process
+ if (data.delta.content) {
+ for (const contentElement of data.delta.content) {
+ if (contentElement.index in snapshot.content) {
+ let currentContent = snapshot.content[contentElement.index];
+ snapshot.content[contentElement.index] = this.#accumulateContent(
+ contentElement,
+ currentContent,
+ );
+ } else {
+ snapshot.content[contentElement.index] = contentElement as
+ | TextContentBlock
+ | ImageFileContentBlock;
+ //This is a new element
+ newContent.push(contentElement);
+ }
+ }
+ }
+
+ return [snapshot, newContent];
+
+ case 'thread.message.in_progress':
+ case 'thread.message.completed':
+ case 'thread.message.incomplete':
+ //No changes on other thread events
+ if (snapshot) {
+ return [snapshot, newContent];
+ } else {
+ throw Error('Received thread message event with no existing snapshot');
+ }
+ }
+ throw Error('Tried to accumulate a non-message event');
+ }
+
+ #accumulateContent(
+ contentElement: MessageContentDelta,
+ currentContent: TextContentBlock | ImageFileContentBlock | undefined,
+ ): TextContentBlock | ImageFileContentBlock {
+ return AssistantStream.accumulateDelta(currentContent as unknown as Record, contentElement) as
+ | TextContentBlock
+ | ImageFileContentBlock;
+ }
+
+ static accumulateDelta(acc: Record, delta: Record): Record {
+ for (const [key, deltaValue] of Object.entries(delta)) {
+ if (!acc.hasOwnProperty(key)) {
+ acc[key] = deltaValue;
+ continue;
+ }
+
+ let accValue = acc[key];
+ if (accValue === null || accValue === undefined) {
+ acc[key] = deltaValue;
+ continue;
+ }
+
+ // We don't accumulate these special properties
+ if (key === 'index' || key === 'type') {
+ acc[key] = deltaValue;
+ continue;
+ }
+
+ // Type-specific accumulation logic
+ if (typeof accValue === 'string' && typeof deltaValue === 'string') {
+ accValue += deltaValue;
+ } else if (typeof accValue === 'number' && typeof deltaValue === 'number') {
+ accValue += deltaValue;
+ } else if (Core.isObj(accValue) && Core.isObj(deltaValue)) {
+ accValue = this.accumulateDelta(accValue as Record, deltaValue as Record);
+ } else if (Array.isArray(accValue) && Array.isArray(deltaValue)) {
+ if (accValue.every((x) => typeof x === 'string' || typeof x === 'number')) {
+ accValue.push(...deltaValue); // Use spread syntax for efficient addition
+ continue;
+ }
+ } else {
+ throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`);
+ }
+ acc[key] = accValue;
+ }
+
+ return acc;
+ }
+
+ #handleRun(event: RunStreamEvent) {
+ this.#currentRunSnapshot = event.data;
+ switch (event.event) {
+ case 'thread.run.created':
+ break;
+ case 'thread.run.queued':
+ break;
+ case 'thread.run.in_progress':
+ break;
+ case 'thread.run.requires_action':
+ case 'thread.run.cancelled':
+ case 'thread.run.failed':
+ case 'thread.run.completed':
+ case 'thread.run.expired':
+ this.#finalRun = event.data;
+ if (this.#currentToolCall) {
+ this._emit('toolCallDone', this.#currentToolCall);
+ this.#currentToolCall = undefined;
+ }
+ break;
+ case 'thread.run.cancelling':
+ break;
+ }
+ }
+}
diff --git a/src/resources/beta/assistants/assistants.ts b/src/resources/beta/assistants/assistants.ts
index 08abb2c91..b4e92fd92 100644
--- a/src/resources/beta/assistants/assistants.ts
+++ b/src/resources/beta/assistants/assistants.ts
@@ -6,6 +6,10 @@ import { isRequestOptions } from 'openai/core';
import * as AssistantsAPI from 'openai/resources/beta/assistants/assistants';
import * as Shared from 'openai/resources/shared';
import * as FilesAPI from 'openai/resources/beta/assistants/files';
+import * as ThreadsAPI from 'openai/resources/beta/threads/threads';
+import * as MessagesAPI from 'openai/resources/beta/threads/messages/messages';
+import * as RunsAPI from 'openai/resources/beta/threads/runs/runs';
+import * as StepsAPI from 'openai/resources/beta/threads/runs/steps';
import { CursorPage, type CursorPageParams } from 'openai/pagination';
export class Assistants extends APIResource {
@@ -145,40 +149,777 @@ export interface Assistant {
* A list of tool enabled on the assistant. There can be a maximum of 128 tools per
* assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`.
*/
- tools: Array;
+ tools: Array;
}
-export namespace Assistant {
- export interface CodeInterpreter {
+export interface AssistantDeleted {
+ id: string;
+
+ deleted: boolean;
+
+ object: 'assistant.deleted';
+}
+
+/**
+ * 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](https://platform.openai.com/docs/assistants/overview)
+ * to learn how to integrate the Assistants API with streaming.
+ */
+export type AssistantStreamEvent =
+ | AssistantStreamEvent.ThreadCreated
+ | AssistantStreamEvent.ThreadRunCreated
+ | AssistantStreamEvent.ThreadRunQueued
+ | AssistantStreamEvent.ThreadRunInProgress
+ | AssistantStreamEvent.ThreadRunRequiresAction
+ | AssistantStreamEvent.ThreadRunCompleted
+ | AssistantStreamEvent.ThreadRunFailed
+ | AssistantStreamEvent.ThreadRunCancelling
+ | AssistantStreamEvent.ThreadRunCancelled
+ | AssistantStreamEvent.ThreadRunExpired
+ | AssistantStreamEvent.ThreadRunStepCreated
+ | AssistantStreamEvent.ThreadRunStepInProgress
+ | AssistantStreamEvent.ThreadRunStepDelta
+ | AssistantStreamEvent.ThreadRunStepCompleted
+ | AssistantStreamEvent.ThreadRunStepFailed
+ | AssistantStreamEvent.ThreadRunStepCancelled
+ | AssistantStreamEvent.ThreadRunStepExpired
+ | AssistantStreamEvent.ThreadMessageCreated
+ | AssistantStreamEvent.ThreadMessageInProgress
+ | AssistantStreamEvent.ThreadMessageDelta
+ | AssistantStreamEvent.ThreadMessageCompleted
+ | AssistantStreamEvent.ThreadMessageIncomplete
+ | AssistantStreamEvent.ErrorEvent;
+
+export namespace AssistantStreamEvent {
+ /**
+ * Occurs when a new
+ * [thread](https://platform.openai.com/docs/api-reference/threads/object) is
+ * created.
+ */
+ export interface ThreadCreated {
+ /**
+ * Represents a thread that contains
+ * [messages](https://platform.openai.com/docs/api-reference/messages).
+ */
+ data: ThreadsAPI.Thread;
+
+ event: 'thread.created';
+ }
+
+ /**
+ * Occurs when a new
+ * [run](https://platform.openai.com/docs/api-reference/runs/object) is created.
+ */
+ export interface ThreadRunCreated {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.created';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `queued` status.
+ */
+ export interface ThreadRunQueued {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.queued';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to an `in_progress` status.
+ */
+ export interface ThreadRunInProgress {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.in_progress';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `requires_action` status.
+ */
+ export interface ThreadRunRequiresAction {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.requires_action';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * is completed.
+ */
+ export interface ThreadRunCompleted {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.completed';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * fails.
+ */
+ export interface ThreadRunFailed {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.failed';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `cancelling` status.
+ */
+ export interface ThreadRunCancelling {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.cancelling';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * is cancelled.
+ */
+ export interface ThreadRunCancelled {
/**
- * The type of tool being defined: `code_interpreter`
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
*/
- type: 'code_interpreter';
+ data: RunsAPI.Run;
+
+ event: 'thread.run.cancelled';
}
- export interface Retrieval {
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * expires.
+ */
+ export interface ThreadRunExpired {
/**
- * The type of tool being defined: `retrieval`
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
*/
- type: 'retrieval';
+ data: RunsAPI.Run;
+
+ event: 'thread.run.expired';
}
- export interface Function {
- function: Shared.FunctionDefinition;
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * created.
+ */
+ export interface ThreadRunStepCreated {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.created';
+ }
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * moves to an `in_progress` state.
+ */
+ export interface ThreadRunStepInProgress {
/**
- * The type of tool being defined: `function`
+ * Represents a step in execution of a run.
*/
- type: 'function';
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.in_progress';
+ }
+
+ /**
+ * Occurs when parts of a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) are
+ * being streamed.
+ */
+ export interface ThreadRunStepDelta {
+ /**
+ * Represents a run step delta i.e. any changed fields on a run step during
+ * streaming.
+ */
+ data: StepsAPI.RunStepDeltaEvent;
+
+ event: 'thread.run.step.delta';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * completed.
+ */
+ export interface ThreadRunStepCompleted {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.completed';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * fails.
+ */
+ export interface ThreadRunStepFailed {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.failed';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * cancelled.
+ */
+ export interface ThreadRunStepCancelled {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.cancelled';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * expires.
+ */
+ export interface ThreadRunStepExpired {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.expired';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) is
+ * created.
+ */
+ export interface ThreadMessageCreated {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.created';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) moves
+ * to an `in_progress` state.
+ */
+ export interface ThreadMessageInProgress {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.in_progress';
+ }
+
+ /**
+ * Occurs when parts of a
+ * [Message](https://platform.openai.com/docs/api-reference/messages/object) are
+ * being streamed.
+ */
+ export interface ThreadMessageDelta {
+ /**
+ * Represents a message delta i.e. any changed fields on a message during
+ * streaming.
+ */
+ data: MessagesAPI.MessageDeltaEvent;
+
+ event: 'thread.message.delta';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) is
+ * completed.
+ */
+ export interface ThreadMessageCompleted {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.completed';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) ends
+ * before it is completed.
+ */
+ export interface ThreadMessageIncomplete {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.incomplete';
+ }
+
+ /**
+ * Occurs when an
+ * [error](https://platform.openai.com/docs/guides/error-codes/api-errors) occurs.
+ * This can happen due to an internal server error or a timeout.
+ */
+ export interface ErrorEvent {
+ data: Shared.ErrorObject;
+
+ event: 'error';
}
}
-export interface AssistantDeleted {
- id: string;
+export type AssistantTool = CodeInterpreterTool | RetrievalTool | FunctionTool;
- deleted: boolean;
+export interface CodeInterpreterTool {
+ /**
+ * The type of tool being defined: `code_interpreter`
+ */
+ type: 'code_interpreter';
+}
- object: 'assistant.deleted';
+export interface FunctionTool {
+ function: Shared.FunctionDefinition;
+
+ /**
+ * The type of tool being defined: `function`
+ */
+ type: 'function';
+}
+
+/**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) is
+ * created.
+ */
+export type MessageStreamEvent =
+ | MessageStreamEvent.ThreadMessageCreated
+ | MessageStreamEvent.ThreadMessageInProgress
+ | MessageStreamEvent.ThreadMessageDelta
+ | MessageStreamEvent.ThreadMessageCompleted
+ | MessageStreamEvent.ThreadMessageIncomplete;
+
+export namespace MessageStreamEvent {
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) is
+ * created.
+ */
+ export interface ThreadMessageCreated {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.created';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) moves
+ * to an `in_progress` state.
+ */
+ export interface ThreadMessageInProgress {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.in_progress';
+ }
+
+ /**
+ * Occurs when parts of a
+ * [Message](https://platform.openai.com/docs/api-reference/messages/object) are
+ * being streamed.
+ */
+ export interface ThreadMessageDelta {
+ /**
+ * Represents a message delta i.e. any changed fields on a message during
+ * streaming.
+ */
+ data: MessagesAPI.MessageDeltaEvent;
+
+ event: 'thread.message.delta';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) is
+ * completed.
+ */
+ export interface ThreadMessageCompleted {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.completed';
+ }
+
+ /**
+ * Occurs when a
+ * [message](https://platform.openai.com/docs/api-reference/messages/object) ends
+ * before it is completed.
+ */
+ export interface ThreadMessageIncomplete {
+ /**
+ * Represents a message within a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: MessagesAPI.Message;
+
+ event: 'thread.message.incomplete';
+ }
+}
+
+export interface RetrievalTool {
+ /**
+ * The type of tool being defined: `retrieval`
+ */
+ type: 'retrieval';
+}
+
+/**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * created.
+ */
+export type RunStepStreamEvent =
+ | RunStepStreamEvent.ThreadRunStepCreated
+ | RunStepStreamEvent.ThreadRunStepInProgress
+ | RunStepStreamEvent.ThreadRunStepDelta
+ | RunStepStreamEvent.ThreadRunStepCompleted
+ | RunStepStreamEvent.ThreadRunStepFailed
+ | RunStepStreamEvent.ThreadRunStepCancelled
+ | RunStepStreamEvent.ThreadRunStepExpired;
+
+export namespace RunStepStreamEvent {
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * created.
+ */
+ export interface ThreadRunStepCreated {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.created';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * moves to an `in_progress` state.
+ */
+ export interface ThreadRunStepInProgress {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.in_progress';
+ }
+
+ /**
+ * Occurs when parts of a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) are
+ * being streamed.
+ */
+ export interface ThreadRunStepDelta {
+ /**
+ * Represents a run step delta i.e. any changed fields on a run step during
+ * streaming.
+ */
+ data: StepsAPI.RunStepDeltaEvent;
+
+ event: 'thread.run.step.delta';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * completed.
+ */
+ export interface ThreadRunStepCompleted {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.completed';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * fails.
+ */
+ export interface ThreadRunStepFailed {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.failed';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object) is
+ * cancelled.
+ */
+ export interface ThreadRunStepCancelled {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.cancelled';
+ }
+
+ /**
+ * Occurs when a
+ * [run step](https://platform.openai.com/docs/api-reference/runs/step-object)
+ * expires.
+ */
+ export interface ThreadRunStepExpired {
+ /**
+ * Represents a step in execution of a run.
+ */
+ data: StepsAPI.RunStep;
+
+ event: 'thread.run.step.expired';
+ }
+}
+
+/**
+ * Occurs when a new
+ * [run](https://platform.openai.com/docs/api-reference/runs/object) is created.
+ */
+export type RunStreamEvent =
+ | RunStreamEvent.ThreadRunCreated
+ | RunStreamEvent.ThreadRunQueued
+ | RunStreamEvent.ThreadRunInProgress
+ | RunStreamEvent.ThreadRunRequiresAction
+ | RunStreamEvent.ThreadRunCompleted
+ | RunStreamEvent.ThreadRunFailed
+ | RunStreamEvent.ThreadRunCancelling
+ | RunStreamEvent.ThreadRunCancelled
+ | RunStreamEvent.ThreadRunExpired;
+
+export namespace RunStreamEvent {
+ /**
+ * Occurs when a new
+ * [run](https://platform.openai.com/docs/api-reference/runs/object) is created.
+ */
+ export interface ThreadRunCreated {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.created';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `queued` status.
+ */
+ export interface ThreadRunQueued {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.queued';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to an `in_progress` status.
+ */
+ export interface ThreadRunInProgress {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.in_progress';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `requires_action` status.
+ */
+ export interface ThreadRunRequiresAction {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.requires_action';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * is completed.
+ */
+ export interface ThreadRunCompleted {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.completed';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * fails.
+ */
+ export interface ThreadRunFailed {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.failed';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * moves to a `cancelling` status.
+ */
+ export interface ThreadRunCancelling {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.cancelling';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * is cancelled.
+ */
+ export interface ThreadRunCancelled {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.cancelled';
+ }
+
+ /**
+ * Occurs when a [run](https://platform.openai.com/docs/api-reference/runs/object)
+ * expires.
+ */
+ export interface ThreadRunExpired {
+ /**
+ * Represents an execution run on a
+ * [thread](https://platform.openai.com/docs/api-reference/threads).
+ */
+ data: RunsAPI.Run;
+
+ event: 'thread.run.expired';
+ }
+}
+
+/**
+ * Occurs when a new
+ * [thread](https://platform.openai.com/docs/api-reference/threads/object) is
+ * created.
+ */
+export interface ThreadStreamEvent {
+ /**
+ * Represents a thread that contains
+ * [messages](https://platform.openai.com/docs/api-reference/messages).
+ */
+ data: ThreadsAPI.Thread;
+
+ event: 'thread.created';
}
export interface AssistantCreateParams {
@@ -226,36 +967,7 @@ export interface AssistantCreateParams {
* A list of tool enabled on the assistant. There can be a maximum of 128 tools per
* assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`.
*/
- tools?: Array<
- | AssistantCreateParams.AssistantToolsCode
- | AssistantCreateParams.AssistantToolsRetrieval
- | AssistantCreateParams.AssistantToolsFunction
- >;
-}
-
-export namespace AssistantCreateParams {
- export interface AssistantToolsCode {
- /**
- * The type of tool being defined: `code_interpreter`
- */
- type: 'code_interpreter';
- }
-
- export interface AssistantToolsRetrieval {
- /**
- * The type of tool being defined: `retrieval`
- */
- type: 'retrieval';
- }
-
- export interface AssistantToolsFunction {
- function: Shared.FunctionDefinition;
-
- /**
- * The type of tool being defined: `function`
- */
- type: 'function';
- }
+ tools?: Array;
}
export interface AssistantUpdateParams {
@@ -305,36 +1017,7 @@ export interface AssistantUpdateParams {
* A list of tool enabled on the assistant. There can be a maximum of 128 tools per
* assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`.
*/
- tools?: Array<
- | AssistantUpdateParams.AssistantToolsCode
- | AssistantUpdateParams.AssistantToolsRetrieval
- | AssistantUpdateParams.AssistantToolsFunction
- >;
-}
-
-export namespace AssistantUpdateParams {
- export interface AssistantToolsCode {
- /**
- * The type of tool being defined: `code_interpreter`
- */
- type: 'code_interpreter';
- }
-
- export interface AssistantToolsRetrieval {
- /**
- * The type of tool being defined: `retrieval`
- */
- type: 'retrieval';
- }
-
- export interface AssistantToolsFunction {
- function: Shared.FunctionDefinition;
-
- /**
- * The type of tool being defined: `function`
- */
- type: 'function';
- }
+ tools?: Array;
}
export interface AssistantListParams extends CursorPageParams {
@@ -356,6 +1039,15 @@ export interface AssistantListParams extends CursorPageParams {
export namespace Assistants {
export import Assistant = AssistantsAPI.Assistant;
export import AssistantDeleted = AssistantsAPI.AssistantDeleted;
+ export import AssistantStreamEvent = AssistantsAPI.AssistantStreamEvent;
+ export import AssistantTool = AssistantsAPI.AssistantTool;
+ export import CodeInterpreterTool = AssistantsAPI.CodeInterpreterTool;
+ export import FunctionTool = AssistantsAPI.FunctionTool;
+ export import MessageStreamEvent = AssistantsAPI.MessageStreamEvent;
+ export import RetrievalTool = AssistantsAPI.RetrievalTool;
+ export import RunStepStreamEvent = AssistantsAPI.RunStepStreamEvent;
+ export import RunStreamEvent = AssistantsAPI.RunStreamEvent;
+ export import ThreadStreamEvent = AssistantsAPI.ThreadStreamEvent;
export import AssistantsPage = AssistantsAPI.AssistantsPage;
export import AssistantCreateParams = AssistantsAPI.AssistantCreateParams;
export import AssistantUpdateParams = AssistantsAPI.AssistantUpdateParams;
diff --git a/src/resources/beta/assistants/index.ts b/src/resources/beta/assistants/index.ts
index 5236bc8de..0ae8c9c67 100644
--- a/src/resources/beta/assistants/index.ts
+++ b/src/resources/beta/assistants/index.ts
@@ -3,6 +3,15 @@
export {
Assistant,
AssistantDeleted,
+ AssistantStreamEvent,
+ AssistantTool,
+ CodeInterpreterTool,
+ FunctionTool,
+ MessageStreamEvent,
+ RetrievalTool,
+ RunStepStreamEvent,
+ RunStreamEvent,
+ ThreadStreamEvent,
AssistantCreateParams,
AssistantUpdateParams,
AssistantListParams,
diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts
index 5fd99990d..74056ed1d 100644
--- a/src/resources/beta/beta.ts
+++ b/src/resources/beta/beta.ts
@@ -16,6 +16,15 @@ export namespace Beta {
export import Assistants = AssistantsAPI.Assistants;
export import Assistant = AssistantsAPI.Assistant;
export import AssistantDeleted = AssistantsAPI.AssistantDeleted;
+ export import AssistantStreamEvent = AssistantsAPI.AssistantStreamEvent;
+ export import AssistantTool = AssistantsAPI.AssistantTool;
+ export import CodeInterpreterTool = AssistantsAPI.CodeInterpreterTool;
+ export import FunctionTool = AssistantsAPI.FunctionTool;
+ export import MessageStreamEvent = AssistantsAPI.MessageStreamEvent;
+ export import RetrievalTool = AssistantsAPI.RetrievalTool;
+ export import RunStepStreamEvent = AssistantsAPI.RunStepStreamEvent;
+ export import RunStreamEvent = AssistantsAPI.RunStreamEvent;
+ export import ThreadStreamEvent = AssistantsAPI.ThreadStreamEvent;
export import AssistantsPage = AssistantsAPI.AssistantsPage;
export import AssistantCreateParams = AssistantsAPI.AssistantCreateParams;
export import AssistantUpdateParams = AssistantsAPI.AssistantUpdateParams;
@@ -26,4 +35,7 @@ export namespace Beta {
export import ThreadCreateParams = ThreadsAPI.ThreadCreateParams;
export import ThreadUpdateParams = ThreadsAPI.ThreadUpdateParams;
export import ThreadCreateAndRunParams = ThreadsAPI.ThreadCreateAndRunParams;
+ export import ThreadCreateAndRunParamsNonStreaming = ThreadsAPI.ThreadCreateAndRunParamsNonStreaming;
+ export import ThreadCreateAndRunParamsStreaming = ThreadsAPI.ThreadCreateAndRunParamsStreaming;
+ export import ThreadCreateAndRunStreamParams = ThreadsAPI.ThreadCreateAndRunStreamParams;
}
diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts
index 4ed7e84b1..d8770c29a 100644
--- a/src/resources/beta/index.ts
+++ b/src/resources/beta/index.ts
@@ -3,6 +3,15 @@
export {
Assistant,
AssistantDeleted,
+ AssistantStreamEvent,
+ AssistantTool,
+ CodeInterpreterTool,
+ FunctionTool,
+ MessageStreamEvent,
+ RetrievalTool,
+ RunStepStreamEvent,
+ RunStreamEvent,
+ ThreadStreamEvent,
AssistantCreateParams,
AssistantUpdateParams,
AssistantListParams,
@@ -17,5 +26,8 @@ export {
ThreadCreateParams,
ThreadUpdateParams,
ThreadCreateAndRunParams,
+ ThreadCreateAndRunParamsNonStreaming,
+ ThreadCreateAndRunParamsStreaming,
+ ThreadCreateAndRunStreamParams,
Threads,
} from './threads/index';
diff --git a/src/resources/beta/threads/index.ts b/src/resources/beta/threads/index.ts
index 54a02dd03..3585be846 100644
--- a/src/resources/beta/threads/index.ts
+++ b/src/resources/beta/threads/index.ts
@@ -1,14 +1,30 @@
// File generated from our OpenAPI spec by Stainless.
export {
- MessageContentImageFile,
- MessageContentText,
- ThreadMessage,
- ThreadMessageDeleted,
+ Annotation,
+ AnnotationDelta,
+ FileCitationAnnotation,
+ FileCitationDeltaAnnotation,
+ FilePathAnnotation,
+ FilePathDeltaAnnotation,
+ ImageFile,
+ ImageFileContentBlock,
+ ImageFileDelta,
+ ImageFileDeltaBlock,
+ Message,
+ MessageContent,
+ MessageContentDelta,
+ MessageDeleted,
+ MessageDelta,
+ MessageDeltaEvent,
+ Text,
+ TextContentBlock,
+ TextDelta,
+ TextDeltaBlock,
MessageCreateParams,
MessageUpdateParams,
MessageListParams,
- ThreadMessagesPage,
+ MessagesPage,
Messages,
} from './messages/index';
export {
@@ -16,9 +32,15 @@ export {
Run,
RunStatus,
RunCreateParams,
+ RunCreateParamsNonStreaming,
+ RunCreateParamsStreaming,
RunUpdateParams,
RunListParams,
+ RunCreateAndStreamParams,
RunSubmitToolOutputsParams,
+ RunSubmitToolOutputsParamsNonStreaming,
+ RunSubmitToolOutputsParamsStreaming,
+ RunSubmitToolOutputsStreamParams,
RunsPage,
Runs,
} from './runs/index';
@@ -28,5 +50,8 @@ export {
ThreadCreateParams,
ThreadUpdateParams,
ThreadCreateAndRunParams,
+ ThreadCreateAndRunParamsNonStreaming,
+ ThreadCreateAndRunParamsStreaming,
+ ThreadCreateAndRunStreamParams,
Threads,
} from './threads';
diff --git a/src/resources/beta/threads/messages/index.ts b/src/resources/beta/threads/messages/index.ts
index cde22c2a9..f68edbbd4 100644
--- a/src/resources/beta/threads/messages/index.ts
+++ b/src/resources/beta/threads/messages/index.ts
@@ -1,14 +1,30 @@
// File generated from our OpenAPI spec by Stainless.
export {
- MessageContentImageFile,
- MessageContentText,
- ThreadMessage,
- ThreadMessageDeleted,
+ Annotation,
+ AnnotationDelta,
+ FileCitationAnnotation,
+ FileCitationDeltaAnnotation,
+ FilePathAnnotation,
+ FilePathDeltaAnnotation,
+ ImageFile,
+ ImageFileContentBlock,
+ ImageFileDelta,
+ ImageFileDeltaBlock,
+ Message,
+ MessageContent,
+ MessageContentDelta,
+ MessageDeleted,
+ MessageDelta,
+ MessageDeltaEvent,
+ Text,
+ TextContentBlock,
+ TextDelta,
+ TextDeltaBlock,
MessageCreateParams,
MessageUpdateParams,
MessageListParams,
- ThreadMessagesPage,
+ MessagesPage,
Messages,
} from './messages';
export { MessageFile, FileListParams, MessageFilesPage, Files } from './files';
diff --git a/src/resources/beta/threads/messages/messages.ts b/src/resources/beta/threads/messages/messages.ts
index 40b436829..b38a4bbf0 100644
--- a/src/resources/beta/threads/messages/messages.ts
+++ b/src/resources/beta/threads/messages/messages.ts
@@ -17,7 +17,7 @@ export class Messages extends APIResource {
threadId: string,
body: MessageCreateParams,
options?: Core.RequestOptions,
- ): Core.APIPromise {
+ ): Core.APIPromise {
return this._client.post(`/threads/${threadId}/messages`, {
body,
...options,
@@ -28,11 +28,7 @@ export class Messages extends APIResource {
/**
* Retrieve a message.
*/
- retrieve(
- threadId: string,
- messageId: string,
- options?: Core.RequestOptions,
- ): Core.APIPromise {
+ retrieve(threadId: string, messageId: string, options?: Core.RequestOptions): Core.APIPromise {
return this._client.get(`/threads/${threadId}/messages/${messageId}`, {
...options,
headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
@@ -47,7 +43,7 @@ export class Messages extends APIResource {
messageId: string,
body: MessageUpdateParams,
options?: Core.RequestOptions,
- ): Core.APIPromise {
+ ): Core.APIPromise {
return this._client.post(`/threads/${threadId}/messages/${messageId}`, {
body,
...options,
@@ -62,17 +58,17 @@ export class Messages extends APIResource {
threadId: string,
query?: MessageListParams,
options?: Core.RequestOptions,
- ): Core.PagePromise;
- list(threadId: string, options?: Core.RequestOptions): Core.PagePromise;
+ ): Core.PagePromise;
+ list(threadId: string, options?: Core.RequestOptions): Core.PagePromise;
list(
threadId: string,
query: MessageListParams | Core.RequestOptions = {},
options?: Core.RequestOptions,
- ): Core.PagePromise {
+ ): Core.PagePromise {
if (isRequestOptions(query)) {
return this.list(threadId, {}, query);
}
- return this._client.getAPIList(`/threads/${threadId}/messages`, ThreadMessagesPage, {
+ return this._client.getAPIList(`/threads/${threadId}/messages`, MessagesPage, {
query,
...options,
headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
@@ -80,129 +76,220 @@ export class Messages extends APIResource {
}
}
-export class ThreadMessagesPage extends CursorPage {}
+export class MessagesPage extends CursorPage {}
/**
- * References an image [File](https://platform.openai.com/docs/api-reference/files)
- * in the content of a message.
+ * A citation within the message that points to a specific quote from a specific
+ * File associated with the assistant or the message. Generated when the assistant
+ * uses the "retrieval" tool to search files.
+ */
+export type Annotation = FileCitationAnnotation | FilePathAnnotation;
+
+/**
+ * A citation within the message that points to a specific quote from a specific
+ * File associated with the assistant or the message. Generated when the assistant
+ * uses the "retrieval" tool to search files.
+ */
+export type AnnotationDelta = FileCitationDeltaAnnotation | FilePathDeltaAnnotation;
+
+/**
+ * A citation within the message that points to a specific quote from a specific
+ * File associated with the assistant or the message. Generated when the assistant
+ * uses the "retrieval" tool to search files.
*/
-export interface MessageContentImageFile {
- image_file: MessageContentImageFile.ImageFile;
+export interface FileCitationAnnotation {
+ end_index: number;
+
+ file_citation: FileCitationAnnotation.FileCitation;
+
+ start_index: number;
/**
- * Always `image_file`.
+ * The text in the message content that needs to be replaced.
*/
- type: 'image_file';
+ text: string;
+
+ /**
+ * Always `file_citation`.
+ */
+ type: 'file_citation';
}
-export namespace MessageContentImageFile {
- export interface ImageFile {
+export namespace FileCitationAnnotation {
+ export interface FileCitation {
/**
- * The [File](https://platform.openai.com/docs/api-reference/files) ID of the image
- * in the message content.
+ * The ID of the specific File the citation is from.
*/
file_id: string;
+
+ /**
+ * The specific quote in the file.
+ */
+ quote: string;
}
}
/**
- * The text content that is part of a message.
+ * A citation within the message that points to a specific quote from a specific
+ * File associated with the assistant or the message. Generated when the assistant
+ * uses the "retrieval" tool to search files.
*/
-export interface MessageContentText {
- text: MessageContentText.Text;
+export interface FileCitationDeltaAnnotation {
+ /**
+ * The index of the annotation in the text content part.
+ */
+ index: number;
/**
- * Always `text`.
+ * Always `file_citation`.
*/
- type: 'text';
+ type: 'file_citation';
+
+ end_index?: number;
+
+ file_citation?: FileCitationDeltaAnnotation.FileCitation;
+
+ start_index?: number;
+
+ /**
+ * The text in the message content that needs to be replaced.
+ */
+ text?: string;
}
-export namespace MessageContentText {
- export interface Text {
- annotations: Array;
+export namespace FileCitationDeltaAnnotation {
+ export interface FileCitation {
+ /**
+ * The ID of the specific File the citation is from.
+ */
+ file_id?: string;
/**
- * The data that makes up the text.
+ * The specific quote in the file.
*/
- value: string;
+ quote?: string;
}
+}
+
+/**
+ * A URL for the file that's generated when the assistant used the
+ * `code_interpreter` tool to generate a file.
+ */
+export interface FilePathAnnotation {
+ end_index: number;
+
+ file_path: FilePathAnnotation.FilePath;
+
+ start_index: number;
+
+ /**
+ * The text in the message content that needs to be replaced.
+ */
+ text: string;
+
+ /**
+ * Always `file_path`.
+ */
+ type: 'file_path';
+}
- export namespace Text {
+export namespace FilePathAnnotation {
+ export interface FilePath {
/**
- * A citation within the message that points to a specific quote from a specific
- * File associated with the assistant or the message. Generated when the assistant
- * uses the "retrieval" tool to search files.
+ * The ID of the file that was generated.
*/
- export interface FileCitation {
- end_index: number;
+ file_id: string;
+ }
+}
+
+/**
+ * A URL for the file that's generated when the assistant used the
+ * `code_interpreter` tool to generate a file.
+ */
+export interface FilePathDeltaAnnotation {
+ /**
+ * The index of the annotation in the text content part.
+ */
+ index: number;
- file_citation: FileCitation.FileCitation;
+ /**
+ * Always `file_path`.
+ */
+ type: 'file_path';
- start_index: number;
+ end_index?: number;
- /**
- * The text in the message content that needs to be replaced.
- */
- text: string;
+ file_path?: FilePathDeltaAnnotation.FilePath;
- /**
- * Always `file_citation`.
- */
- type: 'file_citation';
- }
+ start_index?: number;
- export namespace FileCitation {
- export interface FileCitation {
- /**
- * The ID of the specific File the citation is from.
- */
- file_id: string;
-
- /**
- * The specific quote in the file.
- */
- quote: string;
- }
- }
+ /**
+ * The text in the message content that needs to be replaced.
+ */
+ text?: string;
+}
+export namespace FilePathDeltaAnnotation {
+ export interface FilePath {
/**
- * A URL for the file that's generated when the assistant used the
- * `code_interpreter` tool to generate a file.
+ * The ID of the file that was generated.
*/
- export interface FilePath {
- end_index: number;
+ file_id?: string;
+ }
+}
- file_path: FilePath.FilePath;
+export interface ImageFile {
+ /**
+ * The [File](https://platform.openai.com/docs/api-reference/files) ID of the image
+ * in the message content.
+ */
+ file_id: string;
+}
- start_index: number;
+/**
+ * References an image [File](https://platform.openai.com/docs/api-reference/files)
+ * in the content of a message.
+ */
+export interface ImageFileContentBlock {
+ image_file: ImageFile;
- /**
- * The text in the message content that needs to be replaced.
- */
- text: string;
+ /**
+ * Always `image_file`.
+ */
+ type: 'image_file';
+}
- /**
- * Always `file_path`.
- */
- type: 'file_path';
- }
+export interface ImageFileDelta {
+ /**
+ * The [File](https://platform.openai.com/docs/api-reference/files) ID of the image
+ * in the message content.
+ */
+ file_id?: string;
+}
- export namespace FilePath {
- export interface FilePath {
- /**
- * The ID of the file that was generated.
- */
- file_id: string;
- }
- }
- }
+/**
+ * References an image [File](https://platform.openai.com/docs/api-reference/files)
+ * in the content of a message.
+ */
+export interface ImageFileDeltaBlock {
+ /**
+ * The index of the content part in the message.
+ */
+ index: number;
+
+ /**
+ * Always `image_file`.
+ */
+ type: 'image_file';
+
+ image_file?: ImageFileDelta;
}
/**
* Represents a message within a
* [thread](https://platform.openai.com/docs/api-reference/threads).
*/
-export interface ThreadMessage {
+export interface Message {
/**
* The identifier, which can be referenced in API endpoints.
*/
@@ -215,10 +302,15 @@ export interface ThreadMessage {
*/
assistant_id: string | null;
+ /**
+ * The Unix timestamp (in seconds) for when the message was completed.
+ */
+ completed_at: number | null;
+
/**
* The content of the message in array of text and/or images.
*/
- content: Array;
+ content: Array;
/**
* The Unix timestamp (in seconds) for when the message was created.
@@ -232,6 +324,16 @@ export interface ThreadMessage {
*/
file_ids: Array;
+ /**
+ * The Unix timestamp (in seconds) for when the message was marked as incomplete.
+ */
+ incomplete_at: number | null;
+
+ /**
+ * On an incomplete message, details about why the message is incomplete.
+ */
+ incomplete_details: Message.IncompleteDetails | null;
+
/**
* Set of 16 key-value pairs that can be attached to an object. This can be useful
* for storing additional information about the object in a structured format. Keys
@@ -257,6 +359,12 @@ export interface ThreadMessage {
*/
run_id: string | null;
+ /**
+ * The status of the message, which can be either `in_progress`, `incomplete`, or
+ * `completed`.
+ */
+ status: 'in_progress' | 'incomplete' | 'completed';
+
/**
* The [thread](https://platform.openai.com/docs/api-reference/threads) ID that
* this message belongs to.
@@ -264,7 +372,31 @@ export interface ThreadMessage {
thread_id: string;
}
-export interface ThreadMessageDeleted {
+export namespace Message {
+ /**
+ * On an incomplete message, details about why the message is incomplete.
+ */
+ export interface IncompleteDetails {
+ /**
+ * The reason the message is incomplete.
+ */
+ reason: 'content_filter' | 'max_tokens' | 'run_cancelled' | 'run_expired' | 'run_failed';
+ }
+}
+
+/**
+ * References an image [File](https://platform.openai.com/docs/api-reference/files)
+ * in the content of a message.
+ */
+export type MessageContent = ImageFileContentBlock | TextContentBlock;
+
+/**
+ * References an image [File](https://platform.openai.com/docs/api-reference/files)
+ * in the content of a message.
+ */
+export type MessageContentDelta = ImageFileDeltaBlock | TextDeltaBlock;
+
+export interface MessageDeleted {
id: string;
deleted: boolean;
@@ -272,6 +404,96 @@ export interface ThreadMessageDeleted {
object: 'thread.message.deleted';
}
+/**
+ * The delta containing the fields that have changed on the Message.
+ */
+export interface MessageDelta {
+ /**
+ * The content of the message in array of text and/or images.
+ */
+ content?: Array;
+
+ /**
+ * A list of [file](https://platform.openai.com/docs/api-reference/files) IDs that
+ * the assistant should use. Useful for tools like retrieval and code_interpreter
+ * that can access files. A maximum of 10 files can be attached to a message.
+ */
+ file_ids?: Array;
+
+ /**
+ * The entity that produced the message. One of `user` or `assistant`.
+ */
+ role?: 'user' | 'assistant';
+}
+
+/**
+ * Represents a message delta i.e. any changed fields on a message during
+ * streaming.
+ */
+export interface MessageDeltaEvent {
+ /**
+ * The identifier of the message, which can be referenced in API endpoints.
+ */
+ id: string;
+
+ /**
+ * The delta containing the fields that have changed on the Message.
+ */
+ delta: MessageDelta;
+
+ /**
+ * The object type, which is always `thread.message.delta`.
+ */
+ object: 'thread.message.delta';
+}
+
+export interface Text {
+ annotations: Array;
+
+ /**
+ * The data that makes up the text.
+ */
+ value: string;
+}
+
+/**
+ * The text content that is part of a message.
+ */
+export interface TextContentBlock {
+ text: Text;
+
+ /**
+ * Always `text`.
+ */
+ type: 'text';
+}
+
+export interface TextDelta {
+ annotations?: Array;
+
+ /**
+ * The data that makes up the text.
+ */
+ value?: string;
+}
+
+/**
+ * The text content that is part of a message.
+ */
+export interface TextDeltaBlock {
+ /**
+ * The index of the content part in the message.
+ */
+ index: number;
+
+ /**
+ * Always `text`.
+ */
+ type: 'text';
+
+ text?: TextDelta;
+}
+
export interface MessageCreateParams {
/**
* The content of the message.
@@ -328,11 +550,27 @@ export interface MessageListParams extends CursorPageParams {
}
export namespace Messages {
- export import MessageContentImageFile = MessagesAPI.MessageContentImageFile;
- export import MessageContentText = MessagesAPI.MessageContentText;
- export import ThreadMessage = MessagesAPI.ThreadMessage;
- export import ThreadMessageDeleted = MessagesAPI.ThreadMessageDeleted;
- export import ThreadMessagesPage = MessagesAPI.ThreadMessagesPage;
+ export import Annotation = MessagesAPI.Annotation;
+ export import AnnotationDelta = MessagesAPI.AnnotationDelta;
+ export import FileCitationAnnotation = MessagesAPI.FileCitationAnnotation;
+ export import FileCitationDeltaAnnotation = MessagesAPI.FileCitationDeltaAnnotation;
+ export import FilePathAnnotation = MessagesAPI.FilePathAnnotation;
+ export import FilePathDeltaAnnotation = MessagesAPI.FilePathDeltaAnnotation;
+ export import ImageFile = MessagesAPI.ImageFile;
+ export import ImageFileContentBlock = MessagesAPI.ImageFileContentBlock;
+ export import ImageFileDelta = MessagesAPI.ImageFileDelta;
+ export import ImageFileDeltaBlock = MessagesAPI.ImageFileDeltaBlock;
+ export import Message = MessagesAPI.Message;
+ export import MessageContent = MessagesAPI.MessageContent;
+ export import MessageContentDelta = MessagesAPI.MessageContentDelta;
+ export import MessageDeleted = MessagesAPI.MessageDeleted;
+ export import MessageDelta = MessagesAPI.MessageDelta;
+ export import MessageDeltaEvent = MessagesAPI.MessageDeltaEvent;
+ export import Text = MessagesAPI.Text;
+ export import TextContentBlock = MessagesAPI.TextContentBlock;
+ export import TextDelta = MessagesAPI.TextDelta;
+ export import TextDeltaBlock = MessagesAPI.TextDeltaBlock;
+ export import MessagesPage = MessagesAPI.MessagesPage;
export import MessageCreateParams = MessagesAPI.MessageCreateParams;
export import MessageUpdateParams = MessagesAPI.MessageUpdateParams;
export import MessageListParams = MessagesAPI.MessageListParams;
diff --git a/src/resources/beta/threads/runs/index.ts b/src/resources/beta/threads/runs/index.ts
index b11736c5c..7fa34637a 100644
--- a/src/resources/beta/threads/runs/index.ts
+++ b/src/resources/beta/threads/runs/index.ts
@@ -1,11 +1,22 @@
// File generated from our OpenAPI spec by Stainless.
export {
- CodeToolCall,
+ CodeInterpreterLogs,
+ CodeInterpreterOutputImage,
+ CodeInterpreterToolCall,
+ CodeInterpreterToolCallDelta,
FunctionToolCall,
+ FunctionToolCallDelta,
MessageCreationStepDetails,
RetrievalToolCall,
+ RetrievalToolCallDelta,
RunStep,
+ RunStepDelta,
+ RunStepDeltaEvent,
+ RunStepDeltaMessageDelta,
+ ToolCall,
+ ToolCallDelta,
+ ToolCallDeltaObject,
ToolCallsStepDetails,
StepListParams,
RunStepsPage,
@@ -16,9 +27,15 @@ export {
Run,
RunStatus,
RunCreateParams,
+ RunCreateParamsNonStreaming,
+ RunCreateParamsStreaming,
RunUpdateParams,
RunListParams,
+ RunCreateAndStreamParams,
RunSubmitToolOutputsParams,
+ RunSubmitToolOutputsParamsNonStreaming,
+ RunSubmitToolOutputsParamsStreaming,
+ RunSubmitToolOutputsStreamParams,
RunsPage,
Runs,
} from './runs';
diff --git a/src/resources/beta/threads/runs/runs.ts b/src/resources/beta/threads/runs/runs.ts
index 9a0bc00dd..8fe09ecc6 100644
--- a/src/resources/beta/threads/runs/runs.ts
+++ b/src/resources/beta/threads/runs/runs.ts
@@ -1,12 +1,16 @@
// File generated from our OpenAPI spec by Stainless.
import * as Core from 'openai/core';
+import { APIPromise } from 'openai/core';
import { APIResource } from 'openai/resource';
import { isRequestOptions } from 'openai/core';
+import { AssistantStream, RunCreateParamsBaseStream } from 'openai/lib/AssistantStream';
+import { RunSubmitToolOutputsParamsStream } from 'openai/lib/AssistantStream';
import * as RunsAPI from 'openai/resources/beta/threads/runs/runs';
-import * as Shared from 'openai/resources/shared';
+import * as AssistantsAPI from 'openai/resources/beta/assistants/assistants';
import * as StepsAPI from 'openai/resources/beta/threads/runs/steps';
import { CursorPage, type CursorPageParams } from 'openai/pagination';
+import { Stream } from 'openai/streaming';
export class Runs extends APIResource {
steps: StepsAPI.Steps = new StepsAPI.Steps(this._client);
@@ -14,12 +18,28 @@ export class Runs extends APIResource {
/**
* Create a run.
*/
- create(threadId: string, body: RunCreateParams, options?: Core.RequestOptions): Core.APIPromise {
+ create(threadId: string, body: RunCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise;
+ create(
+ threadId: string,
+ body: RunCreateParamsStreaming,
+ options?: Core.RequestOptions,
+ ): APIPromise>;
+ create(
+ threadId: string,
+ body: RunCreateParamsBase,
+ options?: Core.RequestOptions,
+ ): APIPromise | Run>;
+ create(
+ threadId: string,
+ body: RunCreateParams,
+ options?: Core.RequestOptions,
+ ): APIPromise | APIPromise> {
return this._client.post(`/threads/${threadId}/runs`, {
body,
...options,
headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
- });
+ stream: body.stream ?? false,
+ }) as APIPromise | APIPromise>;
}
/**
@@ -82,23 +102,72 @@ export class Runs extends APIResource {
});
}
+ /**
+ * Create a Run stream
+ */
+ createAndStream(
+ threadId: string,
+ body: RunCreateParamsBaseStream,
+ options?: Core.RequestOptions,
+ ): AssistantStream {
+ return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options);
+ }
+
/**
* When a run has the `status: "requires_action"` and `required_action.type` is
* `submit_tool_outputs`, this endpoint can be used to submit the outputs from the
* tool calls once they're all completed. All outputs must be submitted in a single
* request.
*/
+ submitToolOutputs(
+ threadId: string,
+ runId: string,
+ body: RunSubmitToolOutputsParamsNonStreaming,
+ options?: Core.RequestOptions,
+ ): APIPromise;
+ submitToolOutputs(
+ threadId: string,
+ runId: string,
+ body: RunSubmitToolOutputsParamsStreaming,
+ options?: Core.RequestOptions,
+ ): APIPromise>;
+ submitToolOutputs(
+ threadId: string,
+ runId: string,
+ body: RunSubmitToolOutputsParamsBase,
+ options?: Core.RequestOptions,
+ ): APIPromise | Run>;
submitToolOutputs(
threadId: string,
runId: string,
body: RunSubmitToolOutputsParams,
options?: Core.RequestOptions,
- ): Core.APIPromise {
+ ): APIPromise | APIPromise> {
return this._client.post(`/threads/${threadId}/runs/${runId}/submit_tool_outputs`, {
body,
...options,
headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
- });
+ stream: body.stream ?? false,
+ }) as APIPromise | APIPromise>;
+ }
+
+ /**
+ * Submit the tool outputs from a previous run and stream the run to a terminal
+ * state.
+ */
+ submitToolOutputsStream(
+ threadId: string,
+ runId: string,
+ body: RunSubmitToolOutputsParamsStream,
+ options?: Core.RequestOptions,
+ ): AssistantStream {
+ return AssistantStream.createToolAssistantStream(
+ threadId,
+ runId,
+ this._client.beta.threads.runs,
+ body,
+ options,
+ );
}
}
@@ -180,7 +249,7 @@ export interface Run {
/**
* The Unix timestamp (in seconds) for when the run will expire.
*/
- expires_at: number;
+ expires_at: number | null;
/**
* The Unix timestamp (in seconds) for when the run failed.
@@ -255,7 +324,7 @@ export interface Run {
* [assistant](https://platform.openai.com/docs/api-reference/assistants) used for
* this run.
*/
- tools: Array;
+ tools: Array;
/**
* Usage statistics related to the run. This value will be `null` if the run is not
@@ -308,29 +377,6 @@ export namespace Run {
}
}
- export interface AssistantToolsCode {
- /**
- * The type of tool being defined: `code_interpreter`
- */
- type: 'code_interpreter';
- }
-
- export interface AssistantToolsRetrieval {
- /**
- * The type of tool being defined: `retrieval`
- */
- type: 'retrieval';
- }
-
- export interface AssistantToolsFunction {
- function: Shared.FunctionDefinition;
-
- /**
- * The type of tool being defined: `function`
- */
- type: 'function';
- }
-
/**
* Usage statistics related to the run. This value will be `null` if the run is not
* in a terminal state (i.e. `in_progress`, `queued`, etc.).
@@ -368,7 +414,9 @@ export type RunStatus =
| 'completed'
| 'expired';
-export interface RunCreateParams {
+export type RunCreateParams = RunCreateParamsNonStreaming | RunCreateParamsStreaming;
+
+export interface RunCreateParamsBase {
/**
* The ID of the
* [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to
@@ -406,40 +454,41 @@ export interface RunCreateParams {
*/
model?: string | null;
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: boolean | null;
+
/**
* Override the tools the assistant can use for this run. This is useful for
* modifying the behavior on a per-run basis.
*/
- tools?: Array<
- | RunCreateParams.AssistantToolsCode
- | RunCreateParams.AssistantToolsRetrieval
- | RunCreateParams.AssistantToolsFunction
- > | null;
+ tools?: Array | null;
}
export namespace RunCreateParams {
- export interface AssistantToolsCode {
- /**
- * The type of tool being defined: `code_interpreter`
- */
- type: 'code_interpreter';
- }
-
- export interface AssistantToolsRetrieval {
- /**
- * The type of tool being defined: `retrieval`
- */
- type: 'retrieval';
- }
+ export type RunCreateParamsNonStreaming = RunsAPI.RunCreateParamsNonStreaming;
+ export type RunCreateParamsStreaming = RunsAPI.RunCreateParamsStreaming;
+}
- export interface AssistantToolsFunction {
- function: Shared.FunctionDefinition;
+export interface RunCreateParamsNonStreaming extends RunCreateParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: false | null;
+}
- /**
- * The type of tool being defined: `function`
- */
- type: 'function';
- }
+export interface RunCreateParamsStreaming extends RunCreateParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream: true;
}
export interface RunUpdateParams {
@@ -468,11 +517,67 @@ export interface RunListParams extends CursorPageParams {
order?: 'asc' | 'desc';
}
-export interface RunSubmitToolOutputsParams {
+export interface RunCreateAndStreamParams {
+ /**
+ * The ID of the
+ * [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to
+ * execute this run.
+ */
+ assistant_id: string;
+
+ /**
+ * Appends additional instructions at the end of the instructions for the run. This
+ * is useful for modifying the behavior on a per-run basis without overriding other
+ * instructions.
+ */
+ additional_instructions?: string | null;
+
+ /**
+ * Overrides the
+ * [instructions](https://platform.openai.com/docs/api-reference/assistants/createAssistant)
+ * of the assistant. This is useful for modifying the behavior on a per-run basis.
+ */
+ instructions?: string | null;
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful
+ * for storing additional information about the object in a structured format. Keys
+ * can be a maximum of 64 characters long and values can be a maxium of 512
+ * characters long.
+ */
+ metadata?: unknown | null;
+
+ /**
+ * The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to
+ * be used to execute this run. If a value is provided here, it will override the
+ * model associated with the assistant. If not, the model associated with the
+ * assistant will be used.
+ */
+ model?: string | null;
+
+ /**
+ * Override the tools the assistant can use for this run. This is useful for
+ * modifying the behavior on a per-run basis.
+ */
+ tools?: Array | null;
+}
+
+export type RunSubmitToolOutputsParams =
+ | RunSubmitToolOutputsParamsNonStreaming
+ | RunSubmitToolOutputsParamsStreaming;
+
+export interface RunSubmitToolOutputsParamsBase {
/**
* A list of tools for which the outputs are being submitted.
*/
tool_outputs: Array;
+
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: boolean | null;
}
export namespace RunSubmitToolOutputsParams {
@@ -488,6 +593,49 @@ export namespace RunSubmitToolOutputsParams {
*/
tool_call_id?: string;
}
+
+ export type RunSubmitToolOutputsParamsNonStreaming = RunsAPI.RunSubmitToolOutputsParamsNonStreaming;
+ export type RunSubmitToolOutputsParamsStreaming = RunsAPI.RunSubmitToolOutputsParamsStreaming;
+}
+
+export interface RunSubmitToolOutputsParamsNonStreaming extends RunSubmitToolOutputsParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: false | null;
+}
+
+export interface RunSubmitToolOutputsParamsStreaming extends RunSubmitToolOutputsParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream: true;
+}
+
+export interface RunSubmitToolOutputsStreamParams {
+ /**
+ * A list of tools for which the outputs are being submitted.
+ */
+ tool_outputs: Array;
+}
+
+export namespace RunSubmitToolOutputsStreamParams {
+ export interface ToolOutput {
+ /**
+ * The output of the tool call to be submitted to continue the run.
+ */
+ output?: string;
+
+ /**
+ * The ID of the tool call in the `required_action` object within the run object
+ * the output is being submitted for.
+ */
+ tool_call_id?: string;
+ }
}
export namespace Runs {
@@ -496,15 +644,32 @@ export namespace Runs {
export import RunStatus = RunsAPI.RunStatus;
export import RunsPage = RunsAPI.RunsPage;
export import RunCreateParams = RunsAPI.RunCreateParams;
+ export import RunCreateParamsNonStreaming = RunsAPI.RunCreateParamsNonStreaming;
+ export import RunCreateParamsStreaming = RunsAPI.RunCreateParamsStreaming;
export import RunUpdateParams = RunsAPI.RunUpdateParams;
export import RunListParams = RunsAPI.RunListParams;
+ export import RunCreateAndStreamParams = RunsAPI.RunCreateAndStreamParams;
export import RunSubmitToolOutputsParams = RunsAPI.RunSubmitToolOutputsParams;
+ export import RunSubmitToolOutputsParamsNonStreaming = RunsAPI.RunSubmitToolOutputsParamsNonStreaming;
+ export import RunSubmitToolOutputsParamsStreaming = RunsAPI.RunSubmitToolOutputsParamsStreaming;
+ export import RunSubmitToolOutputsStreamParams = RunsAPI.RunSubmitToolOutputsStreamParams;
export import Steps = StepsAPI.Steps;
- export import CodeToolCall = StepsAPI.CodeToolCall;
+ export import CodeInterpreterLogs = StepsAPI.CodeInterpreterLogs;
+ export import CodeInterpreterOutputImage = StepsAPI.CodeInterpreterOutputImage;
+ export import CodeInterpreterToolCall = StepsAPI.CodeInterpreterToolCall;
+ export import CodeInterpreterToolCallDelta = StepsAPI.CodeInterpreterToolCallDelta;
export import FunctionToolCall = StepsAPI.FunctionToolCall;
+ export import FunctionToolCallDelta = StepsAPI.FunctionToolCallDelta;
export import MessageCreationStepDetails = StepsAPI.MessageCreationStepDetails;
export import RetrievalToolCall = StepsAPI.RetrievalToolCall;
+ export import RetrievalToolCallDelta = StepsAPI.RetrievalToolCallDelta;
export import RunStep = StepsAPI.RunStep;
+ export import RunStepDelta = StepsAPI.RunStepDelta;
+ export import RunStepDeltaEvent = StepsAPI.RunStepDeltaEvent;
+ export import RunStepDeltaMessageDelta = StepsAPI.RunStepDeltaMessageDelta;
+ export import ToolCall = StepsAPI.ToolCall;
+ export import ToolCallDelta = StepsAPI.ToolCallDelta;
+ export import ToolCallDeltaObject = StepsAPI.ToolCallDeltaObject;
export import ToolCallsStepDetails = StepsAPI.ToolCallsStepDetails;
export import RunStepsPage = StepsAPI.RunStepsPage;
export import StepListParams = StepsAPI.StepListParams;
diff --git a/src/resources/beta/threads/runs/steps.ts b/src/resources/beta/threads/runs/steps.ts
index c574c94d1..4218e9769 100644
--- a/src/resources/beta/threads/runs/steps.ts
+++ b/src/resources/beta/threads/runs/steps.ts
@@ -55,10 +55,54 @@ export class Steps extends APIResource {
export class RunStepsPage extends CursorPage {}
+/**
+ * Text output from the Code Interpreter tool call as part of a run step.
+ */
+export interface CodeInterpreterLogs {
+ /**
+ * The index of the output in the outputs array.
+ */
+ index: number;
+
+ /**
+ * Always `logs`.
+ */
+ type: 'logs';
+
+ /**
+ * The text output from the Code Interpreter tool call.
+ */
+ logs?: string;
+}
+
+export interface CodeInterpreterOutputImage {
+ /**
+ * The index of the output in the outputs array.
+ */
+ index: number;
+
+ /**
+ * Always `image`.
+ */
+ type: 'image';
+
+ image?: CodeInterpreterOutputImage.Image;
+}
+
+export namespace CodeInterpreterOutputImage {
+ export interface Image {
+ /**
+ * The [file](https://platform.openai.com/docs/api-reference/files) ID of the
+ * image.
+ */
+ file_id?: string;
+ }
+}
+
/**
* Details of the Code Interpreter tool call the run step was involved in.
*/
-export interface CodeToolCall {
+export interface CodeInterpreterToolCall {
/**
* The ID of the tool call.
*/
@@ -67,7 +111,7 @@ export interface CodeToolCall {
/**
* The Code Interpreter tool call definition.
*/
- code_interpreter: CodeToolCall.CodeInterpreter;
+ code_interpreter: CodeInterpreterToolCall.CodeInterpreter;
/**
* The type of tool call. This is always going to be `code_interpreter` for this
@@ -76,7 +120,7 @@ export interface CodeToolCall {
type: 'code_interpreter';
}
-export namespace CodeToolCall {
+export namespace CodeInterpreterToolCall {
/**
* The Code Interpreter tool call definition.
*/
@@ -131,6 +175,51 @@ export namespace CodeToolCall {
}
}
+/**
+ * Details of the Code Interpreter tool call the run step was involved in.
+ */
+export interface CodeInterpreterToolCallDelta {
+ /**
+ * The index of the tool call in the tool calls array.
+ */
+ index: number;
+
+ /**
+ * The type of tool call. This is always going to be `code_interpreter` for this
+ * type of tool call.
+ */
+ type: 'code_interpreter';
+
+ /**
+ * The ID of the tool call.
+ */
+ id?: string;
+
+ /**
+ * The Code Interpreter tool call definition.
+ */
+ code_interpreter?: CodeInterpreterToolCallDelta.CodeInterpreter;
+}
+
+export namespace CodeInterpreterToolCallDelta {
+ /**
+ * The Code Interpreter tool call definition.
+ */
+ export interface CodeInterpreter {
+ /**
+ * The input to the Code Interpreter tool call.
+ */
+ input?: string;
+
+ /**
+ * The outputs from the Code Interpreter tool call. Code Interpreter can output one
+ * or more items, including text (`logs`) or images (`image`). Each of these are
+ * represented by a different object type.
+ */
+ outputs?: Array;
+ }
+}
+
export interface FunctionToolCall {
/**
* The ID of the tool call object.
@@ -173,6 +262,53 @@ export namespace FunctionToolCall {
}
}
+export interface FunctionToolCallDelta {
+ /**
+ * The index of the tool call in the tool calls array.
+ */
+ index: number;
+
+ /**
+ * The type of tool call. This is always going to be `function` for this type of
+ * tool call.
+ */
+ type: 'function';
+
+ /**
+ * The ID of the tool call object.
+ */
+ id?: string;
+
+ /**
+ * The definition of the function that was called.
+ */
+ function?: FunctionToolCallDelta.Function;
+}
+
+export namespace FunctionToolCallDelta {
+ /**
+ * The definition of the function that was called.
+ */
+ export interface Function {
+ /**
+ * The arguments passed to the function.
+ */
+ arguments?: string;
+
+ /**
+ * The name of the function.
+ */
+ name?: string;
+
+ /**
+ * The output of the function. This will be `null` if the outputs have not been
+ * [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs)
+ * yet.
+ */
+ output?: string | null;
+ }
+}
+
/**
* Details of the message creation by the run step.
*/
@@ -212,6 +348,29 @@ export interface RetrievalToolCall {
type: 'retrieval';
}
+export interface RetrievalToolCallDelta {
+ /**
+ * The index of the tool call in the tool calls array.
+ */
+ index: number;
+
+ /**
+ * The type of tool call. This is always going to be `retrieval` for this type of
+ * tool call.
+ */
+ type: 'retrieval';
+
+ /**
+ * The ID of the tool call object.
+ */
+ id?: string;
+
+ /**
+ * For now, this is always going to be an empty object.
+ */
+ retrieval?: unknown;
+}
+
/**
* Represents a step in execution of a run.
*/
@@ -347,6 +506,85 @@ export namespace RunStep {
}
}
+/**
+ * The delta containing the fields that have changed on the run step.
+ */
+export interface RunStepDelta {
+ /**
+ * The details of the run step.
+ */
+ step_details?: RunStepDeltaMessageDelta | ToolCallDeltaObject;
+}
+
+/**
+ * Represents a run step delta i.e. any changed fields on a run step during
+ * streaming.
+ */
+export interface RunStepDeltaEvent {
+ /**
+ * The identifier of the run step, which can be referenced in API endpoints.
+ */
+ id: string;
+
+ /**
+ * The delta containing the fields that have changed on the run step.
+ */
+ delta: RunStepDelta;
+
+ /**
+ * The object type, which is always `thread.run.step.delta`.
+ */
+ object: 'thread.run.step.delta';
+}
+
+/**
+ * Details of the message creation by the run step.
+ */
+export interface RunStepDeltaMessageDelta {
+ /**
+ * Always `message_creation`.
+ */
+ type: 'message_creation';
+
+ message_creation?: RunStepDeltaMessageDelta.MessageCreation;
+}
+
+export namespace RunStepDeltaMessageDelta {
+ export interface MessageCreation {
+ /**
+ * The ID of the message that was created by this run step.
+ */
+ message_id?: string;
+ }
+}
+
+/**
+ * Details of the Code Interpreter tool call the run step was involved in.
+ */
+export type ToolCall = CodeInterpreterToolCall | RetrievalToolCall | FunctionToolCall;
+
+/**
+ * Details of the Code Interpreter tool call the run step was involved in.
+ */
+export type ToolCallDelta = CodeInterpreterToolCallDelta | RetrievalToolCallDelta | FunctionToolCallDelta;
+
+/**
+ * Details of the tool call.
+ */
+export interface ToolCallDeltaObject {
+ /**
+ * Always `tool_calls`.
+ */
+ type: 'tool_calls';
+
+ /**
+ * An array of tool calls the run step was involved in. These can be associated
+ * with one of three types of tools: `code_interpreter`, `retrieval`, or
+ * `function`.
+ */
+ tool_calls?: Array;
+}
+
/**
* Details of the tool call.
*/
@@ -356,7 +594,7 @@ export interface ToolCallsStepDetails {
* with one of three types of tools: `code_interpreter`, `retrieval`, or
* `function`.
*/
- tool_calls: Array;
+ tool_calls: Array;
/**
* Always `tool_calls`.
@@ -381,11 +619,22 @@ export interface StepListParams extends CursorPageParams {
}
export namespace Steps {
- export import CodeToolCall = StepsAPI.CodeToolCall;
+ export import CodeInterpreterLogs = StepsAPI.CodeInterpreterLogs;
+ export import CodeInterpreterOutputImage = StepsAPI.CodeInterpreterOutputImage;
+ export import CodeInterpreterToolCall = StepsAPI.CodeInterpreterToolCall;
+ export import CodeInterpreterToolCallDelta = StepsAPI.CodeInterpreterToolCallDelta;
export import FunctionToolCall = StepsAPI.FunctionToolCall;
+ export import FunctionToolCallDelta = StepsAPI.FunctionToolCallDelta;
export import MessageCreationStepDetails = StepsAPI.MessageCreationStepDetails;
export import RetrievalToolCall = StepsAPI.RetrievalToolCall;
+ export import RetrievalToolCallDelta = StepsAPI.RetrievalToolCallDelta;
export import RunStep = StepsAPI.RunStep;
+ export import RunStepDelta = StepsAPI.RunStepDelta;
+ export import RunStepDeltaEvent = StepsAPI.RunStepDeltaEvent;
+ export import RunStepDeltaMessageDelta = StepsAPI.RunStepDeltaMessageDelta;
+ export import ToolCall = StepsAPI.ToolCall;
+ export import ToolCallDelta = StepsAPI.ToolCallDelta;
+ export import ToolCallDeltaObject = StepsAPI.ToolCallDeltaObject;
export import ToolCallsStepDetails = StepsAPI.ToolCallsStepDetails;
export import RunStepsPage = StepsAPI.RunStepsPage;
export import StepListParams = StepsAPI.StepListParams;
diff --git a/src/resources/beta/threads/threads.ts b/src/resources/beta/threads/threads.ts
index 5aa1f8c25..cbde41f89 100644
--- a/src/resources/beta/threads/threads.ts
+++ b/src/resources/beta/threads/threads.ts
@@ -1,12 +1,15 @@
// File generated from our OpenAPI spec by Stainless.
import * as Core from 'openai/core';
+import { APIPromise } from 'openai/core';
import { APIResource } from 'openai/resource';
import { isRequestOptions } from 'openai/core';
+import { AssistantStream, ThreadCreateAndRunParamsBaseStream } from 'openai/lib/AssistantStream';
import * as ThreadsAPI from 'openai/resources/beta/threads/threads';
-import * as Shared from 'openai/resources/shared';
+import * as AssistantsAPI from 'openai/resources/beta/assistants/assistants';
import * as MessagesAPI from 'openai/resources/beta/threads/messages/messages';
import * as RunsAPI from 'openai/resources/beta/threads/runs/runs';
+import { Stream } from 'openai/streaming';
export class Threads extends APIResource {
runs: RunsAPI.Runs = new RunsAPI.Runs(this._client);
@@ -65,12 +68,38 @@ export class Threads extends APIResource {
/**
* Create a thread and run it in one request.
*/
- createAndRun(body: ThreadCreateAndRunParams, options?: Core.RequestOptions): Core.APIPromise {
+ createAndRun(
+ body: ThreadCreateAndRunParamsNonStreaming,
+ options?: Core.RequestOptions,
+ ): APIPromise;
+ createAndRun(
+ body: ThreadCreateAndRunParamsStreaming,
+ options?: Core.RequestOptions,
+ ): APIPromise>;
+ createAndRun(
+ body: ThreadCreateAndRunParamsBase,
+ options?: Core.RequestOptions,
+ ): APIPromise | RunsAPI.Run>;
+ createAndRun(
+ body: ThreadCreateAndRunParams,
+ options?: Core.RequestOptions,
+ ): APIPromise | APIPromise> {
return this._client.post('/threads/runs', {
body,
...options,
headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
- });
+ stream: body.stream ?? false,
+ }) as APIPromise | APIPromise>;
+ }
+
+ /**
+ * Create a thread and stream the run back
+ */
+ createAndRunStream(
+ body: ThreadCreateAndRunParamsBaseStream,
+ options?: Core.RequestOptions,
+ ): AssistantStream {
+ return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options);
}
}
@@ -168,7 +197,11 @@ export interface ThreadUpdateParams {
metadata?: unknown | null;
}
-export interface ThreadCreateAndRunParams {
+export type ThreadCreateAndRunParams =
+ | ThreadCreateAndRunParamsNonStreaming
+ | ThreadCreateAndRunParamsStreaming;
+
+export interface ThreadCreateAndRunParamsBase {
/**
* The ID of the
* [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to
@@ -198,6 +231,13 @@ export interface ThreadCreateAndRunParams {
*/
model?: string | null;
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: boolean | null;
+
/**
* If no thread is provided, an empty thread will be created.
*/
@@ -208,9 +248,7 @@ export interface ThreadCreateAndRunParams {
* modifying the behavior on a per-run basis.
*/
tools?: Array<
- | ThreadCreateAndRunParams.AssistantToolsCode
- | ThreadCreateAndRunParams.AssistantToolsRetrieval
- | ThreadCreateAndRunParams.AssistantToolsFunction
+ AssistantsAPI.CodeInterpreterTool | AssistantsAPI.RetrievalTool | AssistantsAPI.FunctionTool
> | null;
}
@@ -265,27 +303,121 @@ export namespace ThreadCreateAndRunParams {
}
}
- export interface AssistantToolsCode {
+ export type ThreadCreateAndRunParamsNonStreaming = ThreadsAPI.ThreadCreateAndRunParamsNonStreaming;
+ export type ThreadCreateAndRunParamsStreaming = ThreadsAPI.ThreadCreateAndRunParamsStreaming;
+}
+
+export interface ThreadCreateAndRunParamsNonStreaming extends ThreadCreateAndRunParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream?: false | null;
+}
+
+export interface ThreadCreateAndRunParamsStreaming extends ThreadCreateAndRunParamsBase {
+ /**
+ * If `true`, returns a stream of events that happen during the Run as server-sent
+ * events, terminating when the Run enters a terminal state with a `data: [DONE]`
+ * message.
+ */
+ stream: true;
+}
+
+export interface ThreadCreateAndRunStreamParams {
+ /**
+ * The ID of the
+ * [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to
+ * execute this run.
+ */
+ assistant_id: string;
+
+ /**
+ * Override the default system message of the assistant. This is useful for
+ * modifying the behavior on a per-run basis.
+ */
+ instructions?: string | null;
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful
+ * for storing additional information about the object in a structured format. Keys
+ * can be a maximum of 64 characters long and values can be a maxium of 512
+ * characters long.
+ */
+ metadata?: unknown | null;
+
+ /**
+ * The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to
+ * be used to execute this run. If a value is provided here, it will override the
+ * model associated with the assistant. If not, the model associated with the
+ * assistant will be used.
+ */
+ model?: string | null;
+
+ /**
+ * If no thread is provided, an empty thread will be created.
+ */
+ thread?: ThreadCreateAndRunStreamParams.Thread;
+
+ /**
+ * Override the tools the assistant can use for this run. This is useful for
+ * modifying the behavior on a per-run basis.
+ */
+ tools?: Array<
+ AssistantsAPI.CodeInterpreterTool | AssistantsAPI.RetrievalTool | AssistantsAPI.FunctionTool
+ > | null;
+}
+
+export namespace ThreadCreateAndRunStreamParams {
+ /**
+ * If no thread is provided, an empty thread will be created.
+ */
+ export interface Thread {
/**
- * The type of tool being defined: `code_interpreter`
+ * A list of [messages](https://platform.openai.com/docs/api-reference/messages) to
+ * start the thread with.
*/
- type: 'code_interpreter';
- }
+ messages?: Array;
- export interface AssistantToolsRetrieval {
/**
- * The type of tool being defined: `retrieval`
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful
+ * for storing additional information about the object in a structured format. Keys
+ * can be a maximum of 64 characters long and values can be a maxium of 512
+ * characters long.
*/
- type: 'retrieval';
+ metadata?: unknown | null;
}
- export interface AssistantToolsFunction {
- function: Shared.FunctionDefinition;
+ export namespace Thread {
+ export interface Message {
+ /**
+ * The content of the message.
+ */
+ content: string;
+
+ /**
+ * The role of the entity that is creating the message. Currently only `user` is
+ * supported.
+ */
+ role: 'user';
- /**
- * The type of tool being defined: `function`
- */
- type: 'function';
+ /**
+ * A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that
+ * the message should use. There can be a maximum of 10 files attached to a
+ * message. Useful for tools like `retrieval` and `code_interpreter` that can
+ * access and use files.
+ */
+ file_ids?: Array;
+
+ /**
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful
+ * for storing additional information about the object in a structured format. Keys
+ * can be a maximum of 64 characters long and values can be a maxium of 512
+ * characters long.
+ */
+ metadata?: unknown | null;
+ }
}
}
@@ -295,21 +427,46 @@ export namespace Threads {
export import ThreadCreateParams = ThreadsAPI.ThreadCreateParams;
export import ThreadUpdateParams = ThreadsAPI.ThreadUpdateParams;
export import ThreadCreateAndRunParams = ThreadsAPI.ThreadCreateAndRunParams;
+ export import ThreadCreateAndRunParamsNonStreaming = ThreadsAPI.ThreadCreateAndRunParamsNonStreaming;
+ export import ThreadCreateAndRunParamsStreaming = ThreadsAPI.ThreadCreateAndRunParamsStreaming;
+ export import ThreadCreateAndRunStreamParams = ThreadsAPI.ThreadCreateAndRunStreamParams;
export import Runs = RunsAPI.Runs;
export import RequiredActionFunctionToolCall = RunsAPI.RequiredActionFunctionToolCall;
export import Run = RunsAPI.Run;
export import RunStatus = RunsAPI.RunStatus;
export import RunsPage = RunsAPI.RunsPage;
export import RunCreateParams = RunsAPI.RunCreateParams;
+ export import RunCreateParamsNonStreaming = RunsAPI.RunCreateParamsNonStreaming;
+ export import RunCreateParamsStreaming = RunsAPI.RunCreateParamsStreaming;
export import RunUpdateParams = RunsAPI.RunUpdateParams;
export import RunListParams = RunsAPI.RunListParams;
+ export import RunCreateAndStreamParams = RunsAPI.RunCreateAndStreamParams;
export import RunSubmitToolOutputsParams = RunsAPI.RunSubmitToolOutputsParams;
+ export import RunSubmitToolOutputsParamsNonStreaming = RunsAPI.RunSubmitToolOutputsParamsNonStreaming;
+ export import RunSubmitToolOutputsParamsStreaming = RunsAPI.RunSubmitToolOutputsParamsStreaming;
+ export import RunSubmitToolOutputsStreamParams = RunsAPI.RunSubmitToolOutputsStreamParams;
export import Messages = MessagesAPI.Messages;
- export import MessageContentImageFile = MessagesAPI.MessageContentImageFile;
- export import MessageContentText = MessagesAPI.MessageContentText;
- export import ThreadMessage = MessagesAPI.ThreadMessage;
- export import ThreadMessageDeleted = MessagesAPI.ThreadMessageDeleted;
- export import ThreadMessagesPage = MessagesAPI.ThreadMessagesPage;
+ export import Annotation = MessagesAPI.Annotation;
+ export import AnnotationDelta = MessagesAPI.AnnotationDelta;
+ export import FileCitationAnnotation = MessagesAPI.FileCitationAnnotation;
+ export import FileCitationDeltaAnnotation = MessagesAPI.FileCitationDeltaAnnotation;
+ export import FilePathAnnotation = MessagesAPI.FilePathAnnotation;
+ export import FilePathDeltaAnnotation = MessagesAPI.FilePathDeltaAnnotation;
+ export import ImageFile = MessagesAPI.ImageFile;
+ export import ImageFileContentBlock = MessagesAPI.ImageFileContentBlock;
+ export import ImageFileDelta = MessagesAPI.ImageFileDelta;
+ export import ImageFileDeltaBlock = MessagesAPI.ImageFileDeltaBlock;
+ export import Message = MessagesAPI.Message;
+ export import MessageContent = MessagesAPI.MessageContent;
+ export import MessageContentDelta = MessagesAPI.MessageContentDelta;
+ export import MessageDeleted = MessagesAPI.MessageDeleted;
+ export import MessageDelta = MessagesAPI.MessageDelta;
+ export import MessageDeltaEvent = MessagesAPI.MessageDeltaEvent;
+ export import Text = MessagesAPI.Text;
+ export import TextContentBlock = MessagesAPI.TextContentBlock;
+ export import TextDelta = MessagesAPI.TextDelta;
+ export import TextDeltaBlock = MessagesAPI.TextDeltaBlock;
+ export import MessagesPage = MessagesAPI.MessagesPage;
export import MessageCreateParams = MessagesAPI.MessageCreateParams;
export import MessageUpdateParams = MessagesAPI.MessageUpdateParams;
export import MessageListParams = MessagesAPI.MessageListParams;
diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts
index c2d6da0be..41216a8e3 100644
--- a/src/resources/chat/completions.ts
+++ b/src/resources/chat/completions.ts
@@ -829,7 +829,7 @@ export interface ChatCompletionCreateParamsBase {
/**
* A list of tools the model may call. Currently, only functions are supported as a
* tool. Use this to provide a list of functions the model may generate JSON inputs
- * for.
+ * for. A max of 128 functions are supported.
*/
tools?: Array;
diff --git a/src/resources/completions.ts b/src/resources/completions.ts
index f3e262f5f..83ecb3e99 100644
--- a/src/resources/completions.ts
+++ b/src/resources/completions.ts
@@ -253,6 +253,8 @@ export interface CompletionCreateParamsBase {
/**
* The suffix that comes after a completion of inserted text.
+ *
+ * This parameter is only supported for `gpt-3.5-turbo-instruct`.
*/
suffix?: string | null;
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 05ab66383..a6b2c11bd 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -1,5 +1,15 @@
// File generated from our OpenAPI spec by Stainless.
+export interface ErrorObject {
+ code: string | null;
+
+ message: string;
+
+ param: string | null;
+
+ type: string;
+}
+
export interface FunctionDefinition {
/**
* The name of the function to be called. Must be a-z, A-Z, 0-9, or contain
diff --git a/src/streaming.ts b/src/streaming.ts
index f90c5d89a..c452737aa 100644
--- a/src/streaming.ts
+++ b/src/streaming.ts
@@ -78,6 +78,20 @@ export class Stream- implements AsyncIterable
- {
}
yield data;
+ } else {
+ let data;
+ try {
+ data = JSON.parse(sse.data);
+ } catch (e) {
+ console.error(`Could not parse message into JSON:`, sse.data);
+ console.error(`From chunk:`, sse.raw);
+ throw e;
+ }
+ // TODO: Is this where the error should be thrown?
+ if (sse.event == 'error') {
+ throw new APIError(undefined, data.error, data.message, undefined);
+ }
+ yield { event: sse.event, data: data } as any;
}
}
done = true;
diff --git a/tests/api-resources/beta/threads/runs/runs.test.ts b/tests/api-resources/beta/threads/runs/runs.test.ts
index 5a720afce..45f17040a 100644
--- a/tests/api-resources/beta/threads/runs/runs.test.ts
+++ b/tests/api-resources/beta/threads/runs/runs.test.ts
@@ -27,6 +27,7 @@ describe('resource runs', () => {
instructions: 'string',
metadata: {},
model: 'string',
+ stream: false,
tools: [{ type: 'code_interpreter' }, { type: 'code_interpreter' }, { type: 'code_interpreter' }],
});
});
@@ -127,6 +128,7 @@ describe('resource runs', () => {
{ tool_call_id: 'string', output: 'string' },
{ tool_call_id: 'string', output: 'string' },
],
+ stream: false,
});
});
});
diff --git a/tests/api-resources/beta/threads/threads.test.ts b/tests/api-resources/beta/threads/threads.test.ts
index fc9fef723..9243dc11c 100644
--- a/tests/api-resources/beta/threads/threads.test.ts
+++ b/tests/api-resources/beta/threads/threads.test.ts
@@ -108,6 +108,7 @@ describe('resource threads', () => {
instructions: 'string',
metadata: {},
model: 'string',
+ stream: false,
thread: {
messages: [
{ role: 'user', content: 'x', file_ids: ['string'], metadata: {} },
diff --git a/tests/streaming/assistants/assistant.test.ts b/tests/streaming/assistants/assistant.test.ts
new file mode 100644
index 000000000..e8db3d585
--- /dev/null
+++ b/tests/streaming/assistants/assistant.test.ts
@@ -0,0 +1,32 @@
+import OpenAI from 'openai';
+import { AssistantStream } from 'openai/lib/AssistantStream';
+
+const openai = new OpenAI({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('assistant tests', () => {
+ test('delta accumulation', () => {
+ expect(AssistantStream.accumulateDelta({}, {})).toEqual({});
+ expect(AssistantStream.accumulateDelta({}, { a: 'apple' })).toEqual({ a: 'apple' });
+
+ // strings
+ expect(AssistantStream.accumulateDelta({ a: 'foo' }, { a: ' bar' })).toEqual({ a: 'foo bar' });
+
+ // dictionaries
+ expect(AssistantStream.accumulateDelta({ a: { foo: '1' } }, { a: { bar: '2' } })).toEqual({
+ a: {
+ foo: '1',
+ bar: '2',
+ },
+ });
+ expect(AssistantStream.accumulateDelta({ a: { foo: 'hello,' } }, { a: { foo: ' world' } })).toEqual({
+ a: { foo: 'hello, world' },
+ });
+
+ expect(AssistantStream.accumulateDelta({}, { a: null })).toEqual({ a: null });
+ expect(AssistantStream.accumulateDelta({ a: null }, { a: 'apple' })).toEqual({ a: 'apple' });
+ expect(AssistantStream.accumulateDelta({ a: null }, { a: null })).toEqual({ a: null });
+ });
+});