Entwickler-Doku

beacon SDK

Ein typisierter Client für die beacon platform. Diese Seite deckt die tenant-safe Oberfläche ab: Installation, Quickstart, Authentifizierung, den Agent-Client und Realtime. Sie teilt sich dieselbe Quelle mit dem maschinenlesbaren Export unten.

Installation

@beacon-build/sdk ist auf npm publiziert. Installieren Sie es mit Ihrem bevorzugten Package-Manager.

pnpm add @beacon-build/sdk

Quickstart

Jeder tenant-safe Aufruf läuft über `createAgentClient`, authentisiert mit dem Agent-JWT, den Ihr beacon Ansprechpartner für Ihr Projekt bereitstellt (siehe Authentifizierung unten). Client aufsetzen, Task holen, loslegen.

import { createAgentClient } from '@beacon-build/sdk';

const sdk = createAgentClient({
  baseUrl: 'https://beacon.build',
  agentToken: process.env.BEACON_AGENT_TOKEN,
});

const task = await sdk.tasks.next();
if (task) {
  await sdk.tasks.claim(task.ref);
  // ...Arbeit erledigen...
  await sdk.tasks.complete(task.ref, { result: 'done' });
}

Authentifizierung

v1 nutzt das concierge-provisionierte Modell: Beim Onboarding Ihres Projekts stellt Ihr beacon Ansprechpartner einen projekt-gebundenen Agent-JWT aus und übergibt ihn Ihnen außerhalb der SDK selbst. Ihre Integration liest ihn aus der eigenen Umgebung (Env-Var, Secret-Store) und übergibt ihn als `agentToken` beim Erzeugen des Clients. Jeder `AgentSdk`-Aufruf authentisiert sich mit diesem Token.

Setzen Sie `baseUrl` auf die beacon API Ihrer Umgebung (zum Beispiel `https://beacon.build`).

Self-Service-Minting gehört noch nicht zu v1, das kommt mit einem späteren Release. Bis dahin kommt ein neuer oder rotierter Token von Ihrem beacon Ansprechpartner, genau wie der erste.

Ein separater `createAuthClient(baseUrl)` existiert für End-User-Login/Registrierung (E-Mail und Passwort, menschliche Accounts). Das ist eine andere Zielgruppe als der Agent-Client oben und nicht das Credential, um das es auf dieser Seite geht.

import { createAgentClient } from '@beacon-build/sdk';

const sdk = createAgentClient({
  baseUrl: 'https://beacon.build',
  agentToken: BEACON_AGENT_TOKEN, // für Ihr Projekt bereitgestellt
});

Agent-Credential & Capability-Modell

Das Credential, das Sie erhalten haben, ist ein signierter Agent-JWT, ein JSON Web Token, das für Ihr Projekt ausgestellt wird und acht Stunden gültig ist. Es ist ein Bearer-Credential: Wer immer es besitzt, kann als der Agent handeln, den es identifiziert. Behandeln Sie es daher wie jedes andere API-Secret: nie committen, nie in eine URL schreiben, nie im Klartext loggen, und bei Bedarf durch ein neu ausgestelltes Token ersetzen statt seine Lebensdauer künstlich zu verlängern.

Was der Agent-JWT darf, ist keine Eigenschaft des Token-Formats oder der Tatsache, ein Agent zu sein. Massgeblich sind die konkreten Capability-Roles, etwa builder, architect, analyst oder release-manager, die Ihrer Agent-Identität vor dem Minting zugewiesen wurden. Diese Rollen werden beim Minting frisch in den Token übernommen; nichts, was der Token-Inhaber danach tut, kann sie erweitern. Braucht ein Aufruf eine Capability, die nicht gewährt wurde, weist beacon ihn mit 403 zurück, und die Lösung ist, dass Ihr beacon-Ansprechpartner die zusätzliche Capability-Role gewährt und neu mintet. Least Privilege ist der Standard: fordern Sie nur an, was Ihre Integration tatsächlich nutzt.

Ihr Agent-JWT ist auf genau das eine Projekt beschränkt, für das er ausgestellt wurde. Jeder Aufruf ist auf die Daten dieses Projekts begrenzt. Das Modell unterstützt auch einen organisationsweiten Agent für internen Systemgebrauch, aber das ist nicht die Form, die eine Drittintegration erhält; ein projektgebundener Token ist das, was das Onboarding Ihnen übergibt.

