diff --git a/internal/ai/runtime/internal/impl/adapter/tool_result_reducer.go b/internal/ai/runtime/internal/impl/adapter/tool_result_reducer.go index 73885c8..fd30034 100644 --- a/internal/ai/runtime/internal/impl/adapter/tool_result_reducer.go +++ b/internal/ai/runtime/internal/impl/adapter/tool_result_reducer.go @@ -3,6 +3,8 @@ package adapter import ( "encoding/json" "fmt" + "regexp" + "strconv" "strings" "cs-agent/internal/ai/mcps" @@ -13,6 +15,14 @@ const ( maxToolResultSegments = 12 ) +var reductionInfoPattern = regexp.MustCompile(`\[tool result reduced: original_length=(\d+), kept_length=(\d+)\]`) + +type ReductionInfo struct { + Reduced bool + OriginalChars int + KeptChars int +} + // BuildReducedToolResultSummary returns a bounded text summary for MCP tool results. // It keeps the main payload visible to the model while preventing a single large tool // response from exhausting too much context. @@ -36,6 +46,23 @@ func BuildReducedToolResultSummary(result *mcps.ToolCallResult) string { return fmt.Sprintf("%s\n\n[tool result reduced: original_length=%d, kept_length=%d]", truncated, len(runes), maxToolResultSummaryChars) } +func ParseReductionInfo(summary string) ReductionInfo { + matches := reductionInfoPattern.FindStringSubmatch(strings.TrimSpace(summary)) + if len(matches) != 3 { + return ReductionInfo{} + } + originalChars, err1 := strconv.Atoi(matches[1]) + keptChars, err2 := strconv.Atoi(matches[2]) + if err1 != nil || err2 != nil { + return ReductionInfo{} + } + return ReductionInfo{ + Reduced: true, + OriginalChars: originalChars, + KeptChars: keptChars, + } +} + func collectToolResultSegments(result *mcps.ToolCallResult) []string { segments := make([]string, 0, len(result.Content)+2) if result.IsError { diff --git a/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go b/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go index 03efdd9..5ace925 100644 --- a/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go +++ b/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go @@ -6,6 +6,7 @@ import ( "strings" "time" + impladapter "cs-agent/internal/ai/runtime/internal/impl/adapter" "cs-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" @@ -43,6 +44,10 @@ func (h *RuntimeTraceHandler) WrapInvokableToolCall(_ context.Context, endpoint LatencyMs: time.Since(startedAt).Milliseconds(), Status: "ok", } + reductionInfo := impladapter.ParseReductionInfo(result) + item.ResultReduced = reductionInfo.Reduced + item.OriginalChars = reductionInfo.OriginalChars + item.KeptChars = reductionInfo.KeptChars if tCtx != nil { item.ToolName = strings.TrimSpace(tCtx.Name) if metadata, ok := h.toolMetadataBy[item.ToolName]; ok { @@ -65,6 +70,9 @@ func (h *RuntimeTraceHandler) WrapInvokableToolCall(_ context.Context, endpoint ToolName: item.ToolName, Arguments: item.Arguments, ResultPreview: item.ResultPreview, + ResultReduced: item.ResultReduced, + OriginalChars: item.OriginalChars, + KeptChars: item.KeptChars, LatencyMs: item.LatencyMs, Status: item.Status, ErrorMessage: item.ErrorMessage, diff --git a/internal/ai/runtime/internal/impl/callbacks/trace_callback.go b/internal/ai/runtime/internal/impl/callbacks/trace_callback.go index bb5d686..604265d 100644 --- a/internal/ai/runtime/internal/impl/callbacks/trace_callback.go +++ b/internal/ai/runtime/internal/impl/callbacks/trace_callback.go @@ -6,6 +6,9 @@ type ToolTraceItem struct { ToolName string `json:"toolName"` Arguments map[string]any `json:"arguments,omitempty"` ResultPreview string `json:"resultPreview,omitempty"` + ResultReduced bool `json:"resultReduced,omitempty"` + OriginalChars int `json:"originalChars,omitempty"` + KeptChars int `json:"keptChars,omitempty"` LatencyMs int64 `json:"latencyMs,omitempty"` Status string `json:"status,omitempty"` ErrorMessage string `json:"errorMessage,omitempty"` @@ -27,6 +30,9 @@ type GraphToolTraceItem struct { ToolName string `json:"toolName"` Arguments map[string]any `json:"arguments,omitempty"` ResultPreview string `json:"resultPreview,omitempty"` + ResultReduced bool `json:"resultReduced,omitempty"` + OriginalChars int `json:"originalChars,omitempty"` + KeptChars int `json:"keptChars,omitempty"` LatencyMs int64 `json:"latencyMs,omitempty"` Status string `json:"status,omitempty"` ErrorMessage string `json:"errorMessage,omitempty"`