|
9 | 9 | ItemHelpers, |
10 | 10 | MessageOutputItem, |
11 | 11 | RunConfig, |
12 | | - RunContextWrapper, |
13 | 12 | Runner, |
14 | 13 | ToolCallItem, |
15 | 14 | ToolCallOutputItem, |
16 | 15 | TResponseInputItem, |
17 | | - function_tool, |
18 | | - handoff, |
19 | 16 | trace, |
20 | 17 | ) |
21 | | - from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX |
22 | | - from pydantic import BaseModel |
23 | 18 |
|
24 | | - |
25 | | -### CONTEXT |
26 | | - |
27 | | - |
28 | | -class AirlineAgentContext(BaseModel): |
29 | | - passenger_name: str | None = None |
30 | | - confirmation_number: str | None = None |
31 | | - seat_number: str | None = None |
32 | | - flight_number: str | None = None |
33 | | - |
34 | | - |
35 | | -### TOOLS |
36 | | - |
37 | | - |
38 | | -@function_tool( |
39 | | - name_override="faq_lookup_tool", |
40 | | - description_override="Lookup frequently asked questions.", |
41 | | -) |
42 | | -async def faq_lookup_tool(question: str) -> str: |
43 | | - if "bag" in question or "baggage" in question: |
44 | | - return ( |
45 | | - "You are allowed to bring one bag on the plane. " |
46 | | - "It must be under 50 pounds and 22 inches x 14 inches x 9 inches." |
47 | | - ) |
48 | | - elif "seats" in question or "plane" in question: |
49 | | - return ( |
50 | | - "There are 120 seats on the plane. " |
51 | | - "There are 22 business class seats and 98 economy seats. " |
52 | | - "Exit rows are rows 4 and 16. " |
53 | | - "Rows 5-8 are Economy Plus, with extra legroom. " |
54 | | - ) |
55 | | - elif "wifi" in question: |
56 | | - return "We have free wifi on the plane, join Airline-Wifi" |
57 | | - return "I'm sorry, I don't know the answer to that question." |
58 | | - |
59 | | - |
60 | | -@function_tool |
61 | | -async def update_seat( |
62 | | - context: RunContextWrapper[AirlineAgentContext], |
63 | | - confirmation_number: str, |
64 | | - new_seat: str, |
65 | | -) -> str: |
66 | | - """ |
67 | | - Update the seat for a given confirmation number. |
68 | | -
|
69 | | - Args: |
70 | | - confirmation_number: The confirmation number for the flight. |
71 | | - new_seat: The new seat to update to. |
72 | | - """ |
73 | | - # Update the context based on the customer's input |
74 | | - context.context.confirmation_number = confirmation_number |
75 | | - context.context.seat_number = new_seat |
76 | | - # Ensure that the flight number has been set by the incoming handoff |
77 | | - assert context.context.flight_number is not None, "Flight number is required" |
78 | | - return f"Updated seat to {new_seat} for confirmation number {confirmation_number}" |
79 | | - |
80 | | - |
81 | | -### HOOKS |
82 | | - |
83 | | - |
84 | | -async def on_seat_booking_handoff( |
85 | | - context: RunContextWrapper[AirlineAgentContext], |
86 | | -) -> None: |
87 | | - flight_number = f"FLT-{workflow.random().randint(100, 999)}" |
88 | | - context.context.flight_number = flight_number |
89 | | - |
90 | | - |
91 | | -### AGENTS |
92 | | - |
93 | | - |
94 | | -def init_agents() -> Agent[AirlineAgentContext]: |
95 | | - """ |
96 | | - Initialize the agents for the airline customer service workflow. |
97 | | - :return: triage agent |
98 | | - """ |
99 | | - faq_agent = Agent[AirlineAgentContext]( |
100 | | - name="FAQ Agent", |
101 | | - handoff_description="A helpful agent that can answer questions about the airline.", |
102 | | - instructions=f"""{RECOMMENDED_PROMPT_PREFIX} |
103 | | - You are an FAQ agent. If you are speaking to a customer, you probably were transferred to from the triage agent. |
104 | | - Use the following routine to support the customer. |
105 | | - # Routine |
106 | | - 1. Identify the last question asked by the customer. |
107 | | - 2. Use the faq lookup tool to answer the question. Do not rely on your own knowledge. |
108 | | - 3. If you cannot answer the question, transfer back to the triage agent.""", |
109 | | - tools=[faq_lookup_tool], |
| 19 | + from openai_agents.workflows.customer_service import ( |
| 20 | + AirlineAgentContext, |
| 21 | + ProcessUserMessageInput, |
| 22 | + init_agents, |
110 | 23 | ) |
111 | 24 |
|
112 | | - seat_booking_agent = Agent[AirlineAgentContext]( |
113 | | - name="Seat Booking Agent", |
114 | | - handoff_description="A helpful agent that can update a seat on a flight.", |
115 | | - instructions=f"""{RECOMMENDED_PROMPT_PREFIX} |
116 | | - You are a seat booking agent. If you are speaking to a customer, you probably were transferred to from the triage agent. |
117 | | - Use the following routine to support the customer. |
118 | | - # Routine |
119 | | - 1. Ask for their confirmation number. |
120 | | - 2. Ask the customer what their desired seat number is. |
121 | | - 3. Use the update seat tool to update the seat on the flight. |
122 | | - If the customer asks a question that is not related to the routine, transfer back to the triage agent. """, |
123 | | - tools=[update_seat], |
124 | | - ) |
125 | | - |
126 | | - triage_agent = Agent[AirlineAgentContext]( |
127 | | - name="Triage Agent", |
128 | | - handoff_description="A triage agent that can delegate a customer's request to the appropriate agent.", |
129 | | - instructions=( |
130 | | - f"{RECOMMENDED_PROMPT_PREFIX} " |
131 | | - "You are a helpful triaging agent. You can use your tools to delegate questions to other appropriate agents." |
132 | | - ), |
133 | | - handoffs=[ |
134 | | - faq_agent, |
135 | | - handoff(agent=seat_booking_agent, on_handoff=on_seat_booking_handoff), |
136 | | - ], |
137 | | - ) |
138 | | - |
139 | | - faq_agent.handoffs.append(triage_agent) |
140 | | - seat_booking_agent.handoffs.append(triage_agent) |
141 | | - return triage_agent |
142 | | - |
143 | | - |
144 | | -class ProcessUserMessageInput(BaseModel): |
145 | | - user_input: str |
146 | | - chat_length: int |
147 | | - |
148 | 25 |
|
149 | 26 | @workflow.defn |
150 | 27 | class CustomerServiceWorkflow: |
| 28 | + @workflow.init |
151 | 29 | def __init__(self, input_items: list[TResponseInputItem] | None = None): |
152 | 30 | self.run_config = RunConfig() |
153 | 31 | self.chat_history: list[str] = [] |
|
0 commit comments