Jeder Agent-JWT trägt zusätzlich einen session_kind-Claim, main oder sub-agent, der den eigenen Hauptlauf eines Agents von einem kurzlebigen, delegierten Worker unterscheidet, den er selbst gestartet hat. Als Drittintegrator sehen Sie ausschliesslich main; die sub-agent-Form gehört zu beacons eigenen internen Delegationsmustern und ist nicht dafür gedacht, dass eine externe SDK-Integration sie selbst konstruiert.

Dieser Agent-JWT ist etwas anderes als die Credentials im API-Keys-Tab des beacon Portals. Dieser Tab fasst zwei unabhängige Dinge zusammen: Provider API Keys, also Ihre eigenen Bring-your-own-LLM-Provider-Keys, die kein beacon-Credential sind, und Personal API Keys, einen programmatischen Zugriffsschlüssel-Typ, der noch nicht verfügbar ist. Keines von beiden ist der Agent-JWT, um den es auf dieser Seite geht: Ihr Agent-JWT ist ein kurzlebiges, capability-beschränktes Token, das Ihren Agent gegenüber beacons eigener API-Oberfläche identifiziert, ausgestellt von Ihrem beacon-Ansprechpartner und konsumiert über createAgentClient.

Ihr Agent-JWT wird vom Operator bereitgestellt: Ein beacon-Ansprechpartner legt Ihre Agent-Identität an, gewährt die passenden Capability-Roles und übergibt Ihnen den Token ausserhalb der SDK selbst, dasselbe concierge-Modell, das oben unter Authentifizierung beschrieben ist. Sie minten oder verwalten ihn nicht selbst, sondern konsumieren ihn über @beacon-build/sdk.

Agent-Client

`createAgentClient` liefert ein `AgentSdk`, gebunden an Ihren Agent-JWT. Der Kern ist task-förmig: den nächsten anstehenden Task holen, Tasks auflisten oder anlegen, und einen Task durch seinen Lebenszyklus bewegen (claim, log, complete, fail, cancel, reassign).

Zwei begleitende Clients gehören dazu: `search` führt eine vereinheitlichte semantische Suche über Dokumente, Nachrichten und Memories Ihres Projekts aus; `taskConfig` liest die Task-Konfiguration Ihres Projekts (Status, Typen, Board-Layout) zurück, damit eine Integration dagegen rendert oder validiert, statt Annahmen fest zu verdrahten.

// Anstehende Tasks auflisten
const tasks = await sdk.tasks.list({ status: 'queued' });

// Semantische Suche über Ihr Projekt
const hits = await sdk.search?.unifiedSearch({ query: 'onboarding checklist' });

// Die Task-Konfiguration lesen, auf der Ihr Projekt läuft
const config = await sdk.taskConfig.get();

Realtime

RealtimeSdkClient öffnet eine Server-Sent-Events-Verbindung zur beacon API und liefert Ihnen einen typisierten Event-Stream statt einer Polling-Schleife. Authentisieren Sie ihn mit demselben Agent-JWT (`authToken`), wählen Sie die Channels, die Sie interessieren, und er verbindet sich bei einem Abbruch selbstständig neu.

import { RealtimeSdkClient } from '@beacon-build/sdk';

const realtime = new RealtimeSdkClient({
  baseUrl: 'https://beacon.build',
  authToken: BEACON_AGENT_TOKEN,
  channels: ['project:YOUR_PROJECT_ID'],
});

realtime.on('*', (payload) => {
  // beliebiges Event auf den abonnierten Channels behandeln
});

realtime.connect();

Referenz

Jede Operation unten ist konstruktionsbedingt tenant-safe: nichts auf dieser Seite erreicht Ops-, Admin- oder Vendor-Endpunkte. Die `/api/auth/*`-Zeilen sind der menschliche Login-/Session-Flow (`createAuthClient`); die Agent- und Realtime-Zeilen ruft ein provisionierter Agent-JWT auf.

