Skip to content

feat: global pass-through setting#1591

Merged
looplj merged 2 commits into
looplj:unstablefrom
raikyou:feat/global-pass-through
May 3, 2026
Merged

feat: global pass-through setting#1591
looplj merged 2 commits into
looplj:unstablefrom
raikyou:feat/global-pass-through

Conversation

@raikyou

@raikyou raikyou commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a system-wide pass-through setting that mirrors the existing global User-Agent pass-through
  • Channels with PassThroughBody unset (nil) now inherit from the global value; explicit true/false still overrides
  • General Settings page groups User-Agent Pass-Through and Pass-Through into a single card to reduce vertical space; the channel form switches its body pass-through control to the same three-state (inherit / enabled / disabled) selector already used for User-Agent

Test plan

  • Toggle the new global Pass-Through switch in System → General Settings and verify the value persists
  • Create a channel with passThroughBody = inherit, enable the global setting, and confirm pass-through takes effect when inbound and outbound API formats match
  • Override per-channel (enabled / disabled) and confirm the channel value wins regardless of the global setting
  • Existing channels with passThroughBody: true keep behaving the same after upgrade
  • go test ./internal/server/orchestrator/... and ./internal/server/biz/... still pass

🤖 Generated with Claude Code

image

Add a system-wide pass-through setting that mirrors the existing global
user-agent pass-through and aggregates with each channel's setting.
Channels with PassThroughBody unset (nil) inherit from the global value;
explicit true/false on a channel still overrides.

The system general settings page now groups User-Agent Pass-Through and
Pass-Through into a single card to save vertical space, and the channel
form switches its body pass-through control to the same three-state
(inherit / enabled / disabled) selector used for User-Agent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a system-wide pass-through toggle that mirrors the existing User-Agent pass-through setting. ChannelSettings.PassThroughBody is promoted from bool to *bool so that nil channels inherit the global default, while an explicit true/false still overrides it. The change is well-structured and backwards-compatible (the old omitempty bool field never persisted false, so existing rows deserialise correctly as nil).

Confidence Score: 5/5

Safe to merge; only P2 findings remain after the previously-raised P1 (multiple DB queries per request) was already noted in an earlier review round.

All findings are P2 or below. The implementation is consistent with the existing User-Agent pass-through pattern, backwards-compatible JSON serialisation is preserved, and the GraphQL schema change is additive.

internal/server/orchestrator/pass_through.go — the global DB lookup is still called up to 3× per request on the inherit path (pre-existing open issue). frontend/src/features/channels/components/channels-action-dialog.tsx — inherit state does not surface the prompt-injection warning.

Important Files Changed

Filename Overview
internal/server/orchestrator/pass_through.go Core logic change: isPassThroughEnabled now takes ctx + systemService, falling back to global DB lookup when channel-level PassThroughBody is nil. Format-check section does not touch channel.Settings so removing the early nil-guard is safe. The global DB lookup is called up to 3× per request on the inherit path (already flagged in previous review).
internal/server/orchestrator/orchestrator.go All five pass-through middleware constructors updated to pass processor.SystemService through; change is mechanical and correct.
internal/objects/channel.go PassThroughBody changed from bool to *bool with omitempty. Existing stored JSON is compatible: absent field → nil (inherit), true → *true; false was never written under the old omitempty bool, so no migration needed.
internal/server/biz/system.go New PassThrough/SetPassThrough methods follow the exact same pattern as UserAgentPassThrough; logic and error handling are correct.
internal/server/gql/system.resolvers.go New PassThroughSettings query and UpdatePassThroughSettings mutation wired correctly to systemService methods.
frontend/src/features/channels/components/channels-action-dialog.tsx passThroughBody state changed to boolean
frontend/src/features/system/components/general-settings.tsx New passThrough toggle added to the combined Pass-Through card with optimistic update and rollback on error, mirroring the UA pass-through pattern correctly.
internal/server/orchestrator/pass_through_test.go All existing tests updated to lo.ToPtr(true) for channel-level flag and nil systemService; new global-inheritance code path remains untested (noted in previous review).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Request enters orchestrator] --> B[isPassThroughEnabled called]
    B --> C{channel == nil?}
    C -- yes --> D[return false]
    C -- no --> E{API formats match?}
    E -- no --> D
    E -- yes --> F{channel.Settings.PassThroughBody != nil?}
    F -- yes --> G[use channel-level value]
    F -- no --> H{systemService != nil?}
    H -- no --> I[return false default]
    H -- yes --> J[systemService.PassThrough DB lookup]
    J --> K{error?}
    K -- yes --> L[log warn, return false]
    K -- no --> M[use global value]
    G --> N[return enabled]
    M --> N
Loading

Reviews (2): Last reviewed commit: "fix: lint issues from global pass-throug..." | Re-trigger Greptile

Comment on lines +42 to +56
switch {
case channel.Settings != nil && channel.Settings.PassThroughBody != nil:
enabled = *channel.Settings.PassThroughBody
case systemService != nil:
global, err := systemService.PassThrough(ctx)
if err != nil {
log.Warn(ctx, "failed to get global pass-through setting", log.Cause(err))

return false
}

enabled = global
}

return enabled

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Multiple DB queries per request on the inherit path

isPassThroughEnabled is called from three separate middlewares per request (applyPassThroughRequestBody, captureRawProviderResponse/captureRawProviderStream, and applyPassThroughResponse/applyPassThroughStream). For channels that inherit from the global setting (PassThroughBody == nil), each call triggers a separate systemService.PassThrough(ctx) DB lookup — up to 3 queries per request. By contrast, applyUserAgentPassThrough queries the DB once.

Consider fetching the global value once per request (e.g. store it in orchestratorState or resolve it once at the top of Process and pass the resolved bool into the middleware constructors) so the hot path is not subject to repeated round-trips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a global system-level "Pass-Through" setting for request and response bodies, allowing individual channels to either inherit this global configuration or explicitly override it. Key changes include updating the PassThroughBody field to a pointer type in the backend to support nullability, implementing new GraphQL queries and mutations for system-wide settings, and enhancing the frontend UI with a three-state selection for channels and a global toggle in the general settings. I have no feedback to provide.

- silence gosec G101 false positive on SystemKeyPassThrough (it's a
  setting key, not a credential), matching the existing suppression on
  SystemKeySecretKey
- fix misspell: behaviour -> behavior

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@looplj looplj merged commit 4f9dd91 into looplj:unstable May 3, 2026
4 checks passed
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.

2 participants