STET

agent_patch

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

8605 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/configuration_visitor.go b/app/v2/pkg/engine/plan/configuration_visitor.go
index 505795a..8896dcb 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/configuration_visitor.go
+++ b/app/v2/pkg/engine/plan/configuration_visitor.go
@@ -38,12 +38,13 @@ type configurationVisitor struct {
 	nodeSuggestions     *NodeSuggestions     // nodeSuggestions holds information about suggested data sources for each field
 	nodeSuggestionHints []NodeSuggestionHint // nodeSuggestionHints holds information about suggested data sources for key fields
 
-	parentTypeNodes    []ast.Node             // parentTypeNodes is a stack of parent type nodes - used to determine if the parent is abstract
-	arrayFields        []arrayField           // arrayFields is a stack of array fields - used to plan nested queries
-	selectionSetRefs   []int                  // selectionSetRefs is a stack of selection set refs - used to add a required fields
-	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
+	parentTypeNodes       []ast.Node             // parentTypeNodes is a stack of parent type nodes - used to determine if the parent is abstract
+	arrayFields           []arrayField           // arrayFields is a stack of array fields - used to plan nested queries
+	selectionSetRefs      []int                  // selectionSetRefs is a stack of selection set refs - used to add a required fields
+	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
+	addedPathTrackerIndex map[pathConfiguration]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,6 +185,7 @@ func (c *configurationVisitor) saveAddedPath(configuration pathConfiguration) {
 	}
 
 	c.addedPathTracker = append(c.addedPathTracker, configuration)
+	c.addedPathTrackerIndex[pathConfiguration{path: configuration.path, dsHash: configuration.dsHash}] = struct{}{}
 
 	c.removeMissingPath(configuration.path)
 }
@@ -199,13 +201,8 @@ func (c *configurationVisitor) addedPathDSHash(path string) (hash DSHash, ok boo
 }
 
 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.addedPathTrackerIndex[pathConfiguration{path: path, dsHash: hash}]
