Tools: delete_file + execute (bash via stdin)
This commit is contained in:
1 parent
6ccd8cdb06
commit
fde6b51b1b
1 file changed
+85
-2
+85
-2
@@ -87,6 +87,34 @@ var toolDefs = new[]
|
|||||||
},
|
},
|
||||||
required = System.Array.Empty<string>()
|
required = System.Array.Empty<string>()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
name = "delete_file",
|
||||||
|
description = "Löscht eine Datei oder ein leeres Verzeichnis.",
|
||||||
|
input_schema = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["path"] = new { type = "string", description = "Relativer Pfad zur Datei oder zum Verzeichnis" }
|
||||||
|
},
|
||||||
|
required = new[] { "path" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
name = "execute",
|
||||||
|
description = "Führt einen Shell-Befehl im Workspace-Verzeichnis aus. Gibt stdout und stderr zurück. Timeout: 30 Sekunden.",
|
||||||
|
input_schema = new
|
||||||
|
{
|
||||||
|
type = "object",
|
||||||
|
properties = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["command"] = new { type = "string", description = "Shell-Befehl zum Ausführen" }
|
||||||
|
},
|
||||||
|
required = new[] { "command" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,7 +128,7 @@ string ResolvePath(string relativePath)
|
|||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ExecuteTool(string name, JsonElement input)
|
async Task<string> ExecuteTool(string name, JsonElement input)
|
||||||
{
|
{
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
@@ -146,6 +174,61 @@ string ExecuteTool(string name, JsonElement input)
|
|||||||
entries.Add(Path.GetRelativePath(workspaceRoot, file));
|
entries.Add(Path.GetRelativePath(workspaceRoot, file));
|
||||||
return entries.Count == 0 ? "(leer)" : string.Join("\n", entries);
|
return entries.Count == 0 ? "(leer)" : string.Join("\n", entries);
|
||||||
}
|
}
|
||||||
|
case "delete_file":
|
||||||
|
{
|
||||||
|
var path = ResolvePath(input.GetProperty("path").GetString() ?? "");
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
return $"Datei gelöscht: {Path.GetRelativePath(workspaceRoot, path)}";
|
||||||
|
}
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
{
|
||||||
|
Directory.Delete(path, recursive: false);
|
||||||
|
return $"Verzeichnis gelöscht: {Path.GetRelativePath(workspaceRoot, path)}";
|
||||||
|
}
|
||||||
|
return $"Fehler: Nicht gefunden: {Path.GetRelativePath(workspaceRoot, path)}";
|
||||||
|
}
|
||||||
|
case "execute":
|
||||||
|
{
|
||||||
|
var command = input.GetProperty("command").GetString() ?? "";
|
||||||
|
var psi = new System.Diagnostics.ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "/bin/bash",
|
||||||
|
WorkingDirectory = workspaceRoot,
|
||||||
|
RedirectStandardInput = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
using var proc = System.Diagnostics.Process.Start(psi);
|
||||||
|
if (proc == null) return "Fehler: Prozess konnte nicht gestartet werden";
|
||||||
|
await proc.StandardInput.WriteAsync(command);
|
||||||
|
proc.StandardInput.Close();
|
||||||
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await proc.WaitForExitAsync(cts.Token);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
proc.Kill(entireProcessTree: true);
|
||||||
|
return "Fehler: Timeout nach 30 Sekunden - Prozess abgebrochen";
|
||||||
|
}
|
||||||
|
var stdout = await proc.StandardOutput.ReadToEndAsync();
|
||||||
|
var stderr = await proc.StandardError.ReadToEndAsync();
|
||||||
|
var result = new StringBuilder();
|
||||||
|
if (!string.IsNullOrEmpty(stdout)) result.Append(stdout);
|
||||||
|
if (!string.IsNullOrEmpty(stderr))
|
||||||
|
{
|
||||||
|
if (result.Length > 0) result.Append("\n--- stderr ---\n");
|
||||||
|
result.Append(stderr);
|
||||||
|
}
|
||||||
|
if (result.Length == 0) result.Append($"(exit code {proc.ExitCode})");
|
||||||
|
else if (proc.ExitCode != 0) result.Append($"\n(exit code {proc.ExitCode})");
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return $"Fehler: Unbekanntes Tool: {name}";
|
return $"Fehler: Unbekanntes Tool: {name}";
|
||||||
}
|
}
|
||||||
@@ -374,7 +457,7 @@ app.MapPost("/api/chat", async (HttpRequest req, HttpResponse res, IHttpClientFa
|
|||||||
// Tool sofort ausführen und streamen
|
// Tool sofort ausführen und streamen
|
||||||
string toolResult;
|
string toolResult;
|
||||||
bool isError = false;
|
bool isError = false;
|
||||||
try { toolResult = ExecuteTool(currentToolName, inputEl); }
|
try { toolResult = await ExecuteTool(currentToolName, inputEl); }
|
||||||
catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; }
|
catch (Exception ex) { toolResult = $"Fehler: {ex.Message}"; isError = true; }
|
||||||
|
|
||||||
executedTools.Add((currentToolId, toolResult, isError));
|
executedTools.Add((currentToolId, toolResult, isError));
|
||||||
|
|||||||
Reference in new issue
Block a user