Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ jobs:
bash ./bin/check-release-environment
env:
NPM_TOKEN: ${{ secrets.GRADIENT_NPM_TOKEN || secrets.NPM_TOKEN }}

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ dist
dist-deno
/*.tgz
.idea/
.eslintcache

2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.1"
".": "0.1.0-alpha.2"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 173
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/digitalocean%2Fgradient-621c3ebf5011c5ca508f78fccbea17de4ca6b35bfe99578c1ae2265021578d6f.yml
openapi_spec_hash: e29d14e3e4679fcf22b3e760e49931b1
config_hash: 3d425c415b7f7ab581418b43eb521cb3
configured_endpoints: 175
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/digitalocean%2Fgradient-cb3bf9b21459cad24410206c27a32fd31ef6cf86711700597549dbbd0d634002.yml
openapi_spec_hash: 6a9149a81ba15e7c5c5c1f4d77daad92
config_hash: bad49c3bf949d5168ec3896bedff253a
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Changelog

## 0.1.0-alpha.2 (2025-10-16)

Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/digitalocean/gradient-typescript/compare/v0.1.0-alpha.1...v0.1.0-alpha.2)

### Features

* **api:** Images generations ([2b2dc1a](https://github.com/digitalocean/gradient-typescript/commit/2b2dc1ab761524a9a4e80d92f627e0777bc72828))
* **api:** Images generations - openai ([6c3d87c](https://github.com/digitalocean/gradient-typescript/commit/6c3d87c4587799d95634709e10d05398a5b5efea))
* **api:** manual updates ([e428407](https://github.com/digitalocean/gradient-typescript/commit/e428407732f68c3958a7a4aefebb16d6fc993ffe))
* **api:** manual updates ([54e9764](https://github.com/digitalocean/gradient-typescript/commit/54e97647408b0713f2788163c8e62950d0978779))


### Performance Improvements

* faster formatting ([8368269](https://github.com/digitalocean/gradient-typescript/commit/83682693c05b0923eda90f309323e79be81f0959))


### Chores

* clean up LICENSING after legal review ([#3](https://github.com/digitalocean/gradient-typescript/issues/3)) ([da51ba0](https://github.com/digitalocean/gradient-typescript/commit/da51ba0ea90a8a938747e1f5500fe78e388046c6))
* do not install brew dependencies in ./scripts/bootstrap by default ([58a58de](https://github.com/digitalocean/gradient-typescript/commit/58a58dee9cef281da36da118e2ac979cd0d755b7))
* **internal:** codegen related update ([caea2ff](https://github.com/digitalocean/gradient-typescript/commit/caea2ff2b2b44b543ede7b06829fbb5a8d0b2694))
* **internal:** fix incremental formatting in some cases ([353630a](https://github.com/digitalocean/gradient-typescript/commit/353630aa9fe2b61a4d4fb04b581e628fe9e5fd3f))
* **internal:** ignore .eslintcache ([49808e2](https://github.com/digitalocean/gradient-typescript/commit/49808e27fd3936c7aaa21c194fc005f7944380b4))
* **internal:** remove .eslintcache ([b318cc0](https://github.com/digitalocean/gradient-typescript/commit/b318cc0a5b59b443357621de22714cf9e893d4a6))
* **internal:** remove deprecated `compilerOptions.baseUrl` from tsconfig.json ([3c74bff](https://github.com/digitalocean/gradient-typescript/commit/3c74bff79b6e18426e0bc6cb4e586a5996f4640f))
* **internal:** use npm pack for build uploads ([2b378fc](https://github.com/digitalocean/gradient-typescript/commit/2b378fc6255fb2753373564871d0e8442b54497b))
* **jsdoc:** fix [@link](https://github.com/link) annotations to refer only to parts of the package‘s public interface ([ffed53e](https://github.com/digitalocean/gradient-typescript/commit/ffed53e3f10f4cf70ce61c65623fc13298200aa8))
* update author ([3dd3c2d](https://github.com/digitalocean/gradient-typescript/commit/3dd3c2d23f3896305077104a7793d7702371843b))
* update github actions ([d678611](https://github.com/digitalocean/gradient-typescript/commit/d6786115dfe34fde95a8317d7f79a8d6aa579a01))

## 0.1.0-alpha.1 (2025-09-12)

Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/digitalocean/gradient-typescript/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The full API of this library can be found in [api.md](api.md).
import Gradient from '@digitalocean/gradient';

const client = new Gradient({
accessToken: process.env['DIGITALOCEAN_ACCESS_TOKEN'], // This is the default and can be omitted
modelAccessKey: process.env['GRADIENT_MODEL_ACCESS_KEY'], // This is the default and can be omitted
});

const completion = await client.chat.completions.create({
Expand Down Expand Up @@ -65,7 +65,7 @@ This library includes TypeScript definitions for all request params and response
import Gradient from '@digitalocean/gradient';

const client = new Gradient({
accessToken: process.env['DIGITALOCEAN_ACCESS_TOKEN'], // This is the default and can be omitted
modelAccessKey: process.env['GRADIENT_MODEL_ACCESS_KEY'], // This is the default and can be omitted
});

const params: Gradient.Chat.CompletionCreateParams = {
Expand Down
16 changes: 16 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Types:
- <code><a href="./src/resources/shared.ts">GarbageCollection</a></code>
- <code><a href="./src/resources/shared.ts">GPUInfo</a></code>
- <code><a href="./src/resources/shared.ts">Image</a></code>
- <code><a href="./src/resources/shared.ts">ImageGenCompletedEvent</a></code>
- <code><a href="./src/resources/shared.ts">ImageGenPartialImageEvent</a></code>
- <code><a href="./src/resources/shared.ts">ImageGenStreamEvent</a></code>
- <code><a href="./src/resources/shared.ts">Kernel</a></code>
- <code><a href="./src/resources/shared.ts">MetaProperties</a></code>
- <code><a href="./src/resources/shared.ts">NetworkV4</a></code>
Expand Down Expand Up @@ -327,6 +330,16 @@ Methods:

- <code title="post /chat/completions">client.chat.completions.<a href="./src/resources/chat/completions.ts">create</a>({ ...params }) -> CompletionCreateResponse</code>

# Images

Types:

- <code><a href="./src/resources/images.ts">ImageGenerateResponse</a></code>

Methods:

- <code title="post /images/generations">client.images.<a href="./src/resources/images.ts">generate</a>({ ...params }) -> ImageGenerateResponse</code>

# GPUDroplets

Types:
Expand Down Expand Up @@ -642,6 +655,7 @@ Methods:

Types:

- <code><a href="./src/resources/gpu-droplets/account/keys.ts">SSHKeys</a></code>
- <code><a href="./src/resources/gpu-droplets/account/keys.ts">KeyCreateResponse</a></code>
- <code><a href="./src/resources/gpu-droplets/account/keys.ts">KeyRetrieveResponse</a></code>
- <code><a href="./src/resources/gpu-droplets/account/keys.ts">KeyUpdateResponse</a></code>
Expand Down Expand Up @@ -707,12 +721,14 @@ Types:
- <code><a href="./src/resources/knowledge-bases/data-sources.ts">DataSourceCreateResponse</a></code>
- <code><a href="./src/resources/knowledge-bases/data-sources.ts">DataSourceListResponse</a></code>
- <code><a href="./src/resources/knowledge-bases/data-sources.ts">DataSourceDeleteResponse</a></code>
- <code><a href="./src/resources/knowledge-bases/data-sources.ts">DataSourceCreatePresignedURLsResponse</a></code>

Methods:

- <code title="post /v2/gen-ai/knowledge_bases/{knowledge_base_uuid}/data_sources">client.knowledgeBases.dataSources.<a href="./src/resources/knowledge-bases/data-sources.ts">create</a>(knowledgeBaseUuid, { ...params }) -> DataSourceCreateResponse</code>
- <code title="get /v2/gen-ai/knowledge_bases/{knowledge_base_uuid}/data_sources">client.knowledgeBases.dataSources.<a href="./src/resources/knowledge-bases/data-sources.ts">list</a>(knowledgeBaseUuid, { ...params }) -> DataSourceListResponse</code>
- <code title="delete /v2/gen-ai/knowledge_bases/{knowledge_base_uuid}/data_sources/{data_source_uuid}">client.knowledgeBases.dataSources.<a href="./src/resources/knowledge-bases/data-sources.ts">delete</a>(dataSourceUuid, { ...params }) -> DataSourceDeleteResponse</code>
- <code title="post /v2/gen-ai/knowledge_bases/data_sources/file_upload_presigned_urls">client.knowledgeBases.dataSources.<a href="./src/resources/knowledge-bases/data-sources.ts">createPresignedURLs</a>({ ...params }) -> DataSourceCreatePresignedURLsResponse</code>

## IndexingJobs

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@digitalocean/gradient",
"version": "0.1.0-alpha.1",
"version": "0.1.0-alpha.2",
"description": "The official TypeScript library for the Gradient API",
"author": "DigitalOcean, LLC <dev@digitalocean.com>",
"types": "dist/index.d.ts",
Expand Down
14 changes: 11 additions & 3 deletions scripts/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ set -e

cd "$(dirname "$0")/.."

if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ]; then
if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
echo "==> Installing Homebrew dependencies…"
brew bundle
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
case "$response" in
[yY][eE][sS]|[yY])
brew bundle
;;
*)
;;
esac
echo
}
fi

Expand Down
40 changes: 40 additions & 0 deletions scripts/fast-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash

set -euo pipefail

echo "Script started with $# arguments"
echo "Arguments: $*"
echo "Script location: $(dirname "$0")"

cd "$(dirname "$0")/.."
echo "Changed to directory: $(pwd)"

if [ $# -eq 0 ]; then
echo "Usage: $0 <file-with-paths> [additional-formatter-args...]"
echo "The file should contain one file path per line"
exit 1
fi

FILE_LIST="$1"

echo "Looking for file: $FILE_LIST"

if [ ! -f "$FILE_LIST" ]; then
echo "Error: File '$FILE_LIST' not found"
exit 1
fi

echo "==> Running eslint --fix"
ESLINT_FILES="$(grep '\.ts$' "$FILE_LIST" || true)"
if ! [ -z "$ESLINT_FILES" ]; then
echo "$ESLINT_FILES" | xargs ./node_modules/.bin/eslint --cache --fix
fi

echo "==> Running prettier --write"
# format things eslint didn't
PRETTIER_FILES="$(grep '\.\(js\|json\)$' "$FILE_LIST" || true)"
if ! [ -z "$PRETTIER_FILES" ]; then
echo "$PRETTIER_FILES" | xargs ./node_modules/.bin/prettier \
--write --cache --cache-strategy metadata --no-error-on-unmatched-pattern \
'!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs'
fi
6 changes: 4 additions & 2 deletions scripts/utils/upload-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ if [[ "$SIGNED_URL" == "null" ]]; then
exit 1
fi

UPLOAD_RESPONSE=$(tar "${BASE_PATH:+-C$BASE_PATH}" -cz "${ARTIFACT_PATH:-dist}" | curl -v -X PUT \
TARBALL=$(cd dist && npm pack --silent)

UPLOAD_RESPONSE=$(curl -v -X PUT \
-H "Content-Type: application/gzip" \
--data-binary @- "$SIGNED_URL" 2>&1)
--data-binary "@dist/$TARBALL" "$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"
Expand Down
58 changes: 57 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ import * as Errors from './core/error';
import * as Uploads from './core/uploads';
import * as API from './resources/index';
import { APIPromise } from './core/api-promise';
import {
ImageGenerateParams,
ImageGenerateParamsNonStreaming,
ImageGenerateParamsStreaming,
ImageGenerateResponse,
Images,
} from './resources/images';
import { RegionListParams, RegionListResponse, Regions } from './resources/regions';
import {
APIAgent,
Expand Down Expand Up @@ -312,18 +319,54 @@ export class Gradient {
return;
}

if (this.modelAccessKey && values.get('authorization')) {
return;
}
if (nulls.has('authorization')) {
return;
}

if (this.agentAccessKey && values.get('authorization')) {
return;
}
if (nulls.has('authorization')) {
return;
}

throw new Error(
'Could not resolve authentication method. Expected the accessToken to be set. Or for the "Authorization" headers to be explicitly omitted',
'Could not resolve authentication method. Expected one of accessToken, modelAccessKey or agentAccessKey to be set. Or for one of the "Authorization", "Authorization" or "Authorization" headers to be explicitly omitted',
);
}

protected async authHeaders(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
return buildHeaders([
await this.bearerAuth(opts),
await this.modelAccessKeyAuth(opts),
await this.agentAccessKeyAuth(opts),
]);
}

protected async bearerAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
if (this.accessToken == null) {
return undefined;
}
return buildHeaders([{ Authorization: `Bearer ${this.accessToken}` }]);
}

protected async modelAccessKeyAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
if (this.modelAccessKey == null) {
return undefined;
}
return buildHeaders([{ Authorization: `Bearer ${this.modelAccessKey}` }]);
}

protected async agentAccessKeyAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
if (this.agentAccessKey == null) {
return undefined;
}
return buildHeaders([{ Authorization: `Bearer ${this.agentAccessKey}` }]);
}

protected stringifyQuery(query: Record<string, unknown>): string {
return qs.stringify(query, { arrayFormat: 'comma' });
}
Expand Down Expand Up @@ -814,6 +857,7 @@ export class Gradient {

agents: API.Agents = new API.Agents(this);
chat: API.Chat = new API.Chat(this);
images: API.Images = new API.Images(this);
gpuDroplets: API.GPUDroplets = new API.GPUDroplets(this);
inference: API.Inference = new API.Inference(this);
knowledgeBases: API.KnowledgeBases = new API.KnowledgeBases(this);
Expand All @@ -824,6 +868,7 @@ export class Gradient {

Gradient.Agents = Agents;
Gradient.Chat = Chat;
Gradient.Images = Images;
Gradient.GPUDroplets = GPUDroplets;
Gradient.Inference = Inference;
Gradient.KnowledgeBases = KnowledgeBases;
Expand Down Expand Up @@ -860,6 +905,14 @@ export declare namespace Gradient {

export { Chat as Chat };

export {
Images as Images,
type ImageGenerateResponse as ImageGenerateResponse,
type ImageGenerateParams as ImageGenerateParams,
type ImageGenerateParamsNonStreaming as ImageGenerateParamsNonStreaming,
type ImageGenerateParamsStreaming as ImageGenerateParamsStreaming,
};

export {
GPUDroplets as GPUDroplets,
type DropletBackupPolicy as DropletBackupPolicy,
Expand Down Expand Up @@ -926,6 +979,9 @@ export declare namespace Gradient {
export type GarbageCollection = API.GarbageCollection;
export type GPUInfo = API.GPUInfo;
export type Image = API.Image;
export type ImageGenCompletedEvent = API.ImageGenCompletedEvent;
export type ImageGenPartialImageEvent = API.ImageGenPartialImageEvent;
export type ImageGenStreamEvent = API.ImageGenStreamEvent;
export type Kernel = API.Kernel;
export type MetaProperties = API.MetaProperties;
export type NetworkV4 = API.NetworkV4;
Expand Down
2 changes: 1 addition & 1 deletion src/internal/to-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export type ToFileInput =

/**
* Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
* @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
* @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts
* @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
* @param {Object=} options additional properties
* @param {string=} options.type the MIME type of the content
Expand Down
Loading