USER
Entwickel einen autonomen Devin AI Self pair Programmer mit Pythonista 3 auf dem iPhone13 mit dem Import Requests und ui und der geminiapi über http Request import requests
class GeminiAPI:
def __init__(self, api_key):
self.url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent'
self.headers = {
'Content-Type': 'application/json',
'x-goog-api-key': api_key
}
def call_gemini_api(self, prompt):
payload = {'contents': [{'parts': [{'text': prompt}]}]}
response = requests.post(self.url, headers=self.headers, json=payload)
return response.json()
def generate_code(self, task_description):
prompt = f"Generiere Python-Code für folgende Aufgabe: {task_description}"
response = self.call_gemini_api(prompt)
return response['candidates'][0]['content']['parts'][0]['text']
# Beispielverwendung
api_key = 'AIzaSyDUaG1ti_VHM89oPD7hLmeWzb-nmcP8gmI'
assistant = GeminiAPI(api_key)
# Generiere Python-Code für eine Aufgabe
print(assistant.generate_code("Erstelle eine Funktion zur Berechnung der Fibonacci-Folge"))
Nimm dabei diese Ausschnitte als startpunkt für den Agenten der autonom und selbstständig komplexe Projekte wie die Entwicklung von Programmen, Apps usw mit Recherche und Informations suche im Internet zu planen und
- run Code
- Test Code
- Agenten starten
-
- Sidebar ca 1/5 des Bildes mit Button zum verstecken und anzeigen
- Agenten und Ziel einstellen und konfigurieren / autonomen Modus
- Aufgaben
- Chat
- Dateien
- Suchen
- Debuggen
- Einstellungen / Konfiguration und Zielsetzung
- Hauptbereich
- Code-Editor (heller Hintergrund)
- Terminal (unterhalb, dunkler Hintergrund)
- Chat (schwebend oder anpassbar)
- Browser-Vorschau Web-View (rechts)
import requests
import json
import os
class GeminiCodeAssistant:
def __init__(self, api_key):
self.api_key = api_key
self.url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent'
self.headers = {
'Content-Type': 'application/json',
'x-goog-api-key': self.api_key
}
self.context = []
def call_gemini_api(self, prompt):
payload = {
'contents': [{'parts': [{'text': prompt}]}]
}
response = requests.post(self.url, headers=self.headers, json=payload)
return response.json()
def extract_response(self, api_response):
if 'candidates' in api_response and api_response['candidates']:
first_candidate = api_response['candidates'][0]
if 'content' in first_candidate and 'parts' in first_candidate['content']:
return first_candidate['content']['parts'][0]['text']
return None
def generate_code(self, task_description):
prompt = f"Generiere Python-Code für folgende Aufgabe: {task_description}"
response = self.call_gemini_api(prompt)
code = self.extract_response(response)
self.context.append(("task", task_description))
self.context.append(("code", code))
return code
def improve_code(self, code):
prompt = f"Verbessere den folgenden Python-Code:\n\n{code}\n\nVerbesserter Code:"
response = self.call_gemini_api(prompt)
improved_code = self.extract_response(response)
self.context.append(("improvement", improved_code))
return improved_code
def analyze_code(self, code):
prompt = f"Analysiere den folgenden Python-Code und gib Verbesserungsvorschläge:\n\n{code}"
response = self.call_gemini_api(prompt)
analysis = self.extract_response(response)
self.context.append(("analysis", analysis))
return analysis
def execute_code(self, code):
try:
exec(code)
return "Code erfolgreich ausgeführt."
except Exception as e:
return f"Fehler bei der Ausführung: {str(e)}"
def self_improve(self):
if self.context:
last_code = next(item[1] for item in reversed(self.context) if item[0] in ["code", "improvement"])
improved_code = self.improve_code(last_code)
analysis = self.analyze_code(improved_code)
return improved_code, analysis
return None, "Kein Kontext für Selbstverbesserung vorhanden."
def pair_program(self, task_description):
initial_code = self.generate_code(task_description)
print("Initialer Code:")
print(initial_code)
improved_code, analysis = self.self_improve()
print("\nVerbesserter Code:")
print(improved_code)
print("\nAnalyse:")
print(analysis)
execution_result = self.execute_code(improved_code)
print("\nAusführungsergebnis:")
print(execution_result)
def save_context(self, filename):
with open(filename, 'w') as f:
json.dump(self.context, f)
def load_context(self, filename):
if os.path.exists(filename):
with open(filename, 'r') as f:
self.context = json.load(f)
# Beispielverwendung
api_key = 'AIzaSyDUaG1ti_VHM89oPD7hLmeWzb-nmcP8gmI'
assistant = GeminiCodeAssistant(api_key)
# Laden des vorherigen Kontexts, falls vorhanden
assistant.load_context('context.json')
# Pair Programming Session
assistant.pair_program("Erstelle eine Funktion zur Berechnung der Fibonacci-Folge")
# Speichern des aktuellen Kontexts
assistant.save_context('context.json')
ASSISTANT
Das Entwickeln eines autonomen Devin AI Self Pair Programmers in Pythonista 3 auf einem iPhone 13 ist ein spannendes Projekt, das mehrere Komponenten umfasst: Interaktion mit der Gemini API, eine benutzerfreundliche Oberfläche (UI), und die Integration von Funktionen wie Code-Generierung, -Verbesserung, -Ausführung und mehr. Im Folgenden findest du eine umfassende Anleitung samt Codebeispielen, die dir als Ausgangspunkt dienen können.
## Übersicht
1. **GeminiAPI Integration**: Verwendung der bereitgestellten `GeminiAPI` und `GeminiCodeAssistant` Klassen zur Interaktion mit der Gemini API.
2. **UI-Design mit Pythonista's `ui` Modul**: Aufbau einer Benutzeroberfläche mit Sidebar, Code-Editor, Terminal, Chat, und Browser-Vorschau.
3. **Autonome Agentensteuerung**: Implementierung von Funktionen zum Ausführen, Testen und Verbessern von Code sowie zur Verwaltung von Aufgaben und Kommunikation.
4. **Speicherung und Laden von Kontext**: Persistenz der Sitzungsdaten für eine nahtlose Benutzererfahrung.
## 1. Integration der GeminiAPI
Du hast bereits eine ausgezeichnete Basis mit den Klassen `GeminiAPI` und `GeminiCodeAssistant` gelegt. Wir werden diese erweitern, um zusätzliche Funktionen zu unterstützen.
```python
import requests
import json
import os
class GeminiAPI:
def __init__(self, api_key):
self.url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent'
self.headers = {
'Content-Type': 'application/json',
'x-goog-api-key': api_key
}
def call_gemini_api(self, prompt):
payload = {'contents': [{'parts': [{'text': prompt}]}]}
response = requests.post(self.url, headers=self.headers, json=payload)
return response.json()
def generate_code(self, task_description):
prompt = f"Generiere Python-Code für folgende Aufgabe: {task_description}"
response = self.call_gemini_api(prompt)
return response['candidates'][0]['content']['parts'][0]['text']
class GeminiCodeAssistant(GeminiAPI):
def __init__(self, api_key):
super().__init__(api_key)
self.context = []
def extract_response(self, api_response):
if 'candidates' in api_response and api_response['candidates']:
first_candidate = api_response['candidates'][0]
if 'content' in first_candidate and 'parts' in first_candidate['content']:
return first_candidate['content']['parts'][0]['text']
return None
def generate_code(self, task_description):
prompt = f"Generiere Python-Code für folgende Aufgabe: {task_description}"
response = self.call_gemini_api(prompt)
code = self.extract_response(response)
self.context.append(("task", task_description))
self.context.append(("code", code))
return code
def improve_code(self, code):
prompt = f"Verbessere den folgenden Python-Code:\n\n{code}\n\nVerbesserter Code:"
response = self.call_gemini_api(prompt)
improved_code = self.extract_response(response)
self.context.append(("improvement", improved_code))
return improved_code
def analyze_code(self, code):
prompt = f"Analysiere den folgenden Python-Code und gib Verbesserungsvorschläge:\n\n{code}"
response = self.call_gemini_api(prompt)
analysis = self.extract_response(response)
self.context.append(("analysis", analysis))
return analysis
def execute_code(self, code):
try:
exec(code)
return "Code erfolgreich ausgeführt."
except Exception as e:
return f"Fehler bei der Ausführung: {str(e)}"
def self_improve(self):
if self.context:
last_code = next(item[1] for item in reversed(self.context) if item[0] in ["code", "improvement"])
improved_code = self.improve_code(last_code)
analysis = self.analyze_code(improved_code)
return improved_code, analysis
return None, "Kein Kontext für Selbstverbesserung vorhanden."
def pair_program(self, task_description):
initial_code = self.generate_code(task_description)
print("Initialer Code:")
print(initial_code)
improved_code, analysis = self.self_improve()
print("\nVerbesserter Code:")
print(improved_code)
print("\nAnalyse:")
print(analysis)
execution_result = self.execute_code(improved_code)
print("\nAusführungsergebnis:")
print(execution_result)
def save_context(self, filename):
with open(filename, 'w') as f:
json.dump(self.context, f)
def load_context(self, filename):
if os.path.exists(filename):
with open(filename, 'r') as f:
self.context = json.load(f)
```
## 2. Benutzeroberfläche mit Pythonista's `ui` Modul
Wir werden eine Hauptansicht mit einer Sidebar und verschiedenen Bereichen für den Code-Editor, Terminal, Chat und Browser-Vorschau erstellen.
### 2.1. Struktur der UI
- **Sidebar (links)**: Enthält Buttons zum Verwalten von Agenten, Aufgaben, Dateien, Suchen, Debuggen und Einstellungen.
- **Hauptbereich (rechts)**:
- **Code-Editor**: Zum Schreiben und Anzeigen von Code.
- **Terminal**: Zur Anzeige von Ausführungsergebnissen.
- **Chat**: Für die Kommunikation mit dem Agenten.
- **Browser-Vorschau**: Zum Anzeigen einer Webansicht des Projekts.
### 2.2. Implementierung der UI
```python
import ui
import os
import sys
import threading
from objc_util import *
import console
# Importiere zuvor definierte Klassen
# from gemini_api import GeminiCodeAssistant # Angenommen, du hast die Klassen in einer Datei gemini_api.py gespeichert
# Initialisiere den GeminiCodeAssistant
API_KEY = 'DEIN_API_KEY_HIER'
assistant = GeminiCodeAssistant(API_KEY)
assistant.load_context('context.json')
class DevinAIApp(ui.View):
def __init__(self):
self.name = "Devin AI Pair Programmer"
self.background_color = '#F0F0F0'
# Sidebar
self.sidebar = ui.View(frame=(0, 0, 200, self.height), bg_color='#333333')
self.add_subview(self.sidebar)
button_titles = ["Dateien", "Aufgaben", "Suchen", "Debuggen", "Einstellungen"]
y = 50
for title in button_titles:
btn = ui.Button(title=title, frame=(10, y, 180, 40))
btn.tint_color = 'white'
btn.background_color = '#555555'
btn.action = self.sidebar_button_tapped
self.sidebar.add_subview(btn)
y += 50
# Hauptbereich - Code Editor
self.code_editor = ui.TextView(frame=(210, 0, self.width - 210, self.height * 0.6), flex='wh', bg_color='white', font=('Menlo', 14))
self.add_subview(self.code_editor)
# Terminal
self.terminal = ui.TextView(frame=(210, self.height * 0.6, self.width - 210, self.height * 0.2), flex='wh', bg_color='black', text_color='white', font=('Menlo', 12))
self.add_subview(self.terminal)
# Chat
self.chat_view = ui.View(frame=(210, self.height * 0.8, self.width - 210, self.height * 0.2), bg_color='#DDDDDD')
self.add_subview(self.chat_view)
self.chat_output = ui.TextView(frame=(0, 0, self.chat_view.width, self.chat_view.height - 30), flex='width', editable=False, bg_color='#DDDDDD', font=('Helvetica', 14))
self.chat_view.add_subview(self.chat_output)
self.chat_input = ui.TextField(frame=(0, self.chat_view.height - 30, self.chat_view.width - 80, 30), flex='width', placeholder='Nachricht...', name='chat_input')
self.chat_view.add_subview(self.chat_input)
self.send_button = ui.Button(title='Senden', frame=(self.chat_view.width - 70, self.chat_view.height - 30, 70, 30), flex='left', tint_color='blue')
self.send_button.action = self.send_chat
self.chat_view.add_subview(self.send_button)
# Run und Test Buttons
self.run_button = ui.Button(title='Run Code', frame=(210, self.height * 0.75, 100, 40), tint_color='white', bg_color='green')
self.run_button.action = self.run_code_action
self.add_subview(self.run_button)
self.test_button = ui.Button(title='Test Code', frame=(320, self.height * 0.75, 100, 40), tint_color='white', bg_color='blue')
self.test_button.action = self.test_code_action
self.add_subview(self.test_button)
# Anpassung bei Layout-Änderungen
self.flex = 'WH'
def sidebar_button_tapped(self, sender):
console.alert('Button Tapped', f'Du hast "{sender.title}" gedrückt.', 'OK')
def run_code_action(self, sender):
code = self.code_editor.text
self.terminal.text = "Ausführen des Codes...\n"
threading.Thread(target=self.execute_code_thread, args=(code,)).start()
def execute_code_thread(self, code):
try:
# Ausgabe umleiten
old_stdout = sys.stdout
redirected_output = sys.stdout = open('/tmp/output.txt', 'w')
exec(code)
sys.stdout = old_stdout
with open('/tmp/output.txt', 'r') as f:
output = f.read()
except Exception as e:
output = f"Fehler bei der Ausführung: {str(e)}"
ui.get_screen().invoke_run_on_main_thread(lambda: self.update_terminal(output))
def update_terminal(self, output):
self.terminal.text += output + "\n"
def test_code_action(self, sender):
# Hier könntest du spezifische Tests für den Code implementieren
self.terminal.text += "Testfunktion ist noch nicht implementiert.\n"
def send_chat(self, sender):
user_input = self.chat_input.text.strip()
if user_input:
self.chat_output.text += f"Du: {user_input}\n"
self.chat_input.text = ""
threading.Thread(target=self.handle_chat, args=(user_input,)).start()
def handle_chat(self, message):
response = self.assistant_respond(message)
ui.get_screen().invoke_run_on_main_thread(lambda: self.update_chat(response))
def assistant_respond(self, message):
# Beispielhafte einfache Antwort
prompt = f"Der Benutzer sagte: {message}\nAntwort:"
response = self.call_gemini_api(prompt)
answer = self.extract_response(response)
return f"Assistant: {answer}\n"
def update_chat(self, response):
self.chat_output.text += response
def call_gemini_api(self, prompt):
# Direkter API-Aufruf für Chat-Funktion
payload = {'contents': [{'parts': [{'text': prompt}]}]}
response = requests.post(self.assistant.url, headers=self.assistant.headers, json=payload)
return response.json()
def extract_response(self, api_response):
if 'candidates' in api_response and api_response['candidates']:
first_candidate = api_response['candidates'][0]
if 'content' in first_candidate and 'parts' in first_candidate['content']:
return first_candidate['content']['parts'][0]['text']
return "Keine Antwort erhalten."
def layout(self):
# Aktualisiere die Größe der Subviews bei Änderung der Hauptansicht
self.sidebar.frame = (0, 0, 200, self.height)
self.code_editor.frame = (210, 0, self.width - 210, self.height * 0.6)
self.terminal.frame = (210, self.height * 0.6, self.width - 210, self.height * 0.2)
self.chat_view.frame = (210, self.height * 0.8, self.width - 210, self.height * 0.2)
self.send_button.frame = (self.chat_view.width - 70, self.chat_view.height - 30, 70, 30)
self.run_button.frame = (210, self.height * 0.75, 100, 40)
self.test_button.frame = (320, self.height * 0.75, 100, 40)
def will_close(self):
# Speichern des Kontextes vor dem Schließen der App
self.assistant.save_context('context.json')
# Starte die App
app = DevinAIApp()
app.present('fullscreen')
```
### Erklärung der UI-Komponenten
1. **Sidebar**: Enthält Buttons für verschiedene Funktionen. Aktuell zeigen die Buttons nur Alert-Nachrichten an. Diese können später mit tatsächlicher Funktionalität verknüpft werden.
2. **Code Editor**: Ein `TextView`, in dem der Benutzer den Code schreiben und anzeigen kann.
3. **Terminal**: Ein dunkler `TextView` zur Anzeige von Ausführungsergebnissen und Fehlern.
4. **Chat**: Besteht aus einem nicht-editierbaren `TextView` zur Anzeige des Gesprächs und einem `TextField` für die Eingabe neuer Nachrichten.
5. **Run und Test Buttons**: Ermöglichen das Ausführen und Testen des geschriebenen Codes.
## 3. Erweiterung der Funktionalitäten
### 3.1. Code-Ausführung und -Verbesserung
Die `run_code_action` führt den im Editor geschriebenen Code aus und zeigt das Ergebnis im Terminal an. Um den Prozess zu verbessern, könntest du zusätzliche Funktionen hinzufügen, wie z.B. das automatische Testen des Codes nach der Ausführung oder die Möglichkeit, den Code mit der Gemini API zu verbessern.
### 3.2. Chat-Funktion mit Gemini
Die Chat-Funktion ermöglicht eine Kommunikation mit dem Gemini-Assistenten. Du kannst die `assistant_respond` Methode erweitern, um spezifischere Antworten zu generieren, oder sogar Funktionen wie das Speichern des Chat-Verlaufs integrieren.
### 3.3. Project Management
Implementiere Funktionen zum Verwalten von Dateien, Aufgaben und Einstellungen. Dies könnte durch zusätzliche Views und Dialoge erreicht werden, die über die Sidebar aufgerufen werden.
## 4. Speicherung und Laden von Kontext
Die `save_context` und `load_context` Methoden in der `GeminiCodeAssistant` Klasse ermöglichen es, den aktuellen Kontext (z.B. laufende Aufgaben und generierter Code) zu speichern und beim nächsten Start der App wiederherzustellen.
Stelle sicher, dass der Pfad `'context.json'` korrekt ist und über die notwendigen Berechtigungen verfügt, um innerhalb von Pythonista zu lesen und zu schreiben.
## 5. Sicherheitshinweis
**Wichtig**: Dein API-Schlüssel sollte niemals im Klartext im Code gespeichert oder öffentlich geteilt werden. Verwende sicherere Methoden zur Speicherung, wie z.B. das Laden aus einer verschlüsselten Datei oder der Verwendung von Umgebungsvariablen.
## 6. Weiterführende Verbesserungen
- **Browser-Vorschau**: Integriere eine Web-View, um die Ausgabe von Web-Anwendungen in Echtzeit anzuzeigen.
- **Dateiverwaltung**: Ermögliche das Erstellen, Bearbeiten und Speichern von Dateien direkt innerhalb der App.
- **Erweiterte Tests**: Implementiere ein Testframework zur automatischen Überprüfung des generierten Codes.
- **Agentensteuerung**: Füge Funktionen hinzu, um verschiedene Agenten zu starten, zu stoppen und zu konfigurieren.
## Fazit
Dieses Projekt kombiniert die Leistungsfähigkeit der Gemini API mit einer benutzerfreundlichen Oberfläche in Pythonista 3, um einen autonomen Pair-Programming-Assistenten zu erstellen. Die bereitgestellten Codebeispiele bilden eine solide Grundlage, die du nach Bedarf erweitern und anpassen kannst. Achte darauf, die Sicherheitsaspekte zu berücksichtigen, insbesondere im Hinblick auf die Verwaltung von API-Schlüsseln und Benutzerdaten.
Viel Erfolg bei der Entwicklung deines Devin AI Self Pair Programmers!