fix: add structured graph tool results
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"cs-agent/internal/ai/runtime/internal/impl/callbacks"
|
||||
"cs-agent/internal/ai/runtime/tooling"
|
||||
"cs-agent/internal/pkg/enums"
|
||||
"cs-agent/internal/pkg/toolx"
|
||||
|
||||
@@ -64,10 +65,13 @@ func consumeAgentEvents(events *adk.AsyncIterator[*adk.AgentEvent], summary *Run
|
||||
summary.InvokedToolCodes = appendIfMissing(summary.InvokedToolCodes, toolCode)
|
||||
if strings.TrimSpace(summary.ReplyText) == "" && toolx.ResolveToolSourceType(toolCode) == enums.ToolSourceTypeGraph {
|
||||
toolReplyText := strings.TrimSpace(messageOutput.Message.Content)
|
||||
if toolReplyText != "" {
|
||||
summary.ReplyText = toolReplyText
|
||||
} else if toolCode == toolx.GraphHandoffConversation.Code {
|
||||
suppressAssistantReply = true
|
||||
if result, ok := tooling.ParseToolResult(toolReplyText); ok {
|
||||
if result.ReplyText != "" && !result.ReplySent {
|
||||
summary.ReplyText = result.ReplyText
|
||||
}
|
||||
if result.Terminal && !result.ShouldRetry {
|
||||
suppressAssistantReply = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"cs-agent/internal/ai/runtime/tooling"
|
||||
"cs-agent/internal/pkg/toolx"
|
||||
|
||||
"github.com/cloudwego/eino/adk"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
)
|
||||
|
||||
func TestConsumeAgentEventsUsesGraphToolTextAsReplyFallback(t *testing.T) {
|
||||
func TestConsumeAgentEventsIgnoresPlainGraphToolText(t *testing.T) {
|
||||
summary := &RunResult{
|
||||
Status: "started",
|
||||
InvokedToolCodes: make([]string, 0),
|
||||
@@ -32,7 +34,7 @@ func TestConsumeAgentEventsUsesGraphToolTextAsReplyFallback(t *testing.T) {
|
||||
toolx.GraphHandoffConversation.Name: toolx.GraphHandoffConversation.Code,
|
||||
})
|
||||
|
||||
if summary.ReplyText != "已为你转接人工客服,请稍候。,请稍候。" {
|
||||
if summary.ReplyText != "" {
|
||||
t.Fatalf("unexpected reply text: %q", summary.ReplyText)
|
||||
}
|
||||
if summary.Status != "completed" {
|
||||
@@ -40,6 +42,109 @@ func TestConsumeAgentEventsUsesGraphToolTextAsReplyFallback(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeAgentEventsUsesGraphToolResultReplyText(t *testing.T) {
|
||||
summary := &RunResult{
|
||||
Status: "started",
|
||||
InvokedToolCodes: make([]string, 0),
|
||||
}
|
||||
payload, err := json.Marshal(tooling.ToolResult{
|
||||
Handled: true,
|
||||
Terminal: true,
|
||||
Action: "off_hours_handoff",
|
||||
ReplyText: "当前暂不在人工客服服务时间内,你可以先继续描述问题。",
|
||||
ShouldRetry: false,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("marshal graph tool result: %v", err)
|
||||
}
|
||||
events, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Tool,
|
||||
ToolName: toolx.GraphHandoffConversation.Name,
|
||||
Message: &schema.Message{
|
||||
Content: string(payload),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Assistant,
|
||||
Message: &schema.Message{
|
||||
Content: "我再试一次转人工。",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Close()
|
||||
|
||||
consumeAgentEvents(events, summary, nil, map[string]string{
|
||||
toolx.GraphHandoffConversation.Name: toolx.GraphHandoffConversation.Code,
|
||||
})
|
||||
|
||||
if summary.ReplyText != "当前暂不在人工客服服务时间内,你可以先继续描述问题。" {
|
||||
t.Fatalf("unexpected reply text: %q", summary.ReplyText)
|
||||
}
|
||||
if summary.Status != "completed" {
|
||||
t.Fatalf("unexpected summary status: %q", summary.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeAgentEventsSuppressesGraphToolResultWhenReplyAlreadySent(t *testing.T) {
|
||||
summary := &RunResult{
|
||||
Status: "started",
|
||||
InvokedToolCodes: make([]string, 0),
|
||||
}
|
||||
payload, err := json.Marshal(tooling.ToolResult{
|
||||
Handled: true,
|
||||
Terminal: true,
|
||||
Action: "off_hours_handoff",
|
||||
ReplyText: "当前暂不在人工客服服务时间内,你可以先继续描述问题。",
|
||||
ReplySent: true,
|
||||
ShouldRetry: false,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("marshal graph tool result: %v", err)
|
||||
}
|
||||
events, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Tool,
|
||||
ToolName: toolx.GraphHandoffConversation.Name,
|
||||
Message: &schema.Message{
|
||||
Content: string(payload),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Assistant,
|
||||
Message: &schema.Message{
|
||||
Content: "我再试一次转人工。",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Close()
|
||||
|
||||
consumeAgentEvents(events, summary, nil, map[string]string{
|
||||
toolx.GraphHandoffConversation.Name: toolx.GraphHandoffConversation.Code,
|
||||
})
|
||||
|
||||
if summary.ReplyText != "" {
|
||||
t.Fatalf("expected no committed reply because graph already sent it, got %q", summary.ReplyText)
|
||||
}
|
||||
if summary.Status != "completed" {
|
||||
t.Fatalf("unexpected summary status: %q", summary.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeAgentEventsCompletesGraphToolWithNoVisibleReply(t *testing.T) {
|
||||
summary := &RunResult{
|
||||
Status: "started",
|
||||
@@ -70,44 +175,3 @@ func TestConsumeAgentEventsCompletesGraphToolWithNoVisibleReply(t *testing.T) {
|
||||
t.Fatalf("unexpected summary status: %q", summary.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeAgentEventsSuppressesAssistantReplyAfterSilentHandoffTool(t *testing.T) {
|
||||
summary := &RunResult{
|
||||
Status: "started",
|
||||
InvokedToolCodes: make([]string, 0),
|
||||
}
|
||||
events, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Tool,
|
||||
ToolName: toolx.GraphHandoffConversation.Name,
|
||||
Message: &schema.Message{
|
||||
Content: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Send(&adk.AgentEvent{
|
||||
Output: &adk.AgentOutput{
|
||||
MessageOutput: &adk.MessageVariant{
|
||||
Role: schema.Assistant,
|
||||
Message: &schema.Message{
|
||||
Content: "好的,已为您发起转接人工客服的请求。系统正在为您确认,请稍候。",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
gen.Close()
|
||||
|
||||
consumeAgentEvents(events, summary, nil, map[string]string{
|
||||
toolx.GraphHandoffConversation.Name: toolx.GraphHandoffConversation.Code,
|
||||
})
|
||||
|
||||
if summary.ReplyText != "" {
|
||||
t.Fatalf("expected assistant reply after silent handoff to be suppressed, got %q", summary.ReplyText)
|
||||
}
|
||||
if summary.Status != "completed" {
|
||||
t.Fatalf("unexpected summary status: %q", summary.Status)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user