feat: force the planning agent to ask questions

This commit is contained in:
Richard Tang
2026-03-12 19:45:07 -07:00
parent 5547432b6e
commit 2a4fe4020c
5 changed files with 60 additions and 5 deletions
@@ -734,8 +734,6 @@ Write a brief intro (1-2 sentences), then call the tool:
])
Examples (single question):
- ask_user("What do you need?",
["Build a new agent", "Run the loaded worker", "Help with code"])
- ask_user("Ready to proceed?",
["Yes, go ahead", "Let me change something"])
+24 -1
View File
@@ -90,6 +90,28 @@ async def create_queen(
phase_state = QueenPhaseState(phase=initial_phase, event_bus=session.event_bus)
session.phase_state = phase_state
# ---- Track ask rounds during planning ----------------------------
# Increment planning_ask_rounds each time the queen requests user
# input (ask_user or ask_user_multiple) while in the planning phase.
async def _track_planning_asks(event: AgentEvent) -> None:
if phase_state.phase != "planning":
return
# Only count explicit ask_user / ask_user_multiple calls, not
# auto-block (text-only turns emit CLIENT_INPUT_REQUESTED with
# an empty prompt and no options/questions).
data = event.data or {}
has_prompt = bool(data.get("prompt"))
has_questions = bool(data.get("questions"))
has_options = bool(data.get("options"))
if has_prompt or has_questions or has_options:
phase_state.planning_ask_rounds += 1
session.event_bus.subscribe(
[EventType.CLIENT_INPUT_REQUESTED],
_track_planning_asks,
filter_stream="queen",
)
# ---- Lifecycle tools (always registered) --------------------------
register_queen_lifecycle_tools(
queen_registry,
@@ -149,7 +171,8 @@ async def create_queen(
worker_identity = (
"\n\n# Worker Profile\n"
"No worker agent loaded. You are operating independently.\n"
"Handle all tasks directly using your coding tools."
"Design or build the agent to solve the user's problem "
"according to your current phase."
)
_planning_body = (
+2 -1
View File
@@ -765,7 +765,8 @@ class SessionManager:
await node.inject_event(
"[SYSTEM] Worker unloaded. You are now operating independently. "
"Handle all tasks directly using your coding tools."
"Design or build the agent to solve the user's problem "
"according to your current phase."
)
async def revive_queen(self, session: Session, initial_prompt: str | None = None) -> None:
@@ -95,6 +95,10 @@ class QueenPhaseState:
# Built during decision-node dissolution at confirm_and_build().
flowchart_map: dict[str, list[str]] | None = None
# Counter for ask_user / ask_user_multiple rounds during planning phase.
# Incremented via event bus subscription in queen_orchestrator.
planning_ask_rounds: int = 0
# Agent path — set after scaffolding so the frontend can query credentials
agent_path: str | None = None
@@ -1251,6 +1255,34 @@ def register_queen_lifecycle_tools(
with a unique color. The queen can override auto-detection by setting
flowchart_type explicitly on a node.
"""
# ── Gate: require at least 2 rounds of user questions ─────────
if (
phase_state is not None
and phase_state.phase == "planning"
and phase_state.planning_ask_rounds < 2
):
return json.dumps({
"error": (
"You haven't asked enough questions yet. You have only "
f"asked {phase_state.planning_ask_rounds} round(s) of "
"questions — at least 2 are required before saving a "
"draft. Think deeper and ask more practical questions "
"to fully understand the user's requirements before "
"designing the agent graph."
)
})
# ── Gate: require at least 5 nodes for a meaningful graph ─────
if len(nodes) < 5:
return json.dumps({
"error": (
f"Draft only has {len(nodes)} node(s) — at least 5 are "
"required for a meaningful agent graph. Think deeper and "
"ask more practical questions to fully understand the "
"user's requirements, then design a more thorough graph."
)
})
# Loose validation: each node needs at minimum an id
validated_nodes = []
for i, n in enumerate(nodes):
+2 -1
View File
@@ -13,7 +13,8 @@ from framework.agents.queen.nodes import (
_DEFAULT_WORKER_IDENTITY = (
"\n\n# Worker Profile\n"
"No worker agent loaded. You are operating independently.\n"
"Handle all tasks directly using your coding tools."
"Design or build the agent to solve the user's problem "
"according to your current phase."
)