feat: add workflow run audit graph component and enhance workflow run details
This commit is contained in:
@@ -134,6 +134,9 @@ func BuildAIWorkflowRunDetail(item *models.AIWorkflowRun, nodes []models.AIWorkf
|
||||
|
||||
func BuildAIWorkflowRunDetailWithContext(item *models.AIWorkflowRun, nodes []models.AIWorkflowNodeRun, workflow *models.AIWorkflow, version *models.AIWorkflowVersion, agent *models.AIAgent) response.AIWorkflowRunResponse {
|
||||
ret := BuildAIWorkflowRunWithContext(item, workflow, version, agent)
|
||||
if version != nil {
|
||||
ret.Definition = parseWorkflowDefinition(version.Definition)
|
||||
}
|
||||
ret.Nodes = BuildAIWorkflowNodeRunList(nodes)
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package builders
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"agent-desk/internal/ai/workflow/dsl"
|
||||
workflowregistry "agent-desk/internal/ai/workflow/registry"
|
||||
"agent-desk/internal/models"
|
||||
)
|
||||
@@ -65,6 +67,40 @@ func TestBuildAIWorkflowRunIncludesAuditDisplayFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildAIWorkflowRunDetailIncludesPublishedDefinitionSnapshot(t *testing.T) {
|
||||
definition := dsl.Definition{
|
||||
SchemaVersion: 1,
|
||||
EntryNodeID: "start_1",
|
||||
Nodes: []dsl.Node{
|
||||
{ID: "start_1", Type: workflowregistry.NodeTypeStart, Name: "开始"},
|
||||
{ID: "reply_1", Type: workflowregistry.NodeTypeLLMReply, Name: "运行时回复"},
|
||||
},
|
||||
Edges: []dsl.Edge{{ID: "edge_start_reply", Source: "start_1", Target: "reply_1"}},
|
||||
}
|
||||
buf, err := json.Marshal(definition)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal definition: %v", err)
|
||||
}
|
||||
|
||||
resp := BuildAIWorkflowRunDetailWithContext(
|
||||
&models.AIWorkflowRun{ID: 9, WorkflowVersionID: 22, Status: 1, StartedAt: time.Now()},
|
||||
nil,
|
||||
&models.AIWorkflow{Name: "当前 Workflow 草稿不应参与审计图"},
|
||||
&models.AIWorkflowVersion{Version: 3, Definition: string(buf)},
|
||||
&models.AIAgent{Name: "售后 Agent"},
|
||||
)
|
||||
|
||||
if resp.Definition.EntryNodeID != "start_1" {
|
||||
t.Fatalf("expected run detail definition from published version, got %#v", resp.Definition)
|
||||
}
|
||||
if len(resp.Definition.Nodes) != 2 || resp.Definition.Nodes[1].Name != "运行时回复" {
|
||||
t.Fatalf("expected published definition nodes, got %#v", resp.Definition.Nodes)
|
||||
}
|
||||
if len(resp.Definition.Edges) != 1 || resp.Definition.Edges[0].ID != "edge_start_reply" {
|
||||
t.Fatalf("expected published definition edges, got %#v", resp.Definition.Edges)
|
||||
}
|
||||
}
|
||||
|
||||
func hasResponseVariable(items []workflowregistry.VariableSpec, name string) bool {
|
||||
for _, item := range items {
|
||||
if item.Name == name {
|
||||
|
||||
@@ -74,6 +74,7 @@ type AIWorkflowRunResponse struct {
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
Definition dsl.Definition `json:"definition"`
|
||||
Nodes []AIWorkflowNodeRunResponse `json:"nodes,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,18 @@ func TestAIWorkflowServiceRunListAndDetail(t *testing.T) {
|
||||
if err := sqls.DB().Create(&workflow).Error; err != nil {
|
||||
t.Fatalf("create workflow: %v", err)
|
||||
}
|
||||
version := models.AIWorkflowVersion{WorkflowID: workflow.ID, Version: 7, Status: enums.StatusOk}
|
||||
versionDefinition := validAIWorkflowDefinition()
|
||||
versionDefinition.Nodes[1].Name = "运行时回复"
|
||||
versionDefinitionJSON, err := json.Marshal(versionDefinition)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal version definition: %v", err)
|
||||
}
|
||||
version := models.AIWorkflowVersion{
|
||||
WorkflowID: workflow.ID,
|
||||
Version: 7,
|
||||
Status: enums.StatusOk,
|
||||
Definition: string(versionDefinitionJSON),
|
||||
}
|
||||
if err := sqls.DB().Create(&version).Error; err != nil {
|
||||
t.Fatalf("create workflow version: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user