Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Openclaw Openclaw ApplyAgentBindings

From Leeroopedia


ApplyAgentBindings

ApplyAgentBindings documents the applyAgentBindings function in src/commands/agents.bindings.ts and the resolveAgentRoute function in src/routing/resolve-route.ts. Together, these implement the two sides of binding configuration: applying bindings to the config (write-time) and resolving bindings at message routing time (read-time).

Principle:Openclaw_Openclaw_Binding_Configuration

Type: API Doc

Source Locations

File Lines Description
src/commands/agents.bindings.ts L39-90 applyAgentBindings() -- applies bindings with deduplication and conflict detection
src/routing/resolve-route.ts L167-260 resolveAgentRoute() -- resolves inbound messages to an agent via binding evaluation
src/commands/agents.bindings.ts L9-19 bindingMatchKey() -- computes the deduplication key for a binding
src/commands/agents.bindings.ts L21-37 describeBinding() -- produces a human-readable description of a binding

applyAgentBindings

Signature

export function applyAgentBindings(
  cfg: OpenClawConfig,
  bindings: AgentBinding[],
): {
  config: OpenClawConfig;
  added: AgentBinding[];
  skipped: AgentBinding[];
  conflicts: Array<{ binding: AgentBinding; existingAgentId: string }>;
}

Parameters

Parameter Type Description
cfg OpenClawConfig The current configuration object containing existing bindings.
bindings AgentBinding[] The new bindings to apply.

Return Value

Field Type Description
config OpenClawConfig Updated config with new bindings appended. Unchanged if no bindings were added.
added AgentBinding[] Bindings that were successfully added (new match keys).
skipped AgentBinding[] Bindings that were idempotent (same match key, same agent).
conflicts Array<{ binding, existingAgentId }> Bindings that conflict with an existing binding for a different agent.

Algorithm

  1. Build a map of existing match keys to agent ids from cfg.bindings.
  2. For each new binding:
    • Compute the match key via bindingMatchKey().
    • If the key exists for the same agent, add to skipped.
    • If the key exists for a different agent, add to conflicts.
    • Otherwise, add to added and update the map.
  3. If no bindings were added, return the original config unchanged.
  4. Otherwise, return a new config with the added bindings appended to the existing array.

Match Key Format

The bindingMatchKey() function produces a pipe-delimited string:

function bindingMatchKey(match: AgentBinding["match"]): string {
  const accountId = match.accountId?.trim() || DEFAULT_ACCOUNT_ID;
  return [
    match.channel,
    accountId,
    match.peer?.kind ?? "",
    match.peer?.id ?? "",
    match.guildId ?? "",
    match.teamId ?? "",
  ].join("|");
}

This ensures that two bindings with the same channel, account, peer, guild, and team are treated as duplicates.

resolveAgentRoute

Signature

export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentRoute

Input Type

export type ResolveAgentRouteInput = {
  cfg: OpenClawConfig;
  channel: string;
  accountId?: string | null;
  peer?: RoutePeer | null;
  parentPeer?: RoutePeer | null;
  guildId?: string | null;
  teamId?: string | null;
};

Output Type

export type ResolvedAgentRoute = {
  agentId: string;
  channel: string;
  accountId: string;
  sessionKey: string;
  mainSessionKey: string;
  matchedBy:
    | "binding.peer"
    | "binding.peer.parent"
    | "binding.guild"
    | "binding.team"
    | "binding.account"
    | "binding.channel"
    | "default";
};

Resolution Algorithm

The function evaluates bindings in strict priority order:

  1. Filter bindings to those matching the channel and account id.
  2. Peer match: Find a binding whose match.peer matches the inbound peer. Returns with matchedBy: "binding.peer".
  3. Parent peer match: If the message is a thread, check the parent peer. Returns with matchedBy: "binding.peer.parent".
  4. Guild match: Find a binding whose match.guildId matches. Returns with matchedBy: "binding.guild".
  5. Team match: Find a binding whose match.teamId matches. Returns with matchedBy: "binding.team".
  6. Account match: Find a binding with no peer/guild/team qualifiers and a specific (non-wildcard) account id. Returns with matchedBy: "binding.account".
  7. Channel match: Find a binding with accountId: "*" and no peer/guild/team qualifiers. Returns with matchedBy: "binding.channel".
  8. Default: Falls back to resolveDefaultAgentId(cfg). Returns with matchedBy: "default".

Each match constructs a session key via buildAgentSessionKey() and a main session key via buildAgentMainSessionKey(), both lowercased for consistency.

Account Matching

The matchesAccountId() helper has three behaviors:

  • Empty/missing match: only matches the default account id.
  • Wildcard ("*"): matches any account id.
  • Specific value: exact match only.

Supporting Functions

Function File Purpose
describeBinding(binding) src/commands/agents.bindings.ts Returns a human-readable string like "whatsapp accountId=personal peer=dm:+15551234567".
buildChannelBindings(params) src/commands/agents.bindings.ts Creates bindings from channel selections during agent creation.
parseBindingSpecs(params) src/commands/agents.bindings.ts Parses CLI --bind flag values into AgentBinding[].
listBindings(cfg) src/routing/bindings.ts Retrieves the bindings array from config.
pickFirstExistingAgentId(cfg, agentId) src/routing/resolve-route.ts Validates the agent id exists in config, falls back to default.

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment