⚠️ BREAKING: Removed the Studio package and renamed Neo to Agent. Configuration file path changed from neo/neo.yml to agent/agent.yml.
Remove deprecated studio package and refactor agent integration - Deleted the studio package, which is no longer in use, to streamline the codebase. - Updated references in the agent and chat modules to utilize the new agent package instead of the deprecated neo package. - Ensured that all related middleware and routing functionalities are now aligned with the agent architecture, enhancing overall system coherence.
This commit is contained in:
parent
0b88fb6098
commit
c54ef71d6a
58 changed files with 537 additions and 1413 deletions
|
|
@ -1,12 +1,12 @@
|
|||
# Neo API Documentation
|
||||
# Agent API Documentation
|
||||
|
||||
Neo is a chat/AI assistant API that provides endpoints for managing conversations, assistants, file uploads, and more.
|
||||
Agent is a chat/AI assistant API that provides endpoints for managing conversations, assistants, file uploads, and more.
|
||||
|
||||
## Base URL
|
||||
|
||||
All endpoints are relative to your base URL + `/api/__yao/neo`
|
||||
All endpoints are relative to your base URL + `/api/__yao/agent`
|
||||
|
||||
Example: `http://localhost:5099/api/__yao/neo`
|
||||
Example: `http://localhost:5099/api/__yao/agent`
|
||||
|
||||
## Authentication
|
||||
|
||||
|
|
@ -46,10 +46,10 @@ Start or continue a conversation with an AI assistant.
|
|||
|
||||
```bash
|
||||
# GET request
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo?content=Hello&chat_id=chat_123&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent?content=Hello&chat_id=chat_123&token=xxx'
|
||||
|
||||
# POST request
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"content": "Hello", "chat_id": "chat_123", "token": "xxx"}'
|
||||
```
|
||||
|
|
@ -70,7 +70,7 @@ Get conversation history for a specific chat.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/history?chat_id=chat_123&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/history?chat_id=chat_123&token=xxx'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
|
@ -111,7 +111,7 @@ Get a paginated list of chat conversations.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/chats?page=1&pagesize=20&keywords=search+term&order=desc&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/chats?page=1&pagesize=20&keywords=search+term&order=desc&token=xxx'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
|
@ -152,7 +152,7 @@ Get the most recent chat or create a new one if none exists.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/chats/latest?assistant_id=assistant_123&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/chats/latest?assistant_id=assistant_123&token=xxx'
|
||||
```
|
||||
|
||||
#### 2.3 Get Chat Details
|
||||
|
|
@ -168,7 +168,7 @@ Get detailed information about a specific chat.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/chats/chat_123?token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/chats/chat_123?token=xxx'
|
||||
```
|
||||
|
||||
#### 2.4 Update Chat
|
||||
|
|
@ -189,7 +189,7 @@ Update chat metadata (e.g., title).
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/chats/chat_123' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/chats/chat_123' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"title": "New Title", "content": "Chat content", "token": "xxx"}'
|
||||
```
|
||||
|
|
@ -203,7 +203,7 @@ Delete a specific chat conversation.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/neo/chats/chat_123?token=xxx'
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/agent/chats/chat_123?token=xxx'
|
||||
```
|
||||
|
||||
### 3. Assistant Management
|
||||
|
|
@ -231,7 +231,7 @@ Get a paginated list of available assistants.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/assistants?page=1&pagesize=20&tags=tag1,tag2&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/assistants?page=1&pagesize=20&tags=tag1,tag2&token=xxx'
|
||||
```
|
||||
|
||||
#### 3.2 Get Assistant Tags
|
||||
|
|
@ -247,7 +247,7 @@ Get all available assistant tags.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/assistants/tags?token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/assistants/tags?token=xxx'
|
||||
```
|
||||
|
||||
#### 3.3 Get Assistant Details
|
||||
|
|
@ -263,7 +263,7 @@ Get detailed information about a specific assistant.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/assistants/assistant_123?token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/assistants/assistant_123?token=xxx'
|
||||
```
|
||||
|
||||
#### 3.4 Execute Assistant API
|
||||
|
|
@ -287,7 +287,7 @@ Call a specific assistant's API functionality.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/assistants/assistant_123/call' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/assistants/assistant_123/call' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"name": "Test", "payload": {"name": "yao", "age": 18}}'
|
||||
```
|
||||
|
|
@ -313,7 +313,7 @@ Create a new assistant or update an existing one.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/assistants' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/assistants' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"name": "My Assistant", "type": "chat", "tags": ["tag1"], "token": "xxx"}'
|
||||
```
|
||||
|
|
@ -327,7 +327,7 @@ Delete a specific assistant.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/neo/assistants/assistant_123?token=xxx'
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/agent/assistants/assistant_123?token=xxx'
|
||||
```
|
||||
|
||||
### 4. File Management
|
||||
|
|
@ -355,7 +355,7 @@ Upload files to different storage types.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/upload/chat?chat_id=chat_123&token=xxx' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/upload/chat?chat_id=chat_123&token=xxx' \
|
||||
-F 'file=@/path/to/file.txt'
|
||||
```
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ Download a previously uploaded file.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/download?file_id=file_123&disposition=attachment&token=xxx' \
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/download?file_id=file_123&disposition=attachment&token=xxx' \
|
||||
-o downloaded_file.txt
|
||||
```
|
||||
|
||||
|
|
@ -406,7 +406,7 @@ Get mentionable assistants for autocomplete.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/mentions?keywords=assistant&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/mentions?keywords=assistant&token=xxx'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
|
@ -445,10 +445,10 @@ Generate a title for chat content.
|
|||
|
||||
```bash
|
||||
# GET request
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/generate/title?content=Chat+content&chat_id=chat_123&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/generate/title?content=Chat+content&chat_id=chat_123&token=xxx'
|
||||
|
||||
# POST request
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/generate/title' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/generate/title' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"content": "Chat content", "chat_id": "chat_123", "token": "xxx"}'
|
||||
```
|
||||
|
|
@ -474,10 +474,10 @@ Generate prompts based on content.
|
|||
|
||||
```bash
|
||||
# GET request
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/generate/prompts?content=Generate+prompts&chat_id=chat_123&token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/generate/prompts?content=Generate+prompts&chat_id=chat_123&token=xxx'
|
||||
|
||||
# POST request
|
||||
curl -X POST 'http://localhost:5099/api/__yao/neo/generate/prompts' \
|
||||
curl -X POST 'http://localhost:5099/api/__yao/agent/generate/prompts' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"content": "Generate prompts", "chat_id": "chat_123", "token": "xxx"}'
|
||||
```
|
||||
|
|
@ -495,7 +495,7 @@ Get available AI connectors.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/utility/connectors?token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/utility/connectors?token=xxx'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
|
@ -524,7 +524,7 @@ Check API service status.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X GET 'http://localhost:5099/api/__yao/neo/status?token=xxx'
|
||||
curl -X GET 'http://localhost:5099/api/__yao/agent/status?token=xxx'
|
||||
```
|
||||
|
||||
**Response:** HTTP 200 status code
|
||||
|
|
@ -540,7 +540,7 @@ Delete all chat conversations for the authenticated user.
|
|||
**Example:**
|
||||
|
||||
```bash
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/neo/dangerous/clear_chats?token=xxx'
|
||||
curl -X DELETE 'http://localhost:5099/api/__yao/agent/dangerous/clear_chats?token=xxx'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
61
agent/agent.go
Normal file
61
agent/agent.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/session"
|
||||
"github.com/yaoapp/yao/agent/assistant"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
)
|
||||
|
||||
// Answer reply the message
|
||||
func (agent *DSL) Answer(ctx chatctx.Context, question string, c *gin.Context) error {
|
||||
var err error
|
||||
var ast assistant.API = Agent.Assistant
|
||||
if ctx.AssistantID != "" {
|
||||
ast, err = agent.Select(ctx.AssistantID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = ast.Execute(c, ctx, question, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// Select select an assistant
|
||||
func (agent *DSL) Select(id string) (assistant.API, error) {
|
||||
if id == "" {
|
||||
return Agent.Assistant, nil
|
||||
}
|
||||
return assistant.Get(id)
|
||||
}
|
||||
|
||||
// UserID get the user id from the session
|
||||
func (agent *DSL) UserID(sid string) (interface{}, error) {
|
||||
fieldID := agent.AuthSetting.SessionFields.ID
|
||||
return session.Global().ID(sid).Get(fieldID)
|
||||
}
|
||||
|
||||
// GuestID get the guest id from the session
|
||||
func (agent *DSL) GuestID(sid string) (interface{}, error) {
|
||||
fieldGuest := agent.AuthSetting.SessionFields.Guest
|
||||
return session.Global().ID(sid).Get(fieldGuest)
|
||||
}
|
||||
|
||||
// UserRoles get the user roles from the session
|
||||
func (agent *DSL) UserRoles(sid string) (interface{}, error) {
|
||||
fieldRoles := agent.AuthSetting.SessionFields.Roles
|
||||
return session.Global().ID(sid).Get(fieldRoles)
|
||||
}
|
||||
|
||||
// UserOrGuestID get the user id or guest id from the session
|
||||
func (agent *DSL) UserOrGuestID(sid string) (interface{}, bool, error) {
|
||||
userID, err := agent.UserID(sid)
|
||||
if err != nil {
|
||||
guestID, err := agent.GuestID(sid)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return guestID, true, nil
|
||||
}
|
||||
return userID, false, nil
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
// type customResponseRecorder struct {
|
||||
// *httptest.ResponseRecorder
|
||||
|
|
@ -21,7 +21,7 @@ package neo
|
|||
// defer Test_clean(t)
|
||||
|
||||
// resetDB()
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// Prompts: []Prompt{
|
||||
// {Role: "system", Content: "You are a helpful assistant", Name: "ai"},
|
||||
// {Role: "user", Content: "Hello", Name: "user"},
|
||||
|
|
@ -31,10 +31,10 @@ package neo
|
|||
// Table: "chat_messages",
|
||||
// },
|
||||
// }
|
||||
// err := neo.newConversation()
|
||||
// err := agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// prompts := neo.prompts()
|
||||
// prompts := agent.prompts()
|
||||
// assert.Equal(t, 2, len(prompts))
|
||||
// assert.Equal(t, "system", prompts[0]["role"])
|
||||
// assert.Equal(t, "You are a helpful assistant", prompts[0]["content"])
|
||||
|
|
@ -46,7 +46,7 @@ package neo
|
|||
// defer Test_clean(t)
|
||||
|
||||
// resetDB()
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// Prompts: []Prompt{
|
||||
// {Role: "system", Content: "You are a helpful assistant"},
|
||||
// },
|
||||
|
|
@ -56,7 +56,7 @@ package neo
|
|||
// },
|
||||
// }
|
||||
|
||||
// err := neo.newConversation()
|
||||
// err := agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// ctx := Context{
|
||||
|
|
@ -64,7 +64,7 @@ package neo
|
|||
// ChatID: "test-chat",
|
||||
// }
|
||||
|
||||
// messages, err := neo.chatMessages(ctx, "Hello AI")
|
||||
// messages, err := agent.chatMessages(ctx, "Hello AI")
|
||||
// assert.NoError(t, err)
|
||||
// assert.Equal(t, 2, len(messages))
|
||||
// assert.Equal(t, "system", messages[0]["role"])
|
||||
|
|
@ -87,7 +87,7 @@ package neo
|
|||
// }
|
||||
|
||||
// resetDB()
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// Connector: "gpt-3_5-turbo",
|
||||
// Option: map[string]interface{}{
|
||||
// "temperature": 0.7,
|
||||
|
|
@ -102,17 +102,17 @@ package neo
|
|||
// },
|
||||
// }
|
||||
|
||||
// err := neo.newAI()
|
||||
// err := agent.newAI()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// err = neo.newConversation()
|
||||
// err = agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// c.Request = httptest.NewRequest("POST", "/chat", nil)
|
||||
|
||||
// neo.AI = &mockAI{}
|
||||
// agent.AI = &mockAI{}
|
||||
|
||||
// err = neo.Answer(ctx, "Hello AI", c)
|
||||
// err = agent.Answer(ctx, "Hello AI", c)
|
||||
// assert.NoError(t, err)
|
||||
// }
|
||||
|
||||
|
|
@ -144,13 +144,13 @@ package neo
|
|||
|
||||
// // for _, tt := range tests {
|
||||
// // t.Run(tt.name, func(t *testing.T) {
|
||||
// // neo := &DSL{
|
||||
// // agent := &DSL{
|
||||
// // Connector: tt.connector,
|
||||
// // }
|
||||
// // neo.newConversation()
|
||||
// // agent.newConversation()
|
||||
|
||||
// // assert.Panics(t, func() {
|
||||
// // neo.newAI()
|
||||
// // agent.newAI()
|
||||
// // })
|
||||
|
||||
// // })
|
||||
|
|
@ -162,22 +162,22 @@ package neo
|
|||
// defer Test_clean(t)
|
||||
|
||||
// resetDB()
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// ConversationSetting: conversation.Setting{
|
||||
// Connector: "default",
|
||||
// Table: "chat_messages",
|
||||
// },
|
||||
// }
|
||||
|
||||
// err := neo.newConversation()
|
||||
// err := agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// err = neo.Select("invalid-model")
|
||||
// err = agent.Select("invalid-model")
|
||||
// assert.Error(t, err)
|
||||
|
||||
// // err = neo.Select("gpt-3_5-turbo")
|
||||
// // err = agent.Select("gpt-3_5-turbo")
|
||||
// // assert.NoError(t, err)
|
||||
// // assert.NotNil(t, neo.AI)
|
||||
// // assert.NotNil(t, agent.AI)
|
||||
|
||||
// }
|
||||
|
||||
|
|
@ -209,13 +209,13 @@ package neo
|
|||
|
||||
// // for _, tt := range tests {
|
||||
// // t.Run(tt.name, func(t *testing.T) {
|
||||
// // neo := &DSL{
|
||||
// // agent := &DSL{
|
||||
// // ConversationSetting: conversation.Setting{
|
||||
// // Connector: tt.connector,
|
||||
// // },
|
||||
// // }
|
||||
// // assert.Panics(t, func() {
|
||||
// // neo.newConversation()
|
||||
// // agent.newConversation()
|
||||
// // })
|
||||
// // })
|
||||
// // }
|
||||
|
|
@ -225,7 +225,7 @@ package neo
|
|||
// test.Prepare(t, config.Conf)
|
||||
// defer Test_clean(t)
|
||||
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// ConversationSetting: conversation.Setting{
|
||||
// Connector: "default",
|
||||
// Table: "chat_messages",
|
||||
|
|
@ -233,7 +233,7 @@ package neo
|
|||
// }
|
||||
|
||||
// resetDB()
|
||||
// err := neo.newConversation()
|
||||
// err := agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
|
||||
// messages := []map[string]interface{}{
|
||||
|
|
@ -245,10 +245,10 @@ package neo
|
|||
// }
|
||||
|
||||
// content := []byte("Hi there!")
|
||||
// neo.saveHistory("test-session", "test-chat", content, messages)
|
||||
// agent.saveHistory("test-session", "test-chat", content, messages)
|
||||
|
||||
// // Verify the history was saved
|
||||
// history, err := neo.Conversation.GetHistory("test-session", "test-chat")
|
||||
// history, err := agent.Conversation.GetHistory("test-session", "test-chat")
|
||||
// assert.NoError(t, err)
|
||||
// assert.NotEmpty(t, history)
|
||||
// }
|
||||
|
|
@ -262,14 +262,14 @@ package neo
|
|||
// c, _ := gin.CreateTestContext(w)
|
||||
|
||||
// resetDB()
|
||||
// neo := &DSL{
|
||||
// agent := &DSL{
|
||||
// ConversationSetting: conversation.Setting{
|
||||
// Connector: "default",
|
||||
// Table: "chat_messages",
|
||||
// },
|
||||
// }
|
||||
|
||||
// err := neo.newConversation()
|
||||
// err := agent.newConversation()
|
||||
// assert.NoError(t, err)
|
||||
// ctx := Context{
|
||||
// Sid: "test-session",
|
||||
|
|
@ -284,7 +284,7 @@ package neo
|
|||
// }
|
||||
// content := []byte("Test content")
|
||||
|
||||
// err = neo.send(ctx, msg, messages, content, c)
|
||||
// err = agent.send(ctx, msg, messages, content, c)
|
||||
// assert.NoError(t, err)
|
||||
// }
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -14,172 +14,172 @@ import (
|
|||
"github.com/yaoapp/gou/api"
|
||||
"github.com/yaoapp/gou/connector"
|
||||
"github.com/yaoapp/gou/process"
|
||||
"github.com/yaoapp/yao/agent/assistant"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
"github.com/yaoapp/yao/attachment"
|
||||
"github.com/yaoapp/yao/helper"
|
||||
"github.com/yaoapp/yao/neo/assistant"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
"github.com/yaoapp/yao/openapi/oauth"
|
||||
)
|
||||
|
||||
// API registers the Neo API endpoints
|
||||
func (neo *DSL) API(router *gin.Engine, path string) error {
|
||||
// API registers the Agent API endpoints
|
||||
func (agent *DSL) API(router *gin.Engine, path string) error {
|
||||
|
||||
// Get the guards
|
||||
middlewares, err := neo.getGuardHandlers()
|
||||
middlewares, err := agent.getGuardHandlers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Register OPTIONS handlers for all endpoints
|
||||
router.OPTIONS(path, neo.optionsHandler)
|
||||
router.OPTIONS(path+"/status", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/chats", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/chats/:id", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/history", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/upload/:storage", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/download", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/mentions", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/generate", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/generate/title", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/generate/prompts", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/dangerous/clear_chats", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants/:id", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants/:id/call", neo.optionsHandler)
|
||||
router.OPTIONS(path, agent.optionsHandler)
|
||||
router.OPTIONS(path+"/status", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/chats", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/chats/:id", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/history", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/upload/:storage", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/download", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/mentions", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/generate", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/generate/title", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/generate/prompts", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/dangerous/clear_chats", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants/:id", agent.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants/:id/call", agent.optionsHandler)
|
||||
|
||||
// Chat endpoint
|
||||
// Chat endpoint
|
||||
// Example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo?content=Hello&chat_id=chat_123&context=previous_context&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo' \
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent?content=Hello&chat_id=chat_123&context=previous_context&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"content": "Hello", "chat_id": "chat_123", "context": "previous_context", "token": "xxx"}'
|
||||
router.GET(path, append(middlewares, neo.handleChat)...)
|
||||
router.POST(path, append(middlewares, neo.handleChat)...)
|
||||
router.GET(path, append(middlewares, agent.handleChat)...)
|
||||
router.POST(path, append(middlewares, agent.handleChat)...)
|
||||
|
||||
// Status check endpoint
|
||||
// Example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/status?token=xxx'
|
||||
router.GET(path+"/status", append(middlewares, neo.handleStatus)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/status?token=xxx'
|
||||
router.GET(path+"/status", append(middlewares, agent.handleStatus)...)
|
||||
|
||||
// Assistant API endpoints
|
||||
// List assistants example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/assistants?page=1&pagesize=20&tags=tag1,tag2&token=xxx'
|
||||
router.GET(path+"/assistants", append(middlewares, neo.HandleAssistantList)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/assistants?page=1&pagesize=20&tags=tag1,tag2&token=xxx'
|
||||
router.GET(path+"/assistants", append(middlewares, agent.HandleAssistantList)...)
|
||||
// Get all assistant tags example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/assistants/tags?token=xxx'
|
||||
router.GET(path+"/assistants/tags", append(middlewares, neo.HandleAssistantTags)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/assistants/tags?token=xxx'
|
||||
router.GET(path+"/assistants/tags", append(middlewares, agent.HandleAssistantTags)...)
|
||||
|
||||
// Get assistant details example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/assistants/assistant_123?token=xxx'
|
||||
router.GET(path+"/assistants/:id", append(middlewares, neo.HandleAssistantDetail)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/assistants/assistant_123?token=xxx'
|
||||
router.GET(path+"/assistants/:id", append(middlewares, agent.HandleAssistantDetail)...)
|
||||
|
||||
// Execute assistant API example:
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/assistants/assistant_123/api' \
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/assistants/assistant_123/api' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"name": "Test", "payload": {"name": "yao", "age": 18}}'
|
||||
router.POST(path+"/assistants/:id/call", append(middlewares, neo.HandleAssistantCall)...)
|
||||
router.POST(path+"/assistants/:id/call", append(middlewares, agent.HandleAssistantCall)...)
|
||||
|
||||
// Create/Update assistant example:
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/assistants' \
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/assistants' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"name": "My Assistant", "type": "chat", "tags": ["tag1", "tag2"], "mentionable": true, "avatar": "path/to/avatar.png", "token": "xxx"}'
|
||||
router.POST(path+"/assistants", append(middlewares, neo.HandleAssistantSave)...)
|
||||
router.POST(path+"/assistants", append(middlewares, agent.HandleAssistantSave)...)
|
||||
|
||||
// Delete assistant example:
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/neo/assistants/assistant_123?token=xxx'
|
||||
router.DELETE(path+"/assistants/:id", append(middlewares, neo.HandleAssistantDelete)...)
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/agent/assistants/assistant_123?token=xxx'
|
||||
router.DELETE(path+"/assistants/:id", append(middlewares, agent.HandleAssistantDelete)...)
|
||||
|
||||
// Chat management endpoints
|
||||
// List chats example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/chats?page=1&pagesize=20&keywords=search+term&order=desc&token=xxx'
|
||||
router.GET(path+"/chats", append(middlewares, neo.handleChatList)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/chats?page=1&pagesize=20&keywords=search+term&order=desc&token=xxx'
|
||||
router.GET(path+"/chats", append(middlewares, agent.handleChatList)...)
|
||||
|
||||
// Get latest chat example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/chats/latest?assistant_id=assistant_123&token=xxx'
|
||||
router.GET(path+"/chats/latest", append(middlewares, neo.handleChatLatest)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/chats/latest?assistant_id=assistant_123&token=xxx'
|
||||
router.GET(path+"/chats/latest", append(middlewares, agent.handleChatLatest)...)
|
||||
|
||||
// Get chat details example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/chats/chat_123?token=xxx'
|
||||
router.GET(path+"/chats/:id", append(middlewares, neo.handleChatDetail)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/chats/chat_123?token=xxx'
|
||||
router.GET(path+"/chats/:id", append(middlewares, agent.handleChatDetail)...)
|
||||
|
||||
// Update chat example:
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/chats/chat_123' \
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/chats/chat_123' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"title": "New Title", "content": "Chat content for title generation", "token": "xxx"}'
|
||||
router.POST(path+"/chats/:id", append(middlewares, neo.handleChatUpdate)...)
|
||||
router.POST(path+"/chats/:id", append(middlewares, agent.handleChatUpdate)...)
|
||||
|
||||
// Delete chat example:
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/neo/chats/chat_123?token=xxx'
|
||||
router.DELETE(path+"/chats/:id", append(middlewares, neo.handleChatDelete)...)
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/agent/chats/chat_123?token=xxx'
|
||||
router.DELETE(path+"/chats/:id", append(middlewares, agent.handleChatDelete)...)
|
||||
|
||||
// Chat history endpoint
|
||||
// Example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/history?chat_id=chat_123&token=xxx'
|
||||
router.GET(path+"/history", append(middlewares, neo.handleChatHistory)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/history?chat_id=chat_123&token=xxx'
|
||||
router.GET(path+"/history", append(middlewares, agent.handleChatHistory)...)
|
||||
|
||||
// File management endpoints
|
||||
// Upload file example:
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/upload?chat_id=chat_123&token=xxx' \
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/upload?chat_id=chat_123&token=xxx' \
|
||||
// -F 'file=@/path/to/file.txt'
|
||||
router.POST(path+"/upload/:storage", append(middlewares, neo.handleUpload)...)
|
||||
router.POST(path+"/upload/:storage", append(middlewares, agent.handleUpload)...)
|
||||
|
||||
// Download file example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/download?file_id=file_123&disposition=attachment&token=xxx' \
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/download?file_id=file_123&disposition=attachment&token=xxx' \
|
||||
// -o downloaded_file.txt
|
||||
router.GET(path+"/download", append(middlewares, neo.handleDownload)...)
|
||||
router.GET(path+"/download", append(middlewares, agent.handleDownload)...)
|
||||
|
||||
// Mentions endpoint
|
||||
// Example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/mentions?keywords=assistant&token=xxx'
|
||||
router.GET(path+"/mentions", append(middlewares, neo.handleMentions)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/mentions?keywords=assistant&token=xxx'
|
||||
router.GET(path+"/mentions", append(middlewares, agent.handleMentions)...)
|
||||
|
||||
// Generate title example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/generate/title?content=Chat+content&chat_id=chat_123&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/generate/title' \
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/generate/title?content=Chat+content&chat_id=chat_123&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/generate/title' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"content": "Chat content", "chat_id": "chat_123", "token": "xxx"}'
|
||||
router.GET(path+"/generate/title", append(middlewares, neo.handleGenerateTitle)...)
|
||||
router.POST(path+"/generate/title", append(middlewares, neo.handleGenerateTitle)...)
|
||||
router.GET(path+"/generate/title", append(middlewares, agent.handleGenerateTitle)...)
|
||||
router.POST(path+"/generate/title", append(middlewares, agent.handleGenerateTitle)...)
|
||||
|
||||
// Generate prompts example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/generate/prompts?content=Generate+prompts&chat_id=chat_123&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/generate/prompts' \
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/generate/prompts?content=Generate+prompts&chat_id=chat_123&token=xxx'
|
||||
// curl -X POST 'http://localhost:5099/api/__yao/agent/generate/prompts' \
|
||||
// -H 'Content-Type: application/json' \
|
||||
// -d '{"content": "Generate prompts", "chat_id": "chat_123", "token": "xxx"}'
|
||||
router.GET(path+"/generate/prompts", append(middlewares, neo.handleGeneratePrompts)...)
|
||||
router.POST(path+"/generate/prompts", append(middlewares, neo.handleGeneratePrompts)...)
|
||||
router.GET(path+"/generate/prompts", append(middlewares, agent.handleGeneratePrompts)...)
|
||||
router.POST(path+"/generate/prompts", append(middlewares, agent.handleGeneratePrompts)...)
|
||||
|
||||
// Utility endpoints
|
||||
// List connectors example:
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/utility/connectors?token=xxx'
|
||||
router.GET(path+"/utility/connectors", append(middlewares, neo.handleConnectors)...)
|
||||
// curl -X GET 'http://localhost:5099/api/__yao/agent/utility/connectors?token=xxx'
|
||||
router.GET(path+"/utility/connectors", append(middlewares, agent.handleConnectors)...)
|
||||
|
||||
// Dangerous operations
|
||||
// Dangerous operations
|
||||
// Clear all chats example:
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/neo/dangerous/clear_chats?token=xxx'
|
||||
router.DELETE(path+"/dangerous/clear_chats", append(middlewares, neo.handleChatsDeleteAll)...)
|
||||
// curl -X DELETE 'http://localhost:5099/api/__yao/agent/dangerous/clear_chats?token=xxx'
|
||||
router.DELETE(path+"/dangerous/clear_chats", append(middlewares, agent.handleChatsDeleteAll)...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleStatus handles the status request
|
||||
func (neo *DSL) handleStatus(c *gin.Context) {
|
||||
func (agent *DSL) handleStatus(c *gin.Context) {
|
||||
c.Status(200)
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleUpload handles the upload request
|
||||
func (neo *DSL) handleUpload(c *gin.Context) {
|
||||
func (agent *DSL) handleUpload(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
sid = uuid.New().String()
|
||||
}
|
||||
|
||||
uid, isGuest, err := neo.UserOrGuestID(sid)
|
||||
uid, isGuest, err := agent.UserOrGuestID(sid)
|
||||
if err != nil {
|
||||
c.JSON(401, gin.H{"message": fmt.Sprintf("Unauthorized, %s", err.Error()), "code": 401})
|
||||
c.Done()
|
||||
|
|
@ -306,7 +306,7 @@ func (neo *DSL) handleUpload(c *gin.Context) {
|
|||
attachment["collection_id"] = option.CollectionID
|
||||
}
|
||||
|
||||
_, err = neo.Store.SaveAttachment(attachment)
|
||||
_, err = agent.Store.SaveAttachment(attachment)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -319,7 +319,7 @@ func (neo *DSL) handleUpload(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleDownload handles the download request
|
||||
func (neo *DSL) handleDownload(c *gin.Context) {
|
||||
func (agent *DSL) handleDownload(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -327,7 +327,7 @@ func (neo *DSL) handleDownload(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
uid, _, err := neo.UserOrGuestID(sid)
|
||||
uid, _, err := agent.UserOrGuestID(sid)
|
||||
if err != nil {
|
||||
c.JSON(401, gin.H{"message": fmt.Sprintf("Unauthorized, %s", err.Error()), "code": 401})
|
||||
c.Done()
|
||||
|
|
@ -348,7 +348,7 @@ func (neo *DSL) handleDownload(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Get the attachment
|
||||
attach, err := neo.Store.GetAttachment(fileID)
|
||||
attach, err := agent.Store.GetAttachment(fileID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -417,7 +417,7 @@ func (neo *DSL) handleDownload(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChat handles the chat request
|
||||
func (neo *DSL) handleChat(c *gin.Context) {
|
||||
func (agent *DSL) handleChat(c *gin.Context) {
|
||||
// Set headers for SSE
|
||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
|
|
@ -470,7 +470,7 @@ func (neo *DSL) handleChat(c *gin.Context) {
|
|||
ctx = chatctx.WithClientType(ctx, clientType)
|
||||
}
|
||||
|
||||
err := neo.Answer(ctx, content, c)
|
||||
err := agent.Answer(ctx, content, c)
|
||||
|
||||
// Error handling
|
||||
if err != nil {
|
||||
|
|
@ -481,7 +481,7 @@ func (neo *DSL) handleChat(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChatList handles the chat list request
|
||||
func (neo *DSL) handleChatList(c *gin.Context) {
|
||||
func (agent *DSL) handleChatList(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -513,7 +513,7 @@ func (neo *DSL) handleChatList(c *gin.Context) {
|
|||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
|
||||
response, err := neo.Store.GetChats(sid, filter, locale)
|
||||
response, err := agent.Store.GetChats(sid, filter, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -525,7 +525,7 @@ func (neo *DSL) handleChatList(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChatHistory handles the chat history request
|
||||
func (neo *DSL) handleChatHistory(c *gin.Context) {
|
||||
func (agent *DSL) handleChatHistory(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -534,7 +534,7 @@ func (neo *DSL) handleChatHistory(c *gin.Context) {
|
|||
}
|
||||
|
||||
cid := c.Query("chat_id")
|
||||
history, err := neo.Store.GetHistory(sid, cid)
|
||||
history, err := agent.Store.GetHistory(sid, cid)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -546,25 +546,25 @@ func (neo *DSL) handleChatHistory(c *gin.Context) {
|
|||
}
|
||||
|
||||
// getCorsHandlers returns CORS middleware handlers
|
||||
func (neo *DSL) getCorsHandlers() ([]gin.HandlerFunc, error) {
|
||||
if len(neo.Allows) == 0 {
|
||||
func (agent *DSL) getCorsHandlers() ([]gin.HandlerFunc, error) {
|
||||
if len(agent.Allows) == 0 {
|
||||
return []gin.HandlerFunc{}, nil
|
||||
}
|
||||
|
||||
allowsMap := map[string]bool{}
|
||||
for _, allow := range neo.Allows {
|
||||
for _, allow := range agent.Allows {
|
||||
allow = strings.TrimPrefix(allow, "http://")
|
||||
allow = strings.TrimPrefix(allow, "https://")
|
||||
allowsMap[allow] = true
|
||||
}
|
||||
|
||||
return []gin.HandlerFunc{neo.corsMiddleware(allowsMap)}, nil
|
||||
return []gin.HandlerFunc{agent.corsMiddleware(allowsMap)}, nil
|
||||
}
|
||||
|
||||
// corsMiddleware handles CORS requests
|
||||
func (neo *DSL) corsMiddleware(allowsMap map[string]bool) gin.HandlerFunc {
|
||||
func (agent *DSL) corsMiddleware(allowsMap map[string]bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
origin := neo.getOrigin(c)
|
||||
origin := agent.getOrigin(c)
|
||||
if origin == "" {
|
||||
c.Next()
|
||||
return
|
||||
|
|
@ -596,8 +596,8 @@ func (neo *DSL) corsMiddleware(allowsMap map[string]bool) gin.HandlerFunc {
|
|||
}
|
||||
|
||||
// optionsHandler handles OPTIONS requests
|
||||
func (neo *DSL) optionsHandler(c *gin.Context) {
|
||||
origin := neo.getOrigin(c)
|
||||
func (agent *DSL) optionsHandler(c *gin.Context) {
|
||||
origin := agent.getOrigin(c)
|
||||
if origin != "" {
|
||||
c.Header("Access-Control-Allow-Origin", origin)
|
||||
c.Header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS")
|
||||
|
|
@ -610,7 +610,7 @@ func (neo *DSL) optionsHandler(c *gin.Context) {
|
|||
}
|
||||
|
||||
// getOrigin returns the request origin
|
||||
func (neo *DSL) getOrigin(c *gin.Context) string {
|
||||
func (agent *DSL) getOrigin(c *gin.Context) string {
|
||||
origin := c.Request.Header.Get("Origin")
|
||||
if origin == "" {
|
||||
origin = c.Request.Referer()
|
||||
|
|
@ -624,35 +624,35 @@ func (neo *DSL) getOrigin(c *gin.Context) string {
|
|||
}
|
||||
|
||||
// getGuardHandlers returns authentication middleware handlers
|
||||
func (neo *DSL) getGuardHandlers() ([]gin.HandlerFunc, error) {
|
||||
func (agent *DSL) getGuardHandlers() ([]gin.HandlerFunc, error) {
|
||||
|
||||
// Cross-Domain handlers
|
||||
cors, err := neo.getCorsHandlers()
|
||||
cors, err := agent.getCorsHandlers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if neo.Guard == "" {
|
||||
middlewares := append(cors, neo.defaultGuard)
|
||||
if agent.Guard == "" {
|
||||
middlewares := append(cors, agent.defaultGuard)
|
||||
return middlewares, nil
|
||||
}
|
||||
|
||||
// Validate the custom guard
|
||||
_, err = process.Of(neo.Guard)
|
||||
_, err = process.Of(agent.Guard)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
middlewares := append(cors, api.ProcessGuard(neo.Guard, cors...))
|
||||
middlewares := append(cors, api.ProcessGuard(agent.Guard, cors...))
|
||||
return middlewares, nil
|
||||
}
|
||||
|
||||
// defaultGuard is the default authentication handler
|
||||
func (neo *DSL) defaultGuard(c *gin.Context) {
|
||||
func (agent *DSL) defaultGuard(c *gin.Context) {
|
||||
|
||||
// Check if the request is for OpenAPI OAuth
|
||||
if oauth.OAuth != nil {
|
||||
neo.guardOpenapiOauth(c)
|
||||
agent.guardOpenapiOauth(c)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -669,9 +669,9 @@ func (neo *DSL) defaultGuard(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Openapi Oauth
|
||||
func (neo *DSL) guardOpenapiOauth(c *gin.Context) {
|
||||
func (agent *DSL) guardOpenapiOauth(c *gin.Context) {
|
||||
s := oauth.OAuth
|
||||
token := neo.getAccessToken(c)
|
||||
token := agent.getAccessToken(c)
|
||||
if token == "" {
|
||||
c.JSON(403, gin.H{"code": 403, "message": "Not Authorized"})
|
||||
c.Abort()
|
||||
|
|
@ -687,7 +687,7 @@ func (neo *DSL) guardOpenapiOauth(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Get the session ID
|
||||
sid := neo.getSessionID(c)
|
||||
sid := agent.getSessionID(c)
|
||||
if sid == "" {
|
||||
c.JSON(403, gin.H{"code": 403, "message": "Not Authorized"})
|
||||
c.Abort()
|
||||
|
|
@ -697,7 +697,7 @@ func (neo *DSL) guardOpenapiOauth(c *gin.Context) {
|
|||
c.Set("__sid", sid)
|
||||
}
|
||||
|
||||
func (neo *DSL) getAccessToken(c *gin.Context) string {
|
||||
func (agent *DSL) getAccessToken(c *gin.Context) string {
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" || token == "Bearer undefined" {
|
||||
cookie, err := c.Cookie("__Host-access_token")
|
||||
|
|
@ -709,7 +709,7 @@ func (neo *DSL) getAccessToken(c *gin.Context) string {
|
|||
return strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
func (neo *DSL) getSessionID(c *gin.Context) string {
|
||||
func (agent *DSL) getSessionID(c *gin.Context) string {
|
||||
sid, err := c.Cookie("__Host-session_id")
|
||||
if err != nil {
|
||||
return ""
|
||||
|
|
@ -718,7 +718,7 @@ func (neo *DSL) getSessionID(c *gin.Context) string {
|
|||
}
|
||||
|
||||
// handleChatLatest handles getting the latest chat
|
||||
func (neo *DSL) handleChatLatest(c *gin.Context) {
|
||||
func (agent *DSL) handleChatLatest(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -732,7 +732,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Get the chats
|
||||
chats, err := neo.Store.GetChats(sid, store.ChatFilter{Page: 1}, locale)
|
||||
chats, err := agent.Store.GetChats(sid, store.ChatFilter{Page: 1}, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -742,7 +742,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
// Create a new chat
|
||||
if len(chats.Groups) == 0 || len(chats.Groups[0].Chats) == 0 {
|
||||
|
||||
assistantID := neo.Use.Default
|
||||
assistantID := agent.Use.Default
|
||||
queryAssistantID := c.Query("assistant_id")
|
||||
if queryAssistantID != "" {
|
||||
assistantID = queryAssistantID
|
||||
|
|
@ -761,7 +761,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
"assistant_id": ast.ID,
|
||||
"assistant_name": ast.GetName(locale),
|
||||
"assistant_avatar": ast.Avatar,
|
||||
"assistant_deleteable": neo.Use.Default != ast.ID,
|
||||
"assistant_deleteable": agent.Use.Default != ast.ID,
|
||||
}})
|
||||
c.Done()
|
||||
return
|
||||
|
|
@ -775,7 +775,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
chat, err := neo.Store.GetChat(sid, chatID, locale)
|
||||
chat, err := agent.Store.GetChat(sid, chatID, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -784,10 +784,10 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
|
||||
// assistant_id is nil return the default assistant
|
||||
if chat.Chat["assistant_id"] == nil {
|
||||
chat.Chat["assistant_id"] = neo.Use.Default
|
||||
chat.Chat["assistant_id"] = agent.Use.Default
|
||||
|
||||
// Get the assistant info
|
||||
ast, err := assistant.Get(neo.Use.Default)
|
||||
ast, err := assistant.Get(agent.Use.Default)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -797,13 +797,13 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
|||
chat.Chat["assistant_avatar"] = ast.Avatar
|
||||
}
|
||||
|
||||
chat.Chat["assistant_deleteable"] = neo.Use.Default != chat.Chat["assistant_id"]
|
||||
chat.Chat["assistant_deleteable"] = agent.Use.Default != chat.Chat["assistant_id"]
|
||||
c.JSON(200, map[string]interface{}{"data": chat})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleChatDetail handles getting a single chat's details
|
||||
func (neo *DSL) handleChatDetail(c *gin.Context) {
|
||||
func (agent *DSL) handleChatDetail(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -824,7 +824,7 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Get the chat details
|
||||
chat, err := neo.Store.GetChat(sid, chatID, locale)
|
||||
chat, err := agent.Store.GetChat(sid, chatID, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -833,10 +833,10 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
|||
|
||||
// assistant_id is nil return the default assistant
|
||||
if chat.Chat["assistant_id"] == nil {
|
||||
chat.Chat["assistant_id"] = neo.Use.Default
|
||||
chat.Chat["assistant_id"] = agent.Use.Default
|
||||
|
||||
// Get the assistant info
|
||||
ast, err := assistant.Get(neo.Use.Default)
|
||||
ast, err := assistant.Get(agent.Use.Default)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -846,13 +846,13 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
|||
chat.Chat["assistant_avatar"] = ast.Avatar
|
||||
}
|
||||
|
||||
chat.Chat["assistant_deleteable"] = neo.Use.Default != chat.Chat["assistant_id"]
|
||||
chat.Chat["assistant_deleteable"] = agent.Use.Default != chat.Chat["assistant_id"]
|
||||
c.JSON(200, map[string]interface{}{"data": chat})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleMentions handles getting mentions for a chat
|
||||
func (neo *DSL) handleMentions(c *gin.Context) {
|
||||
func (agent *DSL) handleMentions(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -877,7 +877,7 @@ func (neo *DSL) handleMentions(c *gin.Context) {
|
|||
PageSize: 20,
|
||||
}
|
||||
|
||||
response, err := neo.Store.GetAssistants(filter, locale)
|
||||
response, err := agent.Store.GetAssistants(filter, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -901,7 +901,7 @@ func (neo *DSL) handleMentions(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChatUpdate handles updating a chat's details
|
||||
func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
||||
func (agent *DSL) handleChatUpdate(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -933,7 +933,7 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
err := neo.Store.UpdateChatTitle(sid, chatID, body.Title)
|
||||
err := agent.Store.UpdateChatTitle(sid, chatID, body.Title)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -945,7 +945,7 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChatDelete handles deleting a single chat
|
||||
func (neo *DSL) handleChatDelete(c *gin.Context) {
|
||||
func (agent *DSL) handleChatDelete(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -960,7 +960,7 @@ func (neo *DSL) handleChatDelete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
err := neo.Store.DeleteChat(sid, chatID)
|
||||
err := agent.Store.DeleteChat(sid, chatID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -972,7 +972,7 @@ func (neo *DSL) handleChatDelete(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleChatsDeleteAll handles deleting all chats for a user
|
||||
func (neo *DSL) handleChatsDeleteAll(c *gin.Context) {
|
||||
func (agent *DSL) handleChatsDeleteAll(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -980,7 +980,7 @@ func (neo *DSL) handleChatsDeleteAll(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
err := neo.Store.DeleteAllChats(sid)
|
||||
err := agent.Store.DeleteAllChats(sid)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -992,7 +992,7 @@ func (neo *DSL) handleChatsDeleteAll(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleGenerateTitle handles generating a chat title
|
||||
func (neo *DSL) handleGenerateTitle(c *gin.Context) {
|
||||
func (agent *DSL) handleGenerateTitle(c *gin.Context) {
|
||||
// Set headers for SSE
|
||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
|
|
@ -1019,9 +1019,9 @@ func (neo *DSL) handleGenerateTitle(c *gin.Context) {
|
|||
|
||||
// Set the assistant ID
|
||||
ctx = chatctx.WithHistoryVisible(ctx, false)
|
||||
ctx = chatctx.WithAssistantID(ctx, neo.Use.Title)
|
||||
ctx = chatctx.WithAssistantID(ctx, agent.Use.Title)
|
||||
|
||||
err := neo.Answer(ctx, content, c)
|
||||
err := agent.Answer(ctx, content, c)
|
||||
|
||||
// Error handling
|
||||
if err != nil {
|
||||
|
|
@ -1032,7 +1032,7 @@ func (neo *DSL) handleGenerateTitle(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleGeneratePrompts handles generating prompts
|
||||
func (neo *DSL) handleGeneratePrompts(c *gin.Context) {
|
||||
func (agent *DSL) handleGeneratePrompts(c *gin.Context) {
|
||||
// Set headers for SSE
|
||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
|
|
@ -1059,8 +1059,8 @@ func (neo *DSL) handleGeneratePrompts(c *gin.Context) {
|
|||
|
||||
// Set the assistant ID
|
||||
ctx = chatctx.WithHistoryVisible(ctx, false)
|
||||
ctx = chatctx.WithAssistantID(ctx, neo.Use.Prompt)
|
||||
err := neo.Answer(ctx, content, c)
|
||||
ctx = chatctx.WithAssistantID(ctx, agent.Use.Prompt)
|
||||
err := agent.Answer(ctx, content, c)
|
||||
|
||||
// Error handling
|
||||
if err != nil {
|
||||
|
|
@ -1071,7 +1071,7 @@ func (neo *DSL) handleGeneratePrompts(c *gin.Context) {
|
|||
}
|
||||
|
||||
// HandleAssistantList handles listing assistants (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantList(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantList(c *gin.Context) {
|
||||
// Parse filter parameters
|
||||
filter := store.AssistantFilter{
|
||||
Type: "assistant",
|
||||
|
|
@ -1146,7 +1146,7 @@ func (neo *DSL) HandleAssistantList(c *gin.Context) {
|
|||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
|
||||
response, err := neo.Store.GetAssistants(filter, locale)
|
||||
response, err := agent.Store.GetAssistants(filter, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -1174,7 +1174,7 @@ func parseBoolValue(value string) *bool {
|
|||
}
|
||||
|
||||
// HandleAssistantCall handles the assistant API call (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantCall(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantCall(c *gin.Context) {
|
||||
assistantID := c.Param("id")
|
||||
if assistantID == "" {
|
||||
c.JSON(400, gin.H{"message": "assistant id is required", "code": 400})
|
||||
|
|
@ -1214,7 +1214,7 @@ func (neo *DSL) HandleAssistantCall(c *gin.Context) {
|
|||
}
|
||||
|
||||
// HandleAssistantDetail handles getting a single assistant's details (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantDetail(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantDetail(c *gin.Context) {
|
||||
assistantID := c.Param("id")
|
||||
if assistantID == "" {
|
||||
c.JSON(400, gin.H{"message": "assistant id is required", "code": 400})
|
||||
|
|
@ -1235,7 +1235,7 @@ func (neo *DSL) HandleAssistantDetail(c *gin.Context) {
|
|||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
|
||||
response, err := neo.Store.GetAssistants(filter, locale)
|
||||
response, err := agent.Store.GetAssistants(filter, locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -1253,7 +1253,7 @@ func (neo *DSL) HandleAssistantDetail(c *gin.Context) {
|
|||
}
|
||||
|
||||
// HandleAssistantSave handles creating or updating an assistant (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantSave(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantSave(c *gin.Context) {
|
||||
var assistantData map[string]interface{}
|
||||
if err := c.BindJSON(&assistantData); err != nil {
|
||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
||||
|
|
@ -1261,7 +1261,7 @@ func (neo *DSL) HandleAssistantSave(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
id, err := neo.Store.SaveAssistant(assistantData)
|
||||
id, err := agent.Store.SaveAssistant(assistantData)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -1291,7 +1291,7 @@ func (neo *DSL) HandleAssistantSave(c *gin.Context) {
|
|||
}
|
||||
|
||||
// HandleAssistantDelete handles deleting an assistant (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantDelete(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantDelete(c *gin.Context) {
|
||||
assistantID := c.Param("id")
|
||||
if assistantID == "" {
|
||||
c.JSON(400, gin.H{"message": "assistant id is required", "code": 400})
|
||||
|
|
@ -1299,7 +1299,7 @@ func (neo *DSL) HandleAssistantDelete(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
err := neo.Store.DeleteAssistant(assistantID)
|
||||
err := agent.Store.DeleteAssistant(assistantID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -1317,7 +1317,7 @@ func (neo *DSL) HandleAssistantDelete(c *gin.Context) {
|
|||
}
|
||||
|
||||
// handleConnectors handles listing connectors
|
||||
func (neo *DSL) handleConnectors(c *gin.Context) {
|
||||
func (agent *DSL) handleConnectors(c *gin.Context) {
|
||||
options := []map[string]interface{}{}
|
||||
|
||||
// Filter and format connectors
|
||||
|
|
@ -1343,7 +1343,7 @@ func (neo *DSL) handleConnectors(c *gin.Context) {
|
|||
}
|
||||
|
||||
// HandleAssistantTags handles getting all assistant tags (exported for use in openapi/agent)
|
||||
func (neo *DSL) HandleAssistantTags(c *gin.Context) {
|
||||
func (agent *DSL) HandleAssistantTags(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
|
|
@ -1356,7 +1356,7 @@ func (neo *DSL) HandleAssistantTags(c *gin.Context) {
|
|||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
|
||||
tags, err := neo.Store.GetAssistantTags(locale)
|
||||
tags, err := agent.Store.GetAssistantTags(locale)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -40,7 +40,7 @@ func TestAPI(t *testing.T) {
|
|||
|
||||
// test router
|
||||
router := testRouter(t)
|
||||
err := Neo.API(router, "/neo/chat")
|
||||
err := Agent.API(router, "/agent/chat")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -59,21 +59,21 @@ func TestAPI(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "Basic Chat Request",
|
||||
url: fmt.Sprintf("/neo/chat?content=hello&token=%s", testToken()),
|
||||
url: fmt.Sprintf("/agent/chat?content=hello&token=%s", testToken()),
|
||||
method: "GET",
|
||||
headers: http.Header{"Content-Type": []string{"application/json"}},
|
||||
expectBody: `{`,
|
||||
},
|
||||
{
|
||||
name: "Chat with System Message",
|
||||
url: fmt.Sprintf("/neo/chat?content=hello&system=You are a helpful assistant&token=%s", testToken()),
|
||||
url: fmt.Sprintf("/agent/chat?content=hello&system=You are a helpful assistant&token=%s", testToken()),
|
||||
method: "GET",
|
||||
headers: http.Header{"Content-Type": []string{"application/json"}},
|
||||
expectBody: `{`,
|
||||
},
|
||||
{
|
||||
name: "Chat with Model Parameter",
|
||||
url: fmt.Sprintf("/neo/chat?content=hello&model=gpt-3.5-turbo&token=%s", testToken()),
|
||||
url: fmt.Sprintf("/agent/chat?content=hello&model=gpt-3.5-turbo&token=%s", testToken()),
|
||||
method: "GET",
|
||||
headers: http.Header{"Content-Type": []string{"application/json"}},
|
||||
expectBody: `{`,
|
||||
|
|
@ -116,7 +116,7 @@ func TestAPIAuth(t *testing.T) {
|
|||
}()
|
||||
|
||||
router := testRouter(t)
|
||||
err := Neo.API(router, "/neo/chat")
|
||||
err := Agent.API(router, "/agent/chat")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -130,13 +130,13 @@ func TestAPIAuth(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "Missing Token",
|
||||
url: "/neo/chat?content=hello",
|
||||
url: "/agent/chat?content=hello",
|
||||
method: "GET",
|
||||
expectCode: http.StatusUnauthorized,
|
||||
},
|
||||
{
|
||||
name: "Invalid Token",
|
||||
url: "/neo/chat?content=hello&token=invalid",
|
||||
url: "/agent/chat?content=hello&token=invalid",
|
||||
method: "GET",
|
||||
expectCode: http.StatusUnauthorized,
|
||||
},
|
||||
|
|
@ -162,7 +162,7 @@ func TestAPIAuth(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "Missing Content",
|
||||
url: fmt.Sprintf("/neo/chat?token=%s", testToken()),
|
||||
url: fmt.Sprintf("/agent/chat?token=%s", testToken()),
|
||||
method: "GET",
|
||||
expectCode: http.StatusBadRequest,
|
||||
},
|
||||
|
|
@ -14,10 +14,10 @@ import (
|
|||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/log"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
"github.com/yaoapp/yao/neo/i18n"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
chatMessage "github.com/yaoapp/yao/neo/message"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
chatMessage "github.com/yaoapp/yao/agent/message"
|
||||
)
|
||||
|
||||
// Get get the assistant by id
|
||||
|
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/google/uuid"
|
||||
"github.com/yaoapp/gou/runtime/v8/bridge"
|
||||
"github.com/yaoapp/kun/log"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
chatMessage "github.com/yaoapp/yao/neo/message"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
chatMessage "github.com/yaoapp/yao/agent/message"
|
||||
"rogchap.com/v8go"
|
||||
)
|
||||
|
||||
|
|
@ -10,9 +10,9 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/kun/log"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
chatMessage "github.com/yaoapp/yao/neo/message"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
chatMessage "github.com/yaoapp/yao/agent/message"
|
||||
)
|
||||
|
||||
// HookCreate create a new assistant
|
||||
|
|
@ -14,9 +14,9 @@ import (
|
|||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/gou/rag/driver"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/yao/neo/i18n"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
neovision "github.com/yaoapp/yao/neo/vision"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
agentvision "github.com/yaoapp/yao/agent/vision"
|
||||
"github.com/yaoapp/yao/openai"
|
||||
"github.com/yaoapp/yao/share"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
|
@ -28,7 +28,7 @@ var storage store.Store = nil
|
|||
var rag *RAG = nil
|
||||
var search interface{} = nil
|
||||
var connectorSettings map[string]ConnectorSetting = map[string]ConnectorSetting{}
|
||||
var vision *neovision.Vision = nil
|
||||
var vision *agentvision.Vision = nil
|
||||
var defaultConnector string = "" // default connector
|
||||
|
||||
// LoadBuiltIn load the built-in assistants
|
||||
|
|
@ -135,7 +135,7 @@ func SetStorage(s store.Store) {
|
|||
}
|
||||
|
||||
// SetVision set the vision
|
||||
func SetVision(v *neovision.Vision) {
|
||||
func SetVision(v *agentvision.Vision) {
|
||||
vision = v
|
||||
}
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
"github.com/yaoapp/yao/test"
|
||||
)
|
||||
|
||||
|
|
@ -7,9 +7,9 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/gou/runtime/v8/bridge"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
chatMessage "github.com/yaoapp/yao/neo/message"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
chatMessage "github.com/yaoapp/yao/agent/message"
|
||||
sui "github.com/yaoapp/yao/sui/core"
|
||||
"rogchap.com/v8go"
|
||||
)
|
||||
|
|
@ -7,9 +7,9 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/rag/driver"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
"github.com/yaoapp/yao/neo/i18n"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
api "github.com/yaoapp/yao/openai"
|
||||
)
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ func WithSilent(ctx Context, silent bool) Context {
|
|||
func WithClientType(ctx Context, clientType string) Context {
|
||||
// Validate the client type
|
||||
if !SupportedClientTypes[clientType] {
|
||||
log.Error("[Neo] Invalid client type: %s", clientType)
|
||||
log.Error("[Agent] Invalid client type: %s", clientType)
|
||||
return ctx
|
||||
}
|
||||
ctx.ClientType = clientType
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -7,34 +7,34 @@ import (
|
|||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/connector"
|
||||
"github.com/yaoapp/gou/model"
|
||||
"github.com/yaoapp/yao/agent/assistant"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
"github.com/yaoapp/yao/attachment"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/neo/assistant"
|
||||
"github.com/yaoapp/yao/neo/i18n"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
)
|
||||
|
||||
// Neo the neo AI assistant
|
||||
var Neo *DSL
|
||||
// Agent the agent AI assistant
|
||||
var Agent *DSL
|
||||
|
||||
// Load load AIGC
|
||||
func Load(cfg config.Config) error {
|
||||
|
||||
setting := DSL{
|
||||
ID: "neo",
|
||||
ID: "agent",
|
||||
Allows: []string{},
|
||||
StoreSetting: store.Setting{
|
||||
Prefix: "yao_neo_",
|
||||
Prefix: "yao_agent_",
|
||||
Connector: "default",
|
||||
},
|
||||
}
|
||||
|
||||
bytes, err := application.App.Read(filepath.Join("neo", "neo.yml"))
|
||||
bytes, err := application.App.Read(filepath.Join("agent", "agent.yml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = application.Parse("neo.yml", bytes, &setting)
|
||||
err = application.Parse("agent.yml", bytes, &setting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -43,9 +43,9 @@ func Load(cfg config.Config) error {
|
|||
setting.StoreSetting.MaxSize = 20 // default is 20
|
||||
}
|
||||
|
||||
// Default Assistant, Neo is the developer name, Mohe is the brand name of the assistant
|
||||
// Default Assistant, Agent is the developer name, Mohe is the brand name of the assistant
|
||||
if setting.Use == nil {
|
||||
setting.Use = &Use{Default: "mohe"} // Neo is the developer name, Mohe is the brand name of the assistant
|
||||
setting.Use = &Use{Default: "mohe"} // Agent is the developer name, Mohe is the brand name of the assistant
|
||||
}
|
||||
|
||||
// Title Assistant
|
||||
|
|
@ -58,7 +58,7 @@ func Load(cfg config.Config) error {
|
|||
setting.Use.Prompt = setting.Use.Default
|
||||
}
|
||||
|
||||
Neo = &setting
|
||||
Agent = &setting
|
||||
|
||||
// Store Setting
|
||||
err = initStore()
|
||||
|
|
@ -101,71 +101,71 @@ func Load(cfg config.Config) error {
|
|||
|
||||
// initAuth initialize the auth
|
||||
func initAuth() error {
|
||||
if Neo.AuthSetting == nil {
|
||||
Neo.AuthSetting = &Auth{
|
||||
if Agent.AuthSetting == nil {
|
||||
Agent.AuthSetting = &Auth{
|
||||
Models: &AuthModels{User: "admin.user", Guest: "guest"},
|
||||
Fields: &AuthFields{ID: "id", Roles: "roles", Permission: "permission"},
|
||||
SessionFields: &AuthSessionFields{ID: "user_id", Roles: "user_roles", Guest: "guest_id"},
|
||||
}
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Models == nil {
|
||||
Neo.AuthSetting.Models = &AuthModels{User: "admin.user", Guest: "guest"}
|
||||
if Agent.AuthSetting.Models == nil {
|
||||
Agent.AuthSetting.Models = &AuthModels{User: "admin.user", Guest: "guest"}
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Fields == nil {
|
||||
Neo.AuthSetting.Fields = &AuthFields{ID: "id", Roles: "roles", Permission: "permission"}
|
||||
if Agent.AuthSetting.Fields == nil {
|
||||
Agent.AuthSetting.Fields = &AuthFields{ID: "id", Roles: "roles", Permission: "permission"}
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.SessionFields == nil {
|
||||
Neo.AuthSetting.SessionFields = &AuthSessionFields{ID: "user_id", Roles: "user_roles", Guest: "guest_id"}
|
||||
if Agent.AuthSetting.SessionFields == nil {
|
||||
Agent.AuthSetting.SessionFields = &AuthSessionFields{ID: "user_id", Roles: "user_roles", Guest: "guest_id"}
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Models.User == "" {
|
||||
Neo.AuthSetting.Models.User = "admin.user"
|
||||
if Agent.AuthSetting.Models.User == "" {
|
||||
Agent.AuthSetting.Models.User = "admin.user"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Models.Guest == "" {
|
||||
Neo.AuthSetting.Models.Guest = "guest"
|
||||
if Agent.AuthSetting.Models.Guest == "" {
|
||||
Agent.AuthSetting.Models.Guest = "guest"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Fields.Roles == "" {
|
||||
Neo.AuthSetting.Fields.Roles = "roles"
|
||||
if Agent.AuthSetting.Fields.Roles == "" {
|
||||
Agent.AuthSetting.Fields.Roles = "roles"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Fields.Permission == "" {
|
||||
Neo.AuthSetting.Fields.Permission = "permission"
|
||||
if Agent.AuthSetting.Fields.Permission == "" {
|
||||
Agent.AuthSetting.Fields.Permission = "permission"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Fields.ID == "" {
|
||||
Neo.AuthSetting.Fields.ID = "id"
|
||||
if Agent.AuthSetting.Fields.ID == "" {
|
||||
Agent.AuthSetting.Fields.ID = "id"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.Fields.ID == "" {
|
||||
Neo.AuthSetting.Fields.ID = "id"
|
||||
if Agent.AuthSetting.Fields.ID == "" {
|
||||
Agent.AuthSetting.Fields.ID = "id"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.SessionFields.ID == "" {
|
||||
Neo.AuthSetting.SessionFields.ID = "user_id"
|
||||
if Agent.AuthSetting.SessionFields.ID == "" {
|
||||
Agent.AuthSetting.SessionFields.ID = "user_id"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.SessionFields.Roles == "" {
|
||||
Neo.AuthSetting.SessionFields.Roles = "user_roles"
|
||||
if Agent.AuthSetting.SessionFields.Roles == "" {
|
||||
Agent.AuthSetting.SessionFields.Roles = "user_roles"
|
||||
}
|
||||
|
||||
if Neo.AuthSetting.SessionFields.Guest == "" {
|
||||
Neo.AuthSetting.SessionFields.Guest = "guest_id"
|
||||
if Agent.AuthSetting.SessionFields.Guest == "" {
|
||||
Agent.AuthSetting.SessionFields.Guest = "guest_id"
|
||||
}
|
||||
|
||||
// Validate User Model and Fields
|
||||
if !model.Exists(Neo.AuthSetting.Models.User) {
|
||||
return fmt.Errorf("model %s not found", Neo.AuthSetting.Models.User)
|
||||
if !model.Exists(Agent.AuthSetting.Models.User) {
|
||||
return fmt.Errorf("model %s not found", Agent.AuthSetting.Models.User)
|
||||
}
|
||||
user := model.Select(Neo.AuthSetting.Models.User)
|
||||
shouldHave := []string{Neo.AuthSetting.Fields.ID, Neo.AuthSetting.Fields.Roles, Neo.AuthSetting.Fields.Permission}
|
||||
user := model.Select(Agent.AuthSetting.Models.User)
|
||||
shouldHave := []string{Agent.AuthSetting.Fields.ID, Agent.AuthSetting.Fields.Roles, Agent.AuthSetting.Fields.Permission}
|
||||
for _, name := range shouldHave {
|
||||
if _, has := user.Columns[name]; !has {
|
||||
return fmt.Errorf("model %s should have column %s", Neo.AuthSetting.Models.User, name)
|
||||
return fmt.Errorf("model %s should have column %s", Agent.AuthSetting.Models.User, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ func initAuth() error {
|
|||
// initUpload initialize the upload
|
||||
func initUpload() error {
|
||||
|
||||
if Neo.UploadSetting == nil {
|
||||
if Agent.UploadSetting == nil {
|
||||
_, err := attachment.RegisterDefault("chat")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -188,7 +188,7 @@ func initUpload() error {
|
|||
}
|
||||
|
||||
// If the chat upload setting is not set, use the default chat upload setting.
|
||||
if Neo.UploadSetting.Chat == nil {
|
||||
if Agent.UploadSetting.Chat == nil {
|
||||
_, err := attachment.RegisterDefault("chat")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -196,14 +196,14 @@ func initUpload() error {
|
|||
}
|
||||
|
||||
// Use the chat upload setting for knowledge upload, if the knowledge upload setting is not set.
|
||||
if Neo.UploadSetting.Knowledge == nil {
|
||||
if Neo.UploadSetting.Chat == nil {
|
||||
if Agent.UploadSetting.Knowledge == nil {
|
||||
if Agent.UploadSetting.Chat == nil {
|
||||
_, err := attachment.RegisterDefault("knowledge")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err := attachment.Register("knowledge", Neo.UploadSetting.Chat.Driver, *Neo.UploadSetting.Chat)
|
||||
_, err := attachment.Register("knowledge", Agent.UploadSetting.Chat.Driver, *Agent.UploadSetting.Chat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -211,25 +211,25 @@ func initUpload() error {
|
|||
}
|
||||
|
||||
// Use custom chat upload setting
|
||||
if Neo.UploadSetting.Chat != nil {
|
||||
Neo.UploadSetting.Chat.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("chat", Neo.UploadSetting.Chat.Driver, *Neo.UploadSetting.Chat) // Register the chat upload manager
|
||||
if Agent.UploadSetting.Chat != nil {
|
||||
Agent.UploadSetting.Chat.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("chat", Agent.UploadSetting.Chat.Driver, *Agent.UploadSetting.Chat) // Register the chat upload manager
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Use custom knowledge upload setting
|
||||
if Neo.UploadSetting.Knowledge != nil {
|
||||
Neo.UploadSetting.Knowledge.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("knowledge", Neo.UploadSetting.Knowledge.Driver, *Neo.UploadSetting.Knowledge)
|
||||
if Agent.UploadSetting.Knowledge != nil {
|
||||
Agent.UploadSetting.Knowledge.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("knowledge", Agent.UploadSetting.Knowledge.Driver, *Agent.UploadSetting.Knowledge)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Use the chat upload setting for asset upload, if the asset upload setting is not set. (public assets)
|
||||
if Neo.UploadSetting.Assets == nil {
|
||||
if Agent.UploadSetting.Assets == nil {
|
||||
_, err := attachment.RegisterDefault("assets")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -237,9 +237,9 @@ func initUpload() error {
|
|||
}
|
||||
|
||||
// Use custom asset upload setting
|
||||
if Neo.UploadSetting.Assets != nil {
|
||||
Neo.UploadSetting.Assets.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("assets", Neo.UploadSetting.Assets.Driver, *Neo.UploadSetting.Assets)
|
||||
if Agent.UploadSetting.Assets != nil {
|
||||
Agent.UploadSetting.Assets.ReplaceEnv(config.Conf.DataRoot)
|
||||
_, err := attachment.Register("assets", Agent.UploadSetting.Assets.Driver, *Agent.UploadSetting.Assets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -249,7 +249,7 @@ func initUpload() error {
|
|||
|
||||
// initGlobalI18n initialize the global i18n
|
||||
func initGlobalI18n() error {
|
||||
locales, err := i18n.GetLocales("neo")
|
||||
locales, err := i18n.GetLocales("agent")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ func initGlobalI18n() error {
|
|||
|
||||
// initConnectors initialize the connectors
|
||||
func initConnectors() error {
|
||||
path := filepath.Join("neo", "connectors.yml")
|
||||
path := filepath.Join("agent", "connectors.yml")
|
||||
if exists, _ := application.App.Exists(path); !exists {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ func initConnectors() error {
|
|||
return err
|
||||
}
|
||||
|
||||
Neo.Connectors = connectors
|
||||
Agent.Connectors = connectors
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -284,46 +284,46 @@ func initConnectors() error {
|
|||
func initStore() error {
|
||||
|
||||
var err error
|
||||
if Neo.StoreSetting.Connector == "default" || Neo.StoreSetting.Connector == "" {
|
||||
Neo.Store, err = store.NewXun(Neo.StoreSetting)
|
||||
if Agent.StoreSetting.Connector == "default" || Agent.StoreSetting.Connector == "" {
|
||||
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
||||
return err
|
||||
}
|
||||
|
||||
// other connector
|
||||
conn, err := connector.Select(Neo.StoreSetting.Connector)
|
||||
conn, err := connector.Select(Agent.StoreSetting.Connector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if conn.Is(connector.DATABASE) {
|
||||
Neo.Store, err = store.NewXun(Neo.StoreSetting)
|
||||
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
||||
return err
|
||||
|
||||
} else if conn.Is(connector.REDIS) {
|
||||
Neo.Store = store.NewRedis()
|
||||
Agent.Store = store.NewRedis()
|
||||
return nil
|
||||
|
||||
} else if conn.Is(connector.MONGO) {
|
||||
Neo.Store = store.NewMongo()
|
||||
Agent.Store = store.NewMongo()
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s store connector %s not support", Neo.ID, Neo.StoreSetting.Connector)
|
||||
return fmt.Errorf("%s store connector %s not support", Agent.ID, Agent.StoreSetting.Connector)
|
||||
}
|
||||
|
||||
// initAssistant initialize the assistant
|
||||
func initAssistant() error {
|
||||
|
||||
// Set Storage
|
||||
assistant.SetStorage(Neo.Store)
|
||||
assistant.SetStorage(Agent.Store)
|
||||
|
||||
// Assistant Vision
|
||||
if Neo.Vision != nil {
|
||||
assistant.SetVision(Neo.Vision)
|
||||
if Agent.Vision != nil {
|
||||
assistant.SetVision(Agent.Vision)
|
||||
}
|
||||
|
||||
if Neo.Connectors != nil {
|
||||
assistant.SetConnectorSettings(Neo.Connectors)
|
||||
if Agent.Connectors != nil {
|
||||
assistant.SetConnectorSettings(Agent.Connectors)
|
||||
}
|
||||
|
||||
// Load Built-in Assistants
|
||||
|
|
@ -338,14 +338,14 @@ func initAssistant() error {
|
|||
return err
|
||||
}
|
||||
|
||||
Neo.Assistant = defaultAssistant
|
||||
Agent.Assistant = defaultAssistant
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultAssistant get the default assistant
|
||||
func defaultAssistant() (*assistant.Assistant, error) {
|
||||
if Neo.Use == nil || Neo.Use.Default == "" {
|
||||
if Agent.Use == nil || Agent.Use.Default == "" {
|
||||
return nil, fmt.Errorf("default assistant not found")
|
||||
}
|
||||
return assistant.Get(Neo.Use.Default)
|
||||
return assistant.Get(Agent.Use.Default)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
|
@ -20,5 +20,5 @@ func TestLoad(t *testing.T) {
|
|||
}
|
||||
|
||||
func check(t *testing.T) {
|
||||
assert.NotNil(t, Neo)
|
||||
assert.NotNil(t, Agent)
|
||||
}
|
||||
|
|
@ -26,9 +26,9 @@ type Message struct {
|
|||
Text string `json:"text,omitempty"` // text content
|
||||
Type string `json:"type,omitempty"` // error, text, plan, table, form, page, file, video, audio, image, markdown, json ...
|
||||
Props map[string]interface{} `json:"props,omitempty"` // props for the types
|
||||
IsDone bool `json:"done,omitempty"` // Mark as a done message from neo
|
||||
IsNew bool `json:"new,omitempty"` // Mark as a new message from neo
|
||||
IsDelta bool `json:"delta,omitempty"` // Mark as a delta message from neo
|
||||
IsDone bool `json:"done,omitempty"` // Mark as a done message from agent
|
||||
IsNew bool `json:"new,omitempty"` // Mark as a new message from agent
|
||||
IsDelta bool `json:"delta,omitempty"` // Mark as a delta message from agent
|
||||
Actions []Action `json:"actions,omitempty"` // Conversation Actions for frontend
|
||||
Attachments []attachment.Attachment `json:"attachments,omitempty"` // File attachments
|
||||
Role string `json:"role,omitempty"` // user, assistant, system ...
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
|
@ -11,19 +11,30 @@ import (
|
|||
"github.com/yaoapp/gou/process"
|
||||
"github.com/yaoapp/gou/rag/driver"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/neo/message"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
)
|
||||
|
||||
// GetNeo returns the Neo instance
|
||||
func GetNeo() *DSL {
|
||||
if Neo == nil {
|
||||
exception.New("Neo is not initialized", 500).Throw()
|
||||
// GetAgent returns the Agent instance
|
||||
func GetAgent() *DSL {
|
||||
if Agent == nil {
|
||||
exception.New("Agent is not initialized", 500).Throw()
|
||||
}
|
||||
return Neo
|
||||
return Agent
|
||||
}
|
||||
|
||||
func init() {
|
||||
process.RegisterGroup("agent", map[string]process.Handler{
|
||||
"write": ProcessWrite,
|
||||
"assistant.create": processAssistantCreate,
|
||||
"assistant.save": processAssistantSave,
|
||||
"assistant.delete": processAssistantDelete,
|
||||
"assistant.search": processAssistantSearch,
|
||||
"assistant.find": processAssistantFind,
|
||||
"assistant.match": processAssistantMatch, // Match assistant by content and params
|
||||
})
|
||||
|
||||
// Neo is deprecated, use agent instead (for backward compatibility, It will be removed in the future)
|
||||
process.RegisterGroup("neo", map[string]process.Handler{
|
||||
"write": ProcessWrite,
|
||||
"assistant.create": processAssistantCreate,
|
||||
|
|
@ -66,12 +77,12 @@ func processAssistantCreate(process *process.Process) interface{} {
|
|||
process.ValidateArgNums(1)
|
||||
data := process.ArgsMap(0)
|
||||
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
id, err := neo.Store.SaveAssistant(data)
|
||||
id, err := agent.Store.SaveAssistant(data)
|
||||
if err != nil {
|
||||
exception.New("Failed to create assistant: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -84,12 +95,12 @@ func processAssistantSave(process *process.Process) interface{} {
|
|||
process.ValidateArgNums(1)
|
||||
data := process.ArgsMap(0)
|
||||
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
id, err := neo.Store.SaveAssistant(data)
|
||||
id, err := agent.Store.SaveAssistant(data)
|
||||
if err != nil {
|
||||
exception.New("Failed to save assistant: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -102,12 +113,12 @@ func processAssistantDelete(process *process.Process) interface{} {
|
|||
process.ValidateArgNums(1)
|
||||
assistantID := process.ArgsString(0)
|
||||
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
err := neo.Store.DeleteAssistant(assistantID)
|
||||
err := agent.Store.DeleteAssistant(assistantID)
|
||||
if err != nil {
|
||||
exception.New("Failed to delete assistant: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -166,7 +177,7 @@ func processAssistantMatch(process *process.Process) interface{} {
|
|||
}
|
||||
|
||||
// Rag Support match using RAG
|
||||
if Neo.RAG != nil && !forceStore {
|
||||
if Agent.RAG != nil && !forceStore {
|
||||
return assistantMatchRAG(content, params)
|
||||
}
|
||||
|
||||
|
|
@ -175,8 +186,8 @@ func processAssistantMatch(process *process.Process) interface{} {
|
|||
}
|
||||
|
||||
func assistantMatchRAG(content interface{}, params map[string]interface{}) interface{} {
|
||||
if Neo == nil {
|
||||
exception.New("Neo is not initialized", 500).Throw()
|
||||
if Agent == nil {
|
||||
exception.New("Agent is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
// Convert content to JSON string
|
||||
|
|
@ -228,7 +239,7 @@ func assistantMatchRAG(content interface{}, params map[string]interface{}) inter
|
|||
ctx := context.Background()
|
||||
|
||||
// Get vectors using vectorizer
|
||||
vectors, err := Neo.RAG.Vectorizer().Vectorize(ctx, contentStr)
|
||||
vectors, err := Agent.RAG.Vectorizer().Vectorize(ctx, contentStr)
|
||||
if err != nil {
|
||||
exception.New("Failed to encode content: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -240,8 +251,8 @@ func assistantMatchRAG(content interface{}, params map[string]interface{}) inter
|
|||
QueryText: contentStr,
|
||||
}
|
||||
|
||||
index := fmt.Sprintf("%sassistants", Neo.RAG.Setting().IndexPrefix)
|
||||
results, err := Neo.RAG.Engine().Search(ctx, index, vectors, opts)
|
||||
index := fmt.Sprintf("%sassistants", Agent.RAG.Setting().IndexPrefix)
|
||||
results, err := Agent.RAG.Engine().Search(ctx, index, vectors, opts)
|
||||
if err != nil {
|
||||
exception.New("Failed to search with RAG: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -269,7 +280,7 @@ func assistantMatchRAG(content interface{}, params map[string]interface{}) inter
|
|||
Page: 1,
|
||||
PageSize: len(ids),
|
||||
}
|
||||
res, err := Neo.Store.GetAssistants(filter)
|
||||
res, err := Agent.Store.GetAssistants(filter)
|
||||
if err != nil {
|
||||
exception.New("get assistants error: %s", 500, err).Throw()
|
||||
}
|
||||
|
|
@ -356,9 +367,9 @@ func parseAssistantFilter(params map[string]interface{}) store.AssistantFilter {
|
|||
}
|
||||
|
||||
func assistantMatchStore(content interface{}, params map[string]interface{}) interface{} {
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
// Convert limit to pagesize
|
||||
|
|
@ -376,7 +387,7 @@ func assistantMatchStore(content interface{}, params map[string]interface{}) int
|
|||
}
|
||||
|
||||
filter := parseAssistantFilter(params)
|
||||
res, err := neo.Store.GetAssistants(filter)
|
||||
res, err := agent.Store.GetAssistants(filter)
|
||||
if err != nil {
|
||||
exception.New("get assistants error: %s", 500, err).Throw()
|
||||
}
|
||||
|
|
@ -390,9 +401,9 @@ func processAssistantSearch(process *process.Process) interface{} {
|
|||
filter := parseAssistantFilter(params)
|
||||
|
||||
// Get assistants
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
locale := "en"
|
||||
|
|
@ -400,7 +411,7 @@ func processAssistantSearch(process *process.Process) interface{} {
|
|||
locale = process.ArgsString(1)
|
||||
}
|
||||
|
||||
res, err := neo.Store.GetAssistants(filter, locale)
|
||||
res, err := agent.Store.GetAssistants(filter, locale)
|
||||
if err != nil {
|
||||
exception.New("get assistants error: %s", 500, err).Throw()
|
||||
}
|
||||
|
|
@ -413,9 +424,9 @@ func processAssistantFind(process *process.Process) interface{} {
|
|||
process.ValidateArgNums(1)
|
||||
assistantID := process.ArgsString(0)
|
||||
|
||||
neo := GetNeo()
|
||||
if neo.Store == nil {
|
||||
exception.New("Neo store is not initialized", 500).Throw()
|
||||
agent := GetAgent()
|
||||
if agent.Store == nil {
|
||||
exception.New("Agent store is not initialized", 500).Throw()
|
||||
}
|
||||
|
||||
filter := store.AssistantFilter{
|
||||
|
|
@ -428,7 +439,7 @@ func processAssistantFind(process *process.Process) interface{} {
|
|||
if len(process.Args) > 1 {
|
||||
locale = process.ArgsString(1)
|
||||
}
|
||||
res, err := neo.Store.GetAssistants(filter, locale)
|
||||
res, err := agent.Store.GetAssistants(filter, locale)
|
||||
if err != nil {
|
||||
exception.New("Failed to find assistant: %s", 500, err.Error()).Throw()
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -19,7 +19,7 @@ func prepare(t *testing.T) {
|
|||
}
|
||||
|
||||
// Clean up the test data before each test
|
||||
p, err := process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err := process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"page": 1,
|
||||
"pagesize": 1000, // Use a large page size to get all records
|
||||
})
|
||||
|
|
@ -35,7 +35,7 @@ func prepare(t *testing.T) {
|
|||
if items != nil {
|
||||
for _, item := range items.([]map[string]interface{}) {
|
||||
assistantID := item["assistant_id"].(string)
|
||||
p, err = process.Of("neo.assistant.delete", assistantID)
|
||||
p, err = process.Of("agent.assistant.delete", assistantID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ func prepare(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify cleanup
|
||||
p, err = process.Of("neo.assistant.search")
|
||||
p, err = process.Of("agent.assistant.search")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test processAssistantCreate with string JSON
|
||||
p, err := process.Of("neo.assistant.create", assistant)
|
||||
p, err := process.Of("agent.assistant.create", assistant)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.NotNil(t, assistantID)
|
||||
|
||||
// Test processAssistantFind
|
||||
p, err = process.Of("neo.assistant.find", assistantID)
|
||||
p, err = process.Of("agent.assistant.find", assistantID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.Equal(t, map[string]interface{}{"model": "gpt-4"}, foundAssistant["options"])
|
||||
|
||||
// Test processAssistantFind with non-existent ID
|
||||
p, err = process.Of("neo.assistant.find", "non-existent-id")
|
||||
p, err = process.Of("agent.assistant.find", "non-existent-id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test processAssistantCreate with native types
|
||||
p, err = process.Of("neo.assistant.create", assistant2)
|
||||
p, err = process.Of("agent.assistant.create", assistant2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test processAssistantCreate with nil fields
|
||||
p, err = process.Of("neo.assistant.create", assistant3)
|
||||
p, err = process.Of("agent.assistant.create", assistant3)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.NotNil(t, assistant3ID)
|
||||
|
||||
// Test processAssistantSearch to verify all assistants
|
||||
p, err = process.Of("neo.assistant.search")
|
||||
p, err = process.Of("agent.assistant.search")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -250,7 +250,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assistant2["assistant_id"] = assistant2ID
|
||||
assistant2["tags"] = `["tag4", "tag5"]`
|
||||
assistant2["options"] = map[string]interface{}{"model": "gpt-3.5"}
|
||||
p, err = process.Of("neo.assistant.save", assistant2)
|
||||
p, err = process.Of("agent.assistant.save", assistant2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -264,7 +264,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.NotNil(t, savedID)
|
||||
|
||||
// Double check with a new search
|
||||
p, err = process.Of("neo.assistant.search")
|
||||
p, err = process.Of("agent.assistant.search")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.True(t, found)
|
||||
|
||||
// Test processAssistantDelete
|
||||
p, err = process.Of("neo.assistant.delete", assistantID)
|
||||
p, err = process.Of("agent.assistant.delete", assistantID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -302,14 +302,14 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.Equal(t, "ok", deleteRes.Get("message"))
|
||||
|
||||
// Delete remaining assistants
|
||||
p, err = process.Of("neo.assistant.delete", assistant2ID)
|
||||
p, err = process.Of("agent.assistant.delete", assistant2ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = p.Exec()
|
||||
assert.Nil(t, err)
|
||||
|
||||
p, err = process.Of("neo.assistant.delete", assistant3ID)
|
||||
p, err = process.Of("agent.assistant.delete", assistant3ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -317,7 +317,7 @@ func TestProcessAssistantCRUD(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
// Verify all assistants are deleted
|
||||
p, err = process.Of("neo.assistant.search")
|
||||
p, err = process.Of("agent.assistant.search")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -351,7 +351,7 @@ func TestProcessAssistantSearchPagination(t *testing.T) {
|
|||
"automated": i%3 == 0,
|
||||
}
|
||||
|
||||
p, err := process.Of("neo.assistant.create", assistant)
|
||||
p, err := process.Of("agent.assistant.create", assistant)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -363,7 +363,7 @@ func TestProcessAssistantSearchPagination(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test first page
|
||||
p, err := process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err := process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"page": 1,
|
||||
"pagesize": 10,
|
||||
})
|
||||
|
|
@ -396,7 +396,7 @@ func TestProcessAssistantSearchPagination(t *testing.T) {
|
|||
assert.Equal(t, 3, pageCnt)
|
||||
|
||||
// Test second page
|
||||
p, err = process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err = process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"page": 2,
|
||||
"pagesize": 10,
|
||||
})
|
||||
|
|
@ -417,7 +417,7 @@ func TestProcessAssistantSearchPagination(t *testing.T) {
|
|||
assert.Equal(t, 10, len(items.([]map[string]interface{})))
|
||||
|
||||
// Test last page
|
||||
p, err = process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err = process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"page": 3,
|
||||
"pagesize": 10,
|
||||
})
|
||||
|
|
@ -438,7 +438,7 @@ func TestProcessAssistantSearchPagination(t *testing.T) {
|
|||
assert.Equal(t, 5, len(items.([]map[string]interface{})))
|
||||
|
||||
// Test filtering with tags
|
||||
p, err = process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err = process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"tags": []string{"tag0"},
|
||||
"page": 1,
|
||||
"pagesize": 10,
|
||||
|
|
@ -465,7 +465,7 @@ func TestProcessAssistantValidation(t *testing.T) {
|
|||
defer test.Clean()
|
||||
|
||||
// Test missing required fields
|
||||
p, err := process.Of("neo.assistant.create", map[string]interface{}{})
|
||||
p, err := process.Of("agent.assistant.create", map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -474,7 +474,7 @@ func TestProcessAssistantValidation(t *testing.T) {
|
|||
assert.NotNil(t, err)
|
||||
|
||||
// Test invalid assistant ID for delete
|
||||
p, err = process.Of("neo.assistant.delete", "non-existent-id")
|
||||
p, err = process.Of("agent.assistant.delete", "non-existent-id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -483,7 +483,7 @@ func TestProcessAssistantValidation(t *testing.T) {
|
|||
assert.NotNil(t, err)
|
||||
|
||||
// Test invalid assistant ID for find
|
||||
p, err = process.Of("neo.assistant.find", "non-existent-id")
|
||||
p, err = process.Of("agent.assistant.find", "non-existent-id")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -493,7 +493,7 @@ func TestProcessAssistantValidation(t *testing.T) {
|
|||
assert.Contains(t, err.Error(), "Assistant not found")
|
||||
|
||||
// Test invalid page number
|
||||
p, err = process.Of("neo.assistant.search", map[string]interface{}{
|
||||
p, err = process.Of("agent.assistant.search", map[string]interface{}{
|
||||
"page": -1,
|
||||
"pagesize": 10,
|
||||
})
|
||||
|
|
@ -59,7 +59,7 @@ func New(setting Setting) (*RAG, error) {
|
|||
}
|
||||
|
||||
if setting.IndexPrefix == "" {
|
||||
setting.IndexPrefix = "yao_neo_"
|
||||
setting.IndexPrefix = "yao_agent_"
|
||||
}
|
||||
|
||||
// Convert options map for vectorizer and handle environment variables
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# YAO Neo Store
|
||||
# YAO Agent Store
|
||||
|
||||
YAO Neo Store is a comprehensive storage abstraction layer for managing conversations, assistants, attachments, and knowledge collections in the YAO Neo platform. It provides a unified interface that supports multiple storage backends including databases (via Xun), Redis, and MongoDB.
|
||||
YAO Agent Store is a comprehensive storage abstraction layer for managing conversations, assistants, attachments, and knowledge collections in the YAO Agent platform. It provides a unified interface that supports multiple storage backends including databases (via Xun), Redis, and MongoDB.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
|
|
@ -77,11 +77,11 @@ type Setting struct {
|
|||
#### Database Configuration
|
||||
|
||||
```yaml
|
||||
# neo.yml
|
||||
neo:
|
||||
# agent.yml
|
||||
agent:
|
||||
store:
|
||||
connector: "mysql" # or "postgresql", "sqlite", "default"
|
||||
prefix: "neo_" # Table prefix
|
||||
prefix: "agent_" # Table prefix
|
||||
max_size: 100 # Maximum chat history size
|
||||
ttl: 7200 # 2 hours TTL for conversations
|
||||
user_field: "user_id" # User identification field
|
||||
|
|
@ -90,20 +90,20 @@ neo:
|
|||
#### Redis Configuration
|
||||
|
||||
```yaml
|
||||
neo:
|
||||
agent:
|
||||
store:
|
||||
connector: "redis"
|
||||
prefix: "neo:"
|
||||
prefix: "agent:"
|
||||
ttl: 3600
|
||||
```
|
||||
|
||||
#### MongoDB Configuration
|
||||
|
||||
```yaml
|
||||
neo:
|
||||
agent:
|
||||
store:
|
||||
connector: "mongodb"
|
||||
prefix: "neo_"
|
||||
prefix: "agent_"
|
||||
ttl: 7200
|
||||
```
|
||||
|
||||
|
|
@ -111,47 +111,47 @@ neo:
|
|||
|
||||
### Automatic Initialization (Recommended)
|
||||
|
||||
The store is automatically initialized when the Neo system starts:
|
||||
The store is automatically initialized when the Agent system starts:
|
||||
|
||||
```go
|
||||
// From yao/neo/load.go
|
||||
// From yao/agent/load.go
|
||||
func initStore() error {
|
||||
var err error
|
||||
if Neo.StoreSetting.Connector == "default" || Neo.StoreSetting.Connector == "" {
|
||||
Neo.Store, err = store.NewXun(Neo.StoreSetting)
|
||||
if Agent.StoreSetting.Connector == "default" || Agent.StoreSetting.Connector == "" {
|
||||
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
||||
return err
|
||||
}
|
||||
|
||||
// Other connector types
|
||||
conn, err := connector.Select(Neo.StoreSetting.Connector)
|
||||
conn, err := connector.Select(Agent.StoreSetting.Connector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if conn.Is(connector.DATABASE) {
|
||||
Neo.Store, err = store.NewXun(Neo.StoreSetting)
|
||||
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
||||
return err
|
||||
} else if conn.Is(connector.REDIS) {
|
||||
Neo.Store = store.NewRedis()
|
||||
Agent.Store = store.NewRedis()
|
||||
return nil
|
||||
} else if conn.Is(connector.MONGO) {
|
||||
Neo.Store = store.NewMongo()
|
||||
Agent.Store = store.NewMongo()
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s store connector %s not support", Neo.ID, Neo.StoreSetting.Connector)
|
||||
return fmt.Errorf("%s store connector %s not support", Agent.ID, Agent.StoreSetting.Connector)
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Initialization
|
||||
|
||||
```go
|
||||
import "github.com/yaoapp/yao/neo/store"
|
||||
import "github.com/yaoapp/yao/agent/store"
|
||||
|
||||
// Database backend
|
||||
setting := store.Setting{
|
||||
Connector: "mysql",
|
||||
Prefix: "neo_",
|
||||
Prefix: "agent_",
|
||||
MaxSize: 100,
|
||||
TTL: 3600,
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ type Store interface {
|
|||
#### 1. History Table (Conversations)
|
||||
|
||||
```sql
|
||||
CREATE TABLE neo_history (
|
||||
CREATE TABLE agent_history (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
sid VARCHAR(255) INDEX, -- Session ID
|
||||
cid VARCHAR(200) INDEX, -- Chat ID
|
||||
|
|
@ -240,7 +240,7 @@ CREATE TABLE neo_history (
|
|||
#### 2. Chat Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE neo_chat (
|
||||
CREATE TABLE agent_chat (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
chat_id VARCHAR(200) UNIQUE INDEX, -- Unique chat identifier
|
||||
title VARCHAR(200), -- Chat title
|
||||
|
|
@ -255,7 +255,7 @@ CREATE TABLE neo_chat (
|
|||
#### 3. Assistant Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE neo_assistant (
|
||||
CREATE TABLE agent_assistant (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
assistant_id VARCHAR(200) UNIQUE INDEX, -- Unique assistant identifier
|
||||
type VARCHAR(200) DEFAULT 'assistant' INDEX, -- Assistant type
|
||||
|
|
@ -286,7 +286,7 @@ CREATE TABLE neo_assistant (
|
|||
#### 4. Attachment Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE neo_attachment (
|
||||
CREATE TABLE agent_attachment (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
file_id VARCHAR(255) UNIQUE INDEX, -- Unique file identifier
|
||||
uid VARCHAR(255) INDEX, -- Owner user ID
|
||||
|
|
@ -310,7 +310,7 @@ CREATE TABLE neo_attachment (
|
|||
#### 5. Knowledge Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE neo_knowledge (
|
||||
CREATE TABLE agent_knowledge (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
collection_id VARCHAR(200) UNIQUE INDEX, -- Unique collection identifier
|
||||
name VARCHAR(200) INDEX, -- Collection name (searchable)
|
||||
|
|
@ -14,7 +14,7 @@ import (
|
|||
"github.com/yaoapp/xun/capsule"
|
||||
"github.com/yaoapp/xun/dbal/query"
|
||||
"github.com/yaoapp/xun/dbal/schema"
|
||||
"github.com/yaoapp/yao/neo/i18n"
|
||||
"github.com/yaoapp/yao/agent/i18n"
|
||||
)
|
||||
|
||||
// Package conversation provides functionality for managing chat conversations and assistants.
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
package neo
|
||||
package agent
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/yao/agent/assistant"
|
||||
"github.com/yaoapp/yao/agent/rag"
|
||||
"github.com/yaoapp/yao/agent/store"
|
||||
"github.com/yaoapp/yao/agent/vision"
|
||||
"github.com/yaoapp/yao/attachment"
|
||||
"github.com/yaoapp/yao/neo/assistant"
|
||||
"github.com/yaoapp/yao/neo/rag"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
"github.com/yaoapp/yao/neo/vision"
|
||||
)
|
||||
|
||||
// DSL AI assistant
|
||||
type DSL struct {
|
||||
|
||||
// Neo Global Settings
|
||||
// Agent Global Settings
|
||||
// ===============================
|
||||
Use *Use `json:"use,omitempty" yaml:"use,omitempty"` // Which assistant to use default, title, prompt
|
||||
StoreSetting store.Setting `json:"store" yaml:"store"` // The store setting of the assistant
|
||||
|
|
@ -24,7 +24,7 @@ type DSL struct {
|
|||
// ===============================
|
||||
Connectors map[string]assistant.ConnectorSetting `json:"connectors,omitempty" yaml:"connectors,omitempty"` // The connectors of the assistant
|
||||
|
||||
// Neo API Settings
|
||||
// Agent API Settings
|
||||
// ===============================s
|
||||
Guard string `json:"guard,omitempty" yaml:"guard,omitempty"` // The guard of the assistant
|
||||
Allows []string `json:"allows,omitempty" yaml:"allows,omitempty"` // The allowed domains of the assistant
|
||||
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/yao/agent/vision/driver/s3"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/neo/vision/driver/s3"
|
||||
"github.com/yaoapp/yao/test"
|
||||
)
|
||||
|
||||
|
|
@ -8,10 +8,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yaoapp/yao/neo/vision/driver"
|
||||
"github.com/yaoapp/yao/neo/vision/driver/local"
|
||||
"github.com/yaoapp/yao/neo/vision/driver/openai"
|
||||
"github.com/yaoapp/yao/neo/vision/driver/s3"
|
||||
"github.com/yaoapp/yao/agent/vision/driver"
|
||||
"github.com/yaoapp/yao/agent/vision/driver/local"
|
||||
"github.com/yaoapp/yao/agent/vision/driver/openai"
|
||||
"github.com/yaoapp/yao/agent/vision/driver/s3"
|
||||
)
|
||||
|
||||
// parseEnvValue parse environment variable if the value starts with $ENV.
|
||||
|
|
@ -15,9 +15,9 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/yao/agent/vision/driver"
|
||||
"github.com/yaoapp/yao/agent/vision/driver/local"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/neo/vision/driver"
|
||||
"github.com/yaoapp/yao/neo/vision/driver/local"
|
||||
"github.com/yaoapp/yao/test"
|
||||
)
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
package studio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/google/uuid"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou/plugin"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/utils"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/engine"
|
||||
"github.com/yaoapp/yao/share"
|
||||
"github.com/yaoapp/yao/studio"
|
||||
)
|
||||
|
||||
// *********************************************************************************
|
||||
// !! Yao Studio Command has been deprecated.
|
||||
// !! Do not use this command in your project.
|
||||
// *********************************************************************************
|
||||
|
||||
// RunCmd command
|
||||
var RunCmd = &cobra.Command{
|
||||
Use: "run",
|
||||
Short: L("Execute Yao Studio Script"),
|
||||
Long: L("Execute Yao Studio Script"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
defer share.SessionStop()
|
||||
defer plugin.KillAll()
|
||||
defer func() {
|
||||
err := exception.Catch(recover())
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
}
|
||||
}()
|
||||
|
||||
Boot()
|
||||
cfg := config.Conf
|
||||
cfg.Session.IsCLI = true
|
||||
|
||||
if len(args) < 1 {
|
||||
fmt.Println(color.RedString(L("Not enough arguments")))
|
||||
fmt.Println(color.WhiteString(share.BUILDNAME + " help"))
|
||||
return
|
||||
}
|
||||
|
||||
_, err := engine.Load(cfg, engine.LoadOption{Action: "studio.run"})
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Engine: %s"), err.Error()))
|
||||
}
|
||||
|
||||
err = studio.Load(cfg)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Studio: %s"), err.Error()))
|
||||
}
|
||||
|
||||
name := strings.Split(args[0], ".")
|
||||
service := strings.Join(name[0:len(name)-1], ".")
|
||||
method := name[len(name)-1]
|
||||
|
||||
fmt.Println(color.GreenString(L("Studio Run: %s"), args[0]))
|
||||
pargs := []interface{}{}
|
||||
for i, arg := range args {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(arg, "::") {
|
||||
arg := strings.TrimPrefix(arg, "::")
|
||||
var v interface{}
|
||||
err := jsoniter.Unmarshal([]byte(arg), &v)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Arguments: %s"), err.Error()))
|
||||
return
|
||||
}
|
||||
pargs = append(pargs, v)
|
||||
fmt.Println(color.WhiteString("args[%d]: %s", i-1, arg))
|
||||
} else if strings.HasPrefix(arg, "\\::") {
|
||||
arg := "::" + strings.TrimPrefix(arg, "\\::")
|
||||
pargs = append(pargs, arg)
|
||||
fmt.Println(color.WhiteString("args[%d]: %s", i-1, arg))
|
||||
} else {
|
||||
pargs = append(pargs, arg)
|
||||
fmt.Println(color.WhiteString("args[%d]: %s", i-1, arg))
|
||||
}
|
||||
}
|
||||
|
||||
script, err := v8.SelectRoot(service)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
}
|
||||
|
||||
sid := uuid.New().String()
|
||||
global := map[string]interface{}{}
|
||||
ctx, err := script.NewContext(sid, global)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
}
|
||||
defer ctx.Close()
|
||||
|
||||
res, err := ctx.Call(method, pargs...)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString("--------------------------------------"))
|
||||
fmt.Println(color.RedString(L("%s Error"), args[0]))
|
||||
fmt.Println(color.RedString("--------------------------------------"))
|
||||
utils.Dump(err)
|
||||
fmt.Println(color.RedString("--------------------------------------"))
|
||||
fmt.Println(color.GreenString(L("✨DONE✨")))
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(color.WhiteString("--------------------------------------"))
|
||||
fmt.Println(color.WhiteString(L("%s Response"), args[0]))
|
||||
fmt.Println(color.WhiteString("--------------------------------------"))
|
||||
utils.Dump(res)
|
||||
fmt.Println(color.WhiteString("--------------------------------------"))
|
||||
fmt.Println(color.GreenString(L("✨DONE✨")))
|
||||
},
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
package studio
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/config"
|
||||
)
|
||||
|
||||
var appPath string
|
||||
var envFile string
|
||||
|
||||
var langs = map[string]string{
|
||||
"Start Engine": "启动象传应用引擎",
|
||||
}
|
||||
|
||||
// L 多语言切换
|
||||
func L(words string) string {
|
||||
|
||||
var lang = os.Getenv("YAO_LANG")
|
||||
if lang == "" {
|
||||
return words
|
||||
}
|
||||
|
||||
if trans, has := langs[words]; has {
|
||||
return trans
|
||||
}
|
||||
return words
|
||||
}
|
||||
|
||||
// Boot 设定配置
|
||||
func Boot() {
|
||||
root := config.Conf.Root
|
||||
if appPath != "" {
|
||||
r, err := filepath.Abs(appPath)
|
||||
if err != nil {
|
||||
exception.New("Root error %s", 500, err.Error()).Throw()
|
||||
}
|
||||
root = r
|
||||
}
|
||||
if envFile != "" {
|
||||
config.Conf = config.LoadFrom(envFile)
|
||||
} else {
|
||||
config.Conf = config.LoadFrom(filepath.Join(root, ".env"))
|
||||
}
|
||||
|
||||
if config.Conf.Mode == "production" {
|
||||
config.Production()
|
||||
} else if config.Conf.Mode == "development" {
|
||||
config.Development()
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/process"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/agent"
|
||||
"github.com/yaoapp/yao/aigc"
|
||||
"github.com/yaoapp/yao/api"
|
||||
"github.com/yaoapp/yao/attachment"
|
||||
|
|
@ -25,7 +26,6 @@ import (
|
|||
"github.com/yaoapp/yao/messenger"
|
||||
"github.com/yaoapp/yao/moapi"
|
||||
"github.com/yaoapp/yao/model"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
"github.com/yaoapp/yao/openapi"
|
||||
"github.com/yaoapp/yao/pack"
|
||||
"github.com/yaoapp/yao/pipe"
|
||||
|
|
@ -298,7 +298,7 @@ func Load(cfg config.Config, options LoadOption) (warnings []Warning, err error)
|
|||
}
|
||||
|
||||
// Load Neo
|
||||
err = neo.Load(cfg)
|
||||
err = agent.Load(cfg)
|
||||
if err != nil {
|
||||
// printErr(cfg.Mode, "Neo", err)
|
||||
warnings = append(warnings, Warning{Widget: "Neo", Error: err})
|
||||
|
|
@ -528,7 +528,7 @@ func Reload(cfg config.Config, options LoadOption) (err error) {
|
|||
}
|
||||
|
||||
// Load Neo
|
||||
err = neo.Load(cfg)
|
||||
err = agent.Load(cfg)
|
||||
if err != nil {
|
||||
printErr(cfg.Mode, "Neo", err)
|
||||
}
|
||||
|
|
|
|||
61
neo/neo.go
61
neo/neo.go
|
|
@ -1,61 +0,0 @@
|
|||
package neo
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/session"
|
||||
"github.com/yaoapp/yao/neo/assistant"
|
||||
chatctx "github.com/yaoapp/yao/neo/context"
|
||||
)
|
||||
|
||||
// Answer reply the message
|
||||
func (neo *DSL) Answer(ctx chatctx.Context, question string, c *gin.Context) error {
|
||||
var err error
|
||||
var ast assistant.API = Neo.Assistant
|
||||
if ctx.AssistantID != "" {
|
||||
ast, err = neo.Select(ctx.AssistantID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = ast.Execute(c, ctx, question, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// Select select an assistant
|
||||
func (neo *DSL) Select(id string) (assistant.API, error) {
|
||||
if id == "" {
|
||||
return Neo.Assistant, nil
|
||||
}
|
||||
return assistant.Get(id)
|
||||
}
|
||||
|
||||
// UserID get the user id from the session
|
||||
func (neo *DSL) UserID(sid string) (interface{}, error) {
|
||||
fieldID := neo.AuthSetting.SessionFields.ID
|
||||
return session.Global().ID(sid).Get(fieldID)
|
||||
}
|
||||
|
||||
// GuestID get the guest id from the session
|
||||
func (neo *DSL) GuestID(sid string) (interface{}, error) {
|
||||
fieldGuest := neo.AuthSetting.SessionFields.Guest
|
||||
return session.Global().ID(sid).Get(fieldGuest)
|
||||
}
|
||||
|
||||
// UserRoles get the user roles from the session
|
||||
func (neo *DSL) UserRoles(sid string) (interface{}, error) {
|
||||
fieldRoles := neo.AuthSetting.SessionFields.Roles
|
||||
return session.Global().ID(sid).Get(fieldRoles)
|
||||
}
|
||||
|
||||
// UserOrGuestID get the user id or guest id from the session
|
||||
func (neo *DSL) UserOrGuestID(sid string) (interface{}, bool, error) {
|
||||
userID, err := neo.UserID(sid)
|
||||
if err != nil {
|
||||
guestID, err := neo.GuestID(sid)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return guestID, true, nil
|
||||
}
|
||||
return userID, false, nil
|
||||
}
|
||||
|
|
@ -2,16 +2,16 @@ package agent
|
|||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
"github.com/yaoapp/yao/agent"
|
||||
"github.com/yaoapp/yao/openapi/oauth/types"
|
||||
)
|
||||
|
||||
// Attach attaches the agent (assistant) API handlers to the router with OAuth protection
|
||||
// This provides OAuth-protected endpoints for assistant management, mirroring the neo assistant API
|
||||
// This provides OAuth-protected endpoints for assistant management, mirroring the agent assistant API
|
||||
func Attach(group *gin.RouterGroup, oauth types.OAuth) {
|
||||
|
||||
// Get the Neo instance
|
||||
n := neo.GetNeo()
|
||||
// Get the Agent instance
|
||||
n := agent.GetAgent()
|
||||
|
||||
// Create agents group with OAuth guard
|
||||
agents := group.Group("/agents")
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import (
|
|||
|
||||
"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/agent"
|
||||
chatctx "github.com/yaoapp/yao/agent/context"
|
||||
"github.com/yaoapp/yao/agent/message"
|
||||
"github.com/yaoapp/yao/openapi/oauth/types"
|
||||
)
|
||||
|
||||
|
|
@ -80,9 +80,9 @@ func chatCompletion(c *gin.Context) {
|
|||
ctx = chatctx.WithClientType(ctx, clientType)
|
||||
}
|
||||
|
||||
// Get neo instance and call Answer
|
||||
neoInstance := neo.GetNeo()
|
||||
err := neoInstance.Answer(ctx, content, c)
|
||||
// Get agent instance and call Answer
|
||||
agentInstance := agent.GetAgent()
|
||||
err := agentInstance.Answer(ctx, content, c)
|
||||
|
||||
// Error handling
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/yao/agent"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/kb"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
"github.com/yaoapp/yao/openapi"
|
||||
"github.com/yaoapp/yao/openapi/oauth"
|
||||
"github.com/yaoapp/yao/openapi/oauth/types"
|
||||
|
|
@ -155,7 +155,7 @@ func Prepare(t *testing.T) string {
|
|||
test.Prepare(t, config.Conf)
|
||||
|
||||
// Load Neo
|
||||
err := neo.Load(config.Conf)
|
||||
err := agent.Load(config.Conf)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load Neo: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/api"
|
||||
"github.com/yaoapp/gou/server/http"
|
||||
"github.com/yaoapp/yao/agent"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
"github.com/yaoapp/yao/openapi"
|
||||
"github.com/yaoapp/yao/share"
|
||||
)
|
||||
|
|
@ -36,9 +36,9 @@ func Start(cfg config.Config) (*http.Server, error) {
|
|||
Timeout: 5 * time.Second,
|
||||
})
|
||||
|
||||
// Neo API
|
||||
if neo.Neo != nil {
|
||||
neo.Neo.API(router, "/api/__yao/neo")
|
||||
// Agent API
|
||||
if agent.Agent != nil {
|
||||
agent.Agent.API(router, "/api/__yao/agent")
|
||||
}
|
||||
|
||||
// OpenAPI Server
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
package studio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/xun"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/helper"
|
||||
)
|
||||
|
||||
// hdRecovered custom recovered
|
||||
func hdRecovered(c *gin.Context, recovered interface{}) {
|
||||
|
||||
var code = http.StatusInternalServerError
|
||||
|
||||
if err, ok := recovered.(string); ok {
|
||||
c.JSON(code, xun.R{
|
||||
"code": code,
|
||||
"message": fmt.Sprintf("%s", err),
|
||||
})
|
||||
} else if err, ok := recovered.(exception.Exception); ok {
|
||||
code = err.Code
|
||||
c.JSON(code, xun.R{
|
||||
"code": code,
|
||||
"message": err.Message,
|
||||
})
|
||||
} else if err, ok := recovered.(*exception.Exception); ok {
|
||||
code = err.Code
|
||||
c.JSON(code, xun.R{
|
||||
"code": code,
|
||||
"message": err.Message,
|
||||
})
|
||||
} else {
|
||||
c.JSON(code, xun.R{
|
||||
"code": code,
|
||||
"message": fmt.Sprintf("%v", recovered),
|
||||
})
|
||||
}
|
||||
|
||||
c.AbortWithStatus(code)
|
||||
}
|
||||
|
||||
// CORS Cross-origin
|
||||
func hdCORS(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
// studio API Auth
|
||||
func hdAuth(c *gin.Context) {
|
||||
|
||||
tokenString := c.Request.Header.Get("Authorization")
|
||||
|
||||
// Get token from query
|
||||
if c.Query("studio") != "" {
|
||||
tokenString = c.Query("studio")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(tokenString, "Bearer") {
|
||||
tokenString = strings.TrimSpace(strings.TrimPrefix(tokenString, "Bearer "))
|
||||
if tokenString == "" {
|
||||
c.JSON(401, gin.H{"code": 401, "message": "Not authenticated"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
claims := helper.JwtValidate(tokenString, []byte(config.Conf.Studio.Secret))
|
||||
c.Set("__sid", claims.SID)
|
||||
c.Next()
|
||||
return
|
||||
|
||||
} else if strings.HasPrefix(tokenString, "Signature ") { // For Yao Studio
|
||||
signature := strings.TrimSpace(strings.TrimPrefix(tokenString, "Signature "))
|
||||
nonce := c.Request.Header.Get("Studio-Nonce")
|
||||
ts := c.Request.Header.Get("Studio-Timestamp")
|
||||
query := c.Request.URL.Query()
|
||||
log.Trace("[Studio] %s, %s %s %v", signature, nonce, ts, query)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(403, gin.H{"code": 403, "message": "No permission"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
261
studio/router.go
261
studio/router.go
|
|
@ -1,261 +0,0 @@
|
|||
package studio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
)
|
||||
|
||||
var regExcp = regexp.MustCompile(`Exception\|(\d+):(.*)`)
|
||||
|
||||
// Serve start the api server
|
||||
func setRouter(router *gin.Engine) {
|
||||
|
||||
router.Use(gin.CustomRecovery(hdRecovered), hdCORS, hdAuth)
|
||||
|
||||
// DSL ReadDir, ReadFile
|
||||
router.GET("/dsl/:method", func(c *gin.Context) {
|
||||
method := strings.ToLower(c.Param("method"))
|
||||
switch method {
|
||||
|
||||
case "readfile":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "file name is required")
|
||||
return
|
||||
}
|
||||
|
||||
data, err := dfs.ReadFile(name)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := map[string]interface{}{}
|
||||
err = jsoniter.Unmarshal(data, &res)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(200, res)
|
||||
c.Done()
|
||||
return
|
||||
|
||||
case "readdir":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "dir name is required")
|
||||
return
|
||||
}
|
||||
|
||||
recursive := false
|
||||
if c.Query("recursive") == "1" || strings.ToLower(c.Query("recursive")) == "true" {
|
||||
recursive = true
|
||||
}
|
||||
data, err := dfs.ReadDir(name, recursive)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(200, data)
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
throw(c, 404, fmt.Sprintf("%s method does not found", c.Param("method")))
|
||||
})
|
||||
|
||||
// DSL WriteFile, Mkdir, MkdirAll, Remove, RemoveAll ...
|
||||
router.POST("/dsl/:method", func(c *gin.Context) {
|
||||
|
||||
method := strings.ToLower(c.Param("method"))
|
||||
switch method {
|
||||
case "writefile":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "dir name is required")
|
||||
return
|
||||
}
|
||||
|
||||
payload, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if payload == nil || len(payload) == 0 {
|
||||
throw(c, 500, "file content is required")
|
||||
return
|
||||
}
|
||||
|
||||
length, err := dfs.WriteFile(name, payload, 0644)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, length)
|
||||
c.Done()
|
||||
return
|
||||
|
||||
case "mkdir":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "dir name is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := dfs.Mkdir(name, uint32(os.ModePerm))
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
c.Done()
|
||||
return
|
||||
|
||||
case "mkdirall":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "dir name is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := dfs.MkdirAll(name, uint32(os.ModePerm))
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
c.Done()
|
||||
return
|
||||
|
||||
case "remove":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "name is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := dfs.Remove(name)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
c.Done()
|
||||
return
|
||||
|
||||
case "removeall":
|
||||
name := c.Query("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "name is required")
|
||||
return
|
||||
}
|
||||
|
||||
err := dfs.RemoveAll(name)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
c.Status(200)
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
throw(c, 404, fmt.Sprintf("%s method does not found", c.Param("method")))
|
||||
})
|
||||
|
||||
// Cloud Functions
|
||||
router.POST("/service/:name", func(c *gin.Context) {
|
||||
|
||||
name := c.Param("name")
|
||||
if name == "" {
|
||||
throw(c, 400, "service name is required")
|
||||
return
|
||||
}
|
||||
|
||||
service := c.Param("name")
|
||||
|
||||
payload, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if payload == nil || len(payload) == 0 {
|
||||
throw(c, 400, "file content is required")
|
||||
return
|
||||
}
|
||||
|
||||
var fun cfunc
|
||||
err = jsoniter.Unmarshal(payload, &fun)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
sid, _ := c.Get("__sid")
|
||||
script, err := v8.SelectRoot(service)
|
||||
if err != nil {
|
||||
throw(c, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ctx, err := script.NewContext(fmt.Sprintf("%v", sid), nil)
|
||||
if err != nil {
|
||||
code := 500
|
||||
message := err.Error()
|
||||
match := regExcp.FindStringSubmatch(message)
|
||||
if len(match) > 0 {
|
||||
code, err = strconv.Atoi(match[1])
|
||||
if err == nil {
|
||||
message = strings.TrimSpace(match[2])
|
||||
}
|
||||
}
|
||||
throw(c, code, message)
|
||||
return
|
||||
}
|
||||
defer ctx.Close()
|
||||
|
||||
res, err := ctx.Call(fun.Method, fun.Args...)
|
||||
if err != nil {
|
||||
code := 500
|
||||
message := err.Error()
|
||||
match := regExcp.FindStringSubmatch(message)
|
||||
if len(match) > 0 {
|
||||
code, err = strconv.Atoi(match[1])
|
||||
if err == nil {
|
||||
message = strings.TrimSpace(match[2])
|
||||
}
|
||||
}
|
||||
throw(c, code, message)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, res)
|
||||
c.Done()
|
||||
})
|
||||
|
||||
// Neo API for studio
|
||||
if neo.Neo != nil {
|
||||
neo.Neo.API(router, "/neo")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func throw(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, map[string]interface{}{
|
||||
"message": message,
|
||||
"code": code,
|
||||
})
|
||||
c.Done()
|
||||
}
|
||||
111
studio/studio.go
111
studio/studio.go
|
|
@ -1,111 +0,0 @@
|
|||
package studio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/yao/config"
|
||||
)
|
||||
|
||||
var shutdownSignal = make(chan bool, 1)
|
||||
var dfs fs.FileSystem
|
||||
var scripts = map[string][]byte{}
|
||||
|
||||
type cfunc struct {
|
||||
Method string `json:"method"`
|
||||
Args []interface{} `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
// Start start the studio api server
|
||||
func Start(cfg config.Config) (err error) {
|
||||
return fmt.Errorf("studio is deprecated")
|
||||
|
||||
// // recive interrupt signal
|
||||
// interrupt := make(chan os.Signal, 1)
|
||||
// signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
|
||||
// errCh := make(chan error, 1)
|
||||
|
||||
// // Set router
|
||||
// router := gin.New()
|
||||
// setRouter(router)
|
||||
|
||||
// // Server setting
|
||||
// addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Studio.Port)
|
||||
// srv := &http.Server{
|
||||
// Addr: addr,
|
||||
// Handler: router,
|
||||
// }
|
||||
|
||||
// // Listen
|
||||
// l, err := net.Listen("tcp", addr)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// defer func() {
|
||||
// log.Info("[Studio] %s Close Serve", addr)
|
||||
// err = srv.Close()
|
||||
// if err != nil {
|
||||
// log.Error("[Studio] Close Serve Error (%v)", err)
|
||||
// }
|
||||
// }()
|
||||
|
||||
// // start serve
|
||||
// go func() {
|
||||
// log.Info("[Studio] Starting: %s", addr)
|
||||
// if err := srv.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
// errCh <- err
|
||||
// }
|
||||
// }()
|
||||
|
||||
// select {
|
||||
|
||||
// case <-shutdownSignal:
|
||||
// log.Info("[Studio] %s Exit (Manual)", addr)
|
||||
// return err
|
||||
|
||||
// case <-interrupt:
|
||||
// log.Info("[Studio] %s Exit (Interrupt) ", addr)
|
||||
// return err
|
||||
|
||||
// case err := <-errCh:
|
||||
// log.Error("[Studio] %s Error (%v)", addr, err)
|
||||
// return err
|
||||
// }
|
||||
}
|
||||
|
||||
// Stop stop the studio api server
|
||||
func Stop() {
|
||||
shutdownSignal <- true
|
||||
}
|
||||
|
||||
// Load studio config
|
||||
func Load(cfg config.Config) error {
|
||||
return fmt.Errorf("studio is deprecated")
|
||||
|
||||
// err := loadDSL(cfg)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return loadScripts()
|
||||
}
|
||||
|
||||
func loadDSL(cfg config.Config) error {
|
||||
return fmt.Errorf("studio is deprecated")
|
||||
// dslDenyList := []string{cfg.DataRoot}
|
||||
// dfs = dsl.New(cfg.AppSource).DenyAbs(dslDenyList...)
|
||||
// return nil
|
||||
}
|
||||
|
||||
func loadScripts() error {
|
||||
return fmt.Errorf("studio is deprecated")
|
||||
// exts := []string{"*.js"}
|
||||
// return application.App.Walk("studio", func(root, file string, isdir bool) error {
|
||||
// if isdir {
|
||||
// return nil
|
||||
// }
|
||||
// _, err := v8.LoadRoot(file, share.ID(root, file))
|
||||
// return err
|
||||
// }, exts...)
|
||||
}
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
package studio
|
||||
|
||||
// import (
|
||||
// "bytes"
|
||||
// "fmt"
|
||||
// "io"
|
||||
// "net/http"
|
||||
// "testing"
|
||||
// "time"
|
||||
|
||||
// jsoniter "github.com/json-iterator/go"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// "github.com/yaoapp/yao/config"
|
||||
// "github.com/yaoapp/yao/helper"
|
||||
// "github.com/yaoapp/yao/test"
|
||||
// )
|
||||
|
||||
// type kv map[string]interface{}
|
||||
// type arr []interface{}
|
||||
|
||||
// func TestLoad(t *testing.T) {
|
||||
|
||||
// test.Prepare(t, config.Conf)
|
||||
// defer test.Clean()
|
||||
|
||||
// err := Load(config.Conf)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// // res, err := gou.Yao.Engine.RootCall(map[string]interface{}{}, "table", "Ping")
|
||||
// // assert.Nil(t, err)
|
||||
// // assert.Equal(t, "PONG", res)
|
||||
|
||||
// // _, err = gou.Yao.Engine.Call(map[string]interface{}{}, "table", "Ping")
|
||||
// // assert.NotNil(t, err)
|
||||
// // assert.Contains(t, err.Error(), "The table does not loaded")
|
||||
// }
|
||||
|
||||
// func TestStartStop(t *testing.T) {
|
||||
|
||||
// test.Prepare(t, config.Conf)
|
||||
// defer test.Clean()
|
||||
|
||||
// var err error
|
||||
// go func() { err = Start(config.Conf) }()
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// time.Sleep(500 * time.Millisecond)
|
||||
// Stop()
|
||||
// time.Sleep(100 * time.Millisecond)
|
||||
// }
|
||||
|
||||
// func TestStartStopError(t *testing.T) {
|
||||
|
||||
// test.Prepare(t, config.Conf)
|
||||
// defer test.Clean()
|
||||
|
||||
// var err error
|
||||
// go func() { err = Start(config.Conf) }()
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// time.Sleep(500 * time.Millisecond)
|
||||
// go func() { err = Start(config.Conf) }()
|
||||
// time.Sleep(100 * time.Millisecond)
|
||||
// assert.NotNil(t, err)
|
||||
|
||||
// Stop()
|
||||
// time.Sleep(100 * time.Millisecond)
|
||||
// }
|
||||
|
||||
// func TestAPI(t *testing.T) {
|
||||
|
||||
// test.Prepare(t, config.Conf)
|
||||
// defer test.Clean()
|
||||
|
||||
// Load(config.Conf)
|
||||
|
||||
// var err error
|
||||
// go func() { err = Start(config.Conf) }()
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// defer Stop()
|
||||
// time.Sleep(500 * time.Millisecond)
|
||||
|
||||
// code, row := httpGet[kv]("/dsl/ReadFile?name=/models/user.mod.yao", t)
|
||||
// assert.Equal(t, 200, code)
|
||||
// assert.Equal(t, "User", row["name"])
|
||||
|
||||
// code, rows := httpGet[arr]("/dsl/ReadDir?name=/models", t)
|
||||
// assert.Equal(t, 200, code)
|
||||
// assert.Equal(t, 8, len(rows))
|
||||
|
||||
// code, rows = httpGet[arr]("/dsl/ReadDir?name=/models&recursive=1", t)
|
||||
// assert.Equal(t, 200, code)
|
||||
// assert.Equal(t, 13, len(rows))
|
||||
|
||||
// code, length := httpPost[int]("/dsl/WriteFile?name=/models/foo.mod.yao", []byte(`{"name":"foo"}`), t)
|
||||
// assert.Equal(t, 200, code)
|
||||
// assert.Equal(t, 19, length)
|
||||
|
||||
// code, _ = httpPost[kv]("/dsl/Remove?name=/models/foo.mod.yao", nil, t)
|
||||
// assert.Equal(t, 200, code)
|
||||
|
||||
// code, _ = httpPost[kv]("/dsl/Mkdir?name=/models/bar", nil, t)
|
||||
// assert.Equal(t, 200, code)
|
||||
|
||||
// code, _ = httpPost[kv]("/dsl/Remove?name=/models/bar", nil, t)
|
||||
// assert.Equal(t, 200, code)
|
||||
|
||||
// code, _ = httpPost[kv]("/dsl/MkdirAll?name=/models/bar/hi", nil, t)
|
||||
// assert.Equal(t, 200, code)
|
||||
|
||||
// code, _ = httpPost[kv]("/dsl/RemoveAll?name=/models/bar", nil, t)
|
||||
// assert.Equal(t, 200, code)
|
||||
|
||||
// code, res := httpPostJSON[arr](
|
||||
// "/service/table",
|
||||
// kv{
|
||||
// "method": "UnitTest",
|
||||
// "args": []interface{}{
|
||||
// "foo", 1, 0.618,
|
||||
// kv{"string": "world", "int": 1, "float": 0.618},
|
||||
// arr{"foo", 1, 0.618},
|
||||
// },
|
||||
// }, t)
|
||||
|
||||
// assert.Equal(t, 200, code)
|
||||
// assert.Equal(t, "foo", res[0])
|
||||
// assert.Equal(t, float64(1), res[1])
|
||||
// assert.Equal(t, 0.618, res[2])
|
||||
// assert.Equal(t, "world", res[3].(map[string]interface{})["string"])
|
||||
// assert.Equal(t, float64(1), res[3].(map[string]interface{})["int"])
|
||||
// assert.Equal(t, 0.618, res[3].(map[string]interface{})["float"])
|
||||
// assert.Equal(t, "foo", res[4].([]interface{})[0])
|
||||
// assert.Equal(t, float64(1), res[4].([]interface{})[1])
|
||||
// assert.Equal(t, 0.618, res[4].([]interface{})[2])
|
||||
|
||||
// code, excp := httpPostJSON[kv]("/service/table", kv{"method": "UnitTest", "args": []interface{}{"throw-test"}}, t)
|
||||
// assert.Equal(t, 418, code)
|
||||
// assert.Equal(t, float64(418), excp["code"])
|
||||
// assert.Equal(t, "I'm a teapot", excp["message"])
|
||||
// }
|
||||
|
||||
// func httpGet[T kv | arr | interface{} | map[string]interface{} | int | []interface{}](url string, t *testing.T) (int, T) {
|
||||
|
||||
// var data T
|
||||
// url = fmt.Sprintf("http://127.0.0.1:%d%s", config.Conf.Studio.Port, url)
|
||||
// req, err := http.NewRequest("GET", url, nil)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// token := getToken(t)
|
||||
// req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
|
||||
// client := http.Client{}
|
||||
// res, err := client.Do(req)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// if res.Body != nil {
|
||||
// body, err := io.ReadAll(res.Body)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// if body != nil && len(body) > 0 {
|
||||
// err = jsoniter.Unmarshal(body, &data)
|
||||
// if err != nil {
|
||||
// t.Fatal(fmt.Sprintf("%s\n%s\n", err.Error(), string(body)))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return res.StatusCode, data
|
||||
// }
|
||||
|
||||
// func httpPost[T kv | arr | interface{} | map[string]interface{} | int | []interface{}](url string, payload []byte, t *testing.T) (int, T) {
|
||||
|
||||
// var data T
|
||||
// var buff *bytes.Buffer = bytes.NewBuffer([]byte{})
|
||||
|
||||
// if payload != nil {
|
||||
// buff = bytes.NewBuffer(payload)
|
||||
// }
|
||||
|
||||
// url = fmt.Sprintf("http://127.0.0.1:%d%s", config.Conf.Studio.Port, url)
|
||||
// req, err := http.NewRequest("POST", url, buff)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// token := getToken(t)
|
||||
// req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
|
||||
// client := http.Client{}
|
||||
// res, err := client.Do(req)
|
||||
// if res.Body != nil {
|
||||
// body, err := io.ReadAll(res.Body)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
// if body != nil && string(body) != "" {
|
||||
// err = jsoniter.Unmarshal(body, &data)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return res.StatusCode, data
|
||||
// }
|
||||
|
||||
// func httpPostJSON[T kv | arr | interface{} | map[string]interface{} | int | []interface{}](url string, payload interface{}, t *testing.T) (int, T) {
|
||||
// var data []byte
|
||||
// var err error
|
||||
// if payload != nil {
|
||||
// data, err = jsoniter.Marshal(payload)
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
// return httpPost[T](url, data, t)
|
||||
// }
|
||||
|
||||
// func getToken(t *testing.T) string {
|
||||
// return helper.JwtMake(
|
||||
// 1,
|
||||
// map[string]interface{}{"id": 1, "user_id": 1, "user": kv{"id": 1, "name": "test"}},
|
||||
// map[string]interface{}{"issuer": "unit-test", "timeout": 3600},
|
||||
// []byte(config.Conf.Studio.Secret),
|
||||
// ).Token
|
||||
// }
|
||||
|
|
@ -18,13 +18,13 @@ import (
|
|||
"github.com/yaoapp/gou/session"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/agent"
|
||||
"github.com/yaoapp/yao/agent/assistant"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/data"
|
||||
"github.com/yaoapp/yao/i18n"
|
||||
"github.com/yaoapp/yao/kb"
|
||||
kbtypes "github.com/yaoapp/yao/kb/types"
|
||||
"github.com/yaoapp/yao/neo"
|
||||
"github.com/yaoapp/yao/neo/assistant"
|
||||
"github.com/yaoapp/yao/openapi"
|
||||
"github.com/yaoapp/yao/share"
|
||||
"github.com/yaoapp/yao/widgets/login"
|
||||
|
|
@ -273,11 +273,11 @@ func processService(process *process.Process) interface{} {
|
|||
}
|
||||
|
||||
//
|
||||
// Forward: Neo confirm Command
|
||||
// @file neo/command/request.go
|
||||
// Forward: Agent confirm Command
|
||||
// @file agent/command/request.go
|
||||
// @method func (req *Request) confirm(args []interface{}, cb func(msg *message.JSON) int)
|
||||
//
|
||||
if service == "__yao_service.__neo" && method == "ExecCommand" {
|
||||
if service == "__yao_service.__agent" && method == "ExecCommand" {
|
||||
if len(args) < 4 {
|
||||
exception.New("args is required (%v)", 400, args).Throw()
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ func processService(process *process.Process) interface{} {
|
|||
ctx := args[3].(map[string]interface{})
|
||||
processName := args[1].(string)
|
||||
processArgs := append(args[2].([]interface{}), ctx)
|
||||
result := forwardNeoExecCommand(process, processName, processArgs...)
|
||||
result := forwardAgentExecCommand(process, processName, processArgs...)
|
||||
return map[string]interface{}{"id": id, "result": result, "context": ctx}
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ func processService(process *process.Process) interface{} {
|
|||
return res
|
||||
}
|
||||
|
||||
func forwardNeoExecCommand(p *process.Process, name string, args ...interface{}) interface{} {
|
||||
func forwardAgentExecCommand(p *process.Process, name string, args ...interface{}) interface{} {
|
||||
new, err := process.Of(name, args...)
|
||||
if err != nil {
|
||||
exception.New(err.Error(), 400).Throw()
|
||||
|
|
@ -550,10 +550,10 @@ func processXgen(process *process.Process) interface{} {
|
|||
}
|
||||
|
||||
// The default assistant
|
||||
agent := map[string]interface{}{}
|
||||
if neo.Neo != nil {
|
||||
if ast, ok := neo.Neo.Assistant.(*assistant.Assistant); ok {
|
||||
agent["default"] = map[string]interface{}{
|
||||
agentConfig := map[string]interface{}{}
|
||||
if agent.Agent != nil {
|
||||
if ast, ok := agent.Agent.Assistant.(*assistant.Assistant); ok {
|
||||
agentConfig["default"] = map[string]interface{}{
|
||||
"assistant_id": ast.ID,
|
||||
"assistant_name": ast.Name,
|
||||
"assistant_avatar": ast.Avatar,
|
||||
|
|
@ -563,27 +563,27 @@ func processXgen(process *process.Process) interface{} {
|
|||
}
|
||||
|
||||
// Available connectors
|
||||
agent["connectors"] = connector.AIConnectors
|
||||
agentConfig["connectors"] = connector.AIConnectors
|
||||
|
||||
// Available storages
|
||||
agent["storages"] = map[string]interface{}{
|
||||
agentConfig["storages"] = map[string]interface{}{
|
||||
"chat": map[string]interface{}{
|
||||
"max_size": neo.Neo.UploadSetting.Chat.MaxSize,
|
||||
"chunk_size": neo.Neo.UploadSetting.Chat.ChunkSize,
|
||||
"allowed_types": neo.Neo.UploadSetting.Chat.AllowedTypes,
|
||||
"gzip": neo.Neo.UploadSetting.Chat.Gzip,
|
||||
"max_size": agent.Agent.UploadSetting.Chat.MaxSize,
|
||||
"chunk_size": agent.Agent.UploadSetting.Chat.ChunkSize,
|
||||
"allowed_types": agent.Agent.UploadSetting.Chat.AllowedTypes,
|
||||
"gzip": agent.Agent.UploadSetting.Chat.Gzip,
|
||||
},
|
||||
"assets": map[string]interface{}{
|
||||
"max_size": neo.Neo.UploadSetting.Assets.MaxSize,
|
||||
"chunk_size": neo.Neo.UploadSetting.Assets.ChunkSize,
|
||||
"allowed_types": neo.Neo.UploadSetting.Assets.AllowedTypes,
|
||||
"gzip": neo.Neo.UploadSetting.Assets.Gzip,
|
||||
"max_size": agent.Agent.UploadSetting.Assets.MaxSize,
|
||||
"chunk_size": agent.Agent.UploadSetting.Assets.ChunkSize,
|
||||
"allowed_types": agent.Agent.UploadSetting.Assets.AllowedTypes,
|
||||
"gzip": agent.Agent.UploadSetting.Assets.Gzip,
|
||||
},
|
||||
"knowledge": map[string]interface{}{
|
||||
"max_size": neo.Neo.UploadSetting.Knowledge.MaxSize,
|
||||
"chunk_size": neo.Neo.UploadSetting.Knowledge.ChunkSize,
|
||||
"allowed_types": neo.Neo.UploadSetting.Knowledge.AllowedTypes,
|
||||
"gzip": neo.Neo.UploadSetting.Knowledge.Gzip,
|
||||
"max_size": agent.Agent.UploadSetting.Knowledge.MaxSize,
|
||||
"chunk_size": agent.Agent.UploadSetting.Knowledge.ChunkSize,
|
||||
"allowed_types": agent.Agent.UploadSetting.Knowledge.AllowedTypes,
|
||||
"gzip": agent.Agent.UploadSetting.Knowledge.Gzip,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -695,7 +695,7 @@ func processXgen(process *process.Process) interface{} {
|
|||
"token": Setting.Token,
|
||||
"optional": Setting.Optional,
|
||||
"login": xgenLogin,
|
||||
"agent": agent,
|
||||
"agent": agentConfig,
|
||||
"openapi": openapiConfig,
|
||||
"kb": kbConfig,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue