Skip to content

@aster/sdk

Canonical package README synced from packages/sdk/README.md.

Canonical source: packages/sdk/README.md · Edit the source file

JavaScript and TypeScript client for the Aster product runtime, plus app and local-server entrypoints for integrations.

Install

Terminal window
npm install @aster/sdk

Quick Start

import { AsterClient } from "@aster/sdk"
const client = AsterClient.make({
baseUrl: "http://127.0.0.1:4040",
authToken: process.env.ASTER_AUTH_TOKEN,
})
const health = await client.gateway.health()
console.log(health)

AsterClient.make() returns the authenticated core Aster surface:

  • client.gateway for low-level HTTP gateway methods
  • client.runtime for managed runtime socket subscriptions
  • client.assistant for prompt, command, abort, and run-stream helpers
  • client.spaces, client.runs, client.space("main"), client.subscribe(...), and client.dispose()
  • client.space("main").promptContext() and client.space("main").prompt.submit(...) for SDK-owned space prompt ergonomics
  • client.runtime.subscribeObserver(...) for SDK-owned observer replay, cursor tracking, event validation, and filtered live updates

External local apps should use the narrower AsterApp.make(), which hides the Aster app token as a transport credential and exposes only paired-app operations, pairing, ingress, and app lifecycle helpers. It does not expose the internal Gateway/core surface:

import { AsterApp } from "@aster/sdk"
const aster = AsterApp.make({
app: {
id: "com.example.notes",
name: "Notes App",
},
scopes: ["events.submit", "turns.submit"],
})
await aster.pair()
await aster.events.submit({
content: "Summarize the current note.",
})

App tokens are transport credentials only. Domain authorization, like which Discord channel or Telegram chat may reach a space, should stay in the app’s own access files or backend state.

Package Boundary

@aster/sdk is the client SDK: gateway clients, runtime sockets, AsterClient, AsterApp, and app-facing transport types. Platform authoring lives in @aster/platform-sdk; import Plugin, Service, Space, tool, and protocol registry helpers there instead of from @aster/sdk.

Naming

The client SDK uses these names consistently:

  • Client is a concrete owner of transport, authentication, and lifecycle. AsterClient is the user/runtime client; AsterApp is the paired local-app client.
  • Surface is the shared capability shape implemented behind those clients. It is internal plumbing, not a package-root export.
  • Resource is a scoped handle returned by a client, often with state or a lifecycle. Examples: AsterPromptContextResource, AsterSpaceResource, and AsterSpaceWorkflowsResource.
  • Input names outbound SDK method parameters authored by a consumer. Examples: AsterSpacePromptSubmitInput and AsterWorkflowRunInput.
  • Request is reserved for inbound SDK requests or gate ABI shapes, such as AsterAppPairRequest and generated gateway request contracts.

Live Thread Projections

Use runtime.subscribeObserver() when an app or UI needs thread-scoped observer updates without rebuilding socket filters and cursor state from separate hooks:

const threadScope = { kind: "task", taskId: "task_01HV2" } as const
const stop = client.runtime.subscribeObserver(
threadScope,
(frame) => {
console.log(frame.kind, frame.source)
},
{
cursor: { scope: threadScope, scopeKey: "task:task_01HV2", sequence: 0 },
},
)
stop()

Prompt and command submissions return accepted Work handles keyed by threadId:

const accepted = await client.assistant.prompt({
target: { kind: "space", spaceSlug: "main" },
input: {
parts: [{ type: "text", text: "Summarize the current note." }],
},
})
console.log(accepted.threadId)

The durable conversation identity is the Task thread. Runtime event fields that still mention native provider or transcript sessions are telemetry, not SDK conversation handles.

Local Server Helpers

The gate entrypoint exports helpers for local development and integration testing:

import { createAster } from "@aster/sdk/gate"
const { client, server } = await createAster({
port: 4041,
})
try {
await client.gateway.health()
} finally {
await server.close()
}

Public Entrypoints

EntrypointContents
@aster/sdkAsterClient, AsterApp, shared client SDK surface types, and app types.
@aster/sdk/gateGate client/server/transport exports plus createAster() for local integration tests.
@aster/sdk/gate/clientAsterClient, createAsterGatewayClient(), createAsterRuntimeSocketClient(), runtime socket helpers, and generated gateway types.
@aster/sdk/gate/serverServer process helpers.
@aster/sdk/appsAsterApp plus pairing-first local app SDK types for spaces, turns, runtime, dictation, interactions, and app events.
@aster/sdk/apps/substrateNode/Bun-only local Gateway substrate pointer construction; absent from browser and React Native graphs.
@aster/sdk/reactReact hooks on top of @aster/sdk/apps for pairing state, app event subscriptions, and SDK live resources.
@aster/platform-sdkPlatform authoring surface for Plugin, Service, Space, tool, and protocol registry helpers.

Source Of Truth

  • REST API shape comes from packages/sdk/openapi.json.
  • Generated client code lives under src/gate/gen/.
  • The Gate framework lives in packages/gate.
  • The platform SDK lives in packages/platform-sdk.
  • The Spaces DSL lives in packages/spaces and is re-exported by the platform SDK.
  • The default product graph is assembled in packages/distro.
  • The public docs site and generated reference pages live in products/docs.
  • packages/platform-sdk provides the platform SDK for space, provider, Role, Processor, and protocol authors.
  • packages/sdk/src/apps provides the local Apps SDK.
  • packages/sdk/src/react provides React hooks for the local Apps SDK.
  • packages/spaces provides the SDK for programmable space modules.
  • packages/gate provides the framework that Distro uses to expose routes, sockets, runtime services, and SDK generation metadata.
  • packages/distro provides the default Aster product runtime.
  • products/docs publishes the generated API and SDK reference.