auto-dev-agent / agents /clarification_agent.py
Siva sai Yadav
ready for HuggingFace Space deployment
8edee29
Raw
History Blame Contribute Delete
4.77 kB
"""
agents/clarification_agent.py
-------------------------------
Clarification Agent for AutoDevAgent.
Checks whether a user task is clear enough to generate correct code
and tests. If the task is ambiguous, incomplete, or contradictory it
returns a concise question asking the user to clarify.
Design:
- Uses the fast model (8B) β€” it's a lightweight classification + Q-gen task.
- Returns {"clear": True} or {"clear": False, "question": "..."}
- Runs in app.py BEFORE the LangGraph pipeline starts, so the
pipeline never wastes tokens on an unclear task.
- Only asks for clarification when genuinely needed β€” simple, well-formed
tasks ("write a function to reverse a string") always pass through.
Usage:
from agents.clarification_agent import ClarificationAgent
agent = ClarificationAgent()
result = agent.check("Write a Python function")
if not result["clear"]:
print(result["question"])
"""
import logging
from typing import Any
from langchain_groq import ChatGroq
from langchain_core.messages import SystemMessage, HumanMessage
from config import settings
logger = logging.getLogger(__name__)
CLARIFICATION_SYSTEM = """
You are a requirements analyst for a code generation assistant that writes
Python and SQL code. Your job is to decide if a user's task description is
clear enough to generate correct, testable code β€” without guessing.
A task is CLEAR if:
- The programming language or goal is inferable (Python function, SQL query, etc.)
- The inputs and expected outputs can be reasonably inferred
- There is enough detail to write a correct implementation
A task is UNCLEAR if:
- It is too vague to know what to implement (e.g. "make something cool")
- Key information is missing that would change the implementation significantly
(e.g. "sort the data" β€” what data? what format? ascending or descending?)
- It is contradictory or impossible to implement as stated
- It is a single word or fragment with no actionable meaning
Rules:
- Be LENIENT β€” most standard programming tasks are clear enough. Do not ask
for clarification on well-known patterns (reverse a string, fibonacci, etc.).
- If UNCLEAR, ask ONE short, specific question (max 20 words) that would give
enough info to proceed. Do not ask multiple questions.
- Never ask for clarification on things the agent can reasonably assume
(e.g. don't ask "should I use a function or a class?" for a simple task).
Respond with ONLY valid JSON β€” no explanation, no markdown:
{"clear": true}
or
{"clear": false, "question": "Your single clarifying question here."}
""".strip()
class ClarificationAgent:
"""
Checks if a task description is clear enough to generate code.
Returns a dict:
{"clear": True}
{"clear": False, "question": "..."}
"""
def __init__(self) -> None:
self._llm = ChatGroq(
api_key=settings.groq_api_key,
model=settings.groq_model_fast, # 8B β€” lightweight task
temperature=0.0,
max_tokens=120,
request_timeout=settings.groq_request_timeout,
)
def check(self, task: str) -> dict[str, Any]:
"""
Check if the task is clear enough to proceed.
Args:
task: The user's raw task description.
Returns:
{"clear": True} β€” task is actionable, proceed
{"clear": False, "question": str} β€” needs clarification
"""
if not task or not task.strip():
return {"clear": False, "question": "Please describe what you'd like me to build."}
try:
response = self._llm.invoke([
SystemMessage(content=CLARIFICATION_SYSTEM),
HumanMessage(content=f"Task: {task.strip()}"),
])
raw = response.content.strip()
# Parse JSON response
import json, re
# Strip markdown fences if model wrapped it
raw = re.sub(r'^```[a-z]*\n?', '', raw).rstrip('`').strip()
result = json.loads(raw)
if result.get("clear") is True:
logger.info("ClarificationAgent: task is clear β€” proceeding")
return {"clear": True}
else:
question = result.get("question", "Could you provide more details about the expected inputs and outputs?")
logger.info("ClarificationAgent: task needs clarification β€” %s", question)
return {"clear": False, "question": question}
except Exception as e:
# On any failure, let the pipeline proceed β€” don't block on a clarification error
logger.warning("ClarificationAgent failed (%s) β€” proceeding anyway", e)
return {"clear": True}