diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3210fc7..aeb4491d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,12 +7,17 @@ on: - 'integrated/**' - 'stl-preview-head/**' - 'stl-preview-base/**' + pull_request: + branches-ignore: + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint runs-on: ${{ github.repository == 'stainless-sdks/togetherai-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@v4 @@ -31,6 +36,7 @@ jobs: timeout-minutes: 5 name: build runs-on: ${{ github.repository == 'stainless-sdks/togetherai-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork permissions: contents: read id-token: write @@ -66,13 +72,14 @@ jobs: timeout-minutes: 10 name: test runs-on: ${{ github.repository == 'stainless-sdks/togetherai-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@v4 - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 905d21e6..397cf896 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v3 with: - node-version: '18' + node-version: '20' - name: Install dependencies run: | diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bc7e4aae..7b51ca08 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.16.0" + ".": "0.17.0" } diff --git a/.stats.yml b/.stats.yml index d9d1b62f..934a5794 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 28 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-c949fc43297a5155ea4c433179ee6f0822e25a351f180a5539871687daead7ad.yml -openapi_spec_hash: ca24d10b37e987becfd16b30ea342459 -config_hash: a60b100624e80dc8d9144e7bc306f5ce +configured_endpoints: 33 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-0587b28a7ae7d241b442a774d024d83dc7d3aaea6d51ecc9bb825888f53a60ce.yml +openapi_spec_hash: 2bccc6c37221bacda7bc3f486fc4684d +config_hash: ae07f8cefe84a8a01ae2d0c8ddc2ef32 diff --git a/CHANGELOG.md b/CHANGELOG.md index d7764b09..766afc03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # Changelog +## 0.17.0 (2025-06-27) + +Full Changelog: [v0.16.0...v0.17.0](https://github.com/togethercomputer/together-typescript/compare/v0.16.0...v0.17.0) + +### Features + +* **api:** add batch api to config ([d51bc5a](https://github.com/togethercomputer/together-typescript/commit/d51bc5aef6cdc4d28ece075adaae4e21b3ad9c28)) +* **api:** Add file_type and file_purpose ([c48b452](https://github.com/togethercomputer/together-typescript/commit/c48b452006a360c32dc4c270740b3e7c8e5ea5b8)) +* **api:** add files/upload apu support and switch upload_file method over to use it. ([c365c86](https://github.com/togethercomputer/together-typescript/commit/c365c86033d20ef677e95707ccd4b3fe43c679a2)) +* **api:** address diagnostic issues in audio api, correct openapi issue in images api, disambiguate a response in finetune api, enable automated testing on finetune and images ([9ab1b66](https://github.com/togethercomputer/together-typescript/commit/9ab1b661c4d830b982e1e2a5a184564c9c16e815)) +* **api:** api update ([4411078](https://github.com/togethercomputer/together-typescript/commit/4411078dad04fdfa6247e6b127d29248a796859c)) +* **api:** api update ([e361be3](https://github.com/togethercomputer/together-typescript/commit/e361be3aa6fd65031e99018c0f2dd88d819c8657)) +* **api:** api update ([850a7da](https://github.com/togethercomputer/together-typescript/commit/850a7da0fcc711164290db4a88e07e31762e9d1f)) +* **api:** api update ([5d0865a](https://github.com/togethercomputer/together-typescript/commit/5d0865add14b040531018e85e59a38ee805a5a41)) +* **api:** api update ([f06baab](https://github.com/togethercomputer/together-typescript/commit/f06baab288f7f54d73ad803550b9f3ce55ab6756)) +* **api:** api update ([8de2307](https://github.com/togethercomputer/together-typescript/commit/8de23078f5b12ace4df74173a0e5fa0c86528d2d)) +* **api:** api update ([d7d7c68](https://github.com/togethercomputer/together-typescript/commit/d7d7c686ca1a2c665d58323bbc5498671c4ee5ef)) +* **api:** api update ([d7b7e65](https://github.com/togethercomputer/together-typescript/commit/d7b7e65ffab825567353d021f8ea1715a0e3b578)) +* **api:** api update ([a149f12](https://github.com/togethercomputer/together-typescript/commit/a149f12a4ed7d852aef5448c827d86bbebe2ebf4)) +* **api:** api update ([dac80cc](https://github.com/togethercomputer/together-typescript/commit/dac80cc60458d89fced596b22a3700be3d7a6c04)) +* **api:** api update ([418cdbf](https://github.com/togethercomputer/together-typescript/commit/418cdbf1c267c33e2f01e4b3d48aa21c6a618268)) +* **api:** Formatting fixes, some lint fixes ([ba11056](https://github.com/togethercomputer/together-typescript/commit/ba11056c22c6ce4ab829356d35a4c31540a2d5e1)) +* **api:** get test_code_interpreter passing ([426d647](https://github.com/togethercomputer/together-typescript/commit/426d647fa45c2220f7293f26c1b79336c0e948df)) +* **api:** update spec / config to remove remaining codegen warnings ([c7c3a91](https://github.com/togethercomputer/together-typescript/commit/c7c3a914e2b0bb866b01ba48a04add83bbb387cd)) +* **api:** Update spec and config to get all tests except code-interpolation an fine_tune unit tests working. ([ac5a26e](https://github.com/togethercomputer/together-typescript/commit/ac5a26e7a65e66e3e7cdb3e83dbe75016c1f785f)) +* **client:** add support for endpoint-specific base URLs ([7d7bb0c](https://github.com/togethercomputer/together-typescript/commit/7d7bb0c308b909713ef0a0fedbe7acea59594946)) + + +### Bug Fixes + +* **ci:** release-doctor — report correct token name ([1b53f5b](https://github.com/togethercomputer/together-typescript/commit/1b53f5b8e355bf392c5da836b315d1c067e70023)) +* publish script — handle NPM errors correctly ([471c909](https://github.com/togethercomputer/together-typescript/commit/471c909ff1918076168d6dd221561c94a24bd947)) +* **tests:** format ([0ad22a6](https://github.com/togethercomputer/together-typescript/commit/0ad22a67f73dce1d4d596c353a31be5abbd1e092)) +* **tests:** remove unused tests ([26a5b65](https://github.com/togethercomputer/together-typescript/commit/26a5b65b48b4a20ac75cdc92b27c55e26b686382)) + + +### Chores + +* **api:** re-enable audio unit tests ([9b41a24](https://github.com/togethercomputer/together-typescript/commit/9b41a241c1d5a89b610ea76b96955b6896f433f1)) +* **ci:** bump node version for release workflows ([328ac07](https://github.com/togethercomputer/together-typescript/commit/328ac079658f878a74a28c3683e340bed6f15876)) +* **ci:** enable for pull requests ([e393ec0](https://github.com/togethercomputer/together-typescript/commit/e393ec0952cb571617df474597a8bdbdfbdf86ff)) +* **ci:** only run for pushes and fork pull requests ([0c5464d](https://github.com/togethercomputer/together-typescript/commit/0c5464dcd9a3038f15ff738db569a567efd2d001)) +* **docs:** grammar improvements ([fcc89b0](https://github.com/togethercomputer/together-typescript/commit/fcc89b0d13f7907fdb33ab23398ebae0003ec96e)) +* **docs:** use top-level-await in example snippets ([24e6833](https://github.com/togethercomputer/together-typescript/commit/24e68333612469dcd5ec1bbd30993cb1d46ed61d)) +* improve publish-npm script --latest tag logic ([6efef6c](https://github.com/togethercomputer/together-typescript/commit/6efef6c02fb2160f1b1a0ac33d128e4b45bf7ef3)) +* **internal:** make base APIResource abstract ([d64b679](https://github.com/togethercomputer/together-typescript/commit/d64b6790659e223a1e003396d39dcd95fe35ef0e)) + + +### Documentation + +* add examples to tsdocs ([e3bdd28](https://github.com/togethercomputer/together-typescript/commit/e3bdd286bdca4d56cae2b106f15283f594b05200)) +* **readme:** fix typo ([29c08f6](https://github.com/togethercomputer/together-typescript/commit/29c08f6c4126aa2a576aea5cbc0d16b033a9a04e)) + + +### Refactors + +* **types:** replace Record with mapped types ([c075e7e](https://github.com/togethercomputer/together-typescript/commit/c075e7eb2a447d4dfc6aca0f283f760f80c277a3)) + ## 0.16.0 (2025-04-28) Full Changelog: [v0.15.2...v0.16.0](https://github.com/togethercomputer/together-typescript/compare/v0.15.2...v0.16.0) diff --git a/README.md b/README.md index 202f7bc2..16be6839 100644 --- a/README.md +++ b/README.md @@ -26,16 +26,12 @@ const client = new Together({ apiKey: process.env['TOGETHER_API_KEY'], // This is the default and can be omitted }); -async function main() { - const chatCompletion = await client.chat.completions.create({ - messages: [{ role: 'user', content: 'Say this is a test!' }], - model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', - }); - - console.log(chatCompletion.choices); -} +const chatCompletion = await client.chat.completions.create({ + messages: [{ role: 'user', content: 'Say this is a test!' }], + model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', +}); -main(); +console.log(chatCompletion.choices); ``` ## Streaming responses @@ -72,19 +68,65 @@ const client = new Together({ apiKey: process.env['TOGETHER_API_KEY'], // This is the default and can be omitted }); -async function main() { - const params: Together.Chat.CompletionCreateParams = { - messages: [{ role: 'user', content: 'Say this is a test' }], - model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', - }; - const chatCompletion: Together.Chat.ChatCompletion = await client.chat.completions.create(params); -} - -main(); +const params: Together.Chat.CompletionCreateParams = { + messages: [{ role: 'user', content: 'Say this is a test' }], + model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', +}; +const chatCompletion: Together.Chat.ChatCompletion = await client.chat.completions.create(params); ``` Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors. +## File uploads + +Request parameters that correspond to file uploads can be passed in many different forms: + +- `File` (or an object with the same structure) +- a `fetch` `Response` (or an object with the same structure) +- an `fs.ReadStream` +- the return value of our `toFile` helper + +```ts +import fs from 'fs'; +import fetch from 'node-fetch'; +import Together, { toFile } from 'together-ai'; + +const client = new Together(); + +// If you have access to Node `fs` we recommend using `fs.createReadStream()`: +await client.files.upload({ + file: fs.createReadStream('/path/to/file'), + file_name: 'dataset.csv', + purpose: 'fine-tune', +}); + +// Or if you have the web `File` API you can pass a `File` instance: +await client.files.upload({ + file: new File(['my bytes'], 'file'), + file_name: 'dataset.csv', + purpose: 'fine-tune', +}); + +// You can also pass a `fetch` `Response`: +await client.files.upload({ + file: await fetch('https://somesite/file'), + file_name: 'dataset.csv', + purpose: 'fine-tune', +}); + +// Finally, if none of the above are convenient, you can use our `toFile` helper: +await client.files.upload({ + file: await toFile(Buffer.from('my bytes'), 'file'), + file_name: 'dataset.csv', + purpose: 'fine-tune', +}); +await client.files.upload({ + file: await toFile(new Uint8Array([0, 1, 2]), 'file'), + file_name: 'dataset.csv', + purpose: 'fine-tune', +}); +``` + ## Handling errors When the library is unable to connect to the API, @@ -93,27 +135,23 @@ a subclass of `APIError` will be thrown: ```ts -async function main() { - const chatCompletion = await client.chat.completions - .create({ - messages: [{ role: 'user', content: 'Say this is a test' }], - model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', - }) - .catch(async (err) => { - if (err instanceof Together.APIError) { - console.log(err.status); // 400 - console.log(err.name); // BadRequestError - console.log(err.headers); // {server: 'nginx', ...} - } else { - throw err; - } - }); -} - -main(); +const chatCompletion = await client.chat.completions + .create({ + messages: [{ role: 'user', content: 'Say this is a test' }], + model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', + }) + .catch(async (err) => { + if (err instanceof Together.APIError) { + console.log(err.status); // 400 + console.log(err.name); // BadRequestError + console.log(err.headers); // {server: 'nginx', ...} + } else { + throw err; + } + }); ``` -Error codes are as followed: +Error codes are as follows: | Status Code | Error Type | | ----------- | -------------------------- | diff --git a/SECURITY.md b/SECURITY.md index c39aa7c8..5f4fe0ec 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,11 +16,11 @@ before making any information public. ## Reporting Non-SDK Related Security Issues If you encounter security issues that are not directly related to SDKs but pertain to the services -or products provided by Together please follow the respective company's security reporting guidelines. +or products provided by Together, please follow the respective company's security reporting guidelines. ### Together Terms and Policies -Please contact dev-feedback@TogetherAI.com for any questions or concerns regarding security of our services. +Please contact dev-feedback@TogetherAI.com for any questions or concerns regarding the security of our services. --- diff --git a/api.md b/api.md index 154059df..db3b88be 100644 --- a/api.md +++ b/api.md @@ -25,6 +25,7 @@ Types: - ChatCompletionToolMessageParam - ChatCompletionStructuredMessageImageURL - ChatCompletionStructuredMessageText +- ChatCompletionStructuredMessageVideoURL - ChatCompletionUsage - ChatCompletionUserMessageParam @@ -37,6 +38,7 @@ Methods: Types: - Completion +- CompletionChunk - LogProbs - ToolChoice - Tools @@ -60,9 +62,12 @@ Methods: Types: - FileObject +- FilePurpose +- FileType - FileRetrieveResponse - FileListResponse - FileDeleteResponse +- FileUploadResponse Methods: @@ -70,24 +75,37 @@ Methods: - client.files.list() -> FileListResponse - client.files.delete(id) -> FileDeleteResponse - client.files.content(id) -> Response +- client.files.upload({ ...params }) -> FileUploadResponse # FineTune Types: +- CosineLrSchedulerArgs - FineTune - FineTuneEvent +- FullTrainingType +- LinearLrSchedulerArgs +- LoRaTrainingType +- LrScheduler +- TrainingMethodDpo +- TrainingMethodSft +- FineTuneCreateResponse - FineTuneListResponse +- FineTuneCancelResponse - FineTuneDownloadResponse +- FineTuneListEventsResponse +- FineTuneRetrieveCheckpointsResponse Methods: -- client.fineTune.create({ ...params }) -> FineTune +- client.fineTune.create({ ...params }) -> FineTuneCreateResponse - client.fineTune.retrieve(id) -> FineTune - client.fineTune.list() -> FineTuneListResponse -- client.fineTune.cancel(id) -> FineTune +- client.fineTune.cancel(id) -> FineTuneCancelResponse - client.fineTune.download({ ...params }) -> FineTuneDownloadResponse -- client.fineTune.listEvents(id) -> FineTuneEvent +- client.fineTune.listEvents(id) -> FineTuneListEventsResponse +- client.fineTune.retrieveCheckpoints(id) -> FineTuneRetrieveCheckpointsResponse # CodeInterpreter @@ -113,6 +131,8 @@ Methods: Types: +- ImageDataB64 +- ImageDataURL - ImageFile Methods: @@ -124,6 +144,7 @@ Methods: Types: - AudioFile +- AudioSpeechStreamChunk Methods: @@ -157,6 +178,7 @@ Methods: Types: +- Autoscaling - EndpointCreateResponse - EndpointRetrieveResponse - EndpointUpdateResponse @@ -179,3 +201,17 @@ Types: Methods: - client.hardware.list({ ...params }) -> HardwareListResponse + +# Batches + +Types: + +- BatchCreateResponse +- BatchRetrieveResponse +- BatchListResponse + +Methods: + +- client.batches.create({ ...params }) -> BatchCreateResponse +- client.batches.retrieve(id) -> BatchRetrieveResponse +- client.batches.list() -> BatchListResponse diff --git a/bin/check-release-environment b/bin/check-release-environment index 88071232..e4b6d58e 100644 --- a/bin/check-release-environment +++ b/bin/check-release-environment @@ -3,7 +3,7 @@ errors=() if [ -z "${NPM_TOKEN}" ]; then - errors+=("The TOGETHER_NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets") + errors+=("The NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets") fi lenErrors=${#errors[@]} diff --git a/bin/publish-npm b/bin/publish-npm index 4c21181b..fa2243d2 100644 --- a/bin/publish-npm +++ b/bin/publish-npm @@ -4,19 +4,55 @@ set -eux npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN" -# Build the project yarn build - -# Navigate to the dist directory cd dist -# Get the version from package.json -VERSION="$(node -p "require('./package.json').version")" +# Get package name and version from package.json +PACKAGE_NAME="$(jq -r -e '.name' ./package.json)" +VERSION="$(jq -r -e '.version' ./package.json)" + +# Get latest version from npm +# +# If the package doesn't exist, npm will return: +# { +# "error": { +# "code": "E404", +# "summary": "Unpublished on 2025-06-05T09:54:53.528Z", +# "detail": "'the_package' is not in this registry..." +# } +# } +NPM_INFO="$(npm view "$PACKAGE_NAME" version --json 2>/dev/null || true)" + +# Check if we got an E404 error +if echo "$NPM_INFO" | jq -e '.error.code == "E404"' > /dev/null 2>&1; then + # Package doesn't exist yet, no last version + LAST_VERSION="" +elif echo "$NPM_INFO" | jq -e '.error' > /dev/null 2>&1; then + # Report other errors + echo "ERROR: npm returned unexpected data:" + echo "$NPM_INFO" + exit 1 +else + # Success - get the version + LAST_VERSION=$(echo "$NPM_INFO" | jq -r '.') # strip quotes +fi -# Extract the pre-release tag if it exists +# Check if current version is pre-release (e.g. alpha / beta / rc) +CURRENT_IS_PRERELEASE=false if [[ "$VERSION" =~ -([a-zA-Z]+) ]]; then - # Extract the part before any dot in the pre-release identifier - TAG="${BASH_REMATCH[1]}" + CURRENT_IS_PRERELEASE=true + CURRENT_TAG="${BASH_REMATCH[1]}" +fi + +# Check if last version is a stable release +LAST_IS_STABLE_RELEASE=true +if [[ -z "$LAST_VERSION" || "$LAST_VERSION" =~ -([a-zA-Z]+) ]]; then + LAST_IS_STABLE_RELEASE=false +fi + +# Use a corresponding alpha/beta tag if there already is a stable release and we're publishing a prerelease. +if $CURRENT_IS_PRERELEASE && $LAST_IS_STABLE_RELEASE; then + TAG="$CURRENT_TAG" else TAG="latest" fi diff --git a/package.json b/package.json index ef6a0e04..a3d99a25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "together-ai", - "version": "0.16.0", + "version": "0.17.0", "description": "The official TypeScript library for the Together API", "author": "Together ", "types": "dist/index.d.ts", diff --git a/scripts/build b/scripts/build index 3d350e76..019e4f72 100755 --- a/scripts/build +++ b/scripts/build @@ -28,7 +28,7 @@ fi node scripts/utils/make-dist-package-json.cjs > dist/package.json # build to .js/.mjs/.d.ts files -npm exec tsc-multi +./node_modules/.bin/tsc-multi # copy over handwritten .js/.mjs/.d.ts files cp src/_shims/*.{d.ts,js,mjs,md} dist/_shims cp src/_shims/auto/*.{d.ts,js,mjs} dist/_shims/auto diff --git a/src/core.ts b/src/core.ts index fe1e225b..779e349a 100644 --- a/src/core.ts +++ b/src/core.ts @@ -184,6 +184,7 @@ export class APIPromise extends Promise { export abstract class APIClient { baseURL: string; + #baseURLOverridden: boolean; maxRetries: number; timeout: number; httpAgent: Agent | undefined; @@ -193,18 +194,21 @@ export abstract class APIClient { constructor({ baseURL, + baseURLOverridden, maxRetries = 5, timeout = 60000, // 1 minute httpAgent, fetch: overriddenFetch, }: { baseURL: string; + baseURLOverridden: boolean; maxRetries?: number | undefined; timeout: number | undefined; httpAgent: Agent | undefined; fetch: Fetch | undefined; }) { this.baseURL = baseURL; + this.#baseURLOverridden = baseURLOverridden; this.maxRetries = validatePositiveInteger('maxRetries', maxRetries); this.timeout = validatePositiveInteger('timeout', timeout); this.httpAgent = httpAgent; @@ -314,7 +318,7 @@ export abstract class APIClient { { retryCount = 0 }: { retryCount?: number } = {}, ): { req: RequestInit; url: string; timeout: number } { const options = { ...inputOptions }; - const { method, path, query, headers: headers = {} } = options; + const { method, path, query, defaultBaseURL, headers: headers = {} } = options; const body = ArrayBuffer.isView(options.body) || (options.__binaryRequest && typeof options.body === 'string') ? @@ -324,7 +328,7 @@ export abstract class APIClient { : null; const contentLength = this.calculateContentLength(body); - const url = this.buildURL(path!, query); + const url = this.buildURL(path!, query, defaultBaseURL); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); options.timeout = options.timeout ?? this.timeout; const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url); @@ -517,11 +521,12 @@ export abstract class APIClient { return new PagePromise(this, request, Page); } - buildURL(path: string, query: Req | null | undefined): string { + buildURL(path: string, query: Req | null | undefined, defaultBaseURL?: string | undefined): string { + const baseURL = (!this.#baseURLOverridden && defaultBaseURL) || this.baseURL; const url = isAbsoluteURL(path) ? new URL(path) - : new URL(this.baseURL + (this.baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path)); + : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path)); const defaultQuery = this.defaultQuery(); if (!isEmptyObj(defaultQuery)) { @@ -806,6 +811,7 @@ export type RequestOptions< query?: Req | undefined; body?: Req | null | undefined; headers?: Headers | undefined; + defaultBaseURL?: string | undefined; maxRetries?: number; stream?: boolean | undefined; @@ -828,6 +834,7 @@ const requestOptionsKeys: KeysEnum = { query: true, body: true, headers: true, + defaultBaseURL: true, maxRetries: true, stream: true, diff --git a/src/index.ts b/src/index.ts index 8613bac0..6a40c245 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,9 +7,24 @@ import * as Uploads from './uploads'; import * as API from './resources/index'; import * as TopLevelAPI from './resources/top-level'; import { RerankParams, RerankResponse } from './resources/top-level'; -import { Audio, AudioCreateParams, AudioFile } from './resources/audio'; +import { + Audio, + AudioCreateParams, + AudioCreateParamsNonStreaming, + AudioCreateParamsStreaming, + AudioFile, + AudioSpeechStreamChunk, +} from './resources/audio'; +import { + BatchCreateParams, + BatchCreateResponse, + BatchListResponse, + BatchRetrieveResponse, + Batches, +} from './resources/batches'; import { Completion, + CompletionChunk, CompletionCreateParams, CompletionCreateParamsNonStreaming, CompletionCreateParamsStreaming, @@ -20,6 +35,7 @@ import { } from './resources/completions'; import { Embedding, EmbeddingCreateParams, Embeddings } from './resources/embeddings'; import { + Autoscaling, EndpointCreateParams, EndpointCreateResponse, EndpointListParams, @@ -33,20 +49,35 @@ import { FileDeleteResponse, FileListResponse, FileObject, + FilePurpose, FileRetrieveResponse, + FileType, + FileUploadParams, + FileUploadResponse, Files, } from './resources/files'; import { + CosineLrSchedulerArgs, FineTune, + FineTuneCancelResponse, FineTuneCreateParams, + FineTuneCreateResponse, FineTuneDownloadParams, FineTuneDownloadResponse, FineTuneEvent, + FineTuneListEventsResponse, FineTuneListResponse, FineTuneResource, + FineTuneRetrieveCheckpointsResponse, + FullTrainingType, + LinearLrSchedulerArgs, + LoRaTrainingType, + LrScheduler, + TrainingMethodDpo, + TrainingMethodSft, } from './resources/fine-tune'; import { Hardware, HardwareListParams, HardwareListResponse } from './resources/hardware'; -import { ImageCreateParams, ImageFile, Images } from './resources/images'; +import { ImageCreateParams, ImageDataB64, ImageDataURL, ImageFile, Images } from './resources/images'; import { JobListResponse, JobRetrieveResponse, Jobs } from './resources/jobs'; import { ModelListResponse, ModelUploadParams, ModelUploadResponse, Models } from './resources/models'; import { Chat } from './resources/chat/chat'; @@ -158,6 +189,7 @@ export class Together extends Core.APIClient { super({ baseURL: options.baseURL!, + baseURLOverridden: baseURL ? baseURL !== 'https://api.together.xyz/v1' : false, timeout: options.timeout ?? 60000 /* 1 minute */, httpAgent: options.httpAgent, maxRetries: options.maxRetries, @@ -181,9 +213,31 @@ export class Together extends Core.APIClient { jobs: API.Jobs = new API.Jobs(this); endpoints: API.Endpoints = new API.Endpoints(this); hardware: API.Hardware = new API.Hardware(this); + batches: API.Batches = new API.Batches(this); + + /** + * Check whether the base URL is set to its default. + */ + #baseURLOverridden(): boolean { + return this.baseURL !== 'https://api.together.xyz/v1'; + } /** * Query a reranker model + * + * @example + * ```ts + * const response = await client.rerank({ + * documents: [ + * { title: 'bar', text: 'bar' }, + * { title: 'bar', text: 'bar' }, + * { title: 'bar', text: 'bar' }, + * { title: 'bar', text: 'bar' }, + * ], + * model: 'Salesforce/Llama-Rank-V1', + * query: 'What animals can I find near Peru?', + * }); + * ``` */ rerank( body: TopLevelAPI.RerankParams, @@ -240,6 +294,7 @@ Together.Models = Models; Together.Jobs = Jobs; Together.Endpoints = Endpoints; Together.Hardware = Hardware; +Together.Batches = Batches; export declare namespace Together { export type RequestOptions = Core.RequestOptions; @@ -250,6 +305,7 @@ export declare namespace Together { export { Completions as Completions, type Completion as Completion, + type CompletionChunk as CompletionChunk, type LogProbs as LogProbs, type ToolChoice as ToolChoice, type Tools as Tools, @@ -267,17 +323,32 @@ export declare namespace Together { export { Files as Files, type FileObject as FileObject, + type FilePurpose as FilePurpose, + type FileType as FileType, type FileRetrieveResponse as FileRetrieveResponse, type FileListResponse as FileListResponse, type FileDeleteResponse as FileDeleteResponse, + type FileUploadResponse as FileUploadResponse, + type FileUploadParams as FileUploadParams, }; export { FineTuneResource as FineTuneResource, + type CosineLrSchedulerArgs as CosineLrSchedulerArgs, type FineTune as FineTune, type FineTuneEvent as FineTuneEvent, + type FullTrainingType as FullTrainingType, + type LinearLrSchedulerArgs as LinearLrSchedulerArgs, + type LoRaTrainingType as LoRaTrainingType, + type LrScheduler as LrScheduler, + type TrainingMethodDpo as TrainingMethodDpo, + type TrainingMethodSft as TrainingMethodSft, + type FineTuneCreateResponse as FineTuneCreateResponse, type FineTuneListResponse as FineTuneListResponse, + type FineTuneCancelResponse as FineTuneCancelResponse, type FineTuneDownloadResponse as FineTuneDownloadResponse, + type FineTuneListEventsResponse as FineTuneListEventsResponse, + type FineTuneRetrieveCheckpointsResponse as FineTuneRetrieveCheckpointsResponse, type FineTuneCreateParams as FineTuneCreateParams, type FineTuneDownloadParams as FineTuneDownloadParams, }; @@ -288,9 +359,22 @@ export declare namespace Together { type CodeInterpreterExecuteParams as CodeInterpreterExecuteParams, }; - export { Images as Images, type ImageFile as ImageFile, type ImageCreateParams as ImageCreateParams }; + export { + Images as Images, + type ImageDataB64 as ImageDataB64, + type ImageDataURL as ImageDataURL, + type ImageFile as ImageFile, + type ImageCreateParams as ImageCreateParams, + }; - export { Audio as Audio, type AudioFile as AudioFile, type AudioCreateParams as AudioCreateParams }; + export { + Audio as Audio, + type AudioFile as AudioFile, + type AudioSpeechStreamChunk as AudioSpeechStreamChunk, + type AudioCreateParams as AudioCreateParams, + type AudioCreateParamsNonStreaming as AudioCreateParamsNonStreaming, + type AudioCreateParamsStreaming as AudioCreateParamsStreaming, + }; export { Models as Models, @@ -307,6 +391,7 @@ export declare namespace Together { export { Endpoints as Endpoints, + type Autoscaling as Autoscaling, type EndpointCreateResponse as EndpointCreateResponse, type EndpointRetrieveResponse as EndpointRetrieveResponse, type EndpointUpdateResponse as EndpointUpdateResponse, @@ -321,6 +406,14 @@ export declare namespace Together { type HardwareListResponse as HardwareListResponse, type HardwareListParams as HardwareListParams, }; + + export { + Batches as Batches, + type BatchCreateResponse as BatchCreateResponse, + type BatchRetrieveResponse as BatchRetrieveResponse, + type BatchListResponse as BatchListResponse, + type BatchCreateParams as BatchCreateParams, + }; } export { toFile, fileFromPath } from './uploads'; diff --git a/src/resource.ts b/src/resource.ts index b1c3a19d..9e04217f 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -2,7 +2,7 @@ import type { Together } from './index'; -export class APIResource { +export abstract class APIResource { protected _client: Together; constructor(client: Together) { diff --git a/src/resources/audio.ts b/src/resources/audio.ts index fe4081d0..d6e8b24b 100644 --- a/src/resources/audio.ts +++ b/src/resources/audio.ts @@ -1,20 +1,48 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../resource'; +import { APIPromise } from '../core'; import * as Core from '../core'; +import * as AudioAPI from './audio'; +import { Stream } from '../streaming'; import { type Response } from '../_shims/index'; export class Audio extends APIResource { /** * Generate audio from input text + * + * @example + * ```ts + * const audio = await client.audio.create({ + * input: 'input', + * model: 'cartesia/sonic', + * voice: 'laidback woman', + * }); + * + * const content = await audio.blob(); + * console.log(content); + * ``` */ - create(body: AudioCreateParams, options?: Core.RequestOptions): Core.APIPromise { + create(body: AudioCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise; + create( + body: AudioCreateParamsStreaming, + options?: Core.RequestOptions, + ): APIPromise>; + create( + body: AudioCreateParamsBase, + options?: Core.RequestOptions, + ): APIPromise | Response>; + create( + body: AudioCreateParams, + options?: Core.RequestOptions, + ): APIPromise | APIPromise> { return this._client.post('/audio/speech', { body, ...options, headers: { Accept: 'application/octet-stream', ...options?.headers }, + stream: body.stream ?? false, __binaryResponse: true, - }); + }) as APIPromise | APIPromise>; } } @@ -22,20 +50,7 @@ export type AudioFile = AudioFile.AudioSpeechStreamEvent | AudioFile.StreamSenti export namespace AudioFile { export interface AudioSpeechStreamEvent { - data: AudioSpeechStreamEvent.Data; - } - - export namespace AudioSpeechStreamEvent { - export interface Data { - /** - * base64 encoded audio stream - */ - b64: string; - - model: string; - - object: 'audio.tts.chunk'; - } + data: AudioAPI.AudioSpeechStreamChunk; } export interface StreamSentinel { @@ -43,7 +58,20 @@ export namespace AudioFile { } } -export interface AudioCreateParams { +export interface AudioSpeechStreamChunk { + /** + * base64 encoded audio stream + */ + b64: string; + + model: string; + + object: 'audio.tts.chunk'; +} + +export type AudioCreateParams = AudioCreateParamsNonStreaming | AudioCreateParamsStreaming; + +export interface AudioCreateParamsBase { /** * Input text to generate the audio for */ @@ -105,6 +133,35 @@ export interface AudioCreateParams { stream?: boolean; } +export namespace AudioCreateParams { + export type AudioCreateParamsNonStreaming = AudioAPI.AudioCreateParamsNonStreaming; + export type AudioCreateParamsStreaming = AudioAPI.AudioCreateParamsStreaming; +} + +export interface AudioCreateParamsNonStreaming extends AudioCreateParamsBase { + /** + * If true, output is streamed for several characters at a time instead of waiting + * for the full response. The stream terminates with `data: [DONE]`. If false, + * return the encoded audio as octet stream + */ + stream?: false; +} + +export interface AudioCreateParamsStreaming extends AudioCreateParamsBase { + /** + * If true, output is streamed for several characters at a time instead of waiting + * for the full response. The stream terminates with `data: [DONE]`. If false, + * return the encoded audio as octet stream + */ + stream: true; +} + export declare namespace Audio { - export { type AudioFile as AudioFile, type AudioCreateParams as AudioCreateParams }; + export { + type AudioFile as AudioFile, + type AudioSpeechStreamChunk as AudioSpeechStreamChunk, + type AudioCreateParams as AudioCreateParams, + type AudioCreateParamsNonStreaming as AudioCreateParamsNonStreaming, + type AudioCreateParamsStreaming as AudioCreateParamsStreaming, + }; } diff --git a/src/resources/batches.ts b/src/resources/batches.ts new file mode 100644 index 00000000..1ebcd49e --- /dev/null +++ b/src/resources/batches.ts @@ -0,0 +1,221 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../resource'; +import * as Core from '../core'; + +export class Batches extends APIResource { + /** + * Create a new batch job with the given input file and endpoint + * + * @example + * ```ts + * const batch = await client.batches.create({ + * endpoint: '/v1/chat/completions', + * input_file_id: 'file-abc123def456ghi789', + * }); + * ``` + */ + create(body: BatchCreateParams, options?: Core.RequestOptions): Core.APIPromise { + return this._client.post('/batches', { body, ...options }); + } + + /** + * Get details of a batch job by ID + * + * @example + * ```ts + * const batch = await client.batches.retrieve( + * 'batch_job_abc123def456', + * ); + * ``` + */ + retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.get(`/batches/${id}`, options); + } + + /** + * List all batch jobs for the authenticated user + * + * @example + * ```ts + * const batches = await client.batches.list(); + * ``` + */ + list(options?: Core.RequestOptions): Core.APIPromise { + return this._client.get('/batches', options); + } +} + +export interface BatchCreateResponse { + job?: BatchCreateResponse.Job; + + warning?: string; +} + +export namespace BatchCreateResponse { + export interface Job { + id?: string; + + completed_at?: string; + + created_at?: string; + + endpoint?: string; + + error?: string; + + error_file_id?: string; + + /** + * Size of input file in bytes + */ + file_size_bytes?: number; + + input_file_id?: string; + + job_deadline?: string; + + /** + * Model used for processing requests + */ + model_id?: string; + + output_file_id?: string; + + /** + * Completion progress (0.0 to 100) + */ + progress?: number; + + /** + * Current status of the batch job + */ + status?: 'VALIDATING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED'; + + user_id?: string; + } +} + +export interface BatchRetrieveResponse { + id?: string; + + completed_at?: string; + + created_at?: string; + + endpoint?: string; + + error?: string; + + error_file_id?: string; + + /** + * Size of input file in bytes + */ + file_size_bytes?: number; + + input_file_id?: string; + + job_deadline?: string; + + /** + * Model used for processing requests + */ + model_id?: string; + + output_file_id?: string; + + /** + * Completion progress (0.0 to 100) + */ + progress?: number; + + /** + * Current status of the batch job + */ + status?: 'VALIDATING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED'; + + user_id?: string; +} + +export type BatchListResponse = Array; + +export namespace BatchListResponse { + export interface BatchListResponseItem { + id?: string; + + completed_at?: string; + + created_at?: string; + + endpoint?: string; + + error?: string; + + error_file_id?: string; + + /** + * Size of input file in bytes + */ + file_size_bytes?: number; + + input_file_id?: string; + + job_deadline?: string; + + /** + * Model used for processing requests + */ + model_id?: string; + + output_file_id?: string; + + /** + * Completion progress (0.0 to 100) + */ + progress?: number; + + /** + * Current status of the batch job + */ + status?: 'VALIDATING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'CANCELLED'; + + user_id?: string; + } +} + +export interface BatchCreateParams { + /** + * The endpoint to use for batch processing + */ + endpoint: string; + + /** + * ID of the uploaded input file containing batch requests + */ + input_file_id: string; + + /** + * Time window for batch completion (optional) + */ + completion_window?: string; + + /** + * Model to use for processing batch requests + */ + model_id?: string; + + /** + * Priority for batch processing (optional) + */ + priority?: number; +} + +export declare namespace Batches { + export { + type BatchCreateResponse as BatchCreateResponse, + type BatchRetrieveResponse as BatchRetrieveResponse, + type BatchListResponse as BatchListResponse, + type BatchCreateParams as BatchCreateParams, + }; +} diff --git a/src/resources/chat/chat.ts b/src/resources/chat/chat.ts index 0dd8f8d3..9f6c30f4 100644 --- a/src/resources/chat/chat.ts +++ b/src/resources/chat/chat.ts @@ -14,6 +14,7 @@ import { ChatCompletionToolMessageParam, ChatCompletionStructuredMessageImageURL, ChatCompletionStructuredMessageText, + ChatCompletionStructuredMessageVideoURL, ChatCompletionUsage, ChatCompletionUserMessageParam, CompletionCreateParams, @@ -42,6 +43,7 @@ export declare namespace Chat { type ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, type ChatCompletionStructuredMessageImageURL as ChatCompletionStructuredMessageImageURL, type ChatCompletionStructuredMessageText as ChatCompletionStructuredMessageText, + type ChatCompletionStructuredMessageVideoURL as ChatCompletionStructuredMessageVideoURL, type ChatCompletionUsage as ChatCompletionUsage, type ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, type CompletionCreateParams as CompletionCreateParams, diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions.ts index 97706839..9e5127c4 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions.ts @@ -11,6 +11,16 @@ import { ChatCompletionStream, ChatCompletionStreamParams } from 'together-ai/li export class Completions extends APIResource { /** * Query a chat model. + * + * @example + * ```ts + * const chatCompletion = await client.chat.completions.create( + * { + * messages: [{ content: 'content', role: 'system' }], + * model: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', + * }, + * ); + * ``` */ create(body: CompletionCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise; create( @@ -245,6 +255,21 @@ export interface ChatCompletionStructuredMessageText { type: 'text'; } +export interface ChatCompletionStructuredMessageVideoURL { + type: 'video_url'; + + video_url: ChatCompletionStructuredMessageVideoURL.VideoURL; +} + +export namespace ChatCompletionStructuredMessageVideoURL { + export interface VideoURL { + /** + * The URL of the video + */ + url: string; + } +} + export interface ChatCompletionUsage { completion_tokens: number; @@ -267,7 +292,13 @@ export interface CompletionCreateParamsBase { /** * A list of messages comprising the conversation so far. */ - messages: Array; + messages: Array< + | CompletionCreateParams.ChatCompletionSystemMessageParam + | CompletionCreateParams.ChatCompletionUserMessageParam + | CompletionCreateParams.ChatCompletionAssistantMessageParam + | CompletionCreateParams.ChatCompletionToolMessageParam + | CompletionCreateParams.ChatCompletionFunctionMessageParam + >; /** * The name of the model to query. @@ -307,11 +338,12 @@ export interface CompletionCreateParamsBase { /** * Adjusts the likelihood of specific tokens appearing in the generated output. */ - logit_bias?: Record; + logit_bias?: { [key: string]: number }; /** - * Integer (0 or 1) that controls whether log probabilities of generated tokens are - * returned. Log probabilities help assess model confidence in token predictions. + * An integer between 0 and 20 of the top k tokens to return log probabilities for + * at each generation step, instead of just the sampled token. Log probabilities + * help assess model confidence in token predictions. */ logprobs?: number; @@ -414,7 +446,15 @@ export interface CompletionCreateParamsBase { } export namespace CompletionCreateParams { - export interface Message { + export interface ChatCompletionSystemMessageParam { + content: string; + + role: 'system'; + + name?: string; + } + + export interface ChatCompletionUserMessageParam { /** * The content of the message, which can either be a simple string or a structured * format. @@ -424,31 +464,96 @@ export namespace CompletionCreateParams { | Array< | ChatCompletionsAPI.ChatCompletionStructuredMessageText | ChatCompletionsAPI.ChatCompletionStructuredMessageImageURL - | Message.Video + | ChatCompletionsAPI.ChatCompletionStructuredMessageVideoURL + | ChatCompletionUserMessageParam.Audio + | ChatCompletionUserMessageParam.InputAudio >; - /** - * The role of the messages author. Choice between: system, user, assistant, or - * tool. - */ - role: 'system' | 'user' | 'assistant' | 'tool'; + role: 'user'; + + name?: string; } - export namespace Message { - export interface Video { - type: 'video_url'; + export namespace ChatCompletionUserMessageParam { + export interface Audio { + audio_url: Audio.AudioURL; - video_url: Video.VideoURL; + type: 'audio_url'; } - export namespace Video { - export interface VideoURL { + export namespace Audio { + export interface AudioURL { /** - * The URL of the video + * The URL of the audio */ url: string; } } + + export interface InputAudio { + input_audio: InputAudio.InputAudio; + + type: 'input_audio'; + } + + export namespace InputAudio { + export interface InputAudio { + /** + * The base64 encoded audio data + */ + data: string; + + /** + * The format of the audio data + */ + format: 'wav'; + } + } + } + + export interface ChatCompletionAssistantMessageParam { + role: 'assistant'; + + content?: string | null; + + /** + * @deprecated + */ + function_call?: ChatCompletionAssistantMessageParam.FunctionCall; + + name?: string; + + tool_calls?: Array; + } + + export namespace ChatCompletionAssistantMessageParam { + /** + * @deprecated + */ + export interface FunctionCall { + arguments: string; + + name: string; + } + } + + export interface ChatCompletionToolMessageParam { + content: string; + + role: 'tool'; + + tool_call_id: string; + } + + /** + * @deprecated + */ + export interface ChatCompletionFunctionMessageParam { + content: string; + + name: string; + + role: 'function'; } export interface Name { @@ -462,7 +567,7 @@ export namespace CompletionCreateParams { /** * The schema of the response format. */ - schema?: Record; + schema?: { [key: string]: unknown }; /** * The type of the response format. @@ -505,6 +610,7 @@ export declare namespace Completions { type ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, type ChatCompletionStructuredMessageImageURL as ChatCompletionStructuredMessageImageURL, type ChatCompletionStructuredMessageText as ChatCompletionStructuredMessageText, + type ChatCompletionStructuredMessageVideoURL as ChatCompletionStructuredMessageVideoURL, type ChatCompletionUsage as ChatCompletionUsage, type ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, type CompletionCreateParams as CompletionCreateParams, diff --git a/src/resources/chat/index.ts b/src/resources/chat/index.ts index 2f80d745..5d1ec3bd 100644 --- a/src/resources/chat/index.ts +++ b/src/resources/chat/index.ts @@ -15,6 +15,7 @@ export { type ChatCompletionChunk, type ChatCompletionStructuredMessageImageURL, type ChatCompletionStructuredMessageText, + type ChatCompletionStructuredMessageVideoURL, type ChatCompletionUsage, type CompletionCreateParams, type CompletionCreateParamsNonStreaming, diff --git a/src/resources/code-interpreter/code-interpreter.ts b/src/resources/code-interpreter/code-interpreter.ts index 98892eba..bf8b4f32 100644 --- a/src/resources/code-interpreter/code-interpreter.ts +++ b/src/resources/code-interpreter/code-interpreter.ts @@ -14,6 +14,15 @@ export class CodeInterpreter extends APIResource { * session_id, the code will be run in that session. This is useful for running * multiple code snippets in the same environment, because dependencies and similar * things are persisted between calls to the same session. + * + * @example + * ```ts + * const executeResponse = + * await client.codeInterpreter.execute({ + * code: "print('Hello, world!')", + * language: 'python', + * }); + * ``` */ execute( body: CodeInterpreterExecuteParams, @@ -45,6 +54,11 @@ export namespace ExecuteResponse { * Identifier of the current session. Used to make follow-up calls. */ session_id: string; + + /** + * Status of the execution. Currently only supports success. + */ + status?: 'success'; } export namespace Data { @@ -75,17 +89,17 @@ export namespace ExecuteResponse { export namespace DisplayorExecuteOutput { export interface Data { - 'application/geo+json'?: Record; + 'application/geo+json'?: { [key: string]: unknown }; 'application/javascript'?: string; - 'application/json'?: Record; + 'application/json'?: { [key: string]: unknown }; 'application/pdf'?: string; - 'application/vnd.vega.v5+json'?: Record; + 'application/vnd.vega.v5+json'?: { [key: string]: unknown }; - 'application/vnd.vegalite.v4+json'?: Record; + 'application/vnd.vegalite.v4+json'?: { [key: string]: unknown }; 'image/gif'?: string; @@ -110,7 +124,7 @@ export namespace ExecuteResponse { export interface FailedExecution { data: null; - errors: Array>; + errors: Array; } } diff --git a/src/resources/code-interpreter/sessions.ts b/src/resources/code-interpreter/sessions.ts index 2da55eb2..104e92f3 100644 --- a/src/resources/code-interpreter/sessions.ts +++ b/src/resources/code-interpreter/sessions.ts @@ -6,6 +6,12 @@ import * as Core from '../../core'; export class Sessions extends APIResource { /** * Lists all your currently active sessions. + * + * @example + * ```ts + * const sessionListResponse = + * await client.codeInterpreter.sessions.list(); + * ``` */ list(options?: Core.RequestOptions): Core.APIPromise { return this._client.get('/tci/sessions', options); @@ -15,7 +21,7 @@ export class Sessions extends APIResource { export interface SessionListResponse { data?: SessionListResponse.Data; - errors?: Array>; + errors?: Array; } export namespace SessionListResponse { diff --git a/src/resources/completions.ts b/src/resources/completions.ts index 5fa01f1e..c9e003a8 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -10,23 +10,32 @@ import { Stream } from '../streaming'; export class Completions extends APIResource { /** * Query a language, code, or image model. + * + * @example + * ```ts + * const completion = await client.completions.create({ + * model: 'mistralai/Mixtral-8x7B-Instruct-v0.1', + * prompt: + * '[INST] What is the capital of France? [/INST]', + * }); + * ``` */ create(body: CompletionCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise; create( body: CompletionCreateParamsStreaming, options?: Core.RequestOptions, - ): APIPromise>; + ): APIPromise>; create( body: CompletionCreateParamsBase, options?: Core.RequestOptions, - ): APIPromise | Completion>; + ): APIPromise | Completion>; create( body: CompletionCreateParams, options?: Core.RequestOptions, - ): APIPromise | APIPromise> { + ): APIPromise | APIPromise> { return this._client.post('/completions', { body, ...options, stream: body.stream ?? false }) as | APIPromise - | APIPromise>; + | APIPromise>; } } @@ -39,7 +48,7 @@ export interface Completion { model: string; - object: 'text_completion'; + object: 'text.completion'; usage: ChatCompletionsAPI.ChatCompletionUsage | null; @@ -64,6 +73,72 @@ export namespace Completion { } } +export interface CompletionChunk { + id: string; + + token: CompletionChunk.Token; + + choices: Array; + + finish_reason: 'stop' | 'eos' | 'length' | 'tool_calls' | 'function_call' | null; + + usage: ChatCompletionsAPI.ChatCompletionUsage | null; + + created?: number; + + object?: 'completion.chunk'; + + seed?: number; +} + +export namespace CompletionChunk { + export interface Token { + id: number; + + logprob: number; + + special: boolean; + + text: string; + } + + export interface Choice { + index: number; + + delta?: Choice.Delta; + + text?: string; + } + + export namespace Choice { + export interface Delta { + role: 'system' | 'user' | 'assistant' | 'function' | 'tool'; + + content?: string | null; + + /** + * @deprecated + */ + function_call?: Delta.FunctionCall | null; + + token_id?: number; + + tool_calls?: Array; + } + + export namespace Delta { + /** + * @deprecated + */ + export interface FunctionCall { + arguments: string; + + name: string; + } + } + } +} + export interface LogProbs { /** * List of token IDs corresponding to the logprobs @@ -114,7 +189,7 @@ export namespace Tools { /** * A map of parameter names to their values. */ - parameters?: Record; + parameters?: { [key: string]: unknown }; } } @@ -153,11 +228,12 @@ export interface CompletionCreateParamsBase { /** * Adjusts the likelihood of specific tokens appearing in the generated output. */ - logit_bias?: Record; + logit_bias?: { [key: string]: number }; /** - * Integer (0 or 1) that controls whether log probabilities of generated tokens are - * returned. Log probabilities help assess model confidence in token predictions. + * An integer between 0 and 20 of the top k tokens to return log probabilities for + * at each generation step, instead of just the sampled token. Log probabilities + * help assess model confidence in token predictions. */ logprobs?: number; @@ -267,6 +343,7 @@ export interface CompletionCreateParamsStreaming extends CompletionCreateParamsB export declare namespace Completions { export { type Completion as Completion, + type CompletionChunk as CompletionChunk, type LogProbs as LogProbs, type ToolChoice as ToolChoice, type Tools as Tools, diff --git a/src/resources/embeddings.ts b/src/resources/embeddings.ts index 5dfeba14..1d7a05d1 100644 --- a/src/resources/embeddings.ts +++ b/src/resources/embeddings.ts @@ -6,6 +6,15 @@ import * as Core from '../core'; export class Embeddings extends APIResource { /** * Query an embedding model for a given string of text. + * + * @example + * ```ts + * const embedding = await client.embeddings.create({ + * input: + * 'Our solar system orbits the Milky Way galaxy at about 515,000 mph', + * model: 'togethercomputer/m2-bert-80M-8k-retrieval', + * }); + * ``` */ create(body: EmbeddingCreateParams, options?: Core.RequestOptions): Core.APIPromise { return this._client.post('/embeddings', { body, ...options }); diff --git a/src/resources/endpoints.ts b/src/resources/endpoints.ts index 1d34cb25..1dee9bf1 100644 --- a/src/resources/endpoints.ts +++ b/src/resources/endpoints.ts @@ -9,6 +9,15 @@ export class Endpoints extends APIResource { * Creates a new dedicated endpoint for serving models. The endpoint will * automatically start after creation. You can deploy any supported model on * hardware configurations that meet the model's requirements. + * + * @example + * ```ts + * const endpoint = await client.endpoints.create({ + * autoscaling: { max_replicas: 5, min_replicas: 2 }, + * hardware: '1x_nvidia_a100_80gb_sxm', + * model: 'meta-llama/Llama-3-8b-chat-hf', + * }); + * ``` */ create(body: EndpointCreateParams, options?: Core.RequestOptions): Core.APIPromise { return this._client.post('/endpoints', { body, ...options }); @@ -17,6 +26,13 @@ export class Endpoints extends APIResource { /** * Retrieves details about a specific endpoint, including its current state, * configuration, and scaling settings. + * + * @example + * ```ts + * const endpoint = await client.endpoints.retrieve( + * 'endpoint-d23901de-ef8f-44bf-b3e7-de9c1ca8f2d7', + * ); + * ``` */ retrieve(endpointId: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/endpoints/${endpointId}`, options); @@ -25,6 +41,13 @@ export class Endpoints extends APIResource { /** * Updates an existing endpoint's configuration. You can modify the display name, * autoscaling settings, or change the endpoint's state (start/stop). + * + * @example + * ```ts + * const endpoint = await client.endpoints.update( + * 'endpoint-d23901de-ef8f-44bf-b3e7-de9c1ca8f2d7', + * ); + * ``` */ update( endpointId: string, @@ -37,6 +60,11 @@ export class Endpoints extends APIResource { /** * Returns a list of all endpoints associated with your account. You can filter the * results by type (dedicated or serverless). + * + * @example + * ```ts + * const endpoints = await client.endpoints.list(); + * ``` */ list(query?: EndpointListParams, options?: Core.RequestOptions): Core.APIPromise; list(options?: Core.RequestOptions): Core.APIPromise; @@ -52,6 +80,13 @@ export class Endpoints extends APIResource { /** * Permanently deletes an endpoint. This action cannot be undone. + * + * @example + * ```ts + * await client.endpoints.delete( + * 'endpoint-d23901de-ef8f-44bf-b3e7-de9c1ca8f2d7', + * ); + * ``` */ delete(endpointId: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.delete(`/endpoints/${endpointId}`, { @@ -61,6 +96,21 @@ export class Endpoints extends APIResource { } } +/** + * Configuration for automatic scaling of replicas based on demand. + */ +export interface Autoscaling { + /** + * The maximum number of replicas to scale up to under load + */ + max_replicas: number; + + /** + * The minimum number of replicas to maintain, even when there is no load + */ + min_replicas: number; +} + /** * Details about a dedicated endpoint deployment */ @@ -73,7 +123,7 @@ export interface EndpointCreateResponse { /** * Configuration for automatic scaling of the endpoint */ - autoscaling: EndpointCreateResponse.Autoscaling; + autoscaling: Autoscaling; /** * Timestamp when the endpoint was created @@ -121,23 +171,6 @@ export interface EndpointCreateResponse { type: 'dedicated'; } -export namespace EndpointCreateResponse { - /** - * Configuration for automatic scaling of the endpoint - */ - export interface Autoscaling { - /** - * The maximum number of replicas to scale up to under load - */ - max_replicas: number; - - /** - * The minimum number of replicas to maintain, even when there is no load - */ - min_replicas: number; - } -} - /** * Details about a dedicated endpoint deployment */ @@ -150,7 +183,7 @@ export interface EndpointRetrieveResponse { /** * Configuration for automatic scaling of the endpoint */ - autoscaling: EndpointRetrieveResponse.Autoscaling; + autoscaling: Autoscaling; /** * Timestamp when the endpoint was created @@ -198,23 +231,6 @@ export interface EndpointRetrieveResponse { type: 'dedicated'; } -export namespace EndpointRetrieveResponse { - /** - * Configuration for automatic scaling of the endpoint - */ - export interface Autoscaling { - /** - * The maximum number of replicas to scale up to under load - */ - max_replicas: number; - - /** - * The minimum number of replicas to maintain, even when there is no load - */ - min_replicas: number; - } -} - /** * Details about a dedicated endpoint deployment */ @@ -227,7 +243,7 @@ export interface EndpointUpdateResponse { /** * Configuration for automatic scaling of the endpoint */ - autoscaling: EndpointUpdateResponse.Autoscaling; + autoscaling: Autoscaling; /** * Timestamp when the endpoint was created @@ -275,23 +291,6 @@ export interface EndpointUpdateResponse { type: 'dedicated'; } -export namespace EndpointUpdateResponse { - /** - * Configuration for automatic scaling of the endpoint - */ - export interface Autoscaling { - /** - * The maximum number of replicas to scale up to under load - */ - max_replicas: number; - - /** - * The minimum number of replicas to maintain, even when there is no load - */ - min_replicas: number; - } -} - export interface EndpointListResponse { data: Array; @@ -349,7 +348,7 @@ export interface EndpointCreateParams { /** * Configuration for automatic scaling of the endpoint */ - autoscaling: EndpointCreateParams.Autoscaling; + autoscaling: Autoscaling; /** * The hardware configuration to use for this endpoint @@ -389,28 +388,11 @@ export interface EndpointCreateParams { state?: 'STARTED' | 'STOPPED'; } -export namespace EndpointCreateParams { - /** - * Configuration for automatic scaling of the endpoint - */ - export interface Autoscaling { - /** - * The maximum number of replicas to scale up to under load - */ - max_replicas: number; - - /** - * The minimum number of replicas to maintain, even when there is no load - */ - min_replicas: number; - } -} - export interface EndpointUpdateParams { /** * New autoscaling configuration for the endpoint */ - autoscaling?: EndpointUpdateParams.Autoscaling; + autoscaling?: Autoscaling; /** * A human-readable name for the endpoint @@ -429,23 +411,6 @@ export interface EndpointUpdateParams { state?: 'STARTED' | 'STOPPED'; } -export namespace EndpointUpdateParams { - /** - * New autoscaling configuration for the endpoint - */ - export interface Autoscaling { - /** - * The maximum number of replicas to scale up to under load - */ - max_replicas: number; - - /** - * The minimum number of replicas to maintain, even when there is no load - */ - min_replicas: number; - } -} - export interface EndpointListParams { /** * Filter endpoints by type @@ -455,6 +420,7 @@ export interface EndpointListParams { export declare namespace Endpoints { export { + type Autoscaling as Autoscaling, type EndpointCreateResponse as EndpointCreateResponse, type EndpointRetrieveResponse as EndpointRetrieveResponse, type EndpointUpdateResponse as EndpointUpdateResponse, diff --git a/src/resources/files.ts b/src/resources/files.ts index f189dcbf..28a7357b 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -2,11 +2,17 @@ import { APIResource } from '../resource'; import * as Core from '../core'; +import * as FilesAPI from './files'; import { type Response } from '../_shims/index'; export class Files extends APIResource { /** * List the metadata for a single uploaded data file. + * + * @example + * ```ts + * const file = await client.files.retrieve('id'); + * ``` */ retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/files/${id}`, options); @@ -14,6 +20,11 @@ export class Files extends APIResource { /** * List the metadata for all uploaded data files. + * + * @example + * ```ts + * const files = await client.files.list(); + * ``` */ list(options?: Core.RequestOptions): Core.APIPromise { return this._client.get('/files', options); @@ -21,6 +32,11 @@ export class Files extends APIResource { /** * Delete a previously uploaded data file. + * + * @example + * ```ts + * const file = await client.files.delete('id'); + * ``` */ delete(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.delete(`/files/${id}`, options); @@ -28,6 +44,14 @@ export class Files extends APIResource { /** * Get the contents of a single uploaded data file. + * + * @example + * ```ts + * const response = await client.files.content('id'); + * + * const content = await response.blob(); + * console.log(content); + * ``` */ content(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/files/${id}/content`, { @@ -55,6 +79,23 @@ export interface FileObject { size?: number; } +/** + * The purpose of the file + */ +export type FilePurpose = + | 'fine-tune' + | 'eval' + | 'eval-sample' + | 'eval-output' + | 'eval-summary' + | 'batch-generated' + | 'batch-api'; + +/** + * The type of the file + */ +export type FileType = 'csv' | 'jsonl' | 'parquet'; + export interface FileRetrieveResponse { id: string; @@ -64,7 +105,10 @@ export interface FileRetrieveResponse { filename: string; - FileType: 'jsonl' | 'parquet'; + /** + * The type of the file + */ + FileType: FileType; LineCount: number; @@ -72,7 +116,10 @@ export interface FileRetrieveResponse { Processed: boolean; - purpose: 'fine-tune'; + /** + * The purpose of the file + */ + purpose: FilePurpose; } export interface FileListResponse { @@ -89,7 +136,10 @@ export namespace FileListResponse { filename: string; - FileType: 'jsonl' | 'parquet'; + /** + * The type of the file + */ + FileType: FilesAPI.FileType; LineCount: number; @@ -97,7 +147,10 @@ export namespace FileListResponse { Processed: boolean; - purpose: 'fine-tune'; + /** + * The purpose of the file + */ + purpose: FilesAPI.FilePurpose; } } @@ -107,11 +160,63 @@ export interface FileDeleteResponse { deleted?: boolean; } +export interface FileUploadResponse { + id: string; + + bytes: number; + + created_at: number; + + filename: string; + + /** + * The type of the file + */ + FileType: FileType; + + LineCount: number; + + object: string; + + Processed: boolean; + + /** + * The purpose of the file + */ + purpose: FilePurpose; +} + +export interface FileUploadParams { + /** + * The content of the file being uploaded + */ + file: Core.Uploadable; + + /** + * The name of the file being uploaded + */ + file_name: string; + + /** + * The purpose of the file + */ + purpose: FilePurpose; + + /** + * The type of the file + */ + file_type?: FileType; +} + export declare namespace Files { export { type FileObject as FileObject, + type FilePurpose as FilePurpose, + type FileType as FileType, type FileRetrieveResponse as FileRetrieveResponse, type FileListResponse as FileListResponse, type FileDeleteResponse as FileDeleteResponse, + type FileUploadResponse as FileUploadResponse, + type FileUploadParams as FileUploadParams, }; } diff --git a/src/resources/fine-tune.ts b/src/resources/fine-tune.ts index af75a091..9b02757e 100644 --- a/src/resources/fine-tune.ts +++ b/src/resources/fine-tune.ts @@ -2,38 +2,71 @@ import { APIResource } from '../resource'; import * as Core from '../core'; +import * as FineTuneAPI from './fine-tune'; export class FineTuneResource extends APIResource { /** - * Use a model to create a fine-tuning job. + * Create a fine-tuning job with the provided model and training data. + * + * @example + * ```ts + * const fineTune = await client.fineTune.create({ + * model: 'model', + * training_file: 'training_file', + * }); + * ``` */ - create(body: FineTuneCreateParams, options?: Core.RequestOptions): Core.APIPromise { + create(body: FineTuneCreateParams, options?: Core.RequestOptions): Core.APIPromise { return this._client.post('/fine-tunes', { body, ...options }); } /** * List the metadata for a single fine-tuning job. + * + * @example + * ```ts + * const fineTune = await client.fineTune.retrieve('id'); + * ``` */ retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/fine-tunes/${id}`, options); } /** - * List the metadata for all fine-tuning jobs. + * List the metadata for all fine-tuning jobs. Returns a list of + * FinetuneResponseTruncated objects. + * + * @example + * ```ts + * const fineTunes = await client.fineTune.list(); + * ``` */ list(options?: Core.RequestOptions): Core.APIPromise { return this._client.get('/fine-tunes', options); } /** - * Cancel a currently running fine-tuning job. + * Cancel a currently running fine-tuning job. Returns a FinetuneResponseTruncated + * object. + * + * @example + * ```ts + * const response = await client.fineTune.cancel('id'); + * ``` */ - cancel(id: string, options?: Core.RequestOptions): Core.APIPromise { + cancel(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.post(`/fine-tunes/${id}/cancel`, options); } /** * Download a compressed fine-tuned model or checkpoint to local disk. + * + * @example + * ```ts + * const response = await client.fineTune.download({ + * ft_id: 'ft_id', + * }); + * ``` */ download( query: FineTuneDownloadParams, @@ -44,10 +77,44 @@ export class FineTuneResource extends APIResource { /** * List the events for a single fine-tuning job. + * + * @example + * ```ts + * const response = await client.fineTune.listEvents('id'); + * ``` */ - listEvents(id: string, options?: Core.RequestOptions): Core.APIPromise { + listEvents(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/fine-tunes/${id}/events`, options); } + + /** + * List the checkpoints for a single fine-tuning job. + * + * @example + * ```ts + * const response = await client.fineTune.retrieveCheckpoints( + * 'id', + * ); + * ``` + */ + retrieveCheckpoints( + id: string, + options?: Core.RequestOptions, + ): Core.APIPromise { + return this._client.get(`/fine-tunes/${id}/checkpoints`, options); + } +} + +export interface CosineLrSchedulerArgs { + /** + * The ratio of the final learning rate to the peak learning rate + */ + min_lr_ratio: number; + + /** + * Number or fraction of cycles for the cosine learning rate scheduler + */ + num_cycles: number; } export interface FineTune { @@ -72,7 +139,7 @@ export interface FineTune { eval_steps?: number; - events?: Array; + events?: Array; from_checkpoint?: string; @@ -80,7 +147,7 @@ export interface FineTune { learning_rate?: number; - lr_scheduler?: FineTune.LrScheduler; + lr_scheduler?: LrScheduler; max_grad_norm?: number; @@ -108,9 +175,9 @@ export interface FineTune { training_file?: string; - training_method?: FineTune.TrainingMethodSft | FineTune.TrainingMethodDpo; + training_method?: TrainingMethodSft | TrainingMethodDpo; - training_type?: FineTune.FullTrainingType | FineTune.LoRaTrainingType; + training_type?: FullTrainingType | LoRaTrainingType; trainingfile_numlines?: number; @@ -129,179 +196,565 @@ export interface FineTune { weight_decay?: number; } -export namespace FineTune { - export interface Event { - checkpoint_path: string; +export interface FineTuneEvent { + checkpoint_path: string; - created_at: string; + created_at: string; - hash: string; + hash: string; - message: string; + message: string; - model_path: string; + model_path: string; - object: 'fine-tune-event'; + object: 'fine-tune-event'; - param_count: number; + param_count: number; - step: number; + step: number; - token_count: number; - - total_steps: number; - - training_offset: number; - - type: - | 'job_pending' - | 'job_start' - | 'job_stopped' - | 'model_downloading' - | 'model_download_complete' - | 'training_data_downloading' - | 'training_data_download_complete' - | 'validation_data_downloading' - | 'validation_data_download_complete' - | 'wandb_init' - | 'training_start' - | 'checkpoint_save' - | 'billing_limit' - | 'epoch_complete' - | 'training_complete' - | 'model_compressing' - | 'model_compression_complete' - | 'model_uploading' - | 'model_upload_complete' - | 'job_complete' - | 'job_error' - | 'cancel_requested' - | 'job_restarted' - | 'refund' - | 'warning'; + token_count: number; - wandb_url: string; + total_steps: number; - level?: 'info' | 'warning' | 'error' | 'legacy_info' | 'legacy_iwarning' | 'legacy_ierror' | null; - } + training_offset: number; - export interface LrScheduler { - lr_scheduler_type: 'linear' | 'cosine'; + type: + | 'job_pending' + | 'job_start' + | 'job_stopped' + | 'model_downloading' + | 'model_download_complete' + | 'training_data_downloading' + | 'training_data_download_complete' + | 'validation_data_downloading' + | 'validation_data_download_complete' + | 'wandb_init' + | 'training_start' + | 'checkpoint_save' + | 'billing_limit' + | 'epoch_complete' + | 'training_complete' + | 'model_compressing' + | 'model_compression_complete' + | 'model_uploading' + | 'model_upload_complete' + | 'job_complete' + | 'job_error' + | 'cancel_requested' + | 'job_restarted' + | 'refund' + | 'warning'; - lr_scheduler_args?: LrScheduler.LinearLrSchedulerArgs | LrScheduler.CosineLrSchedulerArgs; - } + wandb_url: string; - export namespace LrScheduler { - export interface LinearLrSchedulerArgs { - /** - * The ratio of the final learning rate to the peak learning rate - */ - min_lr_ratio?: number; - } - - export interface CosineLrSchedulerArgs { - /** - * The ratio of the final learning rate to the peak learning rate - */ - min_lr_ratio?: number; - - /** - * Number or fraction of cycles for the cosine learning rate scheduler - */ - num_cycles?: number; - } - } + level?: 'info' | 'warning' | 'error' | 'legacy_info' | 'legacy_iwarning' | 'legacy_ierror' | null; +} - export interface TrainingMethodSft { - method: 'sft'; - } +export interface FullTrainingType { + type: 'Full'; +} - export interface TrainingMethodDpo { - method: 'dpo'; +export interface LinearLrSchedulerArgs { + /** + * The ratio of the final learning rate to the peak learning rate + */ + min_lr_ratio?: number; +} - dpo_beta?: number; - } +export interface LoRaTrainingType { + lora_alpha: number; - export interface FullTrainingType { - type: 'Full'; - } + lora_r: number; - export interface LoRaTrainingType { - lora_alpha: number; + type: 'Lora'; - lora_r: number; + lora_dropout?: number; - type: 'Lora'; + lora_trainable_modules?: string; +} - lora_dropout?: number; +export interface LrScheduler { + lr_scheduler_type: 'linear' | 'cosine'; - lora_trainable_modules?: string; - } + lr_scheduler_args?: LinearLrSchedulerArgs | CosineLrSchedulerArgs; } -export interface FineTuneEvent { - data: Array; +export interface TrainingMethodDpo { + method: 'dpo'; + + dpo_beta?: number; + + dpo_normalize_logratios_by_length?: boolean; + + dpo_reference_free?: boolean; + + rpo_alpha?: number; + + simpo_gamma?: number; } -export namespace FineTuneEvent { - export interface Data { - checkpoint_path: string; +export interface TrainingMethodSft { + method: 'sft'; - created_at: string; + /** + * Whether to mask the user messages in conversational data or prompts in + * instruction data. + */ + train_on_inputs: boolean | 'auto'; +} - hash: string; +/** + * A truncated version of the fine-tune response, used for POST /fine-tunes, GET + * /fine-tunes and POST /fine-tunes/{id}/cancel endpoints + */ +export interface FineTuneCreateResponse { + /** + * Unique identifier for the fine-tune job + */ + id: string; - message: string; + /** + * Creation timestamp of the fine-tune job + */ + created_at: string; + + status: + | 'pending' + | 'queued' + | 'running' + | 'compressing' + | 'uploading' + | 'cancel_requested' + | 'cancelled' + | 'error' + | 'completed'; - model_path: string; + /** + * Last update timestamp of the fine-tune job + */ + updated_at: string; - object: 'fine-tune-event'; + /** + * Batch size used for training + */ + batch_size?: number; - param_count: number; + /** + * Events related to this fine-tune job + */ + events?: Array; - step: number; + /** + * Checkpoint used to continue training + */ + from_checkpoint?: string; - token_count: number; - - total_steps: number; - - training_offset: number; - - type: - | 'job_pending' - | 'job_start' - | 'job_stopped' - | 'model_downloading' - | 'model_download_complete' - | 'training_data_downloading' - | 'training_data_download_complete' - | 'validation_data_downloading' - | 'validation_data_download_complete' - | 'wandb_init' - | 'training_start' - | 'checkpoint_save' - | 'billing_limit' - | 'epoch_complete' - | 'training_complete' - | 'model_compressing' - | 'model_compression_complete' - | 'model_uploading' - | 'model_upload_complete' - | 'job_complete' - | 'job_error' - | 'cancel_requested' - | 'job_restarted' - | 'refund' - | 'warning'; + /** + * Learning rate used for training + */ + learning_rate?: number; - wandb_url: string; + /** + * Learning rate scheduler configuration + */ + lr_scheduler?: LrScheduler; - level?: 'info' | 'warning' | 'error' | 'legacy_info' | 'legacy_iwarning' | 'legacy_ierror' | null; - } + /** + * Maximum gradient norm for clipping + */ + max_grad_norm?: number; + + /** + * Base model used for fine-tuning + */ + model?: string; + + model_output_name?: string; + + /** + * Number of checkpoints saved during training + */ + n_checkpoints?: number; + + /** + * Number of training epochs + */ + n_epochs?: number; + + /** + * Number of evaluations during training + */ + n_evals?: number; + + /** + * Owner address information + */ + owner_address?: string; + + /** + * Suffix added to the fine-tuned model name + */ + suffix?: string; + + /** + * Count of tokens processed + */ + token_count?: number; + + /** + * Total price for the fine-tuning job + */ + total_price?: number; + + /** + * File-ID of the training file + */ + training_file?: string; + + /** + * Method of training used + */ + training_method?: TrainingMethodSft | TrainingMethodDpo; + + /** + * Type of training used (full or LoRA) + */ + training_type?: FullTrainingType | LoRaTrainingType; + + /** + * Identifier for the user who created the job + */ + user_id?: string; + + /** + * File-ID of the validation file + */ + validation_file?: string; + + /** + * Weights & Biases run name + */ + wandb_name?: string; + + /** + * Weights & Biases project name + */ + wandb_project_name?: string; + + /** + * Ratio of warmup steps + */ + warmup_ratio?: number; + + /** + * Weight decay value used + */ + weight_decay?: number; } export interface FineTuneListResponse { - data: Array; + data: Array; +} + +export namespace FineTuneListResponse { + /** + * A truncated version of the fine-tune response, used for POST /fine-tunes, GET + * /fine-tunes and POST /fine-tunes/{id}/cancel endpoints + */ + export interface Data { + /** + * Unique identifier for the fine-tune job + */ + id: string; + + /** + * Creation timestamp of the fine-tune job + */ + created_at: string; + + status: + | 'pending' + | 'queued' + | 'running' + | 'compressing' + | 'uploading' + | 'cancel_requested' + | 'cancelled' + | 'error' + | 'completed'; + + /** + * Last update timestamp of the fine-tune job + */ + updated_at: string; + + /** + * Batch size used for training + */ + batch_size?: number; + + /** + * Events related to this fine-tune job + */ + events?: Array; + + /** + * Checkpoint used to continue training + */ + from_checkpoint?: string; + + /** + * Learning rate used for training + */ + learning_rate?: number; + + /** + * Learning rate scheduler configuration + */ + lr_scheduler?: FineTuneAPI.LrScheduler; + + /** + * Maximum gradient norm for clipping + */ + max_grad_norm?: number; + + /** + * Base model used for fine-tuning + */ + model?: string; + + model_output_name?: string; + + /** + * Number of checkpoints saved during training + */ + n_checkpoints?: number; + + /** + * Number of training epochs + */ + n_epochs?: number; + + /** + * Number of evaluations during training + */ + n_evals?: number; + + /** + * Owner address information + */ + owner_address?: string; + + /** + * Suffix added to the fine-tuned model name + */ + suffix?: string; + + /** + * Count of tokens processed + */ + token_count?: number; + + /** + * Total price for the fine-tuning job + */ + total_price?: number; + + /** + * File-ID of the training file + */ + training_file?: string; + + /** + * Method of training used + */ + training_method?: FineTuneAPI.TrainingMethodSft | FineTuneAPI.TrainingMethodDpo; + + /** + * Type of training used (full or LoRA) + */ + training_type?: FineTuneAPI.FullTrainingType | FineTuneAPI.LoRaTrainingType; + + /** + * Identifier for the user who created the job + */ + user_id?: string; + + /** + * File-ID of the validation file + */ + validation_file?: string; + + /** + * Weights & Biases run name + */ + wandb_name?: string; + + /** + * Weights & Biases project name + */ + wandb_project_name?: string; + + /** + * Ratio of warmup steps + */ + warmup_ratio?: number; + + /** + * Weight decay value used + */ + weight_decay?: number; + } +} + +/** + * A truncated version of the fine-tune response, used for POST /fine-tunes, GET + * /fine-tunes and POST /fine-tunes/{id}/cancel endpoints + */ +export interface FineTuneCancelResponse { + /** + * Unique identifier for the fine-tune job + */ + id: string; + + /** + * Creation timestamp of the fine-tune job + */ + created_at: string; + + status: + | 'pending' + | 'queued' + | 'running' + | 'compressing' + | 'uploading' + | 'cancel_requested' + | 'cancelled' + | 'error' + | 'completed'; + + /** + * Last update timestamp of the fine-tune job + */ + updated_at: string; + + /** + * Batch size used for training + */ + batch_size?: number; + + /** + * Events related to this fine-tune job + */ + events?: Array; + + /** + * Checkpoint used to continue training + */ + from_checkpoint?: string; + + /** + * Learning rate used for training + */ + learning_rate?: number; + + /** + * Learning rate scheduler configuration + */ + lr_scheduler?: LrScheduler; + + /** + * Maximum gradient norm for clipping + */ + max_grad_norm?: number; + + /** + * Base model used for fine-tuning + */ + model?: string; + + model_output_name?: string; + + /** + * Number of checkpoints saved during training + */ + n_checkpoints?: number; + + /** + * Number of training epochs + */ + n_epochs?: number; + + /** + * Number of evaluations during training + */ + n_evals?: number; + + /** + * Owner address information + */ + owner_address?: string; + + /** + * Suffix added to the fine-tuned model name + */ + suffix?: string; + + /** + * Count of tokens processed + */ + token_count?: number; + + /** + * Total price for the fine-tuning job + */ + total_price?: number; + + /** + * File-ID of the training file + */ + training_file?: string; + + /** + * Method of training used + */ + training_method?: TrainingMethodSft | TrainingMethodDpo; + + /** + * Type of training used (full or LoRA) + */ + training_type?: FullTrainingType | LoRaTrainingType; + + /** + * Identifier for the user who created the job + */ + user_id?: string; + + /** + * File-ID of the validation file + */ + validation_file?: string; + + /** + * Weights & Biases run name + */ + wandb_name?: string; + + /** + * Weights & Biases project name + */ + wandb_project_name?: string; + + /** + * Ratio of warmup steps + */ + warmup_ratio?: number; + + /** + * Weight decay value used + */ + weight_decay?: number; } export interface FineTuneDownloadResponse { @@ -316,6 +769,26 @@ export interface FineTuneDownloadResponse { size?: number; } +export interface FineTuneListEventsResponse { + data: Array; +} + +export interface FineTuneRetrieveCheckpointsResponse { + data: Array; +} + +export namespace FineTuneRetrieveCheckpointsResponse { + export interface Data { + checkpoint_type: string; + + created_at: string; + + path: string; + + step: number; + } +} + export interface FineTuneCreateParams { /** * Name of the base model to run fine-tune job on @@ -352,7 +825,7 @@ export interface FineTuneCreateParams { * The learning rate scheduler to use. It specifies how the learning rate is * adjusted during training. */ - lr_scheduler?: FineTuneCreateParams.LrScheduler; + lr_scheduler?: LrScheduler; /** * Max gradient norm to be used for gradient clipping. Set to 0 to disable. @@ -381,8 +854,8 @@ export interface FineTuneCreateParams { suffix?: string; /** - * Whether to mask the user messages in conversational data or prompts in - * instruction data. + * @deprecated Whether to mask the user messages in conversational data or prompts + * in instruction data. */ train_on_inputs?: boolean | 'auto'; @@ -390,9 +863,9 @@ export interface FineTuneCreateParams { * The training method to use. 'sft' for Supervised Fine-Tuning or 'dpo' for Direct * Preference Optimization. */ - training_method?: FineTuneCreateParams.TrainingMethodSft | FineTuneCreateParams.TrainingMethodDpo; + training_method?: TrainingMethodSft | TrainingMethodDpo; - training_type?: FineTuneCreateParams.FullTrainingType | FineTuneCreateParams.LoRaTrainingType; + training_type?: FullTrainingType | LoRaTrainingType; /** * File-ID of a validation file uploaded to the Together API @@ -432,65 +905,6 @@ export interface FineTuneCreateParams { weight_decay?: number; } -export namespace FineTuneCreateParams { - /** - * The learning rate scheduler to use. It specifies how the learning rate is - * adjusted during training. - */ - export interface LrScheduler { - lr_scheduler_type: 'linear' | 'cosine'; - - lr_scheduler_args?: LrScheduler.LinearLrSchedulerArgs | LrScheduler.CosineLrSchedulerArgs; - } - - export namespace LrScheduler { - export interface LinearLrSchedulerArgs { - /** - * The ratio of the final learning rate to the peak learning rate - */ - min_lr_ratio?: number; - } - - export interface CosineLrSchedulerArgs { - /** - * The ratio of the final learning rate to the peak learning rate - */ - min_lr_ratio?: number; - - /** - * Number or fraction of cycles for the cosine learning rate scheduler - */ - num_cycles?: number; - } - } - - export interface TrainingMethodSft { - method: 'sft'; - } - - export interface TrainingMethodDpo { - method: 'dpo'; - - dpo_beta?: number; - } - - export interface FullTrainingType { - type: 'Full'; - } - - export interface LoRaTrainingType { - lora_alpha: number; - - lora_r: number; - - type: 'Lora'; - - lora_dropout?: number; - - lora_trainable_modules?: string; - } -} - export interface FineTuneDownloadParams { /** * Fine-tune ID to download. A string that starts with `ft-`. @@ -518,10 +932,21 @@ export interface FineTuneDownloadParams { export declare namespace FineTuneResource { export { + type CosineLrSchedulerArgs as CosineLrSchedulerArgs, type FineTune as FineTune, type FineTuneEvent as FineTuneEvent, + type FullTrainingType as FullTrainingType, + type LinearLrSchedulerArgs as LinearLrSchedulerArgs, + type LoRaTrainingType as LoRaTrainingType, + type LrScheduler as LrScheduler, + type TrainingMethodDpo as TrainingMethodDpo, + type TrainingMethodSft as TrainingMethodSft, + type FineTuneCreateResponse as FineTuneCreateResponse, type FineTuneListResponse as FineTuneListResponse, + type FineTuneCancelResponse as FineTuneCancelResponse, type FineTuneDownloadResponse as FineTuneDownloadResponse, + type FineTuneListEventsResponse as FineTuneListEventsResponse, + type FineTuneRetrieveCheckpointsResponse as FineTuneRetrieveCheckpointsResponse, type FineTuneCreateParams as FineTuneCreateParams, type FineTuneDownloadParams as FineTuneDownloadParams, }; diff --git a/src/resources/images.ts b/src/resources/images.ts index fec1f5db..c68b5116 100644 --- a/src/resources/images.ts +++ b/src/resources/images.ts @@ -6,30 +6,40 @@ import * as Core from '../core'; export class Images extends APIResource { /** * Use an image model to generate an image for a given prompt. + * + * @example + * ```ts + * const imageFile = await client.images.create({ + * model: 'black-forest-labs/FLUX.1-schnell', + * prompt: 'cat floating in space, cinematic', + * }); + * ``` */ create(body: ImageCreateParams, options?: Core.RequestOptions): Core.APIPromise { return this._client.post('/images/generations', { body, ...options }); } } -export interface ImageFile { - id: string; +export interface ImageDataB64 { + b64_json: string; - data: Array; + index: number; +} - model: string; +export interface ImageDataURL { + index: number; - object: 'list'; + url: string; } -export namespace ImageFile { - export interface Data { - index: number; +export interface ImageFile { + id: string; - b64_json?: string; + data: Array; - url?: string; - } + model: string; + + object: 'list'; } export interface ImageCreateParams { @@ -125,5 +135,10 @@ export namespace ImageCreateParams { } export declare namespace Images { - export { type ImageFile as ImageFile, type ImageCreateParams as ImageCreateParams }; + export { + type ImageDataB64 as ImageDataB64, + type ImageDataURL as ImageDataURL, + type ImageFile as ImageFile, + type ImageCreateParams as ImageCreateParams, + }; } diff --git a/src/resources/index.ts b/src/resources/index.ts index a790daf5..8f993f0b 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,6 +1,20 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -export { Audio, type AudioFile, type AudioCreateParams } from './audio'; +export { + Audio, + type AudioFile, + type AudioSpeechStreamChunk, + type AudioCreateParams, + type AudioCreateParamsNonStreaming, + type AudioCreateParamsStreaming, +} from './audio'; +export { + Batches, + type BatchCreateResponse, + type BatchRetrieveResponse, + type BatchListResponse, + type BatchCreateParams, +} from './batches'; export { Chat } from './chat/chat'; export { CodeInterpreter, @@ -10,6 +24,7 @@ export { export { Completions, type Completion, + type CompletionChunk, type LogProbs, type ToolChoice, type Tools, @@ -20,6 +35,7 @@ export { export { Embeddings, type Embedding, type EmbeddingCreateParams } from './embeddings'; export { Endpoints, + type Autoscaling, type EndpointCreateResponse, type EndpointRetrieveResponse, type EndpointUpdateResponse, @@ -31,21 +47,42 @@ export { export { Files, type FileObject, + type FilePurpose, + type FileType, type FileRetrieveResponse, type FileListResponse, type FileDeleteResponse, + type FileUploadResponse, + type FileUploadParams, } from './files'; export { FineTuneResource, + type CosineLrSchedulerArgs, type FineTune, type FineTuneEvent, + type FullTrainingType, + type LinearLrSchedulerArgs, + type LoRaTrainingType, + type LrScheduler, + type TrainingMethodDpo, + type TrainingMethodSft, + type FineTuneCreateResponse, type FineTuneListResponse, + type FineTuneCancelResponse, type FineTuneDownloadResponse, + type FineTuneListEventsResponse, + type FineTuneRetrieveCheckpointsResponse, type FineTuneCreateParams, type FineTuneDownloadParams, } from './fine-tune'; export { Hardware, type HardwareListResponse, type HardwareListParams } from './hardware'; -export { Images, type ImageFile, type ImageCreateParams } from './images'; +export { + Images, + type ImageDataB64, + type ImageDataURL, + type ImageFile, + type ImageCreateParams, +} from './images'; export { Jobs, type JobRetrieveResponse, type JobListResponse } from './jobs'; export { Models, type ModelListResponse, type ModelUploadResponse, type ModelUploadParams } from './models'; export { type RerankResponse, type RerankParams } from './top-level'; diff --git a/src/resources/jobs.ts b/src/resources/jobs.ts index 089afa0d..59041ecd 100644 --- a/src/resources/jobs.ts +++ b/src/resources/jobs.ts @@ -6,6 +6,13 @@ import * as Core from '../core'; export class Jobs extends APIResource { /** * Get the status of a specific job + * + * @example + * ```ts + * const job = await client.jobs.retrieve( + * 'job-a15dad11-8d8e-4007-97c5-a211304de284', + * ); + * ``` */ retrieve(jobId: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.get(`/jobs/${jobId}`, options); @@ -13,6 +20,11 @@ export class Jobs extends APIResource { /** * List all jobs and their statuses + * + * @example + * ```ts + * const jobs = await client.jobs.list(); + * ``` */ list(options?: Core.RequestOptions): Core.APIPromise { return this._client.get('/jobs', options); diff --git a/src/resources/models.ts b/src/resources/models.ts index 22cddb00..33747007 100644 --- a/src/resources/models.ts +++ b/src/resources/models.ts @@ -6,13 +6,26 @@ import * as Core from '../core'; export class Models extends APIResource { /** * Lists all of Together's open-source models + * + * @example + * ```ts + * const models = await client.models.list(); + * ``` */ list(options?: Core.RequestOptions): Core.APIPromise { return this._client.get('/models', options); } /** - * Upload a custom model from Hugging Face or S3 + * Upload a custom model or adapter from Hugging Face or S3 + * + * @example + * ```ts + * const response = await client.models.upload({ + * model_name: 'Qwen2.5-72B-Instruct', + * model_source: 'unsloth/Qwen2.5-72B-Instruct', + * }); + * ``` */ upload(body: ModelUploadParams, options?: Core.RequestOptions): Core.APIPromise { return this._client.post('/models', { body, ...options }); @@ -88,6 +101,12 @@ export interface ModelUploadParams { */ model_source: string; + /** + * The base model to use for an adapter if setting it to run against a serverless + * pool. Only used for model_type `adapter`. + */ + base_model?: string; + /** * A description of your model */ @@ -97,6 +116,17 @@ export interface ModelUploadParams { * Hugging Face token (if uploading from Hugging Face) */ hf_token?: string; + + /** + * The lora pool to use for an adapter if setting it to run against, say, a + * dedicated pool. Only used for model_type `adapter`. + */ + lora_model?: string; + + /** + * Whether the model is a full model or an adapter + */ + model_type?: 'model' | 'adapter'; } export declare namespace Models { diff --git a/src/resources/top-level.ts b/src/resources/top-level.ts index a34be94c..cea1b4da 100644 --- a/src/resources/top-level.ts +++ b/src/resources/top-level.ts @@ -43,7 +43,7 @@ export interface RerankParams { /** * List of documents, which can be either strings or objects. */ - documents: Array> | Array; + documents: Array<{ [key: string]: unknown }> | Array; /** * The model to be used for the rerank request. diff --git a/src/version.ts b/src/version.ts index be03af20..0251da7d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.16.0'; // x-release-please-version +export const VERSION = '0.17.0'; // x-release-please-version diff --git a/tests/api-resources/audio.test.ts b/tests/api-resources/audio.test.ts index f5e307ff..f6baacac 100644 --- a/tests/api-resources/audio.test.ts +++ b/tests/api-resources/audio.test.ts @@ -17,7 +17,7 @@ describe('resource audio', () => { response_encoding: 'pcm_f32le', response_format: 'mp3', sample_rate: 0, - stream: true, + stream: false, }); }); }); diff --git a/tests/api-resources/batches.test.ts b/tests/api-resources/batches.test.ts new file mode 100644 index 00000000..8f58d2bc --- /dev/null +++ b/tests/api-resources/batches.test.ts @@ -0,0 +1,71 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Together from 'together-ai'; +import { Response } from 'node-fetch'; + +const client = new Together({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource batches', () => { + test('create: only required params', async () => { + const responsePromise = client.batches.create({ + endpoint: '/v1/chat/completions', + input_file_id: 'file-abc123def456ghi789', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('create: required and optional params', async () => { + const response = await client.batches.create({ + endpoint: '/v1/chat/completions', + input_file_id: 'file-abc123def456ghi789', + completion_window: '24h', + model_id: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', + priority: 1, + }); + }); + + test('retrieve', async () => { + const responsePromise = client.batches.retrieve('batch_job_abc123def456'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('retrieve: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.batches.retrieve('batch_job_abc123def456', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Together.NotFoundError); + }); + + test('list', async () => { + const responsePromise = client.batches.list(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('list: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect(client.batches.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + Together.NotFoundError, + ); + }); +}); diff --git a/tests/api-resources/chat/completions.test.ts b/tests/api-resources/chat/completions.test.ts index 9fa755e4..becf93c7 100644 --- a/tests/api-resources/chat/completions.test.ts +++ b/tests/api-resources/chat/completions.test.ts @@ -11,7 +11,7 @@ const client = new Together({ describe('resource completions', () => { test('create: only required params', async () => { const responsePromise = client.chat.completions.create({ - messages: [{ content: 'string', role: 'system' }], + messages: [{ content: 'content', role: 'system' }], model: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', }); const rawResponse = await responsePromise.asResponse(); @@ -25,7 +25,7 @@ describe('resource completions', () => { test('create: required and optional params', async () => { const response = await client.chat.completions.create({ - messages: [{ content: 'string', role: 'system' }], + messages: [{ content: 'content', role: 'system', name: 'name' }], model: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo', context_length_exceeded_behavior: 'truncate', echo: true, diff --git a/tests/api-resources/files.test.ts b/tests/api-resources/files.test.ts index bfc9cf73..7bee1e8e 100644 --- a/tests/api-resources/files.test.ts +++ b/tests/api-resources/files.test.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import Together from 'together-ai'; import { Response } from 'node-fetch'; +import Together from 'together-ai'; const client = new Together({ apiKey: 'My API Key', diff --git a/tests/api-resources/fine-tune.test.ts b/tests/api-resources/fine-tune.test.ts index 3b44953b..62be97c9 100644 --- a/tests/api-resources/fine-tune.test.ts +++ b/tests/api-resources/fine-tune.test.ts @@ -9,8 +9,7 @@ const client = new Together({ }); describe('resource fineTune', () => { - // invalid oneOf in required props - test.skip('create: only required params', async () => { + test('create: only required params', async () => { const responsePromise = client.fineTune.create({ model: 'model', training_file: 'training_file' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -21,8 +20,7 @@ describe('resource fineTune', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // invalid oneOf in required props - test.skip('create: required and optional params', async () => { + test('create: required and optional params', async () => { const response = await client.fineTune.create({ model: 'model', training_file: 'training_file', @@ -36,7 +34,7 @@ describe('resource fineTune', () => { n_evals: 0, suffix: 'suffix', train_on_inputs: true, - training_method: { method: 'sft' }, + training_method: { method: 'sft', train_on_inputs: true }, training_type: { type: 'Full' }, validation_file: 'validation_file', wandb_api_key: 'wandb_api_key', @@ -139,4 +137,22 @@ describe('resource fineTune', () => { Together.NotFoundError, ); }); + + test('retrieveCheckpoints', async () => { + const responsePromise = client.fineTune.retrieveCheckpoints('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('retrieveCheckpoints: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.fineTune.retrieveCheckpoints('id', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Together.NotFoundError); + }); }); diff --git a/tests/api-resources/images.test.ts b/tests/api-resources/images.test.ts index 13024d4f..6494e9e3 100644 --- a/tests/api-resources/images.test.ts +++ b/tests/api-resources/images.test.ts @@ -9,8 +9,7 @@ const client = new Together({ }); describe('resource images', () => { - // invalid oneOf in required props - test.skip('create: only required params', async () => { + test('create: only required params', async () => { const responsePromise = client.images.create({ model: 'black-forest-labs/FLUX.1-schnell', prompt: 'cat floating in space, cinematic', @@ -24,8 +23,7 @@ describe('resource images', () => { expect(dataAndResponse.response).toBe(rawResponse); }); - // invalid oneOf in required props - test.skip('create: required and optional params', async () => { + test('create: required and optional params', async () => { const response = await client.images.create({ model: 'black-forest-labs/FLUX.1-schnell', prompt: 'cat floating in space, cinematic', diff --git a/tests/api-resources/models.test.ts b/tests/api-resources/models.test.ts index 6ab7002e..0d31114c 100644 --- a/tests/api-resources/models.test.ts +++ b/tests/api-resources/models.test.ts @@ -45,8 +45,11 @@ describe('resource models', () => { const response = await client.models.upload({ model_name: 'Qwen2.5-72B-Instruct', model_source: 'unsloth/Qwen2.5-72B-Instruct', + base_model: 'Qwen/Qwen2.5-72B-Instruct', description: 'Finetuned Qwen2.5-72B-Instruct by Unsloth', hf_token: 'hf_examplehuggingfacetoken', + lora_model: 'my_username/Qwen2.5-72B-Instruct-lora', + model_type: 'model', }); }); }); diff --git a/tests/index.test.ts b/tests/index.test.ts index 710fb68d..bdc9f744 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -185,6 +185,28 @@ describe('instantiate client', () => { const client = new Together({ apiKey: 'My API Key' }); expect(client.baseURL).toEqual('https://api.together.xyz/v1'); }); + + test('in request options', () => { + const client = new Together({ apiKey: 'My API Key' }); + expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( + 'http://localhost:5000/option/foo', + ); + }); + + test('in request options overridden by client options', () => { + const client = new Together({ apiKey: 'My API Key', baseURL: 'http://localhost:5000/client' }); + expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( + 'http://localhost:5000/client/foo', + ); + }); + + test('in request options overridden by env variable', () => { + process.env['TOGETHER_BASE_URL'] = 'http://localhost:5000/env'; + const client = new Together({ apiKey: 'My API Key' }); + expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( + 'http://localhost:5000/env/foo', + ); + }); }); test('maxRetries option is correctly set', () => {