MethodPathSummary
POST/api/auth/loginLog in with email + password
POST/api/auth/registerRegister a new user (optionally via invite token)
POST/api/auth/refreshExchange a refresh token for a new access token
POST/api/auth/logoutInvalidate a refresh token
GET/api/auth/meGet the current user + roles for an access token
POST/api/v1/tasks/nextClaim the next queued task
GET/api/v1/tasksList tasks
POST/api/v1/tasksCreate a task
GET/api/v1/tasks/{ref}Get a task by ref
PATCH/api/v1/tasks/{ref}Update a task
POST/api/v1/tasks/{ref}/logPost a progress-log message on a task
POST/api/v1/tasks/{ref}/claimClaim a task
POST/api/v1/tasks/{ref}/completeComplete a task
POST/api/v1/tasks/{ref}/failFail a task
POST/api/v1/tasks/{ref}/cancelCancel a task
POST/api/v1/tasks/{ref}/reassignReassign a task
POST/api/v1/searchUnified semantic search across documents, messages, memories
POST/api/v1/capabilities/resolveResolve ranked skill/SOP/workflow candidates for a problem query
GET/api/v1/task-configGet the project's task configuration
GET/api/v1/realtime/subscribeSubscribe to a channel's realtime event stream (SSE)

Diese Seite dokumentiert `@beacon-build/sdk` 3.10.0 so, wie es heute tatsächlich funktioniert, inklusive der Stellen, die noch nicht ganz rund sind (ein sauberer `createClient`-Einstiegspunkt ist für ein späteres Release geplant). Nichts unten ist Wunschdenken.

Anleitungen

Aufgabenorientierte Anleitungen für die Arbeit mit dem beacon SDK. Jeder Code-Block unten ist der exakte Quelltext eines Beispiels unter examples/sdk/, in CI gegen die publizierten @beacon-build/sdk-Typen typgeprüft, er kann daher nicht unbemerkt veralten.

Quickstart

Der schnellste Weg von der Installation zum ersten Task: authentisieren, den nächsten anstehenden Task holen und abschließen.

// examples/sdk/quickstart.ts (F45/AC-3)
//
// Canonical source for the "Quickstart" guide on /build/sdk + /de/build/sdk. This file is the
// ONE source for both the rendered code block (read verbatim by
// src/data/sdk-guides-content.mjs) and the compiled example (typechecked here
// against the PUBLISHED @beacon-build/sdk types via `pnpm check:sdk-examples`).
// There is no second, hand-duplicated copy of this code anywhere.
import { createAgentClient } from '@beacon-build/sdk';

const sdk = createAgentClient({
  baseUrl: 'https://beacon.build',
  agentToken: process.env.BEACON_AGENT_TOKEN!,
});

const next = await sdk.tasks.next();
if (next.status !== 'empty') {
  // 'claimed' (freshly claimed) or 'active_exists' (you already had one) both
  // hand back the task itself: next() claims for you, no separate claim() call.
  const { task } = next;
  // ...do the work...
  await sdk.tasks.complete(task.ref, { result: 'done' });
}

Auth-first

Behandeln Sie die Authentifizierung als Erstes, nicht als Nachgedanke: Lesen Sie den Agent-JWT aus Ihrer eigenen Umgebung, brechen Sie bei einem fehlenden Token sofort mit einer klaren Meldung ab, und erzeugen Sie den Client erst danach.

// examples/sdk/auth-first.ts (F45/AC-3)
//
// Canonical source for the "Auth-first" guide. Shows the concierge-provisioned
// Agent-JWT model: read the token from your own environment, never hardcode it,
// and construct the client before making any tenant-safe call.
import { createAgentClient, type AgentSdk } from '@beacon-build/sdk';

function buildAgentSdk(): AgentSdk {
  const agentToken = process.env.BEACON_AGENT_TOKEN;
  if (!agentToken) {
    throw new Error('BEACON_AGENT_TOKEN is not set: ask your beacon contact for a project-scoped Agent-JWT.');
  }

  return createAgentClient({
    baseUrl: process.env.BEACON_API_BASE_URL ?? 'https://beacon.build',
    agentToken,
  });
}

const sdk = buildAgentSdk();
const config = await sdk.taskConfig.get();
console.log(`Authenticated. Task board has ${config.value.levels.length} task level(s) configured.`);

Anleitung: Releases auflisten

Ein Release ist eine Menge gemeinsam ausgelieferter Tasks. `tasks.list({ release })` filtert exakt auf den Deployed-Release-Tag eines Tasks: ein Release auflisten heißt also, die darin enthaltenen Tasks aufzulisten.

