STET

agent_patch

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

14983 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/compiler.go b/app/v2/pkg/engine/datasource/grpc_datasource/compiler.go
index 1b519b7..6cc424e 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/compiler.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/compiler.go
@@ -295,7 +295,12 @@ func NewProtoCompiler(schema string, mapping *GRPCMapping) (*RPCCompiler, error)
 
 	// Process all services in the schema
 	for i := 0; i < f.Services().Len(); i++ {
-		pc.doc.Services = append(pc.doc.Services, pc.parseService(f.Services().Get(i)))
+		service, err := pc.parseService(f.Services().Get(i))
+		if err != nil {
+			return nil, err
+		}
+
+		pc.doc.Services = append(pc.doc.Services, service)
 	}
 
 	return pc, nil
@@ -322,8 +327,18 @@ func (p *RPCCompiler) Compile(executionPlan *RPCExecutionPlan, inputData gjson.R
 	invocations := make([]Invocation, 0, len(executionPlan.Calls))
 
 	for _, call := range executionPlan.Calls {
-		inputMessage := p.doc.MessageByName(call.Request.Name)
-		outputMessage := p.doc.MessageByName(call.Response.Name)
+		inputMessageRef := p.doc.MessageRefByName(call.Request.Name)
+		if inputMessageRef == -1 {
+			return nil, fmt.Errorf("request message type %q for method %q not found in protobuf schema", call.Request.Name, call.MethodName)
+		}
+
+		outputMessageRef := p.doc.MessageRefByName(call.Response.Name)
+		if outputMessageRef == -1 {
+			return nil, fmt.Errorf("response message type %q for method %q not found in protobuf schema", call.Response.Name, call.MethodName)
+		}
+
+		inputMessage := p.doc.MessageByRef(inputMessageRef)
+		outputMessage := p.doc.MessageByRef(outputMessageRef)
 
 		request := p.buildProtoMessage(inputMessage, &call.Request, inputData)
 		response := p.newEmptyMessage(outputMessage)
@@ -519,16 +534,25 @@ func (p *RPCCompiler) parseEnumValue(v protoref.EnumValueDescriptor, enumValueMa
 
 // parseService extracts information from a protobuf service descriptor,
 // including all its methods.
-func (p *RPCCompiler) parseService(s protoref.ServiceDescriptor) Service {
+func (p *RPCCompiler) parseService(s protoref.ServiceDescriptor) (Service, error) {
 	name := string(s.Name())
 	m := s.Methods()
 
 	methods := make([]Method, 0, m.Len())
 	methodsRefs := make([]int, 0, m.Len())
+	methodOffset := len(p.doc.Methods)
 
 	for j := 0; j < m.Len(); j++ {
-		methods = append(methods, p.parseMethod(m.Get(j)))
-		methodsRefs = append(methodsRefs, j)
+		method := p.parseMethod(m.Get(j))
+		if method.InputRef == -1 {
+			return Service{}, fmt.Errorf("input message type %q for method %q not found in protobuf schema", method.InputName, method.Name)
+		}
+		if method.OutputRef == -1 {
+			return Service{}, fmt.Errorf("output message type %q for method %q not found in protobuf schema", method.OutputName, method.Name)
+		}
+
+		methods = append(methods, method)
+		methodsRefs = append(methodsRefs, methodOffset+j)
 	}
 
 	// Add the methods to the Document
@@ -538,7 +562,7 @@ func (p *RPCCompiler) parseService(s protoref.ServiceDescriptor) Service {
 		Name:        name,
 		FullName:    string(s.FullName()),
 		MethodsRefs: methodsRefs,
-	}
+	}, nil
 }
 
 // parseMethod extracts information from a protobuf method descriptor,
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go b/app/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go
index 5e098c3..17dcb38 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/compiler_test.go
@@ -291,3 +291,38 @@ func TestBuildProtoMessage(t *testing.T) {
 	require.Equal(t, 1, len(invocations))
 
 }
+
+func TestRPCCompilerCompileValidatesReferencedMessageTypes(t *testing.T) {
+	compiler, err := NewProtoCompiler(grpctest.MustProtoSchema(t), nil)
+	require.NoError(t, err)
+
+	_, err = compiler.Compile(&RPCExecutionPlan{
+		Calls: []RPCCall{
+			{
+				MethodName: "QueryUsers",
+				Request: RPCMessage{
+					Name: "MissingRequestMessage",
+				},
+				Response: RPCMessage{
+					Name: "QueryUsersResponse",
+				},
+			},
+		},
+	}, gjson.Parse(`{"variables":{}}`))
+	require.ErrorContains(t, err, `request message type "MissingRequestMessage" for method "QueryUsers" not found in protobuf schema`)
+
+	_, err = compiler.Compile(&RPCExecutionPlan{
+		Calls: []RPCCall{
+			{
+				MethodName: "QueryUsers",
+				Request: RPCMessage{
+					Name: "QueryUsersRequest",
+				},
+				Response: RPCMessage{
+					Name: "MissingResponseMessage",
+				},
+			},
+		},
+	}, gjson.Parse(`{"variables":{}}`))
+	require.ErrorContains(t, err, `response message type "MissingResponseMessage" for method "QueryUsers" not found in protobuf schema`)
+}
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go
index 1eb2b6c..65c8af8 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan.go
@@ -126,11 +126,11 @@ func (r RPCFieldSelectionSet) SelectFieldsForTypes(validTypes []string) RPCField
 		}
 
 		for _, field := range lookupFields {
-			if _, found := fieldSet[field.Name]; found {
+			if _, found := fieldSet[field.JSONPath]; found {
 				continue
 			}
 
-			fieldSet[field.Name] = struct{}{}
+			fieldSet[field.JSONPath] = struct{}{}
 			fields = append(fields, field)
 		}
 	}
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go
index 5c5f066..b06ed8c 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_test.go
@@ -1374,6 +1374,35 @@ func TestQueryExecutionPlans(t *testing.T) {
 	}
 }
 
+func TestQueryExecutionPlan_UsesFieldAliasAsResponsePath(t *testing.T) {
+	report := &operationreport.Report{}
+	schemaDoc := grpctest.MustGraphQLSchema(t)
+
+	astvalidation.DefaultDefinitionValidator().Validate(&schemaDoc, report)
+	require.False(t, report.HasErrors())
+
+	query := `query { users { userId: id userName: name } }`
+	queryDoc, queryReport := astparser.ParseGraphqlDocumentString(query)
+	require.False(t, queryReport.HasErrors())
+
+	astvalidation.DefaultOperationValidator().Validate(&queryDoc, &schemaDoc, report)
+	require.False(t, report.HasErrors())
+
+	planner := NewPlanner("Products", testMapping())
+	outPlan, err := planner.PlanOperation(&queryDoc, &schemaDoc)
+	require.NoError(t, err)
+	require.Len(t, outPlan.Calls, 1)
+	require.Len(t, outPlan.Calls[0].Response.Fields, 1)
+	require.NotNil(t, outPlan.Calls[0].Response.Fields[0].Message)
+
+	messageFields := outPlan.Calls[0].Response.Fields[0].Message.Fields
+	require.Len(t, messageFields, 2)
+	require.Equal(t, "id", messageFields[0].Name)
+	require.Equal(t, "userId", messageFields[0].JSONPath)
+	require.Equal(t, "name", messageFields[1].Name)
+	require.Equal(t, "userName", messageFields[1].JSONPath)
+}
+
 func TestCompositeTypeExecutionPlan(t *testing.T) {
 	tests := []struct {
 		name          string
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go
index f1ad122..11ec5da 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/execution_plan_visitor.go
@@ -289,6 +289,7 @@ func (r *rpcPlanVisitor) handleRootField(ref int) error {
 // EnterField implements astvisitor.EnterFieldVisitor.
 func (r *rpcPlanVisitor) EnterField(ref int) {
 	fieldName := r.operation.FieldNameString(ref)
+	fieldAliasOrName := r.operation.FieldAliasOrNameString(ref)
 	if r.IsRootField() {
 		if err := r.handleRootField(ref); err != nil {
 			r.walker.StopWithInternalErr(err)
@@ -310,11 +311,6 @@ func (r *rpcPlanVisitor) EnterField(ref int) {
 		return
 	}
 
-	// prevent duplicate fields
-	if r.planInfo.currentResponseMessage.Fields.Exists(fieldName) {
-		return
-	}
-
 	fd, ok := r.walker.FieldDefinition(ref)
 	if !ok {
 		r.walker.Report.AddExternalError(operationreport.ExternalError{
@@ -328,10 +324,17 @@ func (r *rpcPlanVisitor) EnterField(ref int) {
 
 	parentTypeName := r.walker.EnclosingTypeDefinition.NameString(r.definition)
 
+	// prevent duplicate response fields for the same response key
+	for _, existingField := range r.planInfo.currentResponseMessage.Fields {
+		if existingField.JSONPath == fieldAliasOrName {
+			return
+		}
+	}
+
 	field := RPCField{
 		Name:     r.resolveFieldMapping(parentTypeName, fieldName),
 		TypeName: typeName.String(),
-		JSONPath: fieldName,
+		JSONPath: fieldAliasOrName,
 		Repeated: r.definition.TypeIsList(fdt),
 	}
 
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go b/app/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
index 71bf396..f2aaca3 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/grpc_datasource_test.go
@@ -830,6 +830,22 @@ func Test_Datasource_Load_WithUnionTypes(t *testing.T) {
 				}
 			},
 		},
+		{
+			name:  "Mutation perform action with aliases",
+			query: `mutation($input: ActionInput!) { actionAlias: performAction(input: $input) { typeName: __typename ... on ActionSuccess { aliasedMessage: message at: timestamp } ... on ActionError { aliasedMessage: message errorCode: code } } }`,
+			vars:  `{"variables":{"input":{"type":"create_user","payload":"user data"}}}`,
+			validate: func(t *testing.T, data map[string]interface{}) {
+				actionResult, ok := data["actionAlias"].(map[string]interface{})
+				require.True(t, ok, "actionAlias should be an object")
+				require.NotEmpty(t, actionResult, "actionAlias should not be empty")
+				require.Equal(t, "ActionSuccess", actionResult["typeName"])
+				require.Equal(t, "Action 'create_user' completed successfully", actionResult["aliasedMessage"])
+				require.Equal(t, "2024-01-01T00:00:00Z", actionResult["at"])
+				require.NotContains(t, actionResult, "__typename")
+				require.NotContains(t, actionResult, "message")
+				require.NotContains(t, actionResult, "timestamp")
+			},
+		},
 		{
 			name:  "Mutation perform action - success case",
 			query: `mutation($input: ActionInput!) { performAction(input: $input) { __typename ... on ActionSuccess { message timestamp } ... on ActionError { message code } } }`,
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go b/app/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
index 10313fe..ae31951 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
+++ b/app/v2/pkg/engine/datasource/grpc_datasource/mapping_test_helper.go
@@ -87,9 +87,9 @@ func testMapping() *GRPCMapping {
 		},
 		MutationRPCs: RPCConfigMap{
 			"createUser": {
-				RPC:      "CreateUser",
-				Request:  "CreateUserRequest",
-				Response: "CreateUserResponse",
+				RPC:      "MutationCreateUser",
+				Request:  "MutationCreateUserRequest",
+				Response: "MutationCreateUserResponse",
 			},
 			"performAction": {
 				RPC:      "MutationPerformAction",
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/grpctest/mapping/mapping.go b/app/v2/pkg/grpctest/mapping/mapping.go
index 9282fa5..1e3e71b 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/grpctest/mapping/mapping.go
+++ b/app/v2/pkg/grpctest/mapping/mapping.go
@@ -89,9 +89,9 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping {
 		},
 		MutationRPCs: grpcdatasource.RPCConfigMap{
 			"createUser": {
-				RPC:      "CreateUser",
-				Request:  "CreateUserRequest",
-				Response: "CreateUserResponse",
+				RPC:      "MutationCreateUser",
+				Request:  "MutationCreateUserRequest",
+				Response: "MutationCreateUserResponse",
 			},
 			"performAction": {
 				RPC:      "MutationPerformAction",
@@ -469,6 +469,25 @@ func DefaultGRPCMapping() *grpcdatasource.GRPCMapping {
 					TargetName: "payload",
 				},
 			},
+			"SearchResult": {
+				"product": {
+					TargetName: "product",
+				},
+				"user": {
+					TargetName: "user",
+				},
+				"category": {
+					TargetName: "category",
+				},
+			},
+			"ActionResult": {
+				"actionSuccess": {
+					TargetName: "action_success",
+				},
+				"actionError": {
+					TargetName: "action_error",
+				},
+			},
 		},
 	}
 }
diff --git a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/grpctest/schema.go b/app/v2/pkg/grpctest/schema.go
index 0e2a9bf..3cbc084 100644
--- a/tmp/agent-patch-flux-pr-1209.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/v2/pkg/grpctest/schema.go
+++ b/app/v2/pkg/grpctest/schema.go
@@ -196,6 +196,16 @@ func GetFieldConfigurations() plan.FieldConfigurations {
 				},
 			},
 		},
+		{
+			TypeName:  "Mutation",
+			FieldName: "performAction",
+			Arguments: []plan.ArgumentConfiguration{
+				{
+					Name:       "input",
+					SourceType: plan.FieldArgumentSource,
+				},
+			},
+		},
 	}
 }
 
@@ -228,17 +238,22 @@ func GetDataSourceMetadata() *plan.DataSourceMetadata {
 					"typeFilterWithArguments",
 					"typeWithMultipleFilterFields",
 					"complexFilterType",
+					"calculateTotals",
 					"categories",
 					"categoriesByKind",
+					"categoriesByKinds",
 					"filterCategories",
 					"randomPet",
 					"allPets",
+					"search",
+					"randomSearchResult",
 				},
 			},
 			{
 				TypeName: "Mutation",
 				FieldNames: []string{
 					"createUser",
+					"performAction",
 				},
 			},
 		},
@@ -370,6 +385,20 @@ func GetDataSourceMetadata() *plan.DataSourceMetadata {
 					"modifiers",
 				},
 			},
+			{
+				TypeName: "ActionSuccess",
+				FieldNames: []string{
+					"message",
+					"timestamp",
+				},
+			},
+			{
+				TypeName: "ActionError",
+				FieldNames: []string{
+					"message",
+					"code",
+				},
+			},
 		},
 	}
 }