yao/agent/context/context.go
Max c54ef71d6a ⚠️ 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.
2025-11-06 18:13:54 +08:00

265 lines
6.8 KiB
Go

package context
import (
"context"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou/plan"
"github.com/yaoapp/kun/log"
)
// Context the context
type Context struct {
context.Context
Sid string `json:"sid" yaml:"-"` // Session ID
ChatID string `json:"chat_id,omitempty"` // Chat ID, use to select chat
AssistantID string `json:"assistant_id,omitempty"` // Assistant ID, use to select assistant
// CUI Context
Namespace string `json:"namespace,omitempty"`
Stack string `json:"stack,omitempty"` // will be removed in the future
Path string `json:"pathname,omitempty"` // wiil be rename to path
FormData map[string]interface{} `json:"formdata,omitempty"`
Field *Field `json:"field,omitempty"`
Config map[string]interface{} `json:"config,omitempty"`
Signal interface{} `json:"signal,omitempty"`
// Locale information
Locale string `json:"locale,omitempty"` // Locale
Theme string `json:"theme,omitempty"` // Theme
Silent bool `json:"silent,omitempty"` // Silent mode
ClientType string `json:"client_type,omitempty"` // The request client type. SDK, Desktop, Web, JSSDK, etc. the default is Web
HistoryVisible bool `json:"history_visible,omitempty"` // History visible, default is true, if false, the history will not be displayed in the UI
Retry bool `json:"retry,omitempty"` // Retry mode
RetryTimes uint8 `json:"retry_times,omitempty"` // Retry times
Vision bool `json:"vision,omitempty"` // Vision support
Search bool `json:"search,omitempty"` // Search support
Knowledge bool `json:"knowledge,omitempty"` // Knowledge support
Args []interface{} `json:"args,omitempty"` // Arguments for call
SharedSpace plan.Space `json:"-"` // Shared space
}
// Field the context field
type Field struct {
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Bind string `json:"bind,omitempty"`
Props map[string]interface{} `json:"props,omitempty"`
Children []interface{} `json:"children,omitempty"`
}
// FileUpload the file upload
type FileUpload struct {
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Size int64 `json:"size,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"
// ClientTypeAndroid is the client type for Android
ClientTypeAndroid = "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,
ClientTypeAndroid: true,
ClientTypeIOS: true,
ClientTypeJSSDK: true,
ClientTypeMacOS: true,
ClientTypeWindows: true,
ClientTypeLinux: true,
}
// New create a new context
func New(sid, cid, payload string) Context {
// Validate the client type
ctx := Context{
Context: context.Background(),
SharedSpace: plan.NewMemorySharedSpace(),
Sid: sid,
ChatID: cid,
HistoryVisible: true,
ClientType: ClientTypeWeb,
Silent: false,
}
if payload == "" {
return ctx
}
err := jsoniter.Unmarshal([]byte(payload), &ctx)
if err != nil {
log.Error("%s", err.Error())
}
return ctx
}
// NewWithCancel create a new context with cancel
func NewWithCancel(sid, cid, payload string) (Context, context.CancelFunc) {
ctx := New(sid, cid, payload)
return WithCancel(ctx)
}
// WithAssistantID set the assistant ID
func WithAssistantID(ctx Context, assistantID string) Context {
ctx.AssistantID = assistantID
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("[Agent] Invalid client type: %s", clientType)
return ctx
}
ctx.ClientType = clientType
return ctx
}
// WithLocale set the locale
func WithLocale(ctx Context, locale string) Context {
ctx.Locale = locale
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
func NewWithTimeout(sid, cid, payload string, timeout time.Duration) (Context, context.CancelFunc) {
ctx := New(sid, cid, payload)
return WithTimeout(ctx, timeout)
}
// WithCancel create a new context
func WithCancel(parent Context) (Context, context.CancelFunc) {
new, cancel := context.WithCancel(parent.Context)
parent.Context = new
return parent, cancel
}
// WithTimeout create a new context
func WithTimeout(parent Context, timeout time.Duration) (Context, context.CancelFunc) {
new, cancel := context.WithTimeout(parent.Context, timeout)
parent.Context = new
return parent, cancel
}
// Release the context
func (ctx *Context) Release() {
ctx.SharedSpace.Clear()
ctx.SharedSpace = nil
ctx = nil
}
// Map the context to a map
func (ctx *Context) Map() map[string]interface{} {
data := map[string]interface{}{
"sid": ctx.Sid,
"knowledge": ctx.Knowledge,
"vision": ctx.Vision,
"search": ctx.Search,
}
if ctx.ChatID != "" {
data["chat_id"] = ctx.ChatID
}
if ctx.AssistantID != "" {
data["assistant_id"] = ctx.AssistantID
}
if ctx.Stack != "" {
data["stack"] = ctx.Stack
}
// Silent mode
if ctx.Silent {
data["silent"] = ctx.Silent
}
// History visible
data["history_visible"] = ctx.HistoryVisible
// Client type
data["client_type"] = ctx.ClientType
// Retry mode
if ctx.Retry {
data["retry"] = ctx.Retry
}
// Arguments for call
if ctx.Args != nil && len(ctx.Args) > 0 {
data["args"] = ctx.Args
}
// Retry times
data["retry_times"] = ctx.RetryTimes
if ctx.Path != "" {
data["pathname"] = ctx.Path
}
if len(ctx.FormData) > 0 {
data["formdata"] = ctx.FormData
}
if ctx.Field != nil {
data["field"] = ctx.Field
}
if ctx.Namespace != "" {
data["namespace"] = ctx.Namespace
}
if len(ctx.Config) > 0 {
data["config"] = ctx.Config
}
if ctx.Signal != nil {
data["signal"] = ctx.Signal
}
// Locale
data["locale"] = ctx.Locale
// Theme
data["theme"] = ctx.Theme
return data
}