This reference is currently available in English. The Cloud console remains in your selected language.
BEEOS CLOUD / DEVELOPER REFERENCE
Registration and lease
Register a runtime, renew its lease with heartbeats, and persist its identity.
A harness first registers with Cloud and receives a short-lived runtime lease. The lease credential authorises every later data-plane call, so the coordinator keeps it alive with signed heartbeats and tells you when it is lost. Registration and heartbeat requests carry an Ed25519 identity proof signed by the key you hold.
InstanceAuthorityRuntimeRegistrationTransport
TypeScript @beeos-ai/cloud-harness-sdk · TypeScript only
Ready-made RuntimeRegistrationTransport that sends registration and heartbeat requests through an AgentGatewayClient. It sends each request once (the coordinator owns retrying), checks the answer, and turns a registration conflict into the matching typed registration error.
class InstanceAuthorityRuntimeRegistrationTransport implements RuntimeRegistrationTransport
new InstanceAuthorityRuntimeRegistrationTransport(readonly options: { gateway: AgentGatewayClient; registrationId: string })TypeScript · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
options | { gateway: AgentGatewayClient; registrationId: string } | yes | gateway is the signed Agent Gateway client; registrationId identifies the registration whose heartbeats are sent. |
register
Sends the registration request and returns the authority's answer.
async register(request: RuntimeRegistrationRequest): Promise<RuntimeRegistrationResult>TypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
request | RuntimeRegistrationRequest | yes | The signed registration request, including the identity proof. |
Returns Promise<RuntimeRegistrationResult>
heartbeat
Sends a heartbeat for the registration and returns the authority's answer.
async heartbeat(request: RuntimeHeartbeatRequest): Promise<RuntimeHeartbeatResult>TypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
request | RuntimeHeartbeatRequest | yes | The signed heartbeat request, including the identity proof. |
Returns Promise<RuntimeHeartbeatResult>
RuntimeRegistrationAuthoritySource
TypeScript @beeos-ai/cloud-harness-sdk · TypeScript only
Read-only view of the current lease and its changes. Data-plane components use it to follow the lease without owning the coordinator.
interface RuntimeRegistrationAuthoritySourceProperties
| Name | Type | Description |
|---|---|---|
readonly authorityLease | RuntimeRegistrationAuthorityLease | null | The current lease together with the handler identity, or null when there is no valid lease. |
subscribeAuthority
Registers a listener that is called with the new lease, or null when the lease is lost. Returns a function that removes the listener.
subscribeAuthority(listener: (lease: RuntimeRegistrationAuthorityLease | null) => void): () => voidTypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
listener | (lease: RuntimeRegistrationAuthorityLease | null) => void | yes | Callback that receives the new lease, or null. |
Returns () => void
RuntimeRegistrationCoordinator
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
Owns runtime registration and the heartbeat loop. Mutating claims must stop as soon as the lease is lost.
class RuntimeRegistrationCoordinator
new RuntimeRegistrationCoordinator(readonly transport: RuntimeRegistrationTransport, readonly config: RuntimeRegistrationConfig, readonly onLeaseLost: (reason: "fenced" | "expired" | "heartbeat_failed", cause?: unknown) => void, readonly now: () => number = Date.now)TypeScript · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
transport | RuntimeRegistrationTransport | yes | Sends the registration and heartbeat requests. | |
config | RuntimeRegistrationConfig | yes | Registration intent, identity and recovery settings. | |
onLeaseLost | (reason: "fenced" | "expired" | "heartbeat_failed", cause?: unknown) => void | yes | Called when the lease is lost. reason is fenced, expired or heartbeat_failed; cause carries the underlying error when there is one. | |
now | () => number | no | Date.now | Clock in milliseconds; replace it in tests. Defaults to Date.now. |
Properties
| Name | Type | Description |
|---|---|---|
readonly lease | RuntimeActiveLease | null / RuntimeActiveLease | None | The active lease, or null when none was granted yet or it has expired by the clock. |
readonly canClaimMutations | boolean | true while a valid lease exists. Mutating claims must stop as soon as it becomes false. |
readonly authorityLease | RuntimeRegistrationAuthorityLease | null | The active lease together with the handler identity, as an immutable object, or null. Do not log or persist it: it contains the lease credential. |
transport | RuntimeRegistrationTransport | Object that sends the registration and heartbeat requests. |
keys | AgentKeyPair | Key pair whose private key signs the identity proofs. |
identity | RuntimeRegistrationIdentity | The durable registration identity: registration id, handler identity, journal store id and journal generation. |
target_instance_id | str | Cloud instance this harness must be registered to. A lease for any other instance counts as fenced. |
runtime_methods | tuple[str, ...] | Runtime methods this harness actually handles, declared in the registration. The SDK cannot infer them. |
capabilities | tuple[str, ...] | Capabilities this harness actually provides, as declared in the registration. |
contract_revision | str | Runtime contract revision declared in the registration. Defaults to RUNTIME_RPC_CONTRACT_REVISION. |
manifest_digest | str | Digest of the runtime method manifest declared in the registration. Defaults to RUNTIME_CURRENT_MANIFEST_DIGEST. |
identity_store_path | Path | None | File where the identity is saved after the coordinator advances the journal generation or the registration lineage. None keeps the change in memory only. |
fenced_retry | BackoffPolicy | Backoff used to register again after a fenced answer. Defaults to FENCED_RETRY: 30 s doubling up to 5 min, without attempt limit. |
heartbeat_failure_threshold | int | Number of consecutive transient heartbeat transport failures tolerated before the lease is dropped. Defaults to 3. |
now | Any | Clock that returns a timezone-aware datetime; replace it in tests. Defaults to the current UTC time. |
active | RuntimeActiveLease | None | The lease received from the last successful registration or heartbeat, or None. It may already have expired; use lease for the checked value. |
lease_ready | asyncio.Event | asyncio.Event that is set while a valid lease exists and cleared when the lease is lost or the coordinator stops. Wait on it instead of polling. |
errors | dict[str, str] | Last error text of each phase, under the keys register and heartbeat. An entry is removed when that phase succeeds. |
is_active | bool | True while a valid, unexpired lease exists. |
subscribeAuthority
TypeScript only
Registers a listener that is called with the new authority lease, or null when the lease is lost. Returns a function that removes the listener.
subscribeAuthority(listener: (lease: RuntimeRegistrationAuthorityLease | null) => void): () => voidTypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
listener | (lease: RuntimeRegistrationAuthorityLease | null) => void | yes | Callback that receives the new authority lease, or null. |
Returns () => void
start
Registers the runtime and starts the heartbeat loop. Returns the lease, or null when registration did not succeed immediately; retries then continue in the background according to the answer.
async start(): Promise<RuntimeActiveLease | null>TypeScript · Parameters
No parameters.
Returns Promise<RuntimeActiveLease | null>
Python · Parameters
No parameters.
Returns RuntimeActiveLease | None
stop
Stops all timers, drops the lease and notifies lease listeners. Responses to requests still in flight are ignored.
stop(): voidTypeScript · Parameters
No parameters.
Returns void
Python · Parameters
No parameters.
Returns None
wait_until_active
Python only
Waits until a usable lease exists and returns it; returns the current (possibly None) lease when the timeout expires.
async def wait_until_active(timeout: float | None = None) -> RuntimeActiveLease | NonePython · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
timeout | float | None | no | None | Maximum wait in seconds; None waits without limit. |
Returns RuntimeActiveLease | None
RuntimeRegistrationTransport
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
Sends the registration and heartbeat requests. Implement it to change how requests reach Cloud.
interface RuntimeRegistrationTransportregister
TypeScript only
Sends the registration request and returns the authority's answer.
register(request: RuntimeRegistrationRequest): Promise<RuntimeRegistrationResult>TypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
request | RuntimeRegistrationRequest | yes | The signed registration request. |
Returns Promise<RuntimeRegistrationResult>
heartbeat
TypeScript only
Sends a heartbeat and returns the authority's answer.
heartbeat(request: RuntimeHeartbeatRequest): Promise<RuntimeHeartbeatResult>TypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
request | RuntimeHeartbeatRequest | yes | The signed heartbeat request. |
Returns Promise<RuntimeHeartbeatResult>
register_runtime
Python only
Sends POST /api/v1/runtime/registrations with the given JSON body and returns the decoded JSON answer.
async def register_runtime(body: Mapping[str, Any]) -> AnyPython · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
body | Mapping[str, Any] | yes | JSON body of the registration request. |
Returns Any
heartbeat_runtime
Python only
Sends POST /api/v1/runtime/registrations/{registrationId}/heartbeat with the given JSON body and returns the decoded JSON answer.
async def heartbeat_runtime(registration_id: str, body: Mapping[str, Any]) -> AnyPython · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
registration_id | str | yes | Identifier of the registration to send the heartbeat for. | |
body | Mapping[str, Any] | yes | JSON body of the heartbeat request. |
Returns Any
RuntimeTransportFailurePolicy
TypeScript @beeos-ai/cloud-harness-sdk · TypeScript only
Counts consecutive transient transport failures and reports when a threshold is reached, so a single gateway blip does not drop a lease or claim.
class RuntimeTransportFailurePolicy
new RuntimeTransportFailurePolicy(readonly threshold = 3)TypeScript · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
threshold | number | no | 3 | Number of consecutive failures that triggers the policy. Defaults to 3. |
recordSuccess
Resets the failure count after any authoritative (non-transport) answer.
recordSuccess(): voidTypeScript · Parameters
No parameters.
Returns void
recordFailure
Records one transport failure. Returns false while still within the tolerance, so the lease or claim stays alive; returns true when the threshold is reached, resets the counter, and the caller must then treat the lease or claim as lost.
recordFailure(): booleanTypeScript · Parameters
No parameters.
Returns boolean
classifyRuntimeRegistrationConflict
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
Parses the body of a registration 409 answer and returns the matching typed error: wait for the handoff, advance the journal generation, or an owner reset is required.
function classifyRuntimeRegistrationConflict(detail: string): RuntimeRegistrationHandoffRequiredError | RuntimeRegistrationJournalAdvanceRequiredError | RuntimeRegistrationOwnerResetRequiredErrorTypeScript · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
detail | string | yes | Body text of the 409 answer to a registration request. |
Returns RuntimeRegistrationHandoffRequiredError | RuntimeRegistrationJournalAdvanceRequiredError | RuntimeRegistrationOwnerResetRequiredError
Python · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
detail | str | yes | Body text of the 409 answer to a registration request. |
Returns RuntimeRegistrationHandoffRequired | RuntimeRegistrationJournalAdvanceRequired | RuntimeRegistrationOwnerResetRequired | RuntimeRegistrationIntentConflict | None
load_or_create_identity
Python beeos_cloud_harness_sdk.registration · Python only
Loads the registration identity from path, or creates and saves a new one. When the stored handler identity differs from the requested one, a new registration id is created and the journal generation is advanced by one.
def load_or_create_identity(path: Path, *, handler_identity: str) -> RuntimeRegistrationIdentityPython · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | Path | yes | Identity file; missing parent directories are created. | |
handler_identity | str | yes | Identity of this handler process, for example the name of its pod or container. |
Returns RuntimeRegistrationIdentity
save_identity
Python beeos_cloud_harness_sdk.registration · Python only
Writes the identity as JSON through a temporary file and an atomic rename, with mode 0600.
def save_identity(path: Path, identity: RuntimeRegistrationIdentity) -> NonePython · Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path | Path | yes | Identity file; missing parent directories are created. | |
identity | RuntimeRegistrationIdentity | yes | The identity to persist. |
Returns None
FENCED_RETRY
Python beeos_cloud_harness_sdk.registration · Python only
Backoff after a fenced answer, which is recoverable: 30 s doubling up to 5 min, without attempt limit.
FENCED_RETRY = BackoffPolicy(float('inf'), 30000, 300000, 2)HEARTBEAT_TRANSPORT_FAILURE_THRESHOLD
Python beeos_cloud_harness_sdk.registration · Python only
Number of consecutive heartbeat transport failures tolerated before the lease is treated as lost.
HEARTBEAT_TRANSPORT_FAILURE_THRESHOLD = 3IDENTITY_FILE_NAME
Python beeos_cloud_harness_sdk.registration · Python only
Conventional file name runtime-registration-identity.json for the saved registration identity.
IDENTITY_FILE_NAME = 'runtime-registration-identity.json'RUNTIME_CURRENT_MANIFEST_DIGEST
Python beeos_cloud_harness_sdk.registration · Python only
Digest of the runtime method manifest that matches the contract revision of this SDK release.
RUNTIME_CURRENT_MANIFEST_DIGEST = 'd5db2c5e7c78cee73e5672a3c18a8e56179b28888f6fbb660d98ec021ca9de9b'RUNTIME_RPC_CONTRACT_REVISION
Python beeos_cloud_harness_sdk.registration · Python only
Runtime contract revision this SDK release implements, sent in the registration.
RUNTIME_RPC_CONTRACT_REVISION = '2026-07-14.3'RUNTIME_RPC_PROTOCOL_VERSION
Python beeos_cloud_harness_sdk.registration · Python only
Version of the runtime RPC protocol, currently 1.
RUNTIME_RPC_PROTOCOL_VERSION = 1RuntimeRegistrationError
Python beeos_cloud_harness_sdk.registration · Python only
Base class of the errors that describe a registration outcome.
class RuntimeRegistrationError(RuntimeError)RuntimeRegistrationHandoffRequiredError
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
A previous lease still owns the instance. Wait until it expires, then register the same intent again.
class RuntimeRegistrationHandoffRequiredError extends Error
new RuntimeRegistrationHandoffRequiredError(retryAfterMs = 65_000)TypeScript · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
retryAfterMs | number | no | 65_000 | Time to wait before registering again, in milliseconds. Defaults to 65000. |
Python · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
retry_after_ms | int | no | 65000 | Time to wait before registering again, in milliseconds. Defaults to 65000. |
Properties
| Name | Type | Description |
|---|---|---|
readonly retryAfterMs | number | Time to wait before registering again, in milliseconds. |
RuntimeRegistrationIntentConflict
Python beeos_cloud_harness_sdk.registration · Python only
The stored registration id no longer matches the registration intent that is being sent, for example after the list of runtime methods changed. The coordinator then creates a new registration id and advances the journal generation.
class RuntimeRegistrationIntentConflict(RuntimeRegistrationError)
def __init__() -> NoneRuntimeRegistrationJournalAdvanceRequiredError
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
The previous lease has expired, so the next registration must use the next journal generation. Advance the durable identity exactly once before retrying; do not treat this as a handoff wait.
class RuntimeRegistrationJournalAdvanceRequiredError extends Error
new RuntimeRegistrationJournalAdvanceRequiredError(detail?: { currentJournalGeneration?: `${bigint}`; expectedJournalGeneration?: `${bigint}`; })TypeScript · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
detail | { currentJournalGeneration?: `${bigint}`; expectedJournalGeneration?: `${bigint}`; } | no | Optional generations parsed from the conflict body: the current journal generation and the expected next one. |
Python · Constructor
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
current | str | None | no | None | Current journal generation reported by the authority, if present. |
expected | str | None | no | None | Journal generation the next registration must use, if present. |
Properties
| Name | Type | Description |
|---|---|---|
readonly currentJournalGeneration? | ${bigint} | Current journal generation, when the conflict answer contains it. |
readonly expectedJournalGeneration? | ${bigint} | Journal generation the next registration must use, when the conflict answer contains it. |
RuntimeRegistrationLeaseExpiredError
TypeScript @beeos-ai/cloud-harness-sdk · TypeScript only
The authority returned a lease that had already expired.
class RuntimeRegistrationLeaseExpiredError extends Error
new RuntimeRegistrationLeaseExpiredError()RuntimeRegistrationOwnerResetRequiredError
TypeScript @beeos-ai/cloud-harness-sdk · Python beeos_cloud_harness_sdk.registration
Registration was refused because the journal store changed without an explicit owner-reset authorization. This is terminal: retrying the same intent loops forever, so surface it for an operator instead of retrying.
class RuntimeRegistrationOwnerResetRequiredError extends Error
new RuntimeRegistrationOwnerResetRequiredError()Errors and exceptions
Error types that this module defines. The description of each method says when it raises one.
| Errors | Language | Description |
|---|---|---|
| RuntimeRegistrationError | Python | Base class of the errors that describe a registration outcome. |
| RuntimeRegistrationHandoffRequiredError | TypeScript, Python | A previous lease still owns the instance. Wait until it expires, then register the same intent again. |
| RuntimeRegistrationIntentConflict | Python | The stored registration id no longer matches the registration intent that is being sent, for example after the list of runtime methods changed. The coordinator then creates a new registration id and advances the journal generation. |
| RuntimeRegistrationJournalAdvanceRequiredError | TypeScript, Python | The previous lease has expired, so the next registration must use the next journal generation. Advance the durable identity exactly once before retrying; do not treat this as a handoff wait. |
| RuntimeRegistrationLeaseExpiredError | TypeScript | The authority returned a lease that had already expired. |
| RuntimeRegistrationOwnerResetRequiredError | TypeScript, Python | Registration was refused because the journal store changed without an explicit owner-reset authorization. This is terminal: retrying the same intent loops forever, so surface it for an operator instead of retrying. |