Implement skill debugging functionality and refactor skill execution flow

This commit is contained in:
mlogclub
2026-04-09 11:58:04 +08:00
parent eb9cd78646
commit 28d18ab6c0
12 changed files with 321 additions and 233 deletions
+55 -32
View File
@@ -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
}