Tool Assignment
Purpose and Scope
This document explains how Composio tools (external app integrations) are assigned to agents in the Automatos AI platform. It covers the AgentAppAssignment table, stable tool ID generation, connection filtering, and the full lifecycle of tool assignments.
For information about the Composio integration architecture and entity management, see Composio Integration. For details on how tools are resolved and executed at runtime, see Tool Resolution Strategies and Tool Router & Execution. For information about establishing OAuth connections, see Connecting Apps.
Assignment Architecture
Tool assignment in Automatos AI follows a database-backed model where each agent-to-app relationship is stored as an AgentAppAssignment record. This approach provides:
Persistence: Assignments survive agent restarts and system redeployments
Configuration: Per-assignment config overrides (priority, custom settings)
Activation Control: Assignments can be enabled/disabled without deletion
Audit Trail: Track who assigned tools and when
Connection Filtering: Only connected apps can be assigned
High-Level Assignment Flow
Sources: orchestrator/api/agents.py:63-110, orchestrator/api/agents.py:362-438, orchestrator/api/agents.py:608-698
Stable Tool IDs
The frontend and backend use a stable hashing function to generate consistent integer IDs for Composio apps based on their names. This allows the UI to work with predictable IDs even before apps are cached in the database.
Hash Algorithm
The hash function in _stable_tool_id() matches the frontend's stableId() function, ensuring consistency:
Key Properties:
Always returns a negative integer (to distinguish from database IDs)
Deterministic: same app name always produces the same ID
Case-sensitive: "GITHUB" and "github" produce different IDs
Sources: orchestrator/api/agents.py:34-44
Assignment Table Schema
The agent_app_assignments table (represented by the AgentAppAssignment model) stores the many-to-many relationship between agents and Composio apps.
Table Structure
id
INTEGER
Primary key
agent_id
INTEGER
Foreign key to agents.id
app_name
VARCHAR
Composio app name (uppercase, e.g. "GITHUB")
app_type
VARCHAR
Always "EXTERNAL" for Composio apps
assigned_by
INTEGER
User ID who made the assignment (if available)
assigned_at
TIMESTAMP
When the assignment was created
is_active
BOOLEAN
Whether the assignment is currently active
priority
INTEGER
Assignment priority (default 0)
config
JSONB
Per-assignment configuration overrides
Entity Relationships
Sources: orchestrator/api/agents.py:13, orchestrator/api/agents.py:146-175
Connection Filtering
A critical feature of tool assignment is connection filtering: only apps that are connected for the current workspace can be assigned to agents. This prevents configuration errors where an agent expects a tool but no OAuth connection exists.
Connection Validation Flow
The _resolve_tool_ids_to_app_names() function performs this validation:
Allowed Connection Statuses:
active- OAuth connection is activeadded- Connection added but not yet authorizedpending- Connection authorization in progress
Rejected Connection Statuses:
disabled- Connection was disabledfailed- Connection authorization failedAny other status
Sources: orchestrator/api/agents.py:63-110, orchestrator/core/composio/entity_manager.py
Creating Tool Assignments
When a new agent is created via POST /api/agents, the frontend sends a list of tool_ids that may include:
Database IDs from
composio_app_cache.idStable hash IDs (negative integers)
Creation Process
Code Implementation
The assignment creation logic in POST /api/agents:
Sources: orchestrator/api/agents.py:407-421, orchestrator/api/agents.py:362-438
Updating Tool Assignments
When updating an agent via PUT /api/agents/{id}, the backend uses a diff-and-sync strategy:
Resolve new tool IDs to app names
Query existing assignments
Disable assignments no longer selected
Re-enable or create assignments for selected tools
Update Process
Soft Deletion Pattern
The backend uses soft deletion by setting is_active = False rather than deleting rows. This provides:
Audit Trail: History of what was assigned and when
Re-activation: Easy to re-enable previously assigned tools
Analytics: Track tool assignment patterns over time
Sources: orchestrator/api/agents.py:651-683, orchestrator/api/agents.py:608-698
Reading Tool Assignments
When reading agent details via GET /api/agents/{id}, the backend loads assignments and enriches them with cached app metadata.
Response Building Process
Tool Object Structure
Each tool in the response includes:
Sources: orchestrator/api/agents.py:146-175, orchestrator/api/agents.py:140-240
Assignment Lifecycle States
Assignments follow a lifecycle managed through the is_active boolean field:
State Diagram
State Transitions
Not Assigned
Active
Create agent with tool_ids
INSERT with is_active=True
Not Assigned
Active
Update agent, add tool
INSERT with is_active=True
Active
Active
Update agent, keep tool
No change
Active
Inactive
Update agent, remove tool
UPDATE SET is_active=False
Inactive
Active
Update agent, re-add tool
UPDATE SET is_active=True
Active/Inactive
Deleted
Delete agent
DELETE (cascade)
Sources: orchestrator/api/agents.py:651-683
User ID Tracking
The assigned_by field attempts to track which user created the assignment. However, due to the current authentication system using Clerk user IDs (strings like "user_..."), while the database column is an INTEGER, the field is often NULL.
Current Implementation
This function returns None for most requests since Clerk IDs are non-numeric. Future work could:
Create a separate user mapping table
Change the column type to VARCHAR
Use a different identifier
Sources: orchestrator/api/agents.py:47-60
Runtime Tool Resolution
At agent execution time, the system loads active assignments and resolves them to Composio tool definitions. This process is separate from assignment management and is covered in detail in Tool Resolution Strategies.
Quick Overview
Sources: See Tool Resolution Strategies for complete details.
Best Practices
For API Consumers
Always send stable IDs: Use the frontend's
stableId()hash function or queryGET /api/tools/connectedto get valid IDsRespect connection status: Don't attempt to assign apps that aren't connected
Use full updates: Send the complete list of desired tool_ids in update requests (the backend handles the diff)
Check tool visibility: After updates, verify tools appear in
GET /api/agents/{id}response
For Backend Developers
Preserve soft deletion: Never hard-delete assignments unless cascading from agent deletion
Filter by is_active: Always filter
WHERE is_active = Truewhen loading for runtimeValidate connections: Always call
_resolve_tool_ids_to_app_names()to enforce connection filteringHandle cache misses: Tools may not have cached metadata; handle
nullgracefully
Sources: orchestrator/api/agents.py:63-110, orchestrator/api/agents.py:146-175, orchestrator/api/agents.py:651-683
API Integration Examples
Creating an Agent with Tools
Updating Agent Tools
Reading Agent Tools
Sources: orchestrator/api/agents.py:362-438, orchestrator/api/agents.py:608-698, orchestrator/api/agents.py:537-555
Last updated

