From 84b4ca120fc2f1f26f494bcc911f1d66fc9f8565 Mon Sep 17 00:00:00 2001 From: Test Date: Sat, 5 Sep 2026 05:45:38 -0700 Subject: [PATCH] feat: add relation wording schema --- action/canvas_reasoner.go | 67 ++++++++++++++++++++++++++++---------- k8s/git-commit.yaml | 2 +- k8s/worker-deployment.yaml | 2 +- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/action/canvas_reasoner.go b/action/canvas_reasoner.go index 567cda4..5a98143 100644 --- a/action/canvas_reasoner.go +++ b/action/canvas_reasoner.go @@ -19,14 +19,34 @@ type CanvasReasonerInput struct { AuthToken string `json:"auth_token,omitempty"` // JWT for LLM calls } +// RelationWording describes semantic meaning of an edge +type RelationWording struct { + Verb string `json:"verb"` // outputs, inputs, depends-on, etc + SourceOutput string `json:"source_output"` // What source produces + TargetInput string `json:"target_input"` // What target requires + ConnectionType string `json:"connection_type"` // direct-map, requires-transformer, conditional + Confidence float64 `json:"confidence"` // 0.0-1.0 + SemanticMatch string `json:"semantic_match"` // Human-readable explanation + TransformerNeeded string `json:"transformer_needed,omitempty"` // If transformation required +} + +// EdgeWithWording pairs an edge with its semantic description +type EdgeWithWording struct { + Source string `json:"source"` + Target string `json:"target"` + RelationType string `json:"relation_type"` // data-flow, dependency, conditional, parallel + RelationLabel string `json:"relation_label"` // e.g., "CloneRepo outputs path → AnalyzeCode requires path" + RelationWording RelationWording `json:"relation_wording"` +} + // CanvasReasonerOutput returns suggested edges and reasoning type CanvasReasonerOutput struct { - SuggestedEdges []db.WorkflowEdge `json:"suggested_edges"` // New edges to add - RemovedEdges []db.WorkflowEdge `json:"removed_edges,omitempty"` // Edges to remove (if redesign) + SuggestedEdges []EdgeWithWording `json:"suggested_edges"` // Edges with wording + RemovedEdges []db.WorkflowEdge `json:"removed_edges,omitempty"` // Edges to remove Reasoning string `json:"reasoning"` // LLM explanation Confidence float64 `json:"confidence"` // 0.0-1.0 - IncompatibleEdges []IncompatibilityWarning `json:"incompatible_edges,omitempty"` // Edges that can't be created - DisconnectedNodes []string `json:"disconnected_nodes,omitempty"` // Nodes with no connections + IncompatibleEdges []IncompatibilityWarning `json:"incompatible_edges,omitempty"` // Can't connect + DisconnectedNodes []string `json:"disconnected_nodes,omitempty"` // No connections UserAlerts []string `json:"user_alerts,omitempty"` // Human-readable warnings } @@ -48,23 +68,34 @@ func CanvasReasonerActivity(ctx context.Context, in CanvasReasonerInput) (Canvas nodeDesc := buildNodeDescriptions(in.Nodes) edgeDesc := buildEdgeDescriptions(in.Edges) - // Create prompt for LLM reasoning with compatibility guidance - systemPrompt := `You are a workflow automation expert. Analyze the following activities and suggest logical connections (edges) between them based on: -1. Activity input/output compatibility (CRITICAL - only connect if outputs match inputs) -2. Logical execution order and data flow -3. Required dependencies -4. Common workflow patterns + // Create prompt for LLM reasoning with relation wording + systemPrompt := `You are a workflow automation expert. Analyze activities and suggest logical connections with semantic descriptions. -IMPORTANT: Only suggest edges where: -- Source activity has outputs (check "outputs" fields) -- Target activity has inputs (check "inputs" fields) -- Data types are compatible (string→string, object→object, etc) -- Connection makes semantic sense (don't connect a notifier to an analyzer) +CRITICAL RULES: +1. Only suggest edges where outputs→inputs match +2. Provide relation wording: verb, source_output, target_input +3. Assess connection confidence (0.0-1.0) +4. Flag type mismatches that need transformers -Respond with JSON containing: +Respond with JSON: { - "edges": [{"source": "node-1", "target": "node-2"}, ...], - "reasoning": "explanation of why these connections make sense and any type mismatches noted", + "edges": [ + { + "source": "node-1", + "target": "node-2", + "relation_type": "data-flow|dependency|conditional|parallel", + "relation_label": "Node1 outputs X → Node2 requires X", + "relation_wording": { + "verb": "outputs|depends-on|triggers|etc", + "source_output": "field_name (type): description", + "target_input": "field_name (type, required?): description", + "connection_type": "direct-map|requires-transformer|conditional", + "confidence": 0.95, + "semantic_match": "Explanation of why this makes sense" + } + } + ], + "reasoning": "Overall workflow structure explanation", "confidence": 0.85 }` diff --git a/k8s/git-commit.yaml b/k8s/git-commit.yaml index a0eb94d..95c3c60 100644 --- a/k8s/git-commit.yaml +++ b/k8s/git-commit.yaml @@ -9,6 +9,6 @@ metadata: app.kubernetes.io/name: poimen app.kubernetes.io/component: orchestrator data: - GIT_COMMIT: "64fa03cae" # Updated automatically by CI/CD + GIT_COMMIT: "eb4c4e989" # Updated automatically by CI/CD GIT_BRANCH: "main" DEPLOYMENT_DATE: "2026-09-05" diff --git a/k8s/worker-deployment.yaml b/k8s/worker-deployment.yaml index 128ffad..a28024d 100644 --- a/k8s/worker-deployment.yaml +++ b/k8s/worker-deployment.yaml @@ -13,7 +13,7 @@ spec: labels: app: poimen-worker annotations: - git-commit: "64fa03cae" # ✅ Updated on each push, triggers rolling restart + git-commit: "eb4c4e989" # ✅ Updated on each push, triggers rolling restart deployment-date: "2026-09-05" spec: containers: