agent_patch
runs/2026-02-21__03-36-16__gpt-5-1-codex-mini/flux-pr-1293/flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/agent-logs/agent.patch
26732 bytes
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_test.go b/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_test.go
index 2e881ca..f90a650 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_test.go
+++ b/app/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_test.go
@@ -3131,42 +3131,6 @@ func TestGraphQLDataSourceFederation(t *testing.T) {
FetchConfiguration: resolve.FetchConfiguration{
Input: `{"method":"POST","url":"http://address-enricher.service","body":{"query":"query($representations: [_Any!]!){_entities(representations: $representations){... on Address {__typename country city}}}","variables":{"representations":[$$0$$]}}}`,
DataSource: &Source{},
- CoordinateDependencies: []resolve.FetchDependency{
- {
- Coordinate: resolve.GraphCoordinate{
- TypeName: "Address",
- FieldName: "country",
- },
- DependsOn: []resolve.FetchDependencyOrigin{
- {
- FetchID: 0,
- Subgraph: "user.service",
- Coordinate: resolve.GraphCoordinate{
- TypeName: "Address",
- FieldName: "id",
- },
- IsKey: true,
- },
- },
- },
- {
- Coordinate: resolve.GraphCoordinate{
- TypeName: "Address",
- FieldName: "city",
- },
- DependsOn: []resolve.FetchDependencyOrigin{
- {
- FetchID: 0,
- Subgraph: "user.service",
- Coordinate: resolve.GraphCoordinate{
- TypeName: "Address",
- FieldName: "id",
- },
- IsKey: true,
- },
- },
- },
- },
PostProcessing: SingleEntityPostProcessingConfiguration,
RequiresEntityFetch: true,
Variables: []resolve.Variable{
@@ -6499,10 +6463,48 @@ func TestGraphQLDataSourceFederation(t *testing.T) {
},
},
},
- },
+ },
+ },
+ },
+ metadata: &resolve.FetchInfo{
+ CoordinateDependencies: []resolve.FetchDependency{
+ {
+ Coordinate: resolve.GraphCoordinate{
+ TypeName: "Address",
+ FieldName: "country",
+ },
+ DependsOn: []resolve.FetchDependencyOrigin{
+ {
+ FetchID: 0,
+ Subgraph: "user.service",
+ Coordinate: resolve.GraphCoordinate{
+ TypeName: "Address",
+ FieldName: "id",
},
+ IsKey: true,
},
- }),
+ },
+ },
+ {
+ Coordinate: resolve.GraphCoordinate{
+ TypeName: "Address",
+ FieldName: "city",
+ },
+ DependsOn: []resolve.FetchDependencyOrigin{
+ {
+ FetchID: 0,
+ Subgraph: "user.service",
+ Coordinate: resolve.GraphCoordinate{
+ TypeName: "Address",
+ FieldName: "id",
+ },
+ IsKey: true,
+ },
+ },
+ },
+ },
+ },
+ }),
},
},
},
@@ -16067,7 +16069,7 @@ func TestGraphQLDataSourceFederation(t *testing.T) {
SelectionSet: "id",
Conditions: []plan.KeyCondition{
{
- Coordinates: []plan.KeyConditionCoordinate{
+ Coordinates: []resolve.FieldCoordinate{
{
TypeName: "User",
FieldName: "hostedImageWithProvides",
@@ -17008,7 +17010,7 @@ func TestGraphQLDataSourceFederation(t *testing.T) {
SelectionSet: "id",
Conditions: []plan.KeyCondition{
{
- Coordinates: []plan.KeyConditionCoordinate{
+ Coordinates: []resolve.FieldCoordinate{
{
TypeName: "Host",
FieldName: "image",
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/configuration.go b/app/v2/pkg/engine/plan/configuration.go
index a5216da..6453f23 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/configuration.go
+++ b/app/v2/pkg/engine/plan/configuration.go
@@ -33,6 +33,9 @@ type Configuration struct {
// DisableIncludeFieldDependencies controls whether the planner generates
// field dependency structures (useful in tests).
DisableIncludeFieldDependencies bool
+
+ // DisableBuildFetchReasons controls whether the planner builds metadata about fetch reasons.
+ DisableBuildFetchReasons bool
}
type DebugConfiguration struct {
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/federation_metadata.go b/app/v2/pkg/engine/plan/federation_metadata.go
index b4479a4..7265395 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/federation_metadata.go
+++ b/app/v2/pkg/engine/plan/federation_metadata.go
@@ -5,6 +5,7 @@ import (
"slices"
"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
+ "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve"
)
type FederationMetaData struct {
@@ -82,15 +83,10 @@ type FederationFieldConfiguration struct {
}
type KeyCondition struct {
- Coordinates []KeyConditionCoordinate `json:"coordinates"`
+ Coordinates []resolve.FieldCoordinate `json:"coordinates"`
FieldPath []string `json:"field_path"`
}
-type KeyConditionCoordinate struct {
- TypeName string `json:"type_name"`
- FieldName string `json:"field_name"`
-}
-
func (f *FederationFieldConfiguration) parseSelectionSet() error {
if f.parsedSelectionSet != nil {
return nil
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__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 6a1259a..731e827 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/node_selection_visitor.go
+++ b/app/v2/pkg/engine/plan/node_selection_visitor.go
@@ -7,6 +7,7 @@ import (
"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
"github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor"
+ "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve"
)
// nodeSelectionVisitor walks through the operation multiple times to rewrite it
@@ -45,7 +46,7 @@ type nodeSelectionVisitor struct {
hasNewFields bool // hasNewFields is used to determine if we need to run the planner again. It will be true in case required fields were added
hasUnresolvedFields bool // hasUnresolvedFields is used to determine if we need to run the planner again. We should set it to true in case we have unresolved fields
- fieldPathCoordinates []KeyConditionCoordinate // currentFieldPathCoordinates is a stack of field path coordinates // TODO: remove me
+ fieldPathCoordinates []resolve.FieldCoordinate // currentFieldPathCoordinates is a stack of field path coordinates // TODO: remove me
rewrittenFieldRefs []int
}
@@ -128,7 +129,7 @@ func (c *nodeSelectionVisitor) EnterDocument(operation, definition *ast.Document
}
if c.fieldPathCoordinates == nil {
- c.fieldPathCoordinates = make([]KeyConditionCoordinate, 0, 8)
+ c.fieldPathCoordinates = make([]resolve.FieldCoordinate, 0, 8)
} else {
c.fieldPathCoordinates = c.fieldPathCoordinates[:0]
}
@@ -219,7 +220,7 @@ func (c *nodeSelectionVisitor) EnterField(fieldRef int) {
c.rewriteSelectionSetHavingAbstractFragments(fieldRef, ds)
}
- c.fieldPathCoordinates = append(c.fieldPathCoordinates, KeyConditionCoordinate{
+ c.fieldPathCoordinates = append(c.fieldPathCoordinates, resolve.FieldCoordinate{
FieldName: fieldName,
TypeName: typeName,
})
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/visitor.go b/app/v2/pkg/engine/plan/visitor.go
index 382be28..a31e73a 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/visitor.go
+++ b/app/v2/pkg/engine/plan/visitor.go
@@ -1325,19 +1325,29 @@ func (v *Visitor) configureFetch(internal *objectFetchConfiguration, external re
DataSourceIdentifier: []byte(dataSourceType),
}
- if !v.Config.DisableIncludeInfo {
- singleFetch.Info = &resolve.FetchInfo{
+ includeInfo := !v.Config.DisableIncludeInfo
+ includeDependencies := !v.Config.DisableIncludeFieldDependencies
+ buildFetchReasons := !v.Config.DisableBuildFetchReasons
+
+ if includeInfo || includeDependencies || buildFetchReasons {
+ meta := &resolve.FetchInfo{
DataSourceID: internal.sourceID,
DataSourceName: internal.sourceName,
RootFields: internal.rootFields,
OperationType: internal.operationType,
QueryPlan: external.QueryPlan,
}
- }
-
- if !v.Config.DisableIncludeFieldDependencies {
- singleFetch.CoordinateDependencies = v.resolveFetchDependencies(internal.fetchID)
- singleFetch.FieldFetchReasons = v.buildFetchReasons(internal.fetchID)
+ if includeDependencies {
+ meta.CoordinateDependencies = v.resolveFetchDependencies(internal.fetchID)
+ }
+ if buildFetchReasons {
+ meta.FetchReasons = v.buildFetchReasons(internal.fetchID)
+ meta.PropagatedFetchReasons = meta.FetchReasons
+ }
+ singleFetch.metadata = meta
+ if includeInfo {
+ singleFetch.Info = meta
+ }
}
return singleFetch
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/create_concrete_single_fetch_types.go b/app/v2/pkg/engine/postprocess/create_concrete_single_fetch_types.go
index 3d6a00b..160defa 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/create_concrete_single_fetch_types.go
+++ b/app/v2/pkg/engine/postprocess/create_concrete_single_fetch_types.go
@@ -75,10 +75,9 @@ func (d *createConcreteSingleFetchTypes) createEntityBatchFetch(fetch *resolve.S
}
return &resolve.BatchEntityFetch{
- FetchDependencies: fetch.FetchDependencies,
- CoordinateDependencies: fetch.CoordinateDependencies,
- FieldFetchReasons: fetch.FieldFetchReasons,
- Info: fetch.Info,
+ FetchDependencies: fetch.FetchDependencies,
+ Info: fetch.Info,
+ metadata: fetch.FetchInfo(),
Input: resolve.BatchInput{
Header: resolve.InputTemplate{
Segments: fetch.InputTemplate.Segments[:representationsVariableIndex],
@@ -122,10 +121,9 @@ func (d *createConcreteSingleFetchTypes) createEntityFetch(fetch *resolve.Single
}
return &resolve.EntityFetch{
- FetchDependencies: fetch.FetchDependencies,
- CoordinateDependencies: fetch.CoordinateDependencies,
- FieldFetchReasons: fetch.FieldFetchReasons,
- Info: fetch.Info,
+ FetchDependencies: fetch.FetchDependencies,
+ Info: fetch.Info,
+ metadata: fetch.FetchInfo(),
Input: resolve.EntityInput{
Header: resolve.InputTemplate{
Segments: fetch.InputTemplate.Segments[:representationsVariableIndex],
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
index c7864fc..2586dff 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
+++ b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
@@ -51,10 +51,12 @@ func (d *deduplicateSingleFetches) replaceDependsOnFetchId(root *resolve.FetchTr
continue
}
- for j := range root.ChildNodes[i].Item.Fetch.DependenciesCoordinates() {
- for k := range root.ChildNodes[i].Item.Fetch.DependenciesCoordinates()[j].DependsOn {
- if root.ChildNodes[i].Item.Fetch.DependenciesCoordinates()[j].DependsOn[k].FetchID == oldId {
- root.ChildNodes[i].Item.Fetch.DependenciesCoordinates()[j].DependsOn[k].FetchID = newId
+ if info := root.ChildNodes[i].Item.Fetch.FetchInfo(); info != nil {
+ for j := range info.CoordinateDependencies {
+ for k := range info.CoordinateDependencies[j].DependsOn {
+ if info.CoordinateDependencies[j].DependsOn[k].FetchID == oldId {
+ info.CoordinateDependencies[j].DependsOn[k].FetchID = newId
+ }
}
}
}
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
index 9a0121b..f48624a 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
+++ b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
@@ -99,6 +99,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "a",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
@@ -123,6 +125,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "a",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
@@ -147,6 +151,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "b",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
@@ -174,6 +180,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "b",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
@@ -219,6 +227,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "a",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
@@ -243,6 +253,8 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
},
FetchConfiguration: resolve.FetchConfiguration{
Input: "b",
+ },
+ metadata: &resolve.FetchInfo{
CoordinateDependencies: []resolve.FetchDependency{
{
DependsOn: []resolve.FetchDependencyOrigin{
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/postprocess.go b/app/v2/pkg/engine/postprocess/postprocess.go
index 9a4fadf..5a81192 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/postprocess.go
+++ b/app/v2/pkg/engine/postprocess/postprocess.go
@@ -180,7 +180,13 @@ func (p *Processor) createFetchTree(res *resolve.GraphQLResponse) {
if p.collectDataSourceInfo {
var list = make([]resolve.DataSourceInfo, 0, len(fetches))
for _, fetch := range fetches {
- dsInfo := fetch.Fetch.DataSourceInfo()
+ if info := fetch.Fetch.FetchInfo(); info == nil {
+ continue
+ }
+ dsInfo := resolve.DataSourceInfo{
+ ID: info.DataSourceID,
+ Name: info.DataSourceName,
+ }
if !slices.Contains(list, dsInfo) {
list = append(list, dsInfo)
}
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go b/app/v2/pkg/engine/resolve/fetch.go
index 137670b..5a81717 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go
+++ b/app/v2/pkg/engine/resolve/fetch.go
@@ -20,9 +20,7 @@ const (
type Fetch interface {
FetchKind() FetchKind
Dependencies() *FetchDependencies
- DataSourceInfo() DataSourceInfo
- DependenciesCoordinates() []FetchDependency
- FetchReasons() []FetchReason
+ FetchInfo() *FetchInfo
}
type FetchItem struct {
@@ -95,25 +93,15 @@ type SingleFetch struct {
DataSourceIdentifier []byte
Trace *DataSourceLoadTrace
Info *FetchInfo
+ metadata *FetchInfo
}
func (s *SingleFetch) Dependencies() *FetchDependencies {
return &s.FetchDependencies
}
-func (s *SingleFetch) DependenciesCoordinates() []FetchDependency {
- return s.CoordinateDependencies
-}
-
-func (s *SingleFetch) FetchReasons() []FetchReason {
- return s.FieldFetchReasons
-}
-
-func (s *SingleFetch) DataSourceInfo() DataSourceInfo {
- return DataSourceInfo{
- ID: s.Info.DataSourceID,
- Name: s.Info.DataSourceName,
- }
+func (s *SingleFetch) FetchInfo() *FetchInfo {
+ return s.metadata
}
// FetchDependencies holding current fetch id and ids of fetches that current fetch depends on
@@ -176,27 +164,15 @@ type BatchEntityFetch struct {
DataSourceIdentifier []byte
Trace *DataSourceLoadTrace
Info *FetchInfo
- CoordinateDependencies []FetchDependency
- FieldFetchReasons []FetchReason
+ metadata *FetchInfo
}
func (b *BatchEntityFetch) Dependencies() *FetchDependencies {
return &b.FetchDependencies
}
-func (b *BatchEntityFetch) DependenciesCoordinates() []FetchDependency {
- return b.CoordinateDependencies
-}
-
-func (b *BatchEntityFetch) FetchReasons() []FetchReason {
- return b.FieldFetchReasons
-}
-
-func (b *BatchEntityFetch) DataSourceInfo() DataSourceInfo {
- return DataSourceInfo{
- ID: b.Info.DataSourceID,
- Name: b.Info.DataSourceName,
- }
+func (b *BatchEntityFetch) FetchInfo() *FetchInfo {
+ return b.metadata
}
type BatchInput struct {
@@ -229,27 +205,15 @@ type EntityFetch struct {
DataSourceIdentifier []byte
Trace *DataSourceLoadTrace
Info *FetchInfo
- CoordinateDependencies []FetchDependency
- FieldFetchReasons []FetchReason
+ metadata *FetchInfo
}
func (e *EntityFetch) Dependencies() *FetchDependencies {
return &e.FetchDependencies
}
-func (e *EntityFetch) DependenciesCoordinates() []FetchDependency {
- return e.CoordinateDependencies
-}
-
-func (e *EntityFetch) FetchReasons() []FetchReason {
- return e.FieldFetchReasons
-}
-
-func (e *EntityFetch) DataSourceInfo() DataSourceInfo {
- return DataSourceInfo{
- ID: e.Info.DataSourceID,
- Name: e.Info.DataSourceName,
- }
+func (e *EntityFetch) FetchInfo() *FetchInfo {
+ return e.metadata
}
type EntityInput struct {
@@ -276,20 +240,12 @@ func (p *ParallelListItemFetch) Dependencies() *FetchDependencies {
return &p.Fetch.FetchDependencies
}
-func (p *ParallelListItemFetch) DependenciesCoordinates() []FetchDependency {
- return p.Fetch.CoordinateDependencies
-}
-
-func (p *ParallelListItemFetch) FetchReasons() []FetchReason {
- return p.Fetch.FieldFetchReasons
-}
-
func (*ParallelListItemFetch) FetchKind() FetchKind {
return FetchKindParallelListItem
}
-func (p *ParallelListItemFetch) DataSourceInfo() DataSourceInfo {
- return p.Fetch.DataSourceInfo()
+func (p *ParallelListItemFetch) FetchInfo() *FetchInfo {
+ return p.Fetch.FetchInfo()
}
type QueryPlan struct {
@@ -341,19 +297,8 @@ type FetchConfiguration struct {
QueryPlan *QueryPlan
- // CoordinateDependencies contain a list of GraphCoordinates (typeName+fieldName)
- // and which fields from other fetches they depend on.
- // This information is useful to understand why a fetch depends on other fetches,
- // and how multiple dependencies lead to a chain of fetches
- CoordinateDependencies []FetchDependency
-
- // FieldFetchReasons contains provenance for fields that require fetch reason to be propagated
- // to their subgraph. It is optional propagation via request extensions;
- // it does not affect execution.
- FieldFetchReasons []FetchReason
-
- // OperationName is non-empty when the operation name is propagated to the upstream subgraph fetch.
- OperationName string
+ // OperationName is non-empty when the operation name is propagated to the upstream subgraph fetch.
+ OperationName string
}
func (fc *FetchConfiguration) Equals(other *FetchConfiguration) bool {
@@ -367,10 +312,6 @@ func (fc *FetchConfiguration) Equals(other *FetchConfiguration) bool {
}
// Note: we do not compare datasources, as they will always be a different instance.
- // Note: we do not compare CoordinateDependencies, as they contain more detailed
- // dependencies information that is already present in the FetchDependencies on the fetch itself.
- // Note: we do not compare FieldFetchReasons, as it is derived data for an extension
- // and does not affect fetch execution semantics.
if fc.RequiresParallelListItemFetch != other.RequiresParallelListItemFetch {
return false
@@ -429,17 +370,31 @@ type FetchReason struct {
IsRequires bool `json:"is_requires,omitempty"`
}
+type FieldCoordinate struct {
+ TypeName string `json:"typeName"`
+ FieldName string `json:"fieldName"`
+}
+
type FetchInfo struct {
DataSourceID string
DataSourceName string
RootFields []GraphCoordinate
OperationType ast.OperationType
QueryPlan *QueryPlan
+ // CoordinateDependencies contain a list of GraphCoordinates (typeName+fieldName)
+ // and which fields from other fetches they depend on.
+ CoordinateDependencies []FetchDependency
+ // FetchReasons contains provenance for fields that require fetch reason to be propagated
+ // to their subgraph. It is optional propagation via request extensions;
+ // it does not affect execution.
+ FetchReasons []FetchReason
+ // PropagatedFetchReasons contains the subset of fetch reasons that should be
+ // propagated to downstream subgraphs.
+ PropagatedFetchReasons []FetchReason
}
type GraphCoordinate struct {
- TypeName string `json:"typeName"`
- FieldName string `json:"fieldName"`
+ FieldCoordinate
HasAuthorizationRule bool `json:"-"`
}
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetchtree.go b/app/v2/pkg/engine/resolve/fetchtree.go
index ad1eb2f..9eb1b3a 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetchtree.go
+++ b/app/v2/pkg/engine/resolve/fetchtree.go
@@ -216,7 +216,9 @@ func (n *FetchTreeNode) queryPlan() *FetchTreeQueryPlanNode {
SubgraphName: f.Info.DataSourceName,
SubgraphID: f.Info.DataSourceID,
Path: n.Item.ResponsePath,
- Dependencies: f.FetchConfiguration.CoordinateDependencies,
+ }
+ if info := f.FetchInfo(); info != nil {
+ queryPlan.Fetch.Dependencies = info.CoordinateDependencies
}
if f.Info.QueryPlan != nil {
@@ -231,7 +233,9 @@ func (n *FetchTreeNode) queryPlan() *FetchTreeQueryPlanNode {
SubgraphName: f.Info.DataSourceName,
SubgraphID: f.Info.DataSourceID,
Path: n.Item.ResponsePath,
- Dependencies: f.CoordinateDependencies,
+ }
+ if info := f.FetchInfo(); info != nil {
+ queryPlan.Fetch.Dependencies = info.CoordinateDependencies
}
if f.Info.QueryPlan != nil {
@@ -246,7 +250,9 @@ func (n *FetchTreeNode) queryPlan() *FetchTreeQueryPlanNode {
SubgraphName: f.Info.DataSourceName,
SubgraphID: f.Info.DataSourceID,
Path: n.Item.ResponsePath,
- Dependencies: f.CoordinateDependencies,
+ }
+ if info := f.FetchInfo(); info != nil {
+ queryPlan.Fetch.Dependencies = info.CoordinateDependencies
}
if f.Info.QueryPlan != nil {
@@ -267,6 +273,9 @@ func (n *FetchTreeNode) queryPlan() *FetchTreeQueryPlanNode {
queryPlan.Fetch.Query = f.Fetch.Info.QueryPlan.Query
queryPlan.Fetch.Representations = f.Fetch.Info.QueryPlan.DependsOnFields
}
+ if info := f.Fetch.FetchInfo(); info != nil {
+ queryPlan.Fetch.Dependencies = info.CoordinateDependencies
+ }
default:
}
case FetchTreeNodeKindSequence, FetchTreeNodeKindParallel:
diff --git a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/loader.go b/app/v2/pkg/engine/resolve/loader.go
index 685383c..1af702c 100644
--- a/tmp/agent-patch-flux-pr-1293.1-of-1.2026-02-21__03-36-16__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/loader.go
+++ b/app/v2/pkg/engine/resolve/loader.go
@@ -1598,20 +1598,22 @@ func (l *Loader) executeSourceLoad(ctx context.Context, fetchItem *FetchItem, so
return
}
}
- if l.propagateFetchReasons && !IsIntrospectionDataSource(res.ds.ID) {
- fetchReasons := fetchItem.Fetch.FetchReasons()
- if len(fetchReasons) > 0 {
- var encoded []byte
- encoded, res.err = json.Marshal(fetchReasons)
- if res.err != nil {
- res.err = errors.WithStack(res.err)
- return
- }
- // We expect that body.extensions is an object
- input, res.err = jsonparser.Set(input, encoded, "body", "extensions", "fetch_reasons")
- if res.err != nil {
- res.err = errors.WithStack(res.err)
- return
+ if l.propagateFetchReasons {
+ if fetchInfo := fetchItem.Fetch.FetchInfo(); fetchInfo != nil && !IsIntrospectionDataSource(fetchInfo.DataSourceID) {
+ fetchReasons := fetchInfo.PropagatedFetchReasons
+ if len(fetchReasons) > 0 {
+ var encoded []byte
+ encoded, res.err = json.Marshal(fetchReasons)
+ if res.err != nil {
+ res.err = errors.WithStack(res.err)
+ return
+ }
+ // We expect that body.extensions is an object
+ input, res.err = jsonparser.Set(input, encoded, "body", "extensions", "fetch_reasons")
+ if res.err != nil {
+ res.err = errors.WithStack(res.err)
+ return
+ }
}
}
}