Kgshop commited on
Commit
27c2995
·
verified ·
1 Parent(s): 82f9da9

Create agent.py

Browse files
Files changed (1) hide show
  1. agent.py +190 -0
agent.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import base64
4
+ import json
5
+ import logging
6
+ import threading
7
+ import time
8
+ import subprocess
9
+ import tkinter as tk
10
+ from tkinter import scrolledtext, simpledialog
11
+ from datetime import datetime, timedelta, timezone
12
+ from uuid import uuid4
13
+ import random
14
+ import string
15
+ from PIL import Image
16
+ import google.generativeai as genai
17
+ from dotenv import load_dotenv
18
+
19
+ load_dotenv()
20
+
21
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
22
+
23
+ if not GOOGLE_API_KEY:
24
+ raise ValueError("GOOGLE_API_KEY environment variable not set.")
25
+
26
+ genai.configure(api_key=GOOGLE_API_KEY)
27
+
28
+ def list_directory(directory_path="."):
29
+ try:
30
+ if not os.path.isdir(directory_path):
31
+ return f"Error: Directory '{directory_path}' not found."
32
+ files = os.listdir(directory_path)
33
+ if not files:
34
+ return f"The directory '{directory_path}' is empty."
35
+ return f"Contents of '{directory_path}':\n" + "\n".join(files)
36
+ except Exception as e:
37
+ return f"Error listing directory '{directory_path}': {e}"
38
+
39
+ def read_file_content(file_path):
40
+ try:
41
+ with open(file_path, 'r', encoding='utf-8') as f:
42
+ content = f.read()
43
+ return f"Content of '{file_path}':\n{content}"
44
+ except FileNotFoundError:
45
+ return f"Error: File '{file_path}' not found."
46
+ except Exception as e:
47
+ return f"Error reading file '{file_path}': {e}"
48
+
49
+ def write_to_file(file_path, content):
50
+ try:
51
+ directory = os.path.dirname(file_path)
52
+ if directory:
53
+ os.makedirs(directory, exist_ok=True)
54
+ with open(file_path, 'w', encoding='utf-8') as f:
55
+ f.write(content)
56
+ return f"Successfully wrote content to '{file_path}'."
57
+ except Exception as e:
58
+ return f"Error writing to file '{file_path}': {e}"
59
+
60
+ def delete_file_or_directory(path):
61
+ try:
62
+ if os.path.isfile(path):
63
+ os.remove(path)
64
+ return f"Successfully deleted file: '{path}'."
65
+ elif os.path.isdir(path):
66
+ os.rmdir(path)
67
+ return f"Successfully deleted empty directory: '{path}'. Note: This function only deletes empty directories."
68
+ else:
69
+ return f"Error: Path '{path}' not found."
70
+ except Exception as e:
71
+ return f"Error deleting '{path}': {e}"
72
+
73
+ def search_web(query):
74
+ return f"Simulating a web search for: '{query}'. In a real application, this would return live search results. Based on general knowledge, here is some information..."
75
+
76
+ def execute_shell_command(command):
77
+ allowed_commands = ['ls', 'dir', 'echo', 'pwd', 'cd']
78
+ try:
79
+ command_base = command.split()[0]
80
+ if command_base not in allowed_commands:
81
+ return f"Error: Command '{command_base}' is not allowed for security reasons. Allowed commands are: {', '.join(allowed_commands)}."
82
+
83
+ result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=10)
84
+
85
+ output = result.stdout or result.stderr
86
+ if result.returncode != 0:
87
+ return f"Command '{command}' failed with return code {result.returncode}:\n{output}"
88
+ return f"Output of command '{command}':\n{output}"
89
+ except subprocess.TimeoutExpired:
90
+ return f"Error: Command '{command}' timed out."
91
+ except Exception as e:
92
+ return f"Error executing command '{command}': {e}"
93
+
94
+ class DesktopAgentApp:
95
+ def __init__(self, root):
96
+ self.root = root
97
+ self.root.title("Desktop AI Agent")
98
+ self.root.geometry("800x600")
99
+
100
+ self.chat_history_display = scrolledtext.ScrolledText(root, state='disabled', wrap=tk.WORD, font=("Helvetica", 12))
101
+ self.chat_history_display.pack(padx=10, pady=10, expand=True, fill='both')
102
+
103
+ input_frame = tk.Frame(root)
104
+ input_frame.pack(padx=10, pady=10, fill='x')
105
+
106
+ self.user_input_field = tk.Entry(input_frame, font=("Helvetica", 12))
107
+ self.user_input_field.pack(side='left', expand=True, fill='x', ipady=5)
108
+ self.user_input_field.bind("<Return>", self.send_message)
109
+
110
+ self.send_button = tk.Button(input_frame, text="Send", command=self.send_message, font=("Helvetica", 11, "bold"))
111
+ self.send_button.pack(side='right', padx=(5, 0))
112
+
113
+ self.model = genai.GenerativeModel(
114
+ model_name='gemma-3-27b-it',
115
+ tools=[
116
+ list_directory,
117
+ read_file_content,
118
+ write_to_file,
119
+ delete_file_or_directory,
120
+ search_web,
121
+ execute_shell_command
122
+ ]
123
+ )
124
+ self.chat = self.model.start_chat(enable_automatic_function_calling=True)
125
+ self.add_message_to_chat("System", "AI Agent initialized. How can I help you today?")
126
+
127
+ def add_message_to_chat(self, sender, message, tag_suffix=""):
128
+ self.chat_history_display.config(state='normal')
129
+
130
+ sender_tag = f"sender_{sender.lower()}{tag_suffix}"
131
+ if sender.lower() == "user":
132
+ self.chat_history_display.tag_configure(sender_tag, foreground="blue", font=("Helvetica", 12, "bold"))
133
+ elif sender.lower() == "agent":
134
+ self.chat_history_display.tag_configure(sender_tag, foreground="black", font=("Helvetica", 12, "bold"))
135
+ elif sender.lower() == "tool":
136
+ self.chat_history_display.tag_configure(sender_tag, foreground="#663300", font=("Helvetica", 10, "italic"))
137
+ else:
138
+ self.chat_history_display.tag_configure(sender_tag, foreground="gray", font=("Helvetica", 10))
139
+
140
+ self.chat_history_display.insert(tk.END, f"{sender}: ", sender_tag)
141
+ self.chat_history_display.insert(tk.END, f"{message}\n\n")
142
+ self.chat_history_display.config(state='disabled')
143
+ self.chat_history_display.yview(tk.END)
144
+
145
+ def send_message(self, event=None):
146
+ user_text = self.user_input_field.get().strip()
147
+ if not user_text:
148
+ return
149
+
150
+ self.add_message_to_chat("User", user_text)
151
+ self.user_input_field.delete(0, tk.END)
152
+
153
+ self.user_input_field.config(state='disabled')
154
+ self.send_button.config(state='disabled')
155
+
156
+ threading.Thread(target=self.get_agent_response, args=(user_text,)).start()
157
+
158
+ def get_agent_response(self, user_text):
159
+ try:
160
+ response = self.chat.send_message(user_text)
161
+
162
+ for part in response:
163
+ if part.function_call:
164
+ function_name = part.function_call.name
165
+ args = ', '.join([f'{k}={v}' for k, v in part.function_call.args.items()])
166
+ self.root.after(0, self.add_message_to_chat, "Tool", f"Executing: {function_name}({args})", "call")
167
+
168
+ if part.function_response:
169
+ function_name = part.function_response.name
170
+ output = part.function_response.response
171
+ self.root.after(0, self.add_message_to_chat, "Tool", f"Result from {function_name}:\n{output}", "response")
172
+
173
+ final_response = response.text
174
+ self.root.after(0, self.add_message_to_chat, "Agent", final_response)
175
+
176
+ except Exception as e:
177
+ error_message = f"An error occurred: {str(e)}"
178
+ self.root.after(0, self.add_message_to_chat, "System", error_message)
179
+ finally:
180
+ self.root.after(0, self.enable_input)
181
+
182
+ def enable_input(self):
183
+ self.user_input_field.config(state='normal')
184
+ self.send_button.config(state='normal')
185
+ self.user_input_field.focus_set()
186
+
187
+ if __name__ == "__main__":
188
+ root = tk.Tk()
189
+ app = DesktopAgentApp(root)
190
+ root.mainloop()