refactor(runtime): remove nil checks for receiver in RuntimeTraceCollector methods

refactor(factory): enforce skill middleware requirement in NewAgentHandlerService
refactor(reply_interrupt): improve error handling for pending interrupts
This commit is contained in:
mlogclub
2026-04-19 11:40:17 +08:00
parent 3e98e9379c
commit 700ec2a38b
6 changed files with 23 additions and 57 deletions
@@ -18,9 +18,6 @@ func NewRuntimeTraceCollector() *RuntimeTraceCollector {
}
func (c *RuntimeTraceCollector) Marshal() string {
if c == nil {
return ""
}
c.mu.Lock()
defer c.mu.Unlock()
buf, err := json.Marshal(c.Data)
@@ -31,9 +28,6 @@ func (c *RuntimeTraceCollector) Marshal() string {
}
func (c *RuntimeTraceCollector) SetTooling(staticToolCodes []string, dynamicToolCodes []string, toolSearchEnabled bool) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Input.StaticToolCodes = append([]string(nil), staticToolCodes...)
@@ -42,9 +36,6 @@ func (c *RuntimeTraceCollector) SetTooling(staticToolCodes []string, dynamicTool
}
func (c *RuntimeTraceCollector) SetInstructionSummary(summary InstructionTraceSummary) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Instruction.SectionTitles = append([]string(nil), summary.SectionTitles...)
@@ -54,9 +45,6 @@ func (c *RuntimeTraceCollector) SetInstructionSummary(summary InstructionTraceSu
}
func (c *RuntimeTraceCollector) SetSkillMiddleware(enabled bool, toolName string) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Skill.MiddlewareEnabled = enabled
@@ -71,7 +59,7 @@ type SkillMetadata struct {
}
func (c *RuntimeTraceCollector) SetVisibleSkills(skills map[string]SkillMetadata) {
if c == nil || len(skills) == 0 {
if len(skills) == 0 {
return
}
c.mu.Lock()
@@ -87,9 +75,6 @@ func (c *RuntimeTraceCollector) SetVisibleSkills(skills map[string]SkillMetadata
}
func (c *RuntimeTraceCollector) ActivateSkill(skill SkillMetadata, routeReason string, routeTrace string) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Skill.Code = skill.Code
@@ -101,18 +86,12 @@ func (c *RuntimeTraceCollector) ActivateSkill(skill SkillMetadata, routeReason s
}
func (c *RuntimeTraceCollector) SetFilteredToolCodes(toolCodes []string) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Skill.FilteredToolCodes = append([]string(nil), toolCodes...)
}
func (c *RuntimeTraceCollector) SetRetrieverSummary(summary RetrieverTraceSummary) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Retriever.TopK = summary.TopK
@@ -128,9 +107,6 @@ func (c *RuntimeTraceCollector) SetRetrieverSummary(summary RetrieverTraceSummar
}
func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.Tools.Count++
@@ -138,9 +114,6 @@ func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) {
}
func (c *RuntimeTraceCollector) AddToolSearchItem(item ToolSearchTraceItem) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.ToolSearch.Count++
@@ -148,9 +121,6 @@ func (c *RuntimeTraceCollector) AddToolSearchItem(item ToolSearchTraceItem) {
}
func (c *RuntimeTraceCollector) AddGraphToolItem(item GraphToolTraceItem) {
if c == nil {
return
}
c.mu.Lock()
defer c.mu.Unlock()
c.Data.GraphTools.Count++
@@ -55,7 +55,7 @@ func NewAgentFactory() *AgentFactory {
chatModelFactory: NewChatModelFactory(),
toolFactory: NewToolFactory(),
instructionService: instruction.NewService(nil, nil, nil),
handlerService: NewAgentHandlerService(nil),
handlerService: NewAgentHandlerService(NewSkillMiddlewareService()),
}
}
@@ -73,21 +73,19 @@ func (f *AgentFactory) BuildCustomerServiceAgent(ctx context.Context, input Buil
allTools = append(allTools, input.StaticTools...)
instructionResult := f.instructionService.Build(input.AIAgent, nil, input.InstructionToolDefinitions, input.StaticToolCodes)
handlers := make([]adk.ChatModelAgentMiddleware, 0, 3)
if f.handlerService != nil {
builtHandlers, err := f.handlerService.Build(ctx, BuildAgentHandlersInput{
AIAgent: input.AIAgent,
InstructionToolDefinitions: input.InstructionToolDefinitions,
DynamicToolDefinitions: input.DynamicMCPToolDefinitions,
DynamicTools: dynamicTools,
StaticToolMetadata: input.StaticToolMetadata,
Collector: input.Collector,
InstructionSummary: buildInstructionTraceSummary(instructionResult.Summary),
})
if err != nil {
return nil, err
}
handlers = append(handlers, builtHandlers...)
builtHandlers, err := f.handlerService.Build(ctx, BuildAgentHandlersInput{
AIAgent: input.AIAgent,
InstructionToolDefinitions: input.InstructionToolDefinitions,
DynamicToolDefinitions: input.DynamicMCPToolDefinitions,
DynamicTools: dynamicTools,
StaticToolMetadata: input.StaticToolMetadata,
Collector: input.Collector,
InstructionSummary: buildInstructionTraceSummary(instructionResult.Summary),
})
if err != nil {
return nil, err
}
handlers = append(handlers, builtHandlers...)
inner, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: strings.TrimSpace(input.AIAgent.Name),
Description: strings.TrimSpace(input.AIAgent.Description),
@@ -31,7 +31,7 @@ type BuildAgentHandlersInput struct {
func NewAgentHandlerService(skillMiddleware *SkillMiddlewareService) *AgentHandlerService {
if skillMiddleware == nil {
skillMiddleware = NewSkillMiddlewareService()
panic("skill middleware is required")
}
return &AgentHandlerService{skillMiddleware: skillMiddleware}
}
@@ -9,7 +9,7 @@ import (
func TestAgentHandlerServiceBuildWithCollectorOnly(t *testing.T) {
collector := einocallbacks.NewRuntimeTraceCollector()
service := NewAgentHandlerService(nil)
service := NewAgentHandlerService(NewSkillMiddlewareService())
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{
Collector: collector,
@@ -33,7 +33,7 @@ func TestAgentHandlerServiceBuildWithCollectorOnly(t *testing.T) {
}
func TestAgentHandlerServiceBuildWithEmptyInput(t *testing.T) {
service := NewAgentHandlerService(nil)
service := NewAgentHandlerService(NewSkillMiddlewareService())
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{})
if err != nil {
@@ -2,6 +2,7 @@ package runtime
import (
"context"
"fmt"
"strings"
applicationruntime "cs-agent/internal/ai/application/runtime"
@@ -16,8 +17,8 @@ func newReplyInterruptService() *replyInterruptService {
}
func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owner *aiReplyService, replyCtx aiReplyContext) error {
if replyCtx.PendingInterrupt == nil || owner == nil {
return nil
if replyCtx.PendingInterrupt == nil {
return fmt.Errorf("pending interrupt is required")
}
summary, err := owner.executor.ResumePendingInterrupt(ctx, runtimeReplyResumeInput{
Conversation: replyCtx.Conversation,
@@ -83,9 +84,6 @@ func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owne
}
func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService, replyCtx aiReplyContext, summary *applicationruntime.Summary) error {
if owner == nil {
return nil
}
pending := buildConversationInterrupt(replyCtx.Conversation, replyCtx.Message, replyCtx.AIAgent, summary)
if err := svc.ConversationInterruptService.CreateOrUpdatePending(pending); err != nil {
return err
@@ -110,8 +108,8 @@ func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService,
}
func (s *replyInterruptService) HandleInterruptedResume(owner *aiReplyService, replyCtx aiReplyContext, summary *applicationruntime.Summary) error {
if replyCtx.PendingInterrupt == nil || owner == nil {
return nil
if replyCtx.PendingInterrupt == nil {
return fmt.Errorf("pending interrupt is required")
}
replyText := resolveInterruptPrompt(summary)
replyMessage, err := owner.commit.CommitAIReply(replyCommitInput{
@@ -55,7 +55,7 @@ func (e *runtimeReplyExecutor) Run(ctx context.Context, input runtimeReplyRunInp
func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, input runtimeReplyResumeInput) (*applicationruntime.Summary, error) {
if input.PendingInterrupt == nil {
return nil, nil
return nil, fmt.Errorf("pending interrupt is required")
}
aiConfig := svc.AIConfigService.Get(input.AIAgent.AIConfigID)
if aiConfig == nil {