feat: Enhance AI Agent and Channel Management
- Updated labels in the AI Agents dashboard for clarity, changing "流程状态" to "Playbook 状态" and "未发布流程" to "未发布 Playbook". - Introduced AI Agent rollout percentage management in channel editing, allowing users to set and rollback rollout percentages. - Added new API endpoints for rolling back AI Agent rollout and fetching agent run metrics. - Implemented new UI components for displaying agent run details, including status, duration, and input/output tokens. - Enhanced type definitions for AdminChannel and AIAgent to include rollout percentages and runtime modes. - Updated navigation to include a section for agent runs. - Added new translations for agent run features in both English and Chinese.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package builders
|
||||
|
||||
import (
|
||||
"agent-desk/internal/models"
|
||||
"agent-desk/internal/pkg/dto/response"
|
||||
)
|
||||
|
||||
func BuildAgentRevision(item *models.AgentRevision) response.AgentRevisionResponse {
|
||||
if item == nil {
|
||||
return response.AgentRevisionResponse{}
|
||||
}
|
||||
publishedAt := ""
|
||||
if item.PublishedAt != nil {
|
||||
publishedAt = item.PublishedAt.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
return response.AgentRevisionResponse{
|
||||
ID: item.ID, AgentID: item.AgentID, Revision: item.Revision, WorkflowVersionID: item.WorkflowVersionID,
|
||||
Status: item.Status, DefinitionHash: item.DefinitionHash, PublishedAt: publishedAt,
|
||||
PublishedByID: item.PublishedByID, PublishedByName: item.PublishedByName,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAgentRevisionList(items []models.AgentRevision) []response.AgentRevisionResponse {
|
||||
ret := make([]response.AgentRevisionResponse, 0, len(items))
|
||||
for i := range items {
|
||||
ret = append(ret, BuildAgentRevision(&items[i]))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package builders
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"agent-desk/internal/models"
|
||||
"agent-desk/internal/pkg/dto/response"
|
||||
)
|
||||
|
||||
func BuildAgentRun(item *models.AgentRun) response.AgentRunResponse {
|
||||
if item == nil {
|
||||
return response.AgentRunResponse{}
|
||||
}
|
||||
return response.AgentRunResponse{
|
||||
ID: item.ID,
|
||||
ConversationID: item.ConversationID,
|
||||
AIAgentID: item.AIAgentID,
|
||||
AgentRevisionID: item.AgentRevisionID,
|
||||
SourceMessageID: item.SourceMessageID,
|
||||
WorkflowRunID: item.WorkflowRunID,
|
||||
EngineCode: item.EngineCode,
|
||||
Status: item.Status,
|
||||
PromptTokens: item.PromptTokens,
|
||||
CompletionTokens: item.CompletionTokens,
|
||||
StartedAt: formatAgentRunTime(item.StartedAt),
|
||||
EndedAt: formatAgentRunTimePtr(item.EndedAt),
|
||||
DurationMS: agentRunDurationMS(item.StartedAt, item.EndedAt),
|
||||
ErrorMessage: item.ErrorMessage,
|
||||
TraceData: item.TraceData,
|
||||
CreatedAt: formatAgentRunTime(item.CreatedAt),
|
||||
UpdatedAt: formatAgentRunTime(item.UpdatedAt),
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAgentRunDetail(item *models.AgentRun, steps []models.AgentStep, toolCalls []models.AgentToolCall, feedback *models.AgentRunQualityFeedback) response.AgentRunResponse {
|
||||
ret := BuildAgentRun(item)
|
||||
ret.Steps = BuildAgentStepList(steps)
|
||||
ret.ToolCalls = BuildAgentToolCallList(toolCalls)
|
||||
ret.QualityFeedback = BuildAgentRunQualityFeedback(feedback)
|
||||
return ret
|
||||
}
|
||||
|
||||
func BuildAgentRunQualityFeedback(item *models.AgentRunQualityFeedback) *response.AgentRunQualityFeedbackResponse {
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
return &response.AgentRunQualityFeedbackResponse{
|
||||
ID: item.ID,
|
||||
AgentRunID: item.AgentRunID,
|
||||
ResolutionStatus: item.ResolutionStatus,
|
||||
EvidenceStatus: item.EvidenceStatus,
|
||||
Comment: item.Comment,
|
||||
UpdateUserName: item.UpdateUserName,
|
||||
UpdatedAt: formatAgentRunTime(item.UpdatedAt),
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAgentRunList(list []models.AgentRun) []response.AgentRunResponse {
|
||||
ret := make([]response.AgentRunResponse, 0, len(list))
|
||||
for i := range list {
|
||||
ret = append(ret, BuildAgentRun(&list[i]))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func BuildAgentStep(item *models.AgentStep) response.AgentStepResponse {
|
||||
if item == nil {
|
||||
return response.AgentStepResponse{}
|
||||
}
|
||||
return response.AgentStepResponse{
|
||||
ID: item.ID,
|
||||
AgentRunID: item.AgentRunID,
|
||||
WorkflowRunID: item.WorkflowRunID,
|
||||
StepType: item.StepType,
|
||||
StepCode: item.StepCode,
|
||||
Status: item.Status,
|
||||
InputPreview: item.InputPreview,
|
||||
OutputPreview: item.OutputPreview,
|
||||
ErrorMessage: item.ErrorMessage,
|
||||
StartedAt: formatAgentRunTime(item.StartedAt),
|
||||
EndedAt: formatAgentRunTimePtr(item.EndedAt),
|
||||
DurationMS: item.DurationMS,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAgentStepList(list []models.AgentStep) []response.AgentStepResponse {
|
||||
ret := make([]response.AgentStepResponse, 0, len(list))
|
||||
for i := range list {
|
||||
ret = append(ret, BuildAgentStep(&list[i]))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func BuildAgentToolCall(item *models.AgentToolCall) response.AgentToolCallResponse {
|
||||
if item == nil {
|
||||
return response.AgentToolCallResponse{}
|
||||
}
|
||||
return response.AgentToolCallResponse{
|
||||
ID: item.ID,
|
||||
AgentRunID: item.AgentRunID,
|
||||
AgentStepID: item.AgentStepID,
|
||||
ToolCode: item.ToolCode,
|
||||
RiskLevel: item.RiskLevel,
|
||||
RequireConfirm: item.RequireConfirm,
|
||||
Status: item.Status,
|
||||
ArgumentsPreview: item.ArgumentsPreview,
|
||||
ResultPreview: item.ResultPreview,
|
||||
ErrorMessage: item.ErrorMessage,
|
||||
DurationMS: item.DurationMS,
|
||||
CreatedAt: formatAgentRunTime(item.CreatedAt),
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAgentToolCallList(list []models.AgentToolCall) []response.AgentToolCallResponse {
|
||||
ret := make([]response.AgentToolCallResponse, 0, len(list))
|
||||
for i := range list {
|
||||
ret = append(ret, BuildAgentToolCall(&list[i]))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func formatAgentRunTime(value time.Time) string {
|
||||
if value.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return value.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func formatAgentRunTimePtr(value *time.Time) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
return formatAgentRunTime(*value)
|
||||
}
|
||||
|
||||
func agentRunDurationMS(startedAt time.Time, endedAt *time.Time) int64 {
|
||||
if startedAt.IsZero() || endedAt == nil || endedAt.IsZero() {
|
||||
return 0
|
||||
}
|
||||
duration := endedAt.Sub(startedAt).Milliseconds()
|
||||
if duration < 0 {
|
||||
return 0
|
||||
}
|
||||
return duration
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
workflowregistry "agent-desk/internal/ai/workflow/registry"
|
||||
"agent-desk/internal/models"
|
||||
"agent-desk/internal/pkg/dto/response"
|
||||
"agent-desk/internal/services"
|
||||
)
|
||||
|
||||
func BuildAIWorkflow(item *models.AIWorkflow) response.AIWorkflowResponse {
|
||||
@@ -89,6 +90,14 @@ func BuildAIWorkflowNodeSpecs(list []workflowregistry.NodeSpec) []response.AIWor
|
||||
return ret
|
||||
}
|
||||
|
||||
func BuildAIWorkflowTemplates(list []services.AIWorkflowTemplate) []response.AIWorkflowTemplateResponse {
|
||||
ret := make([]response.AIWorkflowTemplateResponse, 0, len(list))
|
||||
for _, item := range list {
|
||||
ret = append(ret, response.AIWorkflowTemplateResponse{Code: item.Code, Name: item.Name, Description: item.Description, Definition: item.Definition})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func BuildAIWorkflowRun(item *models.AIWorkflowRun) response.AIWorkflowRunResponse {
|
||||
return BuildAIWorkflowRunWithContext(item, nil, nil, nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user