+	return ok
 }
 
 func (c *configurationVisitor) findPreviousRootPath(currentPath string) (previousRootPath string, found bool) {
@@ -300,6 +297,7 @@ func (c *configurationVisitor) EnterDocument(operation, definition *ast.Document
 
 	c.missingPathTracker = make(map[string]missingPath)
 	c.addedPathTracker = make([]pathConfiguration, 0, 8)
+	c.addedPathTrackerIndex = make(map[pathConfiguration]struct{}, 8)
 
 	c.pendingRequiredFields = make(map[int]selectionSetPendingRequirements)
 	c.fieldDependenciesForPlanners = make(map[int][]int)
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/datasource_configuration.go b/app/v2/pkg/engine/plan/datasource_configuration.go
index f078113..ba87188 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/datasource_configuration.go
+++ b/app/v2/pkg/engine/plan/datasource_configuration.go
@@ -40,6 +40,9 @@ type DataSourceMetadata struct {
 	// Note: Unions are not present in the child or root nodes
 	ChildNodes TypeFields
 	Directives *DirectiveConfigurations
+
+	rootNodesIndex  TypeFieldsIndex
+	childNodesIndex TypeFieldsIndex
 }
 
 type DirectivesConfigurations interface {
@@ -63,19 +66,31 @@ func (d *DataSourceMetadata) DirectiveConfigurations() *DirectiveConfigurations
 }
 
 func (d *DataSourceMetadata) HasRootNode(typeName, fieldName string) bool {
-	return d.RootNodes.HasNode(typeName, fieldName)
+	if d.rootNodesIndex == nil {
+		d.InitNodesIndex()
+	}
+	return d.rootNodesIndex.HasNode(typeName, fieldName)
 }
 
 func (d *DataSourceMetadata) HasRootNodeWithTypename(typeName string) bool {
-	return d.RootNodes.HasNodeWithTypename(typeName)
+	if d.rootNodesIndex == nil {
+		d.InitNodesIndex()
+	}
+	return d.rootNodesIndex.HasNodeWithTypename(typeName)
 }
 
 func (d *DataSourceMetadata) HasChildNode(typeName, fieldName string) bool {
-	return d.ChildNodes.HasNode(typeName, fieldName)
+	if d.childNodesIndex == nil {
+		d.InitNodesIndex()
+	}
+	return d.childNodesIndex.HasNode(typeName, fieldName)
 }
 
 func (d *DataSourceMetadata) HasChildNodeWithTypename(typeName string) bool {
-	return d.ChildNodes.HasNodeWithTypename(typeName)
+	if d.childNodesIndex == nil {
+		d.InitNodesIndex()
+	}
+	return d.childNodesIndex.HasNodeWithTypename(typeName)
 }
 
 func (d *DataSourceMetadata) ListRootNodes() TypeFields {
@@ -102,6 +117,8 @@ func NewDataSourceConfiguration[T any](id string, factory PlannerFactory[T], met
 		return nil, errors.New("data source id could not be empty")
 	}
 
+	metadata.InitNodesIndex()
+
 	return &dataSourceConfiguration[T]{
 		ID:                 id,
 		Factory:            factory,
@@ -158,6 +175,11 @@ func (d *dataSourceConfiguration[T]) Hash() DSHash {
 	return d.hash
 }
 
+func (d *DataSourceMetadata) InitNodesIndex() {
+	d.rootNodesIndex = d.RootNodes.Index()
+	d.childNodesIndex = d.ChildNodes.Index()
+}
+
 type DataSourcePlannerConfiguration struct {
 	RequiredFields FederationFieldConfigurations
 	ProvidedFields *NodeSuggestions
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go b/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
index 5218995..bb25992 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
+++ b/app/v2/pkg/engine/plan/datasource_filter_visitor_test.go
@@ -66,7 +66,9 @@ func newNodeSuggestions(nodes []NodeSuggestion) *NodeSuggestions {
 	for i := range nodes {
 		items = append(items, &nodes[i])
 	}
-	return &NodeSuggestions{items: items}
+	suggestions := &NodeSuggestions{items: items}
+	suggestions.populateHasSuggestions()
+	return suggestions
 }
 
 func TestFindBestDataSourceSet(t *testing.T) {
diff --git a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/type_field.go b/app/v2/pkg/engine/plan/type_field.go
index 80f7125..d993ef6 100644
--- a/tmp/agent-patch-flux-pr-859.1-of-1.2026-02-28__13-38-10__gpt-5-4/app/v2/pkg/engine/plan/type_field.go
+++ b/app/v2/pkg/engine/plan/type_field.go
@@ -7,6 +7,23 @@ type TypeField struct {
 
 type TypeFields []TypeField
 
+type TypeFieldsIndex map[string]map[string]struct{}
+
+func (f TypeFields) Index() TypeFieldsIndex {
+	index := make(TypeFieldsIndex, len(f))
+	for i := range f {
+		fieldNames, ok := index[f[i].TypeName]
+		if !ok {
+			fieldNames = make(map[string]struct{}, len(f[i].FieldNames))
+			index[f[i].TypeName] = fieldNames
+		}
+		for j := range f[i].FieldNames {
+			fieldNames[f[i].FieldNames[j]] = struct{}{}
+		}
+	}
+	return index
+}
+
 func (f TypeFields) HasNode(typeName, fieldName string) bool {
 	for i := range f {
 		if typeName != f[i].TypeName {
@@ -30,3 +47,17 @@ func (f TypeFields) HasNodeWithTypename(typeName string) bool {
 	}
 	return false
 }
+
+func (i TypeFieldsIndex) HasNode(typeName, fieldName string) bool {
+	fieldNames, ok := i[typeName]
+	if !ok {
+		return false
+	}
+	_, ok = fieldNames[fieldName]
+	return ok
+}
+
+func (i TypeFieldsIndex) HasNodeWithTypename(typeName string) bool {
+	_, ok := i[typeName]
+	return ok
+}