Skip to content

feat: add missing OpenAI/Claude/Gemini request fields#2971

Open
seefs001 wants to merge 3 commits intoQuantumNous:mainfrom
seefs001:fix/missing-request-field
Open

feat: add missing OpenAI/Claude/Gemini request fields#2971
seefs001 wants to merge 3 commits intoQuantumNous:mainfrom
seefs001:fix/missing-request-field

Conversation

@seefs001
Copy link
Collaborator

@seefs001 seefs001 commented Feb 19, 2026

Summary by CodeRabbit

  • New Features

    • Channel-level "Allow include obfuscation" toggle for OpenAI and Claude channels.
    • Expanded request options: function call payload, service tier, conversation/context-management fields, safety identifier, and nullable log-prob setting.
    • Admin UI: new "Subscriptions" module in admin sidebar.
  • Improvements

    • Stream and response handling respects channel obfuscation setting; passthrough-enabled flows skip obfuscation removal.
    • Gemini config accepts an enhanced civic answers flag.
  • Tests

    • Added tests ensuring passthrough skips field removal.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

No actionable comments were generated in the recent review. 🎉


Walkthrough

The PR adds a channel setting AllowIncludeObfuscation (DTO + frontend UI) and threads it through relay logic so stream_options.include_obfuscation is removed unless permitted; it also extends several DTOs (OpenAI, Gemini, Claude) with new fields/type adjustments and updates calls to RemoveDisabledFields to accept a pass-through flag.

Changes

Cohort / File(s) Summary
Channel settings DTO
dto/channel_settings.go
Added AllowIncludeObfuscation bool to ChannelOtherSettings to gate inclusion of stream_options.include_obfuscation.
OpenAI request DTOs
dto/openai_request.go
Added FunctionCall, ServiceTier to GeneralOpenAIRequest; added StreamOptions.IncludeObfuscation; OpenAIResponsesRequest gains Conversation, ContextManagement, SafetyIdentifier, StreamOptions; TopLogProbs changed to *int.
Gemini config
dto/gemini.go
Adjusted many field types in GeminiChatGenerationConfig, added EnableEnhancedCivicAnswers, and expanded UnmarshalJSON to accept snake_case variants mapping into camelCase fields.
Claude DTO formatting
dto/claude.go
Reformatted ClaudeRequest and added a commented-out InferenceGeo line; no active behavioral change.
Relay removal logic
relay/common/relay_info.go
RemoveDisabledFields signature now accepts channelPassThroughEnabled; early-exit when global or channel pass-through enabled; removes stream_options.include_obfuscation when not allowed and prunes empty stream_options.
Relay call sites
relay/chat_completions_via_responses.go, relay/claude_handler.go, relay/compatible_handler.go, relay/responses_handler.go
Updated RemoveDisabledFields calls to pass info.ChannelSetting.PassThroughBodyEnabled (new third argument).
Relay tests
relay/common/override_test.go
Added tests asserting RemoveDisabledFields returns the input unchanged when global or channel pass-through is enabled.
Frontend channel modal
web/src/components/table/channels/modals/EditChannelModal.jsx
Added allow_include_obfuscation form state, parsing, reset, UI switch, and inclusion in settings payload for OpenAI/Claude channel types.
Personal settings UI
web/src/components/settings/personal/cards/NotificationSettings.jsx
Added new admin "subscription" module entry and enabled it by default in sidebar modules/defaults.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(200,230,255,0.5)
    participant User
    participant Frontend
    participant API_Server as "Server (Channels API)"
    participant Relay
    participant Upstream as "Provider API"
  end

  User->>Frontend: Toggle "Allow include obfuscation" and Save
  Frontend->>API_Server: Save channel settings (includes allow_include_obfuscation)
  API_Server-->>Frontend: 200 OK
  Frontend->>User: UI confirms saved

  Note over Relay,API_Server: At request time
  API_Server->>Relay: Forward client request JSON + channel settings
  Relay->>Relay: Call RemoveDisabledFields(jsonData, channelOtherSettings, passThroughEnabled)
  alt passThroughEnabled == true
    Relay->>Upstream: Send original JSON
  else passThroughEnabled == false and AllowIncludeObfuscation == false
    Relay->>Relay: Remove stream_options.include_obfuscation (and prune stream_options)
    Relay->>Upstream: Send pruned JSON
  end
  Upstream-->>Relay: Provider response
  Relay-->>API_Server: Return response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion

Poem

🐰
A little hop, a thump, a switch so bright,
Allow or hide what wanders in the night.
From UI burrow to relay’s flow,
Obfuscation may stay — or off it goes.
Fields saved, flags set — the rabbit’s delight. 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding missing request fields for OpenAI, Claude, and Gemini APIs across multiple DTO files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
relay/common/override_test.go (1)

778-813: Add tests for the core AllowIncludeObfuscation removal logic.

The new tests verify the pass-through skip paths, but there is no coverage for the actual include_obfuscation removal behaviour introduced in RemoveDisabledFields. The following scenarios are untested:

  1. include_obfuscation is stripped when AllowIncludeObfuscation = false
  2. include_obfuscation is preserved when AllowIncludeObfuscation = true
  3. stream_options is removed entirely when include_obfuscation was its only field (and AllowIncludeObfuscation = false)
  4. stream_options is kept (with its remaining fields) when other sibling fields (e.g. include_usage) co-exist
