From f54d030486b4e630e5384a68903d8bf6f13f786b Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 27 Jul 2025 15:18:54 +0800 Subject: [PATCH] Add Agent API for AI interactions and chat completions - Introduced the Agent API to facilitate AI agent interactions, including chat completions with real-time streaming capabilities. - Implemented endpoints for GET and POST requests to handle chat completions, supporting features like context management and assistant selection. - Updated the README to include comprehensive documentation for the Agent API, detailing its functionalities, key endpoints, and usage examples. - Enhanced the OpenAPI structure to integrate the new agent handlers into the existing routing system, ensuring OAuth protection for all endpoints. --- openapi/README.md | 60 +++++++ openapi/agent/README.md | 337 ++++++++++++++++++++++++++++++++++++++++ openapi/agent/agent.go | 92 +++++++++++ openapi/openapi.go | 4 + 4 files changed, 493 insertions(+) create mode 100644 openapi/agent/README.md diff --git a/openapi/README.md b/openapi/README.md index ae480ed6..7f8c6d6a 100644 --- a/openapi/README.md +++ b/openapi/README.md @@ -271,6 +271,38 @@ The DSL Management API provides: All DSL endpoints require OAuth authentication. +## Agent API + +Comprehensive API for AI agent interactions and chat completions with real-time streaming capabilities. + +**[View Full Agent API Documentation →](agent/README.md)** + +The Agent API provides: + +- **Chat Completions**: AI-powered chat with streaming responses via Server-Sent Events +- **Assistant Selection**: Multiple AI assistants with different capabilities and personalities +- **Context Management**: Persistent chat sessions with conversation history +- **Real-Time Streaming**: Server-Sent Events for immediate response delivery +- **Session Management**: Automatic session handling with user identification +- **Flexible Parameters**: Configurable behavior for different client types and use cases + +**Key Endpoints:** + +- `GET /agent/chat/completions` - Stream chat completions with query parameters +- `POST /agent/chat/completions` - Stream chat completions with form data + +**Features:** + +- **Server-Sent Events**: Real-time streaming responses reduce latency +- **Multi-Assistant Support**: Choose from different AI assistants (`mohe`, `developer`, `analyst`, etc.) +- **Context Awareness**: Conversation history and additional context support +- **Silent Mode**: Configurable verbose/quiet response modes +- **Client Customization**: Client-type specific behavior and formatting + +**Note:** This is a temporary implementation for full-process testing, and the interface may undergo significant global changes in the future. + +All Agent endpoints require OAuth authentication. + ## File Management API Comprehensive API for managing file uploads, downloads, and file operations with support for multiple storage backends. @@ -420,6 +452,34 @@ curl -X POST "/v1/dsl/create/model" \ }' ``` +### AI Agent Chat Interaction + +1. **Start a chat conversation**: + +```bash +curl -X GET "/v1/agent/chat/completions?content=What%20is%20Yao%20framework?" \ + -H "Authorization: Bearer {access_token}" \ + -H "Accept: text/event-stream" +``` + +2. **Continue conversation with context**: + +```bash +curl -X GET "/v1/agent/chat/completions?content=Show%20me%20an%20example&chat_id=chat_123&assistant_id=developer" \ + -H "Authorization: Bearer {access_token}" \ + -H "Accept: text/event-stream" +``` + +3. **Use POST with form data**: + +```bash +curl -X POST "/v1/agent/chat/completions" \ + -H "Authorization: Bearer {access_token}" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -H "Accept: text/event-stream" \ + -d "content=Help me create a user model&silent=true&client_type=api" +``` + ### File Upload and Management 1. **Upload a file with metadata**: diff --git a/openapi/agent/README.md b/openapi/agent/README.md new file mode 100644 index 00000000..8e9641d3 --- /dev/null +++ b/openapi/agent/README.md @@ -0,0 +1,337 @@ +# Agent API + +This document describes the RESTful API for AI agent interactions and chat completions in Yao applications. + +## Base URL + +All endpoints are prefixed with the configured base URL followed by `/agent` (e.g., `/v1/agent`). + +## Authentication + +All endpoints require OAuth authentication via the configured OAuth provider. + +## Overview + +The Agent API provides AI-powered chat completion capabilities with support for: + +- **Server-Sent Events (SSE)** - Real-time streaming responses +- **Context Management** - Persistent chat sessions with history +- **Assistant Selection** - Multiple AI assistants with different capabilities +- **Flexible Parameters** - Configurable behavior for different use cases +- **Session Management** - Automatic session handling with user identification + +## Endpoints + +### Chat Completions + +Create AI chat completions with streaming responses using Server-Sent Events. + +``` +GET /chat/completions?content={content}&chat_id={chat_id}&assistant_id={assistant_id}&context={context}&silent={silent}&history_visible={history_visible}&client_type={client_type} +POST /chat/completions +``` + +**Note:** This is a temporary implementation for full-process testing, and the interface may undergo significant global changes in the future. + +**Query Parameters (GET) / Form Data (POST):** + +- `content` (required): The user's message or question +- `chat_id` (optional): Chat session identifier (auto-generated if not provided) +- `assistant_id` (optional): Specific assistant to use (defaults to system default) +- `context` (optional): Additional context for the conversation +- `silent` (optional): Silent mode flag ("true"/"false" or "1"/"0") +- `history_visible` (optional): Whether chat history is visible ("true"/"false" or "1"/"0") +- `client_type` (optional): Client type identifier for customization + +**Headers:** + +``` +Authorization: Bearer {access_token} +``` + +**Response Headers:** + +``` +Content-Type: text/event-stream;charset=utf-8 +Cache-Control: no-cache +Connection: keep-alive +``` + +**Example GET Request:** + +```bash +curl -X GET "/v1/agent/chat/completions?content=Hello%2C%20how%20are%20you%3F&chat_id=chat_123&assistant_id=mohe" \ + -H "Authorization: Bearer {token}" \ + -H "Accept: text/event-stream" +``` + +**Example POST Request:** + +```bash +curl -X POST "/v1/agent/chat/completions" \ + -H "Authorization: Bearer {token}" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -H "Accept: text/event-stream" \ + -d "content=Hello, how are you?&chat_id=chat_123&assistant_id=mohe" +``` + +**Response (Server-Sent Events):** + +The response is streamed as Server-Sent Events with the following format: + +``` +data: {"type":"message","content":"Hello! I'm doing well, thank you for asking.","role":"assistant","timestamp":1640995200} + +data: {"type":"done","chat_id":"chat_123","session_id":"session_456"} +``` + +**Response Data Types:** + +- `message` - Content chunk from the AI assistant +- `error` - Error message if something goes wrong +- `done` - Indicates completion of the response + +**Success Response Example:** + +```json +{ + "type": "message", + "content": "Hello! I'm an AI assistant created by Yao. How can I help you today?", + "role": "assistant", + "chat_id": "chat_123", + "timestamp": 1640995200 +} +``` + +**Completion Response:** + +```json +{ + "type": "done", + "chat_id": "chat_123", + "session_id": "session_456" +} +``` + +## Parameters in Detail + +### Content Parameter + +The `content` parameter is the main user input: + +- **Required** for all requests +- Can be a question, command, or conversation message +- Supports natural language input +- Maximum length depends on assistant configuration + +### Chat ID Management + +The `chat_id` parameter manages conversation continuity: + +- **Auto-generated** if not provided (format: `chat_{timestamp}`) +- **Persistent** across multiple requests for the same conversation +- **Unique** identifier for each chat session +- Used for conversation history and context management + +### Assistant Selection + +The `assistant_id` parameter allows choosing specific AI assistants: + +- **Optional** - defaults to system default assistant +- **Different assistants** may have different capabilities, knowledge bases, or personalities +- **Examples**: `mohe`, `developer`, `analyst` + +### Context and Behavior + +Additional parameters for fine-tuning behavior: + +- `context` - Provides additional context for better responses +- `silent` - Controls verbose/quiet response modes +- `history_visible` - Controls whether conversation history affects responses +- `client_type` - Allows client-specific customizations + +## Error Responses + +All endpoints return standardized error responses via Server-Sent Events: + +``` +data: {"type":"error","error":"invalid_request","error_description":"content is required"} +``` + +**Common Error Types:** + +- `invalid_request` - Missing required parameters +- `unauthorized` - Authentication failure +- `assistant_not_found` - Invalid assistant ID +- `internal_error` - Server processing error + +**HTTP Status Codes:** + +- `200` - Success (streaming response) +- `400` - Bad Request (missing content parameter) +- `401` - Unauthorized (authentication required) +- `500` - Internal Server Error + +## Session Management + +The Agent API automatically manages sessions: + +### Session Creation + +- **Automatic** session creation when `__sid` is not present +- **UUID generation** for new sessions +- **Session persistence** across requests + +### Session Context + +- **User identification** through session data +- **Conversation history** maintained per chat_id +- **Context preservation** between messages + +## Real-Time Streaming + +The API uses Server-Sent Events for real-time communication: + +### Connection Management + +- **Keep-alive** connections for streaming +- **Automatic reconnection** support +- **Graceful error handling** + +### Event Types + +- **message** - Streaming content chunks +- **error** - Error notifications +- **done** - Completion indicators + +## Example Workflows + +### Simple Chat Interaction + +1. **Start a conversation:** + +```bash +curl -X GET "/v1/agent/chat/completions?content=What%20is%20Yao?" \ + -H "Authorization: Bearer {token}" \ + -H "Accept: text/event-stream" +``` + +2. **Continue the conversation:** + +```bash +curl -X GET "/v1/agent/chat/completions?content=Tell%20me%20more%20about%20its%20features&chat_id=chat_123" \ + -H "Authorization: Bearer {token}" \ + -H "Accept: text/event-stream" +``` + +### Assistant-Specific Interaction + +1. **Use a specific assistant:** + +```bash +curl -X POST "/v1/agent/chat/completions" \ + -H "Authorization: Bearer {token}" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -H "Accept: text/event-stream" \ + -d "content=Help me debug this code&assistant_id=developer&chat_id=debug_session_456" +``` + +### Context-Aware Conversation + +1. **Provide additional context:** + +```bash +curl -X GET "/v1/agent/chat/completions?content=Optimize%20this%20query&context=PostgreSQL%20database%20with%20large%20user%20table&assistant_id=analyst" \ + -H "Authorization: Bearer {token}" \ + -H "Accept: text/event-stream" +``` + +### Silent Mode Operation + +1. **Use silent mode for concise responses:** + +```bash +curl -X GET "/v1/agent/chat/completions?content=Generate%20user%20model&silent=true&client_type=api" \ + -H "Authorization: Bearer {token}" \ + -H "Accept: text/event-stream" +``` + +## JavaScript Client Example + +Here's how to consume the streaming API in JavaScript: + +```javascript +const eventSource = new EventSource( + "/v1/agent/chat/completions?content=Hello&chat_id=chat_123", + { + headers: { + Authorization: "Bearer " + accessToken, + }, + } +); + +eventSource.onmessage = function (event) { + const data = JSON.parse(event.data); + + switch (data.type) { + case "message": + console.log("Assistant:", data.content); + break; + case "error": + console.error("Error:", data.error_description); + break; + case "done": + console.log("Conversation completed"); + eventSource.close(); + break; + } +}; + +eventSource.onerror = function (error) { + console.error("Connection error:", error); +}; +``` + +## Integration Considerations + +### Performance + +- **Streaming responses** reduce perceived latency +- **Connection pooling** for multiple concurrent chats +- **Automatic session cleanup** prevents memory leaks + +### Security + +- **OAuth 2.1 authentication** required for all requests +- **Session-based access control** +- **Input validation** and sanitization +- **Rate limiting** (configured at server level) + +### Scalability + +- **Stateless design** (session data in external store) +- **Load balancer compatible** (sticky sessions not required) +- **Horizontal scaling** support + +## Development Notes + +**Important:** This is a temporary implementation for full-process testing. The interface design and functionality may undergo significant global changes in future versions. Consider this API experimental and subject to breaking changes. + +### Current Limitations + +- Limited error recovery mechanisms +- Basic assistant selection logic +- Simplified context management +- Minimal response formatting options + +### Future Enhancements + +Future versions may include: + +- Enhanced context management +- Advanced assistant capabilities +- Improved error handling +- Extended parameter options +- WebSocket support as alternative to SSE + +This Agent API provides a foundation for AI-powered interactions in Yao applications with real-time streaming capabilities and flexible configuration options. diff --git a/openapi/agent/agent.go b/openapi/agent/agent.go index 48831554..3603c587 100644 --- a/openapi/agent/agent.go +++ b/openapi/agent/agent.go @@ -1 +1,93 @@ package agent + +import ( + "fmt" + "time" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/yaoapp/yao/neo" + chatctx "github.com/yaoapp/yao/neo/context" + "github.com/yaoapp/yao/neo/message" + "github.com/yaoapp/yao/openapi/oauth/types" +) + +// Attach attaches the agent handlers to the router +func Attach(group *gin.RouterGroup, oauth types.OAuth) { + + // Protect all endpoints with OAuth + group.Use(oauth.Guard) + + // Chat Completion + group.GET("/chat/completions", chatCompletion) + group.POST("/chat/completions", chatCompletion) + +} + +// Chat Completion (SSE) +// Note: This is a temporary implementation for full-process testing, +// and the interface may undergo significant global changes in the future. +func chatCompletion(c *gin.Context) { + // Set headers for SSE + c.Header("Content-Type", "text/event-stream;charset=utf-8") + c.Header("Cache-Control", "no-cache") + c.Header("Connection", "keep-alive") + + sid := c.GetString("__sid") + if sid == "" { + sid = uuid.New().String() + } + + content := c.Query("content") + if content == "" { + msg := message.New().Error("content is required").Done() + msg.Write(c.Writer) + return + } + + chatID := c.Query("chat_id") + if chatID == "" { + // Only generate new chat_id if not provided + chatID = fmt.Sprintf("chat_%d", time.Now().UnixNano()) + } + + // Set the context with validated chat_id + ctx, cancel := chatctx.NewWithCancel(sid, chatID, c.Query("context")) + defer cancel() + defer ctx.Release() // Release the context after the request is done + + // Set the assistant ID + assistantID := c.Query("assistant_id") + if assistantID != "" { + ctx = chatctx.WithAssistantID(ctx, assistantID) + } + + // Set the silent mode + silent := c.Query("silent") + if silent == "true" || silent == "1" { + ctx = chatctx.WithSilent(ctx, true) + } + + // Set the history visible + historyVisible := c.Query("history_visible") + if historyVisible != "" { + ctx = chatctx.WithHistoryVisible(ctx, historyVisible == "true" || historyVisible == "1") + } + + // Set the client type + clientType := c.Query("client_type") + if clientType != "" { + ctx = chatctx.WithClientType(ctx, clientType) + } + + // Get neo instance and call Answer + neoInstance := neo.GetNeo() + err := neoInstance.Answer(ctx, content, c) + + // Error handling + if err != nil { + message.New().Done().Error(err).Write(c.Writer) + c.Done() + return + } +} diff --git a/openapi/openapi.go b/openapi/openapi.go index eda203ee..81cf94e8 100644 --- a/openapi/openapi.go +++ b/openapi/openapi.go @@ -6,6 +6,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yaoapp/gou/application" "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/openapi/agent" "github.com/yaoapp/yao/openapi/dsl" "github.com/yaoapp/yao/openapi/file" "github.com/yaoapp/yao/openapi/hello" @@ -86,5 +87,8 @@ func (openapi *OpenAPI) Attach(router *gin.Engine) { // Knowledge Base handlers kb.Attach(group.Group("/kb"), openapi.OAuth) + // Agent handlers + agent.Attach(group.Group("/agent"), openapi.OAuth) + // Custom handlers (Defined by developer) }