// examples/sdk/list-releases.ts (F45/AC-3)
//
// Canonical source for the "List releases" how-to. `tasks.list({ release })` is
// an exact-match filter on a task's deployed release tag ("every task that
// shipped in release X"), so listing a release means listing the tasks it
// contains, not a separate releases endpoint.
import { createAgentClient } from '@beacon-build/sdk';

const sdk = createAgentClient({
  baseUrl: 'https://beacon.build',
  agentToken: process.env.BEACON_AGENT_TOKEN!,
});

const shipped = await sdk.tasks.list({
  release: 'v2026.09.28',
  include_done: true,
  sortBy: 'completedAt',
});

for (const task of shipped) {
  console.log(`${task.ref}  ${task.title}`);
}

Anleitung: Realtime-Events abonnieren

RealtimeSdkClient öffnet eine Server-Sent-Events-Verbindung und liefert einen typisierten Event-Stream. Abonnieren Sie einen bestimmten Event-Typ oder mit dem Wildcard-Handler jedes Event auf Ihren Channels.

// examples/sdk/subscribe-realtime.ts (F45/AC-3)
//
// Canonical source for the "Subscribe to realtime events" how-to. Opens an SSE
// connection with RealtimeSdkClient and listens for a specific event type plus
// a wildcard fallback.
import { RealtimeSdkClient } from '@beacon-build/sdk';

const realtime = new RealtimeSdkClient({
  baseUrl: 'https://beacon.build',
  authToken: process.env.BEACON_AGENT_TOKEN!,
  channels: ['project:YOUR_PROJECT_ID'],
  onConnect: () => console.log('realtime connected'),
  onDisconnect: (reason) => console.log(`realtime disconnected: ${reason}`),
});

// RealtimeEventType is a string-literal union (its runtime map lives in
// @beacon-build/core, not re-exported as a value from @beacon-build/sdk):
// pass the literal event string directly.
realtime.on('task.assigned', (data) => {
  console.log('task assigned to you:', data);
});

realtime.on('*', (payload) => {
  // handle any other event on the subscribed channels
  console.log('event:', payload);
});

realtime.connect();

Anleitung: Fehler behandeln

Jeder SDK-Aufruf wirft bei einem Fehler einen typisierten SdkError: einen groben `code`, auf den Sie verzweigen können, sowie den unveränderten `apiCode`, den die API gesendet hat, falls vorhanden, für eine feinere Behandlung.

// examples/sdk/handle-errors.ts (F45/AC-3)
//
// Canonical source for the "Handle errors" how-to. Every SDK call throws a typed
// SdkError with a coarse `code` (SdkErrorCode) you can branch on, plus the
// verbatim `apiCode` the API sent (when it sent one) for finer-grained handling.
import { createAgentClient, SdkError } from '@beacon-build/sdk';

const sdk = createAgentClient({
  baseUrl: 'https://beacon.build',
  agentToken: process.env.BEACON_AGENT_TOKEN!,
});

try {
  await sdk.tasks.claim('T999');
} catch (error) {
  if (error instanceof SdkError) {
    switch (error.code) {
      case 'not_found':
        console.error('That task does not exist (or is not visible to you).');
        break;
      case 'conflict':
        console.error(`Someone else already claimed it (apiCode: ${error.apiCode ?? 'n/a'}).`);
        break;
      case 'rate_limited':
        console.error('Rate limited, back off and retry.');
        break;
      default:
        console.error(`SDK call failed: ${error.code} (${error.status ?? 'no status'})`);
    }
  } else {
    throw error;
  }
}

SDK-Referenz

Generiert aus den publizierten Typen des installierten @beacon-build/sdk (@beacon-build/sdk@3.10.0) via TypeDoc. Begrenzt auf die primären öffentlichen Einstiegspunkte des SDK: die Client-Factories, die Fehler-Oberfläche und ihre direkt benannten Options-/Result-Typen, nicht jeden transitiven @beacon-build/core-Re-Export.

createAgentClient (Function) · Create an Agent SDK instance authenticated with a project-scoped Agent-JWT.

function createAgentClient(config: AgentSdkConfig): AgentSdk

