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
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
+}