From 0b28b9a39d6ae029d5e1dafe3a7c73b4fd65388d Mon Sep 17 00:00:00 2001 From: Jonathan Lucas Date: Sun, 18 Aug 2024 10:40:59 -0500 Subject: [PATCH] More fixes for anthropic --- telegram_inference_bot.py | 111 ++++++++++++++++++++++---------------- tools/log_tool.py | 2 +- 2 files changed, 67 insertions(+), 46 deletions(-) diff --git a/telegram_inference_bot.py b/telegram_inference_bot.py index faae2de..cd517ed 100644 --- a/telegram_inference_bot.py +++ b/telegram_inference_bot.py @@ -83,62 +83,78 @@ async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> logging.info(f"Message from user {user_id}: {user_message}") - # Initialize conversation history for new users if user_id not in conversation_history: conversation_history[user_id] = [] - # Add user message to conversation history conversation_history[user_id].append({"role": "user", "content": user_message}) - # Prepare messages for OpenAI API messages = conversation_history[user_id] response = get_chat_response(messages) - - # Extract the assistant's reply - assistant_message = response.choices[0].message - toolUseCount = 0 - if hasattr(assistant_message, 'function_call') and assistant_message.function_call: - while hasattr(assistant_message, 'function_call') and assistant_message.function_call and toolUseCount < 50: # Todo: put amount in env - tool_response = call_tool(assistant_message.function_call) - - conversation_history[user_id].append({"role": "function", "name": assistant_message.function_call.name, "content": json.dumps(tool_response)}) - messages.append({ - "role": "function", - "name": assistant_message.function_call.name, - "content": json.dumps(tool_response) - }) - - # Call API again to get the final response - assistant_message = get_chat_response(messages).choices[0].message - if not hasattr(assistant_message, 'function_call') or not assistant_message.function_call: - assistant_reply = assistant_message.content - conversation_history[user_id].append({"role": "assistant", "content": assistant_reply}) + tool_calls = [] + if use_anthropic: + for message in response.content: + if message.type == "tool_use": + tool_calls.append(message) + assistant_message = "" + else: + assistant_message = message + tool_calls = None else: - assistant_reply = assistant_message.content - # Add assistant's reply to conversation history - conversation_history[user_id].append({"role": "assistant", "content": assistant_reply}) - + assistant_message = response.choices[0].message + if hasattr(assistant_message, 'function_call'): + tool_calls.append(assistant_message.function_call) + toolUseCount = 0 - # Trim conversation history if it gets too long (e.g., keep last 10 messages) - if len(conversation_history[user_id]) > 10: - conversation_history[user_id] = conversation_history[user_id][-10:] + while len(tool_calls) > 0 and toolUseCount < 50: - # Send the reply back to the user - await update.message.reply_text(assistant_reply) + tool_call = tool_calls.pop(0) + function_name = tool_call.name + + tool_response = call_tool(tool_call) + + conversation_history[user_id].append({"role": "function", "name": function_name, "content": json.dumps(tool_response)}) + messages.append({ + "role": "function", + "name": function_name, + "content": json.dumps(tool_response) + }) + + response = get_chat_response(messages) + if use_anthropic: + for message in response.content: + if message.type == "tool_use": + tool_calls.append(message) + assistant_message = "" + else: + assistant_message = message + tool_calls = None + else: + assistant_message = response.choices[0].message + if assistant_message.function_call is not None: + tool_calls.append(assistant_message.function_call) + + toolUseCount += 1 + + assistant_reply = assistant_message + conversation_history[user_id].append({"role": "assistant", "content": assistant_reply}) + + if len(conversation_history[user_id]) > 20: + conversation_history[user_id] = conversation_history[user_id][-20:] + + await update.message.reply_text(assistant_reply.content if not use_anthropic else assistant_reply) except Exception as e: logging.error(f"An error occurred: {str(e)}") await update.message.reply_text("Sorry, an error occurred while processing your request.") def call_tool(function_call): - # Execute the function - function_name = function_call.name - function_args = function_call.arguments + function_name = function_call.name if use_anthropic else function_call.name + function_args = "{}" if use_anthropic else function_call.arguments for tool in tools: if function_name in [f["name"] for f in tool.get_functions()]: - return tool.execute(function_name, **eval(function_args)) + return tool.execute(function_name, **json.loads(function_args)) def get_chat_response(messages): return get_claude_response(messages) if use_anthropic else get_openai_response(messages) @@ -163,13 +179,18 @@ def get_claude_response(messages): } for function in functions ] - response = anthropic_client.messages.create( - system=system_prompt, - messages=messages, - tools=anthropic_tools, - max_tokens=4096, - model="claude-3-5-sonnet-20240620" - ) + try: + response = anthropic_client.messages.create( + model="claude-3-sonnet-20240229", + system=system_prompt, + messages=[{"role": m["role"], "content": m["content"]} for m in messages], + max_tokens=4096, + tools=anthropic_tools + ) + except Exception as e: + logging.error(f"An error occurred: {str(e)}") + return None + return response async def switch(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: @@ -179,7 +200,7 @@ async def switch(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: logging.info(f"Switched to model: {model}") await update.message.reply_text(f"Switched to model: {model}") -async def switch_anthropic(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: +async def switch_providers(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: global use_anthropic use_anthropic = not use_anthropic logging.info("Using Anthropic" if use_anthropic else "Using OpenAI") @@ -200,7 +221,7 @@ def main() -> None: application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("clear", clear)) application.add_handler(CommandHandler("switch", switch)) - application.add_handler(CommandHandler("toggle", switch_anthropic)) + application.add_handler(CommandHandler("toggle", switch_providers)) application.add_handler(CommandHandler("status", status)) application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) diff --git a/tools/log_tool.py b/tools/log_tool.py index f4dc203..9e579e3 100644 --- a/tools/log_tool.py +++ b/tools/log_tool.py @@ -59,7 +59,7 @@ class LogTool(BaseTool): self.logger.error(error_message) return error_message - def _get_log_contents(self, line_count=None): + def _get_log_contents(self, line_count=150): log_file_path = 'logs/output.log' if not os.path.exists(log_file_path):