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:
@@ -18,9 +18,6 @@ func NewRuntimeTraceCollector() *RuntimeTraceCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) Marshal() string {
|
func (c *RuntimeTraceCollector) Marshal() string {
|
||||||
if c == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
buf, err := json.Marshal(c.Data)
|
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) {
|
func (c *RuntimeTraceCollector) SetTooling(staticToolCodes []string, dynamicToolCodes []string, toolSearchEnabled bool) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Input.StaticToolCodes = append([]string(nil), staticToolCodes...)
|
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) {
|
func (c *RuntimeTraceCollector) SetInstructionSummary(summary InstructionTraceSummary) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Instruction.SectionTitles = append([]string(nil), summary.SectionTitles...)
|
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) {
|
func (c *RuntimeTraceCollector) SetSkillMiddleware(enabled bool, toolName string) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Skill.MiddlewareEnabled = enabled
|
c.Data.Skill.MiddlewareEnabled = enabled
|
||||||
@@ -71,7 +59,7 @@ type SkillMetadata struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) SetVisibleSkills(skills map[string]SkillMetadata) {
|
func (c *RuntimeTraceCollector) SetVisibleSkills(skills map[string]SkillMetadata) {
|
||||||
if c == nil || len(skills) == 0 {
|
if len(skills) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.mu.Lock()
|
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) {
|
func (c *RuntimeTraceCollector) ActivateSkill(skill SkillMetadata, routeReason string, routeTrace string) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Skill.Code = skill.Code
|
c.Data.Skill.Code = skill.Code
|
||||||
@@ -101,18 +86,12 @@ func (c *RuntimeTraceCollector) ActivateSkill(skill SkillMetadata, routeReason s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) SetFilteredToolCodes(toolCodes []string) {
|
func (c *RuntimeTraceCollector) SetFilteredToolCodes(toolCodes []string) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Skill.FilteredToolCodes = append([]string(nil), toolCodes...)
|
c.Data.Skill.FilteredToolCodes = append([]string(nil), toolCodes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) SetRetrieverSummary(summary RetrieverTraceSummary) {
|
func (c *RuntimeTraceCollector) SetRetrieverSummary(summary RetrieverTraceSummary) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Retriever.TopK = summary.TopK
|
c.Data.Retriever.TopK = summary.TopK
|
||||||
@@ -128,9 +107,6 @@ func (c *RuntimeTraceCollector) SetRetrieverSummary(summary RetrieverTraceSummar
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) {
|
func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.Tools.Count++
|
c.Data.Tools.Count++
|
||||||
@@ -138,9 +114,6 @@ func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) AddToolSearchItem(item ToolSearchTraceItem) {
|
func (c *RuntimeTraceCollector) AddToolSearchItem(item ToolSearchTraceItem) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.ToolSearch.Count++
|
c.Data.ToolSearch.Count++
|
||||||
@@ -148,9 +121,6 @@ func (c *RuntimeTraceCollector) AddToolSearchItem(item ToolSearchTraceItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *RuntimeTraceCollector) AddGraphToolItem(item GraphToolTraceItem) {
|
func (c *RuntimeTraceCollector) AddGraphToolItem(item GraphToolTraceItem) {
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.Data.GraphTools.Count++
|
c.Data.GraphTools.Count++
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func NewAgentFactory() *AgentFactory {
|
|||||||
chatModelFactory: NewChatModelFactory(),
|
chatModelFactory: NewChatModelFactory(),
|
||||||
toolFactory: NewToolFactory(),
|
toolFactory: NewToolFactory(),
|
||||||
instructionService: instruction.NewService(nil, nil, nil),
|
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...)
|
allTools = append(allTools, input.StaticTools...)
|
||||||
instructionResult := f.instructionService.Build(input.AIAgent, nil, input.InstructionToolDefinitions, input.StaticToolCodes)
|
instructionResult := f.instructionService.Build(input.AIAgent, nil, input.InstructionToolDefinitions, input.StaticToolCodes)
|
||||||
handlers := make([]adk.ChatModelAgentMiddleware, 0, 3)
|
handlers := make([]adk.ChatModelAgentMiddleware, 0, 3)
|
||||||
if f.handlerService != nil {
|
builtHandlers, err := f.handlerService.Build(ctx, BuildAgentHandlersInput{
|
||||||
builtHandlers, err := f.handlerService.Build(ctx, BuildAgentHandlersInput{
|
AIAgent: input.AIAgent,
|
||||||
AIAgent: input.AIAgent,
|
InstructionToolDefinitions: input.InstructionToolDefinitions,
|
||||||
InstructionToolDefinitions: input.InstructionToolDefinitions,
|
DynamicToolDefinitions: input.DynamicMCPToolDefinitions,
|
||||||
DynamicToolDefinitions: input.DynamicMCPToolDefinitions,
|
DynamicTools: dynamicTools,
|
||||||
DynamicTools: dynamicTools,
|
StaticToolMetadata: input.StaticToolMetadata,
|
||||||
StaticToolMetadata: input.StaticToolMetadata,
|
Collector: input.Collector,
|
||||||
Collector: input.Collector,
|
InstructionSummary: buildInstructionTraceSummary(instructionResult.Summary),
|
||||||
InstructionSummary: buildInstructionTraceSummary(instructionResult.Summary),
|
})
|
||||||
})
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
handlers = append(handlers, builtHandlers...)
|
|
||||||
}
|
}
|
||||||
|
handlers = append(handlers, builtHandlers...)
|
||||||
inner, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
|
inner, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
|
||||||
Name: strings.TrimSpace(input.AIAgent.Name),
|
Name: strings.TrimSpace(input.AIAgent.Name),
|
||||||
Description: strings.TrimSpace(input.AIAgent.Description),
|
Description: strings.TrimSpace(input.AIAgent.Description),
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type BuildAgentHandlersInput struct {
|
|||||||
|
|
||||||
func NewAgentHandlerService(skillMiddleware *SkillMiddlewareService) *AgentHandlerService {
|
func NewAgentHandlerService(skillMiddleware *SkillMiddlewareService) *AgentHandlerService {
|
||||||
if skillMiddleware == nil {
|
if skillMiddleware == nil {
|
||||||
skillMiddleware = NewSkillMiddlewareService()
|
panic("skill middleware is required")
|
||||||
}
|
}
|
||||||
return &AgentHandlerService{skillMiddleware: skillMiddleware}
|
return &AgentHandlerService{skillMiddleware: skillMiddleware}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func TestAgentHandlerServiceBuildWithCollectorOnly(t *testing.T) {
|
func TestAgentHandlerServiceBuildWithCollectorOnly(t *testing.T) {
|
||||||
collector := einocallbacks.NewRuntimeTraceCollector()
|
collector := einocallbacks.NewRuntimeTraceCollector()
|
||||||
service := NewAgentHandlerService(nil)
|
service := NewAgentHandlerService(NewSkillMiddlewareService())
|
||||||
|
|
||||||
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{
|
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{
|
||||||
Collector: collector,
|
Collector: collector,
|
||||||
@@ -33,7 +33,7 @@ func TestAgentHandlerServiceBuildWithCollectorOnly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAgentHandlerServiceBuildWithEmptyInput(t *testing.T) {
|
func TestAgentHandlerServiceBuildWithEmptyInput(t *testing.T) {
|
||||||
service := NewAgentHandlerService(nil)
|
service := NewAgentHandlerService(NewSkillMiddlewareService())
|
||||||
|
|
||||||
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{})
|
handlers, err := service.Build(context.Background(), BuildAgentHandlersInput{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package runtime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
applicationruntime "cs-agent/internal/ai/application/runtime"
|
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 {
|
func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owner *aiReplyService, replyCtx aiReplyContext) error {
|
||||||
if replyCtx.PendingInterrupt == nil || owner == nil {
|
if replyCtx.PendingInterrupt == nil {
|
||||||
return nil
|
return fmt.Errorf("pending interrupt is required")
|
||||||
}
|
}
|
||||||
summary, err := owner.executor.ResumePendingInterrupt(ctx, runtimeReplyResumeInput{
|
summary, err := owner.executor.ResumePendingInterrupt(ctx, runtimeReplyResumeInput{
|
||||||
Conversation: replyCtx.Conversation,
|
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 {
|
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)
|
pending := buildConversationInterrupt(replyCtx.Conversation, replyCtx.Message, replyCtx.AIAgent, summary)
|
||||||
if err := svc.ConversationInterruptService.CreateOrUpdatePending(pending); err != nil {
|
if err := svc.ConversationInterruptService.CreateOrUpdatePending(pending); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -110,8 +108,8 @@ func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *replyInterruptService) HandleInterruptedResume(owner *aiReplyService, replyCtx aiReplyContext, summary *applicationruntime.Summary) error {
|
func (s *replyInterruptService) HandleInterruptedResume(owner *aiReplyService, replyCtx aiReplyContext, summary *applicationruntime.Summary) error {
|
||||||
if replyCtx.PendingInterrupt == nil || owner == nil {
|
if replyCtx.PendingInterrupt == nil {
|
||||||
return nil
|
return fmt.Errorf("pending interrupt is required")
|
||||||
}
|
}
|
||||||
replyText := resolveInterruptPrompt(summary)
|
replyText := resolveInterruptPrompt(summary)
|
||||||
replyMessage, err := owner.commit.CommitAIReply(replyCommitInput{
|
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) {
|
func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, input runtimeReplyResumeInput) (*applicationruntime.Summary, error) {
|
||||||
if input.PendingInterrupt == nil {
|
if input.PendingInterrupt == nil {
|
||||||
return nil, nil
|
return nil, fmt.Errorf("pending interrupt is required")
|
||||||
}
|
}
|
||||||
aiConfig := svc.AIConfigService.Get(input.AIAgent.AIConfigID)
|
aiConfig := svc.AIConfigService.Get(input.AIAgent.AIConfigID)
|
||||||
if aiConfig == nil {
|
if aiConfig == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user