refactor: remove trace data from reply context and related services

This commit is contained in:
mlogclub
2026-06-23 23:29:29 +08:00
parent 6122a1d881
commit 02ae515bd6
10 changed files with 1 additions and 110 deletions
@@ -21,7 +21,6 @@ type replyCommitInput struct {
Message models.Message
AIAgent models.AIAgent
ReplyText string
Trace *aiReplyTraceData
ClientPrefix string
IncrementRound bool
}
@@ -35,7 +34,6 @@ func (s *replyCommitService) SendAIReply(input replyCommitInput) (*models.Messag
if replyText == "" {
return nil, nil
}
commitStartedAt := time.Now()
replyMessage, err := svc.MessageService.SendAIMessageWithRequestID(
input.Conversation.ID,
input.AIAgent.ID,
@@ -46,13 +44,6 @@ func (s *replyCommitService) SendAIReply(input replyCommitInput) (*models.Messag
s.buildAIPrincipal(input.AIAgent),
input.Message.RequestID,
)
if input.Trace != nil {
input.Trace.CommitMs = time.Since(commitStartedAt).Milliseconds()
input.Trace.ReplySent = err == nil && replyMessage != nil
if replyMessage != nil {
input.Trace.ReplyMessageID = replyMessage.ID
}
}
if err != nil || !input.IncrementRound {
return replyMessage, err
}
-1
View File
@@ -9,7 +9,6 @@ type aiReplyContext struct {
Conversation models.Conversation
Message models.Message
AIAgent models.AIAgent
Trace *aiReplyTraceData
SummaryRef **applicationruntime.Summary
PendingInterrupt *models.ConversationInterrupt
}
-12
View File
@@ -8,18 +8,6 @@ import (
"agent-desk/internal/pkg/toolx"
)
func TestRuntimeTraceFinalAction(t *testing.T) {
if got := runtimeTraceFinalAction(&applicationruntime.Summary{Status: "completed", ReplyText: "ok"}); got != "reply" {
t.Fatalf("expected reply final action, got %q", got)
}
if got := runtimeTraceFinalAction(&applicationruntime.Summary{Status: "completed"}); got != "completed" {
t.Fatalf("expected completed final action, got %q", got)
}
if got := runtimeTraceFinalAction(&applicationruntime.Summary{Status: "fallback"}); got != "fallback" {
t.Fatalf("expected fallback final action, got %q", got)
}
}
func TestExtractRuntimeToolTraces(t *testing.T) {
summary := &applicationruntime.Summary{
TraceData: `{
@@ -25,21 +25,17 @@ func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owne
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
PendingInterrupt: replyCtx.PendingInterrupt,
Trace: replyCtx.Trace,
})
replyCtx.setSummary(summary)
if err != nil {
if isCheckpointMissingError(err) {
summary = expiredInterruptSummary()
replyCtx.setSummary(summary)
replyCtx.Trace.Status = "interrupt_expired"
replyCtx.Trace.FinalAction = "expired"
replyMessage, expireErr := owner.commit.CommitAIReply(replyCommitInput{
Conversation: replyCtx.Conversation,
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
ReplyText: summary.ReplyText,
Trace: replyCtx.Trace,
ClientPrefix: "ai_interrupt_expired",
})
if expireErr != nil {
@@ -65,7 +61,6 @@ func (s *replyInterruptService) ResumePendingInterrupt(ctx context.Context, owne
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
ReplyText: summary.ReplyText,
Trace: replyCtx.Trace,
ClientPrefix: "ai_resume",
})
if err != nil {
@@ -95,7 +90,6 @@ func (s *replyInterruptService) HandleInterruptedSummary(owner *aiReplyService,
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
ReplyText: replyText,
Trace: replyCtx.Trace,
ClientPrefix: "ai_interrupt",
})
if err != nil {
@@ -117,7 +111,6 @@ func (s *replyInterruptService) HandleInterruptedResume(owner *aiReplyService, r
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
ReplyText: replyText,
Trace: replyCtx.Trace,
ClientPrefix: "ai_interrupt_resume",
})
if err != nil {
+1 -6
View File
@@ -45,13 +45,11 @@ func (s *aiReplyService) TriggerReplyAsync(conversation models.Conversation, mes
}
func (s *aiReplyService) TriggerReply(ctx context.Context, conversation models.Conversation, message models.Message, aiAgent models.AIAgent) (retErr error) {
trace := &aiReplyTraceData{Status: "started"}
var summary *applicationruntime.Summary
replyCtx := aiReplyContext{
Conversation: conversation,
Message: message,
AIAgent: aiAgent,
Trace: trace,
SummaryRef: &summary,
}
if err := ctx.Err(); err != nil {
@@ -76,7 +74,6 @@ func (s *aiReplyService) executeReply(ctx context.Context, replyCtx aiReplyConte
Conversation: replyCtx.Conversation,
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
Trace: replyCtx.Trace,
})
replyCtx.setSummary(summary)
if err != nil {
@@ -86,18 +83,16 @@ func (s *aiReplyService) executeReply(ctx context.Context, replyCtx aiReplyConte
return s.interrupts.HandleInterruptedSummary(s, replyCtx, summary)
}
if summary != nil && strings.TrimSpace(summary.ReplyText) != "" {
replyMessage, err := s.commit.CommitAIReply(replyCommitInput{
_, err := s.commit.CommitAIReply(replyCommitInput{
Conversation: replyCtx.Conversation,
Message: replyCtx.Message,
AIAgent: replyCtx.AIAgent,
ReplyText: summary.ReplyText,
Trace: replyCtx.Trace,
ClientPrefix: "ai_reply",
})
if err != nil {
return err
}
replyCtx.Trace.ReplySent = replyMessage != nil
}
return nil
}
-14
View File
@@ -1,19 +1,5 @@
package runtime
import "encoding/json"
type aiReplyTraceData struct {
Status string `json:"status"`
RuntimeLatencyMs int64 `json:"runtimeLatencyMs,omitempty"`
RecheckMs int64 `json:"recheckMs,omitempty"`
CommitMs int64 `json:"commitMs,omitempty"`
FinalAction string `json:"finalAction,omitempty"`
ResumeSource string `json:"resumeSource,omitempty"`
ReplySent bool `json:"replySent,omitempty"`
ReplyMessageID int64 `json:"replyMessageId,omitempty"`
Runtime json.RawMessage `json:"runtime,omitempty"`
}
const (
defaultAIReplyAsyncTimeoutSeconds = 180
maxAIReplyAsyncTimeoutSeconds = 600
@@ -2,10 +2,8 @@ package runtime
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
applicationruntime "agent-desk/internal/ai/application/runtime"
"agent-desk/internal/ai/runtime/graphs"
@@ -19,7 +17,6 @@ type runtimeReplyRunInput struct {
Conversation models.Conversation
Message models.Message
AIAgent models.AIAgent
Trace *aiReplyTraceData
}
type runtimeReplyResumeInput struct {
@@ -27,7 +24,6 @@ type runtimeReplyResumeInput struct {
Message models.Message
AIAgent models.AIAgent
PendingInterrupt *models.ConversationInterrupt
Trace *aiReplyTraceData
}
func newRuntimeReplyExecutor() *runtimeReplyExecutor {
@@ -39,17 +35,12 @@ func (e *runtimeReplyExecutor) Run(ctx context.Context, input runtimeReplyRunInp
if aiConfig == nil {
return nil, fmt.Errorf("ai config is nil")
}
runtimeStartedAt := time.Now()
summary, err := Service.Run(ctx, applicationruntime.Request{
Conversation: input.Conversation,
UserMessage: input.Message,
AIAgent: input.AIAgent,
AIConfig: *aiConfig,
})
if input.Trace != nil {
input.Trace.RuntimeLatencyMs = time.Since(runtimeStartedAt).Milliseconds()
e.fillTraceFromSummary(input.Trace, summary, err)
}
return summary, err
}
@@ -61,10 +52,6 @@ func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, input
if aiConfig == nil {
return nil, fmt.Errorf("ai config is nil")
}
runtimeStartedAt := time.Now()
if input.Trace != nil {
input.Trace.ResumeSource = "pending_interrupt"
}
summary, err := Service.Resume(ctx, applicationruntime.ResumeRequest{
Conversation: input.Conversation,
UserMessage: input.Message,
@@ -75,32 +62,9 @@ func (e *runtimeReplyExecutor) ResumePendingInterrupt(ctx context.Context, input
strings.TrimSpace(input.PendingInterrupt.InterruptID): strings.TrimSpace(input.Message.Content),
},
})
if input.Trace != nil {
input.Trace.RuntimeLatencyMs = time.Since(runtimeStartedAt).Milliseconds()
e.fillTraceFromSummary(input.Trace, summary, err)
}
return summary, err
}
func (e *runtimeReplyExecutor) fillTraceFromSummary(trace *aiReplyTraceData, summary *applicationruntime.Summary, runErr error) {
if trace == nil {
return
}
if runErr != nil {
trace.Status = "runtime_error"
trace.FinalAction = "error"
if summary != nil {
trace.Runtime = json.RawMessage(summary.TraceData)
}
return
}
trace.Status = "runtime_prepared"
trace.FinalAction = runtimeTraceFinalAction(summary)
if summary != nil && strings.TrimSpace(summary.TraceData) != "" {
trace.Runtime = json.RawMessage(summary.TraceData)
}
}
func expiredInterruptSummary() *applicationruntime.Summary {
return &applicationruntime.Summary{
Status: "expired",
@@ -7,29 +7,6 @@ import (
applicationruntime "agent-desk/internal/ai/application/runtime"
)
func runtimeTraceFinalAction(summary *applicationruntime.Summary) string {
if summary == nil {
return ""
}
switch strings.TrimSpace(summary.Status) {
case "completed":
if strings.TrimSpace(summary.ReplyText) != "" {
return "reply"
}
return "completed"
case "fallback":
return "fallback"
case "error":
return "error"
case "interrupted":
return "interrupted"
case "expired":
return "expired"
default:
return strings.TrimSpace(summary.Status)
}
}
func extractToolSearchTrace(summary *applicationruntime.Summary) string {
if summary == nil {
return ""
-1
View File
@@ -10,7 +10,6 @@ error.e0009: "AI configuration not found."
error.e0010: "Select an AI configuration."
error.e0011: "The AI configuration is not enabled."
error.e0012: "AI configuration not found."
error.e0013: "Agent run log not found."
error.e0014: "Checkpoint not found."
error.e0015: "The checkpoint does not belong to this AI Agent."
error.e0016: "Direct Tool toolCode does not match serverCode."
-1
View File
@@ -10,7 +10,6 @@ error.e0009: "AI 配置不存在"
error.e0010: "AI 配置不能为空"
error.e0011: "AI 配置未启用"
error.e0012: "AI配置不存在"
error.e0013: "Agent 运行日志不存在"
error.e0014: "CheckPoint 不存在"
error.e0015: "CheckPoint 与 AI Agent 不匹配"
error.e0016: "Direct Tool 的 toolCode 与 serverCode 不一致"