agent_patch
runs/2026-02-28__13-38-10__gpt-5-1-codex-mini/flux-pr-1268/flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/agent-logs/agent.patch
27209 bytes
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go b/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go
index 316e2fc..0bbc3eb 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go
+++ b/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go
@@ -269,14 +269,6 @@ func (p *Planner[T]) DownstreamResponseFieldAlias(downstreamFieldRef int) (alias
return "", false
}
-func (p *Planner[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
- return plan.DataSourcePlanningBehavior{
- MergeAliasedRootNodes: true,
- OverrideFieldPathFromAlias: true,
- IncludeTypeNameFields: true,
- }
-}
-
func (p *Planner[T]) Register(visitor *plan.Visitor, configuration plan.DataSourceConfiguration[T], dataSourcePlannerConfiguration plan.DataSourcePlannerConfiguration) error {
p.visitor = visitor
@@ -1721,11 +1713,12 @@ var (
)
type Factory[T Configuration] struct {
- executionContext context.Context
- httpClient *http.Client
- grpcClient grpc.ClientConnInterface
- grpcClientProvider func() grpc.ClientConnInterface
- subscriptionClient GraphQLSubscriptionClient
+ executionContext context.Context
+ httpClient *http.Client
+ grpcClient grpc.ClientConnInterface
+ grpcClientProvider func() grpc.ClientConnInterface
+ subscriptionClient GraphQLSubscriptionClient
+ flattenInlineFragments bool
}
// NewFactory (HTTP) creates a new factory for the GraphQL datasource planner
@@ -1743,9 +1736,10 @@ func NewFactory(executionContext context.Context, httpClient *http.Client, subsc
}
return &Factory[Configuration]{
- executionContext: executionContext,
- httpClient: httpClient,
- subscriptionClient: subscriptionClient,
+ executionContext: executionContext,
+ httpClient: httpClient,
+ subscriptionClient: subscriptionClient,
+ flattenInlineFragments: false,
}, nil
}
@@ -1762,8 +1756,9 @@ func NewFactoryGRPC(executionContext context.Context, grpcClient grpc.ClientConn
}
return &Factory[Configuration]{
- executionContext: executionContext,
- grpcClient: grpcClient,
+ executionContext: executionContext,
+ grpcClient: grpcClient,
+ flattenInlineFragments: true,
}, nil
}
@@ -1782,8 +1777,9 @@ func NewFactoryGRPCClientProvider(executionContext context.Context, clientProvid
}
return &Factory[Configuration]{
- executionContext: executionContext,
- grpcClientProvider: clientProvider,
+ executionContext: executionContext,
+ grpcClientProvider: clientProvider,
+ flattenInlineFragments: true,
}, nil
}
@@ -1825,6 +1821,15 @@ func (f *Factory[T]) UpstreamSchema(dataSourceConfig plan.DataSourceConfiguratio
return schema, true
}
+func (f *Factory[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
+ return plan.DataSourcePlanningBehavior{
+ MergeAliasedRootNodes: true,
+ OverrideFieldPathFromAlias: true,
+ PlanTypeNameFields: true,
+ FlattenInlineFragments: f.flattenInlineFragments,
+ }
+}
+
type Source struct {
httpClient *http.Client
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/introspection_datasource/factory.go b/app/v2/pkg/engine/datasource/introspection_datasource/factory.go
index a251521..65bbfce 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/introspection_datasource/factory.go
+++ b/app/v2/pkg/engine/datasource/introspection_datasource/factory.go
@@ -29,3 +29,11 @@ func (f *Factory[T]) Context() context.Context {
func (f *Factory[T]) UpstreamSchema(dataSourceConfig plan.DataSourceConfiguration[T]) (*ast.Document, bool) {
return nil, false
}
+
+func (f *Factory[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
+ return plan.DataSourcePlanningBehavior{
+ MergeAliasedRootNodes: false,
+ OverrideFieldPathFromAlias: true,
+ PlanTypeNameFields: true,
+ }
+}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/introspection_datasource/planner.go b/app/v2/pkg/engine/datasource/introspection_datasource/planner.go
index 2b05800..481dc3c 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/introspection_datasource/planner.go
+++ b/app/v2/pkg/engine/datasource/introspection_datasource/planner.go
@@ -45,14 +45,6 @@ func (p *Planner[T]) DownstreamResponseFieldAlias(_ int) (alias string, exists b
return
}
-func (p *Planner[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
- return plan.DataSourcePlanningBehavior{
- MergeAliasedRootNodes: false,
- OverrideFieldPathFromAlias: true,
- IncludeTypeNameFields: true,
- }
-}
-
func (p *Planner[T]) EnterField(ref int) {
fieldName := p.v.Operation.FieldNameString(ref)
fieldAliasOrName := p.v.Operation.FieldAliasOrNameString(ref)
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
index 60faa27..30e0345 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
+++ b/app/v2/pkg/engine/datasource/pubsub_datasource/pubsub_datasource.go
@@ -275,14 +275,6 @@ func (p *Planner[T]) ConfigureSubscription() plan.SubscriptionConfiguration {
return plan.SubscriptionConfiguration{}
}
-func (p *Planner[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
- return plan.DataSourcePlanningBehavior{
- MergeAliasedRootNodes: false,
- OverrideFieldPathFromAlias: false,
- IncludeTypeNameFields: true,
- }
-}
-
func (p *Planner[T]) DownstreamResponseFieldAlias(_ int) (alias string, exists bool) {
return "", false
}
@@ -316,6 +308,14 @@ func (f *Factory[T]) UpstreamSchema(dataSourceConfig plan.DataSourceConfiguratio
return nil, false
}
+func (f *Factory[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
+ return plan.DataSourcePlanningBehavior{
+ MergeAliasedRootNodes: false,
+ OverrideFieldPathFromAlias: false,
+ PlanTypeNameFields: true,
+ }
+}
+
func buildEventDataBytes(ref int, visitor *plan.Visitor, variables *resolve.Variables) ([]byte, error) {
// Collect the field arguments for fetch based operations
fieldArgs := visitor.Operation.FieldArguments(ref)
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/staticdatasource/static_datasource.go b/app/v2/pkg/engine/datasource/staticdatasource/static_datasource.go
index 3449afb..5c3e00f 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/staticdatasource/static_datasource.go
+++ b/app/v2/pkg/engine/datasource/staticdatasource/static_datasource.go
@@ -30,6 +30,13 @@ func (f *Factory[T]) UpstreamSchema(dataSourceConfig plan.DataSourceConfiguratio
return nil, false
}
+func (f *Factory[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
+ return plan.DataSourcePlanningBehavior{
+ MergeAliasedRootNodes: false,
+ OverrideFieldPathFromAlias: false,
+ }
+}
+
type Planner[T Configuration] struct {
id int
config Configuration
@@ -48,13 +55,6 @@ func (p *Planner[T]) DownstreamResponseFieldAlias(downstreamFieldRef int) (alias
return
}
-func (p *Planner[T]) DataSourcePlanningBehavior() plan.DataSourcePlanningBehavior {
- return plan.DataSourcePlanningBehavior{
- MergeAliasedRootNodes: false,
- OverrideFieldPathFromAlias: false,
- }
-}
-
func (p *Planner[T]) Register(_ *plan.Visitor, configuration plan.DataSourceConfiguration[T], _ plan.DataSourcePlannerConfiguration) error {
p.config = Configuration(configuration.CustomConfiguration())
return nil
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
index 284ad42..bcfc9c4 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
@@ -57,16 +57,6 @@ In this case if any of rules 1-3 are not satisfied we have to rewrite this fragm
}
}
*/
-type fieldSelectionRewriter struct {
- operation *ast.Document
- definition *ast.Document
-
- upstreamDefinition *ast.Document
- dsConfiguration DataSource
-
- skipFieldRefs []int
-}
-
type RewriteResult struct {
rewritten bool
changedFieldRefs map[int][]int // map[fieldRef][]fieldRef - for each original fieldRef list of new fieldRefs
@@ -74,19 +64,33 @@ type RewriteResult struct {
var resultNotRewritten = RewriteResult{}
-func newFieldSelectionRewriter(operation *ast.Document, definition *ast.Document) *fieldSelectionRewriter {
+type fieldSelectionRewriter struct {
+ operation *ast.Document
+ definition *ast.Document
+ upstreamDefinition *ast.Document
+ dsConfiguration DataSource
+ skipFieldRefs []int
+}
+
+func newFieldSelectionRewriter(operation *ast.Document, definition *ast.Document, upstreamDefinition *ast.Document, dsConfiguration DataSource) *fieldSelectionRewriter {
return &fieldSelectionRewriter{
- operation: operation,
- definition: definition,
+ operation: operation,
+ definition: definition,
+ upstreamDefinition: upstreamDefinition,
+ dsConfiguration: dsConfiguration,
}
}
-func (r *fieldSelectionRewriter) SetUpstreamDefinition(upstreamDefinition *ast.Document) {
- r.upstreamDefinition = upstreamDefinition
-}
+func (r *fieldSelectionRewriter) shouldForceFlatten(selectionInfo selectionSetInfo) bool {
+ if r.dsConfiguration == nil {
+ return false
+ }
+
+ if !r.dsConfiguration.DataSourcePlanningBehavior().FlattenInlineFragments {
+ return false
+ }
-func (r *fieldSelectionRewriter) SetDatasourceConfiguration(dsConfiguration DataSource) {
- r.dsConfiguration = dsConfiguration
+ return selectionInfo.hasInlineFragments()
}
func (r *fieldSelectionRewriter) RewriteFieldSelection(fieldRef int, enclosingNode ast.Node) (res RewriteResult, err error) {
@@ -143,7 +147,7 @@ func (r *fieldSelectionRewriter) processUnionSelection(fieldRef int, unionDefRef
}
needRewrite := r.unionFieldSelectionNeedsRewrite(selectionSetInfo, unionTypeNames, entityNames)
- if !needRewrite {
+ if !needRewrite && !r.shouldForceFlatten(selectionSetInfo) {
return resultNotRewritten, nil
}
@@ -307,7 +311,7 @@ func (r *fieldSelectionRewriter) processObjectSelection(fieldRef int, objectDefR
}
needRewrite := r.objectFieldSelectionNeedsRewrite(selectionSetInfo, fieldTypeNameStr)
- if !needRewrite {
+ if !needRewrite && !r.shouldForceFlatten(selectionSetInfo) {
return resultNotRewritten, nil
}
@@ -386,7 +390,7 @@ func (r *fieldSelectionRewriter) processInterfaceSelection(fieldRef int, interfa
selectionSetInfo.isInterfaceObject = isInterfaceObject
needRewrite := r.interfaceFieldSelectionNeedsRewrite(selectionSetInfo, interfaceTypeNames, entityNames)
- if !needRewrite {
+ if !needRewrite && !r.shouldForceFlatten(selectionSetInfo) {
return resultNotRewritten, nil
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
index 950ccb0..8a7db3f 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
@@ -20,6 +20,10 @@ type selectionSetInfo struct {
hasInlineFragmentsOnUnions bool
}
+func (s selectionSetInfo) hasInlineFragments() bool {
+ return s.hasInlineFragmentsOnObjects || s.hasInlineFragmentsOnInterfaces || s.hasInlineFragmentsOnUnions
+}
+
type fieldSelection struct {
fieldSelectionRef int
fieldName string
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
index 11b5fc8..89236d3 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
@@ -49,9 +49,7 @@ func TestInterfaceSelectionRewriter_RewriteOperation(t *testing.T) {
node, _ := def.Index.FirstNodeByNameStr(testCase.enclosingTypeName)
- rewriter := newFieldSelectionRewriter(&op, &def)
- rewriter.SetUpstreamDefinition(&upstreamDef)
- rewriter.SetDatasourceConfiguration(testCase.dsConfiguration)
+ rewriter := newFieldSelectionRewriter(&op, &def, &upstreamDef, testCase.dsConfiguration)
result, err := rewriter.RewriteFieldSelection(fieldRef, node)
require.NoError(t, err)
@@ -3822,3 +3820,77 @@ func TestInterfaceSelectionRewriter_RewriteOperation(t *testing.T) {
})
}
}
+
+func TestFieldSelectionRewriter_FlattensInlineFragmentsFlag(t *testing.T) {
+ definition := `
+ union SearchResult = Human | Droid
+
+ type Query {
+ search: SearchResult
+ }
+
+ type Human {
+ name: String
+ }
+
+ type Droid {
+ name: String
+ }
+ `
+ operation := `
+ query {
+ search {
+ ... on Human {
+ name
+ }
+ ... on Droid {
+ name
+ }
+ }
+ }
+ `
+ baseDS := dsb().
+ Schema(definition).
+ RootNode("Query", "search").
+ RootNode("Human", "name").
+ RootNode("Droid", "name").
+ DS()
+ flatteningDS := dsb().
+ WithBehavior(DataSourcePlanningBehavior{
+ FlattenInlineFragments: true,
+ }).
+ Schema(definition).
+ RootNode("Query", "search").
+ RootNode("Human", "name").
+ RootNode("Droid", "name").
+ DS()
+
+ run := func(t *testing.T, ds DataSource, expectRewrite bool) {
+ t.Helper()
+
+ op := unsafeparser.ParseGraphqlDocumentString(operation)
+ def := unsafeparser.ParseGraphqlDocumentStringWithBaseSchema(definition)
+ upstreamDef := unsafeparser.ParseGraphqlDocumentStringWithBaseSchema(definition)
+
+ fieldRef := ast.InvalidRef
+ for ref := range op.Fields {
+ if op.FieldNameString(ref) == "search" {
+ fieldRef = ref
+ break
+ }
+ }
+ require.NotEqual(t, ast.InvalidRef, fieldRef)
+
+ node, exists := def.Index.FirstNodeByNameStr("Query")
+ require.True(t, exists)
+
+ rewriter := newFieldSelectionRewriter(&op, &def, &upstreamDef, ds)
+ result, err := rewriter.RewriteFieldSelection(fieldRef, node)
+ require.NoError(t, err)
+
+ assert.Equal(t, expectRewrite, result.rewritten)
+ }
+
+ run(t, baseDS, false)
+ run(t, flatteningDS, true)
+}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_configuration.go b/app/v2/pkg/engine/plan/datasource_configuration.go
index 07ec63e..4cc0507 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_configuration.go
+++ b/app/v2/pkg/engine/plan/datasource_configuration.go
@@ -25,6 +25,7 @@ type PlannerFactory[DataSourceSpecificConfiguration any] interface {
// This method serves as a flag that factory should have a context
Context() context.Context
UpstreamSchema(dataSourceConfig DataSourceConfiguration[DataSourceSpecificConfiguration]) (*ast.Document, bool)
+ DataSourcePlanningBehavior() DataSourcePlanningBehavior
}
type DataSourceMetadata struct {
@@ -212,7 +213,8 @@ type dataSourceConfiguration[T any] struct {
factory PlannerFactory[T] // factory is the factory for the creation of the concrete DataSourcePlanner
custom T // custom is the datasource specific configuration
- hash DSHash // hash is a unique hash for the dataSourceConfiguration used to match datasources
+ hash DSHash // hash is a unique hash for the dataSourceConfiguration used to match datasources
+ planningBehavior DataSourcePlanningBehavior
}
func NewDataSourceConfiguration[T any](id string, factory PlannerFactory[T], metadata *DataSourceMetadata, customConfig T) (DataSourceConfiguration[T], error) {
@@ -237,6 +239,7 @@ func NewDataSourceConfigurationWithName[T any](id string, name string, factory P
factory: factory,
custom: customConfig,
hash: DSHash(xxhash.Sum64([]byte(id))),
+ planningBehavior: factory.DataSourcePlanningBehavior(),
}, nil
}
@@ -257,6 +260,7 @@ type DataSource interface {
Id() string
Name() string
Hash() DSHash
+ DataSourcePlanningBehavior() DataSourcePlanningBehavior
FederationConfiguration() FederationMetaData
CreatePlannerConfiguration(logger abstractlogger.Logger, fetchConfig *objectFetchConfiguration, pathConfig *plannerPathsConfiguration, configuration *Configuration) PlannerConfiguration
}
@@ -303,6 +307,10 @@ func (d *dataSourceConfiguration[T]) Hash() DSHash {
return d.hash
}
+func (d *dataSourceConfiguration[T]) DataSourcePlanningBehavior() DataSourcePlanningBehavior {
+ return d.planningBehavior
+}
+
type DataSourcePlannerConfiguration struct {
RequiredFields FederationFieldConfigurations
ParentPath string
@@ -383,8 +391,12 @@ type DataSourcePlanningBehavior struct {
// When true expected response will be { "rootField": ..., "alias": ... }
// When false expected response will be { "rootField": ..., "original": ... }
OverrideFieldPathFromAlias bool
- // IncludeTypeNameFields should be set to true if the planner allows to plan __typename fields
- IncludeTypeNameFields bool
+ // PlanTypeNameFields should be set to true if the planner wants to plan __typename fields.
+ PlanTypeNameFields bool
+ // FlattenInlineFragments forces the planner to rewrite selection sets that contain inline fragments even when the
+ // standard heuristics do not require a rewrite. This is useful for datasources (like gRPC-backed GraphQL) that
+ // cannot represent inline fragments upstream.
+ FlattenInlineFragments bool
}
type DataSourceFetchPlanner interface {
@@ -392,40 +404,14 @@ type DataSourceFetchPlanner interface {
ConfigureSubscription() SubscriptionConfiguration
}
-type DataSourceBehavior interface {
- DataSourcePlanningBehavior() DataSourcePlanningBehavior
- // DownstreamResponseFieldAlias allows the DataSourcePlanner to overwrite the response path with an alias
- // It's required to set OverrideFieldPathFromAlias to true
- // This function is useful in the following scenario
- // 1. The downstream Query doesn't contain an alias
- // 2. The path configuration rewrites the field to an existing field
- // 3. The DataSourcePlanner is using an alias to the upstream
- // Example:
- //
- // type Query {
- // country: Country
- // countryAlias: Country
- // }
- //
- // Both, country and countryAlias have a path in the FieldConfiguration of "country"
- // In theory, they would be treated as the same field
- // However, by using DownstreamResponseFieldAlias, it's possible for the DataSourcePlanner to use an alias for countryAlias.
- // In this case, the response would contain both, country and countryAlias fields in the response.
- // At the same time, the downstream Query would only expect the response on the path "country",
- // as both country and countryAlias have a mapping to the path "country".
- // The DataSourcePlanner could keep track that it rewrites the upstream query and use DownstreamResponseFieldAlias
- // to indicate to the Planner to expect the response for countryAlias on the path "countryAlias" instead of "country".
- DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool)
-}
-
type Identifyable interface {
astvisitor.VisitorIdentifier
}
type DataSourcePlanner[T any] interface {
DataSourceFetchPlanner
- DataSourceBehavior
Identifyable
+ DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool)
Register(visitor *Visitor, configuration DataSourceConfiguration[T], dataSourcePlannerConfiguration DataSourcePlannerConfiguration) error
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go b/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
index acf02a9..25c3432 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
+++ b/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
@@ -92,7 +92,9 @@ func (b *dsBuilder) DS() DataSource {
}
func (b *dsBuilder) WithBehavior(behavior DataSourcePlanningBehavior) *dsBuilder {
- b.behavior = &behavior
+ behaviorCopy := behavior
+ b.behavior = &behaviorCopy
+ b.ds.planningBehavior = behaviorCopy
return b
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/node_selection_visitor.go b/app/v2/pkg/engine/plan/node_selection_visitor.go
index 95c4f01..bdd73d3 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/node_selection_visitor.go
+++ b/app/v2/pkg/engine/plan/node_selection_visitor.go
@@ -649,9 +649,7 @@ func (c *nodeSelectionVisitor) rewriteSelectionSetHavingAbstractFragments(fieldR
return
}
- rewriter := newFieldSelectionRewriter(c.operation, c.definition)
- rewriter.SetUpstreamDefinition(upstreamSchema)
- rewriter.SetDatasourceConfiguration(ds)
+ rewriter := newFieldSelectionRewriter(c.operation, c.definition, upstreamSchema, ds)
result, err := rewriter.RewriteFieldSelection(fieldRef, c.walker.EnclosingTypeDefinition)
if err != nil {
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/path_builder_visitor.go b/app/v2/pkg/engine/plan/path_builder_visitor.go
index bd4d6b2..ea67a86 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/path_builder_visitor.go
+++ b/app/v2/pkg/engine/plan/path_builder_visitor.go
@@ -719,7 +719,7 @@ func (c *pathBuilderVisitor) isAllFieldDependenciesOnSameDataSource(fieldRef int
func (c *pathBuilderVisitor) planWithExistingPlanners(fieldRef int, typeName, fieldName, currentPath, parentPath, precedingParentPath string, suggestion *NodeSuggestion) (plannerIdx int, planned bool) {
for plannerIdx, plannerConfig := range c.planners {
- planningBehaviour := plannerConfig.DataSourcePlanningBehavior()
+ planningBehaviour := plannerConfig.DataSourceConfiguration().DataSourcePlanningBehavior()
dsConfiguration := plannerConfig.DataSourceConfiguration()
currentPlannerDSHash := dsConfiguration.Hash()
@@ -1247,7 +1247,7 @@ func (c *pathBuilderVisitor) addPlannerPathForTypename(
if fieldName != typeNameField {
return false
}
- if !planningBehaviour.IncludeTypeNameFields {
+ if !planningBehaviour.PlanTypeNameFields {
return false
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/planner_configuration.go b/app/v2/pkg/engine/plan/planner_configuration.go
index 69e23e8..c796cda 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/planner_configuration.go
+++ b/app/v2/pkg/engine/plan/planner_configuration.go
@@ -23,11 +23,11 @@ type plannerConfigurationOptions struct {
}
type PlannerConfiguration interface {
- DataSourceBehavior
PlannerPathConfiguration
ObjectFetchConfiguration() *objectFetchConfiguration
DataSourceConfiguration() DataSource
+ DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool)
RequiredFields() *FederationFieldConfigurations
@@ -62,10 +62,6 @@ func (p *plannerConfiguration[T]) ObjectFetchConfiguration() *objectFetchConfigu
return p.objectFetchConfiguration
}
-func (p *plannerConfiguration[T]) DataSourcePlanningBehavior() DataSourcePlanningBehavior {
- return p.planner.DataSourcePlanningBehavior()
-}
-
func (p *plannerConfiguration[T]) DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool) {
return p.planner.DownstreamResponseFieldAlias(downstreamFieldRef)
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/planner_test.go b/app/v2/pkg/engine/plan/planner_test.go
index 0a498ad..4cf576c 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/planner_test.go
+++ b/app/v2/pkg/engine/plan/planner_test.go
@@ -1006,7 +1006,6 @@ func (f *FakeFactory[T]) Planner(logger abstractlogger.Logger) DataSourcePlanner
return &FakePlanner[T]{
source: source,
upstreamSchema: f.upstreamSchema,
- behavior: f.behavior,
}
}
@@ -1014,11 +1013,21 @@ func (f *FakeFactory[T]) Context() context.Context {
return context.TODO()
}
+func (f *FakeFactory[T]) DataSourcePlanningBehavior() DataSourcePlanningBehavior {
+ if f.behavior == nil {
+ return DataSourcePlanningBehavior{
+ MergeAliasedRootNodes: false,
+ OverrideFieldPathFromAlias: false,
+ }
+ }
+
+ return *f.behavior
+}
+
type FakePlanner[T any] struct {
id int
source *StatefulSource
upstreamSchema *ast.Document
- behavior *DataSourcePlanningBehavior
}
func (f *FakePlanner[T]) ID() int {
@@ -1050,17 +1059,6 @@ func (f *FakePlanner[T]) ConfigureSubscription() SubscriptionConfiguration {
return SubscriptionConfiguration{}
}
-func (f *FakePlanner[T]) DataSourcePlanningBehavior() DataSourcePlanningBehavior {
- if f.behavior == nil {
- return DataSourcePlanningBehavior{
- MergeAliasedRootNodes: false,
- OverrideFieldPathFromAlias: false,
- }
- }
-
- return *f.behavior
-}
-
func (f *FakePlanner[T]) DownstreamResponseFieldAlias(downstreamFieldRef int) (alias string, exists bool) {
return
}
diff --git a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/visitor.go b/app/v2/pkg/engine/plan/visitor.go
index 848c5cc..1c9dcb8 100644
--- a/tmp/agent-patch-flux-pr-1268.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/visitor.go
+++ b/app/v2/pkg/engine/plan/visitor.go
@@ -1021,7 +1021,7 @@ func (v *Visitor) resolveFieldPath(ref int) []string {
aliasOverride := false
if plannerConfig != nil && plannerConfig.Planner() != nil {
- aliasOverride = plannerConfig.DataSourcePlanningBehavior().OverrideFieldPathFromAlias
+ aliasOverride = plannerConfig.DataSourceConfiguration().DataSourcePlanningBehavior().OverrideFieldPathFromAlias
}
for i := range v.Config.Fields {