|
20 | 20 | "import os\n", |
21 | 21 | "import getpass\n", |
22 | 22 | "\n", |
23 | | - "os.environ['ANTHROPIC_API_KEY'] = \"\"\n", |
24 | | - "os.environ['OPENAI_API_KEY'] = \"\"\n", |
| 23 | + "os.environ[\"ANTHROPIC_API_KEY\"] = \"\"\n", |
| 24 | + "os.environ[\"OPENAI_API_KEY\"] = \"\"\n", |
25 | 25 | "\n", |
26 | 26 | "# turn on langsmith tracing\n", |
27 | | - "os.environ['LANGSMITH_API_KEY'] = \"\"\n", |
28 | | - "os.environ['LANGSMITH_TRACING_V2'] = \"true\"" |
| 27 | + "os.environ[\"LANGSMITH_API_KEY\"] = \"\"\n", |
| 28 | + "os.environ[\"LANGSMITH_TRACING_V2\"] = \"true\"" |
29 | 29 | ] |
30 | 30 | }, |
31 | 31 | { |
|
36 | 36 | "outputs": [], |
37 | 37 | "source": [ |
38 | 38 | "from langchain_openai import ChatOpenAI\n", |
| 39 | + "\n", |
39 | 40 | "model = ChatOpenAI(model=\"gpt-4o\")" |
40 | 41 | ] |
41 | 42 | }, |
|
67 | 68 | "# Mock data for tools\n", |
68 | 69 | "RESERVATIONS = defaultdict(lambda: {\"flight_info\": {}, \"hotel_info\": {}})\n", |
69 | 70 | "TOMORROW = (datetime.date.today() + datetime.timedelta(days=1)).isoformat()\n", |
70 | | - "FLIGHTS = [{\"departure_airport\": \"BOS\", \"arrival_airport\": \"JFK\", \"airline\": \"Jet Blue\", \"date\": TOMORROW, \"id\": \"1\"}]\n", |
71 | | - "HOTELS = [{\"location\": \"New York\", \"name\": \"McKittrick Hotel\", \"neighborhood\": \"Chelsea\", \"id\": \"1\"}]\n", |
| 71 | + "FLIGHTS = [\n", |
| 72 | + " {\n", |
| 73 | + " \"departure_airport\": \"BOS\",\n", |
| 74 | + " \"arrival_airport\": \"JFK\",\n", |
| 75 | + " \"airline\": \"Jet Blue\",\n", |
| 76 | + " \"date\": TOMORROW,\n", |
| 77 | + " \"id\": \"1\",\n", |
| 78 | + " }\n", |
| 79 | + "]\n", |
| 80 | + "HOTELS = [\n", |
| 81 | + " {\n", |
| 82 | + " \"location\": \"New York\",\n", |
| 83 | + " \"name\": \"McKittrick Hotel\",\n", |
| 84 | + " \"neighborhood\": \"Chelsea\",\n", |
| 85 | + " \"id\": \"1\",\n", |
| 86 | + " }\n", |
| 87 | + "]\n", |
| 88 | + "\n", |
72 | 89 | "\n", |
73 | 90 | "# Flight tools\n", |
74 | 91 | "def search_flights(\n", |
|
86 | 103 | " # return all flights for simplicity\n", |
87 | 104 | " return FLIGHTS\n", |
88 | 105 | "\n", |
| 106 | + "\n", |
89 | 107 | "def book_flight(\n", |
90 | 108 | " flight_id: str,\n", |
91 | 109 | " config: RunnableConfig,\n", |
|
96 | 114 | " RESERVATIONS[user_id][\"flight_info\"] = flight\n", |
97 | 115 | " return \"Successfully booked flight\"\n", |
98 | 116 | "\n", |
| 117 | + "\n", |
99 | 118 | "# Hotel tools\n", |
100 | | - "def search_hotels(\n", |
101 | | - " location: str\n", |
102 | | - ") -> list[dict]:\n", |
| 119 | + "def search_hotels(location: str) -> list[dict]:\n", |
103 | 120 | " \"\"\"Search hotels.\n", |
104 | 121 | "\n", |
105 | 122 | " Args:\n", |
|
108 | 125 | " # return all hotels for simplicity\n", |
109 | 126 | " return HOTELS\n", |
110 | 127 | "\n", |
| 128 | + "\n", |
111 | 129 | "def book_hotel(\n", |
112 | 130 | " hotel_id: str,\n", |
113 | 131 | " config: RunnableConfig,\n", |
|
118 | 136 | " RESERVATIONS[user_id][\"hotel_info\"] = hotel\n", |
119 | 137 | " return \"Successfully booked hotel\"\n", |
120 | 138 | "\n", |
| 139 | + "\n", |
121 | 140 | "# Handoff tools\n", |
122 | 141 | "transfer_to_hotel_assistant = create_handoff_tool(\n", |
123 | 142 | " agent_name=\"hotel_assistant\",\n", |
124 | | - " description=\"Transfer user to the hotel-booking assistant that can search for and book hotels.\"\n", |
| 143 | + " description=\"Transfer user to the hotel-booking assistant that can search for and book hotels.\",\n", |
125 | 144 | ")\n", |
126 | 145 | "transfer_to_flight_assistant = create_handoff_tool(\n", |
127 | 146 | " agent_name=\"flight_assistant\",\n", |
128 | | - " description=\"Transfer user to the flight-booking assistant that can search for and book flights.\"\n", |
| 147 | + " description=\"Transfer user to the flight-booking assistant that can search for and book flights.\",\n", |
129 | 148 | ")\n", |
130 | 149 | "\n", |
| 150 | + "\n", |
131 | 151 | "# Define agent prompt\n", |
132 | 152 | "def make_prompt(base_system_prompt: str) -> Callable[[dict, RunnableConfig], list]:\n", |
133 | 153 | " def prompt(state: dict, config: RunnableConfig) -> list:\n", |
|
142 | 162 | "\n", |
143 | 163 | " return prompt\n", |
144 | 164 | "\n", |
| 165 | + "\n", |
145 | 166 | "# Define agents\n", |
146 | 167 | "flight_assistant = create_react_agent(\n", |
147 | 168 | " model,\n", |
148 | 169 | " [search_flights, book_flight, transfer_to_hotel_assistant],\n", |
149 | 170 | " prompt=make_prompt(\"You are a flight booking assistant\"),\n", |
150 | | - " name=\"flight_assistant\"\n", |
| 171 | + " name=\"flight_assistant\",\n", |
151 | 172 | ")\n", |
152 | 173 | "\n", |
153 | 174 | "hotel_assistant = create_react_agent(\n", |
154 | 175 | " model,\n", |
155 | 176 | " [search_hotels, book_hotel, transfer_to_flight_assistant],\n", |
156 | 177 | " prompt=make_prompt(\"You are a hotel booking assistant\"),\n", |
157 | | - " name=\"hotel_assistant\"\n", |
| 178 | + " name=\"hotel_assistant\",\n", |
158 | 179 | ")\n", |
159 | 180 | "\n", |
160 | 181 | "# Compile and run!\n", |
161 | 182 | "checkpointer = MemorySaver()\n", |
162 | 183 | "builder = create_swarm(\n", |
163 | | - " [flight_assistant, hotel_assistant],\n", |
164 | | - " default_active_agent=\"flight_assistant\"\n", |
| 184 | + " [flight_assistant, hotel_assistant], default_active_agent=\"flight_assistant\"\n", |
165 | 185 | ")\n", |
166 | 186 | "\n", |
167 | 187 | "# Important: compile the swarm with a checkpointer to remember\n", |
|
208 | 228 | "outputs": [], |
209 | 229 | "source": [ |
210 | 230 | "import uuid\n", |
| 231 | + "\n", |
211 | 232 | "config = {\"configurable\": {\"thread_id\": str(uuid.uuid4()), \"user_id\": \"1\"}}" |
212 | 233 | ] |
213 | 234 | }, |
|
237 | 258 | " if isinstance(node_updates, tuple):\n", |
238 | 259 | " print(node_updates)\n", |
239 | 260 | " continue\n", |
240 | | - " messages_key = next((k for k in node_updates.keys() if \"messages\" in k), None)\n", |
| 261 | + " messages_key = next(\n", |
| 262 | + " (k for k in node_updates.keys() if \"messages\" in k), None\n", |
| 263 | + " )\n", |
241 | 264 | " if messages_key is not None:\n", |
242 | 265 | " node_updates[messages_key][-1].pretty_print()\n", |
243 | 266 | " else:\n", |
|
314 | 337 | } |
315 | 338 | ], |
316 | 339 | "source": [ |
317 | | - "print_stream(app.stream(\n", |
318 | | - " {\"messages\": [{\"role\": \"user\", \"content\": \"i am looking for a flight from boston to ny tomorrow\"}]},\n", |
319 | | - " config,\n", |
320 | | - " subgraphs=True\n", |
321 | | - "))" |
| 340 | + "print_stream(\n", |
| 341 | + " app.stream(\n", |
| 342 | + " {\n", |
| 343 | + " \"messages\": [\n", |
| 344 | + " {\n", |
| 345 | + " \"role\": \"user\",\n", |
| 346 | + " \"content\": \"i am looking for a flight from boston to ny tomorrow\",\n", |
| 347 | + " }\n", |
| 348 | + " ]\n", |
| 349 | + " },\n", |
| 350 | + " config,\n", |
| 351 | + " subgraphs=True,\n", |
| 352 | + " )\n", |
| 353 | + ")" |
322 | 354 | ] |
323 | 355 | }, |
324 | 356 | { |
|
377 | 409 | } |
378 | 410 | ], |
379 | 411 | "source": [ |
380 | | - "print_stream(app.stream(\n", |
381 | | - " {\"messages\": [{\"role\": \"user\", \"content\": \"yes please\"}]},\n", |
382 | | - " config,\n", |
383 | | - " subgraphs=True\n", |
384 | | - "))" |
| 412 | + "print_stream(\n", |
| 413 | + " app.stream(\n", |
| 414 | + " {\"messages\": [{\"role\": \"user\", \"content\": \"yes please\"}]},\n", |
| 415 | + " config,\n", |
| 416 | + " subgraphs=True,\n", |
| 417 | + " )\n", |
| 418 | + ")" |
385 | 419 | ] |
386 | 420 | }, |
387 | 421 | { |
|
479 | 513 | } |
480 | 514 | ], |
481 | 515 | "source": [ |
482 | | - "print_stream(app.stream(\n", |
483 | | - " {\"messages\": [{\"role\": \"user\", \"content\": \"now i'd like to book a hotel as well\"}]},\n", |
484 | | - " config,\n", |
485 | | - " subgraphs=True\n", |
486 | | - "))" |
| 516 | + "print_stream(\n", |
| 517 | + " app.stream(\n", |
| 518 | + " {\n", |
| 519 | + " \"messages\": [\n", |
| 520 | + " {\"role\": \"user\", \"content\": \"now i'd like to book a hotel as well\"}\n", |
| 521 | + " ]\n", |
| 522 | + " },\n", |
| 523 | + " config,\n", |
| 524 | + " subgraphs=True,\n", |
| 525 | + " )\n", |
| 526 | + ")" |
487 | 527 | ] |
488 | 528 | }, |
489 | 529 | { |
|
542 | 582 | } |
543 | 583 | ], |
544 | 584 | "source": [ |
545 | | - "print_stream(app.stream(\n", |
546 | | - " {\"messages\": [{\"role\": \"user\", \"content\": \"yes please\"}]},\n", |
547 | | - " config,\n", |
548 | | - " subgraphs=True\n", |
549 | | - "))" |
| 585 | + "print_stream(\n", |
| 586 | + " app.stream(\n", |
| 587 | + " {\"messages\": [{\"role\": \"user\", \"content\": \"yes please\"}]},\n", |
| 588 | + " config,\n", |
| 589 | + " subgraphs=True,\n", |
| 590 | + " )\n", |
| 591 | + ")" |
550 | 592 | ] |
551 | 593 | }, |
552 | 594 | { |
|
613 | 655 | } |
614 | 656 | ], |
615 | 657 | "source": [ |
616 | | - "print_stream(app.stream(\n", |
617 | | - " {\"messages\": [{\"role\": \"user\", \"content\": \"i wanna talk to flight assistant now\"}]},\n", |
618 | | - " config,\n", |
619 | | - " subgraphs=True\n", |
620 | | - "))" |
| 658 | + "print_stream(\n", |
| 659 | + " app.stream(\n", |
| 660 | + " {\n", |
| 661 | + " \"messages\": [\n", |
| 662 | + " {\"role\": \"user\", \"content\": \"i wanna talk to flight assistant now\"}\n", |
| 663 | + " ]\n", |
| 664 | + " },\n", |
| 665 | + " config,\n", |
| 666 | + " subgraphs=True,\n", |
| 667 | + " )\n", |
| 668 | + ")" |
621 | 669 | ] |
622 | 670 | }, |
623 | 671 | { |
|
0 commit comments