Skip to content

Commit 0b55233

Browse files
authored
Merge pull request #30 from naaa760/feat/feasibility-validator-selection
feat: make feasibility agent choose validators from catalog
2 parents 9a6fbb7 + ddb4dce commit 0b55233

4 files changed

Lines changed: 51 additions & 52 deletions

File tree

src/agents/feasibility_agent/agent.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ async def execute(self, rule_description: str) -> AgentResult:
8787
"is_feasible": result.is_feasible,
8888
"yaml_content": result.yaml_content,
8989
"confidence_score": result.confidence_score,
90+
"chosen_validators": result.chosen_validators,
9091
"rule_type": result.rule_type,
9192
"analysis_steps": result.analysis_steps,
9293
},

src/agents/feasibility_agent/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ class FeasibilityAnalysis(BaseModel):
1010

1111
is_feasible: bool = Field(description="Whether the rule is feasible to implement with Watchflow")
1212
rule_type: str = Field(description="Type of rule (time_restriction, branch_pattern, title_pattern, etc.)")
13+
chosen_validators: list[str] = Field(
14+
description="Names of validators from the catalog that can implement this rule",
15+
default_factory=list,
16+
)
1317
confidence_score: float = Field(description="Confidence score from 0.0 to 1.0", ge=0.0, le=1.0)
1418
feedback: str = Field(description="Detailed feedback on implementation considerations")
1519
analysis_steps: list[str] = Field(description="Step-by-step analysis breakdown", default_factory=list)
@@ -30,4 +34,5 @@ class FeasibilityState(BaseModel):
3034
feedback: str = ""
3135
confidence_score: float = 0.0
3236
rule_type: str = ""
37+
chosen_validators: list[str] = Field(default_factory=list)
3338
analysis_steps: list[str] = Field(default_factory=list)

src/agents/feasibility_agent/nodes.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from src.agents.feasibility_agent.models import FeasibilityAnalysis, FeasibilityState, YamlGeneration
88
from src.agents.feasibility_agent.prompts import RULE_FEASIBILITY_PROMPT, YAML_GENERATION_PROMPT
99
from src.integrations.providers import get_chat_model
10+
from src.rules.validators import get_validator_descriptions
1011

1112
logger = logging.getLogger(__name__)
1213

@@ -23,15 +24,30 @@ async def analyze_rule_feasibility(state: FeasibilityState) -> FeasibilityState:
2324
# Use structured output instead of manual JSON parsing
2425
structured_llm = llm.with_structured_output(FeasibilityAnalysis)
2526

26-
# Analyze rule feasibility
27-
prompt = RULE_FEASIBILITY_PROMPT.format(rule_description=state.rule_description)
27+
# Build validator catalog text for the prompt
28+
validator_catalog = []
29+
for v in get_validator_descriptions():
30+
validator_catalog.append(
31+
f"- name: {v.get('name')}\n"
32+
f" event_types: {v.get('event_types')}\n"
33+
f" parameter_patterns: {v.get('parameter_patterns')}\n"
34+
f" description: {v.get('description')}"
35+
)
36+
validators_text = "\n".join(validator_catalog)
37+
38+
# Analyze rule feasibility with awareness of available validators
39+
prompt = RULE_FEASIBILITY_PROMPT.format(
40+
rule_description=state.rule_description,
41+
validator_catalog=validators_text,
42+
)
2843

2944
# Get structured response with retry logic
3045
result = await structured_llm.ainvoke(prompt)
3146

3247
# Update state with analysis results - now type-safe!
3348
state.is_feasible = result.is_feasible
3449
state.rule_type = result.rule_type
50+
state.chosen_validators = result.chosen_validators
3551
state.confidence_score = result.confidence_score
3652
state.feedback = result.feedback
3753
state.analysis_steps = result.analysis_steps
@@ -67,7 +83,11 @@ async def generate_yaml_config(state: FeasibilityState) -> FeasibilityState:
6783
# Use structured output for YAML generation
6884
structured_llm = llm.with_structured_output(YamlGeneration)
6985

70-
prompt = YAML_GENERATION_PROMPT.format(rule_type=state.rule_type, rule_description=state.rule_description)
86+
prompt = YAML_GENERATION_PROMPT.format(
87+
rule_type=state.rule_type,
88+
rule_description=state.rule_description,
89+
chosen_validators=", ".join(state.chosen_validators),
90+
)
7191

