Agent API Integration Analysis
Date: April 25, 2025
Author: Meta Agent Platform Team
Overview
This document analyzes the integration requirements between the backend Agent APIs, frontend implementation, and A2A (Agent-to-Agent) protocol. It explores the differences between current schemas, identifies key integration points, and proposes a consolidated agent schema that accommodates all requirements.
Table of Contents
- Schema Comparison
- Backend Agent Model
- Frontend Mock Data
- A2A Agent Card
- Key Differences Analysis
- Integration Requirements
- Backend Changes
- Frontend Changes
- Consolidated Agent Schema
- API Implementation
- A2A Protocol Support
- Conclusion
Schema Comparison
Backend Agent Model
Current schema from backend/app/models/agent.py:
class Agent(Base):
__tablename__ = "agents"
id = Column(PUUID(as_uuid=True), primary_key=True)
name = Column(String(255), nullable=False)
description = Column(Text)
type = Column(String(100), nullable=False) # docker, api, a2a, llm, vision, audio, sensor, workflow
configuration = Column(JSON) # Agent configuration, structure varies by type
version = Column(String(50), nullable=False) # Current version (semver)
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
updated_at = Column(DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
owner_id = Column(PUUID(as_uuid=True), ForeignKey("user.id"), nullable=False)
visibility = Column(String(50), nullable=False) # private, public
tags = Column(JSON) # Array of tags
documentation = Column(Text)
license = Column(String(100))
repository_url = Column(String(255))
input_schema = Column(JSON) # JSON Schema for agent inputs
output_schema = Column(JSON) # JSON Schema for agent outputs
modalities = Column(JSON) # Supported modalities
Frontend Mock Data
Structure from frontend/src/lib/data/agents.json:
{
"id": "agent-001",
"name": "Data Validator",
"description": "Validates customer data against business rules",
"type": "text", // Different from backend (text vs. llm)
"status": "active", // Not in backend model
"version": "1.2.0",
"created_at": "2023-03-10T09:15:00Z",
"last_used": "2023-04-18T14:22:01Z", // Not in backend model
"configuration": {
"validation_rules": {
"name": "required|string|min:2",
"email": "required|email",
"company": "required|string"
},
"api_key": "sk_validator_123456"
},
"capabilities": [ // Different from backend (capabilities vs. modalities)
"data_validation",
"schema_enforcement",
"format_correction"
],
"input_schema": { /* ... */ },
"output_schema": { /* ... */ }
}
A2A Agent Card
Key fields from the A2A protocol specification:
{
"name": "String", // Agent name
"description": "String", // Description
"url": "String", // A2A endpoint URL (not in our models)
"provider": { // Provider information (not in our models)
"name": "String",
"url": "String"
},
"version": "String",
"documentationUrl": "String", // Similar to documentation
"capabilities": { // A2A-specific capabilities format
"streaming": true,
"pushNotifications": false,
"stateTransitionHistory": true
},
"authentication": { // Authentication details (not in our models)
"type": "String",
"config": {}
},
"defaultInputModes": ["String"], // Similar to modalities
"defaultOutputModes": ["String"], // Similar to modalities
"skills": [ // Skills/abilities (not in our models)
{
"id": "String",
"name": "String",
"description": "String",
"tags": ["String"],
"examples": ["String"],
"inputModes": ["String"],
"outputModes": ["String"]
}
]
}
Key Differences Analysis
- Agent Type Representation
- Backend: Technical types (
docker,api,a2a,llm,vision,audio,sensor,workflow) -
Frontend: Simplified user-facing types (
text,vision) -
Status Field
- Backend: Missing status field (only available in AgentVersion as
status) -
Frontend: Has explicit
statusfield (active,inactive) -
Last Used Tracking
- Backend: No timestamp for last usage
-
Frontend: Includes
last_usedtimestamp -
Capabilities vs. Modalities
- Backend: Uses
modalitiesfield for supported interaction modes -
Frontend: Uses
capabilitiesfield for agent abilities -
A2A Protocol Requirements
- Several A2A fields not present in either model:
url(endpoint for A2A interactions)providerinformation- Structured
capabilitiesobject authenticationdetailsskillsarray for agent abilities
Integration Requirements
Backend Changes
- Add A2A Support Fields
# Fields to add to Agent model
url = Column(String(255)) # A2A endpoint URL
provider_name = Column(String(100))
provider_url = Column(String(255))
authentication_type = Column(String(50)) # e.g., "none", "api_key", "oauth", "jwt"
authentication_config = Column(JSON)
capabilities_streaming = Column(Boolean, default=False)
capabilities_push = Column(Boolean, default=False)
capabilities_history = Column(Boolean, default=False)
status = Column(String(50), default="active") # active, inactive
last_used = Column(DateTime)
- Add Skills Model
class AgentSkill(Base):
__tablename__ = "agent_skills"
id = Column(PUUID(as_uuid=True), primary_key=True)
agent_id = Column(PUUID(as_uuid=True), ForeignKey("agents.id"), nullable=False)
name = Column(String(100), nullable=False)
description = Column(Text)
tags = Column(JSON) # Array of string tags
examples = Column(JSON) # Array of example usage strings
input_modes = Column(JSON) # Array of supported input types
output_modes = Column(JSON) # Array of supported output types
# Relationship
agent = relationship("Agent", back_populates="skills")
- Update Agent Schema
Update the Pydantic schema in backend/app/schemas/agent.py to include the new fields.
Frontend Changes
- Create Agent API Service
Create frontend/src/lib/api/agentApi.ts following the pattern in authApi.ts.
- Update Agent Store Interface
Update the TypeScript interface in agent-store.ts to match the extended backend model.
- Add Type Mapping
Implement mapping between backend technical types and frontend display types.
Consolidated Agent Schema
The consolidated agent schema should include all fields from backend, frontend, and A2A requirements:
Database Model (Python/SQLAlchemy)
class Agent(Base):
__tablename__ = "agents"
# Core fields
id = Column(PUUID(as_uuid=True), primary_key=True)
name = Column(String(255), nullable=False)
description = Column(Text)
# Type and classification
type = Column(String(100), nullable=False) # docker, api, a2a, llm, vision, audio, sensor, workflow
execution_type = Column(String(100)) # docker, api, a2a, framework, edge
status = Column(String(50), default="active") # active, inactive, deprecated
# Versioning
version = Column(String(50), nullable=False) # Current version (semver)
# Timestamps
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
updated_at = Column(DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
last_used = Column(DateTime)
# Ownership and visibility
owner_id = Column(PUUID(as_uuid=True), ForeignKey("user.id"), nullable=False)
visibility = Column(String(50), nullable=False) # private, public
# Documentation
documentation = Column(Text)
license = Column(String(100))
repository_url = Column(String(255))
# Configuration
configuration = Column(JSON) # Agent configuration, structure varies by type
input_schema = Column(JSON) # JSON Schema for agent inputs
output_schema = Column(JSON) # JSON Schema for agent outputs
# Capabilities/Modalities
modalities = Column(JSON) # Supported modalities (text, vision, audio)
capabilities = Column(JSON) # Agent capabilities/skills as string array
# A2A Protocol Support
url = Column(String(255)) # A2A endpoint URL
provider_name = Column(String(100))
provider_url = Column(String(255))
authentication_type = Column(String(50)) # e.g., "none", "api_key", "oauth", "jwt"
authentication_config = Column(JSON)
capabilities_streaming = Column(Boolean, default=False)
capabilities_push = Column(Boolean, default=False)
capabilities_history = Column(Boolean, default=False)
# Relationships
owner = relationship("User", back_populates="agents")
versions = relationship("AgentVersion", back_populates="agent", cascade="all, delete-orphan")
skills = relationship("AgentSkill", back_populates="agent", cascade="all, delete-orphan")
def __repr__(self):
return f"<Agent {self.name} v{self.version}>"
Frontend Interface (TypeScript)
export interface Agent {
// Core fields
id: string;
name: string;
description: string;
// Type and classification
type: string; // backend type: docker, api, a2a, llm, vision, audio, sensor, workflow
display_type?: string; // frontend type: text, vision, audio, etc. (derived from type)
execution_type?: string; // docker, api, a2a, framework, edge
status: string; // active, inactive, deprecated
// Versioning
version: string;
// Timestamps
created_at: string;
updated_at: string;
last_used?: string;
// Ownership and visibility
owner_id: string;
visibility: string; // private, public
// Documentation
documentation?: string;
license?: string;
repository_url?: string;
// Configuration
configuration: Record<string, any>;
input_schema: Record<string, any>;
output_schema: Record<string, any>;
// Capabilities/Modalities
modalities: string[];
capabilities: string[];
// A2A Protocol Support
url?: string;
provider_name?: string;
provider_url?: string;
authentication_type?: string;
authentication_config?: Record<string, any>;
capabilities_streaming?: boolean;
capabilities_push?: boolean;
capabilities_history?: boolean;
// Related entities
versions?: AgentVersion[];
skills?: AgentSkill[];
}
export interface AgentVersion {
id: string;
agent_id: string;
version: string;
configuration: Record<string, any>;
created_at: string;
created_by: string;
changelog?: string;
status: string; // draft, published, deprecated
input_schema: Record<string, any>;
output_schema: Record<string, any>;
}
export interface AgentSkill {
id: string;
agent_id: string;
name: string;
description?: string;
tags?: string[];
examples?: string[];
input_modes?: string[];
output_modes?: string[];
}
API Implementation
A2A Well-Known Endpoint
To support A2A protocol, implement a special endpoint that serves the AgentCard format:
@router.get("/agents/{agent_id}/.well-known/agent.json", response_model=dict)
def get_agent_card(
agent_id: UUID,
request: Request,
db: Session = Depends(get_db)
):
"""Get A2A Agent Card for the agent"""
service = AgentService(db)
agent = service.get_agent(agent_id)
# Convert to A2A Agent Card format
base_url = str(request.base_url).rstrip('/')
agent_url = f"{base_url}/api/v1/a2a/{agent_id}"
agent_card = {
"name": agent.name,
"description": agent.description,
"url": agent.url or agent_url,
"provider": {
"name": agent.provider_name or "Meta Agent Platform",
"url": agent.provider_url
} if agent.provider_name else None,
"version": agent.version,
"documentationUrl": f"{base_url}/docs/agents/{agent_id}" if agent.documentation else None,
"capabilities": {
"streaming": agent.capabilities_streaming or False,
"pushNotifications": agent.capabilities_push or False,
"stateTransitionHistory": agent.capabilities_history or False
},
"authentication": {
"type": agent.authentication_type,
"config": agent.authentication_config
} if agent.authentication_type else None,
"defaultInputModes": agent.modalities or [],
"defaultOutputModes": agent.modalities or [],
"skills": [
{
"id": str(skill.id),
"name": skill.name,
"description": skill.description,
"tags": skill.tags,
"examples": skill.examples,
"inputModes": skill.input_modes,
"outputModes": skill.output_modes
}
for skill in agent.skills
]
}
return agent_card
Type Mapping Helper
// Agent type mapping
export function mapAgentType(backendType: string): string {
const typeMapping: Record<string, string> = {
'llm': 'text',
'vision': 'vision',
'audio': 'audio',
'a2a': 'a2a',
'docker': 'container',
'api': 'api',
'sensor': 'sensor',
'workflow': 'workflow'
};
return typeMapping[backendType] || backendType;
}
// Display name mapping
export function getAgentTypeDisplayName(type: string): string {
const displayNames: Record<string, string> = {
'text': 'Text Agent',
'vision': 'Vision Agent',
'audio': 'Audio Agent',
'a2a': 'A2A Agent',
'container': 'Container Agent',
'api': 'API Agent',
'sensor': 'Sensor Agent',
'workflow': 'Workflow Agent'
};
return displayNames[type] || type;
}
A2A Protocol Support
The A2A protocol requires specific capabilities:
- Agent Card Endpoint: Implement the
/.well-known/agent.jsonendpoint - Task Lifecycle Management: Support for task submission, status updates, and cancellation
- Content Type Negotiation: Support for different content types (text, files, data)
- Real-time Updates: Streaming updates using SSE (Server-Sent Events)
- Push Notifications: Support for webhook-based notifications
Implementation strategy:
- Add dedicated A2A protocol endpoints under /api/v1/a2a/
- Implement task management for A2A agents
- Support streaming responses using FastAPI's StreamingResponse
- Add webhook support for push notifications
Conclusion
Integrating the backend Agent APIs with the frontend implementation while supporting the A2A protocol requires several modifications to both codebases. The consolidated Agent schema provides a comprehensive model that accommodates all requirements from backend, frontend, and A2A protocol specifications.
Key recommendations: 1. Extend the backend model with A2A protocol fields 2. Add the AgentSkill model for structured skill representation 3. Create proper API service in the frontend for agent operations 4. Implement type mapping between backend and frontend representations 5. Add A2A protocol endpoints for interoperability
These changes will enable seamless integration between all components while supporting the evolving A2A protocol standard for agent interoperability.