Spaces:
Running
Running
File size: 8,999 Bytes
aa0eed8 3d34f94 92fb7b8 031211a 8279036 aa0eed8 32a4665 8279036 0c8e3ae 748e3ec 0c8e3ae eabf47d 20540b2 0c8e3ae 20540b2 2e933f4 32a4665 eabf47d 748e3ec 32a4665 20540b2 32a4665 eabf47d 748e3ec 32a4665 20540b2 32a4665 9f6122c 32a4665 a654ec1 32a4665 9f6122c 32a4665 8279036 32a4665 8278cdc 32a4665 955b26a 32a4665 8279036 99c5eee 8279036 56bb047 8279036 20540b2 8279036 99c5eee 8279036 99c5eee 29455b5 53ed856 7f972c9 84782eb 53ed856 aaf4e3a 7f972c9 84782eb aaf4e3a 881c209 7f972c9 84782eb 881c209 53ed856 453ee12 53ed856 9ea93d2 453ee12 d06678c 7f972c9 84782eb 453ee12 7f972c9 4a9ad4b 6f626b7 79f31ae 4a9ad4b b0a6799 6f626b7 7f972c9 51c03d5 56bb047 0cf7f1c 7f972c9 b0a6799 cee6a57 56bb047 84782eb cee6a57 9f6122c 1d8c0f6 84782eb 1d8c0f6 7f972c9 1d8c0f6 84782eb 1d8c0f6 3017744 32a4665 0c8e3ae e19371c 56bb047 32a4665 0c8e3ae e19371c 56bb047 32a4665 0c8e3ae 56bb047 32a4665 0c8e3ae 56bb047 32a4665 9f6122c 32a4665 80336e1 32a4665 80336e1 32a4665 d42fd6b 9f6122c 84782eb 9f6122c 53ed856 9f6122c cee6a57 9f6122c 51c03d5 7f972c9 b0a6799 7f972c9 9f6122c b0a6799 7f972c9 9f6122c 19797f3 56bb047 7f972c9 c097c3c 39bf620 0d63545 19797f3 8fae4d3 d42fd6b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
import gradio as gr
import json, openai, os, time
from openai import OpenAI
from utils import function_to_schema, show_json
# Tools
triage_agent, sales_agent, issues_repairs_agent = None, None, None
triage_thread, sales_thread, issues_repairs_thread = None, None, None
def transfer_to_triage_agent():
"""Call this if the user brings up a topic outside of your purview,
including escalating to human."""
print("\n===> transfer_to_triage_agent\n")
global triage_agent, triage_thread
set_current_agent(triage_agent)
set_current_thread(triage_thread)
def transfer_to_sales_agent():
"""Use for anything sales or buying related."""
print("\n===> transfer_to_sales_agent\n")
global sales_agent, sales_thread
set_current_agent(sales_agent)
set_current_thread(sales_thread)
def transfer_to_issues_repairs_agent():
"""Use for issues, repairs, or refunds."""
print("\n=> transfer_to_issues_repairs_agent\n")
global issues_repairs_agent, issues_repairs_thread
set_current_agent(issues_repairs_agent)
set_current_thread(issues_repairs_thread)
#
def escalate_to_human(summary):
"""Only call this if explicitly asked to."""
print(f"=> escalate_to_human: summary: {summary}")
#exit()
#
def execute_order(product, price: int):
"""Price should be in USD."""
print("\n\n=== Order Summary ===")
print(f"Product: {product}")
print(f"Price: ${price}")
print("=================\n")
confirm = input("Confirm order? y/n: ").strip().lower()
if confirm == "y":
print("Order execution successful!")
return "Success"
else:
print(color("Order cancelled!", "red"))
return "User cancelled order."
def look_up_item(search_query):
"""Use to find item ID.
Search query can be a description or keywords."""
item_id = "item_13261293"
print("Found item:", item_id)
return item_id
def execute_refund(item_id, reason="not provided"):
print("\n\n=== Refund Summary ===")
print(f"Item ID: {item_id}")
print(f"Reason: {reason}")
print("=================\n")
print("Refund execution successful!")
return "Success"
#
tools = {
"transfer_to_triage_agent": transfer_to_triage_agent,
"transfer_to_sales_agent": transfer_to_sales_agent,
"transfer_to_issues_repairs_agent": transfer_to_issues_repairs_agent,
"escalate_to_human": escalate_to_human,
"execute_order": execute_order,
"look_up_item": look_up_item,
"execute_refund": execute_refund,
}
# Agents
MODEL = "gpt-4o-mini"
def create_triage_agent(client):
return client.beta.assistants.create(
name="Triage Agent",
instructions=(
"You are a customer service bot for ACME Inc. "
"Introduce yourself. Always be very brief. "
"Gather information to direct the customer to the right department. "
"But make your questions subtle and natural."
),
model=MODEL,
tools=[{"type": "function", "function": function_to_schema(transfer_to_sales_agent)},
{"type": "function", "function": function_to_schema(transfer_to_issues_repairs_agent)},
{"type": "function", "function": function_to_schema(escalate_to_human)}],
)
def create_sales_agent(client):
return client.beta.assistants.create(
name="Sales Agent",
instructions=(
"You are a sales agent for ACME Inc. "
"Always answer in a sentence or less. "
"Follow the following routine with the user: "
"1. Ask them about any problems in their life related to catching roadrunners.\n"
"2. Casually mention one of ACME's crazy made-up products can help.\n"
" - Don't mention price.\n"
"3. Once the user is bought in, drop a ridiculous price.\n"
"4. Only after everything, and if the user says yes, "
"tell them a crazy caveat and execute their order.\n"
""
),
model=MODEL,
tools=[{"type": "function", "function": function_to_schema(execute_order)},
{"type": "function", "function": function_to_schema(transfer_to_triage_agent)}],
)
def create_issues_repairs_agent(client):
return client.beta.assistants.create(
name="Issues and Repairs Agent",
instructions=(
"You are a customer support agent for ACME Inc. "
"Always answer in a sentence or less. "
"Follow the following routine with the user: "
"1. First, ask probing questions and understand the user's problem deeper.\n"
" - unless the user has already provided a reason.\n"
"2. Propose a fix (make one up).\n"
"3. ONLY if not satesfied, offer a refund.\n"
"4. If accepted, search for the ID and then execute refund."
""
),
model=MODEL,
tools=[{"type": "function", "function": function_to_schema(look_up_item)},
{"type": "function", "function": function_to_schema(execute_refund)},
{"type": "function", "function": function_to_schema(transfer_to_triage_agent)}],
)
#
def create_thread(client):
thread = client.beta.threads.create()
#show_json("thread", thread)
return thread
def create_message(client, thread, msg):
message = client.beta.threads.messages.create(
role="user",
thread_id=thread.id,
content=msg,
)
#show_json("message", message)
return message
def create_run(client, assistant, thread):
run = client.beta.threads.runs.create(
assistant_id=assistant.id,
thread_id=thread.id,
)
#show_json("run", run)
return run
def wait_on_run(client, thread, run):
while run.status == "queued" or run.status == "in_progress":
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id,
)
time.sleep(0.25)
#show_json("run", run)
return run
def list_steps(client, thread, run):
steps = client.beta.threads.runs.steps.list(
thread_id=thread.id,
run_id=run.id,
order="asc",
)
show_json("steps", steps)
return steps
def execute_tool_call(tool_call):
name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
global tools
tools[name](**args)
def execute_tool_calls(steps):
for step in steps.data:
step_details = step.step_details
show_json("step_details", step_details)
if hasattr(step_details, "tool_calls"):
for tool_call in step_details.tool_calls:
execute_tool_call(tool_call)
show_json("tool_call", tool_call)
def list_messages(client, thread):
messages = client.beta.threads.messages.list(
thread_id=thread.id
)
show_json("messages", messages)
return messages
def extract_content_values(data):
content_values = []
for item in data.data:
for content in item.content:
if content.type == "text":
content_values.append(content.text.value)
return content_values
#
current_agent, current_thread = None, None
def set_current_agent(agent):
global current_agent
current_agent = agent
show_json("Current Agent", current_agent)
def set_current_thread(thread):
global current_thread
current_thread = thread
show_json("Current Thread", current_thread)
def get_current_agent():
global current_agent
show_json("Current Agent", current_agent)
return current_agent
def get_current_thread():
global current_thread
show_json("Current Thread", current_thread)
return current_thread
#
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
triage_agent = create_triage_agent(client)
sales_agent = create_sales_agent(client)
issues_repairs_agent = create_issues_repairs_agent(client)
set_current_agent(triage_agent)
triage_thread = create_thread(client)
sales_thread = create_thread(client)
issues_repairs_thread = create_thread(client)
set_current_thread(triage_thread)
def chat(message, history, openai_api_key):
global client
assistant = get_current_agent()
thread = get_current_thread()
create_message(client, thread, message)
# async
run = create_run(client, assistant, thread)
run = wait_on_run(client, thread, run)
steps = list_steps(client, thread, run)
execute_tool_calls(steps)
messages = list_messages(client, thread)
content_values = extract_content_values(messages)
return content_values[0]
gr.ChatInterface(
chat,
chatbot=gr.Chatbot(),
textbox=gr.Textbox(placeholder="hi", container=False, scale=7),
title="Multi-Agent Orchestration",
description="Demo using hand-off pattern: triage agent, sales agent, and issues & repairs agent",
clear_btn=None,
retry_btn=None,
undo_btn=None,
).launch() |