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:
mlogclub
2026-04-17 17:57:01 +08:00
parent 3b062c327c
commit 976b9defde
36 changed files with 102 additions and 282 deletions
@@ -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"},