LoopEngineBETA

Docs

Documentation

How LoopEngine works, from scaffold to durable approvals — agents, adapters, permission rules, and abilities.

HTTP Notifier

This page is the internal module map for core/http-notifier.ts and its six channel classes. For the full durable-approval design — checkpoints, resumption, security caveats — see Human in the Loop instead; this is where those senders live in the source tree.

resolveHttpNotifier(config) reads AgentConfig.httpNotifier and builds whichever channel-specific sender its channel discriminant names, returning an approver/questionHandler/onRunStart/onRunFinish bundle — only ever consulted for the http channel; cli/http_stream keep the library's own live defaults untouched. Resolved once per AgentConfig object and cached in a WeakMap, since it's called on every runAgent()/resumeAgent() turn.

Setting one up

AgentConfig.httpNotifier is only ever consulted on the http channel — set it on the agent whose approvals/questions/lifecycle events need to reach somewhere durable:

import type { AgentConfig, HttpNotifierConfig } from 'loopengine'

const webhookUrl = process.env.MY_AGENT_WEBHOOK_URL
const webhookSecret = process.env.MY_AGENT_WEBHOOK_SECRET
const httpNotifier: HttpNotifierConfig | undefined =
  webhookUrl && webhookSecret
    ? {
        channel: 'webhook', // or 'slack' | 'lark' | 'email' | 'database' | 'redis'
        config: { webhookUrl, webhookSecret },
        events: ['approval', 'question', 'run_start', 'run_finish'],
      }
    : undefined

export const config: AgentConfig = {
  // ...
  httpNotifier,
}

(agents/customer-service/index.ts's real version — only set when the agent's own webhook env vars are actually configured; unset, it falls straight through to the library's own live defaults on every channel, including http.) events picks which of the four event kinds this notifier actually receives — 'database'/'redis' are restricted to 'approval' alone at the type level, see below.

Six channels, one file each under core/http-notify-triggers/:

channel Class Notes
'webhook' WebhookNotifier Signed HMAC-SHA256 POST — X-Actauth-Signature for an approval, X-Askuser-Signature for a question.
'slack' SlackNotifier chat.postMessage with interactive buttons.
'lark' LarkNotifier Lark/Feishu's own card API.
'email' EmailNotifier A sendEmail callback plus a signed, expiring magic-link token per link.
'database' DatabaseApprover Writes a row for a separate worker/dashboard to poll — approval-only.
'redis' RedisQueueApprover Pushes a queue entry — approval-only.

'database'/'redis' aren't notification channels at all — nothing gets told anything, a human or worker just polls directly — so AgentConfig.ApprovalOnlyHttpNotifierEvent restricts both to the 'approval' event at the type level. Chat channels (slack/lark) share one formatChatLifecycleMessage helper for onRunStart/onRunFinish, since a lifecycle event has no signed payload to react to — just a plain announcement string; email reuses the same text as its message body under its own subject line.