From b866c0fd278d3724aab65860b017610dd8e06286 Mon Sep 17 00:00:00 2001 From: kone Date: Sun, 17 May 2026 06:45:35 +0800 Subject: [PATCH] fix: satisfy backend lint --- backend/cmd/server/main.go | 2 +- backend/internal/domain/constants.go | 4 +- backend/internal/pkg/kiro/fingerprint.go | 2 +- backend/internal/pkg/kiro/translator.go | 178 +++++++++--------- backend/internal/pkg/kiro/websearch.go | 68 +++---- backend/internal/pkg/kiro/websearch_stream.go | 36 ++-- backend/internal/pkg/kirocooldown/store.go | 2 +- backend/internal/service/kiro_http_helpers.go | 2 +- backend/internal/service/kiro_runtime.go | 2 +- backend/internal/service/kiro_websearch.go | 6 +- 10 files changed, 147 insertions(+), 155 deletions(-) diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index e32b4484..752d4e49 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -80,7 +80,7 @@ func main() { runMainServer() } -func runSetupServer() { +func runSetupServer() { //nolint:unused // kept for setup wizard server mode restoration. r := gin.New() r.Use(middleware.Recovery()) r.Use(middleware.CORS(config.CORSConfig{})) diff --git a/backend/internal/domain/constants.go b/backend/internal/domain/constants.go index c631fa17..52096d89 100644 --- a/backend/internal/domain/constants.go +++ b/backend/internal/domain/constants.go @@ -12,8 +12,8 @@ const ( // Role constants const ( - RoleAdmin = "admin" - RoleUser = "user" + RoleAdmin = "admin" + RoleUser = "user" RoleUserAdmin = "useradmin" ) diff --git a/backend/internal/pkg/kiro/fingerprint.go b/backend/internal/pkg/kiro/fingerprint.go index 461b3411..e566a537 100644 --- a/backend/internal/pkg/kiro/fingerprint.go +++ b/backend/internal/pkg/kiro/fingerprint.go @@ -177,7 +177,7 @@ func sha256Hex(seed string) string { func isHexString(value string) bool { for _, c := range value { - if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + if (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') { return false } } diff --git a/backend/internal/pkg/kiro/translator.go b/backend/internal/pkg/kiro/translator.go index 2fecbe02..3f1b42d1 100644 --- a/backend/internal/pkg/kiro/translator.go +++ b/backend/internal/pkg/kiro/translator.go @@ -159,7 +159,7 @@ type KiroToolSpecification struct { } type KiroInputSchema struct { - JSON interface{} `json:"json"` + JSON any `json:"json"` } type KiroAssistantResponseMessage struct { @@ -168,11 +168,11 @@ type KiroAssistantResponseMessage struct { } type KiroToolUse struct { - ToolUseID string `json:"toolUseId"` - Name string `json:"name"` - Input map[string]interface{} `json:"input"` - IsTruncated bool `json:"-"` - TruncatedRaw string `json:"-"` + ToolUseID string `json:"toolUseId"` + Name string `json:"name"` + Input map[string]any `json:"input"` + IsTruncated bool `json:"-"` + TruncatedRaw string `json:"-"` } type toolUseState struct { @@ -501,7 +501,7 @@ func StreamEventStreamAsAnthropicWithContext(ctx context.Context, body io.Reader }, }) } - processStreamingToolUseEvent := func(event map[string]interface{}) error { + processStreamingToolUseEvent := func(event map[string]any) error { tu := nestedEvent(event, "toolUseEvent") toolUseID := getString(tu, "toolUseId") name := getString(tu, "name") @@ -514,7 +514,7 @@ func StreamEventStreamAsAnthropicWithContext(ctx context.Context, body io.Reader if err := emitStreamingToolInput(toolUseID, name, v); err != nil { return err } - case map[string]interface{}: + case map[string]any: encoded, err := json.Marshal(v) if err != nil { return err @@ -825,7 +825,7 @@ func StreamEventStreamAsAnthropicWithContext(ctx context.Context, body io.Reader continue } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal(msg.Payload, &event); err != nil { continue } @@ -988,10 +988,6 @@ func extractSystemPrompt(claudeBody []byte) string { return systemField.String() } -func isThinkingEnabledWithHeaders(body []byte, headers http.Header) bool { - return deriveThinkingDirective(body, headers) != nil -} - func deriveThinkingDirective(body []byte, headers http.Header) *thinkingDirective { if override := thinkingDirectiveFromModel(gjson.GetBytes(body, "model").String()); override != nil { return override @@ -1129,10 +1125,6 @@ func isToolChoiceNone(claudeBody []byte) bool { return strings.EqualFold(strings.TrimSpace(toolChoice.Get("type").String()), "none") } -func kiroToolNameAlias(name string) string { - return mapKiroToolName(name, nil) -} - func prependSystemHistory(history []KiroHistoryMessage, systemPrompt, modelID, origin string) []KiroHistoryMessage { systemPrompt = strings.TrimSpace(systemPrompt) if systemPrompt == "" { @@ -1220,9 +1212,7 @@ func appendChunkedToolDescription(name, description string) string { if suffix == "" { return description } - if strings.Contains(description, suffix) { - description = strings.Replace(description, suffix, "", 1) - } + description = strings.Replace(description, suffix, "", 1) if strings.TrimSpace(description) == "" { return suffix } @@ -1311,11 +1301,11 @@ func normalizeKiroJSONSchema(schema any) any { } func normalizeKiroJSONSchemaValue(schema any, enforceObjectKeywords bool) any { - obj, ok := schema.(map[string]interface{}) + obj, ok := schema.(map[string]any) if !ok || obj == nil { return defaultKiroJSONSchema() } - normalized := make(map[string]interface{}, len(obj)+4) + normalized := make(map[string]any, len(obj)+4) for key, value := range obj { normalized[key] = normalizeSchemaChild(key, value) } @@ -1329,9 +1319,9 @@ func normalizeKiroJSONSchemaValue(schema any, enforceObjectKeywords bool) any { hasSchemaKey(normalized, "required") || hasSchemaKey(normalized, "additionalProperties") if needsObjectKeywords { - properties, ok := normalized["properties"].(map[string]interface{}) + properties, ok := normalized["properties"].(map[string]any) if !ok || properties == nil { - normalized["properties"] = map[string]interface{}{} + normalized["properties"] = map[string]any{} } else { for key, value := range properties { properties[key] = normalizeKiroJSONSchemaValue(value, false) @@ -1341,7 +1331,7 @@ func normalizeKiroJSONSchemaValue(schema any, enforceObjectKeywords bool) any { normalized["required"] = normalizeSchemaRequired(normalized["required"]) switch additional := normalized["additionalProperties"].(type) { case bool: - case map[string]interface{}: + case map[string]any: normalized["additionalProperties"] = normalizeKiroJSONSchemaValue(additional, false) default: normalized["additionalProperties"] = true @@ -1350,26 +1340,26 @@ func normalizeKiroJSONSchemaValue(schema any, enforceObjectKeywords bool) any { return normalized } -func hasSchemaKey(schema map[string]interface{}, key string) bool { +func hasSchemaKey(schema map[string]any, key string) bool { _, ok := schema[key] return ok } -func defaultKiroJSONSchema() map[string]interface{} { - return map[string]interface{}{ +func defaultKiroJSONSchema() map[string]any { + return map[string]any{ "type": "object", - "properties": map[string]interface{}{}, - "required": []interface{}{}, + "properties": map[string]any{}, + "required": []any{}, "additionalProperties": true, } } -func normalizeSchemaRequired(value interface{}) []interface{} { - arr, ok := value.([]interface{}) +func normalizeSchemaRequired(value any) []any { + arr, ok := value.([]any) if !ok { - return []interface{}{} + return []any{} } - out := make([]interface{}, 0, len(arr)) + out := make([]any, 0, len(arr)) for _, item := range arr { if s, ok := item.(string); ok { out = append(out, s) @@ -1378,22 +1368,22 @@ func normalizeSchemaRequired(value interface{}) []interface{} { return out } -func normalizeSchemaChild(key string, value interface{}) interface{} { +func normalizeSchemaChild(key string, value any) any { switch key { case "items", "not": - if obj, ok := value.(map[string]interface{}); ok { + if obj, ok := value.(map[string]any); ok { return normalizeKiroJSONSchemaValue(obj, false) } - if arr, ok := value.([]interface{}); ok { - out := make([]interface{}, 0, len(arr)) + if arr, ok := value.([]any); ok { + out := make([]any, 0, len(arr)) for _, item := range arr { out = append(out, normalizeKiroJSONSchemaValue(item, false)) } return out } case "oneOf", "anyOf", "allOf": - if arr, ok := value.([]interface{}); ok { - out := make([]interface{}, 0, len(arr)) + if arr, ok := value.([]any); ok { + out := make([]any, 0, len(arr)) for _, item := range arr { out = append(out, normalizeKiroJSONSchemaValue(item, false)) } @@ -1658,7 +1648,7 @@ func buildAssistantMessageStruct(msg gjson.Result, requestCtx *KiroRequestContex _, _ = contentBuilder.WriteString(part.Get("text").String()) case "tool_use": toolName := mapKiroToolName(part.Get("name").String(), requestCtx) - input := map[string]interface{}{} + input := map[string]any{} toolInput := part.Get("input") if toolInput.IsObject() { toolInput.ForEach(func(key, value gjson.Result) bool { @@ -1704,7 +1694,7 @@ func mergeAdjacentMessages(messages []gjson.Result) []gjson.Result { merged = append(merged, msg) continue } - mergedMsg := map[string]interface{}{ + mergedMsg := map[string]any{ "role": role, "content": json.RawMessage(mergeMessageContent(lastMsg, msg)), } @@ -1715,7 +1705,7 @@ func mergeAdjacentMessages(messages []gjson.Result) []gjson.Result { } func mergeMessageContent(msg1, msg2 gjson.Result) string { - var blocks1, blocks2 []map[string]interface{} + var blocks1, blocks2 []map[string]any content1 := msg1.Get("content") content2 := msg2.Get("content") if content1.IsArray() { @@ -1723,14 +1713,14 @@ func mergeMessageContent(msg1, msg2 gjson.Result) string { blocks1 = append(blocks1, blockToMap(block)) } } else if content1.Type == gjson.String { - blocks1 = append(blocks1, map[string]interface{}{"type": "text", "text": content1.String()}) + blocks1 = append(blocks1, map[string]any{"type": "text", "text": content1.String()}) } if content2.IsArray() { for _, block := range content2.Array() { blocks2 = append(blocks2, blockToMap(block)) } } else if content2.Type == gjson.String { - blocks2 = append(blocks2, map[string]interface{}{"type": "text", "text": content2.String()}) + blocks2 = append(blocks2, map[string]any{"type": "text", "text": content2.String()}) } if len(blocks1) > 0 && len(blocks2) > 0 && blocks1[len(blocks1)-1]["type"] == "text" && blocks2[0]["type"] == "text" { leftText, leftOK := blocks1[len(blocks1)-1]["text"].(string) @@ -1745,13 +1735,13 @@ func mergeMessageContent(msg1, msg2 gjson.Result) string { return string(result) } -func blockToMap(block gjson.Result) map[string]interface{} { - result := make(map[string]interface{}) +func blockToMap(block gjson.Result) map[string]any { + result := make(map[string]any) block.ForEach(func(key, value gjson.Result) bool { if value.IsObject() { result[key.String()] = blockToMap(value) } else if value.IsArray() { - var arr []interface{} + var arr []any for _, item := range value.Array() { if item.IsObject() { arr = append(arr, blockToMap(item)) @@ -1789,7 +1779,7 @@ func parseEventStream(body io.Reader) (string, []KiroToolUse, Usage, string, err continue } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal(msg.Payload, &event); err != nil { continue } @@ -1835,8 +1825,8 @@ func parseEventStream(body io.Reader) (string, []KiroToolUse, Usage, string, err } if currentTool != nil && currentTool.ToolUseID != "" && !processedIDs[currentTool.ToolUseID] { - completed, _ := processToolUseEvent(map[string]interface{}{ - "toolUseEvent": map[string]interface{}{ + completed, _ := processToolUseEvent(map[string]any{ + "toolUseEvent": map[string]any{ "toolUseId": currentTool.ToolUseID, "name": currentTool.Name, "stop": true, @@ -1866,7 +1856,7 @@ func parseEventStream(body io.Reader) (string, []KiroToolUse, Usage, string, err } func buildClaudeResponse(content string, toolUses []KiroToolUse, model string, usage Usage, stopReason string, requestCtx KiroRequestContext) []byte { - var blocks []map[string]interface{} + var blocks []map[string]any blocks = append(blocks, extractThinkingBlocks(content)...) usableTools := 0 for _, tool := range toolUses { @@ -1874,7 +1864,7 @@ func buildClaudeResponse(content string, toolUses []KiroToolUse, model string, u continue } usableTools++ - blocks = append(blocks, map[string]interface{}{ + blocks = append(blocks, map[string]any{ "type": "tool_use", "id": tool.ToolUseID, "name": restoreResponseToolName(tool.Name, requestCtx), @@ -1883,11 +1873,11 @@ func buildClaudeResponse(content string, toolUses []KiroToolUse, model string, u } pureThinking := hasThinkingBlocksOnly(blocks) && usableTools == 0 if pureThinking { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": ""}) + blocks = append(blocks, map[string]any{"type": "text", "text": ""}) stopReason = "max_tokens" } if len(blocks) == 0 { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": ""}) + blocks = append(blocks, map[string]any{"type": "text", "text": ""}) } if stopReason == "" { if usableTools > 0 { @@ -1896,14 +1886,14 @@ func buildClaudeResponse(content string, toolUses []KiroToolUse, model string, u stopReason = "end_turn" } } - response := map[string]interface{}{ + response := map[string]any{ "id": "msg_" + uuid.NewString()[:24], "type": "message", "role": "assistant", "model": model, "content": blocks, "stop_reason": stopReason, - "usage": map[string]interface{}{ + "usage": map[string]any{ "input_tokens": usage.InputTokens, "output_tokens": usage.OutputTokens, "cache_read_input_tokens": usage.CacheReadInputTokens, @@ -1925,7 +1915,7 @@ func restoreResponseToolName(name string, requestCtx KiroRequestContext) string return name } -func hasThinkingBlocksOnly(blocks []map[string]interface{}) bool { +func hasThinkingBlocksOnly(blocks []map[string]any) bool { if len(blocks) == 0 { return false } @@ -1944,36 +1934,36 @@ func hasThinkingBlocksOnly(blocks []map[string]interface{}) bool { return hasThinking } -func extractThinkingBlocks(content string) []map[string]interface{} { +func extractThinkingBlocks(content string) []map[string]any { if content == "" { return nil } if findRealThinkingStartTag(content, 0) == -1 { - return []map[string]interface{}{{"type": "text", "text": content}} + return []map[string]any{{"type": "text", "text": content}} } - var blocks []map[string]interface{} + var blocks []map[string]any pos := 0 for pos < len(content) { start := findRealThinkingStartTag(content, pos) if start == -1 { if text := content[pos:]; strings.TrimSpace(text) != "" { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": text}) + blocks = append(blocks, map[string]any{"type": "text", "text": text}) } break } end := findRealThinkingEndTag(content, start+len(thinkingStartTag)) if end == -1 { if text := content[pos:]; strings.TrimSpace(text) != "" { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": text}) + blocks = append(blocks, map[string]any{"type": "text", "text": text}) } break } if text := content[pos:start]; strings.TrimSpace(text) != "" { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": text}) + blocks = append(blocks, map[string]any{"type": "text", "text": text}) } thinking := strings.TrimPrefix(content[start+len(thinkingStartTag):end], "\n") if strings.TrimSpace(thinking) != "" { - blocks = append(blocks, map[string]interface{}{ + blocks = append(blocks, map[string]any{ "type": "thinking", "thinking": thinking, "signature": thinkingSignature(thinking), @@ -1985,7 +1975,7 @@ func extractThinkingBlocks(content string) []map[string]interface{} { } } if len(blocks) == 0 { - blocks = append(blocks, map[string]interface{}{"type": "text", "text": ""}) + blocks = append(blocks, map[string]any{"type": "text", "text": ""}) } return blocks } @@ -2238,19 +2228,19 @@ func skipHeaderValue(headers []byte, offset int, valueType byte) (int, bool) { } } -func processToolUseEvent(event map[string]interface{}, currentTool *toolUseState, processedIDs map[string]bool) ([]KiroToolUse, *toolUseState) { +func processToolUseEvent(event map[string]any, currentTool *toolUseState, processedIDs map[string]bool) ([]KiroToolUse, *toolUseState) { tu := nestedEvent(event, "toolUseEvent") toolUseID := getString(tu, "toolUseId") name := getString(tu, "name") isStop, _ := tu["stop"].(bool) var inputFragment string - var inputMap map[string]interface{} + var inputMap map[string]any if inputRaw, ok := tu["input"]; ok { switch v := inputRaw.(type) { case string: inputFragment = v - case map[string]interface{}: + case map[string]any: inputMap = v } } @@ -2283,7 +2273,7 @@ func repairJSON(input string) string { if str == "" { return "{}" } - var parsed interface{} + var parsed any if err := json.Unmarshal([]byte(str), &parsed); err == nil { return str } @@ -2382,7 +2372,7 @@ func finalizeRawToolUse(toolUseID, name, rawInput string) KiroToolUse { tool := KiroToolUse{ ToolUseID: toolUseID, Name: normalizeResponseToolName(name), - Input: map[string]interface{}{}, + Input: map[string]any{}, } rawInput = strings.TrimSpace(rawInput) tool.TruncatedRaw = rawInput @@ -2394,9 +2384,9 @@ func finalizeRawToolUse(toolUseID, name, rawInput string) KiroToolUse { return tool } -func finalizeStructuredToolUse(toolUseID, name string, input map[string]interface{}) KiroToolUse { +func finalizeStructuredToolUse(toolUseID, name string, input map[string]any) KiroToolUse { if input == nil { - input = map[string]interface{}{} + input = map[string]any{} } tool := KiroToolUse{ ToolUseID: toolUseID, @@ -2508,14 +2498,14 @@ func parseEmbeddedToolCalls(text string) (string, []KiroToolUse) { for index < len(text) { start := strings.Index(text[index:], embeddedToolCallPrefix) if start == -1 { - builder.WriteString(text[index:]) + _, _ = builder.WriteString(text[index:]) break } start += index - builder.WriteString(text[index:start]) + _, _ = builder.WriteString(text[index:start]) tool, _, end, ok := parseEmbeddedToolCallAt(text, start) if !ok { - builder.WriteString(text[start:]) + _, _ = builder.WriteString(text[start:]) break } toolUses = append(toolUses, tool) @@ -2596,7 +2586,7 @@ func findMatchingJSONBracket(text string, start int) int { return -1 } -func isTruncatedToolUse(name, rawInput string, input map[string]interface{}) bool { +func isTruncatedToolUse(name, rawInput string, input map[string]any) bool { rawInput = strings.TrimSpace(rawInput) if rawInput == "" { return hasToolRequirements(name) @@ -2625,7 +2615,7 @@ func hasToolRequirements(name string) bool { return ok } -func hasMissingRequiredFields(name string, input map[string]interface{}) bool { +func hasMissingRequiredFields(name string, input map[string]any) bool { groups, ok := requiredToolFields[strings.ToLower(strings.TrimSpace(name))] if !ok { return false @@ -2645,7 +2635,7 @@ func hasMissingRequiredFields(name string, input map[string]interface{}) bool { return false } -func updateUsageFromEvent(usage *Usage, eventType string, event map[string]interface{}) { +func updateUsageFromEvent(usage *Usage, eventType string, event map[string]any) { if usage == nil { return } @@ -2653,7 +2643,7 @@ func updateUsageFromEvent(usage *Usage, eventType string, event map[string]inter if len(meta) == 0 { meta = event } - if tokenUsage, ok := meta["tokenUsage"].(map[string]interface{}); ok { + if tokenUsage, ok := meta["tokenUsage"].(map[string]any); ok { if value, ok := firstInt(tokenUsage, "uncachedInputTokens", "inputTokens", "inputTokenCount", "promptTokens", "prompt_tokens"); ok { usage.InputTokens = value } @@ -2707,7 +2697,7 @@ func updateUsageFromEvent(usage *Usage, eventType string, event map[string]inter } } -func firstInt(m map[string]interface{}, keys ...string) (int, bool) { +func firstInt(m map[string]any, keys ...string) (int, bool) { for _, key := range keys { if value, ok := toInt(m[key]); ok { return value, true @@ -2716,7 +2706,7 @@ func firstInt(m map[string]interface{}, keys ...string) (int, bool) { return 0, false } -func firstFloat(m map[string]interface{}, keys ...string) (float64, bool) { +func firstFloat(m map[string]any, keys ...string) (float64, bool) { for _, key := range keys { switch v := m[key].(type) { case float64: @@ -2786,11 +2776,11 @@ func countKiroTextTokens(text string) int { return tokens } -func readToolUses(primary, fallback map[string]interface{}) []KiroToolUse { - var raw []interface{} - if value, ok := primary["toolUses"].([]interface{}); ok { +func readToolUses(primary, fallback map[string]any) []KiroToolUse { + var raw []any + if value, ok := primary["toolUses"].([]any); ok { raw = value - } else if value, ok := fallback["toolUses"].([]interface{}); ok { + } else if value, ok := fallback["toolUses"].([]any); ok { raw = value } if len(raw) == 0 { @@ -2798,12 +2788,12 @@ func readToolUses(primary, fallback map[string]interface{}) []KiroToolUse { } out := make([]KiroToolUse, 0, len(raw)) for _, item := range raw { - tool, ok := item.(map[string]interface{}) + tool, ok := item.(map[string]any) if !ok { continue } - input := map[string]interface{}{} - if value, ok := tool["input"].(map[string]interface{}); ok { + input := map[string]any{} + if value, ok := tool["input"].(map[string]any); ok { input = value } out = append(out, finalizeStructuredToolUse(getString(tool, "toolUseId"), getString(tool, "name"), input)) @@ -2811,28 +2801,28 @@ func readToolUses(primary, fallback map[string]interface{}) []KiroToolUse { return out } -func nestedEvent(event map[string]interface{}, key string) map[string]interface{} { - if nested, ok := event[key].(map[string]interface{}); ok { +func nestedEvent(event map[string]any, key string) map[string]any { + if nested, ok := event[key].(map[string]any); ok { return nested } return event } -func getString(m map[string]interface{}, key string) string { +func getString(m map[string]any, key string) string { if value, ok := m[key].(string); ok { return value } return "" } -func readStopReason(m map[string]interface{}) string { +func readStopReason(m map[string]any) string { if stop := getString(m, "stop_reason"); stop != "" { return stop } return getString(m, "stopReason") } -func toInt(value interface{}) (int, bool) { +func toInt(value any) (int, bool) { switch v := value.(type) { case float64: return int(v), true diff --git a/backend/internal/pkg/kiro/websearch.go b/backend/internal/pkg/kiro/websearch.go index 28987852..4bae249d 100644 --- a/backend/internal/pkg/kiro/websearch.go +++ b/backend/internal/pkg/kiro/websearch.go @@ -17,10 +17,10 @@ const remoteWebSearchDescription = "WebSearch looks up information outside the m var cachedWebSearchDescription atomic.Value // stores string type MCPRequest struct { - ID string `json:"id"` - JSONRPC string `json:"jsonrpc"` - Method string `json:"method"` - Params interface{} `json:"params,omitempty"` + ID string `json:"id"` + JSONRPC string `json:"jsonrpc"` + Method string `json:"method"` + Params any `json:"params,omitempty"` } type MCPResponse struct { @@ -63,7 +63,9 @@ type SearchIndicator struct { func GetCachedWebSearchDescription() string { if v := cachedWebSearchDescription.Load(); v != nil { - return strings.TrimSpace(v.(string)) + if desc, ok := v.(string); ok { + return strings.TrimSpace(desc) + } } return "" } @@ -138,18 +140,18 @@ func GenerateToolUseID() string { } func ReplaceWebSearchToolDescription(body []byte) ([]byte, error) { - var payload map[string]interface{} + var payload map[string]any if err := json.Unmarshal(body, &payload); err != nil { return body, err } - rawTools, ok := payload["tools"].([]interface{}) + rawTools, ok := payload["tools"].([]any) if !ok { return body, nil } - replaced := make([]interface{}, 0, len(rawTools)) + replaced := make([]any, 0, len(rawTools)) for _, rawTool := range rawTools { - tool, ok := rawTool.(map[string]interface{}) + tool, ok := rawTool.(map[string]any) if !ok { replaced = append(replaced, rawTool) continue @@ -160,13 +162,13 @@ func ReplaceWebSearchToolDescription(body []byte) ([]byte, error) { replaced = append(replaced, rawTool) continue } - replaced = append(replaced, map[string]interface{}{ + replaced = append(replaced, map[string]any{ "name": "web_search", "description": minimalWebSearchDescription, - "input_schema": map[string]interface{}{ + "input_schema": map[string]any{ "type": "object", - "properties": map[string]interface{}{ - "query": map[string]interface{}{ + "properties": map[string]any{ + "query": map[string]any{ "type": "string", "description": "The search query to execute", }, @@ -186,42 +188,42 @@ func ReplaceWebSearchToolDescription(body []byte) ([]byte, error) { } func InjectToolResultsClaude(claudePayload []byte, toolUseID, query string, results *WebSearchResults) ([]byte, error) { - var payload map[string]interface{} + var payload map[string]any if err := json.Unmarshal(claudePayload, &payload); err != nil { return claudePayload, fmt.Errorf("parse claude payload: %w", err) } - rawMessages, ok := payload["messages"].([]interface{}) + rawMessages, ok := payload["messages"].([]any) if !ok { return claudePayload, fmt.Errorf("claude payload missing messages array") } - assistantMsg := map[string]interface{}{ + assistantMsg := map[string]any{ "role": "assistant", - "content": []interface{}{ - map[string]interface{}{ + "content": []any{ + map[string]any{ "type": "tool_use", "id": toolUseID, "name": "web_search", - "input": map[string]interface{}{"query": query}, + "input": map[string]any{"query": query}, }, }, } - userContent := []interface{}{ - map[string]interface{}{ + userContent := []any{ + map[string]any{ "type": "tool_result", "tool_use_id": toolUseID, "content": formatToolResultText(results), }, } if guidance := searchGuidanceText(); guidance != "" { - userContent = append(userContent, map[string]interface{}{ + userContent = append(userContent, map[string]any{ "type": "text", "text": guidance, }) } - userMsg := map[string]interface{}{ + userMsg := map[string]any{ "role": "user", "content": userContent, } @@ -240,20 +242,20 @@ func InjectSearchIndicatorsInResponse(responsePayload []byte, searches []SearchI return responsePayload, nil } - var response map[string]interface{} + var response map[string]any if err := json.Unmarshal(responsePayload, &response); err != nil { return responsePayload, err } - content, _ := response["content"].([]interface{}) - updated := make([]interface{}, 0, len(searches)*2+len(content)) + content, _ := response["content"].([]any) + updated := make([]any, 0, len(searches)*2+len(content)) for _, search := range searches { - updated = append(updated, map[string]interface{}{ + updated = append(updated, map[string]any{ "type": "server_tool_use", "id": search.ToolUseID, "name": "web_search", - "input": map[string]interface{}{"query": search.Query}, + "input": map[string]any{"query": search.Query}, }) - updated = append(updated, map[string]interface{}{ + updated = append(updated, map[string]any{ "type": "web_search_tool_result", "content": buildSearchResultContent(search.Results), }) @@ -268,8 +270,8 @@ func InjectSearchIndicatorsInResponse(responsePayload []byte, searches []SearchI return encoded, nil } -func buildSearchResultContent(results *WebSearchResults) []map[string]interface{} { - content := make([]map[string]interface{}, 0) +func buildSearchResultContent(results *WebSearchResults) []map[string]any { + content := make([]map[string]any, 0) if results == nil { return content } @@ -278,7 +280,7 @@ func buildSearchResultContent(results *WebSearchResults) []map[string]interface{ if result.Snippet != nil { snippet = strings.TrimSpace(*result.Snippet) } - content = append(content, map[string]interface{}{ + content = append(content, map[string]any{ "type": "web_search_result", "title": result.Title, "url": result.URL, @@ -325,7 +327,7 @@ func isWebSearchToolName(name, toolType string) bool { } } -func getInterfaceString(v interface{}) string { +func getInterfaceString(v any) string { if v == nil { return "" } diff --git a/backend/internal/pkg/kiro/websearch_stream.go b/backend/internal/pkg/kiro/websearch_stream.go index 2a6a910a..0beffd7b 100644 --- a/backend/internal/pkg/kiro/websearch_stream.go +++ b/backend/internal/pkg/kiro/websearch_stream.go @@ -14,14 +14,14 @@ type BufferedStreamResult struct { } func GenerateSearchIndicatorEvents(query, toolUseID string, results *WebSearchResults, startIndex int) [][]byte { - searchContent := make([]map[string]interface{}, 0) + searchContent := make([]map[string]any, 0) if results != nil { for _, result := range results.Results { snippet := "" if result.Snippet != nil { snippet = strings.TrimSpace(*result.Snippet) } - searchContent = append(searchContent, map[string]interface{}{ + searchContent = append(searchContent, map[string]any{ "type": "web_search_result", "title": result.Title, "url": result.URL, @@ -33,21 +33,21 @@ func GenerateSearchIndicatorEvents(query, toolUseID string, results *WebSearchRe inputJSON, _ := json.Marshal(map[string]string{"query": query}) - events := []map[string]interface{}{ + events := []map[string]any{ { "type": "content_block_start", "index": startIndex, - "content_block": map[string]interface{}{ + "content_block": map[string]any{ "type": "server_tool_use", "id": toolUseID, "name": "web_search", - "input": map[string]interface{}{}, + "input": map[string]any{}, }, }, { "type": "content_block_delta", "index": startIndex, - "delta": map[string]interface{}{ + "delta": map[string]any{ "type": "input_json_delta", "partial_json": string(inputJSON), }, @@ -59,7 +59,7 @@ func GenerateSearchIndicatorEvents(query, toolUseID string, results *WebSearchRe { "type": "content_block_start", "index": startIndex + 1, - "content_block": map[string]interface{}{ + "content_block": map[string]any{ "type": "web_search_tool_result", "content": searchContent, }, @@ -96,20 +96,20 @@ func AnalyzeBufferedStream(chunks [][]byte) BufferedStreamResult { continue } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal([]byte(payload), &event); err != nil { continue } switch eventType, _ := event["type"].(string); eventType { case "message_delta": - if delta, ok := event["delta"].(map[string]interface{}); ok { + if delta, ok := event["delta"].(map[string]any); ok { if stopReason, ok := delta["stop_reason"].(string); ok && strings.TrimSpace(stopReason) != "" { result.StopReason = stopReason } } case "content_block_start": - contentBlock, ok := event["content_block"].(map[string]interface{}) + contentBlock, ok := event["content_block"].(map[string]any) if !ok { continue } @@ -130,7 +130,7 @@ func AnalyzeBufferedStream(chunks [][]byte) BufferedStreamResult { if currentToolName == "" { continue } - delta, ok := event["delta"].(map[string]interface{}) + delta, ok := event["delta"].(map[string]any) if !ok { continue } @@ -139,7 +139,7 @@ func AnalyzeBufferedStream(chunks [][]byte) BufferedStreamResult { continue } if partialJSON, ok := delta["partial_json"].(string); ok { - toolInputBuilder.WriteString(partialJSON) + _, _ = toolInputBuilder.WriteString(partialJSON) } case "content_block_stop": if !isWebSearchToolName(currentToolName, "") { @@ -191,7 +191,7 @@ func MaxContentBlockIndex(chunks [][]byte) int { if payload == "" || payload == "[DONE]" { continue } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal([]byte(payload), &event); err != nil { continue } @@ -221,7 +221,7 @@ func filterSSEChunk(chunk []byte, webSearchToolUseIndex, indexOffset int) ([]byt continue } } - builder.WriteString(line + "\n") + _, _ = builder.WriteString(line + "\n") hasContent = true continue } @@ -238,12 +238,12 @@ func filterSSEChunk(chunk []byte, webSearchToolUseIndex, indexOffset int) ([]byt if adjusted == "" { continue } - builder.WriteString("data: " + adjusted + "\n") + _, _ = builder.WriteString("data: " + adjusted + "\n") hasContent = true continue } - builder.WriteString(line + "\n") + _, _ = builder.WriteString(line + "\n") if strings.TrimSpace(line) != "" { hasContent = true } @@ -259,7 +259,7 @@ func shouldSuppressEventPayload(payload string, webSearchToolUseIndex int) bool if payload == "" { return false } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal([]byte(payload), &event); err != nil { return false } @@ -280,7 +280,7 @@ func adjustEventPayload(payload string, indexOffset int) string { if payload == "" || indexOffset == 0 { return payload } - var event map[string]interface{} + var event map[string]any if err := json.Unmarshal([]byte(payload), &event); err != nil { return payload } diff --git a/backend/internal/pkg/kirocooldown/store.go b/backend/internal/pkg/kirocooldown/store.go index b2a9980d..cbde780c 100644 --- a/backend/internal/pkg/kirocooldown/store.go +++ b/backend/internal/pkg/kirocooldown/store.go @@ -185,7 +185,7 @@ func (s *Store) ReserveRequest(ctx context.Context, tokenKey string) (time.Durat if err != nil { return 0, fmt.Errorf("kiro cooldown reserve request: %w", err) } - parts, ok := values.([]interface{}) + parts, ok := values.([]any) if !ok || len(parts) != 3 { return 0, fmt.Errorf("kiro cooldown reserve request: unexpected response %T", values) } diff --git a/backend/internal/service/kiro_http_helpers.go b/backend/internal/service/kiro_http_helpers.go index 351eb17a..11a3672d 100644 --- a/backend/internal/service/kiro_http_helpers.go +++ b/backend/internal/service/kiro_http_helpers.go @@ -84,7 +84,7 @@ func buildKiroRequestID(resp *http.Response) string { return strings.TrimSpace(resp.Header.Get("x-amz-request-id")) } -func isKiroInvalidModelIDBody(respBody []byte) bool { +func isKiroInvalidModelIDBody(respBody []byte) bool { //nolint:unused // exercised by internal tests for error classification. var payload struct { Reason string `json:"reason"` Message string `json:"message"` diff --git a/backend/internal/service/kiro_runtime.go b/backend/internal/service/kiro_runtime.go index f277d2f8..360fef59 100644 --- a/backend/internal/service/kiro_runtime.go +++ b/backend/internal/service/kiro_runtime.go @@ -491,7 +491,7 @@ func buildKiroEndpoints(account *Account) []kiroEndpointConfig { } } -func buildKiroPayloadForAccount(ctx context.Context, account *Account, anthropicBody []byte, modelID, token, requestModel string, headers http.Header) ([]byte, error) { +func buildKiroPayloadForAccount(ctx context.Context, account *Account, anthropicBody []byte, modelID, token, requestModel string, headers http.Header) ([]byte, error) { //nolint:unused // exercised by package tests as a narrow payload helper. result, err := buildKiroPayloadForAccountWithRepo(ctx, nil, account, anthropicBody, modelID, token, requestModel, headers) if err != nil { return nil, err diff --git a/backend/internal/service/kiro_websearch.go b/backend/internal/service/kiro_websearch.go index 8e1419cd..b98361e8 100644 --- a/backend/internal/service/kiro_websearch.go +++ b/backend/internal/service/kiro_websearch.go @@ -357,11 +357,11 @@ func buildKiroWebSearchMCPRequest(query string) kiropkg.MCPRequest { ID: fmt.Sprintf("web_search_%s", kiropkg.GenerateToolUseID()), JSONRPC: "2.0", Method: "tools/call", - Params: map[string]interface{}{ + Params: map[string]any{ "name": "web_search", - "arguments": map[string]interface{}{ + "arguments": map[string]any{ "query": query, - "_meta": map[string]interface{}{ + "_meta": map[string]any{ "_isValid": true, "_activePath": []string{"query"}, "_completedPaths": [][]string{{"query"}},