Skip to main content
The Cross-Agent SDK lets one agent operate on another agent’s data within the same tenant. Read executions, walk conversation threads, write reviews against an agent’s work, and curate its memory — all from inside agent code. Without these primitives, client.chat() always targets the current agent. The cross-agent surface closes that gap and unlocks three common patterns:
  • Reviewer agents — judge another agent’s recent executions and write reviews automatically
  • Follow-up agents — find conversations idle for >24h and ping the original agent to re-engage
  • Metrics / curator agents — emit custom domain events from another agent’s logs, or curate its long-term memory
All operations are tenant-scoped via the runtime API key. Cross-tenant references return 404 (not 403) so existence is never leaked across tenants.

The four modules

Agents

Invoke other agents (invoke / invokeAsync), list, get.

Executions

Read execution rows and the hierarchical trace tree, with pagination.

Threads

Walk grouped conversations by entity (phone, email, contact). getFullThread returns thread + executions + traces in one call.

MemoryAdmin

Cross-agent memory: get / set / append / clear / search / list / summarize on another agent’s slots.

Universal agent reference

Every cross-agent endpoint accepts the same three identifier forms for the target agent. Resolution is server-side; the database always sees the canonical UUID.
1

UUID — always works

Keyed on (id, tenantId, ACTIVE). Single-match.
2

Slug — recommended

Exact match on (tenantId, slug, ACTIVE). Slugs are URL-friendly identifiers, unique per tenant. Auto-generated from the agent name on creation when not set explicitly.
3

Name — case-insensitive

Must be unambiguous. If two active agents share the name, the call returns 409 with a “use UUID or assign each a unique slug” hint.
This applies to Agents.*, Reviews.{create,list,stats,exportForTraining}, Executions.list({ agentId }), Threads.list({ agentId }), and MemoryAdmin.*.
The slug field on the agent is optional in the create modal. Leave it blank and the backend derives one from the name (Customer Support Botcustomer-support-bot). Manual edits make the slug “sticky” — renaming the agent won’t overwrite a slug you customized.

Agents

Cross-agent invocation and discovery.

Sync vs async — when to pick which

Flexible input — anything goes to request.*

The entire input object is forwarded to the Go executor and exposed under request.* in the target’s handler. message is not required — pass arbitrary structured payloads.

Executions

Read execution rows across agents in the caller’s tenant.

getDetails — execution + full trace tree

Returns the execution row plus the hierarchical trace tree (LLM calls, tool calls, sub-spans). What you see on the “execution detail” page in the portal.

Trace pagination — protect the DB

A pathological execution (deep workflow, tool loop, RAG-heavy turn) can produce thousands of traces. Before pagination, one bad execution could pin Postgres and return a multi-megabyte payload.

iterateTraces — walk every page without boilerplate

Async generator that walks pages until tracesHasMore is false. Yields one page at a time so memory doesn’t spike on huge executions.
iterateTraces has a hard safety cap of 100 pages (~100k traces). If you hit it, something is wrong upstream — investigate the agent, don’t crank the limit.

Threads

Threads are grouped executions by entity (phone, email, contact). One conversation that spans multiple executions over time = one thread.

Granularity map

getFullThread — thread + executions + traces in one call

Fetches in two stages: list executions, then executions.getDetails for each (concurrency capped at 5). Individual failures are silently dropped so a single bad execution doesn’t break the whole batch.

Memory Admin

The default Memory module is scoped to the caller’s agent. To curate another agent’s memory (audit messages, inject system context, clear stale sessions, summarize), use MemoryAdmin.
Memory keys are prefixed with the target agent’s id (not the caller’s), so the existing data isolation model stays intact. Each agent has its own namespace; MemoryAdmin just flips which namespace you target.

Reviews — full lifecycle

The existing Reviews module covers production execution reviews. Two new ergonomic helpers for the common verdict transitions:
Reviews stamped by SDK callers show up in the UI as reviewedBy: apikey:<name> — easy to filter from human reviews.

Recipes

Reviewer agent — automated quality control

Wire it to a daily CRON trigger and humans only see the bad reviews. See Auto-reviewer agent for the full walkthrough.

Follow-up agent — decoupled from the conversation flow

The follow-up agent is just a normal agent with its own cron trigger — none of the logic leaks into the original conversation.

Metrics agent — custom KPIs from execution logs

Dashboards (or external BI) get a real booking_completed event without touching the target agent at all.

Security model

All cross-agent endpoints sit behind RuntimeAuthGuard or SdkAuthGuard and resolve tenantId from the credential — never from the body or query. Cross-tenant access returns 404 (not 403) — existence is never leaked.

SDK version requirement

@runflow-ai/sdk >= 1.2.0. Older versions don’t have the new namespaces on the API client and throw a clear “namespace missing” error at construction time.

Next steps

Auto-reviewer agent

Full walkthrough of an automated quality-control agent.

Memory

Single-agent memory module (the default).

Observability

Tracing and business events.

Standalone Modules

All standalone SDK exports.