mirror of
https://github.com/humanlayer/12-factor-agents.git
synced 2025-08-20 18:59:53 +03:00
okay
This commit is contained in:
75
workshops/2025-07-16/walkthrough/05-agent.py
Normal file
75
workshops/2025-07-16/walkthrough/05-agent.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# Agent implementation with clarification support
|
||||
import json
|
||||
|
||||
def agent_loop(thread, clarification_handler):
|
||||
"""Run the agent loop until we get a final answer."""
|
||||
while True:
|
||||
# Get the client
|
||||
baml_client = get_baml_client()
|
||||
|
||||
# Serialize the thread
|
||||
thread_json = json.dumps(thread.events, indent=2)
|
||||
|
||||
# Call the agent
|
||||
result = baml_client.DetermineNextStep(thread_json)
|
||||
|
||||
# Check what type of result we got
|
||||
if result.done_for_now:
|
||||
return result.done_for_now.message
|
||||
elif result.clarification_request:
|
||||
# Get clarification from the human
|
||||
clarification = clarification_handler(result.clarification_request.question)
|
||||
|
||||
# Add the clarification to the thread
|
||||
thread.events.append({
|
||||
"type": "clarification_request",
|
||||
"data": result.clarification_request.question
|
||||
})
|
||||
thread.events.append({
|
||||
"type": "clarification_response",
|
||||
"data": clarification
|
||||
})
|
||||
|
||||
# Continue the loop with the clarification
|
||||
elif result.calculator_tool:
|
||||
# Extract tool details
|
||||
tool = result.calculator_tool
|
||||
|
||||
# Execute the appropriate tool
|
||||
if hasattr(tool, 'add') and tool.add:
|
||||
result_value = tool.add.a + tool.add.b
|
||||
operation = f"add({tool.add.a}, {tool.add.b})"
|
||||
elif hasattr(tool, 'subtract') and tool.subtract:
|
||||
result_value = tool.subtract.a - tool.subtract.b
|
||||
operation = f"subtract({tool.subtract.a}, {tool.subtract.b})"
|
||||
elif hasattr(tool, 'multiply') and tool.multiply:
|
||||
result_value = tool.multiply.a * tool.multiply.b
|
||||
operation = f"multiply({tool.multiply.a}, {tool.multiply.b})"
|
||||
elif hasattr(tool, 'divide') and tool.divide:
|
||||
if tool.divide.b == 0:
|
||||
result_value = "Error: Division by zero"
|
||||
else:
|
||||
result_value = tool.divide.a / tool.divide.b
|
||||
operation = f"divide({tool.divide.a}, {tool.divide.b})"
|
||||
else:
|
||||
result_value = "Error: Unknown tool"
|
||||
operation = "unknown"
|
||||
|
||||
print(f"🔧 Calling tool: {operation} = {result_value}")
|
||||
|
||||
# Add the tool call and result to the thread
|
||||
thread.events.append({
|
||||
"type": "tool_call",
|
||||
"data": {
|
||||
"tool": "calculator",
|
||||
"operation": operation,
|
||||
"result": result_value
|
||||
}
|
||||
})
|
||||
else:
|
||||
return "Error: Unexpected result type"
|
||||
|
||||
class Thread:
|
||||
"""Simple thread to track conversation history."""
|
||||
def __init__(self, events):
|
||||
self.events = events
|
||||
29
workshops/2025-07-16/walkthrough/05-main.py
Normal file
29
workshops/2025-07-16/walkthrough/05-main.py
Normal file
@@ -0,0 +1,29 @@
|
||||
def get_human_input(prompt):
|
||||
"""Get input from human, handling both Colab and local environments."""
|
||||
print(f"\n🤔 {prompt}")
|
||||
|
||||
if IN_COLAB:
|
||||
# In Colab, use actual input
|
||||
response = input("Your response: ")
|
||||
else:
|
||||
# In local testing, return a fixed response
|
||||
response = "I meant to multiply 3 and 4"
|
||||
print(f"📝 [Auto-response for testing]: {response}")
|
||||
|
||||
return response
|
||||
|
||||
def main(message="hello from the notebook!"):
|
||||
# Function to handle clarification requests
|
||||
def handle_clarification(question):
|
||||
return get_human_input(f"The agent needs clarification: {question}")
|
||||
|
||||
# Create a new thread with the user's message
|
||||
thread = Thread([{"type": "user_input", "data": message}])
|
||||
|
||||
print(f"🚀 Starting agent with message: '{message}'")
|
||||
|
||||
# Run the agent loop
|
||||
result = agent_loop(thread, handle_clarification)
|
||||
|
||||
# Print the final response
|
||||
print(f"\n✅ Final response: {result}")
|
||||
108
workshops/2025-07-16/walkthrough/07-agent.py
Normal file
108
workshops/2025-07-16/walkthrough/07-agent.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# Agent with configurable serialization formats
|
||||
import json
|
||||
|
||||
class Thread:
|
||||
"""Thread that can serialize to different formats."""
|
||||
def __init__(self, events):
|
||||
self.events = events
|
||||
|
||||
def serialize_as_json(self):
|
||||
"""Serialize thread events to pretty-printed JSON."""
|
||||
return json.dumps(self.events, indent=2)
|
||||
|
||||
def serialize_as_xml(self):
|
||||
"""Serialize thread events to XML format for better token efficiency."""
|
||||
xml_parts = ["<thread>"]
|
||||
|
||||
for event in self.events:
|
||||
event_type = event['type']
|
||||
event_data = event['data']
|
||||
|
||||
if event_type == 'user_input':
|
||||
xml_parts.append(f' <user_input>{event_data}</user_input>')
|
||||
elif event_type == 'tool_call':
|
||||
xml_parts.append(f' <tool_call>')
|
||||
xml_parts.append(f' <tool>{event_data["tool"]}</tool>')
|
||||
xml_parts.append(f' <operation>{event_data["operation"]}</operation>')
|
||||
xml_parts.append(f' <result>{event_data["result"]}</result>')
|
||||
xml_parts.append(f' </tool_call>')
|
||||
elif event_type == 'clarification_request':
|
||||
xml_parts.append(f' <clarification_request>{event_data}</clarification_request>')
|
||||
elif event_type == 'clarification_response':
|
||||
xml_parts.append(f' <clarification_response>{event_data}</clarification_response>')
|
||||
|
||||
xml_parts.append("</thread>")
|
||||
return "\n".join(xml_parts)
|
||||
|
||||
def agent_loop(thread, clarification_handler, use_xml=True):
|
||||
"""Run the agent loop with configurable serialization."""
|
||||
while True:
|
||||
# Get the client
|
||||
baml_client = get_baml_client()
|
||||
|
||||
# Serialize the thread based on format preference
|
||||
if use_xml:
|
||||
thread_str = thread.serialize_as_xml()
|
||||
print(f"📄 Using XML serialization ({len(thread_str)} chars)")
|
||||
else:
|
||||
thread_str = thread.serialize_as_json()
|
||||
print(f"📄 Using JSON serialization ({len(thread_str)} chars)")
|
||||
|
||||
# Call the agent
|
||||
result = baml_client.DetermineNextStep(thread_str)
|
||||
|
||||
# Check what type of result we got
|
||||
if result.done_for_now:
|
||||
return result.done_for_now.message
|
||||
elif result.clarification_request:
|
||||
# Get clarification from the human
|
||||
clarification = clarification_handler(result.clarification_request.question)
|
||||
|
||||
# Add the clarification to the thread
|
||||
thread.events.append({
|
||||
"type": "clarification_request",
|
||||
"data": result.clarification_request.question
|
||||
})
|
||||
thread.events.append({
|
||||
"type": "clarification_response",
|
||||
"data": clarification
|
||||
})
|
||||
|
||||
# Continue the loop with the clarification
|
||||
elif result.calculator_tool:
|
||||
# Extract tool details
|
||||
tool = result.calculator_tool
|
||||
|
||||
# Execute the appropriate tool
|
||||
if hasattr(tool, 'add') and tool.add:
|
||||
result_value = tool.add.a + tool.add.b
|
||||
operation = f"add({tool.add.a}, {tool.add.b})"
|
||||
elif hasattr(tool, 'subtract') and tool.subtract:
|
||||
result_value = tool.subtract.a - tool.subtract.b
|
||||
operation = f"subtract({tool.subtract.a}, {tool.subtract.b})"
|
||||
elif hasattr(tool, 'multiply') and tool.multiply:
|
||||
result_value = tool.multiply.a * tool.multiply.b
|
||||
operation = f"multiply({tool.multiply.a}, {tool.multiply.b})"
|
||||
elif hasattr(tool, 'divide') and tool.divide:
|
||||
if tool.divide.b == 0:
|
||||
result_value = "Error: Division by zero"
|
||||
else:
|
||||
result_value = tool.divide.a / tool.divide.b
|
||||
operation = f"divide({tool.divide.a}, {tool.divide.b})"
|
||||
else:
|
||||
result_value = "Error: Unknown tool"
|
||||
operation = "unknown"
|
||||
|
||||
print(f"🔧 Calling tool: {operation} = {result_value}")
|
||||
|
||||
# Add the tool call and result to the thread
|
||||
thread.events.append({
|
||||
"type": "tool_call",
|
||||
"data": {
|
||||
"tool": "calculator",
|
||||
"operation": operation,
|
||||
"result": result_value
|
||||
}
|
||||
})
|
||||
else:
|
||||
return "Error: Unexpected result type"
|
||||
16
workshops/2025-07-16/walkthrough/07-main.py
Normal file
16
workshops/2025-07-16/walkthrough/07-main.py
Normal file
@@ -0,0 +1,16 @@
|
||||
def main(message="hello from the notebook!", use_xml=True):
|
||||
# Function to handle clarification requests
|
||||
def handle_clarification(question):
|
||||
return get_human_input(f"The agent needs clarification: {question}")
|
||||
|
||||
# Create a new thread with the user's message
|
||||
thread = Thread([{"type": "user_input", "data": message}])
|
||||
|
||||
print(f"🚀 Starting agent with message: '{message}'")
|
||||
print(f"📋 Using {'XML' if use_xml else 'JSON'} format for thread serialization")
|
||||
|
||||
# Run the agent loop with XML serialization
|
||||
result = agent_loop(thread, handle_clarification, use_xml=use_xml)
|
||||
|
||||
# Print the final response
|
||||
print(f"\n✅ Final response: {result}")
|
||||
Reference in New Issue
Block a user