Skip to main content

Harness Sandbox: Vercel

pkg/harness/sandbox/vercel runs pkg/harness sandboxes on Vercel Sandbox, with network policies and template snapshots. It is a Go port of the TypeScript harness's Vercel Sandbox provider.

Package​

import "github.com/digitallysavvy/go-ai/pkg/harness/sandbox/vercel"

Auth options​

type Credentials struct {
Token string
TeamID string
ProjectID string
}

ResolveCredentials mirrors the TypeScript provider's credential resolution: explicit Token/TeamID/ProjectID win when all three fields are set (setting only some of them is an error); otherwise VERCEL_OIDC_TOKEN is read from the environment and decoded as a JWT for its owner_id/project_id claims.

func ResolveCredentials(explicit Credentials) (Credentials, error)
func HasConfiguredCredentials(explicit Credentials) bool

ErrNoCredentials is returned when neither explicit credentials nor VERCEL_OIDC_TOKEN are available.

See Known differences: Vercel Sandbox has no OIDC token refresh loop — unlike the TypeScript provider, this port does not run a background @vercel/oidc refresh loop; VERCEL_OIDC_TOKEN is re-read from the environment on each call.

Creating a session​

func CreateNetworkSandboxSession(ctx context.Context, opts CreateSessionOptions) (harness.NetworkSandboxSession, error)

type CreateSessionOptions struct {
Credentials Credentials
BaseURL string // overrides the Vercel API base URL (tests only)

SandboxID string
Name string

Runtime string
Image string
Source *SnapshotSource
TimeoutMs int64
Ports []int
Persistent *bool
NetworkPolicy *NetworkPolicy
SnapshotExpiration *int64
Resources *ResourcesParams
Env map[string]string
Tags map[string]string
Region string
FailoverRegions []string
KeepLastSnapshots *KeepLastSnapshotsParams

Template *Template // one-time preparation recipe, cached by Template.Identity
}
session, err := vercel.CreateNetworkSandboxSession(ctx, vercel.CreateSessionOptions{
Runtime: "node22",
TimeoutMs: 10 * 60 * 1000,
Env: map[string]string{"NODE_ENV": "production"},
})

When Template is set, CreateNetworkSandboxSession reuses (or creates and caches) a snapshot for Template.Identity, running Template.Prepare only the first time that identity is seen, then forks a live sandbox from the snapshot — this is the template-snapshot behavior mentioned in the v0.5.0 release notes.

Resuming a session​

func ResumeNetworkSandboxSession(ctx context.Context, opts ResumeSessionOptions) (harness.NetworkSandboxSession, error)

type ResumeSessionOptions struct {
Credentials Credentials
BaseURL string
SandboxID string
}
session, err := vercel.ResumeNetworkSandboxSession(ctx, vercel.ResumeSessionOptions{
SandboxID: existingSandboxID,
})

Wrapping an existing sandbox​

If you already created a *vercel.Sandbox through the lower-level CreateSandbox/GetSandbox client calls, wrap it instead of going through CreateNetworkSandboxSession:

func NetworkSessionFromNativeSandbox(sandbox *Sandbox) harness.NetworkSandboxSession
func SessionFromNativeSandbox(sandbox *Sandbox) providerutils.SandboxSession

SessionFromNativeSandbox returns the restricted (file I/O + exec only) session interface; NetworkSessionFromNativeSandbox returns the full network-capable session, including SetNetworkPolicy, SetRequestTransformations, and port endpoint resolution.

Harness docs​

There is no separate top-level reference page for pkg/harness itself yet. See the Harness section of Migrating from the TypeScript AI SDK for the mapping from @ai-sdk/harness concepts (HarnessV1Session, Agent/AgentSession, adapter packages, sandbox providers) to their Go equivalents, and the Migrating from v0.4.x to v0.5.0 guide's "Provider updates to review" section for what's new this cycle.

See Also​