From a1c54bf376f5bdfa1998423a6a768efb68c9b627 Mon Sep 17 00:00:00 2001 From: Meleki Date: Mon, 2 Mar 2026 10:42:54 +0100 Subject: [PATCH] feat: ToolChoice + ToolNames pro Chain in DB speichern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChainRecord: neue Felder ToolChoice (auto/any) und ToolNames (JSON-Array) - DatabaseService: Migration tool_choice + tool_names Spalten, INSERT erweitert - ChatEndpoint: berechnet Tools vor Chain-Erstellung, speichert Werte mit - ToolService: execute-Timeout Beschreibung korrigiert (30s → 180s) --- Endpoints/ChatEndpoint.cs | 22 +++++++++++++++++++--- Models/ChainRecord.cs | 2 ++ Services/DatabaseService.cs | 6 ++++-- Services/ToolService.cs | 2 +- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Endpoints/ChatEndpoint.cs b/Endpoints/ChatEndpoint.cs index 6e0997c..71747e1 100644 --- a/Endpoints/ChatEndpoint.cs +++ b/Endpoints/ChatEndpoint.cs @@ -85,13 +85,31 @@ public static class ChatEndpoint var chainId = Guid.NewGuid().ToString("N"); + var workspace = session.Workspace; + var toolChoice = agent.ToolChoice ?? "any"; + var hasWorkspace = !string.IsNullOrEmpty(workspace); + var includeMemory = agent.UseMemory && !string.IsNullOrEmpty(agent.AgentId); + var toolDefs = (hasWorkspace || includeMemory) + ? toolService.GetToolDefinitions(includeFileTools: hasWorkspace, includeMemory: includeMemory) + : Array.Empty(); + var toolNames = toolDefs.Length > 0 + ? JsonSerializer.Serialize(toolDefs.Select(td => + { + var json = JsonSerializer.Serialize(td); + var el = JsonSerializer.Deserialize(json); + return el.GetProperty("name").GetString(); + }).ToArray()) + : null; + await db.CreateChain(new ChainRecord { ChainId = chainId, SessionId = sessionId, AgentId = agent.AgentId, Model = modelId, - SystemPrompt = systemPromptText + SystemPrompt = systemPromptText, + ToolChoice = (hasWorkspace || includeMemory) ? toolChoice : null, + ToolNames = toolNames }); // Session-Timestamp aktualisieren @@ -150,12 +168,10 @@ public static class ChatEndpoint ? new List() : new List { new { type = "text", text = systemPromptText } }; - var workspace = session.Workspace; if (!string.IsNullOrEmpty(workspace)) Directory.CreateDirectory(workspace); var maxIterations = config.GetValue("MaxIterations", 100); - var toolChoice = agent.ToolChoice ?? "any"; var anthropic = new AnthropicService(httpFactory, token, toolService, db, memoryService); streamingTracker.Start(sessionId, chainId); diff --git a/Models/ChainRecord.cs b/Models/ChainRecord.cs index a2ab7c5..3b61ec5 100644 --- a/Models/ChainRecord.cs +++ b/Models/ChainRecord.cs @@ -15,6 +15,8 @@ public class ChainRecord public int Iterations { get; set; } public string StopReason { get; set; } public long DurationMs { get; set; } + public string ToolChoice { get; set; } + public string ToolNames { get; set; } public string ArchiveId { get; set; } public string CreatedAt { get; set; } } diff --git a/Services/DatabaseService.cs b/Services/DatabaseService.cs index 178d9fe..59dbac2 100644 --- a/Services/DatabaseService.cs +++ b/Services/DatabaseService.cs @@ -124,6 +124,8 @@ public class DatabaseService TryAddColumn(conn, "chains", "agent_id", "TEXT"); TryAddColumn(conn, "chains", "cache_creation_tokens", "INTEGER NOT NULL DEFAULT 0"); TryAddColumn(conn, "chains", "cache_read_tokens", "INTEGER NOT NULL DEFAULT 0"); + TryAddColumn(conn, "chains", "tool_choice", "TEXT"); + TryAddColumn(conn, "chains", "tool_names", "TEXT"); TryAddColumn(conn, "messages", "attachment_count", "INTEGER NOT NULL DEFAULT 0"); TryAddColumn(conn, "messages", "attachment_names", "TEXT"); TryAddColumn(conn, "agents", "tool_choice", "TEXT DEFAULT 'any'"); @@ -396,8 +398,8 @@ public class DatabaseService using var conn = CreateConnection(); chain.CreatedAt = DateTime.UtcNow.ToString("o"); await conn.ExecuteAsync(@" - INSERT INTO chains (chain_id, session_id, archive_id, agent_id, model, system_prompt, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at) - VALUES (@ChainId, @SessionId, @ArchiveId, @AgentId, @Model, @SystemPrompt, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt) + INSERT INTO chains (chain_id, session_id, archive_id, agent_id, model, system_prompt, tool_choice, tool_names, input_tokens, output_tokens, iterations, stop_reason, duration_ms, created_at) + VALUES (@ChainId, @SessionId, @ArchiveId, @AgentId, @Model, @SystemPrompt, @ToolChoice, @ToolNames, @InputTokens, @OutputTokens, @Iterations, @StopReason, @DurationMs, @CreatedAt) ", chain); } diff --git a/Services/ToolService.cs b/Services/ToolService.cs index de887a4..a0cf4f8 100644 --- a/Services/ToolService.cs +++ b/Services/ToolService.cs @@ -101,7 +101,7 @@ public class ToolService new { name = "execute", - description = "Führt einen Shell-Befehl im Workspace-Verzeichnis aus. Gibt stdout und stderr zurück. Timeout: 30 Sekunden.", + description = "Führt einen Shell-Befehl im Workspace-Verzeichnis aus. Gibt stdout und stderr zurück. Timeout: 180 Sekunden.", input_schema = new { type = "object",