Per-session workspace, tools only when workspace set

- Session has workspace field (absolute path, optional)
- ToolService stateless, receives workspace per call
- No workspace = no tools sent to API
- Removed hardcoded workspace from Program.cs
- Workspace field in session edit form
This commit is contained in:
Meleki committed 2026-02-26 22:26:53 +01:00
1 parent 002ef293f0
commit b752c99a64
9 files changed
+50 -40

No files matched your search

+20 -27
View File
@@ -11,13 +11,6 @@ namespace Gott.Services;
public class ToolService
{
private readonly string _workspaceRoot;
public ToolService(string workspaceRoot)
{
_workspaceRoot = workspaceRoot;
}
public object[] GetToolDefinitions()
{
return new object[]
@@ -112,31 +105,31 @@ public class ToolService
};
}
public async Task<string> ExecuteTool(string name, JsonElement input)
public async Task<string> ExecuteTool(string name, JsonElement input, string workspace)
{
switch (name)
{
case "read_file":
{
var path = ResolvePath(input.GetProperty("path").GetString() ?? "");
var path = ResolvePath(input.GetProperty("path").GetString() ?? "", workspace);
if (!File.Exists(path))
return $"Fehler: Datei nicht gefunden: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Fehler: Datei nicht gefunden: {Path.GetRelativePath(workspace, path)}";
return File.ReadAllText(path);
}
case "write_file":
{
var path = ResolvePath(input.GetProperty("path").GetString() ?? "");
var path = ResolvePath(input.GetProperty("path").GetString() ?? "", workspace);
var dir = Path.GetDirectoryName(path);
if (dir != null) Directory.CreateDirectory(dir);
var content = input.GetProperty("content").GetString() ?? "";
File.WriteAllText(path, content);
return $"Datei geschrieben: {Path.GetRelativePath(_workspaceRoot, path)} ({content.Length} Zeichen)";
return $"Datei geschrieben: {Path.GetRelativePath(workspace, path)} ({content.Length} Zeichen)";
}
case "edit_file":
{
var path = ResolvePath(input.GetProperty("path").GetString() ?? "");
var path = ResolvePath(input.GetProperty("path").GetString() ?? "", workspace);
if (!File.Exists(path))
return $"Fehler: Datei nicht gefunden: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Fehler: Datei nicht gefunden: {Path.GetRelativePath(workspace, path)}";
var fileContent = File.ReadAllText(path);
var oldText = input.GetProperty("old_text").GetString() ?? "";
var newText = input.GetProperty("new_text").GetString() ?? "";
@@ -144,34 +137,34 @@ public class ToolService
return "Fehler: old_text nicht in der Datei gefunden. Exakter Match nötig.";
fileContent = fileContent.Replace(oldText, newText);
File.WriteAllText(path, fileContent);
return $"Datei bearbeitet: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Datei bearbeitet: {Path.GetRelativePath(workspace, path)}";
}
case "list_files":
{
var path = ResolvePath(input.TryGetProperty("path", out var p) ? p.GetString() ?? "" : "");
var path = ResolvePath(input.TryGetProperty("path", out var p) ? p.GetString() ?? "" : "", workspace);
if (!Directory.Exists(path))
return $"Fehler: Verzeichnis nicht gefunden: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Fehler: Verzeichnis nicht gefunden: {Path.GetRelativePath(workspace, path)}";
var entries = new List<string>();
foreach (var dir in Directory.GetDirectories(path))
entries.Add(Path.GetRelativePath(_workspaceRoot, dir) + "/");
entries.Add(Path.GetRelativePath(workspace, dir) + "/");
foreach (var file in Directory.GetFiles(path))
entries.Add(Path.GetRelativePath(_workspaceRoot, file));
entries.Add(Path.GetRelativePath(workspace, file));
return entries.Count == 0 ? "(leer)" : string.Join("\n", entries);
}
case "delete_file":
{
var path = ResolvePath(input.GetProperty("path").GetString() ?? "");
var path = ResolvePath(input.GetProperty("path").GetString() ?? "", workspace);
if (File.Exists(path))
{
File.Delete(path);
return $"Datei gelöscht: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Datei gelöscht: {Path.GetRelativePath(workspace, path)}";
}
if (Directory.Exists(path))
{
Directory.Delete(path, recursive: false);
return $"Verzeichnis gelöscht: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Verzeichnis gelöscht: {Path.GetRelativePath(workspace, path)}";
}
return $"Fehler: Nicht gefunden: {Path.GetRelativePath(_workspaceRoot, path)}";
return $"Fehler: Nicht gefunden: {Path.GetRelativePath(workspace, path)}";
}
case "execute":
{
@@ -179,7 +172,7 @@ public class ToolService
var psi = new ProcessStartInfo
{
FileName = "/bin/bash",
WorkingDirectory = _workspaceRoot,
WorkingDirectory = workspace,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
@@ -218,10 +211,10 @@ public class ToolService
}
}
private string ResolvePath(string relativePath)
private string ResolvePath(string relativePath, string workspace)
{
var full = Path.GetFullPath(Path.Combine(_workspaceRoot, relativePath ?? ""));
if (!full.StartsWith(_workspaceRoot))
var full = Path.GetFullPath(Path.Combine(workspace, relativePath ?? ""));
if (!full.StartsWith(workspace))
throw new Exception("Zugriff außerhalb des Workspace nicht erlaubt");
return full;
}