Light Dark

Functions

build-headers

fn (body-text: Str, opts: CallbackOptions): Map

Internal: assemble the headers dictionary for a callback POST. Adds the signature header when a secret is configured.

callback-host

fn (url: Str): Str

Internal: best-effort host extraction for already-lowercased HTTPS callback URLs.

from-body

fn (body: Map?): Any

Build a CallbackOptions from a webhook body. Returns null when the caller didn't supply a callback URL. Recognized keys (both kebab-case and snake_case):

  • callback_url / callback-url
  • callback_secret_env / callback-secret-env
  • callback_signing_header / callback-signing-header

Convenience for transports that accept callback_url in the inbound payload directly. Non-HTTPS URLs are ignored; callers that need local development callbacks should use streams or construct their own stricter transport-local policy.

is-private-callback-host

fn (host: Str): Bool

Internal: reject obvious localhost, link-local, and RFC1918 callback hosts.

is-url-allowed

fn (url: Str?): Bool

Return true when a callback URL is safe for the shared helper to call. The default policy is intentionally narrow: callbacks must be HTTPS and must not target obvious local/private hosts, so untrusted webhook bodies cannot direct the worker at internal services.

ns alias

Alias of ::ai::agent::callbacks/

Outbound callback support for queued / asynchronous agent replies.

The standard agent webhook contract has three reply modes:

  1. response — the agent computed an answer synchronously and returns it in the HTTP response.
  2. queued — the agent kicked off async work (memory recall, LLM call) and returns a placeholder. The transport client is expected to listen on the Hot run stream for the eventual answer, or...
  3. callback — same as queued, but the agent commits to POSTing the final answer to a callback_url provided by the caller. This is the right shape for Slack / Telegram / Discord integrations that don't speak Hot's run stream natively.

This module is the agent-side helper for mode 3.

Surface

  • CallbackOptions{url, signing-secret-env?, signing-header?, timeout-ms?, headers?}.
  • post-callback(payload, opts) — POST payload (JSON-encoded) to an HTTPS opts.url, attaching an HMAC signature header when a signing secret is configured. Returns {ok, status, error?, attempt-ms}.
  • from-body(body) — extract a CallbackOptions from the webhook body's callback_url / callback_secret_env fields, returning null when no callback was requested.

Transports that want callback parity should:

  1. Pull a CallbackOptions from the inbound body via from-body.
  2. Reply synchronously with mode: "queued" and callback: true.
  3. Once the async work finishes, call post-callback(answer, opts).

post-callback

fn (payload: Any, opts: CallbackOptions): CallbackResult

POST payload to opts.url as JSON, optionally signing the body with HMAC-SHA256. Returns a CallbackResult capturing status and elapsed time so the agent can log / retry.

payload may be any value — it's wrapped through ::hot::json/to-json before transmission.

resolve-secret

fn (literal: Str?, env-name: Str?): Str?

Internal: resolve a literal-or-env signing secret. Returns null when neither is set.

Types

CallbackOptions

CallbackOptions type {
    url: Str,
    signing-secret-env: Str?,
    signing-secret: Str?,
    signing-header: Str?,
    headers: Map?,
    timeout-ms: Int?
}

Configuration for a callback POST.

  • url — destination URL.
  • signing-secret-env — env var holding the HMAC secret used to sign the JSON body.
  • signing-secret — literal secret (rare; prefer env).
  • signing-header — header name for the signature. Defaults to x-hot-signature. The value is "sha256=<hex>".
  • headers — extra headers to send.
  • timeout-ms — reserved (HTTP timeout — currently advisory).

CallbackResult

CallbackResult type {
    ok: Bool,
    status: Int,
    error: Str?,
    attempt-ms: Int
}

Outcome of a callback POST.

  • ok — true when the upstream returned a 2xx status.
  • status — HTTP status code (or 0 when the call never reached the server).
  • error — human-readable error string on failure.
  • attempt-ms — wall-clock time spent on the attempt.