@@ -120,6 +120,7 @@ func GenerateWithTool(
TopK: call.TopK,
PresencePenalty: call.PresencePenalty,
FrequencyPenalty: call.FrequencyPenalty,
+ UserAgent: call.UserAgent,
ProviderOptions: call.ProviderOptions,
})
if err != nil {
@@ -212,6 +213,7 @@ func GenerateWithText(
TopK: call.TopK,
PresencePenalty: call.PresencePenalty,
FrequencyPenalty: call.FrequencyPenalty,
+ UserAgent: call.UserAgent,
ProviderOptions: call.ProviderOptions,
})
if err != nil {
@@ -294,6 +296,7 @@ func StreamWithTool(
TopK: call.TopK,
PresencePenalty: call.PresencePenalty,
FrequencyPenalty: call.FrequencyPenalty,
+ UserAgent: call.UserAgent,
ProviderOptions: call.ProviderOptions,
})
if err != nil {
@@ -503,6 +506,7 @@ func StreamWithText(
TopK: call.TopK,
PresencePenalty: call.PresencePenalty,
FrequencyPenalty: call.FrequencyPenalty,
+ UserAgent: call.UserAgent,
ProviderOptions: call.ProviderOptions,
})
if err != nil {
@@ -34,7 +34,11 @@ func ResolveHeaders(headers map[string]string, explicitUA, defaultUA string) map
}
out["User-Agent"] = explicitUA
case len(uaKeys) > 0:
- // keep the header-map value as-is
+ val := out[uaKeys[0]]
+ for _, k := range uaKeys {
+ delete(out, k)
+ }
+ out["User-Agent"] = val
default:
out["User-Agent"] = defaultUA
}
@@ -60,11 +60,13 @@ func TestResolveHeaders_Precedence(t *testing.T) {
assert.False(t, hasLower, "old case-insensitive key should be removed")
})
- t.Run("case-insensitive header key preserved when no explicit UA", func(t *testing.T) {
+ t.Run("case-insensitive header key canonicalized when no explicit UA", func(t *testing.T) {
t.Parallel()
headers := map[string]string{"user-agent": "from-headers"}
got := ResolveHeaders(headers, "", "default-ua")
- assert.Equal(t, "from-headers", got["user-agent"])
+ assert.Equal(t, "from-headers", got["User-Agent"])
+ _, hasLower := got["user-agent"]
+ assert.False(t, hasLower, "non-canonical key should be removed")
})
}
@@ -95,14 +97,30 @@ func TestResolveHeaders_PreservesOtherHeaders(t *testing.T) {
func TestResolveHeaders_DuplicateCaseInsensitiveKeys(t *testing.T) {
t.Parallel()
- headers := map[string]string{
- "User-Agent": "canonical",
- "user-agent": "lowercase",
- }
- got := ResolveHeaders(headers, "explicit", "default")
- assert.Equal(t, "explicit", got["User-Agent"])
- _, hasLower := got["user-agent"]
- assert.False(t, hasLower, "all case-insensitive UA keys must be removed")
+ t.Run("explicit UA removes all variants", func(t *testing.T) {
+ t.Parallel()
+ headers := map[string]string{
+ "User-Agent": "canonical",
+ "user-agent": "lowercase",
+ }
+ got := ResolveHeaders(headers, "explicit", "default")
+ assert.Equal(t, "explicit", got["User-Agent"])
+ _, hasLower := got["user-agent"]
+ assert.False(t, hasLower, "all case-insensitive UA keys must be removed")
+ })
+
+ t.Run("no explicit UA collapses to single canonical key", func(t *testing.T) {
+ t.Parallel()
+ headers := map[string]string{
+ "User-Agent": "canonical",
+ "user-agent": "lowercase",
+ }
+ got := ResolveHeaders(headers, "", "default")
+ _, hasLower := got["user-agent"]
+ hasCanonical := got["User-Agent"]
+ assert.False(t, hasLower, "non-canonical key should be removed")
+ assert.NotEmpty(t, hasCanonical, "canonical User-Agent key must exist")
+ })
}
func TestCallUserAgent(t *testing.T) {