STET

agent_patch

runs/2026-02-28__13-38-10__gpt-5-1-codex-mini/flux-pr-859/flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/agent-logs/agent.patch

14149 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/configuration_visitor.go b/app/v2/pkg/engine/plan/configuration_visitor.go
index 505795a..11b459c 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/configuration_visitor.go
+++ b/app/v2/pkg/engine/plan/configuration_visitor.go
@@ -44,6 +44,7 @@ type configurationVisitor struct {
 	skipFieldsRefs     []int                  // skipFieldsRefs holds required field refs added by planner and should not be added to user response
 	missingPathTracker map[string]missingPath // missingPathTracker is a map of paths which will be added on secondary runs
 	addedPathTracker   []pathConfiguration    // addedPathTracker is a list of paths which were added
+	addedPathIndex     map[string]map[DSHash]struct{}
 
 	pendingRequiredFields             map[int]selectionSetPendingRequirements // pendingRequiredFields is a map[selectionSetRef][]fieldsRequirementConfig
 	processedFieldNotHavingRequires   map[int]struct{}                        // processedFieldNotHavingRequires is a map[FieldRef] of already processed fields which do not have @requires directive
@@ -184,27 +185,41 @@ func (c *configurationVisitor) saveAddedPath(configuration pathConfiguration) {
 	}
 
 	c.addedPathTracker = append(c.addedPathTracker, configuration)
+	if c.addedPathIndex == nil {
+		c.addedPathIndex = make(map[string]map[DSHash]struct{}, 8)
+	}
+	if _, exists := c.addedPathIndex[configuration.path]; !exists {
+		c.addedPathIndex[configuration.path] = make(map[DSHash]struct{}, 1)
+	}
+	c.addedPathIndex[configuration.path][configuration.dsHash] = struct{}{}
 
 	c.removeMissingPath(configuration.path)
 }
 
 func (c *configurationVisitor) addedPathDSHash(path string) (hash DSHash, ok bool) {
-	// NOTE: it will found first occurence of such path
-	for i := range c.addedPathTracker {
-		if c.addedPathTracker[i].path == path {
-			return c.addedPathTracker[i].dsHash, true
+	if c.addedPathIndex == nil {
+		return 0, false
+	}
+
+	if hashes, exists := c.addedPathIndex[path]; exists {
+		for dsHash := range hashes {
+			return dsHash, true
 		}
 	}
+
 	return 0, false
 }
 
 func (c *configurationVisitor) isPathAddedFor(path string, hash DSHash) bool {
-	// TODO: could be optimized by using map[struct{path,hash}]
-	for i := range c.addedPathTracker {
-		if c.addedPathTracker[i].path == path && c.addedPathTracker[i].dsHash == hash {
-			return true
-		}
+	if c.addedPathIndex == nil {
+		return false
 	}
+
+	if hashes, exists := c.addedPathIndex[path]; exists {
+		_, ok := hashes[hash]
+		return ok
+	}
+
 	return false
 }
 
@@ -300,6 +315,7 @@ func (c *configurationVisitor) EnterDocument(operation, definition *ast.Document
 
 	c.missingPathTracker = make(map[string]missingPath)
 	c.addedPathTracker = make([]pathConfiguration, 0, 8)
+	c.addedPathIndex = make(map[string]map[DSHash]struct{}, 8)
 
 	c.pendingRequiredFields = make(map[int]selectionSetPendingRequirements)
 	c.fieldDependenciesForPlanners = make(map[int][]int)
@@ -733,9 +749,7 @@ func (c *configurationVisitor) isParentPathIsRootOperationPath(parentPath string
 }
 
 func (c *configurationVisitor) allowNewPlannerForTypenameField(fieldName string, typeName string, parentPath string, dsCfg DataSource) bool {
-	isEntityInterface := slices.ContainsFunc(dsCfg.FederationConfiguration().EntityInterfaces, func(interfaceObjCfg EntityInterfaceConfiguration) bool {
-		return interfaceObjCfg.InterfaceTypeName == typeName || slices.Contains(interfaceObjCfg.ConcreteTypeNames, typeName)
-	})
+	isEntityInterface := dsCfg.IsEntityInterfaceType(typeName)
 
 	if isEntityInterface {
 		return true
@@ -1226,13 +1240,7 @@ func (c *configurationVisitor) handleFieldsRequiredByKey(plannerIdx int, parentP
 	}
 
 	if len(requiredFieldsForType) > 0 {
-		isInterfaceObject := false
-		for _, interfaceObjCfg := range plannerConfig.DataSourceConfiguration().FederationConfiguration().InterfaceObjects {
-			if slices.Contains(interfaceObjCfg.ConcreteTypeNames, typeName) {
-				isInterfaceObject = true
-				break
-			}
-		}
+		isInterfaceObject := plannerConfig.DataSourceConfiguration().HasInterfaceObjectConcreteType(typeName)
 
 		requiredFieldsConfiguration, planned := c.planKeyRequiredFields(plannerIdx, typeName, parentPath, requiredFieldsForType, isInterfaceObject)
 		if planned {
@@ -1287,9 +1295,7 @@ func (c *configurationVisitor) planKeyRequiredFields(currentPlannerIdx int, type
 		for _, possibleRequiredFieldConfig := range possibleRequiredFields {
 			if c.planners[i].DataSourceConfiguration().HasKeyRequirement(typeName, possibleRequiredFieldConfig.SelectionSet) {
 
-				isInterfaceObject := slices.ContainsFunc(c.planners[i].DataSourceConfiguration().FederationConfiguration().InterfaceObjects, func(interfaceObjCfg EntityInterfaceConfiguration) bool {
-					return slices.Contains(interfaceObjCfg.ConcreteTypeNames, typeName)
-				})
+				isInterfaceObject := c.planners[i].DataSourceConfiguration().HasInterfaceObjectConcreteType(typeName)
 
 				skipTypename := forInterfaceObject && isInterfaceObject
 
diff --git a/tmp/agent-patch-flux-pr-859.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 f078113..6dde7ea 100644
--- a/tmp/agent-patch-flux-pr-859.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
@@ -40,6 +40,14 @@ type DataSourceMetadata struct {
 	// Note: Unions are not present in the child or root nodes
 	ChildNodes TypeFields
 	Directives *DirectiveConfigurations
+
+	rootNodeLookup            map[string]map[string]struct{}
+	childNodeLookup           map[string]map[string]struct{}
+	rootTypeNames             map[string]struct{}
+	childTypeNames            map[string]struct{}
+	interfaceObjectMembers    map[string]struct{}
+	interfaceObjectNameByType map[string]string
+	entityInterfaceMembers    map[string]struct{}
 }
 
 type DirectivesConfigurations interface {
@@ -56,6 +64,10 @@ type NodesInfo interface {
 	HasRootNodeWithTypename(typeName string) bool
 	HasChildNode(typeName, fieldName string) bool
 	HasChildNodeWithTypename(typeName string) bool
+	IsEntityInterfaceType(typeName string) bool
+	IsInterfaceObjectType(typeName string) bool
+	HasInterfaceObjectConcreteType(typeName string) bool
+	InterfaceObjectNameForConcreteType(typeName string) (string, bool)
 }
 
 func (d *DataSourceMetadata) DirectiveConfigurations() *DirectiveConfigurations {
@@ -63,19 +75,130 @@ func (d *DataSourceMetadata) DirectiveConfigurations() *DirectiveConfigurations
 }
 
 func (d *DataSourceMetadata) HasRootNode(typeName, fieldName string) bool {
-	return d.RootNodes.HasNode(typeName, fieldName)
+	d.ensureNodeLookups()
+	if fields, ok := d.rootNodeLookup[typeName]; ok {
+		_, hasField := fields[fieldName]
+		return hasField
+	}
+	return false
 }
 
 func (d *DataSourceMetadata) HasRootNodeWithTypename(typeName string) bool {
-	return d.RootNodes.HasNodeWithTypename(typeName)
+	d.ensureNodeLookups()
+	_, ok := d.rootTypeNames[typeName]
+	return ok
 }
 
 func (d *DataSourceMetadata) HasChildNode(typeName, fieldName string) bool {
-	return d.ChildNodes.HasNode(typeName, fieldName)
+	d.ensureNodeLookups()
+	if fields, ok := d.childNodeLookup[typeName]; ok {
+		_, hasField := fields[fieldName]
+		return hasField
+	}
+	return false
 }
 
 func (d *DataSourceMetadata) HasChildNodeWithTypename(typeName string) bool {
-	return d.ChildNodes.HasNodeWithTypename(typeName)
+	d.ensureNodeLookups()
+	_, ok := d.childTypeNames[typeName]
+	return ok
+}
+
+func (d *DataSourceMetadata) ensureNodeLookups() {
+	if d.rootNodeLookup != nil && d.childNodeLookup != nil {
+		return
+	}
+
+	d.rootNodeLookup = make(map[string]map[string]struct{}, len(d.RootNodes))
+	d.childNodeLookup = make(map[string]map[string]struct{}, len(d.ChildNodes))
+	d.rootTypeNames = make(map[string]struct{}, len(d.RootNodes))
+	d.childTypeNames = make(map[string]struct{}, len(d.ChildNodes))
+
+	for _, node := range d.RootNodes {
+		d.rootTypeNames[node.TypeName] = struct{}{}
+
+		fields := d.rootNodeLookup[node.TypeName]
+		if fields == nil {
+			fields = make(map[string]struct{}, len(node.FieldNames))
+			d.rootNodeLookup[node.TypeName] = fields
+		}
+
+		for _, fieldName := range node.FieldNames {
+			fields[fieldName] = struct{}{}
+		}
+	}
+
+	for _, node := range d.ChildNodes {
+		d.childTypeNames[node.TypeName] = struct{}{}
+
+		fields := d.childNodeLookup[node.TypeName]
+		if fields == nil {
+			fields = make(map[string]struct{}, len(node.FieldNames))
+			d.childNodeLookup[node.TypeName] = fields
+		}
+
+		for _, fieldName := range node.FieldNames {
+			fields[fieldName] = struct{}{}
+		}
+	}
+}
+
+func (d *DataSourceMetadata) ensureInterfaceObjectLookup() {
+	if d.interfaceObjectMembers != nil {
+		return
+	}
+
+	d.interfaceObjectMembers = make(map[string]struct{}, len(d.InterfaceObjects)*2)
+	d.interfaceObjectNameByType = make(map[string]string, len(d.InterfaceObjects)*2)
+
+	for _, cfg := range d.InterfaceObjects {
+		d.interfaceObjectMembers[cfg.InterfaceTypeName] = struct{}{}
+		for _, typeName := range cfg.ConcreteTypeNames {
+			if _, exists := d.interfaceObjectNameByType[typeName]; !exists {
+				d.interfaceObjectNameByType[typeName] = cfg.InterfaceTypeName
+			}
+			d.interfaceObjectMembers[typeName] = struct{}{}
+		}
+	}
+}
+
+func (d *DataSourceMetadata) ensureEntityInterfaceLookup() {
+	if d.entityInterfaceMembers != nil {
+		return
+	}
+
+	d.entityInterfaceMembers = make(map[string]struct{}, len(d.EntityInterfaces)*2)
+
+	for _, cfg := range d.EntityInterfaces {
+		d.entityInterfaceMembers[cfg.InterfaceTypeName] = struct{}{}
+		for _, typeName := range cfg.ConcreteTypeNames {
+			d.entityInterfaceMembers[typeName] = struct{}{}
+		}
+	}
+}
+
+func (d *DataSourceMetadata) HasInterfaceObjectConcreteType(typeName string) bool {
+	d.ensureInterfaceObjectLookup()
+	_, ok := d.interfaceObjectNameByType[typeName]
+	return ok
+}
+
+func (d *DataSourceMetadata) IsInterfaceObjectType(typeName string) bool {
+	d.ensureInterfaceObjectLookup()
+	_, ok := d.interfaceObjectMembers[typeName]
+	return ok
+}
+
+func (d *DataSourceMetadata) InterfaceObjectNameForConcreteType(typeName string) (string, bool) {
+	d.ensureInterfaceObjectLookup()
+	name, ok := d.interfaceObjectNameByType[typeName]
+	return name, ok
+}
+
+func (d *DataSourceMetadata) IsEntityInterfaceType(typeName string) bool {
+	d.ensureEntityInterfaceLookup()
+	_, ok := d.entityInterfaceMembers[typeName]
+	return ok
 }
 
 func (d *DataSourceMetadata) ListRootNodes() TypeFields {
@@ -154,6 +277,22 @@ func (d *dataSourceConfiguration[T]) FederationConfiguration() FederationMetaDat
 	return d.FederationMetaData
 }
 
+func (d *dataSourceConfiguration[T]) HasInterfaceObjectConcreteType(typeName string) bool {
+	return d.DataSourceMetadata.HasInterfaceObjectConcreteType(typeName)
+}
+
+func (d *dataSourceConfiguration[T]) IsInterfaceObjectType(typeName string) bool {
+	return d.DataSourceMetadata.IsInterfaceObjectType(typeName)
+}
+
+func (d *dataSourceConfiguration[T]) InterfaceObjectNameForConcreteType(typeName string) (string, bool) {
+	return d.DataSourceMetadata.InterfaceObjectNameForConcreteType(typeName)
+}
+
+func (d *dataSourceConfiguration[T]) IsEntityInterfaceType(typeName string) bool {
+	return d.DataSourceMetadata.IsEntityInterfaceType(typeName)
+}
+
 func (d *dataSourceConfiguration[T]) Hash() DSHash {
 	return d.hash
 }
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_filter_collect_nodes_visitor.go b/app/v2/pkg/engine/plan/datasource_filter_collect_nodes_visitor.go
index 3852ed6..c295ed0 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/datasource_filter_collect_nodes_visitor.go
+++ b/app/v2/pkg/engine/plan/datasource_filter_collect_nodes_visitor.go
@@ -1,8 +1,6 @@
 package plan
 
 import (
-	"slices"
-
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/ast"
 	"github.com/wundergraph/graphql-go-tools/v2/pkg/astvisitor"
 )
@@ -38,6 +36,9 @@ func (f *collectNodesVisitor) EnterField(ref int) {
 	if f.nodes.IsFieldSeen(ref) {
 		currentNodeId := TreeNodeID(ref)
 		f.parentNodeIds = append(f.parentNodeIds, currentNodeId)
+		if !f.operation.FieldHasSelections(ref) {
+			f.walker.SkipNode()
+		}
 		return
 	}
 	f.nodes.AddSeenField(ref)
@@ -64,12 +65,8 @@ func (f *collectNodesVisitor) EnterField(ref int) {
 		hasChildNode := v.HasChildNode(typeName, fieldName) || (isTypeName && v.HasChildNodeWithTypename(typeName))
 
 		allowTypeName := true
-		// we should not select a typename on the interface object
-		for _, k := range v.FederationConfiguration().InterfaceObjects {
-			if k.InterfaceTypeName == typeName || slices.Contains(k.ConcreteTypeNames, typeName) {
-				allowTypeName = false
-				break
-			}
+		if v.IsInterfaceObjectType(typeName) {
+			allowTypeName = false
 		}
 
 		lessPreferable := false
diff --git a/tmp/agent-patch-flux-pr-859.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 9fa8e45..4c67369 100644
--- a/tmp/agent-patch-flux-pr-859.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
@@ -495,12 +495,9 @@ func (v *Visitor) addInterfaceObjectNameToTypeNames(fieldRef int, typeName []byt
 			continue
 		}
 
-		for _, interfaceObjCfg := range v.planners[i].DataSourceConfiguration().FederationConfiguration().InterfaceObjects {
-			if slices.Contains(interfaceObjCfg.ConcreteTypeNames, string(typeName)) {
-				includeInterfaceObjectName = true
-				interfaceObjectName = interfaceObjCfg.InterfaceTypeName
-				break
-			}
+		if name, ok := v.planners[i].DataSourceConfiguration().InterfaceObjectNameForConcreteType(string(typeName)); ok {
+			includeInterfaceObjectName = true
+			interfaceObjectName = name
 		}
 	}
 	if includeInterfaceObjectName {