{
    "schemes": [
        "https",
        "http"
    ],
    "swagger": "2.0",
    "info": {
        "description": "Business consumer surface of the Flyto Agent Engine: run agents, manage sessions, stream events via SSE, reply to permission prompts, list tools. Observation surface (SafetyChain verdicts / breaker states / health probes) lives on a separate gRPC :9090 + admin HTTP :8081 channel -- see ADR-0002 for the REST/observation bifurcation.",
        "title": "Flyto Agent Engine Business REST API",
        "termsOfService": "https://flytoex.net/terms",
        "contact": {
            "name": "Flyto Agent Platform Team",
            "url": "https://flytoex.net"
        },
        "license": {
            "name": "Proprietary"
        },
        "version": "v1"
    },
    "host": "hub.flytoex.net",
    "basePath": "/api/v1",
    "paths": {
        "/agent/run": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "One-shot Agent run: prompt in, SSE event stream out. Named events are text_delta / text / thinking_delta / thinking / tool_use / tool_result / tool_progress / permission_request / turn_start / turn_end / done / error. Heartbeat \": keepalive\" comment lines fire every 15s. Sessions are not persisted -- use POST /sessions for multi-turn.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "text/event-stream"
                ],
                "tags": [
                    "agent"
                ],
                "summary": "Run agent (one-shot, SSE stream)",
                "parameters": [
                    {
                        "description": "Run request",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/server.RunRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "SSE event stream (text/event-stream)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Server Error",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/health": {
            "get": {
                "description": "Returns server liveness with current UTC timestamp. Allowed without auth and exempt from per-IP rate limit -- liveness probes can hit it freely.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "meta"
                ],
                "summary": "Health probe",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/server.HealthResponse"
                        }
                    }
                }
            }
        },
        "/sessions": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Create a multi-turn session. Body is optional; if session_id is omitted the server generates one (sess_\u003chex\u003e). Sessions live in memory of the serving instance only -- no horizontal-scale persistence today (see ADR-0002 § 6 / TODO L693).",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "session"
                ],
                "summary": "Create session",
                "parameters": [
                    {
                        "description": "Optional explicit session id",
                        "name": "request",
                        "in": "body",
                        "schema": {
                            "$ref": "#/definitions/server.CreateSessionRequest"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "schema": {
                            "$ref": "#/definitions/server.CreateSessionResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "409": {
                        "description": "Session id already exists",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/sessions/{id}": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the session metadata: created_at and message_count. Does not return the message history.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "session"
                ],
                "summary": "Get session",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Session id",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/server.SessionInfoResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            },
            "delete": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Closes the engine session and removes server-side state. Returns {\"status\":\"deleted\"}.",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "session"
                ],
                "summary": "Delete session",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Session id",
                        "name": "id",
                        "in": "path",
                        "required": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/server.StatusResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/sessions/{id}/messages": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Sends a user prompt into an existing session and returns the engine event stream as SSE. Same event vocabulary as POST /agent/run. Session retains assistant turns; subsequent calls continue the same conversation.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "text/event-stream"
                ],
                "tags": [
                    "session"
                ],
                "summary": "Send message in session (SSE stream)",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Session id",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Message body",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/server.SendMessageRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "SSE event stream (text/event-stream)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "404": {
                        "description": "Not Found",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "500": {
                        "description": "Internal Server Error",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/sessions/{id}/permissions/{request_id}": {
            "post": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Used by the client UI to allow/deny a tool permission prompt that was emitted as the permission_request SSE event during an in-progress run. The request_id matches the id field of that event. Returns {\"status\":\"ok\"}.",
                "consumes": [
                    "application/json"
                ],
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "permission"
                ],
                "summary": "Reply to a permission request",
                "parameters": [
                    {
                        "type": "string",
                        "description": "Session id",
                        "name": "id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "type": "string",
                        "description": "Permission request id (from permission_request SSE event)",
                        "name": "request_id",
                        "in": "path",
                        "required": true
                    },
                    {
                        "description": "Allow/deny + reason",
                        "name": "request",
                        "in": "body",
                        "required": true,
                        "schema": {
                            "$ref": "#/definitions/server.PermissionReplyRequest"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/server.StatusResponse"
                        }
                    },
                    "400": {
                        "description": "Bad Request",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "404": {
                        "description": "No pending permission request matches request_id",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "409": {
                        "description": "Permission request already replied",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        },
        "/tools": {
            "get": {
                "security": [
                    {
                        "BearerAuth": []
                    }
                ],
                "description": "Returns the engine's currently registered tools (post Validator/decorator wraps). Tool surface is set at server boot today; per-request filtering is on the roadmap (see RunRequest.Tools godoc).",
                "produces": [
                    "application/json"
                ],
                "tags": [
                    "tools"
                ],
                "summary": "List available tools",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/server.ListToolsResponse"
                        }
                    },
                    "401": {
                        "description": "Unauthorized",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    },
                    "429": {
                        "description": "Too Many Requests",
                        "schema": {
                            "$ref": "#/definitions/server.ErrorResponse"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "server.CreateSessionRequest": {
            "type": "object",
            "properties": {
                "session_id": {
                    "description": "可选,不提供则自动生成",
                    "type": "string"
                }
            }
        },
        "server.CreateSessionResponse": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "session_id": {
                    "type": "string"
                }
            }
        },
        "server.ErrorDetail": {
            "type": "object",
            "properties": {
                "message": {
                    "type": "string"
                },
                "type": {
                    "type": "string"
                }
            }
        },
        "server.ErrorResponse": {
            "type": "object",
            "properties": {
                "error": {
                    "$ref": "#/definitions/server.ErrorDetail"
                }
            }
        },
        "server.HealthResponse": {
            "type": "object",
            "properties": {
                "status": {
                    "type": "string",
                    "example": "ok"
                },
                "timestamp": {
                    "type": "string",
                    "example": "2026-04-26T12:00:00Z"
                }
            }
        },
        "server.ListToolsResponse": {
            "type": "object",
            "properties": {
                "count": {
                    "type": "integer",
                    "example": 12
                },
                "tools": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/server.ToolInfo"
                    }
                }
            }
        },
        "server.PermissionReplyRequest": {
            "type": "object",
            "properties": {
                "allow": {
                    "type": "boolean"
                },
                "reason": {
                    "type": "string"
                }
            }
        },
        "server.RunRequest": {
            "type": "object",
            "properties": {
                "max_turns": {
                    "type": "integer"
                },
                "model": {
                    "type": "string"
                },
                "prompt": {
                    "type": "string"
                },
                "stream": {
                    "description": "兼容字段,本端点始终 SSE 流式",
                    "type": "boolean"
                },
                "system_prompt": {
                    "type": "string"
                },
                "tools": {
                    "description": "Tools 是本次 Run 允许调用的工具名列表(前端工具选择器传入).\n当前版本接收但暂不覆盖引擎级工具注册--工具可用列表由服务器启动参数决定.\n未来版本将实现 WithToolFilter RunOption 支持按请求筛选工具.\n历史包袱(LEGACY): 当前直接忽略前端传入的 tools,\n改进时需在 engine.buildToolDefs 加 runConfig.allowedTools 过滤.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            }
        },
        "server.SendMessageRequest": {
            "type": "object",
            "properties": {
                "model": {
                    "type": "string"
                },
                "prompt": {
                    "type": "string"
                }
            }
        },
        "server.SessionInfoResponse": {
            "type": "object",
            "properties": {
                "created_at": {
                    "type": "string"
                },
                "message_count": {
                    "type": "integer"
                },
                "session_id": {
                    "type": "string"
                }
            }
        },
        "server.StatusResponse": {
            "type": "object",
            "properties": {
                "status": {
                    "type": "string",
                    "example": "deleted"
                }
            }
        },
        "server.ToolInfo": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "input_schema": {
                    "type": "array",
                    "items": {
                        "type": "integer"
                    }
                },
                "name": {
                    "type": "string"
                }
            }
        }
    },
    "securityDefinitions": {
        "BearerAuth": {
            "description": "OIDC bearer token issued by the platform IdP. cmd/common started with --oidc-issuer requires every request (except GET /api/v1/health and CORS OPTIONS) to carry a valid token. Dev mode (no --oidc-issuer) bypasses auth entirely; production must set it.",
            "type": "apiKey",
            "name": "Authorization",
            "in": "header"
        }
    }
}