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
+4 -4
View File
@@ -44,8 +44,8 @@ func DebugRunSkill(ctx context.Context, req request.SkillDebugRunRequest) (*resp
summary, err := Service.Run(ctx, applicationruntime.Request{
Conversation: conversation,
UserMessage: message,
AIAgent: aiAgent,
AIConfig: aiConfig,
AIAgent: *aiAgent,
AIConfig: *aiConfig,
ManualSkillCode: strings.TrimSpace(req.SkillCode),
})
if err != nil {
@@ -91,8 +91,8 @@ func DebugResumeSkill(ctx context.Context, req request.SkillDebugResumeRequest)
resumeText := strings.TrimSpace(req.UserMessage)
summary, err := Service.Resume(ctx, applicationruntime.ResumeRequest{
Conversation: conversation,
AIAgent: aiAgent,
AIConfig: aiConfig,
AIAgent: *aiAgent,
AIConfig: *aiConfig,
CheckPointID: strings.TrimSpace(req.CheckPointID),
ResumeData: map[string]string{
strings.TrimSpace(pendingInterrupt.InterruptID): resumeText,
@@ -22,9 +22,7 @@ func buildRunMessages(ctx context.Context, req RunInput, summary *RunResult, col
}
if collector != nil {
collector.Data.Input.HistoryMessageCount = len(history.Messages)
if req.AIAgent != nil {
collector.Data.Input.KnowledgeBaseIDs = utils.SplitInt64s(req.AIAgent.KnowledgeIDs)
}
collector.Data.Input.KnowledgeBaseIDs = utils.SplitInt64s(req.AIAgent.KnowledgeIDs)
collector.Data.Input.CurrentUserMessagePreview = preview(req.UserMessage.Content, 120)
}
messages := make([]*schema.Message, 0, len(history.Messages)+3)
@@ -41,7 +39,7 @@ func buildRunMessages(ctx context.Context, req RunInput, summary *RunResult, col
}
func appendRetrievedContext(ctx context.Context, req RunInput, summary *RunResult, collector *callbacks.RuntimeTraceCollector, messages *[]*schema.Message) knowledgeGuardDecision {
if req.AIAgent == nil || req.UserMessage == nil || messages == nil {
if req.UserMessage == nil || messages == nil {
return knowledgeGuardDecision{}
}
retriever := retrievers.NewKnowledgeRetriever(req.AIAgent)
@@ -15,8 +15,8 @@ type knowledgeGuardDecision struct {
Instructions []*schema.Message
}
func buildKnowledgeGuardDecision(aiAgent *models.AIAgent, retrieveResult *retrievers.KnowledgeRetrieveResult) knowledgeGuardDecision {
if aiAgent == nil || retrieveResult == nil || len(retrieveResult.KnowledgeBaseIDs) == 0 {
func buildKnowledgeGuardDecision(aiAgent models.AIAgent, retrieveResult *retrievers.KnowledgeRetrieveResult) knowledgeGuardDecision {
if retrieveResult == nil || len(retrieveResult.KnowledgeBaseIDs) == 0 {
return knowledgeGuardDecision{}
}
fallbackReply := resolveKnowledgeFallbackReply(aiAgent, retrieveResult.FallbackMode)
@@ -32,11 +32,9 @@ func buildKnowledgeGuardDecision(aiAgent *models.AIAgent, retrieveResult *retrie
}
}
func resolveKnowledgeFallbackReply(aiAgent *models.AIAgent, fallbackMode enums.KnowledgeFallbackMode) string {
if aiAgent != nil {
if reply := strings.TrimSpace(aiAgent.FallbackMessage); reply != "" {
return reply
}
func resolveKnowledgeFallbackReply(aiAgent models.AIAgent, fallbackMode enums.KnowledgeFallbackMode) string {
if reply := strings.TrimSpace(aiAgent.FallbackMessage); reply != "" {
return reply
}
switch fallbackMode {
case enums.KnowledgeFallbackModeSuggestRetry:
@@ -12,7 +12,7 @@ import (
func TestBuildKnowledgeGuardDecisionFallsBackWhenKnowledgeMisses(t *testing.T) {
agent := newKnowledgeGuardAgentFixture()
decision := buildKnowledgeGuardDecision(&agent, &retrievers.KnowledgeRetrieveResult{
decision := buildKnowledgeGuardDecision(agent, &retrievers.KnowledgeRetrieveResult{
KnowledgeBaseIDs: []int64{1},
FallbackMode: enums.KnowledgeFallbackModeSuggestRetry,
})
@@ -28,7 +28,7 @@ func TestBuildKnowledgeGuardDecisionFallsBackWhenKnowledgeMisses(t *testing.T) {
func TestBuildKnowledgeGuardDecisionUsesAgentFallbackMessage(t *testing.T) {
agent := newKnowledgeGuardAgentFixture()
agent.FallbackMessage = "请联系人工客服"
decision := buildKnowledgeGuardDecision(&agent, &retrievers.KnowledgeRetrieveResult{
decision := buildKnowledgeGuardDecision(agent, &retrievers.KnowledgeRetrieveResult{
KnowledgeBaseIDs: []int64{1},
FallbackMode: enums.KnowledgeFallbackModeNoAnswer,
})
@@ -40,7 +40,7 @@ func TestBuildKnowledgeGuardDecisionUsesAgentFallbackMessage(t *testing.T) {
func TestBuildKnowledgeGuardDecisionInjectsStrictInstructionOnHit(t *testing.T) {
agent := newKnowledgeGuardAgentFixture()
decision := buildKnowledgeGuardDecision(&agent, &retrievers.KnowledgeRetrieveResult{
decision := buildKnowledgeGuardDecision(agent, &retrievers.KnowledgeRetrieveResult{
KnowledgeBaseIDs: []int64{1},
Hits: []rag.RetrieveResult{
{KnowledgeBaseID: 1, Score: 0.88},
+1 -28
View File
@@ -33,7 +33,7 @@ func (s *Service) ExecuteRun(ctx context.Context, req RunInput) (*RunResult, err
}
collector := callbacks.NewRuntimeTraceCollector()
collector.Data.RunID = summary.RunID
if req.AIAgent == nil || req.Conversation == nil || req.UserMessage == nil {
if req.Conversation == nil || req.UserMessage == nil {
summary.Status = "error"
summary.ErrorMessage = "invalid runtime request"
collector.Data.Status = summary.Status
@@ -42,15 +42,6 @@ func (s *Service) ExecuteRun(ctx context.Context, req RunInput) (*RunResult, err
summary.TraceData = collector.Marshal()
return summary, fmt.Errorf("%s", summary.ErrorMessage)
}
if req.AIConfig == nil {
summary.Status = "error"
summary.ErrorMessage = "ai config is nil"
collector.Data.Status = summary.Status
collector.Data.Error.Message = summary.ErrorMessage
collector.Data.Error.Stage = "prepare"
summary.TraceData = collector.Marshal()
return summary, fmt.Errorf("%s", summary.ErrorMessage)
}
toolDefs, err := factory.NewToolFactory().BuildMCPTools(req.AIAgent)
if err != nil {
@@ -149,24 +140,6 @@ func (s *Service) ExecuteResume(ctx context.Context, req ResumeInput) (*RunResul
collector := callbacks.NewRuntimeTraceCollector()
collector.Data.RunID = summary.RunID
collector.Data.Interrupt.CheckPointID = summary.CheckPointID
if req.AIAgent == nil {
summary.Status = "error"
summary.ErrorMessage = "ai agent is nil"
collector.Data.Status = summary.Status
collector.Data.Error.Message = summary.ErrorMessage
collector.Data.Error.Stage = "resume_prepare"
summary.TraceData = collector.Marshal()
return summary, fmt.Errorf("%s", summary.ErrorMessage)
}
if req.AIConfig == nil {
summary.Status = "error"
summary.ErrorMessage = "ai config is nil"
collector.Data.Status = summary.Status
collector.Data.Error.Message = summary.ErrorMessage
collector.Data.Error.Stage = "resume_prepare"
summary.TraceData = collector.Marshal()
return summary, fmt.Errorf("%s", summary.ErrorMessage)
}
if summary.CheckPointID == "" {
summary.Status = "error"
summary.ErrorMessage = "checkpoint id is required"
+4 -4
View File
@@ -8,8 +8,8 @@ import (
type RunInput struct {
Conversation *models.Conversation
UserMessage *models.Message
AIAgent *models.AIAgent
AIConfig *models.AIConfig
AIAgent models.AIAgent
AIConfig models.AIConfig
SelectedSkill *models.SkillDefinition
SkillRouteReason string
SkillRouteTrace string
@@ -19,8 +19,8 @@ type RunInput struct {
type ResumeInput struct {
Conversation *models.Conversation
AIAgent *models.AIAgent
AIConfig *models.AIConfig
AIAgent models.AIAgent
AIConfig models.AIConfig
CheckPointID string
ResumeData map[string]string
ToolSet *registry.ToolSet
@@ -38,10 +38,10 @@ func init() {
type CreateTicketGraph struct {
conversation *models.Conversation
aiAgent *models.AIAgent
aiAgent models.AIAgent
}
func NewCreateTicketGraph(conversation *models.Conversation, aiAgent *models.AIAgent) *CreateTicketGraph {
func NewCreateTicketGraph(conversation *models.Conversation, aiAgent models.AIAgent) *CreateTicketGraph {
return &CreateTicketGraph{
conversation: conversation,
aiAgent: aiAgent,
@@ -49,7 +49,7 @@ func NewCreateTicketGraph(conversation *models.Conversation, aiAgent *models.AIA
}
func (g *CreateTicketGraph) Run(ctx context.Context, argumentsInJSON string) (string, error) {
if g == nil || g.conversation == nil || g.aiAgent == nil {
if g == nil || g.conversation == nil {
return "", fmt.Errorf("create ticket graph not initialized")
}
wasInterrupted, hasState, state := componenttool.GetInterruptState[CreateTicketGraphState](ctx)
@@ -1,45 +0,0 @@
package graphs
import (
"testing"
"cs-agent/internal/models"
)
func TestCreateTicketGraphBuildCreateRequest(t *testing.T) {
graph := NewCreateTicketGraph(&models.Conversation{
ID: 12,
Subject: "fallback-title",
LastMessageSummary: "fallback-description",
}, &models.AIAgent{Name: "AI"})
req, err := graph.buildCreateRequest(`{"title":" test title ","description":" desc ","priority":2,"severity":3}`)
if err != nil {
t.Fatalf("buildCreateRequest returned error: %v", err)
}
if req.Title != "test title" || req.Description != "desc" {
t.Fatalf("unexpected request text fields: %#v", req)
}
if req.Priority != 2 || req.Severity != 3 {
t.Fatalf("unexpected request numeric fields: %#v", req)
}
}
func TestCreateTicketGraphBuildCreateRequestFallbacks(t *testing.T) {
graph := NewCreateTicketGraph(&models.Conversation{
ID: 12,
Subject: "fallback-title",
LastMessageSummary: "fallback-description",
}, &models.AIAgent{Name: "AI"})
req, err := graph.buildCreateRequest(`{}`)
if err != nil {
t.Fatalf("buildCreateRequest returned error: %v", err)
}
if req.Title != "fallback-title" {
t.Fatalf("unexpected fallback title: %#v", req)
}
if req.Description != "fallback-description" {
t.Fatalf("unexpected fallback description: %#v", req)
}
}
+3 -3
View File
@@ -33,10 +33,10 @@ func init() {
type HandoffGraph struct {
conversation *models.Conversation
aiAgent *models.AIAgent
aiAgent models.AIAgent
}
func NewHandoffGraph(conversation *models.Conversation, aiAgent *models.AIAgent) *HandoffGraph {
func NewHandoffGraph(conversation *models.Conversation, aiAgent models.AIAgent) *HandoffGraph {
return &HandoffGraph{
conversation: conversation,
aiAgent: aiAgent,
@@ -44,7 +44,7 @@ func NewHandoffGraph(conversation *models.Conversation, aiAgent *models.AIAgent)
}
func (g *HandoffGraph) Run(ctx context.Context, argumentsInJSON string) (string, error) {
if g == nil || g.conversation == nil || g.aiAgent == nil {
if g == nil || g.conversation == nil {
return "", fmt.Errorf("handoff graph not initialized")
}
wasInterrupted, hasState, state := componenttool.GetInterruptState[HandoffGraphState](ctx)
@@ -1,41 +0,0 @@
package graphs
import (
"testing"
"cs-agent/internal/models"
)
func TestHandoffGraphBuildReason(t *testing.T) {
graph := NewHandoffGraph(&models.Conversation{ID: 1}, &models.AIAgent{Name: "AI"})
reason, err := graph.buildReason(`{"reason":" 用户需要人工确认 "}`)
if err != nil {
t.Fatalf("buildReason returned error: %v", err)
}
if reason != "用户需要人工确认" {
t.Fatalf("unexpected reason: %q", reason)
}
}
func TestHandoffGraphBuildReasonFallback(t *testing.T) {
graph := NewHandoffGraph(&models.Conversation{ID: 1}, &models.AIAgent{Name: "AI"})
reason, err := graph.buildReason(`{}`)
if err != nil {
t.Fatalf("buildReason returned error: %v", err)
}
if reason != "用户需要转人工支持" {
t.Fatalf("unexpected fallback reason: %q", reason)
}
}
func TestHandoffGraphBuildSuccessReply(t *testing.T) {
graph := NewHandoffGraph(&models.Conversation{ID: 1}, &models.AIAgent{Name: "AI"})
got := graph.buildSuccessReply()
want := "已为你转接人工客服,请稍候。,请稍候。"
if got != want {
t.Fatalf("unexpected success reply: %q", got)
}
}
+2 -6
View File
@@ -47,15 +47,11 @@ func NewService(
}
func (s *Service) Build(
aiAgent *models.AIAgent,
aiAgent models.AIAgent,
selectedSkill *models.SkillDefinition,
toolDefinitions []runtimetooling.MCPToolDefinition,
extraToolCodes map[string]string,
) AssemblyResult {
baseInstruction := ""
if aiAgent != nil {
baseInstruction = strings.TrimSpace(aiAgent.SystemPrompt)
}
projectInstruction := ""
governanceInstruction := ""
skillInstruction := ""
@@ -77,7 +73,7 @@ func (s *Service) Build(
assembler = s.assembler
}
return assembler.Assemble(AssemblerInput{
AgentInstruction: baseInstruction,
AgentInstruction: strings.TrimSpace(aiAgent.SystemPrompt),
GovernanceInstruction: governanceInstruction,
SkillInstruction: skillInstruction,
ToolAppendices: toolAppendices,
@@ -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"},
@@ -20,7 +20,7 @@ const defaultRuntimeKnowledgeScoreThreshold = 0.3
const defaultRuntimeKnowledgeMaxContextItems = 5
type KnowledgeRetriever struct {
AIAgent *models.AIAgent
AIAgent models.AIAgent
}
type KnowledgeRetrieveOptions struct {
@@ -53,7 +53,7 @@ type KnowledgeRetrieveResult struct {
Policies []KnowledgeBaseRetrievePolicy
}
func NewKnowledgeRetriever(aiAgent *models.AIAgent) *KnowledgeRetriever {
func NewKnowledgeRetriever(aiAgent models.AIAgent) *KnowledgeRetriever {
return &KnowledgeRetriever{AIAgent: aiAgent}
}
@@ -65,9 +65,6 @@ func DefaultKnowledgeRetrieveOptions() KnowledgeRetrieveOptions {
}
func (r *KnowledgeRetriever) KnowledgeBaseIDs() []int64 {
if r == nil || r.AIAgent == nil {
return nil
}
return utils.SplitInt64s(r.AIAgent.KnowledgeIDs)
}
@@ -50,7 +50,7 @@ func TestResolveBuildsStaticToolMetadata(t *testing.T) {
})
toolSet, err := r.Resolve(registry.Context{
Conversation: &models.Conversation{ID: 1},
AIAgent: &models.AIAgent{ID: 1},
AIAgent: models.AIAgent{ID: 1},
})
if err != nil {
t.Fatalf("resolve returned error: %v", err)
+2 -2
View File
@@ -10,8 +10,8 @@ import (
type Context struct {
Conversation *models.Conversation
AIAgent *models.AIAgent
AIConfig *models.AIConfig
AIAgent models.AIAgent
AIConfig models.AIConfig
UserMessage *models.Message
AllowedToolCodes []string
}
@@ -28,8 +28,8 @@ func (e *runtimeReplyExecutor) Run(ctx context.Context, conversation models.Conv
summary, err := Service.Run(ctx, applicationruntime.Request{
Conversation: &conversation,
UserMessage: &message,
AIAgent: &aiAgent,
AIConfig: aiConfig,
AIAgent: aiAgent,
AIConfig: *aiConfig,
})
if trace != nil {
trace.RuntimeLatencyMs = time.Since(runtimeStartedAt).Milliseconds()
@@ -52,8 +52,8 @@ func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, conve
}
summary, err := Service.Resume(ctx, applicationruntime.ResumeRequest{
Conversation: &conversation,
AIAgent: &aiAgent,
AIConfig: aiConfig,
AIAgent: aiAgent,
AIConfig: *aiConfig,
CheckPointID: strings.TrimSpace(pendingInterrupt.CheckPointID),
ResumeData: map[string]string{
strings.TrimSpace(pendingInterrupt.InterruptID): strings.TrimSpace(message.Content),
@@ -17,7 +17,7 @@ import (
type CreateTicketGraphTool struct {
conversation *models.Conversation
aiAgent *models.AIAgent
aiAgent models.AIAgent
}
func NewCreateTicketGraphTool() *CreateTicketGraphTool {
@@ -37,7 +37,7 @@ func (t *CreateTicketGraphTool) Code() string {
}
func (t *CreateTicketGraphTool) Enabled(ctx registry.Context) bool {
return ctx.Conversation != nil && ctx.AIAgent != nil
return true
}
func (t *CreateTicketGraphTool) Build(ctx registry.Context) (einotool.BaseTool, error) {
@@ -100,7 +100,7 @@ func (t *CreateTicketGraphTool) Info(ctx context.Context) (*schema.ToolInfo, err
}
func (t *CreateTicketGraphTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...einotool.Option) (string, error) {
if t == nil || t.conversation == nil || t.aiAgent == nil {
if t == nil || t.conversation == nil {
return "", fmt.Errorf("create ticket graph tool not initialized")
}
return graphs.NewCreateTicketGraph(t.conversation, t.aiAgent).Run(ctx, argumentsInJSON)
@@ -17,7 +17,7 @@ import (
type HandoffGraphTool struct {
conversation *models.Conversation
aiAgent *models.AIAgent
aiAgent models.AIAgent
}
func NewHandoffGraphTool() *HandoffGraphTool {
@@ -37,7 +37,7 @@ func (t *HandoffGraphTool) Code() string {
}
func (t *HandoffGraphTool) Enabled(ctx registry.Context) bool {
return ctx.Conversation != nil && ctx.AIAgent != nil
return true
}
func (t *HandoffGraphTool) Build(ctx registry.Context) (einotool.BaseTool, error) {
@@ -75,7 +75,7 @@ func (t *HandoffGraphTool) Info(ctx context.Context) (*schema.ToolInfo, error) {
}
func (t *HandoffGraphTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...einotool.Option) (string, error) {
if t == nil || t.conversation == nil || t.aiAgent == nil {
if t == nil || t.conversation == nil {
return "", fmt.Errorf("handoff graph tool not initialized")
}
return graphs.NewHandoffGraph(t.conversation, t.aiAgent).Run(ctx, argumentsInJSON)