feat: Payload-Preview im Chat-Menü + Reminder von hinten gezählt
- Neuer Endpoint GET /api/sessions/{id}/payload-preview
Gibt den exakten Anthropic-API-Payload als JSON zurück (read-only)
- Chat-Menü: 'Payload anzeigen' öffnet Modal mit formatiertem JSON
- Reminder-Logik umgebaut: halbes Intervall (15) vor Ende,
dann volle Intervalle (30) rückwärts statt von vorne gezählt
- CSS: Payload-Modal Styling, kleine Variable-Fixes
This commit is contained in:
1 parent
229e6d9e53
commit
49ef6bedc6
7 files changed
+154
-21
No files matched your search
@@ -26,6 +26,7 @@ public static class SessionEndpoint
|
||||
app.MapDelete("/api/sessions/{sessionId}", HandleDelete);
|
||||
app.MapGet("/api/sessions/{sessionId}/system-prompt", HandleSystemPrompt);
|
||||
app.MapGet("/api/sessions/{sessionId}/system-prompt-blocks", HandleSystemPromptBlocks);
|
||||
app.MapGet("/api/sessions/{sessionId}/payload-preview", HandlePayloadPreview);
|
||||
app.MapGet("/api/sessions/{sessionId}/streaming", HandleStreaming);
|
||||
app.MapPost("/api/sessions/{sessionId}/exec", HandleExec);
|
||||
app.MapGet("/api/sessions/{sessionId}/git-status", HandleGitStatus);
|
||||
@@ -266,6 +267,75 @@ public static class SessionEndpoint
|
||||
await ctx.Response.WriteAsJsonAsync(blocks.Select(b => new { b.Icon, b.Label, b.Content }));
|
||||
}
|
||||
|
||||
private static async Task HandlePayloadPreview(HttpContext ctx, DatabaseService db, MemoryService memoryService, SkillService skillService, ChatService chatService, ToolService toolService, ServerSettingsService settings)
|
||||
{
|
||||
var result = await ResolvePromptContext(ctx, db, memoryService);
|
||||
if (result == null) return;
|
||||
var (session, agent, marked, memDir, skills, user, workspace, planMode) = result.Value;
|
||||
|
||||
// System-Prompt
|
||||
var promptBlocks = SystemPromptBuilder.BuildBlocks(agent, session, marked, memoryService, memDir,
|
||||
skills, skillService, userPersona: user?.GetEffectivePersona(), resolvedWorkspace: workspace, planMode: planMode);
|
||||
var systemPromptText = string.Join("\n\n", promptBlocks.Select(b => b.Content));
|
||||
|
||||
var systemPrompt = new List<object>();
|
||||
if (!string.IsNullOrWhiteSpace(systemPromptText))
|
||||
systemPrompt.Add(new { type = "text", text = systemPromptText });
|
||||
|
||||
// Model
|
||||
var modelId = ChatService.ResolveModelId(agent.Model);
|
||||
|
||||
// Messages aus der DB (exakt wie beim Chat)
|
||||
var messages = await chatService.BuildHistoryFromDb(session.SessionId, promptBlocks: promptBlocks);
|
||||
|
||||
// Tools (exakt wie AddToolsToPayload es machen würde)
|
||||
var hasWorkspace = !string.IsNullOrEmpty(workspace);
|
||||
var includeMemory = agent.UseMemory && !string.IsNullOrEmpty(agent.AgentId);
|
||||
var includeGitHubSearch = agent.UseGitHubSearch && toolService.HasGitHubToken;
|
||||
var includeSerperSearch = agent.UseSerperSearch && toolService.HasSerperKey;
|
||||
var hasTools = hasWorkspace || includeMemory || includeGitHubSearch || includeSerperSearch;
|
||||
|
||||
var tools = new List<object>();
|
||||
if (hasTools)
|
||||
{
|
||||
var allTools = toolService.GetToolDefinitions(
|
||||
includeFileTools: hasWorkspace,
|
||||
includeMemory: includeMemory,
|
||||
includeUserChoice: agent.AllowUserChoice,
|
||||
includeGitHubSearch: includeGitHubSearch,
|
||||
includeSerperSearch: includeSerperSearch);
|
||||
if (planMode)
|
||||
allTools = toolService.FilterReadOnlyTools(allTools);
|
||||
tools.AddRange(allTools);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(agent.WebSearchVersion))
|
||||
tools.Add(new { type = agent.WebSearchVersion, name = "web_search", max_uses = 5 });
|
||||
|
||||
var toolChoice = hasTools || !string.IsNullOrEmpty(agent.WebSearchVersion) ? "any" : null;
|
||||
var effectiveChoice = toolChoice == "any" ? "any" : "auto";
|
||||
|
||||
// Payload zusammenbauen (Anthropic-Format)
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
["model"] = modelId,
|
||||
["max_tokens"] = 16384,
|
||||
["messages"] = messages,
|
||||
["stream"] = true
|
||||
};
|
||||
|
||||
if (systemPrompt.Count > 0)
|
||||
payload["system"] = systemPrompt;
|
||||
|
||||
if (tools.Count > 0)
|
||||
{
|
||||
payload["tools"] = tools;
|
||||
payload["tool_choice"] = new { type = effectiveChoice };
|
||||
}
|
||||
|
||||
ctx.Response.ContentType = "application/json; charset=utf-8";
|
||||
await ctx.Response.WriteAsync(JsonSerializer.Serialize(payload, new JsonSerializerOptions { WriteIndented = true }));
|
||||
}
|
||||
|
||||
private static async Task HandleStreaming(HttpContext ctx, DatabaseService db, StreamingTracker streamingTracker)
|
||||
{
|
||||
var userId = ctx.GetUserId();
|
||||
|
||||
Reference in new issue
Block a user