Refactor skill handling and improve runtime trace capabilities
- Removed the selectSkill method from prepareService and adjusted related logic in the Run method of Service. - Updated tool catalog to parse agent allowed tool codes directly. - Simplified Request and RunInput structures by removing unnecessary fields. - Enhanced the RuntimeTraceCollector to manage skill activation and visibility. - Introduced a new databaseSkillBackend to manage skill definitions and their metadata. - Added tests for skill backend functionalities to ensure correct behavior. - Updated various factory methods to accommodate changes in skill handling. - Improved documentation and descriptions for better clarity.
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"cs-agent/internal/ai/skills"
|
||||
"cs-agent/internal/models"
|
||||
)
|
||||
|
||||
func newPrepareService(catalog *toolCatalog) *prepareService {
|
||||
return &prepareService{catalog: catalog}
|
||||
}
|
||||
@@ -17,28 +8,6 @@ type prepareService struct {
|
||||
catalog *toolCatalog
|
||||
}
|
||||
|
||||
func (s *prepareService) selectSkill(ctx context.Context, req Request) (*models.SkillDefinition, string, string, error) {
|
||||
result, err := skills.Select(ctx, skills.RuntimeContext{
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
UserMessage: strings.TrimSpace(req.UserMessage.Content),
|
||||
ConversationID: req.Conversation.ID,
|
||||
ManualSkillCode: strings.TrimSpace(req.ManualSkillCode),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
if result == nil || result.Plan == nil || result.Plan.Skill == nil {
|
||||
traceData := marshalSkillRouteTrace(result)
|
||||
reason := ""
|
||||
if result != nil && result.Plan != nil {
|
||||
reason = strings.TrimSpace(result.Plan.MatchReason)
|
||||
}
|
||||
return nil, reason, traceData, nil
|
||||
}
|
||||
return result.Plan.Skill, strings.TrimSpace(result.Plan.MatchReason), marshalSkillRouteTrace(result), nil
|
||||
}
|
||||
|
||||
func (s *prepareService) prepareToolsForRun(req *Request) error {
|
||||
if req == nil || req.ToolSet != nil || s.catalog == nil {
|
||||
return nil
|
||||
@@ -66,22 +35,3 @@ func (s *prepareService) prepareToolsForResume(req *ResumeRequest) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func marshalSkillRouteTrace(result *skills.ExecutionResult) string {
|
||||
if result == nil || result.Plan == nil || result.Plan.RouteTrace == nil {
|
||||
return ""
|
||||
}
|
||||
buf, err := json.Marshal(result.Plan.RouteTrace)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func cloneSkillDefinition(item *models.SkillDefinition) *models.SkillDefinition {
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
clone := *item
|
||||
return &clone
|
||||
}
|
||||
|
||||
@@ -27,39 +27,21 @@ func (s *Service) Run(ctx context.Context, req Request) (*Summary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
req.UserMessage.Content = utils.BuildRuntimeMessageText(req.UserMessage.MessageType, req.UserMessage.Content)
|
||||
selectedSkill, skillReason, skillTrace, skillErr := s.prepare.selectSkill(ctx, req)
|
||||
req.SelectedSkill = selectedSkill
|
||||
req.SkillRouteReason = skillReason
|
||||
req.SkillRouteTrace = skillTrace
|
||||
if req.SelectedSkill != nil {
|
||||
req.SelectedSkill = cloneSkillDefinition(req.SelectedSkill)
|
||||
}
|
||||
if err := s.prepare.prepareToolsForRun(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
summary, err := s.runtime.ExecuteRun(ctx, executor.RunInput{
|
||||
Conversation: req.Conversation,
|
||||
UserMessage: req.UserMessage,
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
SelectedSkill: req.SelectedSkill,
|
||||
SkillRouteReason: req.SkillRouteReason,
|
||||
SkillRouteTrace: req.SkillRouteTrace,
|
||||
CheckPointID: req.CheckPointID,
|
||||
ToolSet: req.ToolSet,
|
||||
Conversation: req.Conversation,
|
||||
UserMessage: req.UserMessage,
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
CheckPointID: req.CheckPointID,
|
||||
ToolSet: req.ToolSet,
|
||||
})
|
||||
if err != nil {
|
||||
ret := toSummary(summary)
|
||||
if ret != nil && skillErr != nil && ret.PlanReason == "" {
|
||||
ret.PlanReason = "skill_failed_fallback_runtime"
|
||||
}
|
||||
return ret, err
|
||||
return toSummary(summary), err
|
||||
}
|
||||
ret := toSummary(summary)
|
||||
if ret != nil && skillErr != nil && ret.PlanReason == "" {
|
||||
ret.PlanReason = "skill_failed_fallback_runtime"
|
||||
}
|
||||
return ret, nil
|
||||
return toSummary(summary), nil
|
||||
}
|
||||
|
||||
func (s *Service) Resume(ctx context.Context, req ResumeRequest) (*Summary, error) {
|
||||
|
||||
@@ -41,7 +41,7 @@ func (c *toolCatalog) resolveForRun(req *Request) (*registry.ToolSet, error) {
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
UserMessage: req.UserMessage,
|
||||
AllowedToolCodes: c.resolveAllowedToolCodes(req.AIAgent, req.SelectedSkill),
|
||||
AllowedToolCodes: c.parseAgentAllowedToolCodes(req.AIAgent),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,12 @@ import (
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Conversation models.Conversation
|
||||
UserMessage models.Message
|
||||
AIAgent models.AIAgent
|
||||
AIConfig models.AIConfig
|
||||
ManualSkillCode string
|
||||
SelectedSkill *models.SkillDefinition
|
||||
SkillRouteReason string
|
||||
SkillRouteTrace string
|
||||
CheckPointID string
|
||||
ToolSet *registry.ToolSet
|
||||
Conversation models.Conversation
|
||||
UserMessage models.Message
|
||||
AIAgent models.AIAgent
|
||||
AIConfig models.AIConfig
|
||||
CheckPointID string
|
||||
ToolSet *registry.ToolSet
|
||||
}
|
||||
|
||||
type ResumeRequest struct {
|
||||
|
||||
Reference in New Issue
Block a user