Files
zeekay 51100cafb0 @hanzo/cloud: typed client for the Hanzo Cloud /v1/ platform API
First-class services for agents, agent sessions, and machines, plus a typed
send() escape hatch backed by the OpenAPI-generated paths (the spec is the
single source of truth, regenerated via npm run codegen). Zero runtime deps,
Hanzo IAM-native Bearer auth. Orthogonal to @hanzo/base (datastore) and
@hanzo/ai (inference).

typecheck + build + 51 smoke assertions green.
2026-07-04 01:10:38 -07:00

4.7 KiB

@hanzo/cloud

npm

The typed JavaScript/TypeScript client for the Hanzo Cloud /v1/ platform API at api.hanzo.ai. Auth is Hanzo IAM-native: the client holds the IAM-issued Bearer JWT (or an API key) and sends it on every request.

Zero runtime dependencies. First-class services for agents, agent sessions, and machines, plus a fully-typed send() escape hatch that reaches every one of the 172 operations in the spec.

There is a companion Dart client, hanzoai, that mirrors this shape.

Where it sits

Three orthogonal, IAM-native clients — use them together:

Package Surface
@hanzo/base Base datastore — records, realtime, files
@hanzo/ai Inference — chat completions, models
@hanzo/cloud Platform control plane — agents, sessions, machines, and the full /v1/cloud/* surface

@hanzo/cloud does not wrap or supersede @hanzo/ai. They are orthogonal: @hanzo/ai is the inference data plane (send a prompt, get a completion); @hanzo/cloud is the control plane (create an agent, run it, watch its sessions, provision the machine it runs on). An app that both configures agents and streams model output installs both.

Install

npm install @hanzo/cloud
import { HanzoCloud } from '@hanzo/cloud'

const cloud = new HanzoCloud({ token: process.env.HANZO_TOKEN })

token is a Hanzo IAM JWT (from hanzo.id) or an API key. The origin defaults to https://api.hanzo.ai.

Agents

const agent = await cloud.agents.create({
  name: 'researcher',
  model: 'zen-coder',
  instructions: 'You research and summarize.',
  tools: ['search', 'fetch'],
})

const run = await cloud.agents.run('researcher', { input: 'Summarize RFC 8628.' })
console.log(run.status, run.output)

const agents = await cloud.agents.list()
const detail = await cloud.agents.get('researcher')
const history = await cloud.agents.runs('researcher', 20)
const metrics = await cloud.agents.metrics('7D')

A one-shot agent runs when you POST to /run. A long-running agent additionally carries a 5-field cron schedule and is invoked by the scheduler:

await cloud.agents.create({
  name: 'nightly-digest',
  model: 'zen-coder',
  executionMode: 'long-running',
  schedule: '0 9 * * *',
})

Agent sessions

A session is one live invocation. Sessions linked by parentSessionId form the subagent tree; rootSessionId is the shared key.

const session = await cloud.sessions.register({ agent: 'researcher' })

await cloud.sessions.appendEvent(session.id, {
  kind: 'log',
  payload: { message: 'started' },
})

await cloud.sessions.pause(session.id)
await cloud.sessions.resume(session.id)
await cloud.sessions.message(session.id, { message: 'focus on section 3' })

const tree = await cloud.sessions.tree(session.id)

Stream live session and event updates over SSE:

const ctrl = new AbortController()
for await (const frame of cloud.sessions.stream({ signal: ctrl.signal })) {
  console.log(frame.type, frame.data) // 'session' | 'event'
}

Machines

const machines = await cloud.machines.list({ pageSize: 50 })
const one = await cloud.machines.get('org/name')
await cloud.machines.add({ name: 'gpu-1', region: 'sfo3' })
await cloud.machines.update('org/name', { size: 'xl' })

The full surface

Every /v1/cloud/* resource (nodes, pods, containers, providers, connections, stores, vectors, workflows, …) is reachable through the typed send() method. Pair it with the generated paths type for end-to-end safety:

import type { paths } from '@hanzo/cloud'

type Providers =
  paths['/v1/cloud/get-providers']['get']['responses']['200']['content']['application/json']

const providers = await cloud.send<Providers>('/v1/cloud/get-providers')

The generated paths, components, and operations types are re-exported from the package root. They are produced from openapi.yaml (synced from the hanzo/openapi monorepo) via npm run codegen — the spec is the single source of truth.

Auth

cloud.setToken(jwt)      // seed or replace the Bearer token
cloud.authStore.isValid  // token present and, if a JWT, unexpired
cloud.signOut()          // clear it

Errors are thrown as HanzoCloudError with .status and parsed .detail.

Develop

npm install
npm run codegen   # regenerate src/generated/types.ts from openapi.yaml
npm run typecheck
npm run build
npm test

License

MIT © Hanzo AI, Inc. See LICENSE.