Invocation Model

How all agent work flows through a single unified entry point with consistent policy enforcement — rate limiting, idempotency, trigger validation, and observability.

Unified Entry Point

Every agent invocation — whether from the API, a channel message, a cron schedule, a workflow step, or a system event — flows through the same pipeline:

Invocation Sources

Each invocation carries metadata about its origin:

SourceDescriptionAlways Accepted?
ApiDirect HTTP API callYes (every agent implicitly accepts)
ChannelMessage from Slack, Telegram, etc.Only if agent has matching channel trigger
CronFired by a scheduled jobYes (schedules are platform-managed)
WorkflowStep in a multi-agent pipelineOnly if agent has a workflow trigger
EventSystem/lifecycle eventOnly if agent has matching event pattern

Trigger Acceptance Logic

InvocationContext

The full payload delivered to the invocation layer:

{
  "source": {
    "Workflow": {
      "workflow_id": "a1b2c3d4-...",
      "step_index": 2,
      "upstream_agent_id": "550e8400-..."
    }
  },
  "message": "Process this claim...",
  "idempotency_key": "req-abc123",
  "correlation_id": "7c9e6679-..."
}
FieldPurpose
sourceOrigin metadata for routing, telemetry, and audit
messageThe payload to deliver to the agent
idempotency_keyOptional deduplication key (requests with same key return cached result)
correlation_idUUID for distributed tracing across steps/services

Rate Limiting

Per-agent sliding window rate limiter:

  • Window: 60 seconds (sliding)
  • Default limit: 60 invocations per minute per agent
  • Implementation: in-memory HashMap<AgentId, Vec<Instant>> — timestamps older than 60s are evicted on each check
  • Disabled: set limit to 0 for a specific agent

When exceeded:

{
  "error": {
    "category": "RateLimited",
    "message": "Agent has exceeded the rate limit of 60 invocations per minute",
    "details": {"agent_id": "...", "limit": "60"}
  }
}

Idempotency

Optional deduplication for exactly-once semantics:

  • Requests with the same idempotency_key return the cached result without re-executing
  • Cache is in-memory with TTL (bounded size)
  • Useful for webhook retries and workflow step replays

Trigger Registry

The trigger registry manages per-agent trigger configurations and synchronizes with agent lifecycle:

Trigger States

StateMeaning
ActiveTrigger is accepting matching events
PausedTemporarily inactive (agent suspended)
DisabledPermanently inactive (agent terminated, cannot reactivate)

Lifecycle Synchronization

Agent TransitionTrigger Effect
Running → SuspendedAll triggers → Paused
Suspended → RunningAll triggers → Active
Any → TerminatedAll triggers → Disabled

Telemetry

Every invocation records structured metrics:

{
  "agent_id": "550e8400-...",
  "source": "Workflow",
  "duration_ms": 2100,
  "tokens_used": 342,
  "success": true,
  "correlation_id": "7c9e6679-..."
}

Available via the API as per-agent invocation metrics:

  • Total invocations
  • Error count / error rate
  • Average duration
  • Per-source breakdown (how many from API vs Channel vs Cron vs Workflow)

InvocationResult

The structured response returned from every invocation:

{
  "content": "There are 23 open claims in the queue.",
  "tokens_used": 342,
  "duration_ms": 2100,
  "correlation_id": "7c9e6679-...",
  "source": {"Api": {}}
}

Trigger Types

Agents declare what invocation sources they accept via trigger configuration:

# In agent config
triggers = [
  { lifecycle = {} },
  { channel = { channel_type = "slack" } },
  { cron = { expression = "0 */6 * * *" } },
  { workflow = {} },
  { event = { pattern = "agent_spawned:claims-*" } }
]
Trigger TypeAccepts Source
lifecycleLifecycle events (boot, shutdown)
channelChannel messages matching channel_type
cronScheduled invocations (platform-managed)
workflowWorkflow step invocations
eventSystem events matching pattern
apiDirect API calls (implicit, always present)