Merge pull request #944 from trheyi/main
feat: Enhance context management and update asset metadata in SUI
This commit is contained in:
commit
ac55508e05
10 changed files with 335 additions and 501 deletions
168
data/bindata.go
168
data/bindata.go
File diff suppressed because one or more lines are too long
235
neo/api.go
235
neo/api.go
|
|
@ -134,15 +134,6 @@ func (neo *DSL) API(router *gin.Engine, path string) error {
|
||||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/mentions?keywords=assistant&token=xxx'
|
// curl -X GET 'http://localhost:5099/api/__yao/neo/mentions?keywords=assistant&token=xxx'
|
||||||
router.GET(path+"/mentions", append(middlewares, neo.handleMentions)...)
|
router.GET(path+"/mentions", append(middlewares, neo.handleMentions)...)
|
||||||
|
|
||||||
// Generation endpoints
|
|
||||||
// Generate custom content example:
|
|
||||||
// curl -X GET 'http://localhost:5099/api/__yao/neo/generate?content=Generate+something&type=custom&system_prompt=You+are+a+helpful+assistant&chat_id=chat_123&token=xxx'
|
|
||||||
// curl -X POST 'http://localhost:5099/api/__yao/neo/generate' \
|
|
||||||
// -H 'Content-Type: application/json' \
|
|
||||||
// -d '{"content": "Generate something", "type": "custom", "system_prompt": "You are a helpful assistant", "chat_id": "chat_123", "token": "xxx"}'
|
|
||||||
router.GET(path+"/generate", append(middlewares, neo.handleGenerateCustom)...)
|
|
||||||
router.POST(path+"/generate", append(middlewares, neo.handleGenerateCustom)...)
|
|
||||||
|
|
||||||
// Generate title example:
|
// 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 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 POST 'http://localhost:5099/api/__yao/neo/generate/title' \
|
||||||
|
|
@ -238,6 +229,24 @@ func (neo *DSL) handleChat(c *gin.Context) {
|
||||||
ctx = chatctx.WithAssistantID(ctx, assistantID)
|
ctx = chatctx.WithAssistantID(ctx, assistantID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the silent mode
|
||||||
|
silent := c.Query("silent")
|
||||||
|
if silent == "true" || silent == "1" {
|
||||||
|
ctx = chatctx.WithSilent(ctx, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the history visible
|
||||||
|
historyVisible := c.Query("history_visible")
|
||||||
|
if historyVisible != "" {
|
||||||
|
ctx = chatctx.WithHistoryVisible(ctx, historyVisible == "true" || historyVisible == "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the client type
|
||||||
|
clientType := c.Query("client_type")
|
||||||
|
if clientType != "" {
|
||||||
|
ctx = chatctx.WithClientType(ctx, clientType)
|
||||||
|
}
|
||||||
|
|
||||||
err := neo.Answer(ctx, content, c)
|
err := neo.Answer(ctx, content, c)
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
|
|
@ -485,7 +494,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
||||||
// Create a new chat
|
// Create a new chat
|
||||||
if len(chats.Groups) == 0 || len(chats.Groups[0].Chats) == 0 {
|
if len(chats.Groups) == 0 || len(chats.Groups[0].Chats) == 0 {
|
||||||
|
|
||||||
assistantID := neo.Use
|
assistantID := neo.Use.Default
|
||||||
queryAssistantID := c.Query("assistant_id")
|
queryAssistantID := c.Query("assistant_id")
|
||||||
if queryAssistantID != "" {
|
if queryAssistantID != "" {
|
||||||
assistantID = queryAssistantID
|
assistantID = queryAssistantID
|
||||||
|
|
@ -504,7 +513,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
||||||
"assistant_id": ast.ID,
|
"assistant_id": ast.ID,
|
||||||
"assistant_name": ast.Name,
|
"assistant_name": ast.Name,
|
||||||
"assistant_avatar": ast.Avatar,
|
"assistant_avatar": ast.Avatar,
|
||||||
"assistant_deleteable": neo.Use != ast.ID,
|
"assistant_deleteable": neo.Use.Default != ast.ID,
|
||||||
}})
|
}})
|
||||||
c.Done()
|
c.Done()
|
||||||
return
|
return
|
||||||
|
|
@ -530,7 +539,7 @@ func (neo *DSL) handleChatLatest(c *gin.Context) {
|
||||||
chat.Chat["assistant_id"] = neo.Use
|
chat.Chat["assistant_id"] = neo.Use
|
||||||
|
|
||||||
// Get the assistant info
|
// Get the assistant info
|
||||||
ast, err := assistant.Get(neo.Use)
|
ast, err := assistant.Get(neo.Use.Default)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||||
c.Done()
|
c.Done()
|
||||||
|
|
@ -573,7 +582,7 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
||||||
chat.Chat["assistant_id"] = neo.Use
|
chat.Chat["assistant_id"] = neo.Use
|
||||||
|
|
||||||
// Get the assistant info
|
// Get the assistant info
|
||||||
ast, err := assistant.Get(neo.Use)
|
ast, err := assistant.Get(neo.Use.Default)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||||
c.Done()
|
c.Done()
|
||||||
|
|
@ -583,7 +592,7 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
||||||
chat.Chat["assistant_avatar"] = ast.Avatar
|
chat.Chat["assistant_avatar"] = ast.Avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
chat.Chat["assistant_deleteable"] = neo.Use != chat.Chat["assistant_id"]
|
chat.Chat["assistant_deleteable"] = neo.Use.Default != chat.Chat["assistant_id"]
|
||||||
c.JSON(200, map[string]interface{}{"data": chat})
|
c.JSON(200, map[string]interface{}{"data": chat})
|
||||||
c.Done()
|
c.Done()
|
||||||
}
|
}
|
||||||
|
|
@ -659,20 +668,6 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If content is not empty, Generate the chat title
|
|
||||||
if body.Content != "" {
|
|
||||||
ctx, cancel := chatctx.NewWithCancel(sid, c.Query("chat_id"), "")
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
title, err := neo.GenerateChatTitle(ctx, body.Content, c, true)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
|
||||||
c.Done()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
body.Title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
if body.Title == "" {
|
if body.Title == "" {
|
||||||
c.JSON(400, gin.H{"message": "title is required", "code": 400})
|
c.JSON(400, gin.H{"message": "title is required", "code": 400})
|
||||||
c.Done()
|
c.Done()
|
||||||
|
|
@ -813,155 +808,81 @@ func (r *generateResponse) send(key string) {
|
||||||
|
|
||||||
// handleGenerateTitle handles generating a chat title
|
// handleGenerateTitle handles generating a chat title
|
||||||
func (neo *DSL) handleGenerateTitle(c *gin.Context) {
|
func (neo *DSL) handleGenerateTitle(c *gin.Context) {
|
||||||
var content string
|
// Set headers for SSE
|
||||||
if c.Request.Method == "GET" {
|
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
||||||
content = c.Query("content")
|
c.Header("Cache-Control", "no-cache")
|
||||||
} else {
|
c.Header("Connection", "keep-alive")
|
||||||
var body struct {
|
|
||||||
Content string `json:"content"`
|
sid := c.GetString("__sid")
|
||||||
}
|
if sid == "" {
|
||||||
if err := c.BindJSON(&body); err != nil {
|
sid = uuid.New().String()
|
||||||
// For SSE requests, send error message in SSE format
|
|
||||||
if strings.Contains(c.GetHeader("Accept"), "text/event-stream") {
|
|
||||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
|
||||||
c.Header("Cache-Control", "no-cache")
|
|
||||||
c.Header("Connection", "keep-alive")
|
|
||||||
msg := message.New().Error("invalid request body").Done()
|
|
||||||
msg.Write(c.Writer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
content = body.Content
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &generateResponse{
|
content := c.Query("content")
|
||||||
c: c,
|
if content == "" {
|
||||||
sid: c.GetString("__sid"),
|
msg := message.New().Error("content is required").Done()
|
||||||
content: content,
|
msg.Write(c.Writer)
|
||||||
}
|
|
||||||
|
|
||||||
// For SSE requests, set headers before validation
|
|
||||||
if strings.Contains(c.GetHeader("Accept"), "text/event-stream") {
|
|
||||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
|
||||||
c.Header("Cache-Control", "no-cache")
|
|
||||||
c.Header("Connection", "keep-alive")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.validate() {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := chatctx.NewWithCancel(resp.sid, c.Query("chat_id"), "")
|
chatID := fmt.Sprintf("generate_title_%d", time.Now().UnixNano())
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Use silent mode for regular HTTP requests, streaming for SSE
|
// Set the context with validated chat_id
|
||||||
silent := !strings.Contains(c.GetHeader("Accept"), "text/event-stream")
|
ctx, cancel := chatctx.NewWithCancel(sid, chatID, c.Query("context"))
|
||||||
resp.result, resp.err = neo.GenerateChatTitle(ctx, resp.content, c, silent)
|
defer cancel()
|
||||||
resp.send("result")
|
defer ctx.Release() // Release the context after the request is done
|
||||||
|
|
||||||
|
// Set the assistant ID
|
||||||
|
ctx = chatctx.WithHistoryVisible(ctx, false)
|
||||||
|
ctx = chatctx.WithAssistantID(ctx, neo.Use.Title)
|
||||||
|
|
||||||
|
err := neo.Answer(ctx, content, c)
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
if err != nil {
|
||||||
|
message.New().Done().Error(err).Write(c.Writer)
|
||||||
|
c.Done()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGeneratePrompts handles generating prompts
|
// handleGeneratePrompts handles generating prompts
|
||||||
func (neo *DSL) handleGeneratePrompts(c *gin.Context) {
|
func (neo *DSL) handleGeneratePrompts(c *gin.Context) {
|
||||||
var content string
|
// Set headers for SSE
|
||||||
if c.Request.Method == "GET" {
|
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
||||||
content = c.Query("content")
|
c.Header("Cache-Control", "no-cache")
|
||||||
} else {
|
c.Header("Connection", "keep-alive")
|
||||||
var body struct {
|
|
||||||
Content string `json:"content"`
|
sid := c.GetString("__sid")
|
||||||
}
|
if sid == "" {
|
||||||
if err := c.BindJSON(&body); err != nil {
|
sid = uuid.New().String()
|
||||||
// For SSE requests, send error message in SSE format
|
|
||||||
if strings.Contains(c.GetHeader("Accept"), "text/event-stream") {
|
|
||||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
|
||||||
c.Header("Cache-Control", "no-cache")
|
|
||||||
c.Header("Connection", "keep-alive")
|
|
||||||
msg := message.New().Error("invalid request body").Done()
|
|
||||||
msg.Write(c.Writer)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
content = body.Content
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &generateResponse{
|
content := c.Query("content")
|
||||||
c: c,
|
if content == "" {
|
||||||
sid: c.GetString("__sid"),
|
msg := message.New().Error("content is required").Done()
|
||||||
content: content,
|
msg.Write(c.Writer)
|
||||||
}
|
|
||||||
|
|
||||||
// For SSE requests, set headers before validation
|
|
||||||
if strings.Contains(c.GetHeader("Accept"), "text/event-stream") {
|
|
||||||
c.Header("Content-Type", "text/event-stream;charset=utf-8")
|
|
||||||
c.Header("Cache-Control", "no-cache")
|
|
||||||
c.Header("Connection", "keep-alive")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.validate() {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := chatctx.NewWithCancel(resp.sid, c.Query("chat_id"), "")
|
chatID := fmt.Sprintf("generate_prompts_%d", time.Now().UnixNano())
|
||||||
|
|
||||||
|
// Set the context with validated chat_id
|
||||||
|
ctx, cancel := chatctx.NewWithCancel(sid, chatID, c.Query("context"))
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
defer ctx.Release() // Release the context after the request is done
|
||||||
|
|
||||||
// Use silent mode for regular HTTP requests, streaming for SSE
|
// Set the assistant ID
|
||||||
silent := !strings.Contains(c.GetHeader("Accept"), "text/event-stream")
|
ctx = chatctx.WithHistoryVisible(ctx, false)
|
||||||
resp.result, resp.err = neo.GeneratePrompts(ctx, resp.content, c, silent)
|
ctx = chatctx.WithAssistantID(ctx, neo.Use.Prompt)
|
||||||
resp.send("result")
|
err := neo.Answer(ctx, content, c)
|
||||||
}
|
|
||||||
|
|
||||||
// handleGenerateCustom handles generating custom content
|
// Error handling
|
||||||
func (neo *DSL) handleGenerateCustom(c *gin.Context) {
|
if err != nil {
|
||||||
var content, genType, systemPrompt string
|
message.New().Done().Error(err).Write(c.Writer)
|
||||||
|
c.Done()
|
||||||
if c.Request.Method == "GET" {
|
|
||||||
content = c.Query("content")
|
|
||||||
genType = c.Query("type")
|
|
||||||
systemPrompt = c.Query("system_prompt")
|
|
||||||
} else {
|
|
||||||
var body struct {
|
|
||||||
Content string `json:"content"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
SystemPrompt string `json:"system_prompt"`
|
|
||||||
}
|
|
||||||
if err := c.BindJSON(&body); err != nil {
|
|
||||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
content = body.Content
|
|
||||||
genType = body.Type
|
|
||||||
systemPrompt = body.SystemPrompt
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := &generateResponse{
|
|
||||||
c: c,
|
|
||||||
sid: c.GetString("__sid"),
|
|
||||||
content: content,
|
|
||||||
}
|
|
||||||
if !resp.validate() {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional validations for custom generation
|
|
||||||
if genType == "" {
|
|
||||||
c.JSON(400, gin.H{"message": "type is required", "code": 400})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if systemPrompt == "" {
|
|
||||||
c.JSON(400, gin.H{"message": "system_prompt is required", "code": 400})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := chatctx.NewWithCancel(resp.sid, c.Query("chat_id"), "")
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Use silent mode for regular HTTP requests, streaming for SSE
|
|
||||||
silent := !strings.Contains(c.GetHeader("Accept"), "text/event-stream")
|
|
||||||
resp.result, resp.err = neo.GenerateWithAI(ctx, resp.content, genType, systemPrompt, c, silent)
|
|
||||||
resp.send("result")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAssistantList handles listing assistants
|
// handleAssistantList handles listing assistants
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,8 @@ func (obj *objectCall) run(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
||||||
chatCtx.AssistantID = assistantID
|
chatCtx.AssistantID = assistantID
|
||||||
chatCtx.ChatID = fmt.Sprintf("call_%s", uuid.New().String()) // New chat id
|
chatCtx.ChatID = fmt.Sprintf("call_%s", uuid.New().String()) // New chat id
|
||||||
chatCtx.Silent = options.Silent
|
chatCtx.Silent = options.Silent
|
||||||
chatCtx.Args = goArgs // Arguments for call
|
chatCtx.ClientType = chatctx.ClientTypeAgent // Set the client type to agent
|
||||||
|
chatCtx.Args = goArgs // Arguments for call
|
||||||
|
|
||||||
// Define the callback function
|
// Define the callback function
|
||||||
var cb func(msg *chatMessage.Message) = nil
|
var cb func(msg *chatMessage.Message) = nil
|
||||||
|
|
|
||||||
|
|
@ -12,24 +12,26 @@ import (
|
||||||
// Context the context
|
// Context the context
|
||||||
type Context struct {
|
type Context struct {
|
||||||
context.Context
|
context.Context
|
||||||
Sid string `json:"sid" yaml:"-"` // Session ID
|
Sid string `json:"sid" yaml:"-"` // Session ID
|
||||||
ChatID string `json:"chat_id,omitempty"` // Chat ID, use to select chat
|
ChatID string `json:"chat_id,omitempty"` // Chat ID, use to select chat
|
||||||
AssistantID string `json:"assistant_id,omitempty"` // Assistant ID, use to select assistant
|
AssistantID string `json:"assistant_id,omitempty"` // Assistant ID, use to select assistant
|
||||||
Stack string `json:"stack,omitempty"` // will be removed in the future
|
Stack string `json:"stack,omitempty"` // will be removed in the future
|
||||||
Path string `json:"pathname,omitempty"` // wiil be rename to path
|
Path string `json:"pathname,omitempty"` // wiil be rename to path
|
||||||
FormData map[string]interface{} `json:"formdata,omitempty"`
|
FormData map[string]interface{} `json:"formdata,omitempty"`
|
||||||
Field *Field `json:"field,omitempty"`
|
Field *Field `json:"field,omitempty"`
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
Config map[string]interface{} `json:"config,omitempty"`
|
Config map[string]interface{} `json:"config,omitempty"`
|
||||||
Signal interface{} `json:"signal,omitempty"`
|
Signal interface{} `json:"signal,omitempty"`
|
||||||
Silent bool `json:"silent,omitempty"` // Silent mode
|
Silent bool `json:"silent,omitempty"` // Silent mode
|
||||||
Retry bool `json:"retry,omitempty"` // Retry mode
|
ClientType string `json:"client_type,omitempty"` // The request client type. SDK, Desktop, Web, JSSDK, etc. the default is Web
|
||||||
RetryTimes uint8 `json:"retry_times,omitempty"` // Retry times
|
HistoryVisible bool `json:"history_visible,omitempty"` // History visible, default is true, if false, the history will not be displayed in the UI
|
||||||
Upload *FileUpload `json:"upload,omitempty"`
|
Retry bool `json:"retry,omitempty"` // Retry mode
|
||||||
Version bool `json:"version,omitempty"` // Version support
|
RetryTimes uint8 `json:"retry_times,omitempty"` // Retry times
|
||||||
RAG bool `json:"rag,omitempty"` // RAG support
|
Upload *FileUpload `json:"upload,omitempty"`
|
||||||
Args []interface{} `json:"args,omitempty"` // Arguments for call
|
Version bool `json:"version,omitempty"` // Version support
|
||||||
SharedSpace plan.Space `json:"-"` // Shared space
|
RAG bool `json:"rag,omitempty"` // RAG support
|
||||||
|
Args []interface{} `json:"args,omitempty"` // Arguments for call
|
||||||
|
SharedSpace plan.Space `json:"-"` // Shared space
|
||||||
}
|
}
|
||||||
|
|
||||||
// Field the context field
|
// Field the context field
|
||||||
|
|
@ -49,10 +51,59 @@ type FileUpload struct {
|
||||||
TempFile string `json:"temp_file,omitempty"`
|
TempFile string `json:"temp_file,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// ClientTypeAgent is the client type for Agent
|
||||||
|
ClientTypeAgent = "agent"
|
||||||
|
|
||||||
|
// ClientTypeWeb is the client type for Web (Default UI)
|
||||||
|
ClientTypeWeb = "web"
|
||||||
|
|
||||||
|
// ClientTypeSDK is the client type for SDK
|
||||||
|
ClientTypeSDK = "android"
|
||||||
|
|
||||||
|
// ClientTypeIOS is the client type for IOS
|
||||||
|
ClientTypeIOS = "ios"
|
||||||
|
|
||||||
|
// ClientTypeJSSDK is the client type for JSSDK
|
||||||
|
ClientTypeJSSDK = "jssdk"
|
||||||
|
|
||||||
|
// ClientTypeMacOS is the client type for MacOS Desktop
|
||||||
|
ClientTypeMacOS = "macos"
|
||||||
|
|
||||||
|
// ClientTypeWindows is the client type for Windows Desktop
|
||||||
|
ClientTypeWindows = "windows"
|
||||||
|
|
||||||
|
// ClientTypeLinux is the client type for Linux Desktop
|
||||||
|
ClientTypeLinux = "linux"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SupportedClientTypes is the supported client types
|
||||||
|
var SupportedClientTypes = map[string]bool{
|
||||||
|
ClientTypeAgent: true,
|
||||||
|
ClientTypeWeb: true,
|
||||||
|
ClientTypeSDK: true,
|
||||||
|
ClientTypeIOS: true,
|
||||||
|
ClientTypeJSSDK: true,
|
||||||
|
ClientTypeMacOS: true,
|
||||||
|
ClientTypeWindows: true,
|
||||||
|
ClientTypeLinux: true,
|
||||||
|
}
|
||||||
|
|
||||||
// New create a new context
|
// New create a new context
|
||||||
func New(sid, cid, payload string) Context {
|
func New(sid, cid, payload string) Context {
|
||||||
|
|
||||||
ctx := Context{Context: context.Background(), Sid: sid, ChatID: cid, SharedSpace: plan.NewMemorySharedSpace()}
|
// Validate the client type
|
||||||
|
ctx := Context{
|
||||||
|
Context: context.Background(),
|
||||||
|
SharedSpace: plan.NewMemorySharedSpace(),
|
||||||
|
Sid: sid,
|
||||||
|
ChatID: cid,
|
||||||
|
HistoryVisible: true,
|
||||||
|
ClientType: ClientTypeWeb,
|
||||||
|
Silent: false,
|
||||||
|
}
|
||||||
|
|
||||||
if payload == "" {
|
if payload == "" {
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +128,29 @@ func WithAssistantID(ctx Context, assistantID string) Context {
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSilent set the silent mode
|
||||||
|
func WithSilent(ctx Context, silent bool) Context {
|
||||||
|
ctx.Silent = silent
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithClientType set the client type
|
||||||
|
func WithClientType(ctx Context, clientType string) Context {
|
||||||
|
// Validate the client type
|
||||||
|
if !SupportedClientTypes[clientType] {
|
||||||
|
log.Error("[Neo] Invalid client type: %s", clientType)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
ctx.ClientType = clientType
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHistoryVisible set the history visible
|
||||||
|
func WithHistoryVisible(ctx Context, historyVisible bool) Context {
|
||||||
|
ctx.HistoryVisible = historyVisible
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
// NewWithTimeout create a new context with timeout
|
// NewWithTimeout create a new context with timeout
|
||||||
func NewWithTimeout(sid, cid, payload string, timeout time.Duration) (Context, context.CancelFunc) {
|
func NewWithTimeout(sid, cid, payload string, timeout time.Duration) (Context, context.CancelFunc) {
|
||||||
ctx := New(sid, cid, payload)
|
ctx := New(sid, cid, payload)
|
||||||
|
|
@ -127,6 +201,12 @@ func (ctx *Context) Map() map[string]interface{} {
|
||||||
data["silent"] = ctx.Silent
|
data["silent"] = ctx.Silent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// History visible
|
||||||
|
data["history_visible"] = ctx.HistoryVisible
|
||||||
|
|
||||||
|
// Client type
|
||||||
|
data["client_type"] = ctx.ClientType
|
||||||
|
|
||||||
// Retry mode
|
// Retry mode
|
||||||
if ctx.Retry {
|
if ctx.Retry {
|
||||||
data["retry"] = ctx.Retry
|
data["retry"] = ctx.Retry
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
func (neo *DSL) HookCreate(ctx chatctx.Context, messages []map[string]interface{}, c *gin.Context) (CreateResponse, error) {
|
func (neo *DSL) HookCreate(ctx chatctx.Context, messages []map[string]interface{}, c *gin.Context) (CreateResponse, error) {
|
||||||
|
|
||||||
// Default assistant
|
// Default assistant
|
||||||
assistantID := neo.Use
|
assistantID := neo.Use.Default
|
||||||
if ctx.AssistantID != "" {
|
if ctx.AssistantID != "" {
|
||||||
assistantID = ctx.AssistantID
|
assistantID = ctx.AssistantID
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
neo/load.go
19
neo/load.go
|
|
@ -47,6 +47,21 @@ func Load(cfg config.Config) error {
|
||||||
setting.StoreSetting.MaxSize = 100
|
setting.StoreSetting.MaxSize = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default Assistant
|
||||||
|
if setting.Use == nil {
|
||||||
|
setting.Use = &Use{Default: "neo"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title Assistant
|
||||||
|
if setting.Use.Title == "" {
|
||||||
|
setting.Use.Title = setting.Use.Default
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prompt Assistant
|
||||||
|
if setting.Use.Prompt == "" {
|
||||||
|
setting.Use.Prompt = setting.Use.Default
|
||||||
|
}
|
||||||
|
|
||||||
Neo = &setting
|
Neo = &setting
|
||||||
|
|
||||||
// Store Setting
|
// Store Setting
|
||||||
|
|
@ -185,8 +200,8 @@ func initAssistant() error {
|
||||||
|
|
||||||
// defaultAssistant get the default assistant
|
// defaultAssistant get the default assistant
|
||||||
func defaultAssistant() (*assistant.Assistant, error) {
|
func defaultAssistant() (*assistant.Assistant, error) {
|
||||||
if Neo.Use != "" {
|
if Neo.Use != nil && Neo.Use.Default != "" {
|
||||||
return assistant.Get(Neo.Use)
|
return assistant.Get(Neo.Use.Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
name := Neo.Name
|
name := Neo.Name
|
||||||
|
|
|
||||||
233
neo/neo.go
233
neo/neo.go
|
|
@ -6,10 +6,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/yaoapp/kun/log"
|
|
||||||
"github.com/yaoapp/yao/neo/assistant"
|
"github.com/yaoapp/yao/neo/assistant"
|
||||||
chatctx "github.com/yaoapp/yao/neo/context"
|
chatctx "github.com/yaoapp/yao/neo/context"
|
||||||
"github.com/yaoapp/yao/neo/message"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Answer reply the message
|
// Answer reply the message
|
||||||
|
|
@ -34,237 +32,6 @@ func (neo *DSL) Select(id string) (assistant.API, error) {
|
||||||
return assistant.Get(id)
|
return assistant.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneratePrompts generate prompts for the AI assistant
|
|
||||||
func (neo *DSL) GeneratePrompts(ctx chatctx.Context, input string, c *gin.Context, silent ...bool) (string, error) {
|
|
||||||
prompts := `
|
|
||||||
Optimize the prompts for the AI assistant
|
|
||||||
1. Optimize prompts based on the user's input
|
|
||||||
2. The prompts should be clear and specific
|
|
||||||
3. The prompts should be in the same language as the input
|
|
||||||
4. Keep the prompts concise but comprehensive
|
|
||||||
5. DO NOT ASK USER FOR MORE INFORMATION, JUST GENERATE PROMPTS
|
|
||||||
6. DO NOT ANSWER THE QUESTION, JUST GENERATE PROMPTS
|
|
||||||
`
|
|
||||||
isSilent := false
|
|
||||||
if len(silent) > 0 {
|
|
||||||
isSilent = silent[0]
|
|
||||||
}
|
|
||||||
return neo.GenerateWithAI(ctx, input, "prompts", prompts, c, isSilent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateChatTitle generate the chat title
|
|
||||||
func (neo *DSL) GenerateChatTitle(ctx chatctx.Context, input string, c *gin.Context, silent ...bool) (string, error) {
|
|
||||||
prompts := `
|
|
||||||
Help me generate a title for the chat
|
|
||||||
1. The title should be a short and concise description of the chat.
|
|
||||||
2. The title should be a single sentence.
|
|
||||||
3. The title should be in same language as the chat.
|
|
||||||
4. The title should be no more than 50 characters.
|
|
||||||
5. ANSWER ONLY THE TITLE CONTENT, FOR EXAMPLE: Chat with AI is a valid title, but "Chat with AI" is not a valid title.
|
|
||||||
`
|
|
||||||
isSilent := false
|
|
||||||
if len(silent) > 0 {
|
|
||||||
isSilent = silent[0]
|
|
||||||
}
|
|
||||||
return neo.GenerateWithAI(ctx, input, "title", prompts, c, isSilent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenerateWithAI generate content with AI, type can be "title", "prompts", etc.
|
|
||||||
func (neo *DSL) GenerateWithAI(ctx chatctx.Context, input string, messageType string, systemPrompt string, c *gin.Context, silent bool) (string, error) {
|
|
||||||
messages := []map[string]interface{}{
|
|
||||||
{"role": "system", "content": systemPrompt},
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": input,
|
|
||||||
"type": messageType,
|
|
||||||
"name": ctx.Sid,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := neo.HookCreate(ctx, messages, c)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select Assistant
|
|
||||||
ast, err := neo.Select(res.AssistantID)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ast == nil {
|
|
||||||
msg := message.New().Error("assistant is not initialized").Done()
|
|
||||||
msg.Write(c.Writer)
|
|
||||||
return "", fmt.Errorf("assistant is not initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
clientBreak := make(chan bool, 1)
|
|
||||||
done := make(chan bool, 1)
|
|
||||||
fail := make(chan error, 1)
|
|
||||||
contents := message.NewContents()
|
|
||||||
|
|
||||||
// Chat with AI in background
|
|
||||||
go func() {
|
|
||||||
msgList := []message.Message{}
|
|
||||||
for _, vv := range messages {
|
|
||||||
msg := message.New().Map(vv)
|
|
||||||
if content, ok := vv["content"].(string); ok {
|
|
||||||
msgs, err := message.NewContent(content)
|
|
||||||
if err == nil {
|
|
||||||
for _, v := range msgs {
|
|
||||||
v.AssistantID = msg.AssistantID
|
|
||||||
v.AssistantName = msg.AssistantName
|
|
||||||
v.AssistantAvatar = msg.AssistantAvatar
|
|
||||||
v.Role = msg.Role
|
|
||||||
v.Name = msg.Name
|
|
||||||
v.Mentions = msg.Mentions
|
|
||||||
msgList = append(msgList, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorRaw := ""
|
|
||||||
isFirstThink := true
|
|
||||||
isThinking := false
|
|
||||||
currentMessageID := ""
|
|
||||||
tokenID := ""
|
|
||||||
beganAt := int64(0)
|
|
||||||
err := ast.Chat(c.Request.Context(), msgList, neo.Option, func(data []byte) int {
|
|
||||||
select {
|
|
||||||
case <-clientBreak:
|
|
||||||
return 0 // break
|
|
||||||
|
|
||||||
default:
|
|
||||||
msg := message.NewOpenAI(data, isThinking)
|
|
||||||
if msg == nil {
|
|
||||||
return 1 // continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if msg.Pending {
|
|
||||||
errorRaw += msg.Text
|
|
||||||
return 1 // continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle error
|
|
||||||
if msg.Type == "error" {
|
|
||||||
fail <- fmt.Errorf("%s", msg.Text)
|
|
||||||
return 0 // break
|
|
||||||
}
|
|
||||||
|
|
||||||
// for api reasoning_content response
|
|
||||||
if msg.Type == "think" {
|
|
||||||
if isFirstThink {
|
|
||||||
msg.Text = "<think>\n" + msg.Text // add the think begin tag
|
|
||||||
isFirstThink = false
|
|
||||||
isThinking = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for api reasoning_content response
|
|
||||||
if isThinking && msg.Type != "think" {
|
|
||||||
// add the think close tag
|
|
||||||
end := message.New().Map(map[string]interface{}{"text": "\n</think>\n", "type": "think", "delta": true})
|
|
||||||
end.Write(c.Writer)
|
|
||||||
end.ID = currentMessageID
|
|
||||||
end.AppendTo(contents)
|
|
||||||
isThinking = false
|
|
||||||
|
|
||||||
// Clear the token and make a new line
|
|
||||||
contents.NewText([]byte{}, message.Extra{ID: currentMessageID})
|
|
||||||
contents.ClearToken(currentMessageID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append content and send message
|
|
||||||
msg.AppendTo(contents)
|
|
||||||
|
|
||||||
// Scan the tokens
|
|
||||||
contents.ScanTokens(currentMessageID, tokenID, beganAt, func(params message.ScanCallbackParams) {
|
|
||||||
currentMessageID = params.MessageID
|
|
||||||
msg.ID = params.MessageID
|
|
||||||
msg.Type = params.Token
|
|
||||||
msg.Text = "" // clear the text
|
|
||||||
msg.Props = map[string]interface{}{"text": params.Text} // Update props
|
|
||||||
|
|
||||||
// End of the token clear the text
|
|
||||||
if params.Begin {
|
|
||||||
msg.Begin = beganAt
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of the token clear the text
|
|
||||||
if params.End {
|
|
||||||
msg.End = params.EndAt
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// New message with the tails
|
|
||||||
if params.Tails != "" {
|
|
||||||
newMsg, err := message.NewString(params.Tails, params.MessageID)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msgList = append(msgList, *newMsg)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if !silent {
|
|
||||||
value := msg.String()
|
|
||||||
if value != "" {
|
|
||||||
message.New().
|
|
||||||
Map(map[string]interface{}{
|
|
||||||
"text": value,
|
|
||||||
"delta": true,
|
|
||||||
"done": msg.IsDone,
|
|
||||||
}).
|
|
||||||
Write(c.Writer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete the stream
|
|
||||||
if msg.IsDone {
|
|
||||||
value := msg.String()
|
|
||||||
if value == "" {
|
|
||||||
msg.Write(c.Writer)
|
|
||||||
}
|
|
||||||
done <- true
|
|
||||||
return 0 // break
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1 // continue
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Chat error: %s", err.Error())
|
|
||||||
if !silent {
|
|
||||||
message.New().Error(err).Done().Write(c.Writer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if errorRaw != "" {
|
|
||||||
msg, err := message.NewStringError(errorRaw)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error parsing error message: %s", err.Error())
|
|
||||||
}
|
|
||||||
msg.Write(c.Writer)
|
|
||||||
}
|
|
||||||
|
|
||||||
done <- true
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Wait for completion or client disconnect
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
return contents.Text(), nil
|
|
||||||
case err := <-fail:
|
|
||||||
return "", err
|
|
||||||
case <-c.Writer.CloseNotify():
|
|
||||||
clientBreak <- true
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload upload a file
|
// Upload upload a file
|
||||||
func (neo *DSL) Upload(ctx chatctx.Context, c *gin.Context) (*assistant.File, error) {
|
func (neo *DSL) Upload(ctx chatctx.Context, c *gin.Context) (*assistant.File, error) {
|
||||||
// Get the file
|
// Get the file
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,7 @@ func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid
|
||||||
|
|
||||||
// Get silent flag from context
|
// Get silent flag from context
|
||||||
var silent bool = false
|
var silent bool = false
|
||||||
|
var historyVisible bool = true
|
||||||
if context != nil {
|
if context != nil {
|
||||||
if silentVal, ok := context["silent"]; ok {
|
if silentVal, ok := context["silent"]; ok {
|
||||||
switch v := silentVal.(type) {
|
switch v := silentVal.(type) {
|
||||||
|
|
@ -620,6 +621,20 @@ func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid
|
||||||
silent = v != 0
|
silent = v != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get history visible from context
|
||||||
|
if historyVisibleVal, ok := context["history_visible"]; ok {
|
||||||
|
switch v := historyVisibleVal.(type) {
|
||||||
|
case bool:
|
||||||
|
historyVisible = v
|
||||||
|
case string:
|
||||||
|
historyVisible = v == "true" || v == "1" || v == "yes"
|
||||||
|
case int:
|
||||||
|
historyVisible = v != 0
|
||||||
|
case float64:
|
||||||
|
historyVisible = v != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First ensure chat record exists
|
// First ensure chat record exists
|
||||||
|
|
@ -639,7 +654,7 @@ func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid
|
||||||
"chat_id": cid,
|
"chat_id": cid,
|
||||||
"sid": userID,
|
"sid": userID,
|
||||||
"assistant_id": assistantID,
|
"assistant_id": assistantID,
|
||||||
"silent": silent,
|
"silent": silent || historyVisible == false,
|
||||||
"created_at": time.Now(),
|
"created_at": time.Now(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -653,7 +668,7 @@ func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid
|
||||||
Where("sid", userID).
|
Where("sid", userID).
|
||||||
Update(map[string]interface{}{
|
Update(map[string]interface{}{
|
||||||
"assistant_id": assistantID,
|
"assistant_id": assistantID,
|
||||||
"silent": silent,
|
"silent": silent || historyVisible == false,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
type DSL struct {
|
type DSL struct {
|
||||||
ID string `json:"-" yaml:"-"`
|
ID string `json:"-" yaml:"-"`
|
||||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||||
Use string `json:"use,omitempty" yaml:"use,omitempty"` // Which assistant to use default
|
Use *Use `json:"use,omitempty" yaml:"use,omitempty"` // Which assistant to use default, title, prompt
|
||||||
Guard string `json:"guard,omitempty" yaml:"guard,omitempty"`
|
Guard string `json:"guard,omitempty" yaml:"guard,omitempty"`
|
||||||
Connector string `json:"connector" yaml:"connector"`
|
Connector string `json:"connector" yaml:"connector"`
|
||||||
StoreSetting store.Setting `json:"store" yaml:"store"`
|
StoreSetting store.Setting `json:"store" yaml:"store"`
|
||||||
|
|
@ -34,6 +34,13 @@ type DSL struct {
|
||||||
GuardHandlers []gin.HandlerFunc `json:"-" yaml:"-"`
|
GuardHandlers []gin.HandlerFunc `json:"-" yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the use setting for the assistant
|
||||||
|
type Use struct {
|
||||||
|
Default string `json:"default,omitempty" yaml:"default,omitempty"`
|
||||||
|
Title string `json:"title,omitempty" yaml:"title,omitempty"`
|
||||||
|
Prompt string `json:"prompt,omitempty" yaml:"prompt,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// VisionSetting the vision setting
|
// VisionSetting the vision setting
|
||||||
type VisionSetting struct {
|
type VisionSetting struct {
|
||||||
Storage driver.StorageConfig `json:"storage" yaml:"storage"`
|
Storage driver.StorageConfig `json:"storage" yaml:"storage"`
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ class Agent {
|
||||||
private chat_id?: string;
|
private chat_id?: string;
|
||||||
private es: EventSource | null;
|
private es: EventSource | null;
|
||||||
private context: Record<string, any>;
|
private context: Record<string, any>;
|
||||||
|
private silent?: boolean = false;
|
||||||
|
private history_visible?: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Agent constructor
|
* Agent constructor
|
||||||
|
|
@ -72,6 +74,28 @@ class Agent {
|
||||||
this.chat_id = option.chat_id;
|
this.chat_id = option.chat_id;
|
||||||
this.es = null;
|
this.es = null;
|
||||||
this.context = option.context || {};
|
this.context = option.context || {};
|
||||||
|
|
||||||
|
// Set silent mode, default is true
|
||||||
|
if (option.silent !== undefined) {
|
||||||
|
this.silent =
|
||||||
|
option.silent === true ||
|
||||||
|
option.silent === "true" ||
|
||||||
|
option.silent === 1 ||
|
||||||
|
option.silent === "1"
|
||||||
|
? false
|
||||||
|
: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set history visible mode, default is false
|
||||||
|
if (option.history_visible !== undefined) {
|
||||||
|
this.history_visible =
|
||||||
|
option.history_visible === true ||
|
||||||
|
option.history_visible === "true" ||
|
||||||
|
option.history_visible === 1 ||
|
||||||
|
option.history_visible === "1"
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -152,10 +176,12 @@ class Agent {
|
||||||
const contentRaw = encodeURIComponent(JSON.stringify(content));
|
const contentRaw = encodeURIComponent(JSON.stringify(content));
|
||||||
const contextRaw = encodeURIComponent(JSON.stringify(context));
|
const contextRaw = encodeURIComponent(JSON.stringify(context));
|
||||||
const token = this.token;
|
const token = this.token;
|
||||||
|
const silent = this.silent ? "true" : "false";
|
||||||
|
const history_visible = this.history_visible ? "true" : "false";
|
||||||
const chatId = this.chat_id || this.makeChatID();
|
const chatId = this.chat_id || this.makeChatID();
|
||||||
const assistantParam = `&assistant_id=${this.assistant_id}`;
|
const assistantParam = `&assistant_id=${this.assistant_id}`;
|
||||||
const status_endpoint = `${this.host}/status?content=${contentRaw}&context=${contextRaw}&token=${token}&chat_id=${chatId}${assistantParam}`;
|
const status_endpoint = `${this.host}/status?content=${contentRaw}&context=${contextRaw}&token=${token}&chat_id=${chatId}${assistantParam}`;
|
||||||
const endpoint = `${this.host}?content=${contentRaw}&context=${contextRaw}&token=${token}&chat_id=${chatId}${assistantParam}`;
|
const endpoint = `${this.host}?client_type=jssdk&content=${contentRaw}&context=${contextRaw}&token=${token}&silent=${silent}&history_visible=${history_visible}&chat_id=${chatId}${assistantParam}`;
|
||||||
|
|
||||||
const handleError = async (error: any) => {
|
const handleError = async (error: any) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -447,6 +473,8 @@ type AgentInput =
|
||||||
interface AgentOption {
|
interface AgentOption {
|
||||||
host?: string;
|
host?: string;
|
||||||
token: string;
|
token: string;
|
||||||
|
silent?: boolean | string | number;
|
||||||
|
history_visible?: boolean | string | number;
|
||||||
chat_id?: string;
|
chat_id?: string;
|
||||||
context?: Record<string, any>;
|
context?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue