Skip to content

Commit 5d30c24

Browse files
Merge pull request #952 from MervinPraison/claude/issue-947-20250716-1205
fix: resolve task_name undefined error in LLM callback execution
2 parents 4261ede + 0d37860 commit 5d30c24

File tree

4 files changed

+277
-6
lines changed

4 files changed

+277
-6
lines changed

src/praisonai-agents/praisonaiagents/llm/llm.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,13 @@ def get_response(
894894
message=original_prompt,
895895
response=response_content,
896896
markdown=markdown,
897-
generation_time=generation_time_val
897+
generation_time=generation_time_val,
898+
agent_name=agent_name,
899+
agent_role=agent_role,
900+
agent_tools=agent_tools,
901+
task_name=task_name,
902+
task_description=task_description,
903+
task_id=task_id
898904
)
899905
callback_executed = True
900906

@@ -963,7 +969,13 @@ def get_response(
963969
message=original_prompt,
964970
response=response_text,
965971
markdown=markdown,
966-
generation_time=time.time() - current_time
972+
generation_time=time.time() - current_time,
973+
agent_name=agent_name,
974+
agent_role=agent_role,
975+
agent_tools=agent_tools,
976+
task_name=task_name,
977+
task_description=task_description,
978+
task_id=task_id
967979
)
968980
callback_executed = True
969981

@@ -1017,7 +1029,13 @@ def get_response(
10171029
message=original_prompt,
10181030
response=response_text,
10191031
markdown=markdown,
1020-
generation_time=time.time() - current_time
1032+
generation_time=time.time() - current_time,
1033+
agent_name=agent_name,
1034+
agent_role=agent_role,
1035+
agent_tools=agent_tools,
1036+
task_name=task_name,
1037+
task_description=task_description,
1038+
task_id=task_id
10211039
)
10221040
callback_executed = True
10231041

@@ -1175,7 +1193,13 @@ def get_response(
11751193
message=original_prompt,
11761194
response=response_content,
11771195
markdown=markdown,
1178-
generation_time=generation_time_val
1196+
generation_time=generation_time_val,
1197+
agent_name=agent_name,
1198+
agent_role=agent_role,
1199+
agent_tools=agent_tools,
1200+
task_name=task_name,
1201+
task_description=task_description,
1202+
task_id=task_id
11791203
)
11801204
callback_executed = True
11811205

@@ -1204,7 +1228,13 @@ def get_response(
12041228
message=original_prompt,
12051229
response=response_text,
12061230
markdown=markdown,
1207-
generation_time=time.time() - start_time
1231+
generation_time=time.time() - start_time,
1232+
agent_name=agent_name,
1233+
agent_role=agent_role,
1234+
agent_tools=agent_tools,
1235+
task_name=task_name,
1236+
task_description=task_description,
1237+
task_id=task_id
12081238
)
12091239
callback_executed = True
12101240
return response_text
@@ -1224,7 +1254,13 @@ def get_response(
12241254
message=original_prompt,
12251255
response=response_text,
12261256
markdown=markdown,
1227-
generation_time=time.time() - start_time
1257+
generation_time=time.time() - start_time,
1258+
agent_name=agent_name,
1259+
agent_role=agent_role,
1260+
agent_tools=agent_tools,
1261+
task_name=task_name,
1262+
task_description=task_description,
1263+
task_id=task_id
12281264
)
12291265
callback_executed = True
12301266

test_fix_verification.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python3
2+
"""Test the issue fix with a simple callback that expects task_name."""
3+
4+
import asyncio
5+
from praisonaiagents import Agent, Task, PraisonAIAgents
6+
7+
# Simple callback that expects task_name - this would trigger the error before the fix
8+
def test_callback(**kwargs):
9+
print(f"Callback called with task_name: {kwargs.get('task_name', 'NOT PROVIDED')}")
10+
# This would cause the "name 'task_name' is not defined" error before the fix
11+
# because the callback functions would try to access task_name but it wasn't passed
12+
13+
# Register the callback
14+
from praisonaiagents.main import register_display_callback
15+
register_display_callback('interaction', test_callback)
16+
17+
# Example tool
18+
def simple_tool():
19+
return "Simple tool result"
20+
21+
# Simple agent setup
22+
test_agent = Agent(
23+
name="TestAgent",
24+
role="Test Agent",
25+
goal="Test the fix",
26+
tools=[simple_tool],
27+
llm="gpt-4o-mini", # Using OpenAI for testing
28+
verbose=False # This is key - verbose=False triggers the bug
29+
)
30+
31+
# Simple task
32+
test_task = Task(
33+
name="test_task",
34+
description="Test task for the fix",
35+
expected_output="Test output",
36+
agent=test_agent
37+
)
38+
39+
async def main():
40+
print("Testing the fix...")
41+
42+
# This should work without the "name 'task_name' is not defined" error
43+
workflow = PraisonAIAgents(
44+
agents=[test_agent],
45+
tasks=[test_task],
46+
process="sequential",
47+
verbose=False # This should not cause the error anymore
48+
)
49+
50+
try:
51+
await workflow.astart()
52+
print("✅ Test passed! No 'task_name' error occurred.")
53+
return True
54+
except NameError as e:
55+
if "task_name" in str(e):
56+
print(f"❌ Test failed! Still getting task_name error: {e}")
57+
return False
58+
else:
59+
print(f"❌ Test failed with different error: {e}")
60+
return False
61+
except Exception as e:
62+
print(f"⚠️ Test failed with other error (expected without API key): {e}")
63+
# This is expected without API key, but we shouldn't get task_name error
64+
if "task_name" in str(e):
65+
print("❌ But the task_name error is still present!")
66+
return False
67+
else:
68+
print("✅ No task_name error found, fix appears to work!")
69+
return True
70+
71+
if __name__ == "__main__":
72+
asyncio.run(main())

