feat: complete kiro platform support

This commit is contained in:
nianzs
2026-04-30 14:04:02 +08:00
parent fcaa8ea86a
commit b09bcb6a3c
39 changed files with 2057 additions and 158 deletions
@@ -5,6 +5,7 @@ package service
import (
"context"
"encoding/json"
"net/http/httptest"
"testing"
"time"
@@ -13,6 +14,31 @@ import (
"github.com/stretchr/testify/require"
)
func TestWriteSSEMessageStart_IncludesCacheUsageFields(t *testing.T) {
rec := httptest.NewRecorder()
err := writeSSEMessageStart(rec, "msg_test", "claude-sonnet-4-5")
require.NoError(t, err)
body := rec.Body.String()
require.Contains(t, body, `"cache_creation_input_tokens":0`)
require.Contains(t, body, `"cache_read_input_tokens":0`)
}
func TestWriteSSEServerToolUse_UsesInputJSONDelta(t *testing.T) {
rec := httptest.NewRecorder()
err := writeSSEServerToolUse(rec, "srvtoolu_test", "golang concurrency", 0)
require.NoError(t, err)
body := rec.Body.String()
require.Contains(t, body, `event: content_block_start`)
require.Contains(t, body, `"type":"server_tool_use"`)
require.Contains(t, body, `"input":{}`)
require.Contains(t, body, `event: content_block_delta`)
require.Contains(t, body, `"type":"input_json_delta"`)
require.Contains(t, body, `"{\"query\":\"golang concurrency\"}"`)
require.Contains(t, body, `event: content_block_stop`)
}
// --- isOnlyWebSearchToolInBody ---
func TestIsOnlyWebSearchToolInBody_WebSearchType(t *testing.T) {
@@ -111,12 +137,12 @@ func TestBuildSearchResultBlocks_WithResults(t *testing.T) {
require.Len(t, blocks, 2)
require.Equal(t, "web_search_result", blocks[0]["type"])
require.Equal(t, "https://a.com", blocks[0]["url"])
require.Equal(t, "snippet a", blocks[0]["page_content"])
require.Equal(t, "snippet a", blocks[0]["encrypted_content"])
require.Equal(t, "2 days", blocks[0]["page_age"])
// Second result has no PageAge
require.Equal(t, "https://b.com", blocks[1]["url"])
_, hasPageAge := blocks[1]["page_age"]
require.False(t, hasPageAge)
require.Equal(t, "snippet b", blocks[1]["encrypted_content"])
require.Nil(t, blocks[1]["page_age"])
}
func TestBuildSearchResultBlocks_Empty(t *testing.T) {
@@ -126,8 +152,8 @@ func TestBuildSearchResultBlocks_Empty(t *testing.T) {
func TestBuildSearchResultBlocks_SnippetEmpty(t *testing.T) {
blocks := buildSearchResultBlocks([]websearch.SearchResult{{URL: "https://x.com", Title: "X", Snippet: ""}})
_, hasContent := blocks[0]["page_content"]
require.False(t, hasContent)
require.Equal(t, "", blocks[0]["encrypted_content"])
require.Nil(t, blocks[0]["page_age"])
}
// --- buildTextSummary ---
@@ -165,6 +191,14 @@ func newAnthropicAPIKeyAccount(mode string) *Account {
}
}
func newKiroOAuthAccount() *Account {
return &Account{
ID: 2,
Platform: PlatformKiro,
Type: AccountTypeOAuth,
}
}
// setGlobalWebSearchConfig stores a config in the global cache used by SettingService.IsWebSearchEmulationEnabled.
func setGlobalWebSearchConfig(cfg *WebSearchEmulationConfig) {
webSearchEmulationCache.Store(&cachedWebSearchEmulationConfig{
@@ -378,3 +412,75 @@ func TestShouldEmulateWebSearch_DefaultMode_NilChannelService(t *testing.T) {
// nil channelService + default mode → returns false
require.False(t, svc.shouldEmulateWebSearch(context.Background(), account, &groupID, webSearchToolBody))
}
func TestShouldEmulateWebSearch_KiroChannelEnabled(t *testing.T) {
mgr := websearch.NewManager([]websearch.ProviderConfig{{Type: "brave", APIKey: "k"}}, nil)
SetWebSearchManager(mgr)
defer SetWebSearchManager(nil)
setGlobalWebSearchConfig(&WebSearchEmulationConfig{
Enabled: true,
Providers: []WebSearchProviderConfig{{Type: "brave", APIKey: "k"}},
})
defer clearGlobalWebSearchConfig()
settingSvc := newSettingServiceForWebSearchTest(true)
ch := &Channel{
ID: 11,
Status: StatusActive,
FeaturesConfig: map[string]any{
featureKeyWebSearchEmulation: map[string]any{PlatformKiro: true},
},
}
channelSvc := newChannelServiceWithCache(77, ch)
svc := &GatewayService{settingService: settingSvc, channelService: channelSvc}
account := newKiroOAuthAccount()
groupID := int64(77)
require.True(t, svc.shouldEmulateWebSearch(context.Background(), account, &groupID, webSearchToolBody))
}
func TestShouldEmulateWebSearch_KiroChannelDisabledFallsBack(t *testing.T) {
mgr := websearch.NewManager([]websearch.ProviderConfig{{Type: "brave", APIKey: "k"}}, nil)
SetWebSearchManager(mgr)
defer SetWebSearchManager(nil)
setGlobalWebSearchConfig(&WebSearchEmulationConfig{
Enabled: true,
Providers: []WebSearchProviderConfig{{Type: "brave", APIKey: "k"}},
})
defer clearGlobalWebSearchConfig()
settingSvc := newSettingServiceForWebSearchTest(true)
ch := &Channel{
ID: 12,
Status: StatusActive,
FeaturesConfig: map[string]any{
featureKeyWebSearchEmulation: map[string]any{PlatformKiro: false},
},
}
channelSvc := newChannelServiceWithCache(78, ch)
svc := &GatewayService{settingService: settingSvc, channelService: channelSvc}
account := newKiroOAuthAccount()
groupID := int64(78)
require.False(t, svc.shouldEmulateWebSearch(context.Background(), account, &groupID, webSearchToolBody))
}
func TestShouldEmulateWebSearch_KiroRequiresChannelConfig(t *testing.T) {
mgr := websearch.NewManager([]websearch.ProviderConfig{{Type: "brave", APIKey: "k"}}, nil)
SetWebSearchManager(mgr)
defer SetWebSearchManager(nil)
setGlobalWebSearchConfig(&WebSearchEmulationConfig{
Enabled: true,
Providers: []WebSearchProviderConfig{{Type: "brave", APIKey: "k"}},
})
defer clearGlobalWebSearchConfig()
settingSvc := newSettingServiceForWebSearchTest(true)
svc := &GatewayService{settingService: settingSvc}
account := newKiroOAuthAccount()
require.False(t, svc.shouldEmulateWebSearch(context.Background(), account, nil, webSearchToolBody))
}