feat: add Graph Tool code and handoff reason to agent run log model and related components
This commit is contained in:
@@ -309,6 +309,8 @@ func (s *aiReplyService) writeRunLog(startedAt time.Time, message models.Message
|
|||||||
SkillRouteTrace: strings.TrimSpace(summarySkillRouteTrace(summary)),
|
SkillRouteTrace: strings.TrimSpace(summarySkillRouteTrace(summary)),
|
||||||
ToolSearchTrace: extractToolSearchTrace(summary),
|
ToolSearchTrace: extractToolSearchTrace(summary),
|
||||||
GraphToolTrace: extractGraphToolTrace(summary),
|
GraphToolTrace: extractGraphToolTrace(summary),
|
||||||
|
GraphToolCode: firstGraphToolCode(summary),
|
||||||
|
HandoffReason: extractHandoffReason(summary),
|
||||||
PlannedToolCode: plannedToolCode,
|
PlannedToolCode: plannedToolCode,
|
||||||
PlanReason: planReason,
|
PlanReason: planReason,
|
||||||
InterruptType: firstInterruptType(summary),
|
InterruptType: firstInterruptType(summary),
|
||||||
@@ -597,6 +599,21 @@ func firstGraphToolCode(summary *Summary) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractHandoffReason(summary *Summary) string {
|
||||||
|
trace := parseRuntimeTraceData(summary.TraceData)
|
||||||
|
for _, item := range trace.GraphTools.Items {
|
||||||
|
if strings.TrimSpace(item.ToolCode) != toolx.GraphHandoffConversationToolCode {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(item.Arguments) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
reason, _ := item.Arguments["reason"].(string)
|
||||||
|
return strings.TrimSpace(reason)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type runtimeTraceProjection struct {
|
type runtimeTraceProjection struct {
|
||||||
ToolSearch struct {
|
ToolSearch struct {
|
||||||
Raw json.RawMessage `json:"-"`
|
Raw json.RawMessage `json:"-"`
|
||||||
@@ -608,7 +625,8 @@ type runtimeTraceProjection struct {
|
|||||||
GraphTools struct {
|
GraphTools struct {
|
||||||
Raw json.RawMessage `json:"-"`
|
Raw json.RawMessage `json:"-"`
|
||||||
Items []struct {
|
Items []struct {
|
||||||
ToolCode string `json:"toolCode"`
|
ToolCode string `json:"toolCode"`
|
||||||
|
Arguments map[string]any `json:"arguments"`
|
||||||
} `json:"items"`
|
} `json:"items"`
|
||||||
} `json:"graphTools"`
|
} `json:"graphTools"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ func BuildAgentRunLog(item *models.AgentRunLog) response.AgentRunLogResponse {
|
|||||||
SkillRouteTrace: item.SkillRouteTrace,
|
SkillRouteTrace: item.SkillRouteTrace,
|
||||||
ToolSearchTrace: item.ToolSearchTrace,
|
ToolSearchTrace: item.ToolSearchTrace,
|
||||||
GraphToolTrace: item.GraphToolTrace,
|
GraphToolTrace: item.GraphToolTrace,
|
||||||
|
GraphToolCode: item.GraphToolCode,
|
||||||
|
HandoffReason: item.HandoffReason,
|
||||||
PlannedToolCode: item.PlannedToolCode,
|
PlannedToolCode: item.PlannedToolCode,
|
||||||
PlanReason: item.PlanReason,
|
PlanReason: item.PlanReason,
|
||||||
InterruptType: item.InterruptType,
|
InterruptType: item.InterruptType,
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ func (c *AgentRunLogController) AnyList() *web.JsonResult {
|
|||||||
params.QueryFilter{ParamName: "aiAgentId"},
|
params.QueryFilter{ParamName: "aiAgentId"},
|
||||||
params.QueryFilter{ParamName: "plannedAction"},
|
params.QueryFilter{ParamName: "plannedAction"},
|
||||||
params.QueryFilter{ParamName: "plannedSkillCode", Op: params.Like},
|
params.QueryFilter{ParamName: "plannedSkillCode", Op: params.Like},
|
||||||
|
params.QueryFilter{ParamName: "graphToolCode"},
|
||||||
|
params.QueryFilter{ParamName: "interruptType"},
|
||||||
|
params.QueryFilter{ParamName: "resumeSource"},
|
||||||
|
params.QueryFilter{ParamName: "finalStatus"},
|
||||||
|
params.QueryFilter{ParamName: "handoffReason", Op: params.Like},
|
||||||
params.QueryFilter{ParamName: "finalAction"},
|
params.QueryFilter{ParamName: "finalAction"},
|
||||||
params.QueryFilter{ParamName: "userMessage", Op: params.Like},
|
params.QueryFilter{ParamName: "userMessage", Op: params.Like},
|
||||||
).Desc("id")
|
).Desc("id")
|
||||||
|
|||||||
@@ -952,6 +952,8 @@ type AgentRunLog struct {
|
|||||||
SkillRouteTrace string `gorm:"type:text"`
|
SkillRouteTrace string `gorm:"type:text"`
|
||||||
ToolSearchTrace string `gorm:"type:text"`
|
ToolSearchTrace string `gorm:"type:text"`
|
||||||
GraphToolTrace string `gorm:"type:text"`
|
GraphToolTrace string `gorm:"type:text"`
|
||||||
|
GraphToolCode string `gorm:"type:varchar(200);not null;default:'';index"`
|
||||||
|
HandoffReason string `gorm:"type:varchar(500);not null;default:''"`
|
||||||
PlannedToolCode string `gorm:"type:varchar(200);not null;default:'';index"`
|
PlannedToolCode string `gorm:"type:varchar(200);not null;default:'';index"`
|
||||||
PlanReason string `gorm:"type:varchar(500);not null;default:''"`
|
PlanReason string `gorm:"type:varchar(500);not null;default:''"`
|
||||||
InterruptType string `gorm:"type:varchar(50);not null;default:'';index"`
|
InterruptType string `gorm:"type:varchar(50);not null;default:'';index"`
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ type AgentRunLogResponse struct {
|
|||||||
SkillRouteTrace string `json:"skillRouteTrace"`
|
SkillRouteTrace string `json:"skillRouteTrace"`
|
||||||
ToolSearchTrace string `json:"toolSearchTrace"`
|
ToolSearchTrace string `json:"toolSearchTrace"`
|
||||||
GraphToolTrace string `json:"graphToolTrace"`
|
GraphToolTrace string `json:"graphToolTrace"`
|
||||||
|
GraphToolCode string `json:"graphToolCode"`
|
||||||
|
HandoffReason string `json:"handoffReason"`
|
||||||
PlannedToolCode string `json:"plannedToolCode"`
|
PlannedToolCode string `json:"plannedToolCode"`
|
||||||
PlanReason string `json:"planReason"`
|
PlanReason string `json:"planReason"`
|
||||||
InterruptType string `json:"interruptType"`
|
InterruptType string `json:"interruptType"`
|
||||||
|
|||||||
@@ -51,6 +51,15 @@ const actionOptions = [
|
|||||||
{ value: "fallback", label: "兜底" },
|
{ value: "fallback", label: "兜底" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const finalStatusOptions = [
|
||||||
|
{ value: "all", label: "全部状态" },
|
||||||
|
{ value: "completed", label: "completed" },
|
||||||
|
{ value: "interrupted", label: "interrupted" },
|
||||||
|
{ value: "expired", label: "expired" },
|
||||||
|
{ value: "error", label: "error" },
|
||||||
|
{ value: "fallback", label: "fallback" },
|
||||||
|
]
|
||||||
|
|
||||||
function actionBadgeVariant(action: string) {
|
function actionBadgeVariant(action: string) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "handoff":
|
case "handoff":
|
||||||
@@ -74,10 +83,12 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
const [keywordInput, setKeywordInput] = useState("")
|
const [keywordInput, setKeywordInput] = useState("")
|
||||||
const [plannedActionInput, setPlannedActionInput] = useState("all")
|
const [plannedActionInput, setPlannedActionInput] = useState("all")
|
||||||
const [finalActionInput, setFinalActionInput] = useState("all")
|
const [finalActionInput, setFinalActionInput] = useState("all")
|
||||||
|
const [finalStatusInput, setFinalStatusInput] = useState("all")
|
||||||
const [aiAgentIdInput, setAiAgentIdInput] = useState("all")
|
const [aiAgentIdInput, setAiAgentIdInput] = useState("all")
|
||||||
const [keyword, setKeyword] = useState("")
|
const [keyword, setKeyword] = useState("")
|
||||||
const [plannedAction, setPlannedAction] = useState("all")
|
const [plannedAction, setPlannedAction] = useState("all")
|
||||||
const [finalAction, setFinalAction] = useState("all")
|
const [finalAction, setFinalAction] = useState("all")
|
||||||
|
const [finalStatus, setFinalStatus] = useState("all")
|
||||||
const [aiAgentId, setAiAgentId] = useState("all")
|
const [aiAgentId, setAiAgentId] = useState("all")
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const [limit, setLimit] = useState(20)
|
const [limit, setLimit] = useState(20)
|
||||||
@@ -121,6 +132,7 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
userMessage: keyword.trim() || undefined,
|
userMessage: keyword.trim() || undefined,
|
||||||
plannedAction: plannedAction === "all" ? undefined : plannedAction,
|
plannedAction: plannedAction === "all" ? undefined : plannedAction,
|
||||||
finalAction: finalAction === "all" ? undefined : finalAction,
|
finalAction: finalAction === "all" ? undefined : finalAction,
|
||||||
|
finalStatus: finalStatus === "all" ? undefined : finalStatus,
|
||||||
aiAgentId: aiAgentId === "all" ? undefined : aiAgentId,
|
aiAgentId: aiAgentId === "all" ? undefined : aiAgentId,
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
@@ -131,7 +143,7 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}, [aiAgentId, finalAction, keyword, limit, page, plannedAction])
|
}, [aiAgentId, finalAction, finalStatus, keyword, limit, page, plannedAction])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void loadData()
|
void loadData()
|
||||||
@@ -153,6 +165,7 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
setKeyword(keywordInput)
|
setKeyword(keywordInput)
|
||||||
setPlannedAction(plannedActionInput)
|
setPlannedAction(plannedActionInput)
|
||||||
setFinalAction(finalActionInput)
|
setFinalAction(finalActionInput)
|
||||||
|
setFinalStatus(finalStatusInput)
|
||||||
setAiAgentId(aiAgentIdInput)
|
setAiAgentId(aiAgentIdInput)
|
||||||
setPage(1)
|
setPage(1)
|
||||||
}
|
}
|
||||||
@@ -213,6 +226,16 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
onChange={(value) => setFinalActionInput(value || "all")}
|
onChange={(value) => setFinalActionInput(value || "all")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="w-full xl:w-40">
|
||||||
|
<OptionCombobox
|
||||||
|
value={finalStatusInput}
|
||||||
|
options={finalStatusOptions}
|
||||||
|
placeholder="最终状态"
|
||||||
|
searchPlaceholder="搜索状态"
|
||||||
|
emptyText="未找到状态"
|
||||||
|
onChange={(value) => setFinalStatusInput(value || "all")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="w-full xl:w-52">
|
<div className="w-full xl:w-52">
|
||||||
<OptionCombobox
|
<OptionCombobox
|
||||||
value={aiAgentIdInput}
|
value={aiAgentIdInput}
|
||||||
@@ -278,13 +301,18 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
{item.plannedSkillCode || item.plannedToolCode ? (
|
{item.plannedSkillCode || item.plannedToolCode ? (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Badge variant="outline">
|
<Badge variant="outline">
|
||||||
{item.plannedSkillCode || item.plannedToolCode}
|
{item.plannedSkillCode || item.graphToolCode || item.plannedToolCode}
|
||||||
</Badge>
|
</Badge>
|
||||||
{item.plannedSkillName ? (
|
{item.plannedSkillName ? (
|
||||||
<div className="line-clamp-1 text-xs text-muted-foreground">
|
<div className="line-clamp-1 text-xs text-muted-foreground">
|
||||||
{item.plannedSkillName}
|
{item.plannedSkillName}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
{item.handoffReason ? (
|
||||||
|
<div className="line-clamp-1 text-xs text-muted-foreground">
|
||||||
|
转人工原因:{item.handoffReason}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
"-"
|
"-"
|
||||||
@@ -366,8 +394,10 @@ export default function DashboardAgentRunLogsPage() {
|
|||||||
`plannedAction: ${activeLog.plannedAction || "-"}`,
|
`plannedAction: ${activeLog.plannedAction || "-"}`,
|
||||||
`plannedSkillCode: ${activeLog.plannedSkillCode || "-"}`,
|
`plannedSkillCode: ${activeLog.plannedSkillCode || "-"}`,
|
||||||
`plannedSkillName: ${activeLog.plannedSkillName || "-"}`,
|
`plannedSkillName: ${activeLog.plannedSkillName || "-"}`,
|
||||||
|
`graphToolCode: ${activeLog.graphToolCode || "-"}`,
|
||||||
`plannedToolCode: ${activeLog.plannedToolCode || "-"}`,
|
`plannedToolCode: ${activeLog.plannedToolCode || "-"}`,
|
||||||
`planReason: ${activeLog.planReason || "-"}`,
|
`planReason: ${activeLog.planReason || "-"}`,
|
||||||
|
`handoffReason: ${activeLog.handoffReason || "-"}`,
|
||||||
`skillRouteTrace: ${activeLog.skillRouteTrace || "-"}`,
|
`skillRouteTrace: ${activeLog.skillRouteTrace || "-"}`,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -363,6 +363,8 @@ export type AgentRunLog = {
|
|||||||
skillRouteTrace: string
|
skillRouteTrace: string
|
||||||
toolSearchTrace: string
|
toolSearchTrace: string
|
||||||
graphToolTrace: string
|
graphToolTrace: string
|
||||||
|
graphToolCode: string
|
||||||
|
handoffReason: string
|
||||||
plannedToolCode: string
|
plannedToolCode: string
|
||||||
planReason: string
|
planReason: string
|
||||||
interruptType: string
|
interruptType: string
|
||||||
|
|||||||
Reference in New Issue
Block a user