7292
# Get structured response with retry logic
7393
result = await structured_llm.ainvoke(prompt)

src/agents/feasibility_agent/prompts.py

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,44 @@
33
"""
44

55
RULE_FEASIBILITY_PROMPT = """
6-
You are an expert in Watchflow rules and GitHub automation. Analyze whether a natural language rule description is feasible to implement using Watchflow.
6+
You are an expert in Watchflow rules and GitHub automation. Analyze whether a natural language rule description is feasible to implement using Watchflow’s existing validator catalog. Do NOT invent custom logic; choose from the provided validators. If none fit, mark as not feasible.
77
8-
Rule Description: {rule_description}
8+
Rule Description:
9+
{rule_description}
910
10-
Analyze this rule and determine:
11-
1. Is it feasible to implement with Watchflow's rule system?
12-
2. What type of rule is it?
13-
3. Provide concise feedback on implementation considerations
11+
Available validators (name, event_types, parameter_patterns, description):
12+
{validator_catalog}
1413
15-
Available rule types:
16-
- label_requirement: Rules requiring specific labels
17-
- time_restriction: Rules about when actions can occur (weekends, hours, days)
18-
- approval_requirement: Rules about required approvals
19-
- title_pattern: Rules about PR title formatting
20-
- branch_pattern: Rules about branch naming conventions
21-
- file_size: Rules about file size limits
22-
- commit_message: Rules about commit message format
23-
- branch_protection: Rules about protected branches
24-
25-
Focus on:
26-
- Practical implementation with Watchflow
27-
- Key configuration considerations
28-
- Severity and enforcement level recommendations
29-
- Keep feedback under 150 words
14+
Decide:
15+
1) is_feasible (true/false)
16+
2) rule_type (short label you infer)
17+
3) chosen_validators (list of validator names from the catalog that can implement this rule; empty if not feasible)
18+
4) feedback (practical, under 120 words)
19+
5) analysis_steps (succinct bullets)
3020
"""
3121

3222
YAML_GENERATION_PROMPT = """
33-
Generate a complete Watchflow rule configuration for the following rule:
23+
Generate a complete Watchflow rules.yaml for the rule below using ONLY the selected validators. Do not introduce parameters that the chosen validators do not support.
3424
3525
Rule Type: {rule_type}
3626
Description: {rule_description}
27+
Chosen Validators: {chosen_validators}
3728
38-
Generate a complete rules.yaml file that follows this EXACT structure:
39-
29+
Rules YAML format:
4030
```yaml
4131
rules:
42-
- description: "Clear description of what this rule does"
32+
- description: "<concise description>"
4333
enabled: true
4434
severity: "medium"
4535
event_types: ["pull_request"]
4636
parameters:
47-
required_labels: ["security", "review"]
37+
<validator-appropriate-parameters>
4838
```
4939
50-
IMPORTANT REQUIREMENTS:
51-
- Generate the COMPLETE rules.yaml file including the "rules:" wrapper
52-
- Use the rule description as the primary identifier
53-
- Include enabled: true (allows rule activation/deactivation)
54-
- Set appropriate severity (low, medium, high, critical)
55-
- Include relevant event_types
56-
- Add correct parameters based on rule type
57-
- For regex patterns, use single quotes to avoid YAML parsing issues
58-
59-
Rule type parameters:
60-
- label_requirement: use "required_labels" with array of labels
61-
- time_restriction: use "days" for restricted days or "allowed_hours" for restricted hours
62-
- approval_requirement: use "min_approvals" with number
63-
- title_pattern: use "title_pattern" with regex pattern (use single quotes for regex)
64-
- file_size: use "max_file_size_mb" with number
65-
- commit_message: use "pattern" with regex pattern (use single quotes for regex)
66-
- branch_protection: use "protected_branches" with array of branch names
67-
68-
Examples of proper regex patterns:
69-
- title_pattern: '^feat|^fix|^docs' # Use single quotes
70-
- pattern: '^[A-Z]+-\\d+' # Use single quotes for regex
71-
72-
Return the complete YAML file content.
40+
Guidelines:
41+
- Keep severity appropriate (low/medium/high/critical).
42+
- event_types must align with the validators chosen.
43+
- For regex, use single quotes.
44+
- If no validators fit, return an empty yaml_content.
45+
Return only the YAML content.
7346
"""

0 commit comments

Comments
 (0)