Implement skill debugging functionality and refactor skill execution flow
This commit is contained in:
@@ -2,12 +2,14 @@ package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"cs-agent/internal/ai/runtime/internal/engine"
|
||||
"cs-agent/internal/ai/runtime/registry"
|
||||
"cs-agent/internal/ai/runtime/tools"
|
||||
"cs-agent/internal/ai/skills"
|
||||
"cs-agent/internal/models"
|
||||
)
|
||||
|
||||
var Service = newService()
|
||||
@@ -27,21 +29,27 @@ type service struct {
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context, req Request) (*Summary, error) {
|
||||
skillSummary, skillErr := s.tryRunSkill(ctx, req)
|
||||
if skillSummary != nil && strings.TrimSpace(skillSummary.ReplyText) != "" {
|
||||
return skillSummary, nil
|
||||
selectedSkill, skillReason, skillTrace, skillErr := s.selectSkill(ctx, req)
|
||||
req.SelectedSkill = selectedSkill
|
||||
req.SkillRouteReason = skillReason
|
||||
req.SkillRouteTrace = skillTrace
|
||||
if req.SelectedSkill != nil {
|
||||
req.SelectedSkill = cloneSkillDefinition(req.SelectedSkill)
|
||||
}
|
||||
if err := s.prepareToolsForRun(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
summary, err := s.runtime.Run(ctx, engine.Request{
|
||||
Conversation: req.Conversation,
|
||||
UserMessage: req.UserMessage,
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
CheckPointID: req.CheckPointID,
|
||||
ExtraTools: req.ExtraTools,
|
||||
ExtraToolCodes: req.ExtraToolCodes,
|
||||
Conversation: req.Conversation,
|
||||
UserMessage: req.UserMessage,
|
||||
AIAgent: req.AIAgent,
|
||||
AIConfig: req.AIConfig,
|
||||
SelectedSkill: req.SelectedSkill,
|
||||
SkillRouteReason: req.SkillRouteReason,
|
||||
SkillRouteTrace: req.SkillRouteTrace,
|
||||
CheckPointID: req.CheckPointID,
|
||||
ExtraTools: req.ExtraTools,
|
||||
ExtraToolCodes: req.ExtraToolCodes,
|
||||
})
|
||||
if err != nil {
|
||||
ret := toSummary(summary)
|
||||
@@ -119,8 +127,9 @@ func toSummary(summary *engine.Summary) *Summary {
|
||||
RunID: summary.RunID,
|
||||
Status: summary.Status,
|
||||
ReplyText: summary.ReplyText,
|
||||
PlannedSkillCode: "",
|
||||
PlanReason: "",
|
||||
PlannedSkillCode: strings.TrimSpace(summary.SelectedSkillCode),
|
||||
PlanReason: strings.TrimSpace(summary.SkillRouteReason),
|
||||
SkillRouteTrace: strings.TrimSpace(summary.SkillRouteTrace),
|
||||
ModelName: summary.ModelName,
|
||||
PromptTokens: summary.PromptTokens,
|
||||
CompletionTokens: summary.CompletionTokens,
|
||||
@@ -147,31 +156,45 @@ func toSummary(summary *engine.Summary) *Summary {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *service) tryRunSkill(ctx context.Context, req Request) (*Summary, error) {
|
||||
func (s *service) selectSkill(ctx context.Context, req Request) (*models.SkillDefinition, string, string, error) {
|
||||
if req.AIAgent == nil || req.AIConfig == nil || req.UserMessage == nil || req.Conversation == nil {
|
||||
return nil, nil
|
||||
return nil, "", "", nil
|
||||
}
|
||||
result, err := skills.Execute(ctx, skills.RuntimeContext{
|
||||
AIAgentID: req.AIAgent.ID,
|
||||
UserMessage: strings.TrimSpace(req.UserMessage.Content),
|
||||
ConversationID: req.Conversation.ID,
|
||||
result, err := skills.Select(ctx, skills.RuntimeContext{
|
||||
AIAgentID: req.AIAgent.ID,
|
||||
UserMessage: strings.TrimSpace(req.UserMessage.Content),
|
||||
ConversationID: req.Conversation.ID,
|
||||
ManualSkillCode: strings.TrimSpace(req.ManualSkillCode),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
if result == nil || result.Plan == nil || result.Plan.Skill == nil {
|
||||
return nil, nil
|
||||
traceData := marshalSkillRouteTrace(result)
|
||||
reason := ""
|
||||
if result != nil && result.Plan != nil {
|
||||
reason = strings.TrimSpace(result.Plan.MatchReason)
|
||||
}
|
||||
return nil, reason, traceData, nil
|
||||
}
|
||||
traceData := ""
|
||||
if result.RunLog != nil {
|
||||
traceData = result.RunLog.TraceData
|
||||
}
|
||||
return &Summary{
|
||||
Status: "completed",
|
||||
ReplyText: strings.TrimSpace(result.ReplyText),
|
||||
PlannedSkillCode: strings.TrimSpace(result.Plan.Skill.Code),
|
||||
PlanReason: strings.TrimSpace(result.Plan.MatchReason),
|
||||
ModelName: req.AIConfig.ModelName,
|
||||
TraceData: traceData,
|
||||
}, nil
|
||||
return result.Plan.Skill, strings.TrimSpace(result.Plan.MatchReason), marshalSkillRouteTrace(result), 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user