diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 8ea34be..0000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-# syntax=docker/dockerfile:1
-FROM debian:bookworm-slim AS stainless
-
-RUN apt-get update && apt-get install -y \
- nodejs \
- npm \
- yarnpkg \
- && apt-get clean autoclean
-
-# Ensure UTF-8 encoding
-ENV LANG=C.UTF-8
-ENV LC_ALL=C.UTF-8
-
-# Yarn
-RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn
-
-WORKDIR /workspace
-
-COPY package.json yarn.lock /workspace/
-
-RUN yarn install
-
-COPY . /workspace
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index d55fc4d..763462f 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,20 +1,17 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
{
- "name": "Debian",
- "build": {
- "dockerfile": "Dockerfile"
+ "name": "Development",
+ "image": "mcr.microsoft.com/devcontainers/typescript-node:latest",
+ "features": {
+ "ghcr.io/devcontainers/features/node:1": {}
+ },
+ "postCreateCommand": "yarn install",
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "esbenp.prettier-vscode"
+ ]
+ }
}
-
- // Features to add to the dev container. More info: https://containers.dev/features.
- // "features": {},
-
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
- // "forwardPorts": [],
-
- // Configure tool-specific properties.
- // "customizations": {},
-
- // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
- // "remoteUser": "root"
}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ddb531a..d8b41c9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,19 +1,18 @@
name: CI
on:
push:
- branches:
- - main
- pull_request:
- branches:
- - main
- - next
+ branches-ignore:
+ - 'generated'
+ - 'codegen/**'
+ - 'integrated/**'
+ - 'stl-preview-head/**'
+ - 'stl-preview-base/**'
jobs:
lint:
+ timeout-minutes: 10
name: lint
- runs-on: ubuntu-latest
-
-
+ runs-on: ${{ github.repository == 'stainless-sdks/openlayer-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
@@ -29,10 +28,12 @@ jobs:
run: ./scripts/lint
build:
+ timeout-minutes: 5
name: build
- runs-on: ubuntu-latest
-
-
+ runs-on: ${{ github.repository == 'stainless-sdks/openlayer-node' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ permissions:
+ contents: read
+ id-token: write
steps:
- uses: actions/checkout@v4
@@ -46,3 +47,18 @@ jobs:
- name: Check build
run: ./scripts/build
+
+ - name: Get GitHub OIDC Token
+ if: github.repository == 'stainless-sdks/openlayer-node'
+ id: github-oidc
+ uses: actions/github-script@v6
+ with:
+ script: core.setOutput('github_token', await core.getIDToken());
+
+ - name: Upload tarball
+ if: github.repository == 'stainless-sdks/openlayer-node'
+ env:
+ URL: https://pkg.stainless.com/s
+ AUTH: ${{ steps.github-oidc.outputs.github_token }}
+ SHA: ${{ github.sha }}
+ run: ./scripts/utils/upload-artifact.sh
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 8032c17..ed21d28 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.12.0"
+ ".": "0.13.0"
}
diff --git a/.stats.yml b/.stats.yml
index c254947..2b09528 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1,3 @@
-configured_endpoints: 15
+configured_endpoints: 18
+openapi_spec_hash: 20f058101a252f7500803d66aff58eb3
+config_hash: 30422a4611d93ca69e4f1aff60b9ddb5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b97fbb..085307a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,59 @@
# Changelog
+## 0.13.0 (2025-05-01)
+
+Full Changelog: [v0.12.0...v0.13.0](https://github.com/openlayer-ai/openlayer-ts/compare/v0.12.0...v0.13.0)
+
+### Features
+
+* **api:** add test creation endpoint ([b7cc1b1](https://github.com/openlayer-ai/openlayer-ts/commit/b7cc1b1ee12af1275addac7057d735fb02a43af1))
+* **api:** api update ([372b228](https://github.com/openlayer-ai/openlayer-ts/commit/372b228b95947b7ccb8d6acc9a35eb7a20a31ef6))
+* **api:** api update ([8e2a339](https://github.com/openlayer-ai/openlayer-ts/commit/8e2a33931654d6802087b6435a4beb2c6ed6d7e1))
+* **api:** api update ([2e0a6e1](https://github.com/openlayer-ai/openlayer-ts/commit/2e0a6e1b6a5b3296a3ec905dfa11b5a8501e4583))
+* **api:** api update ([821a692](https://github.com/openlayer-ai/openlayer-ts/commit/821a6926192dad0532029ea9c2b22a4d24f5e1c6))
+* **api:** api update ([28f4085](https://github.com/openlayer-ai/openlayer-ts/commit/28f40851950cfa354930fc8dfab69b4a39f3d13e))
+* **api:** api update ([3345b62](https://github.com/openlayer-ai/openlayer-ts/commit/3345b629c1904bfb2c2f9e05c86312c6c7b88b48))
+* **api:** expose test retrieval endpoint ([da2b9fb](https://github.com/openlayer-ai/openlayer-ts/commit/da2b9fb62bd0eeaebe1325abaee6e4854d2f987f))
+* **api:** expose test retrieval endpoint ([f3fd3fc](https://github.com/openlayer-ai/openlayer-ts/commit/f3fd3fc296af8982eeb965c3427b89abdb7a4a6f))
+* **api:** expose test update endpoint ([785d3b4](https://github.com/openlayer-ai/openlayer-ts/commit/785d3b4ba67f487b49c190d546ae4a7dc7eb333b))
+* **client:** send `X-Stainless-Timeout` header ([333edef](https://github.com/openlayer-ai/openlayer-ts/commit/333edef002f95acecdb29d3e6a698343c3361937))
+
+
+### Bug Fixes
+
+* **api:** improve type resolution when importing as a package ([#119](https://github.com/openlayer-ai/openlayer-ts/issues/119)) ([669c259](https://github.com/openlayer-ai/openlayer-ts/commit/669c259b9fa3ba40ace9901ba24fa80dbc205105))
+* avoid type error in certain environments ([#115](https://github.com/openlayer-ai/openlayer-ts/issues/115)) ([701091f](https://github.com/openlayer-ai/openlayer-ts/commit/701091ff829ca7b7f6ee3bf66af961b660eb3371))
+* **client:** fix export map for index exports ([ac3dffc](https://github.com/openlayer-ai/openlayer-ts/commit/ac3dffce4624d350d5cf73e3020067cb2f71ab59))
+* **client:** send `X-Stainless-Timeout` in seconds ([#117](https://github.com/openlayer-ai/openlayer-ts/issues/117)) ([b8469f3](https://github.com/openlayer-ai/openlayer-ts/commit/b8469f3c2fc46916d994fb20b6ff4550a1c2bed3))
+* **internal:** work around https://github.com/vercel/next.js/issues/76881 ([#116](https://github.com/openlayer-ai/openlayer-ts/issues/116)) ([2349019](https://github.com/openlayer-ai/openlayer-ts/commit/2349019081867529df94ff1143716ce865a30007))
+* **mcp:** remove unused tools.ts ([#120](https://github.com/openlayer-ai/openlayer-ts/issues/120)) ([9d9ab9b](https://github.com/openlayer-ai/openlayer-ts/commit/9d9ab9bd791a42fc4269ad0fcd1dbb57f8616e67))
+
+
+### Chores
+
+* **ci:** add timeout thresholds for CI jobs ([64632ad](https://github.com/openlayer-ai/openlayer-ts/commit/64632ad55c30e27a0ca063c28b410d6b83b245b4))
+* **ci:** only use depot for staging repos ([9c8f4b9](https://github.com/openlayer-ai/openlayer-ts/commit/9c8f4b9181f636898c5ff8365596b47c591575f1))
+* **client:** minor internal fixes ([344120f](https://github.com/openlayer-ai/openlayer-ts/commit/344120f8eb82ea1e374aafadf6c7e90edec2cbce))
+* **exports:** cleaner resource index imports ([#113](https://github.com/openlayer-ai/openlayer-ts/issues/113)) ([9ac3180](https://github.com/openlayer-ai/openlayer-ts/commit/9ac318013fd2128e7f0a98db699534569c8e18a3))
+* **exports:** stop using path fallbacks ([#114](https://github.com/openlayer-ai/openlayer-ts/issues/114)) ([fdcd6e2](https://github.com/openlayer-ai/openlayer-ts/commit/fdcd6e2effcd89201604c545e0c3b8f0f0800032))
+* **internal:** add aliases for Record and Array ([#118](https://github.com/openlayer-ai/openlayer-ts/issues/118)) ([da4702c](https://github.com/openlayer-ai/openlayer-ts/commit/da4702cab36298cc7278a3f0a797742c5e23a002))
+* **internal:** codegen related update ([1128c8f](https://github.com/openlayer-ai/openlayer-ts/commit/1128c8f19942ebfecc014626f859dfdadc5725d1))
+* **internal:** codegen related update ([1016df6](https://github.com/openlayer-ai/openlayer-ts/commit/1016df6f549fd3312c26f6ecfd15b3aac58c5d65))
+* **internal:** codegen related update ([ca17307](https://github.com/openlayer-ai/openlayer-ts/commit/ca173073bc522424d9d6a35b5a2af14ccd7b8c88))
+* **internal:** codegen related update ([fd5d0a9](https://github.com/openlayer-ai/openlayer-ts/commit/fd5d0a9808b2abf8d1b88d3becf2350d9b25887e))
+* **internal:** fix devcontainers setup ([6a459de](https://github.com/openlayer-ai/openlayer-ts/commit/6a459de24ebec36ba38b751b6ab7143b3b9e16fd))
+* **internal:** fix workflows ([59a7cb4](https://github.com/openlayer-ai/openlayer-ts/commit/59a7cb4439a344c0ed6b4adb9e6b113dbed0f940))
+* **internal:** reduce CI branch coverage ([71998ef](https://github.com/openlayer-ai/openlayer-ts/commit/71998ef9132f29569e40aa1310cf2b3611096865))
+* **internal:** upload builds and expand CI branch coverage ([5d8ec66](https://github.com/openlayer-ai/openlayer-ts/commit/5d8ec66ad5ca7ba34da7b56b5f2aa1e9638107cd))
+* **internal:** version bump ([3a31790](https://github.com/openlayer-ai/openlayer-ts/commit/3a317902d8bf523f3f54398cdb077a11a18d9995))
+* **tests:** improve enum examples ([#121](https://github.com/openlayer-ai/openlayer-ts/issues/121)) ([f3a00ab](https://github.com/openlayer-ai/openlayer-ts/commit/f3a00ab15a42239fc71459feb324bd835f5d79e9))
+
+
+### Documentation
+
+* **readme:** fix typo ([3461fd6](https://github.com/openlayer-ai/openlayer-ts/commit/3461fd6e7a989064ef94b9e1d0c8d26374116aa4))
+* update URLs from stainlessapi.com to stainless.com ([e56ef04](https://github.com/openlayer-ai/openlayer-ts/commit/e56ef04346aa002b8481a8018ad540c678a9a21e))
+
## 0.12.0 (2025-03-14)
Full Changelog: [v0.11.0...v0.12.0](https://github.com/openlayer-ai/openlayer-ts/compare/v0.11.0...v0.12.0)
diff --git a/README.md b/README.md
index c0a8352..f6b1ed4 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This library provides convenient access to the Openlayer REST API from server-si
The REST API documentation can be found on [openlayer.com](https://openlayer.com/docs/api-reference/rest/overview). The full API of this library can be found in [api.md](api.md).
-It is generated with [Stainless](https://www.stainlessapi.com/).
+It is generated with [Stainless](https://www.stainless.com/).
## Installation
@@ -134,7 +134,7 @@ async function main() {
main();
```
-Error codes are as followed:
+Error codes are as follows:
| Status Code | Error Type |
| ----------- | -------------------------- |
@@ -380,7 +380,7 @@ await client.inferencePipelines.data.stream(
This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
1. Changes that only affect static types, without breaking runtime behavior.
-2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
+2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
3. Changes that we do not expect to impact the vast majority of users in practice.
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
diff --git a/SECURITY.md b/SECURITY.md
index 6dfa13e..8614b05 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,9 +2,9 @@
## Reporting Security Issues
-This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
+This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
-To report a security issue, please contact the Stainless team at security@stainlessapi.com.
+To report a security issue, please contact the Stainless team at security@stainless.com.
## Responsible Disclosure
diff --git a/api.md b/api.md
index 93b4252..6de15d2 100644
--- a/api.md
+++ b/api.md
@@ -34,6 +34,20 @@ Methods:
- client.projects.inferencePipelines.create(projectId, { ...params }) -> InferencePipelineCreateResponse
- client.projects.inferencePipelines.list(projectId, { ...params }) -> InferencePipelineListResponse
+## Tests
+
+Types:
+
+- TestCreateResponse
+- TestUpdateResponse
+- TestListResponse
+
+Methods:
+
+- client.projects.tests.create(projectId, { ...params }) -> TestCreateResponse
+- client.projects.tests.update(projectId, { ...params }) -> TestUpdateResponse
+- client.projects.tests.list(projectId, { ...params }) -> TestListResponse
+
# Commits
Types:
diff --git a/bin/check-release-environment b/bin/check-release-environment
index 0f4fafe..5da9dd7 100644
--- a/bin/check-release-environment
+++ b/bin/check-release-environment
@@ -2,6 +2,10 @@
errors=()
+if [ -z "${STAINLESS_API_KEY}" ]; then
+ errors+=("The STAINLESS_API_KEY secret has not been set. Please contact Stainless for an API key & set it in your organization secrets on GitHub.")
+fi
+
if [ -z "${NPM_TOKEN}" ]; then
errors+=("The OPENLAYER_NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
fi
diff --git a/package.json b/package.json
index 13eefa3..b6df9a9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openlayer",
- "version": "0.12.0",
+ "version": "0.13.0",
"description": "The official TypeScript library for the Openlayer API",
"author": "Openlayer ",
"types": "dist/index.d.ts",
diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh
new file mode 100755
index 0000000..380c00e
--- /dev/null
+++ b/scripts/utils/upload-artifact.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+set -exuo pipefail
+
+RESPONSE=$(curl -X POST "$URL" \
+ -H "Authorization: Bearer $AUTH" \
+ -H "Content-Type: application/json")
+
+SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url')
+
+if [[ "$SIGNED_URL" == "null" ]]; then
+ echo -e "\033[31mFailed to get signed URL.\033[0m"
+ exit 1
+fi
+
+UPLOAD_RESPONSE=$(tar -cz dist | curl -v -X PUT \
+ -H "Content-Type: application/gzip" \
+ --data-binary @- "$SIGNED_URL" 2>&1)
+
+if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then
+ echo -e "\033[32mUploaded build to Stainless storage.\033[0m"
+ echo -e "\033[32mInstallation: npm install 'https://pkg.stainless.com/s/openlayer-node/$SHA'\033[0m"
+else
+ echo -e "\033[31mFailed to upload artifact.\033[0m"
+ exit 1
+fi
diff --git a/src/_shims/index-deno.ts b/src/_shims/index-deno.ts
index f98dad2..e755878 100644
--- a/src/_shims/index-deno.ts
+++ b/src/_shims/index-deno.ts
@@ -108,3 +108,5 @@ export declare class FsReadStream extends Readable {
const _ReadableStream = ReadableStream;
type _ReadableStream = ReadableStream;
export { _ReadableStream as ReadableStream };
+
+export const init = () => {};
diff --git a/src/_shims/index.d.ts b/src/_shims/index.d.ts
index 63ce99a..e3d9fc4 100644
--- a/src/_shims/index.d.ts
+++ b/src/_shims/index.d.ts
@@ -79,3 +79,5 @@ export function fileFromPath(path: string, options?: FileFromPathOptions): Promi
export function fileFromPath(path: string, filename?: string, options?: FileFromPathOptions): Promise;
export function isFsReadStream(value: any): value is FsReadStream;
+
+export const init: () => void;
diff --git a/src/_shims/index.js b/src/_shims/index.js
index 6b777dd..639ea48 100644
--- a/src/_shims/index.js
+++ b/src/_shims/index.js
@@ -3,7 +3,9 @@
*/
const shims = require('./registry');
const auto = require('openlayer/_shims/auto/runtime');
-if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
+exports.init = () => {
+ if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
+};
for (const property of Object.keys(shims)) {
Object.defineProperty(exports, property, {
get() {
@@ -11,3 +13,5 @@ for (const property of Object.keys(shims)) {
},
});
}
+
+exports.init();
diff --git a/src/_shims/index.mjs b/src/_shims/index.mjs
index 624fd3d..159fb36 100644
--- a/src/_shims/index.mjs
+++ b/src/_shims/index.mjs
@@ -3,5 +3,9 @@
*/
import * as shims from './registry.mjs';
import * as auto from 'openlayer/_shims/auto/runtime';
-if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
+export const init = () => {
+ if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
+};
export * from './registry.mjs';
+
+init();
diff --git a/src/core.ts b/src/core.ts
index 5981ff8..27031d0 100644
--- a/src/core.ts
+++ b/src/core.ts
@@ -16,7 +16,12 @@ import {
type RequestInit,
type Response,
type HeadersInit,
+ init,
} from './_shims/index';
+
+// try running side effects outside of _shims/index to workaround https://github.com/vercel/next.js/issues/76881
+init();
+
export { type Response };
import { BlobLike, isBlobLike, isMultipartBody } from './uploads';
export {
@@ -28,6 +33,20 @@ export {
export type Fetch = (url: RequestInfo, init?: RequestInit) => Promise;
+/**
+ * An alias to the builtin `Array` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Array = Array;
+
+/**
+ * An alias to the builtin `Record` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Record = Record;
+
+export type { _Array as Array, _Record as Record };
+
type PromiseOrValue = T | Promise;
type APIResponseProps = {
@@ -277,9 +296,10 @@ export abstract class APIClient {
}
buildRequest(
- options: FinalRequestOptions,
+ inputOptions: FinalRequestOptions,
{ retryCount = 0 }: { retryCount?: number } = {},
): { req: RequestInit; url: string; timeout: number } {
+ const options = { ...inputOptions };
const { method, path, query, headers: headers = {} } = options;
const body =
@@ -292,9 +312,9 @@ export abstract class APIClient {
const url = this.buildURL(path!, query);
if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
- const timeout = options.timeout ?? this.timeout;
+ options.timeout = options.timeout ?? this.timeout;
const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url);
- const minAgentTimeout = timeout + 1000;
+ const minAgentTimeout = options.timeout + 1000;
if (
typeof (httpAgent as any)?.options?.timeout === 'number' &&
minAgentTimeout > ((httpAgent as any).options.timeout ?? 0)
@@ -307,8 +327,8 @@ export abstract class APIClient {
}
if (this.idempotencyHeader && method !== 'get') {
- if (!options.idempotencyKey) options.idempotencyKey = this.defaultIdempotencyKey();
- headers[this.idempotencyHeader] = options.idempotencyKey;
+ if (!inputOptions.idempotencyKey) inputOptions.idempotencyKey = this.defaultIdempotencyKey();
+ headers[this.idempotencyHeader] = inputOptions.idempotencyKey;
}
const reqHeaders = this.buildHeaders({ options, headers, contentLength, retryCount });
@@ -323,7 +343,7 @@ export abstract class APIClient {
signal: options.signal ?? null,
};
- return { req, url, timeout };
+ return { req, url, timeout: options.timeout };
}
private buildHeaders({
@@ -351,15 +371,22 @@ export abstract class APIClient {
delete reqHeaders['content-type'];
}
- // Don't set the retry count header if it was already set or removed through default headers or by the
- // caller. We check `defaultHeaders` and `headers`, which can contain nulls, instead of `reqHeaders` to
- // account for the removal case.
+ // Don't set theses headers if they were already set or removed through default headers or by the caller.
+ // We check `defaultHeaders` and `headers`, which can contain nulls, instead of `reqHeaders` to account
+ // for the removal case.
if (
getHeader(defaultHeaders, 'x-stainless-retry-count') === undefined &&
getHeader(headers, 'x-stainless-retry-count') === undefined
) {
reqHeaders['x-stainless-retry-count'] = String(retryCount);
}
+ if (
+ getHeader(defaultHeaders, 'x-stainless-timeout') === undefined &&
+ getHeader(headers, 'x-stainless-timeout') === undefined &&
+ options.timeout
+ ) {
+ reqHeaders['x-stainless-timeout'] = String(Math.trunc(options.timeout / 1000));
+ }
this.validateHeaders(reqHeaders, headers);
@@ -387,7 +414,7 @@ export abstract class APIClient {
!headers ? {}
: Symbol.iterator in headers ?
Object.fromEntries(Array.from(headers as Iterable).map((header) => [...header]))
- : { ...headers }
+ : { ...(headers as any as Record) }
);
}
diff --git a/src/index.ts b/src/index.ts
index e2cc2f8..96767aa 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -43,7 +43,7 @@ export interface ClientOptions {
* Note that request timeouts are retried by default, so in a worst-case scenario you may wait
* much longer than this timeout before the promise succeeds or fails.
*/
- timeout?: number;
+ timeout?: number | undefined;
/**
* An HTTP agent used to manage HTTP(S) connections.
@@ -51,7 +51,7 @@ export interface ClientOptions {
* If not provided, an agent will be constructed by default in the Node.js environment,
* otherwise no agent is used.
*/
- httpAgent?: Agent;
+ httpAgent?: Agent | undefined;
/**
* Specify a custom `fetch` function implementation.
@@ -67,7 +67,7 @@ export interface ClientOptions {
*
* @default 2
*/
- maxRetries?: number;
+ maxRetries?: number | undefined;
/**
* Default headers to include with every request to the API.
@@ -75,7 +75,7 @@ export interface ClientOptions {
* These can be removed in individual requests by explicitly setting the
* header to `undefined` or `null` in request options.
*/
- defaultHeaders?: Core.Headers;
+ defaultHeaders?: Core.Headers | undefined;
/**
* Default query parameters to include with every request to the API.
@@ -83,7 +83,7 @@ export interface ClientOptions {
* These can be removed in individual requests by explicitly setting the
* param to `undefined` in request options.
*/
- defaultQuery?: Core.DefaultQuery;
+ defaultQuery?: Core.DefaultQuery | undefined;
}
/**
diff --git a/src/resources.ts b/src/resources.ts
new file mode 100644
index 0000000..b283d57
--- /dev/null
+++ b/src/resources.ts
@@ -0,0 +1 @@
+export * from './resources/index';
diff --git a/src/resources/commits/test-results.ts b/src/resources/commits/test-results.ts
index ab1b977..e8a5d7a 100644
--- a/src/resources/commits/test-results.ts
+++ b/src/resources/commits/test-results.ts
@@ -140,7 +140,48 @@ export namespace TestResultListResponse {
/**
* The test subtype.
*/
- subtype: string;
+ subtype:
+ | 'anomalousColumnCount'
+ | 'characterLength'
+ | 'classImbalanceRatio'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnStatistic'
+ | 'columnValuesMatch'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatureCount'
+ | 'customMetricThreshold'
+ | 'duplicateRowCount'
+ | 'emptyFeature'
+ | 'emptyFeatureCount'
+ | 'driftedFeatureCount'
+ | 'featureMissingValues'
+ | 'featureValueValidation'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricThresholdV2'
+ | 'labelDrift'
+ | 'metricThreshold'
+ | 'newCategoryCount'
+ | 'newLabelCount'
+ | 'nullRowCount'
+ | 'rowCount'
+ | 'ppScoreValueValidation'
+ | 'quasiConstantFeature'
+ | 'quasiConstantFeatureCount'
+ | 'sqlQuery'
+ | 'dtypeValidation'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharactersRatio'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
/**
* Whether the test is suggested or user-created.
@@ -152,7 +193,7 @@ export namespace TestResultListResponse {
/**
* The test type.
*/
- type: string;
+ type: 'integrity' | 'consistency' | 'performance';
/**
* Whether the test is archived.
@@ -201,9 +242,48 @@ export namespace TestResultListResponse {
/**
* The insight name to be evaluated.
*/
- insightName?: string;
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
- insightParameters?: Array;
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
/**
* The measurement to be evaluated.
@@ -213,20 +293,36 @@ export namespace TestResultListResponse {
/**
* The operator to be used for the evaluation.
*/
- operator?: string;
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
/**
* The value to be compared.
*/
value?: number | boolean | string | Array;
}
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
}
}
}
export interface TestResultListParams {
/**
- * Include archived goals.
+ * Filter for archived tests.
*/
includeArchived?: boolean;
diff --git a/src/resources/inference-pipelines/inference-pipelines.ts b/src/resources/inference-pipelines/inference-pipelines.ts
index efdb59b..4e5b1c8 100644
--- a/src/resources/inference-pipelines/inference-pipelines.ts
+++ b/src/resources/inference-pipelines/inference-pipelines.ts
@@ -275,26 +275,59 @@ export namespace InferencePipelineRetrieveResponse {
}
export interface Workspace {
+ /**
+ * The workspace id.
+ */
id: string;
+ /**
+ * The workspace creator id.
+ */
creatorId: string | null;
+ /**
+ * The workspace creation date.
+ */
dateCreated: string;
+ /**
+ * The workspace last updated date.
+ */
dateUpdated: string;
+ /**
+ * The number of invites in the workspace.
+ */
inviteCount: number;
+ /**
+ * The number of members in the workspace.
+ */
memberCount: number;
+ /**
+ * The workspace name.
+ */
name: string;
+ /**
+ * The end date of the current billing period.
+ */
periodEndDate: string | null;
+ /**
+ * The start date of the current billing period.
+ */
periodStartDate: string | null;
+ /**
+ * The number of projects in the workspace.
+ */
projectCount: number;
+ /**
+ * The workspace slug.
+ */
slug: string;
status:
@@ -309,6 +342,9 @@ export namespace InferencePipelineRetrieveResponse {
monthlyUsage?: Array;
+ /**
+ * Whether the workspace only allows SAML authentication.
+ */
samlOnlyAccess?: boolean;
wildcardDomains?: Array;
@@ -528,26 +564,59 @@ export namespace InferencePipelineUpdateResponse {
}
export interface Workspace {
+ /**
+ * The workspace id.
+ */
id: string;
+ /**
+ * The workspace creator id.
+ */
creatorId: string | null;
+ /**
+ * The workspace creation date.
+ */
dateCreated: string;
+ /**
+ * The workspace last updated date.
+ */
dateUpdated: string;
+ /**
+ * The number of invites in the workspace.
+ */
inviteCount: number;
+ /**
+ * The number of members in the workspace.
+ */
memberCount: number;
+ /**
+ * The workspace name.
+ */
name: string;
+ /**
+ * The end date of the current billing period.
+ */
periodEndDate: string | null;
+ /**
+ * The start date of the current billing period.
+ */
periodStartDate: string | null;
+ /**
+ * The number of projects in the workspace.
+ */
projectCount: number;
+ /**
+ * The workspace slug.
+ */
slug: string;
status:
@@ -562,6 +631,9 @@ export namespace InferencePipelineUpdateResponse {
monthlyUsage?: Array;
+ /**
+ * Whether the workspace only allows SAML authentication.
+ */
samlOnlyAccess?: boolean;
wildcardDomains?: Array;
diff --git a/src/resources/inference-pipelines/test-results.ts b/src/resources/inference-pipelines/test-results.ts
index 17a72f9..2e852c6 100644
--- a/src/resources/inference-pipelines/test-results.ts
+++ b/src/resources/inference-pipelines/test-results.ts
@@ -140,7 +140,48 @@ export namespace TestResultListResponse {
/**
* The test subtype.
*/
- subtype: string;
+ subtype:
+ | 'anomalousColumnCount'
+ | 'characterLength'
+ | 'classImbalanceRatio'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnStatistic'
+ | 'columnValuesMatch'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatureCount'
+ | 'customMetricThreshold'
+ | 'duplicateRowCount'
+ | 'emptyFeature'
+ | 'emptyFeatureCount'
+ | 'driftedFeatureCount'
+ | 'featureMissingValues'
+ | 'featureValueValidation'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricThresholdV2'
+ | 'labelDrift'
+ | 'metricThreshold'
+ | 'newCategoryCount'
+ | 'newLabelCount'
+ | 'nullRowCount'
+ | 'rowCount'
+ | 'ppScoreValueValidation'
+ | 'quasiConstantFeature'
+ | 'quasiConstantFeatureCount'
+ | 'sqlQuery'
+ | 'dtypeValidation'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharactersRatio'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
/**
* Whether the test is suggested or user-created.
@@ -152,7 +193,7 @@ export namespace TestResultListResponse {
/**
* The test type.
*/
- type: string;
+ type: 'integrity' | 'consistency' | 'performance';
/**
* Whether the test is archived.
@@ -201,9 +242,48 @@ export namespace TestResultListResponse {
/**
* The insight name to be evaluated.
*/
- insightName?: string;
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
- insightParameters?: Array;
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
/**
* The measurement to be evaluated.
@@ -213,13 +293,29 @@ export namespace TestResultListResponse {
/**
* The operator to be used for the evaluation.
*/
- operator?: string;
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
/**
* The value to be compared.
*/
value?: number | boolean | string | Array;
}
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
}
}
}
diff --git a/src/resources/projects/index.ts b/src/resources/projects/index.ts
index de97190..c53d21e 100644
--- a/src/resources/projects/index.ts
+++ b/src/resources/projects/index.ts
@@ -21,3 +21,12 @@ export {
type ProjectCreateParams,
type ProjectListParams,
} from './projects';
+export {
+ Tests,
+ type TestCreateResponse,
+ type TestUpdateResponse,
+ type TestListResponse,
+ type TestCreateParams,
+ type TestUpdateParams,
+ type TestListParams,
+} from './tests';
diff --git a/src/resources/projects/inference-pipelines.ts b/src/resources/projects/inference-pipelines.ts
index 7f91d92..eed6c61 100644
--- a/src/resources/projects/inference-pipelines.ts
+++ b/src/resources/projects/inference-pipelines.ts
@@ -240,26 +240,59 @@ export namespace InferencePipelineCreateResponse {
}
export interface Workspace {
+ /**
+ * The workspace id.
+ */
id: string;
+ /**
+ * The workspace creator id.
+ */
creatorId: string | null;
+ /**
+ * The workspace creation date.
+ */
dateCreated: string;
+ /**
+ * The workspace last updated date.
+ */
dateUpdated: string;
+ /**
+ * The number of invites in the workspace.
+ */
inviteCount: number;
+ /**
+ * The number of members in the workspace.
+ */
memberCount: number;
+ /**
+ * The workspace name.
+ */
name: string;
+ /**
+ * The end date of the current billing period.
+ */
periodEndDate: string | null;
+ /**
+ * The start date of the current billing period.
+ */
periodStartDate: string | null;
+ /**
+ * The number of projects in the workspace.
+ */
projectCount: number;
+ /**
+ * The workspace slug.
+ */
slug: string;
status:
@@ -274,6 +307,9 @@ export namespace InferencePipelineCreateResponse {
monthlyUsage?: Array;
+ /**
+ * Whether the workspace only allows SAML authentication.
+ */
samlOnlyAccess?: boolean;
wildcardDomains?: Array;
@@ -498,26 +534,59 @@ export namespace InferencePipelineListResponse {
}
export interface Workspace {
+ /**
+ * The workspace id.
+ */
id: string;
+ /**
+ * The workspace creator id.
+ */
creatorId: string | null;
+ /**
+ * The workspace creation date.
+ */
dateCreated: string;
+ /**
+ * The workspace last updated date.
+ */
dateUpdated: string;
+ /**
+ * The number of invites in the workspace.
+ */
inviteCount: number;
+ /**
+ * The number of members in the workspace.
+ */
memberCount: number;
+ /**
+ * The workspace name.
+ */
name: string;
+ /**
+ * The end date of the current billing period.
+ */
periodEndDate: string | null;
+ /**
+ * The start date of the current billing period.
+ */
periodStartDate: string | null;
+ /**
+ * The number of projects in the workspace.
+ */
projectCount: number;
+ /**
+ * The workspace slug.
+ */
slug: string;
status:
@@ -532,6 +601,9 @@ export namespace InferencePipelineListResponse {
monthlyUsage?: Array;
+ /**
+ * Whether the workspace only allows SAML authentication.
+ */
samlOnlyAccess?: boolean;
wildcardDomains?: Array;
@@ -584,12 +656,24 @@ export namespace InferencePipelineCreateParams {
}
export interface Workspace {
+ /**
+ * The workspace name.
+ */
name: string;
+ /**
+ * The workspace slug.
+ */
slug: string;
+ /**
+ * The workspace invite code.
+ */
inviteCode?: string;
+ /**
+ * Whether the workspace only allows SAML authentication.
+ */
samlOnlyAccess?: boolean;
wildcardDomains?: Array;
diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts
index dbf39e5..8591b63 100644
--- a/src/resources/projects/projects.ts
+++ b/src/resources/projects/projects.ts
@@ -19,12 +19,23 @@ import {
InferencePipelineListResponse,
InferencePipelines,
} from './inference-pipelines';
+import * as TestsAPI from './tests';
+import {
+ TestCreateParams,
+ TestCreateResponse,
+ TestListParams,
+ TestListResponse,
+ TestUpdateParams,
+ TestUpdateResponse,
+ Tests,
+} from './tests';
export class Projects extends APIResource {
commits: CommitsAPI.Commits = new CommitsAPI.Commits(this._client);
inferencePipelines: InferencePipelinesAPI.InferencePipelines = new InferencePipelinesAPI.InferencePipelines(
this._client,
);
+ tests: TestsAPI.Tests = new TestsAPI.Tests(this._client);
/**
* Create a project in your workspace.
@@ -324,6 +335,7 @@ export interface ProjectListParams {
Projects.Commits = Commits;
Projects.InferencePipelines = InferencePipelines;
+Projects.Tests = Tests;
export declare namespace Projects {
export {
@@ -348,4 +360,14 @@ export declare namespace Projects {
type InferencePipelineCreateParams as InferencePipelineCreateParams,
type InferencePipelineListParams as InferencePipelineListParams,
};
+
+ export {
+ Tests as Tests,
+ type TestCreateResponse as TestCreateResponse,
+ type TestUpdateResponse as TestUpdateResponse,
+ type TestListResponse as TestListResponse,
+ type TestCreateParams as TestCreateParams,
+ type TestUpdateParams as TestUpdateParams,
+ type TestListParams as TestListParams,
+ };
}
diff --git a/src/resources/projects/tests.ts b/src/resources/projects/tests.ts
new file mode 100644
index 0000000..c2caa83
--- /dev/null
+++ b/src/resources/projects/tests.ts
@@ -0,0 +1,871 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../resource';
+import { isRequestOptions } from '../../core';
+import * as Core from '../../core';
+
+export class Tests extends APIResource {
+ /**
+ * Create a test.
+ */
+ create(
+ projectId: string,
+ body: TestCreateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.post(`/projects/${projectId}/tests`, { body, ...options });
+ }
+
+ /**
+ * Update tests.
+ */
+ update(
+ projectId: string,
+ body: TestUpdateParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ return this._client.put(`/projects/${projectId}/tests`, { body, ...options });
+ }
+
+ /**
+ * List tests under a project.
+ */
+ list(
+ projectId: string,
+ query?: TestListParams,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise;
+ list(projectId: string, options?: Core.RequestOptions): Core.APIPromise;
+ list(
+ projectId: string,
+ query: TestListParams | Core.RequestOptions = {},
+ options?: Core.RequestOptions,
+ ): Core.APIPromise {
+ if (isRequestOptions(query)) {
+ return this.list(projectId, {}, query);
+ }
+ return this._client.get(`/projects/${projectId}/tests`, { query, ...options });
+ }
+}
+
+export interface TestCreateResponse {
+ /**
+ * The test id.
+ */
+ id: string;
+
+ /**
+ * The number of comments on the test.
+ */
+ commentCount: number;
+
+ /**
+ * The test creator id.
+ */
+ creatorId: string | null;
+
+ /**
+ * The date the test was archived.
+ */
+ dateArchived: string | null;
+
+ /**
+ * The creation date.
+ */
+ dateCreated: string;
+
+ /**
+ * The last updated date.
+ */
+ dateUpdated: string;
+
+ /**
+ * The test description.
+ */
+ description: unknown | null;
+
+ /**
+ * The test name.
+ */
+ name: string;
+
+ /**
+ * The test number.
+ */
+ number: number;
+
+ /**
+ * The project version (commit) id where the test was created.
+ */
+ originProjectVersionId: string | null;
+
+ /**
+ * The test subtype.
+ */
+ subtype:
+ | 'anomalousColumnCount'
+ | 'characterLength'
+ | 'classImbalanceRatio'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnStatistic'
+ | 'columnValuesMatch'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatureCount'
+ | 'customMetricThreshold'
+ | 'duplicateRowCount'
+ | 'emptyFeature'
+ | 'emptyFeatureCount'
+ | 'driftedFeatureCount'
+ | 'featureMissingValues'
+ | 'featureValueValidation'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricThresholdV2'
+ | 'labelDrift'
+ | 'metricThreshold'
+ | 'newCategoryCount'
+ | 'newLabelCount'
+ | 'nullRowCount'
+ | 'rowCount'
+ | 'ppScoreValueValidation'
+ | 'quasiConstantFeature'
+ | 'quasiConstantFeatureCount'
+ | 'sqlQuery'
+ | 'dtypeValidation'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharactersRatio'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * Whether the test is suggested or user-created.
+ */
+ suggested: boolean;
+
+ thresholds: Array;
+
+ /**
+ * The test type.
+ */
+ type: 'integrity' | 'consistency' | 'performance';
+
+ /**
+ * Whether the test is archived.
+ */
+ archived?: boolean;
+
+ /**
+ * The delay window in seconds. Only applies to tests that use production data.
+ */
+ delayWindow?: number | null;
+
+ /**
+ * The evaluation window in seconds. Only applies to tests that use production
+ * data.
+ */
+ evaluationWindow?: number | null;
+
+ /**
+ * Whether the test uses an ML model.
+ */
+ usesMlModel?: boolean;
+
+ /**
+ * Whether the test uses production data (monitoring mode only).
+ */
+ usesProductionData?: boolean;
+
+ /**
+ * Whether the test uses a reference dataset (monitoring mode only).
+ */
+ usesReferenceDataset?: boolean;
+
+ /**
+ * Whether the test uses a training dataset.
+ */
+ usesTrainingDataset?: boolean;
+
+ /**
+ * Whether the test uses a validation dataset.
+ */
+ usesValidationDataset?: boolean;
+}
+
+export namespace TestCreateResponse {
+ export interface Threshold {
+ /**
+ * The insight name to be evaluated.
+ */
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
+
+ /**
+ * The measurement to be evaluated.
+ */
+ measurement?: string;
+
+ /**
+ * The operator to be used for the evaluation.
+ */
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
+
+ /**
+ * The value to be compared.
+ */
+ value?: number | boolean | string | Array;
+ }
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
+}
+
+export interface TestUpdateResponse {
+ taskResultId?: string;
+
+ taskResultUrl?: string;
+}
+
+export interface TestListResponse {
+ items: Array;
+}
+
+export namespace TestListResponse {
+ export interface Item {
+ /**
+ * The test id.
+ */
+ id: string;
+
+ /**
+ * The number of comments on the test.
+ */
+ commentCount: number;
+
+ /**
+ * The test creator id.
+ */
+ creatorId: string | null;
+
+ /**
+ * The date the test was archived.
+ */
+ dateArchived: string | null;
+
+ /**
+ * The creation date.
+ */
+ dateCreated: string;
+
+ /**
+ * The last updated date.
+ */
+ dateUpdated: string;
+
+ /**
+ * The test description.
+ */
+ description: unknown | null;
+
+ /**
+ * The test name.
+ */
+ name: string;
+
+ /**
+ * The test number.
+ */
+ number: number;
+
+ /**
+ * The project version (commit) id where the test was created.
+ */
+ originProjectVersionId: string | null;
+
+ /**
+ * The test subtype.
+ */
+ subtype:
+ | 'anomalousColumnCount'
+ | 'characterLength'
+ | 'classImbalanceRatio'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnStatistic'
+ | 'columnValuesMatch'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatureCount'
+ | 'customMetricThreshold'
+ | 'duplicateRowCount'
+ | 'emptyFeature'
+ | 'emptyFeatureCount'
+ | 'driftedFeatureCount'
+ | 'featureMissingValues'
+ | 'featureValueValidation'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricThresholdV2'
+ | 'labelDrift'
+ | 'metricThreshold'
+ | 'newCategoryCount'
+ | 'newLabelCount'
+ | 'nullRowCount'
+ | 'rowCount'
+ | 'ppScoreValueValidation'
+ | 'quasiConstantFeature'
+ | 'quasiConstantFeatureCount'
+ | 'sqlQuery'
+ | 'dtypeValidation'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharactersRatio'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * Whether the test is suggested or user-created.
+ */
+ suggested: boolean;
+
+ thresholds: Array;
+
+ /**
+ * The test type.
+ */
+ type: 'integrity' | 'consistency' | 'performance';
+
+ /**
+ * Whether the test is archived.
+ */
+ archived?: boolean;
+
+ /**
+ * The delay window in seconds. Only applies to tests that use production data.
+ */
+ delayWindow?: number | null;
+
+ /**
+ * The evaluation window in seconds. Only applies to tests that use production
+ * data.
+ */
+ evaluationWindow?: number | null;
+
+ /**
+ * Whether the test uses an ML model.
+ */
+ usesMlModel?: boolean;
+
+ /**
+ * Whether the test uses production data (monitoring mode only).
+ */
+ usesProductionData?: boolean;
+
+ /**
+ * Whether the test uses a reference dataset (monitoring mode only).
+ */
+ usesReferenceDataset?: boolean;
+
+ /**
+ * Whether the test uses a training dataset.
+ */
+ usesTrainingDataset?: boolean;
+
+ /**
+ * Whether the test uses a validation dataset.
+ */
+ usesValidationDataset?: boolean;
+ }
+
+ export namespace Item {
+ export interface Threshold {
+ /**
+ * The insight name to be evaluated.
+ */
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
+
+ /**
+ * The measurement to be evaluated.
+ */
+ measurement?: string;
+
+ /**
+ * The operator to be used for the evaluation.
+ */
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
+
+ /**
+ * The value to be compared.
+ */
+ value?: number | boolean | string | Array;
+ }
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
+ }
+}
+
+export interface TestCreateParams {
+ /**
+ * The test description.
+ */
+ description: unknown | null;
+
+ /**
+ * The test name.
+ */
+ name: string;
+
+ /**
+ * The test subtype.
+ */
+ subtype:
+ | 'anomalousColumnCount'
+ | 'characterLength'
+ | 'classImbalanceRatio'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnStatistic'
+ | 'columnValuesMatch'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatureCount'
+ | 'customMetricThreshold'
+ | 'duplicateRowCount'
+ | 'emptyFeature'
+ | 'emptyFeatureCount'
+ | 'driftedFeatureCount'
+ | 'featureMissingValues'
+ | 'featureValueValidation'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricThresholdV2'
+ | 'labelDrift'
+ | 'metricThreshold'
+ | 'newCategoryCount'
+ | 'newLabelCount'
+ | 'nullRowCount'
+ | 'rowCount'
+ | 'ppScoreValueValidation'
+ | 'quasiConstantFeature'
+ | 'quasiConstantFeatureCount'
+ | 'sqlQuery'
+ | 'dtypeValidation'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharactersRatio'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ thresholds: Array;
+
+ /**
+ * The test type.
+ */
+ type: 'integrity' | 'consistency' | 'performance';
+
+ /**
+ * Whether the test is archived.
+ */
+ archived?: boolean;
+
+ /**
+ * The delay window in seconds. Only applies to tests that use production data.
+ */
+ delayWindow?: number | null;
+
+ /**
+ * The evaluation window in seconds. Only applies to tests that use production
+ * data.
+ */
+ evaluationWindow?: number | null;
+
+ /**
+ * Whether the test uses an ML model.
+ */
+ usesMlModel?: boolean;
+
+ /**
+ * Whether the test uses production data (monitoring mode only).
+ */
+ usesProductionData?: boolean;
+
+ /**
+ * Whether the test uses a reference dataset (monitoring mode only).
+ */
+ usesReferenceDataset?: boolean;
+
+ /**
+ * Whether the test uses a training dataset.
+ */
+ usesTrainingDataset?: boolean;
+
+ /**
+ * Whether the test uses a validation dataset.
+ */
+ usesValidationDataset?: boolean;
+}
+
+export namespace TestCreateParams {
+ export interface Threshold {
+ /**
+ * The insight name to be evaluated.
+ */
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
+
+ /**
+ * The measurement to be evaluated.
+ */
+ measurement?: string;
+
+ /**
+ * The operator to be used for the evaluation.
+ */
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
+
+ /**
+ * The value to be compared.
+ */
+ value?: number | boolean | string | Array;
+ }
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
+}
+
+export interface TestUpdateParams {
+ payloads: Array;
+}
+
+export namespace TestUpdateParams {
+ export interface Payload {
+ id: string;
+
+ /**
+ * Whether the test is archived.
+ */
+ archived?: boolean;
+
+ /**
+ * The test description.
+ */
+ description?: unknown | null;
+
+ /**
+ * The test name.
+ */
+ name?: string;
+
+ suggested?: false;
+
+ thresholds?: Array;
+ }
+
+ export namespace Payload {
+ export interface Threshold {
+ /**
+ * The insight name to be evaluated.
+ */
+ insightName?:
+ | 'characterLength'
+ | 'classImbalance'
+ | 'expectColumnAToBeInColumnB'
+ | 'columnAverage'
+ | 'columnDrift'
+ | 'columnValuesMatch'
+ | 'confidenceDistribution'
+ | 'conflictingLabelRowCount'
+ | 'containsPii'
+ | 'containsValidUrl'
+ | 'correlatedFeatures'
+ | 'customMetric'
+ | 'duplicateRowCount'
+ | 'emptyFeatures'
+ | 'featureDrift'
+ | 'featureProfile'
+ | 'greatExpectations'
+ | 'groupByColumnStatsCheck'
+ | 'illFormedRowCount'
+ | 'isCode'
+ | 'isJson'
+ | 'llmRubricV2'
+ | 'labelDrift'
+ | 'metrics'
+ | 'newCategories'
+ | 'newLabels'
+ | 'nullRowCount'
+ | 'ppScore'
+ | 'quasiConstantFeatures'
+ | 'sentenceLength'
+ | 'sizeRatio'
+ | 'specialCharacters'
+ | 'stringValidation'
+ | 'trainValLeakageRowCount';
+
+ /**
+ * The insight parameters. Required only for some test subtypes. For example, for
+ * tests that require a column name, the insight parameters will be [{'name':
+ * 'column_name', 'value': 'Age'}]
+ */
+ insightParameters?: Array | null;
+
+ /**
+ * The measurement to be evaluated.
+ */
+ measurement?: string;
+
+ /**
+ * The operator to be used for the evaluation.
+ */
+ operator?: 'is' | '>' | '>=' | '<' | '<=' | '!=';
+
+ /**
+ * Whether to use automatic anomaly detection or manual thresholds
+ */
+ thresholdMode?: 'automatic' | 'manual';
+
+ /**
+ * The value to be compared.
+ */
+ value?: number | boolean | string | Array;
+ }
+
+ export namespace Threshold {
+ export interface InsightParameter {
+ /**
+ * The name of the insight filter.
+ */
+ name: string;
+
+ value: unknown;
+ }
+ }
+ }
+}
+
+export interface TestListParams {
+ /**
+ * Filter for archived tests.
+ */
+ includeArchived?: boolean;
+
+ /**
+ * Retrive tests created by a specific project version.
+ */
+ originVersionId?: string | null;
+
+ /**
+ * The page to return in a paginated query.
+ */
+ page?: number;
+
+ /**
+ * Maximum number of items to return per page.
+ */
+ perPage?: number;
+
+ /**
+ * Filter for suggested tests.
+ */
+ suggested?: boolean;
+
+ /**
+ * Filter objects by test type. Available types are `integrity`, `consistency`,
+ * `performance`, `fairness`, and `robustness`.
+ */
+ type?: 'integrity' | 'consistency' | 'performance' | 'fairness' | 'robustness';
+
+ /**
+ * Retrive tests with usesProductionData (monitoring).
+ */
+ usesProductionData?: boolean | null;
+}
+
+export declare namespace Tests {
+ export {
+ type TestCreateResponse as TestCreateResponse,
+ type TestUpdateResponse as TestUpdateResponse,
+ type TestListResponse as TestListResponse,
+ type TestCreateParams as TestCreateParams,
+ type TestUpdateParams as TestUpdateParams,
+ type TestListParams as TestListParams,
+ };
+}
diff --git a/src/version.ts b/src/version.ts
index ce6b899..9d013cc 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.12.0'; // x-release-please-version
+export const VERSION = '0.13.0'; // x-release-please-version
diff --git a/tests/api-resources/commits/test-results.test.ts b/tests/api-resources/commits/test-results.test.ts
index 49a096a..9be61d7 100644
--- a/tests/api-resources/commits/test-results.test.ts
+++ b/tests/api-resources/commits/test-results.test.ts
@@ -34,7 +34,7 @@ describe('resource testResults', () => {
await expect(
client.commits.testResults.list(
'182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
- { includeArchived: true, page: 1, perPage: 1, status: 'running', type: 'integrity' },
+ { includeArchived: true, page: 1, perPage: 1, status: 'passing', type: 'integrity' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Openlayer.NotFoundError);
diff --git a/tests/api-resources/inference-pipelines/test-results.test.ts b/tests/api-resources/inference-pipelines/test-results.test.ts
index 5b55a92..0bf1ad4 100644
--- a/tests/api-resources/inference-pipelines/test-results.test.ts
+++ b/tests/api-resources/inference-pipelines/test-results.test.ts
@@ -36,7 +36,7 @@ describe('resource testResults', () => {
await expect(
client.inferencePipelines.testResults.list(
'182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
- { page: 1, perPage: 1, status: 'running', type: 'integrity' },
+ { page: 1, perPage: 1, status: 'passing', type: 'integrity' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Openlayer.NotFoundError);
diff --git a/tests/api-resources/projects/tests.test.ts b/tests/api-resources/projects/tests.test.ts
new file mode 100644
index 0000000..9a6c452
--- /dev/null
+++ b/tests/api-resources/projects/tests.test.ts
@@ -0,0 +1,131 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Openlayer from 'openlayer';
+import { Response } from 'node-fetch';
+
+const client = new Openlayer({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource tests', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.projects.tests.create('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
+ description: 'This test checks for duplicate rows in the dataset.',
+ name: 'No duplicate rows',
+ subtype: 'duplicateRowCount',
+ thresholds: [{}],
+ type: 'integrity',
+ });
+ 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.projects.tests.create('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
+ description: 'This test checks for duplicate rows in the dataset.',
+ name: 'No duplicate rows',
+ subtype: 'duplicateRowCount',
+ thresholds: [
+ {
+ insightName: 'duplicateRowCount',
+ insightParameters: [{ name: 'column_name', value: 'Age' }],
+ measurement: 'duplicateRowCount',
+ operator: '<=',
+ thresholdMode: 'automatic',
+ value: 0,
+ },
+ ],
+ type: 'integrity',
+ archived: false,
+ delayWindow: 0,
+ evaluationWindow: 3600,
+ usesMlModel: false,
+ usesProductionData: false,
+ usesReferenceDataset: false,
+ usesTrainingDataset: false,
+ usesValidationDataset: true,
+ });
+ });
+
+ test('update: only required params', async () => {
+ const responsePromise = client.projects.tests.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
+ payloads: [{ id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' }],
+ });
+ 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('update: required and optional params', async () => {
+ const response = await client.projects.tests.update('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
+ payloads: [
+ {
+ id: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
+ archived: false,
+ description: 'This test checks for duplicate rows in the dataset.',
+ name: 'No duplicate rows',
+ suggested: false,
+ thresholds: [
+ {
+ insightName: 'duplicateRowCount',
+ insightParameters: [{ name: 'column_name', value: 'Age' }],
+ measurement: 'duplicateRowCount',
+ operator: '<=',
+ thresholdMode: 'automatic',
+ value: 0,
+ },
+ ],
+ },
+ ],
+ });
+ });
+
+ test('list', async () => {
+ const responsePromise = client.projects.tests.list('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');
+ 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.projects.tests.list('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {
+ path: '/_stainless_unknown_path',
+ }),
+ ).rejects.toThrow(Openlayer.NotFoundError);
+ });
+
+ test('list: request options and 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.projects.tests.list(
+ '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
+ {
+ includeArchived: true,
+ originVersionId: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
+ page: 1,
+ perPage: 1,
+ suggested: true,
+ type: 'integrity',
+ usesProductionData: true,
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(Openlayer.NotFoundError);
+ });
+});
diff --git a/tests/index.test.ts b/tests/index.test.ts
index f45c1b0..86dc23a 100644
--- a/tests/index.test.ts
+++ b/tests/index.test.ts
@@ -96,6 +96,15 @@ describe('instantiate client', () => {
expect(response).toEqual({ url: 'http://localhost:5000/foo', custom: true });
});
+ test('explicit global fetch', async () => {
+ // make sure the global fetch type is assignable to our Fetch type
+ const client = new Openlayer({
+ baseURL: 'http://localhost:5000/',
+ apiKey: 'My API Key',
+ fetch: defaultFetch,
+ });
+ });
+
test('custom signal', async () => {
const client = new Openlayer({
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',