Testing with qwen and updating tools

This commit is contained in:
2025-06-01 11:50:12 -05:00
parent 4c4f9b7f2c
commit 7844f26d59
6 changed files with 418 additions and 311 deletions
+6 -3
View File
@@ -11,7 +11,8 @@ class BaseTelegramInferenceBot(ABC):
self.processing_status = {} self.processing_status = {}
self.system_prompt = self.load_system_prompt() self.system_prompt = self.load_system_prompt()
self.tools, self.functions = self.load_functions() self.tools, self.functions = self.load_functions()
print(f'Github Token: {os.environ.get("GITHUB_TOKEN")}') print(f'System Prompt: {os.environ.get("SYSTEM_PROMPT_PATH")}')
print(f'Github Repository: {os.environ.get("GITHUB_REPOSITORY")}')
@staticmethod @staticmethod
def load_system_prompt(): def load_system_prompt():
@@ -59,8 +60,10 @@ class BaseTelegramInferenceBot(ABC):
function_name = function_call_name function_name = function_call_name
function_args = json.loads(function_call_arguments if function_call_arguments is not None else "{}") function_args = json.loads(function_call_arguments if function_call_arguments is not None else "{}")
for tool in self.tools: for tool in self.tools:
if function_name in [f["name"] for f in tool.get_functions()]: for function in tool.get_functions():
return tool.execute(function_name, **function_args) if function["function"]["name"] == function_name:
return tool.execute(function_name, **function_args)
@abstractmethod @abstractmethod
async def start(self): async def start(self):
+18 -14
View File
@@ -8,16 +8,16 @@ from openai import OpenAI
class ChatGPTTelegramInferenceBot(BaseTelegramInferenceBot): class ChatGPTTelegramInferenceBot(BaseTelegramInferenceBot):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) self.client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"), base_url="http://localhost:1234/v1")
self.model = "gpt-4o-mini" self.model = "qwen3-1.7b"
self.max_tokens = 16384 self.max_tokens = 32768
def get_chat_response(self, messages): def get_chat_response(self, messages):
response = self.client.chat.completions.create( response = self.client.chat.completions.create(
model=self.model, model=self.model,
messages=[{"role": "system", "content": self.system_prompt}] + messages, messages=[{"role": "system", "content": self.system_prompt}] + messages,
functions=self.functions, tools=self.functions,
function_call="auto", tool_choice = "auto",
max_tokens=self.max_tokens max_tokens=self.max_tokens
) )
return response return response
@@ -34,8 +34,8 @@ class ChatGPTTelegramInferenceBot(BaseTelegramInferenceBot):
tool_calls = [] tool_calls = []
for message_part in response.choices: for message_part in response.choices:
if message_part.finish_reason == "function_call": if message_part.finish_reason == "tool_calls":
tool_calls.append(message_part.message.function_call) tool_calls.extend(message_part.message.tool_calls)
messages.append(response.choices[0].message) messages.append(response.choices[0].message)
@@ -44,9 +44,13 @@ class ChatGPTTelegramInferenceBot(BaseTelegramInferenceBot):
tool_use_results = [] tool_use_results = []
while len(tool_calls) > 0: while len(tool_calls) > 0:
tool_call = tool_calls.pop(0) tool_call = tool_calls.pop(0).function
tool_response = self.call_tool(tool_call.name, tool_call.arguments) tool_response = self.call_tool(tool_call.name, tool_call.arguments)
tool_use_results.append({"role": "function", "name": tool_call.name, "content": json.dumps(tool_response)}) try:
tool_use_results.append({"role": "tool", "name": tool_call.name, "content": tool_response})
except (TypeError, ValueError) as e:
logging.error(f"Failed to serialize tool response: {e}")
tool_use_results.append({"role": "function", "name": tool_call.name, "content": "Serialization error"})
messages.extend(tool_use_results) messages.extend(tool_use_results)
@@ -84,12 +88,12 @@ class ChatGPTTelegramInferenceBot(BaseTelegramInferenceBot):
return "No active processing to abort." return "No active processing to abort."
async def switch_model(self): async def switch_model(self):
if self.model == "gpt-4o-mini": if self.model == "qwen3-4b":
self.model = "gpt-4o" self.model = "qwen3-30b-a3b"
self.max_tokens = 4096 # self.max_tokens = 4096
else: else:
self.model = "gpt-4o-mini" self.model = "qwen3-4b"
self.max_tokens = 16384 # self.max_tokens = 16384
logging.info(f"Switched to model: {self.model}") logging.info(f"Switched to model: {self.model}")
return f"Switched to model: {self.model}" return f"Switched to model: {self.model}"
+3 -1
View File
@@ -63,7 +63,9 @@ class TelegramHelper:
await context.bot.delete_message(chat_id=update.effective_chat.id, message_id=status_message.message_id) await context.bot.delete_message(chat_id=update.effective_chat.id, message_id=status_message.message_id)
del self.bot.processing_status[user_id] del self.bot.processing_status[user_id]
await update.message.reply_text(response) response = response.replace("<think>", "<blockquote expandable><b>Thinking...</b>").replace("</think>", "</blockquote>")
# Return response as html message
await update.message.reply_html(response)
except Exception as e: except Exception as e:
logging.error(f"An error occurred: {str(e)}") logging.error(f"An error occurred: {str(e)}")
+354 -269
View File
@@ -46,54 +46,65 @@ class GitHubTool(BaseTool):
def get_functions(self): def get_functions(self):
return [ return [
{ {
"name": "read_file", "type": "function",
"description": "Read a file from the repository", "function": {
"parameters": { "name": "read_file",
"type": "object", "description": "Read a file from the repository",
"properties": { "parameters": {
"type": "object",
"properties": {
"path": { "path": {
"type": "string", "type": "string",
"description": "Path to the file in the repository" "description": "Path to the file in the repository"
} }
}, },
"required": ["path"] "required": ["path"]
} }
}, }
{ },
"name": "list_files", {
"description": "List files in a directory of the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "list_files",
"properties": { "description": "List files in a directory of the repository",
"parameters": {
"type": "object",
"properties": {
"path": { "path": {
"type": "string", "type": "string",
"description": "Path to the directory in the repository" "description": "Path to the directory in the repository"
} }
}, },
"required": ["path"] "required": ["path"]
} }
}, }
{ },
"name": "search_code", {
"description": "Search for code in the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "search_code",
"properties": { "description": "Search for code in the repository",
"parameters": {
"type": "object",
"properties": {
"query": { "query": {
"type": "string", "type": "string",
"description": "Search query" "description": "Search query"
} }
}, },
"required": ["query"] "required": ["query"]
} }
}, }
{ },
"name": "create_branch", {
"description": "Create a new branch in the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_branch",
"properties": { "description": "Create a new branch in the repository",
"parameters": {
"type": "object",
"properties": {
"branch_name": { "branch_name": {
"type": "string", "type": "string",
"description": "Name of the new branch" "description": "Name of the new branch"
@@ -103,16 +114,19 @@ class GitHubTool(BaseTool):
"description": "Name of the base branch", "description": "Name of the base branch",
"default": "main" "default": "main"
} }
}, },
"required": ["branch_name"] "required": ["branch_name"]
} }
}, }
{ },
"name": "commit_file", {
"description": "Commit a file to a branch (not main)", "type": "function",
"parameters": { "function": {
"type": "object", "name": "commit_file",
"properties": { "description": "Commit a file to a branch (not main)",
"parameters": {
"type": "object",
"properties": {
"file_path": { "file_path": {
"type": "string", "type": "string",
"description": "Path to the file in the repository" "description": "Path to the file in the repository"
@@ -125,16 +139,19 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "Content of the file" "description": "Content of the file"
} }
}, },
"required": ["file_path", "commit_message", "content"] "required": ["file_path", "commit_message", "content"]
} }
}, }
{ },
"name": "create_pull_request", {
"description": "Create a pull request", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_pull_request",
"properties": { "description": "Create a pull request",
"parameters": {
"type": "object",
"properties": {
"title": { "title": {
"type": "string", "type": "string",
"description": "Title of the pull request" "description": "Title of the pull request"
@@ -148,16 +165,19 @@ class GitHubTool(BaseTool):
"description": "The name of the branch you want the changes pulled into", "description": "The name of the branch you want the changes pulled into",
"default": "main" "default": "main"
} }
}, },
"required": ["title", "body"] "required": ["title", "body"]
} }
}, }
{ },
"name": "get_commit_history", {
"description": "Get commit history for a file", "type": "function",
"parameters": { "function": {
"type": "object", "name": "get_commit_history",
"properties": { "description": "Get commit history for a file",
"parameters": {
"type": "object",
"properties": {
"file_path": { "file_path": {
"type": "string", "type": "string",
"description": "Path to the file in the repository" "description": "Path to the file in the repository"
@@ -167,49 +187,61 @@ class GitHubTool(BaseTool):
"description": "Number of commits to retrieve", "description": "Number of commits to retrieve",
"default": 10 "default": 10
} }
}, },
"required": ["file_path"] "required": ["file_path"]
} }
}, }
{ },
"name": "get_branch_sha", {
"description": "Get the SHA of the latest commit on a branch", "type": "function",
"parameters": { "function": {
"type": "object", "name": "get_branch_sha",
"properties": { "description": "Get the SHA of the latest commit on a branch",
"parameters": {
"type": "object",
"properties": {
"branch": { "branch": {
"type": "string", "type": "string",
"description": "Name of the branch" "description": "Name of the branch"
} }
}, },
"required": ["branch"] "required": ["branch"]
} }
}, }
{ },
"name": "get_current_branch", {
"description": "Get the name of the current branch", "type": "function",
"parameters": {} "function": {
}, "name": "get_current_branch",
{ "description": "Get the name of the current branch",
"name": "set_current_branch", "parameters": { "type": "object", "properties": {} }
"description": "Set the current branch", }
"parameters": { },
"type": "object", {
"properties": { "type": "function",
"function": {
"name": "set_current_branch",
"description": "Set the current branch",
"parameters": {
"type": "object",
"properties": {
"branch_name": { "branch_name": {
"type": "string", "type": "string",
"description": "Name of the branch to set as current" "description": "Name of the branch to set as current"
} }
}, },
"required": ["branch_name"] "required": ["branch_name"]
} }
}, }
{ },
"name": "get_file_at_commit", {
"description": "Get the contents of a file at a specific commit", "type": "function",
"parameters": { "function": {
"type": "object", "name": "get_file_at_commit",
"properties": { "description": "Get the contents of a file at a specific commit",
"parameters": {
"type": "object",
"properties": {
"file_path": { "file_path": {
"type": "string", "type": "string",
"description": "Path to the file in the repository" "description": "Path to the file in the repository"
@@ -218,16 +250,19 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "SHA of the commit to retrieve the file from" "description": "SHA of the commit to retrieve the file from"
} }
}, },
"required": ["file_path", "commit_sha"] "required": ["file_path", "commit_sha"]
} }
}, }
{ },
"name": "list_branches", {
"description": "List all branches in the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "list_branches",
"properties": { "description": "List all branches in the repository",
"parameters": {
"type": "object",
"properties": {
"per_page": { "per_page": {
"type": "integer", "type": "integer",
"description": "Number of branches to return per page (max 100)", "description": "Number of branches to return per page (max 100)",
@@ -238,43 +273,52 @@ class GitHubTool(BaseTool):
"description": "Whether to fetch all pages of results", "description": "Whether to fetch all pages of results",
"default": True "default": True
} }
}
} }
} }
}, },
{ {
"name": "approve_pull_request", "type": "function",
"description": "Approve a pull request", "function": {
"parameters": { "name": "approve_pull_request",
"type": "object", "description": "Approve a pull request",
"properties": { "parameters": {
"type": "object",
"properties": {
"pull_number": { "pull_number": {
"type": "integer", "type": "integer",
"description": "The number of the pull request" "description": "The number of the pull request"
} }
}, },
"required": ["pull_number"] "required": ["pull_number"]
} }
}, }
{ },
"name": "close_pull_request", {
"description": "Close a pull request", "type": "function",
"parameters": { "function": {
"type": "object", "name": "close_pull_request",
"properties": { "description": "Close a pull request",
"parameters": {
"type": "object",
"properties": {
"pull_number": { "pull_number": {
"type": "integer", "type": "integer",
"description": "The number of the pull request" "description": "The number of the pull request"
} }
}, },
"required": ["pull_number"] "required": ["pull_number"]
} }
}, }
{ },
"name": "merge_pull_request", {
"description": "Merge a pull request", "type": "function",
"parameters": { "function": {
"type": "object", "name": "merge_pull_request",
"properties": { "description": "Merge a pull request",
"parameters": {
"type": "object",
"properties": {
"pull_number": { "pull_number": {
"type": "integer", "type": "integer",
"description": "The number of the pull request" "description": "The number of the pull request"
@@ -295,44 +339,53 @@ class GitHubTool(BaseTool):
"enum": ["merge", "squash", "rebase"], "enum": ["merge", "squash", "rebase"],
"default": "merge" "default": "merge"
} }
}, },
"required": ["pull_number"] "required": ["pull_number"]
} }
}, }
{ },
"name": "delete_branch", {
"description": "Delete a branch", "type": "function",
"parameters": { "function": {
"type": "object", "name": "delete_branch",
"properties": { "description": "Delete a branch",
"parameters": {
"type": "object",
"properties": {
"branch_name": { "branch_name": {
"type": "string", "type": "string",
"description": "Name of the branch to delete" "description": "Name of the branch to delete"
} }
}, },
"required": ["branch_name"] "required": ["branch_name"]
} }
}, }
{ },
"name": "get_issue_details", {
"description": "Get details of a specific issue", "type": "function",
"parameters": { "function": {
"type": "object", "name": "get_issue_details",
"properties": { "description": "Get details of a specific issue",
"parameters": {
"type": "object",
"properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": "integer",
"description": "The number of the issue" "description": "The number of the issue"
} }
}, },
"required": ["issue_number"] "required": ["issue_number"]
} }
}, }
{ },
"name": "create_issue", {
"description": "Create a new issue in the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_issue",
"properties": { "description": "Create a new issue in the repository",
"parameters": {
"type": "object",
"properties": {
"title": { "title": {
"type": "string", "type": "string",
"description": "Title of the issue" "description": "Title of the issue"
@@ -344,20 +397,23 @@ class GitHubTool(BaseTool):
"labels": { "labels": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
}, },
"description": "Labels to apply to the issue" "description": "Labels to apply to the issue"
} }
}, },
"required": ["title", "body"] "required": ["title", "body"]
} }
}, }
{ },
"name": "list_issues", {
"description": "List issues in the repository", "type": "function",
"parameters": { "function": {
"type": "object", "name": "list_issues",
"properties": { "description": "List issues in the repository",
"parameters": {
"type": "object",
"properties": {
"state": { "state": {
"type": "string", "type": "string",
"enum": ["open", "closed", "all"], "enum": ["open", "closed", "all"],
@@ -374,15 +430,18 @@ class GitHubTool(BaseTool):
"default": 1, "default": 1,
"description": "Page number of the results to fetch" "description": "Page number of the results to fetch"
} }
}
} }
} }
}, },
{ {
"name": "add_issue_comment", "type": "function",
"description": "Add a comment to an issue", "function": {
"parameters": { "name": "add_issue_comment",
"type": "object", "description": "Add a comment to an issue",
"properties": { "parameters": {
"type": "object",
"properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": "integer",
"description": "The number of the issue" "description": "The number of the issue"
@@ -391,30 +450,36 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "The comment to add to the issue" "description": "The comment to add to the issue"
} }
}, },
"required": ["issue_number", "comment"] "required": ["issue_number", "comment"]
} }
}, }
{ },
"name": "get_issue_comments", {
"description": "Get comments for an issue", "type": "function",
"parameters": { "function": {
"type": "object", "name": "get_issue_comments",
"properties": { "description": "Get comments for an issue",
"parameters": {
"type": "object",
"properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": "integer",
"description": "The number of the issue" "description": "The number of the issue"
} }
}, },
"required": ["issue_number"] "required": ["issue_number"]
} }
}, }
{ },
"name": "create_project_board", {
"description": "Create a new project board", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_project_board",
"properties": { "description": "Create a new project board",
"parameters": {
"type": "object",
"properties": {
"name": { "name": {
"type": "string", "type": "string",
"description": "Name of the project board" "description": "Name of the project board"
@@ -423,16 +488,19 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "Body of the project board" "description": "Body of the project board"
} }
}, },
"required": ["name"] "required": ["name"]
} }
}, }
{ },
"name": "create_project_column", {
"description": "Create a new column in a project board", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_project_column",
"properties": { "description": "Create a new column in a project board",
"parameters": {
"type": "object",
"properties": {
"project_id": { "project_id": {
"type": "integer", "type": "integer",
"description": "ID of the project board" "description": "ID of the project board"
@@ -441,16 +509,19 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "Name of the column" "description": "Name of the column"
} }
}, },
"required": ["project_id", "column_name"] "required": ["project_id", "column_name"]
} }
}, }
{ },
"name": "create_project_card", {
"description": "Create a new card in a project column", "type": "function",
"parameters": { "function": {
"type": "object", "name": "create_project_card",
"properties": { "description": "Create a new card in a project column",
"parameters": {
"type": "object",
"properties": {
"column_id": { "column_id": {
"type": "integer", "type": "integer",
"description": "ID of the project column" "description": "ID of the project column"
@@ -459,16 +530,19 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "Note for the project card" "description": "Note for the project card"
} }
}, },
"required": ["column_id", "note"] "required": ["column_id", "note"]
} }
}, }
{ },
"name": "move_project_card", {
"description": "Move a card to a new position", "type": "function",
"parameters": { "function": {
"type": "object", "name": "move_project_card",
"properties": { "description": "Move a card to a new position",
"parameters": {
"type": "object",
"properties": {
"card_id": { "card_id": {
"type": "integer", "type": "integer",
"description": "ID of the project card" "description": "ID of the project card"
@@ -481,16 +555,19 @@ class GitHubTool(BaseTool):
"type": "integer", "type": "integer",
"description": "ID of the target column" "description": "ID of the target column"
} }
}, },
"required": ["card_id", "position", "column_id"] "required": ["card_id", "position", "column_id"]
} }
}, }
{ },
"name": "link_issue_to_project_card", {
"description": "Link an issue or pull request to a project card", "type": "function",
"parameters": { "function": {
"type": "object", "name": "link_issue_to_project_card",
"properties": { "description": "Link an issue or pull request to a project card",
"parameters": {
"type": "object",
"properties": {
"card_id": { "card_id": {
"type": "integer", "type": "integer",
"description": "ID of the project card" "description": "ID of the project card"
@@ -503,29 +580,36 @@ class GitHubTool(BaseTool):
"type": "string", "type": "string",
"description": "Type of the content (Issue or PullRequest)" "description": "Type of the content (Issue or PullRequest)"
} }
}, },
"required": ["card_id", "content_id", "content_type"] "required": ["card_id", "content_id", "content_type"]
} }
}, }
{ },
"name": "list_project_boards", {
"description": "List project boards associated with the repository", "type": "function",
"parameters": {} "function": {
}, "name": "list_project_boards",
{ "description": "List project boards associated with the repository",
"name": "view_project_board_items", "parameters": { "type": "object", "properties": {} }
"description": "View items (columns and cards) in a specific project board", }
"parameters": { },
"type": "object", {
"properties" : { "type": "function",
"function": {
"name": "view_project_board_items",
"description": "View items (columns and cards) in a specific project board",
"parameters": {
"type": "object",
"properties": {
"project_id": { "project_id": {
"type": "integer", "type": "integer",
"description": "ID of the project board" "description": "ID of the project board"
} }
}, },
"required": ["project_id"] "required": ["project_id"]
}
}
} }
}
] ]
@@ -712,10 +796,11 @@ class GitHubTool(BaseTool):
url = f"{self.base_url}/repos/{self.repo}/contents/{path}" url = f"{self.base_url}/repos/{self.repo}/contents/{path}"
response = requests.get(url, headers=self.headers, params={"ref": self.current_branch}) response = requests.get(url, headers=self.headers, params={"ref": self.current_branch})
if response.status_code == 200: if response.status_code == 200:
files = [item["name"] for item in response.json() if item["type"] == "file"] files = [{"type": "file", "name": item["name"]} for item in response.json() if item["type"] == "file"]
directories = [item["name"] for item in response.json() if item["type"] == "dir"] directories = [{"type": "directory", "name": item["name"]} for item in response.json() if item["type"] == "dir"]
self.logger.info(f"Successfully listed files and directories in {path}") self.logger.info(f"Successfully listed files and directories in {path}")
return {"files": files, "directories": directories} files.extend(directories)
return files
else: else:
error_message = f"Error listing files: {response.status_code}" error_message = f"Error listing files: {response.status_code}"
self.logger.error(error_message) self.logger.error(error_message)
+15 -11
View File
@@ -33,19 +33,23 @@ class LogTool(BaseTool):
pass pass
def get_functions(self): def get_functions(self):
return [ return [
{ {
"name": "get_log_contents", "type": "function",
"description": "Get the contents of the log file.", "function": {
"parameters": { "name": "get_log_contents",
"type": "object", "description": "Get the contents of the log file.",
"properties": { "parameters": {
"line_count": { "type": "object",
"type": "integer", "properties": {
"description": "Number of lines from the end of the log file to retrieve" "line_count": {
} "type": "integer",
}, "description": "Number of lines from the end of the log file to retrieve"
"required": [] }
},
"required": []
}
} }
} }
] ]
+22 -13
View File
@@ -13,40 +13,49 @@ class MetricsTool(BaseTool):
def get_functions(self): def get_functions(self):
return [ return [
{ {
"name": "get_function_metrics", "type": "function",
"description": "Get metrics for all measured functions.", "function": {
"parameters": { "name": "get_function_metrics",
"description": "Get metrics for all measured functions.",
"parameters": {
"type": "object", "type": "object",
"properties": {}, "properties": {},
"required": [] "required": []
}
} }
}, },
{ {
"name": "get_specific_function_metrics", "type": "function",
"description": "Get metrics for a specific function.", "function": {
"parameters": { "name": "get_specific_function_metrics",
"description": "Get metrics for a specific function.",
"parameters": {
"type": "object", "type": "object",
"properties": { "properties": {
"function_name": { "function_name": {
"type": "string", "type": "string",
"description": "Name of the function to get metrics for" "description": "Name of the function to get metrics for"
} }
}, },
"required": ["function_name"] "required": ["function_name"]
}
} }
}, },
{ {
"name": "get_top_n_functions", "type": "function",
"description": "Get the top N functions by total execution time.", "function": {
"parameters": { "name": "get_top_n_functions",
"description": "Get the top N functions by total execution time.",
"parameters": {
"type": "object", "type": "object",
"properties": { "properties": {
"n": { "n": {
"type": "integer", "type": "integer",
"description": "Number of top functions to retrieve" "description": "Number of top functions to retrieve"
} }
}, },
"required": ["n"] "required": ["n"]
}
} }
} }
] ]