| 1417 | return True |
| 1418 | |
| 1419 | def send_message(self, inp): |
| 1420 | self.event("message_send_starting") |
| 1421 | |
| 1422 | # Notify IO that LLM processing is starting |
| 1423 | self.io.llm_started() |
| 1424 | |
| 1425 | self.cur_messages += [ |
| 1426 | dict(role="user", content=inp), |
| 1427 | ] |
| 1428 | |
| 1429 | chunks = self.format_messages() |
| 1430 | messages = chunks.all_messages() |
| 1431 | if not self.check_tokens(messages): |
| 1432 | return |
| 1433 | self.warm_cache(chunks) |
| 1434 | |
| 1435 | if self.verbose: |
| 1436 | utils.show_messages(messages, functions=self.functions) |
| 1437 | |
| 1438 | self.multi_response_content = "" |
| 1439 | if self.show_pretty(): |
| 1440 | self.waiting_spinner = WaitingSpinner("Waiting for " + self.main_model.name) |
| 1441 | self.waiting_spinner.start() |
| 1442 | if self.stream: |
| 1443 | self.mdstream = self.io.get_assistant_mdstream() |
| 1444 | else: |
| 1445 | self.mdstream = None |
| 1446 | else: |
| 1447 | self.mdstream = None |
| 1448 | |
| 1449 | retry_delay = 0.125 |
| 1450 | |
| 1451 | litellm_ex = LiteLLMExceptions() |
| 1452 | |
| 1453 | self.usage_report = None |
| 1454 | exhausted = False |
| 1455 | interrupted = False |
| 1456 | try: |
| 1457 | while True: |
| 1458 | try: |
| 1459 | yield from self.send(messages, functions=self.functions) |
| 1460 | break |
| 1461 | except litellm_ex.exceptions_tuple() as err: |
| 1462 | ex_info = litellm_ex.get_ex_info(err) |
| 1463 | |
| 1464 | if ex_info.name == "ContextWindowExceededError": |
| 1465 | exhausted = True |
| 1466 | break |
| 1467 | |
| 1468 | should_retry = ex_info.retry |
| 1469 | if should_retry: |
| 1470 | retry_delay *= 2 |
| 1471 | if retry_delay > RETRY_TIMEOUT: |
| 1472 | should_retry = False |
| 1473 | |
| 1474 | if not should_retry: |
| 1475 | self.mdstream = None |
| 1476 | self.check_and_open_urls(err, ex_info.description) |