agent_patch
runs/2026-02-28__13-38-10__gpt-5-3-codex/flux-pr-1128/flux-pr-1128.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/agent-logs/agent.patch
8292 bytes
diff --git a/tmp/agent-patch-flux-pr-1128.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 e4eedb8..a851132 100644
--- a/tmp/agent-patch-flux-pr-1128.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
@@ -101,6 +101,7 @@ type objectFetchConfiguration struct {
trigger *resolve.GraphQLSubscriptionTrigger
filter *resolve.SubscriptionFilter
planner DataSourceFetchPlanner
+ skipFetch bool
isSubscription bool
fieldRef int
fieldDefinitionRef int
@@ -828,6 +829,7 @@ func (c *configurationVisitor) addNewPlanner(fieldRef int, typeName, fieldName,
fetchConfiguration := &objectFetchConfiguration{
isSubscription: isSubscription,
+ skipFetch: c.shouldResolveFieldStatically(typeName, fieldName),
fieldRef: fieldRef,
fieldDefinitionRef: fieldDefinition,
fetchID: fetchID,
@@ -992,6 +994,49 @@ func (c *configurationVisitor) resolveRootFieldOperationType(typeName string) as
return ast.OperationTypeQuery
}
+func (c *configurationVisitor) shouldResolveFieldStatically(typeName, fieldName string) bool {
+ if fieldName != typeNameField {
+ return false
+ }
+
+ if !c.isRootOperationField() {
+ return false
+ }
+
+ return c.isRootOperationType(typeName)
+}
+
+func (c *configurationVisitor) isRootOperationField() bool {
+ if len(c.walker.Path) == 0 {
+ return false
+ }
+
+ for i := 1; i < len(c.walker.Path); i++ {
+ if c.walker.Path[i].Kind != ast.InlineFragmentName {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (c *configurationVisitor) isRootOperationType(typeName string) bool {
+ queryTypeName := c.definition.Index.QueryTypeName.String()
+ if queryTypeName == "" {
+ queryTypeName = "Query"
+ }
+ mutationTypeName := c.definition.Index.MutationTypeName.String()
+ if mutationTypeName == "" {
+ mutationTypeName = "Mutation"
+ }
+ subscriptionTypeName := c.definition.Index.SubscriptionTypeName.String()
+ if subscriptionTypeName == "" {
+ subscriptionTypeName = "Subscription"
+ }
+
+ return typeName == queryTypeName || typeName == mutationTypeName || typeName == subscriptionTypeName
+}
+
// handleMissingPath - records missing path for the case when we don't yet have a planner for the field
func (c *configurationVisitor) handleMissingPath(planned bool, typeName string, fieldName string, currentPath string, shareable bool) {
suggestions := c.nodeSuggestions.SuggestionsForPath(typeName, fieldName, currentPath)
diff --git a/tmp/agent-patch-flux-pr-1128.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 222a288..d269b11 100644
--- a/tmp/agent-patch-flux-pr-1128.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
@@ -505,12 +505,13 @@ func TreeNodeID(fieldRef int) uint {
}
const (
- queryTypeName = "Query"
- mutationTypeName = "Mutation"
+ queryTypeName = "Query"
+ mutationTypeName = "Mutation"
+ subscriptionTypeName = "Subscription"
)
func IsMutationOrQueryRootType(typeName string) bool {
- return queryTypeName == typeName || mutationTypeName == typeName
+ return queryTypeName == typeName || mutationTypeName == typeName || subscriptionTypeName == typeName
}
func getFieldInfo(operation, definition *ast.Document) map[int]fieldInfo {
diff --git a/tmp/agent-patch-flux-pr-1128.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/planner_test.go b/app/v2/pkg/engine/plan/planner_test.go
index e9e1f88..325f131 100644
--- a/tmp/agent-patch-flux-pr-1128.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/planner_test.go
+++ b/app/v2/pkg/engine/plan/planner_test.go
@@ -174,6 +174,31 @@ func TestPlanner_Plan(t *testing.T) {
DataSources: []DataSource{testDefinitionDSConfiguration},
}))
+ t.Run("Root operation typename is resolved statically without fetch", test(testDefinition, `
+ query RootTypename {
+ __typename
+ }
+ `, "RootTypename", &SynchronousResponsePlan{
+ Response: &resolve.GraphQLResponse{
+ Data: &resolve.Object{
+ Nullable: false,
+ Fields: []*resolve.Field{
+ {
+ Name: []byte("__typename"),
+ Value: &resolve.StaticString{
+ Path: []string{"__typename"},
+ Value: "Query",
+ },
+ },
+ },
+ },
+ },
+ }, Configuration{
+ DisableResolveFieldPositions: true,
+ DisableIncludeInfo: true,
+ DataSources: []DataSource{testDefinitionDSConfiguration},
+ }))
+
t.Run("Merging duplicate fields in response should not happen", func(t *testing.T) {
t.Run("Interface response type with type fragments and shared field", test(testDefinition, `
query Hero {
diff --git a/tmp/agent-patch-flux-pr-1128.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/visitor.go b/app/v2/pkg/engine/plan/visitor.go
index 261d475..de51326 100644
--- a/tmp/agent-patch-flux-pr-1128.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/plan/visitor.go
+++ b/app/v2/pkg/engine/plan/visitor.go
@@ -336,12 +336,19 @@ func (v *Visitor) EnterField(ref int) {
}
if bytes.Equal(fieldName, literal.TYPENAME) {
- str := &resolve.String{
- Nullable: false,
- Path: []string{v.Operation.FieldAliasOrNameString(ref)},
- IsTypeName: true,
+ if typeName, ok := v.staticRootOperationTypeName(); ok {
+ v.currentField.Value = &resolve.StaticString{
+ Path: []string{v.Operation.FieldAliasOrNameString(ref)},
+ Value: typeName,
+ }
+ } else {
+ str := &resolve.String{
+ Nullable: false,
+ Path: []string{v.Operation.FieldAliasOrNameString(ref)},
+ IsTypeName: true,
+ }
+ v.currentField.Value = str
}
- v.currentField.Value = str
} else {
path := v.resolveFieldPath(ref)
v.currentField.Value = v.resolveFieldValue(ref, fieldDefinitionTypeRef, true, path)
@@ -1144,6 +1151,10 @@ func (v *Visitor) renderJSONValueTemplate(value ast.Value, variables *resolve.Va
}
func (v *Visitor) configureSubscription(config *objectFetchConfiguration) {
+ if config.skipFetch {
+ return
+ }
+
subscription := config.planner.ConfigureSubscription()
config.trigger.Variables = subscription.Variables
config.trigger.Source = subscription.DataSource
@@ -1153,6 +1164,10 @@ func (v *Visitor) configureSubscription(config *objectFetchConfiguration) {
}
func (v *Visitor) configureObjectFetch(config *objectFetchConfiguration) {
+ if config.skipFetch {
+ return
+ }
+
if config.object == nil {
v.Walker.StopWithInternalErr(fmt.Errorf("object fetch configuration has empty object"))
return
@@ -1167,6 +1182,38 @@ func (v *Visitor) configureObjectFetch(config *objectFetchConfiguration) {
config.object.Fetches = append(config.object.Fetches, fetch)
}
+func (v *Visitor) staticRootOperationTypeName() (string, bool) {
+ if len(v.Walker.Path) == 0 {
+ return "", false
+ }
+
+ for i := 1; i < len(v.Walker.Path); i++ {
+ if v.Walker.Path[i].Kind != ast.InlineFragmentName {
+ return "", false
+ }
+ }
+
+ enclosingTypeName := v.Walker.EnclosingTypeDefinition.NameString(v.Definition)
+ queryTypeName := v.Definition.Index.QueryTypeName.String()
+ if queryTypeName == "" {
+ queryTypeName = "Query"
+ }
+ mutationTypeName := v.Definition.Index.MutationTypeName.String()
+ if mutationTypeName == "" {
+ mutationTypeName = "Mutation"
+ }
+ subscriptionTypeName := v.Definition.Index.SubscriptionTypeName.String()
+ if subscriptionTypeName == "" {
+ subscriptionTypeName = "Subscription"
+ }
+
+ if enclosingTypeName != queryTypeName && enclosingTypeName != mutationTypeName && enclosingTypeName != subscriptionTypeName {
+ return "", false
+ }
+
+ return enclosingTypeName, true
+}
+
func (v *Visitor) configureFetch(internal *objectFetchConfiguration, external resolve.FetchConfiguration) *resolve.SingleFetch {
dataSourceType := reflect.TypeOf(external.DataSource).String()
dataSourceType = strings.TrimPrefix(dataSourceType, "*")