package adk import ( "context" "encoding/json" "fmt" "github.com/orchard9/stemedb-go/steme" ) // ConstraintCheckTool provides pre-flight validation for Implementation Agent. // // Returns must-use and forbidden patterns for a given context. type ConstraintCheckTool struct { client EpistemeClient } // NewConstraintCheckTool creates a new ConstraintCheck tool. func NewConstraintCheckTool(client EpistemeClient) *ConstraintCheckTool { return &ConstraintCheckTool{client: client} } // Name returns the tool name. func (t *ConstraintCheckTool) Name() string { return "episteme_constraint_check" } // Description returns the tool description. func (t *ConstraintCheckTool) Description() string { return "Check for must-use and forbidden patterns before code generation. " + "Returns constraints with explanations for contrastive learning. " + "Implementation Agent MUST call this before writing code." } // Execute performs the constraint check. func (t *ConstraintCheckTool) Execute(ctx context.Context, input []byte) ([]byte, error) { var params ConstraintCheckInput if err := json.Unmarshal(input, ¶ms); err != nil { return nil, fmt.Errorf("invalid constraint check input: %w", err) } // Query for constraints in the given context // This queries for assertions with predicate "must_use" or "forbidden" builder := steme.NewQuery(). WithSubject(params.Context). WithLifecycle(steme.LifecycleApproved). // Only approved constraints WithLens(steme.LensAuthority) result, err := t.client.Query(ctx, builder.Build()) if err != nil { return nil, fmt.Errorf("constraint query failed: %w", err) } // Convert assertions to constraints constraints := convertToConstraints(result) outputBytes, err := json.Marshal(ConstraintCheckOutput{ Constraints: constraints, }) if err != nil { return nil, fmt.Errorf("failed to marshal constraint output: %w", err) } return outputBytes, nil }