HarborHarbor
DocumentationGuidesPlugins
Concepts

Orbit Runtime (Beta)

Workspace primitives: storage, cache, db, AI, tool discovery, sockets.

Beta

This surface is in beta. Shape and limits may shift before v1. Track changes in the Changelog.

Inside hrbr exec, every Function handler, and every App route, you have access to the Orbit runtime — the set of workspace primitives Harbor provides for state, AI inference, structured data, and live updates.

Marketing calls this "Shared Memory". Internally everything is orbit.*.

PrimitivePurposeUse when
orbit.storageKey/value blob store with signed URLsSave a generated artifact (report, summary, HTML)
orbit.cacheTTL'd memoized cacheShort-lived state across runs (last-digest, breadcrumbs)
orbit.dbStructured queryable rowsWorkspace records you want to filter/sort
orbit.aiHarbor-managed model inferencerun, embed, classify
orbit.toolsDiscover Harbor tools mid-runAn agent function deciding which plugin to call next
orbit.socketSigned WebSocket URLs + broadcastLive updates pushed from a job to a viewer

Never put OAuth tokens, API keys, or PII in orbit.storage, orbit.cache, or orbit.db. They are workspace-readable. Credentials live in the encrypted vault, not the runtime primitives.

orbit.storage

// Put + read
await orbit.storage.put("weekly-report.md", body, { contentType: "text/markdown" });
const body = await orbit.storage.get("weekly-report.md");

// Signed URL for sharing
const url = await orbit.storage.url("weekly-report.md", { expiresIn: "7d" });

Backed by R2 in Cloud, filesystem in OSS. Signed URLs are workspace-scoped and time-bound.

orbit.cache

// First call computes; subsequent calls within TTL hit the cache
const trending = await orbit.cache.fetch(
  "trending-issues",
  () => sentryMcp.listIssues({ since: "1d" }),
  { ttl: "10m" },
);

Backed by KV in Cloud. Always set a TTL — there's no eviction policy.

orbit.db

// Schema-less per-table rows (workspace-scoped collections)
await orbit.db.feedback.insert({
  id: crypto.randomUUID(),
  subject: input.subject,
  body:    input.body,
  created: new Date().toISOString(),
});

const recent = await orbit.db.feedback.where({ }).orderBy("created", "desc").limit(50).all();

Backed by D1 in Cloud. For now: typed via your handler's input/output, no migrations required. Indexes can be added per-collection in the dashboard.

orbit.ai

const draft = await orbit.ai.run({
  model: "anthropic/claude-3.7-sonnet",     // or "openai/gpt-4.1", etc.
  prompt: `Summarise this Sentry issue:\n${JSON.stringify(issue)}`,
  maxTokens: 400,
});

const embedding = await orbit.ai.embed({ text: issue.message });

const verdict = await orbit.ai.classify({
  text: issue.message,
  labels: ["regression", "flake", "user error"],
});

Billed against the workspace plan. Routed through Cloudflare AI Gateway in Cloud; the OSS path needs your own model provider creds (see Open Source → SDK → orbit.ai).

orbit.tools

// Search inside a run — useful when an agent doesn't know which plugin
// to use yet
const tools = await orbit.tools.search("file a ticket about a build failure");
// → [{ tool_id: "linear-mcp.create_issue", description: ..., schema: ... }, ...]

Same FTS-backed index the dashboard uses, but available from inside the isolate so an agent can introspect mid-run.

orbit.socket

// In a Function: stream progress updates to a viewer
const ws = await orbit.socket.publish("report-progress");
for (const item of items) {
  await processItem(item);
  await ws.send({ done: items.indexOf(item) + 1, total: items.length });
}

Get a signed WebSocket URL with orbit.socket.url("report-progress"). Useful for App routes that show live progress of a backing Function.

What's not here

  • orbit.ui — no such thing. The App UI templates are /sdk/orbit, an authoring import for Apps and Functions. They're not available inside hrbr exec. See Apps.