From 3159e6bdcc815501147db1203f6472c38fbda177 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:21:21 +0000 Subject: [PATCH 01/30] chore: update dependency @types/ws to v8.5.10 (#683) --- ecosystem-tests/node-ts-cjs-auto/package-lock.json | 6 +++--- ecosystem-tests/node-ts-cjs/package-lock.json | 6 +++--- ecosystem-tests/node-ts4.5-jest27/package-lock.json | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ecosystem-tests/node-ts-cjs-auto/package-lock.json b/ecosystem-tests/node-ts-cjs-auto/package-lock.json index 56cf7729..df381f1b 100644 --- a/ecosystem-tests/node-ts-cjs-auto/package-lock.json +++ b/ecosystem-tests/node-ts-cjs-auto/package-lock.json @@ -1121,9 +1121,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { "@types/node": "*" diff --git a/ecosystem-tests/node-ts-cjs/package-lock.json b/ecosystem-tests/node-ts-cjs/package-lock.json index f770caca..c39fc8f1 100644 --- a/ecosystem-tests/node-ts-cjs/package-lock.json +++ b/ecosystem-tests/node-ts-cjs/package-lock.json @@ -1163,9 +1163,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { "@types/node": "*" diff --git a/ecosystem-tests/node-ts4.5-jest27/package-lock.json b/ecosystem-tests/node-ts4.5-jest27/package-lock.json index 682b0f7a..f46e12de 100644 --- a/ecosystem-tests/node-ts4.5-jest27/package-lock.json +++ b/ecosystem-tests/node-ts4.5-jest27/package-lock.json @@ -1096,9 +1096,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { "@types/node": "*" From 684f139c0d913e64db171fe5877c7c5980e29813 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:59:26 -0500 Subject: [PATCH 02/30] chore(ci): update actions/setup-node action to v4 (#685) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b342025c..0f699bc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '18' From 90a733e6ff714e6fef3c71ae36e18eee6787a666 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:16:53 -0500 Subject: [PATCH 03/30] chore(types): extract run status to a named type (#686) --- .github/workflows/ci.yml | 2 +- api.md | 1 + src/resources/beta/threads/index.ts | 1 + src/resources/beta/threads/runs/index.ts | 1 + src/resources/beta/threads/runs/runs.ts | 26 ++++++++++++++++-------- src/resources/beta/threads/threads.ts | 1 + 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f699bc9..f51c7a30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'openai/openai-node' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Node uses: actions/setup-node@v4 diff --git a/api.md b/api.md index 68d8545c..ff3180cb 100644 --- a/api.md +++ b/api.md @@ -221,6 +221,7 @@ Types: - RequiredActionFunctionToolCall - Run +- RunStatus Methods: diff --git a/src/resources/beta/threads/index.ts b/src/resources/beta/threads/index.ts index 53e26a5c..54a02dd0 100644 --- a/src/resources/beta/threads/index.ts +++ b/src/resources/beta/threads/index.ts @@ -14,6 +14,7 @@ export { export { RequiredActionFunctionToolCall, Run, + RunStatus, RunCreateParams, RunUpdateParams, RunListParams, diff --git a/src/resources/beta/threads/runs/index.ts b/src/resources/beta/threads/runs/index.ts index a2261f96..b11736c5 100644 --- a/src/resources/beta/threads/runs/index.ts +++ b/src/resources/beta/threads/runs/index.ts @@ -14,6 +14,7 @@ export { export { RequiredActionFunctionToolCall, Run, + RunStatus, RunCreateParams, RunUpdateParams, RunListParams, diff --git a/src/resources/beta/threads/runs/runs.ts b/src/resources/beta/threads/runs/runs.ts index 749d2c7f..9582a060 100644 --- a/src/resources/beta/threads/runs/runs.ts +++ b/src/resources/beta/threads/runs/runs.ts @@ -242,15 +242,7 @@ export interface Run { * `requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, or * `expired`. */ - status: - | 'queued' - | 'in_progress' - | 'requires_action' - | 'cancelling' - | 'cancelled' - | 'failed' - | 'completed' - | 'expired'; + status: RunStatus; /** * The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) @@ -361,6 +353,21 @@ export namespace Run { } } +/** + * The status of the run, which can be either `queued`, `in_progress`, + * `requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, or + * `expired`. + */ +export type RunStatus = + | 'queued' + | 'in_progress' + | 'requires_action' + | 'cancelling' + | 'cancelled' + | 'failed' + | 'completed' + | 'expired'; + export interface RunCreateParams { /** * The ID of the @@ -486,6 +493,7 @@ export namespace RunSubmitToolOutputsParams { export namespace 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 RunUpdateParams = RunsAPI.RunUpdateParams; diff --git a/src/resources/beta/threads/threads.ts b/src/resources/beta/threads/threads.ts index 8bbe1804..5aa1f8c2 100644 --- a/src/resources/beta/threads/threads.ts +++ b/src/resources/beta/threads/threads.ts @@ -298,6 +298,7 @@ export namespace Threads { 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 RunUpdateParams = RunsAPI.RunUpdateParams; From 0ae349cf18f307a3e901149de8411caaa370fb95 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 23 Feb 2024 06:35:12 -0500 Subject: [PATCH 04/30] chore: update @types/react to 18.2.58, @types/react-dom to 18.2.19 (#688) --- ecosystem-tests/vercel-edge/package-lock.json | 16 ++++++++-------- ecosystem-tests/vercel-edge/package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ecosystem-tests/vercel-edge/package-lock.json b/ecosystem-tests/vercel-edge/package-lock.json index 6b44e077..d1c67b71 100644 --- a/ecosystem-tests/vercel-edge/package-lock.json +++ b/ecosystem-tests/vercel-edge/package-lock.json @@ -15,8 +15,8 @@ }, "devDependencies": { "@types/node": "20.3.3", - "@types/react": "18.2.13", - "@types/react-dom": "18.2.6", + "@types/react": "18.2.58", + "@types/react-dom": "18.2.19", "edge-runtime": "^2.4.3", "fastest-levenshtein": "^1.0.16", "jest": "^29.5.0", @@ -1562,9 +1562,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.13", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.13.tgz", - "integrity": "sha512-vJ+zElvi/Zn9cVXB5slX2xL8PZodPCwPRDpittQdw43JR2AJ5k3vKdgJJyneV/cYgIbLQUwXa9JVDvUZXGba+Q==", + "version": "18.2.58", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.58.tgz", + "integrity": "sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -1573,9 +1573,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz", - "integrity": "sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==", + "version": "18.2.19", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.19.tgz", + "integrity": "sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==", "dev": true, "dependencies": { "@types/react": "*" diff --git a/ecosystem-tests/vercel-edge/package.json b/ecosystem-tests/vercel-edge/package.json index 9ebff4bb..506a9d08 100644 --- a/ecosystem-tests/vercel-edge/package.json +++ b/ecosystem-tests/vercel-edge/package.json @@ -21,8 +21,8 @@ }, "devDependencies": { "@types/node": "20.3.3", - "@types/react": "18.2.13", - "@types/react-dom": "18.2.6", + "@types/react": "18.2.58", + "@types/react-dom": "18.2.19", "edge-runtime": "^2.4.3", "fastest-levenshtein": "^1.0.16", "jest": "^29.5.0", From 5601376ef6cee6c456d94983dbc6745e2cf2ce08 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:51:32 -0500 Subject: [PATCH 05/30] chore: update dependency next to v13.5.6 (#689) --- ecosystem-tests/vercel-edge/package-lock.json | 127 ++++++++---------- ecosystem-tests/vercel-edge/package.json | 2 +- 2 files changed, 60 insertions(+), 69 deletions(-) diff --git a/ecosystem-tests/vercel-edge/package-lock.json b/ecosystem-tests/vercel-edge/package-lock.json index d1c67b71..ebac7eb8 100644 --- a/ecosystem-tests/vercel-edge/package-lock.json +++ b/ecosystem-tests/vercel-edge/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "ai": "2.1.34", - "next": "13.4.6", + "next": "13.5.6", "react": "18.2.0", "react-dom": "18.2.0" }, @@ -1171,14 +1171,14 @@ } }, "node_modules/@next/env": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.6.tgz", - "integrity": "sha512-nqUxEtvDqFhmV1/awSg0K2XHNwkftNaiUqCYO9e6+MYmqNObpKVl7OgMkGaQ2SZnFx5YqF0t60ZJTlyJIDAijg==" + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.6.tgz", + "integrity": "sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw==" }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.6.tgz", - "integrity": "sha512-ahi6VP98o4HV19rkOXPSUu+ovfHfUxbJQ7VVJ7gL2FnZRr7onEFC1oGQ6NQHpm8CxpIzSSBW79kumlFMOmZVjg==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.6.tgz", + "integrity": "sha512-5nvXMzKtZfvcu4BhtV0KH1oGv4XEW+B+jOfmBdpFI3C7FrB/MfujRpWYSBBO64+qbW8pkZiSyQv9eiwnn5VIQA==", "cpu": [ "arm64" ], @@ -1191,9 +1191,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.6.tgz", - "integrity": "sha512-13cXxKFsPJIJKzUqrU5XB1mc0xbUgYsRcdH6/rB8c4NMEbWGdtD4QoK9ShN31TZdePpD4k416Ur7p+deMIxnnA==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.6.tgz", + "integrity": "sha512-6cgBfxg98oOCSr4BckWjLLgiVwlL3vlLj8hXg2b+nDgm4bC/qVXXLfpLB9FHdoDu4057hzywbxKvmYGmi7yUzA==", "cpu": [ "x64" ], @@ -1206,9 +1206,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.6.tgz", - "integrity": "sha512-Ti+NMHEjTNktCVxNjeWbYgmZvA2AqMMI2AMlzkXsU7W4pXCMhrryAmAIoo+7YdJbsx01JQWYVxGe62G6DoCLaA==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.6.tgz", + "integrity": "sha512-txagBbj1e1w47YQjcKgSU4rRVQ7uF29YpnlHV5xuVUsgCUf2FmyfJ3CPjZUvpIeXCJAoMCFAoGnbtX86BK7+sg==", "cpu": [ "arm64" ], @@ -1221,9 +1221,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.6.tgz", - "integrity": "sha512-OHoC6gO7XfjstgwR+z6UHKlvhqJfyMtNaJidjx3sEcfaDwS7R2lqR5AABi8PuilGgi0BO0O0sCXqLlpp3a0emQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.6.tgz", + "integrity": "sha512-cGd+H8amifT86ZldVJtAKDxUqeFyLWW+v2NlBULnLAdWsiuuN8TuhVBt8ZNpCqcAuoruoSWynvMWixTFcroq+Q==", "cpu": [ "arm64" ], @@ -1236,9 +1236,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.6.tgz", - "integrity": "sha512-zHZxPGkUlpfNJCboUrFqwlwEX5vI9LSN70b8XEb0DYzzlrZyCyOi7hwDp/+3Urm9AB7YCAJkgR5Sp1XBVjHdfQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.6.tgz", + "integrity": "sha512-Mc2b4xiIWKXIhBy2NBTwOxGD3nHLmq4keFk+d4/WL5fMsB8XdJRdtUlL87SqVCTSaf1BRuQQf1HvXZcy+rq3Nw==", "cpu": [ "x64" ], @@ -1251,9 +1251,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.6.tgz", - "integrity": "sha512-K/Y8lYGTwTpv5ME8PSJxwxLolaDRdVy+lOd9yMRMiQE0BLUhtxtCWC9ypV42uh9WpLjoaD0joOsB9Q6mbrSGJg==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.6.tgz", + "integrity": "sha512-CFHvP9Qz98NruJiUnCe61O6GveKKHpJLloXbDSWRhqhkJdZD2zU5hG+gtVJR//tyW897izuHpM6Gtf6+sNgJPQ==", "cpu": [ "x64" ], @@ -1266,9 +1266,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.6.tgz", - "integrity": "sha512-U6LtxEUrjBL2tpW+Kr1nHCSJWNeIed7U7l5o7FiKGGwGgIlFi4UHDiLI6TQ2lxi20fAU33CsruV3U0GuzMlXIw==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.6.tgz", + "integrity": "sha512-aFv1ejfkbS7PUa1qVPwzDHjQWQtknzAZWGTKYIAaS4NMtBlk3VyA6AYn593pqNanlicewqyl2jUhQAaFV/qXsg==", "cpu": [ "arm64" ], @@ -1281,9 +1281,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.6.tgz", - "integrity": "sha512-eEBeAqpCfhdPSlCZCayjCiyIllVqy4tcqvm1xmg3BgJG0G5ITiMM4Cw2WVeRSgWDJqQGRyyb+q8Y2ltzhXOWsQ==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.6.tgz", + "integrity": "sha512-XqqpHgEIlBHvzwG8sp/JXMFkLAfGLqkbVsyN+/Ih1mR8INb6YCc2x/Mbwi6hsAgUnqQztz8cvEbHJUbSl7RHDg==", "cpu": [ "ia32" ], @@ -1296,9 +1296,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.6.tgz", - "integrity": "sha512-OrZs94AuO3ZS5tnqlyPRNgfWvboXaDQCi5aXGve3o3C+Sj0ctMUV9+Do+0zMvvLRumR8E0PTWKvtz9n5vzIsWw==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.6.tgz", + "integrity": "sha512-Cqfe1YmOS7k+5mGu92nl5ULkzpKuxJrP3+4AEuPmrpFZ3BHxTY3TnHmU1On3bFmFFs6FbTcdF58CCUProGpIGQ==", "cpu": [ "x64" ], @@ -1410,9 +1410,9 @@ } }, "node_modules/@swc/helpers": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", - "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", "dependencies": { "tslib": "^2.4.0" } @@ -5064,39 +5064,37 @@ "dev": true }, "node_modules/next": { - "version": "13.4.6", - "resolved": "https://registry.npmjs.org/next/-/next-13.4.6.tgz", - "integrity": "sha512-sjVqjxU+U2aXZnYt4Ud6CTLNNwWjdSfMgemGpIQJcN3Z7Jni9xRWbR0ie5fQzCg87aLqQVhKA2ud2gPoqJ9lGw==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/next/-/next-13.5.6.tgz", + "integrity": "sha512-Y2wTcTbO4WwEsVb4A8VSnOsG1I9ok+h74q0ZdxkwM3EODqrs4pasq7O0iUxbcS9VtWMicG7f3+HAj0r1+NtKSw==", "dependencies": { - "@next/env": "13.4.6", - "@swc/helpers": "0.5.1", + "@next/env": "13.5.6", + "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", + "postcss": "8.4.31", "styled-jsx": "5.1.1", - "watchpack": "2.4.0", - "zod": "3.21.4" + "watchpack": "2.4.0" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=16.8.0" + "node": ">=16.14.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.4.6", - "@next/swc-darwin-x64": "13.4.6", - "@next/swc-linux-arm64-gnu": "13.4.6", - "@next/swc-linux-arm64-musl": "13.4.6", - "@next/swc-linux-x64-gnu": "13.4.6", - "@next/swc-linux-x64-musl": "13.4.6", - "@next/swc-win32-arm64-msvc": "13.4.6", - "@next/swc-win32-ia32-msvc": "13.4.6", - "@next/swc-win32-x64-msvc": "13.4.6" + "@next/swc-darwin-arm64": "13.5.6", + "@next/swc-darwin-x64": "13.5.6", + "@next/swc-linux-arm64-gnu": "13.5.6", + "@next/swc-linux-arm64-musl": "13.5.6", + "@next/swc-linux-x64-gnu": "13.5.6", + "@next/swc-linux-x64-musl": "13.5.6", + "@next/swc-win32-arm64-msvc": "13.5.6", + "@next/swc-win32-ia32-msvc": "13.5.6", + "@next/swc-win32-x64-msvc": "13.5.6" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", - "fibers": ">= 3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" @@ -5105,9 +5103,6 @@ "@opentelemetry/api": { "optional": true }, - "fibers": { - "optional": true - }, "sass": { "optional": true } @@ -5419,9 +5414,9 @@ } }, "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -5430,10 +5425,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -6715,14 +6714,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/ecosystem-tests/vercel-edge/package.json b/ecosystem-tests/vercel-edge/package.json index 506a9d08..171ba9c1 100644 --- a/ecosystem-tests/vercel-edge/package.json +++ b/ecosystem-tests/vercel-edge/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "ai": "2.1.34", - "next": "13.4.6", + "next": "13.5.6", "react": "18.2.0", "react-dom": "18.2.0" }, From e84773e3813a2f71cd542c3b04eb9842d99eb0ca Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:31:41 -0500 Subject: [PATCH 06/30] chore: update dependency @types/node to v20.11.20 (#690) --- .../node-ts-cjs-auto/package-lock.json | 17 +++++++++++++---- ecosystem-tests/node-ts-cjs/package-lock.json | 17 +++++++++++++---- .../node-ts-esm-auto/package-lock.json | 17 +++++++++++++---- .../node-ts-esm-web/package-lock.json | 17 +++++++++++++---- ecosystem-tests/node-ts-esm/package-lock.json | 17 +++++++++++++---- .../node-ts4.5-jest27/package-lock.json | 17 +++++++++++++---- 6 files changed, 78 insertions(+), 24 deletions(-) diff --git a/ecosystem-tests/node-ts-cjs-auto/package-lock.json b/ecosystem-tests/node-ts-cjs-auto/package-lock.json index df381f1b..a11f9814 100644 --- a/ecosystem-tests/node-ts-cjs-auto/package-lock.json +++ b/ecosystem-tests/node-ts-cjs-auto/package-lock.json @@ -1093,10 +1093,13 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -3684,6 +3687,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/ecosystem-tests/node-ts-cjs/package-lock.json b/ecosystem-tests/node-ts-cjs/package-lock.json index c39fc8f1..c5280c5b 100644 --- a/ecosystem-tests/node-ts-cjs/package-lock.json +++ b/ecosystem-tests/node-ts-cjs/package-lock.json @@ -1135,10 +1135,13 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -4244,6 +4247,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", diff --git a/ecosystem-tests/node-ts-esm-auto/package-lock.json b/ecosystem-tests/node-ts-esm-auto/package-lock.json index 1123560d..4bce04f8 100644 --- a/ecosystem-tests/node-ts-esm-auto/package-lock.json +++ b/ecosystem-tests/node-ts-esm-auto/package-lock.json @@ -1157,10 +1157,13 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/stack-utils": { "version": "2.0.3", @@ -3812,6 +3815,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/ecosystem-tests/node-ts-esm-web/package-lock.json b/ecosystem-tests/node-ts-esm-web/package-lock.json index a2b14d34..b96128a4 100644 --- a/ecosystem-tests/node-ts-esm-web/package-lock.json +++ b/ecosystem-tests/node-ts-esm-web/package-lock.json @@ -1157,10 +1157,13 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/stack-utils": { "version": "2.0.3", @@ -3812,6 +3815,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/ecosystem-tests/node-ts-esm/package-lock.json b/ecosystem-tests/node-ts-esm/package-lock.json index 480a700f..4aecff6c 100644 --- a/ecosystem-tests/node-ts-esm/package-lock.json +++ b/ecosystem-tests/node-ts-esm/package-lock.json @@ -1157,10 +1157,13 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/stack-utils": { "version": "2.0.3", @@ -3812,6 +3815,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/ecosystem-tests/node-ts4.5-jest27/package-lock.json b/ecosystem-tests/node-ts4.5-jest27/package-lock.json index f46e12de..76813597 100644 --- a/ecosystem-tests/node-ts4.5-jest27/package-lock.json +++ b/ecosystem-tests/node-ts4.5-jest27/package-lock.json @@ -1068,10 +1068,13 @@ } }, "node_modules/@types/node": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", - "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", - "dev": true + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-fetch": { "version": "2.6.5", @@ -4117,6 +4120,12 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", From 0372eaaf6f33bfbc3cb6294a2fd6b3bab9e7ba80 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:18:24 -0500 Subject: [PATCH 07/30] feat(api): add wav and pcm to response_format (#691) --- src/resources/audio/speech.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/resources/audio/speech.ts b/src/resources/audio/speech.ts index faa28168..d5ef0911 100644 --- a/src/resources/audio/speech.ts +++ b/src/resources/audio/speech.ts @@ -35,9 +35,13 @@ export interface SpeechCreateParams { voice: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer'; /** - * The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`. + * The format to return audio in. Supported formats are `mp3`, `opus`, `aac`, + * `flac`, `pcm`, and `wav`. + * + * The `pcm` audio format, similar to `wav` but without a header, utilizes a 24kHz + * sample rate, mono channel, and 16-bit depth in signed little-endian format. */ - response_format?: 'mp3' | 'opus' | 'aac' | 'flac'; + response_format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'pcm' | 'wav'; /** * The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is From 5961cb8cea11065efd1ffee9db14f19ad7054ad5 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Sat, 24 Feb 2024 16:17:31 +0100 Subject: [PATCH 08/30] chore(internal): fix ecosystem tests (#693) --- .../node-ts-cjs-auto/moduleResolution/node/type-tests.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ecosystem-tests/node-ts-cjs-auto/moduleResolution/node/type-tests.ts b/ecosystem-tests/node-ts-cjs-auto/moduleResolution/node/type-tests.ts index a3c4f383..2621b2b4 100644 --- a/ecosystem-tests/node-ts-cjs-auto/moduleResolution/node/type-tests.ts +++ b/ecosystem-tests/node-ts-cjs-auto/moduleResolution/node/type-tests.ts @@ -9,6 +9,5 @@ async function typeTests() { model: 'whisper-1', }) .asResponse(); - // @ts-expect-error this doesn't work with "moduleResolution": "node" response.body; } From 6175eca426b15990be5e5cdb0e8497e547f87d8a Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 28 Feb 2024 06:06:00 +0100 Subject: [PATCH 09/30] release: 4.28.4 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ README.md | 2 +- build-deno | 2 +- package.json | 2 +- src/version.ts | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8d537510..5934251e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.28.3" + ".": "4.28.4" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 274b8e8a..68ebe376 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 4.28.4 (2024-02-28) + +Full Changelog: [v4.28.3...v4.28.4](https://github.com/openai/openai-node/compare/v4.28.3...v4.28.4) + +### Features + +* **api:** add wav and pcm to response_format ([#691](https://github.com/openai/openai-node/issues/691)) ([b1c6171](https://github.com/openai/openai-node/commit/b1c61711961a62a4d7b47909a68ecd65231a66af)) + + +### Chores + +* **ci:** update actions/setup-node action to v4 ([#685](https://github.com/openai/openai-node/issues/685)) ([f2704d5](https://github.com/openai/openai-node/commit/f2704d5f1580c0f1d31584ef88702cde8f6804d4)) +* **internal:** fix ecosystem tests ([#693](https://github.com/openai/openai-node/issues/693)) ([616624d](https://github.com/openai/openai-node/commit/616624d3d9fd10ce254ce0d435b2b73ed11679f2)) +* **types:** extract run status to a named type ([#686](https://github.com/openai/openai-node/issues/686)) ([b3b3b8e](https://github.com/openai/openai-node/commit/b3b3b8ea20e0f311d3bd53dfd22ccc04f5dce5f7)) +* update @types/react to 18.2.58, @types/react-dom to 18.2.19 ([#688](https://github.com/openai/openai-node/issues/688)) ([2a0d0b1](https://github.com/openai/openai-node/commit/2a0d0b1cb197eef25e42bbba88ee90c37d623f24)) +* update dependency @types/node to v20.11.20 ([#690](https://github.com/openai/openai-node/issues/690)) ([4ca005b](https://github.com/openai/openai-node/commit/4ca005be082d6c50fe95da6148896b62080bfe07)) +* update dependency @types/ws to v8.5.10 ([#683](https://github.com/openai/openai-node/issues/683)) ([a617268](https://github.com/openai/openai-node/commit/a6172683a3390422984ad282ac4940781493e772)) +* update dependency next to v13.5.6 ([#689](https://github.com/openai/openai-node/issues/689)) ([abb3b66](https://github.com/openai/openai-node/commit/abb3b6674b8f9f8ff9c2cc61629a31883ae4d8c8)) + ## 4.28.3 (2024-02-20) Full Changelog: [v4.28.2...v4.28.3](https://github.com/openai/openai-node/compare/v4.28.2...v4.28.3) diff --git a/README.md b/README.md index c7779e79..ef174634 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ You can import in Deno via: ```ts -import OpenAI from 'https://deno.land/x/openai@v4.28.3/mod.ts'; +import OpenAI from 'https://deno.land/x/openai@v4.28.4/mod.ts'; ``` diff --git a/build-deno b/build-deno index c8215c85..74d994d0 100755 --- a/build-deno +++ b/build-deno @@ -14,7 +14,7 @@ This is a build produced from https://github.com/openai/openai-node – please g Usage: \`\`\`ts -import OpenAI from "https://deno.land/x/openai@v4.28.3/mod.ts"; +import OpenAI from "https://deno.land/x/openai@v4.28.4/mod.ts"; const client = new OpenAI(); \`\`\` diff --git a/package.json b/package.json index 455c0d18..65d6046f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.28.3", + "version": "4.28.4", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 3975f7a3..9dd89406 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.28.3'; // x-release-please-version +export const VERSION = '4.28.4'; // x-release-please-version From 08c5974033dfdb3e60ad50305e2a9aafd586d3f2 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:39:28 +0100 Subject: [PATCH 10/30] docs(contributing): improve wording (#696) --- CONTRIBUTING.md | 6 +++--- README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 61f37370..693e9ea7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ This repository uses [`yarn@v1`](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable). Other package managers may work but are not officially supported for development. -To setup the repository, run: +To set up the repository, run: ```bash yarn @@ -65,7 +65,7 @@ pnpm link -—global openai ## Running tests -Most tests will require you to [setup a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. +Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. ```bash npx prism path/to/your/openapi.yml @@ -99,7 +99,7 @@ the changes aren't made through the automated pipeline, you may want to make rel ### Publish with a GitHub workflow -You can release to package managers by using [the `Publish NPM` GitHub action](https://www.github.com/openai/openai-node/actions/workflows/publish-npm.yml). This will require a setup organization or repository secret to be set up. +You can release to package managers by using [the `Publish NPM` GitHub action](https://www.github.com/openai/openai-node/actions/workflows/publish-npm.yml). This requires a setup organization or repository secret to be set up. ### Publish manually diff --git a/README.md b/README.md index ef174634..e8ff603e 100644 --- a/README.md +++ b/README.md @@ -424,7 +424,7 @@ import OpenAI from 'openai'; ``` To do the inverse, add `import "openai/shims/node"` (which does import polyfills). -This can also be useful if you are getting the wrong TypeScript types for `Response` - more details [here](https://github.com/openai/openai-node/tree/master/src/_shims#readme). +This can also be useful if you are getting the wrong TypeScript types for `Response` ([more details](https://github.com/openai/openai-node/tree/master/src/_shims#readme)). You may also provide a custom `fetch` function when instantiating the client, which can be used to inspect or alter the `Request` or `Response` before/after each request: From c3fee07c78fef9115da353fab8f5e399f81cdc93 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:56:48 +0100 Subject: [PATCH 11/30] docs(readme): fix typo in custom fetch implementation (#698) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e8ff603e..68d356f8 100644 --- a/README.md +++ b/README.md @@ -434,7 +434,7 @@ import { fetch } from 'undici'; // as one example import OpenAI from 'openai'; const client = new OpenAI({ - fetch: async (url: RequestInfo, init?: RequestInfo): Promise => { + fetch: async (url: RequestInfo, init?: RequestInit): Promise => { console.log('About to make a request', url, init); const response = await fetch(url, init); console.log('Got response', response); From 181a5dddb650f1b060b88cbe3bf7293ddfecebdf Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 1 Mar 2024 01:32:50 +0100 Subject: [PATCH 12/30] fix(ChatCompletionStream): abort on async iterator break and handle errors (#699) `break`-ing the async iterator did not previously abort the request which increases usage. Errors are now handled more effectively in the async iterator. --- src/lib/ChatCompletionRunFunctions.test.ts | 53 +++++++++++++++++++++- src/lib/ChatCompletionStream.ts | 35 +++++++++++--- 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/lib/ChatCompletionRunFunctions.test.ts b/src/lib/ChatCompletionRunFunctions.test.ts index bb360b21..b524218a 100644 --- a/src/lib/ChatCompletionRunFunctions.test.ts +++ b/src/lib/ChatCompletionRunFunctions.test.ts @@ -1,5 +1,5 @@ import OpenAI from 'openai'; -import { OpenAIError } from 'openai/error'; +import { OpenAIError, APIConnectionError } from 'openai/error'; import { PassThrough } from 'stream'; import { ParsingToolFunction, @@ -2207,6 +2207,7 @@ describe('resource completions', () => { await listener.sanityCheck(); }); }); + describe('stream', () => { test('successful flow', async () => { const { fetch, handleRequest } = mockStreamingChatCompletionFetch(); @@ -2273,5 +2274,55 @@ describe('resource completions', () => { expect(listener.finalMessage).toEqual({ role: 'assistant', content: 'The weather is great today!' }); await listener.sanityCheck(); }); + test('handles network errors', async () => { + const { fetch, handleRequest } = mockFetch(); + + const openai = new OpenAI({ apiKey: '...', fetch }); + + const stream = openai.beta.chat.completions.stream( + { + max_tokens: 1024, + model: 'gpt-3.5-turbo', + messages: [{ role: 'user', content: 'Say hello there!' }], + }, + { maxRetries: 0 }, + ); + + handleRequest(async () => { + throw new Error('mock request error'); + }).catch(() => {}); + + async function runStream() { + await stream.done(); + } + + await expect(runStream).rejects.toThrow(APIConnectionError); + }); + test('handles network errors on async iterator', async () => { + const { fetch, handleRequest } = mockFetch(); + + const openai = new OpenAI({ apiKey: '...', fetch }); + + const stream = openai.beta.chat.completions.stream( + { + max_tokens: 1024, + model: 'gpt-3.5-turbo', + messages: [{ role: 'user', content: 'Say hello there!' }], + }, + { maxRetries: 0 }, + ); + + handleRequest(async () => { + throw new Error('mock request error'); + }).catch(() => {}); + + async function runStream() { + for await (const _event of stream) { + continue; + } + } + + await expect(runStream).rejects.toThrow(APIConnectionError); + }); }); }); diff --git a/src/lib/ChatCompletionStream.ts b/src/lib/ChatCompletionStream.ts index a2aa7032..2ea04038 100644 --- a/src/lib/ChatCompletionStream.ts +++ b/src/lib/ChatCompletionStream.ts @@ -210,13 +210,16 @@ export class ChatCompletionStream [Symbol.asyncIterator](): AsyncIterator { const pushQueue: ChatCompletionChunk[] = []; - const readQueue: ((chunk: ChatCompletionChunk | undefined) => void)[] = []; + const readQueue: { + resolve: (chunk: ChatCompletionChunk | undefined) => void; + reject: (err: unknown) => void; + }[] = []; let done = false; this.on('chunk', (chunk) => { const reader = readQueue.shift(); if (reader) { - reader(chunk); + reader.resolve(chunk); } else { pushQueue.push(chunk); } @@ -225,7 +228,23 @@ export class ChatCompletionStream this.on('end', () => { done = true; for (const reader of readQueue) { - reader(undefined); + 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; }); @@ -236,13 +255,17 @@ export class ChatCompletionStream if (done) { return { value: undefined, done: true }; } - return new Promise((resolve) => readQueue.push(resolve)).then( - (chunk) => (chunk ? { value: chunk, done: false } : { 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 }; + }, }; } From 18d9cb729d23871976368e8b5c40515661a8bd4b Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 1 Mar 2024 14:57:12 +0100 Subject: [PATCH 13/30] chore(docs): mention install from git repo (#700) --- CONTRIBUTING.md | 2 ++ README.md | 1 + 2 files changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 693e9ea7..297322d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,6 +43,8 @@ To install via git: ```bash npm install --save git+ssh://git@github.com:openai/openai-node.git +# or +yarn add git+ssh://git@github.com:openai/openai-node.git ``` Alternatively, to link a local copy of the repo: diff --git a/README.md b/README.md index 68d356f8..dd3ac15c 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ To learn how to use the OpenAI API, check out our [API Reference](https://platfo ## Installation ```sh +# install from NPM npm install --save openai # or yarn add openai From c21ef88b650b996dd0cf97f36294db464573b531 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 4 Mar 2024 19:17:09 +0100 Subject: [PATCH 14/30] chore(api): update docs (#703) --- src/resources/audio/speech.ts | 9 +++------ src/resources/audio/transcriptions.ts | 18 ++++++++++++++---- src/resources/audio/translations.ts | 3 ++- src/resources/beta/threads/runs/runs.ts | 4 ++-- src/resources/chat/completions.ts | 14 +++++++++----- src/resources/images.ts | 9 ++++++--- src/resources/moderations.ts | 8 +++----- 7 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/resources/audio/speech.ts b/src/resources/audio/speech.ts index d5ef0911..7d0ee219 100644 --- a/src/resources/audio/speech.ts +++ b/src/resources/audio/speech.ts @@ -35,13 +35,10 @@ export interface SpeechCreateParams { voice: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer'; /** - * The format to return audio in. Supported formats are `mp3`, `opus`, `aac`, - * `flac`, `pcm`, and `wav`. - * - * The `pcm` audio format, similar to `wav` but without a header, utilizes a 24kHz - * sample rate, mono channel, and 16-bit depth in signed little-endian format. + * The format to audio in. Supported formats are `mp3`, `opus`, `aac`, `flac`, + * `wav`, and `pcm`. */ - response_format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'pcm' | 'wav'; + response_format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'; /** * The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is diff --git a/src/resources/audio/transcriptions.ts b/src/resources/audio/transcriptions.ts index 7f381c5a..ab2079ed 100644 --- a/src/resources/audio/transcriptions.ts +++ b/src/resources/audio/transcriptions.ts @@ -14,7 +14,14 @@ export class Transcriptions extends APIResource { } } +/** + * Represents a transcription response returned by model, based on the provided + * input. + */ export interface Transcription { + /** + * The transcribed text. + */ text: string; } @@ -26,7 +33,8 @@ export interface TranscriptionCreateParams { file: Uploadable; /** - * ID of the model to use. Only `whisper-1` is currently available. + * ID of the model to use. Only `whisper-1` (which is powered by our open source + * Whisper V2 model) is currently available. */ model: (string & {}) | 'whisper-1'; @@ -61,9 +69,11 @@ export interface TranscriptionCreateParams { temperature?: number; /** - * The timestamp granularities to populate for this transcription. Any of these - * options: `word`, or `segment`. Note: There is no additional latency for segment - * timestamps, but generating word timestamps incurs additional latency. + * The timestamp granularities to populate for this transcription. + * `response_format` must be set `verbose_json` to use timestamp granularities. + * Either or both of these options are supported: `word`, or `segment`. Note: There + * is no additional latency for segment timestamps, but generating word timestamps + * incurs additional latency. */ timestamp_granularities?: Array<'word' | 'segment'>; } diff --git a/src/resources/audio/translations.ts b/src/resources/audio/translations.ts index 54583ce1..e68a714f 100644 --- a/src/resources/audio/translations.ts +++ b/src/resources/audio/translations.ts @@ -26,7 +26,8 @@ export interface TranslationCreateParams { file: Uploadable; /** - * ID of the model to use. Only `whisper-1` is currently available. + * ID of the model to use. Only `whisper-1` (which is powered by our open source + * Whisper V2 model) is currently available. */ model: (string & {}) | 'whisper-1'; diff --git a/src/resources/beta/threads/runs/runs.ts b/src/resources/beta/threads/runs/runs.ts index 9582a060..9a0bc00d 100644 --- a/src/resources/beta/threads/runs/runs.ts +++ b/src/resources/beta/threads/runs/runs.ts @@ -270,9 +270,9 @@ export namespace Run { */ export interface LastError { /** - * One of `server_error` or `rate_limit_exceeded`. + * One of `server_error`, `rate_limit_exceeded`, or `invalid_prompt`. */ - code: 'server_error' | 'rate_limit_exceeded'; + code: 'server_error' | 'rate_limit_exceeded' | 'invalid_prompt'; /** * A human-readable description of the error. diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 2a521674..44627eb8 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -546,7 +546,9 @@ export interface ChatCompletionTokenLogprob { bytes: Array | null; /** - * The log probability of this token. + * The log probability of this token, if it is within the top 20 most likely + * tokens. Otherwise, the value `-9999.0` is used to signify that the token is very + * unlikely. */ logprob: number; @@ -574,7 +576,9 @@ export namespace ChatCompletionTokenLogprob { bytes: Array | null; /** - * The log probability of this token. + * The log probability of this token, if it is within the top 20 most likely + * tokens. Otherwise, the value `-9999.0` is used to signify that the token is very + * unlikely. */ logprob: number; } @@ -827,9 +831,9 @@ export interface ChatCompletionCreateParamsBase { tools?: Array; /** - * An integer between 0 and 5 specifying the number of most likely tokens to return - * at each token position, each with an associated log probability. `logprobs` must - * be set to `true` if this parameter is used. + * An integer between 0 and 20 specifying the number of most likely tokens to + * return at each token position, each with an associated log probability. + * `logprobs` must be set to `true` if this parameter is used. */ top_logprobs?: number | null; diff --git a/src/resources/images.ts b/src/resources/images.ts index 4bc65490..bc5b9edc 100644 --- a/src/resources/images.ts +++ b/src/resources/images.ts @@ -80,7 +80,8 @@ export interface ImageCreateVariationParams { /** * The format in which the generated images are returned. Must be one of `url` or - * `b64_json`. + * `b64_json`. URLs are only valid for 60 minutes after the image has been + * generated. */ response_format?: 'url' | 'b64_json' | null; @@ -131,7 +132,8 @@ export interface ImageEditParams { /** * The format in which the generated images are returned. Must be one of `url` or - * `b64_json`. + * `b64_json`. URLs are only valid for 60 minutes after the image has been + * generated. */ response_format?: 'url' | 'b64_json' | null; @@ -176,7 +178,8 @@ export interface ImageGenerateParams { /** * The format in which the generated images are returned. Must be one of `url` or - * `b64_json`. + * `b64_json`. URLs are only valid for 60 minutes after the image has been + * generated. */ response_format?: 'url' | 'b64_json' | null; diff --git a/src/resources/moderations.ts b/src/resources/moderations.ts index 8bde6ecc..a43006cc 100644 --- a/src/resources/moderations.ts +++ b/src/resources/moderations.ts @@ -6,7 +6,7 @@ import * as ModerationsAPI from 'openai/resources/moderations'; export class Moderations extends APIResource { /** - * Classifies if text violates OpenAI's Content Policy + * Classifies if text is potentially harmful. */ create( body: ModerationCreateParams, @@ -28,8 +28,7 @@ export interface Moderation { category_scores: Moderation.CategoryScores; /** - * Whether the content violates - * [OpenAI's usage policies](/policies/usage-policies). + * Whether any of the below categories are flagged. */ flagged: boolean; } @@ -170,8 +169,7 @@ export namespace Moderation { } /** - * Represents policy compliance report by OpenAI's content moderation model against - * a given input. + * Represents if a given text input is potentially harmful. */ export interface ModerationCreateResponse { /** From 34e128fad382d1aeac9912d85c50291c4882d298 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:53:09 +0100 Subject: [PATCH 15/30] chore: fix error handler in readme (#704) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dd3ac15c..1cfb2537 100644 --- a/README.md +++ b/README.md @@ -275,7 +275,7 @@ a subclass of `APIError` will be thrown: async function main() { const job = await openai.fineTuning.jobs .create({ model: 'gpt-3.5-turbo', training_file: 'file-abc123' }) - .catch((err) => { + .catch(async (err) => { if (err instanceof OpenAI.APIError) { console.log(err.status); // 400 console.log(err.name); // BadRequestError From 588b30f6f5604387cb2ade716b6cf693e1175cec Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:10:53 +0100 Subject: [PATCH 16/30] docs(readme): fix https proxy example (#705) --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1cfb2537..1207d5d2 100644 --- a/README.md +++ b/README.md @@ -456,7 +456,7 @@ If you would like to disable or customize this behavior, for example to use the ```ts import http from 'http'; -import HttpsProxyAgent from 'https-proxy-agent'; +import { HttpsProxyAgent } from 'https-proxy-agent'; // Configure the default for all requests: const openai = new OpenAI({ @@ -465,9 +465,8 @@ const openai = new OpenAI({ // Override per-request: await openai.models.list({ - baseURL: 'http://localhost:8080/test-api', httpAgent: new http.Agent({ keepAlive: false }), -}) +}); ``` ## Semantic Versioning From 753bced18a57cd4a7739e8e03a7b7933048be79f Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:42:34 +0100 Subject: [PATCH 17/30] fix(streaming): correctly handle trailing new lines in byte chunks (#708) --- src/streaming.ts | 8 +++++++- tests/streaming.test.ts | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/streaming.test.ts diff --git a/src/streaming.ts b/src/streaming.ts index 7d8b4442..1b59bce2 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -267,7 +267,7 @@ class SSEDecoder { * * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 */ -class LineDecoder { +export class LineDecoder { // prettier-ignore static NEWLINE_CHARS = new Set(['\n', '\r', '\x0b', '\x0c', '\x1c', '\x1d', '\x1e', '\x85', '\u2028', '\u2029']); static NEWLINE_REGEXP = /\r\n|[\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029]/g; @@ -300,6 +300,12 @@ class LineDecoder { const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || ''); let lines = text.split(LineDecoder.NEWLINE_REGEXP); + // if there is a trailing new line then the last entry will be an empty + // string which we don't care about + if (trailingNewline) { + lines.pop(); + } + if (lines.length === 1 && !trailingNewline) { this.buffer.push(lines[0]!); return []; diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts new file mode 100644 index 00000000..45cf6f6c --- /dev/null +++ b/tests/streaming.test.ts @@ -0,0 +1,42 @@ +import { LineDecoder } from 'openai/streaming'; + +function decodeChunks(chunks: string[], decoder?: LineDecoder): string[] { + if (!decoder) { + decoder = new LineDecoder(); + } + + const lines = []; + for (const chunk of chunks) { + lines.push(...decoder.decode(chunk)); + } + + return lines; +} + +describe('line decoder', () => { + test('basic', () => { + // baz is not included because the line hasn't ended yet + expect(decodeChunks(['foo', ' bar\nbaz'])).toEqual(['foo bar']); + }); + + test('basic with \\r', () => { + // baz is not included because the line hasn't ended yet + expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']); + }); + + test('trailing new lines', () => { + expect(decodeChunks(['foo', ' bar', 'baz\n', 'thing\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('trailing new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar', 'baz\r\n', 'thing\r\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('escaped new lines', () => { + expect(decodeChunks(['foo', ' bar\\nbaz\n'])).toEqual(['foo bar\\nbaz']); + }); + + test('escaped new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']); + }); +}); From e0deb2285fb35fac8096ebfe6ed5f9dcd1a8b7f0 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:13:10 +0100 Subject: [PATCH 18/30] chore(types): fix accidental exposure of Buffer type to cloudflare (#709) --- src/streaming.ts | 13 ++++++++++++- tests/streaming.test.ts | 15 +-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/streaming.ts b/src/streaming.ts index 1b59bce2..7b0466a3 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -267,7 +267,7 @@ class SSEDecoder { * * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 */ -export class LineDecoder { +class LineDecoder { // prettier-ignore static NEWLINE_CHARS = new Set(['\n', '\r', '\x0b', '\x0c', '\x1c', '\x1d', '\x1e', '\x85', '\u2028', '\u2029']); static NEWLINE_REGEXP = /\r\n|[\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029]/g; @@ -372,6 +372,17 @@ export class LineDecoder { } } +/** This is an internal helper function that's just used for testing */ +export function _decodeChunks(chunks: string[]): string[] { + const decoder = new LineDecoder(); + const lines = []; + for (const chunk of chunks) { + lines.push(...decoder.decode(chunk)); + } + + return lines; +} + function partition(str: string, delimiter: string): [string, string, string] { const index = str.indexOf(delimiter); if (index !== -1) { diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index 45cf6f6c..479b2a34 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -1,17 +1,4 @@ -import { LineDecoder } from 'openai/streaming'; - -function decodeChunks(chunks: string[], decoder?: LineDecoder): string[] { - if (!decoder) { - decoder = new LineDecoder(); - } - - const lines = []; - for (const chunk of chunks) { - lines.push(...decoder.decode(chunk)); - } - - return lines; -} +import { _decodeChunks as decodeChunks } from 'openai/streaming'; describe('line decoder', () => { test('basic', () => { From 0825acf85cd50d02b63a875481aadd5ec6cc6aad Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 6 Mar 2024 21:12:48 +0100 Subject: [PATCH 19/30] docs: remove extraneous --save and yarn install instructions (#710) --- CONTRIBUTING.md | 4 +--- README.md | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 297322d1..d9e64025 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,9 +42,7 @@ If you’d like to use the repository from source, you can either install from g To install via git: ```bash -npm install --save git+ssh://git@github.com:openai/openai-node.git -# or -yarn add git+ssh://git@github.com:openai/openai-node.git +npm install git+ssh://git@github.com:openai/openai-node.git ``` Alternatively, to link a local copy of the repo: diff --git a/README.md b/README.md index 1207d5d2..28262aac 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,7 @@ To learn how to use the OpenAI API, check out our [API Reference](https://platfo ## Installation ```sh -# install from NPM -npm install --save openai -# or -yarn add openai +npm install openai ``` You can import in Deno via: From 50206a06974d558d9df7d8649cc2c71822e67472 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:13:22 +0100 Subject: [PATCH 20/30] docs: use @deprecated decorator for deprecated params (#711) --- src/resources/chat/completions.ts | 30 ++++++++++++++++++------------ src/resources/files.ts | 8 ++++---- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 44627eb8..c2d6da0b 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -133,8 +133,8 @@ export interface ChatCompletionAssistantMessageParam { content?: string | null; /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ function_call?: ChatCompletionAssistantMessageParam.FunctionCall; @@ -152,8 +152,8 @@ export interface ChatCompletionAssistantMessageParam { export namespace ChatCompletionAssistantMessageParam { /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ export interface FunctionCall { /** @@ -250,8 +250,8 @@ export namespace ChatCompletionChunk { content?: string | null; /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ function_call?: Delta.FunctionCall; @@ -265,8 +265,8 @@ export namespace ChatCompletionChunk { export namespace Delta { /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ export interface FunctionCall { /** @@ -378,6 +378,9 @@ export interface ChatCompletionFunctionCallOption { name: string; } +/** + * @deprecated + */ export interface ChatCompletionFunctionMessageParam { /** * The contents of the function message. @@ -410,8 +413,8 @@ export interface ChatCompletionMessage { role: 'assistant'; /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ function_call?: ChatCompletionMessage.FunctionCall; @@ -423,8 +426,8 @@ export interface ChatCompletionMessage { export namespace ChatCompletionMessage { /** - * Deprecated and replaced by `tool_calls`. The name and arguments of a function - * that should be called, as generated by the model. + * @deprecated: Deprecated and replaced by `tool_calls`. The name and arguments of + * a function that should be called, as generated by the model. */ export interface FunctionCall { /** @@ -855,6 +858,9 @@ export interface ChatCompletionCreateParamsBase { } export namespace ChatCompletionCreateParams { + /** + * @deprecated + */ export interface Function { /** * The name of the function to be called. Must be a-z, A-Z, 0-9, or contain diff --git a/src/resources/files.ts b/src/resources/files.ts index db8f3a66..cda487a6 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -154,14 +154,14 @@ export interface FileObject { purpose: 'fine-tune' | 'fine-tune-results' | 'assistants' | 'assistants_output'; /** - * Deprecated. The current status of the file, which can be either `uploaded`, - * `processed`, or `error`. + * @deprecated: Deprecated. The current status of the file, which can be either + * `uploaded`, `processed`, or `error`. */ status: 'uploaded' | 'processed' | 'error'; /** - * Deprecated. For details on why a fine-tuning training file failed validation, - * see the `error` field on `fine_tuning.job`. + * @deprecated: Deprecated. For details on why a fine-tuning training file failed + * validation, see the `error` field on `fine_tuning.job`. */ status_details?: string; } From c71ad7062dc778a3675b104650b21877e811956b Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:10:51 +0100 Subject: [PATCH 21/30] chore(internal): add explicit type annotation to decoder (#712) --- src/streaming.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/streaming.ts b/src/streaming.ts index 7b0466a3..f90c5d89 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -375,7 +375,7 @@ class LineDecoder { /** This is an internal helper function that's just used for testing */ export function _decodeChunks(chunks: string[]): string[] { const decoder = new LineDecoder(); - const lines = []; + const lines: string[] = []; for (const chunk of chunks) { lines.push(...decoder.decode(chunk)); } From beea0c7c6b6b8611f3b95c02fb35e74855f7ba03 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 13 Mar 2024 01:06:20 -0400 Subject: [PATCH 22/30] release: 4.28.5 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 27 +++++++++++++++++++++++++++ README.md | 2 +- build-deno | 2 +- package.json | 2 +- src/version.ts | 2 +- 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5934251e..2813cb97 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.28.4" + ".": "4.28.5" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 68ebe376..8798e4b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## 4.28.5 (2024-03-13) + +Full Changelog: [v4.28.4...v4.28.5](https://github.com/openai/openai-node/compare/v4.28.4...v4.28.5) + +### Bug Fixes + +* **ChatCompletionStream:** abort on async iterator break and handle errors ([#699](https://github.com/openai/openai-node/issues/699)) ([ac417a2](https://github.com/openai/openai-node/commit/ac417a2db31919d2b52f2eb2e38f9c67a8f73254)) +* **streaming:** correctly handle trailing new lines in byte chunks ([#708](https://github.com/openai/openai-node/issues/708)) ([4753be2](https://github.com/openai/openai-node/commit/4753be272b1d1dade7a769cf350b829fc639f36e)) + + +### Chores + +* **api:** update docs ([#703](https://github.com/openai/openai-node/issues/703)) ([e1db98b](https://github.com/openai/openai-node/commit/e1db98bef29d200e2e401e3f5d7b2db6839c7836)) +* **docs:** mention install from git repo ([#700](https://github.com/openai/openai-node/issues/700)) ([c081bdb](https://github.com/openai/openai-node/commit/c081bdbb55585e63370496d324dc6f94d86424d1)) +* fix error handler in readme ([#704](https://github.com/openai/openai-node/issues/704)) ([4ff790a](https://github.com/openai/openai-node/commit/4ff790a67cf876191e04ad0e369e447e080b78a7)) +* **internal:** add explicit type annotation to decoder ([#712](https://github.com/openai/openai-node/issues/712)) ([d728e99](https://github.com/openai/openai-node/commit/d728e9923554e4c72c9efa3bd528561400d50ad8)) +* **types:** fix accidental exposure of Buffer type to cloudflare ([#709](https://github.com/openai/openai-node/issues/709)) ([0323ecb](https://github.com/openai/openai-node/commit/0323ecb98ddbd8910fc5719c8bab5175b945d2ab)) + + +### Documentation + +* **contributing:** improve wording ([#696](https://github.com/openai/openai-node/issues/696)) ([940d569](https://github.com/openai/openai-node/commit/940d5695f4cacddbb58e3bfc50fec28c468c7e63)) +* **readme:** fix https proxy example ([#705](https://github.com/openai/openai-node/issues/705)) ([d144789](https://github.com/openai/openai-node/commit/d1447890a556d37928b628f6449bb80de224d207)) +* **readme:** fix typo in custom fetch implementation ([#698](https://github.com/openai/openai-node/issues/698)) ([64041fd](https://github.com/openai/openai-node/commit/64041fd33da569eccae64afe4e50ee803017b20b)) +* remove extraneous --save and yarn install instructions ([#710](https://github.com/openai/openai-node/issues/710)) ([8ec216d](https://github.com/openai/openai-node/commit/8ec216d6b72ee4d67e26786f06c93af18d042117)) +* use [@deprecated](https://github.com/deprecated) decorator for deprecated params ([#711](https://github.com/openai/openai-node/issues/711)) ([4688ef4](https://github.com/openai/openai-node/commit/4688ef4b36e9f383a3abf6cdb31d498163a7bb9e)) + ## 4.28.4 (2024-02-28) Full Changelog: [v4.28.3...v4.28.4](https://github.com/openai/openai-node/compare/v4.28.3...v4.28.4) diff --git a/README.md b/README.md index 28262aac..24d38ac7 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ You can import in Deno via: ```ts -import OpenAI from 'https://deno.land/x/openai@v4.28.4/mod.ts'; +import OpenAI from 'https://deno.land/x/openai@v4.28.5/mod.ts'; ``` diff --git a/build-deno b/build-deno index 74d994d0..fb739cc5 100755 --- a/build-deno +++ b/build-deno @@ -14,7 +14,7 @@ This is a build produced from https://github.com/openai/openai-node – please g Usage: \`\`\`ts -import OpenAI from "https://deno.land/x/openai@v4.28.4/mod.ts"; +import OpenAI from "https://deno.land/x/openai@v4.28.5/mod.ts"; const client = new OpenAI(); \`\`\` diff --git a/package.json b/package.json index 65d6046f..d51c4ca9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.28.4", + "version": "4.28.5", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 9dd89406..516e764d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.28.4'; // x-release-please-version +export const VERSION = '4.28.5'; // x-release-please-version 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 23/30] 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 ff3180cb..504a103c 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 00000000..a882d219 --- /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 00000000..36c4ed15 --- /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 00000000..bbc2f80c --- /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 80bf95b0..7b3033fa 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 00000000..b600f0df --- /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 00000000..d70cb735 --- /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 08abb2c9..b4e92fd9 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 5236bc8d..0ae8c9c6 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 5fd99990..74056ed1 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 4ed7e84b..d8770c29 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 54a02dd0..3585be84 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 cde22c2a..f68edbbd 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 40b43682..b38a4bbf 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 b11736c5..7fa34637 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 9a0bc00d..8fe09ecc 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 c574c94d..4218e976 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 5aa1f8c2..cbde41f8 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 c2d6da0b..41216a8e 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 f3e262f5..83ecb3e9 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 05ab6638..a6b2c11b 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 f90c5d89..c452737a 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 5a720afc..45f17040 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 fc9fef72..9243dc11 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 00000000..e8db3d58 --- /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 }); + }); +}); From 993669b502416096e4fa3b9f300bf0746ecbec63 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 13 Mar 2024 16:31:06 -0400 Subject: [PATCH 24/30] release: 4.29.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- build-deno | 2 +- package.json | 2 +- src/version.ts | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2813cb97..2f6cf24a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.28.5" + ".": "4.29.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8798e4b6..19dfcc62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 4.29.0 (2024-03-13) + +Full Changelog: [v4.28.5...v4.29.0](https://github.com/openai/openai-node/compare/v4.28.5...v4.29.0) + +### Features + +* **assistants:** add support for streaming ([#714](https://github.com/openai/openai-node/issues/714)) ([7d27d28](https://github.com/openai/openai-node/commit/7d27d286876d0a575d91a4752f401126fe93d2a3)) + ## 4.28.5 (2024-03-13) Full Changelog: [v4.28.4...v4.28.5](https://github.com/openai/openai-node/compare/v4.28.4...v4.28.5) diff --git a/README.md b/README.md index 24d38ac7..93ae9f04 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ You can import in Deno via: ```ts -import OpenAI from 'https://deno.land/x/openai@v4.28.5/mod.ts'; +import OpenAI from 'https://deno.land/x/openai@v4.29.0/mod.ts'; ``` diff --git a/build-deno b/build-deno index fb739cc5..c49755fd 100755 --- a/build-deno +++ b/build-deno @@ -14,7 +14,7 @@ This is a build produced from https://github.com/openai/openai-node – please g Usage: \`\`\`ts -import OpenAI from "https://deno.land/x/openai@v4.28.5/mod.ts"; +import OpenAI from "https://deno.land/x/openai@v4.29.0/mod.ts"; const client = new OpenAI(); \`\`\` diff --git a/package.json b/package.json index d51c4ca9..ce6396c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.28.5", + "version": "4.29.0", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 516e764d..0de2f353 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.28.5'; // x-release-please-version +export const VERSION = '4.29.0'; // x-release-please-version From bc9a1ca308020a88c29d409edc06cdfca8cbf8f5 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:31:36 -0400 Subject: [PATCH 25/30] docs(readme): assistant streaming (#719) --- helpers.md | 158 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 145 insertions(+), 13 deletions(-) diff --git a/helpers.md b/helpers.md index 76423ee0..9f01a126 100644 --- a/helpers.md +++ b/helpers.md @@ -1,6 +1,140 @@ -# Chat Completion Helpers +# Streaming Helpers -## Streaming Responses +OpenAI supports streaming responses when interacting with the [Chat](#chat-streaming) or [Assistant](#assistant-streaming-api) APIs. + +## Assistant Streaming API + +OpenAI supports streaming responses from Assistants. The SDK provides convenience wrappers around the API +so you can subscribe to the types of events you are interested in as well as receive accumulated responses. + +More information can be found in the documentation: [Assistant Streaming](https://platform.openai.com/docs/assistants/overview?lang=node.js) + +#### An example of creating a run and subscribing to some events + +```ts +const run = openai.beta.threads.runs + .createAndStream(thread.id, { + assistant_id: assistant.id, + }) + .on('textCreated', (text) => process.stdout.write('\nassistant > ')) + .on('textDelta', (textDelta, snapshot) => process.stdout.write(textDelta.value)) + .on('toolCallCreated', (toolCall) => process.stdout.write(`\nassistant > ${toolCall.type}\n\n`)) + .on('toolCallDelta', (toolCallDelta, snapshot) => { + if (toolCallDelta.type === 'code_interpreter') { + if (toolCallDelta.code_interpreter.input) { + process.stdout.write(toolCallDelta.code_interpreter.input); + } + if (toolCallDelta.code_interpreter.outputs) { + process.stdout.write('\noutput >\n'); + toolCallDelta.code_interpreter.outputs.forEach((output) => { + if (output.type === 'logs') { + process.stdout.write(`\n${output.logs}\n`); + } + }); + } + } + }); +``` + +### Assistant Events + +The assistant API provides events you can subscribe to for the following events. + +```ts +.on('event', (event: AssistantStreamEvent) => ...) +``` + +This allows you to subscribe to all the possible raw events sent by the OpenAI streaming API. +In many cases it will be more convenient to subscribe to a more specific set of events for your use case. + +More information on the types of events can be found here: [Events](https://platform.openai.com/docs/api-reference/assistants-streaming/events) + +```ts +.on('runStepCreated', (runStep: RunStep) => ...) +.on('runStepDelta', (delta: RunStepDelta, snapshot: RunStep) => ...) +.on('runStepDone', (runStep: RunStep) => ...) +``` + +These events allow you to subscribe to the creation, delta and completion of a RunStep. + +For more information on how Runs and RunSteps work see the documentation [Runs and RunSteps](https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps) + +```ts +.on('messageCreated', (message: Message) => ...) +.on('messageDelta', (delta: MessageDelta, snapshot: Message) => ...) +.on('messageDone', (message: Message) => ...) +``` + +This allows you to subscribe to Message creation, delta and completion events. Messages can contain +different types of content that can be sent from a model (and events are available for specific content types). +For convenience, the delta event includes both the incremental update and an accumulated snapshot of the content. + +More information on messages can be found +on in the documentation page [Message](https://platform.openai.com/docs/api-reference/messages/object). + +```ts +.on('textCreated', (content: Text) => ...) +.on('textDelta', (delta: RunStepDelta, snapshot: Text) => ...) +.on('textDone', (content: Text, snapshot: Message) => ...) +``` + +These events allow you to subscribe to the creation, delta and completion of a Text content (a specific type of message). +For convenience, the delta event includes both the incremental update and an accumulated snapshot of the content. + +```ts +.on('imageFileDone', (content: ImageFile, snapshot: Message) => ...) +``` + +Image files are not sent incrementally so an event is provided for when a image file is available. + +```ts +.on('toolCallCreated', (toolCall: ToolCall) => ...) +.on('toolCallDelta', (delta: RunStepDelta, snapshot: ToolCall) => ...) +.on('toolCallDone', (toolCall: ToolCall) => ...) +``` + +These events allow you to subscribe to events for the creation, delta and completion of a ToolCall. + +More information on tools can be found here [Tools](https://platform.openai.com/docs/assistants/tools) + +```ts +.on('end', () => ...) +``` + +The last event send when a stream ends. + +### Assistant Methods + +The assistant streaming object also provides a few methods for convenience: + +```ts +.currentEvent() + +.currentRun() + +.currentMessageSnapshot() + +.currentRunStepSnapshot() +``` + +These methods are provided to allow you to access additional context from within event handlers. In many cases +the handlers should include all the information you need for processing, but if additional context is required it +can be accessed. + +Note: There is not always a relevant context in certain situations (these will be undefined in those cases). + +```ts +await.finalMessages(); + +await.finalRunSteps(); +``` + +These methods are provided for convenience to collect information at the end of a stream. Calling these events +will trigger consumption of the stream until completion and then return the relevant accumulated objects. + +## Chat Streaming + +### Streaming Responses ```ts openai.chat.completions.stream({ stream?: false, … }, options?): ChatCompletionStreamingRunner @@ -18,7 +152,7 @@ If you need to cancel a stream, you can `break` from a `for await` loop or call See an example of streaming helpers in action in [`examples/stream.ts`](examples/stream.ts). -## Automated Function Calls +### Automated Function Calls ```ts openai.chat.completions.runTools({ stream: false, … }, options?): ChatCompletionRunner @@ -69,9 +203,7 @@ See an example of automated function calls in action in Note, `runFunctions` was also previously available, but has been deprecated in favor of `runTools`. -## Runner API - -### Events +### Chat Events #### `.on('connect', () => …)` @@ -148,7 +280,7 @@ The event fired at the end, returning the total usage of the call. The last event fired in the stream. -### Methods +### Chat Methods #### `.abort()` @@ -190,7 +322,7 @@ A promise which resolves with the last message with a `role: "function"`. Throws A promise which resolves with the total usage. -### Fields +### Chat Fields #### `.messages` @@ -200,9 +332,9 @@ A mutable array of all messages in the conversation. The underlying `AbortController` for the runner. -## Examples +### Chat Examples -### Abort on a function call +#### Abort on a function call If you have a function call flow which you intend to _end_ with a certain function call, then you can use the second argument `runner` given to the function to either mutate `runner.messages` or call `runner.abort()`. @@ -238,7 +370,7 @@ async function main() { main(); ``` -### Integrate with `zod` +#### Integrate with `zod` [`zod`](https://www.npmjs.com/package/zod) is a schema validation library which can help with validating the assistant's response to make sure it conforms to a schema. Paired with [`zod-to-json-schema`](https://www.npmjs.com/package/zod-to-json-schema), the validation schema also acts as the `parameters` JSON Schema passed to the API. @@ -287,10 +419,10 @@ main(); See a more fully-fledged example in [`examples/function-call-helpers-zod.ts`](examples/function-call-helpers-zod.ts). -### Integrate with Next.JS +#### Integrate with Next.JS See an example of a Next.JS integration here [`examples/stream-to-client-next.ts`](examples/stream-to-client-next.ts). -### Proxy Streaming to a Browser +#### Proxy Streaming to a Browser See an example of using express to stream to a browser here [`examples/stream-to-client-express.ts`](examples/stream-to-client-express.ts). From 4760ccc4be8b0951414eb443d186d3c506731195 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:31:56 -0400 Subject: [PATCH 26/30] release: 4.29.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- build-deno | 2 +- package.json | 2 +- src/version.ts | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2f6cf24a..ded4849c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.29.0" + ".": "4.29.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 19dfcc62..741a701b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 4.29.1 (2024-03-15) + +Full Changelog: [v4.29.0...v4.29.1](https://github.com/openai/openai-node/compare/v4.29.0...v4.29.1) + +### Documentation + +* **readme:** assistant streaming ([#719](https://github.com/openai/openai-node/issues/719)) ([bc9a1ca](https://github.com/openai/openai-node/commit/bc9a1ca308020a88c29d409edc06cdfca8cbf8f5)) + ## 4.29.0 (2024-03-13) Full Changelog: [v4.28.5...v4.29.0](https://github.com/openai/openai-node/compare/v4.28.5...v4.29.0) diff --git a/README.md b/README.md index 93ae9f04..68d337e8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ You can import in Deno via: ```ts -import OpenAI from 'https://deno.land/x/openai@v4.29.0/mod.ts'; +import OpenAI from 'https://deno.land/x/openai@v4.29.1/mod.ts'; ``` diff --git a/build-deno b/build-deno index c49755fd..c08e26db 100755 --- a/build-deno +++ b/build-deno @@ -14,7 +14,7 @@ This is a build produced from https://github.com/openai/openai-node – please g Usage: \`\`\`ts -import OpenAI from "https://deno.land/x/openai@v4.29.0/mod.ts"; +import OpenAI from "https://deno.land/x/openai@v4.29.1/mod.ts"; const client = new OpenAI(); \`\`\` diff --git a/package.json b/package.json index ce6396c2..8a639876 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.29.0", + "version": "4.29.1", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 0de2f353..8acef11c 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.29.0'; // x-release-please-version +export const VERSION = '4.29.1'; // x-release-please-version From 05ff8f7671fe6ce5d9517034f76a166a0bd27803 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:27:15 -0400 Subject: [PATCH 27/30] docs: fix typo in CONTRIBUTING.md (#722) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9e64025..9e8f669a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,7 +68,7 @@ pnpm link -—global openai Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. ```bash -npx prism path/to/your/openapi.yml +npx prism mock path/to/your/openapi.yml ``` ```bash From 139e205ed1ed30cb1df982d852a093dcea945aba Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 19 Mar 2024 06:42:30 -0400 Subject: [PATCH 28/30] chore(internal): update generated pragma comment (#724) --- src/error.ts | 2 +- src/index.ts | 2 +- src/pagination.ts | 2 +- src/resource.ts | 2 +- src/resources/audio/audio.ts | 2 +- src/resources/audio/index.ts | 2 +- src/resources/audio/speech.ts | 2 +- src/resources/audio/transcriptions.ts | 2 +- src/resources/audio/translations.ts | 2 +- src/resources/beta/assistants/assistants.ts | 2 +- src/resources/beta/assistants/files.ts | 2 +- src/resources/beta/assistants/index.ts | 2 +- src/resources/beta/beta.ts | 2 +- src/resources/beta/chat/chat.ts | 2 +- src/resources/beta/chat/completions.ts | 2 +- src/resources/beta/chat/index.ts | 2 +- src/resources/beta/index.ts | 2 +- src/resources/beta/threads/index.ts | 2 +- src/resources/beta/threads/messages/files.ts | 2 +- src/resources/beta/threads/messages/index.ts | 2 +- src/resources/beta/threads/messages/messages.ts | 2 +- src/resources/beta/threads/runs/index.ts | 2 +- src/resources/beta/threads/runs/runs.ts | 2 +- src/resources/beta/threads/runs/steps.ts | 2 +- src/resources/beta/threads/threads.ts | 2 +- src/resources/chat/chat.ts | 2 +- src/resources/chat/completions.ts | 2 +- src/resources/chat/index.ts | 2 +- src/resources/completions.ts | 2 +- src/resources/embeddings.ts | 2 +- src/resources/files.ts | 2 +- src/resources/fine-tuning/fine-tuning.ts | 2 +- src/resources/fine-tuning/index.ts | 2 +- src/resources/fine-tuning/jobs.ts | 2 +- src/resources/images.ts | 2 +- src/resources/index.ts | 2 +- src/resources/models.ts | 2 +- src/resources/moderations.ts | 2 +- src/resources/shared.ts | 2 +- tests/api-resources/audio/speech.test.ts | 2 +- tests/api-resources/audio/transcriptions.test.ts | 2 +- tests/api-resources/audio/translations.test.ts | 2 +- tests/api-resources/beta/assistants/assistants.test.ts | 2 +- tests/api-resources/beta/assistants/files.test.ts | 2 +- tests/api-resources/beta/threads/messages/files.test.ts | 2 +- tests/api-resources/beta/threads/messages/messages.test.ts | 2 +- tests/api-resources/beta/threads/runs/runs.test.ts | 2 +- tests/api-resources/beta/threads/runs/steps.test.ts | 2 +- tests/api-resources/beta/threads/threads.test.ts | 2 +- tests/api-resources/chat/completions.test.ts | 2 +- tests/api-resources/completions.test.ts | 2 +- tests/api-resources/embeddings.test.ts | 2 +- tests/api-resources/files.test.ts | 2 +- tests/api-resources/fine-tuning/jobs.test.ts | 2 +- tests/api-resources/images.test.ts | 2 +- tests/api-resources/models.test.ts | 2 +- tests/api-resources/moderations.test.ts | 2 +- tests/index.test.ts | 2 +- 58 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/error.ts b/src/error.ts index fd7477ad..deac34c5 100644 --- a/src/error.ts +++ b/src/error.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { castToError, Headers } from './core'; diff --git a/src/index.ts b/src/index.ts index 7b3033fa..9a2b2eaa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from './core'; import * as Errors from './error'; diff --git a/src/pagination.ts b/src/pagination.ts index 5d890a14..63644e33 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { AbstractPage, Response, APIClient, FinalRequestOptions, PageInfo } from './core'; diff --git a/src/resource.ts b/src/resource.ts index 0bf87cf3..87847c87 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import type { OpenAI } from './index'; diff --git a/src/resources/audio/audio.ts b/src/resources/audio/audio.ts index 960577b0..f3fcba4c 100644 --- a/src/resources/audio/audio.ts +++ b/src/resources/audio/audio.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from 'openai/resource'; import * as SpeechAPI from 'openai/resources/audio/speech'; diff --git a/src/resources/audio/index.ts b/src/resources/audio/index.ts index 17c81d3b..31732a26 100644 --- a/src/resources/audio/index.ts +++ b/src/resources/audio/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Audio } from './audio'; export { SpeechCreateParams, Speech } from './speech'; diff --git a/src/resources/audio/speech.ts b/src/resources/audio/speech.ts index 7d0ee219..4b83bae3 100644 --- a/src/resources/audio/speech.ts +++ b/src/resources/audio/speech.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/audio/transcriptions.ts b/src/resources/audio/transcriptions.ts index ab2079ed..f01e8556 100644 --- a/src/resources/audio/transcriptions.ts +++ b/src/resources/audio/transcriptions.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/audio/translations.ts b/src/resources/audio/translations.ts index e68a714f..23493323 100644 --- a/src/resources/audio/translations.ts +++ b/src/resources/audio/translations.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/assistants/assistants.ts b/src/resources/beta/assistants/assistants.ts index b4e92fd9..1e8ca6ee 100644 --- a/src/resources/beta/assistants/assistants.ts +++ b/src/resources/beta/assistants/assistants.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/assistants/files.ts b/src/resources/beta/assistants/files.ts index 7de700e5..51fd0c0d 100644 --- a/src/resources/beta/assistants/files.ts +++ b/src/resources/beta/assistants/files.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/assistants/index.ts b/src/resources/beta/assistants/index.ts index 0ae8c9c6..c191d338 100644 --- a/src/resources/beta/assistants/index.ts +++ b/src/resources/beta/assistants/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Assistant, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 74056ed1..43ee8c7e 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from 'openai/resource'; import * as AssistantsAPI from 'openai/resources/beta/assistants/assistants'; diff --git a/src/resources/beta/chat/chat.ts b/src/resources/beta/chat/chat.ts index a9cadc68..2b4a7a40 100644 --- a/src/resources/beta/chat/chat.ts +++ b/src/resources/beta/chat/chat.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from 'openai/resource'; import * as CompletionsAPI from 'openai/resources/beta/chat/completions'; diff --git a/src/resources/beta/chat/completions.ts b/src/resources/beta/chat/completions.ts index e7f89f5c..95fd0ac7 100644 --- a/src/resources/beta/chat/completions.ts +++ b/src/resources/beta/chat/completions.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/chat/index.ts b/src/resources/beta/chat/index.ts index 8d0ee40a..23b1b8ff 100644 --- a/src/resources/beta/chat/index.ts +++ b/src/resources/beta/chat/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Chat } from './chat'; export { Completions } from './completions'; diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index d8770c29..7f35730f 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Assistant, diff --git a/src/resources/beta/threads/index.ts b/src/resources/beta/threads/index.ts index 3585be84..097a5281 100644 --- a/src/resources/beta/threads/index.ts +++ b/src/resources/beta/threads/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Annotation, diff --git a/src/resources/beta/threads/messages/files.ts b/src/resources/beta/threads/messages/files.ts index 72c01bb9..994b09d5 100644 --- a/src/resources/beta/threads/messages/files.ts +++ b/src/resources/beta/threads/messages/files.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/threads/messages/index.ts b/src/resources/beta/threads/messages/index.ts index f68edbbd..ef446d01 100644 --- a/src/resources/beta/threads/messages/index.ts +++ b/src/resources/beta/threads/messages/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Annotation, diff --git a/src/resources/beta/threads/messages/messages.ts b/src/resources/beta/threads/messages/messages.ts index b38a4bbf..a2f2aaf1 100644 --- a/src/resources/beta/threads/messages/messages.ts +++ b/src/resources/beta/threads/messages/messages.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/threads/runs/index.ts b/src/resources/beta/threads/runs/index.ts index 7fa34637..636b5d85 100644 --- a/src/resources/beta/threads/runs/index.ts +++ b/src/resources/beta/threads/runs/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { CodeInterpreterLogs, diff --git a/src/resources/beta/threads/runs/runs.ts b/src/resources/beta/threads/runs/runs.ts index 8fe09ecc..a28dd9ae 100644 --- a/src/resources/beta/threads/runs/runs.ts +++ b/src/resources/beta/threads/runs/runs.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIPromise } from 'openai/core'; diff --git a/src/resources/beta/threads/runs/steps.ts b/src/resources/beta/threads/runs/steps.ts index 4218e976..f0816fdb 100644 --- a/src/resources/beta/threads/runs/steps.ts +++ b/src/resources/beta/threads/runs/steps.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/beta/threads/threads.ts b/src/resources/beta/threads/threads.ts index cbde41f8..266f6709 100644 --- a/src/resources/beta/threads/threads.ts +++ b/src/resources/beta/threads/threads.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIPromise } from 'openai/core'; diff --git a/src/resources/chat/chat.ts b/src/resources/chat/chat.ts index 07c7700d..6c7bccb2 100644 --- a/src/resources/chat/chat.ts +++ b/src/resources/chat/chat.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from 'openai/resource'; import * as CompletionsAPI from 'openai/resources/chat/completions'; diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 41216a8e..8119639f 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIPromise } from 'openai/core'; diff --git a/src/resources/chat/index.ts b/src/resources/chat/index.ts index b8b69e45..78a7516e 100644 --- a/src/resources/chat/index.ts +++ b/src/resources/chat/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { Chat } from './chat'; export { diff --git a/src/resources/completions.ts b/src/resources/completions.ts index 83ecb3e9..b64c3a16 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIPromise } from 'openai/core'; diff --git a/src/resources/embeddings.ts b/src/resources/embeddings.ts index 3f59d2a7..208ceb24 100644 --- a/src/resources/embeddings.ts +++ b/src/resources/embeddings.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/files.ts b/src/resources/files.ts index cda487a6..820c7a1f 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/fine-tuning/fine-tuning.ts b/src/resources/fine-tuning/fine-tuning.ts index 5d2d27ac..e62f8f09 100644 --- a/src/resources/fine-tuning/fine-tuning.ts +++ b/src/resources/fine-tuning/fine-tuning.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from 'openai/resource'; import * as JobsAPI from 'openai/resources/fine-tuning/jobs'; diff --git a/src/resources/fine-tuning/index.ts b/src/resources/fine-tuning/index.ts index c2cac49a..2885f62f 100644 --- a/src/resources/fine-tuning/index.ts +++ b/src/resources/fine-tuning/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { FineTuning } from './fine-tuning'; export { diff --git a/src/resources/fine-tuning/jobs.ts b/src/resources/fine-tuning/jobs.ts index 7bc216d7..eb77405c 100644 --- a/src/resources/fine-tuning/jobs.ts +++ b/src/resources/fine-tuning/jobs.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/images.ts b/src/resources/images.ts index bc5b9edc..95f0b6ff 100644 --- a/src/resources/images.ts +++ b/src/resources/images.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/index.ts b/src/resources/index.ts index 16ce8512..a9741f5f 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export * from './chat/index'; export * from './shared'; diff --git a/src/resources/models.ts b/src/resources/models.ts index 6c6c3379..4d5bc57e 100644 --- a/src/resources/models.ts +++ b/src/resources/models.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/moderations.ts b/src/resources/moderations.ts index a43006cc..b9b9d7fc 100644 --- a/src/resources/moderations.ts +++ b/src/resources/moderations.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import * as Core from 'openai/core'; import { APIResource } from 'openai/resource'; diff --git a/src/resources/shared.ts b/src/resources/shared.ts index a6b2c11b..93fa05fa 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export interface ErrorObject { code: string | null; diff --git a/tests/api-resources/audio/speech.test.ts b/tests/api-resources/audio/speech.test.ts index b0cf1a71..18302ce9 100644 --- a/tests/api-resources/audio/speech.test.ts +++ b/tests/api-resources/audio/speech.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; diff --git a/tests/api-resources/audio/transcriptions.test.ts b/tests/api-resources/audio/transcriptions.test.ts index 33652af5..3fc4ca22 100644 --- a/tests/api-resources/audio/transcriptions.test.ts +++ b/tests/api-resources/audio/transcriptions.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI, { toFile } from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/audio/translations.test.ts b/tests/api-resources/audio/translations.test.ts index 723625f6..0853bedf 100644 --- a/tests/api-resources/audio/translations.test.ts +++ b/tests/api-resources/audio/translations.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI, { toFile } from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/assistants/assistants.test.ts b/tests/api-resources/beta/assistants/assistants.test.ts index 60ca0a6e..b11075d0 100644 --- a/tests/api-resources/beta/assistants/assistants.test.ts +++ b/tests/api-resources/beta/assistants/assistants.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/assistants/files.test.ts b/tests/api-resources/beta/assistants/files.test.ts index 8db32844..e285b466 100644 --- a/tests/api-resources/beta/assistants/files.test.ts +++ b/tests/api-resources/beta/assistants/files.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/threads/messages/files.test.ts b/tests/api-resources/beta/threads/messages/files.test.ts index b4a00a86..58c8813f 100644 --- a/tests/api-resources/beta/threads/messages/files.test.ts +++ b/tests/api-resources/beta/threads/messages/files.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/threads/messages/messages.test.ts b/tests/api-resources/beta/threads/messages/messages.test.ts index 35538efb..3a80bfe1 100644 --- a/tests/api-resources/beta/threads/messages/messages.test.ts +++ b/tests/api-resources/beta/threads/messages/messages.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/threads/runs/runs.test.ts b/tests/api-resources/beta/threads/runs/runs.test.ts index 45f17040..5e1b363f 100644 --- a/tests/api-resources/beta/threads/runs/runs.test.ts +++ b/tests/api-resources/beta/threads/runs/runs.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/threads/runs/steps.test.ts b/tests/api-resources/beta/threads/runs/steps.test.ts index 76eec269..76495a1a 100644 --- a/tests/api-resources/beta/threads/runs/steps.test.ts +++ b/tests/api-resources/beta/threads/runs/steps.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/beta/threads/threads.test.ts b/tests/api-resources/beta/threads/threads.test.ts index 9243dc11..24cb815a 100644 --- a/tests/api-resources/beta/threads/threads.test.ts +++ b/tests/api-resources/beta/threads/threads.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/chat/completions.test.ts b/tests/api-resources/chat/completions.test.ts index 49f3562b..e0ccb391 100644 --- a/tests/api-resources/chat/completions.test.ts +++ b/tests/api-resources/chat/completions.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/completions.test.ts b/tests/api-resources/completions.test.ts index 85fc6849..2641bf7e 100644 --- a/tests/api-resources/completions.test.ts +++ b/tests/api-resources/completions.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/embeddings.test.ts b/tests/api-resources/embeddings.test.ts index bcb5ffbb..d4e1f324 100644 --- a/tests/api-resources/embeddings.test.ts +++ b/tests/api-resources/embeddings.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/files.test.ts b/tests/api-resources/files.test.ts index 9e6373ab..514f42e3 100644 --- a/tests/api-resources/files.test.ts +++ b/tests/api-resources/files.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI, { toFile } from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/fine-tuning/jobs.test.ts b/tests/api-resources/fine-tuning/jobs.test.ts index 22f45730..d8f230ab 100644 --- a/tests/api-resources/fine-tuning/jobs.test.ts +++ b/tests/api-resources/fine-tuning/jobs.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/images.test.ts b/tests/api-resources/images.test.ts index 418a55eb..33d633a6 100644 --- a/tests/api-resources/images.test.ts +++ b/tests/api-resources/images.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI, { toFile } from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/models.test.ts b/tests/api-resources/models.test.ts index 91eb0d05..ca1f9836 100644 --- a/tests/api-resources/models.test.ts +++ b/tests/api-resources/models.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/api-resources/moderations.test.ts b/tests/api-resources/moderations.test.ts index ad315df5..ef7298fa 100644 --- a/tests/api-resources/moderations.test.ts +++ b/tests/api-resources/moderations.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { Response } from 'node-fetch'; diff --git a/tests/index.test.ts b/tests/index.test.ts index 3fb42a80..cd5f2a0a 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,4 +1,4 @@ -// File generated from our OpenAPI spec by Stainless. +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import OpenAI from 'openai'; import { APIUserAbortError } from 'openai'; From 6a2c41b0ce833eba0cdea6a7d221697f3be26abb Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:13:42 -0400 Subject: [PATCH 29/30] docs: assistant improvements (#725) --- README.md | 31 +++++++++++++++++++++++++++++++ helpers.md | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 68d337e8..1eca06c8 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,37 @@ Documentation for each method, request param, and response field are available i > [!IMPORTANT] > Previous versions of this SDK used a `Configuration` class. See the [v3 to v4 migration guide](https://github.com/openai/openai-node/discussions/217). +### Streaming Helpers + +The SDK also includes helpers to process streams and handle the incoming events. + +```ts +const run = openai.beta.threads.runs + .createAndStream(thread.id, { + assistant_id: assistant.id, + }) + .on('textCreated', (text) => process.stdout.write('\nassistant > ')) + .on('textDelta', (textDelta, snapshot) => process.stdout.write(textDelta.value)) + .on('toolCallCreated', (toolCall) => process.stdout.write(`\nassistant > ${toolCall.type}\n\n`)) + .on('toolCallDelta', (toolCallDelta, snapshot) => { + if (toolCallDelta.type === 'code_interpreter') { + if (toolCallDelta.code_interpreter.input) { + process.stdout.write(toolCallDelta.code_interpreter.input); + } + if (toolCallDelta.code_interpreter.outputs) { + process.stdout.write('\noutput >\n'); + toolCallDelta.code_interpreter.outputs.forEach((output) => { + if (output.type === 'logs') { + process.stdout.write(`\n${output.logs}\n`); + } + }); + } + } + }); +``` + +More information on streaming helpers can be found in the dedicated documentation: [helpers.md](helpers.md) + ### Streaming responses This library provides several conveniences for streaming chat completions, for example: diff --git a/helpers.md b/helpers.md index 9f01a126..9a94a618 100644 --- a/helpers.md +++ b/helpers.md @@ -36,6 +36,29 @@ const run = openai.beta.threads.runs }); ``` +### Starting a stream + +There are three helper methods for creating streams: + +```ts +openai.beta.threads.runs.createAndStream(); +``` + +This method can be used to start and stream the response to an existing run with an associated thread +that is already populated with messages. + +```ts +openai.beta.threads.createAndRunStream(); +``` + +This method can be used to add a message to a thread, start a run and then stream the response. + +```ts +openai.beta.threads.runs.submitToolOutputsStream(); +``` + +This method can be used to submit a tool output to a run waiting on the output and start a stream. + ### Assistant Events The assistant API provides events you can subscribe to for the following events. @@ -108,25 +131,25 @@ The last event send when a stream ends. The assistant streaming object also provides a few methods for convenience: ```ts -.currentEvent() +.currentEvent(): AssistantStreamEvent | undefined -.currentRun() +.currentRun(): Run | undefined -.currentMessageSnapshot() +.currentMessageSnapshot(): Message -.currentRunStepSnapshot() +.currentRunStepSnapshot(): Runs.RunStep ``` These methods are provided to allow you to access additional context from within event handlers. In many cases the handlers should include all the information you need for processing, but if additional context is required it can be accessed. -Note: There is not always a relevant context in certain situations (these will be undefined in those cases). +Note: There is not always a relevant context in certain situations (these will be `undefined` in those cases). ```ts -await.finalMessages(); +await .finalMessages() : Promise -await.finalRunSteps(); +await .finalRunSteps(): Promise ``` These methods are provided for convenience to collect information at the end of a stream. Calling these events From dda3f6890cf6a6b8f885a6470240b3036eab3b09 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:14:03 -0400 Subject: [PATCH 30/30] release: 4.29.2 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- build-deno | 2 +- package.json | 2 +- src/version.ts | 2 +- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ded4849c..fc4efb3a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.29.1" + ".": "4.29.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 741a701b..497a341a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 4.29.2 (2024-03-19) + +Full Changelog: [v4.29.1...v4.29.2](https://github.com/openai/openai-node/compare/v4.29.1...v4.29.2) + +### Chores + +* **internal:** update generated pragma comment ([#724](https://github.com/openai/openai-node/issues/724)) ([139e205](https://github.com/openai/openai-node/commit/139e205ed1ed30cb1df982d852a093dcea945aba)) + + +### Documentation + +* assistant improvements ([#725](https://github.com/openai/openai-node/issues/725)) ([6a2c41b](https://github.com/openai/openai-node/commit/6a2c41b0ce833eba0cdea6a7d221697f3be26abb)) +* fix typo in CONTRIBUTING.md ([#722](https://github.com/openai/openai-node/issues/722)) ([05ff8f7](https://github.com/openai/openai-node/commit/05ff8f7671fe6ce5d9517034f76a166a0bd27803)) + ## 4.29.1 (2024-03-15) Full Changelog: [v4.29.0...v4.29.1](https://github.com/openai/openai-node/compare/v4.29.0...v4.29.1) diff --git a/README.md b/README.md index 1eca06c8..9699fca4 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ You can import in Deno via: ```ts -import OpenAI from 'https://deno.land/x/openai@v4.29.1/mod.ts'; +import OpenAI from 'https://deno.land/x/openai@v4.29.2/mod.ts'; ``` diff --git a/build-deno b/build-deno index c08e26db..25569475 100755 --- a/build-deno +++ b/build-deno @@ -14,7 +14,7 @@ This is a build produced from https://github.com/openai/openai-node – please g Usage: \`\`\`ts -import OpenAI from "https://deno.land/x/openai@v4.29.1/mod.ts"; +import OpenAI from "https://deno.land/x/openai@v4.29.2/mod.ts"; const client = new OpenAI(); \`\`\` diff --git a/package.json b/package.json index 8a639876..25994c23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.29.1", + "version": "4.29.2", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 8acef11c..a9177ff5 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.29.1'; // x-release-please-version +export const VERSION = '4.29.2'; // x-release-please-version