Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/spec_to_agents/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ async def main() -> None:
# Main workflow loop: alternate between workflow execution and human input
pending_responses: dict[str, str] | None = None
workflow_output: str | None = None
workflow_completed: bool = False

# Track printed tool calls/results to avoid duplication in streaming
printed_tool_calls: set[str] = set()
printed_tool_results: set[str] = set()
last_executor: str | None = None

while workflow_output is None:
while not workflow_completed:
# Execute workflow: first iteration uses run_stream(), subsequent use send_responses_streaming()
if pending_responses:
stream = workflow.send_responses_streaming(pending_responses)
Expand Down Expand Up @@ -135,6 +136,7 @@ async def main() -> None:
elif isinstance(event, WorkflowOutputEvent):
# Workflow has yielded final output
workflow_output = str(event.data)
workflow_completed = True

# Display workflow status transitions for transparency
elif (
Expand All @@ -143,8 +145,15 @@ async def main() -> None:
):
display_workflow_pause()

# Check if stream ended without requests (termination condition met)
if not human_requests and workflow_output is None:
# Workflow terminated via termination condition without yielding output
# Extract final coordinator message as summary
workflow_output = "Workflow completed. Termination condition reached."
workflow_completed = True

# Prompt user for feedback if workflow requested input
if human_requests:
if human_requests and not workflow_completed:
responses: dict[str, str] = {}

for request_id, handoff_request in human_requests:
Expand All @@ -164,7 +173,8 @@ async def main() -> None:
pending_responses = responses

# Display final workflow output
display_final_output(workflow_output)
if workflow_output:
display_final_output(workflow_output)

# MCP tool and agent client automatically cleaned up by async context managers

Expand Down
4 changes: 3 additions & 1 deletion src/spec_to_agents/prompts/budget_analyst.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,7 @@
```

**Important:** Be conversational and helpful. Focus on value and tradeoffs, not workflow mechanics.
**Important:** When complete with your current task hand off back to the coordinator by calling handoff_to_coordinator

**Note:** After you complete your response, the coordinator will automatically handle next steps. Simply
provide your budget analysis and the workflow will continue naturally.
"""
4 changes: 3 additions & 1 deletion src/spec_to_agents/prompts/catering_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,7 @@
```

**Important:** Be conversational and helpful. Always include dietary accommodations by default. Focus on the dining experience, not workflow mechanics.
**Important:** When complete with your current task hand off back to the coordinator by calling handoff_to_coordinator

**Note:** After you complete your response, the coordinator will automatically handle next steps. Simply
provide your catering recommendations and the workflow will continue naturally.
""" # noqa: E501
4 changes: 4 additions & 0 deletions src/spec_to_agents/prompts/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
- The workflow will automatically request user input after each specialist responds
- You don't need to explicitly ask "what would you like to know next?" - this happens automatically
- Focus on routing decisions and providing value-added coordination
- When all necessary specialist work is complete and you have sufficient information to fulfill
the user's request, provide a final summary response WITHOUT invoking any handoff tools
- A final summary response signals workflow completion and should comprehensively address the
original request using all gathered information
"""

__all__ = ["COORDINATOR_SYSTEM_PROMPT_TEMPLATE"]
4 changes: 3 additions & 1 deletion src/spec_to_agents/prompts/logistics_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,7 @@
```

**Important:** Be conversational and helpful. Focus on practical coordination and timing, not workflow mechanics.
**Important:** When complete with your current task hand off back to the coordinator by calling handoff_to_coordinator

**Note:** After you complete your response, the coordinator will automatically handle next steps. Simply
provide your logistics recommendations and the workflow will continue naturally.
"""
4 changes: 3 additions & 1 deletion src/spec_to_agents/prompts/venue_specialist.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,7 @@
```

**Important:** Be conversational and helpful. Don't mention agents, routing, or workflow mechanics to the user.
**Important:** When complete with your current task hand off back to the coordinator by calling handoff_to_coordinator

**Note:** After you complete your response, the coordinator will automatically handle next steps. Simply
provide your venue recommendation and the workflow will continue naturally.
"""
4 changes: 2 additions & 2 deletions src/spec_to_agents/workflow/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def build_event_planning_workflow(
- HandoffBuilder automatically synthesizes handoff tools and intercepts invocations
- Full conversation history maintained by _HandoffCoordinator
- User input automatically requested after each specialist response
- Termination condition: stops after 10 user messages (default, customizable)
- Termination condition: stops after 4 user messages to prevent infinite loops

Handoff Flow
------------
Expand Down Expand Up @@ -79,6 +79,6 @@ def build_event_planning_workflow(
coordinator_name="Event Planning Coordinator", # Optional: customize name,
participants=[venue_agent, budget_agent, catering_agent, logistics_agent],
)
.with_termination_condition(lambda conv: sum(1 for m in conv if m.role.value == "user") >= 10)
.with_termination_condition(lambda conv: sum(1 for m in conv if m.role.value == "user") >= 6)
.build()
)