From 387ddc043a0bbc6c2da44fa5eb138a661fa92cab Mon Sep 17 00:00:00 2001 From: Aditya Chhabra Date: Tue, 7 Oct 2025 21:07:36 +0530 Subject: [PATCH] chore: add working multi agent langraph limerick writer yaml and end to end test file --- ...limerick_writer_multi_agent_langgraph.yaml | 345 ++++++++++++++++++ .../scripts/test_limerick_writer_langgraph.sh | 184 ++++++++++ 2 files changed, 529 insertions(+) create mode 100644 examples/limerick_writer_multi_agent_langgraph.yaml create mode 100644 tests/scripts/test_limerick_writer_langgraph.sh diff --git a/examples/limerick_writer_multi_agent_langgraph.yaml b/examples/limerick_writer_multi_agent_langgraph.yaml new file mode 100644 index 000000000..23e9a1e4c --- /dev/null +++ b/examples/limerick_writer_multi_agent_langgraph.yaml @@ -0,0 +1,345 @@ +# Multi-Agent Limerick Writer - LangGraph with Conditional Routing +# True multi-agent system with dynamic workflow and conditional routing +# +# AGENTS: +# - Coordinator: Routes workflow and manages topic +# - Writer: Creates the initial limerick +# - Rhymer: Improves rhyme scheme (AABBA) +# - Meter: Improves syllable meter +# - Topic Checker: Ensures limerick matches the topic +# +# USAGE: +# cleveragents interactive -c examples/limerick_writer_multi_agent_langgraph.yaml +# +# EXAMPLE: +# /graph limerick_workflow write me a limerick about quantum physics +# +# HOW IT WORKS: +# - LangGraph manages stateful workflow with conditional routing +# - Coordinator decides which specialist agent to invoke next +# - Each agent actually executes (not simulation) +# - Dynamic routing based on workflow stage + +agents: + # Coordinator agent - manages workflow and routes to specialists + coordinator: + type: llm + config: + provider: openai + model: gpt-4o + temperature: 0.3 + memory_enabled: true + max_history: 20 + max_tokens: 2000 + system_prompt: | + You are the COORDINATOR agent in a multi-agent limerick writing system. + + YOUR ROLE: Route workflow to appropriate specialist agents. + + WORKFLOW STAGES: + 1. Get topic from user + 2. Route to WRITER for initial limerick creation + 3. Route to RHYMER for rhyme scheme improvement + 4. Route to METER for syllable meter refinement + 5. Route to TOPIC_CHECKER for final topic alignment + 6. End workflow + + ROUTING DECISIONS: + Output ONE of these routing tags based on workflow stage: + + [ROUTE:WRITER] - When user provides topic, route to writer + [ROUTE:RHYMER] - After writer creates limerick, route to rhymer + [ROUTE:METER] - After rhymer improves rhymes, route to meter + [ROUTE:TOPIC_CHECKER] - After meter refines syllables, route to topic checker + [ROUTE:END] - When limerick is complete + + OUTPUT FORMAT: + For initial topic: + "Great! I'll create a limerick about [topic]. + [ROUTE:WRITER]" + + For routing between agents: + "Proceeding to next stage. + [ROUTE:NEXT_AGENT]" + + Always include the [ROUTE:X] tag! + + # Writer agent - creates the initial limerick + writer: + type: llm + config: + provider: openai + model: gpt-4 + temperature: 1.0 + memory_enabled: true + max_history: 30 + max_tokens: 1500 + system_prompt: | + You are the WRITER agent in a multi-agent limerick writing system. + + YOUR ROLE: Create limericks based on a topic from conversation history. + + LIMERICK STRUCTURE: + - Five lines total + - Lines 1, 2, 5: Three feet (2-3 syllables each), rhyme scheme A + - Lines 3, 4: Two feet (2-3 syllables each), rhyme scheme B + - Overall rhyme scheme: AABBA + - Line 1 traditionally introduces a person and place + + EXAMPLE LIMERICK: + The limerick is furtive and mean + You must keep her in close quarantine + Or she sneaks to the slums + And promptly becomes + Disorderly, drunk, and obscene. + + TASK: + - Review conversation history for the topic + - Create a creative limerick about that topic + - Follow proper limerick structure + + COMPLETION SIGNAL: + End your response with: "[LIMERICK_CREATED]" + + OUTPUT FORMAT: + "[WRITER SPEAKING] + Creating limerick about [topic]... + + [Your limerick here - 5 lines] + + [LIMERICK_CREATED]" + + # Rhymer agent - improves rhyme scheme + rhymer: + type: llm + config: + provider: openai + model: gpt-4 + temperature: 0.5 + memory_enabled: true + max_history: 30 + max_tokens: 1500 + system_prompt: | + You are the RHYMER agent in a multi-agent limerick writing system. + + YOUR ROLE: Improve the rhyme scheme of limericks. + + RHYME SCHEME RULES: + - Limerick rhyme scheme: AABBA + - Lines 1, 2, 5 must rhyme (A rhyme) + - Lines 3, 4 must rhyme (B rhyme) + - Near-rhymes are acceptable + - Last word of line 1 is usually a place or person name + + EXAMPLE: + There was a young rustic named Mallory, (A) + who drew but a very small salary. (A) + When he went to the show, (B) + His purse made him go (B) + To a seat in the uppermost gallery. (A) + + TASK: + - Review conversation history to find the limerick from WRITER + - Look for "[WRITER SPEAKING]" to find the limerick + - Improve the rhyme scheme if needed + - Maintain the topic and meaning + + COMPLETION SIGNAL: + End your response with: "[RHYMES_IMPROVED]" + + OUTPUT FORMAT: + "[RHYMER SPEAKING] + Reviewing rhyme scheme... + + [Improved limerick with better rhymes] + + [RHYMES_IMPROVED]" + + # Meter agent - improves syllable meter + meter: + type: llm + config: + provider: openai + model: gpt-4 + temperature: 0.5 + memory_enabled: true + max_history: 30 + max_tokens: 1500 + system_prompt: | + You are the METER agent in a multi-agent limerick writing system. + + YOUR ROLE: Improve the syllable meter of limericks. + + METER RULES: + - Lines 1, 2, 5: Three feet of 2-3 syllables each (6-9 syllables total) + - Lines 3, 4: Two feet of 2-3 syllables each (4-6 syllables total) + - Maintain natural rhythm and flow + + EXAMPLE: + A dozen, a gross, and a score (9 syllables) + Plus three times the square root of four (9 syllables) + Divided by seven (6 syllables) + Plus five times eleven (6 syllables) + Is nine squared and not a bit more. (8 syllables) + + TASK: + - Review conversation history to find the limerick from RHYMER + - Look for "[RHYMER SPEAKING]" to find the improved limerick + - Improve the syllable meter if needed + - Maintain rhyme scheme and topic + + COMPLETION SIGNAL: + End your response with: "[METER_REFINED]" + + OUTPUT FORMAT: + "[METER SPEAKING] + Refining syllable meter... + + [Improved limerick with better meter] + + [METER_REFINED]" + + # Topic checker agent - ensures limerick matches the topic + topic_checker: + type: llm + config: + provider: openai + model: gpt-4 + temperature: 0.5 + memory_enabled: true + max_history: 30 + max_tokens: 1500 + system_prompt: | + You are the TOPIC_CHECKER agent in a multi-agent limerick writing system. + + YOUR ROLE: Ensure the limerick closely matches the requested topic. + + TASK: + - Review conversation history to find the original topic + - Review the limerick from METER agent + - Look for "[METER SPEAKING]" to find the refined limerick + - Adjust the limerick to better match the topic if needed + - Maintain rhyme scheme and meter + + COMPLETION SIGNAL: + End your response with: "[LIMERICK_COMPLETE]" + + OUTPUT FORMAT: + "[TOPIC_CHECKER SPEAKING] + Verifying topic alignment... + + [Final limerick aligned with topic] + + Limerick complete! + [LIMERICK_COMPLETE]" + +routes: + # LangGraph workflow with conditional routing + limerick_workflow: + type: graph + entry_point: start + checkpointing: true + + nodes: + # Coordinator routes workflow + coordinate: + type: agent + agent: coordinator + + # Writer creates initial limerick + write: + type: agent + agent: writer + + # Rhymer improves rhyme scheme + improve_rhymes: + type: agent + agent: rhymer + + # Meter improves syllable meter + refine_meter: + type: agent + agent: meter + + # Topic checker ensures alignment + check_topic: + type: agent + agent: topic_checker + + edges: + # Always start with coordinator + - source: start + target: coordinate + + # Coordinator routes to writer + - source: coordinate + target: write + condition: + type: content_contains + text: "[ROUTE:WRITER]" + + # Coordinator routes to rhymer + - source: coordinate + target: improve_rhymes + condition: + type: content_contains + text: "[ROUTE:RHYMER]" + + # Coordinator routes to meter + - source: coordinate + target: refine_meter + condition: + type: content_contains + text: "[ROUTE:METER]" + + # Coordinator routes to topic checker + - source: coordinate + target: check_topic + condition: + type: content_contains + text: "[ROUTE:TOPIC_CHECKER]" + + # Coordinator ends workflow + - source: coordinate + target: end + condition: + type: content_contains + text: "[ROUTE:END]" + + # After writer, go back to coordinator to route to rhymer + - source: write + target: coordinate + + # After rhymer, go back to coordinator to route to meter + - source: improve_rhymes + target: coordinate + + # After meter, go back to coordinator to route to topic checker + - source: refine_meter + target: coordinate + + # After topic checker, go to end + - source: check_topic + target: end + + # Stream that executes the graph + graph_executor: + type: stream + stream_type: cold + operators: + - type: graph_execute + params: + graph: limerick_workflow + publications: + - __output__ + +merges: + - sources: [__input__] + target: graph_executor + +context: + global: + app_name: "Multi-Agent Limerick Writer (LangGraph)" + version: "2.0-langgraph" + log_level: "INFO" + diff --git a/tests/scripts/test_limerick_writer_langgraph.sh b/tests/scripts/test_limerick_writer_langgraph.sh new file mode 100644 index 000000000..b3988cbb2 --- /dev/null +++ b/tests/scripts/test_limerick_writer_langgraph.sh @@ -0,0 +1,184 @@ +#!/bin/bash +# End-to-End Test: Multi-Agent Limerick Writer (LangGraph) +# Tests the complete limerick writing workflow + +# Change to project root +cd "$(dirname "$0")/../.." + +# Check for API key +if [ -z "$OPENAI_API_KEY" ]; then + echo "Error: OPENAI_API_KEY environment variable not set" + echo "Usage: export OPENAI_API_KEY='your-key-here'" + exit 1 +fi + +echo "==========================================" +echo "Limerick Writer Test (LangGraph)" +echo "==========================================" +echo "" +echo "Testing complete workflow:" +echo " 1. Coordinator gets topic" +echo " 2. Writer creates initial limerick" +echo " 3. Rhymer improves rhyme scheme" +echo " 4. Meter refines syllable meter" +echo " 5. Topic Checker ensures alignment" +echo "" + +echo "Starting test..." +echo "" + +# Run the interactive session with incremental commands +cat << 'EOF' | timeout 240 python -m cleveragents interactive -c examples/limerick_writer_multi_agent_langgraph.yaml 2>&1 | tee /tmp/limerick_writer_test.log +/graph limerick_workflow hello, what can you do? +/graph limerick_workflow write me a limerick about quantum computing +/graph limerick_workflow continue to improve the rhymes +/graph limerick_workflow now refine the meter +/graph limerick_workflow check if it matches the topic well +/graph limerick_workflow thank you, that's perfect! +exit +EOF + +EXIT_CODE=$? + +echo "" +echo "==========================================" +echo "Test Results" +echo "==========================================" +echo "" + +# Check exit code +if [ $EXIT_CODE -eq 124 ]; then + echo "⚠ WARNING: Test timed out after 240 seconds" +elif [ $EXIT_CODE -ne 0 ]; then + echo "✗ FAILED: Test exited with code $EXIT_CODE" + exit 1 +fi + +# Check log for agent participation +echo "Agent Participation Check:" +echo "----------------------------------------" +agents_found=0 + +if grep -q "COORDINATOR" /tmp/limerick_writer_test.log || grep -q "coordinate" /tmp/limerick_writer_test.log; then + echo "✓ COORDINATOR agent participated" + agents_found=$((agents_found + 1)) +fi + +if grep -q "WRITER" /tmp/limerick_writer_test.log; then + echo "✓ WRITER agent participated" + agents_found=$((agents_found + 1)) +fi + +if grep -q "RHYMER" /tmp/limerick_writer_test.log; then + echo "✓ RHYMER agent participated" + agents_found=$((agents_found + 1)) +fi + +if grep -q "METER" /tmp/limerick_writer_test.log; then + echo "✓ METER agent participated" + agents_found=$((agents_found + 1)) +fi + +if grep -q "TOPIC_CHECKER\|TOPIC CHECKER" /tmp/limerick_writer_test.log; then + echo "✓ TOPIC_CHECKER agent participated" + agents_found=$((agents_found + 1)) +fi + +echo "" +if [ $agents_found -ge 4 ]; then + echo "✓ Multi-agent collaboration verified ($agents_found/5 agents active)" +else + echo "⚠ WARNING: Limited agent participation detected ($agents_found/5 agents)" +fi + +# Check for limerick structure +echo "" +echo "Limerick Structure Check:" +echo "----------------------------------------" +structure_checks=0 + +# Check for 5-line structure (multiple occurrences as limerick gets refined) +limerick_lines=$(grep -E "^[A-Z].*[a-z\.\!\?]$" /tmp/limerick_writer_test.log | wc -l) +if [ $limerick_lines -ge 5 ]; then + echo "✓ Limerick contains multiple lines (found $limerick_lines lines)" + structure_checks=$((structure_checks + 1)) +else + echo "⚠ WARNING: Limerick may not have proper structure (found $limerick_lines lines)" +fi + +# Check for topic mention (quantum computing) +if grep -qi "quantum" /tmp/limerick_writer_test.log; then + echo "✓ Topic (quantum) referenced in output" + structure_checks=$((structure_checks + 1)) +else + echo "⚠ WARNING: Topic may not be properly addressed" +fi + +# Check for rhyme-related activity +if grep -qi "rhyme\|rhymes\|rhyming" /tmp/limerick_writer_test.log; then + echo "✓ Rhyme improvement detected" + structure_checks=$((structure_checks + 1)) +else + echo "⚠ WARNING: No rhyme improvement detected" +fi + +# Check for meter-related activity +if grep -qi "meter\|syllable" /tmp/limerick_writer_test.log; then + echo "✓ Meter refinement detected" + structure_checks=$((structure_checks + 1)) +else + echo "⚠ WARNING: No meter refinement detected" +fi + +echo "" +if [ $structure_checks -ge 3 ]; then + echo "✓ Limerick workflow: SUCCESSFUL ($structure_checks/4 checks passed)" +elif [ $structure_checks -ge 2 ]; then + echo "⚠ Limerick workflow: MOSTLY SUCCESSFUL ($structure_checks/4 checks passed)" +else + echo "✗ Limerick workflow: INCOMPLETE ($structure_checks/4 checks passed)" +fi + +# Extract and display final limerick +echo "" +echo "Final Limerick Extract:" +echo "----------------------------------------" +# Try to find the last occurrence of what looks like a limerick +if grep -A 10 "TOPIC_CHECKER\|TOPIC CHECKER\|Limerick complete" /tmp/limerick_writer_test.log | tail -20 | head -15; then + echo "----------------------------------------" +else + echo "Could not extract final limerick" + echo "Check full log at: /tmp/limerick_writer_test.log" +fi + +echo "" +echo "==========================================" +echo "Test Complete!" +echo "==========================================" +echo "" + +# Final summary +if [ $agents_found -ge 4 ] && [ $structure_checks -ge 3 ]; then + echo "✓ SUCCESS: All tests passed!" + echo "" + echo "Summary:" + echo " • Multi-agent workflow: ✓" + echo " • Limerick creation: ✓" + echo " • Rhyme improvement: ✓" + echo " • Meter refinement: ✓" + echo " • Topic alignment: ✓" + exit_status=0 +else + echo "⚠ PARTIAL SUCCESS: Some tests failed" + echo "" + echo "Summary:" + echo " • Multi-agent workflow: $([ $agents_found -ge 4 ] && echo '✓' || echo '✗')" + echo " • Limerick workflow: $([ $structure_checks -ge 3 ] && echo '✓' || echo '✗')" + exit_status=1 +fi + +echo "" +echo "Full log saved to: /tmp/limerick_writer_test.log" + +exit $exit_status +