104 lines
2.6 KiB
Go
104 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/openai/openai-go"
|
|
oaioption "github.com/openai/openai-go/option"
|
|
|
|
"llm-agent/agent"
|
|
)
|
|
|
|
const baseURL = "http://127.0.0.1:12434/v1"
|
|
|
|
func resolvePath(base, rel string) string {
|
|
if filepath.IsAbs(rel) {
|
|
return rel // absoluter Pfad → direkt nutzen
|
|
}
|
|
return filepath.Join(base, rel)
|
|
}
|
|
|
|
func selectModel(client *openai.Client) string {
|
|
modelsPage, err := client.Models.List(context.Background())
|
|
if err != nil {
|
|
log.Fatalf("Fehler beim Abrufen der Modelle: %v", err)
|
|
}
|
|
models := modelsPage.Data
|
|
if len(models) == 0 {
|
|
log.Fatal("Keine Modelle verfügbar!")
|
|
}
|
|
|
|
fmt.Println("\n📦 Verfügbare Modelle:")
|
|
fmt.Println(strings.Repeat("─", 50))
|
|
for i, m := range models {
|
|
fmt.Printf(" [%d] %s\n", i+1, m.ID)
|
|
}
|
|
fmt.Println(strings.Repeat("─", 50))
|
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
for {
|
|
fmt.Printf("Wähle ein Modell (1-%d): ", len(models))
|
|
if !scanner.Scan() {
|
|
log.Fatal("Eingabe fehlgeschlagen")
|
|
}
|
|
choice, err := strconv.Atoi(strings.TrimSpace(scanner.Text()))
|
|
if err != nil || choice < 1 || choice > len(models) {
|
|
fmt.Printf("❌ Ungültige Eingabe.\n")
|
|
continue
|
|
}
|
|
selected := models[choice-1].ID
|
|
fmt.Printf("✅ Modell gewählt: %s\n", selected)
|
|
return selected
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
// Verzeichnis der ausführbaren Binary ermitteln
|
|
execDir, err := os.Getwd()
|
|
if err != nil {
|
|
log.Fatalf("Konnte Arbeitsverzeichnis nicht ermitteln: %v", err)
|
|
}
|
|
|
|
// Flags definieren
|
|
verbose := flag.Bool("verbose", false, "Zeigt alle Chat-Nachrichten vollständig an")
|
|
workDir := flag.String("workdir", "workspace", "Arbeitsverzeichnis (relativ zur Binary oder absolut)")
|
|
prdFile := flag.String("prd", "PRD.md", "PRD-Datei (relativ zum Arbeitsverzeichnis oder absolut)")
|
|
flag.Parse()
|
|
|
|
// Pfade auflösen
|
|
resolvedWorkDir := resolvePath(execDir, *workDir)
|
|
resolvedPRD := resolvePath(resolvedWorkDir, *prdFile)
|
|
|
|
// Arbeitsverzeichnis anlegen falls nicht vorhanden
|
|
if err := os.MkdirAll(resolvedWorkDir, 0755); err != nil {
|
|
log.Fatalf("Konnte Arbeitsverzeichnis nicht anlegen: %v", err)
|
|
}
|
|
|
|
fmt.Println("🤖 LLM Agent")
|
|
fmt.Printf("📁 Arbeitsverzeichnis : %s\n", resolvedWorkDir)
|
|
fmt.Printf("📋 PRD-Datei : %s\n", resolvedPRD)
|
|
if *verbose {
|
|
fmt.Println("🔍 Verbose-Modus aktiv")
|
|
}
|
|
|
|
client := openai.NewClient(
|
|
oaioption.WithBaseURL(baseURL),
|
|
oaioption.WithAPIKey("ollama"),
|
|
)
|
|
|
|
model := selectModel(&client)
|
|
|
|
loop := agent.NewAgentLoop(model, resolvedWorkDir, resolvedPRD, *verbose)
|
|
if err := loop.Run(); err != nil {
|
|
log.Fatalf("Agent fehlgeschlagen: %v", err)
|
|
}
|
|
}
|