Imported from GrupoANDevelopment-m/alberto-ai (
alberto-ai/upstream/nemoclaw/src/lib/messaging/AGENTS.md). Install upstream withnpx skills add GrupoANDevelopment-m/alberto-ai --skill messaging. Copyright stays with the author.
Agent Instructions for src/lib/messaging
Purpose
This package owns NemoClaw's manifest-first messaging architecture. It turns channel declarations for Telegram, Discord, Slack, WeChat, and WhatsApp into a serializable SandboxMessagingPlan, then applies that plan during onboard, channel add/remove/start/stop, rebuild, image build, runtime setup, diagnostics, and conflict checks.
The design goal is to keep messaging channel behavior out of core onboard/rebuild logic. Add channel-specific behavior to manifests, template resolvers, hooks, runtime assets, and policy metadata first; only change shared engines when the manifest vocabulary cannot express the required behavior.
Data Flow
- Channel manifests live in
channels/<channel>/manifest.tsand are registered bychannels/built-ins.ts. MessagingWorkflowPlannerselects the right workflow shape for onboard, add, remove, start, stop, or rebuild.ManifestCompilerandcompiler/engines/*compile manifests into aSandboxMessagingPlan.MessagingSetupApplierserializes the plan throughNEMOCLAW_MESSAGING_PLAN_B64.onboard/dockerfile-patch.tsbakes the plan into the sandbox build.applier/build/messaging-build-applier.mtsapplies agent install, render, post-agent-install build files, and writes the reduced runtime plan artifact.MessagingHostStateApplierpersists durable plan state under the sandbox registry entry.- Rebuild reads the persisted plan, stages a fresh build plan, and reapplies OpenClaw render/post-install hooks after
openclaw doctorrewrites config.
Package Map
| Path | Ownership |
|---|---|
manifest/ |
Serializable manifest and plan contracts. Keep these JSON-compatible. |
channels/ |
Built-in channel manifests, channel metadata helpers, template resolvers, runtime preload assets, and channel hook implementations. |
compiler/ |
Manifest-to-plan compilation. It may resolve env/config inputs and run enrollment/reachability/build hooks, but should not mutate OpenShell or registry state directly. |
hooks/ |
Hook contracts, registries, runner validation, common prompt/static-output helpers, and conflict error types. |
applier/ |
Host/OpenShell side effects: plan env serialization, provider upsert/reuse, policy apply, agent config writes, hook phase execution, conflict detection, registry persistence, and build-time applier. |
persistence.ts |
Compact persisted plan shape and hydration from current manifests. |
plan-validation.ts |
Defensive parsing for persisted or env-provided plans. |
diagnostics.ts |
Manifest-derived channel diagnostics used by status/doctor paths. |
utils.ts |
Agent/channel availability and selection helpers. |
Core Invariants
- Manifests and compiled plans are serializable data. Do not put functions, classes, live clients, or raw secret values in them.
- Secret inputs must not declare
statePath; persisted plans may containcredentialAvailable,credentialHash, and placeholders, never tokens. - Hook implementations are resolved by stable handler IDs through
MessagingHookRegistry. Manifests reference handlers by string; they do not import handler code. - Hook outputs must match manifest declarations and be JSON-serializable. Add outputs to the manifest before consuming them.
- Channel render/build-file targets must stay inside
/sandbox/.openclawor/sandbox/.hermes; rely on existing applier validation instead of bypassing it. - Disabled channels are not active. Always filter effects through
enabledPlanChannels()orfilterEnabledPlanEntries()when applying providers, policies, render, hooks, runtime setup, or conflicts. - Conflict detection has two axes: generic credential-hash overlap in
applier/conflict-detection/and channel-ownedpre-enablehooks such as Slack Socket Mode gateway checks. - Keep transitional compatibility tables derived from manifests.
src/lib/sandbox/channels.tsintentionally builds legacy CLI metadata fromlistBuiltInMessagingChannelManifests().
Adding or Changing a Channel
Start with channels/<channel>/manifest.ts.
- Declare
auth,inputs,credentials,policyPresets,render,runtime,agentPackages,state, andhooksin the manifest. - Add template placeholders to
channels/<channel>/template-resolver.tswhen static render data needs derived values such as allowlists, booleans, proxy URLs, or Hermes/OpenClaw schema differences. - Add hook implementations under
channels/<channel>/hooks/only for side effects or checks that cannot be represented as static manifest data. - Register hook handlers in the channel
hooks/index.tsand inhooks/builtins.ts. - Add runtime preload assets under
channels/<channel>/runtime/only when the agent runtime needs boot/connect-time shims or diagnostics. - Add or update
nemoclaw-blueprint/policies/presets/<channel>.yamlwhen the manifest declares a channel policy preset. - Cover the behavior with manifest/compiler tests plus applier/onboard/channel CLI tests when host effects change.
Where Changes Belong
- New prompt, token, allowlist, provider, policy, render, package install, runtime setup, state hydration, or health-check metadata belongs in a channel manifest.
- Nontrivial render derivation belongs in a channel template resolver.
- Enrollment, external reachability checks, QR capture, channel-specific conflict checks, runtime status, and health probes belong in hooks.
- Provider creation/reuse, policy application, config-file writes, plan env encoding, and registry persistence belong in
applier/. - Onboard and
actions/sandbox/policy-channel.tsshould orchestrate planner/applier calls, not grow channel-specific rules. - Build-time config generation should use the compiled plan and
applier/build/messaging-build-applier.mts; do not reintroduce channel-specific config rendering inscripts/generate-openclaw-config.mtsoragents/hermes/generate-config.ts.
Testing Guide
Use the narrowest test that covers the changed surface:
- Manifest shape and plan compilation:
npx vitest run src/lib/messaging/compiler src/lib/messaging/manifest src/lib/messaging/channels - Hook behavior:
npx vitest run src/lib/messaging/hooks src/lib/messaging/channels/<channel>/hooks - Host/OpenShell application:
npx vitest run src/lib/messaging/applier - Build-time render/install behavior:
npx vitest run test/messaging-build-applier.test.ts - Onboard/channel CLI integration:
npx vitest run test/onboard-messaging.test.ts test/channels-add-preset.test.ts src/lib/onboard/messaging-channel-setup.test.ts
Mock external messaging APIs. Do not call real Telegram, Discord, Slack, WeChat, WhatsApp, NVIDIA, or OpenShell services from unit tests.
Documentation
User-facing behavior changes usually need docs under docs/manage-sandboxes/messaging-channels.mdx or docs/reference/commands.mdx. Do not edit generated user skills under .agents/skills/nemoclaw-user-*/ for normal docs changes.