mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-31 19:15:17 +02:00
Enable internal and user-facing agents to build pipelines
This commit is contained in:
parent
1246ea47b9
commit
e59a8b75cf
24 changed files with 2100 additions and 1376 deletions
|
|
@ -1,7 +1,5 @@
|
|||
from .access import get_agent_config_by_name, get_agent_data_by_name
|
||||
from src.graph.types import ControlType
|
||||
from src.utils.common import common_logger
|
||||
logger = common_logger
|
||||
|
||||
def get_last_agent_name(state, agent_configs, start_agent_name, msg_type, latest_assistant_msg, start_turn_with_start_agent):
|
||||
default_last_agent_name = state.get("last_agent_name", '')
|
||||
|
|
@ -9,7 +7,7 @@ def get_last_agent_name(state, agent_configs, start_agent_name, msg_type, latest
|
|||
specific_agent_data = get_agent_data_by_name(default_last_agent_name, state.get("agent_data", []))
|
||||
|
||||
# Overrides for special cases
|
||||
logger.info("Setting agent control based on last agent and control type")
|
||||
print("Setting agent control based on last agent and control type")
|
||||
if msg_type == "tool":
|
||||
last_agent_name = default_last_agent_name
|
||||
assert last_agent_name == latest_assistant_msg.get("sender", ''), "Last agent name does not match sender of latest assistant message during tool call handling"
|
||||
|
|
@ -22,7 +20,7 @@ def get_last_agent_name(state, agent_configs, start_agent_name, msg_type, latest
|
|||
if control_type == ControlType.PARENT_AGENT.value:
|
||||
last_agent_name = specific_agent_data.get("most_recent_parent_name", None) if specific_agent_data else None
|
||||
if not last_agent_name:
|
||||
logger.error("Most recent parent is empty, defaulting to same agent instead")
|
||||
print("Most recent parent is empty, defaulting to same agent instead")
|
||||
last_agent_name = default_last_agent_name
|
||||
elif control_type == ControlType.START_AGENT.value:
|
||||
last_agent_name = start_agent_name
|
||||
|
|
@ -30,7 +28,7 @@ def get_last_agent_name(state, agent_configs, start_agent_name, msg_type, latest
|
|||
last_agent_name = default_last_agent_name
|
||||
|
||||
if default_last_agent_name != last_agent_name:
|
||||
logger.info(f"Last agent name changed from {default_last_agent_name} to {last_agent_name} due to control settings")
|
||||
print(f"Last agent name changed from {default_last_agent_name} to {last_agent_name} due to control settings")
|
||||
|
||||
return last_agent_name
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from src.graph.instructions import TRANSFER_CHILDREN_INSTRUCTIONS, TRANSFER_PARENT_AWARE_INSTRUCTIONS, RAG_INSTRUCTIONS, ERROR_ESCALATION_AGENT_INSTRUCTIONS, TRANSFER_GIVE_UP_CONTROL_INSTRUCTIONS, SYSTEM_MESSAGE
|
||||
from src.graph.instructions import TRANSFER_CHILDREN_INSTRUCTIONS, TRANSFER_PARENT_AWARE_INSTRUCTIONS, RAG_INSTRUCTIONS, ERROR_ESCALATION_AGENT_INSTRUCTIONS, TRANSFER_GIVE_UP_CONTROL_INSTRUCTIONS, SYSTEM_MESSAGE, CHILD_TRANSFER_RELATED_INSTRUCTIONS
|
||||
|
||||
def add_transfer_instructions_to_parent_agents(agent, children, transfer_functions):
|
||||
other_agent_name_descriptions_tools = f'\n{'-'*100}\n'.join([f"Name: {agent.name}\nDescription: {agent.description if agent.description else ''}\nTool for transfer: {transfer_functions[agent.name].__name__}" for agent in children.values()])
|
||||
|
|
@ -36,4 +36,9 @@ def get_universal_system_message(messages):
|
|||
|
||||
def add_universal_system_message_to_agent(agent, universal_sys_msg):
|
||||
agent.instructions = agent.instructions + f'\n\n{'-'*100}\n\n' + universal_sys_msg
|
||||
return agent
|
||||
return agent
|
||||
|
||||
def add_child_transfer_related_instructions(agent):
|
||||
prompt = CHILD_TRANSFER_RELATED_INSTRUCTIONS
|
||||
agent.instructions = agent.instructions + f'\n\n{'-'*100}\n\n' + prompt
|
||||
return agent
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import json
|
||||
import uuid
|
||||
import traceback
|
||||
|
||||
def handle_web_search_event(event, current_agent):
|
||||
"""
|
||||
|
|
@ -8,53 +9,166 @@ def handle_web_search_event(event, current_agent):
|
|||
"""
|
||||
messages = []
|
||||
|
||||
# Handle raw response web search
|
||||
if event.type == "raw_response_event":
|
||||
if hasattr(event, 'data') and hasattr(event.data, 'raw_item'):
|
||||
raw_item = event.data.raw_item
|
||||
if (hasattr(raw_item, 'type') and raw_item.type == 'web_search_call') or (
|
||||
isinstance(raw_item, dict) and raw_item.get('type') == 'web_search_call'
|
||||
try:
|
||||
# Handle raw response web search
|
||||
if event.type == "raw_response_event":
|
||||
if hasattr(event, 'data') and hasattr(event.data, 'raw_item'):
|
||||
raw_item = event.data.raw_item
|
||||
if (hasattr(raw_item, 'type') and raw_item.type == 'web_search_call') or (
|
||||
isinstance(raw_item, dict) and raw_item.get('type') == 'web_search_call'
|
||||
):
|
||||
call_id = None
|
||||
if hasattr(raw_item, 'id'):
|
||||
call_id = raw_item.id
|
||||
elif isinstance(raw_item, dict) and 'id' in raw_item:
|
||||
call_id = raw_item['id']
|
||||
else:
|
||||
call_id = str(uuid.uuid4())
|
||||
|
||||
status = 'unknown'
|
||||
if hasattr(raw_item, 'status'):
|
||||
status = raw_item.status
|
||||
elif isinstance(raw_item, dict) and 'status' in raw_item:
|
||||
status = raw_item['status']
|
||||
tool_call_msg = {
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
'tool_calls': [{
|
||||
'function': {
|
||||
'name': 'web_search',
|
||||
'arguments': json.dumps({
|
||||
'search_id': call_id,
|
||||
'status': status
|
||||
})
|
||||
},
|
||||
'id': call_id,
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
}
|
||||
print(f"Condition for tool call matched in raw_response_event. Appending tool call message: {tool_call_msg}")
|
||||
messages.append(tool_call_msg)
|
||||
|
||||
tool_call_output_dummy_msg = {
|
||||
'content': 'Web search completed.',
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
}
|
||||
messages.append(tool_call_output_dummy_msg)
|
||||
|
||||
# Handle run item web search events
|
||||
elif event.type == "run_item_stream_event":
|
||||
if event.item.type == "tool_call_item":
|
||||
try:
|
||||
# Check if it's a web search call
|
||||
if hasattr(event.item.raw_item, 'type') and event.item.raw_item.type == 'web_search_call':
|
||||
call_id = event.item.raw_item.id if hasattr(event.item.raw_item, 'id') else str(uuid.uuid4())
|
||||
tool_call_msg = {
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
'tool_calls': [{
|
||||
'function': {
|
||||
'name': 'web_search',
|
||||
'arguments': json.dumps({
|
||||
'search_id': call_id
|
||||
})
|
||||
},
|
||||
'id': call_id,
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
}
|
||||
print(f"Condition for tool call matched in run_item_stream_event. Appending tool call message: {tool_call_msg}")
|
||||
messages.append(tool_call_msg)
|
||||
|
||||
tool_call_output_dummy_msg = {
|
||||
'content': 'Web search completed.',
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
}
|
||||
messages.append(tool_call_output_dummy_msg)
|
||||
else:
|
||||
# Handle regular tool calls
|
||||
tool_call_msg = {
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
'tool_calls': [{
|
||||
'function': {
|
||||
'name': event.item.raw_item.name,
|
||||
'arguments': event.item.raw_item.arguments
|
||||
},
|
||||
'id': event.item.raw_item.call_id,
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
}
|
||||
print(f"Condition for tool call matched in run_item_stream_event. Appending tool call message: {tool_call_msg}")
|
||||
messages.append(tool_call_msg)
|
||||
|
||||
tool_call_output_dummy_msg = {
|
||||
'content': 'Web search completed.',
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
}
|
||||
messages.append(tool_call_output_dummy_msg)
|
||||
except Exception as e:
|
||||
print("\n=== Error in tool_call_item handling ===")
|
||||
print(f"Error: {str(e)}")
|
||||
print(f"Event type: {event.type}")
|
||||
print(f"Event item type: {event.item.type}")
|
||||
print("Event details:")
|
||||
print(f"Raw item: {event.item.raw_item}")
|
||||
if hasattr(event.item.raw_item, '__dict__'):
|
||||
print(f"Raw item attributes: {event.item.raw_item.__dict__}")
|
||||
print(f"Traceback: {traceback.format_exc()}")
|
||||
print("=" * 50)
|
||||
raise
|
||||
|
||||
elif event.item.type == "tool_call_output_item":
|
||||
if isinstance(event.item.raw_item, dict) and event.item.raw_item.get('type') == 'web_search_results':
|
||||
call_id = event.item.raw_item.get('search_id', event.item.raw_item.get('id', str(uuid.uuid4())))
|
||||
tool_call_output_msg = {
|
||||
'content': str(event.item.output),
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
}
|
||||
print(f"Condition for tool call output matched in run_item_stream_event. Appending tool call output message: {tool_call_output_msg}")
|
||||
messages.append(tool_call_output_msg)
|
||||
|
||||
elif event.item.type == "web_search_call_item" or (
|
||||
hasattr(event.item, 'raw_item') and
|
||||
hasattr(event.item.raw_item, 'type') and
|
||||
event.item.raw_item.type == 'web_search_call'
|
||||
):
|
||||
call_id = None
|
||||
if hasattr(raw_item, 'id'):
|
||||
call_id = raw_item.id
|
||||
elif isinstance(raw_item, dict) and 'id' in raw_item:
|
||||
call_id = raw_item['id']
|
||||
else:
|
||||
call_id = str(uuid.uuid4())
|
||||
|
||||
status = 'unknown'
|
||||
if hasattr(raw_item, 'status'):
|
||||
status = raw_item.status
|
||||
elif isinstance(raw_item, dict) and 'status' in raw_item:
|
||||
status = raw_item['status']
|
||||
|
||||
messages.append({
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
'tool_calls': [{
|
||||
'function': {
|
||||
'name': 'web_search',
|
||||
'arguments': json.dumps({
|
||||
'search_id': call_id,
|
||||
'status': status
|
||||
})
|
||||
},
|
||||
'id': call_id,
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
})
|
||||
|
||||
# Handle run item web search events
|
||||
elif event.type == "run_item_stream_event":
|
||||
if event.item.type == "tool_call_item":
|
||||
if hasattr(event.item.raw_item, 'type') and event.item.raw_item.type == 'web_search_call':
|
||||
call_id = event.item.raw_item.id if hasattr(event.item.raw_item, 'id') else str(uuid.uuid4())
|
||||
messages.append({
|
||||
if hasattr(event.item.raw_item, 'id'):
|
||||
call_id = event.item.raw_item.id
|
||||
tool_call_msg = {
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
|
|
@ -65,107 +179,90 @@ def handle_web_search_event(event, current_agent):
|
|||
'search_id': call_id
|
||||
})
|
||||
},
|
||||
'id': call_id,
|
||||
'id': call_id or str(uuid.uuid4()),
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
})
|
||||
messages.append({
|
||||
'content': "Web search done",
|
||||
}
|
||||
print(f"Condition for tool call matched in run_item_stream_event. Appending tool call message: {tool_call_msg}")
|
||||
messages.append(tool_call_msg)
|
||||
tool_call_output_dummy_msg = {
|
||||
'content': 'Web search completed.',
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
})
|
||||
}
|
||||
messages.append(tool_call_output_dummy_msg)
|
||||
|
||||
elif event.item.type == "tool_call_output_item":
|
||||
if isinstance(event.item.raw_item, dict) and event.item.raw_item.get('type') == 'web_search_results':
|
||||
call_id = event.item.raw_item.get('search_id', event.item.raw_item.get('id', str(uuid.uuid4())))
|
||||
messages.append({
|
||||
'content': str(event.item.output),
|
||||
elif event.item.type == "web_search_results_item" or (
|
||||
hasattr(event.item, 'raw_item') and (
|
||||
(hasattr(event.item.raw_item, 'type') and event.item.raw_item.type == 'web_search_results') or
|
||||
(isinstance(event.item.raw_item, dict) and event.item.raw_item.get('type') == 'web_search_results')
|
||||
)
|
||||
):
|
||||
raw_item = event.item.raw_item
|
||||
call_id = None
|
||||
|
||||
if hasattr(raw_item, 'search_id'):
|
||||
call_id = raw_item.search_id
|
||||
elif isinstance(raw_item, dict) and 'search_id' in raw_item:
|
||||
call_id = raw_item['search_id']
|
||||
elif hasattr(raw_item, 'id'):
|
||||
call_id = raw_item.id
|
||||
elif isinstance(raw_item, dict) and 'id' in raw_item:
|
||||
call_id = raw_item['id']
|
||||
else:
|
||||
call_id = str(uuid.uuid4())
|
||||
|
||||
results = {}
|
||||
if hasattr(event.item, 'output'):
|
||||
results = event.item.output
|
||||
elif hasattr(raw_item, 'results'):
|
||||
results = raw_item.results
|
||||
elif isinstance(raw_item, dict) and 'results' in raw_item:
|
||||
results = raw_item['results']
|
||||
|
||||
results_str = ""
|
||||
try:
|
||||
results_str = json.dumps(results) if results else ""
|
||||
except Exception as e:
|
||||
print(f"Error serializing results: {str(e)}")
|
||||
results_str = str(results)
|
||||
|
||||
tool_call_output_msg = {
|
||||
'content': results_str,
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
})
|
||||
}
|
||||
print(f"Condition for tool call output matched in run_item_stream_event. Appending tool call output message: {tool_call_output_msg}")
|
||||
messages.append(tool_call_output_msg)
|
||||
|
||||
elif event.item.type == "web_search_call_item" or (
|
||||
hasattr(event.item, 'raw_item') and
|
||||
hasattr(event.item.raw_item, 'type') and
|
||||
event.item.raw_item.type == 'web_search_call'
|
||||
):
|
||||
call_id = None
|
||||
if hasattr(event.item.raw_item, 'id'):
|
||||
call_id = event.item.raw_item.id
|
||||
except Exception as e:
|
||||
print("\n=== Error in handle_web_search_event ===")
|
||||
print(f"Error: {str(e)}")
|
||||
print(f"Event type: {event.type}")
|
||||
if hasattr(event, 'item'):
|
||||
print(f"Event item type: {event.item.type}")
|
||||
print("Event item details:")
|
||||
print(f"Raw item: {event.item.raw_item}")
|
||||
if hasattr(event.item.raw_item, '__dict__'):
|
||||
print(f"Raw item attributes: {event.item.raw_item.__dict__}")
|
||||
print(f"Traceback: {traceback.format_exc()}")
|
||||
print("=" * 50)
|
||||
raise
|
||||
|
||||
messages.append({
|
||||
'content': None,
|
||||
'role': 'assistant',
|
||||
'sender': current_agent.name if current_agent else None,
|
||||
'tool_calls': [{
|
||||
'function': {
|
||||
'name': 'web_search',
|
||||
'arguments': json.dumps({
|
||||
'search_id': call_id
|
||||
})
|
||||
},
|
||||
'id': call_id or str(uuid.uuid4()),
|
||||
'type': 'function'
|
||||
}],
|
||||
'tool_call_id': None,
|
||||
'tool_name': None,
|
||||
'response_type': 'internal'
|
||||
})
|
||||
|
||||
elif event.item.type == "web_search_results_item" or (
|
||||
hasattr(event.item, 'raw_item') and (
|
||||
(hasattr(event.item.raw_item, 'type') and event.item.raw_item.type == 'web_search_results') or
|
||||
(isinstance(event.item.raw_item, dict) and event.item.raw_item.get('type') == 'web_search_results')
|
||||
)
|
||||
):
|
||||
raw_item = event.item.raw_item
|
||||
call_id = None
|
||||
|
||||
if hasattr(raw_item, 'search_id'):
|
||||
call_id = raw_item.search_id
|
||||
elif isinstance(raw_item, dict) and 'search_id' in raw_item:
|
||||
call_id = raw_item['search_id']
|
||||
elif hasattr(raw_item, 'id'):
|
||||
call_id = raw_item.id
|
||||
elif isinstance(raw_item, dict) and 'id' in raw_item:
|
||||
call_id = raw_item['id']
|
||||
else:
|
||||
call_id = str(uuid.uuid4())
|
||||
|
||||
results = {}
|
||||
if hasattr(event.item, 'output'):
|
||||
results = event.item.output
|
||||
elif hasattr(raw_item, 'results'):
|
||||
results = raw_item.results
|
||||
elif isinstance(raw_item, dict) and 'results' in raw_item:
|
||||
results = raw_item['results']
|
||||
|
||||
results_str = ""
|
||||
try:
|
||||
results_str = json.dumps(results) if results else ""
|
||||
except Exception as e:
|
||||
print(f"Error serializing results: {str(e)}")
|
||||
results_str = str(results)
|
||||
|
||||
messages.append({
|
||||
'content': results_str,
|
||||
'role': 'tool',
|
||||
'sender': None,
|
||||
'tool_calls': None,
|
||||
'tool_call_id': call_id,
|
||||
'tool_name': 'web_search',
|
||||
'response_type': 'internal'
|
||||
})
|
||||
if messages:
|
||||
print("-"*100)
|
||||
print(f"Web search related messages: {messages}")
|
||||
print("-"*100)
|
||||
|
||||
return messages
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue