Agent Network
Wire triggers, participants, channels, and approval roles around your agents
Agent Network is the tenant-level place where you wire what can start an agent and who an agent can talk to. It replaces the old connector-card mental model with two durable resources:
- Triggers — events that fire one or more agents.
- Participants — people, groups, or AI agents that can message agents, receive replies, or fill approval roles.
Integrations still own credentials and capability metadata. A Slack, Telegram, Twilio, GitHub, Gmail, or Outlook config tells Fruxon how to authenticate and what the provider can emit. The Agent Network resources are the tenant-level runtime wiring that uses those configs.
Mental model
| Resource | What it answers | Where it lives |
|---|---|---|
| Integration | What can this provider do? Tools, trigger types, and channel types. | Integrations |
| Integration config | Which credentials or workspace should Fruxon use? | Integrations |
| Trigger | Which event should start which agents? | Agent Network |
| Participant | Who or what can talk to agents, and through which addresses? | Agent Network |
| Conversation | Which external thread has Fruxon observed? | Agent Network / Conversations |
| Access request | Which unknown sender wants to be added to the participant graph? | Agent Network |
Triggers and participants are flat tenant resources. They are not nested under a single integration because they can cut across integrations: a schedule trigger has no provider at all, and one participant can have Slack, Telegram, Teams, and phone channels on the same row.
Triggers
A trigger is a configured event source that can fire one or more agents. Fruxon supports three broad shapes:
| Trigger kind | Examples | Notes |
|---|---|---|
| Schedule | Cron-like recurring runs from the System integration. | Does not require an integration config. |
| Manual | Test fire or operator-started runs. | Useful for validating wiring. |
| Integration event | slack.message.received, github.push, google_gmail.message.received, outlook.message.received, twilio.message.received. | Usually pinned to an integration config. |
Each integration publishes trigger descriptors with a stable event id, display name, whether a config is required, and payload fields. The trigger picker reads the cross-integration catalog so operators only see integrations that actually emit events.
Bind agents
One trigger can fire many agents. Bindings are managed separately from the trigger details so you can add or remove an agent without recreating the event source. Each binding can also carry payload-to-parameter mappings, so the same inbound event can feed different agent inputs.
Use the event payload namespaces consistently:
| Namespace | Meaning |
|---|---|
{{payload.*}} | Raw provider or normalized inbound-event data, such as payload.text, payload.from, or payload.message_attributes.thread_ts. |
{{trigger.*}} | Trigger execution context, such as fire time and timezone, available at run time. |
Filter events
Integration-event triggers can include a content filter. The structural match happens first: integration, config, and event type. The filter runs after that against payload.* and decides whether the matched event actually fires the bound agents.
Filters are condition trees, not code. They support ALL / ANY matching and operators such as EQUALS, IN, CONTAINS, EXISTS, and numeric comparisons. A missing filter, or a filter with zero conditions, fires every structurally matched event.
Good uses:
- Fire only when a GitHub issue has an urgent label.
- Drop Slack messages from the bot itself.
- React only to messages from an allowlisted email sender.
Manual :fire and schedule runs bypass the content filter because the operator or scheduler is already naming the trigger directly. Use trigger preview to test a sample payload before wiring a provider webhook.
Participants
A participant is a tenant-level actor that can address agents or receive outbound messages from agents. Participants can be:
| Kind | Use it for |
|---|---|
| Person | One human reachable through one or more provider addresses. |
| Group | A Slack channel, Telegram group, Teams channel, phone line, or similar shared venue. |
| AI Agent | Another Fruxon agent represented as an actor in async routing or approval workflows. |
Channels are stored inline on the participant. Each channel points to an integration config and a provider-specific address:
| Field | Meaning |
|---|---|
integrationConfigId | The credentials envelope or workspace used to send and receive. |
address | Provider-specific address: Slack channel/DM id, Telegram chat id, Teams conversation id, phone number, etc. |
priority | Higher priority wins when several channels are available. |
label | Human-friendly label shown in the UI. |
disabled | Pauses one channel without disabling the whole participant. |
Bind a participant to an agent to let that participant address the agent. Disable the participant to pause all inbound and outbound routing while preserving channels and bindings.
Participant avatars
Participant.avatarFileId is the source of truth for the participant's image. Operators can upload an avatar directly, and supported providers can sync one from a channel. Slack and Telegram support sync today. AI-agent participants without an explicit avatar inherit the backing agent avatar at read time, without writing that fallback onto the participant row.
Conversations and messages
Conversations are observed external threads: a Slack channel, Telegram chat, Teams thread, Twilio number, or similar address. They are tenant-level resources observed through one or more integration configs. The config is a lens, not the parent.
That distinction matters when you have multiple configs for the same provider. Filtering by integrationConfigId asks "what did this credential observe?" without duplicating the underlying thread as a separate resource.
Common filters:
| Filter | Use it for |
|---|---|
integrationConfigId | Show traffic through one workspace, bot, app, or phone number. |
agentId | Show conversations involving one agent. |
participantId | Show conversations reachable through one participant. |
triggerId | Show conversations linked to executions fired by one trigger. |
onlyDiscovered | Show provider-discovered addresses before any real traffic arrives. |
Access requests
Access requests are participants-native onboarding. When an unknown sender, or a known participant not bound to the addressed agent, sends a message through a participant-owned inbound path, Fruxon records a pending access request and drops the message. Approval commits the proposed graph change.
Approval modes:
| Mode | What happens |
|---|---|
| Create new | Create a Person participant from the observed sender, add the observed channel, and bind it to the agent. |
| Add to existing | Append the observed channel to an existing participant and ensure the agent binding. |
| Bind only | Bind the already-matched participant to the agent. |
Rejecting records the operator decision. A later message from the same sender can create a fresh pending request; reject means "not now," not a permanent block.
Human approvals
Human-in-the-loop approval roles are modeled as agent slots. The agent revision declares the slot name and required kind; Agent Network binds that slot to a participant. Because the concrete participant is operator-managed, you can change "who approves legal_review" without creating a new agent revision.
An AI-agent participant can fill an AI-agent slot, so async agent-to-agent approval or delegation uses the same participant graph as human routing.
API shape
The public endpoints mirror the model:
| Resource | Endpoint |
|---|---|
| Trigger catalog | GET /v1/tenants/{tenant}/integrations/triggerTypes |
| Integration trigger metadata | GET /v1/tenants/{tenant}/integrations/{integration}/triggers |
| Integration channel metadata | GET /v1/tenants/{tenant}/integrations/{integration}/channels |
| Triggers | GET/POST /v1/tenants/{tenant}/triggers |
| Trigger bindings | PUT/DELETE /v1/tenants/{tenant}/triggers/{trigger}/bindings/{agent} |
| Participants | GET/POST /v1/tenants/{tenant}/participants |
| Participant bindings | PUT/DELETE /v1/tenants/{tenant}/participants/{participant}/bindings/{agent} |
| Access requests | GET /v1/tenants/{tenant}/participantAccessRequests |
| Conversations | GET /v1/tenants/{tenant}/conversations |
| Messages | GET /v1/tenants/{tenant}/messages |
| Network graph | GET /v1/tenants/{tenant}/network/graph |
Inbound webhook URLs live outside the tenant prefix because providers do not know your tenant slug. The path id resolves the tenant server-side:
| Inbound shape | Endpoint |
|---|---|
| One webhook per config | POST /v1/inbound/configs/{config}/{apiKeyAuth} |
| One webhook per binding | POST /v1/inbound/channels/{channelBinding}/{apiKeyAuth} |
The legacy connector guides remain available for older deployments and provider-specific setup details, but new chat and event routing should be modeled with integration configs, triggers, participants, and access requests.
Next steps
- Integrations — create the provider configs that Agent Network uses
- Access Requests — triage unknown senders
- Conversations — inspect observed threads and message history