STET

agent_patch

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

17820 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/abstract_selection_rewriter.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
index c5794ce..cc1e876 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
@@ -60,12 +60,19 @@ type fieldSelectionRewriter struct {
 
 	upstreamDefinition *ast.Document
 	dsConfiguration    DataSource
+
+	definitionInterfaceImplementors map[int][]string
+	upstreamInterfaceImplementors   map[int][]string
+	upstreamInterfaceEntities       map[int][]string
 }
 
 func newFieldSelectionRewriter(operation *ast.Document, definition *ast.Document) *fieldSelectionRewriter {
 	return &fieldSelectionRewriter{
-		operation:  operation,
-		definition: definition,
+		operation:                       operation,
+		definition:                      definition,
+		definitionInterfaceImplementors: make(map[int][]string),
+		upstreamInterfaceImplementors:   make(map[int][]string),
+		upstreamInterfaceEntities:       make(map[int][]string),
 	}
 }
 
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
index ad5ea1d..7652d7c 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
@@ -127,12 +127,9 @@ func (r *fieldSelectionRewriter) collectInlineFragmentInformation(
 		return nil
 	}
 
-	typeNamesImplementingInterface, _ := r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames(definitionNode.Ref)
-	sort.Strings(typeNamesImplementingInterface)
-
 	inlineFragmentSelectionOnInterface := inlineFragmentSelectionOnInterface{
 		inlineFragmentSelection:        inlineFragmentSelection,
-		typeNamesImplementingInterface: typeNamesImplementingInterface,
+		typeNamesImplementingInterface: r.typeNamesImplementingDefinitionInterface(definitionNode.Ref),
 	}
 
 	// NOTE: We are getting type names implementing interface from the current SUBGRAPH definion
@@ -140,11 +137,8 @@ func (r *fieldSelectionRewriter) collectInlineFragmentInformation(
 	upstreamNode, hasUpstreamNode := r.upstreamDefinition.NodeByNameStr(typeCondition)
 	if hasUpstreamNode {
 		if upstreamNode.Kind == ast.NodeKindInterfaceTypeDefinition {
-			typeNamesImplementingInterface, _ := r.upstreamDefinition.InterfaceTypeDefinitionImplementedByObjectWithNames(upstreamNode.Ref)
-			entityNames, _ := r.datasourceHasEntitiesWithName(typeNamesImplementingInterface)
-
-			inlineFragmentSelectionOnInterface.typeNamesImplementingInterfaceInCurrentDS = typeNamesImplementingInterface
-			inlineFragmentSelectionOnInterface.entityNamesImplementingInterface = entityNames
+			inlineFragmentSelectionOnInterface.typeNamesImplementingInterfaceInCurrentDS = r.typeNamesImplementingUpstreamInterface(upstreamNode.Ref)
+			inlineFragmentSelectionOnInterface.entityNamesImplementingInterface = r.entityNamesImplementingUpstreamInterface(upstreamNode.Ref)
 		}
 	}
 
@@ -153,6 +147,39 @@ func (r *fieldSelectionRewriter) collectInlineFragmentInformation(
 	return nil
 }
 
+func (r *fieldSelectionRewriter) typeNamesImplementingDefinitionInterface(interfaceRef int) []string {
+	if implementors, ok := r.definitionInterfaceImplementors[interfaceRef]; ok {
+		return implementors
+	}
+
+	implementors, _ := r.definition.InterfaceTypeDefinitionImplementedByObjectWithNames(interfaceRef)
+	sort.Strings(implementors)
+	r.definitionInterfaceImplementors[interfaceRef] = implementors
+	return implementors
+}
+
+func (r *fieldSelectionRewriter) typeNamesImplementingUpstreamInterface(interfaceRef int) []string {
+	if implementors, ok := r.upstreamInterfaceImplementors[interfaceRef]; ok {
+		return implementors
+	}
+
+	implementors, _ := r.upstreamDefinition.InterfaceTypeDefinitionImplementedByObjectWithNames(interfaceRef)
+	sort.Strings(implementors)
+	r.upstreamInterfaceImplementors[interfaceRef] = implementors
+	return implementors
+}
+
+func (r *fieldSelectionRewriter) entityNamesImplementingUpstreamInterface(interfaceRef int) []string {
+	if entities, ok := r.upstreamInterfaceEntities[interfaceRef]; ok {
+		return entities
+	}
+
+	implementors := r.typeNamesImplementingUpstreamInterface(interfaceRef)
+	entities, _ := r.datasourceHasEntitiesWithName(implementors)
+	r.upstreamInterfaceEntities[interfaceRef] = entities
+	return entities
+}
+
 func (r *fieldSelectionRewriter) collectSelectionSetInformation(selectionSetRef int, skipTypeName bool) (selectionSetInfo, error) {
 	fieldSelections, hasSharedTypename := r.selectionSetFieldSelections(selectionSetRef, skipTypeName)
 
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/configuration_visitor.go b/app/v2/pkg/engine/plan/configuration_visitor.go
index 505795a..3da9298 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/configuration_visitor.go
+++ b/app/v2/pkg/engine/plan/configuration_visitor.go
@@ -44,6 +44,8 @@ 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[pathDSKey]struct{} // addedPathIndex provides O(1) lookups for path+datasource pairs
+	addedPathDSIndex   map[string]DSHash      // addedPathDSIndex stores the first datasource hash seen for a path
 
 	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
@@ -57,6 +59,8 @@ type configurationVisitor struct {
 	secondaryRun bool // secondaryRun is a flag to indicate that we're running the configurationVisitor not the first time
 	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
 	fieldRef     int  // fieldRef is the reference for the current field; it is required by subscription filter to retrieve any variables
+
+	processedFieldRefs map[int]struct{} // processedFieldRefs tracks fields that already went through expensive planning checks
 }
 
 func (c *configurationVisitor) shouldRevisit() bool {
@@ -92,6 +96,11 @@ type missingPath struct {
 	precedingRootNodePath string
 }
 
+type pathDSKey struct {
+	path   string
+	dsHash DSHash
+}
+
 func (p *missingPath) String() string {
 	return fmt.Sprintf(`{"path":"%s","precedingRootNodePath":"%s"}`, p.path, p.precedingRootNodePath)
 }
@@ -184,28 +193,25 @@ func (c *configurationVisitor) saveAddedPath(configuration pathConfiguration) {
 	}
 
 	c.addedPathTracker = append(c.addedPathTracker, configuration)
+	c.addedPathIndex[pathDSKey{
+		path:   configuration.path,
+		dsHash: configuration.dsHash,
+	}] = struct{}{}
+	if _, ok := c.addedPathDSIndex[configuration.path]; !ok {
+		c.addedPathDSIndex[configuration.path] = configuration.dsHash
+	}
 
 	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
-		}
-	}
-	return 0, false
+	hash, ok = c.addedPathDSIndex[path]
+	return hash, ok
 }
 
 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
