fix: Tag-Feld für Sub-Agent-Messages – verhindert API 400 bei tool_use ohne tool_result
- MessageRecord: neues Tag-Feld (null=normal, preparer/review/finalizer=Sub-Agent) - DatabaseService: Migration tag-Spalte, INSERT-Statements erweitert - AnthropicService: RunAgentChat setzt Tag=agentType bei allen 4 SaveMessage-Aufrufen - ChatService: BuildHistoryFromDb filtert getaggte Messages aus API-History Sub-Agent-Messages bleiben in der DB (Frontend-Anzeige), werden aber nie an die Claude API geschickt – löst das Problem für Preparer, Review und Finalizer gleichermaßen.
This commit is contained in:
1 parent
494f431963
commit
43d3e9dc26
4 files changed
+17
-9
No files matched your search
@@ -13,6 +13,7 @@ public class MessageRecord
|
||||
public int Iteration { get; set; } // welche Loop-Iteration
|
||||
public int AttachmentCount { get; set; } // Anzahl angehängter Dateien
|
||||
public string AttachmentNames { get; set; } // JSON-Array mit Dateinamen
|
||||
public string Tag { get; set; } // null = normal, "preparer"/"review"/"finalizer" = Sub-Agent-Message
|
||||
public bool IsMarked { get; set; } // als wichtig markiert
|
||||
public string DeletedOn { get; set; } // null = aktiv, sonst Zeitstempel der Löschung
|
||||
public string CreatedAt { get; set; }
|
||||
|
||||
@@ -691,7 +691,8 @@ public class AnthropicService
|
||||
Iteration = baseIterations + iterations,
|
||||
Role = "assistant",
|
||||
Type = "text",
|
||||
Content = $"[{tag}: {agentName}] {text}"
|
||||
Content = $"[{tag}: {agentName}] {text}",
|
||||
Tag = agentType
|
||||
});
|
||||
}
|
||||
else if (blockType == "tool_use")
|
||||
@@ -718,7 +719,8 @@ public class AnthropicService
|
||||
Type = "tool_use",
|
||||
Content = toolInput.GetRawText(),
|
||||
ToolName = toolName,
|
||||
ToolCallId = toolId
|
||||
ToolCallId = toolId,
|
||||
Tag = agentType
|
||||
});
|
||||
|
||||
string toolResult;
|
||||
@@ -748,7 +750,8 @@ public class AnthropicService
|
||||
Content = toolResult,
|
||||
ToolName = toolName,
|
||||
ToolCallId = toolId,
|
||||
IsError = isError
|
||||
IsError = isError,
|
||||
Tag = agentType
|
||||
});
|
||||
}
|
||||
else if (blockType == "web_search_tool_result")
|
||||
@@ -779,7 +782,8 @@ public class AnthropicService
|
||||
Iteration = baseIterations + iterations,
|
||||
Role = "assistant",
|
||||
Type = "web_search_result",
|
||||
Content = JsonSerializer.Serialize(sources)
|
||||
Content = JsonSerializer.Serialize(sources),
|
||||
Tag = agentType
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +329,9 @@ Bitte speichere es in die Datei products.json im Workspace.
|
||||
var chain = chainsList[i];
|
||||
isLastChain = (i == chainsList.Count - 1);
|
||||
|
||||
var msgs = (await _db.GetChainMessages(chain.ChainId)).ToList();
|
||||
var msgs = (await _db.GetChainMessages(chain.ChainId))
|
||||
.Where(m => string.IsNullOrEmpty(m.Tag)) // Sub-Agent-Messages (preparer/review/finalizer) aus API-History ausfiltern
|
||||
.ToList();
|
||||
|
||||
// Letzte User-Message-ID der letzten Chain merken (für Attachments)
|
||||
if (isLastChain || i == fullChainStartIndex)
|
||||
|
||||
@@ -181,6 +181,7 @@ public class DatabaseService
|
||||
TryAddColumn(conn, "agents", "allow_user_choice", "INTEGER NOT NULL DEFAULT 1");
|
||||
TryAddColumn(conn, "chains", "plan_mode", "INTEGER NOT NULL DEFAULT 0");
|
||||
TryAddColumn(conn, "sessions", "preparer_agent_id", "TEXT");
|
||||
TryAddColumn(conn, "messages", "tag", "TEXT");
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS agent_skills (
|
||||
@@ -629,8 +630,8 @@ public class DatabaseService
|
||||
using var conn = CreateConnection();
|
||||
record.CreatedAt = DateTime.UtcNow.ToString("o");
|
||||
return await conn.ExecuteScalarAsync<long>(@"
|
||||
INSERT INTO messages (chain_id, role, type, content, tool_name, tool_call_id, is_error, iteration, attachment_count, created_at)
|
||||
VALUES (@ChainId, @Role, @Type, @Content, @ToolName, @ToolCallId, @IsError, @Iteration, @AttachmentCount, @CreatedAt);
|
||||
INSERT INTO messages (chain_id, role, type, content, tool_name, tool_call_id, is_error, iteration, attachment_count, tag, created_at)
|
||||
VALUES (@ChainId, @Role, @Type, @Content, @ToolName, @ToolCallId, @IsError, @Iteration, @AttachmentCount, @Tag, @CreatedAt);
|
||||
SELECT last_insert_rowid();
|
||||
", record);
|
||||
}
|
||||
@@ -651,8 +652,8 @@ public class DatabaseService
|
||||
record.AttachmentNames = System.Text.Json.JsonSerializer.Serialize(names);
|
||||
}
|
||||
var messageId = await conn.ExecuteScalarAsync<long>(@"
|
||||
INSERT INTO messages (chain_id, role, type, content, tool_name, tool_call_id, is_error, iteration, attachment_count, attachment_names, created_at)
|
||||
VALUES (@ChainId, @Role, @Type, @Content, @ToolName, @ToolCallId, @IsError, @Iteration, @AttachmentCount, @AttachmentNames, @CreatedAt);
|
||||
INSERT INTO messages (chain_id, role, type, content, tool_name, tool_call_id, is_error, iteration, attachment_count, attachment_names, tag, created_at)
|
||||
VALUES (@ChainId, @Role, @Type, @Content, @ToolName, @ToolCallId, @IsError, @Iteration, @AttachmentCount, @AttachmentNames, @Tag, @CreatedAt);
|
||||
SELECT last_insert_rowid();
|
||||
", record, tx);
|
||||
|
||||
|
||||
Reference in new issue
Block a user