🧪 Proposed additional test cases
+func TestRemoveDisabledFieldsRemovesIncludeObfuscationByDefault(t *testing.T) {
+	input := `{"stream_options":{"include_usage":true,"include_obfuscation":false}}`
+	settings := dto.ChannelOtherSettings{} // AllowIncludeObfuscation = false by default
+
+	out, err := RemoveDisabledFields([]byte(input), settings, false)
+	if err != nil {
+		t.Fatalf("RemoveDisabledFields returned error: %v", err)
+	}
+	assertJSONEqual(t, `{"stream_options":{"include_usage":true}}`, string(out))
+}
+
+func TestRemoveDisabledFieldsRemovesStreamOptionsWhenOnlyIncludeObfuscation(t *testing.T) {
+	input := `{"model":"gpt-4","stream_options":{"include_obfuscation":false}}`
+	settings := dto.ChannelOtherSettings{}
+
+	out, err := RemoveDisabledFields([]byte(input), settings, false)
+	if err != nil {
+		t.Fatalf("RemoveDisabledFields returned error: %v", err)
+	}
+	assertJSONEqual(t, `{"model":"gpt-4"}`, string(out))
+}
+
+func TestRemoveDisabledFieldsPreservesIncludeObfuscationWhenAllowed(t *testing.T) {
+	input := `{"stream_options":{"include_usage":true,"include_obfuscation":false}}`
+	settings := dto.ChannelOtherSettings{AllowIncludeObfuscation: true}
+
+	out, err := RemoveDisabledFields([]byte(input), settings, false)
+	if err != nil {
+		t.Fatalf("RemoveDisabledFields returned error: %v", err)
+	}
+	assertJSONEqual(t, input, string(out))
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@relay/common/override_test.go` around lines 778 - 813, Add unit tests
covering RemoveDisabledFields's AllowIncludeObfuscation branch: write tests that
call RemoveDisabledFields with dto.ChannelOtherSettings{AllowIncludeObfuscation:
false} and payloads containing "stream_options":{"include_obfuscation":true} to
assert include_obfuscation is removed and stream_options is removed if it
becomes empty; another with AllowIncludeObfuscation: true to assert
include_obfuscation is preserved; and a test where stream_options contains
include_obfuscation plus another field (e.g. "include_usage") with
AllowIncludeObfuscation:false to assert include_obfuscation is stripped but
stream_options and the sibling field remain. Use function names like
TestRemoveDisabledFields_StripsIncludeObfuscation_WhenNotAllowed,
TestRemoveDisabledFields_PreservesIncludeObfuscation_WhenAllowed, and
TestRemoveDisabledFields_RemovesEmptyStreamOptions to locate coverage for
RemoveDisabledFields and dto.ChannelOtherSettings.
relay/common/relay_info.go (1)

739-752: Redundant map re-assignment on line 748.

streamOptions is the underlying map[string]interface{} obtained via type assertion from data["stream_options"]. Since Go maps are reference types, delete(streamOptions, "include_obfuscation") already mutates the map in-place, so data["stream_options"] already reflects the deletion without any explicit re-assignment.

♻️ Simplify the else branch
 			if len(streamOptions) == 0 {
 				delete(data, "stream_options")
-			} else {
-				data["stream_options"] = streamOptions
 			}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@relay/common/relay_info.go` around lines 739 - 752, The code redundantly
reassigns streamOptions back into data after mutating it; because maps are
reference types in Go, deleting a key via delete(streamOptions,
"include_obfuscation") already updates data["stream_options"]. Remove the
unnecessary else branch that sets data["stream_options"] = streamOptions and
instead only delete data["stream_options"] when streamOptions becomes empty;
keep the existing type-assertion and delete(streamOptions, ...) logic inside the
AllowIncludeObfuscation check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@relay/common/override_test.go`:
- Around line 778-813: Add unit tests covering RemoveDisabledFields's
AllowIncludeObfuscation branch: write tests that call RemoveDisabledFields with
dto.ChannelOtherSettings{AllowIncludeObfuscation: false} and payloads containing
"stream_options":{"include_obfuscation":true} to assert include_obfuscation is
removed and stream_options is removed if it becomes empty; another with
AllowIncludeObfuscation: true to assert include_obfuscation is preserved; and a
test where stream_options contains include_obfuscation plus another field (e.g.
"include_usage") with AllowIncludeObfuscation:false to assert
include_obfuscation is stripped but stream_options and the sibling field remain.
Use function names like
TestRemoveDisabledFields_StripsIncludeObfuscation_WhenNotAllowed,
TestRemoveDisabledFields_PreservesIncludeObfuscation_WhenAllowed, and
TestRemoveDisabledFields_RemovesEmptyStreamOptions to locate coverage for
RemoveDisabledFields and dto.ChannelOtherSettings.

In `@relay/common/relay_info.go`:
- Around line 739-752: The code redundantly reassigns streamOptions back into
data after mutating it; because maps are reference types in Go, deleting a key
via delete(streamOptions, "include_obfuscation") already updates
data["stream_options"]. Remove the unnecessary else branch that sets
data["stream_options"] = streamOptions and instead only delete
data["stream_options"] when streamOptions becomes empty; keep the existing
type-assertion and delete(streamOptions, ...) logic inside the
AllowIncludeObfuscation check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments