Tool Assignment

chevron-rightRelevant source fileshashtag

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

spinner

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

spinner

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

Column
Type
Description

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

spinner

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

spinner

The _resolve_tool_ids_to_app_names() function performs this validation:

Allowed Connection Statuses:

  • active - OAuth connection is active

  • added - Connection added but not yet authorized

  • pending - Connection authorization in progress

Rejected Connection Statuses:

  • disabled - Connection was disabled

  • failed - Connection authorization failed

  • Any 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.id

  • Stable hash IDs (negative integers)

Creation Process

spinner

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:

  1. Resolve new tool IDs to app names

  2. Query existing assignments

  3. Disable assignments no longer selected

  4. Re-enable or create assignments for selected tools

Update Process

spinner

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

spinner

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

spinner

State Transitions

From State
To State
Trigger
Database Action

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

spinner

Sources: See Tool Resolution Strategies for complete details.


Best Practices

For API Consumers

  1. Always send stable IDs: Use the frontend's stableId() hash function or query GET /api/tools/connected to get valid IDs

  2. Respect connection status: Don't attempt to assign apps that aren't connected

  3. Use full updates: Send the complete list of desired tool_ids in update requests (the backend handles the diff)

  4. Check tool visibility: After updates, verify tools appear in GET /api/agents/{id} response

For Backend Developers

  1. Preserve soft deletion: Never hard-delete assignments unless cascading from agent deletion

  2. Filter by is_active: Always filter WHERE is_active = True when loading for runtime

  3. Validate connections: Always call _resolve_tool_ids_to_app_names() to enforce connection filtering

  4. Handle cache misses: Tools may not have cached metadata; handle null gracefully

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