From 084e2666cb261f0fc0c2ee92e0f38bbb6e0e5e97 Mon Sep 17 00:00:00 2001 From: Ravens Date: Thu, 11 Dec 2025 00:13:44 +0800 Subject: [PATCH] fix(kiro): add SSE event: prefix for Claude client compatibility Amp-Thread-ID: https://ampcode.com/threads/T-019b08fc-ff96-766e-a942-63dd35ed28c6 Co-authored-by: Amp --- .../translator/kiro/claude/kiro_claude.go | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/internal/translator/kiro/claude/kiro_claude.go b/internal/translator/kiro/claude/kiro_claude.go index 9922860e..335873a7 100644 --- a/internal/translator/kiro/claude/kiro_claude.go +++ b/internal/translator/kiro/claude/kiro_claude.go @@ -1,10 +1,14 @@ // Package claude provides translation between Kiro and Claude formats. // Since Kiro uses Claude-compatible format internally, translations are mostly pass-through. +// However, SSE events require proper "event: " prefix for Claude clients. package claude import ( "bytes" "context" + "strings" + + "github.com/tidwall/gjson" ) // ConvertClaudeRequestToKiro converts Claude request to Kiro format. @@ -14,8 +18,52 @@ func ConvertClaudeRequestToKiro(modelName string, inputRawJSON []byte, stream bo } // ConvertKiroResponseToClaude converts Kiro streaming response to Claude format. +// It adds the required "event: " prefix for SSE compliance with Claude clients. +// Input format: "data: {\"type\":\"message_start\",...}" +// Output format: "event: message_start\ndata: {\"type\":\"message_start\",...}" func ConvertKiroResponseToClaude(ctx context.Context, model string, originalRequest, request, rawResponse []byte, param *any) []string { - return []string{string(rawResponse)} + raw := string(rawResponse) + + // Handle multiple data blocks (e.g., message_delta + message_stop) + lines := strings.Split(raw, "\n\n") + var results []string + + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" { + continue + } + + // Extract event type from JSON and add "event:" prefix + formatted := addEventPrefix(line) + if formatted != "" { + results = append(results, formatted) + } + } + + if len(results) == 0 { + return []string{raw} + } + + return results +} + +// addEventPrefix extracts the event type from the data line and adds the event: prefix. +// Input: "data: {\"type\":\"message_start\",...}" +// Output: "event: message_start\ndata: {\"type\":\"message_start\",...}" +func addEventPrefix(dataLine string) string { + if !strings.HasPrefix(dataLine, "data: ") { + return dataLine + } + + jsonPart := strings.TrimPrefix(dataLine, "data: ") + eventType := gjson.Get(jsonPart, "type").String() + + if eventType == "" { + return dataLine + } + + return "event: " + eventType + "\n" + dataLine } // ConvertKiroResponseToClaudeNonStream converts Kiro non-streaming response to Claude format.