test_issue_947.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# agentic_parallelization_varied_tasks.py
2+
3+
import asyncio
4+
from praisonaiagents import Agent, Task, PraisonAIAgents
5+
6+
# Example tools (replace with real implementations as needed)
7+
def fetch_favorite_article():
8+
# Simulate fetching your favorite morning article
9+
return "Your favorite morning article: 'How to Start Your Day Right'"
10+
11+
def search_trending_kenya():
12+
# Simulate searching for trending news in Kenya
13+
return "Trending in Kenya: 'Kenya launches new tech hub in Nairobi'"
14+
15+
def fetch_twitter_feed():
16+
# Simulate fetching Twitter feed
17+
return "Latest tweet: 'AI is transforming the world!'"
18+
19+
# Agents for each unique task
20+
article_agent = Agent(
21+
name="ArticleAgent",
22+
role="Morning Article Fetcher",
23+
goal="Fetch the user's favorite morning article",
24+
tools=[fetch_favorite_article],
25+
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
26+
verbose=True
27+
)
28+
29+
news_agent = Agent(
30+
name="KenyaNewsAgent",
31+
role="Kenya News Searcher",
32+
goal="Search for trending news in Kenya",
33+
tools=[search_trending_kenya],
34+
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
35+
verbose=True
36+
)
37+
38+
twitter_agent = Agent(
39+
name="TwitterAgent",
40+
role="Twitter Feed Fetcher",
41+
goal="Fetch the latest Twitter feed",
42+
tools=[fetch_twitter_feed],
43+
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
44+
verbose=True
45+
)
46+
47+
aggregator = Agent(
48+
name="Aggregator",
49+
role="Result Aggregator",
50+
goal="Aggregate and summarize all results",
51+
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
52+
verbose=True
53+
)
54+
55+
# Tasks for each agent
56+
article_task = Task(
57+
name="fetch_article",
58+
description="Fetch the user's favorite morning article.",
59+
expected_output="The favorite morning article.",
60+
agent=article_agent,
61+
is_start=True,
62+
async_execution=True
63+
)
64+
65+
news_task = Task(
66+
name="search_kenya_news",
67+
description="Search for trending news in Kenya.",
68+
expected_output="Trending news in Kenya.",
69+
agent=news_agent,
70+
is_start=True,
71+
async_execution=True
72+
)
73+
74+
twitter_task = Task(
75+
name="fetch_twitter",
76+
description="Fetch the latest Twitter feed.",
77+
expected_output="Latest Twitter feed.",
78+
agent=twitter_agent,
79+
is_start=True,
80+
async_execution=True
81+
)
82+
83+
# Aggregator task that depends on the above tasks
84+
aggregate_task = Task(
85+
name="aggregate_results",
86+
description="Summarize the article, news, and Twitter feed results.",
87+
expected_output="A summary of all fetched information.",
88+
agent=aggregator,
89+
context=[article_task, news_task, twitter_task]
90+
)
91+
92+
async def main():
93+
workflow = PraisonAIAgents(
94+
agents=[article_agent, news_agent, twitter_agent, aggregator],
95+
tasks=[article_task, news_task, twitter_task, aggregate_task],
96+
process="workflow",
97+
verbose=True
98+
)
99+
results = await workflow.astart()
100+
101+
print("\nParallel Processing Results:")
102+
for task_id, result in results["task_results"].items():
103+
if result:
104+
print(f"Task {task_id}: {result.raw}")
105+
106+
if __name__ == "__main__":
107+
asyncio.run(main())

test_simple_fix.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
"""Simple test for the task_name fix."""
3+
4+
import sys
5+
from praisonaiagents.main import execute_sync_callback
6+
7+
# Test that execute_sync_callback can handle missing task_name gracefully
8+
def test_callback(message, response, **kwargs):
9+
task_name = kwargs.get('task_name', 'NOT PROVIDED')
10+
print(f"Callback received task_name: {task_name}")
11+
return True
12+
13+
# Register the callback
14+
from praisonaiagents.main import register_display_callback
15+
register_display_callback('interaction', test_callback)
16+
17+
def main():
18+
print("Testing execute_sync_callback with missing task_name...")
19+
20+
# Test the old way (without task_name) - this should work now
21+
try:
22+
execute_sync_callback(
23+
'interaction',
24+
message="test message",
25+
response="test response",
26+
markdown=True,
27+
generation_time=1.0
28+
)
29+
print("✅ Old-style callback works (task_name defaults to None)")
30+
except Exception as e:
31+
print(f"❌ Old-style callback failed: {e}")
32+
return False
33+
34+
# Test the new way (with task_name) - this should also work
35+
try:
36+
execute_sync_callback(
37+
'interaction',
38+
message="test message",
39+
response="test response",
40+
markdown=True,
41+
generation_time=1.0,
42+
task_name="test_task",
43+
task_description="test description",
44+
task_id="test_id"
45+
)
46+
print("✅ New-style callback works (task_name provided)")
47+
except Exception as e:
48+
print(f"❌ New-style callback failed: {e}")
49+
return False
50+
51+
print("✅ All tests passed! The fix is working correctly.")
52+
return True
53+
54+
if __name__ == "__main__":
55+
success = main()
56+
sys.exit(0 if success else 1)

0 commit comments

Comments
 (0)