Refactor AI Agent and AI Config handling across multiple files
- Updated function signatures to accept AI Agent and AI Config as non-pointer types for better clarity and safety. - Modified instances where AI Agent and AI Config were dereferenced to improve code readability. - Removed unnecessary nil checks for AI Agent and AI Config, simplifying the logic. - Adjusted related tests and services to align with the new function signatures. - Cleaned up code in runtime, skills, and executor packages to ensure consistency in handling AI configurations.
This commit is contained in:
@@ -31,9 +31,9 @@ type AgentFactory struct {
|
||||
// 3. 后续扩展装配项时继续拉长函数签名。
|
||||
type BuildCustomerServiceAgentInput struct {
|
||||
// AIAgent 为当前运行的业务 Agent 配置,提供名称、描述、系统提示词等基础信息。
|
||||
AIAgent *models.AIAgent
|
||||
AIAgent models.AIAgent
|
||||
// AIConfig 为模型配置,决定底层使用哪个 ChatModel。
|
||||
AIConfig *models.AIConfig
|
||||
AIConfig models.AIConfig
|
||||
// SelectedSkill 为当前命中的技能;为空表示本次运行未命中专项技能。
|
||||
SelectedSkill *models.SkillDefinition
|
||||
// InstructionToolDefinitions 用于生成 instruction 中的工具说明。
|
||||
@@ -63,9 +63,6 @@ func NewAgentFactory() *AgentFactory {
|
||||
|
||||
// BuildCustomerServiceAgent 根据装配输入构建客服 ChatModelAgent。
|
||||
func (f *AgentFactory) BuildCustomerServiceAgent(ctx context.Context, input BuildCustomerServiceAgentInput) (*einoagents.CustomerServiceAgent, error) {
|
||||
if input.AIAgent == nil || input.AIConfig == nil {
|
||||
return nil, nil
|
||||
}
|
||||
chatModel, err := f.chatModelFactory.Build(ctx, input.AIConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -18,27 +18,24 @@ func NewChatModelFactory() *ChatModelFactory {
|
||||
return &ChatModelFactory{}
|
||||
}
|
||||
|
||||
func (f *ChatModelFactory) Build(ctx context.Context, item *models.AIConfig) (model.ToolCallingChatModel, error) {
|
||||
if item == nil {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *ChatModelFactory) Build(ctx context.Context, aiConfig models.AIConfig) (model.ToolCallingChatModel, error) {
|
||||
conf := &openai.ChatModelConfig{
|
||||
APIKey: strings.TrimSpace(item.APIKey),
|
||||
BaseURL: strings.TrimSpace(item.BaseURL),
|
||||
Model: strings.TrimSpace(item.ModelName),
|
||||
APIKey: strings.TrimSpace(aiConfig.APIKey),
|
||||
BaseURL: strings.TrimSpace(aiConfig.BaseURL),
|
||||
Model: strings.TrimSpace(aiConfig.ModelName),
|
||||
}
|
||||
if item.TimeoutMS > 0 {
|
||||
conf.Timeout = time.Duration(item.TimeoutMS) * time.Millisecond
|
||||
if aiConfig.TimeoutMS > 0 {
|
||||
conf.Timeout = time.Duration(aiConfig.TimeoutMS) * time.Millisecond
|
||||
}
|
||||
if item.MaxOutputTokens > 0 {
|
||||
maxCompletionTokens := item.MaxOutputTokens
|
||||
if aiConfig.MaxOutputTokens > 0 {
|
||||
maxCompletionTokens := aiConfig.MaxOutputTokens
|
||||
conf.MaxCompletionTokens = &maxCompletionTokens
|
||||
}
|
||||
if item.Provider == enums.AIProviderOpenAI && isAzureOpenAIBaseURL(item.BaseURL) {
|
||||
if aiConfig.Provider == enums.AIProviderOpenAI && isAzureOpenAIBaseURL(aiConfig.BaseURL) {
|
||||
conf.ByAzure = true
|
||||
conf.APIVersion = "2024-06-01"
|
||||
}
|
||||
if extraFields := providerExtraFields(item); len(extraFields) > 0 {
|
||||
if extraFields := providerExtraFields(aiConfig); len(extraFields) > 0 {
|
||||
conf.ExtraFields = extraFields
|
||||
}
|
||||
return openai.NewChatModel(ctx, conf)
|
||||
@@ -49,12 +46,9 @@ func isAzureOpenAIBaseURL(baseURL string) bool {
|
||||
return strings.Contains(baseURL, ".openai.azure.com")
|
||||
}
|
||||
|
||||
func providerExtraFields(item *models.AIConfig) map[string]any {
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
baseURL := strings.ToLower(strings.TrimSpace(item.BaseURL))
|
||||
modelName := strings.ToLower(strings.TrimSpace(item.ModelName))
|
||||
func providerExtraFields(aiConfig models.AIConfig) map[string]any {
|
||||
baseURL := strings.ToLower(strings.TrimSpace(aiConfig.BaseURL))
|
||||
modelName := strings.ToLower(strings.TrimSpace(aiConfig.ModelName))
|
||||
if strings.Contains(baseURL, "dashscope.aliyuncs.com") && strings.HasPrefix(modelName, "qwen3") {
|
||||
return map[string]any{
|
||||
"enable_thinking": false,
|
||||
|
||||
@@ -20,10 +20,7 @@ func NewToolFactory() *ToolFactory {
|
||||
return &ToolFactory{}
|
||||
}
|
||||
|
||||
func (f *ToolFactory) BuildMCPTools(aiAgent *models.AIAgent) ([]runtimetooling.MCPToolDefinition, error) {
|
||||
if aiAgent == nil || strings.TrimSpace(aiAgent.AllowedMCPTools) == "" {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *ToolFactory) BuildMCPTools(aiAgent models.AIAgent) ([]runtimetooling.MCPToolDefinition, error) {
|
||||
raw, err := toolx.ParseAgentMCPToolsJSON(aiAgent.AllowedMCPTools)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -56,7 +53,7 @@ func (f *ToolFactory) BuildMCPTools(aiAgent *models.AIAgent) ([]runtimetooling.M
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (f *ToolFactory) BuildBaseTools(ctx context.Context, aiAgent *models.AIAgent) ([]einotool.BaseTool, error) {
|
||||
func (f *ToolFactory) BuildBaseTools(ctx context.Context, aiAgent models.AIAgent) ([]einotool.BaseTool, error) {
|
||||
definitions, err := f.BuildMCPTools(aiAgent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func TestBuildMCPToolsSkipsGraphAndBuiltinTools(t *testing.T) {
|
||||
aiAgent := &models.AIAgent{
|
||||
aiAgent := models.AIAgent{
|
||||
AllowedMCPTools: `[
|
||||
{"toolCode":"graph/create_ticket_with_confirmation","serverCode":"graph","toolName":"create_ticket_with_confirmation"},
|
||||
{"toolCode":"builtin/tool_search","serverCode":"builtin","toolName":"tool_search"},
|
||||
|
||||
Reference in New Issue
Block a user