Files
ai-agent/internal/ai/workflow/registry/registry.go
T

242 lines
10 KiB
Go
Raw Normal View History

2026-06-22 00:08:31 +08:00
package registry
import "agent-desk/internal/ai/workflow/dsl"
2026-06-22 00:08:31 +08:00
const (
NodeTypeStart = "start"
NodeTypeConversationUnderstanding = "conversation_understanding"
NodeTypeReplyPolicy = "reply_policy"
NodeTypeKnowledgeRetrieve = "knowledge_retrieve"
NodeTypeAnswerabilityGate = "answerability_gate"
NodeTypeLLMReply = "llm_reply"
NodeTypeCondition = "condition"
NodeTypeAnalyzeConversation = "analyze_conversation"
NodeTypePrepareTicketDraft = "prepare_ticket_draft"
NodeTypeHumanConfirm = "human_confirm"
NodeTypeCreateTicket = "create_ticket"
NodeTypeHandoffToHuman = "handoff_to_human"
NodeTypeSendReply = "send_reply"
NodeTypeEnd = "end"
2026-06-22 00:08:31 +08:00
)
func DefaultRegistry() *Registry {
return NewRegistry(
NodeSpec{
Type: NodeTypeStart,
Title: "Start",
Description: "Conversation workflow entry.",
RiskLevel: NodeRiskLevelLow,
OutputSchema: []VariableSpec{
output("conversationId", VariableTypeInteger, "Conversation ID."),
output("messageId", VariableTypeInteger, "Current user message ID."),
output("aiAgentId", VariableTypeInteger, "AI Agent ID."),
output("userMessage", VariableTypeString, "Current user message content."),
output("knowledgeBaseIds", VariableTypeIntegerArray, "Knowledge bases bound to the AI Agent."),
},
},
NodeSpec{
Type: NodeTypeConversationUnderstanding,
Title: "Conversation Understanding",
Description: "Classify customer message intent and answer scope before retrieval.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("userMessage", VariableTypeString, "Current user message content."),
},
OutputSchema: []VariableSpec{
output("normalizedMessage", VariableTypeString, "Normalized customer message."),
output("messageIntent", VariableTypeString, "Detected customer message intent."),
output("answerScope", VariableTypeString, "Recommended answer scope."),
output("confidence", VariableTypeNumber, "Classifier confidence."),
output("riskSignals", VariableTypeStringArray, "Detected risk signals."),
output("reason", VariableTypeString, "Decision reason."),
},
DefaultInputs: map[string]dsl.VariableSelector{
"userMessage": {NodeID: "start_1", Field: "userMessage"},
},
},
NodeSpec{
Type: NodeTypeReplyPolicy,
Title: "Reply Policy",
Description: "Decide the next customer-service action from understanding output and agent policy.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("messageIntent", VariableTypeString, "Detected customer message intent."),
requiredInput("answerScope", VariableTypeString, "Recommended answer scope."),
optionalInput("userMessage", VariableTypeString, "Current user message content."),
optionalInput("riskSignals", VariableTypeStringArray, "Detected risk signals."),
optionalInput("answerability", VariableTypeString, "Knowledge answerability decision."),
},
OutputSchema: []VariableSpec{
output("action", VariableTypeString, "Selected policy action."),
output("replyText", VariableTypeString, "Customer-visible reply text when the policy can answer directly."),
output("reason", VariableTypeString, "Policy decision reason."),
output("requiresFlow", VariableTypeBoolean, "Whether the decision should continue into workflow actions."),
output("targetFlow", VariableTypeString, "Suggested target flow."),
output("finalReplySource", VariableTypeString, "Source category for the final reply."),
},
},
NodeSpec{
Type: NodeTypeKnowledgeRetrieve,
Title: "Knowledge Retrieve",
Description: "Retrieve knowledge for the current user message.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("query", VariableTypeString, "Search query."),
},
OutputSchema: []VariableSpec{
output("items", VariableTypeObjectArray, "Retrieved knowledge items."),
output("summary", VariableTypeString, "Short retrieval summary."),
},
DefaultInputs: map[string]dsl.VariableSelector{
"query": {NodeID: "start_1", Field: "userMessage"},
},
},
NodeSpec{
Type: NodeTypeAnswerabilityGate,
Title: "Answerability Gate",
Description: "Decide whether retrieved knowledge is enough to answer.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("userMessage", VariableTypeString, "Current user message content."),
requiredInput("knowledgeItems", VariableTypeObjectArray, "Retrieved knowledge items."),
},
OutputSchema: []VariableSpec{
output("answerability", VariableTypeString, "Answerability decision."),
output("reason", VariableTypeString, "Decision reason."),
},
},
NodeSpec{
Type: NodeTypeLLMReply,
Title: "LLM Reply",
Description: "Generate a reply or structured analysis with the configured model.",
RiskLevel: NodeRiskLevelMedium,
InputSchema: []VariableSpec{
requiredInput("userMessage", VariableTypeString, "Current user message content."),
optionalInput("knowledgeItems", VariableTypeObjectArray, "Retrieved knowledge items."),
},
OutputSchema: []VariableSpec{
output("replyText", VariableTypeString, "Generated reply text."),
},
},
NodeSpec{
Type: NodeTypeCondition,
Title: "Condition",
Description: "Route by controlled workflow variables.",
RiskLevel: NodeRiskLevelLow,
OutputSchema: []VariableSpec{
output("matched", VariableTypeBoolean, "Whether the condition matched."),
},
},
NodeSpec{
Type: NodeTypeAnalyzeConversation,
Title: "Analyze Conversation",
Description: "Analyze intent, risk, and recommended next action.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("userMessage", VariableTypeString, "Current user message content."),
},
OutputSchema: []VariableSpec{
output("intent", VariableTypeString, "Detected user intent."),
output("riskLevel", VariableTypeString, "Detected risk level."),
output("needTicket", VariableTypeBoolean, "Whether a ticket is recommended."),
output("needHumanHandoff", VariableTypeBoolean, "Whether human handoff is recommended."),
},
},
NodeSpec{
Type: NodeTypePrepareTicketDraft,
Title: "Prepare Ticket Draft",
Description: "Build a ticket draft from conversation context.",
RiskLevel: NodeRiskLevelMedium,
InputSchema: []VariableSpec{
requiredInput("issue", VariableTypeString, "Issue summary."),
},
OutputSchema: []VariableSpec{
output("ticketDraft", VariableTypeObject, "Draft ticket payload."),
},
},
NodeSpec{
Type: NodeTypeHumanConfirm,
Title: "Human Confirm",
Description: "Interrupt and wait for explicit user confirmation.",
RiskLevel: NodeRiskLevelMedium,
Interruptible: true,
InputSchema: []VariableSpec{
requiredInput("prompt", VariableTypeString, "Confirmation prompt."),
},
OutputSchema: []VariableSpec{
output("confirmed", VariableTypeBoolean, "Whether the user confirmed."),
output("responseText", VariableTypeString, "Confirmation response text."),
},
},
NodeSpec{
Type: NodeTypeCreateTicket,
Title: "Create Ticket",
Description: "Create a ticket from a confirmed draft.",
RiskLevel: NodeRiskLevelHigh,
RequiresConfirmationPredecessor: true,
InputSchema: []VariableSpec{
requiredInput("ticketDraft", VariableTypeObject, "Confirmed draft ticket payload."),
requiredInput("confirmed", VariableTypeBoolean, "Confirmation result."),
},
OutputSchema: []VariableSpec{
output("ticketId", VariableTypeInteger, "Created ticket ID."),
output("ticketNo", VariableTypeString, "Created ticket number."),
output("created", VariableTypeBoolean, "Whether the ticket was created."),
output("message", VariableTypeString, "Customer-visible ticket creation result."),
},
},
NodeSpec{
Type: NodeTypeHandoffToHuman,
Title: "Handoff To Human",
Description: "Transfer the conversation to human support.",
RiskLevel: NodeRiskLevelHigh,
InputSchema: []VariableSpec{
requiredInput("reason", VariableTypeString, "Handoff reason."),
optionalInput("confirmed", VariableTypeBoolean, "Confirmation result."),
},
OutputSchema: []VariableSpec{
output("handoffId", VariableTypeInteger, "Handoff operation ID."),
output("reason", VariableTypeString, "Handoff reason."),
output("decision", VariableTypeString, "Handoff dispatch decision."),
output("teamId", VariableTypeInteger, "Assigned or pending team ID."),
output("assigneeId", VariableTypeInteger, "Assigned agent user ID."),
output("message", VariableTypeString, "Customer-visible handoff notice."),
},
},
NodeSpec{
Type: NodeTypeSendReply,
Title: "Send Reply",
Description: "Return or commit customer-visible reply text.",
RiskLevel: NodeRiskLevelLow,
InputSchema: []VariableSpec{
requiredInput("replyText", VariableTypeString, "Customer-visible reply text."),
},
OutputSchema: []VariableSpec{
output("sent", VariableTypeBoolean, "Whether the reply was sent."),
output("replyMessageId", VariableTypeInteger, "Reply message ID."),
},
},
NodeSpec{
Type: NodeTypeEnd,
Title: "End",
Description: "End workflow execution.",
RiskLevel: NodeRiskLevelLow,
OutputSchema: []VariableSpec{
output("status", VariableTypeString, "Workflow terminal status."),
},
},
2026-06-22 00:08:31 +08:00
)
}
func requiredInput(name string, variableType VariableType, description string) VariableSpec {
return VariableSpec{Name: name, Type: variableType, Required: true, Description: description}
}
func optionalInput(name string, variableType VariableType, description string) VariableSpec {
return VariableSpec{Name: name, Type: variableType, Description: description}
}
func output(name string, variableType VariableType, description string) VariableSpec {
return VariableSpec{Name: name, Type: variableType, Description: description}
}