Compare commits

..

4 Commits

Author SHA1 Message Date
devops 85f3400076 chore: bump version to v0.2.38 [skip ci] 2026-06-09 23:12:40 +00:00
developer a5cbe98f25 fix: Chat-Messages Merge + Session-Key agent:iris:main
CI - Build & Test / Backend (.NET) (push) Successful in 23s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 16s
CI - Build & Test / Security Check (push) Successful in 3s
- fetchChatMessages merged statt replace (verhindert Poll-wipe)
- Chat/Send bereits korrekt via agentId=iris
- Chat/Messages nutzt jetzt agent:iris:main als Session-Key
- Cron-Job deaktiviert (verhinderte Selbst-Konversation)
2026-06-10 01:11:52 +02:00
devops 5b0e3a19f6 chore: bump version to v0.2.37 [skip ci] 2026-06-09 22:58:55 +00:00
developer e1d6b1eeb3 fix: Chat via agentId statt sessionKey + reply aus details parsen
CI - Build & Test / Backend (.NET) (push) Successful in 26s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 15s
CI - Build & Test / Security Check (push) Successful in 3s
- SendChatMessageAsync: sessions_send nutzt agentId (nicht sessionKey)
- Reply parsen aus result.details.reply (sessions_send Antwort-Struktur)
- ChatRequest.Model: SessionKey → AgentId
- Controller default: 'iris' → Agent-ID (nicht Session-Key)
2026-06-10 00:58:04 +02:00
5 changed files with 27 additions and 17 deletions
+1 -1
View File
@@ -1 +1 @@
0.2.36 0.2.38
+4 -4
View File
@@ -95,11 +95,11 @@ public class DashboardController(OpenClawGatewayClient gateway, ILogger<Dashboar
try try
{ {
var sessionKey = string.IsNullOrWhiteSpace(request.SessionKey) var agentId = string.IsNullOrWhiteSpace(request.AgentId)
? "iris" ? "iris"
: request.SessionKey.Trim(); : request.AgentId.Trim();
return await gateway.SendChatMessageAsync(sessionKey, request.Message.Trim()); return await gateway.SendChatMessageAsync(agentId, request.Message.Trim());
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -119,7 +119,7 @@ public class DashboardController(OpenClawGatewayClient gateway, ILogger<Dashboar
{ {
try try
{ {
var key = string.IsNullOrWhiteSpace(sessionKey) ? "iris" : sessionKey.Trim(); var key = string.IsNullOrWhiteSpace(sessionKey) ? "agent:iris:main" : sessionKey.Trim();
var messages = await gateway.GetSessionHistoryAsync(key, Math.Clamp(limit, 1, 200), Math.Max(0, offset)); var messages = await gateway.GetSessionHistoryAsync(key, Math.Clamp(limit, 1, 200), Math.Max(0, offset));
// Filter: only user and assistant messages (exclude tool/system) // Filter: only user and assistant messages (exclude tool/system)
+1 -1
View File
@@ -17,7 +17,7 @@ public sealed record MessageEntry(
public sealed record ChatRequest( public sealed record ChatRequest(
string Message, string Message,
string? SessionKey string? AgentId
); );
public sealed record ChatResponse( public sealed record ChatResponse(
+8 -5
View File
@@ -173,18 +173,21 @@ public sealed class OpenClawGatewayClient(HttpClient httpClient, IConfiguration
} }
} }
public async Task<ChatResponse> SendChatMessageAsync(string sessionKey, string message) public async Task<ChatResponse> SendChatMessageAsync(string agentId, string message)
{ {
try try
{ {
var result = await InvokeToolAsync("sessions_send", new { sessionKey, message }); var result = await InvokeToolAsync("sessions_send", new { agentId, message });
if (result is null) return new ChatResponse(false, null, "Gateway nicht erreichbar"); if (result is null) return new ChatResponse(false, null, "Gateway nicht erreichbar");
var ok = result["ok"]?.GetValue<bool>() ?? false; // sessions_send reply is in details.reply or content[0].text
var reply = result["reply"]?.GetValue<string>() var details = result["details"];
var ok = (details?["status"]?.GetValue<string>() ?? result["status"]?.GetValue<string>()) == "ok";
var reply = details?["reply"]?.GetValue<string>()
?? result["reply"]?.GetValue<string>()
?? result["response"]?.GetValue<string>() ?? result["response"]?.GetValue<string>()
?? result["content"]?[0]?["text"]?.GetValue<string>(); ?? result["content"]?[0]?["text"]?.GetValue<string>();
var error = result["error"]?.GetValue<string>(); var error = details?["error"]?.GetValue<string>() ?? result["error"]?.GetValue<string>();
return new ChatResponse(ok, reply, error); return new ChatResponse(ok, reply, error);
} }
+11 -4
View File
@@ -280,12 +280,19 @@ async function fetchChatMessages(): Promise<void> {
const res = await apiFetch('/api/dashboard/chat/messages?limit=50') const res = await apiFetch('/api/dashboard/chat/messages?limit=50')
if (!res.ok) return if (!res.ok) return
const data: DashboardChatMessage[] = await res.json() const data: DashboardChatMessage[] = await res.json()
chatMessages.value = data.map((msg, idx) => ({ // Merge instead of replace — only add messages not already present
id: `msg-${idx}`, const existingTexts = new Set(chatMessages.value.map(m => m.text))
const existingTimestamps = new Set(chatMessages.value.map(m => m.timestamp))
for (const msg of data) {
const msgTime = new Date(msg.timestamp).getTime()
if (existingTexts.has(msg.content) && existingTimestamps.has(msgTime)) continue
chatMessages.value.push({
id: `msg-${msgTime}-${msg.role}`,
sender: msg.role === 'assistant' ? 'iris' : 'user', sender: msg.role === 'assistant' ? 'iris' : 'user',
text: msg.content, text: msg.content,
timestamp: new Date(msg.timestamp).getTime(), timestamp: msgTime,
})) })
}
} catch { } catch {
// API unreachable keep current values // API unreachable keep current values
} }