agent_patch
runs/2026-02-28__13-38-10__gpt-5-3-codex/flux-pr-1034/flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/agent-logs/agent.patch
14591 bytes
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine.go b/app/pkg/graphql/execution_engine.go
index 0369141..2eb1c18 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine.go
+++ b/app/pkg/graphql/execution_engine.go
@@ -126,7 +126,11 @@ func (e *ExecutionEngine) ExecuteWithWriter(ctx context.Context, operation *Requ
return report
}
- variables, extraArguments := execution.VariablesFromJson(operation.Variables, options.ExtraArguments)
+ execVars := operation.document.Input.Variables
+ if len(operation.variablesForExecution) != 0 {
+ execVars = operation.variablesForExecution
+ }
+ variables, extraArguments := execution.VariablesFromJson(execVars, options.ExtraArguments)
executionContext := execution.Context{
Context: ctx,
Variables: variables,
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine_v2.go b/app/pkg/graphql/execution_engine_v2.go
index 8ca7f3b..59a318c 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine_v2.go
+++ b/app/pkg/graphql/execution_engine_v2.go
@@ -259,7 +259,11 @@ func (e *ExecutionEngineV2) Execute(ctx context.Context, operation *Request, wri
execContext := e.getExecutionCtx()
defer e.putExecutionCtx(execContext)
- execContext.prepare(ctx, operation.Variables, operation.request)
+ execVars := operation.document.Input.Variables
+ if len(operation.variablesForExecution) != 0 {
+ execVars = operation.variablesForExecution
+ }
+ execContext.prepare(ctx, execVars, operation.request)
for i := range options {
options[i](execContext)
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine_v2_test.go b/app/pkg/graphql/execution_engine_v2_test.go
index 62739c8..271364c 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/execution_engine_v2_test.go
+++ b/app/pkg/graphql/execution_engine_v2_test.go
@@ -936,7 +936,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($heroNames: [String!]!){heroes(names: $heroNames)}","variables":{"heroNames":["Luke Skywalker","R2-D2"]}}`,
+ expectedBody: `{"query":"query($a: [String!]!){heroes(names: $a)}","variables":{"a":["Luke Skywalker","R2-D2"]}}`,
sendResponseBody: `{"data":{"heroes":["Human","Droid"]}}`,
sendStatusCode: 200,
}),
@@ -994,7 +994,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($heroNames: [String!], $height: String){heroes(names: $heroNames, height: $height)}","variables":{"height":null}}`,
+ expectedBody: `{"query":"query($a: [String!], $b: String){heroes(names: $a, height: $b)}","variables":{"b":null}}`,
sendResponseBody: `{"data":{"heroes":[]}}`,
sendStatusCode: 200,
}),
@@ -1167,7 +1167,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($ids: [Int]){charactersByIds(ids: $ids){name}}","variables":{"ids":[1]}}`,
+ expectedBody: `{"query":"query($a: [Int]){charactersByIds(ids: $a){name}}","variables":{"a":[1]}}`,
sendResponseBody: `{"data":{"charactersByIds":[{"name": "Luke"}]}}`,
sendStatusCode: 200,
}),
@@ -1272,7 +1272,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($name: String!, $nameOptional: String){hero(name: $name) hero2: hero(name: $nameOptional)}","variables":{"nameOptional":"R2D2","name":"R2D2"}}`,
+ expectedBody: `{"query":"query($a: String!, $b: String){hero(name: $a) hero2: hero(name: $b)}","variables":{"b":"R2D2","a":"R2D2"}}`,
sendResponseBody: `{"data":{"hero":"R2D2","hero2":"R2D2"}}`,
sendStatusCode: 200,
}),
@@ -1327,7 +1327,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($name: String!, $nameOptional: String){hero(name: $name) hero2: hero(name: $nameOptional)}","variables":{"nameOptional":"Skywalker","name":"Luke"}}`,
+ expectedBody: `{"query":"query($a: String!, $b: String){hero(name: $a) hero2: hero(name: $b)}","variables":{"b":"Skywalker","a":"Luke"}}`,
sendResponseBody: `{"data":{"hero":"R2D2","hero2":"R2D2"}}`,
sendStatusCode: 200,
}),
@@ -1381,7 +1381,7 @@ func TestExecutionEngineV2_Execute(t *testing.T) {
HTTPClient: testNetHttpClient(t, roundTripperTestCase{
expectedHost: "example.com",
expectedPath: "/",
- expectedBody: `{"query":"query($name: String!, $nameOptional: String!){hero: heroDefault(name: $name) hero2: heroDefault(name: $nameOptional) hero3: heroDefaultRequired(name: $name) hero4: heroDefaultRequired(name: $nameOptional)}","variables":{"nameOptional":"R2D2","name":"R2D2"}}`,
+ expectedBody: `{"query":"query($a: String!, $b: String!){hero: heroDefault(name: $a) hero2: heroDefault(name: $b) hero3: heroDefaultRequired(name: $a) hero4: heroDefaultRequired(name: $b)}","variables":{"b":"R2D2","a":"R2D2"}}`,
sendResponseBody: `{"data":{"hero":"R2D2","hero2":"R2D2","hero3":"R2D2","hero4":"R2D2"}}`,
sendStatusCode: 200,
}),
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/normalization.go b/app/pkg/graphql/normalization.go
index 55e8f89..5d489a9 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/normalization.go
+++ b/app/pkg/graphql/normalization.go
@@ -23,6 +23,7 @@ func (r *Request) Normalize(schema *Schema) (result NormalizationResult, err err
}
r.document.Input.Variables = r.Variables
+ r.variablesForExecution = nil
normalizer := astnormalization.NewWithOpts(
astnormalization.WithExtractVariables(),
@@ -40,9 +41,12 @@ func (r *Request) Normalize(schema *Schema) (result NormalizationResult, err err
return normalizationResultFromReport(report)
}
- r.isNormalized = true
+ r.remapOperationVariablesToCanonical()
+ if len(r.variablesForExecution) == 0 {
+ r.variablesForExecution = append(r.variablesForExecution[:0], r.document.Input.Variables...)
+ }
- r.Variables = r.document.Input.Variables
+ r.isNormalized = true
return NormalizationResult{Successful: true, Errors: nil}, nil
}
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/normalization_test.go b/app/pkg/graphql/normalization_test.go
index 10db22e..7d6b9f2 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/normalization_test.go
+++ b/app/pkg/graphql/normalization_test.go
@@ -38,11 +38,11 @@ func TestRequest_Normalize(t *testing.T) {
assert.True(t, result.Successful)
assert.True(t, request.isNormalized)
- normalizedOperation := `query Fragments($droidID: ID!){
+ normalizedOperation := `query Fragments($a: ID!){
hero {
name
}
- droid(id: $droidID){
+ droid(id: $a){
name
}
}`
@@ -94,8 +94,8 @@ func TestRequest_Normalize(t *testing.T) {
Query: `query MySearch($s: String!, $other: String) {search(name: $s) {...on Human {name}}}`,
}
- runNormalization(t, &request, `{"s":"Luke"}`, `query MySearch($s: String!){
- search(name: $s){
+ runNormalization(t, &request, `{"a":"Luke"}`, `query MySearch($a: String!){
+ search(name: $a){
... on Human {
name
}
@@ -104,7 +104,7 @@ func TestRequest_Normalize(t *testing.T) {
})
t.Run("should successfully normalize query and remove unused variables and values", func(t *testing.T) {
- const expectedVar = "query MySearch($s: String!){\n search(name: $s){\n ... on Human {\n name\n }\n }\n}"
+ const expectedVar = "query MySearch($a: String!){\n search(name: $a){\n ... on Human {\n name\n }\n }\n}"
for _, v := range []Request{
{
OperationName: "MySearch",
@@ -138,7 +138,7 @@ func TestRequest_Normalize(t *testing.T) {
Query: `query MySearch($s: String!, $s2: String, $s3: String) {search(name: $s) {...on Human {name}}}`,
},
} {
- runNormalization(t, &v, `{"s":"Luke"}`, expectedVar)
+ runNormalization(t, &v, `{"a":"Luke"}`, expectedVar)
}
})
@@ -150,8 +150,8 @@ func TestRequest_Normalize(t *testing.T) {
}),
Query: `query MySearch($s: String!, $other: String) {search(name: $s) {...on Human {name}}}`,
}
- runNormalization(t, &request, `{"s":"Luke"}`, `query MySearch($s: String!){
- search(name: $s){
+ runNormalization(t, &request, `{"a":"Luke"}`, `query MySearch($a: String!){
+ search(name: $a){
... on Human {
name
}
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/request.go b/app/pkg/graphql/request.go
index 2c47e20..af6c6c2 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-02-28__13-38-10__gpt-5-3-codex/app/pkg/graphql/request.go
+++ b/app/pkg/graphql/request.go
@@ -42,6 +42,10 @@ type Request struct {
isNormalized bool
request resolve.Request
+ variableNamesOriginalToNormalized map[string]string
+ variableNamesNormalizedToOriginal map[string]string
+ variablesForExecution json.RawMessage
+
validForSchema map[uint64]ValidationResult
}
diff --git a/app/pkg/graphql/variables_mapper.go b/app/pkg/graphql/variables_mapper.go
new file mode 100644
index 0000000..65f23ea
--- /dev/null
+++ b/app/pkg/graphql/variables_mapper.go
@@ -0,0 +1,153 @@
+package graphql
+
+import (
+ "strings"
+
+ "github.com/buger/jsonparser"
+ "github.com/tidwall/sjson"
+ "github.com/wundergraph/graphql-go-tools/pkg/ast"
+)
+
+func (r *Request) remapOperationVariablesToCanonical() {
+ r.variableNamesOriginalToNormalized = nil
+ r.variableNamesNormalizedToOriginal = nil
+
+ operationDefinitionRef, ok := r.selectedOperationDefinitionRef()
+ if !ok {
+ return
+ }
+
+ operationDefinition := r.document.OperationDefinitions[operationDefinitionRef]
+ if !operationDefinition.HasVariableDefinitions {
+ return
+ }
+
+ oldNamesInOrder := make([]string, 0, len(operationDefinition.VariableDefinitions.Refs))
+ r.variableNamesOriginalToNormalized = make(map[string]string, len(operationDefinition.VariableDefinitions.Refs))
+ r.variableNamesNormalizedToOriginal = make(map[string]string, len(operationDefinition.VariableDefinitions.Refs))
+
+ for i := range operationDefinition.VariableDefinitions.Refs {
+ definitionRef := operationDefinition.VariableDefinitions.Refs[i]
+ oldName := r.document.VariableDefinitionNameString(definitionRef)
+ newName := canonicalVariableName(i)
+ oldNamesInOrder = append(oldNamesInOrder, oldName)
+ r.variableNamesOriginalToNormalized[oldName] = newName
+ r.variableNamesNormalizedToOriginal[newName] = oldName
+ }
+
+ for i := range r.document.VariableValues {
+ oldName := r.document.VariableValueNameString(i)
+ newName, ok := r.variableNamesOriginalToNormalized[oldName]
+ if !ok || oldName == newName {
+ continue
+ }
+ r.document.VariableValues[i].Name = r.document.Input.AppendInputString(newName)
+ }
+
+ canonicalVariables := remapVariablesJSONKeys(r.document.Input.Variables, oldNamesInOrder, r.variableNamesOriginalToNormalized)
+ r.document.Input.Variables = canonicalVariables
+ r.variablesForExecution = mergeVariablesJSONKeys(canonicalVariables, r.Variables)
+}
+
+func (r *Request) selectedOperationDefinitionRef() (int, bool) {
+ opRefs := make([]int, 0, 1)
+ for i := range r.document.RootNodes {
+ if r.document.RootNodes[i].Kind != ast.NodeKindOperationDefinition {
+ continue
+ }
+ opRefs = append(opRefs, r.document.RootNodes[i].Ref)
+ }
+
+ if len(opRefs) == 0 {
+ return -1, false
+ }
+
+ if r.OperationName != "" {
+ for i := range opRefs {
+ if r.document.OperationDefinitionNameString(opRefs[i]) == r.OperationName {
+ return opRefs[i], true
+ }
+ }
+ return -1, false
+ }
+
+ if len(opRefs) == 1 {
+ return opRefs[0], true
+ }
+
+ return -1, false
+}
+
+func canonicalVariableName(index int) string {
+ const alphabetSize = 26
+ repeat := (index / alphabetSize) + 1
+ nameByte := byte('a' + (index % alphabetSize))
+ return strings.Repeat(string(nameByte), repeat)
+}
+
+func remapVariablesJSONKeys(variables []byte, orderedOldNames []string, mapping map[string]string) []byte {
+ if len(mapping) == 0 {
+ return variables
+ }
+
+ remapped := []byte("{}")
+
+ for i := range orderedOldNames {
+ oldName := orderedOldNames[i]
+ newName := mapping[oldName]
+
+ value, valueType, _, err := jsonparser.Get(variables, oldName)
+ if err != nil {
+ continue
+ }
+
+ var (
+ next []byte
+ )
+ switch valueType {
+ case jsonparser.String:
+ next, err = sjson.SetBytes(remapped, newName, string(value))
+ default:
+ next, err = sjson.SetRawBytes(remapped, newName, value)
+ }
+ if err != nil {
+ continue
+ }
+ remapped = next
+ }
+
+ return remapped
+}
+
+func mergeVariablesJSONKeys(canonicalVariables, clientVariables []byte) []byte {
+ if len(canonicalVariables) == 0 {
+ return canonicalVariables
+ }
+
+ merged := append([]byte(nil), canonicalVariables...)
+
+ _ = jsonparser.ObjectEach(clientVariables, func(key, value []byte, valueType jsonparser.ValueType, offset int) error {
+ keyName := string(key)
+ if _, _, _, err := jsonparser.Get(merged, keyName); err == nil {
+ return nil
+ }
+
+ var (
+ next []byte
+ err error
+ )
+ switch valueType {
+ case jsonparser.String:
+ next, err = sjson.SetBytes(merged, keyName, string(value))
+ default:
+ next, err = sjson.SetRawBytes(merged, keyName, value)
+ }
+ if err != nil {
+ return nil
+ }
+ merged = next
+ return nil
+ })
+
+ return merged
+}