feat: Thumbnail-Varianten (256px) für Agent-Avatare und Session-Images

- ImageService: ResizeDataUrlSmall() für 256px WebP-Thumbnails (Quality 70)
- Neue DB-Spalten: agents.avatar_small, sessions.image_small
- Migration generiert Thumbnails für bestehende Bilder automatisch
- Listen-Endpoints (/api/agents, /api/sessions) liefern kleine Variante
- Detail-Endpoints liefern weiterhin das volle 512px-Bild
- Frontend unverändert (Cards nutzen automatisch die kleineren Bilder)
This commit is contained in:
Meleki committed 2026-03-07 20:09:01 +01:00
1 parent 8efce5f2d5
commit 2a2e98ca68
6 files changed
+116 -15

No files matched your search

+7 -2
View File
@@ -42,7 +42,7 @@ public static class AgentEndpoint
{
a.AgentId,
a.Name,
a.Avatar,
Avatar = a.AvatarSmall ?? a.Avatar,
a.Description,
a.Model,
a.ToolChoice,
@@ -96,6 +96,7 @@ public static class AgentEndpoint
UserId = userId,
Name = body.TryGetProperty("name", out var n) ? n.GetString() ?? "Neuer Agent" : "Neuer Agent",
Avatar = imageService.ResizeDataUrl(avatarRaw),
AvatarSmall = imageService.ResizeDataUrlSmall(avatarRaw),
Description = body.TryGetProperty("description", out var d) ? d.GetString() : null,
Model = body.TryGetProperty("model", out var m) ? m.GetString() ?? "sonnet" : "sonnet",
ToolChoice = body.TryGetProperty("toolChoice", out var tc) ? tc.GetString() ?? "any" : "any",
@@ -131,7 +132,11 @@ public static class AgentEndpoint
var body = await JsonSerializer.DeserializeAsync<JsonElement>(ctx.Request.Body);
if (body.TryGetProperty("name", out var n)) agent.Name = n.GetString();
if (body.TryGetProperty("avatar", out var av)) agent.Avatar = imageService.ResizeDataUrl(av.GetString());
if (body.TryGetProperty("avatar", out var av))
{
agent.Avatar = imageService.ResizeDataUrl(av.GetString());
agent.AvatarSmall = imageService.ResizeDataUrlSmall(av.GetString());
}
if (body.TryGetProperty("description", out var d)) agent.Description = d.GetString();
if (body.TryGetProperty("model", out var m)) agent.Model = m.GetString();
if (body.TryGetProperty("toolChoice", out var tc)) agent.ToolChoice = tc.GetString();
+3 -2
View File
@@ -66,7 +66,7 @@ public static class SessionEndpoint
s.SessionId,
s.Name,
s.Description,
s.Image,
Image = s.ImageSmall ?? s.Image,
s.AgentId,
s.Workspace,
s.Context,
@@ -120,6 +120,7 @@ public static class SessionEndpoint
var description = body.TryGetProperty("description", out var d) ? d.GetString() : null;
var imageRaw = body.TryGetProperty("image", out var img) ? img.GetString() : null;
var image = imageService.ResizeDataUrl(imageRaw);
var imageSmall = imageService.ResizeDataUrlSmall(imageRaw);
var agentId = body.TryGetProperty("agentId", out var a) ? a.GetString() : null;
var workspaceRaw = body.TryGetProperty("workspace", out var w) ? w.GetString() : null;
// Relativen Workspace validieren (Path-Traversal verhindern)
@@ -142,7 +143,7 @@ public static class SessionEndpoint
var finalizerAgentId = body.TryGetProperty("finalizerAgentId", out var fa) ? fa.GetString() : null;
var preparerAgentId = body.TryGetProperty("preparerAgentId", out var pra) ? pra.GetString() : null;
var session = await db.CreateSession(userId, name, description, image, agentId, workspace, context, customCommands, avatarScale, avatarOffsetX, avatarOffsetY, reviewAgentId, maxReviewIterations, finalizerAgentId, preparerAgentId);
var session = await db.CreateSession(userId, name, description, image, imageSmall, agentId, workspace, context, customCommands, avatarScale, avatarOffsetX, avatarOffsetY, reviewAgentId, maxReviewIterations, finalizerAgentId, preparerAgentId);
await ctx.Response.WriteAsJsonAsync(session);
}