agent.py
Overview
The agent.py file defines a RESTful API for managing "agents" within the InfiniFlow platform. An "agent" here corresponds to a user-specific canvas entity, optionally with a domain-specific language (DSL) describing its behavior or configuration. This file provides endpoints to list, create, update, and delete agents, ensuring operations are authenticated and scoped by tenant (user) ownership.
The core functionality in this file revolves around CRUD operations on the UserCanvasService and version tracking via UserCanvasVersionService. It includes input validation, JSON DSL handling, and permission enforcement so that only the owner of an agent can modify or delete it.
Detailed Explanation of API Endpoints
1. list_agents
@manager.route('/agents', methods=['GET'])
@token_required
def list_agents(tenant_id):
Purpose: Retrieves a paginated list of agents for the authenticated tenant, optionally filtered by agent
idortitle.Parameters:
tenant_id(str): Injected by the@token_requireddecorator identifying the current user.Query parameters (from
request.args):id(optional): Filter agents by this specific ID.title(optional): Filter agents by this title.page(optional, default=1): Page number for pagination.page_size(optional, default=30): Number of agents per page.orderby(optional, default="update_time"): Field to order results by.desc(optional, default=True): Whether to order descending.
Returns: JSON response with the list of agents matching the query, or an error if a specific agent is requested but not found.
Usage example:
GET /agents?page=2&page_size=10&orderby=title&desc=false Authorization: Bearer <token>Details:
If
idortitlefilters are provided, it first checks for existence and returns an error if no matching agent is found.Handles parsing and defaulting for pagination and sorting parameters.
Delegates the data fetch to
UserCanvasService.get_list.
2. create_agent
@manager.route("/agents", methods=["POST"])
@token_required
def create_agent(tenant_id: str):
Purpose: Creates a new agent for the authenticated tenant.
Parameters:
tenant_id(str): Current user's tenant ID.Request JSON body:
title(str): The agent's title (required).dsl(str or dict): The DSL configuration of the agent (required).Other optional fields may be included and passed to the service.
Returns: JSON result indicating success or failure, including validation error messages.
Usage example:
POST /agents Authorization: Bearer <token> Content-Type: application/json { "title": "My Agent", "dsl": { "node": "start", "actions": [] } }Details:
Validates presence and types of
titleanddsl.Converts nested DSL JSON strings into Python objects for internal consistency.
Checks for duplicate agent titles for the tenant.
Generates a unique agent ID using
get_uuid.Saves agent data using
UserCanvasService.save.Inserts an initial version record into
UserCanvasVersionServicewith timestamped title.Returns a success response if all operations succeed.
3. update_agent
@manager.route("/agents/<agent_id>", methods=["PUT"])
@token_required
def update_agent(tenant_id: str, agent_id: str):
Purpose: Updates an existing agent owned by the tenant.
Parameters:
tenant_id(str): Current user's tenant ID.agent_id(str): The ID of the agent to update (from URL path).Request JSON body: Fields to update (e.g.,
title,dsl).
Returns: JSON result indicating success or failure, including authorization errors.
Usage example:
PUT /agents/1234-uuid Authorization: Bearer <token> Content-Type: application/json { "title": "Updated Agent Title", "dsl": { "node": "start", "actions": ["new_action"] } }Details:
Filters out any
Nonevalues from the input JSON.Parses DSL string to JSON if necessary.
Strips whitespace from the title if provided.
Validates that the agent exists and belongs to the tenant.
Updates agent fields via
UserCanvasService.update_by_id.If a DSL update is present, inserts a new version entry and deletes all previous versions (per the implementation).
Returns success if update succeeds.
4. delete_agent
@manager.route("/agents/<agent_id>", methods=["DELETE"])
@token_required
def delete_agent(tenant_id: str, agent_id: str):
Purpose: Deletes an agent owned by the tenant.
Parameters:
tenant_id(str): Current user's tenant ID.agent_id(str): The ID of the agent to delete.
Returns: JSON result indicating success or failure, including authorization errors.
Usage example:
DELETE /agents/1234-uuid Authorization: Bearer <token>Details:
Verifies ownership before deletion.
Calls
UserCanvasService.delete_by_idto remove the agent.Returns success JSON response on completion.
Important Implementation Details
Authentication and Authorization: All routes are decorated with
@token_required, which injects thetenant_idto ensure that only authenticated users can access the endpoints. Ownership checks are explicitly performed on update and delete operations to prevent unauthorized access.DSL Handling:
The DSL (domain-specific language) describing the agent can be sent as a JSON string or an object. The API normalizes it to a Python dict.
On creation and update, DSL snapshots are versioned with timestamped titles in
UserCanvasVersionService.On update, all previous versions are deleted after inserting the new one, which might imply that only the latest DSL version is kept.
Pagination and Sorting:
The
list_agentssupports pagination with sane defaults and ordering with ascending/descending toggles.
Error Handling:
Uses utility functions like
get_json_result,get_data_error_result, andget_error_data_resultto unify response formats.Returns meaningful messages for missing or invalid parameters and unauthorized operations.
ID Generation:
New agents receive an ID generated by
get_uuid()ensuring uniqueness.
Interaction with Other System Components
UserCanvasService: Core service responsible for querying, saving, updating, and deleting agent (canvas) data tied to users.
UserCanvasVersionService: Maintains version history of agent DSLs. It is used here to insert new versions and delete old versions on update.
Utility Modules:
api.utils.api_utilsprovides decorators and response helpers such astoken_requiredand result formatting functions.api.settings.RetCodedefines return codes used in API responses.
Flask Request Handling: The file uses Flask's
requestobject to parse incoming HTTP query parameters and JSON bodies.
This module is likely part of a larger backend API providing user-specific, version-controlled canvas/agent management within the InfiniFlow system.
Visual Diagram
classDiagram
class AgentAPI {
+list_agents(tenant_id)
+create_agent(tenant_id)
+update_agent(tenant_id, agent_id)
+delete_agent(tenant_id, agent_id)
}
class UserCanvasService {
+query(**kwargs)
+get_list(tenant_id, page, size, orderby, desc, id, title)
+save(**kwargs)
+update_by_id(agent_id, data)
+delete_by_id(agent_id)
}
class UserCanvasVersionService {
+insert(user_canvas_id, title, dsl)
+delete_all_versions(user_canvas_id)
}
AgentAPI ..> UserCanvasService : uses
AgentAPI ..> UserCanvasVersionService : uses
Summary
The agent.py file implements a set of REST API endpoints managing the lifecycle of "agents" (user canvases) with support for DSL versioning, ownership enforcement, and pagination. It acts as a controller layer interfacing between HTTP requests and underlying database service layers, ensuring data integrity and secure multi-tenant access.
This module is a crucial part of the InfiniFlow backend, enabling users to create, view, update, and delete their agents while maintaining version control over the agent DSL configurations.