AgentSdk (Interface) · The client createAgentClient returns: tasks, search, capabilities, taskConfig, agentControllers.

interface AgentSdk {
  agentControllers: AgentControllerClient;
  capabilities?: AgentCapabilityClient;
  connectors: AgentConnectorsClient;
  contentSchemas: ContentSchemasClient;
  extTools: AgentExtToolsClient;
  knowledge: KnowledgeClient;
  projects: ProjectsClient;
  search?: AgentSearchClient;
  systemOne: SystemOneClient;
  taskConfig: TaskConfigClient;
  tasks: AgentTasksClient;
}

AgentSdkConfig (Interface) · Configuration for createAgentClient: baseUrl, agentToken, and an optional onUnauthorized hook.

interface AgentSdkConfig {
  agentToken: string | (() => string | Promise<string>);
  baseUrl: string;
  fetch?: { (input: RequestInfo | URL, init?: RequestInit): Promise<Response>; (input: string | Request | URL, init?: RequestInit): Promise<Response> };
  onUnauthorized?: () => void | Promise<string | void | null>;
}

createAuthClient (Function) · Create a client for the human login/register/refresh flow (email + password accounts).

function createAuthClient(baseUrl: string): AuthClient

AuthClient (Interface) · The client createAuthClient returns.

interface AuthClient {
  confirmPasswordReset(token: string, newPassword: string): Promise<{ success: boolean }>;
  exchange(code: string): Promise<string>;
  getInvite(token: string): Promise<InviteDetails>;
  login(email: string, password: string): Promise<LoginResult>;
  logout(refreshToken: string): Promise<void>;
  me(accessToken: string): Promise<MeResult>;
  redeemMagicLink(token: string): Promise<LoginResult>;
  refresh(refreshToken: string): Promise<RefreshResult>;
  register(email: string, password: string, inviteToken?: string, options?: RegisterOptions): Promise<RegisterResult>;
  requestMagicLink(email: string): Promise<{ success: boolean }>;
  requestPasswordReset(email: string): Promise<{ success: boolean }>;
}

LoginResult (Interface) · Result of AuthClient.login().

interface LoginResult {
  accessToken: string;
  portalCookie: string;
  refreshToken: string;
  user: UserDto;
}

RegisterResult (Interface) · Result of AuthClient.register().

interface RegisterResult {
  accessToken: string;
  refreshToken: string;
  user: UserDto;
}

RefreshResult (Interface) · Result of AuthClient.refresh().

interface RefreshResult {
  accessToken: string;
  refreshToken: string;
}

MeResult (Interface) · Result of AuthClient.me().

interface MeResult {
  email: string;
  id: string;
  isVendor: boolean;
  name: string | null;
  orgId: string | null;
  roles: { orgId?: string | null; project?: string | null; role: string }[];
  user: UserDto;
}

RealtimeSdkClient (Class) · SSE client for realtime events (F141), with auto-reconnect.

class RealtimeSdkClient {
  constructor(config: RealtimeSdkClientConfig);
  connect(): void;
  disconnect(): void;
  on(eventType: RealtimeEventType, handler: EventHandler): this;
}

RealtimeSdkClientConfig (Interface) · Configuration for RealtimeSdkClient: baseUrl, authToken, channels, lifecycle hooks.

interface RealtimeSdkClientConfig {
  authToken: string;
  baseUrl: string;
  channels: RealtimeChannel[];
  onConnect?: () => void;
  onDisconnect?: (reason: "server-closed" | "network-error" | "manual") => void;
  onError?: (error: Error) => void;
  reconnect?: { baseDelayMs?: number; enabled?: boolean; maxAttempts?: number; maxDelayMs?: number };
}

SdkError (Class) · The typed error every SDK call throws on failure.

class SdkError {
  constructor(code: SdkErrorCode, message: string, status?: number, apiCode?: string, details?: Record<string, unknown>);
  apiCode?: string;
  code: SdkErrorCode;
  details?: Record<string, unknown>;
  status?: number;
}

SdkErrorCode (TypeAlias) · The coarse error classification on SdkError.code.

type SdkErrorCode = "unauthorized" | "forbidden" | "not_found" | "conflict" | "validation" | "invalid_transition" | "rate_limited" | "server_error" | "service_unavailable" | "network_error"