mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-25 06:42:52 +08:00
175 lines
6.2 KiB
Plaintext
175 lines
6.2 KiB
Plaintext
---
|
|
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
title: "TypeScript SDK"
|
|
sidebar-title: "TypeScript"
|
|
description: "Install the OpenShell TypeScript SDK, connect to a gateway, and manage a sandbox."
|
|
keywords: "OpenShell, SDK, TypeScript, Node.js, Connect, gRPC, Sandbox"
|
|
position: 4
|
|
---
|
|
|
|
Use the TypeScript SDK in Node.js applications and automation. It provides a
|
|
curated sandbox API and a raw generated client for the full gateway RPC surface.
|
|
Use the SDK and gateway from the same OpenShell release when possible.
|
|
|
|
## Install the SDK
|
|
|
|
The package requires Node.js 20.3 or later and is currently distributed through
|
|
GitHub Packages. Configure the `@nvidia` scope in your project `.npmrc`:
|
|
|
|
```text
|
|
@nvidia:registry=https://npm.pkg.github.com
|
|
```
|
|
|
|
Authenticate npm with a GitHub token that has `read:packages`, then install the
|
|
package:
|
|
|
|
```shell
|
|
npm install @nvidia/openshell-sdk
|
|
```
|
|
|
|
## Connect to a Gateway
|
|
|
|
`OpenShellClient.connect()` accepts a gateway URL. It constructs a lazy client,
|
|
so call `health()` when startup must verify connectivity:
|
|
|
|
```ts
|
|
import { OpenShellClient } from '@nvidia/openshell-sdk'
|
|
|
|
const client = await OpenShellClient.connect({
|
|
gateway: 'https://gateway.example.com',
|
|
oidcToken: process.env.OPENSHELL_TOKEN,
|
|
})
|
|
|
|
const health = await client.health()
|
|
console.log(`${health.status}: ${health.version}`)
|
|
```
|
|
|
|
For long-running OIDC service automation, use a renewable client-credentials
|
|
provider:
|
|
|
|
```ts
|
|
import { clientCredentials, OpenShellClient } from '@nvidia/openshell-sdk'
|
|
|
|
const client = await OpenShellClient.connect({
|
|
gateway: 'https://gateway.example.com',
|
|
oidcTokenProvider: clientCredentials({
|
|
issuer: 'https://idp.example.com/realms/openshell',
|
|
clientId: 'openshell-service',
|
|
clientSecret: () => process.env.OPENSHELL_OIDC_CLIENT_SECRET!,
|
|
audience: 'openshell-gateway',
|
|
}),
|
|
})
|
|
```
|
|
|
|
The provider retains credentials and tokens in memory and renews the access
|
|
token before expiry.
|
|
|
|
## Retrieve Provider Credentials
|
|
|
|
Connect directly with a trusted `OU=operator` client certificate after enabling
|
|
[operator authentication](/how-it-works/gateways/authentication#mtls-operators).
|
|
Do not supply an OIDC or edge token for this connection. No sandbox creation or
|
|
provider attachment is required.
|
|
|
|
```ts
|
|
import { readFileSync } from 'node:fs'
|
|
import { OpenShellClient } from '@nvidia/openshell-sdk'
|
|
|
|
const operator = await OpenShellClient.connect({
|
|
gateway: 'https://gateway.example.com',
|
|
caCert: readFileSync('ca.crt'),
|
|
clientCert: readFileSync('operator.crt'),
|
|
clientKey: readFileSync('operator.key'),
|
|
})
|
|
const credentials = await operator.providers.getCredentials(
|
|
'my-graph',
|
|
['MS_GRAPH_ACCESS_TOKEN'],
|
|
{ workspace: 'production', minimumRemainingLifetimeSecs: 300 },
|
|
)
|
|
const token = credentials.MS_GRAPH_ACCESS_TOKEN!.value
|
|
```
|
|
|
|
`ProviderClient.connect()` provides the same API as a standalone client. Unlike
|
|
sandbox operations, `getCredentials()` requires an explicit workspace. It returns
|
|
a record of `ProviderCredentialValue` objects with `value` and optional
|
|
`expirationTime`, a `Date`. Sub-millisecond expiration precision is truncated.
|
|
`minimumRemainingLifetimeSecs` accepts fractional seconds; omission or zero uses
|
|
the gateway default. Pass `signal` or `timeoutMs` in the operation options to
|
|
bound delivery. The helper does not retry or cache exports, and canceled delivery
|
|
does not roll back a gateway refresh that has already started.
|
|
|
|
Keep returned values out of logs and shared output. See
|
|
[Retrieve Runtime Credentials](/how-it-works/providers/overview#retrieve-runtime-credentials)
|
|
for freshness, supported credentials, and the export security boundary.
|
|
|
|
## Create and Use a Sandbox
|
|
|
|
The curated client uses the `default` workspace unless you pass `workspace` in
|
|
an operation's options:
|
|
|
|
```ts
|
|
const sandbox = await client.sandbox.create({
|
|
name: 'sdk-example',
|
|
image: 'registry.example.com/team/python-agent:1.0',
|
|
})
|
|
|
|
await client.sandbox.waitReady(sandbox.name, 120)
|
|
|
|
const result = await client.sandbox.exec(
|
|
sandbox.name,
|
|
['python', '-c', "print('hello from OpenShell')"],
|
|
)
|
|
console.log(result.stdout.toString())
|
|
|
|
const deletion = await client.sandbox.delete(sandbox.name)
|
|
if (deletion.outcome === 'accepted') {
|
|
await client.sandbox.waitDeleted(sandbox.name, 60, {
|
|
expectedSandboxId: deletion.sandboxId,
|
|
})
|
|
}
|
|
```
|
|
|
|
Sandbox refs returned by `create`, `get`, and `list` include `createdAtMs`, the
|
|
creation time in epoch milliseconds. It is absent when the gateway omits it.
|
|
|
|
`client.sandbox` also supports streaming and interactive exec, TCP forwarding,
|
|
SSH sessions, sandbox provider attachment, configuration, and policy. Close
|
|
operation-scoped streams and forwarding handles when finished. The root client
|
|
does not retain a dedicated session and has no `close()` method.
|
|
|
|
## Watch Logs and Events
|
|
|
|
`watchLogs` streams a sandbox's log lines and platform events with automatic
|
|
reconnect and loss-aware resume. Pass a previous item's `cursor` back in as
|
|
`resumeAfterCursor` to continue after a restart without gaps or duplicates:
|
|
|
|
```ts
|
|
for await (const item of client.sandbox.watchLogs(sandbox.name, { followLogs: true })) {
|
|
if (item.kind === 'log') {
|
|
console.log(`${item.line.level} ${item.line.message}`)
|
|
} else if (item.kind === 'warning') {
|
|
console.warn(`gap: ${item.message}`)
|
|
}
|
|
}
|
|
```
|
|
|
|
When a resume cursor has expired, `watchLogs` stops with an `SdkError` whose
|
|
`code` is `rpc` and whose `connectCode` is `Code.OutOfRange`. To accept the missing
|
|
events, start a new watch with an empty `resumeAfterCursor`.
|
|
|
|
See [Accessing Logs](/observability/accessing-logs) for the cursor and resume
|
|
contract this method implements.
|
|
|
|
## Use the Raw Client
|
|
|
|
Use `client.raw` for RPCs that the curated clients do not yet wrap. Import
|
|
generated message schemas and types from `@nvidia/openshell-sdk/raw`. Raw calls
|
|
return protobuf wire shapes, while curated calls return SDK-specific types.
|
|
|
|
## Next Steps
|
|
|
|
- Review [Gateway Authentication](/how-it-works/gateways/authentication) for OIDC and service authentication.
|
|
- Review [API Errors](/sdk/api-errors) for structured error handling.
|
|
- See the [TypeScript SDK source documentation](https://github.com/NVIDIA/OpenShell/tree/main/sdk/typescript) for streaming, forwarding, and raw client examples.
|