-		}
-	}
-	return false
+	_, ok := c.addedPathIndex[pathDSKey{path: path, dsHash: hash}]
+	return ok
 }
 
 func (c *configurationVisitor) findPreviousRootPath(currentPath string) (previousRootPath string, found bool) {
@@ -300,6 +306,8 @@ func (c *configurationVisitor) EnterDocument(operation, definition *ast.Document
 
 	c.missingPathTracker = make(map[string]missingPath)
 	c.addedPathTracker = make([]pathConfiguration, 0, 8)
+	c.addedPathIndex = make(map[pathDSKey]struct{}, 16)
+	c.addedPathDSIndex = make(map[string]DSHash, 16)
 
 	c.pendingRequiredFields = make(map[int]selectionSetPendingRequirements)
 	c.fieldDependenciesForPlanners = make(map[int][]int)
@@ -310,6 +318,7 @@ func (c *configurationVisitor) EnterDocument(operation, definition *ast.Document
 	c.processedFieldNotHavingRequires = make(map[int]struct{})
 	c.fieldsWithProcessedProvides = make(map[int]struct{})
 	c.visitedFieldsAbstractChecks = make(map[int]struct{})
+	c.processedFieldRefs = make(map[int]struct{})
 }
 
 func (c *configurationVisitor) LeaveDocument(operation, definition *ast.Document) {
@@ -381,6 +390,7 @@ func (c *configurationVisitor) EnterField(ref int) {
 	typeName := c.walker.EnclosingTypeDefinition.NameString(c.definition)
 
 	c.debugPrint("EnterField ref:", ref, "fieldName:", fieldName, "typeName:", typeName)
+	defer c.markFieldProcessed(ref)
 
 	parentPath := c.walker.Path.DotDelimitedString()
 	// we need to also check preceding path for inline fragments
@@ -395,6 +405,10 @@ func (c *configurationVisitor) EnterField(ref int) {
 	currentPath := parentPath + "." + fieldAliasOrName
 
 	c.addArrayField(ref, currentPath)
+	if c.secondaryRun && c.shouldSkipSecondaryRunField(ref, currentPath) {
+		return
+	}
+
 	c.handleProvidesSuggestions(ref, typeName, fieldName, currentPath)
 
 	root := c.walker.Ancestors[0]
@@ -432,6 +446,34 @@ func (c *configurationVisitor) EnterField(ref int) {
 	c.handleMissingPath(typeName, fieldName, currentPath)
 }
 
+func (c *configurationVisitor) markFieldProcessed(fieldRef int) {
+	c.processedFieldRefs[fieldRef] = struct{}{}
+}
+
+func (c *configurationVisitor) shouldSkipSecondaryRunField(fieldRef int, currentPath string) bool {
+	if _, processed := c.processedFieldRefs[fieldRef]; !processed {
+		return false
+	}
+
+	if _, waitingForDependency := c.fieldWaitingForRequiresDependency[fieldRef]; waitingForDependency {
+		return false
+	}
+
+	if _, hasMissingPath := c.missingPathTracker[currentPath]; hasMissingPath {
+		return false
+	}
+
+	if c.hasMissingPathWithParentPath(currentPath) {
+		return false
+	}
+
+	if _, planned := c.fieldsPlannedOn[fieldRef]; !planned {
+		return false
+	}
+
+	return true
+}
+
 func (c *configurationVisitor) addRootField(fieldRef, plannerIdx int) {
 
 	if c.fieldIsChildNode(plannerIdx) {
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/datasource_configuration.go b/app/v2/pkg/engine/plan/datasource_configuration.go
index f078113..695c5b6 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/datasource_configuration.go
+++ b/app/v2/pkg/engine/plan/datasource_configuration.go
@@ -3,6 +3,7 @@ package plan
 import (
 	"context"
 	"errors"
+	"sync"
 
 	"github.com/cespare/xxhash/v2"
 	"github.com/jensneuse/abstractlogger"
@@ -40,6 +41,16 @@ type DataSourceMetadata struct {
 	// Note: Unions are not present in the child or root nodes
 	ChildNodes TypeFields
 	Directives *DirectiveConfigurations
+
+	rootNodesIndex  typeFieldsIndex
+	childNodesIndex typeFieldsIndex
+	indexesMu       sync.Mutex
+	indexesReady    bool
+}
+
+type typeFieldsIndex struct {
+	byType   map[string]map[string]struct{}
+	typeOnly map[string]struct{}
 }
 
 type DirectivesConfigurations interface {
@@ -63,19 +74,35 @@ func (d *DataSourceMetadata) DirectiveConfigurations() *DirectiveConfigurations
 }
 
 func (d *DataSourceMetadata) HasRootNode(typeName, fieldName string) bool {
-	return d.RootNodes.HasNode(typeName, fieldName)
+	d.prepareIndexes()
+	fieldsByType, ok := d.rootNodesIndex.byType[typeName]
+	if !ok {
+		return false
+	}
+	_, ok = fieldsByType[fieldName]
+	return ok
 }
 
 func (d *DataSourceMetadata) HasRootNodeWithTypename(typeName string) bool {
-	return d.RootNodes.HasNodeWithTypename(typeName)
+	d.prepareIndexes()
+	_, ok := d.rootNodesIndex.typeOnly[typeName]
+	return ok
 }
 
 func (d *DataSourceMetadata) HasChildNode(typeName, fieldName string) bool {
-	return d.ChildNodes.HasNode(typeName, fieldName)
+	d.prepareIndexes()
+	fieldsByType, ok := d.childNodesIndex.byType[typeName]
+	if !ok {
+		return false
+	}
+	_, ok = fieldsByType[fieldName]
+	return ok
 }
 
 func (d *DataSourceMetadata) HasChildNodeWithTypename(typeName string) bool {
-	return d.ChildNodes.HasNodeWithTypename(typeName)
+	d.prepareIndexes()
+	_, ok := d.childNodesIndex.typeOnly[typeName]
+	return ok
 }
 
 func (d *DataSourceMetadata) ListRootNodes() TypeFields {
@@ -87,6 +114,43 @@ func (d *DataSourceMetadata) ListChildNodes() TypeFields {
 
 }
 
+func (d *DataSourceMetadata) prepareIndexes() {
+	if d.indexesReady {
+		return
+	}
+
+	d.indexesMu.Lock()
+	defer d.indexesMu.Unlock()
+	if d.indexesReady {
+		return
+	}
+
+	d.rootNodesIndex = buildTypeFieldsIndex(d.RootNodes)
+	d.childNodesIndex = buildTypeFieldsIndex(d.ChildNodes)
+	d.indexesReady = true
+}
+
+func buildTypeFieldsIndex(nodes TypeFields) typeFieldsIndex {
+	index := typeFieldsIndex{
+		byType:   make(map[string]map[string]struct{}, len(nodes)),
+		typeOnly: make(map[string]struct{}, len(nodes)),
+	}
+
+	for i := range nodes {
+		typeName := nodes[i].TypeName
+		index.typeOnly[typeName] = struct{}{}
+
+		if _, ok := index.byType[typeName]; !ok {
+			index.byType[typeName] = make(map[string]struct{}, len(nodes[i].FieldNames))
+		}
+		for j := range nodes[i].FieldNames {
+			index.byType[typeName][nodes[i].FieldNames[j]] = struct{}{}
+		}
+	}
+
+	return index
+}
+
 // dataSourceConfiguration is the configuration for a DataSource
 type dataSourceConfiguration[T any] struct {
 	*DataSourceMetadata                   // DataSourceMetadata is the information about root and child nodes and federation metadata if applicable
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/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..da32829 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/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"
 )
@@ -19,10 +17,18 @@ type collectNodesVisitor struct {
 	parentNodeIds []uint
 
 	saveSelectionReason bool
+
+	dsIndexes []collectNodesDataSourceIndex
+}
+
+type collectNodesDataSourceIndex struct {
+	blockedTypeName         map[string]struct{}
+	lessPreferableRootTypes map[string]struct{}
 }
 
 func (f *collectNodesVisitor) EnterDocument(_, _ *ast.Document) {
 	f.parentNodeIds = []uint{treeRootID}
+	f.buildDataSourceIndexes()
 
 	if !f.secondaryRun {
 		f.nodes = NewNodeSuggestions()
@@ -34,6 +40,33 @@ func (f *collectNodesVisitor) EnterDocument(_, _ *ast.Document) {
 	}
 }
 
+func (f *collectNodesVisitor) buildDataSourceIndexes() {
+	f.dsIndexes = make([]collectNodesDataSourceIndex, len(f.dataSources))
+
+	for i := range f.dataSources {
+		index := collectNodesDataSourceIndex{
+			blockedTypeName:         make(map[string]struct{}),
+			lessPreferableRootTypes: make(map[string]struct{}),
+		}
+
+		federationCfg := f.dataSources[i].FederationConfiguration()
+		for _, interfaceObject := range federationCfg.InterfaceObjects {
+			index.blockedTypeName[interfaceObject.InterfaceTypeName] = struct{}{}
+			for _, concreteType := range interfaceObject.ConcreteTypeNames {
+				index.blockedTypeName[concreteType] = struct{}{}
+			}
+		}
+
+		for _, key := range federationCfg.Keys {
+			if key.DisableEntityResolver {
+				index.lessPreferableRootTypes[key.TypeName] = struct{}{}
+			}
+		}
+
+		f.dsIndexes[i] = index
+	}
+}
+
 func (f *collectNodesVisitor) EnterField(ref int) {
 	if f.nodes.IsFieldSeen(ref) {
 		currentNodeId := TreeNodeID(ref)
@@ -59,27 +92,16 @@ func (f *collectNodesVisitor) EnterField(ref int) {
 
 	itemIds := make([]int, 0, 1)
 
-	for _, v := range f.dataSources {
+	for i, v := range f.dataSources {
 		hasRootNode := v.HasRootNode(typeName, fieldName) || (isTypeName && v.HasRootNodeWithTypename(typeName))
 		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
-			}
-		}
+		_, blockedTypeName := f.dsIndexes[i].blockedTypeName[typeName]
+		allowTypeName := !blockedTypeName
 
 		lessPreferable := false
 		if hasRootNode {
-			for _, k := range v.FederationConfiguration().Keys {
-				if k.TypeName == typeName && k.DisableEntityResolver {
-					lessPreferable = true
-					break
-				}
-			}
+			_, lessPreferable = f.dsIndexes[i].lessPreferableRootTypes[typeName]
 		}
 
 		if !allowTypeName && isTypeName {