Skip to Content
Next — You're reading the unreleased preview docs. APIs and pages may change before the next release.Switch to the current docs →
How-To GuidesTypeScriptWaiting for External Input with Golem Promises (TypeScript)

Waiting for External Input with Golem Promises (TypeScript)

Overview

A Golem promise lets an agent suspend its execution until an external event completes it. The agent creates a promise, passes the promise ID to an external system (another agent, a webhook, a UI, an HTTP API call), and then awaits the result. Creation does not suspend the agent. For durable agents awaiting a pending promise, suspension can occur after the suspension policy delay when all active work permits it. Suspension frees guest execution resources; persisted state and other resources remain.

API

All functions are in @golemcloud/golem-ts-sdk:

FunctionSignatureDescription
createPromise() => PromiseIdCreates a new promise and returns its ID
awaitPromise(id: PromiseId) => Promise<Uint8Array>Awaits promise completion (non-blocking)
completePromise(id: PromiseId, data: Uint8Array) => booleanCompletes a promise with raw bytes

Imports

import { createPromise, awaitPromise, completePromise } from '@golemcloud/golem-ts-sdk'; import type { PromiseId } from '@golemcloud/golem-ts-sdk';

Usage Pattern

1. Create a Promise and Wait

const promiseId = createPromise(); // Pass promiseId to an external system... // Awaiting can suspend the durable agent after the suspension policy delay const resultBytes = await awaitPromise(promiseId); const result = new TextDecoder().decode(resultBytes);

2. Complete a Promise from Another Agent

const data = new TextEncoder().encode(JSON.stringify({ status: "approved" })); completePromise(promiseId, data);

3. Decode JSON from a Completed Promise

const promiseId = createPromise(); const bytes = await awaitPromise(promiseId); const decision = JSON.parse(new TextDecoder().decode(bytes));

PromiseId Structure

A PromiseId contains an agentId, a fingerprint, and an oplogIdx. The fingerprint is a UUID ({ highBits, lowBits }) that identifies the agent incarnation that created the promise: a deleted and re-created agent keeps its agent ID but gets a new fingerprint, so the promise IDs of the deleted incarnation do not complete the promises of the new one. To let an external system complete the promise via the Golem REST API, the agent must expose all three fields. Convert the fingerprint to its string form with uuidToString:

import { uuidToString } from 'golem:core/types@2.0.0'; const fingerprint = uuidToString(promiseId.fingerprint); const oplogIdx = promiseId.oplogIdx.toString();

The external caller then sends:

POST /v1/components/{component_id}/workers/{agent_name}/complete Content-Type: application/json {"oplogIdx": <oplog_idx>, "fingerprint": "<fingerprint_uuid>", "data": [<bytes>]}

All three body fields are required. The display form of a promise ID is <agent-id>/<fingerprint>/<oplog-idx>.

Full Example: Human-in-the-Loop Approval

import { z } from 'zod'; import { defineAgent, method, http, createPromise, awaitPromise } from '@golemcloud/golem-ts-sdk'; export const WorkflowAgent = defineAgent({ name: 'WorkflowAgent', id: { name: z.string() }, http: http.mount('/workflows/{name}'), methods: { startApproval: method({ input: {}, returns: z.string(), http: http.post('/approve') }), }, }); export const WorkflowAgentImpl = WorkflowAgent.implement({ init: ({ id }) => ({ name: id.name }), methods: { async startApproval() { // 1. Create a promise const promiseId = createPromise(); // 2. Pass promiseId.fingerprint and promiseId.oplogIdx to an external system. // Creation does not suspend the agent; awaiting can suspend it after the policy delay. // 3. Wait for external completion const bytes = await awaitPromise(promiseId); const decision = JSON.parse(new TextDecoder().decode(bytes)); return decision.status === 'approved' ? `Workflow ${this.name} approved ✅` : `Workflow ${this.name} rejected ❌`; }, }, });

Use Cases

  • Human-in-the-loop: Pause a workflow until a human approves or rejects
  • Webhook callbacks: Wait for an external HTTP callback to arrive
  • Inter-agent synchronization: One agent creates a promise, another completes it
  • External event ingestion: Suspend until an IoT sensor, payment gateway, or third-party API sends a signal